diff --git a/Moose Development/LDT External Tools/Moose DOCUMENTATION Generate.launch b/Moose Development/LDT External Tools/Moose DOCUMENTATION Generate.launch
index 85f0a3b46..43f710ca8 100644
--- a/Moose Development/LDT External Tools/Moose DOCUMENTATION Generate.launch
+++ b/Moose Development/LDT External Tools/Moose DOCUMENTATION Generate.launch
@@ -3,6 +3,6 @@
-
+
diff --git a/Moose Development/Moose/Actions/Act_Assign.lua b/Moose Development/Moose/Actions/Act_Assign.lua
index 7d45ad21a..e04139698 100644
--- a/Moose Development/Moose/Actions/Act_Assign.lua
+++ b/Moose Development/Moose/Actions/Act_Assign.lua
@@ -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
diff --git a/Moose Development/Moose/Core/Cargo.lua b/Moose Development/Moose/Core/Cargo.lua
index 825bb5084..88635422f 100644
--- a/Moose Development/Moose/Core/Cargo.lua
+++ b/Moose Development/Moose/Core/Cargo.lua
@@ -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
-
diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua
index eebce2873..c9f7ed174 100644
--- a/Moose Development/Moose/Core/Database.lua
+++ b/Moose Development/Moose/Core/Database.lua
@@ -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
diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua
index 8bbaeade6..f9da8ec67 100644
--- a/Moose Development/Moose/Core/Event.lua
+++ b/Moose Development/Moose/Core/Event.lua
@@ -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 )
diff --git a/Moose Development/Moose/Core/Fsm.lua b/Moose Development/Moose/Core/Fsm.lua
index 972071634..51adf9b86 100644
--- a/Moose Development/Moose/Core/Fsm.lua
+++ b/Moose Development/Moose/Core/Fsm.lua
@@ -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 } )
diff --git a/Moose Development/Moose/Core/Menu.lua b/Moose Development/Moose/Core/Menu.lua
index 8e361f41f..b33d8ef2c 100644
--- a/Moose Development/Moose/Core/Menu.lua
+++ b/Moose Development/Moose/Core/Menu.lua
@@ -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
diff --git a/Moose Development/Moose/Core/ScheduleDispatcher.lua b/Moose Development/Moose/Core/ScheduleDispatcher.lua
index a7962e677..9db739ae1 100644
--- a/Moose Development/Moose/Core/ScheduleDispatcher.lua
+++ b/Moose Development/Moose/Core/ScheduleDispatcher.lua
@@ -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
diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua
index 196982ffb..6ca7f6d5d 100644
--- a/Moose Development/Moose/Core/Set.lua
+++ b/Moose Development/Moose/Core/Set.lua
@@ -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]
diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua
index 998bd07fa..5f41cf733 100644
--- a/Moose Development/Moose/Core/Zone.lua
+++ b/Moose Development/Moose/Core/Zone.lua
@@ -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
diff --git a/Moose Development/Moose/Functional/Detection.lua b/Moose Development/Moose/Functional/Detection.lua
index 418767218..f6eb2dc97 100644
--- a/Moose Development/Moose/Functional/Detection.lua
+++ b/Moose Development/Moose/Functional/Detection.lua
@@ -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 ...
diff --git a/Moose Development/Moose/Functional/MissileTrainer.lua b/Moose Development/Moose/Functional/MissileTrainer.lua
index 511cbca44..38b2008ae 100644
--- a/Moose Development/Moose/Functional/MissileTrainer.lua
+++ b/Moose Development/Moose/Functional/MissileTrainer.lua
@@ -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
diff --git a/Moose Development/Moose/Functional/Spawn.lua b/Moose Development/Moose/Functional/Spawn.lua
index c6faf2ee8..6e9386a7d 100644
--- a/Moose Development/Moose/Functional/Spawn.lua
+++ b/Moose Development/Moose/Functional/Spawn.lua
@@ -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
diff --git a/Moose Development/Moose/Moose.lua b/Moose Development/Moose/Moose.lua
index 4c87af909..46fdaa17c 100644
--- a/Moose Development/Moose/Moose.lua
+++ b/Moose Development/Moose/Moose.lua
@@ -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()
diff --git a/Moose Development/Moose/Tasking/CommandCenter.lua b/Moose Development/Moose/Tasking/CommandCenter.lua
index f24527cbb..93fd01162 100644
--- a/Moose Development/Moose/Tasking/CommandCenter.lua
+++ b/Moose Development/Moose/Tasking/CommandCenter.lua
@@ -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
diff --git a/Moose Development/Moose/Tasking/DetectionManager.lua b/Moose Development/Moose/Tasking/DetectionManager.lua
index 7601701a0..7283d50d9 100644
--- a/Moose Development/Moose/Tasking/DetectionManager.lua
+++ b/Moose Development/Moose/Tasking/DetectionManager.lua
@@ -76,6 +76,7 @@ do -- DETECTION MANAGER
self:SetReportInterval( 30 )
self:SetReportDisplayTime( 25 )
+ self:E( { Detection = Detection } )
Detection:__Start( 1 )
return self
diff --git a/Moose Development/Moose/Tasking/Mission.lua b/Moose Development/Moose/Tasking/Mission.lua
index 177376bfd..47563623e 100644
--- a/Moose Development/Moose/Tasking/Mission.lua
+++ b/Moose Development/Moose/Tasking/Mission.lua
@@ -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 "" - Status ""
+-- - Task Types: ,
+-- - Planned Tasks (xp)
+-- - Assigned Tasks(xp)
+-- - Success Tasks (xp)
+-- - Hold Tasks (xp)
+-- - Cancelled Tasks (xp)
+-- - Aborted Tasks (xp)
+-- - 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 "" - Status ""
+-- - Player ": Task , Task
+-- - Player : Task , Task
+-- - ..
+--
+-- @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
diff --git a/Moose Development/Moose/Tasking/Task.lua b/Moose Development/Moose/Tasking/Task.lua
index e9519290e..e2ae85c64 100644
--- a/Moose Development/Moose/Tasking/Task.lua
+++ b/Moose Development/Moose/Tasking/Task.lua
@@ -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()
diff --git a/Moose Development/Moose/Tasking/Task_A2G.lua b/Moose Development/Moose/Tasking/Task_A2G.lua
index 6814847bd..8c99d85f1 100644
--- a/Moose Development/Moose/Tasking/Task_A2G.lua
+++ b/Moose Development/Moose/Tasking/Task_A2G.lua
@@ -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
diff --git a/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua b/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua
index db260cfb0..f7101eea4 100644
--- a/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua
+++ b/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua
@@ -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
diff --git a/Moose Development/Moose/Tasking/Task_CARGO.lua b/Moose Development/Moose/Tasking/Task_CARGO.lua
index 7ad7013e9..776fe499b 100644
--- a/Moose Development/Moose/Tasking/Task_CARGO.lua
+++ b/Moose Development/Moose/Tasking/Task_CARGO.lua
@@ -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
diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua
index 21a67981b..ec62872f1 100644
--- a/Moose Development/Moose/Wrapper/Controllable.lua
+++ b/Moose Development/Moose/Wrapper/Controllable.lua
@@ -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()
diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua
index 3964388f1..3be9bc187 100644
--- a/Moose Development/Moose/Wrapper/Group.lua
+++ b/Moose Development/Moose/Wrapper/Group.lua
@@ -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
diff --git a/Moose Development/Moose/Wrapper/Positionable.lua b/Moose Development/Moose/Wrapper/Positionable.lua
index 7a192ba64..c815b7bfb 100644
--- a/Moose Development/Moose/Wrapper/Positionable.lua
+++ b/Moose Development/Moose/Wrapper/Positionable.lua
@@ -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
diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua
index 0107839b5..c99c2a7a4 100644
--- a/Moose Development/Moose/Wrapper/Unit.lua
+++ b/Moose Development/Moose/Wrapper/Unit.lua
@@ -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
diff --git a/Moose Mission Setup/Moose.lua b/Moose Mission Setup/Moose.lua
index bd6df9c23..c384faa86 100644
--- a/Moose Mission Setup/Moose.lua
+++ b/Moose Mission Setup/Moose.lua
@@ -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
diff --git a/Utils/Deploy.sh b/Utils/Deploy.sh
new file mode 100644
index 000000000..5527631f0
--- /dev/null
+++ b/Utils/Deploy.sh
@@ -0,0 +1,5 @@
+cd slate
+git add -A
+git commit -a -m "Doc Update"
+git push
+./deploy.sh
\ No newline at end of file
diff --git a/Utils/GenerateDocumentations.bat b/Utils/GenerateDocumentations.bat
new file mode 100644
index 000000000..d106f5189
--- /dev/null
+++ b/Utils/GenerateDocumentations.bat
@@ -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 ..
\ No newline at end of file
diff --git a/Utils/Slate Documentation Generator/Generate.bat b/Utils/Slate Documentation Generator/Generate.bat
new file mode 100644
index 000000000..bcd2fd145
--- /dev/null
+++ b/Utils/Slate Documentation Generator/Generate.bat
@@ -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
\ No newline at end of file
diff --git a/Utils/Slate Documentation Generator/bin/SlateDocGenerator2.exe b/Utils/Slate Documentation Generator/bin/SlateDocGenerator2.exe
new file mode 100644
index 000000000..ad688e4b7
Binary files /dev/null and b/Utils/Slate Documentation Generator/bin/SlateDocGenerator2.exe differ
diff --git a/Utils/Slate Documentation Generator/bin/TreeHierarchy.csv b/Utils/Slate Documentation Generator/bin/TreeHierarchy.csv
new file mode 100644
index 000000000..41eb85a6a
--- /dev/null
+++ b/Utils/Slate Documentation Generator/bin/TreeHierarchy.csv
@@ -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,
diff --git a/Utils/Slate Documentation Generator/src/DataStorer.au3 b/Utils/Slate Documentation Generator/src/DataStorer.au3
new file mode 100644
index 000000000..b5903009b
--- /dev/null
+++ b/Utils/Slate Documentation Generator/src/DataStorer.au3
@@ -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
\ No newline at end of file
diff --git a/Utils/Slate Documentation Generator/src/Parser.au3 b/Utils/Slate Documentation Generator/src/Parser.au3
new file mode 100644
index 000000000..307b98d20
--- /dev/null
+++ b/Utils/Slate Documentation Generator/src/Parser.au3
@@ -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 -> Nil)
+; - 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", "Nil")
+ $StringFile = StringReplace($StringFile, "#number", "Number")
+ $StringFile = StringReplace($StringFile, "#boolean", "Boolean")
+ $StringFile = StringReplace($StringFile, "#string", "String")
+ $StringFile = StringReplace($StringFile, "#table", "List[]")
+ $StringFile = StringReplace($StringFile, "#function", "Function()")
+
+ ; 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))*\)(.*))$", ""&$RegExResult[0]&"
", 1)
+ $StringFile = StringRegExpReplace($StringFile, "(?m)^(\d(?:(\.\d))*\)(.*))$", "##### "&$RegExResult[0], 1)
+ WEnd
+
+ Return $StringFile
+EndFunc
\ No newline at end of file
diff --git a/Utils/Slate Documentation Generator/src/SlateGenerator2.au3 b/Utils/Slate Documentation Generator/src/SlateGenerator2.au3
new file mode 100644
index 000000000..75f8ea703
--- /dev/null
+++ b/Utils/Slate Documentation Generator/src/SlateGenerator2.au3
@@ -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
+#include
+#include
+#include
+
+; 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()
diff --git a/Utils/Slate Documentation Generator/src/Writer.au3 b/Utils/Slate Documentation Generator/src/Writer.au3
new file mode 100644
index 000000000..b6a249540
--- /dev/null
+++ b/Utils/Slate Documentation Generator/src/Writer.au3
@@ -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, "" & @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, "
" & @CRLF)
+ Else
+ FileWrite($Output, "" & @CRLF)
+ FileWrite($Output, "The " & $TypeName & " class does not inherit" & @CRLF)
+ FileWrite($Output, "
" & @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, " Attributes
" & @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, " Parameters
" & @CRLF)
+ If IsArray($Parameters) Then
+ FileWrite($Output, ArrayToList($Parameters, False) & @CRLF)
+ EndIf
+
+ ; Write the returns
+ FileWrite($Output, " Returns
" & @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
\ No newline at end of file
diff --git a/docs/Documentation/Cargo.html b/docs/Documentation/Cargo.html
index e2bcae7e2..a9b110ac2 100644
--- a/docs/Documentation/Cargo.html
+++ b/docs/Documentation/Cargo.html
@@ -2847,6 +2847,7 @@ The range till cargo will board.
-
+
CARGO_UNIT.CargoCarrier
diff --git a/docs/Documentation/CommandCenter.html b/docs/Documentation/CommandCenter.html
index 99e1f3291..7b2d84919 100644
--- a/docs/Documentation/CommandCenter.html
+++ b/docs/Documentation/CommandCenter.html
@@ -251,24 +251,60 @@
| REPORT:Add(Text) |
Add a new line to a REPORT.
+ |
+
+
+ | REPORT:AddIndent(Text) |
+
+ Add a new line to a REPORT.
|
| REPORT.ClassName |
+ |
+
+
+ | REPORT:HasText() |
+
+ Has the REPORT Text?
+ |
+
+
+ | REPORT.Indent |
+
+
|
| REPORT:New(Title) |
Create a new REPORT.
+ |
+
+
+ | REPORT.Report |
+
+
+ |
+
+
+ | REPORT:SetIndent(Indent) |
+
+ Set indent of a REPORT.
|
| REPORT:Text(Delimiter) |
Produces the text of the report, taking into account an optional delimeter, which is \n by default.
+ |
+
+
+ | REPORT.Title |
+
+
|
@@ -765,6 +801,32 @@ Group#GROUP
#REPORT:
+
+
+
+-
+
+
+REPORT:AddIndent(Text)
+
+
+-
+
+
Add a new line to a REPORT.
+
+ Parameter
+
+ -
+
+
#string Text :
+
+
+
+ Return value
+
+#REPORT:
+
+
@@ -779,6 +841,38 @@ Group#GROUP
+
+
+
+-
+
+
+REPORT:HasText()
+
+
+-
+
+
Has the REPORT Text?
+
+ Return value
+
+#boolean:
+
+
+
+
+
+-
+
+
+
+REPORT.Indent
+
+
+-
+
+
+
@@ -805,6 +899,46 @@ Group#GROUP
#REPORT:
+
+
+
+-
+
+
+
+REPORT.Report
+
+
+-
+
+
+
+
+
+
+-
+
+
+REPORT:SetIndent(Indent)
+
+
+-
+
+
Set indent of a REPORT.
+
+ Parameter
+
+ -
+
+
#number Indent :
+
+
+
+ Return value
+
+#REPORT:
+
+
@@ -832,6 +966,20 @@ Group#GROUP
#string:
The report text.
+
+
+
+-
+
+
+
+REPORT.Title
+
+
+-
+
+
+
diff --git a/docs/Documentation/Controllable.html b/docs/Documentation/Controllable.html
index 5b025cdc7..ad27bec5c 100644
--- a/docs/Documentation/Controllable.html
+++ b/docs/Documentation/Controllable.html
@@ -382,7 +382,7 @@ This is different from the EnRoute tasks, where the targets of the task need to
- | CONTROLLABLE:IsTargetDetected(DCSObject) |
+ CONTROLLABLE:IsTargetDetected(DCSObject, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK) |
|
@@ -1466,19 +1466,49 @@ WayPoints If WayPoints is given, then return the WayPoints structure.
-CONTROLLABLE:IsTargetDetected(DCSObject)
+CONTROLLABLE:IsTargetDetected(DCSObject, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK)
- Parameter
+ Parameters
-
DCSObject :
+
+ -
+
+
DetectVisual :
+
+
+ -
+
+
DetectOptical :
+
+
+ -
+
+
DetectRadar :
+
+
+ -
+
+
DetectIRST :
+
+
+ -
+
+
DetectRWR :
+
+
+ -
+
+
DetectDLINK :
+
diff --git a/docs/Documentation/Database.html b/docs/Documentation/Database.html
index e43251af7..bdaa3f280 100644
--- a/docs/Documentation/Database.html
+++ b/docs/Documentation/Database.html
@@ -326,6 +326,12 @@ The following iterator methods are currently available within the DATABASE:
DATABASE:ForEachPlayerJoined(IteratorFunction, ...) |
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.
+ |
+
+
+ | DATABASE:ForEachStatic(IteratorFunction, FinalizeFunction, ...) |
+
+ Iterate the DATABASE and call an iterator function for each alive STATIC, providing the STATIC and optional parameters.
|
@@ -1279,6 +1285,43 @@ self
-
+
+DATABASE:ForEachStatic(IteratorFunction, FinalizeFunction, ...)
+
+
+-
+
+
Iterate the DATABASE and call an iterator function for each alive STATIC, providing the STATIC and optional parameters.
+
+ Parameters
+
+ Return value
+
+#DATABASE:
+self
+
+
+
+
+-
+
DATABASE:ForEachUnit(IteratorFunction, FinalizeFunction, ...)
diff --git a/docs/Documentation/Designate.html b/docs/Documentation/Designate.html
index 9854fc628..0b38068a2 100644
--- a/docs/Documentation/Designate.html
+++ b/docs/Documentation/Designate.html
@@ -279,7 +279,7 @@ each detected set of potential targets can be lased or smoked...
- | DESIGNATE:MenuStatus(AttackGroup) |
+ DESIGNATE:MenuStatus(AttackGroup, Duration) |
|
@@ -375,7 +375,7 @@ each detected set of potential targets can be lased or smoked...
- | DESIGNATE:SendStatus(AttackGroup, MenuAttackGroup) |
+ DESIGNATE:SendStatus(AttackGroup, Duration, MenuAttackGroup) |
Sends the status to the Attack Groups.
|
@@ -1065,19 +1065,24 @@ function below will use the range 1-7 just in case
- Parameter
+ Parameters
-
AttackGroup :
+
+ -
+
+
Duration :
+
@@ -1556,7 +1561,7 @@ The Attack collection of GROUP objects to designate and report for.
-DESIGNATE:SendStatus(AttackGroup, MenuAttackGroup)
+DESIGNATE:SendStatus(AttackGroup, Duration, MenuAttackGroup)
@@ -1572,6 +1577,12 @@ The Attack collection of GROUP objects to designate and report for.
+#number Duration :
+The time in seconds the report should be visible.
+
+
+
+
MenuAttackGroup :
diff --git a/docs/Documentation/Detection.html b/docs/Documentation/Detection.html
index af236b70d..4514b29c5 100644
--- a/docs/Documentation/Detection.html
+++ b/docs/Documentation/Detection.html
@@ -192,6 +192,12 @@ DETECTION uses the in-built detection capabilities of DCS World, but adds new fu
DETECTION_AREAS:CreateDetectionItems() |
Make a DetectionSet table.
+ |
+
+
+ | DETECTION_AREAS:DetectedItemMenu(Index) |
+
+ Menu of a detected item using a given numeric index.
|
@@ -204,6 +210,12 @@ DETECTION uses the in-built detection capabilities of DCS World, but adds new fu
| DETECTION_AREAS.DetectedItems |
A list of areas containing the set of Units, Zones, the center Unit within the zone, and ID of each area that was detected within a DetectionZoneRange.
+ |
+
+
+ | DETECTION_AREAS:DetectedReportDetailed() |
+
+ Report detailed of a detection result.
|
@@ -331,7 +343,7 @@ DETECTION uses the in-built detection capabilities of DCS World, but adds new fu
- | DETECTION_BASE:AddDetectedItem(DetectedItemIndex, Set) |
+ DETECTION_BASE:AddDetectedItem(ItemPrefix, DetectedItemIndex, Set) |
Adds a new DetectedItem to the DetectedItems list.
|
@@ -424,6 +436,12 @@ DETECTION uses the in-built detection capabilities of DCS World, but adds new fu
DETECTION_BASE.DetectedItemMax |
+ |
+
+
+ | DETECTION_BASE:DetectedItemMenu(Index) |
+
+ Menu of a detected item using a given numeric index.
|
@@ -513,12 +531,24 @@ The different values of Unit.Category can be:
Multiple Unit.Category entries can be given as a table and then these will be evaluated as an OR expression.
+
+
+
+ | DETECTION_BASE:GetDetectedID(Index) |
+
+ Get a detected ID using a given numeric index.
|
| DETECTION_BASE:GetDetectedItem(Index) |
Get a detected item using a given numeric index.
+ |
+
+
+ | DETECTION_BASE:GetDetectedItemID(Index) |
+
+ Get a detected ItemID using a given numeric index.
|
@@ -905,6 +935,42 @@ The different values of Unit.Category can be:
| DETECTION_BASE.DetectedObject.Identified |
+ |
+
+
+ | DETECTION_BASE.DetectedObject.IsVisible |
+
+
+ |
+
+
+ | DETECTION_BASE.DetectedObject.KnowDistance |
+
+
+ |
+
+
+ | DETECTION_BASE.DetectedObject.KnowType |
+
+
+ |
+
+
+ | DETECTION_BASE.DetectedObject.LastPos |
+
+
+ |
+
+
+ | DETECTION_BASE.DetectedObject.LastTime |
+
+
+ |
+
+
+ | DETECTION_BASE.DetectedObject.LastVelocity |
+
+
|
@@ -917,12 +983,6 @@ The different values of Unit.Category can be:
| DETECTION_BASE.DetectedObject.Type |
- |
-
-
- | DETECTION_BASE.DetectedObject.Visible |
-
-
|
@@ -939,6 +999,12 @@ The different values of Unit.Category can be:
DETECTION_TYPES:CreateDetectionItems() |
Create the DetectedItems list from the DetectedObjects table.
+ |
+
+
+ | DETECTION_TYPES:DetectedItemMenu(Index, DetectedTypeName) |
+
+ Menu of a DetectedItem using a given numeric index.
|
@@ -1015,6 +1081,12 @@ The different values of Unit.Category can be:
| DETECTION_UNITS:CreateDetectionItems() |
Create the DetectedItems list from the DetectedObjects table.
+ |
+
+
+ | DETECTION_UNITS:DetectedItemMenu(Index) |
+
+ Menu of a DetectedItem using a given numeric index.
|
@@ -1258,7 +1330,7 @@ Use the method Detecti
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 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.
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
#DETECTION_AREAS:
self
+
+
+
+-
+
+
+
+-
+
+
Menu of a detected item using a given numeric index.
+
+ Parameter
+
+ Return value
+
+#string:
+
+
@@ -1516,6 +1614,24 @@ self
A list of areas containing the set of Units, Zones, the center Unit within the zone, and ID of each area that was detected within a DetectionZoneRange.
+
+
+
+-
+
+
+DETECTION_AREAS:DetectedReportDetailed()
+
+
+-
+
+
Report detailed of a detection result.
+
+ Return value
+
+#string:
+
+
@@ -1944,7 +2060,7 @@ self
-
-DETECTION_BASE:AddDetectedItem(DetectedItemIndex, Set)
+DETECTION_BASE:AddDetectedItem(ItemPrefix, DetectedItemIndex, Set)
-
@@ -1958,6 +2074,11 @@ self
+
+
+-
+
+
+
+-
+
+
Menu of a detected item using a given numeric index.
+
+ Parameter
+
+ Return value
+
+#string:
+
+
@@ -2328,7 +2476,7 @@ The index of the DetectedItem.
-
- #number
+
DETECTION_BASE.DetectionInterval
@@ -2468,6 +2616,32 @@ self
-
+
+DETECTION_BASE:GetDetectedID(Index)
+
+
+-
+
+
Get a detected ID using a given numeric index.
+
+ Parameter
+
+ -
+
+
#number Index :
+
+
+
+ Return value
+
+#string:
+DetectedItemID
+
+
+
+
+-
+
DETECTION_BASE:GetDetectedItem(Index)
@@ -2489,6 +2663,32 @@ self
#DETECTION_BASE.DetectedItem:
+
+
+
+-
+
+
+DETECTION_BASE:GetDetectedItemID(Index)
+
+
+-
+
+
Get a detected ItemID using a given numeric index.
+
+ Parameter
+
+ -
+
+
#number Index :
+
+
+
+ Return value
+
+#string:
+DetectedItemID
+
@@ -2523,7 +2723,7 @@ self
Return value
#number:
-Count
+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!
@@ -4061,6 +4261,90 @@ The To State string.
+
+
+
+-
+
+ #boolean
+
+DETECTION_BASE.DetectedObject.IsVisible
+
+
+-
+
+
+
+
+
+
+-
+
+ #boolean
+
+DETECTION_BASE.DetectedObject.KnowDistance
+
+
+-
+
+
+
+
+
+
+-
+
+ #boolean
+
+DETECTION_BASE.DetectedObject.KnowType
+
+
+-
+
+
+
+
+
+
+-
+
+ #boolean
+
+DETECTION_BASE.DetectedObject.LastPos
+
+
+-
+
+
+
+
+
+
+-
+
+ #number
+
+DETECTION_BASE.DetectedObject.LastTime
+
+
+-
+
+
+
+
+
+
+-
+
+ #number
+
+DETECTION_BASE.DetectedObject.LastVelocity
+
+
+-
+
+
+
@@ -4089,20 +4373,6 @@ The To State string.
-
-
-
--
-
- #boolean
-
-DETECTION_BASE.DetectedObject.Visible
-
-
--
-
-
-
@@ -4154,6 +4424,37 @@ Beware that when the amount of different types detected is large, the DetectedIt
#DETECTION_TYPES:
self
+
+
+
+-
+
+
+
+-
+
+
Menu of a DetectedItem using a given numeric index.
+
+ Parameters
+
+ -
+
+
Index :
+
+
+ -
+
+
DetectedTypeName :
+
+
+
+ Return value
+
+#string:
+
+
@@ -4389,6 +4690,32 @@ Beware that when the amount of units detected is large, the DetectedItems list w
#DETECTION_UNITS:
self
+
+
+
+-
+
+
+
+-
+
+
Menu of a DetectedItem using a given numeric index.
+
+ Parameter
+
+ Return value
+
+#string:
+
+
diff --git a/docs/Documentation/Mission.html b/docs/Documentation/Mission.html
index 5cf8ca5d8..96f09fc56 100644
--- a/docs/Documentation/Mission.html
+++ b/docs/Documentation/Mission.html
@@ -167,7 +167,7 @@ A CLIENT needs to be registered within the MISSION:GetMenu(TaskGroup)
+ | MISSION:GetMenu() |
Gets the mission menu for the coalition.
|
@@ -200,6 +200,12 @@ A CLIENT needs to be registered within the MISSION:GetTasks()
Get all the TASKs from the Mission.
+ |
+
+
+ | MISSION:GetTasksRemaining() |
+
+
|
@@ -209,39 +215,51 @@ A CLIENT needs to be registered within the MISSION:IsCompleted()
+ | MISSION:IsCOMPLETED() |
- Is the Mission Completed.
+Is the Mission COMPLETED.
|
- | MISSION:IsFailed() |
+ MISSION:IsENGAGED() |
- Is the Mission Failed.
+Is the Mission ENGAGED.
|
- | MISSION:IsHold() |
+ MISSION:IsFAILED() |
- Is the Mission Hold.
+Is the Mission FAILED.
|
- | MISSION:IsIdle() |
+ MISSION:IsHOLD() |
- Is the Mission Idle.
+Is the Mission HOLD.
|
- | MISSION:IsOngoing() |
+ MISSION:IsIDLE() |
- Is the Mission Ongoing.
+Is the Mission IDLE.
|
| MISSION:JoinUnit(PlayerUnit, PlayerGroup) |
Add a Unit to join the Mission.
+ |
+
+
+ | MISSION:MenuReportOverview(TaskStatus, ReportGroup) |
+
+
+ |
+
+
+ | MISSION:MenuReportSummary(ReportGroup) |
+
+
|
@@ -323,51 +341,51 @@ A CLIENT needs to be registered within the MISSION:OnEnterCompleted(From, Event, To)
+ | MISSION:OnEnterCOMPLETED(From, Event, To) |
- OnEnter Transition Handler for State Completed.
+OnEnter Transition Handler for State COMPLETED.
|
- | MISSION:OnEnterFailed(From, Event, To) |
+ MISSION:OnEnterENGAGED(From, Event, To) |
- OnEnter Transition Handler for State Failed.
+OnEnter Transition Handler for State ENGAGED.
|
- | MISSION:OnEnterIdle(From, Event, To) |
+ MISSION:OnEnterFAILED(From, Event, To) |
- OnEnter Transition Handler for State Idle.
+OnEnter Transition Handler for State FAILED.
|
- | MISSION:OnEnterOngoing(From, Event, To) |
+ MISSION:OnEnterIDLE(From, Event, To) |
- OnEnter Transition Handler for State Ongoing.
+OnEnter Transition Handler for State IDLE.
|
- | MISSION:OnLeaveCompleted(From, Event, To) |
+ MISSION:OnLeaveCOMPLETED(From, Event, To) |
- OnLeave Transition Handler for State Completed.
+OnLeave Transition Handler for State COMPLETED.
|
- | MISSION:OnLeaveFailed(From, Event, To) |
+ MISSION:OnLeaveENGAGED(From, Event, To) |
- OnLeave Transition Handler for State Failed.
+OnLeave Transition Handler for State ENGAGED.
|
- | MISSION:OnLeaveIdle(From, Event, To) |
+ MISSION:OnLeaveFAILED(From, Event, To) |
- OnLeave Transition Handler for State Idle.
+OnLeave Transition Handler for State FAILED.
|
- | MISSION:OnLeaveOngoing(From, Event, To) |
+ MISSION:OnLeaveIDLE(From, Event, To) |
- OnLeave Transition Handler for State Ongoing.
+OnLeave Transition Handler for State IDLE.
|
@@ -395,7 +413,7 @@ A CLIENT needs to be registered within the MISSION:ReportOverview()
+ | MISSION:ReportOverview(TaskStatus) |
Create a overview report of the Mission (multiple lines).
|
@@ -467,7 +485,7 @@ A CLIENT needs to be registered within the MISSION:onenterCompleted(From, Event, To)
+ MISSION:onenterCOMPLETED(From, Event, To) |
|
@@ -697,21 +715,13 @@ true if Unit is part of a Task in the Mission.
Gets the mission menu for the coalition.
- Parameter
-
Return value
Core.Menu#MENU_COALITION:
@@ -851,6 +861,24 @@ Returns nil if no task was found.
Tasks = Mission:GetTasks()
env.info( "Task 2 Completion = " .. Tasks[2]:GetGoalPercentage() .. "%" )
+
+
+
+-
+
+
+MISSION:GetTasksRemaining()
+
+
+-
+
+
+
+
Return value
+
+#number:
+
+
@@ -893,13 +921,13 @@ true if the Mission has a Group.
-
-
-MISSION:IsCompleted()
+
+MISSION:IsCOMPLETED()
-
-
Is the Mission Completed.
+Is the Mission COMPLETED.
Return value
@@ -911,13 +939,13 @@ true if the Mission has a Group.
-
-
-MISSION:IsFailed()
+
+MISSION:IsENGAGED()
-
-
Is the Mission Failed.
+Is the Mission ENGAGED.
Return value
@@ -929,13 +957,13 @@ true if the Mission has a Group.
-
-
-MISSION:IsHold()
+
+MISSION:IsFAILED()
-
-
Is the Mission Hold.
+Is the Mission FAILED.
Return value
@@ -947,13 +975,13 @@ true if the Mission has a Group.
-
-
-MISSION:IsIdle()
+
+MISSION:IsHOLD()
-
-
Is the Mission Idle.
+Is the Mission HOLD.
Return value
@@ -965,13 +993,13 @@ true if the Mission has a Group.
-
-
-MISSION:IsOngoing()
+
+MISSION:IsIDLE()
-
-
Is the Mission Ongoing.
+Is the Mission IDLE.
Return value
@@ -1016,6 +1044,54 @@ The GROUP of the player joining the Mission.
#boolean:
true if Unit is part of a Task in the Mission.
+
+
+
+-
+
+
+
+-
+
+
+
+
Parameters
+
+
+
+
+-
+
+
+
+-
+
+
+
+
Parameter
+
@@ -1422,13 +1498,13 @@ Return false to cancel Transition.
-
-
-MISSION:OnEnterCompleted(From, Event, To)
+
+MISSION:OnEnterCOMPLETED(From, Event, To)
-
-
OnEnter Transition Handler for State Completed.
+OnEnter Transition Handler for State COMPLETED.
Parameters
@@ -1456,13 +1532,13 @@ The To State string.
-
-
-MISSION:OnEnterFailed(From, Event, To)
+
+MISSION:OnEnterENGAGED(From, Event, To)
-
-
OnEnter Transition Handler for State Failed.
+OnEnter Transition Handler for State ENGAGED.
Parameters
@@ -1490,13 +1566,13 @@ The To State string.
-
-
-MISSION:OnEnterIdle(From, Event, To)
+
+MISSION:OnEnterFAILED(From, Event, To)
-
-
OnEnter Transition Handler for State Idle.
+OnEnter Transition Handler for State FAILED.
Parameters
@@ -1524,13 +1600,13 @@ The To State string.
-
-
-MISSION:OnEnterOngoing(From, Event, To)
+
+MISSION:OnEnterIDLE(From, Event, To)
-
-
OnEnter Transition Handler for State Ongoing.
+OnEnter Transition Handler for State IDLE.
Parameters
@@ -1558,13 +1634,13 @@ The To State string.
-
-
-MISSION:OnLeaveCompleted(From, Event, To)
+
+MISSION:OnLeaveCOMPLETED(From, Event, To)
-
-
OnLeave Transition Handler for State Completed.
+OnLeave Transition Handler for State COMPLETED.
Parameters
@@ -1597,13 +1673,13 @@ Return false to cancel Transition.
-
-
-MISSION:OnLeaveFailed(From, Event, To)
+
+MISSION:OnLeaveENGAGED(From, Event, To)
-
-
OnLeave Transition Handler for State Failed.
+OnLeave Transition Handler for State ENGAGED.
Parameters
@@ -1636,13 +1712,13 @@ Return false to cancel Transition.
-
-
-MISSION:OnLeaveIdle(From, Event, To)
+
+MISSION:OnLeaveFAILED(From, Event, To)
-
-
OnLeave Transition Handler for State Idle.
+OnLeave Transition Handler for State FAILED.
Parameters
@@ -1675,13 +1751,13 @@ Return false to cancel Transition.
-
-
-MISSION:OnLeaveOngoing(From, Event, To)
+
+MISSION:OnLeaveIDLE(From, Event, To)
-
-
OnLeave Transition Handler for State Ongoing.
+OnLeave Transition Handler for State IDLE.
Parameters
@@ -548,6 +564,20 @@ Return true if you want the task assigning to continue... false will cancel the
The groups to which the FAC will report to.
+
+
+
+-
+
+
+
+TASK_A2G_DISPATCHER.Tasks
+
+
+-
+
+
+
diff --git a/docs/Documentation/Utils.html b/docs/Documentation/Utils.html
index b129e87db..406805680 100644
--- a/docs/Documentation/Utils.html
+++ b/docs/Documentation/Utils.html
@@ -299,6 +299,12 @@ use negative idp for rounding ahead of decimal place, positive for rounding afte
UTILS.tostringLL(lat, lon, acc, DMS) |
+ |
+
+
+ | UTILS.tostringMGRS(MGRS, acc) |
+
+
|
@@ -867,6 +873,35 @@ So:
+
+
+-
+
+
+UTILS.tostringMGRS(MGRS, acc)
+
+
+-
+
+
+
+
+
acc- the accuracy of each easting/northing. 0, 1, 2, 3, 4, or 5.
+
+ Parameters
+
+ -
+
+
MGRS :
+
+
+ -
+
+
acc :
+
+
+
+
diff --git a/docs/Documentation/Zone.html b/docs/Documentation/Zone.html
index f620a9c0c..b9f59126b 100644
--- a/docs/Documentation/Zone.html
+++ b/docs/Documentation/Zone.html
@@ -252,6 +252,12 @@
ZONE_BASE:GetBoundingSquare() |
Get the bounding square the zone.
+ |
+
+
+ | ZONE_BASE:GetCoordinate(Height) |
+
+ Returns a Point#COORDINATE of the zone.
|
@@ -933,6 +939,33 @@ The bounding square.
-
+
+ZONE_BASE:GetCoordinate(Height)
+
+
+-
+
+
Returns a Point#COORDINATE of the zone.
+
+ Parameter
+
+ Return value
+
+Core.Point#COORDINATE:
+The Coordinate of the zone.
+
+
+
+
+-
+
ZONE_BASE:GetName()