mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
OPS Operation
- Condition - Armygroup - Auftrag - OPS
This commit is contained in:
parent
3f296554ed
commit
539dfd6a38
@ -25,10 +25,13 @@
|
||||
-- @field #string lid Class id string for output to DCS log file.
|
||||
-- @field #string name Name of the condition.
|
||||
-- @field #boolean isAny General functions are evaluated as any condition.
|
||||
-- @field #boolean negateResult Negeate result of evaluation.
|
||||
-- @field #boolean negateResult Negate result of evaluation.
|
||||
-- @field #boolean noneResult Boolean that is returned if no condition functions at all were specified.
|
||||
-- @field #table functionsGen General condition functions.
|
||||
-- @field #table functionsAny Any condition functions.
|
||||
-- @field #table functionsAll All condition functions.
|
||||
-- @field #number functionCounter Running number to determine the unique ID of condition functions.
|
||||
-- @field #boolean defaultPersist Default persistence of condition functions.
|
||||
--
|
||||
-- @extends Core.Base#BASE
|
||||
|
||||
@ -42,27 +45,34 @@
|
||||
--
|
||||
-- @field #CONDITION
|
||||
CONDITION = {
|
||||
ClassName = "CONDITION",
|
||||
lid = nil,
|
||||
functionsGen = {},
|
||||
functionsAny = {},
|
||||
functionsAll = {},
|
||||
ClassName = "CONDITION",
|
||||
lid = nil,
|
||||
functionsGen = {},
|
||||
functionsAny = {},
|
||||
functionsAll = {},
|
||||
functionCounter = 0,
|
||||
defaultPersist = false,
|
||||
}
|
||||
|
||||
--- Condition function.
|
||||
-- @type CONDITION.Function
|
||||
-- @field #function func Callback function to check for a condition. Should return a `#boolean`.
|
||||
-- @field #number uid Unique ID of the condition function.
|
||||
-- @field #string type Type of the condition function: "gen", "any", "all".
|
||||
-- @field #boolean persistence If `true`, this is persistent.
|
||||
-- @field #function func Callback function to check for a condition. Must return a `#boolean`.
|
||||
-- @field #table arg (Optional) Arguments passed to the condition callback function if any.
|
||||
|
||||
--- CONDITION class version.
|
||||
-- @field #string version
|
||||
CONDITION.version="0.2.0"
|
||||
CONDITION.version="0.3.0"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: Make FSM.
|
||||
-- TODO: Make FSM. No sure if really necessary.
|
||||
-- DONE: Option to remove condition functions.
|
||||
-- DONE: Persistence option for condition functions.
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
@ -79,6 +89,8 @@ function CONDITION:New(Name)
|
||||
|
||||
self.name=Name or "Condition X"
|
||||
|
||||
self:SetNoneResult(false)
|
||||
|
||||
self.lid=string.format("%s | ", self.name)
|
||||
|
||||
return self
|
||||
@ -102,6 +114,28 @@ function CONDITION:SetNegateResult(Negate)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set whether `true` or `false` is returned, if no conditions at all were specified. By default `false` is returned.
|
||||
-- @param #CONDITION self
|
||||
-- @param #boolean ReturnValue Returns this boolean.
|
||||
-- @return #CONDITION self
|
||||
function CONDITION:SetNoneResult(ReturnValue)
|
||||
if not ReturnValue then
|
||||
self.noneResult=false
|
||||
else
|
||||
self.noneResult=true
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set whether condition functions are persistent, *i.e.* are removed.
|
||||
-- @param #CONDITION self
|
||||
-- @param #boolean IsPersistent If `true`, condition functions are persistent.
|
||||
-- @return #CONDITION self
|
||||
function CONDITION:SetDefaultPersistence(IsPersistent)
|
||||
self.defaultPersist=IsPersistent
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add a function that is evaluated. It must return a `#boolean` value, *i.e.* either `true` or `false` (or `nil`).
|
||||
-- @param #CONDITION self
|
||||
-- @param #function Function The function to call.
|
||||
@ -114,47 +148,109 @@ end
|
||||
--
|
||||
-- myCondition:AddFunction(isAequalB, a, b)
|
||||
--
|
||||
-- @return #CONDITION self
|
||||
-- @return #CONDITION.Function Condition function table.
|
||||
function CONDITION:AddFunction(Function, ...)
|
||||
|
||||
-- Condition function.
|
||||
local condition=self:_CreateCondition(Function, ...)
|
||||
local condition=self:_CreateCondition(0, Function, ...)
|
||||
|
||||
-- Add to table.
|
||||
table.insert(self.functionsGen, condition)
|
||||
|
||||
return self
|
||||
return condition
|
||||
end
|
||||
|
||||
--- Add a function that is evaluated. It must return a `#boolean` value, *i.e.* either `true` or `false` (or `nil`).
|
||||
-- @param #CONDITION self
|
||||
-- @param #function Function The function to call.
|
||||
-- @param ... (Optional) Parameters passed to the function (if any).
|
||||
-- @return #CONDITION self
|
||||
-- @return #CONDITION.Function Condition function table.
|
||||
function CONDITION:AddFunctionAny(Function, ...)
|
||||
|
||||
-- Condition function.
|
||||
local condition=self:_CreateCondition(Function, ...)
|
||||
local condition=self:_CreateCondition(1, Function, ...)
|
||||
|
||||
-- Add to table.
|
||||
table.insert(self.functionsAny, condition)
|
||||
|
||||
return self
|
||||
return condition
|
||||
end
|
||||
|
||||
--- Add a function that is evaluated. It must return a `#boolean` value, *i.e.* either `true` or `false` (or `nil`).
|
||||
-- @param #CONDITION self
|
||||
-- @param #function Function The function to call.
|
||||
-- @param ... (Optional) Parameters passed to the function (if any).
|
||||
-- @return #CONDITION self
|
||||
-- @return #CONDITION.Function Condition function table.
|
||||
function CONDITION:AddFunctionAll(Function, ...)
|
||||
|
||||
-- Condition function.
|
||||
local condition=self:_CreateCondition(Function, ...)
|
||||
local condition=self:_CreateCondition(2, Function, ...)
|
||||
|
||||
-- Add to table.
|
||||
table.insert(self.functionsAll, condition)
|
||||
|
||||
return condition
|
||||
end
|
||||
|
||||
--- Remove a condition function.
|
||||
-- @param #CONDITION self
|
||||
-- @param #CONDITION.Function ConditionFunction The condition function to be removed.
|
||||
-- @return #CONDITION self
|
||||
function CONDITION:RemoveFunction(ConditionFunction)
|
||||
|
||||
if ConditionFunction then
|
||||
|
||||
local data=nil
|
||||
if ConditionFunction.type==0 then
|
||||
data=self.functionsGen
|
||||
elseif ConditionFunction.type==1 then
|
||||
data=self.functionsAny
|
||||
elseif ConditionFunction.type==2 then
|
||||
data=self.functionsAll
|
||||
end
|
||||
|
||||
if data then
|
||||
for i=#data,1,-1 do
|
||||
local cf=data[i] --#CONDITION.Function
|
||||
if cf.uid==ConditionFunction.uid then
|
||||
self:T(self.lid..string.format("Removed ConditionFunction UID=%d", cf.uid))
|
||||
table.remove(data, i)
|
||||
return self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Remove all non-persistant condition functions.
|
||||
-- @param #CONDITION self
|
||||
-- @return #CONDITION self
|
||||
function CONDITION:RemoveNonPersistant()
|
||||
|
||||
for i=#self.functionsGen,1,-1 do
|
||||
local cf=self.functionsGen[i] --#CONDITION.Function
|
||||
if not cf.persistence then
|
||||
table.remove(self.functionsGen, i)
|
||||
end
|
||||
end
|
||||
|
||||
for i=#self.functionsAll,1,-1 do
|
||||
local cf=self.functionsAll[i] --#CONDITION.Function
|
||||
if not cf.persistence then
|
||||
table.remove(self.functionsAll, i)
|
||||
end
|
||||
end
|
||||
|
||||
for i=#self.functionsAny,1,-1 do
|
||||
local cf=self.functionsAny[i] --#CONDITION.Function
|
||||
if not cf.persistence then
|
||||
table.remove(self.functionsAny, i)
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@ -167,11 +263,7 @@ function CONDITION:Evaluate(AnyTrue)
|
||||
|
||||
-- Check if at least one function was given.
|
||||
if #self.functionsAll + #self.functionsAny + #self.functionsAll == 0 then
|
||||
if self.negateResult then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
return self.noneResult
|
||||
end
|
||||
|
||||
-- Any condition for gen.
|
||||
@ -280,13 +372,20 @@ end
|
||||
|
||||
--- Create conditon function object.
|
||||
-- @param #CONDITION self
|
||||
-- @param #number Ftype Function type: 0=Gen, 1=All, 2=Any.
|
||||
-- @param #function Function The function to call.
|
||||
-- @param ... (Optional) Parameters passed to the function (if any).
|
||||
-- @return #CONDITION.Function Condition function.
|
||||
function CONDITION:_CreateCondition(Function, ...)
|
||||
function CONDITION:_CreateCondition(Ftype, Function, ...)
|
||||
|
||||
-- Increase counter.
|
||||
self.functionCounter=self.functionCounter+1
|
||||
|
||||
local condition={} --#CONDITION.Function
|
||||
|
||||
condition.uid=self.functionCounter
|
||||
condition.type=Ftype or 0
|
||||
condition.persistence=self.defaultPersist
|
||||
condition.func=Function
|
||||
condition.arg={}
|
||||
if arg then
|
||||
|
||||
@ -142,6 +142,7 @@ function ARMYGROUP:New(group)
|
||||
------------------------
|
||||
--- Pseudo Functions ---
|
||||
------------------------
|
||||
|
||||
--- Triggers the FSM event "Cruise".
|
||||
-- @function [parent=#ARMYGROUP] Cruise
|
||||
-- @param #ARMYGROUP self
|
||||
@ -253,10 +254,14 @@ function ARMYGROUP:New(group)
|
||||
--- Triggers the FSM event "Retreat".
|
||||
-- @function [parent=#ARMYGROUP] Retreat
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param Core.Zone#ZONE_BASE Zone (Optional) Zone where to retreat. Default is the closest retreat zone.
|
||||
-- @param #number Formation (Optional) Formation of the group.
|
||||
|
||||
--- Triggers the FSM event "Retreat" after a delay.
|
||||
-- @function [parent=#ARMYGROUP] __Retreat
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param Core.Zone#ZONE_BASE Zone (Optional) Zone where to retreat. Default is the closest retreat zone.
|
||||
-- @param #number Formation (Optional) Formation of the group.
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
--- On after "Retreat" event.
|
||||
@ -265,7 +270,8 @@ function ARMYGROUP:New(group)
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
|
||||
-- @param Core.Zone#ZONE_BASE Zone Zone where to retreat.
|
||||
-- @param #number Formation Formation of the group. Can be #nil.
|
||||
|
||||
--- Triggers the FSM event "Retreated".
|
||||
-- @function [parent=#ARMYGROUP] Retreated
|
||||
@ -1010,6 +1016,9 @@ function ARMYGROUP:onbeforeUpdateRoute(From, Event, To, n, N, Speed, Formation)
|
||||
elseif task.dcstask.id==AUFTRAG.SpecialTask.RELOCATECOHORT then
|
||||
-- For relocate
|
||||
self:T2(self.lid.."Allowing update route for Task: Relocate Cohort")
|
||||
elseif task.dcstask.id==AUFTRAG.SpecialTask.REARMING then
|
||||
-- For relocate
|
||||
self:T2(self.lid.."Allowing update route for Task: Rearming")
|
||||
else
|
||||
local taskname=task and task.description or "No description"
|
||||
self:T(self.lid..string.format("WARNING: Update route denied because taskcurrent=%d>0! Task description = %s", self.taskcurrent, tostring(taskname)))
|
||||
@ -1411,10 +1420,15 @@ function ARMYGROUP:onbeforeRearm(From, Event, To, Coordinate, Formation)
|
||||
|
||||
-- Pause current mission.
|
||||
if self:IsOnMission() then
|
||||
self:T(self.lid.."Rearm command but have current mission ==> Pausing mission!")
|
||||
self:PauseMission()
|
||||
dt=-0.1
|
||||
allowed=false
|
||||
local mission=self:GetMissionCurrent()
|
||||
if mission and mission.type~=AUFTRAG.Type.REARMING then
|
||||
self:T(self.lid.."Rearm command but have current mission ==> Pausing mission!")
|
||||
self:PauseMission()
|
||||
dt=-0.1
|
||||
allowed=false
|
||||
else
|
||||
self:T(self.lid.."Rearm command and current mission is REARMING ==> Transition ALLOWED!")
|
||||
end
|
||||
end
|
||||
|
||||
-- Disengage.
|
||||
@ -1480,6 +1494,7 @@ function ARMYGROUP:onafterRearmed(From, Event, To)
|
||||
|
||||
-- Check if this is a rearming mission.
|
||||
if mission and mission.type==AUFTRAG.Type.REARMING then
|
||||
|
||||
-- Rearmed ==> Mission Done! This also checks if the group is done.
|
||||
self:MissionDone(mission)
|
||||
|
||||
@ -1651,8 +1666,12 @@ function ARMYGROUP:onafterRetreat(From, Event, To, Zone, Formation)
|
||||
-- ID of current waypoint.
|
||||
local uid=self:GetWaypointCurrent().uid
|
||||
|
||||
-- Get random coordinate of the zone.
|
||||
local Coordinate=Zone:GetRandomCoordinate()
|
||||
|
||||
-- Debug info.
|
||||
self:T(self.lid..string.format("Retreating to zone %s", Zone:GetName()))
|
||||
|
||||
-- Add waypoint after current.
|
||||
local wp=self:AddWaypoint(Coordinate, nil, uid, Formation, true)
|
||||
|
||||
@ -1952,8 +1971,10 @@ function ARMYGROUP:AddWaypoint(Coordinate, Speed, AfterWaypointWithID, Formation
|
||||
if not Formation then
|
||||
if self.formationPerma then
|
||||
Formation = self.formationPerma
|
||||
elseif self.optionDefault.Formation then
|
||||
Formation = self.optionDefault.Formation
|
||||
elseif self.option.Formation then
|
||||
Formation = self.option.Formation
|
||||
Formation = self.option.Formation
|
||||
else
|
||||
-- Default formation is on road.
|
||||
Formation = ENUMS.Formation.Vehicle.OnRoad
|
||||
@ -2037,8 +2058,11 @@ function ARMYGROUP:_InitGroup(Template)
|
||||
-- Set default radio.
|
||||
self:SetDefaultRadio(self.radio.Freq, self.radio.Modu, self.radio.On)
|
||||
|
||||
-- Set default formation from first waypoint.
|
||||
self.optionDefault.Formation=template.route.points[1].action --self:GetWaypoint(1).action
|
||||
-- Get current formation from first waypoint.
|
||||
self.option.Formation=template.route.points[1].action
|
||||
|
||||
-- Set default formation to "on road".
|
||||
self.optionDefault.Formation=ENUMS.Formation.Vehicle.OnRoad
|
||||
|
||||
-- Default TACAN off.
|
||||
self:SetDefaultTACAN(nil, nil, nil, nil, true)
|
||||
|
||||
@ -628,7 +628,7 @@ AUFTRAG.Category={
|
||||
|
||||
--- AUFTRAG class version.
|
||||
-- @field #string version
|
||||
AUFTRAG.version="0.9.7"
|
||||
AUFTRAG.version="0.9.8"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
@ -5810,7 +5810,7 @@ function AUFTRAG:GetDCSMissionTask()
|
||||
|
||||
table.insert(DCStasks, DCStask)
|
||||
|
||||
elseif self.type==AUFTRAG.Type.AMMOSUPPLY then
|
||||
elseif self.type==AUFTRAG.Type.REARMING then
|
||||
|
||||
----------------------
|
||||
-- REARMING Mission --
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
-- @field #number Tstop Stop time in seconds of abs mission time.
|
||||
-- @field #number duration Duration of the operation in seconds.
|
||||
-- @field Core.Condition#CONDITION conditionStart Start condition.
|
||||
-- @field Core.Condition#CONDITION conditionStop Stop condition.
|
||||
-- @field Core.Condition#CONDITION conditionOver Over condition.
|
||||
-- @field #table branches Branches.
|
||||
-- @field #OPERATION.Branch branchMaster Master branch.
|
||||
-- @field #OPERATION.Branch branchActive Active branch.
|
||||
@ -47,7 +47,7 @@
|
||||
-- @field #table missions Missions.
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
--- *Before this time tomorrow I shall have gained a peerage, or Westminster Abbey* -- Horatio Nelson
|
||||
--- *Before this time tomorrow I shall have gained a peerage, or Westminster Abbey.* -- Horatio Nelson
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -95,6 +95,7 @@ _OPERATIONID=0
|
||||
-- @field Core.Condition#CONDITION conditionOver Conditions when the phase is over.
|
||||
-- @field #string status Phase status.
|
||||
-- @field #number Tstart Abs. mission time when the phase was started.
|
||||
-- @field #number nActive Number of times the phase was active.
|
||||
-- @field #number duration Duration in seconds how long the phase should be active after it started.
|
||||
-- @field #OPERATION.Branch branch The branch this phase belongs to.
|
||||
|
||||
@ -134,6 +135,7 @@ OPERATION.version="0.2.0"
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: "Over" conditions.
|
||||
-- TODO: Repeat phases: after over ==> planned (not over)
|
||||
-- DONE: Branches.
|
||||
-- DONE: Phases.
|
||||
|
||||
@ -168,6 +170,15 @@ function OPERATION:New(Name)
|
||||
-- Master branch.
|
||||
self.branchMaster=self:AddBranch("Master")
|
||||
|
||||
self.conditionStart=CONDITION:New("Operation %s start", self.name)
|
||||
self.conditionStart:SetNoneResult(false) --If no condition function is specified, the ops will NOT be over.
|
||||
self.conditionStart:SetDefaultPersistence(false)
|
||||
|
||||
self.conditionOver=CONDITION:New("Operation %s over", self.name)
|
||||
self.conditionOver:SetNoneResult(false)
|
||||
self.conditionOver:SetDefaultPersistence(false)
|
||||
|
||||
|
||||
-- Set master as active branch.
|
||||
self.branchActive=self.branchMaster
|
||||
|
||||
@ -204,6 +215,12 @@ function OPERATION:New(Name)
|
||||
-- @param #OPERATION self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
--- On after "Start" event.
|
||||
-- @function [parent=#OPERATION] OnAfterStart
|
||||
-- @param #OPERATION self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
|
||||
--- Triggers the FSM event "Stop".
|
||||
-- @function [parent=#OPERATION] Stop
|
||||
@ -375,6 +392,27 @@ function OPERATION:SetTime(ClockStart, ClockStop)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add (all) condition function when the whole operation is over. Must return a `#boolean`.
|
||||
-- @param #OPERATION self
|
||||
-- @param #function Function Function that needs to be `true` before the operation is over.
|
||||
-- @param ... Condition function arguments if any.
|
||||
-- @return Core.Condition#CONDITION.Function Condition function table.
|
||||
function OPERATION:AddConditonOverAll(Function, ...)
|
||||
local cf=self.conditionOver:AddFunctionAll(Function, ...)
|
||||
return cf
|
||||
end
|
||||
|
||||
--- Add (any) condition function when the whole operation is over. Must return a `#boolean`.
|
||||
-- @param #OPERATION self
|
||||
-- @param #function Function Function that needs to be `true` before the operation is over.
|
||||
-- @param ... Condition function arguments if any.
|
||||
-- @return Core.Condition#CONDITION.Function Condition function table.
|
||||
function OPERATION:AddConditonOverAny(Phase, Function, ...)
|
||||
local cf=self.conditionOver:AddFunctionAny(Function, ...)
|
||||
return cf
|
||||
end
|
||||
|
||||
|
||||
--- Add a new phase to the operation. This is added add the end of all previously added phases (if any).
|
||||
-- @param #OPERATION self
|
||||
-- @param #string Name Name of the phase. Default "Phase-01" where the last number is a running number.
|
||||
@ -392,9 +430,9 @@ function OPERATION:AddPhase(Name, Branch, Duration)
|
||||
-- Branch of phase
|
||||
phase.branch=Branch
|
||||
|
||||
-- Set duraction of pahse (if any).
|
||||
phase.duration=Duration
|
||||
|
||||
|
||||
-- Debug output.
|
||||
self:T(self.lid..string.format("Adding phase %s to branch %s", phase.name, Branch.name))
|
||||
|
||||
@ -469,7 +507,7 @@ function OPERATION:SetPhaseStatus(Phase, Status)
|
||||
-- Set time stamp when phase becase active.
|
||||
if Phase.status==OPERATION.PhaseStatus.ACTIVE then
|
||||
Phase.Tstart=timer.getAbsTime()
|
||||
env.info("FF Setting phase start time stamp")
|
||||
Phase.nActive=Phase.nActive+1
|
||||
elseif Phase.status==OPERATION.PhaseStatus.OVER then
|
||||
-- Trigger PhaseOver event.
|
||||
self:PhaseOver(Phase)
|
||||
@ -504,14 +542,15 @@ end
|
||||
--- Add condition function when the given phase is over. Must return a `#boolean`.
|
||||
-- @param #OPERATION self
|
||||
-- @param #OPERATION.Phase Phase The phase.
|
||||
-- @param #function Function Function that needs to be `true`before the phase is over.
|
||||
-- @param #function Function Function that needs to be `true` before the phase is over.
|
||||
-- @param ... Condition function arguments if any.
|
||||
-- @return #OPERATION self
|
||||
-- @return Core.Condition#CONDITION.Function Condition function table.
|
||||
function OPERATION:AddPhaseConditonOverAll(Phase, Function, ...)
|
||||
if Phase then
|
||||
Phase.conditionOver:AddFunctionAll(Function, ...)
|
||||
local cf=Phase.conditionOver:AddFunctionAll(Function, ...)
|
||||
return cf
|
||||
end
|
||||
return self
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Add condition function when the given phase is over. Must return a `#boolean`.
|
||||
@ -519,16 +558,41 @@ end
|
||||
-- @param #OPERATION.Phase Phase The phase.
|
||||
-- @param #function Function Function that needs to be `true` before the phase is over.
|
||||
-- @param ... Condition function arguments if any.
|
||||
-- @return #OPERATION self
|
||||
-- @return Core.Condition#CONDITION.Function Condition function table.
|
||||
function OPERATION:AddPhaseConditonOverAny(Phase, Function, ...)
|
||||
if Phase then
|
||||
Phase.conditionOver:AddFunctionAny(Function, ...)
|
||||
local cf=Phase.conditionOver:AddFunctionAny(Function, ...)
|
||||
return cf
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Set persistence of condition function. By default, condition functions are removed after a phase is over.
|
||||
-- @param #OPERATION self
|
||||
-- @param Core.Condition#CONDITION.Function ConditionFunction Condition function table.
|
||||
-- @param #boolean IsPersistent If `true` or `nil`, condition function is persistent.
|
||||
-- @return #OPERATION self
|
||||
function OPERATION:SetConditionFunctionPersistence(ConditionFunction, IsPersistent)
|
||||
ConditionFunction.persistence=IsPersistent
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add condition function when the given phase is to be repeated. The provided function must return a `#boolean`.
|
||||
-- If the condition evaluation returns `true`, the phase is set to state `Planned` instead of `Over` and can be repeated.
|
||||
-- @param #OPERATION self
|
||||
-- @param #OPERATION.Phase Phase The phase.
|
||||
-- @param #function Function Function that needs to be `true` before the phase is over.
|
||||
-- @param ... Condition function arguments if any.
|
||||
-- @return #OPERATION self
|
||||
function OPERATION:AddPhaseConditonRepeatAll(Phase, Function, ...)
|
||||
if Phase then
|
||||
Phase.conditionRepeat:AddFunctionAll(Function, ...)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Get codition when the given phase is over.
|
||||
--- Get condition when the given phase is over.
|
||||
-- @param #OPERATION self
|
||||
-- @param #OPERATION.Phase Phase The phase.
|
||||
-- @return Core.Condition#CONDITION Condition when the phase is over (if any).
|
||||
@ -536,11 +600,12 @@ function OPERATION:GetPhaseConditonOver(Phase, Condition)
|
||||
return Phase.conditionOver
|
||||
end
|
||||
|
||||
--- Get currrently active phase.
|
||||
--- Get how many times a phase has been active.
|
||||
-- @param #OPERATION self
|
||||
-- @return #OPERATION.Phase Current phase or `nil` if no current phase is active.
|
||||
function OPERATION:GetPhaseActive()
|
||||
return self.phase
|
||||
-- @param #OPERATION.Phase Phase The phase.
|
||||
-- @return #number Number of times the phase has been active.
|
||||
function OPERATION:GetPhaseNactive(Phase)
|
||||
return Phase.nActive
|
||||
end
|
||||
|
||||
--- Get name of a phase.
|
||||
@ -558,18 +623,11 @@ function OPERATION:GetPhaseName(Phase)
|
||||
return "None"
|
||||
end
|
||||
|
||||
--- Check if a phase is the currently active one.
|
||||
--- Get currrently active phase.
|
||||
-- @param #OPERATION self
|
||||
-- @param #OPERATION.Phase Phase The phase to check.
|
||||
-- @return #boolean If `true`, this phase is currently active.
|
||||
function OPERATION:IsPhaseActive(Phase)
|
||||
local phase=self:GetPhaseActive()
|
||||
if phase and phase.uid==Phase.uid then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
return nil
|
||||
-- @return #OPERATION.Phase Current phase or `nil` if no current phase is active.
|
||||
function OPERATION:GetPhaseActive()
|
||||
return self.phase
|
||||
end
|
||||
|
||||
--- Get index of phase.
|
||||
@ -709,19 +767,23 @@ end
|
||||
-- @param #OPERATION.Phase PhaseFrom The phase of the *from* branch *after* which to switch.
|
||||
-- @param #OPERATION.Phase PhaseTo The phase of the *to* branch *to* which to switch.
|
||||
-- @param Core.Condition#CONDITION ConditionSwitch (Optional) Condition(s) when to switch the branches.
|
||||
-- @return #OPERATION.Branch Branch table object.
|
||||
-- @return #OPERATION.Edge Edge table object.
|
||||
function OPERATION:AddEdge(PhaseFrom, PhaseTo, ConditionSwitch)
|
||||
|
||||
local edge={} --#OPERATION.Edge
|
||||
|
||||
|
||||
edge.phaseFrom=PhaseFrom
|
||||
edge.phaseTo=PhaseTo
|
||||
|
||||
edge.branchFrom=PhaseFrom.branch
|
||||
edge.branchTo=PhaseTo.branch
|
||||
|
||||
edge.conditionSwitch=ConditionSwitch or CONDITION:New("Edge")
|
||||
if ConditionSwitch then
|
||||
edge.conditionSwitch=ConditionSwitch
|
||||
else
|
||||
edge.conditionSwitch=CONDITION:New("Edge")
|
||||
edge.conditionSwitch:SetNoneResult(true)
|
||||
end
|
||||
|
||||
table.insert(edge.branchFrom.edges, edge)
|
||||
|
||||
@ -729,16 +791,18 @@ function OPERATION:AddEdge(PhaseFrom, PhaseTo, ConditionSwitch)
|
||||
end
|
||||
|
||||
--- Add condition function to an edge when branches are switched. The function must return a `#boolean`.
|
||||
-- If multiple condition functions are added, all of these must return true for the branch switch to occur.
|
||||
-- @param #OPERATION self
|
||||
-- @param #OPERATION.Edge Edge The edge connecting the two branches.
|
||||
-- @param #function Function Function that needs to be `true` for switching between the branches.
|
||||
-- @param ... Condition function arguments if any.
|
||||
-- @return #OPERATION self
|
||||
-- @return Core.Condition#CONDITION.Function Condition function table.
|
||||
function OPERATION:AddEdgeConditonSwitchAll(Edge, Function, ...)
|
||||
if Edge then
|
||||
Edge.conditionSwitch:AddFunctionAll(Function, ...)
|
||||
local cf=Edge.conditionSwitch:AddFunctionAll(Function, ...)
|
||||
return cf
|
||||
end
|
||||
return self
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Add mission to operation.
|
||||
@ -769,9 +833,9 @@ function OPERATION:AddTarget(Target, Phase)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add Targets from operation.
|
||||
--- Get targets of operation.
|
||||
-- @param #OPERATION self
|
||||
-- @param #OPERATION.Phase Phase
|
||||
-- @param #OPERATION.Phase Phase (Optional) Only return targets set for this phase. Default is targets of all phases.
|
||||
-- @return #table Targets Table of #TARGET objects
|
||||
function OPERATION:GetTargets(Phase)
|
||||
local N = {}
|
||||
@ -926,6 +990,14 @@ function OPERATION:IsStopped()
|
||||
return is
|
||||
end
|
||||
|
||||
--- Check if operation is **not** "Over" or "Stopped".
|
||||
-- @param #OPERATION self
|
||||
-- @return #boolean If `true`, operation is not "Over" or "Stopped".
|
||||
function OPERATION:IsNotOver()
|
||||
local is=not (self:IsOver() or self:IsStopped())
|
||||
return is
|
||||
end
|
||||
|
||||
--- Check if phase is in status "Active".
|
||||
-- @param #OPERATION self
|
||||
-- @param #OPERATION.Phase Phase The phase.
|
||||
@ -937,6 +1009,20 @@ function OPERATION:IsPhaseActive(Phase)
|
||||
return false
|
||||
end
|
||||
|
||||
--- Check if a phase is the currently active one.
|
||||
-- @param #OPERATION self
|
||||
-- @param #OPERATION.Phase Phase The phase to check.
|
||||
-- @return #boolean If `true`, this phase is currently active.
|
||||
function OPERATION:IsPhaseActive(Phase)
|
||||
local phase=self:GetPhaseActive()
|
||||
if phase and phase.uid==Phase.uid then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Check if phase is in status "Planned".
|
||||
-- @param #OPERATION self
|
||||
-- @param #OPERATION.Phase Phase The phase.
|
||||
@ -990,27 +1076,30 @@ function OPERATION:onafterStatusUpdate(From, Event, To)
|
||||
-- Current FSM state.
|
||||
local fsmstate=self:GetState()
|
||||
|
||||
-- Start operation.
|
||||
if self:IsPlanned() then
|
||||
if self.Tstart and Tnow>self.Tstart then
|
||||
|
||||
-- Start operation if start time has passed (if any) and start condition(s) are met (if any).
|
||||
if (self.Tstart and Tnow>self.Tstart or self.Tstart==nil) and (self.conditionStart==nil or self.conditionStart:Evaluate()) then
|
||||
self:Start()
|
||||
end
|
||||
end
|
||||
if (self.Tstop and Tnow>self.Tstop) and not (self:IsOver() or self:IsStopped()) then
|
||||
self:Over()
|
||||
|
||||
elseif self:IsNotOver() then
|
||||
|
||||
-- Operation is over if stop time has passed (if any) and over condition(s) are met (if any).
|
||||
if (self.Tstop and Tnow>self.Tstop or self.Tstop==nil) and (self.conditionOver==nil or self.conditionOver:Evaluate()) then
|
||||
self:Over()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if (not self:IsRunning()) and (self.conditionStart and self.conditionStart:Evaluate()) then
|
||||
self:Start()
|
||||
end
|
||||
if self:IsRunning() and (self.conditionStop and self.conditionStop:Evaluate()) then
|
||||
self:Over()
|
||||
end
|
||||
|
||||
-- Check phases.
|
||||
if self:IsRunning() then
|
||||
self:_CheckPhases()
|
||||
end
|
||||
|
||||
|
||||
-- Debug output.
|
||||
if self.verbose>=1 then
|
||||
|
||||
@ -1035,7 +1124,7 @@ function OPERATION:onafterStatusUpdate(From, Event, To)
|
||||
local text="Phases:"
|
||||
for i,_phase in pairs(self.branchActive.phases) do
|
||||
local phase=_phase --#OPERATION.Phase
|
||||
text=text..string.format("\n[%d] %s: status=%s", i, phase.name, tostring(phase.status))
|
||||
text=text..string.format("\n[%d] %s [uid=%d]: status=%s Nact=%d", i, phase.name, phase.uid, tostring(phase.status), phase.nActive)
|
||||
end
|
||||
if text=="Phases:" then text=text.." None" end
|
||||
self:I(self.lid..text)
|
||||
@ -1107,6 +1196,19 @@ function OPERATION:onafterPhaseChange(From, Event, To, Phase)
|
||||
return self
|
||||
end
|
||||
|
||||
--- On after "PhaseOver" event.
|
||||
-- @param #OPERATION self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param #OPERATION.Phase Phase The phase that is over.
|
||||
function OPERATION:onafterPhaseOver(From, Event, To, Phase)
|
||||
|
||||
-- Remove all non-persistant condition functions.
|
||||
Phase.conditionOver:RemoveNonPersistant()
|
||||
|
||||
end
|
||||
|
||||
--- On after "BranchSwitch" event.
|
||||
-- @param #OPERATION self
|
||||
-- @param #string From From state.
|
||||
@ -1168,14 +1270,18 @@ function OPERATION:_CheckPhases()
|
||||
|
||||
-- Check if active phase is over if conditon over is defined.
|
||||
if phase and phase.conditionOver then
|
||||
|
||||
-- Evaluate if phase is over.
|
||||
local isOver=phase.conditionOver:Evaluate()
|
||||
|
||||
local Tnow=timer.getAbsTime()
|
||||
|
||||
-- Check if duration of phase if over.
|
||||
if phase.duration and phase.Tstart and Tnow-phase.Tstart>phase.duration then
|
||||
isOver=true
|
||||
end
|
||||
|
||||
-- Set phase status to over. This also triggers the PhaseOver() event.
|
||||
if isOver then
|
||||
self:SetPhaseStatus(phase, OPERATION.PhaseStatus.OVER)
|
||||
end
|
||||
@ -1187,6 +1293,11 @@ function OPERATION:_CheckPhases()
|
||||
for _,_edge in pairs(self.branchActive.edges) do
|
||||
local edge=_edge --#OPERATION.Edge
|
||||
|
||||
if phase then
|
||||
--env.info(string.format("phase active uid=%d", phase.uid))
|
||||
--env.info(string.format("Phase from uid=%d", edge.phaseFrom.uid))
|
||||
end
|
||||
|
||||
if (edge.phaseFrom==nil) or (phase and edge.phaseFrom.uid==phase.uid) then
|
||||
|
||||
-- Evaluate switch condition.
|
||||
@ -1197,37 +1308,25 @@ function OPERATION:_CheckPhases()
|
||||
-- Get next phase of the branch
|
||||
local phaseTo=edge.phaseTo or self:GetPhaseNext(edge.branchTo, nil)
|
||||
|
||||
if phaseTo then
|
||||
|
||||
if phaseTo then
|
||||
|
||||
-- Switch to new branch.
|
||||
self:BranchSwitch(edge.branchTo, phaseTo)
|
||||
|
||||
else
|
||||
|
||||
-- No next phase ==> Ops is over!
|
||||
self:Over()
|
||||
|
||||
end
|
||||
|
||||
-- Done here!
|
||||
return
|
||||
|
||||
-- -- If we want to switch to a specific phase of the branch.
|
||||
-- if edge.phaseTo then
|
||||
--
|
||||
-- -- Change phase.
|
||||
-- self:PhaseChange(edge.phaseTo)
|
||||
--
|
||||
-- -- Done here!
|
||||
-- return
|
||||
-- end
|
||||
--
|
||||
-- -- Break the loop.
|
||||
-- break
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- Next phase.
|
||||
self:PhaseNext()
|
||||
|
||||
@ -1248,7 +1347,9 @@ function OPERATION:_CreatePhase(Name)
|
||||
phase.uid=self.counterPhase
|
||||
phase.name=Name or string.format("Phase-%02d", self.counterPhase)
|
||||
phase.conditionOver=CONDITION:New(Name.." Over")
|
||||
phase.conditionOver:SetDefaultPersistence(false)
|
||||
phase.status=OPERATION.PhaseStatus.PLANNED
|
||||
phase.nActive=0
|
||||
|
||||
return phase
|
||||
end
|
||||
|
||||
@ -4043,11 +4043,16 @@ end
|
||||
-- @param #string To To state.
|
||||
-- @param Ops.OpsGroup#OPSGROUP.Task Task The task.
|
||||
function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
|
||||
self:T({Task})
|
||||
|
||||
-- Debug message.
|
||||
local text=string.format("Task %s ID=%d execute", tostring(Task.description), Task.id)
|
||||
|
||||
-- Debug info.
|
||||
self:T(self.lid..text)
|
||||
self:T({Task})
|
||||
|
||||
-- Debug info.
|
||||
self:T2({Task})
|
||||
|
||||
-- Cancel current task if there is any.
|
||||
if self.taskcurrent>0 then
|
||||
self:TaskCancel()
|
||||
@ -4070,7 +4075,7 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
|
||||
-- Get mission of this task (if any).
|
||||
local Mission=self:GetMissionByTaskID(self.taskcurrent)
|
||||
|
||||
|
||||
-- Update push DCS task.
|
||||
self:_UpdateTask(Task, Mission)
|
||||
|
||||
-- Set AUFTRAG status.
|
||||
@ -4080,7 +4085,7 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
|
||||
|
||||
end
|
||||
|
||||
--- Push task
|
||||
--- Push task.
|
||||
-- @param #OPSGROUP self
|
||||
-- @param Ops.OpsGroup#OPSGROUP.Task Task The task.
|
||||
function OPSGROUP:_UpdateTask(Task, Mission)
|
||||
@ -4218,6 +4223,14 @@ function OPSGROUP:_UpdateTask(Task, Mission)
|
||||
-- Check if ammo is full.
|
||||
|
||||
local rearmed=self:_CheckAmmoFull()
|
||||
|
||||
if rearmed then
|
||||
self:T2(self.lid.."Ammo already full ==> reaming task done!")
|
||||
self:TaskDone(Task)
|
||||
else
|
||||
self:T2(self.lid.."Ammo not full ==> Rearm()")
|
||||
self:Rearm()
|
||||
end
|
||||
|
||||
|
||||
elseif Task.dcstask.id==AUFTRAG.SpecialTask.ALERT5 then
|
||||
@ -6070,6 +6083,18 @@ function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint)
|
||||
-- Final zone reached ==> task done.
|
||||
self:TaskDone(task)
|
||||
|
||||
elseif task and task.dcstask.id==AUFTRAG.SpecialTask.REARMING then
|
||||
|
||||
---
|
||||
-- SPECIAL TASK: Rearming Mission
|
||||
---
|
||||
|
||||
-- Debug info.
|
||||
self:T(self.lid..string.format("FF Rearming Mission ==> Rearm()"))
|
||||
|
||||
-- Call rearm event.
|
||||
self:Rearm()
|
||||
|
||||
else
|
||||
|
||||
---
|
||||
@ -7361,8 +7386,10 @@ function OPSGROUP:CancelAllMissions()
|
||||
-- Cancel all missions.
|
||||
for _,_mission in pairs(self.missionqueue) do
|
||||
local mission=_mission --Ops.Auftrag#AUFTRAG
|
||||
self:T(self.lid.."Cancelling mission "..tostring(mission:GetName()))
|
||||
self:MissionCancel(mission)
|
||||
if mission:IsNotOver() then
|
||||
self:T(self.lid.."Cancelling mission "..tostring(mission:GetName()))
|
||||
self:MissionCancel(mission)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@ -10179,7 +10206,7 @@ function OPSGROUP:_CheckAmmoStatus()
|
||||
|
||||
-- Check if rearming is completed.
|
||||
if self:IsRearming() then
|
||||
if ammo.Total==self.ammo.Total then
|
||||
if ammo.Total>=self.ammo.Total then
|
||||
self:Rearmed()
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user