mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'feature/Feature-AI_Cargo_Dispatching_Airplane' into FF/Develop
This commit is contained in:
@@ -114,6 +114,18 @@ function AI_CARGO_AIRPLANE:New( Airplane, CargoSet )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function AI_CARGO_AIRPLANE:IsTransporting()
|
||||||
|
|
||||||
|
return self.Transporting == true
|
||||||
|
end
|
||||||
|
|
||||||
|
function AI_CARGO_AIRPLANE:IsRelocating()
|
||||||
|
|
||||||
|
return self.Relocating == true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Set the Carrier.
|
--- Set the Carrier.
|
||||||
-- @param #AI_CARGO_AIRPLANE self
|
-- @param #AI_CARGO_AIRPLANE self
|
||||||
-- @param Wrapper.Group#GROUP Airplane
|
-- @param Wrapper.Group#GROUP Airplane
|
||||||
@@ -158,7 +170,8 @@ function AI_CARGO_AIRPLANE:SetCarrier( Airplane )
|
|||||||
|
|
||||||
|
|
||||||
function Airplane:OnEventEngineShutdown( EventData )
|
function Airplane:OnEventEngineShutdown( EventData )
|
||||||
AICargo:Landed()
|
self:F("Calling")
|
||||||
|
AICargo:Landed( self.Airplane )
|
||||||
end
|
end
|
||||||
|
|
||||||
self.Coalition = self.Airplane:GetCoalition()
|
self.Coalition = self.Airplane:GetCoalition()
|
||||||
@@ -201,6 +214,10 @@ end
|
|||||||
-- @param To
|
-- @param To
|
||||||
function AI_CARGO_AIRPLANE:onafterLanded( Airplane, From, Event, To )
|
function AI_CARGO_AIRPLANE:onafterLanded( Airplane, From, Event, To )
|
||||||
|
|
||||||
|
self:F({Airplane, From, Event, To})
|
||||||
|
self:F({IsAlive=Airplane:IsAlive()})
|
||||||
|
self:F({RoutePickup=self.RoutePickup})
|
||||||
|
|
||||||
if Airplane and Airplane:IsAlive() then
|
if Airplane and Airplane:IsAlive() then
|
||||||
|
|
||||||
if self.RoutePickup == true then
|
if self.RoutePickup == true then
|
||||||
@@ -240,6 +257,8 @@ function AI_CARGO_AIRPLANE:onafterPickup( Airplane, From, Event, To, Airbase, Sp
|
|||||||
|
|
||||||
-- Set airbase as starting point in the next Route() call.
|
-- Set airbase as starting point in the next Route() call.
|
||||||
self.Airbase = Airbase
|
self.Airbase = Airbase
|
||||||
|
self.Transporting = true
|
||||||
|
self.Relocating = false
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -260,6 +279,8 @@ function AI_CARGO_AIRPLANE:onafterDeploy( Airplane, From, Event, To, Airbase, Sp
|
|||||||
self:Route( Airplane, Airbase, Speed )
|
self:Route( Airplane, Airbase, Speed )
|
||||||
self.RouteDeploy = true
|
self.RouteDeploy = true
|
||||||
self.Airbase = Airbase
|
self.Airbase = Airbase
|
||||||
|
self.Transporting = false
|
||||||
|
self.Relocating = false
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -278,8 +299,9 @@ function AI_CARGO_AIRPLANE:onafterLoad( Airplane, From, Event, To, Coordinate )
|
|||||||
--if Airplane then
|
--if Airplane then
|
||||||
|
|
||||||
for _, Cargo in pairs( self.CargoSet:GetSet() ) do
|
for _, Cargo in pairs( self.CargoSet:GetSet() ) do
|
||||||
local Cargo=Cargo --Cargo.Cargo#CARGO
|
self:F({Cargo:GetName()})
|
||||||
if Cargo:IsInLoadRadius( Coordinate ) then
|
local InRadius = Cargo:IsInLoadRadius( Coordinate )
|
||||||
|
if InRadius then
|
||||||
self:__Board( 5 )
|
self:__Board( 5 )
|
||||||
Cargo:Board( Airplane, 25 )
|
Cargo:Board( Airplane, 25 )
|
||||||
self.Cargo = Cargo
|
self.Cargo = Cargo
|
||||||
@@ -399,6 +421,7 @@ function AI_CARGO_AIRPLANE:Route( Airplane, Airbase, Speed )
|
|||||||
FromWaypoint.helipadId = nil
|
FromWaypoint.helipadId = nil
|
||||||
FromWaypoint.airdromeId = nil
|
FromWaypoint.airdromeId = nil
|
||||||
|
|
||||||
|
local ParkingSpots = self.Airbase:FindFreeParkingSpotForAircraft( Airplane, AIRBASE.TerminalType.OpenBig )
|
||||||
local AirbaseID = self.Airbase:GetID()
|
local AirbaseID = self.Airbase:GetID()
|
||||||
local AirbaseCategory = self.Airbase:GetDesc().category
|
local AirbaseCategory = self.Airbase:GetDesc().category
|
||||||
|
|
||||||
@@ -417,8 +440,8 @@ function AI_CARGO_AIRPLANE:Route( Airplane, Airbase, Speed )
|
|||||||
-- These cause a lot of confusion.
|
-- These cause a lot of confusion.
|
||||||
local UnitTemplate = Template.units[UnitID]
|
local UnitTemplate = Template.units[UnitID]
|
||||||
|
|
||||||
UnitTemplate.parking = 15
|
UnitTemplate.parking = nil
|
||||||
UnitTemplate.parking_id = "1"
|
UnitTemplate.parking_id = nil
|
||||||
UnitTemplate.alt = 0
|
UnitTemplate.alt = 0
|
||||||
|
|
||||||
local SX = UnitTemplate.x
|
local SX = UnitTemplate.x
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module AI.AI_Cargo_Dispatcher
|
-- @module AI.AI_Cargo_Dispatcher
|
||||||
-- @image AI_Cargo_Dispatching_For_Helicopters.JPG
|
-- @image AI_Cargo_Dispatcher.JPG
|
||||||
|
|
||||||
--- @type AI_CARGO_DISPATCHER
|
--- @type AI_CARGO_DISPATCHER
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
AI_CARGO_DISPATCHER = {
|
AI_CARGO_DISPATCHER = {
|
||||||
ClassName = "AI_CARGO_DISPATCHER",
|
ClassName = "AI_CARGO_DISPATCHER",
|
||||||
SetCarrier = nil,
|
SetCarrier = nil,
|
||||||
SetDeployZones = nil,
|
DeployZonesSet = nil,
|
||||||
AI_Cargo = {},
|
AI_Cargo = {},
|
||||||
PickupCargo = {}
|
PickupCargo = {}
|
||||||
}
|
}
|
||||||
@@ -90,23 +90,21 @@ AI_CARGO_DISPATCHER.PickupCargo = {}
|
|||||||
-- @param #AI_CARGO_DISPATCHER self
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
-- @param Core.Set#SET_GROUP SetCarrier
|
-- @param Core.Set#SET_GROUP SetCarrier
|
||||||
-- @param Core.Set#SET_CARGO SetCargo
|
-- @param Core.Set#SET_CARGO SetCargo
|
||||||
-- @param Core.Set#SET_ZONE SetDeployZones
|
|
||||||
-- @return #AI_CARGO_DISPATCHER
|
-- @return #AI_CARGO_DISPATCHER
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
-- -- Create a new cargo dispatcher
|
-- -- Create a new cargo dispatcher
|
||||||
-- SetCarrier = SET_GROUP:New():FilterPrefixes( "APC" ):FilterStart()
|
-- SetCarriers = SET_GROUP:New():FilterPrefixes( "APC" ):FilterStart()
|
||||||
-- SetCargo = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart()
|
-- SetCargos = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart()
|
||||||
-- SetDeployZone = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart()
|
-- SetDeployZone = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart()
|
||||||
-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZone )
|
-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo )
|
||||||
--
|
--
|
||||||
function AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZones )
|
function AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, FSM:New() ) -- #AI_CARGO_DISPATCHER
|
local self = BASE:Inherit( self, FSM:New() ) -- #AI_CARGO_DISPATCHER
|
||||||
|
|
||||||
self.SetCarrier = SetCarrier -- Core.Set#SET_GROUP
|
self.SetCarrier = SetCarrier -- Core.Set#SET_GROUP
|
||||||
self.SetCargo = SetCargo -- Core.Set#SET_CARGO
|
self.SetCargo = SetCargo -- Core.Set#SET_CARGO
|
||||||
self.SetDeployZones = SetDeployZones -- Core.Set#SET_ZONE
|
|
||||||
|
|
||||||
self:SetStartState( "Idle" )
|
self:SetStartState( "Idle" )
|
||||||
|
|
||||||
@@ -144,6 +142,58 @@ function AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZones )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Creates a new AI_CARGO_DISPATCHER object.
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
-- @param Core.Set#SET_GROUP SetCarrier
|
||||||
|
-- @param Core.Set#SET_CARGO SetCargo
|
||||||
|
-- @param Core.Set#SET_ZONE DeployZonesSet
|
||||||
|
-- @return #AI_CARGO_DISPATCHER
|
||||||
|
-- @usage
|
||||||
|
--
|
||||||
|
-- -- Create a new cargo dispatcher
|
||||||
|
-- SetCarriers = SET_GROUP:New():FilterPrefixes( "APC" ):FilterStart()
|
||||||
|
-- SetCargos = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart()
|
||||||
|
-- DeployZonesSet = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart()
|
||||||
|
-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZone )
|
||||||
|
--
|
||||||
|
function AI_CARGO_DISPATCHER:NewWithZones( SetCarriers, SetCargos, DeployZonesSet )
|
||||||
|
|
||||||
|
local self = AI_CARGO_DISPATCHER:New( SetCarriers, SetCargos ) -- #AI_CARGO_DISPATCHER
|
||||||
|
|
||||||
|
self.DeployZonesSet = DeployZonesSet
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Creates a new AI_CARGO_DISPATCHER object.
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
-- @param Core.Set#SET_GROUP SetCarrier
|
||||||
|
-- @param Core.Set#SET_CARGO SetCargo
|
||||||
|
-- @param Core.Set#SET_AIRBASE PickupAirbasesSet
|
||||||
|
-- @param Core.Set#SET_AIRBASE DeployAirbasesSet
|
||||||
|
-- @return #AI_CARGO_DISPATCHER
|
||||||
|
-- @usage
|
||||||
|
--
|
||||||
|
-- -- Create a new cargo dispatcher
|
||||||
|
-- SetCarriers = SET_GROUP:New():FilterPrefixes( "APC" ):FilterStart()
|
||||||
|
-- SetCargos = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart()
|
||||||
|
-- PickupAirbasesSet = SET_AIRBASES:New()
|
||||||
|
-- DeployAirbasesSet = SET_AIRBASES:New()
|
||||||
|
-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, PickupAirbasesSet, DeployAirbasesSet )
|
||||||
|
--
|
||||||
|
function AI_CARGO_DISPATCHER:NewWithAirbases( SetCarriers, SetCargos, PickupAirbasesSet, DeployAirbasesSet )
|
||||||
|
|
||||||
|
local self = AI_CARGO_DISPATCHER:New( SetCarriers, SetCargos ) -- #AI_CARGO_DISPATCHER
|
||||||
|
|
||||||
|
self.DeployAirbasesSet = DeployAirbasesSet
|
||||||
|
self.PickupAirbasesSet = PickupAirbasesSet
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Set the home zone.
|
--- Set the home zone.
|
||||||
-- When there is nothing anymore to pickup, the carriers will go to a random coordinate in this zone.
|
-- When there is nothing anymore to pickup, the carriers will go to a random coordinate in this zone.
|
||||||
-- They will await here new orders.
|
-- They will await here new orders.
|
||||||
@@ -361,7 +411,16 @@ function AI_CARGO_DISPATCHER:onafterMonitor()
|
|||||||
if PickupCargo then
|
if PickupCargo then
|
||||||
self.CarrierHome[Carrier] = nil
|
self.CarrierHome[Carrier] = nil
|
||||||
local PickupCoordinate = PickupCargo:GetCoordinate():GetRandomCoordinateInRadius( self.PickupOuterRadius, self.PickupInnerRadius )
|
local PickupCoordinate = PickupCargo:GetCoordinate():GetRandomCoordinateInRadius( self.PickupOuterRadius, self.PickupInnerRadius )
|
||||||
AI_Cargo:Pickup( PickupCoordinate, math.random( self.PickupMinSpeed, self.PickupMaxSpeed ) )
|
|
||||||
|
if self.PickupAirbasesSet then
|
||||||
|
-- Find airbase within 2km from the cargo with the set.
|
||||||
|
local PickupAirbase = self.PickupAirbasesSet:FindAirbaseInRange( PickupCoordinate, 4000 )
|
||||||
|
if PickupAirbase then
|
||||||
|
AI_Cargo:Pickup( PickupAirbase, math.random( self.PickupMinSpeed, self.PickupMaxSpeed ) )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
AI_Cargo:Pickup( PickupCoordinate, math.random( self.PickupMinSpeed, self.PickupMaxSpeed ) )
|
||||||
|
end
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
if self.HomeZone then
|
if self.HomeZone then
|
||||||
@@ -464,12 +523,22 @@ end
|
|||||||
-- @return #AI_CARGO_DISPATCHER
|
-- @return #AI_CARGO_DISPATCHER
|
||||||
function AI_CARGO_DISPATCHER:OnAfterLoaded( From, Event, To, Carrier, Cargo )
|
function AI_CARGO_DISPATCHER:OnAfterLoaded( From, Event, To, Carrier, Cargo )
|
||||||
|
|
||||||
local DeployZone = self.SetDeployZones:GetRandomZone()
|
if self.DeployZonesSet then
|
||||||
|
|
||||||
local DeployCoordinate = DeployZone:GetCoordinate():GetRandomCoordinateInRadius( self.DeployOuterRadius, self.DeployInnerRadius )
|
local DeployZone = self.DeployZonesSet:GetRandomZone()
|
||||||
self.AI_Cargo[Carrier]:Deploy( DeployCoordinate, math.random( self.DeployMinSpeed, self.DeployMaxSpeed ) )
|
|
||||||
|
local DeployCoordinate = DeployZone:GetCoordinate():GetRandomCoordinateInRadius( self.DeployOuterRadius, self.DeployInnerRadius )
|
||||||
|
self.AI_Cargo[Carrier]:Deploy( DeployCoordinate, math.random( self.DeployMinSpeed, self.DeployMaxSpeed ) )
|
||||||
|
|
||||||
self.PickupCargo[Carrier] = nil
|
end
|
||||||
|
|
||||||
|
if self.DeployAirbasesSet then
|
||||||
|
|
||||||
|
local DeployAirbase = self.DeployAirbasesSet:GetRandomAirbase()
|
||||||
|
self.AI_Cargo[Carrier]:Deploy( DeployAirbase, math.random( self.DeployMinSpeed, self.DeployMaxSpeed ) )
|
||||||
|
end
|
||||||
|
|
||||||
|
self.PickupCargo[Carrier] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ AI_CARGO_DISPATCHER_APC = {
|
|||||||
-- SetDeployZone = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart()
|
-- SetDeployZone = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart()
|
||||||
-- AICargoDispatcher = AI_CARGO_DISPATCHER_APC:New( SetAPC, SetCargo, SetDeployZone, 500 )
|
-- AICargoDispatcher = AI_CARGO_DISPATCHER_APC:New( SetAPC, SetCargo, SetDeployZone, 500 )
|
||||||
--
|
--
|
||||||
function AI_CARGO_DISPATCHER_APC:New( SetAPC, SetCargo, SetDeployZone, CombatRadius )
|
function AI_CARGO_DISPATCHER_APC:NewWithZones( SetAPC, SetCargo, SetDeployZone, CombatRadius )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:New( SetAPC, SetCargo, SetDeployZone ) ) -- #AI_CARGO_DISPATCHER_APC
|
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:New( SetAPC, SetCargo, SetDeployZone ) ) -- #AI_CARGO_DISPATCHER_APC
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
--- Brings a dynamic cargo handling capability for AI groups.
|
--- Brings a dynamic cargo handling capability for AI groups.
|
||||||
--
|
--
|
||||||
-- Airplanes can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Airplanes can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
-- The AI\_CARGO\_DISPATCHER\_AIRPLANE module uses the @{Cargo} capabilities within the MOOSE framework.
|
-- The AI_CARGO_DISPATCHER_AIRPLANE module uses the @{Cargo} capabilities within the MOOSE framework.
|
||||||
-- CARGO derived objects must be declared within the mission to make the AI\_CARGO\_DISPATCHER\_AIRPLANE object recognize the cargo.
|
-- CARGO derived objects must be declared within the mission to make the AI_CARGO_DISPATCHER_AIRPLANE object recognize the cargo.
|
||||||
-- Please consult the @{Cargo} module for more information.
|
-- Please consult the @{Cargo} module for more information.
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
@@ -29,23 +29,33 @@ AI_CARGO_DISPATCHER_AIRPLANE = {
|
|||||||
|
|
||||||
--- Creates a new AI_CARGO_DISPATCHER_AIRPLANE object.
|
--- Creates a new AI_CARGO_DISPATCHER_AIRPLANE object.
|
||||||
-- @param #AI_CARGO_DISPATCHER_AIRPLANE self
|
-- @param #AI_CARGO_DISPATCHER_AIRPLANE self
|
||||||
-- @param Core.Set#SET_GROUP SetAirplane
|
-- @param Core.Set#SET_GROUP SetAirplanes
|
||||||
-- @param Core.Set#SET_CARGO SetCargo
|
-- @param Core.Set#SET_CARGO SetCargos
|
||||||
-- @param Core.Set#SET_ZONE SetDeployZone
|
-- @param Core.Set#SET_AIRBASE PickupAirbasesSet
|
||||||
|
-- @param Core.Set#SET_AIRBASE DeployAirbasesSet
|
||||||
-- @return #AI_CARGO_DISPATCHER_AIRPLANE
|
-- @return #AI_CARGO_DISPATCHER_AIRPLANE
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
-- -- Create a new cargo dispatcher
|
-- -- Create a new cargo dispatcher
|
||||||
-- SetAirplane = SET_GROUP:New():FilterPrefixes( "Airplane" ):FilterStart()
|
-- SetAirplanes = SET_GROUP:New():FilterPrefixes( "Airplane" ):FilterStart()
|
||||||
-- SetCargo = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart()
|
-- SetCargos = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart()
|
||||||
-- SetDeployZone = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart()
|
-- PickupAirbasesSet = SET_AIRBASE:New()
|
||||||
-- AICargoDispatcher = AI_CARGO_DISPATCHER_AIRPLANE:New( SetAirplane, SetCargo )
|
-- DeployAirbasesSet = SET_AIRBASE:New()
|
||||||
|
-- AICargoDispatcher = AI_CARGO_DISPATCHER_AIRPLANE:New( SetAirplanes, SetCargos, PickupAirbasesSet, DeployAirbasesSet )
|
||||||
--
|
--
|
||||||
function AI_CARGO_DISPATCHER_AIRPLANE:New( SetAirplane, SetCargo, SetDeployZones )
|
function AI_CARGO_DISPATCHER_AIRPLANE:New( SetAirplanes, SetCargos, PickupAirbasesSet, DeployAirbasesSet )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:New( SetAirplane, SetCargo, SetDeployZones ) ) -- #AI_CARGO_DISPATCHER_AIRPLANE
|
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:NewWithAirbases( SetAirplanes, SetCargos, PickupAirbasesSet, DeployAirbasesSet ) ) -- #AI_CARGO_DISPATCHER_AIRPLANE
|
||||||
|
|
||||||
|
self:SetDeploySpeed( 200, 150 )
|
||||||
|
self:SetPickupSpeed( 200, 150 )
|
||||||
|
self:SetPickupRadius( 0, 0 )
|
||||||
|
self:SetDeployRadius( 0, 0 )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function AI_CARGO_DISPATCHER_AIRPLANE:AICargo( Airplane, SetCargo )
|
||||||
|
|
||||||
|
return AI_CARGO_AIRPLANE:New( Airplane, SetCargo )
|
||||||
|
end
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ AI_CARGO_DISPATCHER_HELICOPTER = {
|
|||||||
--
|
--
|
||||||
function AI_CARGO_DISPATCHER_HELICOPTER:New( SetHelicopter, SetCargo, SetDeployZones )
|
function AI_CARGO_DISPATCHER_HELICOPTER:New( SetHelicopter, SetCargo, SetDeployZones )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:New( SetHelicopter, SetCargo, SetDeployZones ) ) -- #AI_CARGO_DISPATCHER_HELICOPTER
|
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:NewWithZones( SetHelicopter, SetCargo, SetDeployZones ) ) -- #AI_CARGO_DISPATCHER_HELICOPTER
|
||||||
|
|
||||||
self:SetDeploySpeed( 200, 150 )
|
self:SetDeploySpeed( 200, 150 )
|
||||||
self:SetPickupSpeed( 200, 150 )
|
self:SetPickupSpeed( 200, 150 )
|
||||||
|
|||||||
@@ -4010,6 +4010,45 @@ function SET_AIRBASE:FindAirbase( AirbaseName )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Finds an Airbase in range of a coordinate.
|
||||||
|
-- @param #SET_AIRBASE self
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate
|
||||||
|
-- @param #number Range
|
||||||
|
-- @return Wrapper.Airbase#AIRBASE The found Airbase.
|
||||||
|
function SET_AIRBASE:FindAirbaseInRange( Coordinate, Range )
|
||||||
|
|
||||||
|
local AirbaseFound = nil
|
||||||
|
|
||||||
|
for AirbaseName, AirbaseObject in pairs( self.Set ) do
|
||||||
|
|
||||||
|
local AirbaseCoordinate = AirbaseObject:GetCoordinate()
|
||||||
|
local Distance = Coordinate:Get2DDistance( AirbaseCoordinate )
|
||||||
|
|
||||||
|
self:F({Distance=Distance})
|
||||||
|
|
||||||
|
if Distance <= Range then
|
||||||
|
AirbaseFound = AirbaseObject
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return AirbaseFound
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Finds a random Airbase in the set.
|
||||||
|
-- @param #SET_AIRBASE self
|
||||||
|
-- @return Wrapper.Airbase#AIRBASE The found Airbase.
|
||||||
|
function SET_AIRBASE:GetRandomAirbase()
|
||||||
|
|
||||||
|
local RandomAirbase = self:GetRandom()
|
||||||
|
self:F( { RandomAirbase = RandomAirbase:GetName() } )
|
||||||
|
|
||||||
|
return RandomAirbase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Builds a set of airbases of coalitions.
|
--- Builds a set of airbases of coalitions.
|
||||||
-- Possible current coalitions are red, blue and neutral.
|
-- Possible current coalitions are red, blue and neutral.
|
||||||
|
|||||||
@@ -1,5 +1,58 @@
|
|||||||
--- **Tasking** - Creates and manages player TASK_CARGO tasks.
|
--- **Tasking** - Creates and manages player TASK_CARGO tasks.
|
||||||
--
|
--
|
||||||
|
-- The **TASK_CARGO_DISPATCHER** allows you to setup various tasks for let human
|
||||||
|
-- players transport cargo as part of a task.
|
||||||
|
--
|
||||||
|
-- The cargo dispatcher will implement for you mechanisms to create cargo transportation tasks:
|
||||||
|
--
|
||||||
|
-- * As setup by the mission designer.
|
||||||
|
-- * Dynamically create CSAR missions (when a pilot is downed as part of a downed plane).
|
||||||
|
-- * Dynamically spawn new cargo and create cargo taskings!
|
||||||
|
--
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- **Specific features:**
|
||||||
|
--
|
||||||
|
-- * Creates a task to transport @{Cargo.Cargo} to and between deployment zones.
|
||||||
|
-- * Derived from the TASK_CARGO class, which is derived from the TASK class.
|
||||||
|
-- * Orchestrate the task flow, so go from Planned to Assigned to Success, Failed or Cancelled.
|
||||||
|
-- * Co-operation tasking, so a player joins a group of players executing the same task.
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- **A complete task menu system to allow players to:**
|
||||||
|
--
|
||||||
|
-- * Join the task, abort the task.
|
||||||
|
-- * Mark the task location on the map.
|
||||||
|
-- * Provide details of the target.
|
||||||
|
-- * Route to the cargo.
|
||||||
|
-- * Route to the deploy zones.
|
||||||
|
-- * Load/Unload cargo.
|
||||||
|
-- * Board/Unboard cargo.
|
||||||
|
-- * Slingload cargo.
|
||||||
|
-- * Display the task briefing.
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- **A complete mission menu system to allow players to:**
|
||||||
|
--
|
||||||
|
-- * Join a task, abort the task.
|
||||||
|
-- * Display task reports.
|
||||||
|
-- * Display mission statistics.
|
||||||
|
-- * Mark the task locations on the map.
|
||||||
|
-- * Provide details of the targets.
|
||||||
|
-- * Display the mission briefing.
|
||||||
|
-- * Provide status updates as retrieved from the command center.
|
||||||
|
-- * Automatically assign a random task as part of a mission.
|
||||||
|
-- * Manually assign a specific task as part of a mission.
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- **A settings system, using the settings menu:**
|
||||||
|
--
|
||||||
|
-- * Tweak the duration of the display of messages.
|
||||||
|
-- * Switch between metric and imperial measurement system.
|
||||||
|
-- * Switch between coordinate formats used in messages: BR, BRA, LL DMS, LL DDM, MGRS.
|
||||||
|
-- * Different settings modes for A2G and A2A operations.
|
||||||
|
-- * Various other options.
|
||||||
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **FlightControl**
|
-- ### Author: **FlightControl**
|
||||||
@@ -9,7 +62,7 @@
|
|||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module Tasking.Task_Cargo_Dispatcher
|
-- @module Tasking.Task_Cargo_Dispatcher
|
||||||
-- @image MOOSE.JPG
|
-- @image Task_Cargo_Dispatcher.JPG
|
||||||
|
|
||||||
do -- TASK_CARGO_DISPATCHER
|
do -- TASK_CARGO_DISPATCHER
|
||||||
|
|
||||||
@@ -25,148 +78,189 @@ do -- TASK_CARGO_DISPATCHER
|
|||||||
|
|
||||||
--- Implements the dynamic dispatching of cargo tasks.
|
--- Implements the dynamic dispatching of cargo tasks.
|
||||||
--
|
--
|
||||||
-- 
|
-- The **TASK_CARGO_DISPATCHER** allows you to setup various tasks for let human
|
||||||
|
-- players transport cargo as part of a task.
|
||||||
--
|
--
|
||||||
-- The EWR will detect units, will group them, and will dispatch @{Task}s to groups. Depending on the type of target detected, different tasks will be dispatched.
|
-- There are currently **two types of tasks** that can be constructed:
|
||||||
-- Find a summary below describing for which situation a task type is created:
|
|
||||||
--
|
--
|
||||||
-- 
|
-- * A **normal cargo transport** task, which tasks humans to transport cargo from a location towards a deploy zone.
|
||||||
|
-- * A **CSAR** cargo transport task. CSAR tasks are **automatically generated** when a friendly (AI) plane is downed and the friendly pilot ejects...
|
||||||
|
-- You as a player (the helo pilot) can go out in the battlefield, fly behind enemy lines, and rescue the pilot (back to a deploy zone).
|
||||||
--
|
--
|
||||||
-- * **CSAR Task**: Is created when a fiendly pilot has ejected from a plane, and needs to be rescued (sometimes behind enemy lines).
|
-- Let's explore **step by step** how to setup the task cargo dispatcher.
|
||||||
--
|
--
|
||||||
-- ## 1. TASK\_A2A\_DISPATCHER constructor:
|
-- # 1. Setup a mission environment.
|
||||||
--
|
--
|
||||||
-- The @{#TASK_CARGO_DISPATCHER.New}() method creates a new TASK\_A2A\_DISPATCHER instance.
|
-- It is easy, as it works just like any other task setup, so setup a command center and a mission.
|
||||||
--
|
--
|
||||||
-- ### 1.1. Define or set the **Mission**:
|
-- ## 1.1. Create a command center.
|
||||||
--
|
--
|
||||||
-- Tasking is executed to accomplish missions. Therefore, a MISSION object needs to be given as the first parameter.
|
-- First you need to create a command center using the @{Tasking.CommandCenter#COMMANDCENTER.New}() constructor.
|
||||||
--
|
--
|
||||||
-- local HQ = GROUP:FindByName( "HQ", "Bravo" )
|
-- local CommandCenter = COMMANDCENTER
|
||||||
-- local CommandCenter = COMMANDCENTER:New( HQ, "Lima" )
|
-- :New( HQ, "Lima" ) -- Create the CommandCenter.
|
||||||
-- local Mission = MISSION:New( CommandCenter, "A2A Mission", "High", "Watch the air enemy units being detected.", coalition.side.RED )
|
|
||||||
--
|
|
||||||
-- Missions are governed by COMMANDCENTERS, so, ensure you have a COMMANDCENTER object installed and setup within your mission.
|
|
||||||
-- Create the MISSION object, and hook it under the command center.
|
|
||||||
--
|
|
||||||
-- ### 1.2. Build a set of the groups seated by human players:
|
|
||||||
--
|
|
||||||
-- 
|
|
||||||
--
|
|
||||||
-- A set or collection of the groups wherein human players can be seated, these can be clients or units that can be joined as a slot or jumping into.
|
|
||||||
--
|
--
|
||||||
-- local AttackGroups = SET_GROUP:New():FilterCoalitions( "red" ):FilterPrefixes( "Defender" ):FilterStart()
|
-- ## 1.2. Create a mission.
|
||||||
--
|
|
||||||
-- The set is built using the SET_GROUP class. Apply any filter criteria to identify the correct groups for your mission.
|
|
||||||
-- Only these slots or units will be able to execute the mission and will receive tasks for this mission, once available.
|
|
||||||
--
|
--
|
||||||
-- ### 1.3. Define the **EWR network**:
|
-- Tasks work in a mission, which groups these tasks to achieve a joint mission goal.
|
||||||
|
-- A command center can govern multiple missions.
|
||||||
|
-- Create a new mission, using the @{Tasking.Mission#MISSION.New}() constructor.
|
||||||
--
|
--
|
||||||
-- As part of the TASK\_A2A\_DISPATCHER constructor, an EWR network must be given as the third parameter.
|
-- -- Declare the Mission for the Command Center.
|
||||||
-- An EWR network, or, Early Warning Radar network, is used to early detect potential airborne targets and to understand the position of patrolling targets of the enemy.
|
-- local Mission = MISSION
|
||||||
|
-- :New( CommandCenter,
|
||||||
|
-- "Overlord",
|
||||||
|
-- "High",
|
||||||
|
-- "Transport the cargo.",
|
||||||
|
-- coalition.side.RED
|
||||||
|
-- )
|
||||||
--
|
--
|
||||||
-- 
|
|
||||||
--
|
--
|
||||||
-- Typically EWR networks are setup using 55G6 EWR, 1L13 EWR, Hawk sr and Patriot str ground based radar units.
|
-- # 2. Dispatch a **transport cargo** task.
|
||||||
-- These radars have different ranges and 55G6 EWR and 1L13 EWR radars are Eastern Bloc units (eg Russia, Ukraine, Georgia) while the Hawk and Patriot radars are Western (eg US).
|
|
||||||
-- Additionally, ANY other radar capable unit can be part of the EWR network! Also AWACS airborne units, planes, helicopters can help to detect targets, as long as they have radar.
|
|
||||||
-- The position of these units is very important as they need to provide enough coverage
|
|
||||||
-- to pick up enemy aircraft as they approach so that CAP and GCI flights can be tasked to intercept them.
|
|
||||||
--
|
--
|
||||||
-- 
|
-- So, now that we have a command center and a mission, we now create the transport task.
|
||||||
|
-- We create the transport task using the @{#TASK_CARGO_DISPATCHER.AddTransportTask}() constructor.
|
||||||
|
--
|
||||||
|
-- ## 2.1. Create the cargo in the mission.
|
||||||
|
--
|
||||||
|
-- Because a transport task will not generate the cargo itself, you'll need to create it first.
|
||||||
|
--
|
||||||
|
-- -- Here we define the "cargo set", which is a collection of cargo objects.
|
||||||
|
-- -- The cargo set will be the input for the cargo transportation task.
|
||||||
|
-- -- So a transportation object is handling a cargo set, which is automatically updated when new cargo is added/deleted.
|
||||||
|
-- local WorkmaterialsCargoSet = SET_CARGO:New():FilterTypes( "Workmaterials" ):FilterStart()
|
||||||
|
--
|
||||||
|
-- -- Now we add cargo into the battle scene.
|
||||||
|
-- local PilotGroup = GROUP:FindByName( "Engineers" )
|
||||||
|
--
|
||||||
|
-- -- CARGO_GROUP can be used to setup cargo with a GROUP object underneath.
|
||||||
|
-- -- We name the type of this group "Workmaterials", so that this cargo group will be included within the WorkmaterialsCargoSet.
|
||||||
|
-- -- Note that the name of the cargo is "Engineer Team 1".
|
||||||
|
-- local CargoGroup = CARGO_GROUP:New( PilotGroup, "Workmaterials", "Engineer Team 1", 500 )
|
||||||
|
--
|
||||||
|
-- What is also needed, is to have a set of @{Core.Group}s defined that contains the clients of the players.
|
||||||
|
--
|
||||||
|
-- -- Allocate the Transport, which are the helicopters to retrieve the pilot, that can be manned by players.
|
||||||
|
-- -- The name of these helicopter groups containing one client begins with "Transport", as modelled within the mission editor.
|
||||||
|
-- local PilotGroupSet = SET_GROUP:New():FilterPrefixes( "Transport" ):FilterStart()
|
||||||
|
--
|
||||||
|
-- ## 2.2. Setup the cargo transport task.
|
||||||
|
--
|
||||||
|
-- First, we need to create a TASK_CARGO_DISPATCHER object.
|
||||||
|
--
|
||||||
|
-- TaskDispatcher = TASK_CARGO_DISPATCHER:New( Mission, PilotGroupSet )
|
||||||
|
--
|
||||||
|
-- So, the variable `TaskDispatcher` will contain the object of class TASK_CARGO_DISPATCHER, which will allow you to dispatch cargo transport tasks:
|
||||||
--
|
--
|
||||||
-- Additionally in a hot war situation where the border is no longer respected the placement of radars has a big effect on how fast the war escalates.
|
-- * for mission `Mission`.
|
||||||
-- For example if they are a long way forward and can detect enemy planes on the ground and taking off
|
-- * for the group set `PilotGroupSet`.
|
||||||
-- they will start to vector CAP and GCI flights to attack them straight away which will immediately draw a response from the other coalition.
|
|
||||||
-- Having the radars further back will mean a slower escalation because fewer targets will be detected and
|
|
||||||
-- therefore less CAP and GCI flights will spawn and this will tend to make just the border area active rather than a melee over the whole map.
|
|
||||||
-- It all depends on what the desired effect is.
|
|
||||||
--
|
--
|
||||||
-- EWR networks are **dynamically constructed**, that is, they form part of the @{Functional.Detection#DETECTION_BASE} object that is given as the input parameter of the TASK\_A2A\_DISPATCHER class.
|
-- Now that we have `TaskDispatcher` object, we can now **create the TransportTask**, using the @{#TASK_CARGO_DISPATCHER.AddTransportTask}() method!
|
||||||
-- By defining in a **smart way the names or name prefixes of the groups** with EWR capable units, these groups will be **automatically added or deleted** from the EWR network,
|
|
||||||
-- increasing or decreasing the radar coverage of the Early Warning System.
|
|
||||||
--
|
--
|
||||||
-- See the following example to setup an EWR network containing EWR stations and AWACS.
|
-- local TransportTask = TaskDispatcher:AddTransportTask(
|
||||||
|
-- "Transport workmaterials",
|
||||||
|
-- WorkmaterialsCargoSet,
|
||||||
|
-- "Transport the workers, engineers and the equipment near the Workplace." )
|
||||||
--
|
--
|
||||||
-- local EWRSet = SET_GROUP:New():FilterPrefixes( "EWR" ):FilterCoalitions("red"):FilterStart()
|
-- As a result of this code, the `TransportTask` (returned) variable will contain an object of @{#TASK_CARGO_TRANSPORT}!
|
||||||
--
|
-- We pass to the method the title of the task, and the `WorkmaterialsCargoSet`, which is the set of cargo groups to be transported!
|
||||||
-- local EWRDetection = DETECTION_AREAS:New( EWRSet, 6000 )
|
-- This object can also be used to setup additional things, or to control this specific task with special actions.
|
||||||
-- EWRDetection:SetFriendliesRange( 10000 )
|
|
||||||
-- EWRDetection:SetRefreshTimeInterval(30)
|
|
||||||
--
|
|
||||||
-- -- Setup the A2A dispatcher, and initialize it.
|
|
||||||
-- A2ADispatcher = TASK_CARGO_DISPATCHER:New( Mission, AttackGroups, EWRDetection )
|
|
||||||
--
|
--
|
||||||
-- The above example creates a SET_GROUP instance, and stores this in the variable (object) **EWRSet**.
|
-- And you're done! As you can see, it is a bit of work, but the reward is great.
|
||||||
-- **EWRSet** is then being configured to filter all active groups with a group name starting with **EWR** to be included in the Set.
|
-- And, because all this is done using program interfaces, you can build a mission with a **dynamic cargo transport task mechanism** yourself!
|
||||||
-- **EWRSet** is then being ordered to start the dynamic filtering. Note that any destroy or new spawn of a group with the above names will be removed or added to the Set.
|
-- Based on events happening within your mission, you can use the above methods to create new cargo, and setup a new task for cargo transportation to a group of players!
|
||||||
-- Then a new **EWRDetection** object is created from the class DETECTION_AREAS. A grouping radius of 6000 is choosen, which is 6km.
|
|
||||||
-- The **EWRDetection** object is then passed to the @{#TASK_CARGO_DISPATCHER.New}() method to indicate the EWR network configuration and setup the A2A tasking and detection mechanism.
|
|
||||||
--
|
--
|
||||||
-- ### 2. Define the detected **target grouping radius**:
|
|
||||||
--
|
|
||||||
-- 
|
|
||||||
--
|
|
||||||
-- The target grouping radius is a property of the Detection object, that was passed to the AI\_A2A\_DISPATCHER object, but can be changed.
|
|
||||||
-- The grouping radius should not be too small, but also depends on the types of planes and the era of the simulation.
|
|
||||||
-- Fast planes like in the 80s, need a larger radius than WWII planes.
|
|
||||||
-- Typically I suggest to use 30000 for new generation planes and 10000 for older era aircraft.
|
|
||||||
--
|
|
||||||
-- Note that detected targets are constantly re-grouped, that is, when certain detected aircraft are moving further than the group radius, then these aircraft will become a separate
|
|
||||||
-- group being detected. This may result in additional GCI being started by the dispatcher! So don't make this value too small!
|
|
||||||
--
|
|
||||||
-- ## 3. Set the **Engage radius**:
|
|
||||||
--
|
|
||||||
-- Define the radius to engage any target by airborne friendlies, which are executing cap or returning from an intercept mission.
|
|
||||||
--
|
|
||||||
-- 
|
|
||||||
--
|
|
||||||
-- So, if there is a target area detected and reported,
|
|
||||||
-- then any friendlies that are airborne near this target area,
|
|
||||||
-- will be commanded to (re-)engage that target when available (if no other tasks were commanded).
|
|
||||||
-- For example, if 100000 is given as a value, then any friendly that is airborne within 100km from the detected target,
|
|
||||||
-- will be considered to receive the command to engage that target area.
|
|
||||||
-- You need to evaluate the value of this parameter carefully.
|
|
||||||
-- If too small, more intercept missions may be triggered upon detected target areas.
|
|
||||||
-- If too large, any airborne cap may not be able to reach the detected target area in time, because it is too far.
|
|
||||||
--
|
|
||||||
-- ## 4. Set **Scoring** and **Messages**:
|
|
||||||
--
|
|
||||||
-- The TASK\_A2A\_DISPATCHER is a state machine. It triggers the event Assign when a new player joins a @{Task} dispatched by the TASK\_A2A\_DISPATCHER.
|
|
||||||
-- An _event handler_ can be defined to catch the **Assign** event, and add **additional processing** to set _scoring_ and to _define messages_,
|
|
||||||
-- when the player reaches certain achievements in the task.
|
|
||||||
--
|
|
||||||
-- The prototype to handle the **Assign** event needs to be developed as follows:
|
|
||||||
--
|
|
||||||
-- TaskDispatcher = TASK_CARGO_DISPATCHER:New( ... )
|
|
||||||
--
|
|
||||||
-- --- @param #TaskDispatcher self
|
|
||||||
-- -- @param #string From Contains the name of the state from where the Event was triggered.
|
|
||||||
-- -- @param #string Event Contains the name of the event that was triggered. In this case Assign.
|
|
||||||
-- -- @param #string To Contains the name of the state that will be transitioned to.
|
|
||||||
-- -- @param Tasking.Task_A2A#TASK_A2A Task The Task object, which is any derived object from TASK_A2A.
|
|
||||||
-- -- @param Wrapper.Unit#UNIT TaskUnit The Unit or Client that contains the Player.
|
|
||||||
-- -- @param #string PlayerName The name of the Player that joined the TaskUnit.
|
|
||||||
-- function TaskDispatcher:OnAfterAssign( From, Event, To, Task, TaskUnit, PlayerName )
|
|
||||||
-- Task:SetScoreOnProgress( PlayerName, 20, TaskUnit )
|
|
||||||
-- Task:SetScoreOnSuccess( PlayerName, 200, TaskUnit )
|
|
||||||
-- Task:SetScoreOnFail( PlayerName, -100, TaskUnit )
|
|
||||||
-- end
|
|
||||||
--
|
|
||||||
-- The **OnAfterAssign** method (function) is added to the TaskDispatcher object.
|
|
||||||
-- This method will be called when a new player joins a unit in the set of groups in scope of the dispatcher.
|
|
||||||
-- So, this method will be called only **ONCE** when a player joins a unit in scope of the task.
|
|
||||||
--
|
|
||||||
-- The TASK class implements various methods to additional **set scoring** for player achievements:
|
|
||||||
--
|
|
||||||
-- * @{Tasking.Task#TASK.SetScoreOnProgress}() will add additional scores when a player achieves **Progress** while executing the task.
|
|
||||||
-- Examples of **task progress** can be destroying units, arriving at zones etc.
|
|
||||||
--
|
|
||||||
-- * @{Tasking.Task#TASK.SetScoreOnSuccess}() will add additional scores when the task goes into **Success** state.
|
|
||||||
-- This means the **task has been successfully completed**.
|
|
||||||
--
|
--
|
||||||
-- * @{Tasking.Task#TASK.SetScoreOnSuccess}() will add additional (negative) scores when the task goes into **Failed** state.
|
-- # 3. Dispatch CSAR tasks.
|
||||||
-- This means the **task has not been successfully completed**, and the scores must be given with a negative value!
|
--
|
||||||
|
-- CSAR tasks can be dynamically created when a friendly pilot ejects, or can be created manually.
|
||||||
|
-- We'll explore both options.
|
||||||
|
--
|
||||||
|
-- ## 3.1. CSAR task dynamic creation.
|
||||||
|
--
|
||||||
|
-- Because there is an "event" in a running simulation that creates CSAR tasks, the method @{#TASK_CARGO_DISPATCHER.StartCSARTasks}() will create automatically:
|
||||||
|
--
|
||||||
|
-- 1. a new downed pilot at the location where the plane was shot
|
||||||
|
-- 2. declare that pilot as cargo
|
||||||
|
-- 3. creates a CSAR task automatically to retrieve that pilot
|
||||||
|
-- 4. requires deploy zones to be specified where to transport the downed pilot to, in order to complete that task.
|
||||||
|
--
|
||||||
|
-- You create a CSAR task dynamically in a very easy way:
|
||||||
|
--
|
||||||
|
-- TaskDispatcher:StartCSARTasks(
|
||||||
|
-- "CSAR",
|
||||||
|
-- { ZONE_UNIT:New( "Hospital", STATIC:FindByName( "Hospital" ), 100 ) },
|
||||||
|
-- "One of our pilots has ejected. Go out to Search and Rescue our pilot!\n" ..
|
||||||
|
-- "Use the radio menu to let the command center assist you with the CSAR tasking."
|
||||||
|
-- )
|
||||||
|
--
|
||||||
|
-- The method @{#TASK_CARGO_DISPATCHER.StopCSARTasks}() will automatically stop with the creation of CSAR tasks when friendly pilots eject.
|
||||||
|
--
|
||||||
|
-- **Remarks:**
|
||||||
|
--
|
||||||
|
-- * the ZONE_UNIT can also be a ZONE, or a ZONE_POLYGON object, or any other ZONE_ object!
|
||||||
|
-- * you can declare the array of zones in another variable, or course!
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- ## 3.2. CSAR task manual creation.
|
||||||
|
--
|
||||||
|
-- We create the CSAR task using the @{#TASK_CARGO_DISPATCHER.AddCSARTask}() constructor.
|
||||||
|
--
|
||||||
|
-- The method will create a new CSAR task, and will generate the pilots cargo itself, at the specified coordinate.
|
||||||
|
--
|
||||||
|
-- What is first needed, is to have a set of @{Core.Group}s defined that contains the clients of the players.
|
||||||
|
--
|
||||||
|
-- -- Allocate the Transport, which are the helicopter to retrieve the pilot, that can be manned by players.
|
||||||
|
-- local GroupSet = SET_GROUP:New():FilterPrefixes( "Transport" ):FilterStart()
|
||||||
|
--
|
||||||
|
-- We need to create a TASK_CARGO_DISPATCHER object.
|
||||||
|
--
|
||||||
|
-- TaskDispatcher = TASK_CARGO_DISPATCHER:New( Mission, GroupSet )
|
||||||
|
--
|
||||||
|
-- So, the variable `TaskDispatcher` will contain the object of class TASK_CARGO_DISPATCHER, which will allow you to dispatch cargo CSAR tasks:
|
||||||
|
--
|
||||||
|
-- * for mission `Mission`.
|
||||||
|
-- * for the group of players (pilots) captured within the `GroupSet` (those groups with a name starting with `"Transport"`).
|
||||||
|
--
|
||||||
|
-- Now that we have a PilotsCargoSet and a GroupSet, we can now create the CSAR task manually.
|
||||||
|
--
|
||||||
|
-- -- Declare the CSAR task.
|
||||||
|
-- local CSARTask = TaskDispatcher:AddCSARTask(
|
||||||
|
-- "CSAR Task",
|
||||||
|
-- Coordinate,
|
||||||
|
-- 270,
|
||||||
|
-- "Bring the pilot back!"
|
||||||
|
-- )
|
||||||
|
--
|
||||||
|
-- As a result of this code, the `CSARTask` (returned) variable will contain an object of @{#TASK_CARGO_CSAR}!
|
||||||
|
-- We pass to the method the title of the task, and the `WorkmaterialsCargoSet`, which is the set of cargo groups to be transported!
|
||||||
|
-- This object can also be used to setup additional things, or to control this specific task with special actions.
|
||||||
|
-- Note that when you declare a CSAR task manually, you'll still need to specify a deployment zone!
|
||||||
|
--
|
||||||
|
-- # 4. Setup the deploy zone(s).
|
||||||
|
--
|
||||||
|
-- The task cargo dispatcher also foresees methods to setup the deployment zones to where the cargo needs to be transported!
|
||||||
|
--
|
||||||
|
-- There are two levels on which deployment zones can be configured:
|
||||||
|
--
|
||||||
|
-- * Default deploy zones: The TASK_CARGO_DISPATCHER object can have default deployment zones, which will apply over all tasks active in the task dispatcher.
|
||||||
|
-- * Task specific deploy zones: The TASK_CARGO_DISPATCHER object can have specific deployment zones which apply to a specific task only!
|
||||||
|
--
|
||||||
|
-- Note that for Task specific deployment zones, there are separate deployment zone creation methods per task type!
|
||||||
|
--
|
||||||
|
-- ## 4.1. Setup default deploy zones.
|
||||||
|
--
|
||||||
|
-- Use the @{#TASK_CARGO_DISPATCHER.SetDefaultDeployZone}() to setup one deployment zone, and @{#TASK_CARGO_DISPATCHER.SetDefaultDeployZones}() to setup multiple default deployment zones in one call.
|
||||||
|
--
|
||||||
|
-- ## 4.2. Setup task specific deploy zones for a **transport task**.
|
||||||
|
--
|
||||||
|
-- Use the @{#TASK_CARGO_DISPATCHER.SetTransportDeployZone}() to setup one deployment zone, and @{#TASK_CARGO_DISPATCHER.SetTransportDeployZones}() to setup multiple default deployment zones in one call.
|
||||||
|
--
|
||||||
|
-- ## 4.3. Setup task specific deploy zones for a **CSAR task**.
|
||||||
|
--
|
||||||
|
-- Use the @{#TASK_CARGO_DISPATCHER.SetCSARDeployZone}() to setup one deployment zone, and @{#TASK_CARGO_DISPATCHER.SetCSARDeployZones}() to setup multiple default deployment zones in one call.
|
||||||
|
--
|
||||||
|
--
|
||||||
--
|
--
|
||||||
-- @field #TASK_CARGO_DISPATCHER
|
-- @field #TASK_CARGO_DISPATCHER
|
||||||
TASK_CARGO_DISPATCHER = {
|
TASK_CARGO_DISPATCHER = {
|
||||||
@@ -321,11 +415,11 @@ do -- TASK_CARGO_DISPATCHER
|
|||||||
--
|
--
|
||||||
-- -- Add a CSAR task to rescue a downed pilot from within a coordinate.
|
-- -- Add a CSAR task to rescue a downed pilot from within a coordinate.
|
||||||
-- local Coordinate = PlaneUnit:GetPointVec2()
|
-- local Coordinate = PlaneUnit:GetPointVec2()
|
||||||
-- TaskA2ADispatcher:AddCSARTask( Coordinate )
|
-- TaskA2ADispatcher:AddCSARTask( "CSAR Task", Coordinate )
|
||||||
--
|
--
|
||||||
-- -- Add a CSAR task to rescue a downed pilot from within a coordinate of country RUSSIA, which is pointing to the west (270°).
|
-- -- Add a CSAR task to rescue a downed pilot from within a coordinate of country RUSSIA, which is pointing to the west (270°).
|
||||||
-- local Coordinate = PlaneUnit:GetPointVec2()
|
-- local Coordinate = PlaneUnit:GetPointVec2()
|
||||||
-- TaskA2ADispatcher:AddCSARTask( Coordinate, 270, Country.RUSSIA )
|
-- TaskA2ADispatcher:AddCSARTask( "CSAR Task", Coordinate, 270, Country.RUSSIA )
|
||||||
--
|
--
|
||||||
function TASK_CARGO_DISPATCHER:AddCSARTask( CSARTaskPrefix, CSARCoordinate, CSARHeading, CSARCountry, CSARBriefing )
|
function TASK_CARGO_DISPATCHER:AddCSARTask( CSARTaskPrefix, CSARCoordinate, CSARHeading, CSARCountry, CSARBriefing )
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user