mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'FF/Ops' into FF/OpsDev
This commit is contained in:
@@ -112,7 +112,7 @@
|
||||
--
|
||||
-- # Calculate the Path
|
||||
--
|
||||
-- Finally, we have to calculate the path. This is done by the @{ASTAR.GetPath}(*ExcludeStart, ExcludeEnd*) function. This function returns a table of nodes, which
|
||||
-- Finally, we have to calculate the path. This is done by the @{#GetPath}(*ExcludeStart, ExcludeEnd*) function. This function returns a table of nodes, which
|
||||
-- describe the optimal path from the start node to the end node.
|
||||
--
|
||||
-- By default, the start and end node are include in the table that is returned.
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
--
|
||||
-- ## Example Missions:
|
||||
--
|
||||
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/OPS%20-%20Operation).
|
||||
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Core/Condition).
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
|
||||
@@ -680,7 +680,7 @@ do -- cargo
|
||||
--- Finds an CARGO based on the CargoName.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string CargoName
|
||||
-- @return Wrapper.Cargo#CARGO The found CARGO.
|
||||
-- @return Cargo.Cargo#CARGO The found CARGO.
|
||||
function DATABASE:FindCargo( CargoName )
|
||||
|
||||
local CargoFound = self.CARGOS[CargoName]
|
||||
|
||||
@@ -313,7 +313,7 @@ EVENTS = {
|
||||
-- @field Cargo.Cargo#CARGO Cargo The cargo object.
|
||||
-- @field #string CargoName The name of the cargo object.
|
||||
--
|
||||
-- @field Core.ZONE#ZONE Zone The zone object.
|
||||
-- @field Core.Zone#ZONE Zone The zone object.
|
||||
-- @field #string ZoneName The name of the zone.
|
||||
|
||||
|
||||
@@ -988,7 +988,7 @@ do -- Event Creation
|
||||
|
||||
--- Creation of a New ZoneGoal Event.
|
||||
-- @param #EVENT self
|
||||
-- @param Core.Functional#ZONE_GOAL ZoneGoal The ZoneGoal created.
|
||||
-- @param Functional.ZoneGoal#ZONE_GOAL ZoneGoal The ZoneGoal created.
|
||||
function EVENT:CreateEventNewZoneGoal( ZoneGoal )
|
||||
self:F( { ZoneGoal } )
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ do -- FSM
|
||||
--
|
||||
-- ### Linear Transition Example
|
||||
--
|
||||
-- This example is fully implemented in the MOOSE test mission on GITHUB: [FSM-100 - Transition Explanation](https://github.com/FlightControl-Master/MOOSE/blob/master/Moose%20Test%20Missions/FSM%20-%20Finite%20State%20Machine/FSM-100%20-%20Transition%20Explanation/FSM-100%20-%20Transition%20Explanation.lua)
|
||||
-- This example is fully implemented in the MOOSE test mission on GITHUB: [FSM-100 - Transition Explanation](https://github.com/FlightControl-Master/MOOSE_MISSIONS/blob/master/FSM%20-%20Finite%20State%20Machine/FSM-100%20-%20Transition%20Explanation/FSM-100%20-%20Transition%20Explanation.lua)
|
||||
--
|
||||
-- It models a unit standing still near Batumi, and flaring every 5 seconds while switching between a Green flare and a Red flare.
|
||||
-- The purpose of this example is not to show how exciting flaring is, but it demonstrates how a Linear Transition FSM can be build.
|
||||
@@ -1260,7 +1260,7 @@ do -- FSM_PROCESS
|
||||
|
||||
--- Assign the process to a @{Wrapper.Unit} and activate the process.
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @param Task.Tasking#TASK Task
|
||||
-- @param Tasking.Task#TASK Task
|
||||
-- @param Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @return #FSM_PROCESS self
|
||||
function FSM_PROCESS:Assign( ProcessUnit, Task )
|
||||
|
||||
@@ -513,7 +513,7 @@ do -- MENU_COALITION
|
||||
--- @type MENU_COALITION
|
||||
-- @extends Core.Menu#MENU_BASE
|
||||
|
||||
--- Manages the main menus for @{DCS.coalition}s.
|
||||
--- Manages the main menus for DCS.coalition.
|
||||
--
|
||||
-- You can add menus with the @{#MENU_COALITION.New} method, which constructs a MENU_COALITION object and returns you the object reference.
|
||||
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_COALITION.Remove}.
|
||||
|
||||
@@ -73,7 +73,7 @@ MESSAGE.Type = {
|
||||
Detailed = "Detailed Report",
|
||||
}
|
||||
|
||||
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
|
||||
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{#MESSAGE.ToClient} or @{#MESSAGE.ToCoalition} or @{#MESSAGE.ToAll} to send these Messages to the respective recipients.
|
||||
-- @param self
|
||||
-- @param #string MessageText is the text of the Message.
|
||||
-- @param #number MessageDuration is a number in seconds of how long the MESSAGE should be shown on the display panel.
|
||||
@@ -127,7 +127,7 @@ end
|
||||
|
||||
--- Creates a new MESSAGE object of a certain type.
|
||||
-- Note that these MESSAGE objects are not yet displayed on the display panel.
|
||||
-- You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
|
||||
-- You must use the functions @{Core.Message#ToClient} or @{Core.Message#ToCoalition} or @{Core.Message#ToAll} to send these Messages to the respective recipients.
|
||||
-- The message display times are automatically defined based on the timing settings in the @{Core.Settings} menu.
|
||||
-- @param self
|
||||
-- @param #string MessageText is the text of the Message.
|
||||
@@ -343,7 +343,7 @@ end
|
||||
|
||||
--- Sends a MESSAGE to a Coalition.
|
||||
-- @param #MESSAGE self
|
||||
-- @param #DCS.coalition.side CoalitionSide @{#DCS.coalition.side} to which the message is displayed.
|
||||
-- @param DCS#coalition.side CoalitionSide @{#DCS.coalition.side} to which the message is displayed.
|
||||
-- @param Core.Settings#SETTINGS Settings (Optional) Settings for message display.
|
||||
-- @return #MESSAGE Message object.
|
||||
-- @usage
|
||||
@@ -379,7 +379,7 @@ end
|
||||
|
||||
--- Sends a MESSAGE to a Coalition if the given Condition is true.
|
||||
-- @param #MESSAGE self
|
||||
-- @param CoalitionSide needs to be filled out by the defined structure of the standard scripting engine @{coalition.side}.
|
||||
-- @param CoalitionSide needs to be filled out by the defined structure of the standard scripting engine @{#DCS.coalition.side}.
|
||||
-- @param #boolean Condition Sends the message only if the condition is true.
|
||||
-- @return #MESSAGE self
|
||||
function MESSAGE:ToCoalitionIf( CoalitionSide, Condition )
|
||||
@@ -480,21 +480,24 @@ _MESSAGESRS = {}
|
||||
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS()
|
||||
--
|
||||
function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,Gender,Culture,Voice,Coalition,Volume,Label,Coordinate)
|
||||
local path = PathToSRS or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
|
||||
_MESSAGESRS.MSRS = MSRS:New(path,Frequency,Modulation,Volume)
|
||||
_MESSAGESRS.MSRS = MSRS:New(PathToSRS,Frequency,Modulation,Volume)
|
||||
_MESSAGESRS.MSRS:SetCoalition(Coalition)
|
||||
_MESSAGESRS.MSRS:SetCoordinate(Coordinate)
|
||||
_MESSAGESRS.MSRS:SetCulture(Culture)
|
||||
_MESSAGESRS.MSRS:SetFrequencies(Frequency)
|
||||
_MESSAGESRS.Culture = Culture
|
||||
--_MESSAGESRS.MSRS:SetFrequencies(Frequency)
|
||||
_MESSAGESRS.MSRS:SetGender(Gender)
|
||||
_MESSAGESRS.Gender = Gender
|
||||
_MESSAGESRS.MSRS:SetGoogle(PathToCredentials)
|
||||
_MESSAGESRS.MSRS:SetLabel(Label or "MESSAGE")
|
||||
_MESSAGESRS.MSRS:SetModulations(Modulation)
|
||||
_MESSAGESRS.MSRS:SetPath(PathToSRS)
|
||||
--_MESSAGESRS.MSRS:SetModulations(Modulation)
|
||||
--_MESSAGESRS.MSRS:SetPath(PathToSRS)
|
||||
_MESSAGESRS.MSRS:SetPort(Port)
|
||||
_MESSAGESRS.MSRS:SetVolume(Volume)
|
||||
-- _MESSAGESRS.MSRS:SetVolume(Volume)
|
||||
_MESSAGESRS.MSRS:SetVoice(Voice)
|
||||
_MESSAGESRS.Voice = Voice
|
||||
_MESSAGESRS.SRSQ = MSRSQUEUE:New(Label or "MESSAGE")
|
||||
env.info(_MESSAGESRS.MSRS.provider,false)
|
||||
end
|
||||
|
||||
--- Sends a message via SRS.
|
||||
@@ -517,26 +520,8 @@ end
|
||||
--
|
||||
function MESSAGE:ToSRS(frequency,modulation,gender,culture,voice,coalition,volume,coordinate)
|
||||
if _MESSAGESRS.SRSQ then
|
||||
_MESSAGESRS.MSRS:SetLabel(self.MessageCategory or _MESSAGESRS.MSRS.Label or "MESSAGE")
|
||||
if gender then
|
||||
_MESSAGESRS.MSRS:SetGender(gender)
|
||||
end
|
||||
if coalition then
|
||||
_MESSAGESRS.MSRS:SetCoalition(coalition)
|
||||
end
|
||||
if culture then
|
||||
_MESSAGESRS.MSRS:SetCulture(culture)
|
||||
end
|
||||
if volume then
|
||||
_MESSAGESRS.MSRS:SetVolume(volume)
|
||||
end
|
||||
if coordinate then
|
||||
_MESSAGESRS.MSRS:SetCoordinate(coordinate)
|
||||
end
|
||||
if voice then
|
||||
_MESSAGESRS.MSRS:SetVoice(voice)
|
||||
end
|
||||
_MESSAGESRS.SRSQ:NewTransmission(self.MessageText,nil,_MESSAGESRS.MSRS,nil,1,nil,nil,nil,frequency,modulation)
|
||||
_MESSAGESRS.MSRS:SetVoice(voice or _MESSAGESRS.Voice)
|
||||
_MESSAGESRS.SRSQ:NewTransmission(self.MessageText,nil,_MESSAGESRS.MSRS,nil,nil,nil,nil,nil,frequency,modulation,gender or _MESSAGESRS.Gender,culture or _MESSAGESRS.Culture,voice or _MESSAGESRS.Voice,volume,self.MessageCategory)
|
||||
end
|
||||
return self
|
||||
end
|
||||
@@ -606,4 +591,3 @@ function MESSAGE:ToSRSAll(frequency,modulation,gender,culture,voice,volume,coord
|
||||
self:ToSRS(frequency,modulation,gender,culture,voice,coalition.side.NEUTRAL,volume,coordinate)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **funkyfranky**
|
||||
--
|
||||
--
|
||||
-- ===
|
||||
-- @module Core.Pathline
|
||||
-- @image CORE_Pathline.png
|
||||
@@ -31,30 +31,30 @@
|
||||
-- ===
|
||||
--
|
||||
-- # 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
|
||||
-- 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.
|
||||
-- They can be accessed with the @{#PATHLINE.FindByName) function.
|
||||
--
|
||||
--
|
||||
-- # 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}
|
||||
--
|
||||
--
|
||||
-- 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
|
||||
--
|
||||
--
|
||||
-- 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
|
||||
-- you specify in the draw panel.
|
||||
--
|
||||
--
|
||||
-- # 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.
|
||||
--
|
||||
--
|
||||
-- To remove the marks, use @{#PATHLINE.MarkPoints}(`false`).
|
||||
--
|
||||
-- @field #PATHLINE
|
||||
@@ -108,7 +108,7 @@ function PATHLINE:New(Name)
|
||||
|
||||
-- Inherit everything from INTEL class.
|
||||
local self=BASE:Inherit(self, BASE:New()) --#PATHLINE
|
||||
|
||||
|
||||
self.name=Name or "Unknown Path"
|
||||
|
||||
self.lid=string.format("PATHLINE %s | ", self.name)
|
||||
@@ -172,7 +172,7 @@ end
|
||||
function PATHLINE:AddPointFromVec2(Vec2, Index, Point)
|
||||
|
||||
if Vec2 then
|
||||
|
||||
|
||||
-- Create a new point.
|
||||
local point=self:_CreatePoint(Vec2)
|
||||
|
||||
@@ -189,9 +189,9 @@ function PATHLINE:AddPointFromVec2(Vec2, Index, Point)
|
||||
-- Add add the end.
|
||||
table.insert(self.points, point)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -204,7 +204,7 @@ end
|
||||
function PATHLINE:AddPointFromVec3(Vec3, Index, Point)
|
||||
|
||||
if Vec3 then
|
||||
|
||||
|
||||
local point=self:_CreatePoint(Vec3)
|
||||
|
||||
if Index then
|
||||
@@ -219,17 +219,17 @@ function PATHLINE:AddPointFromVec3(Vec3, Index, Point)
|
||||
table.insert(self.points, point)
|
||||
end
|
||||
end
|
||||
|
||||
return point
|
||||
|
||||
return point
|
||||
end
|
||||
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get name of pathline.
|
||||
-- @param #PATHLINE self
|
||||
-- @return #string Name of the pathline.
|
||||
function PATHLINE:GetName()
|
||||
function PATHLINE:GetName()
|
||||
return self.name
|
||||
end
|
||||
|
||||
@@ -244,7 +244,7 @@ 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.
|
||||
-- @param #PATHLINE self
|
||||
-- @return #list <Core.Pathline#PATHLINE.Point> List of points.
|
||||
function PATHLINE:GetPoints()
|
||||
function PATHLINE:GetPoints()
|
||||
return self.points
|
||||
end
|
||||
|
||||
@@ -261,7 +261,7 @@ function PATHLINE:GetSetments()
|
||||
segment.p2=self.points[i+1]
|
||||
table.insert(segments, segment)
|
||||
end
|
||||
|
||||
|
||||
return segments
|
||||
end
|
||||
|
||||
@@ -271,7 +271,7 @@ end
|
||||
function PATHLINE:GetPoints3D()
|
||||
|
||||
local vecs={}
|
||||
|
||||
|
||||
for _,_point in pairs(self.points) do
|
||||
local point=_point --#PATHLINE.Point
|
||||
table.insert(vecs, point.vec3)
|
||||
@@ -286,7 +286,7 @@ end
|
||||
function PATHLINE:GetPoints2D()
|
||||
|
||||
local vecs={}
|
||||
|
||||
|
||||
for _,_point in pairs(self.points) do
|
||||
local point=_point --#PATHLINE.Point
|
||||
table.insert(vecs, point.vec2)
|
||||
@@ -301,7 +301,7 @@ end
|
||||
function PATHLINE:GetCoordinats()
|
||||
|
||||
local vecs={}
|
||||
|
||||
|
||||
for _,_point in pairs(self.points) do
|
||||
local point=_point --#PATHLINE.Point
|
||||
local coord=COORDINATE:NewFromVec3(point.vec3)
|
||||
@@ -318,11 +318,11 @@ end
|
||||
function PATHLINE:GetPointFromIndex(n)
|
||||
|
||||
local N=self:GetNumberOfPoints()
|
||||
|
||||
|
||||
n=n or 1
|
||||
|
||||
local point=nil --#PATHLINE.Point
|
||||
|
||||
|
||||
if n>=1 and n<=N then
|
||||
point=self.point[n]
|
||||
else
|
||||
@@ -339,11 +339,11 @@ end
|
||||
function PATHLINE:GetPoint3DFromIndex(n)
|
||||
|
||||
local point=self:GetPointFromIndex(n)
|
||||
|
||||
|
||||
if point then
|
||||
return point.vec3
|
||||
end
|
||||
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -354,11 +354,11 @@ end
|
||||
function PATHLINE:GetPoint2DFromIndex(n)
|
||||
|
||||
local point=self:GetPointFromIndex(n)
|
||||
|
||||
|
||||
if point then
|
||||
return point.vec2
|
||||
end
|
||||
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -371,28 +371,28 @@ function PATHLINE:MarkPoints(Switch)
|
||||
|
||||
for i,_point in pairs(self.points) do
|
||||
local point=_point --#PATHLINE.Point
|
||||
|
||||
|
||||
if Switch==false then
|
||||
|
||||
|
||||
if point.markerID then
|
||||
UTILS.RemoveMark(point.markerID)
|
||||
end
|
||||
|
||||
|
||||
else
|
||||
|
||||
|
||||
if point.markerID then
|
||||
UTILS.RemoveMark(point.markerID)
|
||||
end
|
||||
|
||||
|
||||
point.markerID=UTILS.GetMarkID()
|
||||
|
||||
|
||||
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, "")
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -414,32 +414,32 @@ function PATHLINE:Draw(Switch, Coalition, Color, LineType)
|
||||
|
||||
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
|
||||
|
||||
@@ -451,31 +451,31 @@ end
|
||||
-- @return #PATHLINE.Segment Closest segment of ref point.
|
||||
function PATHLINE:GetClosestPoint2D(Vec2)
|
||||
|
||||
local P=nil --DCS#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 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
|
||||
@@ -484,21 +484,21 @@ function PATHLINE:GetClosestPoint2D(Vec2)
|
||||
p=b
|
||||
else
|
||||
local r=UTILS.Vec2Mult(ab, f)
|
||||
p=UTILS.Vec2Add(a, r)
|
||||
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
|
||||
|
||||
@@ -514,32 +514,32 @@ 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 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
|
||||
@@ -548,21 +548,21 @@ function PATHLINE:GetClosestPoint3D(Vec3)
|
||||
p=b
|
||||
else
|
||||
local r=UTILS.VecMult(ab, f)
|
||||
p=UTILS.VecAdd(a, r)
|
||||
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
|
||||
|
||||
@@ -578,26 +578,26 @@ function PATHLINE:WriteJSON(FileName)
|
||||
|
||||
-- JSON script.
|
||||
local json=loadfile("Scripts\\JSON.lua")()
|
||||
|
||||
|
||||
local data={}
|
||||
|
||||
|
||||
-- We store the name and the points.
|
||||
data.name=self.name
|
||||
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
|
||||
@@ -607,10 +607,10 @@ function PATHLINE:WriteJSON(FileName)
|
||||
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
|
||||
|
||||
end
|
||||
|
||||
@@ -625,12 +625,12 @@ function PATHLINE:NewFromJSON(FileName)
|
||||
|
||||
-- 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.
|
||||
@@ -642,36 +642,36 @@ function PATHLINE:NewFromJSON(FileName)
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -685,12 +685,12 @@ end
|
||||
function PATHLINE:_CreatePoint(Vec)
|
||||
|
||||
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
|
||||
@@ -698,17 +698,17 @@ function PATHLINE:_CreatePoint(Vec)
|
||||
point.vec3=UTILS.DeepCopy(Vec)
|
||||
point.vec2={x=Vec.x, y=Vec.z}
|
||||
else
|
||||
-- Given vec is 2D
|
||||
-- Given vec is 2D
|
||||
point.vec2=UTILS.DeepCopy(Vec)
|
||||
point.vec3={x=Vec.x, y=land.getHeight(Vec), z=Vec.y}
|
||||
end
|
||||
|
||||
-- Get surface type.
|
||||
point.surfaceType=land.getSurfaceType(point.vec2)
|
||||
|
||||
|
||||
-- Get land height and depth.
|
||||
point.landHeight, point.depth=land.getSurfaceHeightWithSeabed(point.vec2)
|
||||
|
||||
|
||||
point.markerID=nil
|
||||
|
||||
return point
|
||||
@@ -722,11 +722,11 @@ 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
|
||||
@@ -734,4 +734,4 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
--
|
||||
-- A SCHEDULER can manage **multiple** (repeating) schedules. Each planned or executing schedule has a unique **ScheduleID**.
|
||||
-- The ScheduleID is returned when the method @{#SCHEDULER.Schedule}() is called.
|
||||
-- It is recommended to store the ScheduleID in a variable, as it is used in the methods @{SCHEDULER.Start}() and @{SCHEDULER.Stop}(),
|
||||
-- It is recommended to store the ScheduleID in a variable, as it is used in the methods @{#SCHEDULER.Start}() and @{#SCHEDULER.Stop}(),
|
||||
-- which can start and stop specific repeating schedules respectively within a SCHEDULER object.
|
||||
--
|
||||
-- ## SCHEDULER constructor
|
||||
|
||||
@@ -5471,7 +5471,7 @@ do -- SET_CARGO
|
||||
|
||||
--- (R2.1) Remove CARGOs from SET_CARGO.
|
||||
-- @param Core.Set#SET_CARGO self
|
||||
-- @param Wrapper.Cargo#CARGO RemoveCargoNames A single name or an array of CARGO names.
|
||||
-- @param Cargo.Cargo#CARGO RemoveCargoNames A single name or an array of CARGO names.
|
||||
-- @return Core.Set#SET_CARGO self
|
||||
function SET_CARGO:RemoveCargosByName( RemoveCargoNames ) -- R2.1
|
||||
|
||||
@@ -5487,7 +5487,7 @@ do -- SET_CARGO
|
||||
--- (R2.1) Finds a Cargo based on the Cargo Name.
|
||||
-- @param #SET_CARGO self
|
||||
-- @param #string CargoName
|
||||
-- @return Wrapper.Cargo#CARGO The found Cargo.
|
||||
-- @return Cargo.Cargo#CARGO The found Cargo.
|
||||
function SET_CARGO:FindCargo( CargoName ) -- R2.1
|
||||
|
||||
local CargoFound = self.Set[CargoName]
|
||||
@@ -5630,7 +5630,7 @@ do -- SET_CARGO
|
||||
--- (R2.1) Iterate the SET_CARGO while identifying the nearest @{Cargo.Cargo#CARGO} from a @{Core.Point#POINT_VEC2}.
|
||||
-- @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}.
|
||||
-- @return Wrapper.Cargo#CARGO The closest @{Cargo.Cargo#CARGO}.
|
||||
-- @return Cargo.Cargo#CARGO The closest @{Cargo.Cargo#CARGO}.
|
||||
function SET_CARGO:FindNearestCargoFromPointVec2( PointVec2 ) -- R2.1
|
||||
self:F2( PointVec2 )
|
||||
|
||||
@@ -5842,6 +5842,7 @@ do -- SET_ZONE
|
||||
},
|
||||
FilterMeta = {
|
||||
},
|
||||
Checktime = 5,
|
||||
}
|
||||
|
||||
--- Creates a new SET_ZONE object, building a set of zones.
|
||||
@@ -6182,7 +6183,170 @@ do -- SET_ZONE
|
||||
|
||||
return zmin, dmin
|
||||
end
|
||||
|
||||
|
||||
--- Set the check time for SET_ZONE:Trigger()
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #number seconds Check every seconds for objects entering or leaving the zone. Defaults to 5 secs.
|
||||
-- @return #SET_ZONE self
|
||||
function SET_ZONE:SetCheckTime(seconds)
|
||||
self.Checktime = seconds or 5
|
||||
return self
|
||||
end
|
||||
|
||||
--- Start watching if the Object or Objects move into or out of our set of zones.
|
||||
-- @param #SET_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Objects Object or Objects to watch, can be of type UNIT, GROUP, CLIENT, or SET\_UNIT, SET\_GROUP, SET\_CLIENT
|
||||
-- @return #SET_ZONE self
|
||||
-- @usage
|
||||
-- -- Create a SET_GROUP and a SET_ZONE for this:
|
||||
--
|
||||
-- local groupset = SET_GROUP:New():FilterPrefixes("Aerial"):FilterStart()
|
||||
--
|
||||
-- -- Trigger will check each zone of the SET_ZONE every 5 secs for objects entering or leaving from the groupset
|
||||
-- local zoneset = SET_ZONE:New():FilterPrefixes("Target Zone"):FilterOnce():Trigger(groupset)
|
||||
--
|
||||
-- -- Draw zones on map so we see what's going on
|
||||
-- zoneset:ForEachZone(
|
||||
-- function(zone)
|
||||
-- zone:DrawZone(-1, {0,1,0}, Alpha, FillColor, FillAlpha, 4, ReadOnly)
|
||||
-- end
|
||||
-- )
|
||||
--
|
||||
-- -- This FSM function will be called for entering objects
|
||||
-- function zoneset:OnAfterEnteredZone(From,Event,To,Controllable,Zone)
|
||||
-- MESSAGE:New("Group "..Controllable:GetName() .. " entered zone "..Zone:GetName(),10,"Set Trigger"):ToAll()
|
||||
-- end
|
||||
--
|
||||
-- -- This FSM function will be called for leaving objects
|
||||
-- function zoneset:OnAfterLeftZone(From,Event,To,Controllable,Zone)
|
||||
-- MESSAGE:New("Group "..Controllable:GetName() .. " left zone "..Zone:GetName(),10,"Set Trigger"):ToAll()
|
||||
-- end
|
||||
--
|
||||
-- -- Stop watching after 1 hour
|
||||
-- zoneset:__TriggerStop(3600)
|
||||
function SET_ZONE:Trigger(Objects)
|
||||
--self:I("Added Set_Zone Trigger")
|
||||
self:AddTransition("*","TriggerStart","TriggerRunning")
|
||||
self:AddTransition("*","EnteredZone","*")
|
||||
self:AddTransition("*","LeftZone","*")
|
||||
self:AddTransition("*","TriggerRunCheck","*")
|
||||
self:AddTransition("*","TriggerStop","TriggerStopped")
|
||||
self:TriggerStart()
|
||||
self.checkobjects = Objects
|
||||
if UTILS.IsInstanceOf(Objects,"SET_BASE") then
|
||||
self.objectset = Objects.Set
|
||||
else
|
||||
self.objectset = {Objects}
|
||||
end
|
||||
self:_TriggerCheck(true)
|
||||
self:__TriggerRunCheck(self.Checktime)
|
||||
return self
|
||||
|
||||
------------------------
|
||||
--- Pseudo Functions ---
|
||||
------------------------
|
||||
|
||||
--- Triggers the FSM event "TriggerStop". Stops the SET_ZONE Trigger.
|
||||
-- @function [parent=#SET_ZONE] TriggerStop
|
||||
-- @param #SET_ZONE self
|
||||
|
||||
--- Triggers the FSM event "TriggerStop" after a delay.
|
||||
-- @function [parent=#SET_ZONE] __TriggerStop
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
--- On After "EnteredZone" event. An observed object has entered the zone.
|
||||
-- @function [parent=#SET_ZONE] OnAfterEnteredZone
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The controllable entering the zone.
|
||||
-- @param Core.Zone#ZONE_BASE Zone The zone entered.
|
||||
|
||||
--- On After "LeftZone" event. An observed object has left the zone.
|
||||
-- @function [parent=#SET_ZONE] OnAfterLeftZone
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The controllable leaving the zone.
|
||||
-- @param Core.Zone#ZONE_BASE Zone The zone left.
|
||||
end
|
||||
|
||||
--- (Internal) Check the assigned objects for being in/out of the zone
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #boolean fromstart If true, do the init of the objects
|
||||
-- @return #SET_ZONE self
|
||||
function SET_ZONE:_TriggerCheck(fromstart)
|
||||
--self:I("_TriggerCheck | FromStart = "..tostring(fromstart))
|
||||
if fromstart then
|
||||
for _,_object in pairs(self.objectset) do
|
||||
local obj = _object -- Wrapper.Controllable#CONTROLLABLE
|
||||
if obj and obj:IsAlive() then
|
||||
for _,_zone in pairs(self.Set) do
|
||||
if not obj.TriggerInZone then obj.TriggerInZone = {} end
|
||||
if _zone:IsCoordinateInZone(obj:GetCoordinate()) then
|
||||
obj.TriggerInZone[_zone.ZoneName] = true
|
||||
else
|
||||
obj.TriggerInZone[_zone.ZoneName] = false
|
||||
end
|
||||
--self:I("Object "..obj:GetName().." is in zone = "..tostring(obj.TriggerInZone[_zone.ZoneName]))
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for _,_object in pairs(self.objectset) do
|
||||
local obj = _object -- Wrapper.Controllable#CONTROLLABLE
|
||||
if obj and obj:IsAlive() then
|
||||
for _,_zone in pairs(self.Set) do
|
||||
-- Check for pop-up objects
|
||||
if not obj.TriggerInZone then
|
||||
-- has not been tagged previously - wasn't in set!
|
||||
obj.TriggerInZone = {}
|
||||
end
|
||||
if not obj.TriggerInZone[_zone.ZoneName] then
|
||||
-- has not been tagged previously - wasn't in set!
|
||||
obj.TriggerInZone[_zone.ZoneName] = false
|
||||
end
|
||||
-- is obj in zone?
|
||||
local inzone = _zone:IsCoordinateInZone(obj:GetCoordinate())
|
||||
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
|
||||
if inzone and not obj.TriggerInZone[_zone.ZoneName] then
|
||||
-- wasn't in zone before
|
||||
--self:I("Newly entered")
|
||||
self:__EnteredZone(0.5,obj,_zone)
|
||||
obj.TriggerInZone[_zone.ZoneName] = true
|
||||
elseif (not inzone) and obj.TriggerInZone[_zone.ZoneName] then
|
||||
-- has left the zone
|
||||
--self:I("Newly left")
|
||||
self:__LeftZone(0.5,obj,_zone)
|
||||
obj.TriggerInZone[_zone.ZoneName] = false
|
||||
else
|
||||
--self:I("Not left or not entered, or something went wrong!")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- (Internal) Check the assigned objects for being in/out of the zone
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string to
|
||||
-- @return #SET_ZONE self
|
||||
function SET_ZONE:onafterTriggerRunCheck(From,Event,To)
|
||||
--self:I("onafterTriggerRunCheck")
|
||||
--self:I({From, Event, To})
|
||||
if self:GetState() ~= "TriggerStopped" then
|
||||
self:_TriggerCheck()
|
||||
self:__TriggerRunCheck(self.Checktime)
|
||||
end
|
||||
return self
|
||||
end
|
||||
end
|
||||
|
||||
do -- SET_ZONE_GOAL
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
--
|
||||
-- Will customize which display format is used to indicate A2G coordinates in text as part of the Command Center communications.
|
||||
--
|
||||
-- - A2G BR: [Bearing Range](https://en.wikipedia.org/wiki/Bearing_(navigation)).
|
||||
-- - A2G BR: [Bearing Range](https://en.wikipedia.org/wiki/Bearing_\(navigation\)).
|
||||
-- - A2G MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted.
|
||||
-- - A2G LL DMS: Latitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted.
|
||||
-- - A2G LL DDM: Latitude Longitude [Decimal Degrees Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted.
|
||||
@@ -105,9 +105,9 @@
|
||||
-- There are different methods that can be used to change the **System settings** using the \_SETTINGS object.
|
||||
--
|
||||
-- - @{#SETTINGS.SetA2G_BR}(): Enable the BR display formatting by default.
|
||||
-- - @{#SETTINGS.SetA2G_MGRS}(): Enable the MGRS display formatting by default. Use @{SETTINGS.SetMGRS_Accuracy}() to adapt the accuracy of the MGRS formatting.
|
||||
-- - @{#SETTINGS.SetA2G_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2G_LL_DDM}(): Enable the LL DDM display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2G_MGRS}(): Enable the MGRS display formatting by default. Use @{#SETTINGS.SetMGRS_Accuracy}() to adapt the accuracy of the MGRS formatting.
|
||||
-- - @{#SETTINGS.SetA2G_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{#SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2G_LL_DDM}(): Enable the LL DDM display formatting by default. Use @{#SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
--
|
||||
-- ### 3.1.4) A2G coordinates setting - additional notes
|
||||
--
|
||||
@@ -120,7 +120,7 @@
|
||||
--
|
||||
-- Will customize which display format is used to indicate A2A coordinates in text as part of the Command Center communications.
|
||||
--
|
||||
-- - A2A BRAA: [Bearing Range Altitude Aspect](https://en.wikipedia.org/wiki/Bearing_(navigation)).
|
||||
-- - A2A BRAA: [Bearing Range Altitude Aspect](https://en.wikipedia.org/wiki/Bearing_\(navigation\)).
|
||||
-- - A2A MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted.
|
||||
-- - A2A LL DMS: Lattitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted.
|
||||
-- - A2A LL DDM: Lattitude Longitude [Decimal Degrees and Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted.
|
||||
@@ -135,9 +135,9 @@
|
||||
-- There are different methods that can be used to change the **System settings** using the \_SETTINGS object.
|
||||
--
|
||||
-- - @{#SETTINGS.SetA2A_BRAA}(): Enable the BR display formatting by default.
|
||||
-- - @{#SETTINGS.SetA2A_MGRS}(): Enable the MGRS display formatting by default. Use @{SETTINGS.SetMGRS_Accuracy}() to adapt the accuracy of the MGRS formatting.
|
||||
-- - @{#SETTINGS.SetA2A_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2A_LL_DDM}(): Enable the LL DDM display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2A_MGRS}(): Enable the MGRS display formatting by default. Use @{#SETTINGS.SetMGRS_Accuracy}() to adapt the accuracy of the MGRS formatting.
|
||||
-- - @{#SETTINGS.SetA2A_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{#SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2A_LL_DDM}(): Enable the LL DDM display formatting by default. Use @{#SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||
-- - @{#SETTINGS.SetA2A_BULLS}(): Enable the BULLSeye display formatting by default.
|
||||
--
|
||||
-- ### 3.2.4) A2A coordinates settings - additional notes
|
||||
@@ -190,8 +190,8 @@
|
||||
--
|
||||
-- There are different methods that can be used to change the **System settings** using the \_SETTINGS object.
|
||||
--
|
||||
-- - @{#SETTINGS.SetMessageTime}(): Define for a specific @{Message.MESSAGE.MessageType} the duration to be displayed in seconds.
|
||||
-- - @{#SETTINGS.GetMessageTime}(): Retrieves for a specific @{Message.MESSAGE.MessageType} the duration to be displayed in seconds.
|
||||
-- - @{#SETTINGS.SetMessageTime}(): Define for a specific @{Core.Message#MESSAGE.MessageType} the duration to be displayed in seconds.
|
||||
-- - @{#SETTINGS.GetMessageTime}(): Retrieves for a specific @{Core.Message#MESSAGE.MessageType} the duration to be displayed in seconds.
|
||||
--
|
||||
-- ## 3.5) **Era** of the battle
|
||||
--
|
||||
@@ -283,21 +283,21 @@ do -- SETTINGS
|
||||
function SETTINGS:SetMetric()
|
||||
self.Metric = true
|
||||
end
|
||||
|
||||
|
||||
--- Sets the SETTINGS default text locale.
|
||||
-- @param #SETTINGS self
|
||||
-- @param #string Locale
|
||||
function SETTINGS:SetLocale(Locale)
|
||||
self.Locale = Locale or "en"
|
||||
end
|
||||
|
||||
|
||||
--- Gets the SETTINGS text locale.
|
||||
-- @param #SETTINGS self
|
||||
-- @return #string
|
||||
function SETTINGS:GetLocale()
|
||||
return self.Locale or _SETTINGS:GetLocale()
|
||||
end
|
||||
|
||||
|
||||
--- Gets if the SETTINGS is metric.
|
||||
-- @param #SETTINGS self
|
||||
-- @return #boolean true if metric.
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
-- @field #SPAWN.SpawnZoneTable SpawnZoneTable
|
||||
-- @extends Core.Base#BASE
|
||||
|
||||
--- Allows to spawn dynamically new @{Core.Group}s.
|
||||
--- Allows to spawn dynamically new @{Wrapper.Group}s.
|
||||
--
|
||||
-- Each SPAWN object needs to be have related **template groups** setup in the Mission Editor (ME),
|
||||
-- which is a normal group with the **Late Activation** flag set.
|
||||
@@ -1331,7 +1331,7 @@ do -- Delay methods
|
||||
return self
|
||||
end
|
||||
|
||||
--- Turns the Delay On for the @{Wrapper.Group} when spawning with @{SpawnScheduled}(). In effect then the 1st group will only be spawned
|
||||
--- Turns the Delay On for the @{Wrapper.Group} when spawning with @{#SpawnScheduled}(). In effect then the 1st group will only be spawned
|
||||
-- after the number of seconds given in SpawnScheduled as arguments, and not immediately.
|
||||
-- @param #SPAWN self
|
||||
-- @return #SPAWN The SPAWN object
|
||||
@@ -1669,7 +1669,7 @@ end
|
||||
-- @param #number SpawnTimeVariation The variation to be applied on the defined time interval between each new spawn.
|
||||
-- The variation is a number between 0 and 1, representing the % of variation to be applied on the time interval.
|
||||
-- @param #boolean WithDelay Do not spawn the **first** group immediately, but delay the spawn as per the calculation below.
|
||||
-- Effectively the same as @{InitDelayOn}().
|
||||
-- Effectively the same as @{#InitDelayOn}().
|
||||
-- @return #SPAWN self
|
||||
-- @usage
|
||||
-- -- NATO helicopters engaging in the battle field.
|
||||
@@ -3622,7 +3622,7 @@ function SPAWN:_OnLand( EventData )
|
||||
end
|
||||
|
||||
--- Will detect AIR Units shutting down their engines ...
|
||||
-- When the event takes place, and the method @{RepeatOnEngineShutDown} was called, the spawned Group will Re-SPAWN.
|
||||
-- When the event takes place, and the method @{#InitRepeatOnEngineShutDown} was called, the spawned Group will Re-SPAWN.
|
||||
-- But only when the Unit was registered to have landed.
|
||||
-- @param #SPAWN self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
-- ### Author: **FlightControl**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * [**Ciribob**](https://forums.eagle.ru/member.php?u=112175): Showing the way how to lase targets + how laser codes work!!! Explained the autolase script.
|
||||
-- * [**EasyEB**](https://forums.eagle.ru/member.php?u=112055): Ideas and Beta Testing
|
||||
-- * [**Wingthor**](https://forums.eagle.ru/member.php?u=123698): Beta Testing
|
||||
-- * **Ciribob**: Showing the way how to lase targets + how laser codes work!!! Explained the autolase script.
|
||||
-- * **EasyEB**: Ideas and Beta Testing
|
||||
-- * **Wingthor**: Beta Testing
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
-- @field #number ZoneID ID of zone. Only zones defined in the ME have an ID!
|
||||
-- @field #table Table of any trigger zone properties from the ME. The key is the Name of the property, and the value is the property's Value.
|
||||
-- @field #number Surface Type of surface. Only determined at the center of the zone!
|
||||
-- @field #number Checktime Check every Checktime seconds, used for ZONE:Trigger()
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
|
||||
@@ -122,6 +123,7 @@ ZONE_BASE = {
|
||||
ZoneID=nil,
|
||||
Properties={},
|
||||
Surface=nil,
|
||||
Checktime = 5,
|
||||
}
|
||||
|
||||
--- The ZONE_BASE.BoundingSquare
|
||||
@@ -571,6 +573,154 @@ function ZONE_BASE:GetZoneMaybe()
|
||||
end
|
||||
end
|
||||
|
||||
--- Set the check time for ZONE:Trigger()
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #number seconds Check every seconds for objects entering or leaving the zone. Defaults to 5 secs.
|
||||
-- @return #ZONE_BASE self
|
||||
function ZONE_BASE:SetCheckTime(seconds)
|
||||
self.Checktime = seconds or 5
|
||||
return self
|
||||
end
|
||||
|
||||
--- Start watching if the Object or Objects move into or out of a zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Objects Object or Objects to watch, can be of type UNIT, GROUP, CLIENT, or SET\_UNIT, SET\_GROUP, SET\_CLIENT
|
||||
-- @return #ZONE_BASE self
|
||||
-- @usage
|
||||
-- -- Create a new zone and start watching it every 5 secs for a defined GROUP entering or leaving
|
||||
-- local triggerzone = ZONE:New("ZonetoWatch"):Trigger(GROUP:FindByName("Aerial-1"))
|
||||
--
|
||||
-- -- This FSM function will be called when the group enters the zone
|
||||
-- function triggerzone:OnAfterEnteredZone(From,Event,To,Group)
|
||||
-- MESSAGE:New("Group has entered zone!",15):ToAll()
|
||||
-- end
|
||||
--
|
||||
-- -- This FSM function will be called when the group leaves the zone
|
||||
-- function triggerzone:OnAfterLeftZone(From,Event,To,Group)
|
||||
-- MESSAGE:New("Group has left zone!",15):ToAll()
|
||||
-- end
|
||||
--
|
||||
-- -- Stop watching the zone after 1 hour
|
||||
-- triggerzone:__TriggerStop(3600)
|
||||
function ZONE_BASE:Trigger(Objects)
|
||||
--self:I("Added Zone Trigger")
|
||||
self:SetStartState("TriggerStopped")
|
||||
self:AddTransition("TriggerStopped","TriggerStart","TriggerRunning")
|
||||
self:AddTransition("*","EnteredZone","*")
|
||||
self:AddTransition("*","LeftZone","*")
|
||||
self:AddTransition("*","TriggerRunCheck","*")
|
||||
self:AddTransition("*","TriggerStop","TriggerStopped")
|
||||
self:TriggerStart()
|
||||
self.checkobjects = Objects
|
||||
if UTILS.IsInstanceOf(Objects,"SET_BASE") then
|
||||
self.objectset = Objects.Set
|
||||
else
|
||||
self.objectset = {Objects}
|
||||
end
|
||||
self:_TriggerCheck(true)
|
||||
self:__TriggerRunCheck(self.Checktime)
|
||||
return self
|
||||
|
||||
------------------------
|
||||
--- Pseudo Functions ---
|
||||
------------------------
|
||||
|
||||
--- Triggers the FSM event "TriggerStop". Stops the ZONE_BASE Trigger.
|
||||
-- @function [parent=#ZONE_BASE] TriggerStop
|
||||
-- @param #ZONE_BASE self
|
||||
|
||||
--- Triggers the FSM event "TriggerStop" after a delay.
|
||||
-- @function [parent=#ZONE_BASE] __TriggerStop
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
--- On After "EnteredZone" event. An observed object has entered the zone.
|
||||
-- @function [parent=#ZONE_BASE] OnAfterEnteredZone
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The controllable entering the zone.
|
||||
|
||||
--- On After "LeftZone" event. An observed object has left the zone.
|
||||
-- @function [parent=#ZONE_BASE] OnAfterLeftZone
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The controllable leaving the zone.
|
||||
end
|
||||
|
||||
--- (Internal) Check the assigned objects for being in/out of the zone
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #boolean fromstart If true, do the init of the objects
|
||||
-- @return #ZONE_BASE self
|
||||
function ZONE_BASE:_TriggerCheck(fromstart)
|
||||
--self:I("_TriggerCheck | FromStart = "..tostring(fromstart))
|
||||
local objectset = self.objectset or {}
|
||||
if fromstart then
|
||||
-- just earmark everyone in/out
|
||||
for _,_object in pairs(objectset) do
|
||||
local obj = _object -- Wrapper.Controllable#CONTROLLABLE
|
||||
if not obj.TriggerInZone then obj.TriggerInZone = {} end
|
||||
if obj and obj:IsAlive() and self:IsCoordinateInZone(obj:GetCoordinate()) then
|
||||
obj.TriggerInZone[self.ZoneName] = true
|
||||
else
|
||||
obj.TriggerInZone[self.ZoneName] = false
|
||||
end
|
||||
--self:I("Object "..obj:GetName().." is in zone = "..tostring(obj.TriggerInZone[self.ZoneName]))
|
||||
end
|
||||
else
|
||||
-- Check for changes
|
||||
for _,_object in pairs(objectset) do
|
||||
local obj = _object -- Wrapper.Controllable#CONTROLLABLE
|
||||
if obj and obj:IsAlive() then
|
||||
if not obj.TriggerInZone then
|
||||
-- has not been tagged previously - wasn't in set!
|
||||
obj.TriggerInZone = {}
|
||||
end
|
||||
if not obj.TriggerInZone[self.ZoneName] then
|
||||
-- has not been tagged previously - wasn't in set!
|
||||
obj.TriggerInZone[self.ZoneName] = false
|
||||
end
|
||||
-- is obj in zone?
|
||||
local inzone = self:IsCoordinateInZone(obj:GetCoordinate())
|
||||
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
|
||||
if inzone and not obj.TriggerInZone[self.ZoneName] then
|
||||
-- wasn't in zone before
|
||||
--self:I("Newly entered")
|
||||
self:__EnteredZone(0.5,obj)
|
||||
obj.TriggerInZone[self.ZoneName] = true
|
||||
elseif (not inzone) and obj.TriggerInZone[self.ZoneName] then
|
||||
-- has left the zone
|
||||
--self:I("Newly left")
|
||||
self:__LeftZone(0.5,obj)
|
||||
obj.TriggerInZone[self.ZoneName] = false
|
||||
else
|
||||
--self:I("Not left or not entered, or something went wrong!")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- (Internal) Check the assigned objects for being in/out of the zone
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string to
|
||||
-- @return #ZONE_BASE self
|
||||
function ZONE_BASE:onafterTriggerRunCheck(From,Event,To)
|
||||
if self:GetState() ~= "TriggerStopped" then
|
||||
self:_TriggerCheck()
|
||||
self:__TriggerRunCheck(self.Checktime)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Returns the Value of the zone with the given PropertyName, or nil if no matching property exists.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #string PropertyName The name of a the TriggerZone Property to be retrieved.
|
||||
@@ -921,11 +1071,11 @@ end
|
||||
--- Scan the zone for the presence of units of the given ObjectCategories.
|
||||
-- Note that **only after** a zone has been scanned, the zone can be evaluated by:
|
||||
--
|
||||
-- * @{ZONE_RADIUS.IsAllInZoneOfCoalition}(): Scan the presence of units in the zone of a coalition.
|
||||
-- * @{ZONE_RADIUS.IsAllInZoneOfOtherCoalition}(): Scan the presence of units in the zone of an other coalition.
|
||||
-- * @{ZONE_RADIUS.IsSomeInZoneOfCoalition}(): Scan if there is some presence of units in the zone of the given coalition.
|
||||
-- * @{ZONE_RADIUS.IsNoneInZoneOfCoalition}(): Scan if there isn't any presence of units in the zone of an other coalition than the given one.
|
||||
-- * @{ZONE_RADIUS.IsNoneInZone}(): Scan if the zone is empty.
|
||||
-- * @{Core.Zone#ZONE_RADIUS.IsAllInZoneOfCoalition}(): Scan the presence of units in the zone of a coalition.
|
||||
-- * @{Core.Zone#ZONE_RADIUS.IsAllInZoneOfOtherCoalition}(): Scan the presence of units in the zone of an other coalition.
|
||||
-- * @{Core.Zone#ZONE_RADIUS.IsSomeInZoneOfCoalition}(): Scan if there is some presence of units in the zone of the given coalition.
|
||||
-- * @{Core.Zone#ZONE_RADIUS.IsNoneInZoneOfCoalition}(): Scan if there isn't any presence of units in the zone of an other coalition than the given one.
|
||||
-- * @{Core.Zone#ZONE_RADIUS.IsNoneInZone}(): Scan if the zone is empty.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param ObjectCategories An array of categories of the objects to find in the zone. E.g. `{Object.Category.UNIT}`
|
||||
-- @param UnitCategories An array of unit categories of the objects to find in the zone. E.g. `{Unit.Category.GROUND_UNIT,Unit.Category.SHIP}`
|
||||
@@ -1651,7 +1801,7 @@ ZONE_UNIT = {
|
||||
-- @param #ZONE_UNIT self
|
||||
-- @param #string ZoneName Name of the zone.
|
||||
-- @param Wrapper.Unit#UNIT ZoneUNIT The unit as the center of the zone.
|
||||
-- @param Dcs.DCSTypes#Distance Radius The radius of the zone.
|
||||
-- @param #number Radius The radius of the zone in meters.
|
||||
-- @param #table Offset A table specifying the offset. The offset table may have the following elements:
|
||||
-- dx The offset in X direction, +x is north.
|
||||
-- dy The offset in Y direction, +y is east.
|
||||
@@ -2613,11 +2763,11 @@ end
|
||||
--- Scan the zone for the presence of units of the given ObjectCategories. Does **not** scan for scenery at the moment.
|
||||
-- Note that **only after** a zone has been scanned, the zone can be evaluated by:
|
||||
--
|
||||
-- * @{ZONE_POLYGON.IsAllInZoneOfCoalition}(): Scan the presence of units in the zone of a coalition.
|
||||
-- * @{ZONE_POLYGON.IsAllInZoneOfOtherCoalition}(): Scan the presence of units in the zone of an other coalition.
|
||||
-- * @{ZONE_POLYGON.IsSomeInZoneOfCoalition}(): Scan if there is some presence of units in the zone of the given coalition.
|
||||
-- * @{ZONE_POLYGON.IsNoneInZoneOfCoalition}(): Scan if there isn't any presence of units in the zone of an other coalition than the given one.
|
||||
-- * @{ZONE_POLYGON.IsNoneInZone}(): Scan if the zone is empty.
|
||||
-- * @{Core.Zone#ZONE_POLYGON.IsAllInZoneOfCoalition}(): Scan the presence of units in the zone of a coalition.
|
||||
-- * @{Core.Zone#ZONE_POLYGON.IsAllInZoneOfOtherCoalition}(): Scan the presence of units in the zone of an other coalition.
|
||||
-- * @{Core.Zone#ZONE_POLYGON.IsSomeInZoneOfCoalition}(): Scan if there is some presence of units in the zone of the given coalition.
|
||||
-- * @{Core.Zone#ZONE_POLYGON.IsNoneInZoneOfCoalition}(): Scan if there isn't any presence of units in the zone of an other coalition than the given one.
|
||||
-- * @{Core.Zone#ZONE_POLYGON.IsNoneInZone}(): Scan if the zone is empty.
|
||||
-- @param #ZONE_POLYGON self
|
||||
-- @param ObjectCategories An array of categories of the objects to find in the zone. E.g. `{Object.Category.UNIT}`
|
||||
-- @param UnitCategories An array of unit categories of the objects to find in the zone. E.g. `{Unit.Category.GROUND_UNIT,Unit.Category.SHIP}`
|
||||
|
||||
Reference in New Issue
Block a user