Initial changes to support Naval Cargo

This commit is contained in:
acrojason 2020-09-23 09:40:42 -07:00
parent 18fd9cdc3d
commit 4b8b13dd68
2 changed files with 161 additions and 100 deletions

View File

@ -40,7 +40,7 @@ function AI_CARGO_SHIP:SetCarrier( CargoCarrier )
self:F({AICargoTroops=AICargoTroops}) self:F({AICargoTroops=AICargoTroops})
if AICargoTroops then if AICargoTroops then
self:F({}) self:F({})
if not AICargoTroopsIs( "Loaded" ) then if not AICargoTroops:Is( "Loaded" ) then
-- Better hope they can swim! -- Better hope they can swim!
AICargoTroops:Destroyed() AICargoTroops:Destroyed()
end end
@ -92,6 +92,7 @@ function AI_CARGO_SHIP:SetCombatRadius( CombatRadius )
return self return self
end end
--- Follow Infantry to the Carrier --- Follow Infantry to the Carrier
-- @param #AI_CARGO_SHIP self -- @param #AI_CARGO_SHIP self
-- @param #AI_CARGO_SHIP Me -- @param #AI_CARGO_SHIP Me
@ -99,6 +100,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() } )
@ -107,35 +109,35 @@ function AI_CARGO_SHIP:FollowToCarrier( Me, ShipUnit, CargoGroup )
-- Check if the Cargo is near the CargoCarrier -- Check if the Cargo is near the CargoCarrier
if InfantryGroup:IsPartlyInZone( ZONE_UNIT:New( "Radius", ShipUnit, 1000 ) ) then if InfantryGroup:IsPartlyInZone( ZONE_UNIT:New( "Radius", ShipUnit, 1000 ) ) then
-- Cargo does not need to navigate to Carrier -- Cargo does not need to navigate to Carrier
Me:Guard() Me:Guard()
else else
self:F( { InfantryGroup = InfantryGroup:GetName() } )
if InfantryGroup:IsAlive() then
self:F( { InfantryGroup = InfantryGroup:GetName() } ) self:F( { InfantryGroup = InfantryGroup:GetName() } )
local Waypoints = {} if InfantryGroup:IsAlive() then
-- Calculate new route self:F( { InfantryGroup = InfantryGroup:GetName() } )
local FromCoord = InfantryGroup:GetCoordinate() local Waypoints = {}
local FromGround = FromCoord:WaypointGround( 10, "Diamond" )
self:F({FromGround=FromGround})
table.insert( Waypoints, FromGround )
local ToCoord = ShipUnit:GetCoordinate():GetRandomCoordinateInRadius( 10, 5 ) -- Calculate new route
local ToGround = ToCoord:WaypointGround( 10, "Diamond" ) local FromCoord = InfantryGroup:GetCoordinate()
self:F({ToGround=ToGround}) local FromGround = FromCoord:WaypointGround( 10, "Diamond" )
table.insert( Waypoints, ToGround ) self:F({FromGround=FromGround})
table.insert( Waypoints, FromGround )
local TaskRoute = InfantryGroup:TaskFunction( "AI_CARGO_SHIP.FollowToCarrier", Me, ShipUnit, CargoGroup ) local ToCoord = ShipUnit:GetCoordinate():GetRandomCoordinateInRadius( 10, 5 )
local ToGround = ToCoord:WaypointGround( 10, "Diamond" )
self:F({ToGround=ToGround})
table.insert( Waypoints, ToGround )
self:F({Waypoints=Waypoints}) local TaskRoute = InfantryGroup:TaskFunction( "AI_CARGO_SHIP.FollowToCarrier", Me, ShipUnit, CargoGroup )
local Waypoint = Waypoints[#Waypoints]
InfantryGroup:SetTaskWaypoint( Waypoint, TaskRoute ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone
InfantryGroup:Route( Waypoints, 1 ) -- Move after a random number of seconds to the Route. See Route method for details self:F({Waypoints=Waypoints})
end local Waypoint = Waypoints[#Waypoints]
InfantryGroup:SetTaskWaypoint( Waypoint, TaskRoute ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone
InfantryGroup:Route( Waypoints, 1 ) -- Move after a random number of seconds to the Route. See Route method for details
end
end end
end end
end end
@ -146,76 +148,57 @@ function AI_CARGO_SHIP:onafterMonitor( Ship, From, Event, To )
if self.CombatRadius > 0 then if self.CombatRadius > 0 then
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
local Coordinate = Ship:GetCoordinate() local Coordinate = Ship:GetCoordinate()
if self:Is( "Unloaded" ) or self:Is( "Loaded" ) then if self:Is( "Unloaded" ) or self:Is( "Loaded" ) then
self.Zone:Scan( { Object.Category.UNIT } ) self.Zone:Scan( { Object.Category.UNIT } )
if self.Zone:IsAllInZoneOfCoalition( self.Coalition ) then if self.Zone:IsAllInZoneOfCoalition( self.Coalition ) then
if self:Is( "Unloaded" ) then if self:Is( "Unloaded" ) then
-- There are no enemies within combat radius. Reload the CargoCarrier. -- There are no enemies within combat radius. Reload the CargoCarrier.
self:Reload() self:Reload()
end end
else else
if self:Is( "Loaded" ) then if self:Is( "Loaded" ) then
-- There are enemies within combat radius. Unload the CargoCarrier. -- There are enemies within combat radius. Unload the CargoCarrier.
self:__Unload( 1, nil, true ) -- The 2nd parameter is true, which means that the unload is for defending the carrier, not to deploy! self:__Unload( 1, nil, true ) -- The 2nd parameter is true, which means that the unload is for defending the carrier, not to deploy!
else else
if self:Is( "Unloaded" ) then if self:Is( "Unloaded" ) then
--self:Follow() --self:Follow()
end end
self:F( "I am here" .. self:GetCurrentState() ) self:F( "I am here" .. self:GetCurrentState() )
if self:Is( "Following" ) then if self:Is( "Following" ) then
for Cargo, ShipUnit in pairs( self.Carrier_Cargo ) do for Cargo, ShipUnit in pairs( self.Carrier_Cargo ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO local Cargo = Cargo -- Cargo.Cargo#CARGO
local ShipUnit = ShipUnit -- Wrapper.Unit#UNIT local ShipUnit = ShipUnit -- Wrapper.Unit#UNIT
if Cargo:IsAlive() then if Cargo:IsAlive() then
if not Cargo:IsNear( ShipUnit, 40 ) then if not Cargo:IsNear( ShipUnit, 40 ) then
ShipUnit:RouteStop() ShipUnit:RouteStop()
self.CarrierStopped = true self.CarrierStopped = true
else else
if self.CarrierStopped then if self.CarrierStopped then
if Cargo:IsNear( ShipUnit, 25 ) then if Cargo:IsNear( ShipUnit, 25 ) then
ShipUnit:RouteResume() ShipUnit:RouteResume()
self.CarrierStopped = nil self.CarrierStopped = nil
end end
end
end
end
end
end
end
end end
end end
end
end
end end
end end
end self.CarrierCoordinate = Ship:GetCoordinate()
end
end
end end
self.CarrierCoordinate = Ship:GetCoordinate()
end
self:__Monitor( -5 ) self:__Monitor( -5 )
end end
end end
function AI_CARGO_SHIP:onafterFollow( Ship, From, Event, To )
self:F( { Ship, From, Event, To } )
self:F( "Follow" )
if Ship and Ship:IsAlive() then
for Cargo, ShipUnit in pairs( self.Carrier_Cargo ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
if Cargo:IsUnLoaded() then
self:FollowToCarrier( self, ShipUnit, Cargo )
ShipUnit:RouteResume()
end
end
end
end
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
@ -233,6 +216,39 @@ function AI_CARGO_SHIP._Deploy( Ship, self, Coordinate, DeployZone )
end end
end end
function AI_CARGO_SHIP:onafterPickup( Ship, From, Event, To, Coordinate, Speed, Height, PickupZone )
if Ship and Ship:IsAlive() then
AI_CARGO_SHIP._Pickup( Ship, self, Coordinate, Speed, PickupZone )
self:GetParent( self, AI_CARGO_SHIP ).onafterPickup( self, Ship, From, Event, To, Coordinate, Speed, Height, PickupZone )
end
end
function AI_CARGO_SHIP:onafterPickedUp( Ship, From, Event, To, Coordinate, Speed, Height, PickupZone )
if Ship and Ship:IsAlive() then
Speed = Speed or Ship:GetSpeedMax()*0.8
local lane = self.ShippingLane
if lane then
local Waypoints = {}
for i=1, #lane do
local coord = lane[i]
local Waypoint = coord:WaypointGround(_speed)
table.insert(Waypoints, Waypoint)
end
local Waypoint = Waypoints[#Waypoints]
Ship:Route(Waypoints, 1)
else
BASE:T("ERROR: No shipping lane defined for Naval Transport!")
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
@ -251,15 +267,12 @@ function AI_CARGO_SHIP:onafterHome( Ship, From, Event, To, Coordinate, Speed, He
table.insert(Waypoints, Waypoint) table.insert(Waypoints, Waypoint)
end end
--local TaskFunction = self:_SimpleTaskFunction( "warehouse:_Arrived", Ship )
local Waypoint = Waypoints[#Waypoints] local Waypoint = Waypoints[#Waypoints]
--Ship:SetTaskWaypoint( Waypoint, TaskFunction )
Ship:Route(Waypoints, 1) Ship:Route(Waypoints, 1)
else else
BASE:T("ERROR: No shipping lane defined for Naval Transport!") BASE:T("ERROR: No shipping lane defined for Naval Transport!")
end end
end end
end end

View File

@ -1569,6 +1569,7 @@ WAREHOUSE = {
delivered = {}, delivered = {},
defending = {}, defending = {},
portzone = nil, portzone = nil,
harborzone = nil,
shippinglanes = {}, shippinglanes = {},
offroadpaths = {}, offroadpaths = {},
autodefence = false, autodefence = false,
@ -2709,6 +2710,18 @@ function WAREHOUSE:SetPortZone(zone)
return self return self
end end
--- Add a Harbor Zone for this warehouse where naval cargo units will spawn and be received.
-- Both warehouses must have the harbor zone defined for units to properly spawn on both the
-- sending and receiving side. The harbor zone should be within 3km of the port zone used for
-- warehouse in order to facilitate the boarding process.
-- @param #WAREHOUSE self
-- @param Core.Zone#ZONE zone The zone defining the naval embarcation/debarcation point for cargo units
-- @return #WAREHOUSE self
function WAREHOUSE:SetHarborZone(zone)
self.harborzone=zone
return self
end
--- Add a shipping lane from this warehouse to another remote warehouse. --- Add a shipping lane from this warehouse to another remote warehouse.
-- Note that both warehouses must have a port zone defined before a shipping lane can be added! -- Note that both warehouses must have a port zone defined before a shipping lane can be added!
-- Shipping lane is taken from the waypoints of a (late activated) template group. So set up a group, e.g. a ship or a helicopter, and place its -- Shipping lane is taken from the waypoints of a (late activated) template group. So set up a group, e.g. a ship or a helicopter, and place its
@ -4344,7 +4357,6 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request)
-- Spawn Ship in port zone -- Spawn Ship in port zone
spawngroup=self:_SpawnAssetGroundNaval(_alias, _assetitem, Request, self.portzone) spawngroup=self:_SpawnAssetGroundNaval(_alias, _assetitem, Request, self.portzone)
return
elseif Request.transporttype==WAREHOUSE.TransportType.SELFPROPELLED then elseif Request.transporttype==WAREHOUSE.TransportType.SELFPROPELLED then
@ -4473,8 +4485,7 @@ function WAREHOUSE:onafterRequestSpawned(From, Event, To, Request, CargoGroupSet
elseif Request.transporttype==WAREHOUSE.TransportType.APC then elseif Request.transporttype==WAREHOUSE.TransportType.APC then
--_boardradius=nil --_boardradius=nil
elseif Request.transporttype==WAREHOUSE.TransportType.SHIP then elseif Request.transporttype==WAREHOUSE.TransportType.SHIP then
BASE:T("Big 'ol board radius") _boardradius=6000
_boardradius=5000
end end
-- Empty cargo group set. -- Empty cargo group set.
@ -4485,7 +4496,7 @@ 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)
@ -4494,6 +4505,7 @@ function WAREHOUSE:onafterRequestSpawned(From, Event, To, Request, CargoGroupSet
-- Add group to group set. -- Add group to group set.
CargoGroups:AddCargo(cargogroup) CargoGroups:AddCargo(cargogroup)
end end
------------------------ ------------------------
@ -4543,6 +4555,7 @@ 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)
local DeployZoneSet = SET_ZONE:New():AddZone(Request.warehouse.portzone) local DeployZoneSet = SET_ZONE:New():AddZone(Request.warehouse.portzone)
-- Get the shipping lane to use and pass it to the Dispatcher -- Get the shipping lane to use and pass it to the Dispatcher
@ -4561,17 +4574,43 @@ function WAREHOUSE:onafterRequestSpawned(From, Event, To, Request, CargoGroupSet
-- Set pickup and deploy radii. -- Set pickup and deploy radii.
-- The 20 m inner radius are to ensure that the helo does not land on the warehouse itself in the middle of the default spawn zone. -- The 20 m inner radius are to ensure that the helo does not land on the warehouse itself in the middle of the default spawn zone.
local pickupouter=200 local pickupouter = 200
local pickupinner=0 local pickupinner = 0
if self.spawnzone.Radius~=nil then local deployouter = 200
pickupouter=self.spawnzone.Radius local deployinner = 0
if Request.transporttype==WAREHOUSE.TransportType.SHIP then
pickupouter=1000
pickupinner=20 pickupinner=20
end deployouter=1000
local deployouter=200 deployinner=0
local deployinner=0 --BASE:T("DEBUGGING*** Let's try to move these units")
if self.spawnzone.Radius~=nil then --[[for _,_group in pairs(CargoGroupSet:GetSetObjects()) do
deployouter=Request.warehouse.spawnzone.Radius local group=GROUP:FindByName( _group:GetName() ) --Wrapper.Group#GROUP
deployinner=20
--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
pickupouter=200
pickupinner=0
if self.spawnzone.Radius~=nil then
pickupouter=self.spawnzone.Radius
pickupinner=20
end
deployouter=200
deployinner=0
if self.spawnzone.Radius~=nil then
deployouter=Request.warehouse.spawnzone.Radius
deployinner=20
end
end end
CargoTransport:SetPickupRadius(pickupouter, pickupinner) CargoTransport:SetPickupRadius(pickupouter, pickupinner)
CargoTransport:SetDeployRadius(deployouter, deployinner) CargoTransport:SetDeployRadius(deployouter, deployinner)
@ -4600,6 +4639,15 @@ 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)
@ -4650,7 +4698,7 @@ function WAREHOUSE:onafterRequestSpawned(From, Event, To, Request, CargoGroupSet
-- Get cargo group object. -- Get cargo group object.
local group=Cargo:GetObject() --Wrapper.Group#GROUP local group=Cargo:GetObject() --Wrapper.Group#GROUP
-- Get request. -- Get request.
local request=warehouse:_GetRequestOfGroup(group, warehouse.pending) local request=warehouse:_GetRequestOfGroup(group, warehouse.pending)
-- Add cargo group to this carrier. -- Add cargo group to this carrier.