mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Progress
This commit is contained in:
parent
5c090b108c
commit
f9708de598
@ -175,7 +175,7 @@ do -- ACT_ASSIGN_ACCEPT
|
||||
|
||||
self:Message( "You are assigned to the task " .. self.Task:GetName() )
|
||||
|
||||
self.Task:Assign()
|
||||
self.Task:Assign( ProcessUnit, self.Task )
|
||||
end
|
||||
|
||||
end -- ACT_ASSIGN_ACCEPT
|
||||
|
||||
@ -126,6 +126,17 @@ do -- ACT_ASSIST
|
||||
self.MenuSmokeWhite = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop White smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.White } )
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ASSIST self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIST:onafterStop( ProcessUnit, From, Event, To )
|
||||
|
||||
self.Menu:Remove() -- When stopped, remove the menus
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- ACT_ASSIST_SMOKE_TARGETS_ZONE
|
||||
|
||||
@ -177,6 +177,89 @@ do -- ACT_ROUTE
|
||||
end -- ACT_ROUTE
|
||||
|
||||
|
||||
do -- ACT_ROUTE_POINT
|
||||
|
||||
--- ACT_ROUTE_POINT class
|
||||
-- @type ACT_ROUTE_POINT
|
||||
-- @field Tasking.Task#TASK TASK
|
||||
-- @extends #ACT_ROUTE
|
||||
ACT_ROUTE_POINT = {
|
||||
ClassName = "ACT_ROUTE_POINT",
|
||||
}
|
||||
|
||||
|
||||
--- Creates a new routing state machine.
|
||||
-- The task will route a controllable to a TargetPointVec2 until the controllable is within the TargetDistance.
|
||||
-- @param #ACT_ROUTE_POINT self
|
||||
-- @param Core.Point#POINT_VEC2 The PointVec2 to Target.
|
||||
-- @param #number TargetDistance The Distance to Target.
|
||||
-- @param Core.Zone#ZONE_BASE TargetZone
|
||||
function ACT_ROUTE_POINT:New( TargetPointVec2, TargetDistance )
|
||||
local self = BASE:Inherit( self, ACT_ROUTE:New() ) -- #ACT_ROUTE_POINT
|
||||
|
||||
self.TargetPointVec2 = TargetPointVec2
|
||||
self.TargetDistance = TargetDistance
|
||||
|
||||
self.DisplayInterval = 30
|
||||
self.DisplayCount = 30
|
||||
self.DisplayMessage = true
|
||||
self.DisplayTime = 10 -- 10 seconds is the default
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function ACT_ROUTE_POINT:Init( FsmRoute )
|
||||
|
||||
self.TargetPointVec2 = FsmRoute.TargetPointVec2
|
||||
self.TargetDistance = FsmRoute.TargetDistance
|
||||
|
||||
self.DisplayInterval = 30
|
||||
self.DisplayCount = 30
|
||||
self.DisplayMessage = true
|
||||
self.DisplayTime = 10 -- 10 seconds is the default
|
||||
end
|
||||
|
||||
--- Set PointVec2
|
||||
-- @param #ACT_ROUTE_POINT self
|
||||
-- @param Core.Point#POINT_VEC2 TargetPointVec2 The PointVec2 to Target.
|
||||
function ACT_ROUTE_POINT:SetTargetPointVec2( TargetPointVec2 )
|
||||
self.TargetPointVec2 = TargetPointVec2
|
||||
end
|
||||
|
||||
--- Method override to check if the controllable has arrived.
|
||||
-- @param #ACT_ROUTE_POINT self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @return #boolean
|
||||
function ACT_ROUTE_POINT:onfuncHasArrived( ProcessUnit )
|
||||
|
||||
local Distance = self.TargetPointVec2:Get2DDistance( ProcessUnit:GetPointVec2() )
|
||||
|
||||
if Distance <= self.TargetDistance then
|
||||
local RouteText = "You have arrived within engagement range."
|
||||
self:Message( RouteText )
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--- Task Events
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ROUTE_POINT self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ROUTE_POINT:onenterReporting( ProcessUnit, From, Event, To )
|
||||
|
||||
local TaskUnitPointVec2 = ProcessUnit:GetPointVec2()
|
||||
local RouteText = "Route to " .. TaskUnitPointVec2:GetBRText( self.TargetPointVec2 ) .. " km to target."
|
||||
self:Message( RouteText )
|
||||
end
|
||||
|
||||
end -- ACT_ROUTE_POINT
|
||||
|
||||
|
||||
do -- ACT_ROUTE_ZONE
|
||||
|
||||
|
||||
@ -870,6 +870,27 @@ do -- FSM_PROCESS
|
||||
self:T( "No Initialisation" )
|
||||
end
|
||||
|
||||
function FSM_PROCESS:_call_handler( handler, params, EventName )
|
||||
|
||||
local ErrorHandler = function( errmsg )
|
||||
|
||||
env.info( "Error in FSM_PROCESS call handler:" .. errmsg )
|
||||
if debug ~= nil then
|
||||
env.info( debug.traceback() )
|
||||
end
|
||||
|
||||
return errmsg
|
||||
end
|
||||
|
||||
if self[handler] then
|
||||
self:F3( "Calling " .. handler )
|
||||
self._EventSchedules[EventName] = nil
|
||||
local Result, Value = xpcall( function() return self[handler]( self, self.Controllable, self.Task, unpack( params ) ) end, ErrorHandler )
|
||||
return Value
|
||||
--return self[handler]( self, self.Controllable, unpack( params ) )
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates a new FSM_PROCESS object based on this FSM_PROCESS.
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @return #FSM_PROCESS
|
||||
@ -893,7 +914,7 @@ do -- FSM_PROCESS
|
||||
|
||||
-- Copy Processes
|
||||
for ProcessID, Process in pairs( self:GetProcesses() ) do
|
||||
self:T( { Process} )
|
||||
self:E( { Process} )
|
||||
local FsmProcess = NewFsm:AddProcess( Process.From, Process.Event, Process.fsm:Copy( Controllable, Task ), Process.ReturnEvents )
|
||||
end
|
||||
|
||||
|
||||
@ -240,6 +240,7 @@ SET_BASE = {
|
||||
Filter = {},
|
||||
Set = {},
|
||||
List = {},
|
||||
Index = {},
|
||||
}
|
||||
|
||||
--- Creates a new SET_BASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
|
||||
@ -258,10 +259,14 @@ function SET_BASE:New( Database )
|
||||
self.YieldInterval = 10
|
||||
self.TimeInterval = 0.001
|
||||
|
||||
self.Set = {}
|
||||
|
||||
self.List = {}
|
||||
self.List.__index = self.List
|
||||
self.List = setmetatable( { Count = 0 }, self.List )
|
||||
|
||||
self.Index = {}
|
||||
|
||||
self.CallScheduler = SCHEDULER:New( self )
|
||||
|
||||
self:SetEventPriority( 2 )
|
||||
@ -313,6 +318,8 @@ function SET_BASE:Add( ObjectName, Object )
|
||||
|
||||
self.Set[ObjectName] = t._
|
||||
|
||||
table.insert( self.Index, ObjectName )
|
||||
|
||||
end
|
||||
|
||||
--- Adds a @{Base#BASE} object in the @{Set#SET_BASE}, using the Object Name as the index.
|
||||
@ -364,7 +371,15 @@ function SET_BASE:Remove( ObjectName )
|
||||
t._prev = nil
|
||||
self.List.Count = self.List.Count - 1
|
||||
|
||||
for Index, Key in ipairs( self.Index ) do
|
||||
if Key == ObjectName then
|
||||
table.remove( self.Index, Index )
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
self.Set[ObjectName] = nil
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@ -406,13 +421,26 @@ function SET_BASE:GetLast()
|
||||
return t
|
||||
end
|
||||
|
||||
--- Gets a random object from the @{Set#SET_BASE} and derived classes.
|
||||
-- @param #SET_BASE self
|
||||
-- @return Core.Base#BASE
|
||||
function SET_BASE:GetRandom()
|
||||
self:F()
|
||||
|
||||
local RandomItem = self.Set[self.Index[math.random(#self.Index)]]
|
||||
|
||||
self:T3( { RandomItem } )
|
||||
|
||||
return RandomItem
|
||||
end
|
||||
|
||||
|
||||
--- Retrieves the amount of objects in the @{Set#SET_BASE} and derived classes.
|
||||
-- @param #SET_BASE self
|
||||
-- @return #number Count
|
||||
function SET_BASE:Count()
|
||||
|
||||
return self.List.Count
|
||||
return #self.Index
|
||||
end
|
||||
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
--
|
||||
-- # 1) @{#DETECTION_BASE} class, extends @{Fsm#FSM}
|
||||
--
|
||||
-- The @{#DETECTION_BASE} class defines the core functions to administer detected objects.
|
||||
@ -473,16 +472,20 @@ do -- DETECTION_BASE
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function DETECTION_BASE:onafterDetect(From,Event,To)
|
||||
self:F( {From,Event,To})
|
||||
self:E( {From,Event,To})
|
||||
|
||||
local DetectDelay = 0.01
|
||||
local DetectDelay = 0.1
|
||||
self.DetectionCount = 0
|
||||
self.DetectionRun = 0
|
||||
self:UnIdentifyAllDetectedObjects() -- Resets the DetectedObjectsIdentified table
|
||||
|
||||
self.DetectionSetGroup:Flush()
|
||||
|
||||
for DetectionGroupID, DetectionGroupData in pairs( self.DetectionSetGroup:GetSet() ) do
|
||||
self:E( {DetectionGroupData})
|
||||
self:__DetectionGroup( DetectDelay, DetectionGroupData ) -- Process each detection asynchronously.
|
||||
self.DetectionCount = self.DetectionCount + 1
|
||||
DetectDelay = DetectDelay + 0.1
|
||||
end
|
||||
end
|
||||
|
||||
@ -492,21 +495,17 @@ do -- DETECTION_BASE
|
||||
-- @param #string To The To State string.
|
||||
-- @param Wrapper.Group#GROUP DetectionGroup
|
||||
function DETECTION_BASE:onafterDetectionGroup( From, Event, To, DetectionGroup )
|
||||
self:F( {From,Event,To})
|
||||
|
||||
self:__Detect( self.DetectionInterval )
|
||||
self:E( {From,Event,To})
|
||||
|
||||
self.DetectionRun = self.DetectionRun + 1
|
||||
|
||||
self:UnIdentifyAllDetectedObjects() -- Resets the DetectedObjectsIdentified table
|
||||
|
||||
local HasDetectedObjects = false
|
||||
|
||||
if DetectionGroup:IsAlive() then
|
||||
|
||||
local DetectionGroupName = DetectionGroup:GetName()
|
||||
|
||||
local DetectionGroupObjects = {}
|
||||
local DetectedUnits = {}
|
||||
|
||||
local DetectedTargets = DetectionGroup:GetDetectedTargets(
|
||||
self.DetectVisual,
|
||||
@ -537,7 +536,7 @@ do -- DETECTION_BASE
|
||||
( DetectedObjectVec3.z - DetectionGroupVec3.z )^2
|
||||
) ^ 0.5 / 1000
|
||||
|
||||
self:T2( { DetectionGroupName, DetectedObjectName, Distance } )
|
||||
self:T( { DetectionGroupName, DetectedObjectName, Distance } )
|
||||
|
||||
-- Calculate Acceptance
|
||||
|
||||
@ -615,6 +614,8 @@ do -- DETECTION_BASE
|
||||
|
||||
if DetectionAccepted then
|
||||
|
||||
HasDetectedObjects = true
|
||||
|
||||
if not self.DetectedObjects[DetectedObjectName] then
|
||||
self.DetectedObjects[DetectedObjectName] = {}
|
||||
end
|
||||
@ -623,7 +624,9 @@ do -- DETECTION_BASE
|
||||
self.DetectedObjects[DetectedObjectName].Type = Detection.type
|
||||
self.DetectedObjects[DetectedObjectName].Distance = Distance
|
||||
|
||||
DetectionGroupObjects[DetectedObjectName] = DetectedObject
|
||||
local DetectedUnit = UNIT:FindByName( DetectedObjectName )
|
||||
|
||||
DetectedUnits[DetectedObjectName] = DetectedUnit
|
||||
else
|
||||
-- if beyond the DetectionRange then nullify...
|
||||
if self.DetectedObjects[DetectedObjectName] then
|
||||
@ -636,13 +639,14 @@ do -- DETECTION_BASE
|
||||
end
|
||||
|
||||
if HasDetectedObjects then
|
||||
self:__Detected( 0.1, DetectionGroupObjects )
|
||||
self:__Detected( 0.1, DetectedUnits )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if self.DetectionRun == self.DetectionCount then
|
||||
self:CreateDetectionSets()
|
||||
if self.DetectionCount > 0 and self.DetectionRun == self.DetectionCount then
|
||||
self:__Detect( self.DetectionInterval )
|
||||
--self:CreateDetectionSets()
|
||||
end
|
||||
|
||||
end
|
||||
@ -896,11 +900,14 @@ do -- DETECTION_BASE
|
||||
--- Adds a new DetectedItem to the DetectedItems list.
|
||||
-- The DetectedItem is a table and contains a SET_UNIT in the field Set.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param Core.Set#SET_UNIT Set (optional) The Set of Units to be added.
|
||||
-- @param Core.Zone#ZONE_UNIT Zone (optional) The Zone to be added where the Units are located.
|
||||
-- @return #DETECTION_BASE.DetectedItem
|
||||
function DETECTION_BASE:AddDetectedItem()
|
||||
function DETECTION_BASE:AddDetectedItem( Set, Zone )
|
||||
|
||||
local DetectedItem = {}
|
||||
DetectedItem.Set = SET_UNIT:New()
|
||||
DetectedItem.Set = Set or SET_UNIT:New()
|
||||
DetectedItem.Zone = Zone
|
||||
|
||||
table.insert( self.DetectedItems, DetectedItem )
|
||||
|
||||
@ -963,6 +970,24 @@ do -- DETECTION_BASE
|
||||
return nil
|
||||
end
|
||||
|
||||
do -- Zones
|
||||
|
||||
--- Get the @{Zone#ZONE_UNIT} of a detection area using a given numeric index.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #number Index
|
||||
-- @return Core.Zone#ZONE_UNIT DetectedZone
|
||||
function DETECTION_BASE:GetDetectedZone( Index )
|
||||
|
||||
local DetectedZone = self.DetectedItems[Index].Zone
|
||||
if DetectedZone then
|
||||
return DetectedZone
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Report summary of a detected item using a given numeric index.
|
||||
-- @param #DETECTION_BASE self
|
||||
@ -1057,7 +1082,7 @@ do -- DETECTION_UNITS
|
||||
|
||||
for DetectedUnitName, DetectedObjectData in pairs( self.DetectedObjects ) do
|
||||
|
||||
self:E( { "Detected Unit #", DetectedUnitName } )
|
||||
self:T( { "Detected Unit #", DetectedUnitName } )
|
||||
|
||||
local DetectedUnit = UNIT:FindByName( DetectedUnitName ) -- Wrapper.Unit#UNIT
|
||||
|
||||
@ -1091,10 +1116,8 @@ do -- DETECTION_UNITS
|
||||
|
||||
local DetectedItemUnit = DetectedSet:GetFirst() -- Wrapper.Unit#UNIT
|
||||
|
||||
self:E( DetectedItemUnit )
|
||||
|
||||
if DetectedItemUnit then
|
||||
self:E(DetectedItemUnit)
|
||||
self:T(DetectedItemUnit)
|
||||
|
||||
local UnitCategoryName = DetectedItemUnit:GetCategoryName()
|
||||
local UnitCategoryType = DetectedItemUnit:GetTypeName()
|
||||
@ -1244,7 +1267,7 @@ do -- DETECTION_TYPES
|
||||
|
||||
for DetectedUnitName, DetectedObjectData in pairs( self.DetectedObjects ) do
|
||||
|
||||
self:E( { "Detected Unit #", DetectedUnitName } )
|
||||
self:T( { "Detected Unit #", DetectedUnitName } )
|
||||
|
||||
local DetectedUnit = UNIT:FindByName( DetectedUnitName ) -- Wrapper.Unit#UNIT
|
||||
|
||||
@ -1361,34 +1384,18 @@ do -- DETECTION_AREAS
|
||||
-- @return #DETECTION_AREAS.DetectedItem DetectedItem
|
||||
function DETECTION_AREAS:AddDetectedItem( Set, Zone )
|
||||
self:F( { Set, Zone } )
|
||||
-- local Detected = self:GetDetectedItems()
|
||||
|
||||
local DetectedItem = {}
|
||||
DetectedItem.Set = Set
|
||||
DetectedItem.Zone = Zone
|
||||
local DetectedItem = self:GetParent( self ).AddDetectedItem( self, Set, Zone )
|
||||
|
||||
DetectedItem.Removed = false
|
||||
DetectedItem.AreaID = #self.DetectedItems+1
|
||||
|
||||
self:E( { #self.DetectedItems, DetectedItem } )
|
||||
|
||||
table.insert( self.DetectedItems, DetectedItem )
|
||||
self:T( { #self.DetectedItems, DetectedItem } )
|
||||
|
||||
return DetectedItem
|
||||
|
||||
end
|
||||
|
||||
--- Remove a detected @{#DETECTION_AREAS.DetectedItem} with a given Index.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #number Index The DetectedItemIndex of the DetectedItems list are to be removed.
|
||||
-- @return #nil
|
||||
function DETECTION_AREAS:RemoveDetectedItem( DetectedItemIndex )
|
||||
local DetectedItems = self:GetDetectedItems()
|
||||
local DetectedCount = self:GetDetectedItemsCount()
|
||||
local DetectedArea = self:GetDetectedItem( Index )
|
||||
DetectedArea[Index] = nil
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Report summary of a detected item using a given numeric index.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param Index
|
||||
@ -1419,20 +1426,6 @@ do -- DETECTION_AREAS
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get the @{Zone#ZONE_UNIT} of a detection area using a given numeric index.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #number Index
|
||||
-- @return Core.Zone#ZONE_UNIT DetectedZone
|
||||
function DETECTION_AREAS:GetDetectedZone( Index )
|
||||
|
||||
local DetectedZone = self.DetectedItems[Index].Zone
|
||||
if DetectedZone then
|
||||
return DetectedZone
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Background worker function to determine if there are friendlies nearby ...
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param Wrapper.Unit#UNIT ReportUnit
|
||||
|
||||
@ -182,7 +182,6 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType )
|
||||
|
||||
self.FsmTemplate = self.FsmTemplate or FSM_PROCESS:New()
|
||||
|
||||
Mission:AddTask( self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@ -36,33 +36,99 @@ do -- TASK_SEAD
|
||||
-- @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 Set#SET_UNIT UnitSetTargets
|
||||
-- @param Core.Zone#ZONE_BASE TargetZone
|
||||
-- @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.
|
||||
-- @return #TASK_SEAD self
|
||||
function TASK_SEAD:New( Mission, SetGroup, TaskName, TargetSetUnit, TargetZone )
|
||||
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, "SEAD" ) ) -- Tasking.Task_SEAD#TASK_SEAD
|
||||
function TASK_SEAD:New( Mission, SetGroup, TaskName, TargetSetUnit, TargetDistance )
|
||||
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, "SEAD" ) ) -- Tasking.Task#TASK_SEAD
|
||||
self:F()
|
||||
|
||||
self.TargetSetUnit = TargetSetUnit
|
||||
self.TargetZone = TargetZone
|
||||
self.TargetDistance = TargetDistance
|
||||
|
||||
Mission:AddTask( self )
|
||||
|
||||
local Fsm = self:GetUnitProcess()
|
||||
|
||||
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "Route", Rejected = "Eject" } )
|
||||
Fsm:AddProcess ( "Assigned", "Route", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
|
||||
Fsm:AddTransition( "Rejected", "Eject", "Planned" )
|
||||
Fsm:AddTransition( "Arrived", "Update", "Updated" )
|
||||
Fsm:AddProcess ( "Updated", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "SEAD" ), { Accounted = "Success" } )
|
||||
Fsm:AddProcess ( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
Fsm:AddTransition( "Accounted", "Success", "Success" )
|
||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
function Fsm:onenterUpdated( TaskUnit )
|
||||
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "Route", Rejected = "Reject" } )
|
||||
Fsm:AddTransition( "Assigned", "Route", "Routing" )
|
||||
Fsm:AddProcess ( "Routing", "RouteToPoint", ACT_ROUTE_POINT:New( self.TargetPointVec2, self.TargetDistance ), { Arrived = "Arrive" } )
|
||||
Fsm:AddProcess ( "Routing", "RouteToZone", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Arrive" } )
|
||||
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
|
||||
Fsm:AddTransition( "Arrived", "Arrive", "Accounting" )
|
||||
Fsm:AddProcess ( "Accounting", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "SEAD" ), { Accounted = "Success" } )
|
||||
Fsm:AddProcess ( "Accounting", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
Fsm:AddTransition( "Accounting", "CheckRange", "Accounting" )
|
||||
Fsm:AddTransition( "Accounting", "InRange", "Accounting" )
|
||||
Fsm:AddTransition( "Accounting", "NotInRange", "Assigned" )
|
||||
Fsm:AddTransition( "Accounting", "Success", "Success" )
|
||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
|
||||
--- Test
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task#TASK_SEAD Task
|
||||
function Fsm:onenterRouting( TaskUnit, Task )
|
||||
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
-- Determine the first Unit from the self.TargetSetUnit
|
||||
|
||||
local TargetUnit = Task.TargetSetUnit:GetFirst() -- Wrapper.Unit#UNIT
|
||||
if TargetUnit then
|
||||
self:E( { TargetZone = Task.TargetZone } )
|
||||
if Task.TargetZone then
|
||||
self:__RouteToZone( 0.1 )
|
||||
else
|
||||
local TargetPointVec2 = TargetUnit:GetPointVec2()
|
||||
local RoutePointProcess = self:GetProcess( "Routing", "RouteToPoint" )
|
||||
RoutePointProcess:SetTargetPointVec2( TargetPointVec2 )
|
||||
self:__RouteToPoint( 0.1 )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Fsm:onenterAccounting( TaskUnit, Task )
|
||||
self:E( { self } )
|
||||
self:Account()
|
||||
self:Smoke()
|
||||
self:__CheckRange( -5 )
|
||||
end
|
||||
|
||||
--- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
function Fsm:onafterCheckRange( TaskUnit, Task )
|
||||
self:E( "CheckRange" )
|
||||
local TargetUnit = Task.TargetSetUnit:GetFirst() -- Wrapper.Unit#UNIT
|
||||
if TargetUnit then
|
||||
local PointVec2 = TargetUnit:GetPointVec2()
|
||||
local Distance = PointVec2:Get2DDistance( TaskUnit:GetPointVec2() )
|
||||
if Distance > Task.TargetDistance then
|
||||
self:NotInRange()
|
||||
else
|
||||
self:InRange()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Fsm:onafterNotInRange( TaskUnit )
|
||||
self:E( "Not In Range" )
|
||||
-- Stop accounting etc. and go back to routing.
|
||||
local FsmAccount = self:GetProcess( "Accounting", "Account" )
|
||||
local FsmSmoke = self:GetProcess( "Accounting", "Smoke" )
|
||||
FsmAccount:Stop() -- Stop the Accounting
|
||||
FsmSmoke:Stop() -- Stop the Smoking
|
||||
self:__Route( 1 )
|
||||
end
|
||||
|
||||
function Fsm:onafterInRange( TaskUnit )
|
||||
self:E( "In Range" )
|
||||
self:__CheckRange( -5 )
|
||||
end
|
||||
|
||||
return self
|
||||
|
||||
end
|
||||
|
||||
--- @param #TASK_SEAD self
|
||||
@ -70,4 +136,9 @@ do -- TASK_SEAD
|
||||
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
|
||||
end
|
||||
|
||||
--- @param #TASK_SEAD self
|
||||
function TASK_SEAD:SetTargetZone( TargetZone )
|
||||
self.TargetZone = TargetZone
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -1,3 +1,10 @@
|
||||
2017-02-17
|
||||
|
||||
- Added ACT_ROUTE_POINT
|
||||
-- Routes a controllable to a point with a defined distance.
|
||||
-- Upon arrived within the engagement distance, an arrival text is shown.
|
||||
|
||||
|
||||
2016-12-06
|
||||
|
||||
- Renamed the documentation references following the structure of the files.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
env.info( '*** MOOSE DYNAMIC INCLUDE START *** ' )
|
||||
env.info( 'Moose Generation Timestamp: 20170213_1411' )
|
||||
env.info( 'Moose Generation Timestamp: 20170217_1332' )
|
||||
|
||||
local base = _G
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
env.info( '*** MOOSE DYNAMIC INCLUDE START *** ' )
|
||||
env.info( 'Moose Generation Timestamp: 20170213_1411' )
|
||||
env.info( 'Moose Generation Timestamp: 20170217_1332' )
|
||||
|
||||
local base = _G
|
||||
|
||||
|
||||
@ -37,9 +37,11 @@ function RecceDetection:OnAfterDetect(From,Event,To)
|
||||
|
||||
local DetectionReport = RecceDetection:DetectedReportDetailed()
|
||||
|
||||
CC:MessageToAll( DetectionReport, 15, "" )
|
||||
CC:GetPositionable():MessageToAll( DetectionReport, 15, "" )
|
||||
end
|
||||
|
||||
local ArtilleryTime = {}
|
||||
local ArtilleryAim = 180
|
||||
|
||||
--- OnAfter Transition Handler for Event Detect.
|
||||
-- @param Functional.Detection#DETECTION_UNITS self
|
||||
@ -48,14 +50,21 @@ end
|
||||
-- @param #string To The To State string.
|
||||
-- @param Wrapper.Unit#UNIT DetectedUnits
|
||||
function RecceDetection:OnAfterDetected( From, Event, To, DetectedUnits )
|
||||
|
||||
local ArtilleryArray = ArtillerySetGroup:GetSet()
|
||||
local ArtilleryArrayCount = ArtillerySetGroup:Count()
|
||||
self:E( { From, Event, To, DetectedUnits } )
|
||||
|
||||
for DetectedUnitID, DetectedUnit in pairs( DetectedUnits ) do
|
||||
local DetectedUnit = DetectedUnit -- Wrapper.Unit#UNIT
|
||||
local Artillery = ArtilleryArray[ math.random( 1, ArtilleryArrayCount ) ] -- Wrapper.Group#GROUP
|
||||
local Task = Artillery:TaskFireAtPoint( DetectedUnit:GetVec2(), 500, 2 ) -- Fire 2 rockets to the target point.
|
||||
Artillery:SetTask( Task, 0.5 )
|
||||
local Artillery = ArtillerySetGroup:GetRandom() -- Wrapper.Group#GROUP
|
||||
|
||||
if ArtilleryTime[Artillery] and ArtilleryTime[Artillery] <= timer.getTime() - ArtilleryAim then
|
||||
ArtilleryTime[Artillery] = nil
|
||||
end
|
||||
|
||||
if not ArtilleryTime[Artillery] then
|
||||
local Task = Artillery:TaskFireAtPoint( DetectedUnit:GetVec2(), 500, 4 ) -- Fire 2 rockets to the target point.
|
||||
Artillery:SetTask( Task, 0.5 )
|
||||
ArtilleryTime[Artillery] = timer.getTime()
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Binary file not shown.
@ -104,11 +104,12 @@ local TargetZone = ZONE:New( "Target Zone" )
|
||||
-- 2. The set of groups of planes that pilots can join.
|
||||
-- 3. The name of the Task... This can be any name, and will be provided when the Pilot joins the task.
|
||||
-- 4. A type of the Task. When Tasks are in state Planned, then a menu can be provided that group the task based on this given type.
|
||||
local SEADTask = TASK:New(
|
||||
local SEADTask = TASK_SEAD:New(
|
||||
Mission,
|
||||
SEADSet,
|
||||
"SEAD Radars Vector 1",
|
||||
"SEAD" ) -- Tasking.Task#TASK
|
||||
TargetSet,
|
||||
15000 ) -- Tasking.Task#TASK_SEAD
|
||||
|
||||
-- This is now an important part of the Task process definition.
|
||||
-- Each TASK contains a "Process Template".
|
||||
@ -122,56 +123,14 @@ local SEADTask = TASK:New(
|
||||
|
||||
local SEADProcess = SEADTask:GetUnitProcess() -- #SEADProcess
|
||||
|
||||
-- Adding a new sub-process to the Task Template.
|
||||
-- At first, the task needs to be accepted by a pilot.
|
||||
-- We use for this the SUB-PROCESS ACT_ASSIGN_ACCEPT.
|
||||
-- The method on the FsmSEAD AddProcess accepts the following parameters:
|
||||
-- 1. State From "Planned". When the Fsm is in state "Planned", allow the event "Accept".
|
||||
-- 2. Event "Accept". This event can be triggered through FsmSEAD:Accept() or FsmSEAD:__Accept( 1 ). See documentation on state machines.
|
||||
-- 3. The PROCESS derived class. In this case, we use the ACT_ASSIGN_ACCEPT to accept the task and provide a briefing. So, when the event "Accept" is fired, this process is executed.
|
||||
-- 4. A table with the "return" states of the ACT_ASSIGN_ACCEPT process. This table indicates that for a certain return state, a further event needs to be called.
|
||||
-- 4.1 When the return state is Assigned, fire the event in the Task FsmSEAD:Route()
|
||||
-- 4.2 When the return state is Rejected, fire the event in the Task FsmSEAD:Eject()
|
||||
-- All other AddProcess calls are working in a similar manner.
|
||||
|
||||
SEADProcess:AddProcess( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( "SEAD the Area" ), { Assigned = "Route", Rejected = "Eject" } ) -- FSM SUB for type SEADProcess.
|
||||
|
||||
SEADProcess:AddProcess( "Assigned", "Route", ACT_ROUTE_ZONE:New( TargetZone ), { Arrived = "Update" } ) -- FSM SUB for type SEADProcess.
|
||||
|
||||
-- Adding a new Action...
|
||||
-- Actions define also the flow of the Task, but the actions will need to be programmed within your script.
|
||||
-- See the state machine explanation for further details.
|
||||
-- The AddTransition received a couple of parameters:
|
||||
-- 1. State From "Rejected". When the FsmSEAD is in state "Rejected", the event "Eject" can be fired.
|
||||
-- 2. Event "Eject". This event can be triggered synchronously through FsmSEAD:Eject() or asynchronously through FsmSEAD:__Eject(secs).
|
||||
-- 3. State To "Planned". After the event has been fired, the FsmSEAD will transition to Planned.
|
||||
|
||||
SEADProcess:AddTransition( "Rejected", "Eject", "Planned" )
|
||||
|
||||
SEADProcess:AddTransition( "Arrived", "Update", "Updated" )
|
||||
|
||||
SEADProcess:AddProcess( "Updated", "Account", ACT_ACCOUNT_DEADS:New( TargetSet, "SEAD" ), { Accounted = "Success" } )
|
||||
|
||||
SEADProcess:AddProcess( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( TargetSet, TargetZone ) )
|
||||
|
||||
SEADProcess:AddTransition( "Accounted", "Success", "Success" )
|
||||
|
||||
SEADProcess:AddTransition( "*", "Fail", "Failed" )
|
||||
|
||||
SEADProcess:AddScoreProcess( "Updated", "Account", "Account", "destroyed a radar", 25 )
|
||||
SEADProcess:AddScoreProcess( "Updated", "Account", "Failed", "failed to destroy a radar", -10 )
|
||||
SEADProcess:AddScoreProcess( "Accounting", "Account", "Account", "destroyed a radar", 25 )
|
||||
SEADProcess:AddScoreProcess( "Accounting", "Account", "Failed", "failed to destroy a radar", -10 )
|
||||
|
||||
-- Now we will set the SCORING. Scoring is set using the TaskSEAD object.
|
||||
-- Scores can be set on the status of the Task, and on Process level.
|
||||
SEADProcess:AddScore( "Success", "Destroyed all target radars", 250 )
|
||||
SEADProcess:AddScore( "Failed", "Failed to destroy all target radars", -100 )
|
||||
|
||||
function SEADProcess:OnEnterUpdated( Controllable, From, Event, To )
|
||||
self:E( { self } )
|
||||
self:Account()
|
||||
self:Smoke()
|
||||
end
|
||||
|
||||
-- Here we handle the PlayerAborted event, which is fired when a Player leaves the unit while being assigned to the Task.
|
||||
-- Within the event handler, which is passed the PlayerUnit and PlayerName parameter,
|
||||
-- we check if the SEADTask has still AlivePlayers assigned to the Task.
|
||||
@ -184,14 +143,14 @@ function SEADTask:OnEnterPlayerCrashed( PlayerUnit, PlayerName )
|
||||
end
|
||||
|
||||
|
||||
local TaskSEAD2 = TASK:New( Mission, SEADSet, "SEAD Radars Vector 2", "SEAD" ) -- Tasking.Task#TASK
|
||||
TaskSEAD2:SetUnitProcess( SEADTask:GetUnitProcess():Copy() )
|
||||
Mission:AddTask( TaskSEAD2 )
|
||||
|
||||
Mission:RemoveTask( SEADTask )
|
||||
|
||||
SEADTask = nil
|
||||
SEADProcess = nil
|
||||
--local TaskSEAD2 = TASK:New( Mission, SEADSet, "SEAD Radars Vector 2", "SEAD" ) -- Tasking.Task#TASK
|
||||
--TaskSEAD2:SetUnitProcess( SEADTask:GetUnitProcess():Copy() )
|
||||
--Mission:AddTask( TaskSEAD2 )
|
||||
--
|
||||
--Mission:RemoveTask( SEADTask )
|
||||
--
|
||||
--SEADTask = nil
|
||||
--SEADProcess = nil
|
||||
|
||||
|
||||
collectgarbage()
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user