diff --git a/Moose Development/Moose/AI/AI_Cargo_Airplane.lua b/Moose Development/Moose/AI/AI_Cargo_Airplane.lua index bbbe19ed0..dc3076e95 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Airplane.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Airplane.lua @@ -111,6 +111,18 @@ function AI_CARGO_AIRPLANE:New( Airplane, CargoSet ) end +function AI_CARGO_AIRPLANE:IsTransporting() + + return self.Transporting == true +end + +function AI_CARGO_AIRPLANE:IsRelocating() + + return self.Relocating == true +end + + + --- Set the Carrier. -- @param #AI_CARGO_AIRPLANE self -- @param Wrapper.Group#GROUP Airplane @@ -155,7 +167,8 @@ function AI_CARGO_AIRPLANE:SetCarrier( Airplane ) function Airplane:OnEventEngineShutdown( EventData ) - AICargo:Landed() + self:F("Calling") + AICargo:Landed( self.Airplane ) end self.Coalition = self.Airplane:GetCoalition() @@ -199,6 +212,10 @@ end -- @param #number Speed 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 self.RoutePickup == true then @@ -230,6 +247,8 @@ function AI_CARGO_AIRPLANE:onafterPickup( Airplane, From, Event, To, Airbase, Sp self:Route( Airplane, Airbase, Speed ) self.RoutePickup = true self.Airbase = Airbase + self.Transporting = true + self.Relocating = false end end @@ -248,6 +267,8 @@ function AI_CARGO_AIRPLANE:onafterDeploy( Airplane, From, Event, To, Airbase, Sp self:Route( Airplane, Airbase, Speed ) self.RouteDeploy = true self.Airbase = Airbase + self.Transporting = false + self.Relocating = false end end @@ -260,7 +281,9 @@ function AI_CARGO_AIRPLANE:onafterLoad( Airplane, From, Event, To, Coordinate ) if Airplane and Airplane:IsAlive() then for _, Cargo in pairs( self.CargoSet:GetSet() ) do - if Cargo:IsInLoadRadius( Coordinate ) then + self:F({Cargo:GetName()}) + local InRadius = Cargo:IsInLoadRadius( Coordinate ) + if InRadius then self:__Board( 5 ) Cargo:Board( Airplane, 25 ) self.Cargo = Cargo @@ -359,6 +382,7 @@ function AI_CARGO_AIRPLANE:Route( Airplane, Airbase, Speed ) FromWaypoint.helipadId = nil FromWaypoint.airdromeId = nil + local ParkingSpots = self.Airbase:FindFreeParkingSpotForAircraft( Airplane, AIRBASE.TerminalType.OpenBig ) local AirbaseID = self.Airbase:GetID() local AirbaseCategory = self.Airbase:GetDesc().category @@ -377,8 +401,8 @@ function AI_CARGO_AIRPLANE:Route( Airplane, Airbase, Speed ) -- These cause a lot of confusion. local UnitTemplate = Template.units[UnitID] - UnitTemplate.parking = 15 - UnitTemplate.parking_id = "1" + UnitTemplate.parking = nil + UnitTemplate.parking_id = nil UnitTemplate.alt = 0 local SX = UnitTemplate.x diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua index 0b1700e04..6b3732121 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua @@ -74,7 +74,7 @@ AI_CARGO_DISPATCHER = { ClassName = "AI_CARGO_DISPATCHER", SetCarrier = nil, - SetDeployZones = nil, + DeployZonesSet = nil, AI_Cargo = {}, PickupCargo = {} } @@ -90,23 +90,21 @@ AI_CARGO_DISPATCHER.PickupCargo = {} -- @param #AI_CARGO_DISPATCHER self -- @param Core.Set#SET_GROUP SetCarrier -- @param Core.Set#SET_CARGO SetCargo --- @param Core.Set#SET_ZONE SetDeployZones -- @return #AI_CARGO_DISPATCHER -- @usage -- -- -- Create a new cargo dispatcher --- SetCarrier = SET_GROUP:New():FilterPrefixes( "APC" ):FilterStart() --- SetCargo = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart() +-- SetCarriers = SET_GROUP:New():FilterPrefixes( "APC" ):FilterStart() +-- SetCargos = SET_CARGO:New():FilterTypes( "Infantry" ):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 self.SetCarrier = SetCarrier -- Core.Set#SET_GROUP self.SetCargo = SetCargo -- Core.Set#SET_CARGO - self.SetDeployZones = SetDeployZones -- Core.Set#SET_ZONE self:SetStartState( "Idle" ) @@ -144,6 +142,58 @@ function AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZones ) 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. -- When there is nothing anymore to pickup, the carriers will go to a random coordinate in this zone. -- They will await here new orders. @@ -361,7 +411,16 @@ function AI_CARGO_DISPATCHER:onafterMonitor() if PickupCargo then self.CarrierHome[Carrier] = nil 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 else if self.HomeZone then @@ -464,12 +523,22 @@ end -- @return #AI_CARGO_DISPATCHER 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 ) - self.AI_Cargo[Carrier]:Deploy( DeployCoordinate, math.random( self.DeployMinSpeed, self.DeployMaxSpeed ) ) + local DeployZone = self.DeployZonesSet:GetRandomZone() + + 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 diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua index 561125786..413ca7c26 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua @@ -101,7 +101,7 @@ AI_CARGO_DISPATCHER_APC = { -- SetDeployZone = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart() -- 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 diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua index c208bab9a..52dd0a712 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua @@ -16,8 +16,8 @@ --- Brings a dynamic cargo handling capability for AI groups. -- -- 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. --- CARGO derived objects must be declared within the mission to make the AI\_CARGO\_DISPATCHER\_AIRPLANE object recognize the cargo. +-- 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. -- Please consult the @{Cargo} module for more information. -- -- @@ -29,23 +29,33 @@ AI_CARGO_DISPATCHER_AIRPLANE = { --- Creates a new AI_CARGO_DISPATCHER_AIRPLANE object. -- @param #AI_CARGO_DISPATCHER_AIRPLANE self --- @param Core.Set#SET_GROUP SetAirplane --- @param Core.Set#SET_CARGO SetCargo --- @param Core.Set#SET_ZONE SetDeployZone +-- @param Core.Set#SET_GROUP SetAirplanes +-- @param Core.Set#SET_CARGO SetCargos +-- @param Core.Set#SET_AIRBASE PickupAirbasesSet +-- @param Core.Set#SET_AIRBASE DeployAirbasesSet -- @return #AI_CARGO_DISPATCHER_AIRPLANE -- @usage -- -- -- Create a new cargo dispatcher --- SetAirplane = SET_GROUP:New():FilterPrefixes( "Airplane" ):FilterStart() --- SetCargo = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart() --- SetDeployZone = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart() --- AICargoDispatcher = AI_CARGO_DISPATCHER_AIRPLANE:New( SetAirplane, SetCargo ) +-- SetAirplanes = SET_GROUP:New():FilterPrefixes( "Airplane" ):FilterStart() +-- SetCargos = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart() +-- PickupAirbasesSet = SET_AIRBASE:New() +-- 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 end +function AI_CARGO_DISPATCHER_AIRPLANE:AICargo( Airplane, SetCargo ) + return AI_CARGO_AIRPLANE:New( Airplane, SetCargo ) +end diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua index eaf9666d2..26b5d9aab 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua @@ -102,7 +102,7 @@ AI_CARGO_DISPATCHER_HELICOPTER = { -- 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:SetPickupSpeed( 200, 150 ) diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index e81beb007..7183623e0 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -4010,6 +4010,45 @@ function SET_AIRBASE:FindAirbase( AirbaseName ) 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. -- Possible current coalitions are red, blue and neutral.