Merge remote-tracking branch 'refs/remotes/origin/master' into 344-AI-Bomb-Zone

This commit is contained in:
FlightControl 2017-05-09 09:29:43 +02:00
commit f181101d8b
49 changed files with 4259 additions and 1037 deletions

View File

@ -3,6 +3,6 @@
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.ui.externaltools.launchGroup"/>
</listAttribute>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/Moose_Framework/Utils/luadocumentor.bat}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/Moose_Framework/Utils/GenerateDocumentations.bat}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/Moose_Framework/Utils}"/>
</launchConfiguration>

View File

@ -173,8 +173,6 @@ do -- ACT_ASSIGN_ACCEPT
local ProcessGroup = ProcessUnit:GetGroup()
self:Message( "You are assigned to the task " .. self.Task:GetName() )
self.Task:Assign( ProcessUnit, ProcessUnit:GetPlayerName() )
end

View File

@ -239,12 +239,15 @@ function CARGO:New( Type, Name, Weight ) --R2.1
self:SetStartState( "UnLoaded" )
self:AddTransition( { "UnLoaded", "Boarding" }, "Board", "Boarding" )
self:AddTransition( "Boarding" , "Boarding", "Boarding" )
self:AddTransition( "Boarding", "CancelBoarding", "UnLoaded" )
self:AddTransition( "Boarding", "Load", "Loaded" )
self:AddTransition( "UnLoaded", "Load", "Loaded" )
self:AddTransition( "Loaded", "UnBoard", "UnBoarding" )
self:AddTransition( "UnBoarding", "UnBoarding", "UnBoarding" )
self:AddTransition( "UnBoarding", "UnLoad", "UnLoaded" )
self:AddTransition( "Loaded", "UnLoad", "UnLoaded" )
self:AddTransition( "*", "Destroyed", "Destroyed" )
self:AddTransition( "*", "Respawn", "UnLoaded" )
self.Type = Type
@ -262,6 +265,7 @@ function CARGO:New( Type, Name, Weight ) --R2.1
CARGOS[self.Name] = self
self:SetEventPriority( 5 )
return self
end
@ -273,6 +277,17 @@ function CARGO:GetName() --R2.1
return self.Name
end
--- Get the object name of the Cargo.
-- @param #CARGO self
-- @return #string The object name of the Cargo.
function CARGO:GetObjectName() --R2.1
if self:IsLoaded() then
return self.CargoCarrier:GetName()
else
return self.CargoObject:GetName()
end
end
--- Get the type of the Cargo.
-- @param #CARGO self
-- @return #string The type of the Cargo.
@ -280,6 +295,14 @@ function CARGO:GetType()
return self.Type
end
--- Get the current coordinates of the Cargo.
-- @param #CARGO self
-- @return Core.Point#COORDINATE The coordinates of the Cargo.
function CARGO:GetCoordinate()
return self.CargoObject:GetCoordinate()
end
--- Check if cargo is loaded.
-- @param #CARGO self
-- @return #boolean true if loaded
@ -294,6 +317,20 @@ function CARGO:IsUnLoaded()
return self:Is( "UnLoaded" )
end
--- Check if cargo is alive.
-- @param #CARGO self
-- @return #boolean true if unloaded
function CARGO:IsAlive()
if self:IsLoaded() then
return self.CargoCarrier:IsAlive()
else
return self.CargoObject:IsAlive()
end
end
--- Template method to spawn a new representation of the CARGO in the simulator.
-- @param #CARGO self
@ -329,7 +366,7 @@ end
-- @param #number NearRadius The radius when the cargo will board the Carrier (to avoid collision).
-- @return #boolean
function CARGO:IsNear( PointVec2, NearRadius )
self:F( { PointVec2 } )
self:F( { PointVec2, NearRadius } )
local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
self:T( Distance )
@ -520,6 +557,16 @@ function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius )
self:T( self.ClassName )
self:HandleEvent( EVENTS.Dead,
--- @param #CARGO Cargo
-- @param Core.Event#EVENTDATA EventData
function( Cargo, EventData )
if Cargo:GetObjectName() == EventData.IniUnit:GetName() then
self:E( { "Cargo destroyed", Cargo } )
Cargo:Destroyed()
end
end
)
return self
end
@ -542,7 +589,7 @@ end
-- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2
function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
self:F()
self:F( { From, Event, To, ToPointVec2, NearRadius } )
NearRadius = NearRadius or 25
@ -575,7 +622,7 @@ function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius
-- Respawn the group...
if self.CargoObject then
self.CargoObject:ReSpawn( CargoDeployPointVec2:GetVec3(), CargoDeployHeading )
self:E( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } )
self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } )
self.CargoCarrier = nil
local Points = {}
@ -586,7 +633,8 @@ function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius
local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 1 )
self:__UnBoarding( -1, ToPointVec2, NearRadius )
self:__UnBoarding( 1, ToPointVec2, NearRadius )
end
end
@ -599,7 +647,7 @@ end
-- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2
function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius )
self:F( { ToPointVec2, From, Event, To } )
self:F( { From, Event, To, ToPointVec2, NearRadius } )
NearRadius = NearRadius or 25
@ -611,6 +659,7 @@ function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius
if self:IsNear( ToPointVec2, NearRadius ) then
return true
else
self:__UnBoarding( 1, ToPointVec2, NearRadius )
end
return false
@ -625,7 +674,7 @@ end
-- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2
function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
self:F( { ToPointVec2, From, Event, To } )
self:F( { From, Event, To, ToPointVec2, NearRadius } )
NearRadius = NearRadius or 25
@ -639,7 +688,7 @@ function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius
end
self:__UnLoad( 1, ToPointVec2 )
self:__UnLoad( 1, ToPointVec2, NearRadius )
end
@ -687,9 +736,9 @@ end
-- @param #string From
-- @param #string To
function CARGO_UNIT:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... )
self:F()
self:F( { From, Event, To, CargoCarrier, NearRadius } )
NearRadius = NearRadius or 25
local NearRadius = NearRadius or 25
self.CargoInAir = self.CargoObject:InAir()
@ -722,32 +771,13 @@ function CARGO_UNIT:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ...
local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 2 )
self:__Boarding( -1, CargoCarrier, NearRadius )
self.RunCount = 0
end
end
end
--- Leave Boarding State.
-- @param #CARGO_UNIT self
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Wrapper.Unit#UNIT CargoCarrier
function CARGO_UNIT:onleaveBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
NearRadius = NearRadius or 25
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
self:__Load( 1, CargoCarrier, ... )
return true
end
return true
end
--- Boarding Event.
-- @param #CARGO_UNIT self
-- @param #string Event
@ -759,8 +789,45 @@ function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, NearRadius,
self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
self:__Boarding( -1, CargoCarrier, NearRadius, ... )
self:__Board( -15, CargoCarrier, NearRadius, ... )
if CargoCarrier and CargoCarrier:IsAlive() then
if CargoCarrier:InAir() == false then
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
self:__Load( 1, CargoCarrier, ... )
else
self:__Boarding( -1, CargoCarrier, NearRadius, ... )
self.RunCount = self.RunCount + 1
if self.RunCount >= 20 then
self.RunCount = 0
local Speed = 90
local Angle = 180
local Distance = 5
NearRadius = NearRadius or 25
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading )
local Points = {}
local PointStartVec2 = self.CargoObject:GetPointVec2()
Points[#Points+1] = PointStartVec2:RoutePointGround( Speed )
Points[#Points+1] = CargoDeployPointVec2:RoutePointGround( Speed )
local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 0.2 )
end
end
else
self.CargoObject:MessageToGroup( "Cancelling Boarding... Get back on the ground!", 5, CargoCarrier:GetGroup(), self:GetName() )
self:CancelBoarding( CargoCarrier, NearRadius, ... )
self.CargoObject:SetCommand( self.CargoObject:CommandStopRoute( true ) )
end
else
self:E("Something is wrong")
end
end
@ -778,7 +845,7 @@ function CARGO_UNIT:onenterBoarding( From, Event, To, CargoCarrier, NearRadius,
local Angle = 180
local Distance = 5
NearRadius = NearRadius or 25
local NearRadius = NearRadius or 25
if From == "UnLoaded" or From == "Boarding" then
@ -793,7 +860,7 @@ end
-- @param #string To
-- @param Wrapper.Unit#UNIT CargoCarrier
function CARGO_UNIT:onenterLoaded( From, Event, To, CargoCarrier )
self:F()
self:F( { From, Event, To, CargoCarrier } )
self.CargoCarrier = CargoCarrier
@ -808,6 +875,263 @@ end
end
do -- CARGO_GROUP
--- @type CARGO_GROUP
-- @extends #CARGO_REPORTABLE
--- # CARGO\_GROUP class
--
-- The CARGO\_GROUP class defines a cargo that is represented by a @{Group} object within the simulator, and can be transported by a carrier.
-- Use the event functions as described above to Load, UnLoad, Board, UnBoard the CARGO\_GROUP to and from carrier.
--
-- @field #CARGO_GROUP CARGO_GROUP
--
CARGO_GROUP = {
ClassName = "CARGO_GROUP",
}
--- CARGO_GROUP constructor.
-- @param #CARGO_GROUP self
-- @param Wrapper.Group#GROUP CargoGroup
-- @param #string Type
-- @param #string Name
-- @param #number ReportRadius (optional)
-- @param #number NearRadius (optional)
-- @return #CARGO_GROUP
function CARGO_GROUP:New( CargoGroup, Type, Name, ReportRadius )
local self = BASE:Inherit( self, CARGO_REPORTABLE:New( CargoGroup, Type, Name, 0, ReportRadius ) ) -- #CARGO_GROUP
self:F( { Type, Name, ReportRadius } )
self.CargoSet = SET_CARGO:New()
self.CargoObject = CargoGroup
local WeightGroup = 0
for UnitID, UnitData in pairs( CargoGroup:GetUnits() ) do
local Unit = UnitData -- Wrapper.Unit#UNIT
local WeightUnit = Unit:GetDesc().massEmpty
WeightGroup = WeightGroup + WeightUnit
local CargoUnit = CARGO_UNIT:New( Unit, Type, Unit:GetName(), WeightUnit )
self.CargoSet:Add( CargoUnit:GetName(), CargoUnit )
end
self:SetWeight( WeightGroup )
self:T( { "Weight Cargo", WeightGroup } )
-- Cargo objects are added to the _DATABASE and SET_CARGO objects.
_EVENTDISPATCHER:CreateEventNewCargo( self )
return self
end
--- Enter Boarding State.
-- @param #CARGO_GROUP self
-- @param Wrapper.Unit#UNIT CargoCarrier
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onenterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
self:F( { CargoCarrier.UnitName, From, Event, To } )
local NearRadius = NearRadius or 25
if From == "UnLoaded" then
-- For each Cargo object within the CARGO_GROUPED, route each object to the CargoLoadPointVec2
self.CargoSet:ForEach(
function( Cargo, ... )
Cargo:__Board( 1, CargoCarrier, NearRadius, ... )
end, ...
)
self:__Boarding( 1, CargoCarrier, NearRadius, ... )
end
end
--- Enter Loaded State.
-- @param #CARGO_GROUP self
-- @param Wrapper.Unit#UNIT CargoCarrier
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onenterLoaded( From, Event, To, CargoCarrier, ... )
self:F( { From, Event, To, CargoCarrier, ...} )
if From == "UnLoaded" then
-- For each Cargo object within the CARGO_GROUP, load each cargo to the CargoCarrier.
for CargoID, Cargo in pairs( self.CargoSet:GetSet() ) do
Cargo:Load( CargoCarrier )
end
end
self.CargoObject:Destroy()
self.CargoCarrier = CargoCarrier
end
--- Leave Boarding State.
-- @param #CARGO_GROUP self
-- @param Wrapper.Unit#UNIT CargoCarrier
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
self:F( { CargoCarrier.UnitName, From, Event, To } )
local NearRadius = NearRadius or 25
local Boarded = true
local Cancelled = false
local Dead = true
self.CargoSet:Flush()
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
for CargoID, Cargo in pairs( self.CargoSet:GetSet() ) do
self:T( { Cargo:GetName(), Cargo.current } )
if not Cargo:is( "Loaded" ) then
Boarded = false
end
if Cargo:is( "UnLoaded" ) then
Cancelled = true
end
if not Cargo:is( "Destroyed" ) then
Dead = false
end
end
if not Dead then
if not Cancelled then
if not Boarded then
self:__Boarding( 1, CargoCarrier, NearRadius, ... )
else
self:__Load( 1, CargoCarrier, ... )
end
else
self:__CancelBoarding( 1, CargoCarrier, NearRadius, ... )
end
else
self:__Destroyed( 1, CargoCarrier, NearRadius, ... )
end
end
--- Enter UnBoarding State.
-- @param #CARGO_GROUP self
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
self:F( {From, Event, To, ToPointVec2, NearRadius } )
NearRadius = NearRadius or 25
local Timer = 1
if From == "Loaded" then
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
self.CargoSet:ForEach(
function( Cargo, NearRadius )
Cargo:__UnBoard( Timer, ToPointVec2, NearRadius )
Timer = Timer + 10
end, { NearRadius }
)
self:__UnBoarding( 1, ToPointVec2, NearRadius, ... )
end
end
--- Leave UnBoarding State.
-- @param #CARGO_GROUP self
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
self:F( { From, Event, To, ToPointVec2, NearRadius } )
--local NearRadius = NearRadius or 25
local Angle = 180
local Speed = 10
local Distance = 5
if From == "UnBoarding" then
local UnBoarded = true
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
for CargoID, Cargo in pairs( self.CargoSet:GetSet() ) do
self:T( Cargo.current )
if not Cargo:is( "UnLoaded" ) then
UnBoarded = false
end
end
if UnBoarded then
return true
else
self:__UnBoarding( 1, ToPointVec2, NearRadius, ... )
end
return false
end
end
--- UnBoard Event.
-- @param #CARGO_GROUP self
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
self:F( { From, Event, To, ToPointVec2, NearRadius } )
--local NearRadius = NearRadius or 25
self:__UnLoad( 1, ToPointVec2, ... )
end
--- Enter UnLoaded State.
-- @param #CARGO_GROUP self
-- @param Core.Point#POINT_VEC2
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onenterUnLoaded( From, Event, To, ToPointVec2, ... )
self:F( { From, Event, To, ToPointVec2 } )
if From == "Loaded" then
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
self.CargoSet:ForEach(
function( Cargo )
Cargo:UnLoad( ToPointVec2 )
end
)
end
end
end -- CARGO_GROUP
do -- CARGO_PACKAGE
--- @type CARGO_PACKAGE
@ -1022,238 +1346,3 @@ end
end
do -- CARGO_GROUP
--- @type CARGO_GROUP
-- @extends #CARGO_REPORTABLE
--- # CARGO\_GROUP class
--
-- The CARGO\_GROUP class defines a cargo that is represented by a @{Group} object within the simulator, and can be transported by a carrier.
-- Use the event functions as described above to Load, UnLoad, Board, UnBoard the CARGO\_GROUP to and from carrier.
--
-- @field #CARGO_GROUP CARGO_GROUP
--
CARGO_GROUP = {
ClassName = "CARGO_GROUP",
}
--- CARGO_GROUP constructor.
-- @param #CARGO_GROUP self
-- @param Wrapper.Group#GROUP CargoGroup
-- @param #string Type
-- @param #string Name
-- @param #number ReportRadius (optional)
-- @param #number NearRadius (optional)
-- @return #CARGO_GROUP
function CARGO_GROUP:New( CargoGroup, Type, Name, ReportRadius )
local self = BASE:Inherit( self, CARGO_REPORTABLE:New( CargoGroup, Type, Name, 0, ReportRadius ) ) -- #CARGO_GROUP
self:F( { Type, Name, ReportRadius } )
self.CargoSet = SET_CARGO:New()
self.CargoObject = CargoGroup
local WeightGroup = 0
for UnitID, UnitData in pairs( CargoGroup:GetUnits() ) do
local Unit = UnitData -- Wrapper.Unit#UNIT
local WeightUnit = Unit:GetDesc().massEmpty
WeightGroup = WeightGroup + WeightUnit
local CargoUnit = CARGO_UNIT:New( Unit, Type, Unit:GetName(), WeightUnit )
self.CargoSet:Add( CargoUnit:GetName(), CargoUnit )
end
self:SetWeight( WeightGroup )
self:T( { "Weight Cargo", WeightGroup } )
-- Cargo objects are added to the _DATABASE and SET_CARGO objects.
_EVENTDISPATCHER:CreateEventNewCargo( self )
return self
end
--- Enter Boarding State.
-- @param #CARGO_GROUP self
-- @param Wrapper.Unit#UNIT CargoCarrier
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onenterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
self:F( { CargoCarrier.UnitName, From, Event, To } )
NearRadius = NearRadius or 25
if From == "UnLoaded" then
-- For each Cargo object within the CARGO_GROUPED, route each object to the CargoLoadPointVec2
self.CargoSet:ForEach(
function( Cargo )
Cargo:__Board( 1, CargoCarrier, NearRadius )
end
)
self:__Boarding( 1, CargoCarrier, NearRadius, ... )
end
end
--- Enter Loaded State.
-- @param #CARGO_GROUP self
-- @param Wrapper.Unit#UNIT CargoCarrier
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onenterLoaded( From, Event, To, CargoCarrier, ... )
self:F( { CargoCarrier.UnitName, From, Event, To } )
if From == "UnLoaded" then
-- For each Cargo object within the CARGO_GROUP, load each cargo to the CargoCarrier.
for CargoID, Cargo in pairs( self.CargoSet:GetSet() ) do
Cargo:Load( CargoCarrier )
end
end
self.CargoObject:Destroy()
self.CargoCarrier = CargoCarrier
end
--- Leave Boarding State.
-- @param #CARGO_GROUP self
-- @param Wrapper.Unit#UNIT CargoCarrier
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onleaveBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
self:F( { CargoCarrier.UnitName, From, Event, To } )
NearRadius = NearRadius or 25
local Boarded = true
self.CargoSet:Flush()
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
for CargoID, Cargo in pairs( self.CargoSet:GetSet() ) do
self:T( { Cargo:GetName(), Cargo.current } )
if not Cargo:is( "Loaded" ) then
Boarded = false
end
end
if not Boarded then
self:__Boarding( 1, CargoCarrier, NearRadius, ... )
else
self:__Load( 1, CargoCarrier, ... )
end
return Boarded
end
--- Enter UnBoarding State.
-- @param #CARGO_GROUP self
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
self:F({From, Event, To, ToPointVec2, NearRadius})
NearRadius = NearRadius or 25
local Timer = 1
if From == "Loaded" then
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
self.CargoSet:ForEach(
function( Cargo )
Cargo:__UnBoard( Timer, ToPointVec2, NearRadius )
Timer = Timer + 10
end
)
self:__UnBoarding( 1, ToPointVec2, NearRadius, ... )
end
end
--- Leave UnBoarding State.
-- @param #CARGO_GROUP self
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
self:F( { From, Event, To, ToPointVec2, NearRadius } )
NearRadius = NearRadius or 25
local Angle = 180
local Speed = 10
local Distance = 5
if From == "UnBoarding" then
local UnBoarded = true
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
for CargoID, Cargo in pairs( self.CargoSet:GetSet() ) do
self:T( Cargo.current )
if not Cargo:is( "UnLoaded" ) then
UnBoarded = false
end
end
if UnBoarded then
return true
else
self:__UnBoarding( 1, ToPointVec2, NearRadius, ... )
end
return false
end
end
--- UnBoard Event.
-- @param #CARGO_GROUP self
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
self:F( { From, Event, To, ToPointVec2, NearRadius } )
NearRadius = NearRadius or 25
self:__UnLoad( 1, ToPointVec2, ... )
end
--- Enter UnLoaded State.
-- @param #CARGO_GROUP self
-- @param Core.Point#POINT_VEC2
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_GROUP:onenterUnLoaded( From, Event, To, ToPointVec2, ... )
self:F( { From, Event, To, ToPointVec2 } )
if From == "Loaded" then
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
self.CargoSet:ForEach(
function( Cargo )
Cargo:UnLoad( ToPointVec2 )
end
)
end
end
end -- CARGO_GROUP

View File

@ -51,6 +51,7 @@ DATABASE = {
ClientsByID = {},
},
UNITS = {},
UNITS_Index = {},
STATICS = {},
GROUPS = {},
PLAYERS = {},
@ -99,7 +100,7 @@ function DATABASE:New()
self:HandleEvent( EVENTS.DeleteCargo )
-- Follow alive players and clients
self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit )
-- self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit )
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit )
self:_RegisterTemplates()
@ -108,6 +109,33 @@ function DATABASE:New()
self:_RegisterStatics()
self:_RegisterPlayers()
self:_RegisterAirbases()
self.UNITS_Position = 0
--- @param #DATABASE self
local function CheckPlayers( self )
local UNITS_Count = #self.UNITS_Index
if UNITS_Count > 0 then
self.UNITS_Position = ( ( self.UNITS_Position <= UNITS_Count ) and self.UNITS_Position + 1 ) or 1
local PlayerUnit = self.UNITS[self.UNITS_Index[self.UNITS_Position]]
if PlayerUnit then
local UnitName = PlayerUnit:GetName()
local PlayerName = PlayerUnit:GetPlayerName()
--self:E( { UNITS_Count, self.UNITS_Position, UnitName, PlayerName } )
if PlayerName and PlayerName ~= "" then
if self.PLAYERS[PlayerName] == nil or self.PLAYERS[PlayerName] ~= UnitName then
self:E( { "Add player for unit:", UnitName, PlayerName } )
self:AddPlayer( UnitName, PlayerName )
--_EVENTDISPATCHER:CreateEventPlayerEnterUnit( PlayerUnit )
end
end
end
end
end
self:E( "Scheduling" )
--local PlayerCheckSchedule = SCHEDULER:New( nil, CheckPlayers, { self }, 2, 0.1 )
return self
end
@ -130,6 +158,8 @@ function DATABASE:AddUnit( DCSUnitName )
if not self.UNITS[DCSUnitName] then
local UnitRegister = UNIT:Register( DCSUnitName )
self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName )
table.insert( self.UNITS_Index, DCSUnitName )
end
return self.UNITS[DCSUnitName]
@ -140,7 +170,7 @@ end
-- @param #DATABASE self
function DATABASE:DeleteUnit( DCSUnitName )
--self.UNITS[DCSUnitName] = nil
self.UNITS[DCSUnitName] = nil
end
--- Adds a Static based on the Static Name in the DATABASE.
@ -281,7 +311,7 @@ function DATABASE:AddPlayer( UnitName, PlayerName )
if PlayerName then
self:E( { "Add player for unit:", UnitName, PlayerName } )
self.PLAYERS[PlayerName] = self:FindUnit( UnitName )
self.PLAYERS[PlayerName] = UnitName
self.PLAYERSJOINED[PlayerName] = PlayerName
end
end

View File

@ -730,6 +730,21 @@ do -- Event Creation
world.onEvent( Event )
end
--- Creation of a S_EVENT_PLAYER_ENTER_UNIT Event.
-- @param #EVENT self
-- @param Wrapper.Unit#UNIT PlayerUnit.
function EVENT:CreateEventPlayerEnterUnit( PlayerUnit )
self:F( { PlayerUnit } )
local Event = {
id = EVENTS.PlayerEnterUnit,
time = timer.getTime(),
initiator = PlayerUnit:GetDCSObject()
}
world.onEvent( Event )
end
end
--- @param #EVENT self
@ -748,7 +763,7 @@ function EVENT:onEvent( Event )
local EventMeta = _EVENTMETA[Event.id]
if self and self.Events and self.Events[Event.id] then
if Event.initiator then
@ -863,7 +878,7 @@ function EVENT:onEvent( Event )
local PriorityBegin = PriorityOrder == -1 and 5 or 1
local PriorityEnd = PriorityOrder == -1 and 1 or 5
if Event.IniObjectCategory ~= 3 then
if Event.IniObjectCategory ~= Object.Category.STATIC then
self:E( { EventMeta.Text, Event, Event.IniDCSUnitName, Event.TgtDCSUnitName, PriorityOrder } )
end
@ -874,8 +889,10 @@ function EVENT:onEvent( Event )
-- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do
self:E( { "Evaluating: ", EventClass:GetClassNameAndID() } )
if Event.IniObjectCategory ~= Object.Category.STATIC then
--self:E( { "Evaluating: ", EventClass:GetClassNameAndID() } )
end
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )

View File

@ -1003,15 +1003,20 @@ do -- FSM_PROCESS
-- @param #FSM_PROCESS self
-- @return #FSM_PROCESS
function FSM_PROCESS:Remove()
self:T( { self:GetClassNameAndID() } )
self:F( { self:GetClassNameAndID() } )
self:F( "Clearing Schedules" )
self.CallScheduler:Clear()
-- Copy Processes
for ProcessID, Process in pairs( self:GetProcesses() ) do
self:E( { Process} )
Process.fsm:Remove()
Process.fsm = nil
if Process.fsm then
Process.fsm:Remove()
Process.fsm = nil
end
end
return self
end
@ -1116,7 +1121,7 @@ end
self:T( { ProcessUnit, From, Event, To, Dummy, self:IsTrace() } )
if self:IsTrace() then
MESSAGE:New( "@ Process " .. self:GetClassNameAndID() .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
--MESSAGE:New( "@ Process " .. self:GetClassNameAndID() .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
end
self:T( { Scores = self._Scores, To = To } )

View File

@ -82,7 +82,7 @@ do -- MENU_BASE
-- @param #string MenuText The text of the child menu.
-- @return #MENU_BASE
function MENU_BASE:GetMenu( MenuText )
self:F( { self.Menus, MenuText } )
self:F2( { Menu = self.Menus[MenuText] } )
return self.Menus[MenuText]
end
@ -91,7 +91,7 @@ do -- MENU_BASE
-- @param #boolean RemoveParent If true, the parent menu is automatically removed when this menu is the last child menu of that parent @{Menu}.
-- @return #MENU_BASE
function MENU_BASE:SetRemoveParent( RemoveParent )
self:F( { RemoveParent } )
self:F2( { RemoveParent } )
self.MenuRemoveParent = RemoveParent
return self
end
@ -780,7 +780,9 @@ do
self = MenuGroup._Menus[Path]
else
self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) )
MenuGroup._Menus[Path] = self
--if MenuGroup:IsAlive() then
MenuGroup._Menus[Path] = self
--end
self.MenuGroup = MenuGroup
self.Path = Path
@ -808,9 +810,9 @@ do
-- @param MenuTime
-- @return #MENU_GROUP self
function MENU_GROUP:RemoveSubMenus( MenuTime )
self:F2( { self.MenuPath, MenuTime, self.MenuTime } )
--self:F2( { self.MenuPath, MenuTime, self.MenuTime } )
self:T( { "Removing Group SubMenus:", self.MenuGroup:GetName(), self.MenuPath } )
--self:T( { "Removing Group SubMenus:", self.MenuGroup:GetName(), self.MenuPath } )
for MenuText, Menu in pairs( self.Menus ) do
Menu:Remove( MenuTime )
end
@ -823,7 +825,7 @@ do
-- @param MenuTime
-- @return #nil
function MENU_GROUP:Remove( MenuTime )
self:F( { self.MenuGroupID, self.MenuPath, MenuTime, self.MenuTime } )
--self:F2( { self.MenuGroupID, self.MenuPath, MenuTime, self.MenuTime } )
self:RemoveSubMenus( MenuTime )
@ -837,12 +839,12 @@ do
self.ParentMenu.MenuCount = self.ParentMenu.MenuCount - 1
if self.ParentMenu.MenuCount == 0 then
if self.MenuRemoveParent == true then
self:T( "Removing Parent Menu " )
self:T2( "Removing Parent Menu " )
self.ParentMenu:Remove()
end
end
end
self:T( { "Removing Group Menu:", self.MenuGroup:GetName(), self.MenuGroup._Menus[self.Path].Path } )
self:T( { "Removing Group Menu:", MenuGroup = self.MenuGroup:GetName(), MenuPath = self.MenuGroup._Menus[self.Path].Path } )
self.MenuGroup._Menus[self.Path] = nil
self = nil
end
@ -880,10 +882,13 @@ do
local Path = ( ParentMenu and ( table.concat( ParentMenu.MenuPath or {}, "@" ) .. "@" .. MenuText ) ) or MenuText
if MenuGroup._Menus[Path] then
self = MenuGroup._Menus[Path]
self:T( { "Re-using Group Command Menu:", MenuGroup:GetName(), MenuText } )
self:F2( { "Re-using Group Command Menu:", MenuGroup:GetName(), MenuText } )
else
self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) )
MenuGroup._Menus[Path] = self
--if MenuGroup:IsAlive() then
MenuGroup._Menus[Path] = self
--end
self.Path = Path
self.MenuGroup = MenuGroup
@ -891,13 +896,13 @@ do
self.MenuText = MenuText
self.ParentMenu = ParentMenu
self:T( { "Adding Group Command Menu:", MenuGroup:GetName(), MenuText, self.MenuParentPath } )
self:F( { "Adding Group Command Menu:", MenuGroup = MenuGroup:GetName(), MenuText = MenuText, MenuPath = self.MenuParentPath } )
self.MenuPath = missionCommands.addCommandForGroup( self.MenuGroupID, MenuText, self.MenuParentPath, self.MenuCallHandler, arg )
if self.ParentMenu and self.ParentMenu.Menus then
self.ParentMenu.Menus[MenuText] = self
self.ParentMenu.MenuCount = self.ParentMenu.MenuCount + 1
self:F( { ParentMenu.Menus, MenuText } )
self:F2( { ParentMenu.Menus, MenuText } )
end
end
@ -909,20 +914,20 @@ do
-- @param MenuTime
-- @return #nil
function MENU_GROUP_COMMAND:Remove( MenuTime )
self:F( { self.MenuGroupID, self.MenuPath, MenuTime, self.MenuTime } )
--self:F2( { self.MenuGroupID, self.MenuPath, MenuTime, self.MenuTime } )
if not MenuTime or self.MenuTime ~= MenuTime then
if self.MenuGroup._Menus[self.Path] then
self = self.MenuGroup._Menus[self.Path]
missionCommands.removeItemForGroup( self.MenuGroupID, self.MenuPath )
self:T( { "Removing Group Command Menu:", self.MenuGroup:GetName(), self.MenuText, self.Path, self.MenuGroup._Menus[self.Path].Path } )
self:T( { "Removing Group Command Menu:", MenuGroup = self.MenuGroup:GetName(), MenuText = self.MenuText, MenuPath = self.Path } )
self.ParentMenu.Menus[self.MenuText] = nil
self.ParentMenu.MenuCount = self.ParentMenu.MenuCount - 1
if self.ParentMenu.MenuCount == 0 then
if self.MenuRemoveParent == true then
self:T( "Removing Parent Menu " )
self:T2( "Removing Parent Menu " )
self.ParentMenu:Remove()
end
end

View File

@ -191,7 +191,7 @@ function SCHEDULEDISPATCHER:Start( Scheduler, CallID )
)
end
else
for CallID, Schedule in pairs( self.Schedule[Scheduler] ) do
for CallID, Schedule in pairs( self.Schedule[Scheduler] or {} ) do
self:Start( Scheduler, CallID ) -- Recursive
end
end
@ -209,7 +209,7 @@ function SCHEDULEDISPATCHER:Stop( Scheduler, CallID )
Schedule[CallID].ScheduleID = nil
end
else
for CallID, Schedule in pairs( self.Schedule[Scheduler] ) do
for CallID, Schedule in pairs( self.Schedule[Scheduler] or {} ) do
self:Stop( Scheduler, CallID ) -- Recursive
end
end
@ -218,7 +218,7 @@ end
function SCHEDULEDISPATCHER:Clear( Scheduler )
self:F2( { Scheduler = Scheduler } )
for CallID, Schedule in pairs( self.Schedule[Scheduler] ) do
for CallID, Schedule in pairs( self.Schedule[Scheduler] or {} ) do
self:Stop( Scheduler, CallID ) -- Recursive
end
end

View File

@ -165,11 +165,10 @@ end
-- @param #SET_BASE self
-- @param #string ObjectName
function SET_BASE:Remove( ObjectName )
self:F( ObjectName )
local t = self.Set[ObjectName]
self:E( { ObjectName, t } )
self:F3( { ObjectName, t } )
if t then
if t._next then
@ -1337,6 +1336,11 @@ SET_UNIT = {
}
--- Get the first unit from the set.
-- @function [parent=#SET_UNIT] GetFirst
-- @param #SET_UNIT self
-- @return Wrapper.Unit#UNIT The UNIT object.
--- Creates a new SET_UNIT object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
-- @param #SET_UNIT self
-- @return #SET_UNIT
@ -1568,7 +1572,7 @@ end
-- @return #string The name of the UNIT
-- @return #table The UNIT
function SET_UNIT:FindInDatabase( Event )
self:E( { Event.IniDCSUnitName, self.Set[Event.IniDCSUnitName], Event } )
self:F2( { Event.IniDCSUnitName, self.Set[Event.IniDCSUnitName], Event } )
return Event.IniDCSUnitName, self.Set[Event.IniDCSUnitName]

View File

@ -731,7 +731,7 @@ end
-- @param #ZONE_UNIT self
-- @return Dcs.DCSTypes#Vec2 The location of the zone based on the @{Unit#UNIT}location.
function ZONE_UNIT:GetVec2()
self:F( self.ZoneName )
self:F2( self.ZoneName )
local ZoneVec2 = self.ZoneUNIT:GetVec2()
if ZoneVec2 then
@ -741,7 +741,7 @@ function ZONE_UNIT:GetVec2()
return self.LastVec2
end
self:T( { ZoneVec2 } )
self:T2( { ZoneVec2 } )
return nil
end

View File

@ -190,7 +190,7 @@ do -- DETECTION_BASE
-- local SetGroup = SET_GROUP:New():FilterPrefixes( "FAC" ):FilterStart() -- Build a SetGroup of Forward Air Controllers.
--
-- -- Build a detect object.
-- local Detection = DETECTION_BASE:New( SetGroup )
-- local Detection = DETECTION_UNITS:New( SetGroup )
--
-- -- This will accept detected units if the range is below 5000 meters.
-- Detection:SetAcceptRange( 5000 )
@ -211,7 +211,7 @@ do -- DETECTION_BASE
-- local ZoneAccept2 = ZONE:New( "AcceptZone2" )
--
-- -- Build a detect object.
-- local Detection = DETECTION_BASE:New( SetGroup )
-- local Detection = DETECTION_UNITS:New( SetGroup )
--
-- -- This will accept detected units by Detection when the unit is within ZoneAccept1 OR ZoneAccept2.
-- Detection:SetAcceptZones( { ZoneAccept1, ZoneAccept2 } )
@ -232,7 +232,7 @@ do -- DETECTION_BASE
-- local ZoneReject2 = ZONE:New( "RejectZone2" )
--
-- -- Build a detect object.
-- local Detection = DETECTION_BASE:New( SetGroup )
-- local Detection = DETECTION_UNITS:New( SetGroup )
--
-- -- This will reject detected units by Detection when the unit is within ZoneReject1 OR ZoneReject2.
-- Detection:SetRejectZones( { ZoneReject1, ZoneReject2 } )
@ -273,10 +273,16 @@ do -- DETECTION_BASE
--- @type DETECTION_BASE.DetectedObject
-- @field #string Name
-- @field #boolean Visible
-- @field #boolean IsVisible
-- @field #boolean KnowType
-- @field #boolean KnowDistance
-- @field #string Type
-- @field #number Distance
-- @field #boolean Identified
-- @field #number LastTime
-- @field #boolean LastPos
-- @field #number LastVelocity
--- @type DETECTION_BASE.DetectedItems
-- @list <#DETECTION_BASE.DetectedItem>
@ -309,12 +315,12 @@ do -- DETECTION_BASE
self.DetectionInterval = 30
self:InitDetectVisual( false )
self:InitDetectOptical( false )
self:InitDetectRadar( false )
self:InitDetectRWR( false )
self:InitDetectIRST( false )
self:InitDetectDLINK( false )
self:InitDetectVisual( nil )
self:InitDetectOptical( nil )
self:InitDetectRadar( nil )
self:InitDetectRWR( nil )
self:InitDetectIRST( nil )
self:InitDetectDLINK( nil )
self:FilterCategories( {
Unit.Category.AIRPLANE,
@ -531,6 +537,7 @@ do -- DETECTION_BASE
self:T( { "DetectionGroup is Alive", DetectionGroup:GetName() } )
local DetectionGroupName = DetectionGroup:GetName()
local DetectionUnit = DetectionGroup:GetUnit(1)
local DetectedUnits = {}
@ -550,6 +557,18 @@ do -- DETECTION_BASE
if DetectedObject and DetectedObject:isExist() and DetectedObject.id_ < 50000000 then -- and ( DetectedObject:getCategory() == Object.Category.UNIT or DetectedObject:getCategory() == Object.Category.STATIC ) then
local TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity = DetectionUnit:IsTargetDetected(
DetectedObject,
self.DetectVisual,
self.DetectOptical,
self.DetectRadar,
self.DetectIRST,
self.DetectRWR,
self.DetectDLINK
)
self:T2( { TargetIsDetected = TargetIsDetected, TargetIsVisible = TargetIsVisible, TargetLastTime = TargetLastTime, TargetKnowType = TargetKnowType, TargetKnowDistance = TargetKnowDistance, TargetLastPos = TargetLastPos, TargetLastVelocity = TargetLastVelocity } )
local DetectionAccepted = true
local DetectedObjectName = DetectedObject:getName()
@ -566,7 +585,7 @@ do -- DETECTION_BASE
local DetectedUnitCategory = DetectedObject:getDesc().category
self:T( { "Detected Target:", DetectionGroupName, DetectedObjectName, Distance, DetectedUnitCategory } )
self:T2( { "Detected Target:", DetectionGroupName, DetectedObjectName, Distance, DetectedUnitCategory } )
-- Calculate Acceptance
@ -648,12 +667,14 @@ do -- DETECTION_BASE
HasDetectedObjects = true
if not self.DetectedObjects[DetectedObjectName] then
self.DetectedObjects[DetectedObjectName] = {}
end
self.DetectedObjects[DetectedObjectName] = self.DetectedObjects[DetectedObjectName] or {}
self.DetectedObjects[DetectedObjectName].Name = DetectedObjectName
self.DetectedObjects[DetectedObjectName].Visible = Detection.visible
self.DetectedObjects[DetectedObjectName].Type = Detection.type
self.DetectedObjects[DetectedObjectName].IsVisible = TargetIsVisible
self.DetectedObjects[DetectedObjectName].LastTime = TargetLastTime
self.DetectedObjects[DetectedObjectName].LastPos = TargetLastPos
self.DetectedObjects[DetectedObjectName].LastVelocity = TargetLastVelocity
self.DetectedObjects[DetectedObjectName].KnowType = TargetKnowType
self.DetectedObjects[DetectedObjectName].KnowDistance = Detection.distance -- TargetKnowDistance
self.DetectedObjects[DetectedObjectName].Distance = Distance
local DetectedUnit = UNIT:FindByName( DetectedObjectName )
@ -707,7 +728,7 @@ do -- DETECTION_BASE
local DetectedSet = DetectedItem.Set
if DetectedSet:Count() == 0 then
self.DetectedItems[DetectedItemID] = nil
self:RemoveDetectedItem(DetectedItemID)
end
end
@ -1133,7 +1154,7 @@ do -- DETECTION_BASE
-- @param #string ObjectName
-- @return #DETECTION_BASE.DetectedObject
function DETECTION_BASE:GetDetectedObject( ObjectName )
self:F( ObjectName )
self:F2( ObjectName )
if ObjectName then
local DetectedObject = self.DetectedObjects[ObjectName]
@ -1200,8 +1221,10 @@ do -- DETECTION_BASE
-- @param #number DetectedItemIndex The index or position in the DetectedItems list where the item needs to be removed.
function DETECTION_BASE:RemoveDetectedItem( DetectedItemIndex )
self.DetectedItemCount = self.DetectedItemCount - 1
self.DetectedItems[DetectedItemIndex] = nil
if self.DetectedItems[DetectedItemIndex] then
self.DetectedItemCount = self.DetectedItemCount - 1
self.DetectedItems[DetectedItemIndex] = nil
end
end
@ -1215,7 +1238,7 @@ do -- DETECTION_BASE
--- Get the amount of SETs with detected objects.
-- @param #DETECTION_BASE self
-- @return #number Count
-- @return #number The amount of detected items. Note that the amount of detected items can differ with the reality, because detections are not real-time but doen in intervals!
function DETECTION_BASE:GetDetectedItemsCount()
local DetectedCount = self.DetectedItemCount
@ -1435,7 +1458,6 @@ do -- DETECTION_UNITS
for DetectedItemID, DetectedItem in pairs( self.DetectedItems ) do
local DetectedItemSet = DetectedItem.Set -- Core.Set#SET_UNIT
local DetectedTypeName = DetectedItem.Type
for DetectedUnitName, DetectedUnitData in pairs( DetectedItemSet:GetSet() ) do
local DetectedUnit = DetectedUnitData -- Wrapper.Unit#UNIT
@ -1450,6 +1472,17 @@ do -- DETECTION_UNITS
-- Yes, the DetectedUnit is still detected or exists. Flag as identified.
self:IdentifyDetectedObject( DetectedObject )
-- Update the detection with the new data provided.
DetectedItem.TypeName = DetectedUnit:GetTypeName()
DetectedItem.Name = DetectedObject.Name
DetectedItem.IsVisible = DetectedObject.IsVisible
DetectedItem.LastTime = DetectedObject.LastTime
DetectedItem.LastPos = DetectedObject.LastPos
DetectedItem.LastVelocity = DetectedObject.LastVelocity
DetectedItem.KnowType = DetectedObject.KnowType
DetectedItem.KnowDistance = DetectedObject.KnowDistance
DetectedItem.Distance = DetectedObject.Distance
else
-- There was no DetectedObject, remove DetectedUnit from the Set.
self:AddChangeUnit( DetectedItem, "RU", DetectedUnitName )
@ -1474,10 +1507,15 @@ do -- DETECTION_UNITS
if not DetectedItem then
self:T( "Added new DetectedItem" )
DetectedItem = self:AddDetectedItem( "UNIT", DetectedUnitName )
DetectedItem.Type = DetectedUnit:GetTypeName()
DetectedItem.Name = DetectedObjectData.Name
DetectedItem.Visible = DetectedObjectData.Visible
DetectedItem.Distance = DetectedObjectData.Distance
DetectedItem.TypeName = DetectedUnit:GetTypeName()
DetectedItem.Name = DetectedObject.Name
DetectedItem.IsVisible = DetectedObject.IsVisible
DetectedItem.LastTime = DetectedObject.LastTime
DetectedItem.LastPos = DetectedObject.LastPos
DetectedItem.LastVelocity = DetectedObject.LastVelocity
DetectedItem.KnowType = DetectedObject.KnowType
DetectedItem.KnowDistance = DetectedObject.KnowDistance
DetectedItem.Distance = DetectedObject.Distance
end
DetectedItem.Set:AddUnit( DetectedUnit )
@ -1557,19 +1595,27 @@ do -- DETECTION_UNITS
if DetectedItemUnit and DetectedItemUnit:IsAlive() then
self:T(DetectedItemUnit)
local UnitCategoryName = DetectedItemUnit:GetCategoryName() or ""
local UnitCategoryType = DetectedItemUnit:GetTypeName() or ""
if DetectedItem.Type and UnitCategoryName and UnitCategoryType then
UnitCategoryText = UnitCategoryName .. " (" .. UnitCategoryType .. ") at "
if DetectedItem.KnowType then
local UnitCategoryName = DetectedItemUnit:GetCategoryName()
if UnitCategoryName then
UnitCategoryText = UnitCategoryName
end
if DetectedItem.TypeName then
UnitCategoryText = UnitCategoryText .. " (" .. DetectedItem.TypeName .. ")"
end
else
UnitCategoryText = "Unknown target at "
UnitCategoryText = "Unknown"
end
if DetectedItem.Visible == false then
UnitDistanceText = string.format( "%.2f", DetectedItem.Distance ) .. " km, estimated"
if DetectedItem.KnowDistance then
if DetectedItem.IsVisible then
UnitDistanceText = " at " .. string.format( "%.2f", DetectedItem.Distance ) .. " km"
end
else
UnitDistanceText = string.format( "%.2f", DetectedItem.Distance ) .. " km, visual"
if DetectedItem.IsVisible then
UnitDistanceText = " at +/- " .. string.format( "%.0f", DetectedItem.Distance ) .. " km"
end
end
local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate()
@ -1699,7 +1745,7 @@ do -- DETECTION_TYPES
for DetectedItemID, DetectedItem in pairs( self.DetectedItems ) do
local DetectedItemSet = DetectedItem.Set -- Core.Set#SET_UNIT
local DetectedTypeName = DetectedItem.Type
local DetectedTypeName = DetectedItem.TypeName
for DetectedUnitName, DetectedUnitData in pairs( DetectedItemSet:GetSet() ) do
local DetectedUnit = DetectedUnitData -- Wrapper.Unit#UNIT
@ -1736,7 +1782,7 @@ do -- DETECTION_TYPES
local DetectedItem = self:GetDetectedItem( DetectedTypeName )
if not DetectedItem then
DetectedItem = self:AddDetectedItem( "TYPE", DetectedTypeName )
DetectedItem.Type = DetectedUnit:GetTypeName()
DetectedItem.TypeName = DetectedUnit:GetTypeName()
end
DetectedItem.Set:AddUnit( DetectedUnit )
@ -1808,7 +1854,7 @@ do -- DETECTION_TYPES
local ThreatLevelA2G = DetectedSet:CalculateThreatLevelA2G()
local DetectedItemsCount = DetectedSet:Count()
local DetectedItemType = DetectedItem.Type
local DetectedItemType = DetectedItem.TypeName
local DetectedItemUnit = DetectedSet:GetFirst()
@ -1967,7 +2013,7 @@ do -- DETECTION_AREAS
local ThreatLevelA2G = self:GetTreatLevelA2G( DetectedItem )
local DetectedItemsCount = DetectedSet:Count()
local DetectedItemsTypes = DetectedSet:GetTypeNames()
local ReportSummary = string.format(
"%s - %s - Threat:[%s](%2d)\n %2d of %s",
DetectedItemID,
@ -1983,6 +2029,25 @@ do -- DETECTION_AREAS
return nil
end
--- Report detailed of a detection result.
-- @param #DETECTION_AREAS self
-- @return #string
function DETECTION_AREAS:DetectedReportDetailed() --R2.1 Fixed missing report
self:F()
local Report = REPORT:New( "Detected areas:" )
for DetectedItemIndex, DetectedItem in pairs( self.DetectedItems ) do
local DetectedItem = DetectedItem -- #DETECTION_BASE.DetectedItem
local ReportSummary = self:DetectedItemReportSummary( DetectedItemIndex )
Report:Add( ReportSummary )
end
local ReportText = Report:Text()
return ReportText
end
--- Returns if there are friendlies nearby the FAC units ...

View File

@ -442,7 +442,7 @@ function MISSILETRAINER._MenuMessages( MenuParameters )
if MenuParameters.Distance ~= nil then
self.Distance = MenuParameters.Distance
MESSAGE:New( "Hit detection distance set to " .. self.Distance .. " meters", 15, "Menu" ):ToAll()
MESSAGE:New( "Hit detection distance set to " .. self.Distance * 1000 .. " meters", 15, "Menu" ):ToAll()
end
end

View File

@ -1595,11 +1595,13 @@ function SPAWN:_OnBirth( EventData )
if SpawnGroup then
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
self:T( { "Birth Event:", EventPrefix, self.SpawnTemplatePrefix } )
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
self.AliveUnits = self.AliveUnits + 1
self:T( "Alive Units: " .. self.AliveUnits )
end
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
self:T( { "Birth Event:", EventPrefix, self.SpawnTemplatePrefix } )
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
self.AliveUnits = self.AliveUnits + 1
self:T( "Alive Units: " .. self.AliveUnits )
end
end
end
end
@ -1616,11 +1618,13 @@ function SPAWN:_OnDeadOrCrash( EventData )
if SpawnGroup then
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
self:T( { "Dead event: " .. EventPrefix } )
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
self.AliveUnits = self.AliveUnits - 1
self:T( "Alive Units: " .. self.AliveUnits )
end
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
self:T( { "Dead event: " .. EventPrefix } )
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
self.AliveUnits = self.AliveUnits - 1
self:T( "Alive Units: " .. self.AliveUnits )
end
end
end
end
@ -1634,10 +1638,12 @@ function SPAWN:_OnTakeOff( EventData )
local SpawnGroup = EventData.IniGroup
if SpawnGroup then
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
self:T( { "TakeOff event: " .. EventPrefix } )
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
self:T( "self.Landed = false" )
SpawnGroup:SetState( SpawnGroup, "Spawn_Landed", false )
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
self:T( { "TakeOff event: " .. EventPrefix } )
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
self:T( "self.Landed = false" )
SpawnGroup:SetState( SpawnGroup, "Spawn_Landed", false )
end
end
end
end
@ -1652,16 +1658,18 @@ function SPAWN:_OnLand( EventData )
local SpawnGroup = EventData.IniGroup
if SpawnGroup then
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
self:T( { "Land event: " .. EventPrefix } )
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
-- TODO: Check if this is the last unit of the group that lands.
SpawnGroup:SetState( SpawnGroup, "Spawn_Landed", true )
if self.RepeatOnLanding then
local SpawnGroupIndex = self:GetSpawnIndexFromGroup( SpawnGroup )
self:T( { "Landed:", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
self:ReSpawn( SpawnGroupIndex )
end
end
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
self:T( { "Land event: " .. EventPrefix } )
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
-- TODO: Check if this is the last unit of the group that lands.
SpawnGroup:SetState( SpawnGroup, "Spawn_Landed", true )
if self.RepeatOnLanding then
local SpawnGroupIndex = self:GetSpawnIndexFromGroup( SpawnGroup )
self:T( { "Landed:", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
self:ReSpawn( SpawnGroupIndex )
end
end
end
end
end
@ -1676,16 +1684,18 @@ function SPAWN:_OnEngineShutDown( EventData )
local SpawnGroup = EventData.IniGroup
if SpawnGroup then
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
self:T( { "EngineShutdown event: " .. EventPrefix } )
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
-- todo: test if on the runway
local Landed = SpawnGroup:GetState( SpawnGroup, "Spawn_Landed" )
if Landed and self.RepeatOnEngineShutDown then
local SpawnGroupIndex = self:GetSpawnIndexFromGroup( SpawnGroup )
self:T( { "EngineShutDown: ", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
self:ReSpawn( SpawnGroupIndex )
end
end
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
self:T( { "EngineShutdown event: " .. EventPrefix } )
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
-- todo: test if on the runway
local Landed = SpawnGroup:GetState( SpawnGroup, "Spawn_Landed" )
if Landed and self.RepeatOnEngineShutDown then
local SpawnGroupIndex = self:GetSpawnIndexFromGroup( SpawnGroup )
self:T( { "EngineShutDown: ", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
self:ReSpawn( SpawnGroupIndex )
end
end
end
end
end

View File

@ -9,4 +9,4 @@ _SCHEDULEDISPATCHER = SCHEDULEDISPATCHER:New() -- Core.Timer#SCHEDULEDISPATCHER
--- Declare the main database object, which is used internally by the MOOSE classes.
_DATABASE = DATABASE:New() -- Database#DATABASE
COORDINATE:CoordinateMenu()
--COORDINATE:CoordinateMenu()

View File

@ -9,6 +9,7 @@
-- @extends Core.Base#BASE
REPORT = {
ClassName = "REPORT",
Title = "",
}
--- Create a new REPORT.
@ -20,13 +21,24 @@ function REPORT:New( Title )
local self = BASE:Inherit( self, BASE:New() ) -- #REPORT
self.Report = {}
Title = Title or ""
if Title then
self.Report[#self.Report+1] = Title
self.Title = Title
end
return self
end
--- Has the REPORT Text?
-- @param #REPORT self
-- @return #boolean
function REPORT:HasText() --R2.1
return #self.Report > 0
end
--- Set indent of a REPORT.
-- @param #REPORT self
-- @param #number Indent
@ -61,7 +73,7 @@ end
-- @return #string The report text.
function REPORT:Text( Delimiter )
Delimiter = Delimiter or "\n"
local ReportText = table.concat( self.Report, Delimiter ) or ""
local ReportText = ( self.Title ~= "" and self.Title .. Delimiter or self.Title ) .. table.concat( self.Report, Delimiter ) or ""
return ReportText
end
@ -100,9 +112,9 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
if EventData.IniObjectCategory == 1 then
local EventGroup = GROUP:Find( EventData.IniDCSGroup )
if EventGroup and self:HasGroup( EventGroup ) then
local MenuReporting = MENU_GROUP:New( EventGroup, "Reporting", self.CommandCenterMenu )
local MenuMissionsSummary = MENU_GROUP_COMMAND:New( EventGroup, "Missions Summary Report", MenuReporting, self.ReportSummary, self, EventGroup )
local MenuMissionsDetails = MENU_GROUP_COMMAND:New( EventGroup, "Missions Details Report", MenuReporting, self.ReportDetails, self, EventGroup )
local MenuReporting = MENU_GROUP:New( EventGroup, "Missions Reports", self.CommandCenterMenu )
local MenuMissionsSummary = MENU_GROUP_COMMAND:New( EventGroup, "Missions Status Report", MenuReporting, self.ReportMissionsStatus, self, EventGroup )
local MenuMissionsDetails = MENU_GROUP_COMMAND:New( EventGroup, "Missions Players Report", MenuReporting, self.ReportMissionsPlayers, self, EventGroup )
self:ReportSummary( EventGroup )
end
local PlayerUnit = EventData.IniUnit
@ -161,7 +173,7 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
local PlayerUnit = EventData.IniUnit
for MissionID, Mission in pairs( self:GetMissions() ) do
local Mission = Mission -- Tasking.Mission#MISSION
if Mission:IsOngoing() then
if Mission:IsENGAGED() then
Mission:AbortUnit( PlayerUnit )
end
end
@ -177,7 +189,10 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
function( self, EventData )
local PlayerUnit = EventData.IniUnit
for MissionID, Mission in pairs( self:GetMissions() ) do
Mission:CrashUnit( PlayerUnit )
local Mission = Mission -- Tasking.Mission#MISSION
if Mission:IsENGAGED() then
Mission:CrashUnit( PlayerUnit )
end
end
end
)
@ -257,7 +272,6 @@ end
-- @param #COMMANDCENTER self
-- @return Core.Menu#MENU_COALITION
function COMMANDCENTER:GetMenu()
self:F()
return self.CommandCenterMenu
end
@ -293,11 +307,9 @@ end
-- @param #string Message
-- @param Wrapper.Group#GROUP TaskGroup
-- @param #sring Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown.
function COMMANDCENTER:MessageToGroup( Message, TaskGroup, Name )
function COMMANDCENTER:MessageToGroup( Message, TaskGroup )
local Prefix = Name and "@ " .. Name .. ": " or "@ " .. TaskGroup:GetCallsign() .. ": "
Message = Prefix .. Message
self:GetPositionable():MessageToGroup( Message , 20, TaskGroup, self:GetName() )
self:GetPositionable():MessageToGroup( Message , 15, TaskGroup, self:GetName() )
end
@ -307,7 +319,8 @@ function COMMANDCENTER:MessageToCoalition( Message )
local CCCoalition = self:GetPositionable():GetCoalition()
--TODO: Fix coalition bug!
self:GetPositionable():MessageToCoalition( Message, 20, CCCoalition, self:GetName() )
self:GetPositionable():MessageToCoalition( Message, 15, CCCoalition )
end
@ -315,18 +328,37 @@ end
--- Report the status of all MISSIONs to a GROUP.
-- Each Mission is listed, with an indication how many Tasks are still to be completed.
-- @param #COMMANDCENTER self
function COMMANDCENTER:ReportSummary( ReportGroup )
function COMMANDCENTER:ReportMissionsStatus( ReportGroup )
self:E( ReportGroup )
local Report = REPORT:New()
Report:Add( "Status report of all missions." )
for MissionID, Mission in pairs( self.Missions ) do
local Mission = Mission -- Tasking.Mission#MISSION
Report:Add( " - " .. Mission:ReportStatus() )
end
self:MessageToGroup( Report:Text(), ReportGroup )
end
--- Report the players of all MISSIONs to a GROUP.
-- Each Mission is listed, with an indication how many Tasks are still to be completed.
-- @param #COMMANDCENTER self
function COMMANDCENTER:ReportMissionsPlayers( ReportGroup )
self:E( ReportGroup )
local Report = REPORT:New()
Report:Add( "Players active in all missions." )
for MissionID, Mission in pairs( self.Missions ) do
local Mission = Mission -- Tasking.Mission#MISSION
Report:Add( " - " .. Mission:ReportOverview() )
Report:Add( " - " .. Mission:ReportPlayers() )
end
self:GetPositionable():MessageToGroup( Report:Text(), 30, ReportGroup )
self:MessageToGroup( Report:Text(), ReportGroup )
end
--- Report the status of a Task to a Group.
@ -342,6 +374,6 @@ function COMMANDCENTER:ReportDetails( ReportGroup, Task )
Report:Add( " - " .. Mission:ReportDetails() )
end
self:GetPositionable():MessageToGroup( Report:Text(), 30, ReportGroup )
self:MessageToGroup( Report:Text(), ReportGroup )
end

View File

@ -76,6 +76,7 @@ do -- DETECTION MANAGER
self:SetReportInterval( 30 )
self:SetReportDisplayTime( 25 )
self:E( { Detection = Detection } )
Detection:__Start( 1 )
return self

View File

@ -12,6 +12,7 @@ MISSION = {
ClassName = "MISSION",
Name = "",
MissionStatus = "PENDING",
AssignedGroups = {},
}
--- This is the main MISSION declaration method. Each Mission is like the master or a Mission orchestration between, Clients, Tasks, Stages etc.
@ -26,35 +27,47 @@ function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefi
local self = BASE:Inherit( self, FSM:New() ) -- Core.Fsm#FSM
self:SetStartState( "Idle" )
self:T( { MissionName, MissionPriority, MissionBriefing, MissionCoalition } )
self:AddTransition( "Idle", "Start", "Ongoing" )
self.CommandCenter = CommandCenter
CommandCenter:AddMission( self )
--- OnLeave Transition Handler for State Idle.
-- @function [parent=#MISSION] OnLeaveIdle
self.Name = MissionName
self.MissionPriority = MissionPriority
self.MissionBriefing = MissionBriefing
self.MissionCoalition = MissionCoalition
self.Tasks = {}
self:SetStartState( "IDLE" )
self:AddTransition( "IDLE", "Start", "ENGAGED" )
--- OnLeave Transition Handler for State IDLE.
-- @function [parent=#MISSION] OnLeaveIDLE
-- @param #MISSION self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnEnter Transition Handler for State Idle.
-- @function [parent=#MISSION] OnEnterIdle
--- OnEnter Transition Handler for State IDLE.
-- @function [parent=#MISSION] OnEnterIDLE
-- @param #MISSION self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
--- OnLeave Transition Handler for State Ongoing.
-- @function [parent=#MISSION] OnLeaveOngoing
--- OnLeave Transition Handler for State ENGAGED.
-- @function [parent=#MISSION] OnLeaveENGAGED
-- @param #MISSION self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnEnter Transition Handler for State Ongoing.
-- @function [parent=#MISSION] OnEnterOngoing
--- OnEnter Transition Handler for State ENGAGED.
-- @function [parent=#MISSION] OnEnterENGAGED
-- @param #MISSION self
-- @param #string From The From State string.
-- @param #string Event The Event string.
@ -84,18 +97,18 @@ function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefi
-- @param #MISSION self
-- @param #number Delay The delay in seconds.
self:AddTransition( "Ongoing", "Stop", "Idle" )
self:AddTransition( "ENGAGED", "Stop", "IDLE" )
--- OnLeave Transition Handler for State Idle.
-- @function [parent=#MISSION] OnLeaveIdle
--- OnLeave Transition Handler for State IDLE.
-- @function [parent=#MISSION] OnLeaveIDLE
-- @param #MISSION self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnEnter Transition Handler for State Idle.
-- @function [parent=#MISSION] OnEnterIdle
--- OnEnter Transition Handler for State IDLE.
-- @function [parent=#MISSION] OnEnterIDLE
-- @param #MISSION self
-- @param #string From The From State string.
-- @param #string Event The Event string.
@ -125,18 +138,18 @@ function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefi
-- @param #MISSION self
-- @param #number Delay The delay in seconds.
self:AddTransition( "Ongoing", "Complete", "Completed" )
self:AddTransition( "ENGAGED", "Complete", "COMPLETED" )
--- OnLeave Transition Handler for State Completed.
-- @function [parent=#MISSION] OnLeaveCompleted
--- OnLeave Transition Handler for State COMPLETED.
-- @function [parent=#MISSION] OnLeaveCOMPLETED
-- @param #MISSION self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnEnter Transition Handler for State Completed.
-- @function [parent=#MISSION] OnEnterCompleted
--- OnEnter Transition Handler for State COMPLETED.
-- @function [parent=#MISSION] OnEnterCOMPLETED
-- @param #MISSION self
-- @param #string From The From State string.
-- @param #string Event The Event string.
@ -166,18 +179,18 @@ function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefi
-- @param #MISSION self
-- @param #number Delay The delay in seconds.
self:AddTransition( "*", "Fail", "Failed" )
self:AddTransition( "*", "Fail", "FAILED" )
--- OnLeave Transition Handler for State Failed.
-- @function [parent=#MISSION] OnLeaveFailed
--- OnLeave Transition Handler for State FAILED.
-- @function [parent=#MISSION] OnLeaveFAILED
-- @param #MISSION self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnEnter Transition Handler for State Failed.
-- @function [parent=#MISSION] OnEnterFailed
--- OnEnter Transition Handler for State FAILED.
-- @function [parent=#MISSION] OnEnterFAILED
-- @param #MISSION self
-- @param #string From The From State string.
-- @param #string Event The Event string.
@ -207,17 +220,6 @@ function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefi
-- @param #MISSION self
-- @param #number Delay The delay in seconds.
self:T( { MissionName, MissionPriority, MissionBriefing, MissionCoalition } )
self.CommandCenter = CommandCenter
CommandCenter:AddMission( self )
self.Name = MissionName
self.MissionPriority = MissionPriority
self.MissionBriefing = MissionBriefing
self.MissionCoalition = MissionCoalition
self.Tasks = {}
-- Private implementations
@ -235,7 +237,7 @@ function MISSION:onbeforeComplete( From, Event, To )
for TaskID, Task in pairs( self:GetTasks() ) do
local Task = Task -- Tasking.Task#TASK
if not Task:IsStateSuccess() and not Task:IsStateFailed() and not Task:IsStateAborted() and not Task:IsStateCancelled() then
if not Task:IsStateSuccess() and not Task:IsStateFAILED() and not Task:IsStateAborted() and not Task:IsStateCancelled() then
return false -- Mission cannot be completed. Other Tasks are still active.
end
end
@ -247,7 +249,7 @@ end
-- @param #string From
-- @param #string Event
-- @param #string To
function MISSION:onenterCompleted( From, Event, To )
function MISSION:onenterCOMPLETED( From, Event, To )
self:GetCommandCenter():MessageToCoalition( "Mission " .. self:GetName() .. " has been completed! Good job guys!" )
end
@ -256,7 +258,7 @@ end
-- @param #MISSION self
-- @return #MISSION self
function MISSION:GetName()
return self.Name
return string.format( 'Mission "%s (%s)"', self.Name, self.MissionPriority )
end
--- Add a Unit to join the Mission.
@ -288,19 +290,17 @@ end
-- If the Unit is part of a Task in the Mission, true is returned.
-- @param #MISSION self
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
-- @return #boolean true if Unit is part of a Task in the Mission.
-- @return #MISSION
function MISSION:AbortUnit( PlayerUnit )
self:F( { PlayerUnit = PlayerUnit } )
local PlayerUnitRemoved = false
for TaskID, Task in pairs( self:GetTasks() ) do
if Task:AbortUnit( PlayerUnit ) then
PlayerUnitRemoved = true
end
local Task = Task -- Tasking.Task#TASK
local PlayerGroup = PlayerUnit:GetGroup()
Task:AbortGroup( PlayerGroup )
end
return PlayerUnitRemoved
return self
end
--- Handles a crash of a PlayerUnit from the Mission.
@ -309,19 +309,17 @@ end
-- If the Unit is part of a Task in the Mission, true is returned.
-- @param #MISSION self
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player crashing.
-- @return #boolean true if Unit is part of a Task in the Mission.
-- @return #MISSION
function MISSION:CrashUnit( PlayerUnit )
self:F( { PlayerUnit = PlayerUnit } )
local PlayerUnitRemoved = false
for TaskID, Task in pairs( self:GetTasks() ) do
if Task:CrashUnit( PlayerUnit ) then
PlayerUnitRemoved = true
end
local Task = Task -- Tasking.Task#TASK
local PlayerGroup = PlayerUnit:GetGroup()
Task:CrashGroup( PlayerGroup )
end
return PlayerUnitRemoved
return self
end
--- Add a scoring to the mission.
@ -365,7 +363,7 @@ end
-- @param #MISSION self
-- @param #number MenuTime
function MISSION:SetMenu( MenuTime )
self:F()
self:F( { self:GetName(), MenuTime } )
for _, TaskData in pairs( self:GetTasks() ) do
local Task = TaskData -- Tasking.Task#TASK
@ -377,7 +375,7 @@ end
-- @param #MISSION self
-- @param #number MenuTime
function MISSION:RemoveMenu( MenuTime )
self:F()
self:F( { self:GetName(), MenuTime } )
for _, Task in pairs( self:GetTasks() ) do
local Task = Task -- Tasking.Task#TASK
@ -386,6 +384,58 @@ function MISSION:RemoveMenu( MenuTime )
end
do -- Group Assignment
--- Returns if the @{Mission} is assigned to the Group.
-- @param #MISSION self
-- @param Wrapper.Group#GROUP MissionGroup
-- @return #boolean
function MISSION:IsGroupAssigned( MissionGroup )
local MissionGroupName = MissionGroup:GetName()
if self.AssignedGroups[MissionGroupName] == MissionGroup then
self:T( { "Mission is assigned to:", MissionGroup:GetName() } )
return true
end
self:T( { "Mission is not assigned to:", MissionGroup:GetName() } )
return false
end
--- Set @{Group} assigned to the @{Mission}.
-- @param #MISSION self
-- @param Wrapper.Group#GROUP MissionGroup
-- @return #MISSION
function MISSION:SetGroupAssigned( MissionGroup )
local MissionName = self:GetName()
local MissionGroupName = MissionGroup:GetName()
self.AssignedGroups[MissionGroupName] = MissionGroup
self:E( string.format( "Mission %s is assigned to %s", MissionName, MissionGroupName ) )
return self
end
--- Clear the @{Group} assignment from the @{Mission}.
-- @param #MISSION self
-- @param Wrapper.Group#GROUP MissionGroup
-- @return #MISSION
function MISSION:ClearGroupAssignment( MissionGroup )
local MissionName = self:GetName()
local MissionGroupName = MissionGroup:GetName()
self.AssignedGroups[MissionGroupName] = nil
self:E( string.format( "Mission %s is unassigned to %s", MissionName, MissionGroupName ) )
return self
end
end
--- Gets the COMMANDCENTER.
-- @param #MISSION self
-- @return Tasking.CommandCenter#COMMANDCENTER
@ -489,39 +539,39 @@ function MISSION:GetNextTaskID( Task )
return self.Tasks[TaskName].n
end
--- Is the @{Mission} **Completed**.
--- Is the @{Mission} **COMPLETED**.
-- @param #MISSION self
-- @return #boolean
function MISSION:IsCompleted()
return self:Is( "Completed" )
function MISSION:IsCOMPLETED()
return self:Is( "COMPLETED" )
end
--- Is the @{Mission} **Idle**.
--- Is the @{Mission} **IDLE**.
-- @param #MISSION self
-- @return #boolean
function MISSION:IsIdle()
return self:Is( "Idle" )
function MISSION:IsIDLE()
return self:Is( "IDLE" )
end
--- Is the @{Mission} **Ongoing**.
--- Is the @{Mission} **ENGAGED**.
-- @param #MISSION self
-- @return #boolean
function MISSION:IsOngoing()
return self:Is( "Ongoing" )
function MISSION:IsENGAGED()
return self:Is( "ENGAGED" )
end
--- Is the @{Mission} **Failed**.
--- Is the @{Mission} **FAILED**.
-- @param #MISSION self
-- @return #boolean
function MISSION:IsFailed()
return self:Is( "Failed" )
function MISSION:IsFAILED()
return self:Is( "FAILED" )
end
--- Is the @{Mission} **Hold**.
--- Is the @{Mission} **HOLD**.
-- @param #MISSION self
-- @return #boolean
function MISSION:IsHold()
return self:Is( "Hold" )
function MISSION:IsHOLD()
return self:Is( "HOLD" )
end
--- Validates if the Mission has a Group
@ -556,6 +606,117 @@ function MISSION:GetTasksRemaining()
return TasksRemaining
end
--- @param #MISSION self
-- @return #number
function MISSION:GetTaskTypes()
-- Determine how many tasks are remaining.
local TaskTypeList = {}
local TasksRemaining = 0
for TaskID, Task in pairs( self:GetTasks() ) do
local Task = Task -- Tasking.Task#TASK
local TaskType = Task:GetType()
TaskTypeList[TaskType] = TaskType
end
return TaskTypeList
end
--- Create a status report of the Mission.
-- This reports provides a one liner of the mission status. It indicates how many players and how many Tasks.
--
-- Mission "<MissionName>" - Status "<MissionStatus>"
-- - Task Types: <TaskType>, <TaskType>
-- - <xx> Planned Tasks (xp)
-- - <xx> Assigned Tasks(xp)
-- - <xx> Success Tasks (xp)
-- - <xx> Hold Tasks (xp)
-- - <xx> Cancelled Tasks (xp)
-- - <xx> Aborted Tasks (xp)
-- - <xx> Failed Tasks (xp)
--
-- @param #MISSION self
-- @return #string
function MISSION:ReportStatus()
local Report = REPORT:New()
-- List the name of the mission.
local Name = self:GetName()
-- Determine the status of the mission.
local Status = self:GetState()
local TasksRemaining = self:GetTasksRemaining()
Report:Add( string.format( '%s - Status "%s"', Name, Status ) )
local TaskTypes = self:GetTaskTypes()
Report:Add( string.format( " - Task Types: %s", table.concat(TaskTypes, ", " ) ) )
local TaskStatusList = { "Planned", "Assigned", "Success", "Hold", "Cancelled", "Aborted", "Failed" }
for TaskStatusID, TaskStatus in pairs( TaskStatusList ) do
local TaskCount = 0
local TaskPlayerCount = 0
-- Determine how many tasks are remaining.
for TaskID, Task in pairs( self:GetTasks() ) do
local Task = Task -- Tasking.Task#TASK
if Task:Is( TaskStatus ) then
TaskCount = TaskCount + 1
TaskPlayerCount = TaskPlayerCount + Task:GetPlayerCount()
end
end
if TaskCount > 0 then
Report:Add( string.format( " - %02d %s Tasks (%dp)", TaskCount, TaskStatus, TaskPlayerCount ) )
end
end
return Report:Text()
end
--- Create a player report of the Mission.
-- This reports provides a one liner of the mission status. It indicates how many players and how many Tasks.
--
-- Mission "<MissionName>" - Status "<MissionStatus>"
-- - Player "<PlayerName>: Task <TaskName> <TaskStatus>, Task <TaskName> <TaskStatus>
-- - Player <PlayerName>: Task <TaskName> <TaskStatus>, Task <TaskName> <TaskStatus>
-- - ..
--
-- @param #MISSION self
-- @return #string
function MISSION:ReportPlayers()
local Report = REPORT:New()
-- List the name of the mission.
local Name = self:GetName()
-- Determine the status of the mission.
local Status = self:GetState()
local TasksRemaining = self:GetTasksRemaining()
Report:Add( string.format( '%s - Status "%s"', Name, Status ) )
local PlayerList = {}
-- Determine how many tasks are remaining.
for TaskID, Task in pairs( self:GetTasks() ) do
local Task = Task -- Tasking.Task#TASK
local PlayerNames = Task:GetPlayerNames()
for PlayerID, PlayerName in pairs( PlayerNames ) do
PlayerList[PlayerName] = Task:GetName()
end
end
for PlayerName, TaskName in pairs( PlayerList ) do
Report:Add( string.format( ' - Player (%s): Task "%s"', PlayerName, TaskName ) )
end
return Report:Text()
end
--- Create a summary report of the Mission (one line).
-- @param #MISSION self
-- @return #string
@ -595,7 +756,7 @@ function MISSION:ReportOverview( TaskStatus )
local Status = self:GetState()
local TasksRemaining = self:GetTasksRemaining()
Report:Add( "Mission " .. Name .. " - " .. Status .. " Task Report ")
Report:Add( string.format( '%s - Status "%s"', Name, Status ) )
-- Determine how many tasks are remaining.
local TasksRemaining = 0
@ -622,7 +783,7 @@ function MISSION:ReportDetails()
-- Determine the status of the mission.
local Status = self:GetState()
Report:Add( "Mission " .. Name .. " - " .. Status )
Report:Add( string.format( '%s - Status "%s"', Name, Status ) )
-- Determine how many tasks are remaining.
local TasksRemaining = 0
@ -641,7 +802,6 @@ end
-- Tasks = Mission:GetTasks()
-- env.info( "Task 2 Completion = " .. Tasks[2]:GetGoalPercentage() .. "%" )
function MISSION:GetTasks()
self:F()
return self.Tasks
end

View File

@ -78,6 +78,7 @@ TASK = {
Mission = nil,
CommandCenter = nil,
TimeOut = 0,
AssignedGroups = {},
}
--- FSM PlayerAborted event handler prototype for TASK.
@ -156,14 +157,15 @@ TASK = {
-- @param #string TaskName The name of the Task
-- @param #string TaskType The type of the Task
-- @return #TASK self
function TASK:New( Mission, SetGroupAssign, TaskName, TaskType )
function TASK:New( Mission, SetGroupAssign, TaskName, TaskType, TaskBriefing )
local self = BASE:Inherit( self, FSM_TASK:New() ) -- Core.Fsm#FSM_TASK
local self = BASE:Inherit( self, FSM_TASK:New() ) -- Tasking.Task#TASK
self:SetStartState( "Planned" )
self:AddTransition( "Planned", "Assign", "Assigned" )
self:AddTransition( "Assigned", "AssignUnit", "Assigned" )
self:AddTransition( "Assigned", "Success", "Success" )
self:AddTransition( "Assigned", "Hold", "Hold" )
self:AddTransition( "Assigned", "Fail", "Failed" )
self:AddTransition( "Assigned", "Abort", "Aborted" )
self:AddTransition( "Assigned", "Cancel", "Cancelled" )
@ -187,7 +189,7 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType )
self:SetName( TaskName )
self:SetID( Mission:GetNextTaskID( self ) ) -- The Mission orchestrates the task sequences ..
self.TaskBriefing = "You are invited for the task: " .. self.TaskName .. "."
self:SetBriefing( TaskBriefing )
self.FsmTemplate = self.FsmTemplate or FSM_PROCESS:New()
@ -241,9 +243,9 @@ function TASK:JoinUnit( PlayerUnit, PlayerGroup )
--self:MessageToGroups( PlayerUnit:GetPlayerName() .. " is planning to join Task " .. self:GetName() )
end
if self:IsStateAssigned() then
local IsAssignedToGroup = self:IsAssignedToGroup( PlayerGroup )
self:E( { IsAssignedToGroup = IsAssignedToGroup } )
if IsAssignedToGroup then
local IsGroupAssigned = self:IsGroupAssigned( PlayerGroup )
self:E( { IsGroupAssigned = IsGroupAssigned } )
if IsGroupAssigned then
self:AssignToUnit( PlayerUnit )
self:MessageToGroups( PlayerUnit:GetPlayerName() .. " joined Task " .. self:GetName() )
end
@ -258,14 +260,11 @@ end
-- If the Unit is part of the Task, true is returned.
-- @param #TASK self
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player aborting the Task.
-- @return #boolean true if Unit is part of the Task.
function TASK:AbortUnit( PlayerUnit )
self:F( { PlayerUnit = PlayerUnit } )
local PlayerUnitAborted = false
-- @return #TASK
function TASK:AbortGroup( PlayerGroup )
self:F( { PlayerGroup = PlayerGroup } )
local PlayerGroups = self:GetGroups()
local PlayerGroup = PlayerUnit:GetGroup()
-- Is the PlayerGroup part of the PlayerGroups?
if PlayerGroups:IsIncludeObject( PlayerGroup ) then
@ -273,25 +272,39 @@ function TASK:AbortUnit( PlayerUnit )
-- Check if the PlayerGroup is already assigned to the Task. If yes, the PlayerGroup is aborted from the Task.
-- If the PlayerUnit was the last unit of the PlayerGroup, the menu needs to be removed from the Group.
if self:IsStateAssigned() then
local IsAssignedToGroup = self:IsAssignedToGroup( PlayerGroup )
self:E( { IsAssignedToGroup = IsAssignedToGroup } )
if IsAssignedToGroup then
local PlayerName = PlayerUnit:GetPlayerName()
self:UnAssignFromUnit( PlayerUnit )
local IsGroupAssigned = self:IsGroupAssigned( PlayerGroup )
self:E( { IsGroupAssigned = IsGroupAssigned } )
if IsGroupAssigned then
local PlayerName = PlayerGroup:GetUnit(1):GetPlayerName()
self:MessageToGroups( PlayerName .. " aborted Task " .. self:GetName() )
self:E( { TaskGroup = PlayerGroup:GetName(), GetUnits = PlayerGroup:GetUnits() } )
if #PlayerGroup:GetUnits() == 1 then
self:UnAssignFromGroup( PlayerGroup )
PlayerGroup:SetState( PlayerGroup, "Assigned", nil )
self:RemoveMenuForGroup( PlayerGroup )
self:UnAssignFromGroup( PlayerGroup )
--self:Abort()
-- Now check if the task needs to go to hold...
-- It will go to hold, if there are no players in the mission...
PlayerGroups:Flush()
local IsRemaining = false
for GroupName, AssignedGroup in pairs( PlayerGroups:GetSet() or {} ) do
if self:IsGroupAssigned( AssignedGroup ) == true then
IsRemaining = true
self:F( { Task = self:GetName(), IsRemaining = IsRemaining } )
break
end
end
self:Abort()
self:PlayerAborted( PlayerUnit )
self:F( { Task = self:GetName(), IsRemaining = IsRemaining } )
if IsRemaining == false then
self:Abort()
end
self:PlayerAborted( PlayerGroup:GetUnit(1) )
end
end
end
return PlayerUnitAborted
return self
end
--- A PlayerUnit crashed in a Task. Abort the Player.
@ -299,14 +312,11 @@ end
-- If the Unit is part of the Task, true is returned.
-- @param #TASK self
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player aborting the Task.
-- @return #boolean true if Unit is part of the Task.
function TASK:CrashUnit( PlayerUnit )
self:F( { PlayerUnit = PlayerUnit } )
local PlayerUnitCrashed = false
-- @return #TASK
function TASK:CrashGroup( PlayerGroup )
self:F( { PlayerGroup = PlayerGroup } )
local PlayerGroups = self:GetGroups()
local PlayerGroup = PlayerUnit:GetGroup()
-- Is the PlayerGroup part of the PlayerGroups?
if PlayerGroups:IsIncludeObject( PlayerGroup ) then
@ -314,22 +324,38 @@ function TASK:CrashUnit( PlayerUnit )
-- Check if the PlayerGroup is already assigned to the Task. If yes, the PlayerGroup is aborted from the Task.
-- If the PlayerUnit was the last unit of the PlayerGroup, the menu needs to be removed from the Group.
if self:IsStateAssigned() then
local IsAssignedToGroup = self:IsAssignedToGroup( PlayerGroup )
self:E( { IsAssignedToGroup = IsAssignedToGroup } )
if IsAssignedToGroup then
self:UnAssignFromUnit( PlayerUnit )
self:MessageToGroups( PlayerUnit:GetPlayerName() .. " crashed in Task " .. self:GetName() )
self:E( { TaskGroup = PlayerGroup:GetName(), GetUnits = PlayerGroup:GetUnits() } )
if #PlayerGroup:GetUnits() == 1 then
PlayerGroup:SetState( PlayerGroup, "Assigned", nil )
self:RemoveMenuForGroup( PlayerGroup )
local IsGroupAssigned = self:IsGroupAssigned( PlayerGroup )
self:E( { IsGroupAssigned = IsGroupAssigned } )
if IsGroupAssigned then
local PlayerName = PlayerGroup:GetUnit(1):GetPlayerName()
self:MessageToGroups( PlayerName .. " crashed! " )
self:UnAssignFromGroup( PlayerGroup )
-- Now check if the task needs to go to hold...
-- It will go to hold, if there are no players in the mission...
PlayerGroups:Flush()
local IsRemaining = false
for GroupName, AssignedGroup in pairs( PlayerGroups:GetSet() or {} ) do
if self:IsGroupAssigned( AssignedGroup ) == true then
IsRemaining = true
self:F( { Task = self:GetName(), IsRemaining = IsRemaining } )
break
end
end
self:PlayerCrashed( PlayerUnit )
self:F( { Task = self:GetName(), IsRemaining = IsRemaining } )
if IsRemaining == false then
self:Abort()
end
self:PlayerCrashed( PlayerGroup:GetUnit(1) )
end
end
end
return PlayerUnitCrashed
return self
end
@ -350,39 +376,148 @@ function TASK:GetGroups()
return self.SetGroup
end
do -- Group Assignment
--- Assign the @{Task} to a @{Group}.
-- @param #TASK self
-- @param Wrapper.Group#GROUP TaskGroup
-- @return #TASK
function TASK:AssignToGroup( TaskGroup )
self:F2( TaskGroup:GetName() )
--- Returns if the @{Task} is assigned to the Group.
-- @param #TASK self
-- @param Wrapper.Group#GROUP TaskGroup
-- @return #boolean
function TASK:IsGroupAssigned( TaskGroup )
local TaskGroupName = TaskGroup:GetName()
TaskGroup:SetState( TaskGroup, "Assigned", self )
local Mission = self:GetMission()
local MissionMenu = Mission:GetMenu( TaskGroup )
MissionMenu:RemoveSubMenus()
--self:RemoveMenuForGroup( TaskGroup )
self:SetAssignedMenuForGroup( TaskGroup )
local TaskUnits = TaskGroup:GetUnits()
for UnitID, UnitData in pairs( TaskUnits ) do
local TaskUnit = UnitData -- Wrapper.Unit#UNIT
local PlayerName = TaskUnit:GetPlayerName()
self:E(PlayerName)
if PlayerName ~= nil or PlayerName ~= "" then
self:AssignToUnit( TaskUnit )
local TaskGroupName = TaskGroup:GetName()
if self.AssignedGroups[TaskGroupName] then
self:T( { "Task is assigned to:", TaskGroup:GetName() } )
return true
end
self:T( { "Task is not assigned to:", TaskGroup:GetName() } )
return false
end
--- Set @{Group} assigned to the @{Task}.
-- @param #TASK self
-- @param Wrapper.Group#GROUP TaskGroup
-- @return #TASK
function TASK:SetGroupAssigned( TaskGroup )
local TaskName = self:GetName()
local TaskGroupName = TaskGroup:GetName()
self.AssignedGroups[TaskGroupName] = TaskGroup
self:E( string.format( "Task %s is assigned to %s", TaskName, TaskGroupName ) )
-- Set the group to be assigned at mission level. This allows to decide the menu options on mission level for this group.
self:GetMission():SetGroupAssigned( TaskGroup )
local SetAssignedGroups = self:GetGroups()
-- SetAssignedGroups:ForEachGroup(
-- function( AssignedGroup )
-- if self:IsGroupAssigned(AssignedGroup) then
-- self:GetMission():GetCommandCenter():MessageToGroup( string.format( "Task %s is assigned to group %s.", TaskName, TaskGroupName ), AssignedGroup )
-- else
-- self:GetMission():GetCommandCenter():MessageToGroup( string.format( "Task %s is assigned to your group.", TaskName ), AssignedGroup )
-- end
-- end
-- )
return self
end
--- Clear the @{Group} assignment from the @{Task}.
-- @param #TASK self
-- @param Wrapper.Group#GROUP TaskGroup
-- @return #TASK
function TASK:ClearGroupAssignment( TaskGroup )
local TaskName = self:GetName()
local TaskGroupName = TaskGroup:GetName()
self.AssignedGroups[TaskGroupName] = nil
self:E( string.format( "Task %s is unassigned to %s", TaskName, TaskGroupName ) )
-- Set the group to be assigned at mission level. This allows to decide the menu options on mission level for this group.
self:GetMission():ClearGroupAssignment( TaskGroup )
local SetAssignedGroups = self:GetGroups()
SetAssignedGroups:ForEachGroup(
function( AssignedGroup )
if self:IsGroupAssigned(AssignedGroup) then
self:GetMission():GetCommandCenter():MessageToGroup( string.format( "Task %s is unassigned from group %s.", TaskName, TaskGroupName ), AssignedGroup )
else
self:GetMission():GetCommandCenter():MessageToGroup( string.format( "Task %s is unassigned from your group.", TaskName ), AssignedGroup )
end
end
)
return self
end
return self
end
do -- Group Assignment
--- Assign the @{Task} to a @{Group}.
-- @param #TASK self
-- @param Wrapper.Group#GROUP TaskGroup
-- @return #TASK
function TASK:AssignToGroup( TaskGroup )
self:F( TaskGroup:GetName() )
local TaskGroupName = TaskGroup:GetName()
local Mission = self:GetMission()
local CommandCenter = Mission:GetCommandCenter()
self:SetGroupAssigned( TaskGroup )
local TaskUnits = TaskGroup:GetUnits()
for UnitID, UnitData in pairs( TaskUnits ) do
local TaskUnit = UnitData -- Wrapper.Unit#UNIT
local PlayerName = TaskUnit:GetPlayerName()
self:E(PlayerName)
if PlayerName ~= nil or PlayerName ~= "" then
self:AssignToUnit( TaskUnit )
CommandCenter:MessageToGroup(
string.format( 'Task "%s": Briefing for player (%s):\n%s',
self:GetName(),
PlayerName,
self:GetBriefing()
), TaskGroup
)
end
end
CommandCenter:SetMenu()
return self
end
--- UnAssign the @{Task} from a @{Group}.
-- @param #TASK self
function TASK:UnAssignFromGroup( TaskGroup )
self:F2( { TaskGroup } )
self:ClearGroupAssignment( TaskGroup )
local TaskUnits = TaskGroup:GetUnits()
for UnitID, UnitData in pairs( TaskUnits ) do
local TaskUnit = UnitData -- Wrapper.Unit#UNIT
local PlayerName = TaskUnit:GetPlayerName()
if PlayerName ~= nil or PlayerName ~= "" then
self:UnAssignFromUnit( TaskUnit )
end
end
local Mission = self:GetMission()
local CommandCenter = Mission:GetCommandCenter()
CommandCenter:SetMenu()
end
end
---
-- @param #TASK self
-- @param Wrapper.Group#GROUP FindGroup
@ -458,7 +593,7 @@ function TASK:SendBriefingToAssignedGroups()
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetSet() ) do
if self:IsAssignedToGroup( TaskGroup ) then
if self:IsGroupAssigned( TaskGroup ) then
TaskGroup:Message( self.TaskBriefing, 60 )
end
end
@ -471,50 +606,14 @@ function TASK:UnAssignFromGroups()
self:F2()
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetSet() ) do
self:UnAssignFromGroup( TaskGroup )
end
end
--- UnAssign the @{Task} from a @{Group}.
-- @param #TASK self
function TASK:UnAssignFromGroup( TaskGroup )
self:F2( { TaskGroup } )
TaskGroup:SetState( TaskGroup, "Assigned", nil )
self:RemoveAssignedMenuForGroup( TaskGroup )
local TaskUnits = TaskGroup:GetUnits()
for UnitID, UnitData in pairs( TaskUnits ) do
local TaskUnit = UnitData -- Wrapper.Unit#UNIT
local PlayerName = TaskUnit:GetPlayerName()
if PlayerName ~= nil or PlayerName ~= "" then
self:UnAssignFromUnit( TaskUnit )
if self:IsGroupAssigned(TaskGroup) then
self:UnAssignFromGroup( TaskGroup )
end
end
end
--- Returns if the @{Task} is assigned to the Group.
-- @param #TASK self
-- @param Wrapper.Group#GROUP TaskGroup
-- @return #boolean
function TASK:IsAssignedToGroup( TaskGroup )
local TaskGroupName = TaskGroup:GetName()
if self:IsStateAssigned() then
if TaskGroup:GetState( TaskGroup, "Assigned" ) == self then
self:T( { "Task is assigned to:", TaskGroup:GetName() } )
return true
end
end
self:T( { "Task is not assigned to:", TaskGroup:GetName() } )
return false
end
--- Returns if the @{Task} has still alive and assigned Units.
-- @param #TASK self
-- @return #boolean
@ -523,7 +622,7 @@ function TASK:HasAliveUnits()
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
if self:IsStateAssigned() then
if self:IsAssignedToGroup( TaskGroup ) then
if self:IsGroupAssigned( TaskGroup ) then
for TaskUnitID, TaskUnit in pairs( TaskGroup:GetUnits() ) do
if TaskUnit:IsAlive() then
self:T( { HasAliveUnits = true } )
@ -543,9 +642,9 @@ end
-- @param #number MenuTime
-- @return #TASK
function TASK:SetMenu( MenuTime ) --R2.1 Mission Reports and Task Reports added. Fixes issue #424.
self:F()
self:F( { self:GetName(), MenuTime } )
self.SetGroup:Flush()
--self.SetGroup:Flush()
for TaskGroupID, TaskGroupData in pairs( self.SetGroup:GetSet() ) do
local TaskGroup = TaskGroupData -- Wrapper.Group#GROUP
if TaskGroup:IsAlive() and TaskGroup:GetPlayerNames() then
@ -558,15 +657,15 @@ function TASK:SetMenu( MenuTime ) --R2.1 Mission Reports and Task Reports added.
TaskGroup.MenuReports = MENU_GROUP:New( TaskGroup, "Reports", MissionMenu )
MENU_GROUP_COMMAND:New( TaskGroup, "Report Tasks", TaskGroup.MenuReports, Mission.MenuReportSummary, Mission, TaskGroup )
MENU_GROUP_COMMAND:New( TaskGroup, "Report Planned Tasks", TaskGroup.MenuReports, Mission.MenuReportOverview, Mission, TaskGroup, "Planned" )
MENU_GROUP_COMMAND:New( TaskGroup, "Report Ongoing Tasks", TaskGroup.MenuReports, Mission.MenuReportOverview, Mission, TaskGroup, "Ongoing" )
MENU_GROUP_COMMAND:New( TaskGroup, "Report Assigned Tasks", TaskGroup.MenuReports, Mission.MenuReportOverview, Mission, TaskGroup, "Assigned" )
MENU_GROUP_COMMAND:New( TaskGroup, "Report Successful Tasks", TaskGroup.MenuReports, Mission.MenuReportOverview, Mission, TaskGroup, "Success" )
MENU_GROUP_COMMAND:New( TaskGroup, "Report Failed Tasks", TaskGroup.MenuReports, Mission.MenuReportOverview, Mission, TaskGroup, "Failed" )
MENU_GROUP_COMMAND:New( TaskGroup, "Report Held Tasks", TaskGroup.MenuReports, Mission.MenuReportOverview, Mission, TaskGroup, "Hold" )
end
if self:IsStatePlanned() or self:IsStateReplanned() then
-- if self:IsStatePlanned() or self:IsStateReplanned() then
self:SetMenuForGroup( TaskGroup, MenuTime )
end
-- end
end
end
end
@ -579,12 +678,9 @@ end
-- @return #TASK
function TASK:SetMenuForGroup( TaskGroup, MenuTime )
if not TaskGroup:GetState( TaskGroup, "Assigned" ) then
self:SetPlannedMenuForGroup( TaskGroup, self:GetTaskName(), MenuTime )
else
if not self:IsAssignedToGroup( TaskGroup ) then
self:SetAssignedMenuForGroup( TaskGroup, MenuTime )
end
self:SetPlannedMenuForGroup( TaskGroup, MenuTime )
if self:IsGroupAssigned( TaskGroup ) then
self:SetAssignedMenuForGroup( TaskGroup, MenuTime )
end
end
@ -595,7 +691,7 @@ end
-- @param #string MenuText The menu text.
-- @param #number MenuTime
-- @return #TASK self
function TASK:SetPlannedMenuForGroup( TaskGroup, MenuText, MenuTime )
function TASK:SetPlannedMenuForGroup( TaskGroup, MenuTime )
self:E( TaskGroup:GetName() )
local Mission = self:GetMission()
@ -603,14 +699,26 @@ function TASK:SetPlannedMenuForGroup( TaskGroup, MenuText, MenuTime )
local CommandCenter = Mission:GetCommandCenter()
local CommandCenterMenu = CommandCenter:GetMenu()
local TaskType = self:GetType()
-- local TaskThreatLevel = self.TaskInfo["ThreatLevel"]
-- local TaskThreatLevelString = TaskThreatLevel and " [" .. string.rep( "■", TaskThreatLevel ) .. "]" or " []"
local TaskPlayerCount = self:GetPlayerCount()
local TaskPlayerString = string.format( " (%dp)", TaskPlayerCount )
local TaskText = string.format( "%s%s", self:GetName(), TaskPlayerString ) --, TaskThreatLevelString )
local TaskName = string.format( "%s", self:GetName() )
local MissionMenu = MENU_GROUP:New( TaskGroup, MissionName, CommandCenterMenu ):SetTime( MenuTime )
local MissionMenu = Mission:GetMenu( TaskGroup )
local TaskType = self:GetType()
local TaskTypeMenu = MENU_GROUP:New( TaskGroup, TaskType, MissionMenu ):SetTime( MenuTime )
local TaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, MenuText, TaskTypeMenu, self.MenuAssignToGroup, { self = self, TaskGroup = TaskGroup } ):SetTime( MenuTime ):SetRemoveParent( true )
local TaskPlannedMenu = MENU_GROUP:New( TaskGroup, "Planned Tasks", MissionMenu ):SetTime( MenuTime )
local TaskTypeMenu = MENU_GROUP:New( TaskGroup, TaskType, TaskPlannedMenu ):SetTime( MenuTime ):SetRemoveParent( true )
local TaskTypeMenu = MENU_GROUP:New( TaskGroup, TaskText, TaskTypeMenu ):SetTime( MenuTime ):SetRemoveParent( true )
local ReportTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Report Task Status" ), TaskTypeMenu, self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetRemoveParent( true )
if not Mission:IsGroupAssigned( TaskGroup ) then
local JoinTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Join Task" ), TaskTypeMenu, self.MenuAssignToGroup, { self = self, TaskGroup = TaskGroup } ):SetTime( MenuTime ):SetRemoveParent( true )
end
return self
end
@ -621,15 +729,27 @@ end
-- @param #number MenuTime
-- @return #TASK self
function TASK:SetAssignedMenuForGroup( TaskGroup, MenuTime )
self:E( TaskGroup:GetName() )
self:F( { TaskGroup:GetName(), MenuTime } )
local Mission = self:GetMission()
local MissionName = Mission:GetName()
local CommandCenter = Mission:GetCommandCenter()
local CommandCenterMenu = CommandCenter:GetMenu()
local TaskType = self:GetType()
-- local TaskThreatLevel = self.TaskInfo["ThreatLevel"]
-- local TaskThreatLevelString = TaskThreatLevel and " [" .. string.rep( "■", TaskThreatLevel ) .. "]" or " []"
local TaskPlayerCount = self:GetPlayerCount()
local TaskPlayerString = string.format( " (%dp)", TaskPlayerCount )
local TaskText = string.format( "%s%s", self:GetName(), TaskPlayerString ) --, TaskThreatLevelString )
local TaskName = string.format( "%s", self:GetName() )
local MissionMenu = MENU_GROUP:New( TaskGroup, MissionName, CommandCenterMenu ):SetTime( MenuTime )
local MissionMenu = Mission:GetMenu( TaskGroup )
self:E( { MissionMenu = MissionMenu } )
local TaskTypeMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Task Status", MissionMenu, self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime )
local TaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Abort Task", MissionMenu, self.MenuTaskAbort, self, TaskGroup ):SetTime( MenuTime )
local TaskAssignedMenu = MENU_GROUP:New( TaskGroup, string.format( "Assigned Task %s", TaskName ), MissionMenu ):SetTime( MenuTime )
local TaskTypeMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Report Task Status" ), TaskAssignedMenu, self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetRemoveParent( true )
local TaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Abort Group from Task" ), TaskAssignedMenu, self.MenuTaskAbort, self, TaskGroup ):SetTime( MenuTime ):SetRemoveParent( true )
return self
end
@ -639,14 +759,12 @@ end
-- @param #number MenuTime
-- @return #TASK
function TASK:RemoveMenu( MenuTime )
self:F()
self:F( { self:GetName(), MenuTime } )
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
if TaskGroup:IsAlive() and TaskGroup:GetPlayerNames() then
if not self:IsAssignedToGroup( TaskGroup ) then
self:RemovePlannedMenuForGroup( TaskGroup, MenuTime )
end
self:RefreshMenus( TaskGroup, MenuTime )
end
end
end
@ -657,24 +775,26 @@ end
-- @param Wrapper.Group#GROUP TaskGroup
-- @param #number MenuTime
-- @return #TASK self
function TASK:RemovePlannedMenuForGroup( TaskGroup, MenuTime )
self:F()
function TASK:RefreshMenus( TaskGroup, MenuTime )
self:F( { TaskGroup:GetName(), MenuTime } )
local Mission = self:GetMission()
local MissionName = Mission:GetName()
local CommandCenter = Mission:GetCommandCenter()
local CommandCenterMenu = CommandCenter:GetMenu()
local MissionMenu = Mission:GetMenu( TaskGroup )
local TaskName = self:GetName()
local PlannedMenu = MissionMenu:GetMenu( "Planned Tasks" )
local AssignedMenu = MissionMenu:GetMenu( string.format( "Assigned Task %s", TaskName ) )
if MissionMenu then
local TaskType = self:GetType()
local TypeMenu = MissionMenu:GetMenu( TaskType )
if TypeMenu then
local TaskMenu = TypeMenu:GetMenu( self:GetTaskName() )
if TaskMenu then
TaskMenu:Remove( MenuTime )
end
end
if PlannedMenu then
PlannedMenu:Remove( MenuTime )
end
if AssignedMenu then
AssignedMenu:Remove( MenuTime )
end
end
@ -723,7 +843,7 @@ end
-- @param #TASK self
function TASK:MenuTaskAbort( TaskGroup )
self:Abort()
self:AbortGroup( TaskGroup )
end
@ -735,6 +855,13 @@ function TASK:GetTaskName()
return self.TaskName
end
--- Returns the @{Task} briefing.
-- @param #TASK self
-- @return #string Task briefing.
function TASK:GetTaskBriefing()
return self.TaskBriefing
end
@ -794,11 +921,14 @@ end
function TASK:RemoveStateMachine( TaskUnit )
self:F( { TaskUnit, self.Fsm[TaskUnit] ~= nil } )
self:E( self.Fsm )
for TaskUnitT, Fsm in pairs( self.Fsm ) do
self:E( TaskUnitT )
end
--self:E( self.Fsm )
--for TaskUnitT, Fsm in pairs( self.Fsm ) do
--local Fsm = Fsm -- Core.Fsm#FSM_PROCESS
--self:E( TaskUnitT )
--self.Fsm[TaskUnit] = nil
--end
self.Fsm[TaskUnit]:Remove()
self.Fsm[TaskUnit] = nil
collectgarbage()
@ -1001,10 +1131,18 @@ end
-- @param #string TaskBriefing
-- @return #TASK self
function TASK:SetBriefing( TaskBriefing )
self:E(TaskBriefing)
self.TaskBriefing = TaskBriefing
return self
end
--- Gets the @{Task} briefing.
-- @param #TASK self
-- @return #string The briefing text.
function TASK:GetBriefing()
return self.TaskBriefing
end
@ -1017,14 +1155,17 @@ function TASK:onenterAssigned( From, Event, To, PlayerUnit, PlayerName )
self:E( { "Task Assigned", self.Dispatcher } )
self:MessageToGroups( "Task " .. self:GetName() .. " has been assigned to your group." )
if self.Dispatcher then
self:E( "Firing Assign event " )
self.Dispatcher:Assign( self, PlayerUnit, PlayerName )
if From ~= "Assigned" then
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " is assigned." )
if self.Dispatcher then
self:E( "Firing Assign event " )
self.Dispatcher:Assign( self, PlayerUnit, PlayerName )
end
self:GetMission():__Start( 1 )
self:SetMenu()
end
self:GetMission():__Start( 1 )
end
@ -1053,12 +1194,13 @@ end
function TASK:onenterAborted( From, Event, To )
self:E( "Task Aborted" )
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " has been aborted! Task may be replanned." )
self:UnAssignFromGroups()
if From ~= "Aborted" then
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " has been aborted! Task may be replanned." )
self:__Replan( 5 )
self:SetMenu()
end
self:__Replan( 5 )
end
--- FSM function for a TASK
@ -1098,7 +1240,7 @@ end
function TASK:onstatechange( From, Event, To )
if self:IsTrace() then
MESSAGE:New( "@ Task " .. self.TaskName .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
--MESSAGE:New( "@ Task " .. self.TaskName .. " : " .. From .. " changed to " .. To .. " by " .. Event, 2 ):ToAll()
end
if self.Scores[To] then
@ -1189,6 +1331,47 @@ function TASK:ReportOverview() --R2.1 fixed report. Now nicely formatted and con
return Report:Text()
end
--- Create a count of the players in the Task.
-- @param #TASK self
-- @return #number The total number of players in the task.
function TASK:GetPlayerCount() --R2.1 Get a count of the players.
local PlayerCount = 0
-- Loop each Unit active in the Task, and find Player Names.
for TaskGroupID, PlayerGroup in pairs( self:GetGroups():GetSet() ) do
local PlayerGroup = PlayerGroup -- Wrapper.Group#GROUP
if self:IsGroupAssigned( PlayerGroup ) then
local PlayerNames = PlayerGroup:GetPlayerNames()
PlayerCount = PlayerCount + #PlayerNames
end
end
return PlayerCount
end
--- Create a list of the players in the Task.
-- @param #TASK self
-- @return #map<#string,Wrapper.Group#GROUP> A map of the players
function TASK:GetPlayerNames() --R2.1 Get a map of the players.
local PlayerNameMap = {}
-- Loop each Unit active in the Task, and find Player Names.
for TaskGroupID, PlayerGroup in pairs( self:GetGroups():GetSet() ) do
local PlayerGroup = PlayerGroup -- Wrapper.Group#GROUP
if self:IsGroupAssigned( PlayerGroup ) then
local PlayerNames = PlayerGroup:GetPlayerNames()
for PlayerNameID, PlayerName in pairs( PlayerNames ) do
PlayerNameMap[PlayerName] = PlayerGroup
end
end
end
return PlayerNameMap
end
--- Create a detailed report of the Task.
-- List the Task Status, and the Players assigned to the Task.
@ -1203,18 +1386,13 @@ function TASK:ReportDetails() --R2.1 fixed report. Now nicely formatted and cont
-- Determine the status of the Task.
local State = self:GetState()
-- Loop each Unit active in the Task, and find Player Names.
local PlayerNames = {}
local PlayerNames = self:GetPlayerNames()
local PlayerReport = REPORT:New()
for PlayerGroupID, PlayerGroupData in pairs( self:GetGroups():GetSet() ) do
local PlayerGroup = PlayerGroupData -- Wrapper.Group#GROUP
PlayerNames = PlayerGroup:GetPlayerNames()
if PlayerNames then
PlayerReport:Add( "Group " .. PlayerGroup:GetCallsign() .. ": " .. table.concat( PlayerNames, ", " ) )
end
for PlayerName, PlayerGroup in pairs( PlayerNames ) do
PlayerReport:Add( "Group " .. PlayerGroup:GetCallsign() .. ": " .. PlayerName )
end
local Players = PlayerReport:Text()

View File

@ -86,15 +86,13 @@ do -- TASK_A2G
-- @param Core.Zone#ZONE_BASE TargetZone The target zone, if known.
-- If the TargetZone parameter is specified, the player will be routed to the center of the zone where all the targets are assumed to be.
-- @return #TASK_A2G self
function TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskType )
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, TaskType ) ) -- Tasking.Task#TASK_A2G
function TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskType, TaskBriefing )
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, TaskType, TaskBriefing ) ) -- Tasking.Task#TASK_A2G
self:F()
self.TargetSetUnit = TargetSetUnit
self.TaskType = TaskType
Mission:AddTask( self )
local Fsm = self:GetUnitProcess()
@ -366,14 +364,28 @@ do -- TASK_SEAD
--- Instantiates a new TASK_SEAD.
-- @param #TASK_SEAD self
-- @param Tasking.Mission#MISSION Mission
-- @param Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param Core.Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param #string TaskName The name of the Task.
-- @param Set#SET_UNIT TargetSetUnit
-- @param Core.Set#SET_UNIT TargetSetUnit
-- @param #string TaskBriefing The briefing of the task.
-- @return #TASK_SEAD self
function TASK_SEAD:New( Mission, SetGroup, TaskName, TargetSetUnit )
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "SEAD" ) ) -- #TASK_SEAD
function TASK_SEAD:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "SEAD", TaskBriefing ) ) -- #TASK_SEAD
self:F()
Mission:AddTask( self )
local TargetCoord = TargetSetUnit:GetFirst():GetCoordinate()
local TargetPositionText = TargetCoord:ToString()
local TargetThreatLevel = TargetSetUnit:CalculateThreatLevelA2G()
self:SetBriefing(
TaskBriefing or
"Execute a Suppression of Enemy Air Defenses.\n" ..
"Initial Coordinates: " .. TargetPositionText .. "\n" ..
"Threat Level: [" .. string.rep( "", TargetThreatLevel ) .. "]"
)
return self
end
@ -392,17 +404,28 @@ do -- TASK_BAI
--- Instantiates a new TASK_BAI.
-- @param #TASK_BAI self
-- @param Tasking.Mission#MISSION Mission
-- @param Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param Core.Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param #string TaskName The name of the Task.
-- @param Set#SET_UNIT UnitSetTargets
-- @param #number TargetDistance The distance to Target when the Player is considered to have "arrived" at the engagement range.
-- @param Core.Zone#ZONE_BASE TargetZone The target zone, if known.
-- If the TargetZone parameter is specified, the player will be routed to the center of the zone where all the targets are assumed to be.
-- @param Core.Set#SET_UNIT TargetSetUnit
-- @param #string TaskBriefing The briefing of the task.
-- @return #TASK_BAI self
function TASK_BAI:New( Mission, SetGroup, TaskName, TargetSetUnit )
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "BAI" ) ) -- #TASK_BAI
function TASK_BAI:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "BAI", TaskBriefing ) ) -- #TASK_BAI
self:F()
Mission:AddTask( self )
local TargetCoord = TargetSetUnit:GetFirst():GetCoordinate()
local TargetPositionText = TargetCoord:ToString()
local TargetThreatLevel = TargetSetUnit:CalculateThreatLevelA2G()
self:SetBriefing(
TaskBriefing or
"Execute a Battleground Air Interdiction of a group of enemy targets.\n" ..
"Initial Coordinates: " .. TargetPositionText .. "\n" ..
"Threat Level: [" .. string.rep( "", TargetThreatLevel ) .. "]"
)
return self
end
@ -421,17 +444,29 @@ do -- TASK_CAS
--- Instantiates a new TASK_CAS.
-- @param #TASK_CAS self
-- @param Tasking.Mission#MISSION Mission
-- @param Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param Core.Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param #string TaskName The name of the Task.
-- @param Set#SET_UNIT UnitSetTargets
-- @param #number TargetDistance The distance to Target when the Player is considered to have "arrived" at the engagement range.
-- @param Core.Zone#ZONE_BASE TargetZone The target zone, if known.
-- If the TargetZone parameter is specified, the player will be routed to the center of the zone where all the targets are assumed to be.
-- @param Core.Set#SET_UNIT TargetSetUnit
-- @param #string TaskBriefing The briefing of the task.
-- @return #TASK_CAS self
function TASK_CAS:New( Mission, SetGroup, TaskName, TargetSetUnit )
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "CAS" ) ) -- #TASK_CAS
function TASK_CAS:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "CAS", TaskBriefing ) ) -- #TASK_CAS
self:F()
Mission:AddTask( self )
local TargetCoord = TargetSetUnit:GetFirst():GetCoordinate()
local TargetPositionText = TargetCoord:ToString()
local TargetThreatLevel = TargetSetUnit:CalculateThreatLevelA2G()
self:SetBriefing(
TaskBriefing or
"Execute a Close Air Support for a group of enemy targets.\n" ..
"Beware of friendlies at the vicinity!\n" ..
"Initial Coordinates: " .. TargetPositionText .. "\n" ..
"Threat Level: [" .. string.rep( "", TargetThreatLevel ) .. "]"
)
return self
end

View File

@ -55,6 +55,7 @@ do -- TASK_A2G_DISPATCHER
ClassName = "TASK_A2G_DISPATCHER",
Mission = nil,
Detection = nil,
Tasks = {},
}
@ -181,14 +182,16 @@ do -- TASK_A2G_DISPATCHER
-- @param #TASK_A2G_DISPATCHER self
-- @param Tasking.Mission#MISSION Mission
-- @param Tasking.Task#TASK Task
-- @param Functional.Detection#DETECTION_AREAS.DetectedItem DetectedItem
-- @param #boolean DetectedItemID
-- @param #boolean DetectedItemChange
-- @return Tasking.Task#TASK
function TASK_A2G_DISPATCHER:EvaluateRemoveTask( Mission, Task, DetectedItem )
function TASK_A2G_DISPATCHER:EvaluateRemoveTask( Mission, Task, DetectedItemID, DetectedItemChanged )
if Task then
if Task:IsStatePlanned() and DetectedItem.Changed == true then
if Task:IsStatePlanned() and DetectedItemChanged == true then
self:E( "Removing Tasking: " .. Task:GetTaskName() )
Task = Mission:RemoveTask( Task )
Mission:RemoveTask( Task )
self.Tasks[DetectedItemID] = nil
end
end
@ -208,82 +211,78 @@ do -- TASK_A2G_DISPATCHER
local ChangeMsg = {}
local Mission = self.Mission
--- First we need to the detected targets.
for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do
local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
local DetectedSet = DetectedItem.Set -- Functional.Detection#DETECTION_BASE.DetectedSet
local DetectedZone = DetectedItem.Zone
self:E( { "Targets in DetectedItem", DetectedItem.ItemID, DetectedSet:Count(), tostring( DetectedItem ) } )
DetectedSet:Flush()
local ItemID = DetectedItem.ID
-- Evaluate SEAD Tasking
local SEADTask = Mission:GetTask( string.format( "SEAD.%03d", ItemID ) )
SEADTask = self:EvaluateRemoveTask( Mission, SEADTask, DetectedItem )
if not SEADTask then
local TargetSetUnit = self:EvaluateSEAD( DetectedItem ) -- Returns a SetUnit if there are targets to be SEADed...
if TargetSetUnit then
local Task = TASK_SEAD:New( Mission, self.SetGroup, string.format( "SEAD.%03d", ItemID ), TargetSetUnit )
Task:SetTargetZone( DetectedZone )
Task:SetDispatcher( self )
Task:SetInfo( "Detection", Detection:DetectedItemReportSummary( DetectedItemID ) )
Task:SetInfo( "Changes", Detection:GetChangeText( DetectedItem ) )
SEADTask = Mission:AddTask( Task )
end
end
-- Evaluate CAS Tasking
local CASTask = Mission:GetTask( string.format( "CAS.%03d", ItemID ) )
CASTask = self:EvaluateRemoveTask( Mission, CASTask, DetectedItem )
if not CASTask then
local TargetSetUnit = self:EvaluateCAS( DetectedItem ) -- Returns a SetUnit if there are targets to be SEADed...
if TargetSetUnit then
local Task = TASK_CAS:New( Mission, self.SetGroup, string.format( "CAS.%03d", ItemID ), TargetSetUnit )
Task:SetTargetZone( DetectedZone )
Task:SetDispatcher( self )
Task:SetInfo( "Detection", Detection:DetectedItemReportSummary( DetectedItemID ) )
Task:SetInfo( "Changes", Detection:GetChangeText( DetectedItem ) )
CASTask = Mission:AddTask( Task )
end
end
-- Evaluate BAI Tasking
local BAITask = Mission:GetTask( string.format( "BAI.%03d", ItemID ) )
BAITask = self:EvaluateRemoveTask( Mission, BAITask, DetectedItem )
if not BAITask then
local TargetSetUnit = self:EvaluateBAI( DetectedItem, self.Mission:GetCommandCenter():GetPositionable():GetCoalition() ) -- Returns a SetUnit if there are targets to be SEADed...
if TargetSetUnit then
local Task = TASK_BAI:New( Mission, self.SetGroup, string.format( "BAI.%03d", ItemID ), TargetSetUnit )
Task:SetTargetZone( DetectedZone )
Task:SetDispatcher( self )
Task:SetInfo( "Detection", Detection:DetectedItemReportSummary( DetectedItemID ) )
Task:SetInfo( "Changes", Detection:GetChangeText( DetectedItem ) )
BAITask = Mission:AddTask( Task )
end
end
-- OK, so the tasking has been done, now delete the changes reported for the area.
Detection:AcceptChanges( DetectedItem )
end
if Mission:IsIDLE() or Mission:IsENGAGED() then
-- TODO set menus using the HQ coordinator
Mission:GetCommandCenter():SetMenu()
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
Mission:GetCommandCenter():MessageToGroup( string.format( "There are %d tasks remaining for mission *%s*. Subscribe to a task using the menu.", Mission:GetTasksRemaining(), Mission:GetName() ), TaskGroup )
if not TaskGroup:GetState( TaskGroup, "Assigned" ) then
-- Mission:GetCommandCenter():MessageToGroup(
-- string.format( "HQ Reporting - Planned tasks for mission '%s':\n\n%s\n",
-- self.Mission:GetName(),
-- string.format( "%s\n\n%s\n\n%s\n\n%s", ReportSEAD:Text(), ReportCAS:Text(), ReportBAI:Text(), ReportChanges:Text()
-- )
-- ), TaskGroup
-- )
local TaskReport = REPORT:New()
--- First we need to the detected targets.
for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do
local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
local DetectedZone = DetectedItem.Zone
self:E( { "Targets in DetectedItem", DetectedItem.ItemID, DetectedSet:Count(), tostring( DetectedItem ) } )
DetectedSet:Flush()
local DetectedItemID = DetectedItem.ID
local DetectedItemChanged = DetectedItem.Changed
local Task = self.Tasks[DetectedItemID]
Task = self:EvaluateRemoveTask( Mission, Task, DetectedItemID, DetectedItemChanged ) -- Task will be removed if it is planned and changed.
-- Evaluate SEAD
if not Task then
local TargetSetUnit = self:EvaluateSEAD( DetectedItem ) -- Returns a SetUnit if there are targets to be SEADed...
if TargetSetUnit then
Task = TASK_SEAD:New( Mission, self.SetGroup, string.format( "SEAD.%03d", DetectedItemID ), TargetSetUnit )
end
-- Evaluate CAS
if not Task then
local TargetSetUnit = self:EvaluateCAS( DetectedItem ) -- Returns a SetUnit if there are targets to be CASed...
if TargetSetUnit then
Task = TASK_CAS:New( Mission, self.SetGroup, string.format( "CAS.%03d", DetectedItemID ), TargetSetUnit )
end
-- Evaluate BAI
if not Task then
local TargetSetUnit = self:EvaluateBAI( DetectedItem, self.Mission:GetCommandCenter():GetPositionable():GetCoalition() ) -- Returns a SetUnit if there are targets to be BAIed...
if TargetSetUnit then
Task = TASK_BAI:New( Mission, self.SetGroup, string.format( "BAI.%03d", DetectedItemID ), TargetSetUnit )
end
end
end
if Task then
self.Tasks[DetectedItemID] = Task
Task:SetTargetZone( DetectedZone )
Task:SetDispatcher( self )
Task:SetInfo( "ThreatLevel", DetectedSet:CalculateThreatLevelA2G() )
Task:SetInfo( "Detection", Detection:DetectedItemReportSummary( DetectedItemID ) )
Task:SetInfo( "Changes", Detection:GetChangeText( DetectedItem ) )
Mission:AddTask( Task )
else
self:E("This should not happen")
end
end
TaskReport:Add( Task:GetName() )
-- OK, so the tasking has been done, now delete the changes reported for the area.
Detection:AcceptChanges( DetectedItem )
end
-- TODO set menus using the HQ coordinator
Mission:GetCommandCenter():SetMenu()
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
if not Mission:IsGroupAssigned(TaskGroup) then
Mission:GetCommandCenter():MessageToGroup( string.format( "Mission *%s* has tasks %s. Subscribe to a task using the Mission *Overlord* radio menu.", Mission:GetName(), TaskReport:Text(", ") ), TaskGroup )
end
end
end
return true

View File

@ -153,7 +153,7 @@ do -- TASK_CARGO
--
-- ===
--
-- @field #TASK_CARGO TASK_CARGO
-- @field #TASK_CARGO
--
TASK_CARGO = {
ClassName = "TASK_CARGO",
@ -166,9 +166,10 @@ do -- TASK_CARGO
-- @param #string TaskName The name of the Task.
-- @param Core.Set#SET_CARGO SetCargo The scope of the cargo to be transported.
-- @param #string TaskType The type of Cargo task.
-- @param #string TaskBriefing The Cargo Task briefing.
-- @return #TASK_CARGO self
function TASK_CARGO:New( Mission, SetGroup, TaskName, SetCargo, TaskType )
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, TaskType ) ) -- #TASK_CARGO
function TASK_CARGO:New( Mission, SetGroup, TaskName, SetCargo, TaskType, TaskBriefing )
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, TaskType, TaskBriefing ) ) -- #TASK_CARGO
self:F( {Mission, SetGroup, TaskName, SetCargo, TaskType})
self.SetCargo = SetCargo
@ -181,24 +182,24 @@ do -- TASK_CARGO
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "SelectAction", Rejected = "Reject" } )
Fsm:AddTransition( { "Assigned", "WaitingForCommand", "ArrivedAtPickup", "ArrivedAtDeploy", "Boarded", "UnBoarded", "Landed" }, "SelectAction", "WaitingForCommand" )
Fsm:AddTransition( { "Assigned", "WaitingForCommand", "ArrivedAtPickup", "ArrivedAtDeploy", "Boarded", "UnBoarded", "Landed", "Boarding" }, "SelectAction", "*" )
Fsm:AddTransition( "WaitingForCommand", "RouteToPickup", "RoutingToPickup" )
Fsm:AddTransition( "*", "RouteToPickup", "RoutingToPickup" )
Fsm:AddProcess ( "RoutingToPickup", "RouteToPickupPoint", ACT_ROUTE_POINT:New(), { Arrived = "ArriveAtPickup" } )
Fsm:AddTransition( "Arrived", "ArriveAtPickup", "ArrivedAtPickup" )
Fsm:AddTransition( "WaitingForCommand", "RouteToDeploy", "RoutingToDeploy" )
Fsm:AddTransition( "*", "RouteToDeploy", "RoutingToDeploy" )
Fsm:AddProcess ( "RoutingToDeploy", "RouteToDeployZone", ACT_ROUTE_ZONE:New(), { Arrived = "ArriveAtDeploy" } )
Fsm:AddTransition( "Arrived", "ArriveAtDeploy", "ArrivedAtDeploy" )
Fsm:AddTransition( { "ArrivedAtPickup", "ArrivedAtDeploy", "Landing" }, "Land", "Landing" )
Fsm:AddTransition( "Landing", "Landed", "Landed" )
Fsm:AddTransition( "WaitingForCommand", "PrepareBoarding", "AwaitBoarding" )
Fsm:AddTransition( "*", "PrepareBoarding", "AwaitBoarding" )
Fsm:AddTransition( "AwaitBoarding", "Board", "Boarding" )
Fsm:AddTransition( "Boarding", "Boarded", "Boarded" )
Fsm:AddTransition( "WaitingForCommand", "PrepareUnBoarding", "AwaitUnBoarding" )
Fsm:AddTransition( "*", "PrepareUnBoarding", "AwaitUnBoarding" )
Fsm:AddTransition( "AwaitUnBoarding", "UnBoard", "UnBoarding" )
Fsm:AddTransition( "UnBoarding", "UnBoarded", "UnBoarded" )
@ -211,71 +212,79 @@ do -- TASK_CARGO
---
-- @param #FSM_PROCESS self
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param Tasking.Task_Cargo#TASK_CARGO Task
function Fsm:onenterWaitingForCommand( TaskUnit, Task )
-- @param Tasking.Task_CARGO#TASK_CARGO Task
function Fsm:onafterSelectAction( TaskUnit, Task )
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
if TaskUnit.Menu then
TaskUnit.Menu:Remove()
end
local MenuTime = timer.getTime()
TaskUnit.Menu = MENU_GROUP:New( TaskUnit:GetGroup(), Task:GetName() .. " @ " .. TaskUnit:GetName() )
TaskUnit.Menu = MENU_GROUP:New( TaskUnit:GetGroup(), Task:GetName() .. " @ " .. TaskUnit:GetName() ):SetTime( MenuTime )
Task.SetCargo:ForEachCargo(
--- @param Core.Cargo#CARGO Cargo
function( Cargo )
if Cargo:IsUnLoaded() then
if Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then
MENU_GROUP_COMMAND:New(
TaskUnit:GetGroup(),
"Board cargo " .. Cargo.Name,
TaskUnit.Menu,
self.MenuBoardCargo,
self,
Cargo
)
else
MENU_GROUP_COMMAND:New(
TaskUnit:GetGroup(),
"Route to Pickup cargo " .. Cargo.Name,
TaskUnit.Menu,
self.MenuRouteToPickup,
self,
Cargo
)
end
end
if Cargo:IsLoaded() then
for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do
if Cargo:IsInZone( DeployZone ) then
if Cargo:IsAlive() then
if Cargo:IsUnLoaded() then
if Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then
MENU_GROUP_COMMAND:New(
TaskUnit:GetGroup(),
"Unboard cargo " .. Cargo.Name,
"Board cargo " .. Cargo.Name,
TaskUnit.Menu,
self.MenuUnBoardCargo,
self.MenuBoardCargo,
self,
Cargo,
DeployZone
)
Cargo
):SetTime(MenuTime)
else
MENU_GROUP_COMMAND:New(
TaskUnit:GetGroup(),
"Route to Deploy cargo at " .. DeployZoneName,
"Route to Pickup cargo " .. Cargo.Name,
TaskUnit.Menu,
self.MenuRouteToDeploy,
self.MenuRouteToPickup,
self,
DeployZone
)
Cargo
):SetTime(MenuTime)
end
end
if Cargo:IsLoaded() then
MENU_GROUP_COMMAND:New(
TaskUnit:GetGroup(),
"Unboard cargo " .. Cargo.Name,
TaskUnit.Menu,
self.MenuUnBoardCargo,
self,
Cargo
):SetTime(MenuTime)
-- Deployzones are optional zones that can be selected to request routing information.
for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do
if not Cargo:IsInZone( DeployZone ) then
MENU_GROUP_COMMAND:New(
TaskUnit:GetGroup(),
"Route to Deploy cargo at " .. DeployZoneName,
TaskUnit.Menu,
self.MenuRouteToDeploy,
self,
DeployZone
):SetTime(MenuTime)
end
end
end
end
end
)
TaskUnit.Menu:Remove( MenuTime )
self:__SelectAction( -15 )
Task:GetMission():GetCommandCenter():MessageToGroup("Cargo menu is ready ...", TaskUnit:GetGroup() )
end
---
@ -308,13 +317,19 @@ do -- TASK_CARGO
-- @param #FSM_PROCESS self
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param Tasking.Task_Cargo#TASK_CARGO Task
-- @param From
-- @param Event
-- @param To
-- @param Core.Cargo#CARGO Cargo
function Fsm:onafterRouteToPickup( TaskUnit, Task, From, Event, To, Cargo )
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
if Cargo:IsAlive() then
self.Cargo = Cargo -- Core.Cargo#CARGO
Task:SetCargoPickup( self.Cargo, TaskUnit )
self:__RouteToPickupPoint( -0.1 )
end
self.Cargo = Cargo
Task:SetCargoPickup( self.Cargo, TaskUnit )
self:__RouteToPickupPoint( -0.1 )
end
@ -325,10 +340,13 @@ do -- TASK_CARGO
function Fsm:onafterArriveAtPickup( TaskUnit, Task )
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
if TaskUnit:IsAir() then
self:__Land( -0.1, "Pickup" )
else
self:__SelectAction( -0.1 )
if self.Cargo:IsAlive() then
if TaskUnit:IsAir() then
self.Cargo.CargoObject:GetUnit(1):SmokeRed()
self:__Land( -0.1, "Pickup" )
else
self:__SelectAction( -0.1 )
end
end
end
@ -369,19 +387,21 @@ do -- TASK_CARGO
function Fsm:onafterLand( TaskUnit, Task, From, Event, To, Action )
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then
if TaskUnit:InAir() then
Task:GetMission():GetCommandCenter():MessageToGroup( "Land", TaskUnit:GetGroup() )
self:__Land( -10, Action )
if self.Cargo:IsAlive() then
if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then
if TaskUnit:InAir() then
Task:GetMission():GetCommandCenter():MessageToGroup( "Land", TaskUnit:GetGroup() )
self:__Land( -10, Action )
else
Task:GetMission():GetCommandCenter():MessageToGroup( "Landed ...", TaskUnit:GetGroup() )
self:__Landed( -0.1, Action )
end
else
Task:GetMission():GetCommandCenter():MessageToGroup( "Landed ...", TaskUnit:GetGroup() )
self:__Landed( -0.1, Action )
end
else
if Action == "Pickup" then
self:__RouteToPickupZone( -0.1 )
else
self:__RouteToDeployZone( -0.1 )
if Action == "Pickup" then
self:__RouteToPickupZone( -0.1 )
else
self:__RouteToDeployZone( -0.1 )
end
end
end
end
@ -393,17 +413,19 @@ do -- TASK_CARGO
function Fsm:onafterLanded( TaskUnit, Task, From, Event, To, Action )
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then
if TaskUnit:InAir() then
self:__Land( -0.1, Action )
if self.Cargo:IsAlive() then
if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then
if TaskUnit:InAir() then
self:__Land( -0.1, Action )
else
self:__SelectAction( -0.1 )
end
else
self:__SelectAction( -0.1 )
end
else
if Action == "Pickup" then
self:__RouteToPickupZone( -0.1 )
else
self:__RouteToDeployZone( -0.1 )
if Action == "Pickup" then
self:__RouteToPickupZone( -0.1 )
else
self:__RouteToDeployZone( -0.1 )
end
end
end
end
@ -415,8 +437,10 @@ do -- TASK_CARGO
function Fsm:onafterPrepareBoarding( TaskUnit, Task, From, Event, To, Cargo )
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
self.Cargo = Cargo -- Core.Cargo#CARGO_GROUP
self:__Board( -0.1 )
if Cargo and Cargo:IsAlive() then
self.Cargo = Cargo -- Core.Cargo#CARGO_GROUP
self:__Board( -0.1 )
end
end
---
@ -427,23 +451,21 @@ do -- TASK_CARGO
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
function self.Cargo:OnEnterLoaded( From, Event, To, TaskUnit, TaskProcess )
self:E({From, Event, To, TaskUnit, TaskProcess })
TaskProcess:__Boarded( 0.1 )
end
if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then
if TaskUnit:InAir() then
--- ABORT the boarding. Split group if any and go back to select action.
if self.Cargo:IsAlive() then
if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then
if TaskUnit:InAir() then
--- ABORT the boarding. Split group if any and go back to select action.
else
self.Cargo:MessageToGroup( "Boarding ...", TaskUnit:GetGroup() )
self.Cargo:Board( TaskUnit, 20, self )
end
else
self.Cargo:MessageToGroup( "Boarding ...", TaskUnit:GetGroup() )
self.Cargo:Board( TaskUnit, 20, self )
--self:__ArriveAtCargo( -0.1 )
end
else
--self:__ArriveAtCargo( -0.1 )
end
end
@ -460,8 +482,10 @@ do -- TASK_CARGO
-- TODO:I need to find a more decent solution for this.
Task:E( { CargoPickedUp = Task.CargoPickedUp } )
if Task.CargoPickedUp then
Task:CargoPickedUp( TaskUnit, self.Cargo )
if self.Cargo:IsAlive() then
if Task.CargoPickedUp then
Task:CargoPickedUp( TaskUnit, self.Cargo )
end
end
end
@ -471,31 +495,50 @@ do -- TASK_CARGO
-- @param #FSM_PROCESS self
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param Tasking.Task_Cargo#TASK_CARGO Task
function Fsm:onafterPrepareUnBoarding( TaskUnit, Task, From, Event, To, Cargo, DeployZone )
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
-- @param From
-- @param Event
-- @param To
-- @param Cargo
-- @param Core.Zone#ZONE_BASE DeployZone
function Fsm:onafterPrepareUnBoarding( TaskUnit, Task, From, Event, To, Cargo )
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID(), From, Event, To, Cargo } )
self.Cargo = Cargo
self.DeployZone = DeployZone
self:__UnBoard( -0.1 )
self.DeployZone = nil
-- Check if the Cargo is at a deployzone... If it is, provide it as a parameter!
if Cargo:IsAlive() then
for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do
if Cargo:IsInZone( DeployZone ) then
self.DeployZone = DeployZone -- Core.Zone#ZONE_BASE
break
end
end
self:__UnBoard( -0.1, Cargo, self.DeployZone )
end
end
---
-- @param #FSM_PROCESS self
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param Tasking.Task_Cargo#TASK_CARGO Task
function Fsm:onafterUnBoard( TaskUnit, Task )
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
-- @param From
-- @param Event
-- @param To
-- @param Cargo
-- @param Core.Zone#ZONE_BASE DeployZone
function Fsm:onafterUnBoard( TaskUnit, Task, From, Event, To, Cargo, DeployZone )
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID(), From, Event, To, Cargo, DeployZone } )
function self.Cargo:OnEnterUnLoaded( From, Event, To, DeployZone, TaskProcess )
self:E({From, Event, To, TaskUnit, TaskProcess })
self:E({From, Event, To, DeployZone, TaskProcess })
TaskProcess:__UnBoarded( -0.1 )
end
self.Cargo:MessageToGroup( "UnBoarding ...", TaskUnit:GetGroup() )
self.Cargo:UnBoard( self.DeployZone:GetPointVec2(), 20, self )
if self.Cargo:IsAlive() then
self.Cargo:MessageToGroup( "UnBoarding ...", TaskUnit:GetGroup() )
self.Cargo:UnBoard( DeployZone:GetPointVec2(), 400, self )
end
end
@ -510,8 +553,10 @@ do -- TASK_CARGO
-- TODO:I need to find a more decent solution for this.
Task:E( { CargoDeployed = Task.CargoDeployed } )
if Task.CargoDeployed then
Task:CargoDeployed( TaskUnit, self.Cargo, self.DeployZone )
if self.Cargo:IsAlive() then
if Task.CargoDeployed then
Task:CargoDeployed( TaskUnit, self.Cargo, self.DeployZone )
end
end
self:__SelectAction( 1 )
@ -685,9 +730,10 @@ do -- TASK_CARGO_TRANSPORT
-- @param Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param #string TaskName The name of the Task.
-- @param Core.Set#SET_CARGO SetCargo The scope of the cargo to be transported.
-- @param #string TaskBriefing The Cargo Task briefing.
-- @return #TASK_CARGO_TRANSPORT self
function TASK_CARGO_TRANSPORT:New( Mission, SetGroup, TaskName, SetCargo )
local self = BASE:Inherit( self, TASK_CARGO:New( Mission, SetGroup, TaskName, SetCargo, "Transport" ) ) -- #TASK_CARGO_TRANSPORT
function TASK_CARGO_TRANSPORT:New( Mission, SetGroup, TaskName, SetCargo, TaskBriefing )
local self = BASE:Inherit( self, TASK_CARGO:New( Mission, SetGroup, TaskName, SetCargo, "Transport", TaskBriefing ) ) -- #TASK_CARGO_TRANSPORT
self:F()
Mission:AddTask( self )
@ -698,8 +744,6 @@ do -- TASK_CARGO_TRANSPORT
self:AddTransition( "*", "CargoPickedUp", "*" )
self:AddTransition( "*", "CargoDeployed", "*" )
do
--- OnBefore Transition Handler for Event CargoPickedUp.
-- @function [parent=#TASK_CARGO_TRANSPORT] OnBeforeCargoPickedUp
-- @param #TASK_CARGO_TRANSPORT self
@ -731,9 +775,7 @@ do -- TASK_CARGO_TRANSPORT
-- @param #number Delay The delay in seconds.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that PickedUp the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
end
do
--- OnBefore Transition Handler for Event CargoDeployed.
-- @function [parent=#TASK_CARGO_TRANSPORT] OnBeforeCargoDeployed
-- @param #TASK_CARGO_TRANSPORT self
@ -769,10 +811,26 @@ do -- TASK_CARGO_TRANSPORT
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that Deployed the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
-- @param Core.Zone#ZONE DeployZone The zone where the Cargo got Deployed or UnBoarded.
end
local Fsm = self:GetUnitProcess()
local CargoReport = REPORT:New( "Transport Cargo. The following cargo needs to be transported including initial positions:")
SetCargo:ForEachCargo(
--- @param Core.Cargo#CARGO Cargo
function( Cargo )
local CargoType = Cargo:GetType()
local CargoName = Cargo:GetName()
local CargoCoordinate = Cargo:GetCoordinate()
CargoReport:Add( string.format( '- "%s" (%s) at %s', CargoName, CargoType, CargoCoordinate:ToString() ) )
end
)
self:SetBriefing(
TaskBriefing or
CargoReport:Text()
)
return self
end
@ -804,7 +862,7 @@ do -- TASK_CARGO_TRANSPORT
end
end
end
return CargoDeployed
end

View File

@ -1782,7 +1782,7 @@ function CONTROLLABLE:GetDetectedTargets( DetectVisual, DetectOptical, DetectRad
return nil
end
function CONTROLLABLE:IsTargetDetected( DCSObject )
function CONTROLLABLE:IsTargetDetected( DCSObject, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK )
self:F2( self.ControllableName )
local DCSControllable = self:GetDCSObject()

View File

@ -156,7 +156,6 @@ end
-- @param #GROUP self
-- @return Dcs.DCSWrapper.Group#Group The DCS Group.
function GROUP:GetDCSObject()
self:F(self.GroupName)
local DCSGroup = Group.getByName( self.GroupName )
if DCSGroup then
@ -1142,7 +1141,7 @@ do -- Players
end
end
self:F( PlayerNames )
self:F2( PlayerNames )
return PlayerNames
end

View File

@ -334,7 +334,7 @@ function POSITIONABLE:GetMessageText( Message, Name ) --R2.1 added
local DCSObject = self:GetDCSObject()
if DCSObject then
Name = Name and ( " (" .. Name .. ")" ) or ""
local Callsign = self:GetCallsign() ~= "" and self:GetCallsign() or self:GetName()
local Callsign = string.format( "[%s]", self:GetCallsign() ~= "" and self:GetCallsign() or self:GetName() )
local MessageText = Callsign .. Name .. ": " .. Message
return MessageText
end
@ -383,12 +383,19 @@ end
-- @param #string Message The message text
-- @param Dcs.DCSTYpes#Duration Duration The duration of the message.
-- @param Dcs.DCScoalition#coalition MessageCoalition The Coalition receiving the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, Name )
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition )
self:F2( { Message, Duration } )
local Name = ""
local DCSObject = self:GetDCSObject()
if DCSObject then
if MessageCoalition == coalition.side.BLUE then
Name = "Blue coalition"
end
if MessageCoalition == coalition.side.RED then
Name = "Red coalition"
end
self:GetMessage( Message, Duration, Name ):ToCoalition( MessageCoalition )
end

View File

@ -724,7 +724,7 @@ function UNIT:IsInZone( Zone )
if self:IsAlive() then
local IsInZone = Zone:IsVec3InZone( self:GetVec3() )
self:T( { IsInZone } )
self:T2( { IsInZone } )
return IsInZone
end

View File

@ -1,5 +1,5 @@
env.info( '*** MOOSE DYNAMIC INCLUDE START *** ' )
env.info( 'Moose Generation Timestamp: 20170424_1257' )
env.info( 'Moose Generation Timestamp: 20170426_1017' )
local base = _G

5
Utils/Deploy.sh Normal file
View File

@ -0,0 +1,5 @@
cd slate
git add -A
git commit -a -m "Doc Update"
git push
./deploy.sh

View File

@ -0,0 +1,13 @@
@echo off
:: Generate Luadocumentor documentation
echo Generating LuaDocumentor Documentation
echo --------------------------------------
call luadocumentor.bat
:: Generate Slate documentation
echo Generating Slate Documentation
echo ------------------------------
cd "Slate Documentation Generator"
call Generate.bat
cd ..

View File

@ -0,0 +1,16 @@
@echo off
:: Generate the Markdown doc
"./bin/SlateDocGenerator2.exe" "../../../MOOSE/Moose Development/Moose" ../../../slate/source
:: Do some cleanup
del /s /q "TreeHierarchySorted.csv"
del /s /q "FuctionList.txt"
rmdir /s /q "./bin/TEMP"
:: Copy the Images that go with the documentation
robocopy ../../docs/Presentations ../../../slate/source/includes/Pictures /MIR /NJH /NJS
:: Deploy the Slate documentation
echo A shell will open. To deploy the Slate website, please run the following command. Otherwise, simply close the shell.
echo $ Moose/Utils/Deploy.sh
%localappdata%\GitHub\GitHub.appref-ms --open-shell

View File

@ -0,0 +1,35 @@
@K=function, @M=Task_A2G, @N=onafterRouteToRendezVous, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua, @C=5129,
@K=function, @M=Task_A2G, @N=OnAfterArriveAtRendezVous, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua, @C=5789,
@K=function, @M=Task_A2G, @N=onafterEngage, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua, @C=6186,
@K=function, @M=Task_A2G, @N=onafterRouteToTarget, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua, @C=6508,
@K=function, @M=Task_A2G, @N=onafterRouteToTargets, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua, @C=7380,
@K=function, @M=Task_Cargo, @N=onenterWaitingForCommand, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=10431,
@K=function, @M=Task_Cargo, @N=OnLeaveWaitingForCommand, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=12652,
@K=function, @M=Task_Cargo, @N=onafterRouteToPickup, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=13428,
@K=function, @M=Task_Cargo, @N=onafterArriveAtPickup, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=13882,
@K=function, @M=Task_Cargo, @N=onafterRouteToDeploy, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=14310,
@K=function, @M=Task_Cargo, @N=onafterArriveAtDeploy, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=14757,
@K=function, @M=Task_Cargo, @N=onafterLand, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=15187,
@K=function, @M=Task_Cargo, @N=onafterLanded, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=16069,
@K=function, @M=Task_Cargo, @N=onafterPrepareBoarding, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=16762,
@K=function, @M=Task_Cargo, @N=onafterBoard, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=17166,
@K=function, @M=Task_Cargo, @N=onafterBoarded, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=18074,
@K=function, @M=Task_Cargo, @N=onafterPrepareUnBoarding, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=18704,
@K=function, @M=Task_Cargo, @N=onafterUnBoard, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=19134,
@K=function, @M=Task_Cargo, @N=onafterUnBoarded, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=19788,
@K=function, @M=Designate, @N=OnBeforeLaseOn, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=12232,
@K=function, @M=Designate, @N=OnAfterLaseOn, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=12480,
@K=function, @M=Designate, @N=LaseOn, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=12701,
@K=function, @M=Designate, @N=__LaseOn, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=12824,
@K=function, @M=Designate, @N=OnBeforeLaseOff, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=13114,
@K=function, @M=Designate, @N=OnAfterLaseOff, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=13364,
@K=function, @M=Designate, @N=LaseOff, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=13587,
@K=function, @M=Designate, @N=__LaseOff, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=13712,
@K=function, @M=Designate, @N=OnBeforeSmoke, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=13944,
@K=function, @M=Designate, @N=OnAfterSmoke, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=14190,
@K=function, @M=Designate, @N=Smoke, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=14409,
@K=function, @M=Designate, @N=__Smoke, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=14530,
@K=function, @M=Designate, @N=OnBeforeStatus, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=15628,
@K=function, @M=Designate, @N=OnAfterStatus, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=15876,
@K=function, @M=Designate, @N=Status, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=16097,
@K=function, @M=Designate, @N=__Status, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=16220,
1 @K=function @M=Task_A2G @N=onafterRouteToRendezVous @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua @C=5129
2 @K=function @M=Task_A2G @N=OnAfterArriveAtRendezVous @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua @C=5789
3 @K=function @M=Task_A2G @N=onafterEngage @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua @C=6186
4 @K=function @M=Task_A2G @N=onafterRouteToTarget @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua @C=6508
5 @K=function @M=Task_A2G @N=onafterRouteToTargets @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua @C=7380
6 @K=function @M=Task_Cargo @N=onenterWaitingForCommand @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=10431
7 @K=function @M=Task_Cargo @N=OnLeaveWaitingForCommand @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=12652
8 @K=function @M=Task_Cargo @N=onafterRouteToPickup @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=13428
9 @K=function @M=Task_Cargo @N=onafterArriveAtPickup @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=13882
10 @K=function @M=Task_Cargo @N=onafterRouteToDeploy @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=14310
11 @K=function @M=Task_Cargo @N=onafterArriveAtDeploy @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=14757
12 @K=function @M=Task_Cargo @N=onafterLand @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=15187
13 @K=function @M=Task_Cargo @N=onafterLanded @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=16069
14 @K=function @M=Task_Cargo @N=onafterPrepareBoarding @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=16762
15 @K=function @M=Task_Cargo @N=onafterBoard @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=17166
16 @K=function @M=Task_Cargo @N=onafterBoarded @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=18074
17 @K=function @M=Task_Cargo @N=onafterPrepareUnBoarding @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=18704
18 @K=function @M=Task_Cargo @N=onafterUnBoard @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=19134
19 @K=function @M=Task_Cargo @N=onafterUnBoarded @P=Fsm @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua @C=19788
20 @K=function @M=Designate @N=OnBeforeLaseOn @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=12232
21 @K=function @M=Designate @N=OnAfterLaseOn @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=12480
22 @K=function @M=Designate @N=LaseOn @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=12701
23 @K=function @M=Designate @N=__LaseOn @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=12824
24 @K=function @M=Designate @N=OnBeforeLaseOff @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=13114
25 @K=function @M=Designate @N=OnAfterLaseOff @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=13364
26 @K=function @M=Designate @N=LaseOff @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=13587
27 @K=function @M=Designate @N=__LaseOff @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=13712
28 @K=function @M=Designate @N=OnBeforeSmoke @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=13944
29 @K=function @M=Designate @N=OnAfterSmoke @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=14190
30 @K=function @M=Designate @N=Smoke @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=14409
31 @K=function @M=Designate @N=__Smoke @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=14530
32 @K=function @M=Designate @N=OnBeforeStatus @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=15628
33 @K=function @M=Designate @N=OnAfterStatus @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=15876
34 @K=function @M=Designate @N=Status @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=16097
35 @K=function @M=Designate @N=__Status @P=DESIGNATE @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua @C=16220

View File

@ -0,0 +1,174 @@
; This file only constains function related to storing the hierarchy in a tree-like tructure
Func AddNode($Kind, $Module ,$Node, $Parent, $File, $CarretPos)
FileSetPos($DataFile, 0, $FILE_END)
If $Parent == "" And $Kind == "type" Then
$Parent = "ROOT"
ElseIf $Kind == "module" Then
$Module = " "
$Parent = " "
EndIf
FileWrite($DataFile, "@K="&$Kind&", @M="&$Module&", @N="&$Node&", @P="&$Parent&", @F="&$File&", @C="&$CarretPos&","&@CRLF)
EndFunc
; Search node by name and returns one data
Func GetData($Node, $Data)
FileSetPos($DataFile, 0, $FILE_BEGIN)
Local $CurrentLine = ""
Local $CurrentData
Local $RegexResult
Local $Regex
Switch $Data
Case "kind"
$Regex = "\@K=(.+?),"
Case "parent"
$Regex = "\@P=(.+?),"
Case "file"
$Regex = "\@F=(.+?),"
Case "carretpos"
$Regex = "\@C=(.+?),"
EndSwitch
FileSetPos($DataFile, 0, $FILE_BEGIN)
Do
$CurrentLine = FileReadLine($DataFile)
If @error == -1 Then
Return ""
ExitLoop
EndIf
$CurrentData = StringRegExp($CurrentLine, "\@N=(.+?),", $STR_REGEXPARRAYMATCH)
Until $Node == $CurrentData[0]
$CurrentData = StringRegExp($CurrentLine, $Regex, $STR_REGEXPARRAYMATCH)
Return $CurrentData[0]
EndFunc
; Returns an array of parent nodes, up to the root, starting with the root
Func GetParents($Node)
Local $CurrentParent = $Node
Local $ParentsArray[0]
Local $NbOfParents = 1
While $CurrentParent <> "ROOT"
ReDim $ParentsArray[$NbOfParents]
$ParentsArray[$NbOfParents-1] = $CurrentParent
$CurrentParent = GetData($CurrentParent, "parent")
If $CurrentParent == "" Then
FileWrite($Log, "ERROR : Couldn't find "&$ParentsArray[$NbOfParents-1]&"'s parent !")
$CurrentParent = "ERROR !"
ReDim $ParentsArray[$NbOfParents]
$ParentsArray[$NbOfParents-1] = $CurrentParent
ExitLoop
EndIf
$NbOfParents += 1
WEnd
_ArrayReverse($ParentsArray)
_ArrayDelete($ParentsArray, $NbOfParents)
Return $ParentsArray
EndFunc
Func DataSort()
Local $SortedDataFile = FileOpen(@ScriptDir & "\TreeHierarchySorted.csv", $FO_OVERWRITE)
Local $Line = ""
Local $LineNb = 1
Local $RegexResults
Local $CurrentModule
Local $CurrentType
FileSetPos($DataFile, 0, $FILE_BEGIN)
While True
$Line = FileReadLine($DataFile)
If @error then ExitLoop
$RegexResults = StringRegExp($Line, "\@K=(.+?),", $STR_REGEXPARRAYMATCH)
If $RegexResults[0] == "module" Then
ConsoleWrite(".")
$RegexResults = StringRegExp($Line, "\@N=(.+?),", $STR_REGEXPARRAYMATCH)
$CurrentModule = $RegexResults[0]
FileWriteLine($SortedDataFile, $Line)
FileClose($DataFile)
_FileWriteToLine(@ScriptDir & "\TreeHierarchy.csv", $LineNb, "", True)
$DataFile = FileOpen(@ScriptDir & "\TreeHierarchy.csv", 1)
FileSetPos($DataFile, 0, $FILE_BEGIN)
$LineNb = 1
While True
$Line = FileReadLine($DataFile)
If @error then ExitLoop
$RegexResults = StringRegExp($Line, "\@K=(.+?),", $STR_REGEXPARRAYMATCH)
If $RegexResults[0] == "type" Then
$RegexResults = StringRegExp($Line, "\@M=(.+?),", $STR_REGEXPARRAYMATCH)
If $RegexResults[0] == $CurrentModule Then
$RegexResults = StringRegExp($Line, "\@N=(.+?),", $STR_REGEXPARRAYMATCH)
$CurrentType = $RegexResults[0]
FileWriteLine($SortedDataFile, $Line)
FileClose($DataFile)
_FileWriteToLine(@ScriptDir & "\TreeHierarchy.csv", $LineNb, "", True)
$DataFile = FileOpen(@ScriptDir & "\TreeHierarchy.csv", 1)
FileSetPos($DataFile, 0, $FILE_BEGIN)
$LineNb = 1
While True
$Line = FileReadLine($DataFile)
If @error then ExitLoop
$RegexResults = StringRegExp($Line, "\@K=(.+?),", $STR_REGEXPARRAYMATCH)
If $RegexResults[0] == "function" Then
$RegexResults = StringRegExp($Line, "\@P=(.+?),", $STR_REGEXPARRAYMATCH)
If $RegexResults[0] == $CurrentType Then
FileWriteLine($SortedDataFile, $Line)
FileClose($DataFile)
_FileWriteToLine(@ScriptDir & "\TreeHierarchy.csv", $LineNb, "", True)
$DataFile = FileOpen(@ScriptDir & "\TreeHierarchy.csv", 1)
FileSetPos($DataFile, 0, $FILE_BEGIN)
$LineNb = 0
EndIf
EndIf
$LineNb += 1
WEnd
FileSetPos($DataFile, 0, $FILE_BEGIN)
$LineNb = 0
EndIf
EndIf
$LineNb += 1
WEnd
FileSetPos($DataFile, 0, $FILE_BEGIN)
$LineNb = 0
EndIf
$LineNb += 1
Wend
If FileGetSize(@ScriptDir & "\TreeHierarchy.csv") <> 0 Then
FileWrite($Log, "ERROR : Some items couldn't be sorted. Verify them in the file TreeHierarchy.csv"&@CRLF)
ConsoleWrite(@CRLF&"INFO : Some items couldn't be sorted. Verify them in the file TreeHierarchy.csv"&@CRLF)
EndIf
FileClose($DataFile)
$DataFile = $SortedDataFile
EndFunc
Func FindInFunctionList($String)
Local $Line = ""
Local $TempStringArray
FileSetPos($FunctionList, 0, $FILE_BEGIN)
;FileWrite($Log, 'Trying to find the function prototype for : ' & $String & @CRLF)
While 1
$Line = FileReadLine($FunctionList)
If @error = -1 Then
SetError(0)
FileWrite($Log, "ERROR : Couldn't find " & $String & " in file. Does this method exitsts ?" & @CRLF)
Return $String
EndIf
If StringInStr($Line, $String) Then
$TempStringArray = StringSplit($Line, "-")
$Line = "[" & $TempStringArray[1] & ":" & $TempStringArray[2] & "()]" & '(#' & StringLower($Line) & ')'
Return $Line
EndIf
WEnd
EndFunc

View File

@ -0,0 +1,460 @@
; This file include every function strictly related to the parsing of data in .lua files
; Get the first comment block after $CarretPos
; We will also grab function declaration if possible/applicable
; The return is a Array : CarretPosition|BlockContent|Declaration|CarretPositionStart
Func ReadNextBlock($File, $CarretPos)
local $CommentBlock = "" ; This is where we'll store the comment block
local $Declaration = "" ; This is the next line after the comment block : usually the declaration statement
local $CurrentLine = ""
local $CurrentCarretPos = 0
local $IsCommentBlock = False
local $RegExResult
local $RegexPos
; Start reading from $CarretPos
FileSetPos($File, $CarretPos, $FILE_BEGIN)
; Read till we find a comment block
Do
$CurrentLine = FileReadLine($File)
If @error Then ; We probably reached the eof
Local $ReturnArray[3] = [$CurrentCarretPos, "", ""]
Return $ReturnArray
ElseIf StringInStr($CurrentLine, "---") Then
$IsCommentBlock = True
EndIf
Until $IsCommentBlock
Local $CarretPosStart = FileGetPos($File) - StringLen($CurrentLine) - 2
; Add the first line to our comment block
$RegExResult = StringRegExp($CurrentLine, "---(.*)", $STR_REGEXPARRAYMATCH)
If Not @error Then ; The first line of the comment could be empty !
$CommentBlock &= $RegExResult[0]&@CRLF
EndIf
; Read the comment block
Do
$CurrentCarretPos = FileGetPos($File)
$CurrentLine = FileReadLine($File)
If StringInStr($CurrentLine, "--") Then ; If we can't find any "--" in the line, then it's not the comment block anymore
$RegExResult = StringRegExp($CurrentLine, "--(.*)", $STR_REGEXPARRAYMATCH)
If Not @error Then; The line of the comment could be empty !
$CommentBlock &= $RegExResult[0]&@CRLF
EndIf
Else
$IsCommentBlock = False
EndIf
Until Not $IsCommentBlock
; Ok, so now this is strange. If the comment block is class', we're going to have to check the
; next comment block. If this next comment block contains a field, that is the same name as the class, then this
; new comment block contains the whole informtion for the class. This is very shitty, but it's a workaround to
; make intellisense show classes info while programing
If ParseForOneTag($CommentBlock, "@type") Then
Local $CommentBlock2 = ""
Do
$CurrentLine = FileReadLine($File)
If @error Then
Local $ReturnArray[3] = [$CurrentCarretPos, "", ""]
Return $ReturnArray
ElseIf StringInStr($CurrentLine, "---") Then
$IsCommentBlock = True
EndIf
Until $IsCommentBlock
$RegExResult = StringRegExp($CurrentLine, "---(.*)", $STR_REGEXPARRAYMATCH)
If Not @error Then
$CommentBlock2 &= $RegExResult[0]&@CRLF
EndIf
; Yep, the next comment is the description of the class, let's read on !
If StringInStr($CurrentLine, ParseForOneTag($CommentBlock, "@type")) And StringInStr($CurrentLine, "extend") Then
Do
$CurrentLine = FileReadLine($File)
If StringInStr($CurrentLine, "--") Then
$RegExResult = StringRegExp($CurrentLine, "--(.*)", $STR_REGEXPARRAYMATCH)
If Not @error Then
$CommentBlock2 &= $RegExResult[0]&@CRLF
EndIf
Else
$IsCommentBlock = False
EndIf
Until Not $IsCommentBlock
; remove the line(s) with "@field" in the comment block. They are only needed for the intellisense hack
While 1
$RegexResult = StringRegExp($CommentBlock2, "(.*)@field(.*)", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$CommentBlock2 = StringRegExpReplace($CommentBlock2, "(.*)@field(.*)", "", 1)
WEnd
; We also don't need the first line of the first comment block anymore...
; $CommentBlock = StringRegExpReplace($CommentBlock, "(.*)", "", 1)
; append the description at the start of the comment block
$CommentBlock = $CommentBlock2&$CommentBlock
EndIf
; We also need to check if the type is a list or a map. If so, the comment block does not describe a class, but a simple list / map.
; It will have the formatting of a class, though, because it's closer closer to the actual code, even though it is highly confusing.
; But it will only have 1 field : the list or map.
If StringInStr($CommentBlock, "@list") Then
$RegExResult = StringRegExp($CommentBlock, "@list\h<(.*?)>\h(.*)", $STR_REGEXPARRAYMATCH)
if not @error Then
$CommentBlock &= "@field #table["&$RegExResult[0]&"] "&$RegExResult[1]
EndIf
EndIf
; TODO : Add support for @map the same way...
EndIf
; We'll take the next line, as it might be the declaration statement
$Declaration = $CurrentLine
; let's do some cleanup
$CommentBlock = StringRegExpReplace($CommentBlock, "(?m)^\h+", "") ;remove leading whitespaces
$CommentBlock = StringRegExpReplace($CommentBlock, "(?m)\h+$", "") ;remove trailing whitespaces
$CommentBlock = StringRegExpReplace($CommentBlock, "(?m)^[#]+", "##### ")
$CommentBlock = StringRegExpReplace($CommentBlock, "(?m)^\h+", "") ;remove leading whitespaces again now that we removed the "#"s
$CommentBlock = StringRegExpReplace($CommentBlock, "(?m)-{3,}", "") ;remove sequences of at least 3 "-" which will mess up markdown
$CommentBlock = StringRegExpReplace($CommentBlock, "(?m)={3,}", "") ; remove sequences of at least 3 "=" which will mess up markdown
Local $ReturnArray[4] = [$CurrentCarretPos, $CommentBlock, $Declaration, $CarretPosStart]
Return $ReturnArray
EndFunc
; Parses the block and returns the data for one tag
; don't use it to find the function tag !
Func ParseForOneTag($Block, $Tag)
Local $i = 1
Local $DataArray[1]
Local $RegexResult[1]
Local $RegexPos = 1
Local $Regex
; If we look for @usage, then it's a multiline data, the regex is different
If $Tag == "@usage" Then
$Regex = "(?s)@usage(.*)"
$RegexResult = StringRegExp($Block, $Regex, $STR_REGEXPARRAYMATCH, $RegexPos)
Else
$Regex = $Tag&"\h(.*)\s"
$RegexResult = StringRegExp($Block, $Regex, $STR_REGEXPARRAYMATCH, $RegexPos)
Endif
If @error Then
Return ""
Else
Return $RegexResult[0]
EndIf
EndFunc ;==>ReadOneTag
; Parses the block and returns the data for multiple tags in an array
; Don't use it for @param !
Func ParseForTags($Block, $Tag)
Local $i = 1
Local $DataArray[1]
Local $RegexResult[1]
Local $RegexPos = 1
Local $Regex = $Tag&"(?m)\h([^\s]*)(?:\h)?([^\s]*)?(?:\h)?(.*)?$"
; For each tag
While True
$RegexResult = StringRegExp($Block, $Regex, $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If $RegexPos == 0 Then ; We couldn't find any tag
If Not $DataArray[0] Then
Return ""
Else
Return $DataArray
EndIf
EndIf
; Add the tag to the array.The array looks like this : type1|param1|description1|type2...
ReDim $DataArray[$i * 3]
$DataArray[($i * 3) - 3] = $RegexResult[0]
If $RegexResult[1] == "" Then
$DataArray[($i * 3) - 2] = "self" ; if the first param doesn't have a name, then it's self
Else
$DataArray[($i * 3) - 2] = $RegexResult[1]
EndIf
$DataArray[($i * 3) - 1] = $RegexResult[2]
$i += 1
WEnd
EndFunc
; Parses both the comment block and the declaration to find the function name and it's type
; Compares both of them if possible, but will always return the one in the comment block if possible
Func ParseFunctionName($CommentBlock, $Declaration)
local $RegExResult
local $FunctionNameFromDec
local $FunctionNameFromComment
local $ReturnArray[2]
; Parse for function name in both the comment block and the desclaration
$RegExResult = StringRegExp($CommentBlock, "\@function\h(?:(\[.*\]\h))?(.*)", $STR_REGEXPARRAYMATCH)
If Not @error Then
$FunctionNameFromComment = $RegExResult[1]
EndIf
$RegExResult = StringRegExp($Declaration, "function\h(?:.*\:)?(.*)\(.*\)", $STR_REGEXPARRAYMATCH)
If Not @error Then
$FunctionNameFromDec = $RegExResult[0]
EndIf
; compare them to each other
If $FunctionNameFromComment Then
If $FunctionNameFromDec <> $FunctionNameFromComment Then
FileWrite($Log,"CAUTION : The commented function doesn't match its declaration : "&$FunctionNameFromComment& " -> "&$Declaration&@CRLF)
EndIf
$ReturnArray[0] = $FunctionNameFromComment
ElseIf $FunctionNameFromDec Then
;FileWrite($Log, "CAUTION: No data matching @function found in block, inferring the function name from its declaration : "& $FunctionNameFromDec & @CRLF)
$ReturnArray[0] = $FunctionNameFromDec
Else
$ReturnArray[0] = ""
$ReturnArray[1] = ""
return $ReturnArray
EndIf
;parses for function type in both the comment block and the desclaration
local $TypeFromComment
local $TypeFromDec
$RegExResult = StringRegExp($Declaration, "function\h(.*):", $STR_REGEXPARRAYMATCH)
If Not @error Then
$TypeFromDec = $RegExResult[0]
EndIf
$RegExResult = StringRegExp($CommentBlock, "function\h\[parent=#(.*)\]", $STR_REGEXPARRAYMATCH)
If Not @error Then
$TypeFromComment = $RegExResult[0]
EndIf
; compare them to each other
If $TypeFromComment Then
If $TypeFromDec <> $TypeFromComment Then
FileWrite($Log,"CAUTION : The commented function type doesn't match its declaration : "&$TypeFromComment& " -> "&$Declaration&@CRLF)
EndIf
$ReturnArray[1] = $TypeFromComment
ElseIf $TypeFromDec Then
;FileWrite($Log, "CAUTION: No function type found in block, inferring the function type from its declaration : "& $TypeFromDec & @CRLF)
$ReturnArray[1] = $TypeFromDec
Else
$ReturnArray[0] = ""
$ReturnArray[1] = ""
return $ReturnArray
EndIf
Return $ReturnArray
EndFunc
; Specifically designed to parse for @param tags
; will verify the comment by matching with the declaration (theoretically, I'm pretty sure it's bugged)
Func ParseParams($CommentBlock, $Declaration)
Local $ParamsFromComment = ParseForTags($CommentBlock, "@param")
Local $RegExResult
Local $RegexPos = StringInStr($Declaration, "(")
Local $ParamsFromDec[0]
Local $NbParam = 0
If StringInStr($Declaration, ":") Then
$NbParam = 1
ReDim $ParamsFromDec[1]
$ParamsFromDec[0] = "self"
EndIf
; extract params from function decaration
While True
$RegExResult = StringRegExp($Declaration, "([^,\(\)\h]+)", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NbParam += 1
Redim $ParamsFromDec[$NbParam]
$ParamsFromDec[$NbParam-1] = $RegExResult[0]
WEnd
; compare these parameters with those found in the comment block
If UBound($ParamsFromComment) <> UBound($ParamsFromDec)*3 Then
FileWrite($Log, "CAUTION: The number of parameters don't match between the comment block and declaration "& @CRLF)
Else
For $i=0 To $NbParam-1
If $ParamsFromDec[$i] <> $ParamsFromComment[($i*3)+1] Then
FileWrite($Log, "CAUTION: Parameters missmatch between the comment block and declaration "& @CRLF)
FileWrite($Log, $ParamsFromComment[($i*3)+1]& " -> " & $ParamsFromDec[$i]&@CRLF)
ExitLoop
EndIf
Next
EndIf
Return $ParamsFromComment
EndFunc
; This does 3 things :
; - Replace the hyperlinks with new ones
; - change the stuff starting with # (#nil -> <u>Nil</u>)
; - Replace pictures paths
Func ReplaceHyperlinks($TempFile)
Local $StringFile = ""
Local $RegexResult
Local $RegexPos = 1
Local $NewURL = ""
Local $i = 0
FileSetPos($TempFile, 0, $FILE_BEGIN)
$StringFile = FileRead($TempFile)
; Replace HyperLinks Using Regexs
; ---------------------------------------------------------
While 1 ; @{File.Module}
$RegexResult = StringRegExp($StringFile, "\@{([A-Z][^\.#}]+)\.([^\.#}]+)}", $STR_REGEXPARRAYMATCH, $RegexPos) ;
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewURL = "[" & $RegexResult[1] & "](#" & StringLower($RegexResult[1]) & "-module-)"
;FileWrite($Log, "Module : " & $RegexPos & " : " & _ArrayToString($RegexResult) & " -> " & $NewURL & @CRLF)
$StringFile = StringRegExpReplace($StringFile, "\@{([A-Z][^\.#}]+)\.([^\.#}]+)}", $NewURL, 1)
WEnd
While 1 ; @{Module}
$RegexResult = StringRegExp($StringFile, "\@{([A-Z][^\.#}]+)}", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewURL = "[" & $RegexResult[0] & "](#" & StringLower($RegexResult[0]) & "-module-)"
;FileWrite($Log, "Module : " & $RegexPos & " : " & _ArrayToString($RegexResult) & " -> " & $NewURL & @CRLF)
$StringFile = StringRegExpReplace($StringFile, "\@{([A-Z][^\.#}]+)}", $NewURL, 1)
WEnd
While 1 ; @{File.Module#TYPE}
$RegexResult = StringRegExp($StringFile, "\@{([A-Z][^\.#}]+)\.([A-Z][^\.#}]+)#([A-Z,_]+)}", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewURL = "[" & $RegexResult[2] & "](#" & StringLower($RegexResult[2]) & "-class-)"
;FileWrite($Log, "Class : " & $RegexPos & " : " & _ArrayToString($RegexResult) & " -> " & $NewURL & @CRLF)
$StringFile = StringRegExpReplace($StringFile, "\@{([A-Z][^\.#}]+)\.([A-Z][^\.#}]+)#([A-Z,_]+)}", $NewURL, 1)
WEnd
While 1 ; @{Module#TYPE}
$RegexResult = StringRegExp($StringFile, "\@{([A-Z][^\.#}]+)#([A-Z,_]+)}", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewURL = "[" & $RegexResult[1] & "](#" & StringLower($RegexResult[1]) & "-class-)"
;FileWrite($Log, "Class : " & $RegexPos & " : " & _ArrayToString($RegexResult) & " -> " & $NewURL & @CRLF)
$StringFile = StringRegExpReplace($StringFile, "\@{([A-Z][^\.#}]+)#([A-Z,_]+)}", $NewURL, 1)
WEnd
While 1 ; @{#TYPE}
$RegexResult = StringRegExp($StringFile, "\@{#([A-Z,_]+)}", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewURL = "[" & $RegexResult[0] & "](#" & StringLower($RegexResult[0]) & "-class-)"
;FileWrite($Log, "Class : " & $RegexPos & " : " & _ArrayToString($RegexResult) & " -> " & $NewURL & @CRLF)
$StringFile = StringRegExpReplace($StringFile, "\@{#([A-Z,_]+)}", $NewURL, 1)
WEnd
While 1 ; #TYPE&@CR
$RegexResult = StringRegExp($StringFile, "\h#([A-Z,_]+)\s", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewURL = " [" & $RegexResult[0] & "](#" & StringLower($RegexResult[0]) & "-class-)"&@CRLF
;FileWrite($Log, "Class : " & $RegexPos & " : " & _ArrayToString($RegexResult) & " -> " & $NewURL & @CRLF)
$StringFile = StringRegExpReplace($StringFile, "\h#([A-Z,_]+)\s", $NewURL, 1)
WEnd
While 1 ; @{File.Module#TYPE.Function}(), catches the parenthesis
$RegexResult = StringRegExp($StringFile, "\@{([A-Z][^#}\.]+)\.([A-Z][^#}\.]+)#([A-Z,_]+)\.([^#\.]+)}[\(]?[\)]?", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewURL = FindInFunctionList($RegexResult[2] & "-" & $RegexResult[3]&"-")
;FileWrite($Log, "Class : " & $RegexPos & " : " & _ArrayToString($RegexResult) & " -> " & $NewURL & @CRLF)
$StringFile = StringRegExpReplace($StringFile, "\@{([A-Z][^#}\.]+)\.([A-Z][^#}\.]+)#([A-Z,_]+)\.([^#\.]+)}[\(]?[\)]?", $NewURL, 1)
WEnd
While 1 ; @{Module#TYPE.Function}(), catches the parenthesis
$RegexResult = StringRegExp($StringFile, "\@{([A-Z][^#}\.]+)#([A-Z,_]+)\.([^#}\.]+)}[\(]?[\)]?", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewURL = FindInFunctionList($RegexResult[1] & "-" & $RegexResult[2]&"-")
;FileWrite($Log, "Class : " & $RegexPos & " : " & _ArrayToString($RegexResult) & " -> " & $NewURL & @CRLF)
$StringFile = StringRegExpReplace($StringFile, "\@{([A-Z][^#}\.]+)#([A-Z,_]+)\.([^#}\.]+)}[\(]?[\)]?", $NewURL, 1)
WEnd
While 1 ; @{#TYPE.Function}(), catches the parenthesis
$RegexResult = StringRegExp($StringFile, "\@{#([A-Z,_]+)\.([^#}\.]+)}[\(]?[\)]?", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewURL = FindInFunctionList($RegexResult[0] & "-" & $RegexResult[1]&"-")
;FileWrite($Log, "Class : " & $RegexPos & " : " & _ArrayToString($RegexResult) & " -> " & $NewURL & @CRLF)
$StringFile = StringRegExpReplace($StringFile, "\@{#([A-Z,_]+)\.([^#}\.]+)}[\(]?[\)]?", $NewURL, 1)
WEnd
While 1 ; Module#TYPE
$RegexResult = StringRegExp($StringFile, "\h(\w+[^\h\_])#(.*?)\h", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewURL = " [" & $RegexResult[1] & "](#" & StringLower($RegexResult[1]) & "-class-) "
;FileWrite($Log, "Class : " & $RegexPos & " : " & _ArrayToString($RegexResult) & " -> " & $NewURL & @CRLF)
$StringFile = StringRegExpReplace($StringFile, "\h(\w+[^\h\_])#(.*?)\h", $NewURL, 1)
WEnd
While 1 ; File.Module#TYPE
$RegexResult = StringRegExp($StringFile, "\h(\w+)\.(\w+)#(.*?)\h", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewURL = " [" & $RegexResult[2] & "](#" & StringLower($RegexResult[2]) & "-class-) "
;FileWrite($Log, "Class : " & $RegexPos & " : " & _ArrayToString($RegexResult) & " -> " & $NewURL & @CRLF)
$StringFile = StringRegExpReplace($StringFile, "\h(\w+)\.(\w+)#(.*?)\h", $NewURL, 1)
WEnd
While 1 ; #TYPE.type (nested type... really annoying and confusing lua stuff)
$RegexResult = StringRegExp($StringFile, "\h#([A-Z,_]+)\.(\w+)\h", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewURL = " [" & $RegexResult[1] & "](#" &StringLower($RegexResult[0])& "-"& StringLower($RegexResult[1]) & "-class-)"
;FileWrite($Log, "Class : " & $RegexPos & " : " & _ArrayToString($RegexResult) & " -> " & $NewURL & @CRLF)
$StringFile = StringRegExpReplace($StringFile, "\h#([A-Z,_]+)\.(\w+)\h", $NewURL, 1)
WEnd
; Clean stuff with #
; ---------------------------------------------------------
$StringFile = StringReplace($StringFile, "#nil", "<u>Nil</u>")
$StringFile = StringReplace($StringFile, "#number", "<u>Number</u>")
$StringFile = StringReplace($StringFile, "#boolean", "<u>Boolean</u>")
$StringFile = StringReplace($StringFile, "#string", "<u>String</u>")
$StringFile = StringReplace($StringFile, "#table", "<u>List[]</u>")
$StringFile = StringReplace($StringFile, "#function", "<u>Function()</u>")
; And replace the pictures Path if any
; ---------------------------------------------------------
While 1
$RegexResult = StringRegExp($StringFile, "!\[(.*)\]\(.*\\(.*)\\(.*)\)", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
$NewPic = "![" & $RegexResult[0] & "](/includes/Pictures/" & $RegexResult[1] & "/"& $RegexResult[2]&")"
$StringFile = StringRegExpReplace($StringFile, "!\[(.*)\]\(.*\\(.*)\\(.*)\)", $NewPic, 1)
WEnd
While 1
$RegexResult = StringRegExp($StringFile, "(?m)^(\d(?:(\.\d))*\)(.*))$", $STR_REGEXPARRAYMATCH, $RegexPos)
$RegexPos = @extended
If @extended == 0 Then ExitLoop
;$StringFile = StringRegExpReplace($StringFile, "(?m)^(\d(?:(\.\d))*\)(.*))$", "<h4>"&$RegExResult[0]&"</h4>", 1)
$StringFile = StringRegExpReplace($StringFile, "(?m)^(\d(?:(\.\d))*\)(.*))$", "##### "&$RegExResult[0], 1)
WEnd
Return $StringFile
EndFunc

View File

@ -0,0 +1,310 @@
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=..\bin\SlateDocGenerator2.exe
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#cs
This is the main script
The script goal is to read .lua file, extract the documentation in comment blocks, and write .md files to be converted to html by Slate : https://github.com/lord/slate
It works in 5 steps :
First, it reads the .lua files one bt one, indentifying the comment blocks. for each comment block, it determines the kind of content the comment block describes (module, class/type or function),
find some usefull stuff (for exemple in the declaration...) and writes all of this info in the creatively named TreeHierarchy.csv, with this format :
@K=kind, @M=ParentModule, @N=Name, @P=Parent, @F=FileWhereTheCommentBlockIsLocated, @C=CarretPositionOfTheCommentBlock
The functions used to do this step are mostly found in Parser.au3
Then the second step is the longest : we sort the TreeHiearchy.csv, and put the result into TreeHierarchySorted.csv
The idea is to have the data in this order :
Module A
Class A (belongs to Module A)
Function A (belongs to Class A)
Function B (belongs to Class A)
Class B Class A (belongs to Module A)
Function C (belongs to Class B)
Function D (belongs to Class B)
Module B ...
The functions used to do this step are found in DataStorer.au3
Then, step 3 : We read each line of TreeHierarchySorted.csv, read the appropriate comment block in the .lua source files,
and write the appropriate Markdown documentation for it in a temporary folder
This is where the markdown documentation is actually written for the first time.
The functions used to do this step are found in Writer.au3
Step 4 ! We read the newly created Markdown files, trying to find hyperlinks/picture paths... and we replace them with the new ones.
We copy each processed file into it's final destination.
The functions used to do this step are mostly found in Parser.au3
And finally Step 5 : We add the new markdown files to Slate's index and delete temporary files and folder
#ce
#include <FileConstants.au3>
#include <StringConstants.au3>
#include <Array.au3>
#include <File.au3>
; Those are the arguments that need to be passed at the start
Global $SourceFolder = $CmdLine[1] ;"./Results"
Global $OutputFolder = $CmdLine[2] ;"@ScriptDir&"/source/index.html.md"
Global $Log = FileOpen(@ScriptDir & "\SlateGenerator2.log", 2)
Global $DataFile = FileOpen(@ScriptDir & "\TreeHierarchy.csv", 2)
Global $FunctionList = FileOpen(@ScriptDir & "\FuctionList.txt", 2)
#include "Parser.au3"
#include "DataStorer.au3"
#include "Writer.au3"
Func ExitCleanly()
FileClose($DataFile)
FileClose($FunctionList)
FileWrite($Log, "SlateGenerator2 exited cleanly")
FileClose($Log)
EndFunc
; Small function to determine if a comment block is describing a module, a type or a function
Func IdentifyBlock($Block, $Declaration)
Local $Kind
Local $KindFunction
$Kind = ParseForOneTag($Block, "@module")
If $Kind Then
Return "module"
EndIf
$Kind = ParseForOneTag($Block, "@type")
If $Kind Then
Return "type"
EndIf
$KindFunction = ParseFunctionName($Block, $Declaration)
If $KindFunction[0] Then
Return "function"
EndIf
Return ""
EndFunc
; -----------------------------------------------------------------
; Main
; -----------------------------------------------------------------
; Step 1 !
; -----------------------------------------------------------------
Local $SourceList = _FileListToArrayRec($SourceFolder, "*", $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH)
Local $CurrentFile
Local $CarretPos = 0
Local $CommentBlock
Local $CommentKind
Local $CommentInfo[2]
Local $CurrentModule
ConsoleWrite("1. Parsing Source Files... ")
FileWrite($Log, @CRLF&@CRLF&@TAB&"INFO : Building Hierarchy" & @CRLF)
For $i=1 To $SourceList[0] ; for each .lua source file
FileWrite($Log, "DEBUG : "&$SourceList[$i])
; let's read the next .lua source file
$CurrentFile = FileOpen($SourceList[$i], $FO_READ)
FileWrite($Log, @CRLF&"INFO : Reading File "&$SourceList[$i] & @CRLF)
While True ; for each comment block in the current .lua source file
; We read the next comment block. If we could not, it's probably eof, time to open the next .lua file
$CommentBlock = ReadNextBlock($CurrentFile, $CarretPos)
If Not $CommentBlock[1] Then
ExitLoop
EndIf
$CarretPos = $CommentBlock[0]
$CommentKind = IdentifyBlock($CommentBlock[1], $CommentBlock[2])
; Depending on the kind of comment block it is, we write the appropriate line in TreeHierarchy.csv
Switch $CommentKind
Case "function"
$CommentInfo = ParseFunctionName($CommentBlock[1], $CommentBlock[2])
AddNode("function", $CurrentModule, $CommentInfo[0], $CommentInfo[1], $SourceList[$i], $CommentBlock[3])
FileWrite($Log, "INFO : Added function "&$CommentInfo[0]&" to hierarchy" & @CRLF)
Case "type"
$CommentInfo[0] = ParseForOneTag($CommentBlock[1], "@type")
$CommentInfo[1] = ParseForOneTag($CommentBlock[1], "@extends")
$CommentInfo[1] = StringRegExpReplace($CommentInfo[1], "(.*#)", "")
AddNode("type", $CurrentModule, $CommentInfo[0], $CommentInfo[1], $SourceList[$i], $CommentBlock[3])
FileWrite($Log, "INFO : Added type "&$CommentInfo[0]&" to hierarchy" & @CRLF)
Case "module"
$CurrentModule = ParseForOneTag($CommentBlock[1], "@module")
AddNode("module", "", $CurrentModule, "", $SourceList[$i], $CommentBlock[3])
FileWrite($Log, "INFO : Added module "&$CurrentModule&" to hierarchy" & @CRLF)
EndSwitch
WEnd
$CarretPos = 0
FileClose($CurrentFile)
Next
ConsoleWrite("Done"&@CRLF)
; Step 2 !
; -----------------------------------------------------------------
ConsoleWrite("2. Sorting Hierarchy")
FileWrite($Log, @CRLF&@CRLF&@TAB&"INFO : Sorting Hierarchy" & @CRLF)
; The magic happens in DataStorer.au3
DataSort()
ConsoleWrite("Done"&@CRLF)
; Step 3 !
; -----------------------------------------------------------------
ConsoleWrite("3. Writing Markdown Documentation")
FileWrite($Log, @CRLF&@CRLF&@TAB&"INFO : Writing Markdown Documentation" & @CRLF)
Local $CurrentOutput
Local $CurrentFolder
Local $RegexResult
Local $Line
Local $CarretPos = 0
Local $Results
Local $Output
Local $Declaration
FileSetPos($DataFile, 0, $FILE_BEGIN)
While True ; For each line in TreeHierarchySorted.csv
; read the next line until eof
FileSetPos($DataFile, $CarretPos, $FILE_BEGIN)
$Line = FileReadLine($DataFile)
If @error Then ; eof
ExitLoop
Endif
$CarretPos = FileGetPos($DataFile)
; find the file/position of the next comment block referenced in the line
$RegexResult = StringRegExp($Line, "\@F=(.+?),", $STR_REGEXPARRAYMATCH)
$CurrentFile = FileOpen($RegexResult[0], $FO_READ)
$RegexResult = StringRegExp($Line, "\@C=(.+?),", $STR_REGEXPARRAYMATCH)
$DataPos = $RegexResult[0]
; get the comment block itself
$Results = ReadNextBlock($CurrentFile, $DataPos)
$Block = $Results[1]
$Declaration = $Results[2]
; choose the right function to write mardown depending on the type of comment block
$RegexResult = StringRegExp($Line, "\@K=(.+?),", $STR_REGEXPARRAYMATCH)
If $RegexResult[0] == "module" Then
ConsoleWrite(".")
; We need the name of the folder containing this particular source file
$RegexResult = StringRegExp($Line, "\@F=(.+?),", $STR_REGEXPARRAYMATCH)
$RegexResult = StringRegExp($RegexResult[0], "\\(.*)\\.*\.lua", $STR_REGEXPARRAYMATCH)
If @error Then
$CurrentFolder = ""
Else
$CurrentFolder = $RegexResult[0]
Endif
; Now we can write the markdown for this module
$CurrentOutput = WriteModule($Block, $CurrentFolder)
EndIf
If $RegexResult[0] == "type" Then
; We need the name of the Module containing the type
$RegexResult = StringRegExp($Line, "\@M=(.+?),", $STR_REGEXPARRAYMATCH)
; Now we can write the markdown for this type
WriteType($Block, $RegexResult[0], $CurrentOutput)
EndIf
If $RegexResult[0] == "function" Then
; We can write the markdown for this function
WriteFunction($Block, $Declaration, $CurrentOutput)
EndIf
FileClose($CurrentFile)
Wend
ConsoleWrite("Done"&@CRLF)
; Step 4 !
; -----------------------------------------------------------------
ConsoleWrite("4. Processing Hyperlinks...")
FileWrite($Log, @CRLF&@CRLF&@TAB&"INFO : Processing Hyperlinks" & @CRLF)
Local $i=1
Local $TempFilesArray = _FileListToArray(@ScriptDir & "/TEMP")
Local $CurrentFile
Local $FinalFile
While $i <= $TempFilesArray[0] ; For each markdown file in the temporary folder
;read the file
$CurrentFile = FileOpen(@ScriptDir & "/TEMP/" & $TempFilesArray[$i], 0)
; The magic happens in Parser.au3
$FinalString = ReplaceHyperlinks($CurrentFile)
; copy the result to the final file location
$FinalFile = FileOpen($OutputFolder & "/includes/" & $TempFilesArray[$i], 2)
FileWrite($FinalFile, $FinalString)
FileClose($FinalFile)
FileClose($CurrentFile)
$i += 1
WEnd
ConsoleWrite("Done"&@CRLF)
; Step 5 !
; -----------------------------------------------------------------
ConsoleWrite("5. Adding new documentation to index...")
FileWrite($Log, @CRLF&@CRLF&@TAB&"INFO : Adding new documentation to index" & @CRLF)
; Now this is a bit annoying : there is no way to insert a line in a document.
; So we need to read the first half of it, read the second half, and the wipe the whole document
; This way, in the new doc, we can write the first half, what we wanted to insert, and then the second half !
; Let's store the index file in $IndexString
Local $IndexFile = $OutputFolder&"/index.html.md"
Local $IndexFileHandle = FileOpen($IndexFile, 0)
Local $IndexString = FileRead($IndexFileHandle)
$IndexString = StringRegExpReplace($IndexString, "-\h[A-Z][a-z]+\.[A-Z][a-z]+\s", "")
; Now we slpit it into and store the results in $BeforeString and $AfterString
Local $SearchPos = StringInStr($IndexString, "search:")
local $BeforeString = StringTrimRight($IndexString, StringLen($IndexString) - $SearchPos + 5)
local $AfterString = StringTrimLeft($IndexString, $SearchPos - 1)
; reopening the index file wiping everything
FileClose($IndexFileHandle)
$IndexFileHandle = FileOpen($IndexFile, 2)
; write the first half
FileWrite($IndexFileHandle, $BeforeString)
Local $IncludePos = StringInStr($IndexString, "includes:")
FileSetPos($IndexFileHandle, $IncludePos + 10, $FILE_BEGIN)
; add the new markdown files to the index
$i = 1
While $i <= $TempFilesArray[0]
FileWrite($Log, StringTrimRight($TempFilesArray[$i], 3)&@CRLF)
FileWrite($IndexFileHandle, " - "&StringTrimRight($TempFilesArray[$i], 3)&@CRLF)
$i+=1
WEnd
FileWrite($IndexFileHandle, @CRLF)
; append the second half of the file
FileWrite($IndexFileHandle, $AfterString)
FileClose($IndexFileHandle)
ConsoleWrite("Done"&@CRLF)
; WE ARE DONE !
ExitCleanly()

View File

@ -0,0 +1,209 @@
; Takes an array and returns it in a markdown flavored list
; If the list is a retun, then, there is no variable name...
Func ArrayToList($Array, $Return)
$String = ""
$i = 0
do
$String &= "* "
$String &= $Array[$i] & " "
If $Return Then
If $Array[$i + 2] == "" or $Array[$i + 2] == " " Then
$String &= @CRLF
Else
$String &= " " & $Array[$i + 1] & " " & $Array[$i + 2] & @CRLF
EndIf
Else
$String &= $Array[$i + 1]
If $Array[$i + 2] == "" or $Array[$i + 2] == " " Then
$String &= @CRLF
Else
$String &= " : " & $Array[$i + 2] & @CRLF
EndIf
EndIf
$i += 3
Until $i >= UBound($Array)
Return $String
EndFunc
Func WriteModule($Block, $Group)
Local $ModuleName = ParseForOneTag($Block, "@module")
DirCreate(@ScriptDir & "\TEMP")
Local $Output = FileOpen(@ScriptDir & "\TEMP\" & $Group & "." & $ModuleName & ".md", $FO_OVERWRITE)
Local $Data = ""
Local $DataPos = 1
FileWrite($Log, @CRLF&@TAB&"Writing "&$Group & "." & $ModuleName & ".md" &@CRLF)
FileWrite($Log, "Writing Module "&$ModuleName&@CRLF)
; Add title of Module
FileWrite($Output, "# " & $Group & "." & $ModuleName & " Module" & @CRLF)
; Copy the short description
While StringRight($Data, 1) <> @CRLF And StringRight($Data, 1) <> @CR
If StringRight($Data, 7) == "@module" Then ; If there is no comment in the module block
Return $Output
EndIf
$Data &= StringMid($Block, $DataPos, 1)
$DataPos += 1
WEnd
$Data = StringTrimRight($Data, 1)
$Block = StringTrimLeft($Block, $DataPos)
FileWrite($Output, $Data & @CRLF)
; copy the long description
$DataPos = 1
$Data = ""
$Omit = False
While StringRight($Data, 7) <> "@module"
$Data &= StringMid($Block, $DataPos, 1)
$DataPos += 1
WEnd
$Data = StringTrimRight($Data, 8)
FileWrite($Output, $Data & @CRLF)
Return $Output
EndFunc
Func WriteType($Block, $ModuleName, $Output)
Local $TypeName = ParseForOneTag($Block, "@type")
Local $ParentClass = GetData($TypeName, "parent")
Local $Fields = ParseForTags($Block, "@field")
FileWrite($Log, "Writing Type "&$TypeName&@CRLF)
; Add title of Type
FileWrite($Output, "## " & $TypeName & " Class" & @CRLF)
; Add hierearchy info if necessary. Some cool ASCII drawing is going on !
If $ParentClass <> "ROOT" Then
FileWrite($Output, "<pre>" & @CRLF)
FileWrite($Output, "Inheritance : The " & $TypeName & " Class inherits from the following parents :" & @CRLF)
Local $Hierarchy = GetParents($TypeName)
Local $String = ""
Local $TabBuffer = @TAB
$String &= $Hierarchy[0]&@CRLF
For $i=1 to UBound($Hierarchy)-1
$String &= $TabBuffer&"`-- "&$Hierarchy[$i]&@CRLF
$TabBuffer &= @TAB
Next
FileWrite($Output, $String)
FileWrite($Output, "</pre>" & @CRLF)
Else
FileWrite($Output, "<pre>" & @CRLF)
FileWrite($Output, "The " & $TypeName & " class does not inherit" & @CRLF)
FileWrite($Output, "</pre>" & @CRLF)
EndIf
; Copy the long description
Local $DataPos = 1
Local $Data = ""
Local $Omit = False
While StringRight($Data, 1) <> @CR ; We discard the first line
$Data &= StringMid($Block, $DataPos, 1)
$DataPos += 1
WEnd
; If there is a tag in the first line, there is no description
if StringInStr($Data, "@type") == 0 and StringInStr($Data, "@extends") == 0 and StringInStr($Data, "@field") == 0 Then
$Data = ""
$DataPos += 1
While StringRight($Data, 5) <> "@type"
$Data &= StringMid($Block, $DataPos, 1)
$DataPos += 1
WEnd
$Data = StringTrimRight($Data, 5)
FileWrite($Output, $Data & @CRLF)
EndIf
; Add the Attributes
If IsArray($Fields) Then
FileWrite($Output, "<h4> Attributes </h4>" & @CRLF & @CRLF)
FileWrite($Output, ArrayToList($Fields, False) & @CRLF)
EndIf
FileWrite($Output, @CRLF)
Return $TypeName
EndFunc
Func WriteFunction($Block, $Declaration, $Output)
Local $RegexResult = ParseFunctionName($Block, $Declaration)
Local $FunctionName = $RegexResult[0]
Local $TypeName = $RegexResult[1]
Local $Parameters = ParseParams($Block, $Declaration)
Local $Returns = ParseForTags($Block, "@return")
Local $Usage = ParseForOneTag($Block, "@usage")
Local $RegexResult
FileWrite($Log, "Writing Function "&$FunctionName&@CRLF)
If StringLeft($FunctionName, 1) == "_" Then
_FileWriteLog($Log, @TAB&@Tab&"Function is private. Ignored." & @CRLF)
Return $FunctionName
EndIf
; Add the class before the function name
If IsArray($Parameters) Then
If $Parameters[1] == "self" Then
$FunctionName = $TypeName & ":" & $FunctionName
EndIf
Else
$FunctionName = $TypeName & "." & $FunctionName
EndIf
; add the parameters in parenthesis
$FunctionName &= "("
If IsArray($Parameters) Then
For $i = 3 To UBound($Parameters) - 3 Step 3
$FunctionName &= $Parameters[$i + 1] & ", "
Next
If UBound($Parameters) > 3 Then
$FunctionName = StringTrimRight($FunctionName, 2)
EndIf
EndIf
$FunctionName &= ")"
;write the file name
FileWrite($Output, "### " & $FunctionName & @CRLF)
;Write the exemple if any
If $Usage <> "" Then
FileWrite($Output, "``` lua")
FileWrite($Output, $Usage)
FileWrite($Output, "```" & @CRLF)
EndIf
;Write the description
FileWrite($Log, $Block)
FileWrite($Log, StringTrimRight($Block, StringLen($Block) - StringInStr($Block, "@param") + 1) & @CRLF)
FileWrite($Output, StringTrimRight($Block, StringLen($Block) - StringInStr($Block, "@param") + 1) & @CRLF)
; Write the parameters
FileWrite($Output, "<h4> Parameters </h4>" & @CRLF)
If IsArray($Parameters) Then
FileWrite($Output, ArrayToList($Parameters, False) & @CRLF)
EndIf
; Write the returns
FileWrite($Output, "<h4> Returns </h4>" & @CRLF)
If IsArray($Returns) Then
FileWrite($Output, ArrayToList($Returns, True) & @CRLF)
EndIf
FileWrite($Output, @CRLF)
; add to the list of function balises (useful for hyperlinks)
$RegexResult = ParseFunctionName($Block, $Declaration)
Local $URLBalise = $TypeName & "-" & $RegexResult[0] & "-"
If IsArray($Parameters) Then
For $i = 3 To UBound($Parameters) - 3 Step 3
$URLBalise &= StringLower($Parameters[$i + 1]) & "-"
Next
EndIf
$URLBalise = StringTrimRight($URLBalise, 1)
FileWrite($FunctionList, $URLBalise & @CRLF)
return $FunctionName
EndFunc

View File

@ -2847,6 +2847,7 @@ The range till cargo will board.</p>
<dl class="function">
<dt>
<em></em>
<a id="#(CARGO_UNIT).CargoCarrier" >
<strong>CARGO_UNIT.CargoCarrier</strong>
</a>

View File

@ -251,24 +251,60 @@
<td class="name" nowrap="nowrap"><a href="##(REPORT).Add">REPORT:Add(Text)</a></td>
<td class="summary">
<p>Add a new line to a REPORT.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(REPORT).AddIndent">REPORT:AddIndent(Text)</a></td>
<td class="summary">
<p>Add a new line to a REPORT.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(REPORT).ClassName">REPORT.ClassName</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(REPORT).HasText">REPORT:HasText()</a></td>
<td class="summary">
<p>Has the REPORT Text?</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(REPORT).Indent">REPORT.Indent</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(REPORT).New">REPORT:New(Title)</a></td>
<td class="summary">
<p>Create a new REPORT.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(REPORT).Report">REPORT.Report</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(REPORT).SetIndent">REPORT:SetIndent(Indent)</a></td>
<td class="summary">
<p>Set indent of a REPORT.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(REPORT).Text">REPORT:Text(Delimiter)</a></td>
<td class="summary">
<p>Produces the text of the report, taking into account an optional delimeter, which is \n by default.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(REPORT).Title">REPORT.Title</a></td>
<td class="summary">
</td>
</tr>
</table>
@ -765,6 +801,32 @@ Group#GROUP</p>
<p><em><a href="##(REPORT)">#REPORT</a>:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(REPORT).AddIndent" >
<strong>REPORT:AddIndent(Text)</strong>
</a>
</dt>
<dd>
<p>Add a new line to a REPORT.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#string Text </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(REPORT)">#REPORT</a>:</em></p>
</dd>
</dl>
<dl class="function">
@ -779,6 +841,38 @@ Group#GROUP</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(REPORT).HasText" >
<strong>REPORT:HasText()</strong>
</a>
</dt>
<dd>
<p>Has the REPORT Text?</p>
<h3>Return value</h3>
<p><em>#boolean:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(REPORT).Indent" >
<strong>REPORT.Indent</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -805,6 +899,46 @@ Group#GROUP</p>
<p><em><a href="##(REPORT)">#REPORT</a>:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(REPORT).Report" >
<strong>REPORT.Report</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(REPORT).SetIndent" >
<strong>REPORT:SetIndent(Indent)</strong>
</a>
</dt>
<dd>
<p>Set indent of a REPORT.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#number Indent </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(REPORT)">#REPORT</a>:</em></p>
</dd>
</dl>
<dl class="function">
@ -832,6 +966,20 @@ Group#GROUP</p>
<p><em>#string:</em>
The report text.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(REPORT).Title" >
<strong>REPORT.Title</strong>
</a>
</dt>
<dd>
</dd>
</dl>

View File

@ -382,7 +382,7 @@ This is different from the EnRoute tasks, where the targets of the task need to
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).IsTargetDetected">CONTROLLABLE:IsTargetDetected(DCSObject)</a></td>
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).IsTargetDetected">CONTROLLABLE:IsTargetDetected(DCSObject, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK)</a></td>
<td class="summary">
</td>
@ -1466,19 +1466,49 @@ WayPoints If WayPoints is given, then return the WayPoints structure.</p>
<dt>
<a id="#(CONTROLLABLE).IsTargetDetected" >
<strong>CONTROLLABLE:IsTargetDetected(DCSObject)</strong>
<strong>CONTROLLABLE:IsTargetDetected(DCSObject, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em> DCSObject </em></code>: </p>
</li>
<li>
<p><code><em> DetectVisual </em></code>: </p>
</li>
<li>
<p><code><em> DetectOptical </em></code>: </p>
</li>
<li>
<p><code><em> DetectRadar </em></code>: </p>
</li>
<li>
<p><code><em> DetectIRST </em></code>: </p>
</li>
<li>
<p><code><em> DetectRWR </em></code>: </p>
</li>
<li>
<p><code><em> DetectDLINK </em></code>: </p>
</li>
</ul>
</dd>

View File

@ -326,6 +326,12 @@ The following iterator methods are currently available within the DATABASE:</p>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).ForEachPlayerJoined">DATABASE:ForEachPlayerJoined(IteratorFunction, ...)</a></td>
<td class="summary">
<p>Iterate the DATABASE and call an iterator function for each player who has joined the mission, providing the Unit of the player and optional parameters.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).ForEachStatic">DATABASE:ForEachStatic(IteratorFunction, FinalizeFunction, ...)</a></td>
<td class="summary">
<p>Iterate the DATABASE and call an iterator function for each <strong>alive</strong> STATIC, providing the STATIC and optional parameters.</p>
</td>
</tr>
<tr>
@ -1279,6 +1285,43 @@ self</p>
<dl class="function">
<dt>
<a id="#(DATABASE).ForEachStatic" >
<strong>DATABASE:ForEachStatic(IteratorFunction, FinalizeFunction, ...)</strong>
</a>
</dt>
<dd>
<p>Iterate the DATABASE and call an iterator function for each <strong>alive</strong> STATIC, providing the STATIC and optional parameters.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#function IteratorFunction </em></code>:
The function that will be called for each object in the database. The function needs to accept a STATIC parameter.</p>
</li>
<li>
<p><code><em> FinalizeFunction </em></code>: </p>
</li>
<li>
<p><code><em> ... </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE).ForEachUnit" >
<strong>DATABASE:ForEachUnit(IteratorFunction, FinalizeFunction, ...)</strong>
</a>

View File

@ -279,7 +279,7 @@ each detected set of potential targets can be lased or smoked...</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DESIGNATE).MenuStatus">DESIGNATE:MenuStatus(AttackGroup)</a></td>
<td class="name" nowrap="nowrap"><a href="##(DESIGNATE).MenuStatus">DESIGNATE:MenuStatus(AttackGroup, Duration)</a></td>
<td class="summary">
</td>
@ -375,7 +375,7 @@ each detected set of potential targets can be lased or smoked...</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DESIGNATE).SendStatus">DESIGNATE:SendStatus(AttackGroup, MenuAttackGroup)</a></td>
<td class="name" nowrap="nowrap"><a href="##(DESIGNATE).SendStatus">DESIGNATE:SendStatus(AttackGroup, Duration, MenuAttackGroup)</a></td>
<td class="summary">
<p>Sends the status to the Attack Groups.</p>
</td>
@ -1065,19 +1065,24 @@ function below will use the range 1-7 just in case</p>
<dt>
<a id="#(DESIGNATE).MenuStatus" >
<strong>DESIGNATE:MenuStatus(AttackGroup)</strong>
<strong>DESIGNATE:MenuStatus(AttackGroup, Duration)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em> AttackGroup </em></code>: </p>
</li>
<li>
<p><code><em> Duration </em></code>: </p>
</li>
</ul>
</dd>
@ -1556,7 +1561,7 @@ The Attack collection of GROUP objects to designate and report for.</p>
<dt>
<a id="#(DESIGNATE).SendStatus" >
<strong>DESIGNATE:SendStatus(AttackGroup, MenuAttackGroup)</strong>
<strong>DESIGNATE:SendStatus(AttackGroup, Duration, MenuAttackGroup)</strong>
</a>
</dt>
<dd>
@ -1572,6 +1577,12 @@ The Attack collection of GROUP objects to designate and report for.</p>
</li>
<li>
<p><code><em>#number Duration </em></code>:
The time in seconds the report should be visible.</p>
</li>
<li>
<p><code><em> MenuAttackGroup </em></code>: </p>
</li>

View File

@ -192,6 +192,12 @@ DETECTION uses the in-built detection capabilities of DCS World, but adds new fu
<td class="name" nowrap="nowrap"><a href="##(DETECTION_AREAS).CreateDetectionItems">DETECTION_AREAS:CreateDetectionItems()</a></td>
<td class="summary">
<p>Make a DetectionSet table.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_AREAS).DetectedItemMenu">DETECTION_AREAS:DetectedItemMenu(Index)</a></td>
<td class="summary">
<p>Menu of a detected item using a given numeric index.</p>
</td>
</tr>
<tr>
@ -204,6 +210,12 @@ DETECTION uses the in-built detection capabilities of DCS World, but adds new fu
<td class="name" nowrap="nowrap"><a href="##(DETECTION_AREAS).DetectedItems">DETECTION_AREAS.DetectedItems</a></td>
<td class="summary">
<p>A list of areas containing the set of <a href="Unit.html">Unit</a>s, <a href="Zone.html">Zone</a>s, the center <a href="Unit.html">Unit</a> within the zone, and ID of each area that was detected within a DetectionZoneRange.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_AREAS).DetectedReportDetailed">DETECTION_AREAS:DetectedReportDetailed()</a></td>
<td class="summary">
<p>Report detailed of a detection result.</p>
</td>
</tr>
<tr>
@ -331,7 +343,7 @@ DETECTION uses the in-built detection capabilities of DCS World, but adds new fu
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE).AddDetectedItem">DETECTION_BASE:AddDetectedItem(DetectedItemIndex, Set)</a></td>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE).AddDetectedItem">DETECTION_BASE:AddDetectedItem(ItemPrefix, DetectedItemIndex, Set)</a></td>
<td class="summary">
<p>Adds a new DetectedItem to the DetectedItems list.</p>
</td>
@ -424,6 +436,12 @@ DETECTION uses the in-built detection capabilities of DCS World, but adds new fu
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE).DetectedItemMax">DETECTION_BASE.DetectedItemMax</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE).DetectedItemMenu">DETECTION_BASE:DetectedItemMenu(Index)</a></td>
<td class="summary">
<p>Menu of a detected item using a given numeric index.</p>
</td>
</tr>
<tr>
@ -513,12 +531,24 @@ The different values of Unit.Category can be:</p>
</ul>
<p>Multiple Unit.Category entries can be given as a table and then these will be evaluated as an OR expression.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE).GetDetectedID">DETECTION_BASE:GetDetectedID(Index)</a></td>
<td class="summary">
<p>Get a detected ID using a given numeric index.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE).GetDetectedItem">DETECTION_BASE:GetDetectedItem(Index)</a></td>
<td class="summary">
<p>Get a detected item using a given numeric index.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE).GetDetectedItemID">DETECTION_BASE:GetDetectedItemID(Index)</a></td>
<td class="summary">
<p>Get a detected ItemID using a given numeric index.</p>
</td>
</tr>
<tr>
@ -905,6 +935,42 @@ The different values of Unit.Category can be:</p>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE.DetectedObject).Identified">DETECTION_BASE.DetectedObject.Identified</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE.DetectedObject).IsVisible">DETECTION_BASE.DetectedObject.IsVisible</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE.DetectedObject).KnowDistance">DETECTION_BASE.DetectedObject.KnowDistance</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE.DetectedObject).KnowType">DETECTION_BASE.DetectedObject.KnowType</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE.DetectedObject).LastPos">DETECTION_BASE.DetectedObject.LastPos</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE.DetectedObject).LastTime">DETECTION_BASE.DetectedObject.LastTime</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE.DetectedObject).LastVelocity">DETECTION_BASE.DetectedObject.LastVelocity</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -917,12 +983,6 @@ The different values of Unit.Category can be:</p>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE.DetectedObject).Type">DETECTION_BASE.DetectedObject.Type</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE.DetectedObject).Visible">DETECTION_BASE.DetectedObject.Visible</a></td>
<td class="summary">
</td>
</tr>
</table>
@ -939,6 +999,12 @@ The different values of Unit.Category can be:</p>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_TYPES).CreateDetectionItems">DETECTION_TYPES:CreateDetectionItems()</a></td>
<td class="summary">
<p>Create the DetectedItems list from the DetectedObjects table.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_TYPES).DetectedItemMenu">DETECTION_TYPES:DetectedItemMenu(Index, DetectedTypeName)</a></td>
<td class="summary">
<p>Menu of a DetectedItem using a given numeric index.</p>
</td>
</tr>
<tr>
@ -1015,6 +1081,12 @@ The different values of Unit.Category can be:</p>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_UNITS).CreateDetectionItems">DETECTION_UNITS:CreateDetectionItems()</a></td>
<td class="summary">
<p>Create the DetectedItems list from the DetectedObjects table.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DETECTION_UNITS).DetectedItemMenu">DETECTION_UNITS:DetectedItemMenu(Index)</a></td>
<td class="summary">
<p>Menu of a DetectedItem using a given numeric index.</p>
</td>
</tr>
<tr>
@ -1258,7 +1330,7 @@ Use the method <a href="Detection.html##(DETECTION_BASE).SetAcceptRange">Detecti
<pre><code> local SetGroup = SET_GROUP:New():FilterPrefixes( "FAC" ):FilterStart() -- Build a SetGroup of Forward Air Controllers.
-- Build a detect object.
local Detection = DETECTION_BASE:New( SetGroup )
local Detection = DETECTION_UNITS:New( SetGroup )
-- This will accept detected units if the range is below 5000 meters.
Detection:SetAcceptRange( 5000 )
@ -1280,7 +1352,7 @@ Use the method <a href="Detection.html##(DETECTION_BASE).SetAcceptZones">Detecti
local ZoneAccept2 = ZONE:New( "AcceptZone2" )
-- Build a detect object.
local Detection = DETECTION_BASE:New( SetGroup )
local Detection = DETECTION_UNITS:New( SetGroup )
-- This will accept detected units by Detection when the unit is within ZoneAccept1 OR ZoneAccept2.
Detection:SetAcceptZones( { ZoneAccept1, ZoneAccept2 } )
@ -1302,7 +1374,7 @@ An example of how to use the method is shown below.</p>
local ZoneReject2 = ZONE:New( "RejectZone2" )
-- Build a detect object.
local Detection = DETECTION_BASE:New( SetGroup )
local Detection = DETECTION_UNITS:New( SetGroup )
-- This will reject detected units by Detection when the unit is within ZoneReject1 OR ZoneReject2.
Detection:SetRejectZones( { ZoneReject1, ZoneReject2 } )
@ -1476,6 +1548,32 @@ self</p>
<p><em><a href="##(DETECTION_AREAS)">#DETECTION_AREAS</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DETECTION_AREAS).DetectedItemMenu" >
<strong>DETECTION_AREAS:DetectedItemMenu(Index)</strong>
</a>
</dt>
<dd>
<p>Menu of a detected item using a given numeric index.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> Index </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em>#string:</em></p>
</dd>
</dl>
<dl class="function">
@ -1516,6 +1614,24 @@ self</p>
<p>A list of areas containing the set of <a href="Unit.html">Unit</a>s, <a href="Zone.html">Zone</a>s, the center <a href="Unit.html">Unit</a> within the zone, and ID of each area that was detected within a DetectionZoneRange.</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DETECTION_AREAS).DetectedReportDetailed" >
<strong>DETECTION_AREAS:DetectedReportDetailed()</strong>
</a>
</dt>
<dd>
<p>Report detailed of a detection result.</p>
<h3>Return value</h3>
<p><em>#string:</em></p>
</dd>
</dl>
<dl class="function">
@ -1944,7 +2060,7 @@ self</p>
<dt>
<a id="#(DETECTION_BASE).AddDetectedItem" >
<strong>DETECTION_BASE:AddDetectedItem(DetectedItemIndex, Set)</strong>
<strong>DETECTION_BASE:AddDetectedItem(ItemPrefix, DetectedItemIndex, Set)</strong>
</a>
</dt>
<dd>
@ -1958,6 +2074,11 @@ self</p>
<ul>
<li>
<p><code><em> ItemPrefix </em></code>: </p>
</li>
<li>
<p><code><em>#string DetectedItemIndex </em></code>:
The index of the DetectedItem.</p>
@ -2201,6 +2322,7 @@ The index of the DetectedItem.</p>
<dl class="function">
<dt>
<em>#number</em>
<a id="#(DETECTION_BASE).DetectedItemCount" >
<strong>DETECTION_BASE.DetectedItemCount</strong>
</a>
@ -2223,6 +2345,32 @@ The index of the DetectedItem.</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DETECTION_BASE).DetectedItemMenu" >
<strong>DETECTION_BASE:DetectedItemMenu(Index)</strong>
</a>
</dt>
<dd>
<p>Menu of a detected item using a given numeric index.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> Index </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em>#string:</em></p>
</dd>
</dl>
<dl class="function">
@ -2328,7 +2476,7 @@ The index of the DetectedItem.</p>
<dl class="function">
<dt>
<em>#number</em>
<em></em>
<a id="#(DETECTION_BASE).DetectionInterval" >
<strong>DETECTION_BASE.DetectionInterval</strong>
</a>
@ -2468,6 +2616,32 @@ self</p>
<dl class="function">
<dt>
<a id="#(DETECTION_BASE).GetDetectedID" >
<strong>DETECTION_BASE:GetDetectedID(Index)</strong>
</a>
</dt>
<dd>
<p>Get a detected ID using a given numeric index.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#number Index </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em>#string:</em>
DetectedItemID</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DETECTION_BASE).GetDetectedItem" >
<strong>DETECTION_BASE:GetDetectedItem(Index)</strong>
</a>
@ -2489,6 +2663,32 @@ self</p>
<p><em><a href="##(DETECTION_BASE.DetectedItem)">#DETECTION_BASE.DetectedItem</a>:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DETECTION_BASE).GetDetectedItemID" >
<strong>DETECTION_BASE:GetDetectedItemID(Index)</strong>
</a>
</dt>
<dd>
<p>Get a detected ItemID using a given numeric index.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#number Index </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em>#string:</em>
DetectedItemID</p>
</dd>
</dl>
<dl class="function">
@ -2523,7 +2723,7 @@ self</p>
<h3>Return value</h3>
<p><em>#number:</em>
Count</p>
The amount of detected items. Note that the amount of detected items can differ with the reality, because detections are not real-time but doen in intervals!</p>
</dd>
</dl>
@ -4061,6 +4261,90 @@ The To State string.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em>#boolean</em>
<a id="#(DETECTION_BASE.DetectedObject).IsVisible" >
<strong>DETECTION_BASE.DetectedObject.IsVisible</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em>#boolean</em>
<a id="#(DETECTION_BASE.DetectedObject).KnowDistance" >
<strong>DETECTION_BASE.DetectedObject.KnowDistance</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em>#boolean</em>
<a id="#(DETECTION_BASE.DetectedObject).KnowType" >
<strong>DETECTION_BASE.DetectedObject.KnowType</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em>#boolean</em>
<a id="#(DETECTION_BASE.DetectedObject).LastPos" >
<strong>DETECTION_BASE.DetectedObject.LastPos</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em>#number</em>
<a id="#(DETECTION_BASE.DetectedObject).LastTime" >
<strong>DETECTION_BASE.DetectedObject.LastTime</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em>#number</em>
<a id="#(DETECTION_BASE.DetectedObject).LastVelocity" >
<strong>DETECTION_BASE.DetectedObject.LastVelocity</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -4089,20 +4373,6 @@ The To State string.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em>#boolean</em>
<a id="#(DETECTION_BASE.DetectedObject).Visible" >
<strong>DETECTION_BASE.DetectedObject.Visible</strong>
</a>
</dt>
<dd>
</dd>
</dl>
@ -4154,6 +4424,37 @@ Beware that when the amount of different types detected is large, the DetectedIt
<p><em><a href="##(DETECTION_TYPES)">#DETECTION_TYPES</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DETECTION_TYPES).DetectedItemMenu" >
<strong>DETECTION_TYPES:DetectedItemMenu(Index, DetectedTypeName)</strong>
</a>
</dt>
<dd>
<p>Menu of a DetectedItem using a given numeric index.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em> Index </em></code>: </p>
</li>
<li>
<p><code><em> DetectedTypeName </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em>#string:</em></p>
</dd>
</dl>
<dl class="function">
@ -4389,6 +4690,32 @@ Beware that when the amount of units detected is large, the DetectedItems list w
<p><em><a href="##(DETECTION_UNITS)">#DETECTION_UNITS</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DETECTION_UNITS).DetectedItemMenu" >
<strong>DETECTION_UNITS:DetectedItemMenu(Index)</strong>
</a>
</dt>
<dd>
<p>Menu of a DetectedItem using a given numeric index.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> Index </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em>#string:</em></p>
</dd>
</dl>
<dl class="function">

View File

@ -167,7 +167,7 @@ A <a href="CLIENT.html">CLIENT</a> needs to be registered within the <a href="MI
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).GetMenu">MISSION:GetMenu(TaskGroup)</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).GetMenu">MISSION:GetMenu()</a></td>
<td class="summary">
<p>Gets the mission menu for the coalition.</p>
</td>
@ -200,6 +200,12 @@ A <a href="CLIENT.html">CLIENT</a> needs to be registered within the <a href="MI
<td class="name" nowrap="nowrap"><a href="##(MISSION).GetTasks">MISSION:GetTasks()</a></td>
<td class="summary">
<p>Get all the TASKs from the Mission.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).GetTasksRemaining">MISSION:GetTasksRemaining()</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -209,39 +215,51 @@ A <a href="CLIENT.html">CLIENT</a> needs to be registered within the <a href="MI
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).IsCompleted">MISSION:IsCompleted()</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).IsCOMPLETED">MISSION:IsCOMPLETED()</a></td>
<td class="summary">
<p>Is the <a href="Mission.html">Mission</a> <strong>Completed</strong>.</p>
<p>Is the <a href="Mission.html">Mission</a> <strong>COMPLETED</strong>.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).IsFailed">MISSION:IsFailed()</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).IsENGAGED">MISSION:IsENGAGED()</a></td>
<td class="summary">
<p>Is the <a href="Mission.html">Mission</a> <strong>Failed</strong>.</p>
<p>Is the <a href="Mission.html">Mission</a> <strong>ENGAGED</strong>.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).IsHold">MISSION:IsHold()</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).IsFAILED">MISSION:IsFAILED()</a></td>
<td class="summary">
<p>Is the <a href="Mission.html">Mission</a> <strong>Hold</strong>.</p>
<p>Is the <a href="Mission.html">Mission</a> <strong>FAILED</strong>.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).IsIdle">MISSION:IsIdle()</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).IsHOLD">MISSION:IsHOLD()</a></td>
<td class="summary">
<p>Is the <a href="Mission.html">Mission</a> <strong>Idle</strong>.</p>
<p>Is the <a href="Mission.html">Mission</a> <strong>HOLD</strong>.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).IsOngoing">MISSION:IsOngoing()</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).IsIDLE">MISSION:IsIDLE()</a></td>
<td class="summary">
<p>Is the <a href="Mission.html">Mission</a> <strong>Ongoing</strong>.</p>
<p>Is the <a href="Mission.html">Mission</a> <strong>IDLE</strong>.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).JoinUnit">MISSION:JoinUnit(PlayerUnit, PlayerGroup)</a></td>
<td class="summary">
<p>Add a Unit to join the Mission.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).MenuReportOverview">MISSION:MenuReportOverview(TaskStatus, ReportGroup)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).MenuReportSummary">MISSION:MenuReportSummary(ReportGroup)</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -323,51 +341,51 @@ A <a href="CLIENT.html">CLIENT</a> needs to be registered within the <a href="MI
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnEnterCompleted">MISSION:OnEnterCompleted(From, Event, To)</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnEnterCOMPLETED">MISSION:OnEnterCOMPLETED(From, Event, To)</a></td>
<td class="summary">
<p>OnEnter Transition Handler for State Completed.</p>
<p>OnEnter Transition Handler for State COMPLETED.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnEnterFailed">MISSION:OnEnterFailed(From, Event, To)</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnEnterENGAGED">MISSION:OnEnterENGAGED(From, Event, To)</a></td>
<td class="summary">
<p>OnEnter Transition Handler for State Failed.</p>
<p>OnEnter Transition Handler for State ENGAGED.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnEnterIdle">MISSION:OnEnterIdle(From, Event, To)</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnEnterFAILED">MISSION:OnEnterFAILED(From, Event, To)</a></td>
<td class="summary">
<p>OnEnter Transition Handler for State Idle.</p>
<p>OnEnter Transition Handler for State FAILED.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnEnterOngoing">MISSION:OnEnterOngoing(From, Event, To)</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnEnterIDLE">MISSION:OnEnterIDLE(From, Event, To)</a></td>
<td class="summary">
<p>OnEnter Transition Handler for State Ongoing.</p>
<p>OnEnter Transition Handler for State IDLE.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnLeaveCompleted">MISSION:OnLeaveCompleted(From, Event, To)</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnLeaveCOMPLETED">MISSION:OnLeaveCOMPLETED(From, Event, To)</a></td>
<td class="summary">
<p>OnLeave Transition Handler for State Completed.</p>
<p>OnLeave Transition Handler for State COMPLETED.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnLeaveFailed">MISSION:OnLeaveFailed(From, Event, To)</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnLeaveENGAGED">MISSION:OnLeaveENGAGED(From, Event, To)</a></td>
<td class="summary">
<p>OnLeave Transition Handler for State Failed.</p>
<p>OnLeave Transition Handler for State ENGAGED.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnLeaveIdle">MISSION:OnLeaveIdle(From, Event, To)</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnLeaveFAILED">MISSION:OnLeaveFAILED(From, Event, To)</a></td>
<td class="summary">
<p>OnLeave Transition Handler for State Idle.</p>
<p>OnLeave Transition Handler for State FAILED.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnLeaveOngoing">MISSION:OnLeaveOngoing(From, Event, To)</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).OnLeaveIDLE">MISSION:OnLeaveIDLE(From, Event, To)</a></td>
<td class="summary">
<p>OnLeave Transition Handler for State Ongoing.</p>
<p>OnLeave Transition Handler for State IDLE.</p>
</td>
</tr>
<tr>
@ -395,7 +413,7 @@ A <a href="CLIENT.html">CLIENT</a> needs to be registered within the <a href="MI
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).ReportOverview">MISSION:ReportOverview()</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).ReportOverview">MISSION:ReportOverview(TaskStatus)</a></td>
<td class="summary">
<p>Create a overview report of the Mission (multiple lines).</p>
</td>
@ -467,7 +485,7 @@ A <a href="CLIENT.html">CLIENT</a> needs to be registered within the <a href="MI
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).onenterCompleted">MISSION:onenterCompleted(From, Event, To)</a></td>
<td class="name" nowrap="nowrap"><a href="##(MISSION).onenterCOMPLETED">MISSION:onenterCOMPLETED(From, Event, To)</a></td>
<td class="summary">
</td>
@ -697,21 +715,13 @@ true if Unit is part of a Task in the Mission.</p>
<dt>
<a id="#(MISSION).GetMenu" >
<strong>MISSION:GetMenu(TaskGroup)</strong>
<strong>MISSION:GetMenu()</strong>
</a>
</dt>
<dd>
<p>Gets the mission menu for the coalition.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em><a href="Wrapper.Group.html##(GROUP)">Wrapper.Group#GROUP</a> TaskGroup </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="Core.Menu.html##(MENU_COALITION)">Core.Menu#MENU_COALITION</a>:</em>
@ -851,6 +861,24 @@ Returns nil if no task was found.</p>
Tasks = Mission:GetTasks()
env.info( "Task 2 Completion = " .. Tasks[2]:GetGoalPercentage() .. "%" )</code></pre>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSION).GetTasksRemaining" >
<strong>MISSION:GetTasksRemaining()</strong>
</a>
</dt>
<dd>
<h3>Return value</h3>
<p><em>#number:</em></p>
</dd>
</dl>
<dl class="function">
@ -893,13 +921,13 @@ true if the Mission has a Group.</p>
<dl class="function">
<dt>
<a id="#(MISSION).IsCompleted" >
<strong>MISSION:IsCompleted()</strong>
<a id="#(MISSION).IsCOMPLETED" >
<strong>MISSION:IsCOMPLETED()</strong>
</a>
</dt>
<dd>
<p>Is the <a href="Mission.html">Mission</a> <strong>Completed</strong>.</p>
<p>Is the <a href="Mission.html">Mission</a> <strong>COMPLETED</strong>.</p>
<h3>Return value</h3>
@ -911,13 +939,13 @@ true if the Mission has a Group.</p>
<dl class="function">
<dt>
<a id="#(MISSION).IsFailed" >
<strong>MISSION:IsFailed()</strong>
<a id="#(MISSION).IsENGAGED" >
<strong>MISSION:IsENGAGED()</strong>
</a>
</dt>
<dd>
<p>Is the <a href="Mission.html">Mission</a> <strong>Failed</strong>.</p>
<p>Is the <a href="Mission.html">Mission</a> <strong>ENGAGED</strong>.</p>
<h3>Return value</h3>
@ -929,13 +957,13 @@ true if the Mission has a Group.</p>
<dl class="function">
<dt>
<a id="#(MISSION).IsHold" >
<strong>MISSION:IsHold()</strong>
<a id="#(MISSION).IsFAILED" >
<strong>MISSION:IsFAILED()</strong>
</a>
</dt>
<dd>
<p>Is the <a href="Mission.html">Mission</a> <strong>Hold</strong>.</p>
<p>Is the <a href="Mission.html">Mission</a> <strong>FAILED</strong>.</p>
<h3>Return value</h3>
@ -947,13 +975,13 @@ true if the Mission has a Group.</p>
<dl class="function">
<dt>
<a id="#(MISSION).IsIdle" >
<strong>MISSION:IsIdle()</strong>
<a id="#(MISSION).IsHOLD" >
<strong>MISSION:IsHOLD()</strong>
</a>
</dt>
<dd>
<p>Is the <a href="Mission.html">Mission</a> <strong>Idle</strong>.</p>
<p>Is the <a href="Mission.html">Mission</a> <strong>HOLD</strong>.</p>
<h3>Return value</h3>
@ -965,13 +993,13 @@ true if the Mission has a Group.</p>
<dl class="function">
<dt>
<a id="#(MISSION).IsOngoing" >
<strong>MISSION:IsOngoing()</strong>
<a id="#(MISSION).IsIDLE" >
<strong>MISSION:IsIDLE()</strong>
</a>
</dt>
<dd>
<p>Is the <a href="Mission.html">Mission</a> <strong>Ongoing</strong>.</p>
<p>Is the <a href="Mission.html">Mission</a> <strong>IDLE</strong>.</p>
<h3>Return value</h3>
@ -1016,6 +1044,54 @@ The GROUP of the player joining the Mission.</p>
<p><em>#boolean:</em>
true if Unit is part of a Task in the Mission.</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSION).MenuReportOverview" >
<strong>MISSION:MenuReportOverview(TaskStatus, ReportGroup)</strong>
</a>
</dt>
<dd>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#string TaskStatus </em></code>:
The status</p>
</li>
<li>
<p><code><em><a href="Wrapper.Group.html##(GROUP)">Wrapper.Group#GROUP</a> ReportGroup </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSION).MenuReportSummary" >
<strong>MISSION:MenuReportSummary(ReportGroup)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em><a href="Wrapper.Group.html##(GROUP)">Wrapper.Group#GROUP</a> ReportGroup </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
@ -1422,13 +1498,13 @@ Return false to cancel Transition.</p>
<dl class="function">
<dt>
<a id="#(MISSION).OnEnterCompleted" >
<strong>MISSION:OnEnterCompleted(From, Event, To)</strong>
<a id="#(MISSION).OnEnterCOMPLETED" >
<strong>MISSION:OnEnterCOMPLETED(From, Event, To)</strong>
</a>
</dt>
<dd>
<p>OnEnter Transition Handler for State Completed.</p>
<p>OnEnter Transition Handler for State COMPLETED.</p>
<h3>Parameters</h3>
<ul>
@ -1456,13 +1532,13 @@ The To State string.</p>
<dl class="function">
<dt>
<a id="#(MISSION).OnEnterFailed" >
<strong>MISSION:OnEnterFailed(From, Event, To)</strong>
<a id="#(MISSION).OnEnterENGAGED" >
<strong>MISSION:OnEnterENGAGED(From, Event, To)</strong>
</a>
</dt>
<dd>
<p>OnEnter Transition Handler for State Failed.</p>
<p>OnEnter Transition Handler for State ENGAGED.</p>
<h3>Parameters</h3>
<ul>
@ -1490,13 +1566,13 @@ The To State string.</p>
<dl class="function">
<dt>
<a id="#(MISSION).OnEnterIdle" >
<strong>MISSION:OnEnterIdle(From, Event, To)</strong>
<a id="#(MISSION).OnEnterFAILED" >
<strong>MISSION:OnEnterFAILED(From, Event, To)</strong>
</a>
</dt>
<dd>
<p>OnEnter Transition Handler for State Idle.</p>
<p>OnEnter Transition Handler for State FAILED.</p>
<h3>Parameters</h3>
<ul>
@ -1524,13 +1600,13 @@ The To State string.</p>
<dl class="function">
<dt>
<a id="#(MISSION).OnEnterOngoing" >
<strong>MISSION:OnEnterOngoing(From, Event, To)</strong>
<a id="#(MISSION).OnEnterIDLE" >
<strong>MISSION:OnEnterIDLE(From, Event, To)</strong>
</a>
</dt>
<dd>
<p>OnEnter Transition Handler for State Ongoing.</p>
<p>OnEnter Transition Handler for State IDLE.</p>
<h3>Parameters</h3>
<ul>
@ -1558,13 +1634,13 @@ The To State string.</p>
<dl class="function">
<dt>
<a id="#(MISSION).OnLeaveCompleted" >
<strong>MISSION:OnLeaveCompleted(From, Event, To)</strong>
<a id="#(MISSION).OnLeaveCOMPLETED" >
<strong>MISSION:OnLeaveCOMPLETED(From, Event, To)</strong>
</a>
</dt>
<dd>
<p>OnLeave Transition Handler for State Completed.</p>
<p>OnLeave Transition Handler for State COMPLETED.</p>
<h3>Parameters</h3>
<ul>
@ -1597,13 +1673,13 @@ Return false to cancel Transition.</p>
<dl class="function">
<dt>
<a id="#(MISSION).OnLeaveFailed" >
<strong>MISSION:OnLeaveFailed(From, Event, To)</strong>
<a id="#(MISSION).OnLeaveENGAGED" >
<strong>MISSION:OnLeaveENGAGED(From, Event, To)</strong>
</a>
</dt>
<dd>
<p>OnLeave Transition Handler for State Failed.</p>
<p>OnLeave Transition Handler for State ENGAGED.</p>
<h3>Parameters</h3>
<ul>
@ -1636,13 +1712,13 @@ Return false to cancel Transition.</p>
<dl class="function">
<dt>
<a id="#(MISSION).OnLeaveIdle" >
<strong>MISSION:OnLeaveIdle(From, Event, To)</strong>
<a id="#(MISSION).OnLeaveFAILED" >
<strong>MISSION:OnLeaveFAILED(From, Event, To)</strong>
</a>
</dt>
<dd>
<p>OnLeave Transition Handler for State Idle.</p>
<p>OnLeave Transition Handler for State FAILED.</p>
<h3>Parameters</h3>
<ul>
@ -1675,13 +1751,13 @@ Return false to cancel Transition.</p>
<dl class="function">
<dt>
<a id="#(MISSION).OnLeaveOngoing" >
<strong>MISSION:OnLeaveOngoing(From, Event, To)</strong>
<a id="#(MISSION).OnLeaveIDLE" >
<strong>MISSION:OnLeaveIDLE(From, Event, To)</strong>
</a>
</dt>
<dd>
<p>OnLeave Transition Handler for State Ongoing.</p>
<p>OnLeave Transition Handler for State IDLE.</p>
<h3>Parameters</h3>
<ul>
@ -1811,13 +1887,21 @@ self</p>
<dt>
<a id="#(MISSION).ReportOverview" >
<strong>MISSION:ReportOverview()</strong>
<strong>MISSION:ReportOverview(TaskStatus)</strong>
</a>
</dt>
<dd>
<p>Create a overview report of the Mission (multiple lines).</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> TaskStatus </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em>#string:</em></p>
@ -2047,8 +2131,8 @@ The delay in seconds.</p>
<dl class="function">
<dt>
<a id="#(MISSION).onenterCompleted" >
<strong>MISSION:onenterCompleted(From, Event, To)</strong>
<a id="#(MISSION).onenterCOMPLETED" >
<strong>MISSION:onenterCOMPLETED(From, Event, To)</strong>
</a>
</dt>
<dd>

View File

@ -157,6 +157,14 @@
<h2>Global(s)</h2>
<table class="function_list">
<tr>
<td class="name" nowrap="nowrap"><a href="#COORDINATE">COORDINATE</a></td>
<td class="summary">
<h1>COORDINATE class, extends <a href="Point.html##(COORDINATE)">Point#COORDINATE</a></h1>
<p>The COORDINATE class defines a 2D coordinate in the simulator.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="#POINT_VEC2">POINT_VEC2</a></td>
<td class="summary">
@ -174,6 +182,107 @@
</td>
</tr>
</table>
<h2><a id="#(COORDINATE)">Type <code>COORDINATE</code></a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).CoordinateMenu">COORDINATE:CoordinateMenu(RootMenu)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).LL_Accuracy">COORDINATE.LL_Accuracy</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).LL_DMS">COORDINATE.LL_DMS</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).MGRS_Accuracy">COORDINATE.MGRS_Accuracy</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).MenuLL_Accuracy">COORDINATE:MenuLL_Accuracy(LL_Accuracy)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).MenuLL_DMS">COORDINATE:MenuLL_DMS(LL_DMS)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).MenuMGRS_Accuracy">COORDINATE:MenuMGRS_Accuracy(MGRS_Accuracy)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).MenuSystem">COORDINATE:MenuSystem(System)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).New">COORDINATE:New(x, y, LandHeightAdd)</a></td>
<td class="summary">
<p>COORDINATE constructor.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).NewFromVec2">COORDINATE:NewFromVec2(Vec2, LandHeightAdd)</a></td>
<td class="summary">
<p>Create a new COORDINATE object from Vec2 coordinates.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).NewFromVec3">COORDINATE:NewFromVec3(Vec3)</a></td>
<td class="summary">
<p>Create a new COORDINATE object from Vec3 coordinates.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).System">COORDINATE.System</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).SystemMenu">COORDINATE.SystemMenu</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).ToString">COORDINATE:ToString()</a></td>
<td class="summary">
<p>Provides a coordinate string of the point, based on a coordinate format system:
* Uses default settings in COORDINATE.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).ToStringLL">COORDINATE:ToStringLL(LL_Accuracy, LL_DMS)</a></td>
<td class="summary">
<p>Provides a Lat Lon string</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(COORDINATE).ToStringMGRS">COORDINATE:ToStringMGRS(MGRS_Accuracy)</a></td>
<td class="summary">
<p>Provides a MGRS string</p>
</td>
</tr>
</table>
<h2><a id="#(POINT_VEC2)">Type <code>POINT_VEC2</code></a></h2>
<table class="function_list">
<tr>
@ -622,12 +731,6 @@
<td class="name" nowrap="nowrap"><a href="##(POINT_VEC3).ToStringBR">POINT_VEC3:ToStringBR(AngleRadians, Distance)</a></td>
<td class="summary">
<p>Provides a Bearing / Range string</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(POINT_VEC3).ToStringLL">POINT_VEC3:ToStringLL(AngleRadians, Distance, acc, DMS)</a></td>
<td class="summary">
<p>Provides a Bearing / Range string</p>
</td>
</tr>
<tr>
@ -702,6 +805,51 @@
<dl class="function">
<dt>
<em><a href="##(COORDINATE)">#COORDINATE</a></em>
<a id="COORDINATE" >
<strong>COORDINATE</strong>
</a>
</dt>
<dd>
<h1>COORDINATE class, extends <a href="Point.html##(COORDINATE)">Point#COORDINATE</a></h1>
<p>The COORDINATE class defines a 2D coordinate in the simulator.</p>
<p>The height coordinate (if needed) will be the land height + an optional added height specified.
A COORDINATE can be expressed in LL or in MGRS.</p>
<h2>COORDINATE constructor</h2>
<p>A new COORDINATE instance can be created with:</p>
<ul>
<li><a href="Point.html##(COORDINATE).New">Point#COORDINATE.New</a>(): a 2D point, taking an additional height parameter.</li>
<li><a href="Point.html##(COORDINATE).NewFromVec2">Point#COORDINATE.NewFromVec2</a>(): a 2D point created from a <a href="DCSTypes.html##(Vec2)">DCSTypes#Vec2</a>.</li>
</ul>
<h2>Manupulate the X, Altitude, Y coordinates of the 2D point</h2>
<p>A COORDINATE class works in 2D space, with an altitude setting. It contains internally an X, Altitude, Y coordinate.
Methods exist to manupulate these coordinates.</p>
<p>The current X, Altitude, Y axis can be retrieved with the methods <a href="##(COORDINATE).GetX">COORDINATE.GetX</a>(), <a href="##(COORDINATE).GetAlt">COORDINATE.GetAlt</a>(), <a href="##(COORDINATE).GetY">COORDINATE.GetY</a>() respectively.
The methods <a href="##(COORDINATE).SetX">COORDINATE.SetX</a>(), <a href="##(COORDINATE).SetAlt">COORDINATE.SetAlt</a>(), <a href="##(COORDINATE).SetY">COORDINATE.SetY</a>() change the respective axis with a new value.
The current Lat(itude), Alt(itude), Lon(gitude) values can also be retrieved with the methods <a href="##(COORDINATE).GetLat">COORDINATE.GetLat</a>(), <a href="##(COORDINATE).GetAlt">COORDINATE.GetAlt</a>(), <a href="##(COORDINATE).GetLon">COORDINATE.GetLon</a>() respectively.
The current axis values can be changed by using the methods <a href="##(COORDINATE).AddX">COORDINATE.AddX</a>(), <a href="##(COORDINATE).AddAlt">COORDINATE.AddAlt</a>(), <a href="##(COORDINATE).AddY">COORDINATE.AddY</a>()
to add or substract a value from the current respective axis value.
Note that the Set and Add methods return the current COORDINATE object, so these manipulation methods can be chained... For example:</p>
<pre><code> local Vec2 = PointVec2:AddX( 100 ):AddY( 2000 ):GetVec2()
</code></pre>
</dd>
</dl>
<dl class="function">
<dt>
<em><a href="##(POINT_VEC2)">#POINT_VEC2</a></em>
<a id="POINT_VEC2" >
<strong>POINT_VEC2</strong>
@ -904,6 +1052,378 @@ Note that the Set and Add methods return the current POINT_VEC3 object, so these
</dl>
<h2><a id="#(Point)" >Type <code>Point</code></a></h2>
<h2><a id="#(COORDINATE)" >Type <code>COORDINATE</code></a></h2>
<h3>Field(s)</h3>
<dl class="function">
<dt>
<a id="#(COORDINATE).CoordinateMenu" >
<strong>COORDINATE:CoordinateMenu(RootMenu)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> RootMenu </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em>#string:</em>
The coordinate Text in the configured coordinate system.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em>#number</em>
<a id="#(COORDINATE).LL_Accuracy" >
<strong>COORDINATE.LL_Accuracy</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em>#boolean</em>
<a id="#(COORDINATE).LL_DMS" >
<strong>COORDINATE.LL_DMS</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em>#number</em>
<a id="#(COORDINATE).MGRS_Accuracy" >
<strong>COORDINATE.MGRS_Accuracy</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(COORDINATE).MenuLL_Accuracy" >
<strong>COORDINATE:MenuLL_Accuracy(LL_Accuracy)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> LL_Accuracy </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(COORDINATE).MenuLL_DMS" >
<strong>COORDINATE:MenuLL_DMS(LL_DMS)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> LL_DMS </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(COORDINATE).MenuMGRS_Accuracy" >
<strong>COORDINATE:MenuMGRS_Accuracy(MGRS_Accuracy)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> MGRS_Accuracy </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(COORDINATE).MenuSystem" >
<strong>COORDINATE:MenuSystem(System)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> System </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(COORDINATE).New" >
<strong>COORDINATE:New(x, y, LandHeightAdd)</strong>
</a>
</dt>
<dd>
<p>COORDINATE constructor.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em><a href="Dcs.DCSTypes.html##(Distance)">Dcs.DCSTypes#Distance</a> x </em></code>:
The x coordinate of the Vec3 point, pointing to the North.</p>
</li>
<li>
<p><code><em><a href="Dcs.DCSTypes.html##(Distance)">Dcs.DCSTypes#Distance</a> y </em></code>:
The y coordinate of the Vec3 point, pointing to the Right.</p>
</li>
<li>
<p><code><em><a href="Dcs.DCSTypes.html##(Distance)">Dcs.DCSTypes#Distance</a> LandHeightAdd </em></code>:
(optional) The default height if required to be evaluated will be the land height of the x, y coordinate. You can specify an extra height to be added to the land height.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="Core.Point.html##(COORDINATE)">Core.Point#COORDINATE</a>:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(COORDINATE).NewFromVec2" >
<strong>COORDINATE:NewFromVec2(Vec2, LandHeightAdd)</strong>
</a>
</dt>
<dd>
<p>Create a new COORDINATE object from Vec2 coordinates.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em><a href="Dcs.DCSTypes.html##(Vec2)">Dcs.DCSTypes#Vec2</a> Vec2 </em></code>:
The Vec2 point.</p>
</li>
<li>
<p><code><em><a href="Dcs.DCSTypes.html##(Distance)">Dcs.DCSTypes#Distance</a> LandHeightAdd </em></code>:
(optional) The default height if required to be evaluated will be the land height of the x, y coordinate. You can specify an extra height to be added to the land height.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="Core.Point.html##(COORDINATE)">Core.Point#COORDINATE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(COORDINATE).NewFromVec3" >
<strong>COORDINATE:NewFromVec3(Vec3)</strong>
</a>
</dt>
<dd>
<p>Create a new COORDINATE object from Vec3 coordinates.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em><a href="Dcs.DCSTypes.html##(Vec3)">Dcs.DCSTypes#Vec3</a> Vec3 </em></code>:
The Vec3 point.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="Core.Point.html##(COORDINATE)">Core.Point#COORDINATE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<em>#string</em>
<a id="#(COORDINATE).System" >
<strong>COORDINATE.System</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(COORDINATE).SystemMenu" >
<strong>COORDINATE.SystemMenu</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(COORDINATE).ToString" >
<strong>COORDINATE:ToString()</strong>
</a>
</dt>
<dd>
<p>Provides a coordinate string of the point, based on a coordinate format system:
* Uses default settings in COORDINATE.</p>
<ul>
<li>Can be overridden if for a GROUP containing x clients, a menu was selected to override the default.</li>
</ul>
<h3>Return value</h3>
<p><em>#string:</em>
The coordinate Text in the configured coordinate system.</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(COORDINATE).ToStringLL" >
<strong>COORDINATE:ToStringLL(LL_Accuracy, LL_DMS)</strong>
</a>
</dt>
<dd>
<p>Provides a Lat Lon string</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#number LL_Accuracy </em></code>:
The accurancy of significant numbers behind the comma... So Accurancy of 2 is 0.01.</p>
</li>
<li>
<p><code><em>#boolean LL_DMS </em></code>:
true = Degrees, Minutes, Seconds; false = Degrees, Minutes</p>
</li>
</ul>
<h3>Return value</h3>
<p><em>#string:</em>
The LL Text</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(COORDINATE).ToStringMGRS" >
<strong>COORDINATE:ToStringMGRS(MGRS_Accuracy)</strong>
</a>
</dt>
<dd>
<p>Provides a MGRS string</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#number MGRS_Accuracy </em></code>:
of the 5 digit code.
Precision depends on the Accuracy choosen:
* 0 = no digits - precision level 100 km
* 1 = 1 digits - precision level 10 km
* 2 = 2 digits - precision level 1 km
* 3 = 3 digits - precision level 100 m
* 4 = 4 digits - precision level 10 m.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em>#string:</em>
The MGRS Text</p>
</dd>
</dl>
<h2><a id="#(POINT_VEC2)" >Type <code>POINT_VEC2</code></a></h2>
<h3>Field(s)</h3>
<dl class="function">
@ -1451,7 +1971,6 @@ The new calculated POINT_VEC2.</p>
<dl class="function">
<dt>
<em></em>
<a id="#(POINT_VEC2).z" >
<strong>POINT_VEC2.z</strong>
</a>
@ -2664,49 +3183,6 @@ The BR Text</p>
<dl class="function">
<dt>
<a id="#(POINT_VEC3).ToStringLL" >
<strong>POINT_VEC3:ToStringLL(AngleRadians, Distance, acc, DMS)</strong>
</a>
</dt>
<dd>
<p>Provides a Bearing / Range string</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#number AngleRadians </em></code>:
The angle in randians</p>
</li>
<li>
<p><code><em>#number Distance </em></code>:
The distance</p>
</li>
<li>
<p><code><em> acc </em></code>: </p>
</li>
<li>
<p><code><em> DMS </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em>#string:</em>
The BR Text</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(POINT_VEC3).Translate" >
<strong>POINT_VEC3:Translate(Distance, Angle)</strong>
</a>

View File

@ -163,6 +163,12 @@
<td class="name" nowrap="nowrap"><a href="##(POSITIONABLE).GetBeacon">POSITIONABLE:GetBeacon()</a></td>
<td class="summary">
<p>Create a <a href="Radio.html##(BEACON)">Radio#BEACON</a>, to allow this POSITIONABLE to broadcast beacon signals</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(POSITIONABLE).GetCoordinate">POSITIONABLE:GetCoordinate()</a></td>
<td class="summary">
<p>Returns a COORDINATE object indicating the point in 3D of the POSITIONABLE within the mission.</p>
</td>
</tr>
<tr>
@ -457,6 +463,34 @@ Radio</p>
<dl class="function">
<dt>
<a id="#(POSITIONABLE).GetCoordinate" >
<strong>POSITIONABLE:GetCoordinate()</strong>
</a>
</dt>
<dd>
<p>Returns a COORDINATE object indicating the point in 3D of the POSITIONABLE within the mission.</p>
<h3>Return values</h3>
<ol>
<li>
<p><em><a href="Core.Point.html##(COORDINATE)">Core.Point#COORDINATE</a>:</em>
The COORDINATE of the POSITIONABLE.</p>
</li>
<li>
<p><em>#nil:</em>
The POSITIONABLE is not existing or alive. </p>
</li>
</ol>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(POSITIONABLE).GetHeading" >
<strong>POSITIONABLE:GetHeading()</strong>
</a>

View File

@ -2527,9 +2527,6 @@ when nothing was spawned.</p>
<p> Overwrite unit names by default with group name.</p>
</dd>
</dl>
<dl class="function">

View File

@ -424,6 +424,12 @@
<td class="name" nowrap="nowrap"><a href="##(TASK).ReportDetails">TASK:ReportDetails()</a></td>
<td class="summary">
<p>Create a detailed report of the Task.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(TASK).ReportOverview">TASK:ReportOverview()</a></td>
<td class="summary">
<p>Create an overiew report of the Task.</p>
</td>
</tr>
<tr>
@ -466,6 +472,12 @@
<td class="name" nowrap="nowrap"><a href="##(TASK).SetID">TASK:SetID(TaskID)</a></td>
<td class="summary">
<p>Sets the ID of the Task</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(TASK).SetInfo">TASK:SetInfo(TaskInfo, TaskInfoText)</a></td>
<td class="summary">
<p>Sets the Information on the Task</p>
</td>
</tr>
<tr>
@ -1859,6 +1871,27 @@ self</p>
<p><em>#string:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(TASK).ReportOverview" >
<strong>TASK:ReportOverview()</strong>
</a>
</dt>
<dd>
<p>Create an overiew report of the Task.</p>
<p>List the Task Name and Status</p>
<h3>Return value</h3>
<p><em>#string:</em></p>
</dd>
</dl>
<dl class="function">
@ -2016,6 +2049,32 @@ self</p>
<dl class="function">
<dt>
<a id="#(TASK).SetInfo" >
<strong>TASK:SetInfo(TaskInfo, TaskInfoText)</strong>
</a>
</dt>
<dd>
<p>Sets the Information on the Task</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#string TaskInfo </em></code>: </p>
</li>
<li>
<p><code><em> TaskInfoText </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(TASK).SetMenu" >
<strong>TASK:SetMenu(MenuTime)</strong>
</a>

View File

@ -182,7 +182,7 @@ Find a summary below describing for which situation a task type is created:</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(TASK_A2G_DISPATCHER).EvaluateRemoveTask">TASK_A2G_DISPATCHER:EvaluateRemoveTask(Mission, Task, DetectedItem)</a></td>
<td class="name" nowrap="nowrap"><a href="##(TASK_A2G_DISPATCHER).EvaluateRemoveTask">TASK_A2G_DISPATCHER:EvaluateRemoveTask(Mission, Task, DetectedItemID, DetectedItemChange, DetectedItemChanged)</a></td>
<td class="summary">
<p>Evaluates the removal of the Task from the Mission.</p>
</td>
@ -221,6 +221,12 @@ Find a summary below describing for which situation a task type is created:</p>
<td class="name" nowrap="nowrap"><a href="##(TASK_A2G_DISPATCHER).SetGroup">TASK_A2G_DISPATCHER.SetGroup</a></td>
<td class="summary">
<p>The groups to which the FAC will report to.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(TASK_A2G_DISPATCHER).Tasks">TASK_A2G_DISPATCHER.Tasks</a></td>
<td class="summary">
</td>
</tr>
</table>
@ -336,7 +342,7 @@ Find a summary below describing for which situation a task type is created:</p>
<dt>
<a id="#(TASK_A2G_DISPATCHER).EvaluateRemoveTask" >
<strong>TASK_A2G_DISPATCHER:EvaluateRemoveTask(Mission, Task, DetectedItem)</strong>
<strong>TASK_A2G_DISPATCHER:EvaluateRemoveTask(Mission, Task, DetectedItemID, DetectedItemChange, DetectedItemChanged)</strong>
</a>
</dt>
<dd>
@ -360,7 +366,17 @@ Find a summary below describing for which situation a task type is created:</p>
</li>
<li>
<p><code><em><a href="Functional.Detection.html##(DETECTION_AREAS.DetectedItem)">Functional.Detection#DETECTION_AREAS.DetectedItem</a> DetectedItem </em></code>: </p>
<p><code><em>#boolean DetectedItemID </em></code>: </p>
</li>
<li>
<p><code><em>#boolean DetectedItemChange </em></code>: </p>
</li>
<li>
<p><code><em> DetectedItemChanged </em></code>: </p>
</li>
</ul>
@ -548,6 +564,20 @@ Return true if you want the task assigning to continue... false will cancel the
<p>The groups to which the FAC will report to.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(TASK_A2G_DISPATCHER).Tasks" >
<strong>TASK_A2G_DISPATCHER.Tasks</strong>
</a>
</dt>
<dd>
</dd>
</dl>

View File

@ -299,6 +299,12 @@ use negative idp for rounding ahead of decimal place, positive for rounding afte
<td class="name" nowrap="nowrap"><a href="##(UTILS).tostringLL">UTILS.tostringLL(lat, lon, acc, DMS)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(UTILS).tostringMGRS">UTILS.tostringMGRS(MGRS, acc)</a></td>
<td class="summary">
</td>
</tr>
</table>
@ -867,6 +873,35 @@ So:
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(UTILS).tostringMGRS" >
<strong>UTILS.tostringMGRS(MGRS, acc)</strong>
</a>
</dt>
<dd>
<p> acc- the accuracy of each easting/northing. 0, 1, 2, 3, 4, or 5.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em> MGRS </em></code>: </p>
</li>
<li>
<p><code><em> acc </em></code>: </p>
</li>
</ul>
</dd>
</dl>
</div>

View File

@ -252,6 +252,12 @@
<td class="name" nowrap="nowrap"><a href="##(ZONE_BASE).GetBoundingSquare">ZONE_BASE:GetBoundingSquare()</a></td>
<td class="summary">
<p>Get the bounding square the zone.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(ZONE_BASE).GetCoordinate">ZONE_BASE:GetCoordinate(Height)</a></td>
<td class="summary">
<p>Returns a <a href="Point.html##(COORDINATE)">Point#COORDINATE</a> of the zone.</p>
</td>
</tr>
<tr>
@ -933,6 +939,33 @@ The bounding square.</p>
<dl class="function">
<dt>
<a id="#(ZONE_BASE).GetCoordinate" >
<strong>ZONE_BASE:GetCoordinate(Height)</strong>
</a>
</dt>
<dd>
<p>Returns a <a href="Point.html##(COORDINATE)">Point#COORDINATE</a> of the zone.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em><a href="Dcs.DCSTypes.html##(Distance)">Dcs.DCSTypes#Distance</a> Height </em></code>:
The height to add to the land height where the center of the zone is located.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="Core.Point.html##(COORDINATE)">Core.Point#COORDINATE</a>:</em>
The Coordinate of the zone.</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(ZONE_BASE).GetName" >
<strong>ZONE_BASE:GetName()</strong>
</a>