From 2aecf45316e2bb26096a6e6d0e1dbf853884433e Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Tue, 8 Aug 2017 09:42:42 +0200 Subject: [PATCH] Many Fixes --- Moose Development/Moose/AI/AI_A2A.lua | 35 ++-- Moose Development/Moose/AI/AI_A2A_Cap.lua | 13 +- .../Moose/AI/AI_A2A_Dispatcher.lua | 4 +- Moose Development/Moose/AI/AI_A2A_Gci.lua | 10 +- Moose Development/Moose/AI/AI_A2A_Patrol.lua | 9 +- .../Moose/Core/ScheduleDispatcher.lua | 6 +- Moose Development/Moose/Functional/Escort.lua | 2 +- .../Moose/Wrapper/Controllable.lua | 170 +++++++++++++---- Moose Development/Moose/Wrapper/Group.lua | 26 +++ .../Moose/Wrapper/Positionable.lua | 2 +- Moose Development/Moose/Wrapper/Unit.lua | 4 +- docs/Documentation/AI_A2A.html | 33 +++- docs/Documentation/AI_A2A_Cap.html | 11 +- docs/Documentation/AI_A2A_GCI.html | 9 +- docs/Documentation/AI_A2A_Patrol.html | 11 +- docs/Documentation/Cargo.html | 2 - docs/Documentation/Controllable.html | 177 ++++++++++++++++-- docs/Documentation/Designate.html | 1 + docs/Documentation/Fsm.html | 3 +- docs/Documentation/Group.html | 37 ++++ docs/Documentation/Movement.html | 4 - docs/Documentation/Positionable.html | 1 + docs/Documentation/Spawn.html | 10 +- docs/Documentation/Spot.html | 4 + docs/Documentation/Task_Cargo.html | 5 +- docs/Documentation/Unit.html | 4 +- 26 files changed, 455 insertions(+), 138 deletions(-) diff --git a/Moose Development/Moose/AI/AI_A2A.lua b/Moose Development/Moose/AI/AI_A2A.lua index ad72d92f6..dce4c1431 100644 --- a/Moose Development/Moose/AI/AI_A2A.lua +++ b/Moose Development/Moose/AI/AI_A2A.lua @@ -448,8 +448,7 @@ function AI_A2A:onafterStatus() end - - local Fuel = self.Controllable:GetUnit(1):GetFuel() + local Fuel = self.Controllable:GetFuel() self:F({Fuel=Fuel}) if Fuel < self.PatrolFuelThresholdPercentage then if self.TankerName then @@ -510,27 +509,23 @@ end --- @param Wrapper.Group#GROUP AIGroup -function AI_A2A.RTBRoute( AIGroup ) +function AI_A2A.RTBRoute( AIGroup, Fsm ) AIGroup:F( { "AI_A2A.RTBRoute:", AIGroup:GetName() } ) if AIGroup:IsAlive() then - local _AI_A2A = AIGroup:GetState( AIGroup, "AI_A2A" ) -- #AI_A2A - _AI_A2A:__RTB( 0.5 ) - local Task = AIGroup:TaskOrbitCircle( 4000, 400 ) - AIGroup:SetTask( Task ) + Fsm:__RTB( 0.5 ) end end --- @param Wrapper.Group#GROUP AIGroup -function AI_A2A.RTBHold( AIGroup ) +function AI_A2A.RTBHold( AIGroup, Fsm ) AIGroup:F( { "AI_A2A.RTBHold:", AIGroup:GetName() } ) if AIGroup:IsAlive() then - local _AI_A2A = AIGroup:GetState( AIGroup, "AI_A2A" ) -- #AI_A2A - _AI_A2A:__RTB( 0.5 ) - _AI_A2A:Return() + Fsm:__RTB( 0.5 ) + Fsm:Return() local Task = AIGroup:TaskOrbitCircle( 4000, 400 ) AIGroup:SetTask( Task ) end @@ -590,11 +585,11 @@ function AI_A2A:onafterRTB( AIGroup, From, Event, To ) AIGroup:WayPointInitialize( EngageRoute ) local Tasks = {} - Tasks[#Tasks+1] = AIGroup:TaskFunction( 1, 1, "AI_A2A.RTBRoute" ) + Tasks[#Tasks+1] = AIGroup:TaskFunction( "AI_A2A.RTBRoute", self ) Tasks[#Tasks+1] = AIGroup:TaskOrbitCircle( 4000, 350 ) EngageRoute[#EngageRoute].task = AIGroup:TaskCombo( Tasks ) - AIGroup:SetState( AIGroup, "AI_A2A", self ) + --AIGroup:SetState( AIGroup, "AI_A2A", self ) --- NOW ROUTE THE GROUP! AIGroup:SetTask( AIGroup:TaskRoute( EngageRoute ), 1 ) @@ -628,11 +623,11 @@ function AI_A2A:onafterHold( AIGroup, From, Event, To, HoldTime ) local OrbitTask = AIGroup:TaskOrbitCircle( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ), self.PatrolMinSpeed ) local TimedOrbitTask = AIGroup:TaskControlled( OrbitTask, AIGroup:TaskCondition( nil, nil, nil, nil, HoldTime , nil ) ) - local RTBTask = AIGroup:TaskFunction( 1, 1, "AI_A2A.RTBHold" ) + local RTBTask = AIGroup:TaskFunction( "AI_A2A.RTBHold", self ) local OrbitHoldTask = AIGroup:TaskOrbitCircle( 4000, self.PatrolMinSpeed ) - AIGroup:SetState( AIGroup, "AI_A2A", self ) + --AIGroup:SetState( AIGroup, "AI_A2A", self ) AIGroup:SetTask( AIGroup:TaskCombo( { TimedOrbitTask, RTBTask, OrbitHoldTask } ), 0 ) end @@ -640,13 +635,11 @@ function AI_A2A:onafterHold( AIGroup, From, Event, To, HoldTime ) end --- @param Wrapper.Group#GROUP AIGroup -function AI_A2A.Resume( AIGroup ) +function AI_A2A.Resume( AIGroup, Fsm ) AIGroup:F( { "AI_A2A.Resume:", AIGroup:GetName() } ) if AIGroup:IsAlive() then - local _AI_A2A = AIGroup:GetState( AIGroup, "AI_A2A" ) -- #AI_A2A - _AI_A2A:__RTB( 0.5 ) - --_AI_A2A:Retur() + Fsm:__RTB( 0.5 ) end end @@ -689,9 +682,9 @@ function AI_A2A:onafterRefuel( AIGroup, From, Event, To ) local Tasks = {} Tasks[#Tasks+1] = AIGroup:TaskRefueling() - Tasks[#Tasks+1] = AIGroup:TaskFunction( 1, 1, self:GetClassName() .. ".Resume" ) + Tasks[#Tasks+1] = AIGroup:TaskFunction( self:GetClassName() .. ".Resume", self ) RefuelRoute[#RefuelRoute].task = AIGroup:TaskCombo( Tasks ) - AIGroup:SetState( AIGroup, "AI_A2A", self ) + --AIGroup:SetState( AIGroup, "AI_A2A", self ) --- NOW ROUTE THE GROUP! AIGroup:SetTask( AIGroup:TaskRoute( RefuelRoute ), 1 ) diff --git a/Moose Development/Moose/AI/AI_A2A_Cap.lua b/Moose Development/Moose/AI/AI_A2A_Cap.lua index 3be0ffc31..6f43824a2 100644 --- a/Moose Development/Moose/AI/AI_A2A_Cap.lua +++ b/Moose Development/Moose/AI/AI_A2A_Cap.lua @@ -348,16 +348,12 @@ end -- todo: need to fix this global function --- @param Wrapper.Group#GROUP AIGroup -function AI_A2A_CAP.AttackRoute( AIGroup ) +function AI_A2A_CAP.AttackRoute( AIGroup, Fsm ) AIGroup:F( { "AI_A2A_CAP.AttackRoute:", AIGroup:GetName() } ) if AIGroup:IsAlive() then - local _AI_A2A_CAP = AIGroup:GetState( AIGroup, "AI_A2A_CAP" ) -- AI.AI_Cap#AI_A2A_CAP - _AI_A2A_CAP:__Engage( 0.5 ) - - --local Task = AIGroup:TaskOrbitCircle( 4000, 400 ) - --AIGroup:SetTask( Task ) + Fsm:__Engage( 0.5 ) end end @@ -441,13 +437,12 @@ function AI_A2A_CAP:onafterEngage( AIGroup, From, Event, To, AttackSetUnit ) AIGroup:OptionROEOpenFire() AIGroup:OptionROTPassiveDefense() - AttackTasks[#AttackTasks+1] = AIGroup:TaskFunction( 1, 1, "AI_A2A_CAP.AttackRoute" ) - --AttackTasks[#AttackTasks+1] = AIGroup:TaskOrbitCircle( AIGroup:GetHeight(), self.PatrolMinSpeed ) + AttackTasks[#AttackTasks+1] = AIGroup:TaskFunction( "AI_A2A_CAP.AttackRoute", self ) EngageRoute[1].task = AIGroup:TaskCombo( AttackTasks ) --- Do a trick, link the NewEngageRoute function of the object to the AIControllable in a temporary variable ... - AIGroup:SetState( AIGroup, "AI_A2A_CAP", self ) + --AIGroup:SetState( AIGroup, "AI_A2A_CAP", self ) end --- NOW ROUTE THE GROUP! diff --git a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua index b6a3fa3e0..843d9ad5d 100644 --- a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua @@ -2921,7 +2921,7 @@ do -- AI_A2A_DISPATCHER for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do local Defender = Defender -- Wrapper.Group#GROUP if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then - local Fuel = Defender:GetUnit(1):GetFuel() * 100 + local Fuel = Defender:GetFuel() * 100 local Damage = Defender:GetLife() / Defender:GetLife0() * 100 Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s", Defender:GetName(), @@ -2944,7 +2944,7 @@ do -- AI_A2A_DISPATCHER local Defender = Defender -- Wrapper.Group#GROUP if not DefenderTask.Target then local DefenderHasTask = Defender:HasTask() - local Fuel = Defender:GetUnit(1):GetFuel() * 100 + local Fuel = Defender:GetFuel() * 100 local Damage = Defender:GetLife() / Defender:GetLife0() * 100 Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s", Defender:GetName(), diff --git a/Moose Development/Moose/AI/AI_A2A_Gci.lua b/Moose Development/Moose/AI/AI_A2A_Gci.lua index 46be6c667..990f73181 100644 --- a/Moose Development/Moose/AI/AI_A2A_Gci.lua +++ b/Moose Development/Moose/AI/AI_A2A_Gci.lua @@ -311,13 +311,12 @@ end -- todo: need to fix this global function --- @param Wrapper.Group#GROUP AIControllable -function AI_A2A_GCI.InterceptRoute( AIGroup ) +function AI_A2A_GCI.InterceptRoute( AIGroup, Fsm ) AIGroup:F( { "AI_A2A_GCI.InterceptRoute:", AIGroup:GetName() } ) if AIGroup:IsAlive() then - local _AI_A2A_GCI = AIGroup:GetState( AIGroup, "AI_A2A_GCI" ) -- AI.AI_Cap#AI_A2A_GCI - _AI_A2A_GCI:__Engage( 0.5 ) + Fsm:__Engage( 0.5 ) --local Task = AIGroup:TaskOrbitCircle( 4000, 400 ) --AIGroup:SetTask( Task ) @@ -417,12 +416,11 @@ function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To, AttackSetUnit ) AIGroup:OptionROEOpenFire() AIGroup:OptionROTPassiveDefense() - AttackTasks[#AttackTasks+1] = AIGroup:TaskFunction( 1, 1, "AI_A2A_GCI.InterceptRoute" ) - --AttackTasks[#AttackTasks+1] = AIGroup:TaskOrbitCircle( AIGroup:GetHeight(), self.EngageMinSpeed ) + AttackTasks[#AttackTasks+1] = AIGroup:TaskFunction( "AI_A2A_GCI.InterceptRoute", self ) EngageRoute[#EngageRoute].task = AIGroup:TaskCombo( AttackTasks ) --- Do a trick, link the NewEngageRoute function of the object to the AIControllable in a temporary variable ... - AIGroup:SetState( AIGroup, "AI_A2A_GCI", self ) + --AIGroup:SetState( AIGroup, "AI_A2A_GCI", self ) end --- NOW ROUTE THE GROUP! diff --git a/Moose Development/Moose/AI/AI_A2A_Patrol.lua b/Moose Development/Moose/AI/AI_A2A_Patrol.lua index a2d682f86..d06ec5eb8 100644 --- a/Moose Development/Moose/AI/AI_A2A_Patrol.lua +++ b/Moose Development/Moose/AI/AI_A2A_Patrol.lua @@ -317,13 +317,12 @@ end --- @param Wrapper.Group#GROUP AIGroup -- This statis method is called from the route path within the last task at the last waaypoint of the Controllable. -- Note that this method is required, as triggers the next route when patrolling for the Controllable. -function AI_A2A_PATROL.PatrolRoute( AIGroup ) +function AI_A2A_PATROL.PatrolRoute( AIGroup, Fsm ) AIGroup:F( { "AI_A2A_PATROL.PatrolRoute:", AIGroup:GetName() } ) if AIGroup:IsAlive() then - local _AI_A2A_Patrol = AIGroup:GetState( AIGroup, "AI_A2A_PATROL" ) -- #AI_A2A_PATROL - _AI_A2A_Patrol:Route() + Fsm:Route() end end @@ -372,12 +371,12 @@ function AI_A2A_PATROL:onafterRoute( AIGroup, From, Event, To ) PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint local Tasks = {} - Tasks[#Tasks+1] = AIGroup:TaskFunction( 1, 1, "AI_A2A_PATROL.PatrolRoute" ) + Tasks[#Tasks+1] = AIGroup:TaskFunction( "AI_A2A_PATROL.PatrolRoute", self ) PatrolRoute[#PatrolRoute].task = AIGroup:TaskCombo( Tasks ) --- Do a trick, link the NewPatrolRoute function of the PATROLGROUP object to the AIControllable in a temporary variable ... - AIGroup:SetState( AIGroup, "AI_A2A_PATROL", self ) + --AIGroup:SetState( AIGroup, "AI_A2A_PATROL", self ) AIGroup:OptionROEReturnFire() AIGroup:OptionROTPassiveDefense() diff --git a/Moose Development/Moose/Core/ScheduleDispatcher.lua b/Moose Development/Moose/Core/ScheduleDispatcher.lua index 9c2da0edc..204c5fee0 100644 --- a/Moose Development/Moose/Core/ScheduleDispatcher.lua +++ b/Moose Development/Moose/Core/ScheduleDispatcher.lua @@ -100,11 +100,12 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr if not Scheduler then Scheduler = self.PersistentSchedulers[CallID] end - + --self:T3( { Scheduler = Scheduler } ) if Scheduler then + local MasterObject = tostring(Scheduler.MasterObject) local Schedule = self.Schedule[Scheduler][CallID] --self:T3( { Schedule = Schedule } ) @@ -134,6 +135,9 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr local CurrentTime = timer.getTime() local StartTime = Schedule.StartTime + + self:F3( { Master = MasterObject, CurrentTime = CurrentTime, StartTime = StartTime, Start = Start, Repeat = Repeat, Randomize = Randomize, Stop = Stop } ) + if Status and (( Result == nil ) or ( Result and Result ~= false ) ) then if Repeat ~= 0 and ( ( Stop == 0 ) or ( Stop ~= 0 and CurrentTime <= StartTime + Stop ) ) then diff --git a/Moose Development/Moose/Functional/Escort.lua b/Moose Development/Moose/Functional/Escort.lua index e436d4032..4540156db 100644 --- a/Moose Development/Moose/Functional/Escort.lua +++ b/Moose Development/Moose/Functional/Escort.lua @@ -875,7 +875,7 @@ function ESCORT:_AttackTarget( DetectedItemID ) end, Tasks ) - Tasks[#Tasks+1] = EscortGroup:TaskFunction( 1, 2, "_Resume", { "''" } ) + Tasks[#Tasks+1] = EscortGroup:TaskFunction( "_Resume", { "''" } ) EscortGroup:SetTask( EscortGroup:TaskCombo( diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 3baff32e2..3e9feb5b3 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -95,6 +95,22 @@ -- * @{#CONTROLLABLE.TaskCondition}: Return a condition section for a controlled task. -- * @{#CONTROLLABLE.TaskControlled}: Return a Controlled Task taking a Task and a TaskCondition. -- +-- ### Call a function as a Task +-- +-- A function can be called which is part of a Task. The method @{#CONTROLLABLE.TaskFunction}() prepares +-- a Task that can call a GLOBAL function from within the Controller execution. +-- This method can also be used to **embed a function call when a certain waypoint has been reached**. +-- See below the **Tasks at Waypoints** section. +-- +-- Demonstration Mission: [GRP-502 - Route at waypoint to random point](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/release-2-2-pre/GRP - Group Commands/GRP-502 - Route at waypoint to random point) +-- +-- ### Tasks at Waypoints +-- +-- Special Task methods are available to set tasks at certain waypoints. +-- The method @{#CONTROLLABLE.SetTaskAtWaypoint}() helps preparing a Route, embedding a Task at the Waypoint of the Route. +-- +-- This creates a Task element, with an action to call a function as part of a Wrapped Task. +-- -- ### Obtain the mission from controllable templates -- -- Controllable templates contain complete mission descriptions. Sometimes you want to copy a complete mission from a controllable and assign it to another: @@ -257,6 +273,16 @@ function CONTROLLABLE:GetLife0() return nil end +--- Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks. +-- This method returns nil to ensure polymorphic behaviour! This method needs to be overridden by GROUP or UNIT. +-- @param #CONTROLLABLE self +-- @return #nil The CONTROLLABLE is not existing or alive. +function CONTROLLABLE:GetFuel() + self:F( self.ControllableName ) + + return nil +end + @@ -449,11 +475,11 @@ function CONTROLLABLE:TaskWrappedAction( DCSCommand, Index ) self:F2( { DCSCommand } ) local DCSTaskWrappedAction - + DCSTaskWrappedAction = { id = "WrappedAction", enabled = true, - number = Index, + number = Index or 1, auto = false, params = { action = DCSCommand, @@ -464,6 +490,23 @@ function CONTROLLABLE:TaskWrappedAction( DCSCommand, Index ) return DCSTaskWrappedAction end +--- Set a Task at a Waypoint using a Route list. +-- @param #CONTROLLABLE self +-- @param Wrapper.Controllable#CONTROLLABLE.RouteList RouteList A list of Waypoints. +-- @param #number WaypointNumber The number of the Waypoint. The first Waypoint starts at 1! +-- @param Dcs.DCSTasking.Task#Task Task The Task structure to be executed! +-- @return Dcs.DCSTasking.Task#Task +function CONTROLLABLE:SetTaskAtWaypoint( RouteList, WaypointNumber, Task ) + + RouteList[ WaypointNumber ].task = self:TaskCombo( { Task } ) + + self:T3( { RouteList[ WaypointNumber ].task } ) + return RouteList[ WaypointNumber ].task +end + + + + --- Executes a command action -- @param #CONTROLLABLE self -- @param Dcs.DCSCommand#Command DCSCommand @@ -1480,6 +1523,84 @@ function CONTROLLABLE:TaskEmbarkToTransport( Point, Radius ) return DCSTask end +--- This creates a Task element, with an action to call a function as part of a Wrapped Task. +-- This Task can then be embedded at a Waypoint by calling the method @{#CONTROLLABLE.SetTaskAtWaypoint}. +-- @param #CONTROLLABLE self +-- @param #string FunctionString The function name embedded as a string that will be called. +-- @param ... The variable arguments passed to the function when called! These arguments can be of any type! +-- @return #CONTROLLABLE +-- @usage +-- +-- local ZoneList = { +-- ZONE:New( "ZONE1" ), +-- ZONE:New( "ZONE2" ), +-- ZONE:New( "ZONE3" ), +-- ZONE:New( "ZONE4" ), +-- ZONE:New( "ZONE5" ) +-- } +-- +-- GroundGroup = GROUP:FindByName( "Vehicle" ) +-- +-- --- @param Wrapper.Group#GROUP GroundGroup +-- function RouteToZone( Vehicle, ZoneRoute ) +-- +-- local Route = {} +-- +-- Vehicle:E( { ZoneRoute = ZoneRoute } ) +-- +-- Vehicle:MessageToAll( "Moving to zone " .. ZoneRoute:GetName(), 10 ) +-- +-- -- Get the current coordinate of the Vehicle +-- local FromCoord = Vehicle:GetCoordinate() +-- +-- -- Select a random Zone and get the Coordinate of the new Zone. +-- local RandomZone = ZoneList[ math.random( 1, #ZoneList ) ] -- Core.Zone#ZONE +-- local ToCoord = RandomZone:GetCoordinate() +-- +-- -- Create a "ground route point", which is a "point" structure that can be given as a parameter to a Task +-- Route[#Route+1] = FromCoord:RoutePointGround( 72 ) +-- Route[#Route+1] = ToCoord:RoutePointGround( 60, "Vee" ) +-- +-- local TaskRouteToZone = Vehicle:TaskFunction( "RouteToZone", RandomZone ) +-- +-- Vehicle:SetTaskAtWaypoint( Route, #Route, TaskRouteToZone ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone. +-- +-- Vehicle:Route( Route, math.random( 10, 20 ) ) -- Move after a random seconds to the Route. See the Route method for details. +-- +-- end +-- +-- RouteToZone( GroundGroup, ZoneList[1] ) +-- +function CONTROLLABLE:TaskFunction( FunctionString, ... ) + self:F2( { FunctionString, arg } ) + + local DCSTask + + local DCSScript = {} + DCSScript[#DCSScript+1] = "local MissionControllable = GROUP:Find( ... ) " + + if arg and arg.n > 0 then + local ArgumentKey = tostring( arg ) + self:SetState( self, ArgumentKey, arg ) + DCSScript[#DCSScript+1] = "local Arguments = MissionControllable:GetState( MissionControllable, '" .. ArgumentKey .. "' ) " + DCSScript[#DCSScript+1] = "MissionControllable:ClearState( MissionControllable, '" .. ArgumentKey .. "' ) " + DCSScript[#DCSScript+1] = FunctionString .. "( MissionControllable, unpack( Arguments ) )" + else + DCSScript[#DCSScript+1] = FunctionString .. "( MissionControllable )" + end + + DCSTask = self:TaskWrappedAction( + self:CommandDoScript( + table.concat( DCSScript ) + ) + ) + + self:T( DCSTask ) + + return DCSTask + +end + --- (AIR + GROUND) Return a mission task from a mission template. @@ -1620,19 +1741,16 @@ end --- Make the controllable to follow a given route. -- @param #CONTROLLABLE self --- @param #table GoPoints A table of Route Points. --- @return #CONTROLLABLE self -function CONTROLLABLE:Route( GoPoints ) - self:F2( GoPoints ) +-- @param #table Route A table of Route Points. +-- @param #number DelaySeconds Wait for the specified seconds before executing the Route. +-- @return #CONTROLLABLE The CONTROLLABLE. +function CONTROLLABLE:Route( Route, DelaySeconds ) + self:F2( Route ) local DCSControllable = self:GetDCSObject() - if DCSControllable then - local Points = routines.utils.deepCopy( GoPoints ) - local MissionTask = { id = 'Mission', params = { route = { points = Points, }, }, } - local Controller = self:_GetController() - --Controller.setTask( Controller, MissionTask ) - self.TaskScheduler:Schedule( Controller, Controller.setTask, { MissionTask }, 1 ) + local RouteTask = self:TaskRoute( Route ) -- Create a RouteTask, that will route the CONTROLLABLE to the Route. + self:SetTask( RouteTask, DelaySeconds or 1 ) -- Execute the RouteTask after the specified seconds (default is 1). return self end @@ -2321,37 +2439,11 @@ function CONTROLLABLE:WayPointFunction( WayPoint, WayPointIndex, WayPointFunctio self:F2( { WayPoint, WayPointIndex, WayPointFunction } ) table.insert( self.WayPoints[WayPoint].task.params.tasks, WayPointIndex ) - self.WayPoints[WayPoint].task.params.tasks[WayPointIndex] = self:TaskFunction( WayPoint, WayPointIndex, WayPointFunction, arg ) + self.WayPoints[WayPoint].task.params.tasks[WayPointIndex] = self:TaskFunction( WayPointFunction, arg ) return self end -function CONTROLLABLE:TaskFunction( WayPoint, WayPointIndex, FunctionString, FunctionArguments ) - self:F2( { WayPoint, WayPointIndex, FunctionString, FunctionArguments } ) - - local DCSTask - - local DCSScript = {} - DCSScript[#DCSScript+1] = "local MissionControllable = GROUP:Find( ... ) " - - if FunctionArguments and #FunctionArguments > 0 then - DCSScript[#DCSScript+1] = FunctionString .. "( MissionControllable, " .. table.concat( FunctionArguments, "," ) .. ")" - else - DCSScript[#DCSScript+1] = FunctionString .. "( MissionControllable )" - end - - DCSTask = self:TaskWrappedAction( - self:CommandDoScript( - table.concat( DCSScript ) - ), WayPointIndex - ) - - self:T( DCSTask ) - - return DCSTask - -end - --- Executes the WayPoint plan. -- The function gets a WayPoint parameter, that you can use to restart the mission at a specific WayPoint. -- Note that when the WayPoint parameter is used, the new start mission waypoint of the controllable will be 1! diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 5879bd2af..39b1c8dcf 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -565,6 +565,32 @@ function GROUP:GetHeading() end +--- Returns relative amount of fuel (from 0.0 to 1.0) the group has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0. +-- @param #GROUP self +-- @return #number The relative amount of fuel (from 0.0 to 1.0). +-- @return #nil The GROUP is not existing or alive. +function GROUP:GetFuel() + self:F( self.ControllableName ) + + local DCSControllable = self:GetDCSObject() + + if DCSControllable then + local GroupSize = self:GetSize() + local TotalFuel = 0 + for UnitID, UnitData in pairs( self:GetUnits() ) do + local Unit = UnitData -- Wrapper.Unit#UNIT + local UnitFuel = Unit:GetFuel() + self:F( { Fuel = UnitFuel } ) + TotalFuel = TotalFuel + UnitFuel + end + local GroupFuel = TotalFuel / GroupSize + return GroupFuel + end + + return 0 +end + + do -- Is Zone methods --- Returns true if all units of the group are within a @{Zone}. diff --git a/Moose Development/Moose/Wrapper/Positionable.lua b/Moose Development/Moose/Wrapper/Positionable.lua index 0cdf5c7e8..a316366dc 100644 --- a/Moose Development/Moose/Wrapper/Positionable.lua +++ b/Moose Development/Moose/Wrapper/Positionable.lua @@ -14,7 +14,7 @@ -- @extends Wrapper.Identifiable#IDENTIFIABLE --- @type POSITIONABLE --- @extends POSITIONABLE.__ +-- @extends Wrapper.Identifiable#IDENTIFIABLE --- # POSITIONABLE class, extends @{Identifiable#IDENTIFIABLE} diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index d30758c54..7f9a34ed2 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -486,12 +486,12 @@ function UNIT:GetRadar() return nil, nil end ---- Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0. +--- Returns relative amount of fuel (from 0.0 to 1.0) the UNIT has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0. -- @param #UNIT self -- @return #number The relative amount of fuel (from 0.0 to 1.0). -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetFuel() - self:F2( self.UnitName ) + self:F( self.UnitName ) local DCSUnit = self:GetDCSObject() diff --git a/docs/Documentation/AI_A2A.html b/docs/Documentation/AI_A2A.html index a806e13d7..34f484bce 100644 --- a/docs/Documentation/AI_A2A.html +++ b/docs/Documentation/AI_A2A.html @@ -341,13 +341,13 @@ - AI_A2A.RTBHold(AIGroup) + AI_A2A.RTBHold(AIGroup, Fsm) - AI_A2A.RTBRoute(AIGroup) + AI_A2A.RTBRoute(AIGroup, Fsm) @@ -359,7 +359,7 @@ - AI_A2A.Resume(AIGroup) + AI_A2A.Resume(AIGroup, Fsm) @@ -1476,19 +1476,24 @@ Return false to cancel Transition.

-AI_A2A.RTBHold(AIGroup) +AI_A2A.RTBHold(AIGroup, Fsm)
-

Parameter

+

Parameters

@@ -1497,19 +1502,24 @@ Return false to cancel Transition.

-AI_A2A.RTBRoute(AIGroup) +AI_A2A.RTBRoute(AIGroup, Fsm)
-

Parameter

+

Parameters

@@ -1531,19 +1541,24 @@ Return false to cancel Transition.

-AI_A2A.Resume(AIGroup) +AI_A2A.Resume(AIGroup, Fsm)
-

Parameter

+

Parameters

diff --git a/docs/Documentation/AI_A2A_Cap.html b/docs/Documentation/AI_A2A_Cap.html index 09d0a09c5..b93320257 100644 --- a/docs/Documentation/AI_A2A_Cap.html +++ b/docs/Documentation/AI_A2A_Cap.html @@ -171,7 +171,7 @@ and automatically engage any airborne enemies that are within a certain range or - AI_A2A_CAP.AttackRoute(AIGroup) + AI_A2A_CAP.AttackRoute(AIGroup, Fsm) @@ -553,19 +553,24 @@ Use the method AICap#AI -AI_A2A_CAP.AttackRoute(AIGroup) +AI_A2A_CAP.AttackRoute(AIGroup, Fsm)
-

Parameter

+

Parameters

diff --git a/docs/Documentation/AI_A2A_GCI.html b/docs/Documentation/AI_A2A_GCI.html index e3a59b407..7a6e7ed7b 100644 --- a/docs/Documentation/AI_A2A_GCI.html +++ b/docs/Documentation/AI_A2A_GCI.html @@ -204,7 +204,7 @@ - AI_A2A_GCI.InterceptRoute(AIControllable, AIGroup) + AI_A2A_GCI.InterceptRoute(AIControllable, AIGroup, Fsm) @@ -617,7 +617,7 @@ Use the method AICap#AI -AI_A2A_GCI.InterceptRoute(AIControllable, AIGroup) +AI_A2A_GCI.InterceptRoute(AIControllable, AIGroup, Fsm)
@@ -635,6 +635,11 @@ Use the method AICap#AI AIGroup :

+ +
  • + +

    Fsm :

    +
  • diff --git a/docs/Documentation/AI_A2A_Patrol.html b/docs/Documentation/AI_A2A_Patrol.html index f05d91c1a..4b46dcbc5 100644 --- a/docs/Documentation/AI_A2A_Patrol.html +++ b/docs/Documentation/AI_A2A_Patrol.html @@ -242,7 +242,7 @@ - AI_A2A_PATROL.PatrolRoute(AIGroup) + AI_A2A_PATROL.PatrolRoute(AIGroup, Fsm) @@ -852,14 +852,14 @@ Return false to cancel Transition.

    -AI_A2A_PATROL.PatrolRoute(AIGroup) +AI_A2A_PATROL.PatrolRoute(AIGroup, Fsm)
    -

    Parameter

    +

    Parameters

    • @@ -867,6 +867,11 @@ Return false to cancel Transition.

      This statis method is called from the route path within the last task at the last waaypoint of the Controllable. Note that this method is required, as triggers the next route when patrolling for the Controllable.

      +
    • +
    • + +

      Fsm :

      +
    diff --git a/docs/Documentation/Cargo.html b/docs/Documentation/Cargo.html index 21b706849..9f6098452 100644 --- a/docs/Documentation/Cargo.html +++ b/docs/Documentation/Cargo.html @@ -3417,7 +3417,6 @@ The range till cargo will board.

    - CARGO_UNIT.CargoCarrier @@ -3543,7 +3542,6 @@ The range till cargo will board.

    - #number CARGO_UNIT.RunCount diff --git a/docs/Documentation/Controllable.html b/docs/Documentation/Controllable.html index a07c91687..4290ac3d0 100644 --- a/docs/Documentation/Controllable.html +++ b/docs/Documentation/Controllable.html @@ -235,6 +235,12 @@ CONTROLLABLE:GetDetectedTargets(DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK)

    Return the detected targets of the controllable.

    + + + + CONTROLLABLE:GetFuel() + +

    Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks.

    @@ -424,7 +430,7 @@ - CONTROLLABLE:Route(GoPoints) + CONTROLLABLE:Route(Route, DelaySeconds)

    Make the controllable to follow a given route.

    @@ -451,6 +457,12 @@ CONTROLLABLE:SetTask(DCSTask, WaitTime)

    Clearing the Task Queue and Setting the Task on the queue from the controllable.

    + + + + CONTROLLABLE:SetTaskAtWaypoint(RouteList, WaypointNumber, Task) + +

    Set a Task at a Waypoint using a Route list.

    @@ -538,9 +550,9 @@ - CONTROLLABLE:TaskFunction(WayPoint, WayPointIndex, FunctionString, FunctionArguments) + CONTROLLABLE:TaskFunction(FunctionString, ...) - +

    This creates a Task element, with an action to call a function as part of a Wrapped Task.

    @@ -769,6 +781,22 @@ This is different from the EnRoute tasks, where the targets of the task need to
  • CONTROLLABLE.TaskControlled: Return a Controlled Task taking a Task and a TaskCondition.
  • +

    Call a function as a Task

    + +

    A function can be called which is part of a Task. The method CONTROLLABLE.TaskFunction() prepares +a Task that can call a GLOBAL function from within the Controller execution. +This method can also be used to embed a function call when a certain waypoint has been reached. +See below the Tasks at Waypoints section.

    + +

    Demonstration Mission: GRP-502 - Route at waypoint to random point

    + +

    Tasks at Waypoints

    + +

    Special Task methods are available to set tasks at certain waypoints. +The method CONTROLLABLE.SetTaskAtWaypoint() helps preparing a Route, embedding a Task at the Waypoint of the Route.

    + +

    This creates a Task element, with an action to call a function as part of a Wrapped Task.

    +

    Obtain the mission from controllable templates

    Controllable templates contain complete mission descriptions. Sometimes you want to copy a complete mission from a controllable and assign it to another:

    @@ -1478,6 +1506,27 @@ DetectedTargets

    + +CONTROLLABLE:GetFuel() + +
    +
    + +

    Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks.

    + + +

    This method returns nil to ensure polymorphic behaviour! This method needs to be overridden by GROUP or UNIT.

    + +

    Return value

    + +

    #nil: +The CONTROLLABLE is not existing or alive.

    + +
    +
    +
    +
    + CONTROLLABLE:GetLife() @@ -2133,26 +2182,32 @@ self

    -CONTROLLABLE:Route(GoPoints) +CONTROLLABLE:Route(Route, DelaySeconds)

    Make the controllable to follow a given route.

    -

    Parameter

    +

    Parameters

    • -

      #table GoPoints : +

      #table Route : A table of Route Points.

      +
    • +
    • + +

      #number DelaySeconds : +Wait for the specified seconds before executing the Route.

      +

    Return value

    #CONTROLLABLE: -self

    +The CONTROLLABLE.

    @@ -2277,6 +2332,45 @@ self

    Wrapper.Controllable#CONTROLLABLE: self

    + +
    +
    +
    + + +CONTROLLABLE:SetTaskAtWaypoint(RouteList, WaypointNumber, Task) + +
    +
    + +

    Set a Task at a Waypoint using a Route list.

    + +

    Parameters

    + +

    Return value

    + +

    Dcs.DCSTasking.Task#Task:

    + +
    @@ -2971,36 +3065,79 @@ The DCS task structure.

    -CONTROLLABLE:TaskFunction(WayPoint, WayPointIndex, FunctionString, FunctionArguments) +CONTROLLABLE:TaskFunction(FunctionString, ...)
    +

    This creates a Task element, with an action to call a function as part of a Wrapped Task.

    + +

    This Task can then be embedded at a Waypoint by calling the method CONTROLLABLE.SetTaskAtWaypoint.

    Parameters

    • -

      WayPoint :

      +

      #string FunctionString : +The function name embedded as a string that will be called.

    • -

      WayPointIndex :

      - -
    • -
    • - -

      FunctionString :

      - -
    • -
    • - -

      FunctionArguments :

      +

      ... : +The variable arguments passed to the function when called! These arguments can be of any type!

    +

    Return value

    + +

    #CONTROLLABLE:

    + + +

    Usage:

    +
    
    + local ZoneList = { 
    +   ZONE:New( "ZONE1" ), 
    +   ZONE:New( "ZONE2" ), 
    +   ZONE:New( "ZONE3" ), 
    +   ZONE:New( "ZONE4" ), 
    +   ZONE:New( "ZONE5" ) 
    + }
    + 
    + GroundGroup = GROUP:FindByName( "Vehicle" )
    + 
    + --- @param Wrapper.Group#GROUP GroundGroup
    + function RouteToZone( Vehicle, ZoneRoute )
    + 
    +   local Route = {}
    +   
    +   Vehicle:E( { ZoneRoute = ZoneRoute } )
    +   
    +   Vehicle:MessageToAll( "Moving to zone " .. ZoneRoute:GetName(), 10 )
    + 
    +   -- Get the current coordinate of the Vehicle
    +   local FromCoord = Vehicle:GetCoordinate()
    +   
    +   -- Select a random Zone and get the Coordinate of the new Zone.
    +   local RandomZone = ZoneList[ math.random( 1, #ZoneList ) ] -- Core.Zone#ZONE
    +   local ToCoord = RandomZone:GetCoordinate()
    +   
    +   -- Create a "ground route point", which is a "point" structure that can be given as a parameter to a Task
    +   Route[#Route+1] = FromCoord:RoutePointGround( 72 )
    +   Route[#Route+1] = ToCoord:RoutePointGround( 60, "Vee" )
    +   
    +   local TaskRouteToZone = Vehicle:TaskFunction( "RouteToZone", RandomZone )
    +   
    +   Vehicle:SetTaskAtWaypoint( Route, #Route, TaskRouteToZone ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone.
    + 
    +   Vehicle:Route( Route, math.random( 10, 20 ) ) -- Move after a random seconds to the Route. See the Route method for details.
    +   
    + end
    +   
    +   RouteToZone( GroundGroup, ZoneList[1] )
    +
    +
    diff --git a/docs/Documentation/Designate.html b/docs/Documentation/Designate.html index c80c67564..36c6d0e0f 100644 --- a/docs/Documentation/Designate.html +++ b/docs/Documentation/Designate.html @@ -923,6 +923,7 @@ function below will use the range 1-7 just in case

    + DESIGNATE.LaserCodes diff --git a/docs/Documentation/Fsm.html b/docs/Documentation/Fsm.html index e0276d335..177f34281 100644 --- a/docs/Documentation/Fsm.html +++ b/docs/Documentation/Fsm.html @@ -1598,7 +1598,7 @@ A string defining the start state.

    - + #string FSM._StartState @@ -1897,7 +1897,6 @@ A string defining the start state.

    - FSM.current diff --git a/docs/Documentation/Group.html b/docs/Documentation/Group.html index d82748101..095665155 100644 --- a/docs/Documentation/Group.html +++ b/docs/Documentation/Group.html @@ -256,6 +256,12 @@ GROUP:GetDCSUnits()

    Returns the DCS Units of the DCS Group.

    + + + + GROUP:GetFuel() + +

    Returns relative amount of fuel (from 0.0 to 1.0) the group has in its internal tanks.

    @@ -1026,6 +1032,37 @@ The DCS Units.

    + +GROUP:GetFuel() + +
    +
    + +

    Returns relative amount of fuel (from 0.0 to 1.0) the group has in its internal tanks.

    + + +

    If there are additional fuel tanks the value may be greater than 1.0.

    + +

    Return values

    +
      +
    1. + +

      #number: +The relative amount of fuel (from 0.0 to 1.0).

      + +
    2. +
    3. + +

      #nil: +The GROUP is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + GROUP:GetHeading() diff --git a/docs/Documentation/Movement.html b/docs/Documentation/Movement.html index be5ce073c..4307c3aaa 100644 --- a/docs/Documentation/Movement.html +++ b/docs/Documentation/Movement.html @@ -227,7 +227,6 @@ on defined intervals (currently every minute).

    - #number MOVEMENT.AliveUnits @@ -236,9 +235,6 @@ on defined intervals (currently every minute).

    - -

    Contains the counter how many units are currently alive

    -
    diff --git a/docs/Documentation/Positionable.html b/docs/Documentation/Positionable.html index 78befb2bf..82d94f58f 100644 --- a/docs/Documentation/Positionable.html +++ b/docs/Documentation/Positionable.html @@ -1838,6 +1838,7 @@ self

    + Core.Spot#SPOT POSITIONABLE.Spot diff --git a/docs/Documentation/Spawn.html b/docs/Documentation/Spawn.html index c9dc9dd3f..20fe7f177 100644 --- a/docs/Documentation/Spawn.html +++ b/docs/Documentation/Spawn.html @@ -2194,6 +2194,9 @@ The group that was spawned. You can use this group for further actions.

    + +

    Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning.

    +
    @@ -2746,6 +2749,9 @@ when nothing was spawned.

    + +

    By default, no InitLimit

    +
    @@ -2781,7 +2787,7 @@ when nothing was spawned.

    - + #number SPAWN.SpawnMaxGroups @@ -2798,7 +2804,7 @@ when nothing was spawned.

    - + #number SPAWN.SpawnMaxUnitsAlive diff --git a/docs/Documentation/Spot.html b/docs/Documentation/Spot.html index ead3792db..5fdc3b305 100644 --- a/docs/Documentation/Spot.html +++ b/docs/Documentation/Spot.html @@ -765,6 +765,7 @@ true if it is lasing

    + SPOT.ScheduleID @@ -778,6 +779,7 @@ true if it is lasing

    + SPOT.SpotIR @@ -791,6 +793,7 @@ true if it is lasing

    + SPOT.SpotLaser @@ -804,6 +807,7 @@ true if it is lasing

    + SPOT.Target diff --git a/docs/Documentation/Task_Cargo.html b/docs/Documentation/Task_Cargo.html index ab67c2b1a..349f0de89 100644 --- a/docs/Documentation/Task_Cargo.html +++ b/docs/Documentation/Task_Cargo.html @@ -552,7 +552,7 @@ based on the tasking capabilities defined in Task#TA
    - + Core.Cargo#CARGO_GROUP FSM_PROCESS.Cargo @@ -566,6 +566,7 @@ based on the tasking capabilities defined in Task#TA
    + FSM_PROCESS.DeployZone @@ -630,7 +631,7 @@ based on the tasking capabilities defined in Task#TA
    - + #number TASK_CARGO.CargoLimit diff --git a/docs/Documentation/Unit.html b/docs/Documentation/Unit.html index be295ced4..2185df762 100644 --- a/docs/Documentation/Unit.html +++ b/docs/Documentation/Unit.html @@ -181,7 +181,7 @@ UNIT:GetFuel() -

    Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks.

    +

    Returns relative amount of fuel (from 0.0 to 1.0) the UNIT has in its internal tanks.

    @@ -641,7 +641,7 @@ Category name = Helicopter, Airplane, Ground Unit, Ship

    -

    Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks.

    +

    Returns relative amount of fuel (from 0.0 to 1.0) the UNIT has in its internal tanks.

    If there are additional fuel tanks the value may be greater than 1.0.