Add support for naval logistics

This commit is contained in:
acrojason 2020-12-31 10:15:32 -08:00
parent 4b8b13dd68
commit 1b80d68f50
7 changed files with 398 additions and 118 deletions

View File

@ -1,10 +1,166 @@
--- **AI** -- (2.5.1) - Models the intelligent transportation of infantry and other cargo using Ships --- **AI** -- (2.5.1) - Models the intelligent transportation of infantry and other cargo using Ships
--
-- ## Features:
--
-- * Transport cargo to various deploy zones using naval vehicles.
-- * Various @{Cargo.Cargo#CARGO} types can be transported, including infantry, vehicles, and crates.
-- * Define a deploy zone of various types to determine the destination of the cargo.
-- * Ships will follow shipping lanes as defined in the Mission Editor.
-- * Multiple ships can transport multiple cargo as a single group.
--
-- ===
--
-- ## Test Missions:
--
-- NEED TO DO
--
-- ===
--
-- ### Author: **acrojason** (derived from AI_Cargo_Dispatcher_APC by FlightControl)
--
-- ===
--
-- @module AI.AI_Cargo_Dispatcher_Ship
-- @image AI_Cargo_Dispatching_For_Ship.JPG
--- @type AI_CARGO_DISPATCHER_SHIP
-- @extends AI.AI_Cargo_Dispatcher#AI_CARGO_DISPATCHER
--- A dynamic cargo transportation capability for AI groups.
--
-- Naval vessels can be mobilized to semi-intelligently transport cargo within the simulation.
--
-- The AI_CARGO_DISPATCHER_SHIP module is derived from the AI_CARGO_DISPATCHER module.
--
-- ## Note! In order to fully understand the mechanisms of the AI_CARGO_DISPATCHER_SHIP class, it is recommended that you first consult and READ the documentation of the @{AI.AI_Cargo_Dispatcher} module!!!
--
-- This will be particularly helpful in order to determine how to **Tailor the different cargo handling events**.
--
-- The AI_CARGO_DISPATCHER_SHIP class uses the @{Cargo.Cargo} capabilities within the MOOSE framwork.
-- Also ensure that you fully understand how to declare and setup Cargo objects within the MOOSE framework before using this class.
-- CARGO derived objects must generally be declared within the mission to make the AI_CARGO_DISPATCHER_SHIP object recognize the cargo.
--
--
-- # 1) AI_CARGO_DISPATCHER_SHIP constructor.
--
-- * @{AI_CARGO_DISPATCHER_SHIP.New}(): Creates a new AI_CARGO_DISPATCHER_SHIP object.
--
-- ---
--
-- # 2) AI_CARGO_DISPATCHER_SHIP is a Finite State Machine.
--
-- This section must be read as follows... Each of the rows indicate a state transition, triggered through an event, and with an ending state of the event was executed.
-- The first column is the **From** state, the second column the **Event**, and the third column the **To** state.
--
-- So, each of the rows have the following structure.
--
-- * **From** => **Event** => **To**
--
-- Important to know is that an event can only be executed if the **current state** is the **From** state.
-- This, when an **Event** that is being triggered has a **From** state that is equal to the **Current** state of the state machine, the event will be executed,
-- and the resulting state will be the **To** state.
--
-- These are the different possible state transitions of this state machine implementation:
--
-- * Idle => Start => Monitoring
-- * Monitoring => Monitor => Monitoring
-- * Monitoring => Stop => Idle
--
-- * Monitoring => Pickup => Monitoring
-- * Monitoring => Load => Monitoring
-- * Monitoring => Loading => Monitoring
-- * Monitoring => Loaded => Monitoring
-- * Monitoring => PickedUp => Monitoring
-- * Monitoring => Deploy => Monitoring
-- * Monitoring => Unload => Monitoring
-- * Monitoring => Unloaded => Monitoring
-- * Monitoring => Deployed => Monitoring
-- * Monitoring => Home => Monitoring
--
--
-- ## 2.1) AI_CARGO_DISPATCHER States.
--
-- * **Monitoring**: The process is dispatching.
-- * **Idle**: The process is idle.
--
-- ## 2.2) AI_CARGO_DISPATCHER Events.
--
-- * **Start**: Start the transport process.
-- * **Stop**: Stop the transport process.
-- * **Monitor**: Monitor and take action.
--
-- * **Pickup**: Pickup cargo.
-- * **Load**: Load the cargo.
-- * **Loading**: The dispatcher is coordinating the loading of a cargo.
-- * **Loaded**: Flag that the cargo is loaded.
-- * **PickedUp**: The dispatcher has loaded all requested cargo into the CarrierGroup.
-- * **Deploy**: Deploy cargo to a location.
-- * **Unload**: Unload the cargo.
-- * **Unloaded**: Flag that the cargo is unloaded.
-- * **Deployed**: All cargo is unloaded from the carriers in the group.
-- * **Home**: A Carrier is going home.
--
-- ## 2.3) Enhance your mission scripts with **Tailored** Event Handling!
--
-- Within your mission, you can capture these events when triggered, and tailor the events with your own code!
-- Check out the @{AI.AI_Cargo_Dispatcher#AI_CARGO_DISPATCHER} class at chapter 3 for details on the different event handlers that are available and how to use them.
--
-- **There are a lot of templates available that allows you to quickly setup an event handler for a specific event type!**
--
-- ---
--
-- # 3) Set the pickup parameters.
--
-- Several parameters can be set to pickup cargo:
--
-- * @{#AI_CARGO_DISPATCHER_SHIP.SetPickupRadius}(): Sets or randomizes the pickup location for the Ship around the cargo coordinate in a radius defined an outer and optional inner radius.
-- * @{#AI_CARGO_DISPATCHER_SHIP.SetPickupSpeed}(): Set the speed or randomizes the speed in km/h to pickup the cargo.
--
-- # 4) Set the deploy parameters.
--
-- Several parameters can be set to deploy cargo:
--
-- * @{#AI_CARGO_DISPATCHER_SHIP.SetDeployRadius}(): Sets or randomizes the deploy location for the Ship around the cargo coordinate in a radius defined an outer and an optional inner radius.
-- * @{#AI_CARGO_DISPATCHER_SHIP.SetDeploySpeed}(): Set the speed or randomizes the speed in km/h to deploy the cargo.
--
-- # 5) Set the home zone when there isn't any more cargo to pickup.
--
-- A home zone can be specified to where the Ship will move when there isn't any cargo left for pickup.
-- Use @{#AI_CARGO_DISPATCHER_SHIP.SetHomeZone}() to specify the home zone.
--
-- If no home zone is specified, the Ship will wait near the deploy zone for a new pickup command.
--
-- ===
--
-- @field #AI_CARGO_DISPATCHER_SHIP -- @field #AI_CARGO_DISPATCHER_SHIP
AI_CARGO_DISPATCHER_SHIP = { AI_CARGO_DISPATCHER_SHIP = {
ClassName = "AI_CARGO_DISPATCHER_SHIP" ClassName = "AI_CARGO_DISPATCHER_SHIP"
} }
--- Creates a new AI_CARGO_DISPATCHER_SHIP object.
-- @param #AI_CARGO_DISPATCHER_SHIP self
-- @param Core.Set#SET_GROUP ShipSet The set of @{Wrapper.Group#GROUP} objects of Ships that will transport the cargo
-- @param Core.Set#SET_CARGO CargoSet The set of @{Cargo.Cargo#CARGO} objects, which can be CARGO_GROUP, CARGO_CRATE, or CARGO_SLINGLOAD objects.
-- @param Core.Set#SET_ZONE PickupZoneSet The set of pickup zones which are used to determine from where the cargo can be picked up by the Ship.
-- @param Core.Set#SET_ZONE DeployZoneSet The set of deploy zones which determine where the cargo will be deployed by the Ship.
-- @param #table ShippingLane Table containing list of Shipping Lanes to be used
-- @return #AI_CARGO_DISPATCHER_SHIP
-- @usage
--
-- -- An AI dispatcher object for a naval group, moving cargo from pickup zones to deploy zones via a predetermined Shipping Lane
--
-- local SetCargoInfantry = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart()
-- local SetShip = SET_GROUP:New():FilterPrefixes( "Ship" ):FilterStart()
-- local SetPickupZones = SET_ZONE:New():FilterPrefixes( "Pickup" ):FilterStart()
-- local SetDeployZones = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart()
-- NEED MORE THOUGHT - ShippingLane is part of Warehouse.......
-- local ShippingLane = GROUP:New():FilterPrefixes( "ShippingLane" ):FilterStart()
--
-- AICargoDispatcherShip = AI_CARGO_DISPATCHER_SHIP:New( SetShip, SetCargoInfantry, SetPickupZones, SetDeployZones, ShippingLane )
-- AICargoDispatcherShip:Start()
--
function AI_CARGO_DISPATCHER_SHIP:New( ShipSet, CargoSet, PickupZoneSet, DeployZoneSet, ShippingLane ) function AI_CARGO_DISPATCHER_SHIP:New( ShipSet, CargoSet, PickupZoneSet, DeployZoneSet, ShippingLane )
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:New( ShipSet, CargoSet, PickupZoneSet, DeployZoneSet ) ) local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:New( ShipSet, CargoSet, PickupZoneSet, DeployZoneSet ) )
@ -12,8 +168,8 @@ AI_CARGO_DISPATCHER_SHIP = {
self:SetPickupSpeed( 60, 10 ) self:SetPickupSpeed( 60, 10 )
self:SetDeploySpeed( 60, 10 ) self:SetDeploySpeed( 60, 10 )
self:SetPickupRadius( 500, 3000 ) self:SetPickupRadius( 500, 6000 )
self:SetDeployRadius( 500, 3000 ) self:SetDeployRadius( 500, 6000 )
self:SetPickupHeight( 0, 0 ) self:SetPickupHeight( 0, 0 )
self:SetDeployHeight( 0, 0 ) self:SetDeployHeight( 0, 0 )

View File

@ -1,5 +1,60 @@
--- **AI** -- (R2.5.1) - Models the intelligent transportation of infantry and other cargo. --- **AI** -- (R2.5.1) - Models the intelligent transportation of infantry and other cargo.
--
-- ===
--
-- ### Author: **acrojason** (derived from AI_Cargo_APC by FlightControl)
--
-- ===
--
-- @module AI.AI_Cargo_Ship
-- @image AI_Cargo_Dispatching_For_Ship.JPG
--- @type AI_CARGO_SHIP
-- @extends AI.AI_Cargo#AI_CARGO
--- Brings a dynamic cargo handling capability for an AI naval group.
--
-- Naval ships can be utilized to transport cargo around the map following naval shipping lanes.
-- The AI_CARGO_SHIP class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
-- @{Cargo.Cargo} must be declared within the mission or warehouse to make the AI_CARGO_SHIP recognize the cargo.
-- Please consult the @{Cargo.Cargo} module for more information.
--
-- ## Cargo loading.
--
-- The module will automatically load cargo when the Ship is within boarding or loading radius.
-- The boarding or loading radius is specified when the cargo is created in the simulation and depends on the type of
-- cargo and the specified boarding radius.
--
-- ## Defending the Ship when enemies are nearby
-- This is not supported for naval cargo because most tanks don't float. Protect your transports...
--
-- ## Infantry or cargo **health**.
-- When cargo is unboarded from the Ship, the cargo is actually respawned into the battlefield.
-- As a result, the unboarding cargo is very _healthy_ every time it unboards.
-- This is due to the limitation of the DCS simulator, which is not able to specify the health of newly spawned units as a parameter.
-- However, cargo that was destroyed when unboarded and following the Ship won't be respawned again (this is likely not a thing for
-- naval cargo due to the lack of support for defending the Ship mentioned above). Destroyed is destroyed.
-- As a result, there is some additional strength that is gained when an unboarding action happens, but in terms of simulation balance
-- this has marginal impact on the overall battlefield simulation. Given the relatively short duration of DCS missions and the somewhat
-- lengthy naval transport times, most units entering the Ship as cargo will be freshly en route to an amphibious landing or transporting
-- between warehouses.
--
-- ## Control the Ships on the map.
--
-- Currently, naval transports can only be controlled via scripts due to their reliance upon predefined Shipping Lanes created in the Mission
-- Editor. An interesting future enhancement could leverage new pathfinding functionality for ships in the Ops module.
--
-- ## Cargo deployment.
--
-- Using the @{AI_CARGO_SHIP.Deploy}() method, you are able to direct the Ship towards a Deploy zone to unboard/unload the cargo at the
-- specified coordinate. The Ship will follow the Shipping Lane to ensure consistent cargo transportation within the simulation environment.
--
-- ## Cargo pickup.
--
-- Using the @{AI_CARGO_SHIP.Pickup}() method, you are able to direct the Ship towards a Pickup zone to board/load the cargo at the specified
-- coordinate. The Ship will follow the Shipping Lane to ensure consistent cargo transportation within the simulation environment.
--
--
-- @field #AI_CARGO_SHIP -- @field #AI_CARGO_SHIP
AI_CARGO_SHIP = { AI_CARGO_SHIP = {
ClassName = "AI_CARGO_SHIP", ClassName = "AI_CARGO_SHIP",
@ -7,16 +62,21 @@ AI_CARGO_SHIP = {
} }
--- Creates a new AI_CARGO_SHIP object. --- Creates a new AI_CARGO_SHIP object.
-- @param #AI_CARGO_SHIP self
-- @param Wrapper.Group#GROUP Ship The carrier Ship group
-- @param Core.Set#SET_CARGO CargoSet The set of cargo to be transported
-- @param #number CombatRadius Provide the combat radius to defend the carrier by unboarding the cargo when enemies are nearby. When CombatRadius is 0, no defense will occur.
-- @param #table ShippingLane Table containing list of Shipping Lanes to be used
-- @return #AI_CARGO_SHIP
function AI_CARGO_SHIP:New( Ship, CargoSet, CombatRadius, ShippingLane ) function AI_CARGO_SHIP:New( Ship, CargoSet, CombatRadius, ShippingLane )
local self = BASE:Inherit( self, AI_CARGO:New( Ship, CargoSet ) ) -- #AI_CARGO_SHIP local self = BASE:Inherit( self, AI_CARGO:New( Ship, CargoSet ) ) -- #AI_CARGO_SHIP
self:AddTransition( "*", "Monitor", "*" ) self:AddTransition( "*", "Monitor", "*" )
self:AddTransition( "*", "Destroyed", "Destroyed" ) self:AddTransition( "*", "Destroyed", "Destroyed" )
self:AddTransition( "*", "Home", "*" ) self:AddTransition( "*", "Home", "*" )
self:SetCombatRadius( CombatRadius ) self:SetCombatRadius( 0 ) -- Don't want to deploy cargo in middle of water to defend Ship, so set CombatRadius to 0
self:SetShippingLane ( ShippingLane ) self:SetShippingLane ( ShippingLane )
self:SetCarrier( Ship ) self:SetCarrier( Ship )
@ -100,7 +160,7 @@ end
-- @param Cargo.CargoGroup#CARGO_GROUP Cargo -- @param Cargo.CargoGroup#CARGO_GROUP Cargo
-- @return #AI_CARGO_SHIP -- @return #AI_CARGO_SHIP
function AI_CARGO_SHIP:FollowToCarrier( Me, ShipUnit, CargoGroup ) function AI_CARGO_SHIP:FollowToCarrier( Me, ShipUnit, CargoGroup )
BASE:T("DEBUGGING*** AI_CARGO_SHIP:FollowToCarrier")
local InfantryGroup = CargoGroup:GetGroup() local InfantryGroup = CargoGroup:GetGroup()
self:F( { self=self:GetClassNameAndID(), InfantryGroup = InfantryGroup:GetName() } ) self:F( { self=self:GetClassNameAndID(), InfantryGroup = InfantryGroup:GetName() } )
@ -147,6 +207,8 @@ function AI_CARGO_SHIP:onafterMonitor( Ship, From, Event, To )
self:F( { Ship, From, Event, To, IsTransporting = self:IsTransporting() } ) self:F( { Ship, From, Event, To, IsTransporting = self:IsTransporting() } )
if self.CombatRadius > 0 then if self.CombatRadius > 0 then
-- We really shouldn't find ourselves in here for Ships since the CombatRadius should always be 0.
-- This is to avoid Unloading the Ship in the middle of the sea.
if Ship and Ship:IsAlive() then if Ship and Ship:IsAlive() then
if self.CarrierCoordinate then if self.CarrierCoordinate then
if self:IsTransporting() == true then if self:IsTransporting() == true then
@ -197,8 +259,11 @@ function AI_CARGO_SHIP:onafterMonitor( Ship, From, Event, To )
end end
end end
--- Check if cargo ship is alive and trigger Load event
-- @param Wrapper.Group#Group Ship
-- @param #AI_CARGO_SHIP self
function AI_CARGO_SHIP._Pickup( Ship, self, Coordinate, Speed, PickupZone ) function AI_CARGO_SHIP._Pickup( Ship, self, Coordinate, Speed, PickupZone )
Ship:F( { "AI_CARGO_Ship._Pickup:", Ship:GetName() } ) Ship:F( { "AI_CARGO_Ship._Pickup:", Ship:GetName() } )
if Ship:IsAlive() then if Ship:IsAlive() then
@ -206,9 +271,10 @@ function AI_CARGO_SHIP._Pickup( Ship, self, Coordinate, Speed, PickupZone )
end end
end end
--- Check if cargo ship is alive and trigger Unload event. Good time to remind people that Lua is case sensitive and Unload != UnLoad
-- @param Wrapper.Group#GROUP Ship
-- @param #AI_CARGO_SHIP self
function AI_CARGO_SHIP._Deploy( Ship, self, Coordinate, DeployZone ) function AI_CARGO_SHIP._Deploy( Ship, self, Coordinate, DeployZone )
Ship:F( { "AI_CARGO_Ship._Deploy:", Ship } ) Ship:F( { "AI_CARGO_Ship._Deploy:", Ship } )
if Ship:IsAlive() then if Ship:IsAlive() then
@ -216,6 +282,15 @@ function AI_CARGO_SHIP._Deploy( Ship, self, Coordinate, DeployZone )
end end
end end
--- on after Pickup event.
-- @param AI_CARGO_SHIP Ship
-- @param From
-- @param Event
-- @param To
-- @param Core.Point#COORDINATE Coordinate of the pickup point
-- @param #number Speed Speed in km/h to sail to the pickup coordinate. Default is 50% of max speed for the unit
-- @param #number Height Altitude in meters to move to the pickup coordinate. This parameter is ignored for Ships
-- @param Core.Zone#ZONE PickupZone (optional) The zone where the cargo will be picked up. The PickupZone can be nil if there was no PickupZoneSet provided
function AI_CARGO_SHIP:onafterPickup( Ship, From, Event, To, Coordinate, Speed, Height, PickupZone ) function AI_CARGO_SHIP:onafterPickup( Ship, From, Event, To, Coordinate, Speed, Height, PickupZone )
if Ship and Ship:IsAlive() then if Ship and Ship:IsAlive() then
@ -224,12 +299,23 @@ function AI_CARGO_SHIP:onafterPickup( Ship, From, Event, To, Coordinate, Speed,
end end
end end
function AI_CARGO_SHIP:onafterPickedUp( Ship, From, Event, To, Coordinate, Speed, Height, PickupZone ) --- On after Deploy event.
-- @param #AI_CARGO_SHIP self
-- @param Wrapper.Group#GROUP SHIP
-- @param From
-- @param Event
-- @param To
-- @param Core.Point#COORDINATE Coordinate Coordinate of the deploy point
-- @param #number Speed Speed in km/h to sail to the deploy coordinate. Default is 50% of max speed for the unit
-- @param #number Height Altitude in meters to move to the deploy coordinate. This parameter is ignored for Ships
-- @param Core.Zone#ZONE DeployZone The zone where the cargo will be deployed.
function AI_CARGO_SHIP:onafterDeploy( Ship, From, Event, To, Coordinate, Speed, Height, DeployZone )
if Ship and Ship:IsAlive() then if Ship and Ship:IsAlive() then
Speed = Speed or Ship:GetSpeedMax()*0.8
Speed = Speed or Ship:GetSpeedMax()*0.8
local lane = self.ShippingLane local lane = self.ShippingLane
if lane then if lane then
local Waypoints = {} local Waypoints = {}
@ -239,40 +325,73 @@ function AI_CARGO_SHIP:onafterPickedUp( Ship, From, Event, To, Coordinate, Speed
table.insert(Waypoints, Waypoint) table.insert(Waypoints, Waypoint)
end end
local TaskFunction = Ship:TaskFunction( "AI_CARGO_SHIP._Deploy", self, Coordinate, DeployZone )
local Waypoint = Waypoints[#Waypoints] local Waypoint = Waypoints[#Waypoints]
Ship:SetTaskWaypoint( Waypoint, TaskFunction )
Ship:Route(Waypoints, 1) Ship:Route(Waypoints, 1)
self:GetParent( self, AI_CARGO_SHIP ).onafterDeploy( self, Ship, From, Event, To, Coordinate, Speed, Height, DeployZone )
else else
BASE:T("ERROR: No shipping lane defined for Naval Transport!") self:E(self.lid.."ERROR: No shipping lane defined for Naval Transport!")
end end
end end
end end
--- On after Unload event.
-- @param #AI_CARGO_SHIP self
-- @param Wrapper.Group#GROUP Ship
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Core.Zone#ZONE DeployZone The zone wherein the cargo is deployed. This can be any zone type, like a ZONE, ZONE_GROUP, ZONE_AIRBASE.
function AI_CARGO_SHIP:onafterUnload( Ship, From, Event, To, DeployZone, Defend )
self:F( { Ship, From, Event, To, DeployZone, Defend = Defend } )
local UnboardInterval = 5
local UnboardDelay = 5
if Ship and Ship:IsAlive() then
for _, ShipUnit in pairs( Ship:GetUnits() ) do
local ShipUnit = ShipUnit -- Wrapper.Unit#UNIT
Ship:RouteStop()
for _, Cargo in pairs( ShipUnit:GetCargo() ) do
self:F( { Cargo = Cargo:GetName(), Isloaded = Cargo:IsLoaded() } )
if Cargo:IsLoaded() then
local unboardCoord = DeployZone:GetRandomPointVec2()
Cargo:__UnBoard( UnboardDelay, unboardCoord, 1000)
UnboardDelay = UnboardDelay + Cargo:GetCount() * UnboardInterval
self:__Unboard( UnboardDelay, Cargo, ShipUnit, DeployZone, Defend )
if not Defend == true then
Cargo:SetDeployed( true )
end
end
end
end
end
end
function AI_CARGO_SHIP:onafterHome( Ship, From, Event, To, Coordinate, Speed, Height, HomeZone ) function AI_CARGO_SHIP:onafterHome( Ship, From, Event, To, Coordinate, Speed, Height, HomeZone )
if Ship and Ship:IsAlive() then if Ship and Ship:IsAlive() then
self.RouteHome = true self.RouteHome = true
Speed = Speed or Ship:GetSpeedMax()*0.8 Speed = Speed or Ship:GetSpeedMax()*0.8
local lane = self.ShippingLane local lane = self.ShippingLane
if lane then
if lane then
local Waypoints = {} local Waypoints = {}
for i=1, #lane do -- Need to find a more generalized way to do this instead of reversing the shipping lane.
-- This only works if the Source/Dest route waypoints are numbered 1..n and not n..1
for i=#lane, 1, -1 do
local coord = lane[i] local coord = lane[i]
local Waypoint = coord:WaypointGround(_speed) local Waypoint = coord:WaypointGround(_speed)
table.insert(Waypoints, Waypoint) table.insert(Waypoints, Waypoint)
end end
local Waypoint = Waypoints[#Waypoints] local Waypoint = Waypoints[#Waypoints]
Ship:Route(Waypoints, 1) Ship:Route(Waypoints, 1)
else else
BASE:T("ERROR: No shipping lane defined for Naval Transport!") self:E(self.lid.."ERROR: No shipping lane defined for Naval Transport!")
end end
end end
end end

View File

@ -100,7 +100,12 @@ do -- CARGO_UNIT
-- Respawn the group... -- Respawn the group...
if self.CargoObject then if self.CargoObject then
if CargoCarrier:IsShip() then
-- If CargoCarrier is a ship, we don't want to spawn the units in the water next to the boat. Use destination coord instead.
self.CargoObject:ReSpawnAt( ToPointVec2, CargoDeployHeading )
else
self.CargoObject:ReSpawnAt( FromPointVec2, CargoDeployHeading ) self.CargoObject:ReSpawnAt( FromPointVec2, CargoDeployHeading )
end
self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } ) self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } )
self.CargoCarrier = nil self.CargoCarrier = nil

View File

@ -1777,7 +1777,7 @@ WAREHOUSE.version="1.0.2"
-- TODO: Make more examples: ARTY, CAP, ... -- TODO: Make more examples: ARTY, CAP, ...
-- TODO: Check also general requests like all ground. Is this a problem for self propelled if immobile units are among the assets? Check if transport. -- TODO: Check also general requests like all ground. Is this a problem for self propelled if immobile units are among the assets? Check if transport.
-- TODO: Handle the case when units of a group die during the transfer. -- TODO: Handle the case when units of a group die during the transfer.
-- TODO: Added habours as interface for transport to from warehouses? Could make a rudimentary shipping dispatcher. -- DONE: Added harbours as interface for transport to/from warehouses. Simplifies process of spawning units near the ship, especially if cargo not self-propelled.
-- DONE: Test capturing a neutral warehouse. -- DONE: Test capturing a neutral warehouse.
-- DONE: Add save/load capability of warehouse <==> persistance after mission restart. Difficult in lua! -- DONE: Add save/load capability of warehouse <==> persistance after mission restart. Difficult in lua!
-- DONE: Get cargo bay and weight from CARGO_GROUP and GROUP. No necessary any more! -- DONE: Get cargo bay and weight from CARGO_GROUP and GROUP. No necessary any more!
@ -1830,7 +1830,6 @@ WAREHOUSE.version="1.0.2"
-- @param #string alias (Optional) Alias of the warehouse, i.e. the name it will be called when sending messages etc. Default is the name of the static -- @param #string alias (Optional) Alias of the warehouse, i.e. the name it will be called when sending messages etc. Default is the name of the static
-- @return #WAREHOUSE self -- @return #WAREHOUSE self
function WAREHOUSE:New(warehouse, alias) function WAREHOUSE:New(warehouse, alias)
BASE:T({warehouse=warehouse})
-- Check if just a string was given and convert to static. -- Check if just a string was given and convert to static.
if type(warehouse)=="string" then if type(warehouse)=="string" then
@ -4496,7 +4495,6 @@ function WAREHOUSE:onafterRequestSpawned(From, Event, To, Request, CargoGroupSet
-- Find asset belonging to this group. -- Find asset belonging to this group.
local asset=self:FindAssetInDB(_group) local asset=self:FindAssetInDB(_group)
BASE:T("DEBUGGING*** load radius: "..asset.loadradius)
-- New cargo group object. -- New cargo group object.
local cargogroup=CARGO_GROUP:New(_group, _cargotype,_group:GetName(),_boardradius, asset.loadradius) local cargogroup=CARGO_GROUP:New(_group, _cargotype,_group:GetName(),_boardradius, asset.loadradius)
@ -4556,7 +4554,8 @@ function WAREHOUSE:onafterRequestSpawned(From, Event, To, Request, CargoGroupSet
-- Pickup and deploy zones. -- Pickup and deploy zones.
local PickupZoneSet = SET_ZONE:New():AddZone(self.portzone) local PickupZoneSet = SET_ZONE:New():AddZone(self.portzone)
PickupZoneSet:AddZone(self.harborzone) PickupZoneSet:AddZone(self.harborzone)
local DeployZoneSet = SET_ZONE:New():AddZone(Request.warehouse.portzone) local DeployZoneSet = SET_ZONE:New():AddZone(Request.warehouse.harborzone)
-- Get the shipping lane to use and pass it to the Dispatcher -- Get the shipping lane to use and pass it to the Dispatcher
local remotename = Request.warehouse.warehouse:GetName() local remotename = Request.warehouse.warehouse:GetName()
@ -4583,21 +4582,6 @@ function WAREHOUSE:onafterRequestSpawned(From, Event, To, Request, CargoGroupSet
pickupinner=20 pickupinner=20
deployouter=1000 deployouter=1000
deployinner=0 deployinner=0
--BASE:T("DEBUGGING*** Let's try to move these units")
--[[for _,_group in pairs(CargoGroupSet:GetSetObjects()) do
local group=GROUP:FindByName( _group:GetName() ) --Wrapper.Group#GROUP
--local _speed = group:GetSpeedMax()*0.7
BASE:T("DEBUGGING*** Group ".._.." coordinate is "..CargoTransport:GetCoordinate())
--local FromCoord = group:GetCoordinate()
local ToCoord = CargoTransport:GetCoordinate()
local FromWP = FromCoord:WaypointGround()
local ToWP = ToCoord:WaypointGround( 15, "Vee" )
group:Route( { FromWP, ToWP }, 10 )
end]]--
else else
pickupouter=200 pickupouter=200
pickupinner=0 pickupinner=0
@ -4639,15 +4623,6 @@ function WAREHOUSE:onafterRequestSpawned(From, Event, To, Request, CargoGroupSet
-- Dispatcher Event Functions -- -- Dispatcher Event Functions --
-------------------------------- --------------------------------
--- Function called before carrier loads something
function CargoTransport:OnBeforeMonitor(From, Event, To, Carrier, Cargo, PickupZone)
-- Need to get the cargo over to the portzone
-- But what if the cargo can't move on it's own?
BASE:T("DEBUGGING*** CargoTransport:OnBeforeMonitor")
end
--- Function called after carrier picked up something. --- Function called after carrier picked up something.
function CargoTransport:OnAfterPickedUp(From, Event, To, Carrier, PickupZone) function CargoTransport:OnAfterPickedUp(From, Event, To, Carrier, PickupZone)

View File

@ -95,10 +95,12 @@ __Moose.Include( 'Scripts/Moose/AI/AI_Cargo.lua' )
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_APC.lua' ) __Moose.Include( 'Scripts/Moose/AI/AI_Cargo_APC.lua' )
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Helicopter.lua' ) __Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Helicopter.lua' )
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Airplane.lua' ) __Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Airplane.lua' )
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Ship.lua' )
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher.lua' ) __Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher.lua' )
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher_APC.lua' ) __Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher_APC.lua' )
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua' ) __Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua' )
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua' ) __Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua' )
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher_Ship.lua' )
__Moose.Include( 'Scripts/Moose/Actions/Act_Assign.lua' ) __Moose.Include( 'Scripts/Moose/Actions/Act_Assign.lua' )
__Moose.Include( 'Scripts/Moose/Actions/Act_Route.lua' ) __Moose.Include( 'Scripts/Moose/Actions/Act_Route.lua' )

View File

@ -1390,6 +1390,19 @@ do -- Cargo
} }
self.__.CargoBayWeightLimit = Weights[Desc.typeName] or ( Desc.massMax - ( Desc.massEmpty + Desc.fuelMassMax ) ) self.__.CargoBayWeightLimit = Weights[Desc.typeName] or ( Desc.massMax - ( Desc.massEmpty + Desc.fuelMassMax ) )
elseif self:IsShip() then
local Desc = self:GetDesc()
self:F({Desc=Desc})
local Weights = {
["Type_071"] = 245000,
["LHA_Tarawa"] = 500000,
["Ropucha-class"] = 150000,
["Dry-cargo ship-1"] = 70000,
["Dry-cargo ship-2"] = 70000,
}
self.__.CargoBayWeightLimit = Weights[Desc.typeName]
else else
local Desc = self:GetDesc() local Desc = self:GetDesc()

View File

@ -1,3 +1,4 @@
Utilities/Enums.lua
Utilities/Routines.lua Utilities/Routines.lua
Utilities/Utils.lua Utilities/Utils.lua
@ -11,6 +12,7 @@ Core/Event.lua
Core/Settings.lua Core/Settings.lua
Core/Menu.lua Core/Menu.lua
Core/Zone.lua Core/Zone.lua
Core/Zone_Detection.lua
Core/Database.lua Core/Database.lua
Core/Set.lua Core/Set.lua
Core/Point.lua Core/Point.lua
@ -18,6 +20,8 @@ Core/Velocity.lua
Core/Message.lua Core/Message.lua
Core/Fsm.lua Core/Fsm.lua
Core/Radio.lua Core/Radio.lua
Core/RadioQueue.lua
Core/RadioSpeech.lua
Core/Spawn.lua Core/Spawn.lua
Core/SpawnStatic.lua Core/SpawnStatic.lua
Core/Goal.lua Core/Goal.lua
@ -48,6 +52,7 @@ Functional/Escort.lua
Functional/MissileTrainer.lua Functional/MissileTrainer.lua
Functional/ATC_Ground.lua Functional/ATC_Ground.lua
Functional/Detection.lua Functional/Detection.lua
Functional/DetectionZones.lua
Functional/Designate.lua Functional/Designate.lua
Functional/RAT.lua Functional/RAT.lua
Functional/Range.lua Functional/Range.lua
@ -67,31 +72,35 @@ Ops/ATIS.lua
AI/AI_Balancer.lua AI/AI_Balancer.lua
AI/AI_Air.lua AI/AI_Air.lua
AI/AI_A2A.lua AI/AI_Air_Patrol.lua
AI/AI_Air_Engage.lua
AI/AI_A2A_Patrol.lua AI/AI_A2A_Patrol.lua
AI/AI_A2A_Cap.lua AI/AI_A2A_Cap.lua
AI/AI_A2A_Gci.lua AI/AI_A2A_Gci.lua
AI/AI_A2A_Dispatcher.lua AI/AI_A2A_Dispatcher.lua
AI/AI_A2G.lua
AI/AI_A2G_Engage.lua
AI/AI_A2G_BAI.lua AI/AI_A2G_BAI.lua
AI/AI_A2G_CAS.lua AI/AI_A2G_CAS.lua
AI/AI_A2G_SEAD.lua AI/AI_A2G_SEAD.lua
AI/AI_A2G_Patrol.lua
AI/AI_A2G_Dispatcher.lua AI/AI_A2G_Dispatcher.lua
AI/AI_Patrol.lua AI/AI_Patrol.lua
AI/AI_Cap.lua AI/AI_CAP.lua
AI/AI_Cas.lua AI/AI_CAS.lua
AI/AI_Bai.lua AI/AI_BAI.lua
AI/AI_Formation.lua AI/AI_Formation.lua
AI/AI_Escort.lua
AI/AI_Escort_Request.lua
AI/AI_Escort_Dispatcher.lua
AI/AI_Escort_Dispatcher_Request.lua
AI/AI_Cargo.lua AI/AI_Cargo.lua
AI/AI_Cargo_APC.lua AI/AI_Cargo_APC.lua
AI/AI_Cargo_Helicopter.lua AI/AI_Cargo_Helicopter.lua
AI/AI_Cargo_Airplane.lua AI/AI_Cargo_Airplane.lua
AI/AI_Cargo_Ship.lua
AI/AI_Cargo_Dispatcher.lua AI/AI_Cargo_Dispatcher.lua
AI/AI_Cargo_Dispatcher_APC.lua AI/AI_Cargo_Dispatcher_APC.lua
AI/AI_Cargo_Dispatcher_Helicopter.lua AI/AI_Cargo_Dispatcher_Helicopter.lua
AI/AI_Cargo_Dispatcher_Airplane.lua AI/AI_Cargo_Dispatcher_Airplane.lua
AI/AI_Cargo_Dispatcher_Ship.lua
Actions/Act_Assign.lua Actions/Act_Assign.lua
Actions/Act_Route.lua Actions/Act_Route.lua
@ -108,10 +117,11 @@ Tasking/Task_A2G_Dispatcher.lua
Tasking/Task_A2G.lua Tasking/Task_A2G.lua
Tasking/Task_A2A_Dispatcher.lua Tasking/Task_A2A_Dispatcher.lua
Tasking/Task_A2A.lua Tasking/Task_A2A.lua
Tasking/Task_Cargo.lua Tasking/Task_CARGO.lua
Tasking/Task_Cargo_Transport.lua Tasking/Task_Cargo_Transport.lua
Tasking/Task_Cargo_CSAR.lua Tasking/Task_Cargo_CSAR.lua
Tasking/Task_Cargo_Dispatcher.lua Tasking/Task_Cargo_Dispatcher.lua
Tasking/TaskZoneCapture.lua Tasking/Task_Capture_Zone.lua
Tasking/Task_Capture_Dispatcher.lua
Globals.lua Globals.lua