diff --git a/Moose Development/Moose/Core/Spawn.lua b/Moose Development/Moose/Core/Spawn.lua index 200d8a7a0..eecaca873 100644 --- a/Moose Development/Moose/Core/Spawn.lua +++ b/Moose Development/Moose/Core/Spawn.lua @@ -509,14 +509,17 @@ end -- @param #SPAWN self -- @param #string AirbaseName Name of the airbase. -- @param #number Takeoff (Optional) Takeoff type. Can be SPAWN.Takeoff.Hot (default), SPAWN.Takeoff.Cold or SPAWN.Takeoff.Runway. +-- @param #number TerminalTyple (Optional) The terminal type. -- @return #SPAWN self -function SPAWN:InitAirbase( AirbaseName, Takeoff ) +function SPAWN:InitAirbase( AirbaseName, Takeoff, TerminalType ) self:F( ) self.SpawnInitAirbase=AIRBASE:FindByName(AirbaseName) self.SpawnInitTakeoff=Takeoff or SPAWN.Takeoff.Hot + self.SpawnInitTerminalType=TerminalType + return self end @@ -1133,7 +1136,7 @@ function SPAWN:Spawn() self:F( { self.SpawnTemplatePrefix, self.SpawnIndex, self.AliveUnits } ) if self.SpawnInitAirbase then - return self:SpawnAtAirbase(self.SpawnInitAirbase, self.SpawnInitTakeoff) + return self:SpawnAtAirbase(self.SpawnInitAirbase, self.SpawnInitTakeoff, nil, self.SpawnInitTerminalType) else return self:SpawnWithIndex( self.SpawnIndex + 1 ) end diff --git a/Moose Development/Moose/Core/UserFlag.lua b/Moose Development/Moose/Core/UserFlag.lua index bef5cefff..30e0d99d9 100644 --- a/Moose Development/Moose/Core/UserFlag.lua +++ b/Moose Development/Moose/Core/UserFlag.lua @@ -19,6 +19,8 @@ do -- UserFlag --- @type USERFLAG + -- @field #string ClassName Name of the class + -- @field #string UserFlagName Name of the flag. -- @extends Core.Base#BASE @@ -30,7 +32,8 @@ do -- UserFlag -- -- @field #USERFLAG USERFLAG = { - ClassName = "USERFLAG", + ClassName = "USERFLAG", + UserFlagName = nil, } --- USERFLAG Constructor. @@ -46,6 +49,12 @@ do -- UserFlag return self end + --- Get the userflag name. + -- @param #USERFLAG self + -- @return #string Name of the user flag. + function USERFLAG:GetName() + return self.UserFlagName + end --- Set the userflag to a given Number. -- @param #USERFLAG self diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 747342506..28f9a5d1d 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -305,6 +305,7 @@ FLIGHTGROUP.TaskType={ -- @field #number duration Duration before task is cancelled in seconds. Default never. -- @field #number timestamp Abs. mission time, when task was started. -- @field #number waypoint Waypoint index if task is a waypoint task. +-- @field Core.UserFlag#USERFLAG stopflag If flag is set to 1 (=true), the task is stopped. --- FLIGHTGROUP class version. @@ -501,6 +502,14 @@ end -- User functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--- Add a *scheduled* task. +-- @param #FLIGHTGROUP self +-- @param #number id Task id. +-- @return #string Name of the stop flag +function FLIGHTGROUP:StopTaskFlagname(id) + return string.format("StopTaskFlag %d", id) +end + --- Add a *scheduled* task. -- @param #FLIGHTGROUP self -- @param #table task DCS task table structure. @@ -535,6 +544,9 @@ function FLIGHTGROUP:AddTask(task, clock, description, prio, duration) newtask.duration=duration newtask.waypoint=-1 newtask.type=FLIGHTGROUP.TaskType.SCHEDULED + newtask.stopflag=USERFLAG:New(self:StopTaskFlagname(newtask.id)) + newtask.stopflag:Set(0) + -- Info. self:I(self.lid..string.format("Adding task %s scheduled at %s", newtask.description, UTILS.SecondsToClock(time, true))) @@ -572,6 +584,8 @@ function FLIGHTGROUP:AddTaskWaypoint(task, waypointindex, description, prio, dur newtask.time=0 newtask.waypoint=waypointindex or (self.currentwp and self.currentwp+1 or 2) newtask.type=FLIGHTGROUP.TaskType.WAYPOINT + newtask.stopflag=USERFLAG:New(self:StopTaskFlagname(newtask.id)) + newtask.stopflag:Set(0) self:T2({newtask=newtask}) @@ -587,6 +601,27 @@ function FLIGHTGROUP:AddTaskWaypoint(task, waypointindex, description, prio, dur return self.taskcounter end +--- Add an *enroute* task. +-- @param #FLIGHTGROUP self +-- @param #table task DCS task table stucture. +function FLIGHTGROUP:AddTaskEnroute(task) + if not self.taskenroute then + self.taskenroute={} + end + table.insert(self.taskenroute, task) +end + +--- Add an *enroute* task to attack targets in a certain **cicular** zone. +-- @param #FLIGHTGROUP self +-- @param Core.Zone#ZONE_RADIUS ZoneRadius The circular zone, where to engage targets. +-- @param #table TargetTypes (Optional) The target types, passed as a table, i.e. mind the cirly brackets {}. +-- @param #number Priority (Optional) Priority. +function FLIGHTGROUP:AddTaskEnrouteEngageTargetsInZone(ZoneRadius, TargetTypes, Priority) + local Task=self.group:EnRouteTaskEngageTargetsInZone(ZoneRadius:GetVec2(), ZoneRadius:GetRadius(), TargetTypes, Priority) + self:AddTaskEnroute(Task) +end + + --- Remove task. -- @param #FLIGHTGROUP self -- @param #number taskid ID of the task to remove. @@ -1150,7 +1185,7 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To) if task.type==FLIGHTGROUP.TaskType.SCHEDULED then text=text..string.format("\n[%d] %s: %s: status=%s, scheduled=%s (%d sec), started=%s, duration=%d", i, taskid, name, status, clock, eta, started, duration) elseif task.type==FLIGHTGROUP.TaskType.WAYPOINT then - text=text..string.format("\n[%d] %s: %s: status=%s, waypoint=%d, started=%s, duration=%d", i, taskid, name, status, task.waypoint, started, duration) + text=text..string.format("\n[%d] %s: %s: status=%s, waypoint=%d, started=%s, duration=%d, stopflag=%d", i, taskid, name, status, task.waypoint, started, duration, task.stopflag:Get()) end end if #self.taskqueue>0 then @@ -2110,7 +2145,7 @@ function FLIGHTGROUP:onafterPassingWaypoint(From, Event, To, n, N) local tasks=self:GetTasksWaypoint(n) - local text=string.format("WP %d/N tasks:", n, N) + local text=string.format("WP %d/%d tasks:", n, N) if tasks then for i,_task in pairs(tasks) do local task=_task --#FLIGHTGROUP.Task @@ -2121,9 +2156,36 @@ function FLIGHTGROUP:onafterPassingWaypoint(From, Event, To, n, N) end self:I(self.lid..text) + + local taskswp={} + for _,task in pairs(tasks) do + local Task=task --#FLIGHTGROUP.Task + + -- Task execute. + table.insert(taskswp, self.group:TaskFunction("FLIGHTGROUP._TaskExecute", self, Task)) + + -- Stop condition if userflag is set to 1. + local TaskCondition=self.group:TaskCondition(nil, Task.stopflag:GetName(), 1, nil, Task.duration) + + -- Controlled task. + table.insert(taskswp, self.group:TaskControlled(Task.dcstask, TaskCondition)) + + --table.insert(taskswp, Task.dcstask) + + -- Task done. + table.insert(taskswp, self.group:TaskFunction("FLIGHTGROUP._TaskDone", self, Task)) + + end + + -- At the final AIR waypoint, we set the flight to hold. if self.destbase and n>1 and n==N-1 then self:__Hold(-1, self.destbase) + else + -- Waypoint task combo. + if #taskswp>0 then + self.group:SetTask(self.group:TaskCombo(taskswp)) + end end end @@ -2414,6 +2476,15 @@ function FLIGHTGROUP:onafterLandAt(From, Event, To, Coordinate, Duration) -- Add task with high priority. self:AddTask(task, 1, "Task_Land_At", 0) +end + +--- Create a DCS task sandwitch. +-- @param #FLIGHTGROUP self +-- @param #FLIGHTGROUP.Task Task The task. +-- @param #table DCS task sandwitch +function FLIGHTGROUP:_GetTaskSandwitch(Task) + + end --- On after TaskExecute event. @@ -2444,13 +2515,11 @@ function FLIGHTGROUP:onafterTaskExecute(From, Event, To, Task) Task.status=FLIGHTGROUP.TaskStatus.EXECUTING -- If task is scheduled (not waypoint) set task. - if Task.type==FLIGHTGROUP.TaskType.SCHEDULED or true then + if Task.type==FLIGHTGROUP.TaskType.SCHEDULED then -- Clear all tasks. --self.group:ClearTasks() - -- Task done. - local TaskDone=self.group:TaskFunction("FLIGHTGROUP._TaskDone", self, Task) local DCStasks={} if Task.dcstask.id=='ComboTask' then @@ -2461,16 +2530,31 @@ function FLIGHTGROUP:onafterTaskExecute(From, Event, To, Task) else table.insert(DCStasks, Task.dcstask) end + + -- Task done. + local TaskDone=self.group:TaskFunction("FLIGHTGROUP._TaskDone", self, Task) table.insert(DCStasks, TaskDone) - + + env.info("FF DCS task combo") + for i,DCStask in pairs(DCStasks) do + self:I{{DCStask=DCStask}} + end + -- Combo task. local TaskCombo=self.group:TaskCombo(DCStasks) + + + -- Stop condition! + local TaskCondition=self.group:TaskCondition(nil, Task.stopflag:GetName(), 1) - env.info("FF executing Taskcombo:") - self:I({task=TaskCombo}) + -- Controlled task. + local TaskControlled=self.group:TaskControlled(TaskCombo, TaskCondition) + + env.info("FF executing controlled Task:") + self:I({task=TaskControlled}) -- Set task for group. - self.group:SetTask(TaskCombo, 1) + self.group:SetTask(TaskControlled, 1) end @@ -2512,7 +2596,9 @@ function FLIGHTGROUP:onafterTaskCancel(From, Event, To) MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug) self:I(self.lid..text) -- Clear tasks. - self.group:ClearTasks() + --self.group:ClearTasks() + --self.group:PopCurrentTask() + task.stopflag:Set(1) self:TaskDone(task) else local text=string.format("WARNING: No current task to cancel!") @@ -2702,8 +2788,8 @@ end function FLIGHTGROUP._TaskExecute(group, flightgroup, task) -- Debug message. - local text=string.format("Task Execute %s", task.description) - flightgroup:T2(flightgroup.lid..text) + local text=string.format("_TaskExecute %s", task.description) + flightgroup:I(flightgroup.lid..text) -- Set current task to nil so that the next in line can be executed. if flightgroup then @@ -2719,8 +2805,8 @@ end function FLIGHTGROUP._TaskDone(group, flightgroup, task) -- Debug message. - local text=string.format("Task Done %s", task.description) - flightgroup:T2(flightgroup.lid..text) + local text=string.format("_TaskDone %s", task.description) + flightgroup:I(flightgroup.lid..text) -- Set current task to nil so that the next in line can be executed. if flightgroup then @@ -2738,6 +2824,7 @@ function FLIGHTGROUP._PassingWaypoint(group, flightgroup, i) -- Debug message. local text=string.format("Group %s passing waypoint %d of %d.", group:GetName(), i, final) + env.info(text) -- Debug smoke and marker. if flightgroup.Debug then @@ -3269,27 +3356,51 @@ function FLIGHTGROUP:_UpdateWaypointTasks() -- Tasks of this waypoint local taskswp={} + + if self.taskenroute then + table.insert(taskswp, self.taskenroute[1]) + end -- At each waypoint report passing. local TaskPassingWaypoint=self.group:TaskFunction("FLIGHTGROUP._PassingWaypoint", self, i) table.insert(taskswp, TaskPassingWaypoint) + + -- For some reason THIS DOES NOT WORK if executed at the last waypoint if it is an AIR WAYPOINT. + -- I have moved it to the onafterpassingwaypoint function instead. + + --[[ + -- Get taks local tasks=self:GetTasksWaypoint(i) for _,task in pairs(tasks) do local Task=task --#FLIGHTGROUP.Task - -- Add task execute. + -- Task execute. table.insert(taskswp, self.group:TaskFunction("FLIGHTGROUP._TaskExecute", self, Task)) + + -- Stop condition if userflag is set to 1. + local TaskCondition=self.group:TaskCondition(nil, Task.stopflag:GetName(), 1, nil, Task.duration) + + -- Controlled task. + table.insert(taskswp, self.group:TaskControlled(Task.dcstask, TaskCondition)) + + --table.insert(taskswp, Task.dcstask) + + -- Task done. + table.insert(taskswp, self.group:TaskFunction("FLIGHTGROUP._TaskDone", self, Task)) end + + ]] -- Waypoint task combo. wp.task=self.group:TaskCombo(taskswp) -- Debug info. - self:T3({wptask=taskswp}) + env.info("FF task waypoint combo:") + self:I({wptask=taskswp}) end end diff --git a/Moose Development/Moose/Ops/TankerGroup.lua b/Moose Development/Moose/Ops/TankerGroup.lua index 1baa16203..7dc111c7b 100644 --- a/Moose Development/Moose/Ops/TankerGroup.lua +++ b/Moose Development/Moose/Ops/TankerGroup.lua @@ -75,12 +75,20 @@ TANKERGROUP = { -- @field #number Tstop Time the mission is stopped. -- @field #number Tsopped Time the mission was stopped. +--- Mission status. +-- @type TANKERGROUP.MissionStatus +-- @field #string SCHEDULED Task is scheduled. +-- @field #string EXECUTING Task is being executed. +-- @field #string ACCOMPLISHED Task is accomplished. +TANKERGROUP.MissionStatus={ + SCHEDULED="scheduled", + EXECUTING="executing", + ACCOMPLISHED="accomplished", +} --- TANKERGROUP class version. -- @field #string version TANKERGROUP.version="0.0.1" -_TANKERGROUPS={} - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -118,20 +126,17 @@ function TANKERGROUP:New(groupname) -- Add FSM transitions. -- From State --> Event --> To State - --self:AddTransition("*", "TankerState", "*") -- Tanker is on station and ready to refuel. + self:AddTransition("*", "TankerState", "*") -- Tanker is on station and ready to refuel. self:AddTransition("*", "OnStation", "Ready2Refuel") -- Tanker is on station and ready to refuel. self:AddTransition("*", "MissionStart", "*") -- Tanker is on station and ready to refuel. -- Scheduler to update the status. - self.Statusupdater=SCHEDULER:New(self, TANKERGROUP.TankerState, {self}, 1, 5) + --self.Statusupdater=SCHEDULER:New(self, TANKERGROUP.TankerState, {self}, 1, 5) -- Call status update. -- TODO: WARNING, if the call is delayed, it is NOT executed! - --self:__TankerState(5) - - --_TANKERGROUPS[groupname]=self - --table.insert(_TANKERGROUPS, self) + self:__TankerState(-5) self:Start() @@ -189,6 +194,9 @@ function TANKERGROUP:AddMission(Zone, Altitude, Distance, Heading, SpeedOrbit, C mission.Tadded=Tnow mission.Tstart=Tstart mission.Tstop=Tstop + if Tstop then + mission.duration=mission.Tstop-mission.Tstart + end mission.tid=nil -- Add mission to queue. @@ -211,7 +219,7 @@ end -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -function TANKERGROUP:TankerState(From, Event, To) +function TANKERGROUP:onafterTankerState(From, Event, To) -- First call flight status. --self:GetParent(self).onafterFlightStatus(self, From, Event, To) @@ -240,7 +248,7 @@ function TANKERGROUP:TankerState(From, Event, To) self:I(self.lid..text) -- Nest status update in 30 sec. - --self:__TankerState(0.5) + self:__TankerState(-30) end --- On after "MissionStart" event. @@ -275,6 +283,9 @@ function TANKERGROUP:onafterMissionStart(From, Event, To, Mission) -- Set current mission. self.currentmission=Mission + + -- Set Tstarted time stamp. + self.currentmission.Tstarted=timer.getAbsTime() -- Route flight to mission zone. self:RouteToMission(Mission, delay)