mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Compare commits
161 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f20b830b7 | ||
|
|
0678ad17f8 | ||
|
|
be4beea9d0 | ||
|
|
5da899138b | ||
|
|
1ec1e00bde | ||
|
|
d7d46d4f1b | ||
|
|
5d93b33d42 | ||
|
|
b2077bfc74 | ||
|
|
e958ca103a | ||
|
|
1d9ef869a7 | ||
|
|
6fdf9a649f | ||
|
|
90c6c57449 | ||
|
|
d013bbc751 | ||
|
|
e0092fdba0 | ||
|
|
ecce2eff9b | ||
|
|
fbeada439f | ||
|
|
6c8858d2f5 | ||
|
|
e2b77878df | ||
|
|
53d7972858 | ||
|
|
04a55e4104 | ||
|
|
d11acecdac | ||
|
|
0531b8f57e | ||
|
|
98e2997e26 | ||
|
|
7d3bffcfef | ||
|
|
5b76ec6b99 | ||
|
|
4b23c86daa | ||
|
|
49c11073e6 | ||
|
|
daa5caa125 | ||
|
|
1a156e7e12 | ||
|
|
6fe88a6319 | ||
|
|
1856754614 | ||
|
|
b9f6c1b9c7 | ||
|
|
6ac452ff15 | ||
|
|
b52176a0ff | ||
|
|
d707a4775c | ||
|
|
ffccc31e38 | ||
|
|
0405af2bde | ||
|
|
d09f0b1f6f | ||
|
|
e50e572c78 | ||
|
|
2e688e7da1 | ||
|
|
3083599158 | ||
|
|
2921f7a76b | ||
|
|
b7b6c1ea19 | ||
|
|
8a185c352e | ||
|
|
5b107ce2da | ||
|
|
5c1e342a79 | ||
|
|
3fc8f52796 | ||
|
|
ddf33da787 | ||
|
|
e7cee4d97b | ||
|
|
b0a192a767 | ||
|
|
986c340211 | ||
|
|
2109537f86 | ||
|
|
bad9d1ea92 | ||
|
|
690db7f12f | ||
|
|
4f3fd06cc9 | ||
|
|
f5b1050086 | ||
|
|
4074023ed3 | ||
|
|
f729b1d358 | ||
|
|
6c00b0c7eb | ||
|
|
5adefe6f7b | ||
|
|
76dc0d690a | ||
|
|
13c16b8674 | ||
|
|
222722225e | ||
|
|
82e1dcfc04 | ||
|
|
c26220d1fd | ||
|
|
d783f7be99 | ||
|
|
b66e91b11f | ||
|
|
eeca95c77f | ||
|
|
e406fb0c88 | ||
|
|
bdec6eb82d | ||
|
|
9bdacfbcf7 | ||
|
|
be2eda25df | ||
|
|
fa8e1d2a56 | ||
|
|
5242754c60 | ||
|
|
3dbafd7a19 | ||
|
|
56e751193a | ||
|
|
b2b258cff0 | ||
|
|
75068a2a26 | ||
|
|
d82df93eff | ||
|
|
5168380eac | ||
|
|
a7ffbab850 | ||
|
|
a238294079 | ||
|
|
accb4b45fb | ||
|
|
ba4ff5c9e9 | ||
|
|
171c450576 | ||
|
|
f35078b426 | ||
|
|
8921007805 | ||
|
|
8fd3034503 | ||
|
|
a20b6e8a62 | ||
|
|
4ce6cc7776 | ||
|
|
434296ab11 | ||
|
|
a5232f49c0 | ||
|
|
befc8207f5 | ||
|
|
23947b7c30 | ||
|
|
da91b710a9 | ||
|
|
d656bbc014 | ||
|
|
ed23f11e4a | ||
|
|
068465a8f2 | ||
|
|
4e24a7bf80 | ||
|
|
1ece7238dc | ||
|
|
db53f427e3 | ||
|
|
d2e2c51275 | ||
|
|
691748082b | ||
|
|
b294ef10c8 | ||
|
|
5d40091947 | ||
|
|
7453a6c55d | ||
|
|
153ef7cd08 | ||
|
|
b6a550a247 | ||
|
|
3568f27150 | ||
|
|
c46061466c | ||
|
|
9c7b5e8506 | ||
|
|
b11df6b523 | ||
|
|
66dcd44fb8 | ||
|
|
f35237f86f | ||
|
|
f19c877a11 | ||
|
|
792a487eeb | ||
|
|
f5e8bd0ffc | ||
|
|
cbdbf36f32 | ||
|
|
1116b19b00 | ||
|
|
edb490fa97 | ||
|
|
9fa16c6385 | ||
|
|
a0ee957493 | ||
|
|
f32c303c0a | ||
|
|
6febbbc8e6 | ||
|
|
d5aa9eaf0f | ||
|
|
321b2d761d | ||
|
|
18581e4a78 | ||
|
|
b03905154d | ||
|
|
2fda1709bc | ||
|
|
39f626390a | ||
|
|
aa1e12163d | ||
|
|
abb7f860ae | ||
|
|
cffada1a1e | ||
|
|
f8d91798e3 | ||
|
|
548aa8d5a9 | ||
|
|
1e929d1d19 | ||
|
|
d5f215505e | ||
|
|
851660c793 | ||
|
|
ee57b46c14 | ||
|
|
36eac9fccc | ||
|
|
1f630ab490 | ||
|
|
8f0c6948ac | ||
|
|
eb2380c3f6 | ||
|
|
df3e182de4 | ||
|
|
bda7988118 | ||
|
|
72deb9ee17 | ||
|
|
ced1f30f3f | ||
|
|
47c0006537 | ||
|
|
21e5c124c0 | ||
|
|
3ff374e1b9 | ||
|
|
02000be9af | ||
|
|
663c6cead0 | ||
|
|
6867df58c4 | ||
|
|
639625d3d5 | ||
|
|
0ace200e5a | ||
|
|
e76c26ff59 | ||
|
|
cb11de6f9c | ||
|
|
cdd78e5163 | ||
|
|
a8da02774a | ||
|
|
04258a69c4 | ||
|
|
49882f03d9 |
@@ -657,8 +657,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 +666,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 +761,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 } )
|
||||||
|
|
||||||
|
|||||||
@@ -453,7 +453,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 +462,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 +536,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 +544,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!
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ function AI_AIR_PATROL:onafterPatrolRoute( AIPatrol, From, Event, To )
|
|||||||
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
||||||
local speedkmh=ToTargetSpeed
|
local speedkmh=ToTargetSpeed
|
||||||
|
|
||||||
local FromWP = CurrentCoord:WaypointAir(self.PatrolAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, ToTargetSpeed, true)
|
local FromWP = CurrentCoord:WaypointAir(self.PatrolAltType or "RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, ToTargetSpeed, true)
|
||||||
PatrolRoute[#PatrolRoute+1] = FromWP
|
PatrolRoute[#PatrolRoute+1] = FromWP
|
||||||
|
|
||||||
if self.racetrack then
|
if self.racetrack then
|
||||||
@@ -359,9 +359,9 @@ function AI_AIR_PATROL:onafterPatrolRoute( AIPatrol, From, Event, To )
|
|||||||
else
|
else
|
||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local ToWP = ToTargetCoord:WaypointAir(self.PatrolAltType, POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, ToTargetSpeed, true)
|
local ToWP = ToTargetCoord:WaypointAir(self.PatrolAltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, ToTargetSpeed, true)
|
||||||
PatrolRoute[#PatrolRoute+1] = ToWP
|
PatrolRoute[#PatrolRoute+1] = ToWP
|
||||||
|
|
||||||
local Tasks = {}
|
local Tasks = {}
|
||||||
Tasks[#Tasks+1] = AIPatrol:TaskFunction("AI_AIR_PATROL.___PatrolRoute", self)
|
Tasks[#Tasks+1] = AIPatrol:TaskFunction("AI_AIR_PATROL.___PatrolRoute", self)
|
||||||
PatrolRoute[#PatrolRoute].task = AIPatrol:TaskCombo( Tasks )
|
PatrolRoute[#PatrolRoute].task = AIPatrol:TaskCombo( Tasks )
|
||||||
|
|||||||
@@ -521,12 +521,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 +577,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
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -220,16 +220,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
|
||||||
|
|
||||||
|
|||||||
@@ -423,12 +423,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 +445,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
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -465,12 +465,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
|
||||||
)
|
)
|
||||||
@@ -507,13 +507,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
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -440,7 +440,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
|
||||||
|
|||||||
@@ -367,8 +367,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 +380,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 +427,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 +496,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 +563,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 +573,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 +631,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 +639,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
|
||||||
|
|
||||||
|
|||||||
@@ -725,7 +725,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 +877,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 +936,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 )
|
||||||
|
|||||||
@@ -751,12 +751,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 +767,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 +792,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 +890,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
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -275,14 +275,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 +307,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 +467,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 +897,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 +1094,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 )
|
||||||
|
|||||||
@@ -114,7 +114,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,6 +22,7 @@ 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.
|
||||||
@@ -410,7 +411,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 +454,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 +492,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 +772,4 @@ do -- CARGO_GROUP
|
|||||||
|
|
||||||
|
|
||||||
end -- CARGO_GROUP
|
end -- CARGO_GROUP
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,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 +145,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 +171,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 +197,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 } )
|
||||||
|
|
||||||
|
|||||||
@@ -157,6 +157,8 @@ ASTAR = {
|
|||||||
-- @field #number surfacetype Surface type.
|
-- @field #number surfacetype Surface type.
|
||||||
-- @field #table valid Cached valid/invalid nodes.
|
-- @field #table valid Cached valid/invalid nodes.
|
||||||
-- @field #table cost Cached cost.
|
-- @field #table cost Cached cost.
|
||||||
|
-- @field Core.Pathline#PATHLINE pathline Pathline that node is part of.
|
||||||
|
-- @field Core.Pathline#PATHLINE.Point pathpoint Pathline point.
|
||||||
|
|
||||||
--- ASTAR infinity.
|
--- ASTAR infinity.
|
||||||
-- @field #number INF
|
-- @field #number INF
|
||||||
@@ -164,7 +166,7 @@ ASTAR.INF=1/0
|
|||||||
|
|
||||||
--- ASTAR class version.
|
--- ASTAR class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
ASTAR.version="0.4.0"
|
ASTAR.version="0.5.0"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@@ -172,6 +174,7 @@ ASTAR.version="0.4.0"
|
|||||||
|
|
||||||
-- TODO: Add more valid neighbour functions.
|
-- TODO: Add more valid neighbour functions.
|
||||||
-- TODO: Write docs.
|
-- TODO: Write docs.
|
||||||
|
-- DONE: Add pathlines for seach/valid neighbours.
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Constructor
|
-- Constructor
|
||||||
@@ -244,7 +247,10 @@ end
|
|||||||
function ASTAR:AddNode(Node)
|
function ASTAR:AddNode(Node)
|
||||||
|
|
||||||
self.nodes[Node.id]=Node
|
self.nodes[Node.id]=Node
|
||||||
self.Nnodes=self.Nnodes+1
|
self.Nnodes=self.Nnodes+1
|
||||||
|
|
||||||
|
self:T3(self.lid..string.format("Adding node UID=%d", Node.id))
|
||||||
|
--Node.coordinate:MarkToAll(string.format("Node ID=%d", Node.id))
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -262,6 +268,47 @@ function ASTAR:AddNodeFromCoordinate(Coordinate)
|
|||||||
return node
|
return node
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Adds nodes to the table of grid nodes from a PATHLINE.
|
||||||
|
-- @param #ASTAR self
|
||||||
|
-- @param Core.Pathline#PATHLINE Pathline Pathline or name of pathline. Has to exist.
|
||||||
|
-- @return #ASTAR self
|
||||||
|
function ASTAR:AddNodeFromPathlineName(Pathline)
|
||||||
|
|
||||||
|
if type(Pathline)=="string" then
|
||||||
|
Pathline=PATHLINE:FindByName(Pathline)
|
||||||
|
end
|
||||||
|
|
||||||
|
if Pathline then
|
||||||
|
|
||||||
|
for i,_point in pairs(Pathline.points) do
|
||||||
|
local point=_point --Core.Pathline#PATHLINE.Point
|
||||||
|
|
||||||
|
-- Create node from point coordinate.
|
||||||
|
local node=self:AddNodeFromCoordinate(COORDINATE:NewFromVec3(point.vec3))
|
||||||
|
|
||||||
|
-- Add pathline parameters.
|
||||||
|
node.pathline=Pathline
|
||||||
|
node.pathpoint=point
|
||||||
|
|
||||||
|
-- Debug.
|
||||||
|
local name=node.pathline and node.pathline.name or "N/A"
|
||||||
|
local idx=node.pathline and node.pathline:_GetPointIndex(node.pathpoint) or "N/A"
|
||||||
|
|
||||||
|
-- Debug message.
|
||||||
|
self:T(self.lid..string.format("Adding node UID=%d pathline=%s [%s]", node.id, name, tostring(idx)))
|
||||||
|
|
||||||
|
-- Debug mark
|
||||||
|
--node.coordinate:MarkToAll(string.format("Node ID=%d\npathline=%s [%s]", node.id, name, tostring(idx)))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
env.error("FF error pathline")
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Check if the coordinate of a node has is at a valid surface type.
|
--- Check if the coordinate of a node has is at a valid surface type.
|
||||||
-- @param #ASTAR self
|
-- @param #ASTAR self
|
||||||
-- @param #ASTAR.Node Node The node to be added.
|
-- @param #ASTAR.Node Node The node to be added.
|
||||||
@@ -340,6 +387,18 @@ function ASTAR:SetValidNeighbourRoad(MaxDistance)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set valid neighbours to be on the same pathline or not further apart than 10 meters to jump from one pathline to another.
|
||||||
|
-- @param #ASTAR self
|
||||||
|
-- @param #number MaxDistance Max allowed distance between nodes of different pathlines in meters. Default is 10 m.
|
||||||
|
-- @return #ASTAR self
|
||||||
|
function ASTAR:SetValidNeighbourPathline(MaxDistance)
|
||||||
|
|
||||||
|
self:SetValidNeighbourFunction(ASTAR.Pathline, MaxDistance)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set the function which calculates the "cost" to go from one to another node.
|
--- Set the function which calculates the "cost" to go from one to another node.
|
||||||
-- The first to arguments of this function are always the two nodes under consideration. But you can add optional arguments.
|
-- The first to arguments of this function are always the two nodes under consideration. But you can add optional arguments.
|
||||||
-- Very often the distance between nodes is a good measure for the cost.
|
-- Very often the distance between nodes is a good measure for the cost.
|
||||||
@@ -384,7 +443,7 @@ end
|
|||||||
-- @return #ASTAR self
|
-- @return #ASTAR self
|
||||||
function ASTAR:SetCostRoad()
|
function ASTAR:SetCostRoad()
|
||||||
|
|
||||||
self:SetCostFunction(ASTAR)
|
self:SetCostFunction(ASTAR.Road)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -544,6 +603,55 @@ function ASTAR.Road(nodeA, nodeB)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Function to check if two nodes are on the same pathline or if nodes are less than 10 meters apart.
|
||||||
|
-- @param #ASTAR.Node nodeA First node.
|
||||||
|
-- @param #ASTAR.Node nodeB Other node.
|
||||||
|
-- @param #number distmax Max distance in meters. Default is 10 m.
|
||||||
|
-- @return #boolean If true, two nodes are connected.
|
||||||
|
function ASTAR.Pathline(nodeA, nodeB, distmax)
|
||||||
|
|
||||||
|
distmax=distmax or 10
|
||||||
|
|
||||||
|
if nodeA.pathline.name==nodeB.pathline.name then
|
||||||
|
|
||||||
|
-- Nodes are on the same pathline. We use the index to check if they are neighbours.
|
||||||
|
|
||||||
|
local pathline=nodeA.pathline
|
||||||
|
|
||||||
|
local idxA=pathline:_GetPointIndex(nodeA.pathpoint)
|
||||||
|
local idxB=pathline:_GetPointIndex(nodeB.pathpoint)
|
||||||
|
|
||||||
|
if math.abs(idxA-idxB)<=1 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Check if nodeB is close to pathline of nodeA.
|
||||||
|
local c, dist, segA=nodeA.pathline:GetClosestPoint3D(nodeB.coordinate)
|
||||||
|
local seg=segA --Core.Pathline#PATHLINE.Segment
|
||||||
|
|
||||||
|
if dist<distmax and (nodeA.pathpoint.uid==seg.p1.uid or nodeA.pathpoint.uid==seg.p2.uid) then
|
||||||
|
--env.info(string.format("FF NodeB=%d [pathline=%s] is close to NodeA=%d [pathline=%s] ==> valid neighbour", nodeB.id, nodeB.pathline.name, nodeA.id, nodeA.pathline.name))
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Check if nodeA is close to pathline of nodeB.
|
||||||
|
local c, dist, segB=nodeB.pathline:GetClosestPoint3D(nodeA.coordinate)
|
||||||
|
local seg=segB --Core.Pathline#PATHLINE.Segment
|
||||||
|
|
||||||
|
if dist<distmax and (nodeB.pathpoint.uid==seg.p1.uid or nodeB.pathpoint.uid==seg.p2.uid) then
|
||||||
|
--env.info(string.format("FF NodeA=%d [pathline=%s] is close to NodeB=%d [pathline=%s] ==> valid neighbour", nodeA.id, nodeA.pathline.name, nodeB.id, nodeB.pathline.name))
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Function to check if distance between two nodes is less than a threshold distance.
|
--- Function to check if distance between two nodes is less than a threshold distance.
|
||||||
-- @param #ASTAR.Node nodeA First node.
|
-- @param #ASTAR.Node nodeA First node.
|
||||||
-- @param #ASTAR.Node nodeB Other node.
|
-- @param #ASTAR.Node nodeB Other node.
|
||||||
@@ -567,7 +675,9 @@ end
|
|||||||
-- @param #ASTAR.Node nodeB Other node.
|
-- @param #ASTAR.Node nodeB Other node.
|
||||||
-- @return #number Distance between the two nodes.
|
-- @return #number Distance between the two nodes.
|
||||||
function ASTAR.Dist2D(nodeA, nodeB)
|
function ASTAR.Dist2D(nodeA, nodeB)
|
||||||
local dist=nodeA.coordinate:Get2DDistance(nodeB)
|
local dist=nodeA.coordinate:Get2DDistance(nodeB.coordinate)
|
||||||
|
--local text=string.format("FF Cost Dist2D NodeA=%d-->NodeB=%d = %.1f", nodeA.id, nodeB.id, dist)
|
||||||
|
--env.info(text)
|
||||||
return dist
|
return dist
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -594,7 +704,7 @@ function ASTAR.DistRoad(nodeA, nodeB)
|
|||||||
local dist=0
|
local dist=0
|
||||||
|
|
||||||
for i=2,#path do
|
for i=2,#path do
|
||||||
local b=path[i] --DCS#Vec2
|
local b=path[i] --DCS#Vec2
|
||||||
local a=path[i-1] --DCS#Vec2
|
local a=path[i-1] --DCS#Vec2
|
||||||
|
|
||||||
dist=dist+UTILS.VecDist2D(a,b)
|
dist=dist+UTILS.VecDist2D(a,b)
|
||||||
@@ -604,7 +714,6 @@ function ASTAR.DistRoad(nodeA, nodeB)
|
|||||||
return dist
|
return dist
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return math.huge
|
return math.huge
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -614,10 +723,11 @@ end
|
|||||||
|
|
||||||
--- Find the closest node from a given coordinate.
|
--- Find the closest node from a given coordinate.
|
||||||
-- @param #ASTAR self
|
-- @param #ASTAR self
|
||||||
-- @param Core.Point#COORDINATE Coordinate.
|
-- @param Core.Point#COORDINATE Coordinate Reference coordinate.
|
||||||
-- @return #ASTAR.Node Cloest node to the coordinate.
|
-- @param #table ExcludeNodes Table of nodes that are excluded.
|
||||||
|
-- @return #ASTAR.Node Closest node to the coordinate.
|
||||||
-- @return #number Distance to closest node in meters.
|
-- @return #number Distance to closest node in meters.
|
||||||
function ASTAR:FindClosestNode(Coordinate)
|
function ASTAR:FindClosestNode(Coordinate, ExcludeNodes)
|
||||||
|
|
||||||
local distMin=math.huge
|
local distMin=math.huge
|
||||||
local closeNode=nil
|
local closeNode=nil
|
||||||
@@ -625,11 +735,15 @@ function ASTAR:FindClosestNode(Coordinate)
|
|||||||
for _,_node in pairs(self.nodes) do
|
for _,_node in pairs(self.nodes) do
|
||||||
local node=_node --#ASTAR.Node
|
local node=_node --#ASTAR.Node
|
||||||
|
|
||||||
local dist=node.coordinate:Get2DDistance(Coordinate)
|
if ExcludeNodes==nil or self:_IsNodeNotInTable(ExcludeNodes, node) then
|
||||||
|
|
||||||
if dist<distMin then
|
local dist=node.coordinate:Get2DDistance(Coordinate)
|
||||||
distMin=dist
|
|
||||||
closeNode=node
|
if dist<distMin then
|
||||||
|
distMin=dist
|
||||||
|
closeNode=node
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -637,38 +751,162 @@ function ASTAR:FindClosestNode(Coordinate)
|
|||||||
return closeNode, distMin
|
return closeNode, distMin
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Find the closest pathline to a given reference coordinate.
|
||||||
|
-- @param #ASTAR self
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate Reference coordinate.
|
||||||
|
-- @return Core.Pathline#PATHLINE Closest pathline
|
||||||
|
-- @return #number Distance in meters.
|
||||||
|
-- @return DCS#Vec3 Closest point on pathline to the ref coordinate.
|
||||||
|
-- @return Core.Pathline#PATHLINE.Segment Segment.
|
||||||
|
function ASTAR:FindClosestPathline(Coordinate)
|
||||||
|
|
||||||
|
local pathline=nil --Core.Pathline#PATHLINE
|
||||||
|
local dist=math.huge
|
||||||
|
local vec3=nil
|
||||||
|
local S=nil
|
||||||
|
|
||||||
|
for _,_node in pairs(self.nodes) do
|
||||||
|
local node=_node --#ASTAR.Node
|
||||||
|
|
||||||
|
if node.pathline then
|
||||||
|
|
||||||
|
local vec, d, s=node.pathline:GetClosestPoint3D(Coordinate)
|
||||||
|
|
||||||
|
if d<dist then
|
||||||
|
pathline=node.pathline
|
||||||
|
dist=d
|
||||||
|
vec3=vec
|
||||||
|
S=s
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if pathline then
|
||||||
|
-- Debug info.
|
||||||
|
self:T(self.lid..string.format("Closest pathline %s: dist=%.1f", pathline.name, dist))
|
||||||
|
end
|
||||||
|
|
||||||
|
return pathline, dist, vec3, S
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Find the closest node to the given coordinate.
|
||||||
|
-- @param #ASTAR self
|
||||||
|
-- @param Core.Point#COORDINATE Coord Reference coordinate.
|
||||||
|
-- @param #table ExcludeNodes Nodes that are excluded.
|
||||||
|
-- @return #ASTAR.Node The node that was fround
|
||||||
|
function ASTAR:_FindClosestTerminalNode(Coord, ExcludeNodes)
|
||||||
|
|
||||||
|
-- Find the closest pathline to the ref coordinate.
|
||||||
|
local pathline, dist, vec3, s=self:FindClosestPathline(Coord)
|
||||||
|
|
||||||
|
-- Find the closest node to the given start coordinate.
|
||||||
|
local node, dist2=self:FindClosestNode(Coord)
|
||||||
|
|
||||||
|
if pathline and vec3 and dist and dist2>dist then
|
||||||
|
|
||||||
|
-- Create a node on the closest pathline so we first go straight there and then along the pathline.
|
||||||
|
local node=self:AddNodeFromCoordinate(COORDINATE:NewFromVec3(vec3))
|
||||||
|
|
||||||
|
-- We also need the pathline point.
|
||||||
|
local point=pathline:AddPointFromVec3(vec3, nil, s.p1)
|
||||||
|
|
||||||
|
node.pathline=pathline
|
||||||
|
node.pathpoint=point
|
||||||
|
|
||||||
|
self:T2(self.lid..string.format("Added new node=%d, which is closest to start coord. dist=%.1f m", node.id, dist))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Find the closest node to the given start coordinate.
|
||||||
|
local Node, dist3=self:FindClosestNode(Coord, ExcludeNodes)
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:T(self.lid..string.format("CLOSEST node ID=%d, distance=%.1f", Node.id, dist3))
|
||||||
|
|
||||||
|
return Node, dist3
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Find the start node.
|
--- Find the start node.
|
||||||
-- @param #ASTAR self
|
-- @param #ASTAR self
|
||||||
-- @param #ASTAR.Node Node The node to be added to the nodes table.
|
|
||||||
-- @return #ASTAR self
|
-- @return #ASTAR self
|
||||||
function ASTAR:FindStartNode()
|
function ASTAR:FindStartNode()
|
||||||
|
|
||||||
|
-- Find the closest pathline to the
|
||||||
|
local pathline, dist, vec3, s=self:FindClosestPathline(self.startCoord)
|
||||||
|
|
||||||
local node, dist=self:FindClosestNode(self.startCoord)
|
-- Find the closest node to the given start coordinate.
|
||||||
|
local node, dist2=self:FindClosestNode(self.startCoord)
|
||||||
|
|
||||||
self.startNode=node
|
if pathline and vec3 and dist and dist2>dist then
|
||||||
|
|
||||||
if dist>1000 then
|
-- Create a node on the closest pathline so we first go straight there and then along the pathline.
|
||||||
self:T(self.lid.."Adding start node to node grid!")
|
local node=self:AddNodeFromCoordinate(COORDINATE:NewFromVec3(vec3))
|
||||||
self:AddNode(node)
|
|
||||||
|
-- We also need the pathline point.
|
||||||
|
local point=pathline:AddPointFromVec3(vec3, nil, s.p1)
|
||||||
|
|
||||||
|
node.pathline=pathline
|
||||||
|
node.pathpoint=point
|
||||||
|
|
||||||
|
self:T2(self.lid..string.format("Added new node=%d, which is closest to start coord. dist=%.1f m", node.id, dist))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Find the closest node to the given start coordinate.
|
||||||
|
self.startNode, dist2=self:FindClosestNode(self.startCoord)
|
||||||
|
|
||||||
|
--self.startNode.coordinate:MarkToAll("Start Node")
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:T(self.lid..string.format("START node ID=%d", self.startNode.id))
|
||||||
|
|
||||||
|
-- Not sure why I did this. The node does not need to be added again as it is already contained in self.nodes!
|
||||||
|
-- if dist>1000 then
|
||||||
|
-- self:T(self.lid.."Adding start node to node grid!")
|
||||||
|
-- self:AddNode(node)
|
||||||
|
-- end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Add a node.
|
--- Find the end node.
|
||||||
-- @param #ASTAR self
|
-- @param #ASTAR self
|
||||||
-- @param #ASTAR.Node Node The node to be added to the nodes table.
|
|
||||||
-- @return #ASTAR self
|
-- @return #ASTAR self
|
||||||
function ASTAR:FindEndNode()
|
function ASTAR:FindEndNode()
|
||||||
|
|
||||||
local node, dist=self:FindClosestNode(self.endCoord)
|
|
||||||
|
|
||||||
self.endNode=node
|
|
||||||
|
|
||||||
if dist>1000 then
|
local pathline, dist, vec3, s=self:FindClosestPathline(self.endCoord)
|
||||||
self:T(self.lid.."Adding end node to node grid!")
|
|
||||||
self:AddNode(node)
|
-- Find the closest node to the given start coordinate.
|
||||||
|
local node, dist2=self:FindClosestNode(self.endCoord)
|
||||||
|
|
||||||
|
if pathline and vec3 and dist and dist2>dist then
|
||||||
|
|
||||||
|
-- Create a node on the closest pathline so we first go straight there and then along the pathline.
|
||||||
|
local node=self:AddNodeFromCoordinate(COORDINATE:NewFromVec3(vec3))
|
||||||
|
|
||||||
|
-- We also need the point.
|
||||||
|
local point=pathline:AddPointFromVec3(vec3, nil, s.p1)
|
||||||
|
|
||||||
|
-- Add pathline parameters to node.
|
||||||
|
node.pathline=pathline
|
||||||
|
node.pathpoint=point
|
||||||
|
|
||||||
|
self:T2(self.lid..string.format("Added new node=%d, which is closest to END coord: dist=%.1f m", node.id, dist))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Find closest node to the end coordinate (exclude the start coordinate.
|
||||||
|
self.endNode, dist=self:FindClosestNode(self.endCoord, {self.startNode})
|
||||||
|
|
||||||
|
--self.endNode.coordinate:MarkToAll("End Node")
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:T(self.lid..string.format("END node ID=%d", self.endNode.id))
|
||||||
|
|
||||||
|
-- Not sure why I did this. The node does not need to be added again as it is already contained in self.nodes!
|
||||||
|
-- if dist>1000 then
|
||||||
|
-- self:T(self.lid.."Adding end node to node grid!")
|
||||||
|
-- self:AddNode(node)
|
||||||
|
-- end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -684,12 +922,21 @@ end
|
|||||||
-- @return #table Table of nodes from start to finish.
|
-- @return #table Table of nodes from start to finish.
|
||||||
function ASTAR:GetPath(ExcludeStartNode, ExcludeEndNode)
|
function ASTAR:GetPath(ExcludeStartNode, ExcludeEndNode)
|
||||||
|
|
||||||
self:FindStartNode()
|
-- self:FindStartNode()
|
||||||
self:FindEndNode()
|
-- self:FindEndNode()
|
||||||
|
|
||||||
|
-- Find start Node (closest node to start coordinate).
|
||||||
|
self.startNode=self:_FindClosestTerminalNode(self.startCoord)
|
||||||
|
|
||||||
|
-- Find end node, which is not the start node (excluded).
|
||||||
|
self.endNode=self:_FindClosestTerminalNode(self.endCoord, {self.startNode})
|
||||||
|
|
||||||
local nodes=self.nodes
|
local nodes=self.nodes
|
||||||
local start=self.startNode
|
local start=self.startNode
|
||||||
local goal=self.endNode
|
local goal=self.endNode
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:T(self.lid..string.format("GetPath Start Node=%d, End Node=%d", start.id, goal.id))
|
||||||
|
|
||||||
-- Sets.
|
-- Sets.
|
||||||
local openset = {}
|
local openset = {}
|
||||||
@@ -746,7 +993,12 @@ function ASTAR:GetPath(ExcludeStartNode, ExcludeEndNode)
|
|||||||
text=text..string.format(", OS Time %.6f sec", dT)
|
text=text..string.format(", OS Time %.6f sec", dT)
|
||||||
end
|
end
|
||||||
text=text..string.format(", Nvalid=%d [%d cached]", self.nvalid, self.nvalidcache)
|
text=text..string.format(", Nvalid=%d [%d cached]", self.nvalid, self.nvalidcache)
|
||||||
text=text..string.format(", Ncost=%d [%d cached]", self.ncost, self.ncostcache)
|
text=text..string.format(", Ncost=%d [%d cached]", self.ncost, self.ncostcache)
|
||||||
|
text=text..string.format("\nNodes:")
|
||||||
|
for i,_node in ipairs(path) do
|
||||||
|
local node=_node --#ASTAR.Node
|
||||||
|
text=text..string.format("\n[%d] Node ID=%d", i, node.id)
|
||||||
|
end
|
||||||
self:T(self.lid..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
return path
|
return path
|
||||||
@@ -759,13 +1011,16 @@ function ASTAR:GetPath(ExcludeStartNode, ExcludeEndNode)
|
|||||||
|
|
||||||
-- Get neighbour nodes.
|
-- Get neighbour nodes.
|
||||||
local neighbors=self:_NeighbourNodes(current, nodes)
|
local neighbors=self:_NeighbourNodes(current, nodes)
|
||||||
|
|
||||||
-- Loop over neighbours.
|
-- Loop over neighbours.
|
||||||
for _,neighbor in pairs(neighbors) do
|
for _,neighbor in pairs(neighbors) do
|
||||||
|
|
||||||
|
-- Node is not in closed set.
|
||||||
if self:_NotIn(closedset, neighbor.id) then
|
if self:_NotIn(closedset, neighbor.id) then
|
||||||
|
|
||||||
local tentative_g_score=g_score[current.id]+self:_DistNodes(current, neighbor)
|
-- Calculate tentative_g_score.
|
||||||
|
--local tentative_g_score=g_score[current.id] + self:_DistNodes(current, neighbor)
|
||||||
|
local tentative_g_score=g_score[current.id] + self:_HeuristicCost(current, neighbor)
|
||||||
|
|
||||||
if self:_NotIn(openset, neighbor.id) or tentative_g_score < g_score[neighbor.id] then
|
if self:_NotIn(openset, neighbor.id) or tentative_g_score < g_score[neighbor.id] then
|
||||||
|
|
||||||
@@ -793,6 +1048,73 @@ function ASTAR:GetPath(ExcludeStartNode, ExcludeEndNode)
|
|||||||
return nil -- no valid path
|
return nil -- no valid path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- A* pathfinding function. This seaches the path along nodes between start and end nodes/coordinates.
|
||||||
|
-- It automatically creates a PATHLINE object that is returned in combination with the nodes of the optimal path.
|
||||||
|
-- @param #ASTAR self
|
||||||
|
-- @param #boolean ExcludeStartNode If *true*, do not include start node in found path. Default is to include it.
|
||||||
|
-- @param #boolean ExcludeEndNode If *true*, do not include end node in found path. Default is to include it.
|
||||||
|
-- @return Core.Pathline#PATHLINE Pathline.
|
||||||
|
-- @return #table Nodes of path.
|
||||||
|
function ASTAR:GetPathline(ExcludeStartNode, ExcludeEndNode)
|
||||||
|
|
||||||
|
local nodes=self:GetPath(ExcludeStartNode, ExcludeEndNode)
|
||||||
|
|
||||||
|
local pathline=nil --Core.Pathline#PATHLINE
|
||||||
|
if nodes then
|
||||||
|
|
||||||
|
pathline=PATHLINE:New("Astar")
|
||||||
|
|
||||||
|
for _,_node in pairs(nodes) do
|
||||||
|
local node=_node --#ASTAR.Node
|
||||||
|
|
||||||
|
local point=pathline:AddPointFromVec3(node.coordinate)
|
||||||
|
point.name=node.pathline.name
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return pathline, nodes
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get pathlines from nodes.
|
||||||
|
-- @param #ASTAR self
|
||||||
|
-- @param #table Nodes Given nodes.
|
||||||
|
-- @return #table Table of PATHLINES used in the path.
|
||||||
|
function ASTAR:GetPathlinesFromNodes(Nodes)
|
||||||
|
|
||||||
|
local pathlines={}
|
||||||
|
|
||||||
|
--for _,_node in pairs(Nodes or {}) do
|
||||||
|
for i=1,#Nodes do
|
||||||
|
local node=Nodes[i] --#ASTAR.Node
|
||||||
|
|
||||||
|
-- Pathline.
|
||||||
|
local pathline=node.pathline
|
||||||
|
|
||||||
|
if pathline and i>1 and i<#Nodes then
|
||||||
|
|
||||||
|
-- Previous and next nodes.
|
||||||
|
local n=Nodes[i-1] --#ASTAR.Node
|
||||||
|
local N=Nodes[i+1] --#ASTAR.Node
|
||||||
|
|
||||||
|
-- Check if previous and next nodes are on the same pathline.
|
||||||
|
-- If only one point in beteen is of another pathline, this is a junction and we dont actually switch to the other pathline.
|
||||||
|
if n.pathline and N.pathline and n.pathline.name==N.pathline.name and n.pathline.name~=pathline.name then
|
||||||
|
pathline=n.pathline
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- We do not want to add the same pathline two times in a row.
|
||||||
|
if #pathlines==0 or (#pathlines>0 and pathlines[#pathlines].name~=pathline.name) then
|
||||||
|
table.insert(pathlines, pathline)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return pathlines
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- A* pathfinding helper functions
|
-- A* pathfinding helper functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -811,16 +1133,18 @@ function ASTAR:_HeuristicCost(nodeA, nodeB)
|
|||||||
local cost=nodeA.cost[nodeB.id]
|
local cost=nodeA.cost[nodeB.id]
|
||||||
if cost~=nil then
|
if cost~=nil then
|
||||||
self.ncostcache=self.ncostcache+1
|
self.ncostcache=self.ncostcache+1
|
||||||
|
self:T(self.lid..string.format("Cost nodeA=%d --> nodeB=%d = %.1f (Cashed!)", nodeA.id, nodeB.id, cost))
|
||||||
return cost
|
return cost
|
||||||
end
|
end
|
||||||
|
|
||||||
local cost=nil
|
|
||||||
if self.CostFunc then
|
if self.CostFunc then
|
||||||
cost=self.CostFunc(nodeA, nodeB, unpack(self.CostArg))
|
cost=self.CostFunc(nodeA, nodeB, unpack(self.CostArg))
|
||||||
else
|
else
|
||||||
cost=self:_DistNodes(nodeA, nodeB)
|
cost=self:_DistNodes(nodeA, nodeB)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self:T(self.lid..string.format("Cost nodeA=%d --> nodeB=%d = %.1f", nodeA.id, nodeB.id, cost))
|
||||||
|
|
||||||
nodeA.cost[nodeB.id]=cost
|
nodeA.cost[nodeB.id]=cost
|
||||||
nodeB.cost[nodeA.id]=cost -- Symmetric problem.
|
nodeB.cost[nodeA.id]=cost -- Symmetric problem.
|
||||||
|
|
||||||
@@ -834,9 +1158,10 @@ end
|
|||||||
-- @return #boolean If true, transition between nodes is possible.
|
-- @return #boolean If true, transition between nodes is possible.
|
||||||
function ASTAR:_IsValidNeighbour(node, neighbor)
|
function ASTAR:_IsValidNeighbour(node, neighbor)
|
||||||
|
|
||||||
-- Counter.
|
-- Counter of function calls.
|
||||||
self.nvalid=self.nvalid+1
|
self.nvalid=self.nvalid+1
|
||||||
|
|
||||||
|
-- Check if neighbour is in cached set.
|
||||||
local valid=node.valid[neighbor.id]
|
local valid=node.valid[neighbor.id]
|
||||||
if valid~=nil then
|
if valid~=nil then
|
||||||
--env.info(string.format("Node %d has valid=%s neighbour %d", node.id, tostring(valid), neighbor.id))
|
--env.info(string.format("Node %d has valid=%s neighbour %d", node.id, tostring(valid), neighbor.id))
|
||||||
@@ -844,13 +1169,16 @@ function ASTAR:_IsValidNeighbour(node, neighbor)
|
|||||||
return valid
|
return valid
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Check if this is a valid neighbour.
|
||||||
local valid=nil
|
local valid=nil
|
||||||
if self.ValidNeighbourFunc then
|
if self.ValidNeighbourFunc then
|
||||||
valid=self.ValidNeighbourFunc(node, neighbor, unpack(self.ValidNeighbourArg))
|
valid=self.ValidNeighbourFunc(node, neighbor, unpack(self.ValidNeighbourArg))
|
||||||
else
|
else
|
||||||
|
-- If no valid neighbour function is defined, we assume all nodes are valid neighbours.
|
||||||
valid=true
|
valid=true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Cache valid neighbour.
|
||||||
node.valid[neighbor.id]=valid
|
node.valid[neighbor.id]=valid
|
||||||
neighbor.valid[node.id]=valid -- Symmetric problem.
|
neighbor.valid[node.id]=valid -- Symmetric problem.
|
||||||
|
|
||||||
@@ -884,6 +1212,9 @@ function ASTAR:_LowestFscore(set, f_score)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:T(self.lid..string.format("Lowest Fscore=%.1f, Node=%s", lowest, tostring(bestNode)))
|
||||||
|
|
||||||
return self.nodes[bestNode]
|
return self.nodes[bestNode]
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -928,16 +1259,46 @@ end
|
|||||||
-- @param #table map Map.
|
-- @param #table map Map.
|
||||||
-- @param #ASTAR.Node current_node The current node.
|
-- @param #ASTAR.Node current_node The current node.
|
||||||
-- @return #table Unwinded path.
|
-- @return #table Unwinded path.
|
||||||
function ASTAR:_UnwindPath( flat_path, map, current_node )
|
function ASTAR:_UnwindPath(flat_path, map, current_node)
|
||||||
|
|
||||||
if map [current_node] then
|
local previous_node=map[current_node]
|
||||||
table.insert (flat_path, 1, map[current_node])
|
|
||||||
return self:_UnwindPath(flat_path, map, map[current_node])
|
if previous_node then
|
||||||
|
table.insert(flat_path, 1, previous_node)
|
||||||
|
return self:_UnwindPath(flat_path, map, previous_node)
|
||||||
else
|
else
|
||||||
|
-- No previous node ==> return path.
|
||||||
return flat_path
|
return flat_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Function to check if a certain node is in a given table.
|
||||||
|
-- @param #ASTAR self
|
||||||
|
-- @param #table Nodes Nodes table.
|
||||||
|
-- @param #ASTAR.Node Node The node to check.
|
||||||
|
-- @return #boolean If true, the node is not in the set.
|
||||||
|
function ASTAR:_IsNodeInTable(Nodes, Node)
|
||||||
|
|
||||||
|
for _,_node in pairs(Nodes) do
|
||||||
|
local node=_node --#ASTAR.Node
|
||||||
|
if node.id==Node.id then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Function to check if a certain node is **not** in a given table.
|
||||||
|
-- @param #ASTAR self
|
||||||
|
-- @param #table Nodes Nodes table.
|
||||||
|
-- @param #ASTAR.Node Node The node to check.
|
||||||
|
-- @return #boolean If true, the node is not in the set.
|
||||||
|
function ASTAR:_IsNodeNotInTable(Nodes, Node)
|
||||||
|
local is=self:_IsNodeInTable(Nodes, Node)
|
||||||
|
return not is
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -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
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -5,11 +5,13 @@
|
|||||||
-- * Path from A to B
|
-- * Path from A to B
|
||||||
-- * Arbitrary number of points
|
-- * Arbitrary number of points
|
||||||
-- * Automatically from lines drawtool
|
-- * Automatically from lines drawtool
|
||||||
|
-- * Draw line or mark points on F10 map
|
||||||
|
-- * Find closest points to path
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **funkyfranky**
|
-- ### Author: **funkyfranky**
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
-- @module Core.Pathline
|
-- @module Core.Pathline
|
||||||
-- @image CORE_Pathline.png
|
-- @image CORE_Pathline.png
|
||||||
@@ -21,6 +23,7 @@
|
|||||||
-- @field #string lid Class id string for output to DCS log file.
|
-- @field #string lid Class id string for output to DCS log file.
|
||||||
-- @field #string name Name of the path line.
|
-- @field #string name Name of the path line.
|
||||||
-- @field #table points List of 3D points defining the path.
|
-- @field #table points List of 3D points defining the path.
|
||||||
|
-- @field #number counter Running number counting the point IDs.
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
--- *The shortest distance between two points is a straight line.* -- Archimedes
|
--- *The shortest distance between two points is a straight line.* -- Archimedes
|
||||||
@@ -28,30 +31,30 @@
|
|||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- # The PATHLINE Concept
|
-- # The PATHLINE Concept
|
||||||
--
|
--
|
||||||
-- List of points defining a path from A to B. The pathline can consist of multiple points. Each point holds the information of its position, the surface type, the land height
|
-- List of points defining a path from A to B. The pathline can consist of multiple points. Each point holds the information of its position, the surface type, the land height
|
||||||
-- and the water depth (if over sea).
|
-- and the water depth (if over sea).
|
||||||
--
|
--
|
||||||
-- Line drawings created in the mission editor are automatically registered as pathlines and stored in the MOOSE database.
|
-- Line drawings created in the mission editor are automatically registered as pathlines and stored in the MOOSE database.
|
||||||
-- They can be accessed with the @{#PATHLINE.FindByName) function.
|
-- They can be accessed with the @{#PATHLINE.FindByName) function.
|
||||||
--
|
--
|
||||||
-- # Constructor
|
-- # Constructor
|
||||||
--
|
--
|
||||||
-- The @{PATHLINE.New) function creates a new PATHLINE object. This does not hold any points. Points can be added with the @{#PATHLINE.AddPointFromVec2} and @{#PATHLINE.AddPointFromVec3}
|
-- The @{PATHLINE.New) function creates a new PATHLINE object. This does not hold any points. Points can be added with the @{#PATHLINE.AddPointFromVec2} and @{#PATHLINE.AddPointFromVec3}
|
||||||
--
|
--
|
||||||
-- For a given table of 2D or 3D positions, a new PATHLINE object can be created with the @{#PATHLINE.NewFromVec2Array} or @{#PATHLINE.NewFromVec3Array}, respectively.
|
-- For a given table of 2D or 3D positions, a new PATHLINE object can be created with the @{#PATHLINE.NewFromVec2Array} or @{#PATHLINE.NewFromVec3Array}, respectively.
|
||||||
--
|
--
|
||||||
-- # Line Drawings
|
-- # Line Drawings
|
||||||
--
|
--
|
||||||
-- The most convenient way to create a pathline is the draw panel feature in the DCS mission editor. You can select "Line" and then "Segments", "Segment" or "Free" to draw your lines.
|
-- The most convenient way to create a pathline is the draw panel feature in the DCS mission editor. You can select "Line" and then "Segments", "Segment" or "Free" to draw your lines.
|
||||||
-- These line drawings are then automatically added to the MOOSE database as PATHLINE objects and can be retrieved with the @{#PATHLINE.FindByName) function, where the name is the one
|
-- These line drawings are then automatically added to the MOOSE database as PATHLINE objects and can be retrieved with the @{#PATHLINE.FindByName) function, where the name is the one
|
||||||
-- you specify in the draw panel.
|
-- you specify in the draw panel.
|
||||||
--
|
--
|
||||||
-- # Mark on F10 map
|
-- # Mark on F10 map
|
||||||
--
|
--
|
||||||
-- The ponints of the PATHLINE can be marked on the F10 map with the @{#PATHLINE.MarkPoints}(`true`) function. The mark points contain information of the surface type, land height and
|
-- The ponints of the PATHLINE can be marked on the F10 map with the @{#PATHLINE.MarkPoints}(`true`) function. The mark points contain information of the surface type, land height and
|
||||||
-- water depth.
|
-- water depth.
|
||||||
--
|
--
|
||||||
-- To remove the marks, use @{#PATHLINE.MarkPoints}(`false`).
|
-- To remove the marks, use @{#PATHLINE.MarkPoints}(`false`).
|
||||||
--
|
--
|
||||||
-- @field #PATHLINE
|
-- @field #PATHLINE
|
||||||
@@ -59,27 +62,39 @@ PATHLINE = {
|
|||||||
ClassName = "PATHLINE",
|
ClassName = "PATHLINE",
|
||||||
lid = nil,
|
lid = nil,
|
||||||
points = {},
|
points = {},
|
||||||
|
counter = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Point of line.
|
--- Point of line.
|
||||||
-- @type PATHLINE.Point
|
-- @type PATHLINE.Point
|
||||||
|
-- @field #number uid Unique ID of this point.
|
||||||
|
-- @field #string mother Name of the pathline this point belongs to.
|
||||||
|
-- @field #string name Name of this point.
|
||||||
-- @field DCS#Vec3 vec3 3D position.
|
-- @field DCS#Vec3 vec3 3D position.
|
||||||
-- @field DCS#Vec2 vec2 2D position.
|
-- @field DCS#Vec2 vec2 2D position.
|
||||||
-- @field #number surfaceType Surface type.
|
-- @field #number surfaceType Surface type.
|
||||||
-- @field #number landHeight Land height in meters.
|
-- @field #number landHeight Land height in meters.
|
||||||
-- @field #number depth Water depth in meters.
|
-- @field #number depth Water depth in meters.
|
||||||
-- @field #number markerID Marker ID.
|
-- @field #number markerID Marker ID.
|
||||||
|
-- @field #number lineID Marker of pathline ID.
|
||||||
|
|
||||||
|
--- Segment of line.
|
||||||
|
-- @type PATHLINE.Segment
|
||||||
|
-- @field #PATHLINE.Point p1 First point.
|
||||||
|
-- @field #PATHLINE.Point p2 Second point.
|
||||||
|
|
||||||
|
|
||||||
--- PATHLINE class version.
|
--- PATHLINE class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
PATHLINE.version="0.1.1"
|
PATHLINE.version="0.3.0"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- TODO: A lot...
|
-- TODO: Read/write to JSON file
|
||||||
|
-- TODO: Translate/rotate pathline
|
||||||
|
-- TODO: Add color.
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Constructor
|
-- Constructor
|
||||||
@@ -93,10 +108,10 @@ function PATHLINE:New(Name)
|
|||||||
|
|
||||||
-- Inherit everything from INTEL class.
|
-- Inherit everything from INTEL class.
|
||||||
local self=BASE:Inherit(self, BASE:New()) --#PATHLINE
|
local self=BASE:Inherit(self, BASE:New()) --#PATHLINE
|
||||||
|
|
||||||
self.name=Name or "Unknown Path"
|
self.name=Name or "Unknown Path"
|
||||||
|
|
||||||
self.lid=string.format("PATHLINE %s | ", Name)
|
self.lid=string.format("PATHLINE %s | ", self.name)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -151,41 +166,70 @@ end
|
|||||||
--- Add a point to the path from a given 2D position. The third dimension is determined from the land height.
|
--- Add a point to the path from a given 2D position. The third dimension is determined from the land height.
|
||||||
-- @param #PATHLINE self
|
-- @param #PATHLINE self
|
||||||
-- @param DCS#Vec2 Vec2 The 2D vector (x,y) to add.
|
-- @param DCS#Vec2 Vec2 The 2D vector (x,y) to add.
|
||||||
|
-- @param #number Index Index to add this point, *e.g.* 1 for first point or 2 for second point. Default is at the end.
|
||||||
|
-- @param #PATHLINE.Point Point Add point after given point. Default is at the end or at given index.
|
||||||
-- @return #PATHLINE self
|
-- @return #PATHLINE self
|
||||||
function PATHLINE:AddPointFromVec2(Vec2)
|
function PATHLINE:AddPointFromVec2(Vec2, Index, Point)
|
||||||
|
|
||||||
if Vec2 then
|
if Vec2 then
|
||||||
|
|
||||||
|
-- Create a new point.
|
||||||
local point=self:_CreatePoint(Vec2)
|
local point=self:_CreatePoint(Vec2)
|
||||||
|
|
||||||
table.insert(self.points, point)
|
if Index then
|
||||||
|
-- Add at given index.
|
||||||
|
table.insert(self.points, Index, point)
|
||||||
|
else
|
||||||
|
if Point then
|
||||||
|
-- Get index of given point.
|
||||||
|
local i=self:_GetPointIndex(Point)
|
||||||
|
-- Add new point after given point.
|
||||||
|
table.insert(self.points, i+1, point)
|
||||||
|
else
|
||||||
|
-- Add add the end.
|
||||||
|
table.insert(self.points, point)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Add a point to the path from a given 3D position.
|
--- Add a point to the path from a given 3D position.
|
||||||
-- @param #PATHLINE self
|
-- @param #PATHLINE self
|
||||||
-- @param DCS#Vec3 Vec3 The 3D vector (x,y) to add.
|
-- @param DCS#Vec3 Vec3 The 3D vector (x,y) to add.
|
||||||
-- @return #PATHLINE self
|
-- @param #number Index Index to add this point, *e.g.* 1 for first point or 2 for second point. Default is at the end.
|
||||||
function PATHLINE:AddPointFromVec3(Vec3)
|
-- @param #PATHLINE.Point Point Add point after given point. Default is at the end or at given index.
|
||||||
|
-- @return #PATHLINE.Point Point that was added.
|
||||||
|
function PATHLINE:AddPointFromVec3(Vec3, Index, Point)
|
||||||
|
|
||||||
if Vec3 then
|
if Vec3 then
|
||||||
|
|
||||||
local point=self:_CreatePoint(Vec3)
|
local point=self:_CreatePoint(Vec3)
|
||||||
|
|
||||||
table.insert(self.points, point)
|
if Index then
|
||||||
|
-- Add add given index.
|
||||||
|
table.insert(self.points, Index, point)
|
||||||
|
else
|
||||||
|
if Point then
|
||||||
|
local i=self:_GetPointIndex(Point)
|
||||||
|
table.insert(self.points, i+1, point)
|
||||||
|
else
|
||||||
|
-- Add add the end.
|
||||||
|
table.insert(self.points, point)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return point
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get name of pathline.
|
--- Get name of pathline.
|
||||||
-- @param #PATHLINE self
|
-- @param #PATHLINE self
|
||||||
-- @return #string Name of the pathline.
|
-- @return #string Name of the pathline.
|
||||||
function PATHLINE:GetName()
|
function PATHLINE:GetName()
|
||||||
return self.name
|
return self.name
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -199,18 +243,35 @@ end
|
|||||||
|
|
||||||
--- Get points of pathline. Not that points are tables, that contain more information as just the 2D or 3D position but also the surface type etc.
|
--- Get points of pathline. Not that points are tables, that contain more information as just the 2D or 3D position but also the surface type etc.
|
||||||
-- @param #PATHLINE self
|
-- @param #PATHLINE self
|
||||||
-- @return #list <#PATHLINE.Point> List of points.
|
-- @return #list <Core.Pathline#PATHLINE.Point> List of points.
|
||||||
function PATHLINE:GetPoints()
|
function PATHLINE:GetPoints()
|
||||||
return self.points
|
return self.points
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get segments of pathline.
|
||||||
|
-- @param #PATHLINE self
|
||||||
|
-- @return #list <Core.Pathline#PATHLINE.Segment> List of points.
|
||||||
|
function PATHLINE:GetSetments()
|
||||||
|
|
||||||
|
local segments={}
|
||||||
|
|
||||||
|
for i=1,#self.points-1 do
|
||||||
|
local segment={} --#PATHLINE.Segment
|
||||||
|
segment.p1=self.points[i]
|
||||||
|
segment.p2=self.points[i+1]
|
||||||
|
table.insert(segments, segment)
|
||||||
|
end
|
||||||
|
|
||||||
|
return segments
|
||||||
|
end
|
||||||
|
|
||||||
--- Get 3D points of pathline.
|
--- Get 3D points of pathline.
|
||||||
-- @param #PATHLINE self
|
-- @param #PATHLINE self
|
||||||
-- @return <DCS#Vec3> List of DCS#Vec3 points.
|
-- @return #list <DCS#Vec3> List of DCS#Vec3 points.
|
||||||
function PATHLINE:GetPoints3D()
|
function PATHLINE:GetPoints3D()
|
||||||
|
|
||||||
local vecs={}
|
local vecs={}
|
||||||
|
|
||||||
for _,_point in pairs(self.points) do
|
for _,_point in pairs(self.points) do
|
||||||
local point=_point --#PATHLINE.Point
|
local point=_point --#PATHLINE.Point
|
||||||
table.insert(vecs, point.vec3)
|
table.insert(vecs, point.vec3)
|
||||||
@@ -221,11 +282,11 @@ end
|
|||||||
|
|
||||||
--- Get 2D points of pathline.
|
--- Get 2D points of pathline.
|
||||||
-- @param #PATHLINE self
|
-- @param #PATHLINE self
|
||||||
-- @return <DCS#Vec2> List of DCS#Vec2 points.
|
-- @return #list <DCS#Vec2> List of DCS#Vec2 points.
|
||||||
function PATHLINE:GetPoints2D()
|
function PATHLINE:GetPoints2D()
|
||||||
|
|
||||||
local vecs={}
|
local vecs={}
|
||||||
|
|
||||||
for _,_point in pairs(self.points) do
|
for _,_point in pairs(self.points) do
|
||||||
local point=_point --#PATHLINE.Point
|
local point=_point --#PATHLINE.Point
|
||||||
table.insert(vecs, point.vec2)
|
table.insert(vecs, point.vec2)
|
||||||
@@ -240,11 +301,11 @@ end
|
|||||||
function PATHLINE:GetCoordinates()
|
function PATHLINE:GetCoordinates()
|
||||||
|
|
||||||
local vecs={}
|
local vecs={}
|
||||||
|
|
||||||
for _,_point in pairs(self.points) do
|
for _,_point in pairs(self.points) do
|
||||||
local point=_point --#PATHLINE.Point
|
local point=_point --#PATHLINE.Point
|
||||||
local coord=COORDINATE:NewFromVec3(point.vec3)
|
local coord=COORDINATE:NewFromVec3(point.vec3)
|
||||||
table.insert(vecs,coord)
|
table.insert(vecs, coord)
|
||||||
end
|
end
|
||||||
|
|
||||||
return vecs
|
return vecs
|
||||||
@@ -257,11 +318,11 @@ end
|
|||||||
function PATHLINE:GetPointFromIndex(n)
|
function PATHLINE:GetPointFromIndex(n)
|
||||||
|
|
||||||
local N=self:GetNumberOfPoints()
|
local N=self:GetNumberOfPoints()
|
||||||
|
|
||||||
n=n or 1
|
n=n or 1
|
||||||
|
|
||||||
local point=nil --#PATHLINE.Point
|
local point=nil --#PATHLINE.Point
|
||||||
|
|
||||||
if n>=1 and n<=N then
|
if n>=1 and n<=N then
|
||||||
point=self.points[n]
|
point=self.points[n]
|
||||||
else
|
else
|
||||||
@@ -278,11 +339,11 @@ end
|
|||||||
function PATHLINE:GetPoint3DFromIndex(n)
|
function PATHLINE:GetPoint3DFromIndex(n)
|
||||||
|
|
||||||
local point=self:GetPointFromIndex(n)
|
local point=self:GetPointFromIndex(n)
|
||||||
|
|
||||||
if point then
|
if point then
|
||||||
return point.vec3
|
return point.vec3
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -293,11 +354,11 @@ end
|
|||||||
function PATHLINE:GetPoint2DFromIndex(n)
|
function PATHLINE:GetPoint2DFromIndex(n)
|
||||||
|
|
||||||
local point=self:GetPointFromIndex(n)
|
local point=self:GetPointFromIndex(n)
|
||||||
|
|
||||||
if point then
|
if point then
|
||||||
return point.vec2
|
return point.vec2
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -305,33 +366,314 @@ end
|
|||||||
--- Mark points on F10 map.
|
--- Mark points on F10 map.
|
||||||
-- @param #PATHLINE self
|
-- @param #PATHLINE self
|
||||||
-- @param #boolean Switch If `true` or nil, set marks. If `false`, remove marks.
|
-- @param #boolean Switch If `true` or nil, set marks. If `false`, remove marks.
|
||||||
-- @return <DCS#Vec3> List of DCS#Vec3 points.
|
-- @return #PATHLINE self
|
||||||
function PATHLINE:MarkPoints(Switch)
|
function PATHLINE:MarkPoints(Switch)
|
||||||
|
|
||||||
for i,_point in pairs(self.points) do
|
for i,_point in pairs(self.points) do
|
||||||
local point=_point --#PATHLINE.Point
|
local point=_point --#PATHLINE.Point
|
||||||
|
|
||||||
if Switch==false then
|
if Switch==false then
|
||||||
|
|
||||||
if point.markerID then
|
|
||||||
UTILS.RemoveMark(point.markerID, Delay)
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
if point.markerID then
|
if point.markerID then
|
||||||
UTILS.RemoveMark(point.markerID)
|
UTILS.RemoveMark(point.markerID)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if point.markerID then
|
||||||
|
UTILS.RemoveMark(point.markerID)
|
||||||
|
end
|
||||||
|
|
||||||
point.markerID=UTILS.GetMarkID()
|
point.markerID=UTILS.GetMarkID()
|
||||||
|
|
||||||
local text=string.format("Pathline %s: Point #%d\nSurface Type=%d\nHeight=%.1f m\nDepth=%.1f m", self.name, i, point.surfaceType, point.landHeight, point.depth)
|
local text=string.format("Pathline %s: Point #%d [UID=%d]\nSurface Type=%d\nHeight=%.1f m\nDepth=%.1f m", self.name, i, point.uid, point.surfaceType, point.landHeight, point.depth)
|
||||||
|
|
||||||
trigger.action.markToAll(point.markerID, text, point.vec3, "")
|
trigger.action.markToAll(point.markerID, text, point.vec3, "")
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Draw line on F10 map.
|
||||||
|
-- @param #PATHLINE self
|
||||||
|
-- @param #boolean Switch If `true` or nil, draw pathline. If `false`, remove drawing.
|
||||||
|
-- @param #number Coalition Coalition side. Default -1 for all.
|
||||||
|
-- @param #table Color RGB color and alpha `{r, g, b, a}`. Default {0, 1, 0, 0.5}.
|
||||||
|
-- @param #number LineType Line type. Default 1=solid.
|
||||||
|
-- @return #PATHLINE self
|
||||||
|
function PATHLINE:Draw(Switch, Coalition, Color, LineType)
|
||||||
|
|
||||||
|
Coalition=Coalition or -1
|
||||||
|
Color=Color or {0, 1, 0, 0.5}
|
||||||
|
LineType=LineType or 1
|
||||||
|
|
||||||
|
if Switch==false then
|
||||||
|
|
||||||
|
for i,_point in pairs(self.points) do
|
||||||
|
local point=_point --#PATHLINE.Point
|
||||||
|
|
||||||
|
if point.lineID then
|
||||||
|
UTILS.RemoveMark(point.lineID)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
for i=2,#self.points do
|
||||||
|
|
||||||
|
local p1=self.points[i-1] --#PATHLINE.Point
|
||||||
|
local p2=self.points[i] --#PATHLINE.Point
|
||||||
|
|
||||||
|
if p2.lineID then
|
||||||
|
UTILS.RemoveMark(p2.lineID)
|
||||||
|
end
|
||||||
|
|
||||||
|
p2.lineID=UTILS.GetMarkID()
|
||||||
|
|
||||||
|
trigger.action.lineToAll(Coalition, p2.lineID, p1.vec3, p2.vec3, Color, LineType)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the closest point on the pathline for a given reference point.
|
||||||
|
-- @param #PATHLINE self
|
||||||
|
-- @param DCS#Vec2 Vec2 Reference Point in 2D.
|
||||||
|
-- @return DCS#Vec2 Cloest point on pathline.
|
||||||
|
-- @return #number Distance from closest point to ref point in meters.
|
||||||
|
-- @return #PATHLINE.Segment Closest segment of ref point.
|
||||||
|
function PATHLINE:GetClosestPoint2D(Vec2)
|
||||||
|
|
||||||
|
local P=nil --DCS#Vec2
|
||||||
|
local D=math.huge
|
||||||
|
local S={} --#PATHLINE.Segment
|
||||||
|
|
||||||
|
for i=2,#self.points do
|
||||||
|
|
||||||
|
local A=self.points[i-1] --#PATHLINE.Point
|
||||||
|
local B=self.points[i] --#PATHLINE.Point
|
||||||
|
|
||||||
|
local a=A.vec2
|
||||||
|
local b=B.vec2
|
||||||
|
|
||||||
|
local ab=UTILS.Vec2Substract(b, a)
|
||||||
|
local ap=UTILS.Vec2Substract(Vec2, a)
|
||||||
|
|
||||||
|
local proj=UTILS.Vec2Dot(ap, ab)
|
||||||
|
|
||||||
|
local lab=UTILS.Vec2Norm(ab)
|
||||||
|
|
||||||
|
local f=proj/lab/lab
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
local text=string.format("FF Proj=%.1f, |ab|=%.1f, f=%.1f", proj, lab, f)
|
||||||
|
self:T(self.lid..text)
|
||||||
|
|
||||||
|
-- Cases for finite segment.
|
||||||
|
local p=nil --DCS#Vec2
|
||||||
|
if f<0 then
|
||||||
|
p=a
|
||||||
|
elseif f>1 then
|
||||||
|
p=b
|
||||||
|
else
|
||||||
|
local r=UTILS.Vec2Mult(ab, f)
|
||||||
|
p=UTILS.Vec2Add(a, r)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Distance.
|
||||||
|
local d=UTILS.VecDist2D(p, Vec2)
|
||||||
|
|
||||||
|
if d<=D then
|
||||||
|
D=d
|
||||||
|
P=p
|
||||||
|
S.p1=A
|
||||||
|
S.p2=B
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return P, D, S
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the closest point on the pathline for a given reference point.
|
||||||
|
-- This point does not necessarily is a node of the pathline. In general it will be somewhere in between the nodes defining the pathline.
|
||||||
|
-- @param #PATHLINE self
|
||||||
|
-- @param DCS#Vec3 Vec3 Reference Point in 3D. Can also be a `COORDINATE`.
|
||||||
|
-- @return DCS#Vec3 Closest point on pathline.
|
||||||
|
-- @return #number Distance from closest point to ref point in meters.
|
||||||
|
-- @return #PATHLINE.Segment Closest segment of ref point.
|
||||||
|
function PATHLINE:GetClosestPoint3D(Vec3)
|
||||||
|
|
||||||
|
local P=nil --DCS#Vec3
|
||||||
|
local D=math.huge
|
||||||
|
local S={} --#PATHLINE.Segment
|
||||||
|
|
||||||
|
if not Vec3 then
|
||||||
|
self:E(self.lid.."ERROR: input Vec3 is nil!")
|
||||||
|
return nil, nil, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=2,#self.points do
|
||||||
|
|
||||||
|
local A=self.points[i-1] --#PATHLINE.Point
|
||||||
|
local B=self.points[i] --#PATHLINE.Point
|
||||||
|
|
||||||
|
local a=A.vec3
|
||||||
|
local b=B.vec3
|
||||||
|
|
||||||
|
local ab=UTILS.VecSubstract(b, a)
|
||||||
|
local ap=UTILS.VecSubstract(Vec3, a)
|
||||||
|
|
||||||
|
local proj=UTILS.VecDot(ap, ab)
|
||||||
|
|
||||||
|
local lab=UTILS.VecNorm(ab)
|
||||||
|
|
||||||
|
local f=proj/lab/lab
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:T(self.lid..string.format("Proj=%.1f, |ab|=%.1f, f=%.1f", proj, lab, f))
|
||||||
|
|
||||||
|
-- Cases for finite segment.
|
||||||
|
local p=nil --DCS#Vec2
|
||||||
|
if f<0 then
|
||||||
|
p=a
|
||||||
|
elseif f>1 then
|
||||||
|
p=b
|
||||||
|
else
|
||||||
|
local r=UTILS.VecMult(ab, f)
|
||||||
|
p=UTILS.VecAdd(a, r)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Distance.
|
||||||
|
local d=UTILS.VecDist3D(p, Vec3)
|
||||||
|
|
||||||
|
if d<=D then
|
||||||
|
D=d
|
||||||
|
P=p
|
||||||
|
S.p1=A
|
||||||
|
S.p2=B
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return P, D, S
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Write PATHLINE to JSON file.
|
||||||
|
-- **NOTE**: Requires `io` and `lfs` to be de-sanitized!
|
||||||
|
-- @param #PATHLINE self
|
||||||
|
-- @param #string FileName Name of the file. Default is the name of the pathline.
|
||||||
|
-- @return #PATHLINE self
|
||||||
|
function PATHLINE:WriteJSON(FileName)
|
||||||
|
|
||||||
|
if io and lfs then
|
||||||
|
|
||||||
|
-- JSON script.
|
||||||
|
local json=loadfile("Scripts\\JSON.lua")()
|
||||||
|
|
||||||
|
local data={}
|
||||||
|
|
||||||
|
-- We store the name and the points.
|
||||||
|
data.name=self.name
|
||||||
|
data.points=self.points
|
||||||
|
for i,_point in pairs(self.points) do
|
||||||
|
local point=_point --#PATHLINE.Point
|
||||||
|
--point.markerID=nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Encode data to raw JSON. Encode converts a lua table into JSON string that can be written to file.
|
||||||
|
local raw_json=json:encode(data)
|
||||||
|
|
||||||
|
-- Debug data.
|
||||||
|
self:T(data)
|
||||||
|
|
||||||
|
-- Write in "User/Saved Games/" Folder.
|
||||||
|
local filepath=lfs.writedir() .. FileName
|
||||||
|
|
||||||
|
-- Open file for writing.
|
||||||
|
local f = io.open(filepath, "wb")
|
||||||
|
if f then
|
||||||
|
f:write(raw_json)
|
||||||
|
f:close()
|
||||||
|
self:T(self.lid .. string.format("Saving PATHLINE %s file %s", self.name, tostring(filepath)))
|
||||||
|
else
|
||||||
|
self:E(self.lid .. string.format( "ERROR: Could not save PATHLINE to file %s", tostring(filepath)))
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
self:E(self.lid .. string.format( "ERROR: Could not save results because IO and/or LFS are not de-sanitized!"))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Read PATHLINE from JSON file.
|
||||||
|
-- **NOTE**: Requires `io` and `lfs` to be de-sanitized!
|
||||||
|
-- @param #PATHLINE self
|
||||||
|
-- @param #string FileName Name of the file.
|
||||||
|
-- @return #PATHLINE self
|
||||||
|
function PATHLINE:NewFromJSON(FileName)
|
||||||
|
|
||||||
|
if io and lfs then
|
||||||
|
|
||||||
|
-- JSON script.
|
||||||
|
local json=loadfile("Scripts\\JSON.lua")()
|
||||||
|
|
||||||
|
local data={}
|
||||||
|
|
||||||
|
-- Write in "User/Saved Games/" Folder.
|
||||||
|
local filepath=lfs.writedir() .. FileName
|
||||||
|
|
||||||
|
--env.info(filepath)
|
||||||
|
|
||||||
|
-- Open file in binary mode for reading.
|
||||||
|
local f = io.open(filepath, "rb")
|
||||||
|
if f then
|
||||||
|
data = f:read("*all")
|
||||||
|
f:close()
|
||||||
|
else
|
||||||
|
env.info(string.format("WARNING: Could not load PATHLINE from file %s!", tostring(filepath)))
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Decode JSON data to get a lua table.
|
||||||
|
local data=json:decode(data)
|
||||||
|
|
||||||
|
if data and data.name then
|
||||||
|
|
||||||
|
-- Create a new pathline instance.
|
||||||
|
local self=PATHLINE:New(data.name)
|
||||||
|
|
||||||
|
for i=1,#data.points do
|
||||||
|
local point=data.points[i] --#PATHLINE.Point
|
||||||
|
|
||||||
|
-- Create new point from data.
|
||||||
|
local p=self:AddPointFromVec3(point.vec3)
|
||||||
|
|
||||||
|
-- Set name.
|
||||||
|
p.name=point.name
|
||||||
|
|
||||||
|
-- Remove marker ID.
|
||||||
|
p.markerID=nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
else
|
||||||
|
BASE:E("ERROR: Cannot find pathline name in data from JSON file. File may be corrupted!")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
BASE:E("ERROR: IO and/or LFS not de-sanitized! Cannot read file.")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Private functions
|
-- Private functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -339,32 +681,56 @@ end
|
|||||||
--- Get 3D points of pathline.
|
--- Get 3D points of pathline.
|
||||||
-- @param #PATHLINE self
|
-- @param #PATHLINE self
|
||||||
-- @param DCS#Vec3 Vec Position vector. Can also be a DCS#Vec2 in which case the altitude at landheight is taken.
|
-- @param DCS#Vec3 Vec Position vector. Can also be a DCS#Vec2 in which case the altitude at landheight is taken.
|
||||||
-- @return #PATHLINE.Point
|
-- @return #PATHLINE.Point Pathline Point.
|
||||||
function PATHLINE:_CreatePoint(Vec)
|
function PATHLINE:_CreatePoint(Vec)
|
||||||
|
|
||||||
local point={} --#PATHLINE.Point
|
local point={} --#PATHLINE.Point
|
||||||
|
|
||||||
|
self.counter=self.counter+1
|
||||||
|
|
||||||
|
point.uid=self.counter
|
||||||
|
point.mother=self.name
|
||||||
|
|
||||||
|
point.name=string.format("%s #%d", self.name, point.uid)
|
||||||
|
|
||||||
if Vec.z then
|
if Vec.z then
|
||||||
-- Given vec is 3D
|
-- Given vec is 3D
|
||||||
point.vec3=UTILS.DeepCopy(Vec)
|
point.vec3=UTILS.DeepCopy(Vec)
|
||||||
point.vec2={x=Vec.x, y=Vec.z}
|
point.vec2={x=Vec.x, y=Vec.z}
|
||||||
else
|
else
|
||||||
-- Given vec is 2D
|
-- Given vec is 2D
|
||||||
point.vec2=UTILS.DeepCopy(Vec)
|
point.vec2=UTILS.DeepCopy(Vec)
|
||||||
point.vec3={x=Vec.x, y=land.getHeight(Vec), z=Vec.y}
|
point.vec3={x=Vec.x, y=land.getHeight(Vec), z=Vec.y}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Get surface type.
|
-- Get surface type.
|
||||||
point.surfaceType=land.getSurfaceType(point.vec2)
|
point.surfaceType=land.getSurfaceType(point.vec2)
|
||||||
|
|
||||||
-- Get land height and depth.
|
-- Get land height and depth.
|
||||||
point.landHeight, point.depth=land.getSurfaceHeightWithSeabed(point.vec2)
|
point.landHeight, point.depth=land.getSurfaceHeightWithSeabed(point.vec2)
|
||||||
|
|
||||||
point.markerID=nil
|
point.markerID=nil
|
||||||
|
|
||||||
return point
|
return point
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get index of point in the lua table.
|
||||||
|
-- @param #PATHLINE self
|
||||||
|
-- @param #PATHLINE.Point Point Given point.
|
||||||
|
-- @return #number index
|
||||||
|
function PATHLINE:_GetPointIndex(Point)
|
||||||
|
|
||||||
|
for i,_point in pairs(self.points) do
|
||||||
|
local point=_point --#PATHLINE.Point
|
||||||
|
|
||||||
|
if point.uid==Point.uid then
|
||||||
|
return i
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -453,6 +453,23 @@ do -- COORDINATE
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Returns the coordinate from the latitude and longitude given in degrees, minutes and seconds (DMS).
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #string Latitude Latitude in DMS as string, e.g. "`42° 24' 14.3"`". Not that the characters `°`, `'` and `"` are important.
|
||||||
|
-- @param #string Longitude Longitude in DMS as string, e.g. "`42° 24' 14.3"`". Not that the characters `°`, `'` and `"` are important.
|
||||||
|
-- @param #number Altitude (Optional) Altitude in meters. Default is the land height at the coordinate.
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:NewFromLLDMS(Latitude, Longitude, Altitude)
|
||||||
|
|
||||||
|
local lat=UTILS.LLDMSstringToDD(Latitude)
|
||||||
|
local lon=UTILS.LLDMSstringToDD(Longitude)
|
||||||
|
|
||||||
|
self=COORDINATE:NewFromLLDD(lat, lon, Altitude)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns if the 2 coordinates are at the same 2D position.
|
--- Returns if the 2 coordinates are at the same 2D position.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #COORDINATE Coordinate
|
-- @param #COORDINATE Coordinate
|
||||||
@@ -661,7 +678,7 @@ do -- COORDINATE
|
|||||||
local _,_,_,_,_,scenerys=self:ScanObjects(radius, false, false, true)
|
local _,_,_,_,_,scenerys=self:ScanObjects(radius, false, false, true)
|
||||||
|
|
||||||
local set={}
|
local set={}
|
||||||
|
|
||||||
for _,_scenery in pairs(scenerys) do
|
for _,_scenery in pairs(scenerys) do
|
||||||
local scenery=_scenery --DCS#Object
|
local scenery=_scenery --DCS#Object
|
||||||
|
|
||||||
@@ -1157,6 +1174,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:
|
||||||
@@ -3474,9 +3647,18 @@ do -- COORDINATE
|
|||||||
return flat, elev
|
return flat, elev
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Return a random COORDINATE within an Outer Radius and optionally NOT within an Inner Radius of the COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param DCS#Distance OuterRadius
|
||||||
|
-- @param DCS#Distance InnerRadius
|
||||||
|
-- @return #COORDINATE
|
||||||
|
function COORDINATE:GetRandomPointVec3InRadius( OuterRadius, InnerRadius )
|
||||||
|
return COORDINATE:NewFromVec3( self:GetRandomVec3InRadius( OuterRadius, InnerRadius ) )
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- POINT_VEC3
|
do
|
||||||
|
|
||||||
--- The POINT_VEC3 class
|
--- The POINT_VEC3 class
|
||||||
-- @type POINT_VEC3
|
-- @type POINT_VEC3
|
||||||
@@ -3493,6 +3675,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 +3764,19 @@ do -- POINT_VEC3
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Create a new POINT_VEC3 object from Vec2 coordinates.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param DCS#Vec2 Vec2 The Vec2 point.
|
|
||||||
-- @param DCS#Distance LandHeightAdd (optional) Add a landheight.
|
|
||||||
-- @return Core.Point#POINT_VEC3 self
|
|
||||||
function POINT_VEC3:NewFromVec2( Vec2, LandHeightAdd )
|
|
||||||
|
|
||||||
local self = BASE:Inherit( self, COORDINATE:NewFromVec2( Vec2, LandHeightAdd ) ) -- Core.Point#POINT_VEC3
|
|
||||||
self:F2( self )
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Create a new POINT_VEC3 object from Vec3 coordinates.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param DCS#Vec3 Vec3 The Vec3 point.
|
|
||||||
-- @return Core.Point#POINT_VEC3 self
|
|
||||||
function POINT_VEC3:NewFromVec3( Vec3 )
|
|
||||||
|
|
||||||
local self = BASE:Inherit( self, COORDINATE:NewFromVec3( Vec3 ) ) -- Core.Point#POINT_VEC3
|
|
||||||
self:F2( self )
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Return the x coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @return #number The x coordinate.
|
|
||||||
function POINT_VEC3:GetX()
|
|
||||||
return self.x
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Return the y coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @return #number The y coordinate.
|
|
||||||
function POINT_VEC3:GetY()
|
|
||||||
return self.y
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Return the z coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @return #number The z coordinate.
|
|
||||||
function POINT_VEC3:GetZ()
|
|
||||||
return self.z
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the x coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param #number x The x coordinate.
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:SetX( x )
|
|
||||||
self.x = x
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the y coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param #number y The y coordinate.
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:SetY( y )
|
|
||||||
self.y = y
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the z coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param #number z The z coordinate.
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:SetZ( z )
|
|
||||||
self.z = z
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Add to the x coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param #number x The x coordinate value to add to the current x coordinate.
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:AddX( x )
|
|
||||||
self.x = self.x + x
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Add to the y coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param #number y The y coordinate value to add to the current y coordinate.
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:AddY( y )
|
|
||||||
self.y = self.y + y
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Add to the z coordinate of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param #number z The z coordinate value to add to the current z coordinate.
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:AddZ( z )
|
|
||||||
self.z = self.z +z
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Return a random POINT_VEC3 within an Outer Radius and optionally NOT within an Inner Radius of the POINT_VEC3.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param DCS#Distance OuterRadius
|
|
||||||
-- @param DCS#Distance InnerRadius
|
|
||||||
-- @return #POINT_VEC3
|
|
||||||
function POINT_VEC3:GetRandomPointVec3InRadius( OuterRadius, InnerRadius )
|
|
||||||
|
|
||||||
return POINT_VEC3:NewFromVec3( self:GetRandomVec3InRadius( OuterRadius, InnerRadius ) )
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- POINT_VEC2
|
do
|
||||||
|
|
||||||
-- @type POINT_VEC2
|
--- @type POINT_VEC2
|
||||||
-- @field DCS#Distance x The x coordinate in meters.
|
-- @field DCS#Distance x The x coordinate in meters.
|
||||||
-- @field DCS#Distance y the y coordinate in meters.
|
-- @field DCS#Distance y the y coordinate in meters.
|
||||||
-- @extends Core.Point#COORDINATE
|
-- @extends Core.Point#COORDINATE
|
||||||
|
|
||||||
--- Defines a 2D point in the simulator. The height coordinate (if needed) will be the land height + an optional added height specified.
|
--- Defines a 2D point in the simulator. The height coordinate (if needed) will be the land height + an optional added height specified.
|
||||||
--
|
--
|
||||||
|
-- **DEPRECATED - PLEASE USE COORDINATE!**
|
||||||
|
--
|
||||||
-- ## POINT_VEC2 constructor
|
-- ## POINT_VEC2 constructor
|
||||||
--
|
--
|
||||||
-- A new POINT_VEC2 instance can be created with:
|
-- A new POINT_VEC2 instance can be created with:
|
||||||
@@ -3751,166 +3824,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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -1242,12 +1242,12 @@ do
|
|||||||
return GroupFound
|
return GroupFound
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Iterate the SET_GROUP while identifying the nearest object from a @{Core.Point#POINT_VEC2}.
|
--- Iterate the SET_GROUP while identifying the nearest object from a @{Core.Point#COORDINATE}.
|
||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
-- @param Core.Point#POINT_VEC2 PointVec2 A @{Core.Point#POINT_VEC2} object from where to evaluate the closest object in the set.
|
-- @param Core.Point#COORDINATE Coordinate A @{Core.Point#COORDINATE} object from where to evaluate the closest object in the set.
|
||||||
-- @return Wrapper.Group#GROUP The closest group.
|
-- @return Wrapper.Group#GROUP The closest group.
|
||||||
function SET_GROUP:FindNearestGroupFromPointVec2( PointVec2 )
|
function SET_GROUP:FindNearestGroupFromPointVec2( Coordinate )
|
||||||
--self:F2( PointVec2 )
|
--self:F2( Coordinate )
|
||||||
|
|
||||||
local NearestGroup = nil -- Wrapper.Group#GROUP
|
local NearestGroup = nil -- Wrapper.Group#GROUP
|
||||||
local ClosestDistance = nil
|
local ClosestDistance = nil
|
||||||
@@ -1257,9 +1257,9 @@ do
|
|||||||
for ObjectID, ObjectData in pairs( Set ) do
|
for ObjectID, ObjectData in pairs( Set ) do
|
||||||
if NearestGroup == nil then
|
if NearestGroup == nil then
|
||||||
NearestGroup = ObjectData
|
NearestGroup = ObjectData
|
||||||
ClosestDistance = PointVec2:DistanceFromPointVec2( ObjectData:GetCoordinate() )
|
ClosestDistance = Coordinate:DistanceFromPointVec2( ObjectData:GetCoordinate() )
|
||||||
else
|
else
|
||||||
local Distance = PointVec2:DistanceFromPointVec2( ObjectData:GetCoordinate() )
|
local Distance = Coordinate:DistanceFromPointVec2( ObjectData:GetCoordinate() )
|
||||||
if Distance < ClosestDistance then
|
if Distance < ClosestDistance then
|
||||||
NearestGroup = ObjectData
|
NearestGroup = ObjectData
|
||||||
ClosestDistance = Distance
|
ClosestDistance = Distance
|
||||||
@@ -2519,6 +2519,35 @@ do -- SET_UNIT
|
|||||||
)
|
)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Builds a set of units which belong to groups with certain **group names**.
|
||||||
|
-- @param #SET_UNIT self
|
||||||
|
-- @param #string Prefixes The (partial) group names to look for. Can be a single string or a table of strings.
|
||||||
|
-- @return #SET_UNIT self
|
||||||
|
function SET_UNIT:FilterGroupPrefixes(Prefixes)
|
||||||
|
if type(Prefixes) == "string" then
|
||||||
|
Prefixes = {Prefixes}
|
||||||
|
end
|
||||||
|
self:FilterFunction(
|
||||||
|
function(unit,prefixes)
|
||||||
|
local outcome = false
|
||||||
|
if unit then
|
||||||
|
local grp = unit:GetGroup()
|
||||||
|
local gname = grp ~= nil and grp:GetName() or "none"
|
||||||
|
for _,_fix in pairs(prefixes or {}) do
|
||||||
|
if string.find(gname,_fix) then
|
||||||
|
outcome = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return outcome
|
||||||
|
end, Prefixes
|
||||||
|
)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Builds a set of units having a radar of give types.
|
--- Builds a set of units having a radar of give types.
|
||||||
-- All the units having a radar of a given type will be included within the set.
|
-- All the units having a radar of a given type will be included within the set.
|
||||||
@@ -4434,6 +4463,35 @@ do -- SET_CLIENT
|
|||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Builds a set of clients which belong to groups with certain **group names**.
|
||||||
|
-- @param #SET_CLIENT self
|
||||||
|
-- @param #string Prefixes The (partial) group names to look for. Can be anywhere in the group name. Can be a single string or a table of strings.
|
||||||
|
-- @return #SET_CLIENT self
|
||||||
|
function SET_CLIENT:FilterGroupPrefixes(Prefixes)
|
||||||
|
if type(Prefixes) == "string" then
|
||||||
|
Prefixes = {Prefixes}
|
||||||
|
end
|
||||||
|
self:FilterFunction(
|
||||||
|
function(unit,prefixes)
|
||||||
|
local outcome = false
|
||||||
|
if unit then
|
||||||
|
local grp = unit:GetGroup()
|
||||||
|
local gname = grp ~= nil and grp:GetName() or "none"
|
||||||
|
for _,_fix in pairs(prefixes or {}) do
|
||||||
|
if string.find(gname,_fix) then
|
||||||
|
outcome = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return outcome
|
||||||
|
end, Prefixes
|
||||||
|
)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Builds a set of clients that are only active.
|
--- Builds a set of clients that are only active.
|
||||||
-- Only the clients that are active will be included within the set.
|
-- Only the clients that are active will be included within the set.
|
||||||
@@ -5670,14 +5728,14 @@ do -- SET_AIRBASE
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Iterate the SET_AIRBASE while identifying the nearest @{Wrapper.Airbase#AIRBASE} from a @{Core.Point#POINT_VEC2}.
|
--- Iterate the SET_AIRBASE while identifying the nearest @{Wrapper.Airbase#AIRBASE} from a @{Core.Point#COORDINATE}.
|
||||||
-- @param #SET_AIRBASE self
|
-- @param #SET_AIRBASE self
|
||||||
-- @param Core.Point#POINT_VEC2 PointVec2 A @{Core.Point#POINT_VEC2} object from where to evaluate the closest @{Wrapper.Airbase#AIRBASE}.
|
-- @param Core.Point#COORDINATE Coordinate A @{Core.Point#COORDINATE} object from where to evaluate the closest @{Wrapper.Airbase#AIRBASE}.
|
||||||
-- @return Wrapper.Airbase#AIRBASE The closest @{Wrapper.Airbase#AIRBASE}.
|
-- @return Wrapper.Airbase#AIRBASE The closest @{Wrapper.Airbase#AIRBASE}.
|
||||||
function SET_AIRBASE:FindNearestAirbaseFromPointVec2( PointVec2 )
|
function SET_AIRBASE:FindNearestAirbaseFromPointVec2( Coordinate )
|
||||||
--self:F2( PointVec2 )
|
--self:F2( Coordinate )
|
||||||
|
|
||||||
local NearestAirbase = self:FindNearestObjectFromPointVec2( PointVec2 )
|
local NearestAirbase = self:FindNearestObjectFromPointVec2( Coordinate )
|
||||||
return NearestAirbase
|
return NearestAirbase
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -6007,17 +6065,19 @@ do -- SET_CARGO
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (R2.1) Iterate the SET_CARGO while identifying the nearest @{Cargo.Cargo#CARGO} from a @{Core.Point#POINT_VEC2}.
|
--- (R2.1) Iterate the SET_CARGO while identifying the nearest @{Cargo.Cargo#CARGO} from a @{Core.Point#COORDINATE}.
|
||||||
-- @param #SET_CARGO self
|
-- @param #SET_CARGO self
|
||||||
-- @param Core.Point#POINT_VEC2 PointVec2 A @{Core.Point#POINT_VEC2} object from where to evaluate the closest @{Cargo.Cargo#CARGO}.
|
-- @param Core.Point#COORDINATE Coordinate A @{Core.Point#COORDINATE} object from where to evaluate the closest @{Cargo.Cargo#CARGO}.
|
||||||
-- @return Cargo.Cargo#CARGO The closest @{Cargo.Cargo#CARGO}.
|
-- @return Cargo.Cargo#CARGO The closest @{Cargo.Cargo#CARGO}.
|
||||||
function SET_CARGO:FindNearestCargoFromPointVec2( PointVec2 ) -- R2.1
|
function SET_CARGO:FindNearestCargoFromPointVec2( Coordinate ) -- R2.1
|
||||||
--self:F2( PointVec2 )
|
--self:F2( Coordinate )
|
||||||
|
|
||||||
local NearestCargo = self:FindNearestObjectFromPointVec2( PointVec2 )
|
local NearestCargo = self:FindNearestObjectFromPointVec2( Coordinate )
|
||||||
return NearestCargo
|
return NearestCargo
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @param #SET_CARGO self
|
||||||
function SET_CARGO:FirstCargoWithState( State )
|
function SET_CARGO:FirstCargoWithState( State )
|
||||||
|
|
||||||
local FirstCargo = nil
|
local FirstCargo = nil
|
||||||
@@ -6032,6 +6092,8 @@ do -- SET_CARGO
|
|||||||
return FirstCargo
|
return FirstCargo
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @param #SET_CARGO self
|
||||||
function SET_CARGO:FirstCargoWithStateAndNotDeployed( State )
|
function SET_CARGO:FirstCargoWithStateAndNotDeployed( State )
|
||||||
|
|
||||||
local FirstCargo = nil
|
local FirstCargo = nil
|
||||||
@@ -8693,7 +8755,6 @@ do -- SET_DYNAMICCARGO
|
|||||||
-- @field #SET_DYNAMICCARGO SET_DYNAMICCARGO
|
-- @field #SET_DYNAMICCARGO SET_DYNAMICCARGO
|
||||||
SET_DYNAMICCARGO = {
|
SET_DYNAMICCARGO = {
|
||||||
ClassName = "SET_DYNAMICCARGO",
|
ClassName = "SET_DYNAMICCARGO",
|
||||||
Filter = {},
|
|
||||||
Set = {},
|
Set = {},
|
||||||
List = {},
|
List = {},
|
||||||
Index = {},
|
Index = {},
|
||||||
|
|||||||
@@ -1631,7 +1631,7 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
|
|||||||
|
|
||||||
if SpawnTemplate then
|
if SpawnTemplate then
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:New( SpawnTemplate.route.points[1].x, SpawnTemplate.route.points[1].alt, SpawnTemplate.route.points[1].y )
|
local PointVec3 = COORDINATE:New( SpawnTemplate.route.points[1].x, SpawnTemplate.route.points[1].alt, SpawnTemplate.route.points[1].y )
|
||||||
--self:T2( { "Current point of ", self.SpawnTemplatePrefix, PointVec3 } )
|
--self:T2( { "Current point of ", self.SpawnTemplatePrefix, PointVec3 } )
|
||||||
|
|
||||||
-- If RandomizePosition, then Randomize the formation in the zone band, keeping the template.
|
-- If RandomizePosition, then Randomize the formation in the zone band, keeping the template.
|
||||||
@@ -2830,7 +2830,7 @@ end
|
|||||||
function SPAWN:SpawnFromVec3( Vec3, SpawnIndex )
|
function SPAWN:SpawnFromVec3( Vec3, SpawnIndex )
|
||||||
--self:F( { self.SpawnTemplatePrefix, Vec3, SpawnIndex } )
|
--self:F( { self.SpawnTemplatePrefix, Vec3, SpawnIndex } )
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:NewFromVec3( Vec3 )
|
local PointVec3 = COORDINATE:NewFromVec3( Vec3 )
|
||||||
--self:T2( PointVec3 )
|
--self:T2( PointVec3 )
|
||||||
|
|
||||||
if SpawnIndex then
|
if SpawnIndex then
|
||||||
@@ -2906,7 +2906,7 @@ end
|
|||||||
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
|
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
|
||||||
-- You can use the returned group to further define the route to be followed.
|
-- You can use the returned group to further define the route to be followed.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param Core.Point#POINT_VEC3 PointVec3 The PointVec3 coordinates where to spawn the group.
|
-- @param Core.Point#COORDINATE PointVec3 The COORDINATE coordinates where to spawn the group.
|
||||||
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
||||||
-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned.
|
-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned.
|
||||||
-- @usage
|
-- @usage
|
||||||
@@ -2954,12 +2954,12 @@ function SPAWN:SpawnFromVec2( Vec2, MinHeight, MaxHeight, SpawnIndex )
|
|||||||
return self:SpawnFromVec3( { x = Vec2.x, y = Height, z = Vec2.y }, SpawnIndex ) -- y can be nil. In this case, spawn on the ground for vehicles, and in the template altitude for air.
|
return self:SpawnFromVec3( { x = Vec2.x, y = Height, z = Vec2.y }, SpawnIndex ) -- y can be nil. In this case, spawn on the ground for vehicles, and in the template altitude for air.
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Will spawn a group from a POINT_VEC2 in 3D space.
|
--- Will spawn a group from a COORDINATE in 3D space.
|
||||||
-- This method is mostly advisable to be used if you want to simulate spawning groups on the ground from air units, like vehicles.
|
-- This method is mostly advisable to be used if you want to simulate spawning groups on the ground from air units, like vehicles.
|
||||||
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
|
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
|
||||||
-- You can use the returned group to further define the route to be followed.
|
-- You can use the returned group to further define the route to be followed.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param Core.Point#POINT_VEC2 PointVec2 The PointVec2 coordinates where to spawn the group.
|
-- @param Core.Point#COORDINATE PointVec2 The coordinates where to spawn the group.
|
||||||
-- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone.
|
-- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone.
|
||||||
-- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone.
|
-- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone.
|
||||||
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
--
|
--
|
||||||
-- * @{#SPAWNSTATIC.Spawn}(Heading, NewName) spawns the static with the set parameters. Optionally, heading and name can be given. The name **must be unique**!
|
-- * @{#SPAWNSTATIC.Spawn}(Heading, NewName) spawns the static with the set parameters. Optionally, heading and name can be given. The name **must be unique**!
|
||||||
-- * @{#SPAWNSTATIC.SpawnFromCoordinate}(Coordinate, Heading, NewName) spawn the static at the given coordinate. Optionally, heading and name can be given. The name **must be unique**!
|
-- * @{#SPAWNSTATIC.SpawnFromCoordinate}(Coordinate, Heading, NewName) spawn the static at the given coordinate. Optionally, heading and name can be given. The name **must be unique**!
|
||||||
-- * @{#SPAWNSTATIC.SpawnFromPointVec2}(PointVec2, Heading, NewName) spawns the static at a POINT_VEC2 coordinate. Optionally, heading and name can be given. The name **must be unique**!
|
-- * @{#SPAWNSTATIC.SpawnFromPointVec2}(PointVec2, Heading, NewName) spawns the static at a COORDINATE coordinate. Optionally, heading and name can be given. The name **must be unique**!
|
||||||
-- * @{#SPAWNSTATIC.SpawnFromZone}(Zone, Heading, NewName) spawns the static at the center of a @{Core.Zone}. Optionally, heading and name can be given. The name **must be unique**!
|
-- * @{#SPAWNSTATIC.SpawnFromZone}(Zone, Heading, NewName) spawns the static at the center of a @{Core.Zone}. Optionally, heading and name can be given. The name **must be unique**!
|
||||||
--
|
--
|
||||||
-- @field #SPAWNSTATIC SPAWNSTATIC
|
-- @field #SPAWNSTATIC SPAWNSTATIC
|
||||||
@@ -411,9 +411,9 @@ function SPAWNSTATIC:Spawn(Heading, NewName)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Creates a new @{Wrapper.Static} from a POINT_VEC2.
|
--- Creates a new @{Wrapper.Static} from a COORDINATE.
|
||||||
-- @param #SPAWNSTATIC self
|
-- @param #SPAWNSTATIC self
|
||||||
-- @param Core.Point#POINT_VEC2 PointVec2 The 2D coordinate where to spawn the static.
|
-- @param Core.Point#COORDINATE PointVec2 The 2D coordinate where to spawn the static.
|
||||||
-- @param #number Heading The heading of the static, which is a number in degrees from 0 to 360.
|
-- @param #number Heading The heading of the static, which is a number in degrees from 0 to 360.
|
||||||
-- @param #string NewName (Optional) The name of the new static.
|
-- @param #string NewName (Optional) The name of the new static.
|
||||||
-- @return Wrapper.Static#STATIC The static spawned.
|
-- @return Wrapper.Static#STATIC The static spawned.
|
||||||
|
|||||||
1200
Moose Development/Moose/Core/Vector.lua
Normal file
1200
Moose Development/Moose/Core/Vector.lua
Normal file
File diff suppressed because it is too large
Load Diff
@@ -213,7 +213,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 +227,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 +261,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 } )
|
||||||
|
|
||||||
@@ -305,6 +305,20 @@ function ZONE_BASE:GetCoordinate( Height ) --R2.1
|
|||||||
return self.Coordinate
|
return self.Coordinate
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns the @{Core.Vector#VECTOR} of the zone.
|
||||||
|
-- @param #ZONE_BASE self
|
||||||
|
-- @param DCS#Distance Height The height in meters to add to the land height where the center of the zone is located.
|
||||||
|
-- @return Core.Vector#VECTOR The vector of the zone.
|
||||||
|
function ZONE_BASE:GetVector( Height )
|
||||||
|
self:F2(self.ZoneName)
|
||||||
|
|
||||||
|
local Vec3 = self:GetVec3( Height )
|
||||||
|
|
||||||
|
local vector=VECTOR:NewFromVec(Vec3)
|
||||||
|
|
||||||
|
return vector
|
||||||
|
end
|
||||||
|
|
||||||
--- Get 2D distance to a coordinate.
|
--- Get 2D distance to a coordinate.
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @param Core.Point#COORDINATE Coordinate Reference coordinate. Can also be a DCS#Vec2 or DCS#Vec3 object.
|
-- @param Core.Point#COORDINATE Coordinate Reference coordinate. Can also be a DCS#Vec2 or DCS#Vec3 object.
|
||||||
@@ -330,16 +344,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
|
||||||
@@ -814,8 +828,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 +1024,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 +1054,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
|
||||||
@@ -1561,15 +1575,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 +1606,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 } )
|
||||||
|
|
||||||
@@ -2036,15 +2050,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 +2206,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
|
||||||
--
|
--
|
||||||
@@ -2769,7 +2783,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 +2818,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
|
||||||
@@ -2880,26 +2894,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 )
|
||||||
|
|
||||||
@@ -3931,18 +3945,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 +4096,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 } )
|
||||||
|
|
||||||
|
|||||||
@@ -107,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
|
||||||
@@ -138,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
|
||||||
@@ -202,4 +202,3 @@ function ZONE_DETECTION:IsVec3InZone( Vec3 )
|
|||||||
|
|
||||||
return InZone
|
return InZone
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -437,16 +437,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 +461,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="Short", Radar="PantsirS1" },
|
||||||
["PantsirS2 CHM"] = { Range=30, Blindspot=1.2, Height=18, Type="Medium", Radar="PantsirS2" },
|
["PantsirS2 CHM"] = { Range=30, Blindspot=1.2, Height=18, Type="Medium", Radar="PantsirS2" },
|
||||||
["PGL-625 CHM"] = { Range=10, Blindspot=0.5, Height=5, Type="Short", Radar="PGL_625" },
|
["PGL-625 CHM"] = { Range=10, Blindspot=1, Height=5, Type="Short", Radar="PGL_625" },
|
||||||
["HQ-17A CHM"] = { Range=20, Blindspot=1.5, Height=10, Type="Short", Radar="HQ17A" },
|
["HQ-17A CHM"] = { Range=15, Blindspot=1.5, Height=10, Type="Short", Radar="HQ17A" },
|
||||||
["M903PAC2 CHM"] = { Range=160, Blindspot=3, Height=24.5, Type="Long", Radar="MIM104_M903_PAC2" },
|
["M903PAC2 CHM"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="MIM104_M903_PAC2" },
|
||||||
["M903PAC3 CHM"] = { Range=120, Blindspot=1, Height=40, Type="Long", Radar="MIM104_M903_PAC3" },
|
["M903PAC3 CHM"] = { Range=160, Blindspot=1, Height=40, Type="Long", Radar="MIM104_M903_PAC3" },
|
||||||
["TorM2 CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2" },
|
["TorM2 CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2" },
|
||||||
["TorM2K CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2K" },
|
["TorM2K CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2K" },
|
||||||
["TorM2M CHM"] = { Range=16, Blindspot=1, Height=10, Type="Short", Radar="TorM2M" },
|
["TorM2M CHM"] = { Range=16, Blindspot=1, Height=10, Type="Short", Radar="TorM2M" },
|
||||||
["NASAMS3-AMRAAMER CHM"] = { Range=50, Blindspot=2, Height=35.7, Type="Medium", Radar="CH_NASAMS3_LN_AMRAAM_ER" },
|
["NASAMS3-AMRAAMER CHM"] = { Range=50, Blindspot=2, Height=35.7, Type="Medium", Radar="CH_NASAMS3_LN_AMRAAM_ER" },
|
||||||
["NASAMS3-AIM9X2 CHM"] = { Range=20, Blindspot=0.2, Height=18, Type="Short", Radar="CH_NASAMS3_LN_AIM9X2" },
|
["NASAMS3-AIM9X2 CHM"] = { Range=20, Blindspot=0.2, Height=18, Type="Short", Radar="CH_NASAMS3_LN_AIM9X2" },
|
||||||
["C-RAM CHM"] = { Range=2, Blindspot=0, Height=2, Type="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" },
|
||||||
}
|
}
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Core/MarkerOps_Base.lua' )
|
|||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Core/TextAndSound.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Core/TextAndSound.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Core/Pathline.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Core/Pathline.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Core/ClientMenu.lua')
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Core/ClientMenu.lua')
|
||||||
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Core/Vector.lua')
|
||||||
|
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Object.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Object.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Identifiable.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Identifiable.lua' )
|
||||||
@@ -186,4 +187,9 @@ __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Tasking/Task_Cargo_Dispatcher
|
|||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Tasking/Task_Capture_Zone.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Tasking/Task_Capture_Zone.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Tasking/Task_Capture_Dispatcher.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Tasking/Task_Capture_Dispatcher.lua' )
|
||||||
|
|
||||||
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Navigation/Beacons.lua' )
|
||||||
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Navigation/Point.lua' )
|
||||||
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Navigation/Procedure.lua' )
|
||||||
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Navigation/FlightPlan.lua' )
|
||||||
|
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Globals.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Globals.lua' )
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ __Moose.Include( 'Core\\MarkerOps_Base.lua' )
|
|||||||
__Moose.Include( 'Core\\TextAndSound.lua' )
|
__Moose.Include( 'Core\\TextAndSound.lua' )
|
||||||
__Moose.Include( 'Core\\Condition.lua' )
|
__Moose.Include( 'Core\\Condition.lua' )
|
||||||
__Moose.Include( 'Core\\ClientMenu.lua' )
|
__Moose.Include( 'Core\\ClientMenu.lua' )
|
||||||
|
__Moose.Include( 'Core\\Vector.lua' )
|
||||||
|
|
||||||
__Moose.Include( 'Wrapper\\Object.lua' )
|
__Moose.Include( 'Wrapper\\Object.lua' )
|
||||||
__Moose.Include( 'Wrapper\\Identifiable.lua' )
|
__Moose.Include( 'Wrapper\\Identifiable.lua' )
|
||||||
@@ -178,4 +179,7 @@ __Moose.Include( 'Tasking\\Task_Cargo_Dispatcher.lua' )
|
|||||||
__Moose.Include( 'Tasking\\Task_Capture_Zone.lua' )
|
__Moose.Include( 'Tasking\\Task_Capture_Zone.lua' )
|
||||||
__Moose.Include( 'Tasking\\Task_Capture_Dispatcher.lua' )
|
__Moose.Include( 'Tasking\\Task_Capture_Dispatcher.lua' )
|
||||||
|
|
||||||
|
__Moose.Include( 'Navigation\\Point.lua' )
|
||||||
|
__Moose.Include( 'Navigation\\Beacons.lua' )
|
||||||
|
|
||||||
__Moose.Include( 'Globals.lua' )
|
__Moose.Include( 'Globals.lua' )
|
||||||
|
|||||||
139
Moose Development/Moose/Navigation/Beacons.lua
Normal file
139
Moose Development/Moose/Navigation/Beacons.lua
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
--- **NAVIGATION** - Beacons of the map/theatre.
|
||||||
|
--
|
||||||
|
-- **Main Features:**
|
||||||
|
--
|
||||||
|
-- * Beacons of the map
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ## Example Missions:
|
||||||
|
--
|
||||||
|
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Navigation%20-%20Beacons).
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **funkyfranky**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
-- @module Navigation.Beacons
|
||||||
|
-- @image NAVIGATION_Beacons.png
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- BEACONS class.
|
||||||
|
-- @type BEACONS
|
||||||
|
--
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field #number verbose Verbosity of output.
|
||||||
|
-- @field #table beacons Beacons.
|
||||||
|
--
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
--- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- # The BEACONS Concept
|
||||||
|
--
|
||||||
|
-- The NAVFIX class has a great concept!
|
||||||
|
--
|
||||||
|
-- Bla, bla...
|
||||||
|
--
|
||||||
|
-- # Basic Setup
|
||||||
|
--
|
||||||
|
-- A new `BEACONS` object can be created with the @{#BEACONS.New}() function.
|
||||||
|
--
|
||||||
|
-- local beacons=BEACONS:New("G:\Games\DCS World Testing\Mods\terrains\GermanyColdWar\beacons.lua")
|
||||||
|
--
|
||||||
|
-- This is how it works.
|
||||||
|
--
|
||||||
|
-- @field #BEACONS
|
||||||
|
BEACONS = {
|
||||||
|
ClassName = "BEACONS",
|
||||||
|
verbose = 0,
|
||||||
|
beacons = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
--- BEACONS class version.
|
||||||
|
-- @field #string version
|
||||||
|
BEACONS.version="0.0.0"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- ToDo list
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- TODO: A lot...
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Constructor(s)
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Create a new BECAONS class instance from a given file.
|
||||||
|
-- @param #BEACONS self
|
||||||
|
-- @param #string FileName Full path to the file containing the map beacons.
|
||||||
|
-- @return #BEACONS self
|
||||||
|
function BEACONS:NewFromFile(FileName)
|
||||||
|
|
||||||
|
-- Inherit everything from BASE class.
|
||||||
|
self=BASE:Inherit(self, BASE:New()) -- #BEACONS
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- User Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Add marker all beacons on the F10 map.
|
||||||
|
-- @param #BEACONS self
|
||||||
|
-- @return #BEACONS self
|
||||||
|
function BEACONS:MarkerShow()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove markers of all beacons from the F10 map.
|
||||||
|
-- @param #BEACONS self
|
||||||
|
-- @return #BEACONS self
|
||||||
|
function BEACONS:MarkerRemove()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Private Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Get text displayed in the F10 marker.
|
||||||
|
-- @param #BEACONS self
|
||||||
|
-- @return #string Marker text.
|
||||||
|
function BEACONS:_GetMarkerText(beacon)
|
||||||
|
|
||||||
|
local altmin=self.altMin and tostring(self.altMin) or ""
|
||||||
|
local altmax=self.altMax and tostring(self.altMax) or ""
|
||||||
|
local speedmin=self.speedMin and tostring(self.speedMin) or ""
|
||||||
|
local speedmax=self.speedMax and tostring(self.speedMax) or ""
|
||||||
|
|
||||||
|
|
||||||
|
local text=string.format("NAVFIX %s", self.name)
|
||||||
|
if self.isIAF then
|
||||||
|
text=text..string.format(" (IAF)")
|
||||||
|
end
|
||||||
|
if self.isIF then
|
||||||
|
text=text..string.format(" (IF)")
|
||||||
|
end
|
||||||
|
text=text..string.format("\nAltitude [ft]: %s - %s", altmin, altmax)
|
||||||
|
text=text..string.format("\nSpeed [knots]: %s - %s", speedmin, speedmax)
|
||||||
|
text=text..string.format("\nCompulsory: %s", tostring(self.isCompulsory))
|
||||||
|
text=text..string.format("\nFly Over: %s", tostring(self.isFlyover))
|
||||||
|
|
||||||
|
return text
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
481
Moose Development/Moose/Navigation/FlightPlan.lua
Normal file
481
Moose Development/Moose/Navigation/FlightPlan.lua
Normal file
@@ -0,0 +1,481 @@
|
|||||||
|
--- **NAVIGATION** - Flight Plan.
|
||||||
|
--
|
||||||
|
-- **Main Features:**
|
||||||
|
--
|
||||||
|
-- * Manage navigation aids
|
||||||
|
-- * VOR, NDB
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ## Example Missions:
|
||||||
|
--
|
||||||
|
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Ops%20-%20FlightPlan).
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **funkyfranky**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
-- @module Navigation.FlightPlan
|
||||||
|
-- @image NAVIGATION_FlightPlan.png
|
||||||
|
|
||||||
|
|
||||||
|
--- FLIGHTPLAN class.
|
||||||
|
-- @type FLIGHTPLAN
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field #number verbose Verbosity of output.
|
||||||
|
-- @field #table fixes Navigation fixes.
|
||||||
|
-- @field Core.Pathline#PATHLINE pathline Pathline of the plan.
|
||||||
|
-- @field Wrapper.Airbase#AIRBASE departureAirbase Departure airbase.
|
||||||
|
-- @field Wrapper.Airbase#AIRBASE destinationAirbase Destination airbase.
|
||||||
|
-- @field #number altitudeCruiseMin Minimum cruise altitude in feet MSL.
|
||||||
|
-- @field #number altitudeCruiseMax Maximum cruise altitude in feet MSL.
|
||||||
|
-- @extends Core.Pathline#PATHLINE
|
||||||
|
|
||||||
|
--- *Life is what happens to us while we are making other plans.* -- Allen Saunders
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- # The FLIGHTPLAN Concept
|
||||||
|
--
|
||||||
|
-- This class has a great concept!
|
||||||
|
--
|
||||||
|
-- # Basic Setup
|
||||||
|
--
|
||||||
|
-- A new `FLIGHTPLAN` object can be created with the @{#FLIGHTPLAN.New}() function.
|
||||||
|
--
|
||||||
|
-- myFlightplan=FLIGHTPLAN:New("Plan A")
|
||||||
|
-- myFleet:SetPortZone(ZonePort1stFleet)
|
||||||
|
-- myFleet:Start()
|
||||||
|
--
|
||||||
|
-- A fleet needs a *port zone*, which is set via the @{#FLIGHTPLAN.SetPortZone}(`PortZone`) function. This is the zone where the naval assets are spawned and return to.
|
||||||
|
--
|
||||||
|
-- Finally, the fleet needs to be started using the @{#FLIGHTPLAN.Start}() function. If the fleet is not started, it will not process any requests.
|
||||||
|
--
|
||||||
|
-- @field #FLIGHTPLAN
|
||||||
|
FLIGHTPLAN = {
|
||||||
|
ClassName = "FLIGHTPLAN",
|
||||||
|
verbose = 0,
|
||||||
|
fixes = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Type of flightplan.
|
||||||
|
-- @type FLIGHTPLAN.Type
|
||||||
|
-- @field #string IFRH Instrument Flying Rules High Altitude.
|
||||||
|
-- @field #string IFRL Instrument Flying Rules Low Altitude.
|
||||||
|
-- @field #string VFR Visual Flight Rules.
|
||||||
|
FLIGHTPLAN.Type={
|
||||||
|
IFRH = "IFR High",
|
||||||
|
IFRL = "IFR Low",
|
||||||
|
VFR = "VFR",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- FLIGHTPLAN class version.
|
||||||
|
-- @field #string version
|
||||||
|
FLIGHTPLAN.version="0.0.1"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- ToDo list
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- TODO: How to connect SID, STAR, ENROUTE, TRANSITION, APPROACH. Typical flightplan SID --> ENROUTE --> STAR --> APPROACH
|
||||||
|
-- TODO: Add approach.
|
||||||
|
-- DONE: How to handle the FLIGHTGROUP:_LandAtAirBase
|
||||||
|
-- TODO: Do we always need a holding pattern? https://www.faa.gov/air_traffic/publications/atpubs/aip_html/part2_enr_section_1.5.html#:~:text=If%20no%20holding%20pattern%20is,than%20that%20desired%20by%20ATC.
|
||||||
|
-- DOEN: Read from MSFS file.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Constructor
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Create a new FLIGHTPLAN instance.
|
||||||
|
-- @param #FLIGHTPLAN self
|
||||||
|
-- @param #string Name Name of this flight plan.
|
||||||
|
-- @return #FLIGHTPLAN self
|
||||||
|
function FLIGHTPLAN:New(Name)
|
||||||
|
|
||||||
|
-- Inherit everything from BASE class.
|
||||||
|
self=BASE:Inherit(self, PATHLINE:New(Name)) -- #FLIGHTPLAN
|
||||||
|
|
||||||
|
-- Set alias.
|
||||||
|
self.alias=tostring(Name)
|
||||||
|
|
||||||
|
-- Set some string id for output to DCS.log file.
|
||||||
|
self.lid=string.format("FLIGHTPLAN %s | ", self.alias)
|
||||||
|
|
||||||
|
--self.pathline=PATHLINE:New(Name)
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:I(self.lid..string.format("Created FLIGHTPLAN!"))
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a new FLIGHTPLAN instance from another FLIGHTPLAN acting as blue print.
|
||||||
|
-- The newly created flight plan is deep copied from the given one.
|
||||||
|
-- @param #FLIGHTPLAN self
|
||||||
|
-- @param #FLIGHTPLAN FlightPlan Blue print of the flight plan to copy.
|
||||||
|
-- @return #FLIGHTPLAN self
|
||||||
|
function FLIGHTPLAN:NewFromFlightPlan(FlightPlan)
|
||||||
|
self=UTILS.DeepCopy(FlightPlan)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Create a new FLIGHTPLAN instance from a given file.
|
||||||
|
-- Currently, the file has to be an MSFS 2020 .pln file as, *e.g.*, exported from [Navigraph](https://navigraph.com/).
|
||||||
|
--
|
||||||
|
-- **Note** that the flight plan does only cover the departure, enroute and arrival portions but **not the approach** part!
|
||||||
|
-- @param #FLIGHTPLAN self
|
||||||
|
-- @param #string FileName Full path to file.
|
||||||
|
-- @return #FLIGHTPLAN self
|
||||||
|
function FLIGHTPLAN:NewFromFile(FileName)
|
||||||
|
|
||||||
|
if UTILS.FileExists(FileName) then
|
||||||
|
|
||||||
|
self=FLIGHTPLAN._ReadFileMSFS(FileName)
|
||||||
|
|
||||||
|
else
|
||||||
|
error(string.format("ERROR: File not found! File name=%s", tostring(FileName)))
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- User Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Add navigation fix to the flight plan.
|
||||||
|
-- @param #FLIGHTPLAN self
|
||||||
|
-- @param Navigation.Point#NAVPOINT NavFix The nav fix.
|
||||||
|
-- @return #FLIGHTPLAN self
|
||||||
|
function FLIGHTPLAN:AddNavFix(NavFix)
|
||||||
|
|
||||||
|
table.insert(self.fixes, NavFix)
|
||||||
|
|
||||||
|
local point=self:AddPointFromVec3(NavFix.vector:GetVec3(true))
|
||||||
|
|
||||||
|
point.navpoint=NavFix
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set departure airbase.
|
||||||
|
-- @param #FLIGHTPLAN self
|
||||||
|
-- @param #string AirbaseName Name of the airbase or AIRBASE object.
|
||||||
|
-- @return #FLIGHTPLAN self
|
||||||
|
function FLIGHTPLAN:SetDepartureAirbase(AirbaseName)
|
||||||
|
|
||||||
|
self.departureAirbase=AIRBASE:FindByName(AirbaseName)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set destination airbase.
|
||||||
|
-- @param #FLIGHTPLAN self
|
||||||
|
-- @param #string AirbaseName Name of the airbase or AIRBASE object.
|
||||||
|
-- @return #FLIGHTPLAN self
|
||||||
|
function FLIGHTPLAN:SetDestinationAirbase(AirbaseName)
|
||||||
|
|
||||||
|
self.destinationAirbase=AIRBASE:FindByName(AirbaseName)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set cruise altitude.
|
||||||
|
-- @param #FLIGHTPLAN self
|
||||||
|
-- @param #number AltMin Minimum altitude in feet MSL.
|
||||||
|
-- @param #number AltMax Maximum altitude in feet MSL. Default is `AltMin`.
|
||||||
|
-- @return #FLIGHTPLAN self
|
||||||
|
function FLIGHTPLAN:SetCruiseAltitude(AltMin, AltMax)
|
||||||
|
|
||||||
|
self.altitudeCruiseMin=AltMin
|
||||||
|
self.altitudeCruiseMax=AltMax or self.altitudeCruiseMin
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set cruise speed.
|
||||||
|
-- @param #FLIGHTPLAN self
|
||||||
|
-- @param #number SpeedMin Minimum speed in knots.
|
||||||
|
-- @param #number SpeedMax Maximum speed in knots. Default is `SpeedMin`.
|
||||||
|
-- @return #FLIGHTPLAN self
|
||||||
|
function FLIGHTPLAN:SetCruiseSpeed(SpeedMin, SpeedMax)
|
||||||
|
|
||||||
|
self.speedCruiseMin=SpeedMin
|
||||||
|
self.speedCruiseMax=SpeedMax or self.speedCruiseMin
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the name of this flight plan.
|
||||||
|
-- @param #FLIGHTPLAN self
|
||||||
|
-- @return #string The name.
|
||||||
|
function FLIGHTPLAN:GetName()
|
||||||
|
return self.alias
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get cruise altitude. This returns a random altitude between the set min/max cruise altitudes.
|
||||||
|
-- @param #FLIGHTPLAN self
|
||||||
|
-- @return #number Cruise altitude in feet MSL.
|
||||||
|
function FLIGHTPLAN:GetCruiseAltitude()
|
||||||
|
|
||||||
|
local alt=10000
|
||||||
|
if self.altitudeCruiseMin and self.altitudeCruiseMax then
|
||||||
|
alt=math.random(self.altitudeCruiseMin, self.altitudeCruiseMax)
|
||||||
|
elseif self.altitudeCruiseMin then
|
||||||
|
alt=self.altitudeCruiseMin
|
||||||
|
elseif self.altitudeCruiseMax then
|
||||||
|
alt=self.altitudeCruiseMax
|
||||||
|
end
|
||||||
|
|
||||||
|
return alt
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get cruise speed. This returns a random speed between the set min/max cruise speeds.
|
||||||
|
-- @param #FLIGHTPLAN self
|
||||||
|
-- @return #number Cruise speed in knots.
|
||||||
|
function FLIGHTPLAN:GetCruiseSpeed()
|
||||||
|
|
||||||
|
local speed=250
|
||||||
|
|
||||||
|
if self.speedCruiseMin and self.speedCruiseMax then
|
||||||
|
speed=math.random(self.speedCruiseMin, self.speedCruiseMax)
|
||||||
|
elseif self.speedCruiseMin then
|
||||||
|
speed=self.speedCruiseMin
|
||||||
|
elseif self.altitudeCruiseMax then
|
||||||
|
speed=self.speedCruiseMax
|
||||||
|
end
|
||||||
|
|
||||||
|
return speed
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Private Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Read flight plan from a given MSFS 2020 .plt file.
|
||||||
|
-- @param #string FileName Name of the file.
|
||||||
|
-- @return #FLIGHTPLAN The flight plan.
|
||||||
|
function FLIGHTPLAN._ReadFileMSFS(FileName)
|
||||||
|
|
||||||
|
local function readfile(filename)
|
||||||
|
|
||||||
|
local lines = {}
|
||||||
|
|
||||||
|
-- Open file in read binary mode.
|
||||||
|
local file=assert(io.open(filename, "rb"), string.format("File not found! File name = %s", tostring(filename)))
|
||||||
|
|
||||||
|
for line in file:lines() do
|
||||||
|
lines[#lines+1] = line
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Close file.
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
-- Return data
|
||||||
|
return lines
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- This function returns an XML element, i.e. the string between <...> and </...>.
|
||||||
|
local function getXMLelement(line)
|
||||||
|
local element=string.match(line, ">(.+)<")
|
||||||
|
return element
|
||||||
|
end
|
||||||
|
|
||||||
|
--- This function returns Latitude and Longitude
|
||||||
|
local function getLatLong(line)
|
||||||
|
local latlong=getXMLelement(line)
|
||||||
|
-- The format is "N41° 38' 20.00",E41° 33' 19.00",+000000.00" so we still need to process that.
|
||||||
|
local lat,long=string.match(latlong, "(.+),(.+),")
|
||||||
|
return lat,long
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Read data from file.
|
||||||
|
local data=readfile(FileName)
|
||||||
|
|
||||||
|
local flightplan={}
|
||||||
|
local waypoints={}
|
||||||
|
local wp=nil
|
||||||
|
|
||||||
|
local gotwaypoint=false
|
||||||
|
for i,line in pairs(data) do
|
||||||
|
|
||||||
|
|
||||||
|
--print(line)
|
||||||
|
|
||||||
|
-- Title
|
||||||
|
if string.find(line, "<Title>") then
|
||||||
|
flightplan.title=getXMLelement(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Departure ICAO
|
||||||
|
if string.find(line, "<DepartureID>") then
|
||||||
|
flightplan.departureICAO=getXMLelement(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Destination ICAO
|
||||||
|
if string.find(line, "<DestinationID>") then
|
||||||
|
flightplan.destinationICAO=getXMLelement(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- FPType
|
||||||
|
if string.find(line, "<FPType>") then
|
||||||
|
flightplan.plantype=getXMLelement(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Route type
|
||||||
|
if string.find(line, "<RouteType>") then
|
||||||
|
flightplan.routetype=getXMLelement(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Cruise alt in feet
|
||||||
|
if string.find(line, "<CruisingAlt>") then
|
||||||
|
flightplan.altCruise=getXMLelement(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Departure LLA
|
||||||
|
if string.find(line, "<DepartureLLA>") then
|
||||||
|
local lat,long=getLatLong(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Destination LLA
|
||||||
|
if string.find(line, "<DestinationLLA>") then
|
||||||
|
local lat,long=getLatLong(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Departure Name
|
||||||
|
if string.find(line, "<DepartureName>") then
|
||||||
|
local DepartureName=getXMLelement(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- DestinationName
|
||||||
|
if string.find(line, "<DestinationName>") then
|
||||||
|
local DestinationName=getXMLelement(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- Waypoint stuff
|
||||||
|
---
|
||||||
|
|
||||||
|
-- New waypoint starts.
|
||||||
|
if string.find(line, "ATCWaypoint id") then
|
||||||
|
|
||||||
|
--Get string inside quotes " and ".
|
||||||
|
local wpid=string.match(line, [["(.+)"]])
|
||||||
|
|
||||||
|
-- Create a new wp table.
|
||||||
|
wp={}
|
||||||
|
|
||||||
|
-- Set waypoint name.
|
||||||
|
wp.name=wpid
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Waypoint info ends.
|
||||||
|
if string.find(line, "</ATCWaypoint>") then
|
||||||
|
-- This is the end of the waypoint.
|
||||||
|
|
||||||
|
-- Add info to waypoints table.
|
||||||
|
table.insert(waypoints, wp)
|
||||||
|
|
||||||
|
-- Set waypoint to nil. We create an empty table if the next wp starts.
|
||||||
|
wp=nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Waypoint type (Airport, Intersection, NDB, VORTAC)
|
||||||
|
if string.find(line, "<ATCWaypointType>") then
|
||||||
|
local wptype=getXMLelement(line)
|
||||||
|
wp.type=wptype
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Waypoint position.
|
||||||
|
if string.find(line, "<WorldPosition>") then
|
||||||
|
wp.lat, wp.long=getLatLong(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Runway should exist for initial and final WP if it is an airport.
|
||||||
|
if string.find(line, "RunwayNumberFP") then
|
||||||
|
wp.runway=getXMLelement(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Runway designator: LEFT, RIGHT, CENTER
|
||||||
|
if string.find(line, "RunwayDesignatorFP") then
|
||||||
|
wp.runwayDesignator=getXMLelement(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Segment is Departure
|
||||||
|
if string.find(line, "<DepartureFP>") then
|
||||||
|
wp.segment="Departure"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Segment is Arrival
|
||||||
|
if string.find(line, "<ArrivalFP>") then
|
||||||
|
wp.segment="Arrival"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Segment is Enroute
|
||||||
|
if string.find(line, "<ATCAirway>") then
|
||||||
|
wp.segment="Enroute"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Approach type: VORDME, LOCALIZER
|
||||||
|
if string.find(line, "ApproachTypeFP") then
|
||||||
|
flightplan.approachtype=getXMLelement(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Approach type suffic: Z
|
||||||
|
if string.find(line, "SuffixFP") then
|
||||||
|
local SuffixFP=getXMLelement(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
for key, value in pairs(flightplan) do
|
||||||
|
env.info(string.format("Flightplan %s=%s", key, tostring(value)))
|
||||||
|
end
|
||||||
|
|
||||||
|
env.info(string.format("Number of waypoints=%d", #waypoints))
|
||||||
|
for i,wp in pairs(waypoints) do
|
||||||
|
env.info(string.format("Waypoint name=%s type=%s segment=%s runway=%s lat=%s long=%s", wp.name, wp.type, tostring(wp.segment), tostring(wp.runway)..tostring(wp.runwayDesignator or ""), wp.lat, wp.long))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create a new flightplan.
|
||||||
|
local fp=FLIGHTPLAN:New(flightplan.title)
|
||||||
|
|
||||||
|
-- Set cruise altitude.
|
||||||
|
fp:SetCruiseAltitude(flightplan.altCruise)
|
||||||
|
|
||||||
|
-- Set departure and destination airports.
|
||||||
|
fp:SetDepartureAirbase(flightplan.departureICAO)
|
||||||
|
fp:SetDestinationAirbase(flightplan.destinationICAO)
|
||||||
|
|
||||||
|
--TODO: Remove first and last waypoint if they are identical to the departure/destination airport!
|
||||||
|
|
||||||
|
for i,wp in pairs(waypoints) do
|
||||||
|
|
||||||
|
-- Create a navpoint.
|
||||||
|
local navpoint=NAVPOINT:NewFromLLDMS(wp.name, wp.type, wp.lat, wp.long)
|
||||||
|
|
||||||
|
navpoint:SetAltMin(flightplan.altCruise)
|
||||||
|
|
||||||
|
-- Add point to flightplan.
|
||||||
|
-- TODO: section departure, enroute, arrival.
|
||||||
|
fp:AddNavFix(navpoint)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return fp
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
587
Moose Development/Moose/Navigation/Point.lua
Normal file
587
Moose Development/Moose/Navigation/Point.lua
Normal file
@@ -0,0 +1,587 @@
|
|||||||
|
--- **NAVIGATION** - Navigation Airspace Points, Fixes and Aids.
|
||||||
|
--
|
||||||
|
-- **Main Features:**
|
||||||
|
--
|
||||||
|
-- * Stuff
|
||||||
|
-- * More Stuff
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ## Example Missions:
|
||||||
|
--
|
||||||
|
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Navigation%20-%20NavFix).
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **funkyfranky**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
-- @module Navigation.Point
|
||||||
|
-- @image NAVIGATION_Point.png
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- NAVFIX class.
|
||||||
|
-- @type NAVFIX
|
||||||
|
--
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field #number verbose Verbosity of output.
|
||||||
|
-- @field #string name Name of the point.
|
||||||
|
-- @field #string typePoint Type of the point, *e.g. "Intersection", "VOR", "Airport".
|
||||||
|
-- @field Core.Vector#VECTOR vector Position vector of the fix.
|
||||||
|
-- @field Wrapper.Marker#MARKER marker Marker on F10 map.
|
||||||
|
-- @field #number altMin Minimum altitude in meters.
|
||||||
|
-- @field #number altMax Maximum altitude in meters.
|
||||||
|
-- @field #number speedMin Minimum speed in knots.
|
||||||
|
-- @field #number speedMax Maximum speed in knots.
|
||||||
|
--
|
||||||
|
-- @field #boolean isCompulsory Is this a compulsory fix.
|
||||||
|
-- @field #boolean isFlyover Is this a flyover fix (`true`) or turning point otherwise.
|
||||||
|
-- @field #boolean isFAF Is this a final approach fix.
|
||||||
|
-- @field #boolean isIAF Is this an initial approach fix.
|
||||||
|
-- @field #boolean isIF Is this an initial fix.
|
||||||
|
-- @field #boolean isMAF Is this an initial fix.
|
||||||
|
--
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
--- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- # The NAVFIX Concept
|
||||||
|
--
|
||||||
|
-- The NAVFIX class has a great concept!
|
||||||
|
--
|
||||||
|
-- A NAVFIX describes a geo position and can, *e.g.*, be part of a FLIGHTPLAN. It has a unique name and is of a certain type, *e.g.* "Intersection", "VOR", "Airbase" etc.
|
||||||
|
-- It can also have further properties as min/max altitudes and speeds that aircraft need to obey when they pass the point.
|
||||||
|
--
|
||||||
|
-- # Basic Setup
|
||||||
|
--
|
||||||
|
-- A new `NAVFIX` object can be created with the @{#NAVFIX.New}() function.
|
||||||
|
--
|
||||||
|
-- myNavPoint=NAVFIX:New()
|
||||||
|
-- myTemplate:SetXYZ(X, Y, Z)
|
||||||
|
--
|
||||||
|
-- This is how it works.
|
||||||
|
--
|
||||||
|
-- @field #NAVFIX
|
||||||
|
NAVFIX = {
|
||||||
|
ClassName = "NAVFIX",
|
||||||
|
verbose = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Type of point.
|
||||||
|
-- @type NAVFIX.Type
|
||||||
|
-- @field #string POINT Waypoint.
|
||||||
|
-- @field #string INTERSECTION Intersection of airway.
|
||||||
|
-- @field #string AIRPORT Airport.
|
||||||
|
-- @field #string VOR Very High Frequency Omnidirectional Range Station.
|
||||||
|
-- @field #string DME Distance Measuring Equipment.
|
||||||
|
-- @field #string NDB Non-Directional Beacon.
|
||||||
|
-- @field #string VORDME Combined VHF omnidirectional range (VOR) with a distance-measuring equipment (DME).
|
||||||
|
-- @field #string LOC Localizer.
|
||||||
|
-- @field #string ILS Instrument Landing System.
|
||||||
|
-- @field #string TACAN TACtical Air Navigation System (TACAN).
|
||||||
|
NAVFIX.Type={
|
||||||
|
POINT="Point",
|
||||||
|
INTERSECTION="Intersection",
|
||||||
|
AIRPORT="Airport",
|
||||||
|
NDB="NDB",
|
||||||
|
VOR="VOR",
|
||||||
|
DME="DME",
|
||||||
|
VORDME="VOR/DME",
|
||||||
|
LOC="Localizer",
|
||||||
|
ILS="ILS",
|
||||||
|
TACAN="TACAN"
|
||||||
|
}
|
||||||
|
|
||||||
|
--- NAVFIX class version.
|
||||||
|
-- @field #string version
|
||||||
|
NAVFIX.version="0.0.1"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- ToDo list
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- TODO: A lot...
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Constructor(s)
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Create a new NAVFIX class instance from a given VECTOR.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #string Name Name/ident of the point. Should be unique!
|
||||||
|
-- @param #string Type Type of the point. Default `NAVFIX.Type.POINT`.
|
||||||
|
-- @param Core.Vector#VECTOR Vector Position vector of the navpoint.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:NewFromVector(Name, Type, Vector)
|
||||||
|
|
||||||
|
-- Inherit everything from BASE class.
|
||||||
|
self=BASE:Inherit(self, BASE:New()) -- #NAVFIX
|
||||||
|
|
||||||
|
-- Vector of point.
|
||||||
|
self.vector=Vector
|
||||||
|
|
||||||
|
-- Name of point.
|
||||||
|
self.name=Name
|
||||||
|
|
||||||
|
-- Type of the point.
|
||||||
|
self.typePoint=Type or NAVFIX.Type.POINT
|
||||||
|
|
||||||
|
local coord=COORDINATE:NewFromVec3(self.vector)
|
||||||
|
|
||||||
|
-- Marker on F10.
|
||||||
|
self.marker=MARKER:New(coord, self:_GetMarkerText())
|
||||||
|
|
||||||
|
-- Log ID string.
|
||||||
|
self.lid=string.format("NAVFIX %s [%s] | ", tostring(self.name), tostring(self.typePoint))
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:I(self.lid..string.format("Created NAVFIX"))
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Create a new NAVFIX class instance from a given COORDINATE.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #string Name Name of the fix. Should be unique!
|
||||||
|
-- @param #string Type Type of the point. Default `NAVFIX.Type.POINT`.
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate Coordinate of the point.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:NewFromCoordinate(Name, Type, Coordinate)
|
||||||
|
|
||||||
|
-- Create a VECTOR from the coordinate.
|
||||||
|
local Vector=VECTOR:NewFromVec(Coordinate)
|
||||||
|
|
||||||
|
-- Create NAVFIX.
|
||||||
|
self=NAVFIX:NewFromVector(Name, Type, Vector)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Create a new NAVFIX instance from given latitude and longitude in degrees, minutes and seconds (DMS).
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #string Name Name of the fix. Should be unique!
|
||||||
|
-- @param #string Type Type of the point. Default `NAVFIX.Type.POINT`.
|
||||||
|
-- @param #string Latitude Latitude in DMS as string.
|
||||||
|
-- @param #string Longitude Longitude in DMS as string.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:NewFromLLDMS(Name, Type, Latitude, Longitude)
|
||||||
|
|
||||||
|
-- Create a VECTOR from the coordinate.
|
||||||
|
local Vector=VECTOR:NewFromLLDMS(Latitude, Longitude)
|
||||||
|
|
||||||
|
-- Create NAVFIX.
|
||||||
|
self=NAVFIX:NewFromVector(Name, Type, Vector)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a new NAVFIX instance from given latitude and longitude in decimal degrees (DD).
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #string Name Name of the fix. Should be unique!
|
||||||
|
-- @param #string Type Type of the point. Default `NAVFIX.Type.POINT`.
|
||||||
|
-- @param #number Latitude Latitude in DD.
|
||||||
|
-- @param #number Longitude Longitude in DD.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:NewFromLLDD(Name, Type, Latitude, Longitude)
|
||||||
|
|
||||||
|
-- Create a VECTOR from the coordinate.
|
||||||
|
local Vector=VECTOR:NewFromLLDD(Latitude, Longitude)
|
||||||
|
|
||||||
|
-- Create NAVFIX.
|
||||||
|
self=NAVFIX:NewFromVector(Name, Type, Vector)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Create a new NAVFIX class instance relative to a given other NAVFIX.
|
||||||
|
-- You have to specify the distance and bearing from the new point to the given point. *E.g.*, for a distance of 5 NM and a bearing of 090° (West), the
|
||||||
|
-- new nav point is created 5 NM East of the given nav point. The reason is that this corresponts to convention used in most maps.
|
||||||
|
-- You can, however, use the `Reciprocal` switch to create the new point in the direction you specify.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #string Name Name of the fix. Should be unique!
|
||||||
|
-- @param #string Type Type of navfix.
|
||||||
|
-- @param #NAVFIX NavFix The given/existing navigation fix relative to which the new fix is created.
|
||||||
|
-- @param #number Distance Distance from the given to the new point in nautical miles.
|
||||||
|
-- @param #number Bearing Bearing [Deg] from the new point to the given one.
|
||||||
|
-- @param #boolean Reciprocal If `true` the reciprocal `Bearing` is taken so it specifies the direction from the given point to the new one.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:NewFromNavFix(Name, Type, NavFix, Distance, Bearing, Reciprocal)
|
||||||
|
|
||||||
|
-- Convert magnetic to true bearing by adding magnetic declination, e.g. mag. bearing 10°M ==> true bearing 16°M (for 6° variation on Caucasus map)
|
||||||
|
Bearing=Bearing+UTILS.GetMagneticDeclination()
|
||||||
|
|
||||||
|
if Reciprocal then
|
||||||
|
Bearing=Bearing-180
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Translate.
|
||||||
|
local Vector=NavFix.vector:Translate(UTILS.NMToMeters(Distance), Bearing, true)
|
||||||
|
|
||||||
|
self=NAVFIX:NewFromVector(Name, Type, Vector)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- User Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Set whether this is the intermediate fix (IF).
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:SetIntermediateFix(IntermediateFix)
|
||||||
|
self.isIF=IntermediateFix
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set whether this is an initial approach fix (IAF).
|
||||||
|
-- The IAF is the point where the initial approach segment of an instrument approach begins.
|
||||||
|
-- It is usually a designated intersection, VHF omidirectional range (VOR) non-directional beacon (NDB)
|
||||||
|
-- or distance measuring equipment (DME) fix.
|
||||||
|
-- The IAF may be collocated with the intermediate fix (IF) of the instrument apprach an in such case they designate the
|
||||||
|
-- beginning of the intermediate segment of the approach. When the IAF and the IF are combined, there is no inital approach segment.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #boolean IntermediateFix If `true`, this is an intermediate fix.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:SetInitialApproachFix(IntermediateFix)
|
||||||
|
self.isIAF=IntermediateFix
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set whether this is the final approach fix (FAF).
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #boolean FinalApproachFix If `true`, this is a final approach fix.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:SetFinalApproachFix(FinalApproachFix)
|
||||||
|
self.isFAF=FinalApproachFix
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set whether this is the final approach fix (FAF).
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #boolean FinalApproachFix If `true`, this is a final approach fix.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:SetMissedApproachFix(MissedApproachFix)
|
||||||
|
self.isMAF=MissedApproachFix
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set minimum altitude.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #number Altitude Min altitude in feet.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:SetAltMin(Altitude)
|
||||||
|
|
||||||
|
self.altMin=Altitude
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set maximum altitude.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #number Altitude Max altitude in feet.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:SetAltMax(Altitude)
|
||||||
|
|
||||||
|
self.altMax=Altitude
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set mandatory altitude (min alt = max alt).
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #number Altitude Altitude in feet.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:SetAltMandatory(Altitude)
|
||||||
|
|
||||||
|
self.altMin=Altitude
|
||||||
|
self.altMax=Altitude
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set minimum allowed speed at this fix.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #number Speed Min speed in knots.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:SetSpeedMin(Speed)
|
||||||
|
|
||||||
|
self.speedMin=Speed
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set maximum allowed speed at this fix.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #number Speed Max speed in knots.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:SetSpeedMax(Speed)
|
||||||
|
|
||||||
|
self.speedMax=Speed
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set mandatory speed (min speed = max speed) at this fix.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #number Speed Mandatory speed in knots.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:SetSpeedMandatory(Speed)
|
||||||
|
|
||||||
|
self.speedMin=Speed
|
||||||
|
self.speedMax=Speed
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set whether this fix is compulsory.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #boolean Compulsory If `true`, this is a compusory fix. If `false` or nil, it is non-compulsory.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:SetCompulsory(Compulsory)
|
||||||
|
self.isCompulsory=Compulsory
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set whether this is a fly-over fix fix.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @param #boolean FlyOver If `true`, this is a fly over fix. If `false` or nil, it is not.
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:SetFlyOver(FlyOver)
|
||||||
|
self.isFlyover=FlyOver
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the altitude in feet MSL. If min and max altitudes are set, it will return a random altitude between min and max.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @return #number Altitude in feet MSL. Can be `nil`, if neither min nor max altitudes have beeen set.
|
||||||
|
function NAVFIX:GetAltitude()
|
||||||
|
|
||||||
|
local alt=nil
|
||||||
|
if self.altMin and self.altMax and self.altMin~=self.altMax then
|
||||||
|
alt=math.random(self.altMin, self.altMax)
|
||||||
|
elseif self.altMin then
|
||||||
|
alt=self.altMin
|
||||||
|
elseif self.altMax then
|
||||||
|
alt=self.altMax
|
||||||
|
end
|
||||||
|
|
||||||
|
return alt
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the speed. If min and max speeds are set, it will return a random speed between min and max.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @return #number Speed in knots. Can be `nil`, if neither min nor max speeds have beeen set.
|
||||||
|
function NAVFIX:GetSpeed()
|
||||||
|
|
||||||
|
local speed=nil
|
||||||
|
if self.speedMin and self.speedMax and self.speedMin~=self.speedMax then
|
||||||
|
speed=math.random(self.speedMin, self.speedMax)
|
||||||
|
elseif self.speedMin then
|
||||||
|
speed=self.speedMin
|
||||||
|
elseif self.speedMax then
|
||||||
|
speed=self.speedMax
|
||||||
|
end
|
||||||
|
|
||||||
|
return speed
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Add marker the NAVFIX on the F10 map.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:MarkerShow()
|
||||||
|
|
||||||
|
self.marker:ToAll()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove marker of the NAVFIX from the F10 map.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @return #NAVFIX self
|
||||||
|
function NAVFIX:MarkerRemove()
|
||||||
|
|
||||||
|
self.marker:Remove()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Private Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Get text displayed in the F10 marker.
|
||||||
|
-- @param #NAVFIX self
|
||||||
|
-- @return #string Marker text.
|
||||||
|
function NAVFIX:_GetMarkerText()
|
||||||
|
|
||||||
|
local altmin=self.altMin and tostring(self.altMin) or ""
|
||||||
|
local altmax=self.altMax and tostring(self.altMax) or ""
|
||||||
|
local speedmin=self.speedMin and tostring(self.speedMin) or ""
|
||||||
|
local speedmax=self.speedMax and tostring(self.speedMax) or ""
|
||||||
|
|
||||||
|
|
||||||
|
local text=string.format("NAVFIX %s", self.name)
|
||||||
|
if self.isIAF then
|
||||||
|
text=text..string.format(" (IAF)")
|
||||||
|
end
|
||||||
|
if self.isIF then
|
||||||
|
text=text..string.format(" (IF)")
|
||||||
|
end
|
||||||
|
text=text..string.format("\nAltitude [ft]: %s - %s", altmin, altmax)
|
||||||
|
text=text..string.format("\nSpeed [knots]: %s - %s", speedmin, speedmax)
|
||||||
|
text=text..string.format("\nCompulsory: %s", tostring(self.isCompulsory))
|
||||||
|
text=text..string.format("\nFly Over: %s", tostring(self.isFlyover))
|
||||||
|
|
||||||
|
return text
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- NAVAID class.
|
||||||
|
-- @type NAVAID
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field #number verbose Verbosity of output.
|
||||||
|
-- @extends Navigation.Point#NAVFIX
|
||||||
|
|
||||||
|
--- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- # The NAVAID Concept
|
||||||
|
--
|
||||||
|
-- A NAVAID consists of one or multiple FLOTILLAs. These flotillas "live" in a WAREHOUSE that has a phyiscal struction (STATIC or UNIT) and can be captured or destroyed.
|
||||||
|
--
|
||||||
|
-- # Basic Setup
|
||||||
|
--
|
||||||
|
-- A new `NAVAID` object can be created with the @{#NAVAID.New}(`WarehouseName`, `FleetName`) function, where `WarehouseName` is the name of the static or unit object hosting the fleet
|
||||||
|
-- and `FleetName` is the name you want to give the fleet. This must be *unique*!
|
||||||
|
--
|
||||||
|
-- myFleet=NAVAID:New("myWarehouseName", "1st Fleet")
|
||||||
|
-- myFleet:SetPortZone(ZonePort1stFleet)
|
||||||
|
-- myFleet:Start()
|
||||||
|
--
|
||||||
|
-- A fleet needs a *port zone*, which is set via the @{#NAVAID.SetPortZone}(`PortZone`) function. This is the zone where the naval assets are spawned and return to.
|
||||||
|
--
|
||||||
|
-- Finally, the fleet needs to be started using the @{#NAVAID.Start}() function. If the fleet is not started, it will not process any requests.
|
||||||
|
--
|
||||||
|
-- @field #NAVAID
|
||||||
|
NAVAID = {
|
||||||
|
ClassName = "NAVAID",
|
||||||
|
verbose = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- NAVAID class version.
|
||||||
|
-- @field #string version
|
||||||
|
NAVAID.version="0.0.1"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- ToDo list
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- TODO: Add frequencies. Which unit MHz, kHz, Hz?
|
||||||
|
-- TODO: Add radial function
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Constructor
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Create a new NAVAID class instance.
|
||||||
|
-- @param #NAVAID self
|
||||||
|
-- @param #string Name Name/ident of this navaid.
|
||||||
|
-- @param #string Type Type of the point. Default `NAVFIX.Type.POINT`.
|
||||||
|
-- @param #string ZoneName Name of the zone to scan the scenery.
|
||||||
|
-- @param #string SceneryName Name of the scenery object.
|
||||||
|
-- @return #NAVAID self
|
||||||
|
function NAVAID:NewFromScenery(Name, Type, ZoneName, SceneryName)
|
||||||
|
|
||||||
|
-- Get the zone.
|
||||||
|
local zone=ZONE:FindByName(ZoneName)
|
||||||
|
|
||||||
|
-- Get coordinate.
|
||||||
|
local Coordinate=zone:GetCoordinate()
|
||||||
|
|
||||||
|
-- Inherit everything from NAVFIX class.
|
||||||
|
self=BASE:Inherit(self, NAVFIX:NewFromCoordinate(Name, Type, Coordinate)) -- #NAVAID
|
||||||
|
|
||||||
|
-- Set zone.
|
||||||
|
self.zone=ZONE:FindByName(ZoneName)
|
||||||
|
|
||||||
|
-- Try to get the scenery object. Note not all can be found unfortunately.
|
||||||
|
if SceneryName then
|
||||||
|
self.scenery=SCENERY:FindByNameInZone(SceneryName, ZoneName)
|
||||||
|
if not self.scenery then
|
||||||
|
self:E(string.format("ERROR: Could not find scenery object %s in zone %s", SceneryName, ZoneName))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Alias.
|
||||||
|
self.alias=string.format("%s %s %s", tostring(ZoneName), tostring(SceneryName), tostring(Type))
|
||||||
|
|
||||||
|
-- Set some string id for output to DCS.log file.
|
||||||
|
self.lid=string.format("NAVAID %s | ", self.alias)
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:I(self.lid..string.format("Created NAVAID!"))
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- User Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Set frequency the beacon transmits on.
|
||||||
|
-- @param #NAVAID self
|
||||||
|
-- @param #number Frequency Frequency in Hz.
|
||||||
|
-- @return #NAVAID self
|
||||||
|
function NAVAID:SetFrequency(Frequency)
|
||||||
|
|
||||||
|
self.frequency=Frequency
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set channel of, *e.g.*, TACAN beacons.
|
||||||
|
-- @param #NAVAID self
|
||||||
|
-- @param #number Channel The channel.
|
||||||
|
-- @param #string Band The band either `"X"` (default) or `"Y"`.
|
||||||
|
-- @return #NAVAID self
|
||||||
|
function NAVAID:SetChannel(Channel, Band)
|
||||||
|
|
||||||
|
self.channel=Channel
|
||||||
|
self.band=Band or "X"
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Private Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- Add private CLASS functions here.
|
||||||
|
-- No private NAVAID functions yet.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
333
Moose Development/Moose/Navigation/Procedure.lua
Normal file
333
Moose Development/Moose/Navigation/Procedure.lua
Normal file
@@ -0,0 +1,333 @@
|
|||||||
|
--- **NAVIGATION** - Prodedures for Departure (*e.g.* SID), Enroute, Arrival (*e.g.* STAR) and Approach.
|
||||||
|
--
|
||||||
|
-- **Main Features:**
|
||||||
|
--
|
||||||
|
-- * Stuff
|
||||||
|
-- * More Stuff
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ## Example Missions:
|
||||||
|
--
|
||||||
|
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Navigation%20-%20Template).
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **funkyfranky**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
-- @module Navigation.Procedure
|
||||||
|
-- @image NAVIGATION_Procedure.png
|
||||||
|
|
||||||
|
|
||||||
|
--- APPROACH class.
|
||||||
|
-- @type APPROACH
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field #number verbose Verbosity of output.
|
||||||
|
-- @field #string apptype Approach type (ILS, VOR, LOC).
|
||||||
|
-- @field Wrapper.Airbase#AIRBASE airbase Airbase of this approach.
|
||||||
|
-- @field Wrapper.Airbase#AIRBASE.Runway runway Runway of this approach.
|
||||||
|
-- @field Navigation.Point#NAVAID navaid Primary navigation aid.
|
||||||
|
-- @field #number wpcounter Running number counting the waypoints to generate its UID.
|
||||||
|
-- @list <#APPROACH.Waypoint> path Path of approach consisting of waypoints.
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
--- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- # The APPROACH Concept
|
||||||
|
--
|
||||||
|
-- A typical approach has (up to) four segments. It starts with the initial approach segment, followed by the intermediate approach segment, followed
|
||||||
|
-- by the final approach segment. In case something goes wrong during the final approach, the missed approach segment kicks in.
|
||||||
|
--
|
||||||
|
-- The initial approach segment starts at the initial approach fix (IAF). The segment can contain multiple other fixes, that need to be passed.
|
||||||
|
-- Note, that an approach procedure can have more than one intitial approach segment and IAF.
|
||||||
|
--
|
||||||
|
-- The intermediate approach segment starts at the intermediate fix (IF). The intermediate approach segment blends the initial approach segment into the final approach segment.
|
||||||
|
-- It is the segment in which aircraft configuration, speed, and positioning adjustments are made for entry into the final approach segment.
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- https://en.wikipedia.org/wiki/Visual_approach
|
||||||
|
-- https://en.wikipedia.org/wiki/Instrument_approach
|
||||||
|
--
|
||||||
|
-- # Basic Setup
|
||||||
|
--
|
||||||
|
-- A new `APPROACH` object can be created with the @{#APPROACH.New}() function.
|
||||||
|
--
|
||||||
|
-- myTemplate=APPROACH:New()
|
||||||
|
-- myTemplate:SetXYZ(X, Y, Z)
|
||||||
|
--
|
||||||
|
-- This is how it works.
|
||||||
|
--
|
||||||
|
-- @field #APPROACH
|
||||||
|
APPROACH = {
|
||||||
|
ClassName = "APPROACH",
|
||||||
|
verbose = 0,
|
||||||
|
wpcounter = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Type of approach.
|
||||||
|
-- @type APPROACH.Type
|
||||||
|
-- @field #string VFR Visual Flight Rules.
|
||||||
|
-- @field #string VOR VOR
|
||||||
|
-- @field #string NDB NDB
|
||||||
|
APPROACH.Type={
|
||||||
|
VFR="VFR",
|
||||||
|
VOR="VOR",
|
||||||
|
ILS="ILS",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--- Setments of approach.
|
||||||
|
-- @type APPROACH.Segment
|
||||||
|
-- @field #string INITIAL Initial approach segment.
|
||||||
|
-- @field #string INTERMEDIATE Intermediate approach segment.
|
||||||
|
-- @field #string FINAL Final approach segment.
|
||||||
|
-- @field #string MISSED Missed approach segment.
|
||||||
|
APPROACH.Segment={
|
||||||
|
INITIAL="Initial",
|
||||||
|
INTERMEDIATE="Intermediate",
|
||||||
|
FINAL="Final",
|
||||||
|
MISSED="Missed",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Waypoint of the approach.
|
||||||
|
-- @type APPROACH.Waypoint
|
||||||
|
-- @field #number uid Unique ID of the point.
|
||||||
|
-- @field #string segment The segment this point belongs to.
|
||||||
|
-- @field Navigation.Point#NAVFIX navfix The navigation fix that determines the coordinates of this point.
|
||||||
|
|
||||||
|
--- APPROACH class version.
|
||||||
|
-- @field #string version
|
||||||
|
APPROACH.version="0.0.1"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- ToDo list
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- TODO: A lot...
|
||||||
|
-- Initial approach segment --> Intermediate approach segment: starts at IF --> Final approach segment
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Constructor
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Create a new APPROACH class instance.
|
||||||
|
-- @param #APPROACH self
|
||||||
|
-- @param #string Type Type of approach (ILS, VOR, LOC).
|
||||||
|
-- @param Wrapper.Airbase#AIRBASE Airbase The airbase or name of the airbase.
|
||||||
|
-- @param Wrapper.Airbase#AIRBASE.Runway Runway The runway or name of the runway.
|
||||||
|
-- @return #APPROACH self
|
||||||
|
function APPROACH:New(Type, Airbase, Runway)
|
||||||
|
|
||||||
|
-- Inherit everything from BASE class.
|
||||||
|
self=BASE:Inherit(self, BASE:New()) -- #APPROACH
|
||||||
|
|
||||||
|
-- Set approach type.
|
||||||
|
-- TODO: Check if this is a valid/known approach type.
|
||||||
|
self.apptype=Type
|
||||||
|
|
||||||
|
if type(Airbase)=="string" then
|
||||||
|
self.airbase=AIRBASE:FindByName(Airbase)
|
||||||
|
else
|
||||||
|
self.airbase=Airbase
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(Runway)=="string" then
|
||||||
|
self.runway=self.airbase:GetRunwayByName(Runway)
|
||||||
|
else
|
||||||
|
self.runway=Runway
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:I("Created new approach for airbase %s: type=%s, runway=%s", self.airbase:GetName(), self.apptype, self.runway.name)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- User Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Set the primary navigation aid used in the approach.
|
||||||
|
-- @param #APPROACH self
|
||||||
|
-- @param Navigation.Point#NAVAID NavAid The NAVAID.
|
||||||
|
-- @return #APPROACH self
|
||||||
|
function APPROACH:SetNavAid(NavAid)
|
||||||
|
|
||||||
|
self.navaid=NavAid
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add a waypoint to the path of the approach.
|
||||||
|
-- @param #APPROACH self
|
||||||
|
-- @param Navigation.Point#NAVFIX NavFix The navigation fix.
|
||||||
|
-- @param #string Segment The approach segment this fix belongs to.
|
||||||
|
-- @return #APPROACH.Waypoint The waypoint data table.
|
||||||
|
function APPROACH:AddNavFix(NavFix, Segment)
|
||||||
|
|
||||||
|
self.wpcounter=self.wpcounter+1
|
||||||
|
|
||||||
|
local point={} --#APPROACH.Waypoint
|
||||||
|
point.uid=self.wpcounter
|
||||||
|
point.segment=Segment
|
||||||
|
point.navfix=NavFix
|
||||||
|
|
||||||
|
table.insert(self.path, point)
|
||||||
|
|
||||||
|
return point
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Private Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- Add private functions here.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- DEPARTURE class.
|
||||||
|
-- @type DEPARTURE
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field #number verbose Verbosity of output.
|
||||||
|
-- @field #string apptype DEPARTURE type (ILS, VOR, LOC).
|
||||||
|
-- @field Wrapper.Airbase#AIRBASE airbase Airbase of this DEPARTURE.
|
||||||
|
-- @field Wrapper.Airbase#AIRBASE.Runway runway Runway of this DEPARTURE.
|
||||||
|
-- @field Navigation.Point#NAVAID navaid Primary navigation aid.
|
||||||
|
-- @field #number wpcounter Running number counting the waypoints to generate its UID.
|
||||||
|
-- @list <#DEPARTURE.Waypoint> path Path of DEPARTURE consisting of waypoints.
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
--- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- # The DEPARTURE Concept
|
||||||
|
--
|
||||||
|
-- Bla.
|
||||||
|
--
|
||||||
|
-- @field #DEPARTURE
|
||||||
|
DEPARTURE = {
|
||||||
|
ClassName = "DEPARTURE",
|
||||||
|
verbose = 0,
|
||||||
|
wpcounter = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Type of DEPARTURE.
|
||||||
|
-- @type DEPARTURE.Type
|
||||||
|
-- @field #string VOR VOR
|
||||||
|
-- @field #string NDB NDB
|
||||||
|
DEPARTURE.Type={
|
||||||
|
VOR="VOR",
|
||||||
|
ILS="ILS",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--- Setments of DEPARTURE.
|
||||||
|
-- @type DEPARTURE.Segment
|
||||||
|
-- @field #string INITIAL Initial DEPARTURE segment.
|
||||||
|
-- @field #string INTERMEDIATE Intermediate DEPARTURE segment.
|
||||||
|
-- @field #string FINAL Final DEPARTURE segment.
|
||||||
|
-- @field #string MISSED Missed DEPARTURE segment.
|
||||||
|
DEPARTURE.Segment={
|
||||||
|
INITIAL="Initial",
|
||||||
|
INTERMEDIATE="Intermediate",
|
||||||
|
FINAL="Final",
|
||||||
|
MISSED="Missed",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Waypoint of the DEPARTURE.
|
||||||
|
-- @type DEPARTURE.Waypoint
|
||||||
|
-- @field #number uid Unique ID of the point.
|
||||||
|
-- @field #string segment The segment this point belongs to.
|
||||||
|
-- @field Navigation.Point#NAVFIX navfix The navigation fix that determines the coordinates of this point.
|
||||||
|
|
||||||
|
--- DEPARTURE class version.
|
||||||
|
-- @field #string version
|
||||||
|
DEPARTURE.version="0.0.1"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- ToDo list
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- TODO: A lot...
|
||||||
|
-- Initial DEPARTURE segment --> Intermediate DEPARTURE segment: starts at IF --> Final DEPARTURE segment
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Constructor
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Create a new DEPARTURE class instance.
|
||||||
|
-- @param #DEPARTURE self
|
||||||
|
-- @param Wrapper.Airbase#AIRBASE Airbase The airbase or name of the airbase.
|
||||||
|
-- @param Wrapper.Airbase#AIRBASE.Runway Runway The runway or name of the runway.
|
||||||
|
-- @param #string Type Type of DEPARTURE (ILS, VOR, LOC).
|
||||||
|
-- @return #DEPARTURE self
|
||||||
|
function DEPARTURE:New(Airbase, Runway)
|
||||||
|
|
||||||
|
-- Inherit everything from BASE class.
|
||||||
|
self=BASE:Inherit(self, BASE:New()) -- #DEPARTURE
|
||||||
|
|
||||||
|
if type(Airbase)=="string" then
|
||||||
|
self.airbase=AIRBASE:FindByName(Airbase)
|
||||||
|
else
|
||||||
|
self.airbase=Airbase
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(Runway)=="string" then
|
||||||
|
self.runway=self.airbase:GetRunwayByName(Runway)
|
||||||
|
else
|
||||||
|
self.runway=Runway
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- User Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Set the primary navigation aid used in the DEPARTURE.
|
||||||
|
-- @param #DEPARTURE self
|
||||||
|
-- @param Navigation.Point#NAVAID NavAid The NAVAID.
|
||||||
|
-- @return #DEPARTURE self
|
||||||
|
function DEPARTURE:SetNavAid(NavAid)
|
||||||
|
|
||||||
|
self.navaid=NavAid
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add a waypoint to the path of the DEPARTURE.
|
||||||
|
-- @param #DEPARTURE self
|
||||||
|
-- @param Navigation.Point#NAVFIX NavFix The navigation fix.
|
||||||
|
-- @param #string Segment The DEPARTURE segment this fix belongs to.
|
||||||
|
-- @return #DEPARTURE.Waypoint The waypoint data.
|
||||||
|
function DEPARTURE:AddWaypoint(NavFix, Segment)
|
||||||
|
|
||||||
|
self.wpcounter=self.wpcounter+1
|
||||||
|
|
||||||
|
local point={} --#DEPARTURE.Waypoint
|
||||||
|
point.uid=self.wpcounter
|
||||||
|
point.segment=Segment
|
||||||
|
point.navfix=NavFix
|
||||||
|
|
||||||
|
table.insert(self.path, point)
|
||||||
|
|
||||||
|
return point
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Private Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- Add DEPARTURE private functions here.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
108
Moose Development/Moose/Navigation/Template.lua
Normal file
108
Moose Development/Moose/Navigation/Template.lua
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
--- **NAVIGATION** - Template.
|
||||||
|
--
|
||||||
|
-- **Main Features:**
|
||||||
|
--
|
||||||
|
-- * Stuff
|
||||||
|
-- * More Stuff
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ## Example Missions:
|
||||||
|
--
|
||||||
|
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Navigation%20-%20Template).
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **funkyfranky**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
-- @module Navigation.Template
|
||||||
|
-- @image NAVIGATION_Template.png
|
||||||
|
|
||||||
|
|
||||||
|
--- TEMPLATE class.
|
||||||
|
-- @type TEMPLATE
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field #number verbose Verbosity of output.
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
--- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- # The TEMPLATE Concept
|
||||||
|
--
|
||||||
|
-- The TEMPLATE class has a great concept!
|
||||||
|
--
|
||||||
|
-- # Basic Setup
|
||||||
|
--
|
||||||
|
-- A new `TEMPLATE` object can be created with the @{#TEMPLATE.New}() function.
|
||||||
|
--
|
||||||
|
-- myTemplate=TEMPLATE:New()
|
||||||
|
-- myTemplate:SetXYZ(X, Y, Z)
|
||||||
|
--
|
||||||
|
-- This is how it works.
|
||||||
|
--
|
||||||
|
-- @field #TEMPLATE
|
||||||
|
TEMPLATE = {
|
||||||
|
ClassName = "TEMPLATE",
|
||||||
|
verbose = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Type of navaid
|
||||||
|
-- @type TEMPLATE.Type
|
||||||
|
-- @field #string VOR VOR
|
||||||
|
-- @field #string NDB NDB
|
||||||
|
TEMPLATE.TYPE={
|
||||||
|
VOR="VOR",
|
||||||
|
NDB="NDB",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- TEMPLATE class version.
|
||||||
|
-- @field #string version
|
||||||
|
TEMPLATE.version="0.0.1"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- ToDo list
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- TODO: A lot...
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Constructor
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Create a new TEMPLATE class instance.
|
||||||
|
-- @param #TEMPLATE self
|
||||||
|
-- @return #TEMPLATE self
|
||||||
|
function TEMPLATE:New()
|
||||||
|
|
||||||
|
-- Inherit everything from SCENERY class.
|
||||||
|
self=BASE:Inherit(self, BASE:New()) -- #TEMPLATE
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- User Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Set frequency.
|
||||||
|
-- @param #TEMPLATE self
|
||||||
|
-- @param #number Frequency Frequency in Hz.
|
||||||
|
-- @return #TEMPLATE self
|
||||||
|
function TEMPLATE:SetFrequency(Frequency)
|
||||||
|
|
||||||
|
self.frequency=Frequency
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Private Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -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.
|
||||||
|
|||||||
@@ -599,7 +599,80 @@ function BRIGADE:onafterStatus(From, Event, To)
|
|||||||
text=text..string.format("\n* %s: spawned=%s", asset.spawngroupname, tostring(asset.spawned))
|
text=text..string.format("\n* %s: spawned=%s", asset.spawngroupname, tostring(asset.spawned))
|
||||||
end
|
end
|
||||||
self:I(self.lid..text)
|
self:I(self.lid..text)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.verbose>=3 then
|
||||||
|
|
||||||
|
-- Count numbers
|
||||||
|
local Ntotal=0
|
||||||
|
local Nspawned=0
|
||||||
|
local Nrequested=0
|
||||||
|
local Nreserved=0
|
||||||
|
local Nstock=0
|
||||||
|
|
||||||
|
local text="\n===========================================\n"
|
||||||
|
text=text.."Assets:"
|
||||||
|
local legion=self --Ops.Legion#LEGION
|
||||||
|
|
||||||
|
for _,_cohort in pairs(legion.cohorts) do
|
||||||
|
local cohort=_cohort --Ops.Cohort#COHORT
|
||||||
|
|
||||||
|
for _,_asset in pairs(cohort.assets) do
|
||||||
|
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
||||||
|
|
||||||
|
local state="In Stock"
|
||||||
|
if asset.flightgroup then
|
||||||
|
state=asset.flightgroup:GetState()
|
||||||
|
local mission=legion:GetAssetCurrentMission(asset)
|
||||||
|
if mission then
|
||||||
|
state=state..string.format(", Mission \"%s\" [%s]", mission:GetName(), mission:GetType())
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if asset.spawned then
|
||||||
|
env.info("FF ERROR: asset has opsgroup but is NOT spawned!")
|
||||||
|
end
|
||||||
|
if asset.requested and asset.isReserved then
|
||||||
|
env.info("FF ERROR: asset is requested and reserved. Should not be both!")
|
||||||
|
state="Reserved+Requested!"
|
||||||
|
elseif asset.isReserved then
|
||||||
|
state="Reserved"
|
||||||
|
elseif asset.requested then
|
||||||
|
state="Requested"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Text.
|
||||||
|
text=text..string.format("\n[UID=%03d] %s Legion=%s [%s]: State=%s [RID=%s]",
|
||||||
|
asset.uid, asset.spawngroupname, legion.alias, cohort.name, state, tostring(asset.rid))
|
||||||
|
|
||||||
|
|
||||||
|
if asset.spawned then
|
||||||
|
Nspawned=Nspawned+1
|
||||||
|
end
|
||||||
|
if asset.requested then
|
||||||
|
Nrequested=Nrequested+1
|
||||||
|
end
|
||||||
|
if asset.isReserved then
|
||||||
|
Nreserved=Nreserved+1
|
||||||
|
end
|
||||||
|
if not (asset.spawned or asset.requested or asset.isReserved) then
|
||||||
|
Nstock=Nstock+1
|
||||||
|
end
|
||||||
|
|
||||||
|
Ntotal=Ntotal+1
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
text=text.."\n-------------------------------------------"
|
||||||
|
text=text..string.format("\nNstock = %d", Nstock)
|
||||||
|
text=text..string.format("\nNreserved = %d", Nreserved)
|
||||||
|
text=text..string.format("\nNrequested = %d", Nrequested)
|
||||||
|
text=text..string.format("\nNspawned = %d", Nspawned)
|
||||||
|
text=text..string.format("\nNtotal = %d (=%d)", Ntotal, Nstock+Nspawned+Nrequested+Nreserved)
|
||||||
|
text=text.."\n==========================================="
|
||||||
|
self:I(self.lid..text)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1242,7 +1242,21 @@ do
|
|||||||
-- end
|
-- end
|
||||||
-- end
|
-- end
|
||||||
--
|
--
|
||||||
|
-- ## 8. Transport crates and troops with CA (Combined Arms) trucks
|
||||||
--
|
--
|
||||||
|
-- You can optionally also allow to CTLD with CA trucks and other vehicles:
|
||||||
|
--
|
||||||
|
-- -- Create a SET_CLIENT to capture CA vehicles steered by players
|
||||||
|
-- local truckers = SET_CLIENT:New():HandleCASlots():FilterCoalitions("blue"):FilterPrefixes("Truck"):FilterStart()
|
||||||
|
-- -- Allow CA transport
|
||||||
|
-- my_ctld:AllowCATransport(true,truckers)
|
||||||
|
-- -- Set truck capability by typename
|
||||||
|
-- my_ctld:SetUnitCapabilities("M 818", true, true, 2, 12, 9, 4500)
|
||||||
|
-- -- Alternatively set truck capability with a UNIT object
|
||||||
|
-- local GazTruck = UNIT:FindByName("GazTruck-1-1")
|
||||||
|
-- my_ctld:SetUnitCapabilities(GazTruck, true, true, 2, 12, 9, 4500)
|
||||||
|
--
|
||||||
|
--
|
||||||
-- @field #CTLD
|
-- @field #CTLD
|
||||||
CTLD = {
|
CTLD = {
|
||||||
ClassName = "CTLD",
|
ClassName = "CTLD",
|
||||||
@@ -1277,6 +1291,7 @@ CTLD = {
|
|||||||
UserSetGroup = nil,
|
UserSetGroup = nil,
|
||||||
LoadedGroupsTable = {},
|
LoadedGroupsTable = {},
|
||||||
keeploadtable = true,
|
keeploadtable = true,
|
||||||
|
allowCATransport = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
------------------------------
|
------------------------------
|
||||||
@@ -1384,6 +1399,7 @@ CTLD.UnitTypeCapabilities = {
|
|||||||
["OH58D"] = {type="OH58D", crates=false, troops=false, cratelimit = 0, trooplimit = 0, length = 14, cargoweightlimit = 400},
|
["OH58D"] = {type="OH58D", crates=false, troops=false, cratelimit = 0, trooplimit = 0, length = 14, cargoweightlimit = 400},
|
||||||
["CH-47Fbl1"] = {type="CH-47Fbl1", crates=true, troops=true, cratelimit = 4, trooplimit = 31, length = 20, cargoweightlimit = 10800},
|
["CH-47Fbl1"] = {type="CH-47Fbl1", crates=true, troops=true, cratelimit = 4, trooplimit = 31, length = 20, cargoweightlimit = 10800},
|
||||||
["MosquitoFBMkVI"] = {type="MosquitoFBMkVI", crates= true, troops=false, cratelimit = 2, trooplimit = 0, length = 13, cargoweightlimit = 1800},
|
["MosquitoFBMkVI"] = {type="MosquitoFBMkVI", crates= true, troops=false, cratelimit = 2, trooplimit = 0, length = 13, cargoweightlimit = 1800},
|
||||||
|
["M 818"] = {type="M 818", crates= true, troops=true, cratelimit = 4, trooplimit = 12, length = 9, cargoweightlimit = 4500},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Allowed Fixed Wing Types
|
--- Allowed Fixed Wing Types
|
||||||
@@ -1396,7 +1412,7 @@ CTLD.FixedWingTypes = {
|
|||||||
|
|
||||||
--- CTLD class version.
|
--- CTLD class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CTLD.version="1.1.31"
|
CTLD.version="1.2.33"
|
||||||
|
|
||||||
--- Instantiate a new CTLD.
|
--- Instantiate a new CTLD.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
@@ -1606,6 +1622,10 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
|||||||
math.random()
|
math.random()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- CA Transport
|
||||||
|
self.allowCATransport = false -- #boolean
|
||||||
|
self.CATransportSet = nil -- Core.Set#SET_CLIENT
|
||||||
|
|
||||||
self:_GenerateVHFrequencies()
|
self:_GenerateVHFrequencies()
|
||||||
self:_GenerateUHFrequencies()
|
self:_GenerateUHFrequencies()
|
||||||
self:_GenerateFMFrequencies()
|
self:_GenerateFMFrequencies()
|
||||||
@@ -1949,6 +1969,16 @@ function CTLD:_GetUnitCapabilities(Unit)
|
|||||||
return capabilities
|
return capabilities
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- (User) Function to allow transport via Combined Arms Trucks.
|
||||||
|
-- @param #CTLD self
|
||||||
|
-- @param #boolean OnOff Switch on (true) or off (false).
|
||||||
|
-- @param Core.Set#SET_CLIENT ClientSet The CA handling client set for ground transport.
|
||||||
|
-- @return #CTLD self
|
||||||
|
function CTLD:AllowCATransport(OnOff,ClientSet)
|
||||||
|
self.allowCATransport = OnOff -- #boolean
|
||||||
|
self.CATransportSet = ClientSet -- Core.Set#SET_CLIENT
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- (Internal) Function to generate valid UHF Frequencies
|
--- (Internal) Function to generate valid UHF Frequencies
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
@@ -2029,6 +2059,12 @@ function CTLD:_EventHandler(EventData)
|
|||||||
self.Loaded_Cargo[unitname] = nil
|
self.Loaded_Cargo[unitname] = nil
|
||||||
self:_RefreshF10Menus()
|
self:_RefreshF10Menus()
|
||||||
end
|
end
|
||||||
|
-- CA support
|
||||||
|
if _unit:IsGround() and self.allowCATransport then
|
||||||
|
local unitname = event.IniUnitName or "none"
|
||||||
|
self.Loaded_Cargo[unitname] = nil
|
||||||
|
self:_RefreshF10Menus()
|
||||||
|
end
|
||||||
return
|
return
|
||||||
elseif event.id == EVENTS.Land or event.id == EVENTS.Takeoff then
|
elseif event.id == EVENTS.Land or event.id == EVENTS.Takeoff then
|
||||||
local unitname = event.IniUnitName
|
local unitname = event.IniUnitName
|
||||||
@@ -2742,6 +2778,7 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack)
|
|||||||
-- spawn crates in front of helicopter
|
-- spawn crates in front of helicopter
|
||||||
local IsHerc = self:IsFixedWing(Unit) -- Herc, Bronco and Hook load from behind
|
local IsHerc = self:IsFixedWing(Unit) -- Herc, Bronco and Hook load from behind
|
||||||
local IsHook = self:IsHook(Unit) -- Herc, Bronco and Hook load from behind
|
local IsHook = self:IsHook(Unit) -- Herc, Bronco and Hook load from behind
|
||||||
|
local IsTruck = Unit:IsGround()
|
||||||
local cargotype = Cargo -- Ops.CTLD#CTLD_CARGO
|
local cargotype = Cargo -- Ops.CTLD#CTLD_CARGO
|
||||||
local number = number or cargotype:GetCratesNeeded() --#number
|
local number = number or cargotype:GetCratesNeeded() --#number
|
||||||
local cratesneeded = cargotype:GetCratesNeeded() --#number
|
local cratesneeded = cargotype:GetCratesNeeded() --#number
|
||||||
@@ -2763,7 +2800,7 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack)
|
|||||||
local rheading = 0
|
local rheading = 0
|
||||||
local angleOffNose = 0
|
local angleOffNose = 0
|
||||||
local addon = 0
|
local addon = 0
|
||||||
if IsHerc or IsHook then
|
if IsHerc or IsHook or IsTruck then
|
||||||
-- spawn behind the Herc
|
-- spawn behind the Herc
|
||||||
addon = 180
|
addon = 180
|
||||||
end
|
end
|
||||||
@@ -3093,24 +3130,24 @@ function CTLD:_FindCratesNearby( _group, _unit, _dist, _ignoreweight, ignoretype
|
|||||||
if not _ignoreweight then
|
if not _ignoreweight then
|
||||||
maxloadable = self:_GetMaxLoadableMass(_unit)
|
maxloadable = self:_GetMaxLoadableMass(_unit)
|
||||||
end
|
end
|
||||||
self:T2(self.lid .. " Max loadable mass: " .. maxloadable)
|
self:T(self.lid .. " Max loadable mass: " .. maxloadable)
|
||||||
for _,_cargoobject in pairs (existingcrates) do
|
for _,_cargoobject in pairs (existingcrates) do
|
||||||
local cargo = _cargoobject -- #CTLD_CARGO
|
local cargo = _cargoobject -- #CTLD_CARGO
|
||||||
local static = cargo:GetPositionable() -- Wrapper.Static#STATIC -- crates
|
local static = cargo:GetPositionable() -- Wrapper.Static#STATIC -- crates
|
||||||
local weight = cargo:GetMass() -- weight in kgs of this cargo
|
local weight = cargo:GetMass() -- weight in kgs of this cargo
|
||||||
local staticid = cargo:GetID()
|
local staticid = cargo:GetID()
|
||||||
self:T2(self.lid .. " Found cargo mass: " .. weight)
|
self:T(self.lid .. " Found cargo mass: " .. weight)
|
||||||
if static and static:IsAlive() then --or cargoalive) then
|
if static and static:IsAlive() then --or cargoalive) then
|
||||||
local restricthooktononstatics = self.enableChinookGCLoading and IsHook
|
local restricthooktononstatics = self.enableChinookGCLoading and IsHook
|
||||||
--self:I(self.lid .. " restricthooktononstatics: " .. tostring(restricthooktononstatics))
|
self:T(self.lid .. " restricthooktononstatics: " .. tostring(restricthooktononstatics))
|
||||||
local cargoisstatic = cargo:GetType() == CTLD_CARGO.Enum.STATIC and true or false
|
local cargoisstatic = cargo:GetType() == CTLD_CARGO.Enum.STATIC and true or false
|
||||||
--self:I(self.lid .. " Cargo is static: " .. tostring(cargoisstatic))
|
self:T(self.lid .. " Cargo is static: " .. tostring(cargoisstatic))
|
||||||
local restricted = cargoisstatic and restricthooktononstatics
|
local restricted = cargoisstatic and restricthooktononstatics
|
||||||
--self:I(self.lid .. " Loading restricted: " .. tostring(restricted))
|
self:T(self.lid .. " Loading restricted: " .. tostring(restricted))
|
||||||
local staticpos = static:GetCoordinate() --or dcsunitpos
|
local staticpos = static:GetCoordinate() --or dcsunitpos
|
||||||
local cando = cargo:UnitCanCarry(_unit)
|
local cando = cargo:UnitCanCarry(_unit)
|
||||||
if ignoretype == true then cando = true end
|
if ignoretype == true then cando = true end
|
||||||
--self:I(self.lid .. " Unit can carry: " .. tostring(cando))
|
self:T(self.lid .. " Unit can carry: " .. tostring(cando))
|
||||||
--- Testing
|
--- Testing
|
||||||
local distance = self:_GetDistance(location,staticpos)
|
local distance = self:_GetDistance(location,staticpos)
|
||||||
self:T(self.lid .. string.format("Dist %dm/%dm | weight %dkg | maxloadable %dkg",distance,finddist,weight,maxloadable))
|
self:T(self.lid .. string.format("Dist %dm/%dm | weight %dkg | maxloadable %dkg",distance,finddist,weight,maxloadable))
|
||||||
@@ -4110,6 +4147,7 @@ function CTLD:_MoveGroupToZone(Group)
|
|||||||
local groupcoord = Group:GetCoordinate()
|
local groupcoord = Group:GetCoordinate()
|
||||||
-- Get closest zone of type
|
-- Get closest zone of type
|
||||||
local outcome, name, zone, distance = self:IsUnitInZone(Group,CTLD.CargoZoneType.MOVE)
|
local outcome, name, zone, distance = self:IsUnitInZone(Group,CTLD.CargoZoneType.MOVE)
|
||||||
|
self:T({canmove=outcome, name=name, zone=zone, dist=distance,max=self.movetroopsdistance})
|
||||||
if (distance <= self.movetroopsdistance) and outcome == true and zone~= nil then
|
if (distance <= self.movetroopsdistance) and outcome == true and zone~= nil then
|
||||||
-- yes, we can ;)
|
-- yes, we can ;)
|
||||||
local groupname = Group:GetName()
|
local groupname = Group:GetName()
|
||||||
@@ -4184,6 +4222,19 @@ function CTLD:_RefreshF10Menus()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- 3) CA Units
|
||||||
|
if self.allowCATransport and self.CATransportSet then
|
||||||
|
for _,_clientobj in pairs(self.CATransportSet.Set) do
|
||||||
|
local client = _clientobj -- Wrapper.Client#CLIENT
|
||||||
|
if client:IsGround() then
|
||||||
|
local cname = client:GetName()
|
||||||
|
self:T(self.lid.."Adding: "..cname)
|
||||||
|
_UnitList[cname] = cname
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
self.CtldUnits = _UnitList
|
self.CtldUnits = _UnitList
|
||||||
|
|
||||||
-- subcats?
|
-- subcats?
|
||||||
@@ -4212,10 +4263,15 @@ function CTLD:_RefreshF10Menus()
|
|||||||
local menus = {}
|
local menus = {}
|
||||||
for _, _unitName in pairs(self.CtldUnits) do
|
for _, _unitName in pairs(self.CtldUnits) do
|
||||||
if (not self.MenusDone[_unitName]) or (self.showstockinmenuitems == true) then
|
if (not self.MenusDone[_unitName]) or (self.showstockinmenuitems == true) then
|
||||||
|
self:T(self.lid.."Menu not done yet for ".._unitName)
|
||||||
local _unit = UNIT:FindByName(_unitName)
|
local _unit = UNIT:FindByName(_unitName)
|
||||||
|
if not _unit and self.allowCATransport then
|
||||||
|
_unit = CLIENT:FindByName(_unitName)
|
||||||
|
end
|
||||||
if _unit and _unit:IsAlive() then
|
if _unit and _unit:IsAlive() then
|
||||||
local _group = _unit:GetGroup()
|
local _group = _unit:GetGroup()
|
||||||
if _group then
|
if _group then
|
||||||
|
self:T(self.lid.."Unit and Group exist")
|
||||||
local capabilities = self:_GetUnitCapabilities(_unit)
|
local capabilities = self:_GetUnitCapabilities(_unit)
|
||||||
local cantroops = capabilities.troops
|
local cantroops = capabilities.troops
|
||||||
local cancrates = capabilities.crates
|
local cancrates = capabilities.crates
|
||||||
@@ -5191,6 +5247,8 @@ function CTLD:ActivateZone(Name,ZoneType,NewState)
|
|||||||
table = self.dropOffZones
|
table = self.dropOffZones
|
||||||
elseif ZoneType == CTLD.CargoZoneType.SHIP then
|
elseif ZoneType == CTLD.CargoZoneType.SHIP then
|
||||||
table = self.shipZones
|
table = self.shipZones
|
||||||
|
elseif ZoneType == CTLD.CargoZoneType.BEACON then
|
||||||
|
table = self.droppedBeacons
|
||||||
else
|
else
|
||||||
table = self.wpZones
|
table = self.wpZones
|
||||||
end
|
end
|
||||||
@@ -5623,7 +5681,8 @@ function CTLD:IsUnitInZone(Unit,Zonetype)
|
|||||||
end
|
end
|
||||||
local distance = self:_GetDistance(zonecoord,unitcoord)
|
local distance = self:_GetDistance(zonecoord,unitcoord)
|
||||||
self:T("Distance Zone: "..distance)
|
self:T("Distance Zone: "..distance)
|
||||||
if (zone:IsVec2InZone(unitVec2) or Zonetype == CTLD.CargoZoneType.MOVE) and active == true and maxdist > distance then
|
self:T("Zone Active: "..tostring(active))
|
||||||
|
if (zone:IsVec2InZone(unitVec2) or Zonetype == CTLD.CargoZoneType.MOVE) and active == true and distance < maxdist then
|
||||||
outcome = true
|
outcome = true
|
||||||
maxdist = distance
|
maxdist = distance
|
||||||
zoneret = zone
|
zoneret = zone
|
||||||
@@ -5730,9 +5789,8 @@ end
|
|||||||
local unit = nil
|
local unit = nil
|
||||||
if type(Unittype) == "string" then
|
if type(Unittype) == "string" then
|
||||||
unittype = Unittype
|
unittype = Unittype
|
||||||
elseif type(Unittype) == "table" then
|
elseif type(Unittype) == "table" and Unittype.ClassName and Unittype:IsInstanceOf("UNIT") then
|
||||||
unit = UNIT:FindByName(Unittype) -- Wrapper.Unit#UNIT
|
unittype = Unittype:GetTypeName()
|
||||||
unittype = unit:GetTypeName()
|
|
||||||
else
|
else
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -7699,7 +7757,7 @@ end
|
|||||||
--- [Internal] Function to spawn a soldier group of 10 units
|
--- [Internal] Function to spawn a soldier group of 10 units
|
||||||
-- @param #CTLD_HERCULES self
|
-- @param #CTLD_HERCULES self
|
||||||
-- @param Wrapper.Group#GROUP Cargo_Drop_initiator
|
-- @param Wrapper.Group#GROUP Cargo_Drop_initiator
|
||||||
-- @param Core.Point#POINT_VEC3 Cargo_Drop_Position
|
-- @param Core.Point#COORDINATE Cargo_Drop_Position
|
||||||
-- @param #string Cargo_Type_name
|
-- @param #string Cargo_Type_name
|
||||||
-- @param #number CargoHeading
|
-- @param #number CargoHeading
|
||||||
-- @param #number Cargo_Country
|
-- @param #number Cargo_Country
|
||||||
@@ -7722,7 +7780,7 @@ end
|
|||||||
--- [Internal] Function to spawn a group
|
--- [Internal] Function to spawn a group
|
||||||
-- @param #CTLD_HERCULES self
|
-- @param #CTLD_HERCULES self
|
||||||
-- @param Wrapper.Group#GROUP Cargo_Drop_initiator
|
-- @param Wrapper.Group#GROUP Cargo_Drop_initiator
|
||||||
-- @param Core.Point#POINT_VEC3 Cargo_Drop_Position
|
-- @param Core.Point#COORDINATE Cargo_Drop_Position
|
||||||
-- @param #string Cargo_Type_name
|
-- @param #string Cargo_Type_name
|
||||||
-- @param #number CargoHeading
|
-- @param #number CargoHeading
|
||||||
-- @param #number Cargo_Country
|
-- @param #number Cargo_Country
|
||||||
@@ -7746,7 +7804,7 @@ end
|
|||||||
--- [Internal] Function to spawn static cargo
|
--- [Internal] Function to spawn static cargo
|
||||||
-- @param #CTLD_HERCULES self
|
-- @param #CTLD_HERCULES self
|
||||||
-- @param Wrapper.Group#GROUP Cargo_Drop_initiator
|
-- @param Wrapper.Group#GROUP Cargo_Drop_initiator
|
||||||
-- @param Core.Point#POINT_VEC3 Cargo_Drop_Position
|
-- @param Core.Point#COORDINATE Cargo_Drop_Position
|
||||||
-- @param #string Cargo_Type_name
|
-- @param #string Cargo_Type_name
|
||||||
-- @param #number CargoHeading
|
-- @param #number CargoHeading
|
||||||
-- @param #boolean dead
|
-- @param #boolean dead
|
||||||
@@ -7768,7 +7826,7 @@ end
|
|||||||
--- [Internal] Function to spawn cargo by type at position
|
--- [Internal] Function to spawn cargo by type at position
|
||||||
-- @param #CTLD_HERCULES self
|
-- @param #CTLD_HERCULES self
|
||||||
-- @param #string Cargo_Type_name
|
-- @param #string Cargo_Type_name
|
||||||
-- @param Core.Point#POINT_VEC3 Cargo_Drop_Position
|
-- @param Core.Point#COORDINATE Cargo_Drop_Position
|
||||||
-- @return #CTLD_HERCULES self
|
-- @return #CTLD_HERCULES self
|
||||||
function CTLD_HERCULES:Cargo_SpawnDroppedAsCargo(_name, _pos)
|
function CTLD_HERCULES:Cargo_SpawnDroppedAsCargo(_name, _pos)
|
||||||
local theCargo = self.CTLD:_FindCratesCargoObject(_name) -- #CTLD_CARGO
|
local theCargo = self.CTLD:_FindCratesCargoObject(_name) -- #CTLD_CARGO
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
-- @field #number repeatsonfailure
|
-- @field #number repeatsonfailure
|
||||||
-- @field Core.Set#SET_ZONE GoZoneSet
|
-- @field Core.Set#SET_ZONE GoZoneSet
|
||||||
-- @field Core.Set#SET_ZONE NoGoZoneSet
|
-- @field Core.Set#SET_ZONE NoGoZoneSet
|
||||||
|
-- @field Core.Set#SET_ZONE ConflictZoneSet
|
||||||
-- @field #boolean Monitor
|
-- @field #boolean Monitor
|
||||||
-- @field #boolean TankerInvisible
|
-- @field #boolean TankerInvisible
|
||||||
-- @field #number CapFormation
|
-- @field #number CapFormation
|
||||||
@@ -102,6 +103,11 @@
|
|||||||
-- Next put a late activated template group for your CAP/GCI Squadron on the map. Last, put a zone on the map for the CAP operations, let's name it "Blue Zone 1". Size of the zone plays no role.
|
-- Next put a late activated template group for your CAP/GCI Squadron on the map. Last, put a zone on the map for the CAP operations, let's name it "Blue Zone 1". Size of the zone plays no role.
|
||||||
-- Put an EW radar system on the map and name it aptly, like "Blue EWR".
|
-- Put an EW radar system on the map and name it aptly, like "Blue EWR".
|
||||||
--
|
--
|
||||||
|
-- ### Zones
|
||||||
|
--
|
||||||
|
-- For our example, you create a RED and a BLUE border, as a closed polygonal zone representing the borderlines. You can also have conflict zone, where - for our example - BLUE will attack
|
||||||
|
-- RED planes, despite being on RED territory. Think of a no-fly zone or an limited area of engagement. Conflict zones take precedence over borders, i.e. they can overlap all borders.
|
||||||
|
--
|
||||||
-- ### Code it
|
-- ### Code it
|
||||||
--
|
--
|
||||||
-- -- Set up a basic system for the blue side, we'll reside on Kutaisi, and use GROUP objects with "Blue EWR" in the name as EW Radar Systems.
|
-- -- Set up a basic system for the blue side, we'll reside on Kutaisi, and use GROUP objects with "Blue EWR" in the name as EW Radar Systems.
|
||||||
@@ -114,10 +120,10 @@
|
|||||||
-- mywing:AddSquadron("Blue Sq1 M2000c","CAP Kutaisi",AIRBASE.Caucasus.Kutaisi,20,AI.Skill.GOOD,102,"ec1.5_Vendee_Jeanne_clean")
|
-- mywing:AddSquadron("Blue Sq1 M2000c","CAP Kutaisi",AIRBASE.Caucasus.Kutaisi,20,AI.Skill.GOOD,102,"ec1.5_Vendee_Jeanne_clean")
|
||||||
--
|
--
|
||||||
-- -- Add a couple of zones
|
-- -- Add a couple of zones
|
||||||
-- -- We'll defend our border
|
-- -- We'll defend our own border
|
||||||
-- mywing:AddAcceptZone(ZONE_POLYGON:New( "Blue Border", GROUP:FindByName( "Blue Border" ) ))
|
-- mywing:AddAcceptZone(ZONE_POLYGON:New( "Blue Border", GROUP:FindByName( "Blue Border" ) ))
|
||||||
-- -- We'll attack intruders also here
|
-- -- We'll attack intruders also here - conflictzones can overlap borders(!) - limited zone of engagement
|
||||||
-- mywing:AddAcceptZone(ZONE_POLYGON:New("Red Defense Zone", GROUP:FindByName( "Red Defense Zone" )))
|
-- mywing:AddConflictZone(ZONE_POLYGON:New("Red Defense Zone", GROUP:FindByName( "Red Defense Zone" )))
|
||||||
-- -- We'll leave the reds alone on their turf
|
-- -- We'll leave the reds alone on their turf
|
||||||
-- mywing:AddRejectZone(ZONE_POLYGON:New( "Red Border", GROUP:FindByName( "Red Border" ) ))
|
-- mywing:AddRejectZone(ZONE_POLYGON:New( "Red Border", GROUP:FindByName( "Red Border" ) ))
|
||||||
--
|
--
|
||||||
@@ -125,10 +131,10 @@
|
|||||||
-- -- Set up borders on map
|
-- -- Set up borders on map
|
||||||
-- local BlueBorder = ZONE_POLYGON:New( "Blue Border", GROUP:FindByName( "Blue Border" ) )
|
-- local BlueBorder = ZONE_POLYGON:New( "Blue Border", GROUP:FindByName( "Blue Border" ) )
|
||||||
-- BlueBorder:DrawZone(-1,{0,0,1},1,FillColor,FillAlpha,1,true)
|
-- BlueBorder:DrawZone(-1,{0,0,1},1,FillColor,FillAlpha,1,true)
|
||||||
-- local BlueNoGoZone = ZONE_POLYGON:New("Red Defense Zone", GROUP:FindByName( "Red Defense Zone" ))
|
-- local ConflictZone = ZONE_POLYGON:New("Red Defense Zone", GROUP:FindByName( "Red Defense Zone" ))
|
||||||
-- BlueNoGoZone:DrawZone(-1,{1,1,0},1,FillColor,FillAlpha,2,true)
|
-- ConflictZone:DrawZone(-1,{1,1,0},1,FillColor,FillAlpha,2,true)
|
||||||
-- local BlueNoGoZone2 = ZONE_POLYGON:New( "Red Border", GROUP:FindByName( "Red Border" ) )
|
-- local BlueNoGoZone = ZONE_POLYGON:New( "Red Border", GROUP:FindByName( "Red Border" ) )
|
||||||
-- BlueNoGoZone2:DrawZone(-1,{1,0,0},1,FillColor,FillAlpha,4,true)
|
-- BlueNoGoZone:DrawZone(-1,{1,0,0},1,FillColor,FillAlpha,4,true)
|
||||||
--
|
--
|
||||||
-- ### Add a second airwing with squads and own CAP point (optional)
|
-- ### Add a second airwing with squads and own CAP point (optional)
|
||||||
--
|
--
|
||||||
@@ -210,6 +216,7 @@ EASYGCICAP = {
|
|||||||
repeatsonfailure = 3,
|
repeatsonfailure = 3,
|
||||||
GoZoneSet = nil,
|
GoZoneSet = nil,
|
||||||
NoGoZoneSet = nil,
|
NoGoZoneSet = nil,
|
||||||
|
ConflictZoneSet = nil,
|
||||||
Monitor = false,
|
Monitor = false,
|
||||||
TankerInvisible = true,
|
TankerInvisible = true,
|
||||||
CapFormation = nil,
|
CapFormation = nil,
|
||||||
@@ -252,7 +259,7 @@ EASYGCICAP = {
|
|||||||
|
|
||||||
--- EASYGCICAP class version.
|
--- EASYGCICAP class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
EASYGCICAP.version="0.1.17"
|
EASYGCICAP.version="0.1.18"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@@ -287,6 +294,7 @@ function EASYGCICAP:New(Alias, AirbaseName, Coalition, EWRName)
|
|||||||
self.airbase = AIRBASE:FindByName(self.airbasename)
|
self.airbase = AIRBASE:FindByName(self.airbasename)
|
||||||
self.GoZoneSet = SET_ZONE:New()
|
self.GoZoneSet = SET_ZONE:New()
|
||||||
self.NoGoZoneSet = SET_ZONE:New()
|
self.NoGoZoneSet = SET_ZONE:New()
|
||||||
|
self.ConflictZoneSet = SET_ZONE:New()
|
||||||
self.resurrection = 900
|
self.resurrection = 900
|
||||||
self.capspeed = 300
|
self.capspeed = 300
|
||||||
self.capalt = 25000
|
self.capalt = 25000
|
||||||
@@ -1113,7 +1121,7 @@ end
|
|||||||
-- @param Core.Zone#ZONE_BASE Zone
|
-- @param Core.Zone#ZONE_BASE Zone
|
||||||
-- @return #EASYGCICAP self
|
-- @return #EASYGCICAP self
|
||||||
function EASYGCICAP:AddAcceptZone(Zone)
|
function EASYGCICAP:AddAcceptZone(Zone)
|
||||||
self:T(self.lid.."AddAcceptZone0")
|
self:T(self.lid.."AddAcceptZone")
|
||||||
self.GoZoneSet:AddZone(Zone)
|
self.GoZoneSet:AddZone(Zone)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1128,6 +1136,18 @@ function EASYGCICAP:AddRejectZone(Zone)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add a zone to the conflict zones set.
|
||||||
|
-- @param #EASYGCICAP self
|
||||||
|
-- @param Core.Zone#ZONE_BASE Zone
|
||||||
|
-- @return #EASYGCICAP self
|
||||||
|
function EASYGCICAP:AddConflictZone(Zone)
|
||||||
|
self:T(self.lid.."AddConflictZone")
|
||||||
|
self.ConflictZoneSet:AddZone(Zone)
|
||||||
|
self.GoZoneSet:AddZone(Zone)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- (Internal) Try to assign the intercept to a FlightGroup already in air and ready.
|
--- (Internal) Try to assign the intercept to a FlightGroup already in air and ready.
|
||||||
-- @param #EASYGCICAP self
|
-- @param #EASYGCICAP self
|
||||||
-- @param #table ReadyFlightGroups ReadyFlightGroups
|
-- @param #table ReadyFlightGroups ReadyFlightGroups
|
||||||
@@ -1193,6 +1213,7 @@ function EASYGCICAP:_AssignIntercept(Cluster)
|
|||||||
local ctlpts = self.ManagedCP
|
local ctlpts = self.ManagedCP
|
||||||
local MaxAliveMissions = self.MaxAliveMissions --* self.capgrouping
|
local MaxAliveMissions = self.MaxAliveMissions --* self.capgrouping
|
||||||
local nogozoneset = self.NoGoZoneSet
|
local nogozoneset = self.NoGoZoneSet
|
||||||
|
local conflictzoneset = self.ConflictZoneSet
|
||||||
local ReadyFlightGroups = self.ReadyFlightGroups
|
local ReadyFlightGroups = self.ReadyFlightGroups
|
||||||
|
|
||||||
-- Aircraft?
|
-- Aircraft?
|
||||||
@@ -1271,18 +1292,22 @@ function EASYGCICAP:_AssignIntercept(Cluster)
|
|||||||
|
|
||||||
if nogozoneset:Count() > 0 then
|
if nogozoneset:Count() > 0 then
|
||||||
InterceptAuftrag:AddConditionSuccess(
|
InterceptAuftrag:AddConditionSuccess(
|
||||||
function(group,zoneset)
|
function(group,zoneset,conflictset)
|
||||||
local success = false
|
local success = false
|
||||||
if group and group:IsAlive() then
|
if group and group:IsAlive() then
|
||||||
local coord = group:GetCoordinate()
|
local coord = group:GetCoordinate()
|
||||||
if coord and zoneset:IsCoordinateInZone(coord) then
|
if coord and zoneset:Count() > 0 and zoneset:IsCoordinateInZone(coord) then
|
||||||
success = true
|
success = true
|
||||||
end
|
end
|
||||||
|
if coord and conflictset:Count() > 0 and conflictset:IsCoordinateInZone(coord) then
|
||||||
|
success = false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return success
|
return success
|
||||||
end,
|
end,
|
||||||
contact.group,
|
contact.group,
|
||||||
nogozoneset
|
nogozoneset,
|
||||||
|
conflictzoneset
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1316,6 +1341,7 @@ function EASYGCICAP:_StartIntel()
|
|||||||
BlueIntel:SetForgetTime(300)
|
BlueIntel:SetForgetTime(300)
|
||||||
BlueIntel:SetAcceptZones(self.GoZoneSet)
|
BlueIntel:SetAcceptZones(self.GoZoneSet)
|
||||||
BlueIntel:SetRejectZones(self.NoGoZoneSet)
|
BlueIntel:SetRejectZones(self.NoGoZoneSet)
|
||||||
|
BlueIntel:SetConflictZones(self.ConflictZoneSet)
|
||||||
BlueIntel:SetVerbosity(0)
|
BlueIntel:SetVerbosity(0)
|
||||||
BlueIntel:Start()
|
BlueIntel:Start()
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -445,6 +445,7 @@ OPSGROUP.TaskType={
|
|||||||
-- @field Wrapper.Marker#MARKER marker Marker on the F10 map.
|
-- @field Wrapper.Marker#MARKER marker Marker on the F10 map.
|
||||||
-- @field #string formation Ground formation. Similar to action but on/off road.
|
-- @field #string formation Ground formation. Similar to action but on/off road.
|
||||||
-- @field #number missionUID Mission UID (Auftragsnr) this waypoint belongs to.
|
-- @field #number missionUID Mission UID (Auftragsnr) this waypoint belongs to.
|
||||||
|
-- @field Navigation.FlightPlan#FLIGHTPLAN flightplan Flightplan this waypoint belongs to.
|
||||||
|
|
||||||
--- Cargo Carrier status.
|
--- Cargo Carrier status.
|
||||||
-- @type OPSGROUP.CarrierStatus
|
-- @type OPSGROUP.CarrierStatus
|
||||||
@@ -573,6 +574,11 @@ function OPSGROUP:New(group)
|
|||||||
|
|
||||||
-- Set DCS group and controller.
|
-- Set DCS group and controller.
|
||||||
self.dcsgroup=self:GetDCSGroup()
|
self.dcsgroup=self:GetDCSGroup()
|
||||||
|
|
||||||
|
if not self.dcsgroup then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
self.controller=self.dcsgroup:getController()
|
self.controller=self.dcsgroup:getController()
|
||||||
|
|
||||||
-- Category.
|
-- Category.
|
||||||
@@ -9045,7 +9051,7 @@ function OPSGROUP:AddWeightCargo(UnitName, Weight)
|
|||||||
self:T(self.lid..string.format("%s: Adding %.1f kg cargo weight. New cargo weight=%.1f kg", UnitName, Weight, element.weightCargo))
|
self:T(self.lid..string.format("%s: Adding %.1f kg cargo weight. New cargo weight=%.1f kg", UnitName, Weight, element.weightCargo))
|
||||||
|
|
||||||
-- For airborne units, we set the weight in game.
|
-- For airborne units, we set the weight in game.
|
||||||
if self.isFlightgroup then
|
if self.isFlightgroup and element.unit and element.unit:IsAlive() then -- #2272 trying to deduct cargo weight from possibly dead units
|
||||||
trigger.action.setUnitInternalCargo(element.name, element.weightCargo) --https://wiki.hoggitworld.com/view/DCS_func_setUnitInternalCargo
|
trigger.action.setUnitInternalCargo(element.name, element.weightCargo) --https://wiki.hoggitworld.com/view/DCS_func_setUnitInternalCargo
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -11349,9 +11355,9 @@ function OPSGROUP:_SimpleTaskFunction(Function, uid)
|
|||||||
return DCSTask
|
return DCSTask
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Enhance waypoint table.
|
--- Enhanced waypoint table.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #OPSGROUP.Waypoint Waypoint data.
|
-- @param #OPSGROUP.Waypoint waypoint Waypoint data.
|
||||||
-- @return #OPSGROUP.Waypoint Modified waypoint data.
|
-- @return #OPSGROUP.Waypoint Modified waypoint data.
|
||||||
function OPSGROUP:_CreateWaypoint(waypoint)
|
function OPSGROUP:_CreateWaypoint(waypoint)
|
||||||
|
|
||||||
@@ -12779,7 +12785,7 @@ function OPSGROUP:_UpdatePosition()
|
|||||||
self.positionLast=self.position or self:GetVec3()
|
self.positionLast=self.position or self:GetVec3()
|
||||||
self.headingLast=self.heading or self:GetHeading()
|
self.headingLast=self.heading or self:GetHeading()
|
||||||
self.orientXLast=self.orientX or self:GetOrientationX()
|
self.orientXLast=self.orientX or self:GetOrientationX()
|
||||||
self.velocityLast=self.velocity or self.group:GetVelocityMPS()
|
self.velocityLast=self.velocity or self.group:GetVelocityMPS()
|
||||||
|
|
||||||
-- Current state.
|
-- Current state.
|
||||||
self.position=self:GetVec3()
|
self.position=self:GetVec3()
|
||||||
@@ -13607,20 +13613,24 @@ end
|
|||||||
-- @return Core.Point#COORDINATE The coordinate of the object.
|
-- @return Core.Point#COORDINATE The coordinate of the object.
|
||||||
function OPSGROUP:_CoordinateFromObject(Object)
|
function OPSGROUP:_CoordinateFromObject(Object)
|
||||||
|
|
||||||
|
env.info("FF coordfrom object")
|
||||||
if Object then
|
if Object then
|
||||||
if Object:IsInstanceOf("COORDINATE") then
|
if VECTOR._IsVector(Object) then
|
||||||
|
env.info("FF VECTOR")
|
||||||
|
return Object:GetCoordinate()
|
||||||
|
elseif Object:IsInstanceOf("COORDINATE") then
|
||||||
return Object
|
return Object
|
||||||
else
|
else
|
||||||
if Object:IsInstanceOf("POSITIONABLE") or Object:IsInstanceOf("ZONE_BASE") then
|
if Object:IsInstanceOf("POSITIONABLE") or Object:IsInstanceOf("ZONE_BASE") then
|
||||||
self:T(self.lid.."WARNING: Coordinate is not a COORDINATE but a POSITIONABLE or ZONE. Trying to get coordinate")
|
self:E(self.lid.."WARNING: Coordinate is not a COORDINATE but a POSITIONABLE or ZONE. Trying to get coordinate")
|
||||||
local coord=Object:GetCoordinate()
|
local coord=Object:GetCoordinate()
|
||||||
return coord
|
return coord
|
||||||
else
|
else
|
||||||
self:T(self.lid.."ERROR: Coordinate is neither a COORDINATE nor any POSITIONABLE or ZONE!")
|
self:E(self.lid.."ERROR: Coordinate is neither a COORDINATE nor any POSITIONABLE or ZONE!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:T(self.lid.."ERROR: Object passed is nil!")
|
self:E(self.lid.."ERROR: Object passed is nil!")
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -1331,6 +1331,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
|
||||||
|
|||||||
@@ -58,6 +58,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 +71,8 @@ DCSMAP = {
|
|||||||
Sinai="SinaiMap",
|
Sinai="SinaiMap",
|
||||||
Kola="Kola",
|
Kola="Kola",
|
||||||
Afghanistan="Afghanistan",
|
Afghanistan="Afghanistan",
|
||||||
Iraq="Iraq"
|
Iraq="Iraq",
|
||||||
|
GermanyCW="GermanyCW",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -349,7 +351,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 )
|
||||||
|
|
||||||
@@ -795,6 +797,33 @@ UTILS.kg2lbs = function( kg )
|
|||||||
return kg * 2.20462
|
return kg * 2.20462
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Convert latitude or longitude from degrees, minutes, seconds (DMS) to decimal degrees (DD).
|
||||||
|
-- @param #number Degrees Degrees in grad.
|
||||||
|
-- @param #number Minutes Minutes.
|
||||||
|
-- @param #number Seconds Seconds.
|
||||||
|
-- @return #number Latitude or Longitude in decimal degrees.
|
||||||
|
UTILS.LLDMSToDD = function(Degrees, Minutes, Seconds)
|
||||||
|
|
||||||
|
local dd=tonumber(Degrees or 0) + tonumber(Minutes or 0)/60 + tonumber(Seconds or 0)/3600
|
||||||
|
|
||||||
|
return dd
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Convert latitude or longitude from degrees, minutes, seconds (DMS) given in text form to decimal degrees (DD).
|
||||||
|
-- @param #string LatOrLongString Latitude or longitude passed as ttring in format `DD°MM'SS.SS"`.
|
||||||
|
-- @return #number Latitude or Longitude in decimal degrees.
|
||||||
|
UTILS.LLDMSstringToDD = function(LatOrLongString)
|
||||||
|
|
||||||
|
local hem=string.match(LatOrLongString, "(%a)")
|
||||||
|
local Degrees=string.match(LatOrLongString, "(%d+)°")
|
||||||
|
local Minutes=string.match(LatOrLongString, "(%d+)'")
|
||||||
|
local Seconds=string.match(LatOrLongString, "([%d\.]+)\"")
|
||||||
|
|
||||||
|
local dd=UTILS.LLDMSToDD(Degrees, Minutes, Seconds)
|
||||||
|
|
||||||
|
return dd
|
||||||
|
end
|
||||||
|
|
||||||
--[[acc:
|
--[[acc:
|
||||||
in DM: decimal point of minutes.
|
in DM: decimal point of minutes.
|
||||||
In DMS: decimal point of seconds.
|
In DMS: decimal point of seconds.
|
||||||
@@ -1515,6 +1544,22 @@ function UTILS.Vec2Add(a, b)
|
|||||||
return {x=a.x+b.x, y=a.y+b.y}
|
return {x=a.x+b.x, y=a.y+b.y}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Multiply 2D vector by a scalar value.
|
||||||
|
-- @param DCS#Vec2 a Vector in 2D with x, y components.
|
||||||
|
-- @param #number c Scalar value.
|
||||||
|
-- @return DCS#Vec2 Vector
|
||||||
|
function UTILS.Vec2Mult(a, c)
|
||||||
|
return {x=c*a.x, y=c*a.y}
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Multiply 3D vector by a scalar value.
|
||||||
|
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||||
|
-- @param #number c Scalar value.
|
||||||
|
-- @return DCS#Vec3 Vector
|
||||||
|
function UTILS.VecMult(a, c)
|
||||||
|
return {x=c*a.x, y=c*a.y, z=c*a.z}
|
||||||
|
end
|
||||||
|
|
||||||
--- Calculate the angle between two 3D vectors.
|
--- Calculate the angle between two 3D vectors.
|
||||||
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||||
-- @param DCS#Vec3 b Vector in 3D with x, y, z components.
|
-- @param DCS#Vec3 b Vector in 3D with x, y, z components.
|
||||||
@@ -1535,6 +1580,24 @@ function UTILS.VecAngle(a, b)
|
|||||||
return math.deg(alpha)
|
return math.deg(alpha)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Calculate the angle between two 3D vectors.
|
||||||
|
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||||
|
-- @param DCS#Vec3 b Vector in 3D with x, y, z components.
|
||||||
|
-- @return #number Angle alpha between and b in degrees.
|
||||||
|
function UTILS.VecAngleSigned(a, b)
|
||||||
|
|
||||||
|
local a=UTILS.VecSubstract(s1.p2.vec3, s1.p1.vec3)
|
||||||
|
|
||||||
|
local b=UTILS.VecSubstract(s2.p2.vec3, s2.p1.vec3)
|
||||||
|
|
||||||
|
local h1=UTILS.VecHdg(a)
|
||||||
|
local h2=UTILS.VecHdg(b)
|
||||||
|
|
||||||
|
local angle=h1-h2 --UTILS.VecAngle(a, b)
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
--- Calculate "heading" of a 3D vector in the X-Z plane.
|
--- Calculate "heading" of a 3D vector in the X-Z plane.
|
||||||
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||||
-- @return #number Heading in degrees in [0,360).
|
-- @return #number Heading in degrees in [0,360).
|
||||||
@@ -1557,6 +1620,20 @@ function UTILS.Vec2Hdg(a)
|
|||||||
return h
|
return h
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Calculate the difference between two "heading", i.e. angles in [0,360) deg.
|
||||||
|
-- @param DCS#Vec3 a Vector a.
|
||||||
|
-- @param DCS#Vec3 a Vector b.
|
||||||
|
-- @return #number Heading difference in degrees.
|
||||||
|
function UTILS.VecHdgDiff(a, b)
|
||||||
|
|
||||||
|
local ha=math.deg(math.atan2(a.z, a.x))
|
||||||
|
local hb=math.deg(math.atan2(b.z, b.x))
|
||||||
|
|
||||||
|
local angle=ha-hb
|
||||||
|
|
||||||
|
return angle
|
||||||
|
end
|
||||||
|
|
||||||
--- Calculate the difference between two "heading", i.e. angles in [0,360) deg.
|
--- Calculate the difference between two "heading", i.e. angles in [0,360) deg.
|
||||||
-- @param #number h1 Heading one.
|
-- @param #number h1 Heading one.
|
||||||
-- @param #number h2 Heading two.
|
-- @param #number h2 Heading two.
|
||||||
@@ -1759,7 +1836,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 +1870,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
|
||||||
@@ -2024,6 +2105,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
|
||||||
@@ -2329,8 +2414,12 @@ function UTILS.IsLoadingDoorOpen( unit_name )
|
|||||||
BASE:T(unit_name .. " rear cargo door is open")
|
BASE:T(unit_name .. " rear cargo door is open")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
-- ground
|
||||||
|
local UnitDescriptor = unit:getDesc()
|
||||||
|
local IsGroundResult = (UnitDescriptor.category == Unit.Category.GROUND_UNIT)
|
||||||
|
|
||||||
|
return IsGroundResult
|
||||||
|
|
||||||
end -- nil
|
end -- nil
|
||||||
|
|
||||||
@@ -3188,6 +3277,62 @@ function UTILS.BearingToCardinal(Heading)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Adjust given heading so that is is in [0, 360).
|
||||||
|
-- @param #number Heading The heading in degrees.
|
||||||
|
-- @return #number Adjust heading in [0,360).
|
||||||
|
function UTILS.AdjustHeading360(Heading)
|
||||||
|
|
||||||
|
if Heading>=360 then
|
||||||
|
Heading=Heading-360
|
||||||
|
elseif Heading<0 then
|
||||||
|
Heading=Heading+360
|
||||||
|
end
|
||||||
|
|
||||||
|
return Heading
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Transfroms a given 2D vector 3D.
|
||||||
|
-- This takes care of ED's different conventions for 2D and 3D coordinate systems.
|
||||||
|
-- @param DCS#Vec2 Vec Vector to be transformed. Can be any table/object that has at least x and y and optionally a z component.
|
||||||
|
-- @param #boolean OnSurface If `true`, new vector's y-component (alt) is at surface height. Otherwise, it is set to 0.
|
||||||
|
-- @return DCS#Vec3 Vector in 3D with x-, y- and z-components.
|
||||||
|
function UTILS.VecTo3D(Vec, OnSurface)
|
||||||
|
|
||||||
|
local vec={x=0, y=0, z=0} --DCS#Vec3
|
||||||
|
if Vec.z then
|
||||||
|
-- Vector is 3D already ==> Nothing to do.
|
||||||
|
vec.x=Vec.x
|
||||||
|
vec.y=Vec.y
|
||||||
|
vec.z=Vec.z
|
||||||
|
else
|
||||||
|
-- Vector is 2D
|
||||||
|
vec.x=Vec.x
|
||||||
|
vec.y=OnSurface and land.getHeight({x=Vec.x, y=Vec.y}) or 0
|
||||||
|
vec.z=Vec.y
|
||||||
|
end
|
||||||
|
|
||||||
|
return vec
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Transfroms a given 3D (or 2D) vector to 2D.
|
||||||
|
-- This takes care of ED's different conventions for 2D and 3D coordinate systems.
|
||||||
|
-- @param DCS#Vec3 Vec Vector to be transformed. Can be any table/object that has at least x and y and optionally a z component.
|
||||||
|
-- @return DCS#Vec2 Vector in 2D with x- and y-components.
|
||||||
|
function UTILS.VecTo2D(Vec)
|
||||||
|
|
||||||
|
local vec={x=0, y=0} --DCS#Vec2
|
||||||
|
|
||||||
|
if Vec.z then
|
||||||
|
vec.x=Vec.x
|
||||||
|
vec.y=Vec.z
|
||||||
|
else
|
||||||
|
vec.x=Vec.x
|
||||||
|
vec.y=Vec.y
|
||||||
|
end
|
||||||
|
|
||||||
|
return vec
|
||||||
|
end
|
||||||
|
|
||||||
--- Create a BRAA NATO call string BRAA between two GROUP objects
|
--- Create a BRAA NATO call string BRAA between two GROUP objects
|
||||||
-- @param Wrapper.Group#GROUP FromGrp GROUP object
|
-- @param Wrapper.Group#GROUP FromGrp GROUP object
|
||||||
-- @param Wrapper.Group#GROUP ToGrp GROUP object
|
-- @param Wrapper.Group#GROUP ToGrp GROUP object
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
-- @field #AIRBASE.Runway runwayLanding Runway used for landing.
|
-- @field #AIRBASE.Runway runwayLanding Runway used for landing.
|
||||||
-- @field #AIRBASE.Runway runwayTakeoff Runway used for takeoff.
|
-- @field #AIRBASE.Runway runwayTakeoff Runway used for takeoff.
|
||||||
-- @field Wrapper.Storage#STORAGE storage The DCS warehouse storage.
|
-- @field Wrapper.Storage#STORAGE storage The DCS warehouse storage.
|
||||||
|
-- @field #table taxiways Taxiways stored as PATHLINEs.
|
||||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||||
|
|
||||||
--- Wrapper class to handle the DCS Airbase objects:
|
--- Wrapper class to handle the DCS Airbase objects:
|
||||||
@@ -78,6 +79,7 @@ AIRBASE = {
|
|||||||
[Airbase.Category.SHIP] = "Ship",
|
[Airbase.Category.SHIP] = "Ship",
|
||||||
},
|
},
|
||||||
activerwyno = nil,
|
activerwyno = nil,
|
||||||
|
taxiways = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Enumeration to identify the airbases in the Caucasus region.
|
--- Enumeration to identify the airbases in the Caucasus region.
|
||||||
@@ -909,6 +911,413 @@ AIRBASE.Iraq = {
|
|||||||
["K1_Base"] = "K1 Base",
|
["K1_Base"] = "K1 Base",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- Airbases of the Germany Cold War map
|
||||||
|
-- * AIRBASE.GermanyCW.Airracing_Frankfurt
|
||||||
|
-- * AIRBASE.GermanyCW.Airracing_Koblenz
|
||||||
|
-- * AIRBASE.GermanyCW.Airracing_Luebeck
|
||||||
|
-- * AIRBASE.GermanyCW.Allstedt
|
||||||
|
-- * AIRBASE.GermanyCW.Alt_Daber
|
||||||
|
-- * 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.Gatow
|
||||||
|
-- * AIRBASE.GermanyCW.Gelnhausen
|
||||||
|
-- * AIRBASE.GermanyCW.Giebelstadt
|
||||||
|
-- * AIRBASE.GermanyCW.Glindbruchkippe
|
||||||
|
-- * AIRBASE.GermanyCW.Gross_Doelln
|
||||||
|
-- * AIRBASE.GermanyCW.Gross_Mohrdorf
|
||||||
|
-- * AIRBASE.GermanyCW.Grosse_Wiese
|
||||||
|
-- * AIRBASE.GermanyCW.Gaerz
|
||||||
|
-- * 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_Med_FRG_02
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_04
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_06
|
||||||
|
-- * AIRBASE.GermanyCW.H_Med_FRG_09
|
||||||
|
-- * 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.Leipzig_Halle
|
||||||
|
-- * AIRBASE.GermanyCW.Leipzig_Mockau
|
||||||
|
-- * AIRBASE.GermanyCW.Laerz
|
||||||
|
-- * 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.Schweinfurt
|
||||||
|
-- * AIRBASE.GermanyCW.Schoenefeld
|
||||||
|
-- * AIRBASE.GermanyCW.Sembach
|
||||||
|
-- * AIRBASE.GermanyCW.Spangdahlem
|
||||||
|
-- * AIRBASE.GermanyCW.Sperenberg
|
||||||
|
-- * AIRBASE.GermanyCW.Stendal
|
||||||
|
-- * AIRBASE.GermanyCW.Tegel
|
||||||
|
-- * AIRBASE.GermanyCW.Tempelhof
|
||||||
|
-- * 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.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",
|
||||||
|
["Alt_Daber"] = "Alt Daber",
|
||||||
|
["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",
|
||||||
|
["Gatow"] = "Gatow",
|
||||||
|
["Gelnhausen"] = "Gelnhausen",
|
||||||
|
["Giebelstadt"] = "Giebelstadt",
|
||||||
|
["Glindbruchkippe_"] = "Glindbruchkippe ",
|
||||||
|
["Gross_Doelln"] = "Gross Dolln",
|
||||||
|
["Gross_Mohrdorf"] = "Gross Mohrdorf",
|
||||||
|
["Grosse_Wiese"] = "Grosse Wiese",
|
||||||
|
["Gaerz"] = "Garz",
|
||||||
|
["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_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_09"] = "H Med FRG 09",
|
||||||
|
["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",
|
||||||
|
["Leipzig_Halle"] = "Leipzig Halle",
|
||||||
|
["Leipzig_Mockau"] = "Leipzig Mockau",
|
||||||
|
["Laerz"] = "Larz",
|
||||||
|
["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",
|
||||||
|
["Schweinfurt"] = "Schweinfurt",
|
||||||
|
["Schoenefeld"] = "Schonefeld",
|
||||||
|
["Sembach"] = "Sembach",
|
||||||
|
["Spangdahlem"] = "Spangdahlem",
|
||||||
|
["Sperenberg"] = "Sperenberg",
|
||||||
|
["Stendal"] = "Stendal",
|
||||||
|
["Tegel"] = "Tegel",
|
||||||
|
["Tempelhof"] = "Tempelhof",
|
||||||
|
["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",
|
||||||
|
["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.
|
||||||
@@ -975,6 +1384,32 @@ AIRBASE.SpotStatus = {
|
|||||||
RESERVED="Reserved",
|
RESERVED="Reserved",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- ICAO Codes.
|
||||||
|
-- @type AIRBASE.ICAO
|
||||||
|
AIRBASE.ICAO = {
|
||||||
|
UGTB=AIRBASE.Caucasus.Tbilisi_Lochini,
|
||||||
|
UGKO=AIRBASE.Caucasus.Kutaisi,
|
||||||
|
UG5X=AIRBASE.Caucasus.Kobuleti,
|
||||||
|
UG24=AIRBASE.Caucasus.Soganlug,
|
||||||
|
UG27=AIRBASE.Caucasus.Vaziani,
|
||||||
|
UGSS=AIRBASE.Caucasus.Sukhumi_Babushara,
|
||||||
|
UG23=AIRBASE.Caucasus.Gudauta,
|
||||||
|
URSS=AIRBASE.Caucasus.Sochi_Adler,
|
||||||
|
URMO=AIRBASE.Caucasus.Beslan,
|
||||||
|
URMN=AIRBASE.Caucasus.Nalchik,
|
||||||
|
XRMF=AIRBASE.Caucasus.Mozdok,
|
||||||
|
URMM=AIRBASE.Caucasus.Mineralnye_Vody,
|
||||||
|
URKH=AIRBASE.Caucasus.Maykop_Khanskaya,
|
||||||
|
URKK=AIRBASE.Caucasus.Krasnodar_Pashkovsky,
|
||||||
|
URKL=AIRBASE.Caucasus.Krasnodar_Center,
|
||||||
|
URKG=AIRBASE.Caucasus.Gelendzhik,
|
||||||
|
URKN=AIRBASE.Caucasus.Novorossiysk,
|
||||||
|
URKW=AIRBASE.Caucasus.Krymsk,
|
||||||
|
URKA=AIRBASE.Caucasus.Anapa_Vityazevo,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Runway data.
|
--- Runway data.
|
||||||
-- @type AIRBASE.Runway
|
-- @type AIRBASE.Runway
|
||||||
-- @field #string name Runway name.
|
-- @field #string name Runway name.
|
||||||
@@ -1152,14 +1587,47 @@ end
|
|||||||
|
|
||||||
--- Find a AIRBASE in the _DATABASE using the name of an existing DCS Airbase.
|
--- Find a AIRBASE in the _DATABASE using the name of an existing DCS Airbase.
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
-- @param #string AirbaseName The Airbase Name.
|
-- @param #string AirbaseName The name of the airbase. Can also be the ICAO code or the airbase ID.
|
||||||
-- @return #AIRBASE self
|
-- @return #AIRBASE self
|
||||||
function AIRBASE:FindByName( AirbaseName )
|
function AIRBASE:FindByName( AirbaseName )
|
||||||
|
|
||||||
local AirbaseFound = _DATABASE:FindAirbase( AirbaseName )
|
local AirbaseFound = _DATABASE:FindAirbase( AirbaseName )
|
||||||
|
|
||||||
|
if not AirbaseFound then
|
||||||
|
AirbaseFound=self:FindByICAO(AirbaseName)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not AirbaseFound then
|
||||||
|
AirbaseFound=self:FindByID(AirbaseName)
|
||||||
|
end
|
||||||
|
|
||||||
return AirbaseFound
|
return AirbaseFound
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Find an AIRBASE in the _DATABASE using the [International Civil Aviation Organization](https://en.wikipedia.org/wiki/ICAO_airport_code) (ICAO) airport code.
|
||||||
|
-- The code consists of four characters. Typically, the first one or two letters of the ICAO code indicate the country and the remaining letters identify the airport.
|
||||||
|
--
|
||||||
|
-- **NOTE** that the ICAO code cannot be retrieved via the DCS API and has to be hard coded into the MOOSE code. Therefore, it is a rare occasion where
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @param #string AirbaseICAO The Airbase ICAO code.
|
||||||
|
-- @return #AIRBASE self
|
||||||
|
function AIRBASE:FindByICAO( AirbaseICAO )
|
||||||
|
|
||||||
|
if AirbaseICAO then
|
||||||
|
|
||||||
|
local name=AIRBASE.ICAO[AirbaseICAO]
|
||||||
|
|
||||||
|
env.info(string.format("FF ICAO=%s, Name=%s", tostring(AirbaseICAO), tostring(name)))
|
||||||
|
|
||||||
|
local Airbase=self:FindByName(name)
|
||||||
|
return Airbase
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Find a AIRBASE in the _DATABASE by its ID.
|
--- Find a AIRBASE in the _DATABASE by its ID.
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
-- @param #number id Airbase ID.
|
-- @param #number id Airbase ID.
|
||||||
@@ -1472,6 +1940,129 @@ function AIRBASE:IsShip()
|
|||||||
return self.isShip
|
return self.isShip
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Taxi ways
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Add a taxiway from a given PATHLINE.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @param Core.Pathline#PATHLINE TaxiPathline Pathline of the taxi way or name of pathline as #string.
|
||||||
|
-- @param #string Name Name of the taxi way, *e.g.* "Alpha", or "Alpha-Kilo". Default is name of pathline.
|
||||||
|
-- @return #AIRBASE self
|
||||||
|
function AIRBASE:AddTaxiway(TaxiPathline, Name)
|
||||||
|
|
||||||
|
-- If passed as string, get pathline.
|
||||||
|
if type(TaxiPathline)=="string" then
|
||||||
|
TaxiPathline=PATHLINE:FindByName(TaxiPathline)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set name.
|
||||||
|
Name=Name or TaxiPathline:GetName()
|
||||||
|
|
||||||
|
-- Create a deep copy.
|
||||||
|
local taxiway=UTILS.DeepCopy(TaxiPathline) --Core.Pathline#PATHLINE
|
||||||
|
|
||||||
|
-- Set name.
|
||||||
|
taxiway.name=Name
|
||||||
|
|
||||||
|
-- Add to taxiways.
|
||||||
|
self.taxiways[Name]=taxiway
|
||||||
|
|
||||||
|
|
||||||
|
--self:I(self.taxiways)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Find the shortest path using taxiways to get from given coodinates A to B on the airbase.
|
||||||
|
-- Note that the taxi ways have to be manually added with the `AIRBASE:AddTaxiway()` function.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @param Core.Point#COORDINATE StartCoord Start coordinate.
|
||||||
|
-- @param Core.Point#COORDINATE EndCoord End coordinate.
|
||||||
|
-- @return Core.Pathline#PATHLINE Shortest path on taxiways from `StartCoord` to `EndCoord`.
|
||||||
|
-- @return #table Table of used taxi way pathlines.
|
||||||
|
function AIRBASE:FindTaxiwaysFromAtoB(StartCoord, EndCoord)
|
||||||
|
|
||||||
|
-- Create A* pathfinding.
|
||||||
|
local astar=ASTAR:New()
|
||||||
|
|
||||||
|
-- Add pathlines of taxiways of airport.
|
||||||
|
for _,_taxiway in pairs(self.taxiways) do
|
||||||
|
local taxiway=_taxiway --Core.Pathline#PATHLINE
|
||||||
|
|
||||||
|
astar:AddNodeFromPathlineName(taxiway)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set cost function.
|
||||||
|
astar:SetCostDist2D()
|
||||||
|
|
||||||
|
-- Set valid neighbours to be on the same pathline or at most 10 meters between nodes to jump from one pathline/taxiway to another.
|
||||||
|
astar:SetValidNeighbourPathline(10)
|
||||||
|
|
||||||
|
-- Set start and end coordinates.
|
||||||
|
astar:SetStartCoordinate(StartCoord)
|
||||||
|
astar:SetEndCoordinate(EndCoord)
|
||||||
|
|
||||||
|
-- Get pathline.
|
||||||
|
local taxipath, nodes=astar:GetPathline()
|
||||||
|
|
||||||
|
local taxiways=astar:GetPathlinesFromNodes(nodes)
|
||||||
|
|
||||||
|
return taxipath, taxiways
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get closest taxiway from a given reference coordinate.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @param Core.Point#COORDINATE Coord Reference coordinate.
|
||||||
|
-- @return Core.Pathline#PATHLINE Taxiway.
|
||||||
|
-- @return #number Distance to taxiway in meters.
|
||||||
|
-- @return Core.Point#COORDINATE Coordinate on taxiway closest to reference coordinate.
|
||||||
|
-- @return Core.Pathline#PATHLINE.Segment Segment of the taxiway closest to the reference coordinate.
|
||||||
|
function AIRBASE:GetClosestTaxiway(Coord)
|
||||||
|
|
||||||
|
local taxipath=nil
|
||||||
|
local distmin=math.huge
|
||||||
|
local coordmin=nil
|
||||||
|
local segmin=nil
|
||||||
|
|
||||||
|
for name,_pathline in pairs(self.taxiways) do
|
||||||
|
local pathline=_pathline --Core.Pathline#PATHLINE
|
||||||
|
|
||||||
|
local coord, dist, segment=pathline:GetClosestPoint3D(Coord)
|
||||||
|
|
||||||
|
if dist<distmin then
|
||||||
|
taxipath=pathline
|
||||||
|
coordmin=coord
|
||||||
|
distmin=dist
|
||||||
|
segmin=segment
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return taxipath, distmin, coordmin, segmin
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Find the shortest path using taxiways to get from given parking spot to the starting point of a runway.
|
||||||
|
-- Note that the taxi ways have to be manually added with the `AIRBASE:AddTaxiway()` function.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @param #AIRBASE.ParkingSpot ParkingSpot Parking spot.
|
||||||
|
-- @param #AIRBASE.Runway Runway The runway. If none is given, we take the active runway for takeoff.
|
||||||
|
-- @return Core.Pathline#PATHLINE Shortest path on taxiways from `StartCoord` to `EndCoord`.
|
||||||
|
-- @return #table Table of used taxi way pathlines.
|
||||||
|
function AIRBASE:FindTaxiwaysParkingToRunway(ParkingSpot, Runway)
|
||||||
|
|
||||||
|
Runway=Runway or self:GetActiveRunwayTakeoff()
|
||||||
|
|
||||||
|
local StartCoord=ParkingSpot.Coordinate
|
||||||
|
local EndCoord=Runway.position
|
||||||
|
|
||||||
|
local taxipath, taxiways=self:FindTaxiwaysFromAtoB(StartCoord,EndCoord)
|
||||||
|
|
||||||
|
return taxipath, taxiways
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Parking
|
-- Parking
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -2131,7 +2722,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 +2749,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,6 +2765,7 @@ function AIRBASE:_InitRunways(IncludeInverse)
|
|||||||
runway.name=string.format("%02d", tonumber(namefromheading))
|
runway.name=string.format("%02d", tonumber(namefromheading))
|
||||||
else
|
else
|
||||||
runway.name=string.format("%02d", tonumber(name))
|
runway.name=string.format("%02d", tonumber(name))
|
||||||
|
self:I("RunwayName: "..runway.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
--runway.name=string.format("%02d", tonumber(name))
|
--runway.name=string.format("%02d", tonumber(name))
|
||||||
@@ -2495,7 +3087,7 @@ function AIRBASE:GetRunwayData(magvar, mark)
|
|||||||
runway.endpoint=c2
|
runway.endpoint=c2
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
--self:I(string.format("Airbase %s: Adding runway id=%s, heading=%03d, length=%d m i=%d j=%d", self:GetName(), runway.idx, runway.heading, runway.length, i, j))
|
self:T(string.format("Airbase %s: Adding runway id=%s, heading=%03d, length=%d m i=%d j=%d", self:GetName(), runway.idx, runway.heading, runway.length, i, j))
|
||||||
|
|
||||||
-- Debug mark
|
-- Debug mark
|
||||||
if mark then
|
if mark then
|
||||||
@@ -2622,8 +3214,8 @@ function AIRBASE:GetRunwayIntoWind(PreferLeft)
|
|||||||
|
|
||||||
-- Loop over runways.
|
-- Loop over runways.
|
||||||
local dotmin=nil
|
local dotmin=nil
|
||||||
for i,_runway in pairs(runways) do
|
for i ,_runway in pairs(runways) do
|
||||||
local runway=_runway --#AIRBASE.Runway
|
local runway=_runway --#AIRBASE.Runway
|
||||||
|
|
||||||
if PreferLeft==nil or PreferLeft==runway.isLeft then
|
if PreferLeft==nil or PreferLeft==runway.isLeft then
|
||||||
|
|
||||||
|
|||||||
@@ -994,6 +994,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.
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -124,7 +124,7 @@ DYNAMICCARGO.AircraftDimensions = {
|
|||||||
|
|
||||||
--- DYNAMICCARGO class version.
|
--- DYNAMICCARGO class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
DYNAMICCARGO.version="0.0.5"
|
DYNAMICCARGO.version="0.0.7"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@@ -183,7 +183,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 +227,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 +238,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 +376,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 +420,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]
|
local hovering, height = self:_HeloHovering(helo,dimensions.ropelength)
|
||||||
if dimensions then
|
local helolanded = not helo:InAir()
|
||||||
local delta2D = hpos:Get2DDistance(pos)
|
self:T(self.lid.." InAir: AGL/Hovering: "..hpos.y-hpos:GetLandHeight().."/"..tostring(hovering))
|
||||||
local delta3D = hpos:Get3DDistance(pos)
|
if hpos and typename and dimensions then
|
||||||
if self.testing then
|
local delta2D = hpos:Get2DDistance(pos)
|
||||||
self:T(string.format("Cargo relative position: 2D %dm | 3D %dm",delta2D,delta3D))
|
local delta3D = hpos:Get3DDistance(pos)
|
||||||
self:T(string.format("Helo dimension: length %dm | width %dm | rope %dm",dimensions.length,dimensions.width,dimensions.ropelength))
|
if self.testing then
|
||||||
end
|
self:T(string.format("Cargo relative position: 2D %dm | 3D %dm",delta2D,delta3D))
|
||||||
if loading~=true and delta2D > dimensions.length or delta2D > dimensions.width or delta3D > dimensions.ropelength then
|
self:T(string.format("Helo dimension: length %dm | width %dm | rope %dm",dimensions.length,dimensions.width,dimensions.ropelength))
|
||||||
success = true
|
self:T(string.format("Helo hovering: %s at %dm",tostring(hovering),height))
|
||||||
Helo = helo
|
end
|
||||||
Playername = name
|
-- unloading from ground
|
||||||
end
|
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.
|
||||||
if loading == true and delta2D < dimensions.length or delta2D < dimensions.width or delta3D < dimensions.ropelength then
|
success = true
|
||||||
success = true
|
Helo = helo
|
||||||
Helo = helo
|
Playername = name
|
||||||
Playername = name
|
end
|
||||||
end
|
-- unloading from hover/rope
|
||||||
|
if loading~=true and delta3D > dimensions.ropelength then
|
||||||
|
success = true
|
||||||
|
Helo = helo
|
||||||
|
Playername = name
|
||||||
|
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,20 +468,22 @@ 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
|
||||||
---------------
|
---------------
|
||||||
elseif self.CargoState == DYNAMICCARGO.State.LOADED then
|
-- 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
|
||||||
-- 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
|
||||||
local count = _DYNAMICCARGO_HELOS:CountAlive()
|
local count = _DYNAMICCARGO_HELOS:CountAlive()
|
||||||
@@ -459,26 +495,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
|
||||||
|
|||||||
@@ -1179,9 +1179,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 +1194,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
|
||||||
@@ -1843,7 +1843,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 +2096,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 +2147,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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
@@ -284,9 +284,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 +296,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 +329,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
|
||||||
|
|
||||||
|
|||||||
@@ -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 = '.'
|
||||||
@@ -15,8 +16,9 @@ with open( os.path.dirname(__file__) + '/docs-header.html', 'r') as file:
|
|||||||
# that directory
|
# that directory
|
||||||
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!**
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user