Many Fixes

This commit is contained in:
FlightControl_Master
2017-08-08 09:42:42 +02:00
parent 63866e4aa9
commit 2aecf45316
26 changed files with 455 additions and 138 deletions

View File

@@ -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 )

View File

@@ -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!

View File

@@ -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(),

View File

@@ -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!

View File

@@ -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()

View File

@@ -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

View File

@@ -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(

View File

@@ -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!

View File

@@ -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}.

View File

@@ -14,7 +14,7 @@
-- @extends Wrapper.Identifiable#IDENTIFIABLE
--- @type POSITIONABLE
-- @extends POSITIONABLE.__
-- @extends Wrapper.Identifiable#IDENTIFIABLE
--- # POSITIONABLE class, extends @{Identifiable#IDENTIFIABLE}

View File

@@ -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()