mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Compare commits
293 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6058160160 | ||
|
|
479dfc28b9 | ||
|
|
8392788cdb | ||
|
|
55242edbde | ||
|
|
2c5d9f043e | ||
|
|
2b2acbe244 | ||
|
|
7d4e103660 | ||
|
|
86798ae9ea | ||
|
|
2830e6d199 | ||
|
|
8c07573f8f | ||
|
|
f3af0262df | ||
|
|
0f270a6a35 | ||
|
|
8432f46e48 | ||
|
|
faccee88e7 | ||
|
|
e8246b3b90 | ||
|
|
eb4e7b9281 | ||
|
|
1e2190a6cc | ||
|
|
1644c1dc5b | ||
|
|
5fc3798c42 | ||
|
|
fae81cdb1b | ||
|
|
dbae37f151 | ||
|
|
f7d58a0b76 | ||
|
|
2e0d1fd90f | ||
|
|
69e6497655 | ||
|
|
ef8c7c9084 | ||
|
|
e4eaf72769 | ||
|
|
5138ced630 | ||
|
|
534f445f8c | ||
|
|
b2cc3e5329 | ||
|
|
efde321616 | ||
|
|
3a61581608 | ||
|
|
3a10f0b946 | ||
|
|
6dc6972bdb | ||
|
|
405235a59d | ||
|
|
9c148625e4 | ||
|
|
a08d82a3d9 | ||
|
|
48b51f21de | ||
|
|
3260279cb7 | ||
|
|
1e60a0a32a | ||
|
|
146f869aaa | ||
|
|
0bd35727f4 | ||
|
|
5183fcc316 | ||
|
|
bf7596521c | ||
|
|
a85b6c960c | ||
|
|
a1aebf0575 | ||
|
|
0f42218681 | ||
|
|
5404f9ef19 | ||
|
|
8a84be19df | ||
|
|
fd4ea81e46 | ||
|
|
3df79aedb1 | ||
|
|
4141aa35ba | ||
|
|
6e45ee558e | ||
|
|
db138be5f3 | ||
|
|
5ae6495e69 | ||
|
|
58f1bc5531 | ||
|
|
935b52c489 | ||
|
|
aace98545a | ||
|
|
f39236c8fd | ||
|
|
43b4a6834b | ||
|
|
aa3978b04d | ||
|
|
b51e758516 | ||
|
|
5be1832c09 | ||
|
|
362652ac6c | ||
|
|
aec69884dc | ||
|
|
8fb4d4c7c6 | ||
|
|
b5524b9a69 | ||
|
|
ec0ff7afcd | ||
|
|
d0cf68c2e2 | ||
|
|
3beb98a5e9 | ||
|
|
dd83ebe0e2 | ||
|
|
6fdf3957bd | ||
|
|
f3d586d455 | ||
|
|
c2f0ce0fa2 | ||
|
|
354490d149 | ||
|
|
c5b0be5d21 | ||
|
|
5e8676cf8a | ||
|
|
f4264cd149 | ||
|
|
65d1c4187e | ||
|
|
cda1432d04 | ||
|
|
09e5fca1a5 | ||
|
|
e38d73df8b | ||
|
|
7df90b2d30 | ||
|
|
a917ee8f1e | ||
|
|
44f3c776eb | ||
|
|
873879ff79 | ||
|
|
6c1907f7e0 | ||
|
|
42ecdd3b14 | ||
|
|
297164a0ee | ||
|
|
323f09b06c | ||
|
|
e003b91bbe | ||
|
|
f1636fc5a9 | ||
|
|
db053398d2 | ||
|
|
417caf1b62 | ||
|
|
cc76851614 | ||
|
|
27fe314c1e | ||
|
|
2c12cfe4fd | ||
|
|
9adf342dd8 | ||
|
|
facac82130 | ||
|
|
3e095711f4 | ||
|
|
ca1ddb4013 | ||
|
|
8169235d2f | ||
|
|
4553785918 | ||
|
|
78b3efcf00 | ||
|
|
67cb844550 | ||
|
|
b9cf1e46af | ||
|
|
4a04d7cce7 | ||
|
|
35f15435a3 | ||
|
|
4c97d966a2 | ||
|
|
674c6eec81 | ||
|
|
c75c3d8777 | ||
|
|
4fa63986dc | ||
|
|
029f7a3f5c | ||
|
|
e9194c59f4 | ||
|
|
c8d693c8e7 | ||
|
|
2341014882 | ||
|
|
eb15fadcfe | ||
|
|
13fa8f373e | ||
|
|
b318e8ae13 | ||
|
|
7e963bef41 | ||
|
|
933000ffc7 | ||
|
|
9b217e1c97 | ||
|
|
324f4944b4 | ||
|
|
f735f1eb53 | ||
|
|
7149226283 | ||
|
|
4164a5288a | ||
|
|
1992276b07 | ||
|
|
21a7023b7b | ||
|
|
f094716b73 | ||
|
|
4b1888a34d | ||
|
|
b9be3aa7f8 | ||
|
|
fd2dacaefb | ||
|
|
cc60e85901 | ||
|
|
f172f6efeb | ||
|
|
b6b6686873 | ||
|
|
5e724e7a3f | ||
|
|
90f1d1df2a | ||
|
|
a5726c0ed8 | ||
|
|
23ff128ac8 | ||
|
|
7d3fc1740a | ||
|
|
b2a084d669 | ||
|
|
30203668e4 | ||
|
|
ebecc70693 | ||
|
|
74712b6e27 | ||
|
|
40253ea8bb | ||
|
|
4e56078d2a | ||
|
|
4bbf20ca4e | ||
|
|
a462c5a493 | ||
|
|
367014ebf3 | ||
|
|
326b20b08d | ||
|
|
11b0ce6275 | ||
|
|
03763e16d6 | ||
|
|
c1e8ee12e0 | ||
|
|
ac8cc408c1 | ||
|
|
ada38fa3ea | ||
|
|
2ee0597d48 | ||
|
|
7ae4cdc8f1 | ||
|
|
8c92a578ed | ||
|
|
096f2caf9c | ||
|
|
0b37c909b3 | ||
|
|
1b18ae1597 | ||
|
|
c9ac6d73e6 | ||
|
|
0e836973fd | ||
|
|
be40d7be9a | ||
|
|
f3b7740041 | ||
|
|
7d7488db6f | ||
|
|
4964cc2f2d | ||
|
|
f0a4c5b008 | ||
|
|
1b6412821b | ||
|
|
926a0733e4 | ||
|
|
da70f4ce6c | ||
|
|
727cb3276c | ||
|
|
33e63a4819 | ||
|
|
3543b2c79a | ||
|
|
4489efff94 | ||
|
|
6a4bddde99 | ||
|
|
dc2511942c | ||
|
|
f0c257c4a5 | ||
|
|
068d21612f | ||
|
|
773461aad9 | ||
|
|
f9257b2b0d | ||
|
|
9e0f03a3cd | ||
|
|
a467fabdc8 | ||
|
|
a2ab84c45a | ||
|
|
9fd6729967 | ||
|
|
f1d4f1753a | ||
|
|
6d9c3fd0aa | ||
|
|
28ae63bd8d | ||
|
|
42e7e3f94f | ||
|
|
6466c5e95e | ||
|
|
829f5af25f | ||
|
|
0d1147bac4 | ||
|
|
24b47b02e0 | ||
|
|
3cabc07d58 | ||
|
|
b0546b1e60 | ||
|
|
a988e67490 | ||
|
|
2594c5bbf0 | ||
|
|
db70fa341c | ||
|
|
763e3852ac | ||
|
|
8ec86973c6 | ||
|
|
eb2c6ac6f2 | ||
|
|
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 |
@ -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.
|
||||||
|
|||||||
@ -18,6 +18,8 @@
|
|||||||
--- 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.
|
||||||
|
|||||||
@ -33,6 +33,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # 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.
|
||||||
|
|||||||
@ -17,6 +17,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.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # 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,7 +361,7 @@ 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 = {}
|
||||||
|
|||||||
@ -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.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
@ -521,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
|
||||||
)
|
)
|
||||||
@ -577,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.
|
||||||
|
|||||||
@ -15,6 +15,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.
|
||||||
--
|
--
|
||||||
-- The AI_CARGO_AIRPLANE module uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
-- The AI_CARGO_AIRPLANE module uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
||||||
@ -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.
|
||||||
|
|||||||
@ -41,6 +41,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!!!
|
||||||
-- The purpose of the class is to:
|
-- The purpose of the class is to:
|
||||||
@ -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
|
||||||
)
|
)
|
||||||
@ -890,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.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -11,6 +11,8 @@ 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
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # @{#ACT_ASSIGN} FSM template class, extends @{Core.Fsm#FSM_PROCESS}
|
-- # @{#ACT_ASSIGN} FSM template class, extends @{Core.Fsm#FSM_PROCESS}
|
||||||
--
|
--
|
||||||
-- ## ACT_ASSIGN state machine:
|
-- ## ACT_ASSIGN state machine:
|
||||||
|
|||||||
@ -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 } )
|
||||||
|
|
||||||
|
|||||||
@ -974,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, ... )
|
||||||
|
|
||||||
|
|||||||
@ -577,13 +577,19 @@ do -- Zones and Pathlines
|
|||||||
-- For a rectangular polygon drawing, we have the width (y) and height (x).
|
-- For a rectangular polygon drawing, we have the width (y) and height (x).
|
||||||
local w=objectData.width
|
local w=objectData.width
|
||||||
local h=objectData.height
|
local h=objectData.height
|
||||||
|
local rotation = UTILS.ToRadian(objectData.angle or 0)
|
||||||
|
|
||||||
-- Create points from center using with and height (width for y and height for x is a bit confusing, but this is how ED implemented it).
|
local sinRot = math.sin(rotation)
|
||||||
local points={}
|
local cosRot = math.cos(rotation)
|
||||||
points[1]={x=vec2.x-h/2, y=vec2.y+w/2} --Upper left
|
local dx = h / 2
|
||||||
points[2]={x=vec2.x+h/2, y=vec2.y+w/2} --Upper right
|
local dy = w / 2
|
||||||
points[3]={x=vec2.x+h/2, y=vec2.y-w/2} --Lower right
|
|
||||||
points[4]={x=vec2.x-h/2, y=vec2.y-w/2} --Lower left
|
local points = {
|
||||||
|
{ x = -dx * cosRot - (-dy * sinRot) + vec2.x, y = -dx * sinRot + (-dy * cosRot) + vec2.y },
|
||||||
|
{ x = dx * cosRot - (-dy * sinRot) + vec2.x, y = dx * sinRot + (-dy * cosRot) + vec2.y },
|
||||||
|
{ x = dx * cosRot - (dy * sinRot) + vec2.x, y = dx * sinRot + (dy * cosRot) + vec2.y },
|
||||||
|
{ x = -dx * cosRot - (dy * sinRot) + vec2.x, y = -dx * sinRot + (dy * cosRot) + vec2.y },
|
||||||
|
}
|
||||||
|
|
||||||
--local coord=COORDINATE:NewFromVec2(vec2):MarkToAll("MapX, MapY")
|
--local coord=COORDINATE:NewFromVec2(vec2):MarkToAll("MapX, MapY")
|
||||||
|
|
||||||
@ -872,6 +878,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
|
||||||
@ -1110,7 +1118,7 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category
|
|||||||
self:E("WARNING: Invalid STN "..tostring(UnitTemplate.AddPropAircraft.STN_L16).." for ".. UnitTemplate.name)
|
self:E("WARNING: Invalid STN "..tostring(UnitTemplate.AddPropAircraft.STN_L16).." for ".. UnitTemplate.name)
|
||||||
else
|
else
|
||||||
self.STNS[stn] = UnitTemplate.name
|
self.STNS[stn] = UnitTemplate.name
|
||||||
self:I("Register STN "..tostring(UnitTemplate.AddPropAircraft.STN_L16).." for ".. UnitTemplate.name)
|
self:T("Register STN "..tostring(UnitTemplate.AddPropAircraft.STN_L16).." for ".. UnitTemplate.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if UnitTemplate.AddPropAircraft.SADL_TN then
|
if UnitTemplate.AddPropAircraft.SADL_TN then
|
||||||
@ -1119,7 +1127,7 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category
|
|||||||
self:E("WARNING: Invalid SADL "..tostring(UnitTemplate.AddPropAircraft.SADL_TN).." for ".. UnitTemplate.name)
|
self:E("WARNING: Invalid SADL "..tostring(UnitTemplate.AddPropAircraft.SADL_TN).." for ".. UnitTemplate.name)
|
||||||
else
|
else
|
||||||
self.SADL[sadl] = UnitTemplate.name
|
self.SADL[sadl] = UnitTemplate.name
|
||||||
self:I("Register SADL "..tostring(UnitTemplate.AddPropAircraft.SADL_TN).." for ".. UnitTemplate.name)
|
self:T("Register SADL "..tostring(UnitTemplate.AddPropAircraft.SADL_TN).." for ".. UnitTemplate.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1380,7 +1388,7 @@ function DATABASE:GetCoalitionFromClientTemplate( ClientName )
|
|||||||
if self.Templates.ClientsByName[ClientName] then
|
if self.Templates.ClientsByName[ClientName] then
|
||||||
return self.Templates.ClientsByName[ClientName].CoalitionID
|
return self.Templates.ClientsByName[ClientName].CoalitionID
|
||||||
end
|
end
|
||||||
self:E("WARNING: Template does not exist for client "..tostring(ClientName))
|
self:T("WARNING: Template does not exist for client "..tostring(ClientName))
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1392,7 +1400,7 @@ function DATABASE:GetCategoryFromClientTemplate( ClientName )
|
|||||||
if self.Templates.ClientsByName[ClientName] then
|
if self.Templates.ClientsByName[ClientName] then
|
||||||
return self.Templates.ClientsByName[ClientName].CategoryID
|
return self.Templates.ClientsByName[ClientName].CategoryID
|
||||||
end
|
end
|
||||||
self:E("WARNING: Template does not exist for client "..tostring(ClientName))
|
self:T("WARNING: Template does not exist for client "..tostring(ClientName))
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1404,7 +1412,7 @@ function DATABASE:GetCountryFromClientTemplate( ClientName )
|
|||||||
if self.Templates.ClientsByName[ClientName] then
|
if self.Templates.ClientsByName[ClientName] then
|
||||||
return self.Templates.ClientsByName[ClientName].CountryID
|
return self.Templates.ClientsByName[ClientName].CountryID
|
||||||
end
|
end
|
||||||
self:E("WARNING: Template does not exist for client "..tostring(ClientName))
|
self:T("WARNING: Template does not exist for client "..tostring(ClientName))
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1697,7 +1705,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 and 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
|
||||||
---
|
---
|
||||||
@ -1507,10 +1508,12 @@ function EVENT:onEvent( Event )
|
|||||||
else
|
else
|
||||||
if Event.place:isExist() and Object.getCategory(Event.place) ~= Object.Category.SCENERY then
|
if Event.place:isExist() and Object.getCategory(Event.place) ~= Object.Category.SCENERY then
|
||||||
Event.Place=AIRBASE:Find(Event.place)
|
Event.Place=AIRBASE:Find(Event.place)
|
||||||
|
if Event.Place then
|
||||||
Event.PlaceName=Event.Place:GetName()
|
Event.PlaceName=Event.Place:GetName()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Mark points.
|
-- Mark points.
|
||||||
if Event.idx then
|
if Event.idx then
|
||||||
|
|||||||
@ -50,7 +50,7 @@ MARKEROPS_BASE = {
|
|||||||
ClassName = "MARKEROPS",
|
ClassName = "MARKEROPS",
|
||||||
Tag = "mytag",
|
Tag = "mytag",
|
||||||
Keywords = {},
|
Keywords = {},
|
||||||
version = "0.1.3",
|
version = "0.1.4",
|
||||||
debug = false,
|
debug = false,
|
||||||
Casesensitive = true,
|
Casesensitive = true,
|
||||||
}
|
}
|
||||||
@ -154,14 +154,7 @@ function MARKEROPS_BASE:OnEventMark(Event)
|
|||||||
self:E("Skipping onEvent. Event or Event.idx unknown.")
|
self:E("Skipping onEvent. Event or Event.idx unknown.")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
--position
|
|
||||||
local vec3={y=Event.pos.y, x=Event.pos.x, z=Event.pos.z}
|
|
||||||
local coord=COORDINATE:NewFromVec3(vec3)
|
|
||||||
if self.debug then
|
|
||||||
local coordtext = coord:ToStringLLDDM()
|
|
||||||
local text = tostring(Event.text)
|
|
||||||
local m = MESSAGE:New(string.format("Mark added at %s with text: %s",coordtext,text),10,"Info",false):ToAll()
|
|
||||||
end
|
|
||||||
local coalition = Event.MarkCoalition
|
local coalition = Event.MarkCoalition
|
||||||
-- decision
|
-- decision
|
||||||
if Event.id==world.event.S_EVENT_MARK_ADDED then
|
if Event.id==world.event.S_EVENT_MARK_ADDED then
|
||||||
@ -170,6 +163,12 @@ function MARKEROPS_BASE:OnEventMark(Event)
|
|||||||
local Eventtext = tostring(Event.text)
|
local Eventtext = tostring(Event.text)
|
||||||
if Eventtext~=nil then
|
if Eventtext~=nil then
|
||||||
if self:_MatchTag(Eventtext) then
|
if self:_MatchTag(Eventtext) then
|
||||||
|
local coord=COORDINATE:NewFromVec3({y=Event.pos.y, x=Event.pos.x, z=Event.pos.z})
|
||||||
|
if self.debug then
|
||||||
|
local coordtext = coord:ToStringLLDDM()
|
||||||
|
local text = tostring(Event.text)
|
||||||
|
local m = MESSAGE:New(string.format("Mark added at %s with text: %s",coordtext,text),10,"Info",false):ToAll()
|
||||||
|
end
|
||||||
local matchtable = self:_MatchKeywords(Eventtext)
|
local matchtable = self:_MatchKeywords(Eventtext)
|
||||||
self:MarkAdded(Eventtext,matchtable,coord,Event.idx,coalition,Event.PlayerName,Event)
|
self:MarkAdded(Eventtext,matchtable,coord,Event.idx,coalition,Event.PlayerName,Event)
|
||||||
end
|
end
|
||||||
@ -180,6 +179,12 @@ function MARKEROPS_BASE:OnEventMark(Event)
|
|||||||
local Eventtext = tostring(Event.text)
|
local Eventtext = tostring(Event.text)
|
||||||
if Eventtext~=nil then
|
if Eventtext~=nil then
|
||||||
if self:_MatchTag(Eventtext) then
|
if self:_MatchTag(Eventtext) then
|
||||||
|
local coord=COORDINATE:NewFromVec3({y=Event.pos.y, x=Event.pos.x, z=Event.pos.z})
|
||||||
|
if self.debug then
|
||||||
|
local coordtext = coord:ToStringLLDDM()
|
||||||
|
local text = tostring(Event.text)
|
||||||
|
local m = MESSAGE:New(string.format("Mark changed at %s with text: %s",coordtext,text),10,"Info",false):ToAll()
|
||||||
|
end
|
||||||
local matchtable = self:_MatchKeywords(Eventtext)
|
local matchtable = self:_MatchKeywords(Eventtext)
|
||||||
self:MarkChanged(Eventtext,matchtable,coord,Event.idx,coalition,Event.PlayerName,Event)
|
self:MarkChanged(Eventtext,matchtable,coord,Event.idx,coalition,Event.PlayerName,Event)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -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
|
||||||
@ -452,7 +452,7 @@ end
|
|||||||
_MESSAGESRS = {}
|
_MESSAGESRS = {}
|
||||||
|
|
||||||
--- Set up MESSAGE generally to allow Text-To-Speech via SRS and TTS functions. `SetMSRS()` will try to use as many attributes configured with @{Sound.SRS#MSRS.LoadConfigFile}() as possible.
|
--- Set up MESSAGE generally to allow Text-To-Speech via SRS and TTS functions. `SetMSRS()` will try to use as many attributes configured with @{Sound.SRS#MSRS.LoadConfigFile}() as possible.
|
||||||
-- @param #string PathToSRS (optional) Path to SRS Folder, defaults to "C:\\\\Program Files\\\\DCS-SimpleRadio-Standalone" or your configuration file setting.
|
-- @param #string PathToSRS (optional) Path to SRS TTS Folder, defaults to "C:\\\\Program Files\\\\DCS-SimpleRadio-Standalone\\ExternalAudio" or your configuration file setting.
|
||||||
-- @param #number Port Port (optional) number of SRS, defaults to 5002 or your configuration file setting.
|
-- @param #number Port Port (optional) number of SRS, defaults to 5002 or your configuration file setting.
|
||||||
-- @param #string PathToCredentials (optional) Path to credentials file for Google.
|
-- @param #string PathToCredentials (optional) Path to credentials file for Google.
|
||||||
-- @param #number Frequency Frequency in MHz. Can also be given as a #table of frequencies.
|
-- @param #number Frequency Frequency in MHz. Can also be given as a #table of frequencies.
|
||||||
@ -468,13 +468,13 @@ _MESSAGESRS = {}
|
|||||||
-- @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
|
||||||
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
|
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
|
||||||
-- -- 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,Backend)
|
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\\ExternalAudio"
|
||||||
|
|
||||||
_MESSAGESRS.frequency = Frequency or MSRS.frequencies or 243
|
_MESSAGESRS.frequency = Frequency or MSRS.frequencies or 243
|
||||||
_MESSAGESRS.modulation = Modulation or MSRS.modulations or radio.modulation.AM
|
_MESSAGESRS.modulation = Modulation or MSRS.modulations or radio.modulation.AM
|
||||||
@ -535,7 +535,7 @@ end
|
|||||||
-- @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
|
||||||
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
|
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
|
||||||
-- -- later on in your code
|
-- -- later on in your code
|
||||||
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS()
|
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS()
|
||||||
--
|
--
|
||||||
@ -567,7 +567,7 @@ end
|
|||||||
-- @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
|
||||||
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
|
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
|
||||||
-- -- later on in your code
|
-- -- later on in your code
|
||||||
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSBlue()
|
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSBlue()
|
||||||
--
|
--
|
||||||
@ -589,7 +589,7 @@ end
|
|||||||
-- @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
|
||||||
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.RED)
|
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.RED)
|
||||||
-- -- later on in your code
|
-- -- later on in your code
|
||||||
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSRed()
|
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSRed()
|
||||||
--
|
--
|
||||||
@ -611,7 +611,7 @@ end
|
|||||||
-- @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
|
||||||
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.NEUTRAL)
|
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.NEUTRAL)
|
||||||
-- -- later on in your code
|
-- -- later on in your code
|
||||||
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSAll()
|
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSAll()
|
||||||
--
|
--
|
||||||
|
|||||||
@ -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
|
||||||
--
|
--
|
||||||
@ -773,7 +777,9 @@ do -- COORDINATE
|
|||||||
-- @return DCS#Vec2 Vec2
|
-- @return DCS#Vec2 Vec2
|
||||||
function COORDINATE:GetRandomVec2InRadius( OuterRadius, InnerRadius )
|
function COORDINATE:GetRandomVec2InRadius( OuterRadius, InnerRadius )
|
||||||
self:F2( { OuterRadius, InnerRadius } )
|
self:F2( { OuterRadius, InnerRadius } )
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
local Theta = 2 * math.pi * math.random()
|
local Theta = 2 * math.pi * math.random()
|
||||||
local Radials = math.random() + math.random()
|
local Radials = math.random() + math.random()
|
||||||
if Radials > 1 then
|
if Radials > 1 then
|
||||||
@ -833,6 +839,26 @@ do -- COORDINATE
|
|||||||
return land.getHeight( Vec2 )
|
return land.getHeight( Vec2 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns a table of DCS#Vec3 points representing the terrain profile between two points.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param Destination DCS#Vec3 Ending point of the profile.
|
||||||
|
-- @return #table DCS#Vec3 table of the profile
|
||||||
|
function COORDINATE:GetLandProfileVec3(Destination)
|
||||||
|
return land.profile(self:GetVec3(), Destination)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns a table of #COORDINATE representing the terrain profile between two points.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param Destination #COORDINATE Ending coordinate of the profile.
|
||||||
|
-- @return #table #COORDINATE table of the profile
|
||||||
|
function COORDINATE:GetLandProfileCoordinates(Destination)
|
||||||
|
local points = self:GetLandProfileVec3(Destination:GetVec3())
|
||||||
|
local coords = {}
|
||||||
|
for _, point in ipairs(points) do
|
||||||
|
table.insert(coords, COORDINATE:NewFromVec3(point))
|
||||||
|
end
|
||||||
|
return coords
|
||||||
|
end
|
||||||
|
|
||||||
--- Set the heading of the coordinate, if applicable.
|
--- Set the heading of the coordinate, if applicable.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
@ -1157,6 +1183,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:
|
||||||
@ -1455,6 +1637,7 @@ do -- COORDINATE
|
|||||||
if AirbaseCategory == Airbase.Category.SHIP or AirbaseCategory == Airbase.Category.HELIPAD then
|
if AirbaseCategory == Airbase.Category.SHIP or AirbaseCategory == Airbase.Category.HELIPAD then
|
||||||
RoutePoint.linkUnit = AirbaseID
|
RoutePoint.linkUnit = AirbaseID
|
||||||
RoutePoint.helipadId = AirbaseID
|
RoutePoint.helipadId = AirbaseID
|
||||||
|
RoutePoint.airdromeId = airbase:IsAirdrome() and AirbaseID or nil
|
||||||
elseif AirbaseCategory == Airbase.Category.AIRDROME then
|
elseif AirbaseCategory == Airbase.Category.AIRDROME then
|
||||||
RoutePoint.airdromeId = AirbaseID
|
RoutePoint.airdromeId = AirbaseID
|
||||||
else
|
else
|
||||||
@ -1962,16 +2145,114 @@ 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.
|
||||||
-- @param #string name (Optional) Name if you want to stop the smoke early (normal duration: 5mins)
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
function COORDINATE:Smoke( SmokeColor, name )
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
self:F2( { SmokeColor } )
|
-- @param #string Name (Optional) Name if you want to stop the smoke early (normal duration: 5mins)
|
||||||
self.firename = name or "Smoke-"..math.random(1,100000)
|
-- @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 )
|
trigger.action.smoke( self:GetVec3(), SmokeColor, self.firename )
|
||||||
end
|
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.
|
--- Stops smoking the point in a color.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #string name (Optional) Name if you want to stop the smoke early (normal duration: 5mins)
|
-- @param #string name (Optional) Name if you want to stop the smoke early (normal duration: 5mins)
|
||||||
@ -1981,49 +2262,83 @@ do -- COORDINATE
|
|||||||
|
|
||||||
--- 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.
|
||||||
@ -2036,82 +2351,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.
|
||||||
@ -2765,8 +3096,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 type(sunrise) == "string" or type(sunset) == "string" then
|
||||||
if sunrise == "N/R" then return false end
|
if sunrise == "N/R" then return false end
|
||||||
if sunrise == "N/S" then return true end
|
if sunset == "N/S" then return true end
|
||||||
|
end
|
||||||
|
|
||||||
local time=UTILS.ClockToSeconds(clock)
|
local time=UTILS.ClockToSeconds(clock)
|
||||||
|
|
||||||
@ -2785,6 +3118,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()
|
||||||
|
|
||||||
@ -3474,9 +3812,37 @@ 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
|
||||||
|
|
||||||
do -- POINT_VEC3
|
|
||||||
|
--- Search for clear zones in a given area. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
||||||
|
-- @param #number SearchRadius Radius of the search area.
|
||||||
|
-- @param #number PosRadius Required clear radius around each position.
|
||||||
|
-- @param #number NumPositions Number of positions to find.
|
||||||
|
-- @return #table A table of Core.Point#COORDINATE that are clear of map objects within the given PosRadius. nil if no positions are found.
|
||||||
|
function COORDINATE:GetSimpleZones(SearchRadius, PosRadius, NumPositions)
|
||||||
|
local clearPositions = UTILS.GetSimpleZones(self:GetVec3(), SearchRadius, PosRadius, NumPositions)
|
||||||
|
if clearPositions and #clearPositions > 0 then
|
||||||
|
local coords = {}
|
||||||
|
for _, pos in pairs(clearPositions) do
|
||||||
|
local coord = COORDINATE:NewFromVec2(pos)
|
||||||
|
table.insert(coords, coord)
|
||||||
|
end
|
||||||
|
return coords
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
|
||||||
--- The POINT_VEC3 class
|
--- The POINT_VEC3 class
|
||||||
-- @type POINT_VEC3
|
-- @type POINT_VEC3
|
||||||
@ -3493,6 +3859,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,
|
||||||
@ -3580,130 +3948,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
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
|
||||||
--- Create a new POINT_VEC3 object from Vec3 coordinates.
|
--- @type POINT_VEC2
|
||||||
-- @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
|
|
||||||
|
|
||||||
do -- 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:
|
||||||
@ -3751,166 +4008,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
|
||||||
|
|||||||
@ -175,7 +175,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
|||||||
local Name = Info.name or "?"
|
local Name = Info.name or "?"
|
||||||
|
|
||||||
local ErrorHandler = function( errmsg )
|
local ErrorHandler = function( errmsg )
|
||||||
env.info( "Error in timer function: " .. errmsg )
|
env.info( "Error in timer function: " .. errmsg or "" )
|
||||||
if BASE.Debug ~= nil then
|
if BASE.Debug ~= nil then
|
||||||
env.info( BASE.Debug.traceback() )
|
env.info( BASE.Debug.traceback() )
|
||||||
end
|
end
|
||||||
@ -326,7 +326,7 @@ function SCHEDULEDISPATCHER:Stop( Scheduler, CallID )
|
|||||||
local Schedule = self.Schedule[Scheduler][CallID] -- #SCHEDULEDISPATCHER.ScheduleData
|
local Schedule = self.Schedule[Scheduler][CallID] -- #SCHEDULEDISPATCHER.ScheduleData
|
||||||
|
|
||||||
-- Only stop when there is a ScheduleID defined for the CallID. So, when the scheduler was stopped before, do nothing.
|
-- Only stop when there is a ScheduleID defined for the CallID. So, when the scheduler was stopped before, do nothing.
|
||||||
if Schedule.ScheduleID then
|
if Schedule and Schedule.ScheduleID then
|
||||||
|
|
||||||
self:T( string.format( "SCHEDULEDISPATCHER stopping scheduler CallID=%s, ScheduleID=%s", tostring( CallID ), tostring( Schedule.ScheduleID ) ) )
|
self:T( string.format( "SCHEDULEDISPATCHER stopping scheduler CallID=%s, ScheduleID=%s", tostring( CallID ), tostring( Schedule.ScheduleID ) ) )
|
||||||
|
|
||||||
|
|||||||
@ -629,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
|
||||||
@ -644,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
|
||||||
@ -959,6 +959,25 @@ do -- SET_BASE
|
|||||||
return ObjectNames
|
return ObjectNames
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get a *new* set table that only contains alive objects.
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @return #table Set table of alive objects.
|
||||||
|
function SET_BASE:GetAliveSet()
|
||||||
|
--self:F2()
|
||||||
|
|
||||||
|
local AliveSet = {}
|
||||||
|
-- Clean the Set before returning with only the alive Objects.
|
||||||
|
for ObjectName, Object in pairs( self.Set ) do
|
||||||
|
if Object then
|
||||||
|
if Object:IsAlive() then
|
||||||
|
AliveSet[#AliveSet+1] = Object
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return AliveSet or {}
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -1125,25 +1144,25 @@ do
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get a *new* set that only contains alive groups.
|
--- Get a *new* set table that only contains alive groups.
|
||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
-- @return #SET_GROUP Set of alive groups.
|
-- @return #table Set of alive groups.
|
||||||
function SET_GROUP:GetAliveSet()
|
function SET_GROUP:GetAliveSet()
|
||||||
--self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local AliveSet = SET_GROUP:New()
|
--local AliveSet = SET_GROUP:New()
|
||||||
|
local AliveSet = {}
|
||||||
-- Clean the Set before returning with only the alive Groups.
|
-- Clean the Set before returning with only the alive Groups.
|
||||||
for GroupName, GroupObject in pairs( self.Set ) do
|
for GroupName, GroupObject in pairs( self.Set ) do
|
||||||
local GroupObject = GroupObject -- Wrapper.Group#GROUP
|
local GroupObject = GroupObject -- Wrapper.Group#GROUP
|
||||||
if GroupObject then
|
if GroupObject then
|
||||||
if GroupObject:IsAlive() then
|
if GroupObject:IsAlive() then
|
||||||
AliveSet:Add( GroupName, GroupObject )
|
AliveSet[GroupName] = GroupObject
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return AliveSet.Set or {}
|
return AliveSet or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a report of of unit types.
|
--- Returns a report of of unit types.
|
||||||
@ -1242,12 +1261,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
|
||||||
@ -1257,9 +1276,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
|
||||||
@ -2520,6 +2539,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.
|
||||||
-- @param #SET_UNIT self
|
-- @param #SET_UNIT self
|
||||||
@ -2566,7 +2614,7 @@ do -- SET_UNIT
|
|||||||
|
|
||||||
--- Gets the alive set.
|
--- Gets the alive set.
|
||||||
-- @param #SET_UNIT self
|
-- @param #SET_UNIT self
|
||||||
-- @return #table Table of SET objects
|
-- @return #table Table of alive UNIT objects
|
||||||
-- @return #SET_UNIT AliveSet
|
-- @return #SET_UNIT AliveSet
|
||||||
function SET_UNIT:GetAliveSet()
|
function SET_UNIT:GetAliveSet()
|
||||||
|
|
||||||
@ -2574,10 +2622,8 @@ do -- SET_UNIT
|
|||||||
|
|
||||||
-- Clean the Set before returning with only the alive Groups.
|
-- Clean the Set before returning with only the alive Groups.
|
||||||
for GroupName, GroupObject in pairs(self.Set) do
|
for GroupName, GroupObject in pairs(self.Set) do
|
||||||
local GroupObject=GroupObject --Wrapper.Client#CLIENT
|
|
||||||
|
|
||||||
if GroupObject and GroupObject:IsAlive() then
|
if GroupObject and GroupObject:IsAlive() then
|
||||||
AliveSet:Add(GroupName, GroupObject)
|
AliveSet[GroupName] = GroupObject
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -4435,6 +4481,35 @@ do -- SET_CLIENT
|
|||||||
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.
|
||||||
-- @param #SET_CLIENT self
|
-- @param #SET_CLIENT self
|
||||||
@ -4726,18 +4801,16 @@ do -- SET_CLIENT
|
|||||||
-- @return #table Table of SET objects
|
-- @return #table Table of SET objects
|
||||||
function SET_CLIENT:GetAliveSet()
|
function SET_CLIENT:GetAliveSet()
|
||||||
|
|
||||||
local AliveSet = SET_CLIENT:New()
|
local AliveSet = {}
|
||||||
|
|
||||||
-- Clean the Set before returning with only the alive Groups.
|
-- Clean the Set before returning with only the alive Groups.
|
||||||
for GroupName, GroupObject in pairs(self.Set) do
|
for GroupName, GroupObject in pairs(self.Set) do
|
||||||
local GroupObject=GroupObject --Wrapper.Client#CLIENT
|
|
||||||
|
|
||||||
if GroupObject and GroupObject:IsAlive() then
|
if GroupObject and GroupObject:IsAlive() then
|
||||||
AliveSet:Add(GroupName, GroupObject)
|
AliveSet[GroupName] = GroupObject
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return AliveSet.Set or {}
|
return AliveSet or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [User] Add a custom condition function.
|
--- [User] Add a custom condition function.
|
||||||
@ -5670,14 +5743,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
|
||||||
|
|
||||||
@ -6007,17 +6080,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
|
||||||
@ -6032,6 +6107,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
|
||||||
@ -6614,6 +6691,8 @@ do -- SET_ZONE
|
|||||||
--
|
--
|
||||||
-- -- Stop watching after 1 hour
|
-- -- Stop watching after 1 hour
|
||||||
-- zoneset:__TriggerStop(3600)
|
-- zoneset:__TriggerStop(3600)
|
||||||
|
-- -- Call :SetPartlyInside() on any zone (or SET_ZONE) if you want GROUPs to count as inside when any of their units enters even if they are far apart.
|
||||||
|
-- -- Make sure to call :SetPartlyInside() before :Trigger()!.
|
||||||
function SET_ZONE:Trigger(Objects)
|
function SET_ZONE:Trigger(Objects)
|
||||||
--self:I("Added Set_Zone Trigger")
|
--self:I("Added Set_Zone Trigger")
|
||||||
self:AddTransition("*","TriggerStart","TriggerRunning")
|
self:AddTransition("*","TriggerStart","TriggerRunning")
|
||||||
@ -6664,6 +6743,20 @@ do -- SET_ZONE
|
|||||||
-- @param Core.Zone#ZONE_BASE Zone The zone left.
|
-- @param Core.Zone#ZONE_BASE Zone The zone left.
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Toggle “partly-inside” handling for every zone in the set when those zones are used with :Trigger().
|
||||||
|
-- * Call with no argument or **true** → enable for all.
|
||||||
|
-- * Call with **false** → disable again (handy if it was enabled before).
|
||||||
|
-- @param #SET_ZONE self
|
||||||
|
-- @return #SET_ZONE self
|
||||||
|
function SET_ZONE:SetPartlyInside(state)
|
||||||
|
for _,Zone in pairs(self.Set) do
|
||||||
|
if Zone.SetPartlyInside then
|
||||||
|
Zone:SetPartlyInside(state)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- (Internal) Check the assigned objects for being in/out of the zone
|
--- (Internal) Check the assigned objects for being in/out of the zone
|
||||||
-- @param #SET_ZONE self
|
-- @param #SET_ZONE self
|
||||||
-- @param #boolean fromstart If true, do the init of the objects
|
-- @param #boolean fromstart If true, do the init of the objects
|
||||||
@ -6699,8 +6792,13 @@ do -- SET_ZONE
|
|||||||
-- has not been tagged previously - wasn't in set!
|
-- has not been tagged previously - wasn't in set!
|
||||||
obj.TriggerInZone[_zone.ZoneName] = false
|
obj.TriggerInZone[_zone.ZoneName] = false
|
||||||
end
|
end
|
||||||
-- is obj in zone?
|
-- is obj in this zone?
|
||||||
local inzone = _zone:IsCoordinateInZone(obj:GetCoordinate())
|
local inzone
|
||||||
|
if _zone.PartlyInside and obj.ClassName == "GROUP" then
|
||||||
|
inzone = obj:IsAnyInZone(_zone) -- TRUE as soon as any unit is inside
|
||||||
|
else
|
||||||
|
inzone = _zone:IsCoordinateInZone(obj:GetCoordinate()) -- original centroid test
|
||||||
|
end
|
||||||
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
|
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
|
||||||
if inzone and not obj.TriggerInZone[_zone.ZoneName] then
|
if inzone and not obj.TriggerInZone[_zone.ZoneName] then
|
||||||
-- wasn't in zone before
|
-- wasn't in zone before
|
||||||
@ -7767,6 +7865,28 @@ do -- SET_OPSGROUP
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Iterate the SET_OPSGROUP and count how many GROUPs and UNITs are alive.
|
||||||
|
-- @param #SET_GROUP self
|
||||||
|
-- @return #number The number of GROUPs alive.
|
||||||
|
-- @return #number The number of UNITs alive.
|
||||||
|
function SET_OPSGROUP:CountAlive()
|
||||||
|
local CountG = 0
|
||||||
|
local CountU = 0
|
||||||
|
|
||||||
|
local Set = self:GetSet()
|
||||||
|
|
||||||
|
for GroupID, GroupData in pairs( Set ) do -- For each GROUP in SET_GROUP
|
||||||
|
if GroupData and GroupData:IsAlive() then
|
||||||
|
CountG = CountG + 1
|
||||||
|
-- Count Units.
|
||||||
|
CountU = CountU + GroupData:GetGroup():CountAliveUnits()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return CountG, CountU
|
||||||
|
end
|
||||||
|
|
||||||
--- Finds an OPSGROUP based on the group name.
|
--- Finds an OPSGROUP based on the group name.
|
||||||
-- @param #SET_OPSGROUP self
|
-- @param #SET_OPSGROUP self
|
||||||
-- @param #string GroupName Name of the group.
|
-- @param #string GroupName Name of the group.
|
||||||
@ -8693,7 +8813,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 = {},
|
||||||
|
|||||||
@ -1049,6 +1049,23 @@ function SPAWN:InitSetUnitAbsolutePositions(Positions)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Uses Disposition and other fallback logic to find better ground positions for ground units.
|
||||||
|
--- NOTE: This is not a spawn randomizer.
|
||||||
|
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area.
|
||||||
|
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
||||||
|
-- @param #SPAWN self
|
||||||
|
-- @param #boolean OnOff Enable/disable the feature.
|
||||||
|
-- @param #number MaxRadius (Optional) Max radius to search for valid ground locations in meters. Default is double the max radius of the units.
|
||||||
|
-- @param #number Spacing (Optional) Minimum spacing between units in meters. Default is 5% of the search radius or 5 meters, whichever is larger.
|
||||||
|
-- @return #SPAWN
|
||||||
|
function SPAWN:InitValidateAndRepositionGroundUnits(OnOff, MaxRadius, Spacing)
|
||||||
|
self.SpawnValidateAndRepositionGroundUnits = OnOff
|
||||||
|
self.SpawnValidateAndRepositionGroundUnitsRadius = MaxRadius
|
||||||
|
self.SpawnValidateAndRepositionGroundUnitsSpacing = Spacing
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- This method is rather complicated to understand. But I'll try to explain.
|
--- This method is rather complicated to understand. But I'll try to explain.
|
||||||
-- This method becomes useful when you need to spawn groups with random templates of groups defined within the mission editor,
|
-- This method becomes useful when you need to spawn groups with random templates of groups defined within the mission editor,
|
||||||
-- 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.
|
||||||
@ -1631,7 +1648,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.
|
||||||
@ -1830,6 +1847,12 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
|
|||||||
SpawnTemplate.hidden=self.SpawnHiddenOnMap
|
SpawnTemplate.hidden=self.SpawnHiddenOnMap
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.SpawnValidateAndRepositionGroundUnits then
|
||||||
|
local units = SpawnTemplate.units
|
||||||
|
local gPos = { x = SpawnTemplate.x, y = SpawnTemplate.y }
|
||||||
|
UTILS.ValidateAndRepositionGroundUnits(units, gPos, self.SpawnValidateAndRepositionGroundUnitsRadius, self.SpawnValidateAndRepositionGroundUnitsSpacing)
|
||||||
|
end
|
||||||
|
|
||||||
-- Set country, coalition and category.
|
-- Set country, coalition and category.
|
||||||
SpawnTemplate.CategoryID = self.SpawnInitCategory or SpawnTemplate.CategoryID
|
SpawnTemplate.CategoryID = self.SpawnInitCategory or SpawnTemplate.CategoryID
|
||||||
SpawnTemplate.CountryID = self.SpawnInitCountry or SpawnTemplate.CountryID
|
SpawnTemplate.CountryID = self.SpawnInitCountry or SpawnTemplate.CountryID
|
||||||
@ -2830,7 +2853,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
|
||||||
@ -2906,7 +2929,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
|
||||||
@ -2954,12 +2977,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.
|
||||||
|
|||||||
@ -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
|
||||||
@ -149,6 +149,7 @@ function SPAWNSTATIC:NewFromStatic(SpawnTemplateName, SpawnCountryID)
|
|||||||
self.CategoryID = CategoryID
|
self.CategoryID = CategoryID
|
||||||
self.CoalitionID = CoalitionID
|
self.CoalitionID = CoalitionID
|
||||||
self.SpawnIndex = 0
|
self.SpawnIndex = 0
|
||||||
|
self.StaticCopyFrom = SpawnTemplateName
|
||||||
else
|
else
|
||||||
error( "SPAWNSTATIC:New: There is no static declared in the mission editor with SpawnTemplatePrefix = '" .. tostring(SpawnTemplateName) .. "'" )
|
error( "SPAWNSTATIC:New: There is no static declared in the mission editor with SpawnTemplatePrefix = '" .. tostring(SpawnTemplateName) .. "'" )
|
||||||
end
|
end
|
||||||
@ -302,12 +303,16 @@ end
|
|||||||
-- @param #number CallsignID Callsign ID. Default 1 (="London").
|
-- @param #number CallsignID Callsign ID. Default 1 (="London").
|
||||||
-- @param #number Frequency Frequency in MHz. Default 127.5 MHz.
|
-- @param #number Frequency Frequency in MHz. Default 127.5 MHz.
|
||||||
-- @param #number Modulation Modulation 0=AM, 1=FM.
|
-- @param #number Modulation Modulation 0=AM, 1=FM.
|
||||||
|
-- @param #boolean DynamicSpawns If true, allow Dynamic Spawns
|
||||||
|
-- @param #boolean DynamicHotStarts If true, and DynamicSpawns is true, then allow Dynamic Spawns with hot starts.
|
||||||
-- @return #SPAWNSTATIC self
|
-- @return #SPAWNSTATIC self
|
||||||
function SPAWNSTATIC:InitFARP(CallsignID, Frequency, Modulation)
|
function SPAWNSTATIC:InitFARP(CallsignID, Frequency, Modulation, DynamicSpawns,DynamicHotStarts)
|
||||||
self.InitFarp=true
|
self.InitFarp=true
|
||||||
self.InitFarpCallsignID=CallsignID or 1
|
self.InitFarpCallsignID=CallsignID or 1
|
||||||
self.InitFarpFreq=Frequency or 127.5
|
self.InitFarpFreq=Frequency or 127.5
|
||||||
self.InitFarpModu=Modulation or 0
|
self.InitFarpModu=Modulation or 0
|
||||||
|
self.InitFarpDynamicSpawns = DynamicSpawns
|
||||||
|
self.InitFarpDynamicHotStarts = (DynamicSpawns == true and DynamicHotStarts == true) and true or nil
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -373,6 +378,20 @@ function SPAWNSTATIC:InitLinkToUnit(Unit, OffsetX, OffsetY, OffsetAngle)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Uses Disposition and other fallback logic to find a better and valid ground spawn position.
|
||||||
|
--- NOTE: This is not a spawn randomizer.
|
||||||
|
--- It will try to a find clear ground location avoiding trees, water, roads, runways, map scenery, other statics and other units in the area.
|
||||||
|
--- Uses the initial position if it's a valid location.
|
||||||
|
-- @param #SPAWNSTATIC self
|
||||||
|
-- @param #boolean OnOff Enable/disable the feature.
|
||||||
|
-- @param #number MaxRadius (Optional) Max radius to search for a valid ground location in meters. Default is 10 times the max radius of the static.
|
||||||
|
-- @return #SPAWNSTATIC self
|
||||||
|
function SPAWNSTATIC:InitValidateAndRepositionStatic(OnOff, MaxRadius)
|
||||||
|
self.ValidateAndRepositionStatic = OnOff
|
||||||
|
self.ValidateAndRepositionStaticMaxRadius = MaxRadius
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Allows to place a CallFunction hook when a new static spawns.
|
--- Allows to place a CallFunction hook when a new static spawns.
|
||||||
-- The provided method will be called when a new group is spawned, including its given parameters.
|
-- The provided method will be called when a new group is spawned, including its given parameters.
|
||||||
-- The first parameter of the SpawnFunction is the @{Wrapper.Static#STATIC} that was spawned.
|
-- The first parameter of the SpawnFunction is the @{Wrapper.Static#STATIC} that was spawned.
|
||||||
@ -411,9 +430,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.
|
||||||
@ -459,7 +478,8 @@ end
|
|||||||
function SPAWNSTATIC:SpawnFromZone(Zone, Heading, NewName)
|
function SPAWNSTATIC:SpawnFromZone(Zone, Heading, NewName)
|
||||||
|
|
||||||
-- Spawn the new static at the center of the zone.
|
-- Spawn the new static at the center of the zone.
|
||||||
local Static = self:SpawnFromPointVec2( Zone:GetPointVec2(), Heading, NewName )
|
--local Static = self:SpawnFromPointVec2( Zone:GetPointVec2(), Heading, NewName )
|
||||||
|
local Static = self:SpawnFromCoordinate(Zone:GetCoordinate(), Heading, NewName)
|
||||||
|
|
||||||
return Static
|
return Static
|
||||||
end
|
end
|
||||||
@ -538,6 +558,14 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
|
|||||||
-- Add static to the game.
|
-- Add static to the game.
|
||||||
local Static=nil --DCS#StaticObject
|
local Static=nil --DCS#StaticObject
|
||||||
|
|
||||||
|
if self.ValidateAndRepositionStatic then
|
||||||
|
local validPos = UTILS.ValidateAndRepositionStatic(CountryID, Template.category, Template.type, Template, Template.shape_name, self.ValidateAndRepositionStaticMaxRadius)
|
||||||
|
if validPos then
|
||||||
|
Template.x = validPos.x
|
||||||
|
Template.y = validPos.y
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if self.InitFarp then
|
if self.InitFarp then
|
||||||
|
|
||||||
local TemplateGroup={}
|
local TemplateGroup={}
|
||||||
@ -550,12 +578,20 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
|
|||||||
TemplateGroup.y=Template.y
|
TemplateGroup.y=Template.y
|
||||||
TemplateGroup.name=Template.name
|
TemplateGroup.name=Template.name
|
||||||
|
|
||||||
|
if self.InitFarpDynamicSpawns == true then
|
||||||
|
TemplateGroup.units[1].dynamicSpawn = true
|
||||||
|
if self.InitFarpDynamicHotStarts == true then
|
||||||
|
TemplateGroup.units[1].allowHotStart = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
self:T("Spawning FARP")
|
self:T("Spawning FARP")
|
||||||
self:T({Template=Template})
|
self:T({Template=Template})
|
||||||
self:T({TemplateGroup=TemplateGroup})
|
self:T({TemplateGroup=TemplateGroup})
|
||||||
|
|
||||||
-- ED's dirty way to spawn FARPS.
|
-- ED's dirty way to spawn FARPS.
|
||||||
Static=coalition.addGroup(CountryID, -1, TemplateGroup)
|
Static=coalition.addGroup(CountryID, -1, TemplateGroup)
|
||||||
|
--Static=coalition.addStaticObject(CountryID, Template)
|
||||||
|
|
||||||
-- Currently DCS 2.8 does not trigger birth events if FARPS are spawned!
|
-- Currently DCS 2.8 does not trigger birth events if FARPS are spawned!
|
||||||
-- We create such an event. The airbase is registered in Core.Event
|
-- We create such an event. The airbase is registered in Core.Event
|
||||||
@ -595,5 +631,17 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
|
|||||||
self:ScheduleOnce(0.3, self.SpawnFunctionHook, mystatic, unpack(self.SpawnFunctionArguments))
|
self:ScheduleOnce(0.3, self.SpawnFunctionHook, mystatic, unpack(self.SpawnFunctionArguments))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.StaticCopyFrom ~= nil then
|
||||||
|
mystatic.StaticCopyFrom = self.StaticCopyFrom
|
||||||
|
end
|
||||||
|
|
||||||
|
local TemplateGroup={}
|
||||||
|
TemplateGroup.units={}
|
||||||
|
TemplateGroup.units[1]=Template
|
||||||
|
TemplateGroup.x=Template.x
|
||||||
|
TemplateGroup.y=Template.y
|
||||||
|
TemplateGroup.name=Template.name
|
||||||
|
_DATABASE:_RegisterStaticTemplate( TemplateGroup, self.CoalitionID, self.CategoryID, CountryID )
|
||||||
|
|
||||||
return mystatic
|
return mystatic
|
||||||
end
|
end
|
||||||
|
|||||||
@ -70,6 +70,7 @@
|
|||||||
-- @field #table Table of any trigger zone properties from the ME. The key is the Name of the property, and the value is the property's Value.
|
-- @field #table Table of any trigger zone properties from the ME. The key is the Name of the property, and the value is the property's Value.
|
||||||
-- @field #number Surface Type of surface. Only determined at the center of the zone!
|
-- @field #number Surface Type of surface. Only determined at the center of the zone!
|
||||||
-- @field #number Checktime Check every Checktime seconds, used for ZONE:Trigger()
|
-- @field #number Checktime Check every Checktime seconds, used for ZONE:Trigger()
|
||||||
|
-- @field #boolean PartlyInside When called, a GROUP is considered inside as soon as any of its units enters the zone even if they are far apart.
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
|
|
||||||
@ -213,7 +214,7 @@ end
|
|||||||
|
|
||||||
--- Returns if a PointVec3 is within the zone.
|
--- Returns if a PointVec3 is within the zone.
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @param Core.Point#POINT_VEC3 PointVec3 The PointVec3 to test.
|
-- @param Core.Point#COORDINATE PointVec3 The PointVec3 to test.
|
||||||
-- @return #boolean true if the PointVec3 is within the zone.
|
-- @return #boolean true if the PointVec3 is within the zone.
|
||||||
function ZONE_BASE:IsPointVec3InZone( PointVec3 )
|
function ZONE_BASE:IsPointVec3InZone( PointVec3 )
|
||||||
local InZone = self:IsPointVec2InZone( PointVec3 )
|
local InZone = self:IsPointVec2InZone( PointVec3 )
|
||||||
@ -227,16 +228,16 @@ function ZONE_BASE:GetVec2()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a @{Core.Point#POINT_VEC2} of the zone.
|
--- Returns a @{Core.Point#COORDINATE} of the zone.
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
||||||
-- @return Core.Point#POINT_VEC2 The PointVec2 of the zone.
|
-- @return Core.Point#COORDINATE The COORDINATE of the zone.
|
||||||
function ZONE_BASE:GetPointVec2()
|
function ZONE_BASE:GetPointVec2()
|
||||||
--self:F2( self.ZoneName )
|
--self:F2( self.ZoneName )
|
||||||
|
|
||||||
local Vec2 = self:GetVec2()
|
local Vec2 = self:GetVec2()
|
||||||
|
|
||||||
local PointVec2 = POINT_VEC2:NewFromVec2( Vec2 )
|
local PointVec2 = COORDINATE:NewFromVec2( Vec2 )
|
||||||
|
|
||||||
--self:T2( { PointVec2 } )
|
--self:T2( { PointVec2 } )
|
||||||
|
|
||||||
@ -261,16 +262,16 @@ function ZONE_BASE:GetVec3( Height )
|
|||||||
return Vec3
|
return Vec3
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a @{Core.Point#POINT_VEC3} of the zone.
|
--- Returns a @{Core.Point#COORDINATE} of the zone.
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
||||||
-- @return Core.Point#POINT_VEC3 The PointVec3 of the zone.
|
-- @return Core.Point#COORDINATE The PointVec3 of the zone.
|
||||||
function ZONE_BASE:GetPointVec3( Height )
|
function ZONE_BASE:GetPointVec3( Height )
|
||||||
--self:F2( self.ZoneName )
|
--self:F2( self.ZoneName )
|
||||||
|
|
||||||
local Vec3 = self:GetVec3( Height )
|
local Vec3 = self:GetVec3( Height )
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:NewFromVec3( Vec3 )
|
local PointVec3 = COORDINATE:NewFromVec3( Vec3 )
|
||||||
|
|
||||||
--self:T2( { PointVec3 } )
|
--self:T2( { PointVec3 } )
|
||||||
|
|
||||||
@ -330,16 +331,16 @@ function ZONE_BASE:GetRandomVec2()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Define a random @{Core.Point#POINT_VEC2} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
|
--- Define a random @{Core.Point#COORDINATE} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @return Core.Point#POINT_VEC2 The PointVec2 coordinates.
|
-- @return Core.Point#COORDINATE The COORDINATE coordinates.
|
||||||
function ZONE_BASE:GetRandomPointVec2()
|
function ZONE_BASE:GetRandomPointVec2()
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Define a random @{Core.Point#POINT_VEC3} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
|
--- Define a random @{Core.Point#COORDINATE} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @return Core.Point#POINT_VEC3 The PointVec3 coordinates.
|
-- @return Core.Point#COORDINATE The COORDINATE coordinates.
|
||||||
function ZONE_BASE:GetRandomPointVec3()
|
function ZONE_BASE:GetRandomPointVec3()
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
@ -534,6 +535,19 @@ function ZONE_BASE:GetZoneProbability()
|
|||||||
return self.ZoneProbability
|
return self.ZoneProbability
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get the coordinate on the radius of the zone nearest to Outsidecoordinate. Useto e.g. find an ingress point.
|
||||||
|
-- @param #ZONE_BASE self
|
||||||
|
-- @param Core.Point#COORDINATE Outsidecoordinate The coordinate outside of the zone from where to look.
|
||||||
|
-- @return Core.Point#COORDINATE CoordinateOnRadius
|
||||||
|
function ZONE_BASE:FindNearestCoordinateOnRadius(Outsidecoordinate)
|
||||||
|
local Vec1 = self:GetVec2()
|
||||||
|
local Radius = self:GetRadius()
|
||||||
|
local Vec2 = Outsidecoordinate:GetVec2()
|
||||||
|
local Point = UTILS.FindNearestPointOnCircle(Vec1,Radius,Vec2)
|
||||||
|
local rc = COORDINATE:NewFromVec2(Point)
|
||||||
|
return rc
|
||||||
|
end
|
||||||
|
|
||||||
--- Get the zone taking into account the randomization probability of a zone to be selected.
|
--- Get the zone taking into account the randomization probability of a zone to be selected.
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @return #ZONE_BASE The zone is selected taking into account the randomization probability factor.
|
-- @return #ZONE_BASE The zone is selected taking into account the randomization probability factor.
|
||||||
@ -599,6 +613,8 @@ end
|
|||||||
--
|
--
|
||||||
-- -- Stop watching the zone after 1 hour
|
-- -- Stop watching the zone after 1 hour
|
||||||
-- triggerzone:__TriggerStop(3600)
|
-- triggerzone:__TriggerStop(3600)
|
||||||
|
-- -- Call :SetPartlyInside() if you use SET_GROUP to count as inside when any of their units enters even when they are far apart.
|
||||||
|
-- -- Make sure to call :SetPartlyInside() before :Trigger()!
|
||||||
function ZONE_BASE:Trigger(Objects)
|
function ZONE_BASE:Trigger(Objects)
|
||||||
--self:I("Added Zone Trigger")
|
--self:I("Added Zone Trigger")
|
||||||
self:SetStartState("TriggerStopped")
|
self:SetStartState("TriggerStopped")
|
||||||
@ -667,6 +683,16 @@ function ZONE_BASE:Trigger(Objects)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Toggle “partly-inside” handling for this zone. To be used before :Trigger().
|
||||||
|
-- * Default:* flag is **false** until you call the method.
|
||||||
|
-- * Call with no argument or with **true** → enable.
|
||||||
|
-- * Call with **false** → disable again (handy if it was enabled before).
|
||||||
|
-- @param #ZONE_BASE self
|
||||||
|
-- @return #ZONE_BASE self
|
||||||
|
function ZONE_BASE:SetPartlyInside(state)
|
||||||
|
self.PartlyInside = state or not ( state == false )
|
||||||
|
return self
|
||||||
|
end
|
||||||
--- (Internal) Check the assigned objects for being in/out of the zone
|
--- (Internal) Check the assigned objects for being in/out of the zone
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @param #boolean fromstart If true, do the init of the objects
|
-- @param #boolean fromstart If true, do the init of the objects
|
||||||
@ -705,7 +731,12 @@ function ZONE_BASE:_TriggerCheck(fromstart)
|
|||||||
obj.TriggerInZone[self.ZoneName] = false
|
obj.TriggerInZone[self.ZoneName] = false
|
||||||
end
|
end
|
||||||
-- is obj in zone?
|
-- is obj in zone?
|
||||||
local inzone = self:IsCoordinateInZone(obj:GetCoordinate())
|
local inzone
|
||||||
|
if self.PartlyInside and obj.ClassName == "GROUP" then
|
||||||
|
inzone = obj:IsAnyInZone(self) -- TRUE if any unit is inside
|
||||||
|
else
|
||||||
|
inzone = self:IsCoordinateInZone(obj:GetCoordinate()) -- original barycentre test
|
||||||
|
end
|
||||||
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
|
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
|
||||||
if inzone and obj.TriggerInZone[self.ZoneName] then
|
if inzone and obj.TriggerInZone[self.ZoneName] then
|
||||||
-- just count
|
-- just count
|
||||||
@ -814,8 +845,8 @@ end
|
|||||||
-- Various functions exist to find random points within the zone.
|
-- Various functions exist to find random points within the zone.
|
||||||
--
|
--
|
||||||
-- * @{#ZONE_RADIUS.GetRandomVec2}(): Gets a random 2D point in the zone.
|
-- * @{#ZONE_RADIUS.GetRandomVec2}(): Gets a random 2D point in the zone.
|
||||||
-- * @{#ZONE_RADIUS.GetRandomPointVec2}(): Gets a @{Core.Point#POINT_VEC2} object representing a random 2D point in the zone.
|
-- * @{#ZONE_RADIUS.GetRandomPointVec2}(): Gets a @{Core.Point#COORDINATE} object representing a random 2D point in the zone.
|
||||||
-- * @{#ZONE_RADIUS.GetRandomPointVec3}(): Gets a @{Core.Point#POINT_VEC3} object representing a random 3D point in the zone. Note that the height of the point is at landheight.
|
-- * @{#ZONE_RADIUS.GetRandomPointVec3}(): Gets a @{Core.Point#COORDINATE} object representing a random 3D point in the zone. Note that the height of the point is at landheight.
|
||||||
--
|
--
|
||||||
-- ## Draw zone
|
-- ## Draw zone
|
||||||
--
|
--
|
||||||
@ -1010,7 +1041,7 @@ function ZONE_RADIUS: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
|
||||||
@ -1040,7 +1071,7 @@ function ZONE_RADIUS: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
|
||||||
@ -1149,15 +1180,13 @@ function ZONE_RADIUS:Scan( ObjectCategories, UnitCategories )
|
|||||||
|
|
||||||
local function EvaluateZone( ZoneObject )
|
local function EvaluateZone( ZoneObject )
|
||||||
--if ZoneObject:isExist() then --FF: isExist always returns false for SCENERY objects since DCS 2.2 and still in DCS 2.5
|
--if ZoneObject:isExist() then --FF: isExist always returns false for SCENERY objects since DCS 2.2 and still in DCS 2.5
|
||||||
if ZoneObject then
|
if ZoneObject and self:IsVec3InZone(ZoneObject:getPoint()) then
|
||||||
|
|
||||||
-- Get object category.
|
-- Get object category.
|
||||||
local ObjectCategory = Object.getCategory(ZoneObject)
|
local ObjectCategory = Object.getCategory(ZoneObject)
|
||||||
|
|
||||||
if ( ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive() ) or (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then
|
if ( ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive() ) or (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then
|
||||||
|
|
||||||
local CoalitionDCSUnit = ZoneObject:getCoalition()
|
|
||||||
|
|
||||||
local Include = false
|
local Include = false
|
||||||
if not UnitCategories then
|
if not UnitCategories then
|
||||||
-- Anything found is included.
|
-- Anything found is included.
|
||||||
@ -1509,6 +1538,26 @@ function ZONE_RADIUS:IsVec3InZone( Vec3 )
|
|||||||
return InZone
|
return InZone
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Search for clear ground spawn zones within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
||||||
|
-- @param #ZONE_RADIUS self
|
||||||
|
-- @param #number PosRadius Required clear radius around each position.
|
||||||
|
-- @param #number NumPositions Number of positions to find.
|
||||||
|
-- @return #table A table of DCS#Vec2 positions that are clear of map objects within the given PosRadius. nil if no clear positions are found.
|
||||||
|
function ZONE_RADIUS:GetClearZonePositions(PosRadius, NumPositions)
|
||||||
|
return UTILS.GetClearZonePositions(self, PosRadius, NumPositions)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Search for a random clear ground spawn coordinate within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
||||||
|
-- @param #ZONE_RADIUS self
|
||||||
|
-- @param #number PosRadius (Optional) Required clear radius around each position. (Default is math.min(Radius/10, 200))
|
||||||
|
-- @param #number NumPositions (Optional) Number of positions to find. (Default 50)
|
||||||
|
-- @return Core.Point#COORDINATE A random coordinate for a clear zone. nil if no clear positions are found.
|
||||||
|
-- @return #number Assigned radius for the found zones. nil if no clear positions are found.
|
||||||
|
function ZONE_RADIUS:GetRandomClearZoneCoordinate(PosRadius, NumPositions)
|
||||||
|
return UTILS.GetRandomClearZoneCoordinate(self, PosRadius, NumPositions)
|
||||||
|
end
|
||||||
|
|
||||||
--- Returns a random Vec2 location within the zone.
|
--- Returns a random Vec2 location within the zone.
|
||||||
-- @param #ZONE_RADIUS self
|
-- @param #ZONE_RADIUS self
|
||||||
-- @param #number inner (Optional) Minimal distance from the center of the zone. Default is 0.
|
-- @param #number inner (Optional) Minimal distance from the center of the zone. Default is 0.
|
||||||
@ -1521,6 +1570,10 @@ function ZONE_RADIUS:GetRandomVec2(inner, outer, surfacetypes)
|
|||||||
local _inner = inner or 0
|
local _inner = inner or 0
|
||||||
local _outer = outer or self:GetRadius()
|
local _outer = outer or self:GetRadius()
|
||||||
|
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
|
||||||
if surfacetypes and type(surfacetypes)~="table" then
|
if surfacetypes and type(surfacetypes)~="table" then
|
||||||
surfacetypes={surfacetypes}
|
surfacetypes={surfacetypes}
|
||||||
end
|
end
|
||||||
@ -1561,15 +1614,15 @@ function ZONE_RADIUS:GetRandomVec2(inner, outer, surfacetypes)
|
|||||||
return point
|
return point
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a @{Core.Point#POINT_VEC2} object reflecting a random 2D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
|
--- Returns a @{Core.Point#COORDINATE} object reflecting a random 2D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
|
||||||
-- @param #ZONE_RADIUS self
|
-- @param #ZONE_RADIUS self
|
||||||
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
||||||
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
||||||
-- @return Core.Point#POINT_VEC2 The @{Core.Point#POINT_VEC2} object reflecting the random 3D location within the zone.
|
-- @return Core.Point#COORDINATE The @{Core.Point#COORDINATE} object reflecting the random 3D location within the zone.
|
||||||
function ZONE_RADIUS:GetRandomPointVec2( inner, outer )
|
function ZONE_RADIUS:GetRandomPointVec2( inner, outer )
|
||||||
--self:F( self.ZoneName, inner, outer )
|
--self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2( inner, outer ) )
|
local PointVec2 = COORDINATE:NewFromVec2( self:GetRandomVec2( inner, outer ) )
|
||||||
|
|
||||||
--self:T3( { PointVec2 } )
|
--self:T3( { PointVec2 } )
|
||||||
|
|
||||||
@ -1592,15 +1645,15 @@ function ZONE_RADIUS:GetRandomVec3( inner, outer )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns a @{Core.Point#POINT_VEC3} object reflecting a random 3D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
|
--- Returns a @{Core.Point#COORDINATE} object reflecting a random 3D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
|
||||||
-- @param #ZONE_RADIUS self
|
-- @param #ZONE_RADIUS self
|
||||||
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
||||||
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
||||||
-- @return Core.Point#POINT_VEC3 The @{Core.Point#POINT_VEC3} object reflecting the random 3D location within the zone.
|
-- @return Core.Point#COORDINATE The @{Core.Point#COORDINATE} object reflecting the random 3D location within the zone.
|
||||||
function ZONE_RADIUS:GetRandomPointVec3( inner, outer )
|
function ZONE_RADIUS:GetRandomPointVec3( inner, outer )
|
||||||
--self:F( self.ZoneName, inner, outer )
|
--self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2( inner, outer ) )
|
local PointVec3 = COORDINATE:NewFromVec2( self:GetRandomVec2( inner, outer ) )
|
||||||
|
|
||||||
--self:T3( { PointVec3 } )
|
--self:T3( { PointVec3 } )
|
||||||
|
|
||||||
@ -1881,6 +1934,21 @@ function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, Offset)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Updates the current location from a @{Wrapper.Group}.
|
||||||
|
-- @param #ZONE_UNIT self
|
||||||
|
-- @param Wrapper.Group#GROUP Group (optional) Update from this Unit, if nil, update from the UNIT this zone is based on.
|
||||||
|
-- @return self
|
||||||
|
function ZONE_UNIT:UpdateFromUnit(Unit)
|
||||||
|
if Unit and Unit:IsAlive() then
|
||||||
|
local vec2 = Unit:GetVec2()
|
||||||
|
self.LastVec2 = vec2
|
||||||
|
elseif self.ZoneUNIT and self.ZoneUNIT:IsAlive() then
|
||||||
|
local ZoneVec2 = self.ZoneUNIT:GetVec2()
|
||||||
|
self.LastVec2 = ZoneVec2
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns the current location of the @{Wrapper.Unit#UNIT}.
|
--- Returns the current location of the @{Wrapper.Unit#UNIT}.
|
||||||
-- @param #ZONE_UNIT self
|
-- @param #ZONE_UNIT self
|
||||||
@ -2018,6 +2086,22 @@ function ZONE_GROUP:GetVec2()
|
|||||||
return ZoneVec2
|
return ZoneVec2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Updates the current location from a @{Wrapper.Group}.
|
||||||
|
-- @param #ZONE_GROUP self
|
||||||
|
-- @param Wrapper.Group#GROUP Group (optional) Update from this Group, if nil, update from the GROUP this zone is based on.
|
||||||
|
-- @return self
|
||||||
|
function ZONE_GROUP:UpdateFromGroup(Group)
|
||||||
|
if Group and Group:IsAlive() then
|
||||||
|
local vec2 = Group:GetVec2()
|
||||||
|
self.Vec2 = vec2
|
||||||
|
elseif self._.ZoneGROUP and self._.ZoneGROUP:IsAlive() then
|
||||||
|
local ZoneVec2 = self._.ZoneGROUP:GetVec2()
|
||||||
|
self.Vec2 = ZoneVec2
|
||||||
|
self._.ZoneVec2Cache = ZoneVec2
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Returns a random location within the zone of the @{Wrapper.Group}.
|
--- Returns a random location within the zone of the @{Wrapper.Group}.
|
||||||
-- @param #ZONE_GROUP self
|
-- @param #ZONE_GROUP self
|
||||||
-- @return DCS#Vec2 The random location of the zone based on the @{Wrapper.Group} location.
|
-- @return DCS#Vec2 The random location of the zone based on the @{Wrapper.Group} location.
|
||||||
@ -2036,15 +2120,15 @@ function ZONE_GROUP:GetRandomVec2()
|
|||||||
return Point
|
return Point
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a @{Core.Point#POINT_VEC2} object reflecting a random 2D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
|
--- Returns a @{Core.Point#COORDINATE} object reflecting a random 2D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
|
||||||
-- @param #ZONE_GROUP self
|
-- @param #ZONE_GROUP self
|
||||||
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
||||||
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
||||||
-- @return Core.Point#POINT_VEC2 The @{Core.Point#POINT_VEC2} object reflecting the random 3D location within the zone.
|
-- @return Core.Point#COORDINATE The @{Core.Point#COORDINATE} object reflecting the random 3D location within the zone.
|
||||||
function ZONE_GROUP:GetRandomPointVec2( inner, outer )
|
function ZONE_GROUP:GetRandomPointVec2( inner, outer )
|
||||||
--self:F( self.ZoneName, inner, outer )
|
--self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
|
local PointVec2 = COORDINATE:NewFromVec2( self:GetRandomVec2() )
|
||||||
|
|
||||||
--self:T3( { PointVec2 } )
|
--self:T3( { PointVec2 } )
|
||||||
|
|
||||||
@ -2192,8 +2276,8 @@ end
|
|||||||
-- Various functions exist to find random points within the zone.
|
-- Various functions exist to find random points within the zone.
|
||||||
--
|
--
|
||||||
-- * @{#ZONE_POLYGON_BASE.GetRandomVec2}(): Gets a random 2D point in the zone.
|
-- * @{#ZONE_POLYGON_BASE.GetRandomVec2}(): Gets a random 2D point in the zone.
|
||||||
-- * @{#ZONE_POLYGON_BASE.GetRandomPointVec2}(): Return a @{Core.Point#POINT_VEC2} object representing a random 2D point within the zone.
|
-- * @{#ZONE_POLYGON_BASE.GetRandomPointVec2}(): Return a @{Core.Point#COORDINATE} object representing a random 2D point within the zone.
|
||||||
-- * @{#ZONE_POLYGON_BASE.GetRandomPointVec3}(): Return a @{Core.Point#POINT_VEC3} object representing a random 3D point at landheight within the zone.
|
-- * @{#ZONE_POLYGON_BASE.GetRandomPointVec3}(): Return a @{Core.Point#COORDINATE} object representing a random 3D point at landheight within the zone.
|
||||||
--
|
--
|
||||||
-- ## Draw zone
|
-- ## Draw zone
|
||||||
--
|
--
|
||||||
@ -2487,6 +2571,26 @@ function ZONE_POLYGON_BASE:Flush()
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Search for clear ground spawn zones within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
||||||
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
|
-- @param #number PosRadius Required clear radius around each position.
|
||||||
|
-- @param #number NumPositions Number of positions to find.
|
||||||
|
-- @return #table A table of DCS#Vec2 positions that are clear of map objects within the given PosRadius. nil if no clear positions are found.
|
||||||
|
function ZONE_POLYGON_BASE:GetClearZonePositions(PosRadius, NumPositions)
|
||||||
|
return UTILS.GetClearZonePositions(self, PosRadius, NumPositions)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Search for a random clear ground spawn coordinate within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
||||||
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
|
-- @param #number PosRadius (Optional) Required clear radius around each position. (Default is math.min(Radius/10, 200))
|
||||||
|
-- @param #number NumPositions (Optional) Number of positions to find. (Default 50)
|
||||||
|
-- @return Core.Point#COORDINATE A random coordinate for a clear zone. nil if no clear positions are found.
|
||||||
|
-- @return #number Assigned radius for the found zones. nil if no clear positions are found.
|
||||||
|
function ZONE_POLYGON_BASE:GetRandomClearZoneCoordinate(PosRadius, NumPositions)
|
||||||
|
return UTILS.GetRandomClearZoneCoordinate(self, PosRadius, NumPositions)
|
||||||
|
end
|
||||||
|
|
||||||
--- Smokes the zone boundaries in a color.
|
--- Smokes the zone boundaries in a color.
|
||||||
-- @param #ZONE_POLYGON_BASE self
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
-- @param #boolean UnBound If true, the tyres will be destroyed.
|
-- @param #boolean UnBound If true, the tyres will be destroyed.
|
||||||
@ -2769,7 +2873,7 @@ function ZONE_POLYGON_BASE:SmokeZone( SmokeColor, Segments )
|
|||||||
for Segment = 0, Segments do -- We divide each line in 5 segments and smoke a point on the line.
|
for Segment = 0, Segments do -- We divide each line in 5 segments and smoke a point on the line.
|
||||||
local PointX = self._.Polygon[i].x + ( Segment * DeltaX / Segments )
|
local PointX = self._.Polygon[i].x + ( Segment * DeltaX / Segments )
|
||||||
local PointY = self._.Polygon[i].y + ( Segment * DeltaY / Segments )
|
local PointY = self._.Polygon[i].y + ( Segment * DeltaY / Segments )
|
||||||
POINT_VEC2:New( PointX, PointY ):Smoke( SmokeColor )
|
COORDINATE:New( PointX, 0, PointY ):Smoke( SmokeColor )
|
||||||
end
|
end
|
||||||
j = i
|
j = i
|
||||||
i = i + 1
|
i = i + 1
|
||||||
@ -2804,7 +2908,7 @@ function ZONE_POLYGON_BASE:FlareZone( FlareColor, Segments, Azimuth, AddHeight )
|
|||||||
for Segment = 0, Segments do -- We divide each line in 5 segments and smoke a point on the line.
|
for Segment = 0, Segments do -- We divide each line in 5 segments and smoke a point on the line.
|
||||||
local PointX = self._.Polygon[i].x + ( Segment * DeltaX / Segments )
|
local PointX = self._.Polygon[i].x + ( Segment * DeltaX / Segments )
|
||||||
local PointY = self._.Polygon[i].y + ( Segment * DeltaY / Segments )
|
local PointY = self._.Polygon[i].y + ( Segment * DeltaY / Segments )
|
||||||
POINT_VEC2:New( PointX, PointY, AddHeight ):Flare(FlareColor, Azimuth)
|
COORDINATE:New( PointX, AddHeight, PointY ):Flare(FlareColor, Azimuth)
|
||||||
end
|
end
|
||||||
j = i
|
j = i
|
||||||
i = i + 1
|
i = i + 1
|
||||||
@ -2865,6 +2969,11 @@ end
|
|||||||
function ZONE_POLYGON_BASE:GetRandomVec2()
|
function ZONE_POLYGON_BASE:GetRandomVec2()
|
||||||
-- make sure we assign weights to the triangles based on their surface area, otherwise
|
-- make sure we assign weights to the triangles based on their surface area, otherwise
|
||||||
-- we'll be more likely to generate random points in smaller triangles
|
-- we'll be more likely to generate random points in smaller triangles
|
||||||
|
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
|
||||||
local weights = {}
|
local weights = {}
|
||||||
for _, triangle in pairs(self._Triangles) do
|
for _, triangle in pairs(self._Triangles) do
|
||||||
weights[triangle] = triangle.SurfaceArea / self.SurfaceArea
|
weights[triangle] = triangle.SurfaceArea / self.SurfaceArea
|
||||||
@ -2880,26 +2989,26 @@ function ZONE_POLYGON_BASE:GetRandomVec2()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Return a @{Core.Point#POINT_VEC2} object representing a random 2D point at landheight within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
|
--- Return a @{Core.Point#COORDINATE} object representing a random 2D point at landheight within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
|
||||||
-- @param #ZONE_POLYGON_BASE self
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
-- @return @{Core.Point#POINT_VEC2}
|
-- @return @{Core.Point#COORDINATE}
|
||||||
function ZONE_POLYGON_BASE:GetRandomPointVec2()
|
function ZONE_POLYGON_BASE:GetRandomPointVec2()
|
||||||
--self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
|
local PointVec2 = COORDINATE:NewFromVec2( self:GetRandomVec2() )
|
||||||
|
|
||||||
--self:T2( PointVec2 )
|
--self:T2( PointVec2 )
|
||||||
|
|
||||||
return PointVec2
|
return PointVec2
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Return a @{Core.Point#POINT_VEC3} object representing a random 3D point at landheight within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
|
--- Return a @{Core.Point#COORDINATE} object representing a random 3D point at landheight within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
|
||||||
-- @param #ZONE_POLYGON_BASE self
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
-- @return @{Core.Point#POINT_VEC3}
|
-- @return @{Core.Point#COORDINATE}
|
||||||
function ZONE_POLYGON_BASE:GetRandomPointVec3()
|
function ZONE_POLYGON_BASE:GetRandomPointVec3()
|
||||||
--self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2() )
|
local PointVec3 = COORDINATE:NewFromVec2( self:GetRandomVec2() )
|
||||||
|
|
||||||
--self:T2( PointVec3 )
|
--self:T2( PointVec3 )
|
||||||
|
|
||||||
@ -3204,12 +3313,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
|
|||||||
|
|
||||||
local vectors = self:GetBoundingSquare()
|
local vectors = self:GetBoundingSquare()
|
||||||
|
|
||||||
local minVec3 = {x=vectors.x1, y=0, z=vectors.y1}
|
local ZoneRadius = UTILS.VecDist2D({x=vectors.x1, y=vectors.y1}, {x=vectors.x2, y=vectors.y2})/2
|
||||||
local maxVec3 = {x=vectors.x2, y=0, z=vectors.y2}
|
|
||||||
|
|
||||||
local minmarkcoord = COORDINATE:NewFromVec3(minVec3)
|
|
||||||
local maxmarkcoord = COORDINATE:NewFromVec3(maxVec3)
|
|
||||||
local ZoneRadius = minmarkcoord:Get2DDistance(maxmarkcoord)/2
|
|
||||||
-- self:I("Scan Radius:" ..ZoneRadius)
|
-- self:I("Scan Radius:" ..ZoneRadius)
|
||||||
local CenterVec3 = self:GetCoordinate():GetVec3()
|
local CenterVec3 = self:GetCoordinate():GetVec3()
|
||||||
|
|
||||||
@ -3233,14 +3337,12 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
|
|||||||
|
|
||||||
local function EvaluateZone( ZoneObject )
|
local function EvaluateZone( ZoneObject )
|
||||||
|
|
||||||
if ZoneObject then
|
if ZoneObject and self:IsVec3InZone(ZoneObject:getPoint()) then
|
||||||
|
|
||||||
local ObjectCategory = Object.getCategory(ZoneObject)
|
local ObjectCategory = Object.getCategory(ZoneObject)
|
||||||
|
|
||||||
if ( ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive() ) or (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then
|
if ( ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive() ) or (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then
|
||||||
|
|
||||||
local CoalitionDCSUnit = ZoneObject:getCoalition()
|
|
||||||
|
|
||||||
local Include = false
|
local Include = false
|
||||||
if not UnitCategories then
|
if not UnitCategories then
|
||||||
-- Anything found is included.
|
-- Anything found is included.
|
||||||
@ -3272,7 +3374,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- trying with box search
|
-- trying with box search
|
||||||
if ObjectCategory == Object.Category.SCENERY and self:IsVec3InZone(ZoneObject:getPoint()) then
|
if ObjectCategory == Object.Category.SCENERY then
|
||||||
local SceneryType = ZoneObject:getTypeName()
|
local SceneryType = ZoneObject:getTypeName()
|
||||||
local SceneryName = ZoneObject:getName()
|
local SceneryName = ZoneObject:getName()
|
||||||
self.ScanData.Scenery[SceneryType] = self.ScanData.Scenery[SceneryType] or {}
|
self.ScanData.Scenery[SceneryType] = self.ScanData.Scenery[SceneryType] or {}
|
||||||
@ -3931,18 +4033,18 @@ function ZONE_OVAL:GetRandomVec2()
|
|||||||
return {x=rx, y=ry}
|
return {x=rx, y=ry}
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Define a random @{Core.Point#POINT_VEC2} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
|
--- Define a random @{Core.Point#COORDINATE} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
|
||||||
-- @param #ZONE_OVAL self
|
-- @param #ZONE_OVAL self
|
||||||
-- @return Core.Point#POINT_VEC2 The PointVec2 coordinates.
|
-- @return Core.Point#COORDINATE The COORDINATE coordinates.
|
||||||
function ZONE_OVAL:GetRandomPointVec2()
|
function ZONE_OVAL:GetRandomPointVec2()
|
||||||
return POINT_VEC2:NewFromVec2(self:GetRandomVec2())
|
return COORDINATE:NewFromVec2(self:GetRandomVec2())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Define a random @{Core.Point#POINT_VEC2} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
|
--- Define a random @{Core.Point#COORDINATE} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
|
||||||
-- @param #ZONE_OVAL self
|
-- @param #ZONE_OVAL self
|
||||||
-- @return Core.Point#POINT_VEC2 The PointVec2 coordinates.
|
-- @return Core.Point#COORDINATE The COORDINATE coordinates.
|
||||||
function ZONE_OVAL:GetRandomPointVec3()
|
function ZONE_OVAL:GetRandomPointVec3()
|
||||||
return POINT_VEC3:NewFromVec3(self:GetRandomVec2())
|
return COORDINATE:NewFromVec3(self:GetRandomVec2())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Draw the zone on the F10 map.
|
--- Draw the zone on the F10 map.
|
||||||
@ -4082,15 +4184,15 @@ do -- ZONE_AIRBASE
|
|||||||
return ZoneVec2
|
return ZoneVec2
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a @{Core.Point#POINT_VEC2} object reflecting a random 2D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
|
--- Returns a @{Core.Point#COORDINATE} object reflecting a random 2D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
|
||||||
-- @param #ZONE_AIRBASE self
|
-- @param #ZONE_AIRBASE self
|
||||||
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
||||||
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
||||||
-- @return Core.Point#POINT_VEC2 The @{Core.Point#POINT_VEC2} object reflecting the random 3D location within the zone.
|
-- @return Core.Point#COORDINATE The @{Core.Point#COORDINATE} object reflecting the random 3D location within the zone.
|
||||||
function ZONE_AIRBASE:GetRandomPointVec2( inner, outer )
|
function ZONE_AIRBASE:GetRandomPointVec2( inner, outer )
|
||||||
--self:F( self.ZoneName, inner, outer )
|
--self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
|
local PointVec2 = COORDINATE:NewFromVec2( self:GetRandomVec2() )
|
||||||
|
|
||||||
--self:T3( { PointVec2 } )
|
--self:T3( { PointVec2 } )
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
-- @module Functional.Mantis
|
-- @module Functional.Mantis
|
||||||
-- @image Functional.Mantis.jpg
|
-- @image Functional.Mantis.jpg
|
||||||
--
|
--
|
||||||
-- Last Update: Mar 2025
|
-- Last Update: August 2025
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **MANTIS** class, extends Core.Base#BASE
|
--- **MANTIS** class, extends Core.Base#BASE
|
||||||
@ -62,7 +62,9 @@
|
|||||||
-- @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 #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 SmokeDecoyColor Color to use, defaults to SMOKECOLOR.White
|
||||||
-- @field #number checkcounter Counter for SAM Table refreshes
|
-- @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
|
||||||
|
|
||||||
|
|
||||||
@ -74,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) will 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
|
||||||
--
|
--
|
||||||
@ -107,10 +108,15 @@
|
|||||||
-- * Patriot
|
-- * Patriot
|
||||||
-- * Rapier
|
-- * Rapier
|
||||||
-- * Roland
|
-- * Roland
|
||||||
|
-- * IRIS-T SLM
|
||||||
|
-- * Pantsir S1
|
||||||
|
-- * TOR M2
|
||||||
|
-- * C-RAM
|
||||||
-- * Silkworm (though strictly speaking this is a surface to ship missile)
|
-- * Silkworm (though strictly speaking this is a surface to ship missile)
|
||||||
-- * SA-2, SA-3, SA-5, SA-6, SA-7, SA-8, SA-9, SA-10, SA-11, SA-13, SA-15, SA-19
|
-- * SA-2, SA-3, SA-5, SA-6, SA-7, SA-8, SA-9, SA-10, SA-11, SA-13, SA-15, SA-19
|
||||||
-- * From IDF mod: STUNNER IDFA, TAMIR IDFA (Note all caps!)
|
-- * From IDF mod: STUNNER IDFA, TAMIR IDFA (Note all caps!)
|
||||||
-- * From HDS (see note on HDS below): SA-2, SA-3, SA-10B, SA-10C, SA-12, SA-17, SA-20A, SA-20B, SA-23, HQ-2
|
-- * From HDS (see note on HDS below): SA-2, SA-3, SA-10B, SA-10C, SA-12, SA-17, SA-20A, SA-20B, SA-23, HQ-2, SAMP/T Block 1, SAMP/T Block 1INT, SAMP/T Block2
|
||||||
|
-- * Other Mods: Nike
|
||||||
--
|
--
|
||||||
-- * From SMA: RBS98M, RBS70, RBS90, RBS90M, RBS103A, RBS103B, RBS103AM, RBS103BM, Lvkv9040M
|
-- * From SMA: RBS98M, RBS70, RBS90, RBS90M, RBS103A, RBS103B, RBS103AM, RBS103BM, Lvkv9040M
|
||||||
-- **NOTE** If you are using the Swedish Military Assets (SMA), please note that the **group name** for RBS-SAM types also needs to contain the keyword "SMA"
|
-- **NOTE** If you are using the Swedish Military Assets (SMA), please note that the **group name** for RBS-SAM types also needs to contain the keyword "SMA"
|
||||||
@ -124,19 +130,20 @@
|
|||||||
-- * SA-2 (with V759 missile, e.g. "Red SAM SA-2 HDS")
|
-- * SA-2 (with V759 missile, e.g. "Red SAM SA-2 HDS")
|
||||||
-- * SA-2 (with HQ-2 launcher, use HQ-2 in the group name, e.g. "Red SAM HQ-2" )
|
-- * SA-2 (with HQ-2 launcher, use HQ-2 in the group name, e.g. "Red SAM HQ-2" )
|
||||||
-- * SA-3 (with V601P missile, e.g. "Red SAM SA-3 HDS")
|
-- * SA-3 (with V601P missile, e.g. "Red SAM SA-3 HDS")
|
||||||
-- * SA-10B (overlap with other SA-10 types, e.g. "Red SAM SA-10B HDS")
|
-- * SA-10B (overlap with other SA-10 types, e.g. "Red SAM SA-10B HDS" with 5P85CE launcher)
|
||||||
-- * SA-10C (overlap with other SA-10 types, e.g. "Red SAM SA-10C HDS")
|
-- * SA-10C (overlap with other SA-10 types, e.g. "Red SAM SA-10C HDS" with 5P85SE launcher)
|
||||||
-- * SA-12 (launcher dependent range, e.g. "Red SAM SA-12 HDS")
|
-- * SA-12 (launcher dependent range, e.g. "Red SAM SA-12 HDS 2" for the 9A82 variant and "Red SAM SA-12 HDS 1" for the 9A83 variant)
|
||||||
-- * SA-23 (launcher dependent range, e.g. "Red SAM SA-23 HDS")
|
-- * SA-23 (launcher dependent range, e.g. "Red SAM SA-23 HDS 2" for the 9A82ME variant and "Red SAM SA-23 HDS 1" for the 9A83ME variant)
|
||||||
|
-- * SAMP/T (launcher dependent range, e.g. "Blue SAM SAMPT Block 1 HDS" for Block 1, "Blue SAM SAMPT Block 1INT HDS", "Blue SAM SAMPT Block 2 HDS")
|
||||||
--
|
--
|
||||||
-- The other HDS types work like the rest of the known SAM systems.
|
-- The other HDS types work like the rest of the known SAM systems.
|
||||||
--
|
--
|
||||||
-- # 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.
|
||||||
--
|
--
|
||||||
@ -188,7 +195,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
|
||||||
@ -206,9 +213,6 @@
|
|||||||
--
|
--
|
||||||
-- ### 2.1.4 Advanced features
|
-- ### 2.1.4 Advanced features
|
||||||
--
|
--
|
||||||
-- -- Option to switch off auto mode **before** you start MANTIS (not recommended)
|
|
||||||
-- mybluemantis.automode = false
|
|
||||||
--
|
|
||||||
-- -- Option to set the scale of the activation range, i.e. don't activate at the fringes of max range, defaults below.
|
-- -- Option to set the 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
|
||||||
@ -221,6 +225,12 @@
|
|||||||
-- -- 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]
|
||||||
--
|
--
|
||||||
-- By default, the following settings are active:
|
-- By default, the following settings are active:
|
||||||
@ -243,25 +253,7 @@
|
|||||||
--
|
--
|
||||||
-- 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, not recommended for manual setup]
|
-- # 5. Integrated SEAD
|
||||||
--
|
|
||||||
-- You can also choose to integrate Mantis with @{Functional.Shorad#SHORAD} for protection against HARMs and AGMs manually. 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.
|
|
||||||
--
|
|
||||||
-- (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
|
||||||
@ -288,6 +280,7 @@
|
|||||||
MANTIS = {
|
MANTIS = {
|
||||||
ClassName = "MANTIS",
|
ClassName = "MANTIS",
|
||||||
name = "mymantis",
|
name = "mymantis",
|
||||||
|
version = "0.9.34",
|
||||||
SAM_Templates_Prefix = "",
|
SAM_Templates_Prefix = "",
|
||||||
SAM_Group = nil,
|
SAM_Group = nil,
|
||||||
EWR_Templates_Prefix = "",
|
EWR_Templates_Prefix = "",
|
||||||
@ -336,6 +329,8 @@ MANTIS = {
|
|||||||
SmokeDecoy = false,
|
SmokeDecoy = false,
|
||||||
SmokeDecoyColor = SMOKECOLOR.White,
|
SmokeDecoyColor = SMOKECOLOR.White,
|
||||||
checkcounter = 1,
|
checkcounter = 1,
|
||||||
|
DLinkCacheTime = 120,
|
||||||
|
logsamstatus = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Advanced state enumerator
|
--- Advanced state enumerator
|
||||||
@ -374,7 +369,7 @@ MANTIS.radiusscale[MANTIS.SamType.POINT] = 3
|
|||||||
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" },
|
||||||
@ -382,7 +377,8 @@ 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="Point", 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="Point", Radar="Strela", Point="true" },
|
["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" },
|
||||||
@ -393,14 +389,21 @@ MANTIS.SamData = {
|
|||||||
["Chaparral"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Chaparral" },
|
["Chaparral"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Chaparral" },
|
||||||
["Linebacker"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="Linebacker", Point="true" },
|
["Linebacker"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="Linebacker", Point="true" },
|
||||||
["Silkworm"] = { Range=90, Blindspot=1, Height=0.2, Type="Long", Radar="Silkworm" },
|
["Silkworm"] = { Range=90, Blindspot=1, Height=0.2, Type="Long", Radar="Silkworm" },
|
||||||
|
["C-RAM"] = { Range=2, Blindspot=0, Height=2, Type="Point", Radar="HEMTT_C-RAM_Phalanx", Point="true" },
|
||||||
-- units from HDS Mod, multi launcher options is tricky
|
-- units from HDS Mod, multi launcher options is tricky
|
||||||
["SA-10B"] = { Range=75, Blindspot=0, Height=18, Type="Medium" , Radar="SA-10B"},
|
["SA-10B"] = { Range=75, Blindspot=0, Height=18, Type="Medium" , Radar="SA-10B"},
|
||||||
["SA-17"] = { Range=50, Blindspot=3, Height=30, Type="Medium", Radar="SA-17" },
|
["SA-17"] = { Range=50, Blindspot=3, Height=50, 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" },
|
||||||
["TAMIR IDFA"] = { Range=20, Blindspot=0.6, Height=12.3, Type="Short", Radar="IRON_DOME_LN" },
|
["TAMIR IDFA"] = { Range=20, Blindspot=0.6, Height=12.3, Type="Short", Radar="IRON_DOME_LN" },
|
||||||
["STUNNER IDFA"] = { Range=250, Blindspot=1, Height=45, Type="Long", Radar="DAVID_SLING_LN" },
|
["STUNNER IDFA"] = { Range=250, Blindspot=1, Height=45, Type="Long", Radar="DAVID_SLING_LN" },
|
||||||
|
["NIKE"] = { Range=155, Blindspot=6, Height=30, Type="Long", Radar="HIPAR" },
|
||||||
|
["Dog Ear"] = { Range=11, Blindspot=0, Height=9, Type="Point", Radar="Dog Ear", Point="true" },
|
||||||
|
-- CH Added to DCS core 2.9.19.x
|
||||||
|
["Pantsir S1"] = { Range=20, Blindspot=1.2, Height=15, Type="Point", Radar="PantsirS1" , Point="true" },
|
||||||
|
["Tor M2"] = { Range=12, Blindspot=1, Height=10, Type="Point", Radar="TorM2", Point="true" },
|
||||||
|
["IRIS-T SLM"] = { Range=40, Blindspot=0.5, Height=20, Type="Medium", Radar="CH_IRIST_SLM" },
|
||||||
}
|
}
|
||||||
|
|
||||||
--- SAM data HDS
|
--- SAM data HDS
|
||||||
@ -416,13 +419,17 @@ MANTIS.SamDataHDS = {
|
|||||||
-- group name MUST contain HDS to ID launcher type correctly!
|
-- group name MUST contain HDS to ID launcher type correctly!
|
||||||
["SA-2 HDS"] = { Range=56, Blindspot=7, Height=30, Type="Medium", Radar="V759" },
|
["SA-2 HDS"] = { Range=56, Blindspot=7, Height=30, Type="Medium", Radar="V759" },
|
||||||
["SA-3 HDS"] = { Range=20, Blindspot=6, Height=30, Type="Short", Radar="V-601P" },
|
["SA-3 HDS"] = { Range=20, Blindspot=6, Height=30, Type="Short", Radar="V-601P" },
|
||||||
["SA-10C HDS 2"] = { Range=90, Blindspot=5, Height=25, Type="Long" , Radar="5P85DE ln"}, -- V55RUD
|
["SA-10B HDS"] = { Range=90, Blindspot=5, Height=25, Type="Long" , Radar="5P85CE ln"}, -- V55RUD
|
||||||
["SA-10C HDS 1"] = { Range=90, Blindspot=5, Height=25, Type="Long" , Radar="5P85CE ln"}, -- V55RUD
|
["SA-10C HDS"] = { Range=75, Blindspot=5, Height=25, Type="Long" , Radar="5P85SE ln"}, -- V55RUD
|
||||||
["SA-12 HDS 2"] = { Range=100, Blindspot=10, Height=25, Type="Long" , Radar="S-300V 9A82 l"},
|
["SA-17 HDS"] = { Range=50, Blindspot=3, Height=50, Type="Medium", Radar="SA-17 " },
|
||||||
["SA-12 HDS 1"] = { Range=75, Blindspot=1, Height=25, Type="Long" , Radar="S-300V 9A83 l"},
|
["SA-12 HDS 2"] = { Range=100, Blindspot=13, Height=30, Type="Long" , Radar="S-300V 9A82 l"},
|
||||||
|
["SA-12 HDS 1"] = { Range=75, Blindspot=6, Height=25, Type="Long" , Radar="S-300V 9A83 l"},
|
||||||
["SA-23 HDS 2"] = { Range=200, Blindspot=5, Height=37, Type="Long", Radar="S-300VM 9A82ME" },
|
["SA-23 HDS 2"] = { Range=200, Blindspot=5, Height=37, Type="Long", Radar="S-300VM 9A82ME" },
|
||||||
["SA-23 HDS 1"] = { Range=100, Blindspot=1, Height=50, Type="Long", Radar="S-300VM 9A83ME" },
|
["SA-23 HDS 1"] = { Range=100, Blindspot=1, Height=50, Type="Long", Radar="S-300VM 9A83ME" },
|
||||||
["HQ-2 HDS"] = { Range=50, Blindspot=6, Height=35, Type="Medium", Radar="HQ_2_Guideline_LN" },
|
["HQ-2 HDS"] = { Range=50, Blindspot=6, Height=35, Type="Medium", Radar="HQ_2_Guideline_LN" },
|
||||||
|
["SAMPT Block 1 HDS"] = { Range=120, Blindspot=1, Height=20, Type="long", Radar="SAMPT_MLT_Blk1" }, -- Block 1 Launcher
|
||||||
|
["SAMPT Block 1INT HDS"] = { Range=150, Blindspot=1, Height=25, Type="long", Radar="SAMPT_MLT_Blk1NT" }, -- Block 1-INT Launcher
|
||||||
|
["SAMPT Block 2 HDS"] = { Range=200, Blindspot=10, Height=70, Type="long", Radar="SAMPT_MLT_Blk2" }, -- Block 2 Launcher
|
||||||
}
|
}
|
||||||
|
|
||||||
--- SAM data SMA
|
--- SAM data SMA
|
||||||
@ -437,16 +444,16 @@ 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="Point", Radar="LvKv9040",Point="true" },
|
["Lvkv9040M SMA"] = { Range=2, Blindspot=0.1, Height=1.2, Type="Point", Radar="LvKv9040",Point="true" },
|
||||||
}
|
}
|
||||||
|
|
||||||
--- SAM data CH
|
--- SAM data CH
|
||||||
@ -461,47 +468,49 @@ 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="Point", Radar="PantsirS1", Point="true" },
|
||||||
["PantsirS2 CHM"] = { Range=30, Blindspot=1.2, Height=18, Type="Medium", Radar="PantsirS2" },
|
["PantsirS2 CHM"] = { Range=30, Blindspot=1.2, Height=18, Type="Medium", Radar="PantsirS2" },
|
||||||
["PGL-625 CHM"] = { Range=10, Blindspot=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="Point", Radar="TorM2", Point="true" },
|
||||||
["TorM2K CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2K" },
|
["TorM2K CHM"] = { Range=12, Blindspot=1, Height=10, Type="Point", Radar="TorM2K", Point="true" },
|
||||||
["TorM2M CHM"] = { Range=16, Blindspot=1, Height=10, Type="Short", Radar="TorM2M" },
|
["TorM2M CHM"] = { Range=16, Blindspot=1, Height=10, Type="Point", Radar="TorM2M", Point="true" },
|
||||||
["NASAMS3-AMRAAMER CHM"] = { Range=50, Blindspot=2, Height=35.7, Type="Medium", Radar="CH_NASAMS3_LN_AMRAAM_ER" },
|
["NASAMS3-AMRAAMER CHM"] = { Range=50, Blindspot=2, Height=35.7, Type="Medium", Radar="CH_NASAMS3_LN_AMRAAM_ER" },
|
||||||
["NASAMS3-AIM9X2 CHM"] = { Range=20, Blindspot=0.2, Height=18, Type="Short", Radar="CH_NASAMS3_LN_AIM9X2" },
|
["NASAMS3-AIM9X2 CHM"] = { Range=20, Blindspot=0.2, Height=18, Type="Short", Radar="CH_NASAMS3_LN_AIM9X2" },
|
||||||
["C-RAM CHM"] = { Range=2, Blindspot=0, Height=2, Type="Point", Radar="CH_Centurion_C_RAM", Point="true" },
|
["C-RAM CHM"] = { Range=2, Blindspot=0, Height=2, Type="Point", Radar="CH_Centurion_C_RAM", Point="true" },
|
||||||
["PGZ-09 CHM"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="CH_PGZ09", Point="true" },
|
["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="Point", Radar="CH_PGZ95",Point="true" },
|
["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="Point", Radar="CH_LD3000_stationary", Point="true" },
|
["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="Point", Radar="CH_LD3000", Point="true" },
|
["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="Point", Radar="CH_SkynexHX", Point="true" },
|
["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="Point", Radar="CH_Skyshield_Gun", Point="true" },
|
["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="Point", Radar="LvKv9040", Point="true" },
|
["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" },
|
||||||
}
|
}
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
@ -623,6 +632,7 @@ do
|
|||||||
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)
|
||||||
@ -656,6 +666,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)
|
||||||
@ -685,9 +697,6 @@ do
|
|||||||
-- counter for SAM table updates
|
-- counter for SAM table updates
|
||||||
self.checkcounter = 1
|
self.checkcounter = 1
|
||||||
|
|
||||||
-- TODO Version
|
|
||||||
-- @field #string version
|
|
||||||
self.version="0.9.27"
|
|
||||||
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
||||||
|
|
||||||
--- FSM Functions ---
|
--- FSM Functions ---
|
||||||
@ -884,7 +893,11 @@ do
|
|||||||
self.AcceptZones = AcceptZones or {}
|
self.AcceptZones = AcceptZones or {}
|
||||||
self.RejectZones = RejectZones or {}
|
self.RejectZones = RejectZones or {}
|
||||||
self.ConflictZones = ConflictZones or {}
|
self.ConflictZones = ConflictZones or {}
|
||||||
if #self.AcceptZones > 0 or #self.RejectZones > 0 or #self.ConflictZones > 0 then
|
self.AcceptZonesNo = UTILS.TableLength(self.AcceptZones)
|
||||||
|
self.RejectZonesNo = UTILS.TableLength(self.RejectZones)
|
||||||
|
self.ConflictZonesNo = UTILS.TableLength(self.ConflictZones)
|
||||||
|
self:T(string.format("AcceptZonesNo = %d | RejectZonesNo = %d | ConflictZonesNo = %d",self.AcceptZonesNo,self.RejectZonesNo,self.ConflictZonesNo))
|
||||||
|
if self.AcceptZonesNo > 0 or self.RejectZonesNo > 0 or self.ConflictZonesNo > 0 then
|
||||||
self.usezones = true
|
self.usezones = true
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
@ -1038,6 +1051,16 @@ do
|
|||||||
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
|
||||||
-- @param #number interval The interval in seconds
|
-- @param #number interval The interval in seconds
|
||||||
@ -1266,7 +1289,8 @@ do
|
|||||||
self:T(self.lid.."_CheckCoordinateInZones")
|
self:T(self.lid.."_CheckCoordinateInZones")
|
||||||
local inzone = false
|
local inzone = false
|
||||||
-- acceptzones
|
-- acceptzones
|
||||||
if #self.AcceptZones > 0 then
|
self:T(string.format("AcceptZonesNo = %d | RejectZonesNo = %d | ConflictZonesNo = %d",self.AcceptZonesNo,self.RejectZonesNo,self.ConflictZonesNo))
|
||||||
|
if self.AcceptZonesNo > 0 then
|
||||||
for _,_zone in pairs(self.AcceptZones) do
|
for _,_zone in pairs(self.AcceptZones) do
|
||||||
local zone = _zone -- Core.Zone#ZONE
|
local zone = _zone -- Core.Zone#ZONE
|
||||||
if zone:IsCoordinateInZone(coord) then
|
if zone:IsCoordinateInZone(coord) then
|
||||||
@ -1277,7 +1301,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- rejectzones
|
-- rejectzones
|
||||||
if #self.RejectZones > 0 and inzone then -- maybe in accept zone, but check the overlaps
|
if self.RejectZonesNo > 0 then
|
||||||
for _,_zone in pairs(self.RejectZones) do
|
for _,_zone in pairs(self.RejectZones) do
|
||||||
local zone = _zone -- Core.Zone#ZONE
|
local zone = _zone -- Core.Zone#ZONE
|
||||||
if zone:IsCoordinateInZone(coord) then
|
if zone:IsCoordinateInZone(coord) then
|
||||||
@ -1288,7 +1312,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- conflictzones
|
-- conflictzones
|
||||||
if #self.ConflictZones > 0 and not inzone then -- if not already accepted, might be in conflict zones
|
if self.ConflictZonesNo > 0 then
|
||||||
for _,_zone in pairs(self.ConflictZones) do
|
for _,_zone in pairs(self.ConflictZones) do
|
||||||
local zone = _zone -- Core.Zone#ZONE
|
local zone = _zone -- Core.Zone#ZONE
|
||||||
if zone:IsCoordinateInZone(coord) then
|
if zone:IsCoordinateInZone(coord) then
|
||||||
@ -1354,6 +1378,7 @@ do
|
|||||||
end
|
end
|
||||||
-- check accept/reject zones
|
-- check accept/reject zones
|
||||||
local zonecheck = true
|
local zonecheck = true
|
||||||
|
self:T("self.usezones = "..tostring(self.usezones))
|
||||||
if self.usezones then
|
if self.usezones then
|
||||||
-- DONE
|
-- DONE
|
||||||
zonecheck = self:_CheckCoordinateInZones(coord)
|
zonecheck = self:_CheckCoordinateInZones(coord)
|
||||||
@ -1429,7 +1454,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)
|
||||||
@ -1491,7 +1518,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())
|
||||||
@ -1692,7 +1719,9 @@ 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)
|
||||||
local radaralive = group:IsSAM()
|
-- 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( 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 and radaralive then
|
if type == MANTIS.SamType.LONG and radaralive then
|
||||||
@ -1789,7 +1818,7 @@ do
|
|||||||
if self.Shorad and self.Shorad.ActiveGroups and self.Shorad.ActiveGroups[name] then
|
if self.Shorad and self.Shorad.ActiveGroups and self.Shorad.ActiveGroups[name] then
|
||||||
activeshorad = true
|
activeshorad = true
|
||||||
end
|
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
|
||||||
local switch = false
|
local switch = false
|
||||||
@ -1821,7 +1850,7 @@ do
|
|||||||
-- 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
|
||||||
local Shorad = self.Shorad
|
local Shorad = self.Shorad --Functional.Shorad#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)
|
||||||
@ -1854,7 +1883,7 @@ do
|
|||||||
end --end alive
|
end --end alive
|
||||||
end --end check
|
end --end check
|
||||||
end --for loop
|
end --for loop
|
||||||
if self.debug or self.verbose 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
|
||||||
@ -1875,8 +1904,9 @@ do
|
|||||||
-- @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()
|
||||||
@ -1903,7 +1933,8 @@ do
|
|||||||
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
|
||||||
instatusred, instatusgreen, activeshorads = self:_CheckLoop(samset,detset,dlink,self.maxclassic)
|
instatusred, instatusgreen, activeshorads = self:_CheckLoop(samset,detset,dlink,self.maxclassic)
|
||||||
end
|
end
|
||||||
if self.debug or self.verbose then
|
|
||||||
|
local function GetReport()
|
||||||
local statusreport = REPORT:New("\nMANTIS Status "..self.name)
|
local statusreport = REPORT:New("\nMANTIS Status "..self.name)
|
||||||
statusreport:Add("+-----------------------------+")
|
statusreport:Add("+-----------------------------+")
|
||||||
statusreport:Add(string.format("+ SAM in RED State: %2d",instatusred))
|
statusreport:Add(string.format("+ SAM in RED State: %2d",instatusred))
|
||||||
@ -1912,7 +1943,15 @@ do
|
|||||||
statusreport:Add(string.format("+ SHORAD active: %2d",activeshorads))
|
statusreport:Add(string.format("+ SHORAD active: %2d",activeshorads))
|
||||||
end
|
end
|
||||||
statusreport:Add("+-----------------------------+")
|
statusreport:Add("+-----------------------------+")
|
||||||
|
return statusreport
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.debug or self.verbose then
|
||||||
|
local statusreport = GetReport()
|
||||||
MESSAGE:New(statusreport:Text(),10):ToAll():ToLog()
|
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
|
||||||
@ -2020,7 +2059,7 @@ 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
|
||||||
|
|
||||||
local EWRAlive = self:_CheckAnyEWRAlive()
|
local EWRAlive = self:_CheckAnyEWRAlive()
|
||||||
@ -2091,7 +2130,7 @@ do
|
|||||||
if self.debug and self.verbose then
|
if self.debug and self.verbose then
|
||||||
self:I(self.lid .. "Status Report")
|
self:I(self.lid .. "Status Report")
|
||||||
for _name,_state in pairs(self.SamStateTracker) do
|
for _name,_state in pairs(self.SamStateTracker) do
|
||||||
self:I(string.format("Site %s\tStatus %s",_name,_state))
|
self:I(string.format("Site %s | Status %s",_name,_state))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local interval = self.detectinterval * -1
|
local interval = self.detectinterval * -1
|
||||||
|
|||||||
@ -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.
|
||||||
--
|
--
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -2102,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 )
|
||||||
|
|||||||
@ -320,8 +320,10 @@ function SCORING:New( GameName, SavePath, AutoSave )
|
|||||||
|
|
||||||
-- Create the CSV file.
|
-- Create the CSV file.
|
||||||
self.AutoSavePath = SavePath
|
self.AutoSavePath = SavePath
|
||||||
self.AutoSave = AutoSave or true
|
self.AutoSave = (AutoSave == nil or AutoSave == true) and true or false
|
||||||
|
if self.AutoSavePath and self.AutoSave == true then
|
||||||
self:OpenCSV( GameName )
|
self:OpenCSV( GameName )
|
||||||
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@ -985,6 +987,7 @@ function SCORING:_EventOnHit( Event )
|
|||||||
local TargetUnitCoalition = nil
|
local TargetUnitCoalition = nil
|
||||||
local TargetUnitCategory = nil
|
local TargetUnitCategory = nil
|
||||||
local TargetUnitType = nil
|
local TargetUnitType = nil
|
||||||
|
local TargetIsScenery = false
|
||||||
|
|
||||||
if Event.IniDCSUnit then
|
if Event.IniDCSUnit then
|
||||||
|
|
||||||
@ -1025,6 +1028,12 @@ function SCORING:_EventOnHit( Event )
|
|||||||
TargetCategory = Event.TgtCategory
|
TargetCategory = Event.TgtCategory
|
||||||
TargetType = Event.TgtTypeName
|
TargetType = Event.TgtTypeName
|
||||||
|
|
||||||
|
-- Scenery hit
|
||||||
|
if (not TargetCategory) and TargetUNIT ~= nil and TargetUnit:IsInstanceOf("SCENERY") then
|
||||||
|
TargetCategory = Unit.Category.STRUCTURE
|
||||||
|
TargetIsScenery = true
|
||||||
|
end
|
||||||
|
|
||||||
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
|
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
|
||||||
TargetUnitCategory = _SCORINGCategory[TargetCategory]
|
TargetUnitCategory = _SCORINGCategory[TargetCategory]
|
||||||
TargetUnitType = TargetType
|
TargetUnitType = TargetType
|
||||||
@ -1117,17 +1126,22 @@ function SCORING:_EventOnHit( Event )
|
|||||||
MESSAGE.Type.Update )
|
MESSAGE.Type.Update )
|
||||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||||
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||||
else
|
elseif TargetIsScenery ~= true then
|
||||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " ..
|
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " ..
|
||||||
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||||
MESSAGE.Type.Update )
|
MESSAGE.Type.Update )
|
||||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||||
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||||
|
elseif TargetIsScenery == true then
|
||||||
|
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit scenery object." .. " Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||||
|
MESSAGE.Type.Update )
|
||||||
|
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||||
|
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||||
end
|
end
|
||||||
self:ScoreCSV( InitPlayerName, TargetPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
self:ScoreCSV( InitPlayerName, TargetPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
end
|
end
|
||||||
else -- A scenery object was hit.
|
else -- A scenery object was hit.
|
||||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit scenery object.",
|
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit nothing special.",
|
||||||
MESSAGE.Type.Update )
|
MESSAGE.Type.Update )
|
||||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||||
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||||
@ -1923,7 +1937,7 @@ function SCORING:ScoreCSV( PlayerName, TargetPlayerName, ScoreType, ScoreTimes,
|
|||||||
TargetUnitType = TargetUnitType or ""
|
TargetUnitType = TargetUnitType or ""
|
||||||
TargetUnitName = TargetUnitName or ""
|
TargetUnitName = TargetUnitName or ""
|
||||||
|
|
||||||
if lfs and io and os and self.AutoSave then
|
if lfs and io and os and self.AutoSave == true and self.CSVFile ~= nil then
|
||||||
self.CSVFile:write(
|
self.CSVFile:write(
|
||||||
'"' .. self.GameName .. '"' .. ',' ..
|
'"' .. self.GameName .. '"' .. ',' ..
|
||||||
'"' .. self.RunTime .. '"' .. ',' ..
|
'"' .. self.RunTime .. '"' .. ',' ..
|
||||||
|
|||||||
@ -3153,7 +3153,7 @@ end
|
|||||||
-- @param #WAREHOUSE self
|
-- @param #WAREHOUSE self
|
||||||
-- @return Core.Point#COORDINATE The coordinate of the warehouse.
|
-- @return Core.Point#COORDINATE The coordinate of the warehouse.
|
||||||
function WAREHOUSE:GetCoordinate()
|
function WAREHOUSE:GetCoordinate()
|
||||||
return self.warehouse:GetCoordinate()
|
return self.warehouse:GetCoord()
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get 3D vector of warehouse static.
|
--- Get 3D vector of warehouse static.
|
||||||
@ -4247,6 +4247,16 @@ function WAREHOUSE:_AssetItemInfo(asset)
|
|||||||
self:T3({Template=asset.template})
|
self:T3({Template=asset.template})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- This function uses Disposition and other fallback logic to find better ground positions for ground units.
|
||||||
|
--- NOTE: This is not a spawn randomizer.
|
||||||
|
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
|
||||||
|
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
||||||
|
--- Uses UTILS.ValidateAndRepositionGroundUnits.
|
||||||
|
-- @param #boolean Enabled Enable/disable the feature.
|
||||||
|
function WAREHOUSE:SetValidateAndRepositionGroundUnits(Enabled)
|
||||||
|
self.ValidateAndRepositionGroundUnits = Enabled
|
||||||
|
end
|
||||||
|
|
||||||
--- On after "NewAsset" event. A new asset has been added to the warehouse stock.
|
--- On after "NewAsset" event. A new asset has been added to the warehouse stock.
|
||||||
-- @param #WAREHOUSE self
|
-- @param #WAREHOUSE self
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
@ -5965,6 +5975,10 @@ function WAREHOUSE:_SpawnAssetGroundNaval(alias, asset, request, spawnzone, late
|
|||||||
template.y = coord.z
|
template.y = coord.z
|
||||||
template.alt = coord.y
|
template.alt = coord.y
|
||||||
|
|
||||||
|
if self.ValidateAndRepositionGroundUnits then
|
||||||
|
UTILS.ValidateAndRepositionGroundUnits(template.units)
|
||||||
|
end
|
||||||
|
|
||||||
-- Spawn group.
|
-- Spawn group.
|
||||||
local group=_DATABASE:Spawn(template) --Wrapper.Group#GROUP
|
local group=_DATABASE:Spawn(template) --Wrapper.Group#GROUP
|
||||||
|
|
||||||
@ -6893,7 +6907,7 @@ function WAREHOUSE:_CheckConquered()
|
|||||||
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 distance=coord:Get2DDistance(unit:GetCoordinate())
|
local distance=coord:Get2DDistance(unit:GetCoord())
|
||||||
|
|
||||||
-- Filter only alive groud units. Also check distance again, because the scan routine might give some larger distances.
|
-- Filter only alive groud units. Also check distance again, because the scan routine might give some larger distances.
|
||||||
if unit:IsGround() and unit:IsAlive() and distance <= radius then
|
if unit:IsGround() and unit:IsAlive() and distance <= radius then
|
||||||
|
|||||||
@ -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
|
||||||
--
|
--
|
||||||
|
|||||||
@ -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.
|
||||||
@ -2794,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
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,7 @@
|
|||||||
-- @image OPS_CSAR.jpg
|
-- @image OPS_CSAR.jpg
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Last Update Jan 2025
|
-- Last Update Oct 2025
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
||||||
@ -130,7 +130,7 @@
|
|||||||
-- ## 2.2 SRS Features and Other Features
|
-- ## 2.2 SRS Features and Other Features
|
||||||
--
|
--
|
||||||
-- mycsar.useSRS = false -- Set true to use FF\'s SRS integration
|
-- mycsar.useSRS = false -- Set true to use FF\'s SRS integration
|
||||||
-- mycsar.SRSPath = "C:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your SRS installation -- server(!)
|
-- mycsar.SRSPath = "C:\\Progra~1\\DCS-SimpleRadio-Standalone\\ExternalAudio\\" -- adjust your own path in your SRS installation -- server(!)
|
||||||
-- mycsar.SRSchannel = 300 -- radio channel
|
-- mycsar.SRSchannel = 300 -- radio channel
|
||||||
-- mycsar.SRSModulation = radio.modulation.AM -- modulation
|
-- mycsar.SRSModulation = radio.modulation.AM -- modulation
|
||||||
-- mycsar.SRSport = 5002 -- and SRS Server port
|
-- mycsar.SRSport = 5002 -- and SRS Server port
|
||||||
@ -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,
|
||||||
@ -304,6 +305,7 @@ CSAR.AircraftType["Mi-24P"] = 8
|
|||||||
CSAR.AircraftType["Mi-24V"] = 8
|
CSAR.AircraftType["Mi-24V"] = 8
|
||||||
CSAR.AircraftType["Bell-47"] = 2
|
CSAR.AircraftType["Bell-47"] = 2
|
||||||
CSAR.AircraftType["UH-60L"] = 10
|
CSAR.AircraftType["UH-60L"] = 10
|
||||||
|
CSAR.AircraftType["UH-60L_DAP"] = 2
|
||||||
CSAR.AircraftType["AH-64D_BLK_II"] = 2
|
CSAR.AircraftType["AH-64D_BLK_II"] = 2
|
||||||
CSAR.AircraftType["Bronco-OV-10A"] = 2
|
CSAR.AircraftType["Bronco-OV-10A"] = 2
|
||||||
CSAR.AircraftType["MH-60R"] = 10
|
CSAR.AircraftType["MH-60R"] = 10
|
||||||
@ -313,7 +315,7 @@ CSAR.AircraftType["CH-47Fbl1"] = 31
|
|||||||
|
|
||||||
--- CSAR class version.
|
--- CSAR class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CSAR.version="1.0.30"
|
CSAR.version="1.0.34"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- ToDo list
|
-- ToDo list
|
||||||
@ -468,7 +470,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
|
||||||
@ -480,7 +482,7 @@ function CSAR:New(Coalition, Template, Alias)
|
|||||||
-- for this to work you need to de-sanitize your mission environment in <DCS root>\Scripts\MissionScripting.lua
|
-- for this to work you need to de-sanitize your mission environment in <DCS root>\Scripts\MissionScripting.lua
|
||||||
-- needs SRS => 1.9.6 to work (works on the *server* side)
|
-- needs SRS => 1.9.6 to work (works on the *server* side)
|
||||||
self.useSRS = false -- Use FF\'s SRS integration
|
self.useSRS = false -- Use FF\'s SRS integration
|
||||||
self.SRSPath = "E:\\Program Files\\DCS-SimpleRadio-Standalone" -- adjust your own path in your server(!)
|
self.SRSPath = "E:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio" -- adjust your own path in your server(!)
|
||||||
self.SRSchannel = 300 -- radio channel
|
self.SRSchannel = 300 -- radio channel
|
||||||
self.SRSModulation = radio.modulation.AM -- modulation
|
self.SRSModulation = radio.modulation.AM -- modulation
|
||||||
self.SRSport = 5002 -- port
|
self.SRSport = 5002 -- port
|
||||||
@ -1145,6 +1147,37 @@ function CSAR:_EventHandler(EventData)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local initdcscoord = nil
|
||||||
|
local initcoord = nil
|
||||||
|
if _event.id == EVENTS.Ejection and _event.TgtDCSUnit then
|
||||||
|
initdcscoord = _event.TgtDCSUnit:getPoint()
|
||||||
|
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
||||||
|
self:T({initdcscoord})
|
||||||
|
elseif _event.IniDCSUnit then
|
||||||
|
initdcscoord = _event.IniDCSUnit:getPoint()
|
||||||
|
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
||||||
|
self:T({initdcscoord})
|
||||||
|
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.
|
-- limit no of pilots in the field.
|
||||||
if self.limitmaxdownedpilots and self:_ReachedPilotLimit() then
|
if self.limitmaxdownedpilots and self:_ReachedPilotLimit() then
|
||||||
self:T("Maxed Downed Pilot!")
|
self:T("Maxed Downed Pilot!")
|
||||||
@ -1157,18 +1190,6 @@ function CSAR:_EventHandler(EventData)
|
|||||||
|
|
||||||
local wetfeet = false
|
local wetfeet = false
|
||||||
|
|
||||||
local initdcscoord = nil
|
|
||||||
local initcoord = nil
|
|
||||||
if _event.id == EVENTS.Ejection then
|
|
||||||
initdcscoord = _event.TgtDCSUnit:getPoint()
|
|
||||||
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
|
||||||
self:T({initdcscoord})
|
|
||||||
else
|
|
||||||
initdcscoord = _event.IniDCSUnit:getPoint()
|
|
||||||
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
|
||||||
self:T({initdcscoord})
|
|
||||||
end
|
|
||||||
|
|
||||||
--local surface = _unit:GetCoordinate():GetSurfaceType()
|
--local surface = _unit:GetCoordinate():GetSurfaceType()
|
||||||
local surface = initcoord:GetSurfaceType()
|
local surface = initcoord:GetSurfaceType()
|
||||||
|
|
||||||
@ -1179,7 +1200,7 @@ function CSAR:_EventHandler(EventData)
|
|||||||
-- all checks passed, get going.
|
-- all checks passed, get going.
|
||||||
if self.csarUsePara == false or (self.csarUsePara and wetfeet ) then --shagrat check parameter LandingAfterEjection, if true don't spawn a Pilot from EJECTION event, wait for the Chute to land
|
if self.csarUsePara == false or (self.csarUsePara and wetfeet ) then --shagrat check parameter LandingAfterEjection, if true don't spawn a Pilot from EJECTION event, wait for the Chute to land
|
||||||
local _freq = self:_GenerateADFFrequency()
|
local _freq = self:_GenerateADFFrequency()
|
||||||
self:_AddCsar(_coalition, _unit:GetCountry(), initcoord , _unit:GetTypeName(), _unit:GetName(), _event.IniPlayerName, _freq, false, "none")
|
self:_AddCsar(_coalition, _unit:GetCountry(), initcoord , _unit:GetTypeName(), _unit:GetName(), _event.IniPlayerName, _freq, self.suppressmessages, "none")
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1223,7 +1244,10 @@ function CSAR:_EventHandler(EventData)
|
|||||||
|
|
||||||
if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then
|
if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then
|
||||||
self:__Landed(2,_event.IniUnitName, _place)
|
self:__Landed(2,_event.IniUnitName, _place)
|
||||||
self:_ScheduledSARFlight(_event.IniUnitName,_event.IniGroupName,true,true)
|
local IsHeloBase = false
|
||||||
|
local ABName = _place:GetName()
|
||||||
|
if ABName and string.find(ABName,"^H") then IsHeloBase = true end -- if name starts with an H it's an (possibly elevated) helo base on current maps
|
||||||
|
self:_ScheduledSARFlight(_event.IniUnitName,_event.IniGroupName,true,true,IsHeloBase)
|
||||||
else
|
else
|
||||||
self:T(string.format("Airfield %d, Unit %d", _place:GetCoalition(), _unit:GetCoalition()))
|
self:T(string.format("Airfield %d, Unit %d", _place:GetCoalition(), _unit:GetCoalition()))
|
||||||
end
|
end
|
||||||
@ -1244,7 +1268,7 @@ function CSAR:_EventHandler(EventData)
|
|||||||
if _coalition == self.coalition then
|
if _coalition == self.coalition then
|
||||||
local _freq = self:_GenerateADFFrequency()
|
local _freq = self:_GenerateADFFrequency()
|
||||||
self:I({coalition=_coalition,country= _country, coord=_LandingPos, name=_unitname, player=_event.IniPlayerName, freq=_freq})
|
self:I({coalition=_coalition,country= _country, coord=_LandingPos, name=_unitname, player=_event.IniPlayerName, freq=_freq})
|
||||||
self:_AddCsar(_coalition, _country, _LandingPos, nil, _unitname, _event.IniPlayerName, _freq, false, "none")--shagrat add CSAR at Parachute location.
|
self:_AddCsar(_coalition, _country, _LandingPos, nil, _unitname, _event.IniPlayerName, _freq, self.suppressmessages, "none")--shagrat add CSAR at Parachute location.
|
||||||
|
|
||||||
Unit.destroy(_event.initiator) -- shagrat remove static Pilot model
|
Unit.destroy(_event.initiator) -- shagrat remove static Pilot model
|
||||||
end
|
end
|
||||||
@ -1710,8 +1734,9 @@ end
|
|||||||
-- @param #string heliname Heli name
|
-- @param #string heliname Heli name
|
||||||
-- @param #string groupname Group name
|
-- @param #string groupname Group name
|
||||||
-- @param #boolean isairport If true, EVENT.Landing took place at an airport or FARP
|
-- @param #boolean isairport If true, EVENT.Landing took place at an airport or FARP
|
||||||
-- @param #boolean noreschedule If true, do not try to reschedule this is distances are not ok (coming from landing event)
|
-- @param #boolean noreschedule If true, do not try to reschedule this if distances are not ok (coming from landing event)
|
||||||
function CSAR:_ScheduledSARFlight(heliname,groupname, isairport, noreschedule)
|
-- @param #boolean IsHeloBase If true, landing took place at a Helo Base (name "H ..." on current maps)
|
||||||
|
function CSAR:_ScheduledSARFlight(heliname,groupname, isairport, noreschedule, IsHeloBase)
|
||||||
self:T(self.lid .. " _ScheduledSARFlight")
|
self:T(self.lid .. " _ScheduledSARFlight")
|
||||||
self:T({heliname,groupname})
|
self:T({heliname,groupname})
|
||||||
local _heliUnit = self:_GetSARHeli(heliname)
|
local _heliUnit = self:_GetSARHeli(heliname)
|
||||||
@ -1737,7 +1762,7 @@ function CSAR:_ScheduledSARFlight(heliname,groupname, isairport, noreschedule)
|
|||||||
|
|
||||||
self:T(self.lid.."[Drop off debug] Check distance to MASH for "..heliname.." Distance km: "..math.floor(_dist/1000))
|
self:T(self.lid.."[Drop off debug] Check distance to MASH for "..heliname.." Distance km: "..math.floor(_dist/1000))
|
||||||
|
|
||||||
if ( _dist < self.FARPRescueDistance or isairport ) and _heliUnit:InAir() == false then
|
if ( _dist < self.FARPRescueDistance or isairport ) and ((_heliUnit:InAir() == false) or (IsHeloBase == true)) then
|
||||||
self:T(self.lid.."[Drop off debug] Distance ok, door check")
|
self:T(self.lid.."[Drop off debug] Distance ok, door check")
|
||||||
if self.pilotmustopendoors and self:_IsLoadingDoorOpen(heliname) == false then
|
if self.pilotmustopendoors and self:_IsLoadingDoorOpen(heliname) == false then
|
||||||
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me out!", self.messageTime, true, true)
|
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me out!", self.messageTime, true, true)
|
||||||
@ -1752,7 +1777,7 @@ function CSAR:_ScheduledSARFlight(heliname,groupname, isairport, noreschedule)
|
|||||||
--queue up
|
--queue up
|
||||||
if not noreschedule then
|
if not noreschedule then
|
||||||
self:__Returning(5,heliname,_woundedGroupName, isairport)
|
self:__Returning(5,heliname,_woundedGroupName, isairport)
|
||||||
self:ScheduleOnce(5,self._ScheduledSARFlight,self,heliname,groupname, isairport, noreschedule)
|
self:ScheduleOnce(5,self._ScheduledSARFlight,self,heliname,groupname, isairport, noreschedule, IsHeloBase)
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -2116,56 +2141,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
|
||||||
|
if _mashUnit and (not _mashUnit:IsInstanceOf("ZONE_BASE")) and _mashUnit:IsAlive() then
|
||||||
|
_mashcoord = _mashUnit:GetCoordinate()
|
||||||
|
elseif _mashUnit and _mashUnit:IsInstanceOf("ZONE_BASE") then
|
||||||
|
_mashcoord = _mashUnit:GetCoordinate()
|
||||||
|
end
|
||||||
_distance = self:_GetDistance(_helicoord, _mashcoord)
|
_distance = self:_GetDistance(_helicoord, _mashcoord)
|
||||||
if _distance ~= nil and (_shortestDistance == -1 or _distance < _shortestDistance) then
|
if _distance ~= nil and (_shortestDistance == -1 or _distance < _shortestDistance) then
|
||||||
_shortestDistance = _distance
|
_shortestDistance = _distance
|
||||||
|
MashName = _mashUnit:GetName() or "Unknown"
|
||||||
end
|
end
|
||||||
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.
|
||||||
@ -2323,9 +2342,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
|
||||||
@ -2346,10 +2365,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
|
||||||
|
|
||||||
@ -2370,9 +2390,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
|
||||||
@ -2403,6 +2427,21 @@ function CSAR:_ReachedPilotLimit()
|
|||||||
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
|
||||||
|
if self.useFIFOLimitReplacement then
|
||||||
|
local oldIndex = -1
|
||||||
|
local oldDownedPilot = nil
|
||||||
|
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
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
@ -2454,9 +2493,10 @@ function CSAR:onafterStart(From, Event, To)
|
|||||||
|
|
||||||
self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart()
|
self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart()
|
||||||
|
|
||||||
local staticmashes = SET_STATIC:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterOnce()
|
self.staticmashes = SET_STATIC:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart()
|
||||||
local zonemashes = SET_ZONE:New():FilterPrefixes(self.mashprefix):FilterOnce()
|
self.zonemashes = SET_ZONE:New():FilterPrefixes(self.mashprefix):FilterStart()
|
||||||
|
|
||||||
|
--[[
|
||||||
if staticmashes:Count() > 0 then
|
if staticmashes:Count() > 0 then
|
||||||
for _,_mash in pairs(staticmashes.Set) do
|
for _,_mash in pairs(staticmashes.Set) do
|
||||||
self.mash:AddObject(_mash)
|
self.mash:AddObject(_mash)
|
||||||
@ -2464,10 +2504,13 @@ function CSAR:onafterStart(From, Event, To)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if zonemashes:Count() > 0 then
|
if zonemashes:Count() > 0 then
|
||||||
|
self:T("Adding zones to self.mash SET")
|
||||||
for _,_mash in pairs(zonemashes.Set) do
|
for _,_mash in pairs(zonemashes.Set) do
|
||||||
self.mash:AddObject(_mash)
|
self.mash:AddObject(_mash)
|
||||||
end
|
end
|
||||||
|
self:T("Objects in SET: "..self.mash:Count())
|
||||||
end
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
if not self.coordinate then
|
if not self.coordinate then
|
||||||
local csarhq = self.mash:GetRandom()
|
local csarhq = self.mash:GetRandom()
|
||||||
@ -2968,7 +3011,7 @@ function CSAR:onafterLoad(From, Event, To, path, filename)
|
|||||||
local unitName = dataset[9]
|
local unitName = dataset[9]
|
||||||
local freq = tonumber(dataset[10])
|
local freq = tonumber(dataset[10])
|
||||||
|
|
||||||
self:_AddCsar(coalition, country, point, typeName, unitName, playerName, freq, nil, description, nil)
|
self:_AddCsar(coalition, country, point, typeName, unitName, playerName, freq, false, description, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -72,7 +72,7 @@ end
|
|||||||
|
|
||||||
--- Checks if a point is contained within the circle.
|
--- Checks if a point is contained within the circle.
|
||||||
-- @param #table point The point to check
|
-- @param #table point The point to check
|
||||||
-- @return #bool True if the point is contained, false otherwise
|
-- @return #boolean True if the point is contained, false otherwise
|
||||||
function CIRCLE:ContainsPoint(point)
|
function CIRCLE:ContainsPoint(point)
|
||||||
if ((point.x - self.CenterVec2.x) ^ 2 + (point.y - self.CenterVec2.y) ^ 2) ^ 0.5 <= self.Radius then
|
if ((point.x - self.CenterVec2.x) ^ 2 + (point.y - self.CenterVec2.y) ^ 2) ^ 0.5 <= self.Radius then
|
||||||
return true
|
return true
|
||||||
@ -226,6 +226,11 @@ end
|
|||||||
--- Returns a random Vec2 within the circle.
|
--- Returns a random Vec2 within the circle.
|
||||||
-- @return #table The random Vec2
|
-- @return #table The random Vec2
|
||||||
function CIRCLE:GetRandomVec2()
|
function CIRCLE:GetRandomVec2()
|
||||||
|
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
|
||||||
local angle = math.random() * 2 * math.pi
|
local angle = math.random() * 2 * math.pi
|
||||||
|
|
||||||
local rx = math.random(0, self.Radius) * math.cos(angle) + self.CenterVec2.x
|
local rx = math.random(0, self.Radius) * math.cos(angle) + self.CenterVec2.x
|
||||||
@ -237,6 +242,11 @@ end
|
|||||||
--- Returns a random Vec2 on the border of the circle.
|
--- Returns a random Vec2 on the border of the circle.
|
||||||
-- @return #table The random Vec2
|
-- @return #table The random Vec2
|
||||||
function CIRCLE:GetRandomVec2OnBorder()
|
function CIRCLE:GetRandomVec2OnBorder()
|
||||||
|
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
|
||||||
local angle = math.random() * 2 * math.pi
|
local angle = math.random() * 2 * math.pi
|
||||||
|
|
||||||
local rx = self.Radius * math.cos(angle) + self.CenterVec2.x
|
local rx = self.Radius * math.cos(angle) + self.CenterVec2.x
|
||||||
|
|||||||
@ -352,6 +352,7 @@ end
|
|||||||
--- Returns a random Vec2 within the polygon. The Vec2 is weighted by the areas of the triangles that make up the polygon.
|
--- Returns a random Vec2 within the polygon. The Vec2 is weighted by the areas of the triangles that make up the polygon.
|
||||||
-- @return #table The random Vec2
|
-- @return #table The random Vec2
|
||||||
function POLYGON:GetRandomVec2()
|
function POLYGON:GetRandomVec2()
|
||||||
|
|
||||||
local weights = {}
|
local weights = {}
|
||||||
for _, triangle in pairs(self.Triangles) do
|
for _, triangle in pairs(self.Triangles) do
|
||||||
weights[triangle] = triangle.SurfaceArea / self.SurfaceArea
|
weights[triangle] = triangle.SurfaceArea / self.SurfaceArea
|
||||||
|
|||||||
@ -73,6 +73,11 @@ end
|
|||||||
-- @param #table points The points of the triangle, or 3 other points if you're just using the TRIANGLE class without an object of it
|
-- @param #table points The points of the triangle, or 3 other points if you're just using the TRIANGLE class without an object of it
|
||||||
-- @return #table The random Vec2
|
-- @return #table The random Vec2
|
||||||
function TRIANGLE:GetRandomVec2(points)
|
function TRIANGLE:GetRandomVec2(points)
|
||||||
|
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
math.random()
|
||||||
|
|
||||||
points = points or self.Points
|
points = points or self.Points
|
||||||
local pt = {math.random(), math.random()}
|
local pt = {math.random(), math.random()}
|
||||||
table.sort(pt)
|
table.sort(pt)
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -443,28 +443,32 @@ MSRS.Voices = {
|
|||||||
["en_AU_Standard_B"] = 'en-AU-Standard-B', -- [2] MALE
|
["en_AU_Standard_B"] = 'en-AU-Standard-B', -- [2] MALE
|
||||||
["en_AU_Standard_C"] = 'en-AU-Standard-C', -- [3] FEMALE
|
["en_AU_Standard_C"] = 'en-AU-Standard-C', -- [3] FEMALE
|
||||||
["en_AU_Standard_D"] = 'en-AU-Standard-D', -- [4] MALE
|
["en_AU_Standard_D"] = 'en-AU-Standard-D', -- [4] MALE
|
||||||
["en_IN_Standard_A"] = 'en-IN-Standard-A', -- [5] FEMALE
|
-- IN
|
||||||
["en_IN_Standard_B"] = 'en-IN-Standard-B', -- [6] MALE
|
["en_IN_Standard_A"] = 'en-IN-Standard-A', -- Female
|
||||||
["en_IN_Standard_C"] = 'en-IN-Standard-C', -- [7] MALE
|
["en_IN_Standard_B"] = 'en-IN-Standard-B', -- Male
|
||||||
["en_IN_Standard_D"] = 'en-IN-Standard-D', -- [8] FEMALE
|
["en_IN_Standard_C"] = 'en-IN-Standard-C', -- Male
|
||||||
|
["en_IN_Standard_D"] = 'en-IN-Standard-D', -- Female
|
||||||
|
["en_IN_Standard_E"] = 'en-IN-Standard-E', -- Female
|
||||||
|
["en_IN_Standard_F"] = 'en-IN-Standard-F', -- Male
|
||||||
-- 2025 changes
|
-- 2025 changes
|
||||||
["en_GB_Standard_A"] = 'en-GB-Standard-N', -- [9] FEMALE
|
["en_GB_Standard_A"] = 'en-GB-Standard-A', -- Female
|
||||||
["en_GB_Standard_B"] = 'en-GB-Standard-O', -- [10] MALE
|
["en_GB_Standard_B"] = 'en-GB-Standard-B', -- Male
|
||||||
["en_GB_Standard_C"] = 'en-GB-Standard-N', -- [11] FEMALE
|
["en_GB_Standard_C"] = 'en-GB-Standard-C', -- Female
|
||||||
["en_GB_Standard_D"] = 'en-GB-Standard-O', -- [12] MALE
|
["en_GB_Standard_D"] = 'en-GB-Standard-D', -- Male
|
||||||
["en_GB_Standard_F"] = 'en-GB-Standard-N', -- [13] FEMALE
|
["en_GB_Standard_F"] = 'en-GB-Standard-F', -- Female
|
||||||
["en_GB_Standard_O"] = 'en-GB-Standard-O', -- [12] MALE
|
["en_GB_Standard_N"] = 'en-GB-Standard-N', -- Female
|
||||||
["en_GB_Standard_N"] = 'en-GB-Standard-N', -- [13] FEMALE
|
["en_GB_Standard_O"] = 'en-GB-Standard-O', -- Male
|
||||||
["en_US_Standard_A"] = 'en-US-Standard-A', -- [14] MALE
|
-- US
|
||||||
["en_US_Standard_B"] = 'en-US-Standard-B', -- [15] MALE
|
["en_US_Standard_A"] = 'en-US-Standard-A', -- Male
|
||||||
["en_US_Standard_C"] = 'en-US-Standard-C', -- [16] FEMALE
|
["en_US_Standard_B"] = 'en-US-Standard-B', -- Male
|
||||||
["en_US_Standard_D"] = 'en-US-Standard-D', -- [17] MALE
|
["en_US_Standard_C"] = 'en-US-Standard-C', -- Female
|
||||||
["en_US_Standard_E"] = 'en-US-Standard-E', -- [18] FEMALE
|
["en_US_Standard_D"] = 'en-US-Standard-D', -- Male
|
||||||
["en_US_Standard_F"] = 'en-US-Standard-F', -- [19] FEMALE
|
["en_US_Standard_E"] = 'en-US-Standard-E', -- Female
|
||||||
["en_US_Standard_G"] = 'en-US-Standard-G', -- [20] FEMALE
|
["en_US_Standard_F"] = 'en-US-Standard-F', -- Female
|
||||||
["en_US_Standard_H"] = 'en-US-Standard-H', -- [21] FEMALE
|
["en_US_Standard_G"] = 'en-US-Standard-G', -- Female
|
||||||
["en_US_Standard_I"] = 'en-US-Standard-I', -- [22] MALE
|
["en_US_Standard_H"] = 'en-US-Standard-H', -- Female
|
||||||
["en_US_Standard_J"] = 'en-US-Standard-J', -- [23] MALE
|
["en_US_Standard_I"] = 'en-US-Standard-I', -- Male
|
||||||
|
["en_US_Standard_J"] = 'en-US-Standard-J', -- Male
|
||||||
-- 2025 catalog changes
|
-- 2025 catalog changes
|
||||||
["fr_FR_Standard_A"] = "fr-FR-Standard-F", -- Female
|
["fr_FR_Standard_A"] = "fr-FR-Standard-F", -- Female
|
||||||
["fr_FR_Standard_B"] = "fr-FR-Standard-G", -- Male
|
["fr_FR_Standard_B"] = "fr-FR-Standard-G", -- Male
|
||||||
@ -474,14 +478,15 @@ MSRS.Voices = {
|
|||||||
["fr_FR_Standard_G"] = "fr-FR-Standard-G", -- Male
|
["fr_FR_Standard_G"] = "fr-FR-Standard-G", -- Male
|
||||||
["fr_FR_Standard_F"] = "fr-FR-Standard-F", -- Female
|
["fr_FR_Standard_F"] = "fr-FR-Standard-F", -- Female
|
||||||
-- 2025 catalog changes
|
-- 2025 catalog changes
|
||||||
["de_DE_Standard_A"] = "de-DE-Standard-G", -- Female
|
["de_DE_Standard_A"] = 'de-DE-Standard-A', -- Female
|
||||||
["de_DE_Standard_B"] = "de-DE-Standard-H", -- Male
|
["de_DE_Standard_B"] = 'de-DE-Standard-B', -- Male
|
||||||
["de_DE_Standard_C"] = "de-DE-Standard-G", -- Female
|
["de_DE_Standard_C"] = 'de-DE-Standard-C', -- Female
|
||||||
["de_DE_Standard_D"] = "de-DE-Standard-H", -- Male
|
["de_DE_Standard_D"] = 'de-DE-Standard-D', -- Male
|
||||||
["de_DE_Standard_E"] = "de-DE-Standard-H", -- Male
|
["de_DE_Standard_E"] = 'de-DE-Standard-E', -- Male
|
||||||
["de_DE_Standard_F"] = "de-DE-Standard-G", -- Female
|
["de_DE_Standard_F"] = 'de-DE-Standard-F', -- Female
|
||||||
["de_DE_Standard_H"] = "de-DE-Standard-H", -- Male
|
["de_DE_Standard_G"] = 'de-DE-Standard-G', -- Female
|
||||||
["de_DE_Standard_G"] = "de-DE-Standard-G", -- Female
|
["de_DE_Standard_H"] = 'de-DE-Standard-H', -- Male
|
||||||
|
-- ES
|
||||||
["es_ES_Standard_A"] = "es-ES-Standard-E", -- Female
|
["es_ES_Standard_A"] = "es-ES-Standard-E", -- Female
|
||||||
["es_ES_Standard_B"] = "es-ES-Standard-F", -- Male
|
["es_ES_Standard_B"] = "es-ES-Standard-F", -- Male
|
||||||
["es_ES_Standard_C"] = "es-ES-Standard-E", -- Female
|
["es_ES_Standard_C"] = "es-ES-Standard-E", -- Female
|
||||||
@ -497,32 +502,36 @@ MSRS.Voices = {
|
|||||||
["it_IT_Standard_F"] = "it-IT-Standard-F", -- Male
|
["it_IT_Standard_F"] = "it-IT-Standard-F", -- Male
|
||||||
},
|
},
|
||||||
Wavenet = {
|
Wavenet = {
|
||||||
["en_AU_Wavenet_A"] = 'en-AU-Wavenet-A', -- [1] FEMALE
|
["en_AU_Wavenet_A"] = 'en-AU-Wavenet-A', -- Female
|
||||||
["en_AU_Wavenet_B"] = 'en-AU-Wavenet-B', -- [2] MALE
|
["en_AU_Wavenet_B"] = 'en-AU-Wavenet-B', -- Male
|
||||||
["en_AU_Wavenet_C"] = 'en-AU-Wavenet-C', -- [3] FEMALE
|
["en_AU_Wavenet_C"] = 'en-AU-Wavenet-C', -- Female
|
||||||
["en_AU_Wavenet_D"] = 'en-AU-Wavenet-D', -- [4] MALE
|
["en_AU_Wavenet_D"] = 'en-AU-Wavenet-D', -- Male
|
||||||
["en_IN_Wavenet_A"] = 'en-IN-Wavenet-A', -- [5] FEMALE
|
-- IN
|
||||||
["en_IN_Wavenet_B"] = 'en-IN-Wavenet-B', -- [6] MALE
|
["en_IN_Wavenet_A"] = 'en-IN-Wavenet-A', -- Female
|
||||||
["en_IN_Wavenet_C"] = 'en-IN-Wavenet-C', -- [7] MALE
|
["en_IN_Wavenet_B"] = 'en-IN-Wavenet-B', -- Male
|
||||||
["en_IN_Wavenet_D"] = 'en-IN-Wavenet-D', -- [8] FEMALE
|
["en_IN_Wavenet_C"] = 'en-IN-Wavenet-C', -- Male
|
||||||
|
["en_IN_Wavenet_D"] = 'en-IN-Wavenet-D', -- Female
|
||||||
|
["en_IN_Wavenet_E"] = 'en-IN-Wavenet-E', -- Female
|
||||||
|
["en_IN_Wavenet_F"] = 'en-IN-Wavenet-F', -- Male
|
||||||
-- 2025 changes
|
-- 2025 changes
|
||||||
["en_GB_Wavenet_A"] = 'en-GB-Wavenet-N', -- [9] FEMALE
|
["en_GB_Wavenet_A"] = 'en-GB-Wavenet-A', -- [9] FEMALE
|
||||||
["en_GB_Wavenet_B"] = 'en-GB-Wavenet-O', -- [10] MALE
|
["en_GB_Wavenet_B"] = 'en-GB-Wavenet-B', -- [10] MALE
|
||||||
["en_GB_Wavenet_C"] = 'en-GB-Wavenet-N', -- [11] FEMALE
|
["en_GB_Wavenet_C"] = 'en-GB-Wavenet-C', -- [11] FEMALE
|
||||||
["en_GB_Wavenet_D"] = 'en-GB-Wavenet-O', -- [12] MALE
|
["en_GB_Wavenet_D"] = 'en-GB-Wavenet-D', -- [12] MALE
|
||||||
["en_GB_Wavenet_F"] = 'en-GB-Wavenet-N', -- [13] FEMALE
|
["en_GB_Wavenet_F"] = 'en-GB-Wavenet-F', -- [13] FEMALE
|
||||||
["en_GB_Wavenet_O"] = 'en-GB-Wavenet-O', -- [12] MALE
|
["en_GB_Wavenet_O"] = 'en-GB-Wavenet-O', -- [12] MALE
|
||||||
["en_GB_Wavenet_N"] = 'en-GB-Wavenet-N', -- [13] FEMALE
|
["en_GB_Wavenet_N"] = 'en-GB-Wavenet-N', -- [13] FEMALE
|
||||||
["en_US_Wavenet_A"] = 'en-US-Wavenet-N', -- [14] MALE
|
-- US
|
||||||
["en_US_Wavenet_B"] = 'en-US-Wavenet-B', -- [15] MALE
|
["en_US_Wavenet_A"] = 'en-US-Wavenet-A', -- Male
|
||||||
["en_US_Wavenet_C"] = 'en-US-Wavenet-C', -- [16] FEMALE
|
["en_US_Wavenet_B"] = 'en-US-Wavenet-B', -- Male
|
||||||
["en_US_Wavenet_D"] = 'en-US-Wavenet-D', -- [17] MALE
|
["en_US_Wavenet_C"] = 'en-US-Wavenet-C', -- Female
|
||||||
["en_US_Wavenet_E"] = 'en-US-Wavenet-E', -- [18] FEMALE
|
["en_US_Wavenet_D"] = 'en-US-Wavenet-D', -- Male
|
||||||
["en_US_Wavenet_F"] = 'en-US-Wavenet-F', -- [19] FEMALE
|
["en_US_Wavenet_E"] = 'en-US-Wavenet-E', -- Female
|
||||||
["en_US_Wavenet_G"] = 'en-US-Wavenet-G', -- [20] FEMALE
|
["en_US_Wavenet_F"] = 'en-US-Wavenet-F', -- Female
|
||||||
["en_US_Wavenet_H"] = 'en-US-Wavenet-H', -- [21] FEMALE
|
["en_US_Wavenet_G"] = 'en-US-Wavenet-G', -- Female
|
||||||
["en_US_Wavenet_I"] = 'en-US-Wavenet-I', -- [22] MALE
|
["en_US_Wavenet_H"] = 'en-US-Wavenet-H', -- Female
|
||||||
["en_US_Wavenet_J"] = 'en-US-Wavenet-J', -- [23] MALE
|
["en_US_Wavenet_I"] = 'en-US-Wavenet-I', -- Male
|
||||||
|
["en_US_Wavenet_J"] = 'en-US-Wavenet-J', -- Male
|
||||||
-- 2025 catalog changes
|
-- 2025 catalog changes
|
||||||
["fr_FR_Wavenet_A"] = "fr-FR-Wavenet-F", -- Female
|
["fr_FR_Wavenet_A"] = "fr-FR-Wavenet-F", -- Female
|
||||||
["fr_FR_Wavenet_B"] = "fr-FR-Wavenet-G", -- Male
|
["fr_FR_Wavenet_B"] = "fr-FR-Wavenet-G", -- Male
|
||||||
@ -532,14 +541,15 @@ MSRS.Voices = {
|
|||||||
["fr_FR_Wavenet_G"] = "fr-FR-Wavenet-G", -- Male
|
["fr_FR_Wavenet_G"] = "fr-FR-Wavenet-G", -- Male
|
||||||
["fr_FR_Wavenet_F"] = "fr-FR-Wavenet-F", -- Female
|
["fr_FR_Wavenet_F"] = "fr-FR-Wavenet-F", -- Female
|
||||||
-- 2025 catalog changes
|
-- 2025 catalog changes
|
||||||
["de_DE_Wavenet_A"] = "de-DE-Wavenet-G", -- Female
|
["de_DE_Wavenet_A"] = 'de-DE-Wavenet-A', -- Female
|
||||||
["de_DE_Wavenet_B"] = "de-DE-Wavenet-H", -- Male
|
["de_DE_Wavenet_B"] = 'de-DE-Wavenet-B', -- Male
|
||||||
["de_DE_Wavenet_C"] = "de-DE-Wavenet-G", -- Female
|
["de_DE_Wavenet_C"] = 'de-DE-Wavenet-C', -- Female
|
||||||
["de_DE_Wavenet_D"] = "de-DE-Wavenet-H", -- Male
|
["de_DE_Wavenet_D"] = 'de-DE-Wavenet-D', -- Male
|
||||||
["de_DE_Wavenet_E"] = "de-DE-Wavenet-H", -- Male
|
["de_DE_Wavenet_E"] = 'de-DE-Wavenet-E', -- Male
|
||||||
["de_DE_Wavenet_F"] = "de-DE-Wavenet-G", -- Female
|
["de_DE_Wavenet_F"] = 'de-DE-Wavenet-F', -- Female
|
||||||
["de_DE_Wavenet_H"] = "de-DE-Wavenet-H", -- Male
|
["de_DE_Wavenet_G"] = 'de-DE-Wavenet-G', -- Female
|
||||||
["de_DE_Wavenet_G"] = "de-DE-Wavenet-G", -- Female
|
["de_DE_Wavenet_H"] = 'de-DE-Wavenet-H', -- Male
|
||||||
|
-- ES
|
||||||
["es_ES_Wavenet_B"] = "es-ES-Wavenet-E", -- Male
|
["es_ES_Wavenet_B"] = "es-ES-Wavenet-E", -- Male
|
||||||
["es_ES_Wavenet_C"] = "es-ES-Wavenet-F", -- Female
|
["es_ES_Wavenet_C"] = "es-ES-Wavenet-F", -- Female
|
||||||
["es_ES_Wavenet_D"] = "es-ES-Wavenet-E", -- Female
|
["es_ES_Wavenet_D"] = "es-ES-Wavenet-E", -- Female
|
||||||
@ -553,6 +563,134 @@ MSRS.Voices = {
|
|||||||
["it_IT_Wavenet_E"] = "it-IT-Wavenet-E", -- Female
|
["it_IT_Wavenet_E"] = "it-IT-Wavenet-E", -- Female
|
||||||
["it_IT_Wavenet_F"] = "it-IT-Wavenet-F", -- Male
|
["it_IT_Wavenet_F"] = "it-IT-Wavenet-F", -- Male
|
||||||
} ,
|
} ,
|
||||||
|
Chirp3HD = {
|
||||||
|
["en_GB_Chirp3_HD_Aoede"] = 'en-GB-Chirp3-HD-Aoede', -- Female
|
||||||
|
["en_GB_Chirp3_HD_Charon"] = 'en-GB-Chirp3-HD-Charon', -- Male
|
||||||
|
["en_GB_Chirp3_HD_Fenrir"] = 'en-GB-Chirp3-HD-Fenrir', -- Male
|
||||||
|
["en_GB_Chirp3_HD_Kore"] = 'en-GB-Chirp3-HD-Kore', -- Female
|
||||||
|
["en_GB_Chirp3_HD_Leda"] = 'en-GB-Chirp3-HD-Leda', -- Female
|
||||||
|
["en_GB_Chirp3_HD_Orus"] = 'en-GB-Chirp3-HD-Orus', -- Male
|
||||||
|
["en_GB_Chirp3_HD_Puck"] = 'en-GB-Chirp3-HD-Puck', -- Male
|
||||||
|
["en_GB_Chirp3_HD_Zephyr"] = 'en-GB-Chirp3-HD-Zephyr', -- Female
|
||||||
|
--["de_DE_Chirp3_HD_Aoede"] = 'de-DE-Chirp3-HD-Aoede', -- Female (Datenfehler im Original)
|
||||||
|
["en_US_Chirp3_HD_Charon"] = 'en-US-Chirp3-HD-Charon', -- Male
|
||||||
|
["en_US_Chirp3_HD_Fenrir"] = 'en-US-Chirp3-HD-Fenrir', -- Male
|
||||||
|
["en_US_Chirp3_HD_Kore"] = 'en-US-Chirp3-HD-Kore', -- Female
|
||||||
|
["en_US_Chirp3_HD_Leda"] = 'en-US-Chirp3-HD-Leda', -- Female
|
||||||
|
["en_US_Chirp3_HD_Orus"] = 'en-US-Chirp3-HD-Orus', -- Male
|
||||||
|
["en_US_Chirp3_HD_Puck"] = 'en-US-Chirp3-HD-Puck', -- Male
|
||||||
|
--["de_DE_Chirp3_HD_Zephyr"] = 'de-DE-Chirp3-HD-Zephyr', -- Female (Datenfehler im Original)
|
||||||
|
-- DE
|
||||||
|
["de_DE_Chirp3_HD_Aoede"] = 'de-DE-Chirp3-HD-Aoede', -- Female
|
||||||
|
["de_DE_Chirp3_HD_Charon"] = 'de-DE-Chirp3-HD-Charon', -- Male
|
||||||
|
["de_DE_Chirp3_HD_Fenrir"] = 'de-DE-Chirp3-HD-Fenrir', -- Male
|
||||||
|
["de_DE_Chirp3_HD_Kore"] = 'de-DE-Chirp3-HD-Kore', -- Female
|
||||||
|
["de_DE_Chirp3_HD_Leda"] = 'de-DE-Chirp3-HD-Leda', -- Female
|
||||||
|
["de_DE_Chirp3_HD_Orus"] = 'de-DE-Chirp3-HD-Orus', -- Male
|
||||||
|
["de_DE_Chirp3_HD_Puck"] = 'de-DE-Chirp3-HD-Puck', -- Male
|
||||||
|
["de_DE_Chirp3_HD_Zephyr"] = 'de-DE-Chirp3-HD-Zephyr', -- Female
|
||||||
|
-- AU
|
||||||
|
["en_AU_Chirp3_HD_Aoede"] = 'en-AU-Chirp3-HD-Aoede', -- Female
|
||||||
|
["en_AU_Chirp3_HD_Charon"] = 'en-AU-Chirp3-HD-Charon', -- Male
|
||||||
|
["en_AU_Chirp3_HD_Fenrir"] = 'en-AU-Chirp3-HD-Fenrir', -- Male
|
||||||
|
["en_AU_Chirp3_HD_Kore"] = 'en-AU-Chirp3-HD-Kore', -- Female
|
||||||
|
["en_AU_Chirp3_HD_Leda"] = 'en-AU-Chirp3-HD-Leda', -- Female
|
||||||
|
["en_AU_Chirp3_HD_Orus"] = 'en-AU-Chirp3-HD-Orus', -- Male
|
||||||
|
["en_AU_Chirp3_HD_Puck"] = 'en-AU-Chirp3-HD-Puck', -- Male
|
||||||
|
["en_AU_Chirp3_HD_Zephyr"] = 'en-AU-Chirp3-HD-Zephyr', -- Female
|
||||||
|
-- IN
|
||||||
|
["en_IN_Chirp3_HD_Aoede"] = 'en-IN-Chirp3-HD-Aoede', -- Female
|
||||||
|
["en_IN_Chirp3_HD_Charon"] = 'en-IN-Chirp3-HD-Charon', -- Male
|
||||||
|
["en_IN_Chirp3_HD_Fenrir"] = 'en-IN-Chirp3-HD-Fenrir', -- Male
|
||||||
|
["en_IN_Chirp3_HD_Kore"] = 'en-IN-Chirp3-HD-Kore', -- Female
|
||||||
|
["en_IN_Chirp3_HD_Leda"] = 'en-IN-Chirp3-HD-Leda', -- Female
|
||||||
|
["en_IN_Chirp3_HD_Orus"] = 'en-IN-Chirp3-HD-Orus', -- Male
|
||||||
|
},
|
||||||
|
ChirpHD = {
|
||||||
|
["en_US_Chirp_HD_D"] = 'en-US-Chirp-HD-D', -- Male
|
||||||
|
["en_US_Chirp_HD_F"] = 'en-US-Chirp-HD-F', -- Female
|
||||||
|
["en_US_Chirp_HD_O"] = 'en-US-Chirp-HD-O', -- Female
|
||||||
|
-- DE
|
||||||
|
["de_DE_Chirp_HD_D"] = 'de-DE-Chirp-HD-D', -- Male
|
||||||
|
["de_DE_Chirp_HD_F"] = 'de-DE-Chirp-HD-F', -- Female
|
||||||
|
["de_DE_Chirp_HD_O"] = 'de-DE-Chirp-HD-O', -- Female
|
||||||
|
-- AU
|
||||||
|
["en_AU_Chirp_HD_D"] = 'en-AU-Chirp-HD-D', -- Male
|
||||||
|
["en_AU_Chirp_HD_F"] = 'en-AU-Chirp-HD-F', -- Female
|
||||||
|
["en_AU_Chirp_HD_O"] = 'en-AU-Chirp-HD-O', -- Female
|
||||||
|
-- IN
|
||||||
|
["en_IN_Chirp_HD_D"] = 'en-IN-Chirp-HD-D', -- Male
|
||||||
|
["en_IN_Chirp_HD_F"] = 'en-IN-Chirp-HD-F', -- Female
|
||||||
|
["en_IN_Chirp_HD_O"] = 'en-IN-Chirp-HD-O', -- Female
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Neural2 = {
|
||||||
|
["en_GB_Neural2_A"] = 'en-GB-Neural2-A', -- Female
|
||||||
|
["en_GB_Neural2_B"] = 'en-GB-Neural2-B', -- Male
|
||||||
|
["en_GB_Neural2_C"] = 'en-GB-Neural2-C', -- Female
|
||||||
|
["en_GB_Neural2_D"] = 'en-GB-Neural2-D', -- Male
|
||||||
|
["en_GB_Neural2_F"] = 'en-GB-Neural2-F', -- Female
|
||||||
|
["en_GB_Neural2_N"] = 'en-GB-Neural2-N', -- Female
|
||||||
|
["en_GB_Neural2_O"] = 'en-GB-Neural2-O', -- Male
|
||||||
|
-- US
|
||||||
|
["en_US_Neural2_A"] = 'en-US-Neural2-A', -- Male
|
||||||
|
["en_US_Neural2_C"] = 'en-US-Neural2-C', -- Female
|
||||||
|
["en_US_Neural2_D"] = 'en-US-Neural2-D', -- Male
|
||||||
|
["en_US_Neural2_E"] = 'en-US-Neural2-E', -- Female
|
||||||
|
["en_US_Neural2_F"] = 'en-US-Neural2-F', -- Female
|
||||||
|
["en_US_Neural2_G"] = 'en-US-Neural2-G', -- Female
|
||||||
|
["en_US_Neural2_H"] = 'en-US-Neural2-H', -- Female
|
||||||
|
["en_US_Neural2_I"] = 'en-US-Neural2-I', -- Male
|
||||||
|
["en_US_Neural2_J"] = 'en-US-Neural2-J', -- Male
|
||||||
|
-- DE
|
||||||
|
["de_DE_Neural2_G"] = 'de-DE-Neural2-G', -- Female
|
||||||
|
["de_DE_Neural2_H"] = 'de-DE-Neural2-H', -- Male
|
||||||
|
-- AU
|
||||||
|
["en_AU_Neural2_A"] = 'en-AU-Neural2-A', -- Female
|
||||||
|
["en_AU_Neural2_B"] = 'en-AU-Neural2-B', -- Male
|
||||||
|
["en_AU_Neural2_C"] = 'en-AU-Neural2-C', -- Female
|
||||||
|
["en_AU_Neural2_D"] = 'en-AU-Neural2-D', -- Male
|
||||||
|
-- IN
|
||||||
|
["en_IN_Neural2_A"] = 'en-IN-Neural2-A', -- Female
|
||||||
|
["en_IN_Neural2_B"] = 'en-IN-Neural2-B', -- Male
|
||||||
|
["en_IN_Neural2_C"] = 'en-IN-Neural2-C', -- Male
|
||||||
|
["en_IN_Neural2_D"] = 'en-IN-Neural2-D', -- Female
|
||||||
|
},
|
||||||
|
News = {
|
||||||
|
["en_GB_News_G"] = 'en-GB-News-G', -- Female
|
||||||
|
["en_GB_News_H"] = 'en-GB-News-H', -- Female
|
||||||
|
["en_GB_News_I"] = 'en-GB-News-I', -- Female
|
||||||
|
["en_GB_News_J"] = 'en-GB-News-J', -- Male
|
||||||
|
["en_GB_News_K"] = 'en-GB-News-K', -- Male
|
||||||
|
["en_GB_News_L"] = 'en-GB-News-L', -- Male
|
||||||
|
["en_GB_News_M"] = 'en-GB-News-M', -- Male
|
||||||
|
-- US
|
||||||
|
["en_US_News_K"] = 'en-US-News-K', -- Female
|
||||||
|
["en_US_News_L"] = 'en-US-News-L', -- Female
|
||||||
|
["en_US_News_N"] = 'en-US-News-N', -- Male
|
||||||
|
-- AU
|
||||||
|
["en_AU_News_E"] = 'en-AU-News-E', -- Female
|
||||||
|
["en_AU_News_F"] = 'en-AU-News-F', -- Female
|
||||||
|
["en_AU_News_G"] = 'en-AU-News-G', -- Male
|
||||||
|
},
|
||||||
|
Casual = {
|
||||||
|
["en_US_Casual_K"] = 'en-US-Casual-K', -- Male
|
||||||
|
},
|
||||||
|
Polyglot = {
|
||||||
|
["en_US_Polyglot_1"] = 'en-US-Polyglot-1', -- Male
|
||||||
|
["de_DE_Polyglot_1"] = 'de-DE-Polyglot-1', -- Male
|
||||||
|
["en_AU_Polyglot_1"] = 'en-AU-Polyglot-1', -- Male
|
||||||
|
},
|
||||||
|
Studio = {
|
||||||
|
-- Englisch (UK) - Studio
|
||||||
|
["en_GB_Studio_B"] = 'en-GB-Studio-B', -- Male
|
||||||
|
["en_GB_Studio_C"] = 'en-GB-Studio-C', -- Female
|
||||||
|
-- Englisch (USA) - Studio
|
||||||
|
["en_US_Studio_O"] = 'en-US-Studio-O', -- Female
|
||||||
|
["en_US_Studio_Q"] = 'en-US-Studio-Q', -- Male
|
||||||
|
-- DE
|
||||||
|
["de_DE_Studio_B"] = 'de-DE-Studio-B', -- Male
|
||||||
|
["de_DE_Studio_C"] = 'de-DE-Studio-C', -- Female
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,7 +770,7 @@ end
|
|||||||
-- set the path to the exe file via @{#MSRS.SetPath}.
|
-- set the path to the exe file via @{#MSRS.SetPath}.
|
||||||
--
|
--
|
||||||
-- @param #MSRS self
|
-- @param #MSRS self
|
||||||
-- @param #string Path Path to SRS directory. Default `C:\\Program Files\\DCS-SimpleRadio-Standalone`.
|
-- @param #string Path Path to SRS directory. Default `C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio`.
|
||||||
-- @param #number Frequency Radio frequency in MHz. Default 143.00 MHz. Can also be given as a #table of multiple frequencies.
|
-- @param #number Frequency Radio frequency in MHz. Default 143.00 MHz. Can also be given as a #table of multiple frequencies.
|
||||||
-- @param #number Modulation Radio modulation: 0=AM (default), 1=FM. See `radio.modulation.AM` and `radio.modulation.FM` enumerators. Can also be given as a #table of multiple modulations.
|
-- @param #number Modulation Radio modulation: 0=AM (default), 1=FM. See `radio.modulation.AM` and `radio.modulation.FM` enumerators. Can also be given as a #table of multiple modulations.
|
||||||
-- @param #string Backend Backend used: `MSRS.Backend.SRSEXE` (default) or `MSRS.Backend.GRPC`.
|
-- @param #string Backend Backend used: `MSRS.Backend.SRSEXE` (default) or `MSRS.Backend.GRPC`.
|
||||||
@ -767,13 +905,13 @@ end
|
|||||||
|
|
||||||
--- Set path to SRS install directory. More precisely, path to where the `DCS-SR-ExternalAudio.exe` is located.
|
--- Set path to SRS install directory. More precisely, path to where the `DCS-SR-ExternalAudio.exe` is located.
|
||||||
-- @param #MSRS self
|
-- @param #MSRS self
|
||||||
-- @param #string Path Path to the directory, where the sound file is located. Default is `C:\\Program Files\\DCS-SimpleRadio-Standalone`.
|
-- @param #string Path Path to the directory, where the sound file is located. Default is `C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio`.
|
||||||
-- @return #MSRS self
|
-- @return #MSRS self
|
||||||
function MSRS:SetPath(Path)
|
function MSRS:SetPath(Path)
|
||||||
self:F( {Path=Path} )
|
self:F( {Path=Path} )
|
||||||
|
|
||||||
-- Set path.
|
-- Set path.
|
||||||
self.path=Path or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
|
self.path=Path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio"
|
||||||
|
|
||||||
-- Remove (back)slashes.
|
-- Remove (back)slashes.
|
||||||
local n=1 ; local nmax=1000
|
local n=1 ; local nmax=1000
|
||||||
@ -1817,7 +1955,7 @@ end
|
|||||||
--
|
--
|
||||||
-- -- Moose MSRS default Config
|
-- -- Moose MSRS default Config
|
||||||
-- MSRS_Config = {
|
-- MSRS_Config = {
|
||||||
-- Path = "C:\\Program Files\\DCS-SimpleRadio-Standalone", -- Path to SRS install directory.
|
-- Path = "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio", -- Path to SRS install directory.
|
||||||
-- Port = 5002, -- Port of SRS server. Default 5002.
|
-- Port = 5002, -- Port of SRS server. Default 5002.
|
||||||
-- Backend = "srsexe", -- Interface to SRS: "srsexe" or "grpc".
|
-- Backend = "srsexe", -- Interface to SRS: "srsexe" or "grpc".
|
||||||
-- Frequency = {127, 243}, -- Default frequences. Must be a table 1..n entries!
|
-- Frequency = {127, 243}, -- Default frequences. Must be a table 1..n entries!
|
||||||
@ -1837,7 +1975,7 @@ end
|
|||||||
-- -- Google Cloud
|
-- -- Google Cloud
|
||||||
-- gcloud = {
|
-- gcloud = {
|
||||||
-- voice = "en-GB-Standard-A", -- The Google Cloud voice to use (see https://cloud.google.com/text-to-speech/docs/voices).
|
-- voice = "en-GB-Standard-A", -- The Google Cloud voice to use (see https://cloud.google.com/text-to-speech/docs/voices).
|
||||||
-- credentials="C:\\Program Files\\DCS-SimpleRadio-Standalone\\yourfilename.json", -- Full path to credentials JSON file (only for SRS-TTS.exe backend)
|
-- credentials="C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio\\yourfilename.json", -- Full path to credentials JSON file (only for SRS-TTS.exe backend)
|
||||||
-- key="Your access Key", -- Google API access key (only for DCS-gRPC backend)
|
-- key="Your access Key", -- Google API access key (only for DCS-gRPC backend)
|
||||||
-- },
|
-- },
|
||||||
-- -- Amazon Web Service
|
-- -- Amazon Web Service
|
||||||
@ -1905,7 +2043,7 @@ function MSRS:LoadConfigFile(Path,Filename)
|
|||||||
|
|
||||||
local Self = self or MSRS --#MSRS
|
local Self = self or MSRS --#MSRS
|
||||||
|
|
||||||
Self.path = MSRS_Config.Path or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
|
Self.path = MSRS_Config.Path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio"
|
||||||
Self.port = MSRS_Config.Port or 5002
|
Self.port = MSRS_Config.Port or 5002
|
||||||
Self.backend = MSRS_Config.Backend or MSRS.Backend.SRSEXE
|
Self.backend = MSRS_Config.Backend or MSRS.Backend.SRSEXE
|
||||||
Self.frequencies = MSRS_Config.Frequency or {127,243}
|
Self.frequencies = MSRS_Config.Frequency or {127,243}
|
||||||
|
|||||||
@ -30,6 +30,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.
|
||||||
-- The commandcenter provides the facilitites to communicate between human players online, executing a task.
|
-- The commandcenter provides the facilitites to communicate between human players online, executing a task.
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -31,6 +31,8 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
|
|
||||||
--- 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.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- The EWR will detect units, will group them, and will dispatch @{Tasking.Task}s to groups. Depending on the type of target detected, different tasks will be dispatched.
|
-- The EWR will detect units, will group them, and will dispatch @{Tasking.Task}s to groups. Depending on the type of target detected, different tasks will be dispatched.
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -34,6 +34,8 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
|
|
||||||
--- 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,
|
||||||
-- in a true co-operation environment wherein **Multiple Teams** will collaborate in Missions to **achieve a common Mission Goal**.
|
-- in a true co-operation environment wherein **Multiple Teams** will collaborate in Missions to **achieve a common Mission Goal**.
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -3,6 +3,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:
|
||||||
--
|
--
|
||||||
-- * As setup by the mission designer.
|
-- * As setup by the mission designer.
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -606,6 +606,7 @@ ENUMS.Storage = {
|
|||||||
OH58 = {}, -- Kiowa specifics
|
OH58 = {}, -- Kiowa specifics
|
||||||
UH1H = {}, -- Huey specifics
|
UH1H = {}, -- Huey specifics
|
||||||
AH64D = {}, -- Huey specifics
|
AH64D = {}, -- Huey specifics
|
||||||
|
UH60L = {}, -- Blackhawk specifics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1315,6 +1316,26 @@ ENUMS.Storage.weapons.UH1H.M134_MiniGun_Right_Door = {4,15,46,175}
|
|||||||
ENUMS.Storage.weapons.UH1H.M60_MG_Right_Door = {4,15,46,177}
|
ENUMS.Storage.weapons.UH1H.M60_MG_Right_Door = {4,15,46,177}
|
||||||
ENUMS.Storage.weapons.UH1H.M134_MiniGun_Left_Door = {4,15,46,174}
|
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}
|
||||||
|
-- UH-60L
|
||||||
|
ENUMS.Storage.weapons.UH60L.M151_HYDRA = {4, 7, 33, 147} -- 2.75" Hydra, UnGd Rkts M151, HE
|
||||||
|
ENUMS.Storage.weapons.UH60L.M156_HYDRA = {4, 7, 33, 148} -- 2.75" Hydra, UnGd Rkts M156, Wht Phos
|
||||||
|
ENUMS.Storage.weapons.UH60L.M229_HYDRA = {4, 7, 33, 148} -- 2.75" Hydra, UnGd Rkts M229, HE
|
||||||
|
ENUMS.Storage.weapons.UH60L.M257_HYDRA = {4, 7, 33, 151} -- 2.75" Hydra, UnGd Rkts M257, Para Illum
|
||||||
|
ENUMS.Storage.weapons.UH60L.M259_HYDRA = {4, 7, 33, 151} -- 2.75" Hydra, UnGd Rkts M259, Smoke Marker
|
||||||
|
ENUMS.Storage.weapons.UH60L.M274_HYDRA = {4, 7, 33, 150} -- 2.75" Hydra, UnGd Rkts M274, Practice Smk
|
||||||
|
ENUMS.Storage.weapons.UH60L.M134_DOOR_GUN = {4, 15, 46, 3031}
|
||||||
|
ENUMS.Storage.weapons.UH60L.M3M = {4, 15, 46, 2496}
|
||||||
|
ENUMS.Storage.weapons.UH60L.M3M_DOOR_GUN = {4, 15, 46, 3032}
|
||||||
|
ENUMS.Storage.weapons.UH60L.M60_DOOR_GUN = {4, 15, 46, 3033}
|
||||||
|
ENUMS.Storage.weapons.UH60L.FUEL_TANK_200 = {1,3,43,3023}
|
||||||
|
ENUMS.Storage.weapons.UH60L.FUEL_TANK_230 = {1,3,43,3024}
|
||||||
|
ENUMS.Storage.weapons.UH60L.FUEL_TANK_450 = {1,3,43,3025}
|
||||||
|
ENUMS.Storage.weapons.UH60L.FUEL_TANK_DUAL_AUX = {1,3,43,3026}
|
||||||
|
ENUMS.Storage.weapons.UH60L.CARGO_SEAT_REAR_ROW = {1,3,43,3030}
|
||||||
|
ENUMS.Storage.weapons.UH60L.CARGO_SEAT_THREE_ROWS = {1,3,43,3029}
|
||||||
|
ENUMS.Storage.weapons.UH60L.EMPTY_GUNNER_SEAT_1 = {1,3,43,3027}
|
||||||
|
ENUMS.Storage.weapons.UH60L.EMPTY_GUNNER_SEAT_2 = {1,3,43,3028}
|
||||||
|
|
||||||
-- 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,2611}
|
ENUMS.Storage.weapons.OH58.MG_M3P100 = {4,15,46,2611}
|
||||||
@ -1331,6 +1352,12 @@ ENUMS.Storage.weapons.OH58.Smk_Grenade_Yellow = {4,5,9,491}
|
|||||||
-- Apache
|
-- Apache
|
||||||
ENUMS.Storage.weapons.AH64D.AN_APG78 = {4,15,44,2114}
|
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
|
||||||
|
|||||||
@ -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
|
||||||
@ -1576,12 +1586,12 @@ function UTILS.HdgDiff(h1, h2)
|
|||||||
return math.abs(delta)
|
return math.abs(delta)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the heading from one vec3 to another vec3.
|
--- Returns the heading from one vec2/vec3 to another vec2/vec3.
|
||||||
-- @param DCS#Vec3 a From vec3.
|
-- @param DCS#Vec3 a From Vec2 or Vec3.
|
||||||
-- @param DCS#Vec3 b To vec3.
|
-- @param DCS#Vec3 b To Vec2 or Vec3.
|
||||||
-- @return #number Heading in degrees.
|
-- @return #number Heading in degrees.
|
||||||
function UTILS.HdgTo(a, b)
|
function UTILS.HdgTo(a, b)
|
||||||
local dz=b.z-a.z
|
local dz=(b.z or b.y) - (a.z or a.y)
|
||||||
local dx=b.x-a.x
|
local dx=b.x-a.x
|
||||||
local heading=math.deg(math.atan2(dz, dx))
|
local heading=math.deg(math.atan2(dz, dx))
|
||||||
if heading < 0 then
|
if heading < 0 then
|
||||||
@ -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
|
||||||
@ -1900,6 +1914,13 @@ 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)
|
||||||
if string.find(typename,svalue,1,true) then
|
if string.find(typename,svalue,1,true) then
|
||||||
@ -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
|
||||||
@ -2305,6 +2330,16 @@ function UTILS.IsLoadingDoorOpen( unit_name )
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if type_name == "UH-60L_DAP" and (unit:getDrawArgumentValue(401) == 1 or unit:getDrawArgumentValue(402) == 1) then
|
||||||
|
BASE:T(unit_name .. " cargo door is open")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if type_name == "UH-60L_DAP" and (unit:getDrawArgumentValue(38) > 0 or unit:getDrawArgumentValue(400) == 1 ) then
|
||||||
|
BASE:T(unit_name .. " front door(s) are open")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
if type_name == "AH-64D_BLK_II" then
|
if type_name == "AH-64D_BLK_II" then
|
||||||
BASE:T(unit_name .. " front door(s) are open")
|
BASE:T(unit_name .. " front door(s) are open")
|
||||||
return true -- no doors on this one ;)
|
return true -- no doors on this one ;)
|
||||||
@ -2330,7 +2365,11 @@ function UTILS.IsLoadingDoorOpen( unit_name )
|
|||||||
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
|
||||||
|
|
||||||
@ -4098,6 +4137,45 @@ function UTILS.LCGRandom()
|
|||||||
return UTILS.lcg.seed / UTILS.lcg.m
|
return UTILS.lcg.seed / UTILS.lcg.m
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Create a table of grid-points for n points.
|
||||||
|
-- @param #number startVec2 Starting DCS#Vec2 map coordinate, e.g. `{x=63598575,y=-63598575}`
|
||||||
|
-- @param #number n Number of points to generate.
|
||||||
|
-- @param #number spacingX Horizonzal spacing (meters).
|
||||||
|
-- @param #number spacingY Vertical spacing (meters).
|
||||||
|
-- @return #table Grid Table of DCS#Vec2 entries.
|
||||||
|
function UTILS.GenerateGridPoints(startVec2, n, spacingX, spacingY)
|
||||||
|
local points = {}
|
||||||
|
local gridSize = math.ceil(math.sqrt(n))
|
||||||
|
local count = 0
|
||||||
|
local n = n or 1
|
||||||
|
local spacingX = spacingX or 100
|
||||||
|
local spacingY = spacingY or 100
|
||||||
|
local startX = startVec2.x or 100
|
||||||
|
local startY = startVec2.y or 100
|
||||||
|
|
||||||
|
for row = 0, gridSize - 1 do
|
||||||
|
for col = 0, gridSize - 1 do
|
||||||
|
if count >= n then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
local point = {
|
||||||
|
x = startX + (col * spacingX),
|
||||||
|
y = startY + (row * spacingY)
|
||||||
|
}
|
||||||
|
|
||||||
|
table.insert(points, point)
|
||||||
|
count = count + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if count >= n then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return points
|
||||||
|
end
|
||||||
|
|
||||||
--- Spawns a new FARP of a defined type and coalition and functional statics (fuel depot, ammo storage, tent, windsock) around that FARP to make it operational.
|
--- Spawns a new FARP of a defined type and coalition and functional statics (fuel depot, ammo storage, tent, windsock) around that FARP to make it operational.
|
||||||
-- Adds vehicles from template if given. Fills the FARP warehouse with liquids and known materiels.
|
-- Adds vehicles from template if given. Fills the FARP warehouse with liquids and known materiels.
|
||||||
-- References: [DCS Forum Topic](https://forum.dcs.world/topic/282989-farp-equipment-to-run-it)
|
-- References: [DCS Forum Topic](https://forum.dcs.world/topic/282989-farp-equipment-to-run-it)
|
||||||
@ -4114,9 +4192,42 @@ end
|
|||||||
-- @param #string VehicleTemplate, template name for additional vehicles. Can be nil for no additional vehicles.
|
-- @param #string VehicleTemplate, template name for additional vehicles. Can be nil for no additional vehicles.
|
||||||
-- @param #number Liquids Tons of fuel to be added initially to the FARP. Defaults to 10 (tons). Set to 0 for no fill.
|
-- @param #number Liquids Tons of fuel to be added initially to the FARP. Defaults to 10 (tons). Set to 0 for no fill.
|
||||||
-- @param #number Equipment Number of equipment items per known item to be added initially to the FARP. Defaults to 10 (items). Set to 0 for no fill.
|
-- @param #number Equipment Number of equipment items per known item to be added initially to the FARP. Defaults to 10 (items). Set to 0 for no fill.
|
||||||
|
-- @param #number Airframes Number of helicopter airframes per known type in Ops.CSAR#CSAR.AircraftType to be added initially to the FARP. Set to 0 for no airframes.
|
||||||
|
-- @param #string F10Text Text to display on F10 map if given. Handy to post things like the ADF beacon Frequency, Callsign and ATC Frequency.
|
||||||
|
-- @param #boolean DynamicSpawns If true, allow Dynamic Spawns from this FARP.
|
||||||
|
-- @param #boolean HotStart If true and DynamicSpawns is true, allow hot starts for Dynamic Spawns from this FARP.
|
||||||
|
-- @param #number NumberPads If given, spawn this number of pads.
|
||||||
|
-- @param #number SpacingX For NumberPads > 1, space this many meters horizontally. Defaults to 100.
|
||||||
|
-- @param #number SpacingY For NumberPads > 1, space this many meters vertically. Defaults to 100.
|
||||||
-- @return #list<Wrapper.Static#STATIC> Table of spawned objects and vehicle object (if given).
|
-- @return #list<Wrapper.Static#STATIC> Table of spawned objects and vehicle object (if given).
|
||||||
-- @return #string ADFBeaconName Name of the ADF beacon, to be able to remove/stop it later.
|
-- @return #string ADFBeaconName Name of the ADF beacon, to be able to remove/stop it later.
|
||||||
function UTILS.SpawnFARPAndFunctionalStatics(Name,Coordinate,FARPType,Coalition,Country,CallSign,Frequency,Modulation,ADF,SpawnRadius,VehicleTemplate,Liquids,Equipment)
|
-- @return #number MarkerID ID of the F10 Text, to be able to remove it later.
|
||||||
|
function UTILS.SpawnFARPAndFunctionalStatics(Name,Coordinate,FARPType,Coalition,Country,CallSign,Frequency,Modulation,ADF,SpawnRadius,VehicleTemplate,Liquids,Equipment,Airframes,F10Text,DynamicSpawns,HotStart,NumberPads,SpacingX,SpacingY)
|
||||||
|
|
||||||
|
local function PopulateStorage(Name,liquids,equip,airframes)
|
||||||
|
local newWH = STORAGE:New(Name)
|
||||||
|
if liquids and liquids > 0 then
|
||||||
|
-- Storage fill-up
|
||||||
|
newWH:SetLiquid(STORAGE.Liquid.DIESEL,liquids) -- kgs to tons
|
||||||
|
newWH:SetLiquid(STORAGE.Liquid.GASOLINE,liquids)
|
||||||
|
newWH:SetLiquid(STORAGE.Liquid.JETFUEL,liquids)
|
||||||
|
newWH:SetLiquid(STORAGE.Liquid.MW50,liquids)
|
||||||
|
end
|
||||||
|
|
||||||
|
if equip and equip > 0 then
|
||||||
|
for cat,nitem in pairs(ENUMS.Storage.weapons) do
|
||||||
|
for name,item in pairs(nitem) do
|
||||||
|
newWH:SetItem(item,equip)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if airframes and airframes > 0 then
|
||||||
|
for typename in pairs (CSAR.AircraftType) do
|
||||||
|
newWH:SetItem(typename,airframes)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Set Defaults
|
-- Set Defaults
|
||||||
local farplocation = Coordinate
|
local farplocation = Coordinate
|
||||||
@ -4130,18 +4241,81 @@ function UTILS.SpawnFARPAndFunctionalStatics(Name,Coordinate,FARPType,Coalition,
|
|||||||
local liquids = Liquids or 10
|
local liquids = Liquids or 10
|
||||||
liquids = liquids * 1000 -- tons to kg
|
liquids = liquids * 1000 -- tons to kg
|
||||||
local equip = Equipment or 10
|
local equip = Equipment or 10
|
||||||
|
local airframes = Airframes or 10
|
||||||
local statictypes = ENUMS.FARPObjectTypeNamesAndShape[farptype] or {TypeName="FARP", ShapeName="FARPS"}
|
local statictypes = ENUMS.FARPObjectTypeNamesAndShape[farptype] or {TypeName="FARP", ShapeName="FARPS"}
|
||||||
local STypeName = statictypes.TypeName
|
local STypeName = statictypes.TypeName
|
||||||
local SShapeName = statictypes.ShapeName
|
local SShapeName = statictypes.ShapeName
|
||||||
local Country = Country or (Coalition == coalition.side.BLUE and country.id.USA or country.id.RUSSIA)
|
local Country = Country or (Coalition == coalition.side.BLUE and country.id.USA or country.id.RUSSIA)
|
||||||
local ReturnObjects = {}
|
local ReturnObjects = {}
|
||||||
|
|
||||||
|
-- many FARPs
|
||||||
|
local NumberPads = NumberPads or 1
|
||||||
|
local SpacingX = SpacingX or 100
|
||||||
|
local SpacingY = SpacingY or 100
|
||||||
|
local FarpVec2 = Coordinate:GetVec2()
|
||||||
|
|
||||||
|
if NumberPads > 1 then
|
||||||
|
local Grid = UTILS.GenerateGridPoints(FarpVec2, NumberPads, SpacingX, SpacingY)
|
||||||
|
local groupData = {
|
||||||
|
["visible"] = true,
|
||||||
|
["hidden"] = false,
|
||||||
|
["units"] = {},
|
||||||
|
["y"] = 0, -- Group center latitude
|
||||||
|
["x"] = 0, -- Group center longitude
|
||||||
|
["name"] = Name,
|
||||||
|
}
|
||||||
|
local unitData = {
|
||||||
|
["category"] = "Heliports",
|
||||||
|
["type"] = STypeName, -- FARP type
|
||||||
|
["y"] = 0, -- Latitude coordinate (meters)
|
||||||
|
["x"] = 0, -- Longitude coordinate (meters)
|
||||||
|
["name"] = Name,
|
||||||
|
["heading"] = 0, -- Heading in radians
|
||||||
|
["heliport_modulation"] = mod, -- 0 = AM, 1 = FM
|
||||||
|
["heliport_frequency"] = freq, -- Radio frequency in MHz
|
||||||
|
["heliport_callsign_id"] = callsign, -- Callsign ID
|
||||||
|
["dead"] = false,
|
||||||
|
["shape_name"] = SShapeName,
|
||||||
|
["dynamicSpawn"] = DynamicSpawns,
|
||||||
|
["allowHotStart"] = HotStart,
|
||||||
|
}
|
||||||
|
for id,gridpoint in ipairs(Grid) do
|
||||||
|
-- Spawn FARP
|
||||||
|
local UnitTemplate = UTILS.DeepCopy(unitData)
|
||||||
|
UnitTemplate.x = gridpoint.x
|
||||||
|
UnitTemplate.y = gridpoint.y
|
||||||
|
if id > 1 then UnitTemplate.name = Name.."-"..id end
|
||||||
|
table.insert(groupData.units,UnitTemplate)
|
||||||
|
if id==1 then
|
||||||
|
groupData.x = gridpoint.x
|
||||||
|
groupData.y = gridpoint.y
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--BASE:I("Spawning FARP")
|
||||||
|
--UTILS.PrintTableToLog(groupData,1)
|
||||||
|
local Static=coalition.addGroup(Country, -1, groupData)
|
||||||
|
-- Currently DCS >= 2.8 does not trigger birth events if FARPS are spawned!
|
||||||
|
-- We create such an event. The airbase is registered in Core.Event
|
||||||
|
local Event = {
|
||||||
|
id = EVENTS.Birth,
|
||||||
|
time = timer.getTime(),
|
||||||
|
initiator = Static
|
||||||
|
}
|
||||||
|
-- Create BIRTH event.
|
||||||
|
world.onEvent(Event)
|
||||||
|
|
||||||
|
PopulateStorage(Name.."-1",liquids,equip,airframes)
|
||||||
|
else
|
||||||
-- Spawn FARP
|
-- Spawn FARP
|
||||||
local newfarp = SPAWNSTATIC:NewFromType(STypeName,"Heliports",Country) -- "Invisible FARP" "FARP"
|
local newfarp = SPAWNSTATIC:NewFromType(STypeName,"Heliports",Country) -- "Invisible FARP" "FARP"
|
||||||
newfarp:InitShape(SShapeName) -- "invisiblefarp" "FARPS"
|
newfarp:InitShape(SShapeName) -- "invisiblefarp" "FARPS"
|
||||||
newfarp:InitFARP(callsign,freq,mod)
|
newfarp:InitFARP(callsign,freq,mod,DynamicSpawns,HotStart)
|
||||||
local spawnedfarp = newfarp:SpawnFromCoordinate(farplocation,0,Name)
|
local spawnedfarp = newfarp:SpawnFromCoordinate(farplocation,0,Name)
|
||||||
table.insert(ReturnObjects,spawnedfarp)
|
table.insert(ReturnObjects,spawnedfarp)
|
||||||
|
|
||||||
|
PopulateStorage(Name,liquids,equip,airframes)
|
||||||
|
end
|
||||||
|
|
||||||
-- Spawn Objects
|
-- Spawn Objects
|
||||||
local FARPStaticObjectsNato = {
|
local FARPStaticObjectsNato = {
|
||||||
["FUEL"] = { TypeName = "FARP Fuel Depot", ShapeName = "GSM Rus", Category = "Fortifications"},
|
["FUEL"] = { TypeName = "FARP Fuel Depot", ShapeName = "GSM Rus", Category = "Fortifications"},
|
||||||
@ -4175,23 +4349,6 @@ function UTILS.SpawnFARPAndFunctionalStatics(Name,Coordinate,FARPType,Coalition,
|
|||||||
table.insert(ReturnObjects,spawnedvehicle)
|
table.insert(ReturnObjects,spawnedvehicle)
|
||||||
end
|
end
|
||||||
|
|
||||||
local newWH = STORAGE:New(Name)
|
|
||||||
if liquids and liquids > 0 then
|
|
||||||
-- Storage fill-up
|
|
||||||
newWH:SetLiquid(STORAGE.Liquid.DIESEL,liquids) -- kgs to tons
|
|
||||||
newWH:SetLiquid(STORAGE.Liquid.GASOLINE,liquids)
|
|
||||||
newWH:SetLiquid(STORAGE.Liquid.JETFUEL,liquids)
|
|
||||||
newWH:SetLiquid(STORAGE.Liquid.MW50,liquids)
|
|
||||||
end
|
|
||||||
|
|
||||||
if equip and equip > 0 then
|
|
||||||
for cat,nitem in pairs(ENUMS.Storage.weapons) do
|
|
||||||
for name,item in pairs(nitem) do
|
|
||||||
newWH:SetItem(item,equip)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local ADFName
|
local ADFName
|
||||||
if ADF and type(ADF) == "number" then
|
if ADF and type(ADF) == "number" then
|
||||||
local ADFFreq = ADF*1000 -- KHz to Hz
|
local ADFFreq = ADF*1000 -- KHz to Hz
|
||||||
@ -4202,7 +4359,150 @@ function UTILS.SpawnFARPAndFunctionalStatics(Name,Coordinate,FARPType,Coalition,
|
|||||||
trigger.action.radioTransmission(Sound, vec3, 0, true, ADFFreq, 250, ADFName)
|
trigger.action.radioTransmission(Sound, vec3, 0, true, ADFFreq, 250, ADFName)
|
||||||
end
|
end
|
||||||
|
|
||||||
return ReturnObjects, ADFName
|
local MarkerID = nil
|
||||||
|
if F10Text then
|
||||||
|
local Color = {0,0,1}
|
||||||
|
if Coalition == coalition.side.RED then
|
||||||
|
Color = {1,0,0}
|
||||||
|
elseif Coalition == coalition.side.NEUTRAL then
|
||||||
|
Color = {0,1,0}
|
||||||
|
end
|
||||||
|
local Alpha = 0.75
|
||||||
|
local coordinate = Coordinate:Translate(600,0)
|
||||||
|
MarkerID = coordinate:TextToAll(F10Text,Coalition,Color,1,{1,1,1},Alpha,14,true)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ReturnObjects, ADFName, MarkerID
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Spawn a MASH at a given coordinate, optionally, add an ADF Beacon.
|
||||||
|
-- @param #string Name Unique Name of the Mash.
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate Coordinate where to spawn the MASH. Can be given as a Core.Zone#ZONE object, in this case we take the center coordinate.
|
||||||
|
-- @param #number Country Country ID the MASH belongs to, e.g. country.id.USA or country.id.RUSSIA.
|
||||||
|
-- @param #number ADF (Optional) ADF Frequency in kHz (Kilohertz), if given activate an ADF Beacon at the location of the MASH.
|
||||||
|
-- @param #string Livery (Optional) The livery of the static CH-47, defaults to dark green.
|
||||||
|
-- @param #boolean DeployHelo (Optional) If true, deploy the helicopter static.
|
||||||
|
-- @param #number MASHRadio MASH Radio Frequency, defaults to 127.5.
|
||||||
|
-- @param #number MASHRadioModulation MASH Radio Modulation, defaults to radio.modulation.AM.
|
||||||
|
-- @param #number MASHCallsign Defaults to CALLSIGN.FARP.Berlin.
|
||||||
|
-- @param #table Templates (Optional) You can hand in your own template table of numbered(!) entries. Each entry consist of a relative(!) x,y position and data of a
|
||||||
|
-- static, shape_name is optional. Also, livery_id is optional, but is applied to the helicopter static only.
|
||||||
|
-- @return #table Table of Wrapper.Static#STATIC objects that were spawned.
|
||||||
|
-- @return #string ADFName Name of the ADF Beacon to remove it later.
|
||||||
|
-- @usage
|
||||||
|
-- -- MASH Template example, this one is the built in one used in the function:
|
||||||
|
-- MASHTemplates = {
|
||||||
|
-- [1]={category='Infantry',type='Soldier M4',shape_name='none',heading=0,x=0.000000,y=0.000000,},
|
||||||
|
-- [2]={category='Infantry',type='Soldier M4',shape_name='none',heading=0,x=0.313533,y=8.778935,},
|
||||||
|
-- [3]={category='Infantry',type='Soldier M4',shape_name='none',heading=0,x=16.303737,y=20.379671,},
|
||||||
|
-- [4]={category='Helicopters',type='CH-47Fbl1',shape_name='none',heading=0,x=-20.047735,y=-63.166179,livery_id = "us army dark green",},
|
||||||
|
-- [5]={category='Infantry',type='Soldier M4',shape_name='none',heading=0,x=26.650339,y=20.066138,},
|
||||||
|
-- [6]={category='Heliports',type='FARP_SINGLE_01',shape_name='FARP_SINGLE_01',heading=0,x=-25.432292,y=9.077099,},
|
||||||
|
-- [7]={category='Heliports',type='FARP_SINGLE_01',shape_name='FARP_SINGLE_01',heading=0,x=-12.717421,y=-3.216114,},
|
||||||
|
-- [8]={category='Heliports',type='FARP_SINGLE_01',shape_name='FARP_SINGLE_01',heading=0,x=-25.439281,y=-3.216114,},
|
||||||
|
-- [9]={category='Heliports',type='FARP_SINGLE_01',shape_name='FARP_SINGLE_01',heading=0,x=-12.717421,y=9.155603,},
|
||||||
|
-- [10]={category='Fortifications',type='TACAN_beacon',shape_name='none',heading=0,x=-2.329847,y=-16.579903,},
|
||||||
|
-- [11]={category='Fortifications',type='FARP Fuel Depot',shape_name='GSM Rus',heading=0,x=2.222011,y=4.487030,},
|
||||||
|
-- [12]={category='Fortifications',type='APFC fuel',shape_name='M92_APFCfuel',heading=0,x=3.614927,y=0.367838,},
|
||||||
|
-- [13]={category='Fortifications',type='Camouflage03',shape_name='M92_Camouflage03',heading=0,x=21.544148,y=21.998879,},
|
||||||
|
-- [14]={category='Fortifications',type='Container_generator',shape_name='M92_Container_generator',heading=0,x=20.989192,y=37.314334,},
|
||||||
|
-- [15]={category='Fortifications',type='FireExtinguisher02',shape_name='M92_FireExtinguisher02',heading=0,x=3.988003,y=8.362333,},
|
||||||
|
-- [16]={category='Fortifications',type='FireExtinguisher02',shape_name='M92_FireExtinguisher02',heading=0,x=-3.953195,y=12.945844,},
|
||||||
|
-- [17]={category='Fortifications',type='Windsock',shape_name='H-Windsock_RW',heading=0,x=-18.944173,y=-33.042196,},
|
||||||
|
-- [18]={category='Fortifications',type='Tent04',shape_name='M92_Tent04',heading=0,x=21.220671,y=30.247529,},
|
||||||
|
-- }
|
||||||
|
--
|
||||||
|
function UTILS.SpawnMASHStatics(Name,Coordinate,Country,ADF,Livery,DeployHelo,MASHRadio,MASHRadioModulation,MASHCallsign,Templates)
|
||||||
|
|
||||||
|
-- Basic objects table
|
||||||
|
|
||||||
|
local MASHTemplates = {
|
||||||
|
[1]={category='Infantry',type='Soldier M4',shape_name='none',heading=0,x=0.000000,y=0.000000,},
|
||||||
|
[2]={category='Infantry',type='Soldier M4',shape_name='none',heading=0,x=0.313533,y=8.778935,},
|
||||||
|
[3]={category='Infantry',type='Soldier M4',shape_name='none',heading=0,x=16.303737,y=20.379671,},
|
||||||
|
[4]={category='Helicopters',type='CH-47Fbl1',shape_name='none',heading=0,x=-20.047735,y=-63.166179,livery_id = "us army dark green",},
|
||||||
|
[5]={category='Infantry',type='Soldier M4',shape_name='none',heading=0,x=26.650339,y=20.066138,},
|
||||||
|
[6]={category='Heliports',type='FARP_SINGLE_01',shape_name='FARP_SINGLE_01',heading=0,x=-25.432292,y=9.077099,},
|
||||||
|
[7]={category='Heliports',type='FARP_SINGLE_01',shape_name='FARP_SINGLE_01',heading=0,x=-12.717421,y=-3.216114,},
|
||||||
|
[8]={category='Heliports',type='FARP_SINGLE_01',shape_name='FARP_SINGLE_01',heading=0,x=-25.439281,y=-3.216114,},
|
||||||
|
[9]={category='Heliports',type='FARP_SINGLE_01',shape_name='FARP_SINGLE_01',heading=0,x=-12.717421,y=9.155603,},
|
||||||
|
[10]={category='Fortifications',type='TACAN_beacon',shape_name='none',heading=0,x=-2.329847,y=-16.579903,},
|
||||||
|
[11]={category='Fortifications',type='FARP Fuel Depot',shape_name='GSM Rus',heading=0,x=2.222011,y=4.487030,},
|
||||||
|
[12]={category='Fortifications',type='APFC fuel',shape_name='M92_APFCfuel',heading=0,x=3.614927,y=0.367838,},
|
||||||
|
[13]={category='Fortifications',type='Camouflage03',shape_name='M92_Camouflage03',heading=0,x=21.544148,y=21.998879,},
|
||||||
|
[14]={category='Fortifications',type='Container_generator',shape_name='M92_Container_generator',heading=0,x=20.989192,y=37.314334,},
|
||||||
|
[15]={category='Fortifications',type='FireExtinguisher02',shape_name='M92_FireExtinguisher02',heading=0,x=3.988003,y=8.362333,},
|
||||||
|
[16]={category='Fortifications',type='FireExtinguisher02',shape_name='M92_FireExtinguisher02',heading=0,x=-3.953195,y=12.945844,},
|
||||||
|
[17]={category='Fortifications',type='Windsock',shape_name='H-Windsock_RW',heading=0,x=-18.944173,y=-33.042196,},
|
||||||
|
[18]={category='Fortifications',type='Tent04',shape_name='M92_Tent04',heading=0,x=21.220671,y=30.247529,},
|
||||||
|
}
|
||||||
|
|
||||||
|
if Templates then MASHTemplates=Templates end
|
||||||
|
|
||||||
|
-- locals
|
||||||
|
local name = Name or "Florence Nightingale"
|
||||||
|
local positionVec2
|
||||||
|
local positionVec3
|
||||||
|
local ReturnStatics = {}
|
||||||
|
local CountryID = Country or country.id.USA
|
||||||
|
local livery = "us army dark green"
|
||||||
|
local MASHRadio = MASHRadio or 127.5
|
||||||
|
local MASHRadioModulation = MASHRadioModulation or radio.modulation.AM
|
||||||
|
local MASHCallsign = MASHCallsign or CALLSIGN.FARP.Berlin
|
||||||
|
|
||||||
|
-- check for coordinate or zone
|
||||||
|
if type(Coordinate) == "table" then
|
||||||
|
if Coordinate:IsInstanceOf("COORDINATE") or Coordinate:IsInstanceOf("ZONE_BASE") then
|
||||||
|
positionVec2 = Coordinate:GetVec2()
|
||||||
|
positionVec3 = Coordinate:GetVec3()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
BASE:E("Spawn MASH - no ZONE or COORDINATE handed!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- position
|
||||||
|
local BaseX = positionVec2.x
|
||||||
|
local BaseY = positionVec2.y
|
||||||
|
|
||||||
|
-- Statics
|
||||||
|
for id,object in pairs(MASHTemplates) do
|
||||||
|
local NewName = string.format("%s#%3d",name,id)
|
||||||
|
local vec2 = {x=BaseX+object.x,y=BaseY+object.y}
|
||||||
|
local Coordinate=COORDINATE:NewFromVec2(vec2)
|
||||||
|
local static = SPAWNSTATIC:NewFromType(object.type,object.category,CountryID)
|
||||||
|
if object.shape_name and object.shape_name ~= "none" then
|
||||||
|
static:InitShape(object.shape_name)
|
||||||
|
end
|
||||||
|
if object.category == "Helicopters" and DeployHelo == true then
|
||||||
|
if object.livery_id ~= nil then
|
||||||
|
livery = object.livery_id
|
||||||
|
end
|
||||||
|
static:InitLivery(livery)
|
||||||
|
local newstatic = static:SpawnFromCoordinate(Coordinate,object.heading,NewName)
|
||||||
|
table.insert(ReturnStatics,newstatic)
|
||||||
|
elseif object.category == "Heliports" then
|
||||||
|
static:InitFARP(MASHCallsign,MASHRadio,MASHRadioModulation,false,false)
|
||||||
|
local newstatic = static:SpawnFromCoordinate(Coordinate,object.heading,NewName)
|
||||||
|
table.insert(ReturnStatics,newstatic)
|
||||||
|
elseif object.category ~= "Helicopters" and object.category ~= "Heliports" then
|
||||||
|
local newstatic = static:SpawnFromCoordinate(Coordinate,object.heading,NewName)
|
||||||
|
table.insert(ReturnStatics,newstatic)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Beacon
|
||||||
|
local ADFName
|
||||||
|
if ADF and type(ADF) == "number" then
|
||||||
|
local ADFFreq = ADF*1000 -- KHz to Hz
|
||||||
|
local Sound = "l10n/DEFAULT/beacon.ogg"
|
||||||
|
ADFName = Name .. " ADF "..tostring(ADF).."KHz"
|
||||||
|
--BASE:I(string.format("Adding MASH Beacon %d KHz Name %s",ADF,ADFName))
|
||||||
|
trigger.action.radioTransmission(Sound, positionVec3, 0, true, ADFFreq, 250, ADFName)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ReturnStatics, ADFName
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Converts a Vec2 to a Vec3.
|
--- Converts a Vec2 to a Vec3.
|
||||||
@ -4399,3 +4699,449 @@ end
|
|||||||
function UTILS.Weather.StopFogAnimation()
|
function UTILS.Weather.StopFogAnimation()
|
||||||
return world.weather.setFogAnimation({})
|
return world.weather.setFogAnimation({})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Find a ME created zone by its name
|
||||||
|
function UTILS.GetEnvZone(name)
|
||||||
|
for _,v in ipairs(env.mission.triggers.zones) do
|
||||||
|
if v.name == name then
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- net.dostring_in
|
||||||
|
function UTILS.DoStringIn(State,DoString)
|
||||||
|
return net.dostring_in(State,DoString)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show a picture on the screen to all
|
||||||
|
-- @param #string FileName File name of the picture
|
||||||
|
-- @param #number Duration Duration in seconds, defaults to 10
|
||||||
|
-- @param #boolean ClearView If true, clears the view before showing the picture, defaults to false
|
||||||
|
-- @param #number StartDelay Delay in seconds before showing the picture, defaults to 0
|
||||||
|
-- @param #number HorizontalAlign Horizontal alignment of the picture, 0: Left, 1: Center, 2: Right
|
||||||
|
-- @param #number VerticalAlign Vertical alignment of the picture, 0: Top, 1: Center, 2: Bottom
|
||||||
|
-- @param #number Size Size of the picture in percent, defaults to 100
|
||||||
|
-- @param #number SizeUnits Size units, 0 for % of original picture size, and 1 for % of window size
|
||||||
|
function UTILS.ShowPictureToAll(FilePath, Duration, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits)
|
||||||
|
ClearView = ClearView or false
|
||||||
|
StartDelay = StartDelay or 0
|
||||||
|
HorizontalAlign = HorizontalAlign or 1
|
||||||
|
VerticalAlign = VerticalAlign or 1
|
||||||
|
Size = Size or 100
|
||||||
|
SizeUnits = SizeUnits or 0
|
||||||
|
|
||||||
|
if ClearView then ClearView = "true" else ClearView = "false" end
|
||||||
|
|
||||||
|
net.dostring_in("mission", string.format("a_out_picture(\"%s\", %d, %s, %d, \"%d\", \"%d\", %d, \"%d\")", FilePath, Duration or 10, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show a picture on the screen to Coalition
|
||||||
|
-- @param #number Coalition Coalition ID, can be coalition.side.BLUE, coalition.side.RED or coalition.side.NEUTRAL
|
||||||
|
-- @param #string FileName File name of the picture
|
||||||
|
-- @param #number Duration Duration in seconds, defaults to 10
|
||||||
|
-- @param #boolean ClearView If true, clears the view before showing the picture, defaults to false
|
||||||
|
-- @param #number StartDelay Delay in seconds before showing the picture, defaults to 0
|
||||||
|
-- @param #number HorizontalAlign Horizontal alignment of the picture, 0: Left, 1: Center, 2: Right
|
||||||
|
-- @param #number VerticalAlign Vertical alignment of the picture, 0: Top, 1: Center, 2: Bottom
|
||||||
|
-- @param #number Size Size of the picture in percent, defaults to 100
|
||||||
|
-- @param #number SizeUnits Size units, 0 for % of original picture size, and 1 for % of window size
|
||||||
|
function UTILS.ShowPictureToCoalition(Coalition, FilePath, Duration, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits)
|
||||||
|
ClearView = ClearView or false
|
||||||
|
StartDelay = StartDelay or 0
|
||||||
|
HorizontalAlign = HorizontalAlign or 1
|
||||||
|
VerticalAlign = VerticalAlign or 1
|
||||||
|
Size = Size or 100
|
||||||
|
SizeUnits = SizeUnits or 0
|
||||||
|
|
||||||
|
if ClearView then ClearView = "true" else ClearView = "false" end
|
||||||
|
|
||||||
|
local coalName = string.lower(UTILS.GetCoalitionName(Coalition))
|
||||||
|
|
||||||
|
net.dostring_in("mission", string.format("a_out_picture_s(\"%s\", \"%s\", %d, %s, %d, \"%d\", \"%d\", %d, \"%d\")", coalName, FilePath, Duration or 10, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show a picture on the screen to Country
|
||||||
|
-- @param #number Country Country ID, can be country.id.USA, country.id.RUSSIA, etc.
|
||||||
|
-- @param #string FileName File name of the picture
|
||||||
|
-- @param #number Duration Duration in seconds, defaults to 10
|
||||||
|
-- @param #boolean ClearView If true, clears the view before showing the picture, defaults to false
|
||||||
|
-- @param #number StartDelay Delay in seconds before showing the picture, defaults to 0
|
||||||
|
-- @param #number HorizontalAlign Horizontal alignment of the picture, 0: Left, 1: Center, 2: Right
|
||||||
|
-- @param #number VerticalAlign Vertical alignment of the picture, 0: Top, 1: Center, 2: Bottom
|
||||||
|
-- @param #number Size Size of the picture in percent, defaults to 100
|
||||||
|
-- @param #number SizeUnits Size units, 0 for % of original picture size, and 1 for % of window size
|
||||||
|
function UTILS.ShowPictureToCountry(Country, FilePath, Duration, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits)
|
||||||
|
ClearView = ClearView or false
|
||||||
|
StartDelay = StartDelay or 0
|
||||||
|
HorizontalAlign = HorizontalAlign or 1
|
||||||
|
VerticalAlign = VerticalAlign or 1
|
||||||
|
Size = Size or 100
|
||||||
|
SizeUnits = SizeUnits or 0
|
||||||
|
|
||||||
|
if ClearView then ClearView = "true" else ClearView = "false" end
|
||||||
|
|
||||||
|
net.dostring_in("mission", string.format("a_out_picture_c(%d, \"%s\", %d, %s, %d, \"%d\", \"%d\", %d, \"%d\")", Country, FilePath, Duration or 10, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show a picture on the screen to Group
|
||||||
|
-- @param Wrapper.Group#GROUP Group Group to show the picture to
|
||||||
|
-- @param #string FileName File name of the picture
|
||||||
|
-- @param #number Duration Duration in seconds, defaults to 10
|
||||||
|
-- @param #boolean ClearView If true, clears the view before showing the picture, defaults to false
|
||||||
|
-- @param #number StartDelay Delay in seconds before showing the picture, defaults to 0
|
||||||
|
-- @param #number HorizontalAlign Horizontal alignment of the picture, 0: Left, 1: Center, 2: Right
|
||||||
|
-- @param #number VerticalAlign Vertical alignment of the picture, 0: Top, 1: Center, 2: Bottom
|
||||||
|
-- @param #number Size Size of the picture in percent, defaults to 100
|
||||||
|
-- @param #number SizeUnits Size units, 0 for % of original picture size, and 1 for % of window size
|
||||||
|
function UTILS.ShowPictureToGroup(Group, FilePath, Duration, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits)
|
||||||
|
ClearView = ClearView or false
|
||||||
|
StartDelay = StartDelay or 0
|
||||||
|
HorizontalAlign = HorizontalAlign or 1
|
||||||
|
VerticalAlign = VerticalAlign or 1
|
||||||
|
Size = Size or 100
|
||||||
|
SizeUnits = SizeUnits or 0
|
||||||
|
|
||||||
|
if ClearView then ClearView = "true" else ClearView = "false" end
|
||||||
|
|
||||||
|
net.dostring_in("mission", string.format("a_out_picture_g(%d, \"%s\", %d, %s, %d, \"%d\", \"%d\", %d, \"%d\")", Group:GetID(), FilePath, Duration or 10, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show a picture on the screen to Unit
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit Unit to show the picture to
|
||||||
|
-- @param #string FileName File name of the picture
|
||||||
|
-- @param #number Duration Duration in seconds, defaults to 10
|
||||||
|
-- @param #boolean ClearView If true, clears the view before showing the picture, defaults to false
|
||||||
|
-- @param #number StartDelay Delay in seconds before showing the picture, defaults to 0
|
||||||
|
-- @param #number HorizontalAlign Horizontal alignment of the picture, 0: Left, 1: Center, 2: Right
|
||||||
|
-- @param #number VerticalAlign Vertical alignment of the picture, 0: Top, 1: Center, 2: Bottom
|
||||||
|
-- @param #number Size Size of the picture in percent, defaults to 100
|
||||||
|
-- @param #number SizeUnits Size units, 0 for % of original picture size, and 1 for % of window size
|
||||||
|
function UTILS.ShowPictureToUnit(Unit, FilePath, Duration, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits)
|
||||||
|
ClearView = ClearView or false
|
||||||
|
StartDelay = StartDelay or 0
|
||||||
|
HorizontalAlign = HorizontalAlign or 1
|
||||||
|
VerticalAlign = VerticalAlign or 1
|
||||||
|
Size = Size or 100
|
||||||
|
SizeUnits = SizeUnits or 0
|
||||||
|
|
||||||
|
if ClearView then ClearView = "true" else ClearView = "false" end
|
||||||
|
|
||||||
|
net.dostring_in("mission", string.format("a_out_picture_u(%d, \"%s\", %d, %s, %d, \"%d\", \"%d\", %d, \"%d\")", Unit:GetID(), FilePath, Duration or 10, ClearView, StartDelay, HorizontalAlign, VerticalAlign, Size, SizeUnits))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Load a mission file. This will replace the current mission with the one given carrying along the online clients.
|
||||||
|
-- @param #string FileName Mission filename
|
||||||
|
function UTILS.LoadMission(FileName)
|
||||||
|
net.dostring_in("mission", string.format("a_load_mission(\"%s\")", FileName))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the mission briefing for a coalition.
|
||||||
|
-- @param #number Coalition Briefing coalition ID, can be coalition.side.BLUE, coalition.side.RED or coalition.side.NEUTRAL
|
||||||
|
-- @param #string Text Briefing text, can contain newlines, will be converted formatted properly for DCS
|
||||||
|
-- @param #string Picture Picture file path, can be a file in the DEFAULT folder inside the .miz
|
||||||
|
function UTILS.SetMissionBriefing(Coalition, Text, Picture)
|
||||||
|
Text = Text or ""
|
||||||
|
Text = Text:gsub("\n", "\\n")
|
||||||
|
Picture = Picture or ""
|
||||||
|
local coalName = string.lower(UTILS.GetCoalitionName(Coalition))
|
||||||
|
net.dostring_in("mission", string.format("a_set_briefing(\"%s\", \"%s\", \"%s\")", coalName, Picture, Text))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show a helper gate at a DCS#Vec3 position
|
||||||
|
-- @param DCS#Vec3 pos The position
|
||||||
|
-- @param #number heading Heading in degrees, can be 0..359 degrees
|
||||||
|
function UTILS.ShowHelperGate(pos, heading)
|
||||||
|
net.dostring_in("mission",string.format("a_show_helper_gate(%s, %s, %s, %f)", pos.x, pos.y, pos.z, math.rad(heading)))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show a helper gate for a unit.
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit The unit to show the gate for
|
||||||
|
-- @param #number Flag Helper gate flag
|
||||||
|
function UTILS.ShowHelperGateForUnit(Unit, Flag)
|
||||||
|
net.dostring_in("mission",string.format("a_show_route_gates_for_unit(%d, \"%d\")", Unit:GetID(), Flag))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the carrier illumination mode. -2: OFF, -1: AUTO, 0: NAVIGATION, 1: AC LAUNCH, 2: AC RECOVERY
|
||||||
|
-- @param #number UnitID Carrier unit ID ( UNIT:GetID() )
|
||||||
|
-- @param #number Mode Illumination mode, can be -2: OFF, -1: AUTO, 0: NAVIGATION, 1: AC LAUNCH, 2: AC RECOVERY
|
||||||
|
function UTILS.SetCarrierIlluminationMode(UnitID, Mode)
|
||||||
|
net.dostring_in("mission",string.format("a_set_carrier_illumination_mode(%d, %d)", UnitID, Mode))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Shell a zone, zone must ME created
|
||||||
|
-- @param #string name The name of the ME created zone
|
||||||
|
-- @param #number power Equals kg of TNT, e.g. 75
|
||||||
|
-- @param #count Number of shells simulated
|
||||||
|
function UTILS.ShellZone(name, power, count)
|
||||||
|
local z = UTILS.GetEnvZone(name)
|
||||||
|
if z then
|
||||||
|
net.dostring_in("mission",string.format("a_shelling_zone(%d, %d, %d)", z.zoneId, power, count))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove objects from a zone, zone must ME created
|
||||||
|
-- @param #string name The name of the ME created zone
|
||||||
|
-- @param #number type Type of objects to remove can be 0:all, 1: trees, 2:objects
|
||||||
|
function UTILS.RemoveObjects(name, type)
|
||||||
|
local z = UTILS.GetEnvZone(name)
|
||||||
|
if z then
|
||||||
|
net.dostring_in("mission",string.format("a_remove_scene_objects(%d, %d)", z.zoneId, type))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove scenery objects from a zone, zone must ME created
|
||||||
|
-- @param #string name The name of the ME created zone
|
||||||
|
-- @param #number level Level of removal
|
||||||
|
function UTILS.DestroyScenery(name, level)
|
||||||
|
local z = UTILS.GetEnvZone(name)
|
||||||
|
if z then
|
||||||
|
net.dostring_in("mission",string.format("a_scenery_destruction_zone(%d, %d)", z.zoneId, level))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Search for clear zones in a given area. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
||||||
|
-- @param DCS##Vec3 Center position vector for the search area.
|
||||||
|
-- @param #number SearchRadius Radius of the search area.
|
||||||
|
-- @param #number PosRadius Required clear radius around each position.
|
||||||
|
-- @param #number NumPositions Number of positions to find.
|
||||||
|
-- @return #table A table of DCS#Vec2 positions that are clear of map objects within the given PosRadius.
|
||||||
|
function UTILS.GetSimpleZones(Vec3, SearchRadius, PosRadius, NumPositions)
|
||||||
|
return Disposition.getSimpleZones(Vec3, SearchRadius, PosRadius, NumPositions)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Search for clear ground spawn zones within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
||||||
|
-- @param Core.Zone#ZONE Zone to search.
|
||||||
|
-- @param #number (Optional) PosRadius Required clear radius around each position. (Default is math.min(Radius/10, 200))
|
||||||
|
-- @param #number (Optional) NumPositions Number of positions to find. (Default 50)
|
||||||
|
-- @return #table A table of DCS#Vec2 positions that are clear of map objects within the given PosRadius. nil if no clear positions are found.
|
||||||
|
function UTILS.GetClearZonePositions(Zone, PosRadius, NumPositions)
|
||||||
|
local radius = PosRadius or math.min(Zone:GetRadius()/10, 200)
|
||||||
|
local clearPositions = UTILS.GetSimpleZones(Zone:GetVec3(), Zone:GetRadius(), radius, NumPositions or 50)
|
||||||
|
if clearPositions and #clearPositions > 0 then
|
||||||
|
local validZones = {}
|
||||||
|
for _, vec2 in pairs(clearPositions) do
|
||||||
|
if Zone:IsVec2InZone(vec2) then
|
||||||
|
table.insert(validZones, vec2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #validZones > 0 then
|
||||||
|
return validZones, radius
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Search for a random clear ground spawn coordinate within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
|
||||||
|
-- @param Core.Zone#ZONE Zone to search.
|
||||||
|
-- @param #number PosRadius (Optional) Required clear radius around each position. (Default is math.min(Radius/10, 200))
|
||||||
|
-- @param #number NumPositions (Optional) Number of positions to find. (Default 50)
|
||||||
|
-- @return Core.Point#COORDINATE A random coordinate for a clear zone. nil if no clear positions are found.
|
||||||
|
-- @return #number Assigned radius for the found zones. nil if no clear positions are found.
|
||||||
|
function UTILS.GetRandomClearZoneCoordinate(Zone, PosRadius, NumPositions)
|
||||||
|
local clearPositions = UTILS.GetClearZonePositions(Zone, PosRadius, NumPositions)
|
||||||
|
if clearPositions and #clearPositions > 0 then
|
||||||
|
local randomPosition, radius = clearPositions[math.random(1, #clearPositions)]
|
||||||
|
return COORDINATE:NewFromVec2(randomPosition), radius
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Find the point on the radius of a circle closest to a point outside of the radius.
|
||||||
|
-- @param DCS#Vec2 Vec1 Simple Vec2 marking the middle of the circle.
|
||||||
|
-- @param #number Radius The radius of the circle.
|
||||||
|
-- @param DCS#Vec2 Vec2 Simple Vec2 marking the point outside of the circle.
|
||||||
|
-- @return DCS#Vec2 Vec2 point on the radius.
|
||||||
|
function UTILS.FindNearestPointOnCircle(Vec1,Radius,Vec2)
|
||||||
|
local r = Radius
|
||||||
|
local cx = Vec1.x or 1
|
||||||
|
local cy = Vec1.y or 1
|
||||||
|
local px = Vec2.x or 1
|
||||||
|
local py = Vec2.y or 1
|
||||||
|
|
||||||
|
-- Berechne den Vektor vom Mittelpunkt zum externen Punkt
|
||||||
|
local dx = px - cx
|
||||||
|
local dy = py - cy
|
||||||
|
|
||||||
|
-- Berechne die Länge des Vektors
|
||||||
|
local dist = math.sqrt(dx * dx + dy * dy)
|
||||||
|
|
||||||
|
-- Wenn der Punkt im Mittelpunkt liegt, wähle einen Punkt auf der X-Achse
|
||||||
|
if dist == 0 then
|
||||||
|
return {x=cx + r, y=cy}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Normalisiere den Vektor (richtungsweise Vektor mit Länge 1)
|
||||||
|
local norm_dx = dx / dist
|
||||||
|
local norm_dy = dy / dist
|
||||||
|
|
||||||
|
-- Berechne den Punkt auf dem Rand des Kreises
|
||||||
|
local qx = cx + r * norm_dx
|
||||||
|
local qy = cy + r * norm_dy
|
||||||
|
|
||||||
|
local shift_factor = 1
|
||||||
|
qx = qx + shift_factor * norm_dx
|
||||||
|
qy = qy + shift_factor * norm_dy
|
||||||
|
|
||||||
|
return {x=qx, y=qy}
|
||||||
|
end
|
||||||
|
|
||||||
|
--- This function uses Disposition and other fallback logic to find better ground positions for ground units.
|
||||||
|
--- NOTE: This is not a spawn randomizer.
|
||||||
|
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
|
||||||
|
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
||||||
|
-- @param #table Positions A table of DCS#Vec2 or DCS#Vec3, can be a units table from the group template.
|
||||||
|
-- @param DCS#Vec2 Anchor (Optional) DCS#Vec2 or DCS#Vec3 as anchor point to calculate offset of the units.
|
||||||
|
-- @param #number MaxRadius (Optional) Max radius to search for valid ground locations in meters. Default is double the max radius of the units.
|
||||||
|
-- @param #number Spacing (Optional) Minimum spacing between units in meters. Default is 5% of the search radius or 5 meters, whichever is larger.
|
||||||
|
function UTILS.ValidateAndRepositionGroundUnits(Positions, Anchor, MaxRadius, Spacing)
|
||||||
|
local units = Positions
|
||||||
|
Anchor = Anchor or UTILS.GetCenterPoint(units)
|
||||||
|
local gPos = { x = Anchor.x, y = Anchor.z or Anchor.y }
|
||||||
|
local maxRadius = 0
|
||||||
|
local unitCount = 0
|
||||||
|
for _, unit in pairs(units) do
|
||||||
|
local pos = { x = unit.x, y = unit.z or unit.y }
|
||||||
|
local dist = UTILS.VecDist2D(pos, gPos)
|
||||||
|
if dist > maxRadius then
|
||||||
|
maxRadius = dist
|
||||||
|
end
|
||||||
|
unitCount = unitCount + 1
|
||||||
|
end
|
||||||
|
maxRadius = MaxRadius or math.max(maxRadius * 2, 10)
|
||||||
|
local spacing = Spacing or math.max(maxRadius * 0.05, 5)
|
||||||
|
if unitCount > 0 and maxRadius > 5 then
|
||||||
|
local spots = UTILS.GetSimpleZones(UTILS.Vec2toVec3(gPos), maxRadius, spacing, 1000)
|
||||||
|
if spots and #spots > 0 then
|
||||||
|
local validSpots = {}
|
||||||
|
for _, spot in pairs(spots) do -- Disposition sometimes returns points on roads, hence this filter.
|
||||||
|
if land.getSurfaceType(spot) == land.SurfaceType.LAND then
|
||||||
|
table.insert(validSpots, spot)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
spots = validSpots
|
||||||
|
end
|
||||||
|
|
||||||
|
local step = spacing
|
||||||
|
for _, unit in pairs(units) do
|
||||||
|
local pos = { x = unit.x, y = unit.z or unit.y }
|
||||||
|
local isOnLand = land.getSurfaceType(pos) == land.SurfaceType.LAND
|
||||||
|
local isValid = false
|
||||||
|
if spots and #spots > 0 then
|
||||||
|
local si = 1
|
||||||
|
local sid = 0
|
||||||
|
local closestDist = 100000000
|
||||||
|
local closestSpot
|
||||||
|
for _, spot in pairs(spots) do
|
||||||
|
local dist = UTILS.VecDist2D(pos, spot)
|
||||||
|
if dist < closestDist then
|
||||||
|
closestDist = dist
|
||||||
|
closestSpot = spot
|
||||||
|
sid = si
|
||||||
|
end
|
||||||
|
si = si + 1
|
||||||
|
end
|
||||||
|
if closestSpot then
|
||||||
|
if closestDist >= spacing then
|
||||||
|
pos = closestSpot
|
||||||
|
end
|
||||||
|
isValid = true
|
||||||
|
table.remove(spots, sid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Failsafe calculation
|
||||||
|
if not isValid and not isOnLand then
|
||||||
|
|
||||||
|
local h = UTILS.HdgTo(pos, gPos)
|
||||||
|
local retries = 0
|
||||||
|
while not isValid and retries < 500 do
|
||||||
|
|
||||||
|
local dist = UTILS.VecDist2D(pos, gPos)
|
||||||
|
pos = UTILS.Vec2Translate(pos, step, h)
|
||||||
|
|
||||||
|
local skip = false
|
||||||
|
for _, unit2 in pairs(units) do
|
||||||
|
if unit ~= unit2 then
|
||||||
|
local pos2 = { x = unit2.x, y = unit2.z or unit2.y }
|
||||||
|
local dist2 = UTILS.VecDist2D(pos, pos2)
|
||||||
|
if dist2 < 12 then
|
||||||
|
isValid = false
|
||||||
|
skip = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not skip and dist > step and land.getSurfaceType(pos) == land.SurfaceType.LAND then
|
||||||
|
isValid = true
|
||||||
|
break
|
||||||
|
elseif dist <= step then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
retries = retries + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if isValid then
|
||||||
|
unit.x = pos.x
|
||||||
|
if unit.z then
|
||||||
|
unit.z = pos.y
|
||||||
|
else
|
||||||
|
unit.y = pos.y
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- This function uses Disposition and other fallback logic to find better ground positions for statics.
|
||||||
|
--- NOTE: This is not a spawn randomizer.
|
||||||
|
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
|
||||||
|
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
||||||
|
-- @param #table Positions A table of DCS#Vec2 or DCS#Vec3, can be a units table from the group template.
|
||||||
|
-- @param DCS#Vec2 Position DCS#Vec2 or DCS#Vec3 initial spawn location.
|
||||||
|
-- @param #number MaxRadius (Optional) Max radius to search for valid ground locations in meters. Default is double the max radius of the static.
|
||||||
|
-- @return DCS#Vec2 Initial Position if it's valid, else a valid spawn position. nil if no valid position found.
|
||||||
|
function UTILS.ValidateAndRepositionStatic(Country, Category, Type, Position, ShapeName, MaxRadius)
|
||||||
|
local coord = COORDINATE:NewFromVec2(Position)
|
||||||
|
local st = SPAWNSTATIC:NewFromType(Type, Category, Country)
|
||||||
|
if ShapeName then
|
||||||
|
st:InitShape(ShapeName)
|
||||||
|
end
|
||||||
|
local sName = "s-"..timer.getTime().."-"..math.random(1,10000)
|
||||||
|
local tempStatic = st:SpawnFromCoordinate(coord, 0, sName)
|
||||||
|
if tempStatic then
|
||||||
|
local sRadius = tempStatic:GetBoundingRadius(2) or 3
|
||||||
|
tempStatic:Destroy()
|
||||||
|
sRadius = sRadius * 0.5
|
||||||
|
MaxRadius = MaxRadius or math.max(sRadius * 10, 100)
|
||||||
|
local positions = UTILS.GetSimpleZones(coord:GetVec3(), MaxRadius, sRadius, 20)
|
||||||
|
if positions and #positions > 0 then
|
||||||
|
local closestSpot
|
||||||
|
local closestDist = math.huge
|
||||||
|
for _, spot in pairs(positions) do -- Disposition sometimes returns points on roads, hence this filter.
|
||||||
|
if land.getSurfaceType(spot) == land.SurfaceType.LAND then
|
||||||
|
local dist = UTILS.VecDist2D(Position, spot)
|
||||||
|
if dist < closestDist then
|
||||||
|
closestDist = dist
|
||||||
|
closestSpot = spot
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if closestSpot then
|
||||||
|
if closestDist >= sRadius then
|
||||||
|
return closestSpot
|
||||||
|
else
|
||||||
|
return Position
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
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",
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,6 +611,35 @@ AIRBASE.MarianaIslands = {
|
|||||||
["Tinian_Intl"] = "Tinian Intl",
|
["Tinian_Intl"] = "Tinian Intl",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- Airbase of the Marianas WWII map
|
||||||
|
--
|
||||||
|
-- * AIRBASE.MarianaIslandsWWII.Agana
|
||||||
|
-- * AIRBASE.MarianaIslandsWWII.Airfield_3
|
||||||
|
-- * AIRBASE.MarianaIslandsWWII.Charon_Kanoa
|
||||||
|
-- * AIRBASE.MarianaIslandsWWII.Gurguan_Point
|
||||||
|
-- * AIRBASE.MarianaIslandsWWII.Isley
|
||||||
|
-- * AIRBASE.MarianaIslandsWWII.Kagman
|
||||||
|
-- * AIRBASE.MarianaIslandsWWII.Marpi
|
||||||
|
-- * AIRBASE.MarianaIslandsWWII.Orote
|
||||||
|
-- * AIRBASE.MarianaIslandsWWII.Pagan
|
||||||
|
-- * AIRBASE.MarianaIslandsWWII.Rota
|
||||||
|
-- * AIRBASE.MarianaIslandsWWII.Ushi
|
||||||
|
-- @field AIRBASE.MarianaIslandsWWII
|
||||||
|
AIRBASE.MarianaIslandsWWII =
|
||||||
|
{
|
||||||
|
["Agana"] = "Agana",
|
||||||
|
["Airfield_3"] = "Airfield 3",
|
||||||
|
["Charon_Kanoa"] = "Charon Kanoa",
|
||||||
|
["Gurguan_Point"] = "Gurguan Point",
|
||||||
|
["Isley"] = "Isley",
|
||||||
|
["Kagman"] = "Kagman",
|
||||||
|
["Marpi"] = "Marpi",
|
||||||
|
["Orote"] = "Orote",
|
||||||
|
["Pagan"] = "Pagan",
|
||||||
|
["Rota"] = "Rota",
|
||||||
|
["Ushi"] = "Ushi",
|
||||||
|
}
|
||||||
|
|
||||||
--- Airbases of the South Atlantic map:
|
--- Airbases of the South Atlantic map:
|
||||||
--
|
--
|
||||||
-- * AIRBASE.SouthAtlantic.Almirante_Schroeders
|
-- * AIRBASE.SouthAtlantic.Almirante_Schroeders
|
||||||
@ -674,51 +703,56 @@ AIRBASE.SouthAtlantic={
|
|||||||
|
|
||||||
--- Airbases of the Sinai map:
|
--- Airbases of the Sinai map:
|
||||||
--
|
--
|
||||||
-- * AIRBASE.Sinai.Abu_Rudeis
|
-- * AIRBASE.SinaiMap.Abu_Rudeis
|
||||||
-- * AIRBASE.Sinai.Abu_Suwayr
|
-- * AIRBASE.SinaiMap.Abu_Suwayr
|
||||||
-- * AIRBASE.Sinai.Al_Bahr_al_Ahmar
|
-- * AIRBASE.SinaiMap.Al_Bahr_al_Ahmar
|
||||||
-- * AIRBASE.Sinai.Al_Ismailiyah
|
-- * AIRBASE.SinaiMap.Al_Ismailiyah
|
||||||
-- * AIRBASE.Sinai.Al_Khatatbah
|
-- * AIRBASE.SinaiMap.Al_Khatatbah
|
||||||
-- * AIRBASE.Sinai.Al_Mansurah
|
-- * AIRBASE.SinaiMap.Al_Mansurah
|
||||||
-- * AIRBASE.Sinai.Al_Rahmaniyah_Air_Base
|
-- * AIRBASE.SinaiMap.Al_Rahmaniyah_Air_Base
|
||||||
-- * AIRBASE.Sinai.As_Salihiyah
|
-- * AIRBASE.SinaiMap.As_Salihiyah
|
||||||
-- * AIRBASE.Sinai.AzZaqaziq
|
-- * AIRBASE.SinaiMap.AzZaqaziq
|
||||||
-- * AIRBASE.Sinai.Baluza
|
-- * AIRBASE.SinaiMap.Baluza
|
||||||
-- * AIRBASE.Sinai.Ben_Gurion
|
-- * AIRBASE.SinaiMap.Ben_Gurion
|
||||||
-- * AIRBASE.Sinai.Beni_Suef
|
-- * AIRBASE.SinaiMap.Beni_Suef
|
||||||
-- * AIRBASE.Sinai.Bilbeis_Air_Base
|
-- * AIRBASE.SinaiMap.Bilbeis_Air_Base
|
||||||
-- * AIRBASE.Sinai.Bir_Hasanah
|
-- * AIRBASE.SinaiMap.Bir_Hasanah
|
||||||
-- * AIRBASE.Sinai.Birma_Air_Base
|
-- * AIRBASE.SinaiMap.Birma_Air_Base
|
||||||
-- * AIRBASE.Sinai.Borj_El_Arab_International_Airport
|
-- * AIRBASE.SinaiMap.Borg_El_Arab_International_Airport
|
||||||
-- * AIRBASE.Sinai.Cairo_International_Airport
|
-- * AIRBASE.SinaiMap.Cairo_International_Airport
|
||||||
-- * AIRBASE.Sinai.Cairo_West
|
-- * AIRBASE.SinaiMap.Cairo_West
|
||||||
-- * AIRBASE.Sinai.Difarsuwar_Airfield
|
-- * AIRBASE.SinaiMap.Damascus_Intl
|
||||||
-- * AIRBASE.Sinai.El_Arish
|
-- * AIRBASE.SinaiMap.Difarsuwar_Airfield
|
||||||
-- * AIRBASE.Sinai.El_Gora
|
-- * AIRBASE.SinaiMap.El_Arish
|
||||||
-- * AIRBASE.Sinai.El_Minya
|
-- * AIRBASE.SinaiMap.El_Gora
|
||||||
-- * AIRBASE.Sinai.Fayed
|
-- * AIRBASE.SinaiMap.El_Minya
|
||||||
-- * AIRBASE.Sinai.Gebel_El_Basur_Air_Base
|
-- * AIRBASE.SinaiMap.Fayed
|
||||||
-- * AIRBASE.Sinai.Hatzerim
|
-- * AIRBASE.SinaiMap.Gebel_El_Basur_Air_Base
|
||||||
-- * AIRBASE.Sinai.Hatzor
|
-- * AIRBASE.SinaiMap.Hatzerim
|
||||||
-- * AIRBASE.Sinai.Hurghada_International_Airport
|
-- * AIRBASE.SinaiMap.Hatzor
|
||||||
-- * AIRBASE.Sinai.Inshas_Airbase
|
-- * AIRBASE.SinaiMap.Hurghada_International_Airport
|
||||||
-- * AIRBASE.Sinai.Jiyanklis_Air_Base
|
-- * AIRBASE.SinaiMap.Inshas_Airbase
|
||||||
-- * AIRBASE.Sinai.Kedem
|
-- * AIRBASE.SinaiMap.Jiyanklis_Air_Base
|
||||||
-- * AIRBASE.Sinai.Kibrit_Air_Base
|
-- * AIRBASE.SinaiMap.Kedem
|
||||||
-- * AIRBASE.Sinai.Kom_Awshim
|
-- * AIRBASE.SinaiMap.Kibrit_Air_Base
|
||||||
-- * AIRBASE.Sinai.Melez
|
-- * AIRBASE.SinaiMap.Kom_Awshim
|
||||||
-- * AIRBASE.Sinai.Nevatim
|
-- * AIRBASE.SinaiMap.Melez
|
||||||
-- * AIRBASE.Sinai.Ovda
|
-- * AIRBASE.SinaiMap.Mezzeh_Air_Base
|
||||||
-- * AIRBASE.Sinai.Palmachim
|
-- * AIRBASE.SinaiMap.Nevatim
|
||||||
-- * AIRBASE.Sinai.Quwaysina
|
-- * AIRBASE.SinaiMap.Ovda
|
||||||
-- * AIRBASE.Sinai.Ramon_Airbase
|
-- * AIRBASE.SinaiMap.Palmachim
|
||||||
-- * AIRBASE.Sinai.Ramon_International_Airport
|
-- * AIRBASE.SinaiMap.Quwaysina
|
||||||
-- * AIRBASE.Sinai.Sde_Dov
|
-- * AIRBASE.SinaiMap.Rafic_Hariri_Intl
|
||||||
-- * AIRBASE.Sinai.Sharm_El_Sheikh_International_Airport
|
-- * AIRBASE.SinaiMap.Ramat_David
|
||||||
-- * AIRBASE.Sinai.St_Catherine
|
-- * AIRBASE.SinaiMap.Ramon_Airbase
|
||||||
-- * AIRBASE.Sinai.Tel_Nof
|
-- * AIRBASE.SinaiMap.Ramon_International_Airport
|
||||||
-- * AIRBASE.Sinai.Wadi_Abu_Rish
|
-- * AIRBASE.SinaiMap.Sde_Dov
|
||||||
-- * AIRBASE.Sinai.Wadi_al_Jandali
|
-- * AIRBASE.SinaiMap.Sharm_El_Sheikh_International_Airport
|
||||||
|
-- * AIRBASE.SinaiMap.St_Catherine
|
||||||
|
-- * AIRBASE.SinaiMap.Tabuk
|
||||||
|
-- * AIRBASE.SinaiMap.Tel_Nof
|
||||||
|
-- * AIRBASE.SinaiMap.Wadi_Abu_Rish
|
||||||
|
-- * AIRBASE.SinaiMap.Wadi_al_Jandali
|
||||||
--
|
--
|
||||||
-- @field Sinai
|
-- @field Sinai
|
||||||
AIRBASE.Sinai = {
|
AIRBASE.Sinai = {
|
||||||
@ -737,9 +771,10 @@ 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",
|
||||||
|
["Damascus_Intl"] = "Damascus Intl",
|
||||||
["Difarsuwar_Airfield"] = "Difarsuwar Airfield",
|
["Difarsuwar_Airfield"] = "Difarsuwar Airfield",
|
||||||
["El_Arish"] = "El Arish",
|
["El_Arish"] = "El Arish",
|
||||||
["El_Gora"] = "El Gora",
|
["El_Gora"] = "El Gora",
|
||||||
@ -755,15 +790,19 @@ AIRBASE.Sinai = {
|
|||||||
["Kibrit_Air_Base"] = "Kibrit Air Base",
|
["Kibrit_Air_Base"] = "Kibrit Air Base",
|
||||||
["Kom_Awshim"] = "Kom Awshim",
|
["Kom_Awshim"] = "Kom Awshim",
|
||||||
["Melez"] = "Melez",
|
["Melez"] = "Melez",
|
||||||
|
["Mezzeh_Air_Base"] = "Mezzeh Air Base",
|
||||||
["Nevatim"] = "Nevatim",
|
["Nevatim"] = "Nevatim",
|
||||||
["Ovda"] = "Ovda",
|
["Ovda"] = "Ovda",
|
||||||
["Palmachim"] = "Palmachim",
|
["Palmachim"] = "Palmachim",
|
||||||
["Quwaysina"] = "Quwaysina",
|
["Quwaysina"] = "Quwaysina",
|
||||||
|
["Rafic_Hariri_Intl"] = "Rafic Hariri Intl",
|
||||||
|
["Ramat_David"] = "Ramat David",
|
||||||
["Ramon_Airbase"] = "Ramon Airbase",
|
["Ramon_Airbase"] = "Ramon Airbase",
|
||||||
["Ramon_International_Airport"] = "Ramon International Airport",
|
["Ramon_International_Airport"] = "Ramon International Airport",
|
||||||
["Sde_Dov"] = "Sde Dov",
|
["Sde_Dov"] = "Sde Dov",
|
||||||
["Sharm_El_Sheikh_International_Airport"] = "Sharm El Sheikh International Airport",
|
["Sharm_El_Sheikh_International_Airport"] = "Sharm El Sheikh International Airport",
|
||||||
["St_Catherine"] = "St Catherine",
|
["St_Catherine"] = "St Catherine",
|
||||||
|
["Tabuk"] = "Tabuk",
|
||||||
["Tel_Nof"] = "Tel Nof",
|
["Tel_Nof"] = "Tel Nof",
|
||||||
["Wadi_Abu_Rish"] = "Wadi Abu Rish",
|
["Wadi_Abu_Rish"] = "Wadi Abu Rish",
|
||||||
["Wadi_al_Jandali"] = "Wadi al Jandali",
|
["Wadi_al_Jandali"] = "Wadi al Jandali",
|
||||||
@ -790,9 +829,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.Kittila
|
||||||
-- * AIRBASE.Kola.Bardufoss
|
-- * 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 = {
|
||||||
@ -815,9 +859,20 @@ AIRBASE.Kola = {
|
|||||||
["Vidsel"] = "Vidsel",
|
["Vidsel"] = "Vidsel",
|
||||||
["Vuojarvi"] = "Vuojarvi",
|
["Vuojarvi"] = "Vuojarvi",
|
||||||
["Andoya"] = "Andoya",
|
["Andoya"] = "Andoya",
|
||||||
["Alakourtti"] = "Alakourtti",
|
["Alakurtti"] = "Alakurtti",
|
||||||
["Kittila"] = "Kittila",
|
["Kittila"] = "Kittila",
|
||||||
["Bardufoss"] = "Bardufoss",
|
["Bardufoss"] = "Bardufoss",
|
||||||
|
["Alta"] = "Alta",
|
||||||
|
["Sodankyla"] = "Sodankyla",
|
||||||
|
["Enontekio"] = "Enontekio",
|
||||||
|
["Evenes"] = "Evenes",
|
||||||
|
["Hosio"] = "Hosio",
|
||||||
|
["Kilpyavr"] = "Kilpyavr",
|
||||||
|
["Afrikanda"] = "Afrikanda",
|
||||||
|
["Kalevala"] = "Kalevala",
|
||||||
|
["Koshka_Yavr"] = "Koshka Yavr",
|
||||||
|
["Poduzhemye"] = "Poduzhemye",
|
||||||
|
["Luostari_Pechenga"] = "Luostari Pechenga",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Airbases of the Afghanistan map
|
--- Airbases of the Afghanistan map
|
||||||
@ -878,37 +933,461 @@ AIRBASE.Afghanistan = {
|
|||||||
|
|
||||||
--- Airbases of the Iraq map
|
--- Airbases of the Iraq map
|
||||||
--
|
--
|
||||||
-- * AIRBASE.Iraq.Baghdad_International_Airport
|
|
||||||
-- * AIRBASE.Iraq.Sulaimaniyah_International_Airport
|
|
||||||
-- * AIRBASE.Iraq.Al_Sahra_Airport
|
|
||||||
-- * AIRBASE.Iraq.Erbil_International_Airpor
|
|
||||||
-- * AIRBASE.Iraq.Al_Taji_Airport
|
|
||||||
-- * AIRBASE.Iraq.Al_Asad_Airbase
|
-- * AIRBASE.Iraq.Al_Asad_Airbase
|
||||||
|
-- * AIRBASE.Iraq.Al_Kut_Airbase
|
||||||
|
-- * AIRBASE.Iraq.Al_Sahra_Airport
|
||||||
-- * AIRBASE.Iraq.Al_Salam_Airbase
|
-- * AIRBASE.Iraq.Al_Salam_Airbase
|
||||||
-- * AIRBASE.Iraq.Balad_Airbase
|
-- * AIRBASE.Iraq.Al_Taji_Airport
|
||||||
-- * AIRBASE.Iraq.Kirkuk_International_Airport
|
|
||||||
-- * AIRBASE.Iraq.Bashur_Airport
|
|
||||||
-- * AIRBASE.Iraq.Al_Taquddum_Airport
|
-- * AIRBASE.Iraq.Al_Taquddum_Airport
|
||||||
-- * AIRBASE.Iraq.Qayyarah_Airfield_West
|
-- * AIRBASE.Iraq.Baghdad_International_Airport
|
||||||
|
-- * AIRBASE.Iraq.Balad_Airbase
|
||||||
|
-- * AIRBASE.Iraq.Bashur_Airport
|
||||||
|
-- * AIRBASE.Iraq.Erbil_International_Airport
|
||||||
|
-- * AIRBASE.Iraq.Sulaimaniyah_International_Airport
|
||||||
|
-- * AIRBASE.Iraq.H2_Airbase
|
||||||
|
-- * AIRBASE.Iraq.H3_Main_Airbase
|
||||||
|
-- * AIRBASE.Iraq.H3_Northwest_Airbase
|
||||||
|
-- * AIRBASE.Iraq.H3_Southwest_Airbase
|
||||||
-- * AIRBASE.Iraq.K1_Base
|
-- * AIRBASE.Iraq.K1_Base
|
||||||
|
-- * AIRBASE.Iraq.Kirkuk_International_Airport
|
||||||
|
-- * AIRBASE.Iraq.Mosul_International_Airport
|
||||||
|
-- * AIRBASE.Iraq.Qayyarah_Airfield_West
|
||||||
|
-- * AIRBASE.Iraq.Sulaimaniyah_International_Airport
|
||||||
--
|
--
|
||||||
-- @field Iraq
|
-- @field Iraq
|
||||||
AIRBASE.Iraq = {
|
AIRBASE.Iraq = {
|
||||||
["Baghdad_International_Airport"] = "Baghdad International Airport",
|
|
||||||
["Sulaimaniyah_International_Airport"] = "Sulaimaniyah International Airport",
|
|
||||||
["Al_Sahra_Airport"] = "Al-Sahra Airport",
|
|
||||||
["Erbil_International_Airport"] = "Erbil International Airport",
|
|
||||||
["Al_Taji_Airport"] = "Al-Taji Airport",
|
|
||||||
["Al_Asad_Airbase"] = "Al-Asad Airbase",
|
["Al_Asad_Airbase"] = "Al-Asad Airbase",
|
||||||
|
["Al_Kut_Airport"] = "Al-Kut Airport",
|
||||||
|
["Al_Sahra_Airport"] = "Al-Sahra Airport",
|
||||||
["Al_Salam_Airbase"] = "Al-Salam Airbase",
|
["Al_Salam_Airbase"] = "Al-Salam Airbase",
|
||||||
["Balad_Airbase"] = "Balad Airbase",
|
["Al_Taji_Airport"] = "Al-Taji Airport",
|
||||||
["Kirkuk_International_Airport"] = "Kirkuk International Airport",
|
|
||||||
["Bashur_Airport"] = "Bashur Airport",
|
|
||||||
["Al_Taquddum_Airport"] = "Al-Taquddum Airport",
|
["Al_Taquddum_Airport"] = "Al-Taquddum Airport",
|
||||||
["Qayyarah_Airfield_West"] = "Qayyarah Airfield West",
|
["Baghdad_International_Airport"] = "Baghdad International Airport",
|
||||||
|
["Balad_Airbase"] = "Balad Airbase",
|
||||||
|
["Bashur_Airport"] = "Bashur Airport",
|
||||||
|
["Erbil_International_Airport"] = "Erbil International Airport",
|
||||||
|
["H2_Airbase"] = "H-2 Airbase",
|
||||||
|
["H3_Main_Airbase"] = "H-3 Main Airbase",
|
||||||
|
["H3_Northwest_Airbase"] = "H-3 Northwest Airbase",
|
||||||
|
["H3_Southwest_Airbase"] = "H-3 Southwest Airbase",
|
||||||
["K1_Base"] = "K1 Base",
|
["K1_Base"] = "K1 Base",
|
||||||
|
["Kirkuk_International_Airport"] = "Kirkuk International Airport",
|
||||||
|
["Mosul_International_Airport"] = "Mosul International Airport",
|
||||||
|
["Qayyarah_Airfield_West"] = "Qayyarah Airfield West",
|
||||||
|
["Sulaimaniyah_International_Airport"] = "Sulaimaniyah International Airport",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--- 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.
|
||||||
@ -1012,7 +1491,7 @@ function AIRBASE:Register(AirbaseName)
|
|||||||
self.descriptors=self:GetDesc()
|
self.descriptors=self:GetDesc()
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
--self:I({airbase=AirbaseName, descriptors=self.descriptors})
|
--self:T({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
|
||||||
@ -1095,6 +1574,17 @@ end
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the true airbase center as seen in the ME. The position returned by the dcs object is is wrong and often at the start of the runway.
|
||||||
|
-- @return DCS#Vec2 The center of the true center of the airbase if it contains runways, otherwise the default DCS object position.
|
||||||
|
function AIRBASE:GetVec2()
|
||||||
|
local runways = self:GetRunways()
|
||||||
|
if runways and #runways > 0 then
|
||||||
|
return runways[1].center:GetVec2()
|
||||||
|
end
|
||||||
|
return self:GetCoordinate():GetVec2()
|
||||||
|
end
|
||||||
|
|
||||||
--- Get the category of this airbase. This is only a debug function because DCS 2.9 incorrectly returns heliports as airdromes.
|
--- Get the category of this airbase. This is only a debug function because DCS 2.9 incorrectly returns heliports as airdromes.
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
function AIRBASE:_GetCategory()
|
function AIRBASE:_GetCategory()
|
||||||
@ -2131,7 +2621,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
|
||||||
@ -2158,7 +2648,7 @@ function AIRBASE:_InitRunways(IncludeInverse)
|
|||||||
|
|
||||||
--- 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
|
||||||
|
|
||||||
@ -2174,10 +2664,12 @@ 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))
|
||||||
runway.magheading=tonumber(runway.name)*10
|
runway.magheading=tonumber(runway.name)*10
|
||||||
|
runway.idx=runway.magheading
|
||||||
runway.heading=heading
|
runway.heading=heading
|
||||||
runway.width=width or 0
|
runway.width=width or 0
|
||||||
runway.length=length or 0
|
runway.length=length or 0
|
||||||
@ -2490,12 +2982,13 @@ function AIRBASE:GetRunwayData(magvar, mark)
|
|||||||
local runway={} --#AIRBASE.Runway
|
local runway={} --#AIRBASE.Runway
|
||||||
runway.heading=hdg
|
runway.heading=hdg
|
||||||
runway.idx=idx
|
runway.idx=idx
|
||||||
|
runway.magheading=idx
|
||||||
runway.length=c1:Get2DDistance(c2)
|
runway.length=c1:Get2DDistance(c2)
|
||||||
runway.position=c1
|
runway.position=c1
|
||||||
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
|
||||||
@ -2507,6 +3000,57 @@ function AIRBASE:GetRunwayData(magvar, mark)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Look for identical (parallel) runways, e.g. 03L and 03R at Nellis.
|
||||||
|
local rpairs={}
|
||||||
|
for i,_ri in pairs(runways) do
|
||||||
|
local ri=_ri --#AIRBASE.Runway
|
||||||
|
for j,_rj in pairs(runways) do
|
||||||
|
local rj=_rj --#AIRBASE.Runway
|
||||||
|
if i<j then
|
||||||
|
if ri.name==rj.name then
|
||||||
|
rpairs[i]=j
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function isLeft(a, b, c)
|
||||||
|
--return ((b.x - a.x)*(c.z - a.z) - (b.z - a.z)*(c.x - a.x)) > 0
|
||||||
|
return ((b.z - a.z)*(c.x - a.x) - (b.x - a.x)*(c.z - a.z)) > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
for i,j in pairs(rpairs) do
|
||||||
|
local ri=runways[i] --#AIRBASE.Runway
|
||||||
|
local rj=runways[j] --#AIRBASE.Runway
|
||||||
|
|
||||||
|
-- Draw arrow.
|
||||||
|
--ri.center:ArrowToAll(rj.center)
|
||||||
|
|
||||||
|
local c0=ri.position
|
||||||
|
|
||||||
|
-- Vector in the direction of the runway.
|
||||||
|
local a=UTILS.VecTranslate(c0, 1000, ri.heading)
|
||||||
|
|
||||||
|
-- Vector from runway i to runway j.
|
||||||
|
local b=UTILS.VecSubstract(rj.position, ri.position)
|
||||||
|
b=UTILS.VecAdd(ri.position, b)
|
||||||
|
|
||||||
|
-- Check if rj is left of ri.
|
||||||
|
local left=isLeft(c0, a, b)
|
||||||
|
|
||||||
|
--env.info(string.format("Found pair %s: i=%d, j=%d, left==%s", ri.name, i, j, tostring(left)))
|
||||||
|
|
||||||
|
if left then
|
||||||
|
ri.isLeft=false
|
||||||
|
rj.isLeft=true
|
||||||
|
else
|
||||||
|
ri.isLeft=true
|
||||||
|
rj.isLeft=false
|
||||||
|
end
|
||||||
|
|
||||||
|
--break
|
||||||
|
end
|
||||||
|
|
||||||
return runways
|
return runways
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -168,17 +168,26 @@
|
|||||||
-- * @{#CONTROLLABLE.OptionAlarmStateGreen}
|
-- * @{#CONTROLLABLE.OptionAlarmStateGreen}
|
||||||
-- * @{#CONTROLLABLE.OptionAlarmStateRed}
|
-- * @{#CONTROLLABLE.OptionAlarmStateRed}
|
||||||
--
|
--
|
||||||
-- ## 5.4) Jettison weapons:
|
-- ## 5.4) [AIR] Jettison weapons:
|
||||||
--
|
--
|
||||||
-- * @{#CONTROLLABLE.OptionAllowJettisonWeaponsOnThreat}
|
-- * @{#CONTROLLABLE.OptionAllowJettisonWeaponsOnThreat}
|
||||||
-- * @{#CONTROLLABLE.OptionKeepWeaponsOnThreat}
|
-- * @{#CONTROLLABLE.OptionKeepWeaponsOnThreat}
|
||||||
--
|
--
|
||||||
-- ## 5.5) Air-2-Air missile attack range:
|
-- ## 5.5) [AIR] Air-2-Air missile attack range:
|
||||||
-- * @{#CONTROLLABLE.OptionAAAttackRange}(): Defines the usage of A2A missiles against possible targets.
|
-- * @{#CONTROLLABLE.OptionAAAttackRange}(): Defines the usage of A2A missiles against possible targets.
|
||||||
--
|
--
|
||||||
-- # 6) [GROUND] IR Maker Beacons for GROUPs and UNITs
|
-- # 6) [GROUND] IR Maker Beacons for GROUPs and UNITs
|
||||||
-- * @{#CONTROLLABLE:NewIRMarker}(): Create a blinking IR Marker on a GROUP or UNIT.
|
-- * @{#CONTROLLABLE:NewIRMarker}(): Create a blinking IR Marker on a GROUP or UNIT.
|
||||||
--
|
--
|
||||||
|
-- # 7) [HELICOPTER] Units prefer vertical landing and takeoffs:
|
||||||
|
-- * @{#CONTROLLABLE.OptionPreferVerticalLanding}(): Set aircraft to prefer vertical landing and takeoff.
|
||||||
|
--
|
||||||
|
-- # 8) [AIRCRAFT] Landing approach options
|
||||||
|
-- * @{#CONTROLLABLE.SetOptionLandingStraightIn}(): Landing approach straight in.
|
||||||
|
-- * @{#CONTROLLABLE.SetOptionLandingForcePair}(): Landing approach in pairs for groups > 1 unit.
|
||||||
|
-- * @{#CONTROLLABLE.SetOptionLandingRestrictPair}(): Landing approach single.
|
||||||
|
-- * @{#CONTROLLABLE.SetOptionLandingOverheadBreak}(): Landing approach overhead break.
|
||||||
|
--
|
||||||
-- @field #CONTROLLABLE
|
-- @field #CONTROLLABLE
|
||||||
CONTROLLABLE = {
|
CONTROLLABLE = {
|
||||||
ClassName = "CONTROLLABLE",
|
ClassName = "CONTROLLABLE",
|
||||||
@ -994,6 +1003,65 @@ function CONTROLLABLE:CommandSetFrequencyForUnit(Frequency,Modulation,Power,Unit
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [AIR] Set smoke on or off. See [DCS command smoke on off](https://wiki.hoggitworld.com/view/DCS_command_smoke_on_off)
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @param #boolean OnOff Set to true for on and false for off. Defaults to true.
|
||||||
|
-- @param #number Delay (Optional) Delay the command by this many seconds.
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:CommandSmokeOnOff(OnOff, Delay)
|
||||||
|
local switch = (OnOff == nil) and true or OnOff
|
||||||
|
local command = {
|
||||||
|
id = 'SMOKE_ON_OFF',
|
||||||
|
params = {
|
||||||
|
value = switch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
SCHEDULER:New(nil,self.CommandSmokeOnOff,{self,switch},Delay)
|
||||||
|
else
|
||||||
|
self:SetCommand(command)
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [AIR] Set smoke on. See [DCS command smoke on off](https://wiki.hoggitworld.com/view/DCS_command_smoke_on_off)
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @param #number Delay (Optional) Delay the command by this many seconds.
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:CommandSmokeON(Delay)
|
||||||
|
local command = {
|
||||||
|
id = 'SMOKE_ON_OFF',
|
||||||
|
params = {
|
||||||
|
value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
SCHEDULER:New(nil,self.CommandSmokeON,{self},Delay)
|
||||||
|
else
|
||||||
|
self:SetCommand(command)
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [AIR] Set smoke off. See [DCS command smoke on off](https://wiki.hoggitworld.com/view/DCS_command_smoke_on_off)
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @param #number Delay (Optional) Delay the command by this many seconds.
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:CommandSmokeOFF(Delay)
|
||||||
|
local command = {
|
||||||
|
id = 'SMOKE_ON_OFF',
|
||||||
|
params = {
|
||||||
|
value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
SCHEDULER:New(nil,self.CommandSmokeOFF,{self},Delay)
|
||||||
|
else
|
||||||
|
self:SetCommand(command)
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Set EPLRS data link on/off.
|
--- Set EPLRS data link on/off.
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @param #boolean SwitchOnOff If true (or nil) switch EPLRS on. If false switch off.
|
-- @param #boolean SwitchOnOff If true (or nil) switch EPLRS on. If false switch off.
|
||||||
@ -1373,7 +1441,7 @@ end
|
|||||||
-- @param #number Speed The speed [m/s] flying when holding the position.
|
-- @param #number Speed The speed [m/s] flying when holding the position.
|
||||||
-- @return #CONTROLLABLE self
|
-- @return #CONTROLLABLE self
|
||||||
function CONTROLLABLE:TaskOrbitCircleAtVec2( Point, Altitude, Speed )
|
function CONTROLLABLE:TaskOrbitCircleAtVec2( Point, Altitude, Speed )
|
||||||
self:F2( { self.ControllableName, Point, Altitude, Speed } )
|
--self:F2( { self.ControllableName, Point, Altitude, Speed } )
|
||||||
|
|
||||||
local DCSTask = {
|
local DCSTask = {
|
||||||
id = 'Orbit',
|
id = 'Orbit',
|
||||||
@ -3570,6 +3638,26 @@ function CONTROLLABLE:OptionROTPassiveDefense()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Helicopter - prefer vertical landing.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:OptionPreferVerticalLanding()
|
||||||
|
self:F2( { self.ControllableName } )
|
||||||
|
|
||||||
|
local DCSControllable = self:GetDCSObject()
|
||||||
|
if DCSControllable then
|
||||||
|
local Controller = self:_GetController()
|
||||||
|
|
||||||
|
if self:IsAir() then
|
||||||
|
Controller:setOption( AI.Option.Air.id.PREFER_VERTICAL, true )
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Can the CONTROLLABLE evade on enemy fire?
|
--- Can the CONTROLLABLE evade on enemy fire?
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
@ -4075,7 +4163,7 @@ function CONTROLLABLE:OptionRestrictBurner( RestrictBurner )
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets Controllable Option for A2A attack range for AIR FIGHTER units.
|
--- [AIR] Sets Controllable Option for A2A attack range for AIR FIGHTER units.
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @param #number range Defines the range
|
-- @param #number range Defines the range
|
||||||
-- @return #CONTROLLABLE self
|
-- @return #CONTROLLABLE self
|
||||||
@ -4100,6 +4188,66 @@ function CONTROLLABLE:OptionAAAttackRange( range )
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [GROUND/AAA] Sets Controllable Option for Ground AAA minimum firing height.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @param #number meters The minimum height in meters.
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:OptionAAAMinFiringHeightMeters(meters)
|
||||||
|
self:F2( { self.ControllableName } )
|
||||||
|
local meters = meters or 20
|
||||||
|
local DCSControllable = self:GetDCSObject()
|
||||||
|
if DCSControllable then
|
||||||
|
local Controller = self:_GetController()
|
||||||
|
if Controller then
|
||||||
|
if self:IsGround() then
|
||||||
|
self:SetOption(27, meters)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [GROUND/AAA] Sets Controllable Option for Ground AAA maximum firing height.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @param #number meters The maximum height in meters.
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:OptionAAAMaxFiringHeightMeters(meters)
|
||||||
|
self:F2( { self.ControllableName } )
|
||||||
|
local meters = meters or 1000
|
||||||
|
local DCSControllable = self:GetDCSObject()
|
||||||
|
if DCSControllable then
|
||||||
|
local Controller = self:_GetController()
|
||||||
|
if Controller then
|
||||||
|
if self:IsGround() then
|
||||||
|
self:SetOption(29, meters)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [GROUND/AAA] Sets Controllable Option for Ground AAA minimum firing height.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @param #number feet The minimum height in feet.
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:OptionAAAMinFiringHeightFeet(feet)
|
||||||
|
self:F2( { self.ControllableName } )
|
||||||
|
local feet = feet or 60
|
||||||
|
return self:OptionAAAMinFiringHeightMeters(UTILS.FeetToMeters(feet))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [GROUND/AAA] Sets Controllable Option for Ground AAA maximum firing height.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @param #number feet The maximum height in feet.
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:OptionAAAMaxFiringHeightfeet(feet)
|
||||||
|
self:F2( { self.ControllableName } )
|
||||||
|
local feet = feet or 3000
|
||||||
|
return self:OptionAAAMaxFiringHeightMeters(UTILS.FeetToMeters(feet))
|
||||||
|
end
|
||||||
|
|
||||||
--- Defines the range at which a GROUND unit/group is allowed to use its weapons automatically.
|
--- Defines the range at which a GROUND unit/group is allowed to use its weapons automatically.
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @param #number EngageRange Engage range limit in percent (a number between 0 and 100). Default 100.
|
-- @param #number EngageRange Engage range limit in percent (a number between 0 and 100). Default 100.
|
||||||
@ -4124,6 +4272,50 @@ function CONTROLLABLE:OptionEngageRange( EngageRange )
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [AIR] Set how the AI lands on an airfield. Here: Straight in.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:SetOptionLandingStraightIn()
|
||||||
|
self:F2( { self.ControllableName } )
|
||||||
|
if self:IsAir() then
|
||||||
|
self:SetOption("36","0")
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [AIR] Set how the AI lands on an airfield. Here: In pairs (if > 1 aircraft in group)
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:SetOptionLandingForcePair()
|
||||||
|
self:F2( { self.ControllableName } )
|
||||||
|
if self:IsAir() then
|
||||||
|
self:SetOption("36","1")
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [AIR] Set how the AI lands on an airfield. Here: No landing in pairs.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:SetOptionLandingRestrictPair()
|
||||||
|
self:F2( { self.ControllableName } )
|
||||||
|
if self:IsAir() then
|
||||||
|
self:SetOption("36","2")
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [AIR] Set how the AI lands on an airfield. Here: Overhead break.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:SetOptionLandingOverheadBreak()
|
||||||
|
self:F2( { self.ControllableName } )
|
||||||
|
if self:IsAir() then
|
||||||
|
self:SetOption("36","3")
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- [AIR] Set how the AI uses the onboard radar.
|
--- [AIR] Set how the AI uses the onboard radar.
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @param #number Option Options are: `NEVER = 0, FOR_ATTACK_ONLY = 1,FOR_SEARCH_IF_REQUIRED = 2, FOR_CONTINUOUS_SEARCH = 3`
|
-- @param #number Option Options are: `NEVER = 0, FOR_ATTACK_ONLY = 1,FOR_SEARCH_IF_REQUIRED = 2, FOR_CONTINUOUS_SEARCH = 3`
|
||||||
|
|||||||
@ -2,17 +2,17 @@
|
|||||||
--
|
--
|
||||||
-- ## Main Features:
|
-- ## Main Features:
|
||||||
--
|
--
|
||||||
-- * Convenient access to DCS API functions
|
-- * Convenient access to Ground Crew created cargo items.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ## Example Missions:
|
-- ## Example Missions:
|
||||||
--
|
--
|
||||||
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_Demos/tree/master/Wrapper/Storage).
|
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_Demos/tree/master/).
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Applevangelist**
|
-- ### Author: **Applevangelist**; additional checks **Chesster**
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
-- @module Wrapper.DynamicCargo
|
-- @module Wrapper.DynamicCargo
|
||||||
@ -108,6 +108,8 @@ DYNAMICCARGO.State = {
|
|||||||
-- @type DYNAMICCARGO.AircraftTypes
|
-- @type DYNAMICCARGO.AircraftTypes
|
||||||
DYNAMICCARGO.AircraftTypes = {
|
DYNAMICCARGO.AircraftTypes = {
|
||||||
["CH-47Fbl1"] = "CH-47Fbl1",
|
["CH-47Fbl1"] = "CH-47Fbl1",
|
||||||
|
["Mi-8MTV2"] = "CH-47Fbl1",
|
||||||
|
["Mi-8MT"] = "CH-47Fbl1",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Helo types possible.
|
--- Helo types possible.
|
||||||
@ -120,17 +122,30 @@ DYNAMICCARGO.AircraftDimensions = {
|
|||||||
["length"] = 11,
|
["length"] = 11,
|
||||||
["ropelength"] = 30,
|
["ropelength"] = 30,
|
||||||
},
|
},
|
||||||
|
["Mi-8MTV2"] = {
|
||||||
|
["width"] = 6,
|
||||||
|
["height"] = 6,
|
||||||
|
["length"] = 15,
|
||||||
|
["ropelength"] = 30,
|
||||||
|
},
|
||||||
|
["Mi-8MT"] = {
|
||||||
|
["width"] = 6,
|
||||||
|
["height"] = 6,
|
||||||
|
["length"] = 15,
|
||||||
|
["ropelength"] = 30,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- DYNAMICCARGO class version.
|
--- DYNAMICCARGO class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
DYNAMICCARGO.version="0.0.5"
|
DYNAMICCARGO.version="0.0.9"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- TODO: A lot...
|
-- TODO: A lot...
|
||||||
|
-- DONE: Added Mi-8 type and dimensions
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Constructor
|
-- Constructor
|
||||||
@ -183,7 +198,7 @@ end
|
|||||||
-- @param #DYNAMICCARGO self
|
-- @param #DYNAMICCARGO self
|
||||||
-- @return DCS static object
|
-- @return DCS static object
|
||||||
function DYNAMICCARGO:GetDCSObject()
|
function DYNAMICCARGO:GetDCSObject()
|
||||||
local DCSStatic = Unit.getByName( self.StaticName )
|
local DCSStatic = StaticObject.getByName( self.StaticName ) or Unit.getByName( self.StaticName )
|
||||||
if DCSStatic then
|
if DCSStatic then
|
||||||
return DCSStatic
|
return DCSStatic
|
||||||
end
|
end
|
||||||
@ -227,7 +242,7 @@ end
|
|||||||
-- @param #DYNAMICCARGO self
|
-- @param #DYNAMICCARGO self
|
||||||
-- @return #boolean Outcome
|
-- @return #boolean Outcome
|
||||||
function DYNAMICCARGO:IsUnloaded()
|
function DYNAMICCARGO:IsUnloaded()
|
||||||
if self.CargoState and self.CargoState == DYNAMICCARGO.State.REMOVED then
|
if self.CargoState and self.CargoState == DYNAMICCARGO.State.UNLOADED then
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
@ -238,7 +253,7 @@ end
|
|||||||
-- @param #DYNAMICCARGO self
|
-- @param #DYNAMICCARGO self
|
||||||
-- @return #boolean Outcome
|
-- @return #boolean Outcome
|
||||||
function DYNAMICCARGO:IsRemoved()
|
function DYNAMICCARGO:IsRemoved()
|
||||||
if self.CargoState and self.CargoState == DYNAMICCARGO.State.UNLOADED then
|
if self.CargoState and self.CargoState == DYNAMICCARGO.State.REMOVED then
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
@ -376,6 +391,33 @@ end
|
|||||||
-- Private Functions
|
-- Private Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- [Internal] _Get helo hovering intel
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit The Unit to test
|
||||||
|
-- @param #number ropelength Ropelength to test
|
||||||
|
-- @return #boolean Outcome
|
||||||
|
function DYNAMICCARGO:_HeloHovering(Unit,ropelength)
|
||||||
|
local DCSUnit = Unit:GetDCSObject() --DCS#Unit
|
||||||
|
local hovering = false
|
||||||
|
local Height = 0
|
||||||
|
if DCSUnit then
|
||||||
|
local UnitInAir = DCSUnit:inAir()
|
||||||
|
local UnitCategory = DCSUnit:getDesc().category
|
||||||
|
if UnitInAir == true and UnitCategory == 1 then
|
||||||
|
local VelocityVec3 = DCSUnit:getVelocity()
|
||||||
|
local Velocity = UTILS.VecNorm(VelocityVec3)
|
||||||
|
local Coordinate = DCSUnit:getPoint()
|
||||||
|
local LandHeight = land.getHeight({ x = Coordinate.x, y = Coordinate.z })
|
||||||
|
Height = Coordinate.y - LandHeight
|
||||||
|
if Velocity < 1 and Height <= ropelength and Height > 6 then -- hover lower than ropelength but higher than the normal FARP height.
|
||||||
|
hovering = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return hovering, Height
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
--- [Internal] _Get Possible Player Helo Nearby
|
--- [Internal] _Get Possible Player Helo Nearby
|
||||||
-- @param #DYNAMICCARGO self
|
-- @param #DYNAMICCARGO self
|
||||||
-- @param Core.Point#COORDINATE pos
|
-- @param Core.Point#COORDINATE pos
|
||||||
@ -393,30 +435,37 @@ function DYNAMICCARGO:_GetPossibleHeloNearby(pos,loading)
|
|||||||
local name = helo:GetPlayerName() or _DATABASE:_FindPlayerNameByUnitName(helo:GetName()) or "None"
|
local name = helo:GetPlayerName() or _DATABASE:_FindPlayerNameByUnitName(helo:GetName()) or "None"
|
||||||
self:T(self.lid.." Checking: "..name)
|
self:T(self.lid.." Checking: "..name)
|
||||||
local hpos = helo:GetCoordinate()
|
local hpos = helo:GetCoordinate()
|
||||||
-- TODO Unloading via sling load?
|
-- TODO Check unloading via sling load?
|
||||||
--local inair = hpos.y-hpos:GetLandHeight() > 4.5 and true or false -- Standard FARP is 4.5m
|
|
||||||
local inair = helo:InAir()
|
|
||||||
self:T(self.lid.." InAir: AGL/InAir: "..hpos.y-hpos:GetLandHeight().."/"..tostring(inair))
|
|
||||||
local typename = helo:GetTypeName()
|
local typename = helo:GetTypeName()
|
||||||
if hpos and typename and inair == false then
|
|
||||||
local dimensions = DYNAMICCARGO.AircraftDimensions[typename]
|
local dimensions = DYNAMICCARGO.AircraftDimensions[typename]
|
||||||
if dimensions then
|
local hovering, height = self:_HeloHovering(helo,dimensions.ropelength)
|
||||||
|
local helolanded = not helo:InAir()
|
||||||
|
self:T(self.lid.." InAir: AGL/Hovering: "..hpos.y-hpos:GetLandHeight().."/"..tostring(hovering))
|
||||||
|
if hpos and typename and dimensions then
|
||||||
local delta2D = hpos:Get2DDistance(pos)
|
local delta2D = hpos:Get2DDistance(pos)
|
||||||
local delta3D = hpos:Get3DDistance(pos)
|
local delta3D = hpos:Get3DDistance(pos)
|
||||||
if self.testing then
|
if self.testing then
|
||||||
self:T(string.format("Cargo relative position: 2D %dm | 3D %dm",delta2D,delta3D))
|
self:T(string.format("Cargo relative position: 2D %dm | 3D %dm",delta2D,delta3D))
|
||||||
self:T(string.format("Helo dimension: length %dm | width %dm | rope %dm",dimensions.length,dimensions.width,dimensions.ropelength))
|
self:T(string.format("Helo dimension: length %dm | width %dm | rope %dm",dimensions.length,dimensions.width,dimensions.ropelength))
|
||||||
|
self:T(string.format("Helo hovering: %s at %dm",tostring(hovering),height))
|
||||||
end
|
end
|
||||||
if loading~=true and delta2D > dimensions.length or delta2D > dimensions.width or delta3D > dimensions.ropelength then
|
-- unloading from ground
|
||||||
|
if loading~=true and (delta2D > dimensions.length or delta2D > dimensions.width) and helolanded then -- Theoretically the cargo could still be attached to the sling if landed next to the cargo. But once moved again it would go back into loaded state once lifted again.
|
||||||
success = true
|
success = true
|
||||||
Helo = helo
|
Helo = helo
|
||||||
Playername = name
|
Playername = name
|
||||||
end
|
end
|
||||||
if loading == true and delta2D < dimensions.length or delta2D < dimensions.width or delta3D < dimensions.ropelength then
|
-- unloading from hover/rope
|
||||||
|
if loading~=true and delta3D > dimensions.ropelength then
|
||||||
success = true
|
success = true
|
||||||
Helo = helo
|
Helo = helo
|
||||||
Playername = name
|
Playername = name
|
||||||
end
|
end
|
||||||
|
-- loading
|
||||||
|
if loading == true and ((delta2D < dimensions.length and delta2D < dimensions.width and helolanded) or (delta3D == dimensions.ropelength and helo:InAir())) then -- Loaded via ground or sling
|
||||||
|
success = true
|
||||||
|
Helo = helo
|
||||||
|
Playername = name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -434,19 +483,21 @@ function DYNAMICCARGO:_UpdatePosition()
|
|||||||
self:T(string.format("Cargo position: x=%d, y=%d, z=%d",pos.x,pos.y,pos.z))
|
self:T(string.format("Cargo position: x=%d, y=%d, z=%d",pos.x,pos.y,pos.z))
|
||||||
self:T(string.format("Last position: x=%d, y=%d, z=%d",self.LastPosition.x,self.LastPosition.y,self.LastPosition.z))
|
self:T(string.format("Last position: x=%d, y=%d, z=%d",self.LastPosition.x,self.LastPosition.y,self.LastPosition.z))
|
||||||
end
|
end
|
||||||
if UTILS.Round(UTILS.VecDist3D(pos,self.LastPosition),2) > 0.5 then
|
if UTILS.Round(UTILS.VecDist3D(pos,self.LastPosition),2) > 0.5 then -- This checks if the cargo has moved more than 0.5m since last check. If so then the cargo is loaded
|
||||||
---------------
|
---------------
|
||||||
-- LOAD Cargo
|
-- LOAD Cargo
|
||||||
---------------
|
---------------
|
||||||
if self.CargoState == DYNAMICCARGO.State.NEW then
|
if self.CargoState == DYNAMICCARGO.State.NEW or self.CargoState == DYNAMICCARGO.State.UNLOADED then
|
||||||
local isloaded, client, playername = self:_GetPossibleHeloNearby(pos,true)
|
local isloaded, client, playername = self:_GetPossibleHeloNearby(pos,true)
|
||||||
self:T(self.lid.." moved! NEW -> LOADED by "..tostring(playername))
|
self:T(self.lid.." moved! NEW -> LOADED by "..tostring(playername))
|
||||||
self.CargoState = DYNAMICCARGO.State.LOADED
|
self.CargoState = DYNAMICCARGO.State.LOADED
|
||||||
self.Owner = playername
|
self.Owner = playername
|
||||||
_DATABASE:CreateEventDynamicCargoLoaded(self)
|
_DATABASE:CreateEventDynamicCargoLoaded(self)
|
||||||
|
end
|
||||||
---------------
|
---------------
|
||||||
-- UNLOAD Cargo
|
-- UNLOAD Cargo
|
||||||
---------------
|
---------------
|
||||||
|
-- If the cargo is stationary then we need to end this condition here to check whether it is unloaded or still onboard or still hooked if anyone can hover that precisly
|
||||||
elseif self.CargoState == DYNAMICCARGO.State.LOADED then
|
elseif self.CargoState == DYNAMICCARGO.State.LOADED then
|
||||||
-- TODO add checker if we are in flight somehow
|
-- TODO add checker if we are in flight somehow
|
||||||
-- ensure not just the helo is moving
|
-- ensure not just the helo is moving
|
||||||
@ -459,26 +510,19 @@ function DYNAMICCARGO:_UpdatePosition()
|
|||||||
local isunloaded = true
|
local isunloaded = true
|
||||||
local client
|
local client
|
||||||
local playername = self.Owner
|
local playername = self.Owner
|
||||||
if count > 0 and (agl > 0 or self.testing) then
|
if count > 0 then
|
||||||
self:T(self.lid.." Possible alive helos: "..count or -1)
|
self:T(self.lid.." Possible alive helos: "..count or -1)
|
||||||
if agl ~= 0 or self.testing then
|
|
||||||
isunloaded, client, playername = self:_GetPossibleHeloNearby(pos,false)
|
isunloaded, client, playername = self:_GetPossibleHeloNearby(pos,false)
|
||||||
end
|
|
||||||
if isunloaded then
|
if isunloaded then
|
||||||
self:T(self.lid.." moved! LOADED -> UNLOADED by "..tostring(playername))
|
self:T(self.lid.." moved! LOADED -> UNLOADED by "..tostring(playername))
|
||||||
self.CargoState = DYNAMICCARGO.State.UNLOADED
|
self.CargoState = DYNAMICCARGO.State.UNLOADED
|
||||||
self.Owner = playername
|
self.Owner = playername
|
||||||
_DATABASE:CreateEventDynamicCargoUnloaded(self)
|
_DATABASE:CreateEventDynamicCargoUnloaded(self)
|
||||||
end
|
end
|
||||||
elseif count > 0 and agl == 0 then
|
|
||||||
self:T(self.lid.." moved! LOADED -> UNLOADED by "..tostring(playername))
|
|
||||||
self.CargoState = DYNAMICCARGO.State.UNLOADED
|
|
||||||
self.Owner = playername
|
|
||||||
_DATABASE:CreateEventDynamicCargoUnloaded(self)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.LastPosition = pos
|
self.LastPosition = pos
|
||||||
end
|
--end
|
||||||
else
|
else
|
||||||
---------------
|
---------------
|
||||||
-- REMOVED Cargo
|
-- REMOVED Cargo
|
||||||
|
|||||||
@ -230,6 +230,8 @@ GROUP.Attribute = {
|
|||||||
GROUND_EWR="Ground_EWR",
|
GROUND_EWR="Ground_EWR",
|
||||||
GROUND_AAA="Ground_AAA",
|
GROUND_AAA="Ground_AAA",
|
||||||
GROUND_SAM="Ground_SAM",
|
GROUND_SAM="Ground_SAM",
|
||||||
|
GROUND_SHORAD="Ground_SHORAD",
|
||||||
|
GROUND_BALLISTICMISSILE="Ground_BallisticMissile",
|
||||||
GROUND_OTHER="Ground_OtherGround",
|
GROUND_OTHER="Ground_OtherGround",
|
||||||
NAVAL_AIRCRAFTCARRIER="Naval_AircraftCarrier",
|
NAVAL_AIRCRAFTCARRIER="Naval_AircraftCarrier",
|
||||||
NAVAL_WARSHIP="Naval_WarShip",
|
NAVAL_WARSHIP="Naval_WarShip",
|
||||||
@ -912,15 +914,18 @@ function GROUP:GetVelocityVec3()
|
|||||||
|
|
||||||
if DCSGroup and DCSGroup:isExist() then
|
if DCSGroup and DCSGroup:isExist() then
|
||||||
local GroupUnits = DCSGroup:getUnits()
|
local GroupUnits = DCSGroup:getUnits()
|
||||||
local GroupCount = #GroupUnits
|
local GroupCount = 0
|
||||||
|
|
||||||
local VelocityVec3 = { x = 0, y = 0, z = 0 }
|
local VelocityVec3 = { x = 0, y = 0, z = 0 }
|
||||||
|
|
||||||
for _, DCSUnit in pairs( GroupUnits ) do
|
for _, DCSUnit in pairs( GroupUnits ) do
|
||||||
|
if DCSUnit:isExist() and DCSUnit:isActive() then
|
||||||
local UnitVelocityVec3 = DCSUnit:getVelocity()
|
local UnitVelocityVec3 = DCSUnit:getVelocity()
|
||||||
VelocityVec3.x = VelocityVec3.x + UnitVelocityVec3.x
|
VelocityVec3.x = VelocityVec3.x + UnitVelocityVec3.x
|
||||||
VelocityVec3.y = VelocityVec3.y + UnitVelocityVec3.y
|
VelocityVec3.y = VelocityVec3.y + UnitVelocityVec3.y
|
||||||
VelocityVec3.z = VelocityVec3.z + UnitVelocityVec3.z
|
VelocityVec3.z = VelocityVec3.z + UnitVelocityVec3.z
|
||||||
|
GroupCount = GroupCount + 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
VelocityVec3.x = VelocityVec3.x / GroupCount
|
VelocityVec3.x = VelocityVec3.x / GroupCount
|
||||||
@ -1179,9 +1184,9 @@ function GROUP:GetAverageVec3()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a POINT_VEC2 object indicating the point in 2D of the first UNIT of the GROUP within the mission.
|
--- Returns a COORDINATE object indicating the point in 2D of the first UNIT of the GROUP within the mission.
|
||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return Core.Point#POINT_VEC2 The 2D point vector of the first DCS Unit of the GROUP.
|
-- @return Core.Point#COORDINATE The 3D point vector of the first DCS Unit of the GROUP.
|
||||||
-- @return #nil The first UNIT is not existing or alive.
|
-- @return #nil The first UNIT is not existing or alive.
|
||||||
function GROUP:GetPointVec2()
|
function GROUP:GetPointVec2()
|
||||||
--self:F2(self.GroupName)
|
--self:F2(self.GroupName)
|
||||||
@ -1194,7 +1199,7 @@ function GROUP:GetPointVec2()
|
|||||||
return FirstUnitPointVec2
|
return FirstUnitPointVec2
|
||||||
end
|
end
|
||||||
|
|
||||||
BASE:E( { "Cannot GetPointVec2", Group = self, Alive = self:IsAlive() } )
|
BASE:E( { "Cannot get COORDINATE", Group = self, Alive = self:IsAlive() } )
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
@ -1754,6 +1759,7 @@ function GROUP:GetMaxVelocity()
|
|||||||
|
|
||||||
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
|
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
|
||||||
|
|
||||||
|
if UnitData:isExist() and UnitData:isActive() then
|
||||||
local UnitVelocityVec3 = UnitData:getVelocity()
|
local UnitVelocityVec3 = UnitData:getVelocity()
|
||||||
local UnitVelocity = math.abs( UnitVelocityVec3.x ) + math.abs( UnitVelocityVec3.y ) + math.abs( UnitVelocityVec3.z )
|
local UnitVelocity = math.abs( UnitVelocityVec3.x ) + math.abs( UnitVelocityVec3.y ) + math.abs( UnitVelocityVec3.z )
|
||||||
|
|
||||||
@ -1761,6 +1767,7 @@ function GROUP:GetMaxVelocity()
|
|||||||
GroupVelocityMax = UnitVelocity
|
GroupVelocityMax = UnitVelocity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return GroupVelocityMax
|
return GroupVelocityMax
|
||||||
end
|
end
|
||||||
@ -1843,7 +1850,10 @@ end
|
|||||||
-- @return #table
|
-- @return #table
|
||||||
function GROUP:GetTemplateRoutePoints()
|
function GROUP:GetTemplateRoutePoints()
|
||||||
local GroupName = self:GetName()
|
local GroupName = self:GetName()
|
||||||
return UTILS.DeepCopy( _DATABASE:GetGroupTemplate( GroupName ).route.points )
|
local template = _DATABASE:GetGroupTemplate(GroupName)
|
||||||
|
if template and template.route and template.route.points then
|
||||||
|
return UTILS.DeepCopy(template.route.points)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -2093,7 +2103,7 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
GroupUnitVec3 = Zone:GetRandomVec3()
|
GroupUnitVec3 = Zone:GetRandomVec3()
|
||||||
else
|
else
|
||||||
if self.InitRespawnRandomizePositionInner and self.InitRespawnRandomizePositionOuter then
|
if self.InitRespawnRandomizePositionInner and self.InitRespawnRandomizePositionOuter then
|
||||||
GroupUnitVec3 = POINT_VEC3:NewFromVec2( From ):GetRandomPointVec3InRadius( self.InitRespawnRandomizePositionsOuter, self.InitRespawnRandomizePositionsInner )
|
GroupUnitVec3 = COORDINATE:NewFromVec3(From):GetRandomVec3InRadius(self.InitRespawnRandomizePositionsOuter, self.InitRespawnRandomizePositionsInner)
|
||||||
else
|
else
|
||||||
GroupUnitVec3 = Zone:GetVec3()
|
GroupUnitVec3 = Zone:GetVec3()
|
||||||
end
|
end
|
||||||
@ -2144,7 +2154,7 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
GroupUnitVec3 = Zone:GetRandomVec3()
|
GroupUnitVec3 = Zone:GetRandomVec3()
|
||||||
else
|
else
|
||||||
if self.InitRespawnRandomizePositionInner and self.InitRespawnRandomizePositionOuter then
|
if self.InitRespawnRandomizePositionInner and self.InitRespawnRandomizePositionOuter then
|
||||||
GroupUnitVec3 = POINT_VEC3:NewFromVec2( From ):GetRandomPointVec3InRadius( self.InitRespawnRandomizePositionsOuter, self.InitRespawnRandomizePositionsInner )
|
GroupUnitVec3 = COORDINATE:NewFromVec2( From ):GetRandomPointVec3InRadius( self.InitRespawnRandomizePositionsOuter, self.InitRespawnRandomizePositionsInner )
|
||||||
else
|
else
|
||||||
GroupUnitVec3 = Zone:GetVec3()
|
GroupUnitVec3 = Zone:GetVec3()
|
||||||
end
|
end
|
||||||
@ -2222,6 +2232,10 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
|
|
||||||
--UTILS.PrintTableToLog(Template)
|
--UTILS.PrintTableToLog(Template)
|
||||||
|
|
||||||
|
if self.ValidateAndRepositionGroundUnits then
|
||||||
|
UTILS.ValidateAndRepositionGroundUnits(Template.units)
|
||||||
|
end
|
||||||
|
|
||||||
-- Spawn new group.
|
-- Spawn new group.
|
||||||
self:ScheduleOnce(0.1,_DATABASE.Spawn,_DATABASE,Template)
|
self:ScheduleOnce(0.1,_DATABASE.Spawn,_DATABASE,Template)
|
||||||
--_DATABASE:Spawn(Template)
|
--_DATABASE:Spawn(Template)
|
||||||
@ -2630,6 +2644,8 @@ function GROUP:GetAttribute()
|
|||||||
local artillery=self:HasAttribute("Artillery")
|
local artillery=self:HasAttribute("Artillery")
|
||||||
local tank=self:HasAttribute("Old Tanks") or self:HasAttribute("Modern Tanks") or self:HasAttribute("Tanks")
|
local tank=self:HasAttribute("Old Tanks") or self:HasAttribute("Modern Tanks") or self:HasAttribute("Tanks")
|
||||||
local aaa=self:HasAttribute("AAA") and (not self:HasAttribute("SAM elements"))
|
local aaa=self:HasAttribute("AAA") and (not self:HasAttribute("SAM elements"))
|
||||||
|
local ballisticMissile=artillery and self:HasAttribute("SS_missile")
|
||||||
|
local shorad=self:HasAttribute("SR SAM")
|
||||||
local ewr=self:HasAttribute("EWR")
|
local ewr=self:HasAttribute("EWR")
|
||||||
local ifv=self:HasAttribute("IFV")
|
local ifv=self:HasAttribute("IFV")
|
||||||
local sam=self:HasAttribute("SAM elements") or self:HasAttribute("Optical Tracker")
|
local sam=self:HasAttribute("SAM elements") or self:HasAttribute("Optical Tracker")
|
||||||
@ -2671,6 +2687,8 @@ function GROUP:GetAttribute()
|
|||||||
attribute=GROUP.Attribute.GROUND_SAM
|
attribute=GROUP.Attribute.GROUND_SAM
|
||||||
elseif aaa then
|
elseif aaa then
|
||||||
attribute=GROUP.Attribute.GROUND_AAA
|
attribute=GROUP.Attribute.GROUND_AAA
|
||||||
|
elseif artillery and ballisticMissile then
|
||||||
|
attribute=GROUP.Attribute.GROUND_BALLISTICMISSILE
|
||||||
elseif artillery then
|
elseif artillery then
|
||||||
attribute=GROUP.Attribute.GROUND_ARTILLERY
|
attribute=GROUP.Attribute.GROUND_ARTILLERY
|
||||||
elseif tank then
|
elseif tank then
|
||||||
@ -3183,3 +3201,60 @@ function GROUP:IsAAA()
|
|||||||
end
|
end
|
||||||
return isAAA
|
return isAAA
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- This function uses Disposition and other fallback logic to find better ground positions for ground units.
|
||||||
|
--- NOTE: This is not a spawn randomizer.
|
||||||
|
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
|
||||||
|
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
||||||
|
--- Uses UTILS.ValidateAndRepositionGroundUnits.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @param #boolean Enabled Enable/disable the feature.
|
||||||
|
function GROUP:SetValidateAndRepositionGroundUnits(Enabled)
|
||||||
|
self.ValidateAndRepositionGroundUnits = Enabled
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the bounding box of the group combining UNIT:GetBoundingBox() units.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @return DCS#Box3 The bounding box of the GROUP.
|
||||||
|
-- @return #nil The GROUP does not have any alive units.
|
||||||
|
function GROUP:GetBoundingBox()
|
||||||
|
local bbox = { min = { x = math.huge, y = math.huge, z = math.huge },
|
||||||
|
max = { x = -math.huge, y = -math.huge, z = -math.huge }
|
||||||
|
}
|
||||||
|
|
||||||
|
local Units = self:GetUnits() or {}
|
||||||
|
if #Units == 0 then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, unit in pairs(Units) do
|
||||||
|
if unit and unit:IsAlive() then
|
||||||
|
local ubox = unit:GetBoundingBox()
|
||||||
|
|
||||||
|
if ubox then
|
||||||
|
if ubox.min.x < bbox.min.x then
|
||||||
|
bbox.min.x = ubox.min.x
|
||||||
|
end
|
||||||
|
if ubox.min.y < bbox.min.y then
|
||||||
|
bbox.min.y = ubox.min.y
|
||||||
|
end
|
||||||
|
if ubox.min.z < bbox.min.z then
|
||||||
|
bbox.min.z = ubox.min.z
|
||||||
|
end
|
||||||
|
|
||||||
|
if ubox.max.x > bbox.max.x then
|
||||||
|
bbox.max.x = ubox.max.x
|
||||||
|
end
|
||||||
|
if ubox.max.y > bbox.max.y then
|
||||||
|
bbox.max.y = ubox.max.y
|
||||||
|
end
|
||||||
|
if ubox.max.z > bbox.max.z then
|
||||||
|
bbox.max.z = ubox.max.z
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return bbox
|
||||||
|
end
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
--- @type POSITIONABLE
|
--- @type POSITIONABLE
|
||||||
-- @field Core.Point#COORDINATE coordinate Coordinate object.
|
-- @field Core.Point#COORDINATE coordinate Coordinate object.
|
||||||
-- @field Core.Point#POINT_VEC3 pointvec3 Point Vec3 object.
|
-- @field Core.Point#COORDINATE pointvec3 Point Vec3 object.
|
||||||
-- @extends Wrapper.Identifiable#IDENTIFIABLE
|
-- @extends Wrapper.Identifiable#IDENTIFIABLE
|
||||||
|
|
||||||
|
|
||||||
@ -246,18 +246,20 @@ end
|
|||||||
function POSITIONABLE:GetVec3()
|
function POSITIONABLE:GetVec3()
|
||||||
local DCSPositionable = self:GetDCSObject()
|
local DCSPositionable = self:GetDCSObject()
|
||||||
if DCSPositionable then
|
if DCSPositionable then
|
||||||
--local status, vec3 = pcall(
|
|
||||||
-- function()
|
|
||||||
-- local vec3 = DCSPositionable:getPoint()
|
|
||||||
-- return vec3
|
|
||||||
--end
|
|
||||||
--)
|
|
||||||
local vec3 = DCSPositionable:getPoint()
|
local vec3 = DCSPositionable:getPoint()
|
||||||
--if status then
|
|
||||||
|
if not vec3 then
|
||||||
|
local pos = DCSPositionable:getPosition()
|
||||||
|
if pos and pos.p then
|
||||||
|
vec3 = pos.p
|
||||||
|
else
|
||||||
|
self:E( { "Cannot get the position from DCS Object for GetVec3", Positionable = self, Alive = self:IsAlive() } )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return vec3
|
return vec3
|
||||||
--else
|
|
||||||
--self:E( { "Cannot get Vec3 from DCS Object", Positionable = self, Alive = self:IsAlive() } )
|
|
||||||
--end
|
|
||||||
end
|
end
|
||||||
-- ERROR!
|
-- ERROR!
|
||||||
self:E( { "Cannot get the Positionable DCS Object for GetVec3", Positionable = self, Alive = self:IsAlive() } )
|
self:E( { "Cannot get the Positionable DCS Object for GetVec3", Positionable = self, Alive = self:IsAlive() } )
|
||||||
@ -284,9 +286,9 @@ function POSITIONABLE:GetVec2()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a POINT_VEC2 object indicating the point in 2D of the POSITIONABLE within the mission.
|
--- Returns a COORDINATE object indicating the point in 2D of the POSITIONABLE within the mission.
|
||||||
-- @param #POSITIONABLE self
|
-- @param #POSITIONABLE self
|
||||||
-- @return Core.Point#POINT_VEC2 The 2D point vector of the POSITIONABLE.
|
-- @return Core.Point#COORDINATE The 3D point vector of the POSITIONABLE.
|
||||||
-- @return #nil The POSITIONABLE is not existing or alive.
|
-- @return #nil The POSITIONABLE is not existing or alive.
|
||||||
function POSITIONABLE:GetPointVec2()
|
function POSITIONABLE:GetPointVec2()
|
||||||
self:F2( self.PositionableName )
|
self:F2( self.PositionableName )
|
||||||
@ -296,20 +298,20 @@ function POSITIONABLE:GetPointVec2()
|
|||||||
if DCSPositionable then
|
if DCSPositionable then
|
||||||
local PositionableVec3 = DCSPositionable:getPosition().p
|
local PositionableVec3 = DCSPositionable:getPosition().p
|
||||||
|
|
||||||
local PositionablePointVec2 = POINT_VEC2:NewFromVec3( PositionableVec3 )
|
local PositionablePointVec2 = COORDINATE:NewFromVec3( PositionableVec3 )
|
||||||
|
|
||||||
-- self:F( PositionablePointVec2 )
|
-- self:F( PositionablePointVec2 )
|
||||||
return PositionablePointVec2
|
return PositionablePointVec2
|
||||||
end
|
end
|
||||||
|
|
||||||
self:E( { "Cannot GetPointVec2", Positionable = self, Alive = self:IsAlive() } )
|
self:E( { "Cannot Coordinate", Positionable = self, Alive = self:IsAlive() } )
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a POINT_VEC3 object indicating the point in 3D of the POSITIONABLE within the mission.
|
--- Returns a COORDINATE object indicating the point in 3D of the POSITIONABLE within the mission.
|
||||||
-- @param #POSITIONABLE self
|
-- @param #POSITIONABLE self
|
||||||
-- @return Core.Point#POINT_VEC3 The 3D point vector of the POSITIONABLE.
|
-- @return Core.Point#COORDINATE The 3D point vector of the POSITIONABLE.
|
||||||
-- @return #nil The POSITIONABLE is not existing or alive.
|
-- @return #nil The POSITIONABLE is not existing or alive.
|
||||||
function POSITIONABLE:GetPointVec3()
|
function POSITIONABLE:GetPointVec3()
|
||||||
|
|
||||||
@ -329,8 +331,8 @@ function POSITIONABLE:GetPointVec3()
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
-- Create a new POINT_VEC3 object.
|
-- Create a new COORDINATE object.
|
||||||
self.pointvec3 = POINT_VEC3:NewFromVec3( PositionableVec3 )
|
self.pointvec3 = COORDINATE:NewFromVec3( PositionableVec3 )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -359,6 +361,7 @@ function POSITIONABLE:GetCoord()
|
|||||||
-- Get the current position.
|
-- Get the current position.
|
||||||
local PositionableVec3 = self:GetVec3()
|
local PositionableVec3 = self:GetVec3()
|
||||||
|
|
||||||
|
if PositionableVec3 then
|
||||||
if self.coordinate then
|
if self.coordinate then
|
||||||
-- Update COORDINATE from 3D vector.
|
-- Update COORDINATE from 3D vector.
|
||||||
self.coordinate:UpdateFromVec3( PositionableVec3 )
|
self.coordinate:UpdateFromVec3( PositionableVec3 )
|
||||||
@ -369,6 +372,7 @@ function POSITIONABLE:GetCoord()
|
|||||||
|
|
||||||
return self.coordinate
|
return self.coordinate
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Error message.
|
-- Error message.
|
||||||
BASE:E( { "Cannot GetCoordinate", Positionable = self, Alive = self:IsAlive() } )
|
BASE:E( { "Cannot GetCoordinate", Positionable = self, Alive = self:IsAlive() } )
|
||||||
@ -388,13 +392,13 @@ function POSITIONABLE:GetCoordinate()
|
|||||||
|
|
||||||
-- Get the current position.
|
-- Get the current position.
|
||||||
local PositionableVec3 = self:GetVec3()
|
local PositionableVec3 = self:GetVec3()
|
||||||
|
if PositionableVec3 then
|
||||||
local coord=COORDINATE:NewFromVec3(PositionableVec3)
|
local coord=COORDINATE:NewFromVec3(PositionableVec3)
|
||||||
local heading = self:GetHeading()
|
local heading = self:GetHeading()
|
||||||
coord.Heading = heading
|
coord.Heading = heading
|
||||||
-- Return a new coordiante object.
|
-- Return a new coordiante object.
|
||||||
return coord
|
return coord
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Error message.
|
-- Error message.
|
||||||
@ -1861,6 +1865,7 @@ do -- Cargo
|
|||||||
["HL_DSHK"] = 6*POSITIONABLE.DefaultInfantryWeight,
|
["HL_DSHK"] = 6*POSITIONABLE.DefaultInfantryWeight,
|
||||||
["CCKW_353"] = 16*POSITIONABLE.DefaultInfantryWeight, --GMC CCKW 2½-ton 6×6 truck, estimating 16 soldiers,
|
["CCKW_353"] = 16*POSITIONABLE.DefaultInfantryWeight, --GMC CCKW 2½-ton 6×6 truck, estimating 16 soldiers,
|
||||||
["MaxxPro_MRAP"] = 7*POSITIONABLE.DefaultInfantryWeight,
|
["MaxxPro_MRAP"] = 7*POSITIONABLE.DefaultInfantryWeight,
|
||||||
|
["Sd_Kfz_251"] = 10*POSITIONABLE.DefaultInfantryWeight,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -753,7 +753,7 @@ function STORAGE:LoadFromFile(Path,Filename)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:E("File for Liquids could not be found: "..tostring(Path).."\\"..tostring(Filename"_Liquids.csv"))
|
self:E("File for Liquids could not be found: "..tostring(Path).."\\"..tostring(Filename).."_Liquids.csv")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -773,7 +773,7 @@ function STORAGE:LoadFromFile(Path,Filename)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:E("File for Aircraft could not be found: "..tostring(Path).."\\"..tostring(Filename"_Aircraft.csv"))
|
self:E("File for Aircraft could not be found: "..tostring(Path).."\\"..tostring(Filename).."_Aircraft.csv")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -805,7 +805,7 @@ function STORAGE:LoadFromFile(Path,Filename)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:E("File for Weapons could not be found: "..tostring(Path).."\\"..tostring(Filename"_Weapons.csv"))
|
self:E("File for Weapons could not be found: "..tostring(Path).."\\"..tostring(Filename).."_Weapons.csv")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -377,6 +377,10 @@ function UNIT:ReSpawnAt(Coordinate, Heading)
|
|||||||
|
|
||||||
--self:T( SpawnGroupTemplate )
|
--self:T( SpawnGroupTemplate )
|
||||||
|
|
||||||
|
if self.ValidateAndRepositionGroundUnits then
|
||||||
|
UTILS.ValidateAndRepositionGroundUnits(SpawnGroupTemplate.units)
|
||||||
|
end
|
||||||
|
|
||||||
_DATABASE:Spawn(SpawnGroupTemplate)
|
_DATABASE:Spawn(SpawnGroupTemplate)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -897,7 +901,7 @@ function UNIT:GetAmmunition()
|
|||||||
nAPshells = nAPshells + Nammo
|
nAPshells = nAPshells + Nammo
|
||||||
end
|
end
|
||||||
|
|
||||||
if ammotable[w].desc.typeName and string.find(ammotable[w].desc.typeName, "_HE", 1, true) then
|
if ammotable[w].desc.typeName and (string.find(ammotable[w].desc.typeName, "_HE", 1, true) or string.find(ammotable[w].desc.typeName, "HESH", 1, true)) then
|
||||||
nHEshells = nHEshells + Nammo
|
nHEshells = nHEshells + Nammo
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1107,7 +1111,6 @@ function UNIT:GetUnits()
|
|||||||
|
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
Units[1] = UNIT:Find(DCSUnit)
|
Units[1] = UNIT:Find(DCSUnit)
|
||||||
- self:T3(Units)
|
|
||||||
return Units
|
return Units
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1925,3 +1928,28 @@ function UNIT:IsAAA()
|
|||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set the relative life points of a UNIT object
|
||||||
|
-- @param #UNIT self
|
||||||
|
-- @param #number Percent Percent to set, can be 0..100.
|
||||||
|
function UNIT:SetLife(Percent)
|
||||||
|
net.dostring_in("mission",string.format("a_unit_set_life_percentage(%d, %f)", self:GetID(), Percent))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the carrier illumination mode. -2: OFF, -1: AUTO, 0: NAVIGATION, 1: AC LAUNCH, 2: AC RECOVERY
|
||||||
|
-- @param #UNIT self
|
||||||
|
-- @param #number Mode Illumination mode, can be -2: OFF, -1: AUTO, 0: NAVIGATION, 1: AC LAUNCH, 2: AC RECOVERY
|
||||||
|
function UNIT:SetCarrierIlluminationMode(Mode)
|
||||||
|
UTILS.SetCarrierIlluminationMode(self:GetID(), Mode)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- This function uses Disposition and other fallback logic to find better ground positions for ground units.
|
||||||
|
--- NOTE: This is not a spawn randomizer.
|
||||||
|
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
|
||||||
|
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
|
||||||
|
--- Uses UTILS.ValidateAndRepositionGroundUnits.
|
||||||
|
-- @param #UNIT self
|
||||||
|
-- @param #boolean Enabled Enable/disable the feature.
|
||||||
|
function UNIT:SetValidateAndRepositionGroundUnits(Enabled)
|
||||||
|
self.ValidateAndRepositionGroundUnits = Enabled
|
||||||
|
end
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
# import required module
|
# import required module
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import os
|
import os
|
||||||
|
import codecs
|
||||||
|
|
||||||
# assign directory
|
# assign directory
|
||||||
directory = '.'
|
directory = '.'
|
||||||
@ -16,7 +17,8 @@ with open( os.path.dirname(__file__) + '/docs-header.html', 'r') as file:
|
|||||||
files = Path(directory).glob('*.html')
|
files = Path(directory).glob('*.html')
|
||||||
for file in files:
|
for file in files:
|
||||||
#print(file)
|
#print(file)
|
||||||
with open(file, 'r') as fileread:
|
#with open(file, 'r') as fileread:
|
||||||
|
with codecs.open(file, 'r', encoding='utf-8', errors='ignore') as fileread:
|
||||||
filedata = fileread.read()
|
filedata = fileread.read()
|
||||||
# Replace the target string
|
# Replace the target string
|
||||||
filedata = filedata.replace( '<head>', newhead )
|
filedata = filedata.replace( '<head>', newhead )
|
||||||
|
|||||||
@ -169,10 +169,6 @@ Defines an extensive API to manage 3D points in the DCS World 3D simulation spac
|
|||||||
**Features:**
|
**Features:**
|
||||||
|
|
||||||
* Provides a COORDINATE class, which allows to manage points in 3D space and perform various operations on it.
|
* Provides a COORDINATE class, which allows to manage points in 3D space and perform various operations on it.
|
||||||
* Provides a POINT_VEC2 class, which is derived from COORDINATE, and allows to manage points in 3D space, but from a
|
|
||||||
Lat/Lon and Altitude perspective.
|
|
||||||
* Provides a POINT_VEC3 class, which is derived from COORDINATE, and allows to manage points in 3D space, but from a
|
|
||||||
X, Z and Y vector perspective.
|
|
||||||
|
|
||||||
**The coordinate system classes are essential to understand. Learn this!**
|
**The coordinate system classes are essential to understand. Learn this!**
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user