diff --git a/Moose Development/Moose/AI/AI_Cargo_APC.lua b/Moose Development/Moose/AI/AI_Cargo_APC.lua index f867256b9..9e4351bee 100644 --- a/Moose Development/Moose/AI/AI_Cargo_APC.lua +++ b/Moose Development/Moose/AI/AI_Cargo_APC.lua @@ -190,6 +190,7 @@ function AI_CARGO_APC:New( CargoCarrier, CargoSet, CombatRadius ) self:SetCarrier( CargoCarrier ) self.Transporting = false + self.Relocating = false return self end @@ -227,7 +228,7 @@ function AI_CARGO_APC:SetCarrier( CargoCarrier ) self:F( { OnHitLoaded = AICargoTroops:Is( "Loaded" ) } ) if AICargoTroops:Is( "Loaded" ) or AICargoTroops:Is( "Boarding" ) then -- There are enemies within combat range. Unload the CargoCarrier. - AICargoTroops:Unload() + AICargoTroops:Unload( false ) end end end @@ -248,6 +249,11 @@ function AI_CARGO_APC:IsTransporting() return self.Transporting == true end +function AI_CARGO_APC:IsRelocating() + + return self.Relocating == true +end + --- Find a free Carrier within a range. -- @param #AI_CARGO_APC self -- @param Core.Point#COORDINATE Coordinate @@ -337,7 +343,7 @@ function AI_CARGO_APC:onafterMonitor( APC, From, Event, To ) if APC and APC:IsAlive() then if self.CarrierCoordinate then - if self:IsTransporting() then + if self:IsRelocating() == true then local Coordinate = APC:GetCoordinate() self.Zone:Scan( { Object.Category.UNIT } ) if self.Zone:IsAllInZoneOfCoalition( self.Coalition ) then @@ -348,7 +354,7 @@ function AI_CARGO_APC:onafterMonitor( APC, From, Event, To ) else if self:Is( "Loaded" ) then -- There are enemies within combat range. Unload the CargoCarrier. - self:__Unload( 1 ) + self:__Unload( 1, false ) else if self:Is( "Unloaded" ) then self:Follow() @@ -398,8 +404,8 @@ function AI_CARGO_APC:onbeforeLoad( APC, From, Event, To ) local APCUnit = APCUnit -- Wrapper.Unit#UNIT for _, Cargo in pairs( self.CargoSet:GetSet() ) do local Cargo = Cargo -- Cargo.Cargo#CARGO - self:F( { IsUnLoaded = Cargo:IsUnLoaded(), Cargo:GetName(), APC:GetName() } ) - if Cargo:IsUnLoaded() then + self:F( { IsUnLoaded = Cargo:IsUnLoaded(), IsDeployed = Cargo:IsDeployed(), Cargo:GetName(), APC:GetName() } ) + if Cargo:IsUnLoaded() and not Cargo:IsDeployed() then if Cargo:IsInLoadRadius( APCUnit:GetCoordinate() ) then self:F( { "In radius", APCUnit:GetName() } ) APC:RouteStop() @@ -467,8 +473,8 @@ end --- @param #AI_CARGO_APC self -- @param Wrapper.Group#GROUP APC -function AI_CARGO_APC:onafterUnload( APC, From, Event, To ) - self:F( { APC, From, Event, To } ) +function AI_CARGO_APC:onafterUnload( APC, From, Event, To, Deployed ) + self:F( { APC, From, Event, To, Deployed } ) if APC and APC:IsAlive() then for _, APCUnit in pairs( APC:GetUnits() ) do @@ -476,7 +482,7 @@ function AI_CARGO_APC:onafterUnload( APC, From, Event, To ) APC:RouteStop() for _, Cargo in pairs( APCUnit:GetCargo() ) do Cargo:UnBoard() - self:__Unboard( 10, Cargo ) + self:__Unboard( 10, Cargo, Deployed ) end end end @@ -485,14 +491,14 @@ end --- @param #AI_CARGO_APC self -- @param Wrapper.Group#GROUP APC -function AI_CARGO_APC:onafterUnboard( APC, From, Event, To, Cargo ) +function AI_CARGO_APC:onafterUnboard( APC, From, Event, To, Cargo, Deployed ) self:F( { APC, From, Event, To, Cargo:GetName() } ) if APC and APC:IsAlive() then if not Cargo:IsUnLoaded() then - self:__Unboard( 10, Cargo ) + self:__Unboard( 10, Cargo, Deployed ) else - self:__Unloaded( 1, Cargo ) + self:__Unloaded( 1, Cargo, Deployed ) end end @@ -500,8 +506,8 @@ end --- @param #AI_CARGO_APC self -- @param Wrapper.Group#GROUP APC -function AI_CARGO_APC:onbeforeUnloaded( APC, From, Event, To, Cargo ) - self:F( { APC, From, Event, To, Cargo:GetName() } ) +function AI_CARGO_APC:onbeforeUnloaded( APC, From, Event, To, Cargo, Deployed ) + self:F( { APC, From, Event, To, Cargo:GetName(), Deployed = Deployed } ) local AllUnloaded = true @@ -521,6 +527,13 @@ function AI_CARGO_APC:onbeforeUnloaded( APC, From, Event, To, Cargo ) end if AllUnloaded == true then + if Deployed == true then + for APCUnit, Cargo in pairs( self.APC_Cargo ) do + local Cargo = Cargo -- Cargo.Cargo#CARGO + Cargo:SetDeployed( true ) + end + self.APC_Cargo = {} + end self:Guard() self.CargoCarrier = APC end @@ -559,7 +572,7 @@ function AI_CARGO_APC._Pickup( APC, self ) if APC:IsAlive() then self:Load() - self.Transporting = true + self.Relocating = true end end @@ -571,9 +584,9 @@ function AI_CARGO_APC._Deploy( APC, self ) APC:F( { "AI_CARGO_APC._Deploy:", APC } ) if APC:IsAlive() then - self:Unload() + self:Unload( true ) self.Transporting = false - self.APC_Cargo = {} + self.Relocating = false end end @@ -606,6 +619,8 @@ function AI_CARGO_APC:onafterPickup( APC, From, Event, To, Coordinate, Speed, En else AI_CARGO_APC._Pickup( APC, self ) end + + self.Transporting = true end end diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua new file mode 100644 index 000000000..eeaffec9f --- /dev/null +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua @@ -0,0 +1,188 @@ +--- **AI** -- (R2.4) - Models the intelligent transportation of infantry and other cargo. +-- +-- === +-- +-- ### Author: **FlightControl** +-- +-- === +-- +-- @module AI_Cargo_Dispatcher + +--- @type AI_CARGO_DISPATCHER +-- @extends Core.Fsm#FSM_CONTROLLABLE + + +--- # AI\_CARGO\_DISPATCHER class, extends @{Core.Base#BASE} +-- +-- === +-- +-- AI\_CARGO\_DISPATCHER brings a dynamic cargo handling capability for AI groups. +-- +-- Armoured Personnel APCs (APC), Trucks, Jeeps and other carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation. +-- The AI\_CARGO\_DISPATCHER module uses the @{Cargo} capabilities within the MOOSE framework. +-- CARGO derived objects must be declared within the mission to make the AI\_CARGO\_DISPATCHER object recognize the cargo. +-- Please consult the @{Cargo} module for more information. +-- +-- +-- +-- @field #AI_CARGO_DISPATCHER +AI_CARGO_DISPATCHER = { + ClassName = "AI_CARGO_DISPATCHER", + SetAPC = nil, + SetDeployZones = nil, + AI_CARGO_APC = {} +} + +--- @type AI_CARGO_DISPATCHER.AI_CARGO_APC +-- @map + +--- @field #AI_CARGO_DISPATCHER.AI_CARGO_APC +AI_CARGO_DISPATCHER.AICargoAPC = {} + +--- @field #AI_CARGO_DISPATCHER.PickupCargo +AI_CARGO_DISPATCHER.PickupCargo = {} + +--- Creates a new AI_CARGO_DISPATCHER object. +-- @param #AI_CARGO_DISPATCHER self +-- @param Core.Set#SET_GROUP SetAPC +-- @param Core.Set#SET_CARGO SetCargo +-- @param Core.Set#SET_ZONE SetDeployZone +-- @return #AI_CARGO_DISPATCHER +-- @usage +-- +-- -- Create a new cargo dispatcher +-- SetAPC = SET_GROUP:New():FilterPrefixes( "APC" ):FilterStart() +-- SetCargo = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart() +-- SetDeployZone = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart() +-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetAPC, SetCargo ) +-- +function AI_CARGO_DISPATCHER:New( SetAPC, SetCargo, SetDeployZones ) + + local self = BASE:Inherit( self, FSM:New() ) -- #AI_CARGO_DISPATCHER + + self.SetAPC = SetAPC -- Core.Set#SET_GROUP + self.SetCargo = SetCargo -- Core.Set#SET_CARGO + self.SetDeployZones = SetDeployZones -- Core.Set#SET_ZONE + + self:SetStartState( "APC" ) + + self:AddTransition( "*", "Monitor", "*" ) + + self:AddTransition( "*", "Pickup", "*" ) + self:AddTransition( "*", "Loading", "*" ) + self:AddTransition( "*", "Loaded", "*" ) + + self:AddTransition( "*", "Deploy", "*" ) + self:AddTransition( "*", "Unloading", "*" ) + self:AddTransition( "*", "Unloaded", "*" ) + + self.MonitorTimeInterval = 120 + self.CombatRadius = 500 + self.DeployRadiusInner = 200 + self.DeployRadiusOuter = 500 + + self:Monitor( 1 ) + + return self +end + + +--- The Start trigger event, which actually takes action at the specified time interval. +-- @param #AI_CARGO_DISPATCHER self +-- @param Wrapper.Group#GROUP APC +-- @return #AI_CARGO_DISPATCHER +function AI_CARGO_DISPATCHER:onafterMonitor() + + for APCGroupName, APC in pairs( self.SetAPC:GetSet() ) do + local APC = APC -- Wrapper.Group#GROUP + local AICargoAPC = self.AICargoAPC[APC] + if not AICargoAPC then + -- ok, so this APC does not have yet an AI_CARGO_APC object... + -- let's create one and also declare the Loaded and UnLoaded handlers. + self.AICargoAPC[APC] = AI_CARGO_APC:New( APC, self.SetCargo, self.CombatRadius ) + AICargoAPC = self.AICargoAPC[APC] + + function AICargoAPC.OnAfterPickup( AICargoAPC, APC, From, Event, To, Cargo ) + self:Pickup( APC, Cargo ) + end + + function AICargoAPC.OnAfterLoad( AICargoAPC, APC ) + self:Load( APC ) + end + + function AICargoAPC.OnAfterLoaded( AICargoAPC, APC, From, Event, To, Cargo ) + self:Loaded( APC, Cargo ) + end + + function AICargoAPC.OnAfterDeploy( AICargoAPC, APC ) + self:Deploy( APC ) + end + + function AICargoAPC.OnAfterUnload( AICargoAPC, APC ) + self:Unload( APC ) + end + + function AICargoAPC.OnAfterUnloaded( AICargoAPC, APC ) + self:Unloaded( APC ) + end + end + + -- The Pickup sequence ... + -- Check if this APC need to go and Pickup something... + self:I( { IsTransporting = AICargoAPC:IsTransporting() } ) + if AICargoAPC:IsTransporting() == false then + -- ok, so there is a free APC + -- now find the first cargo that is Unloaded + + local PickupCargo = nil + + for CargoName, Cargo in pairs( self.SetCargo:GetSet() ) do + if Cargo:IsUnLoaded() and not Cargo:IsDeployed() then + if not self.PickupCargo[Cargo] then + self.PickupCargo[Cargo] = APC + PickupCargo = Cargo + break + end + end + end + if PickupCargo then + AICargoAPC:Pickup( PickupCargo:GetCoordinate(), 70 ) + break + end + end + end + + self:__Monitor( self.MonitorTimeInterval ) + + return self +end + + + +--- Make a APC run for a cargo deploy action after the cargo Pickup trigger has been initiated, by default. +-- @param #AI_CARGO_DISPATCHER self +-- @param Wrapper.Group#GROUP APC +-- @return #AI_CARGO_DISPATCHER +function AI_CARGO_DISPATCHER:onafterPickup( From, Event, To, APC, Cargo ) + return self +end + +--- Make a APC run for a cargo deploy action after the cargo has been loaded, by default. +-- @param #AI_CARGO_DISPATCHER self +-- @param Wrapper.Group#GROUP APC +-- @return #AI_CARGO_DISPATCHER +function AI_CARGO_DISPATCHER:OnAfterLoaded( From, Event, To, APC, Cargo ) + + self:I( { "Loaded Dispatcher", APC } ) + local RandomZone = self.SetDeployZones:GetRandomZone() + self:I( { RandomZone = RandomZone } ) + + self.AICargoAPC[APC]:Deploy( RandomZone:GetCoordinate(), 70 ) + self.PickupCargo[Cargo] = nil + + return self +end + + + + diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua index d9c93e936..eb3c0d4f7 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua @@ -1,4 +1,4 @@ ---- **AI** -- (R2.4) - Models the intelligent transportation of infantry and other cargo. +--- **AI** -- (R2.4) - Models the intelligent transportation of infantry and other cargo using APCs. -- -- === -- @@ -6,10 +6,10 @@ -- -- === -- --- @module AI_Cargo_Dispatcher +-- @module AI_Cargo_Dispatcher_APC --- @type AI_CARGO_DISPATCHER_APC --- @extends Core.Fsm#FSM_CONTROLLABLE +-- @extends AI.AI_Cargo_Dispatcher#AI_CARGO_DISPATCHER --- # AI\_CARGO\_DISPATCHER\_APC class, extends @{Core.Base#BASE} @@ -28,17 +28,8 @@ -- @field #AI_CARGO_DISPATCHER_APC AI_CARGO_DISPATCHER_APC = { ClassName = "AI_CARGO_DISPATCHER_APC", - SetAPC = nil, - SetDeployZones = nil, - AI_CARGO_APC = {} } ---- @type AI_CARGO_DISPATCHER_APC.AI_CARGO_APC --- @map - ---- @field #AI_CARGO_DISPATCHER_APC.AI_CARGO_APC -AI_CARGO_DISPATCHER_APC.AICargoAPC = {} - --- Creates a new AI_CARGO_DISPATCHER_APC object. -- @param #AI_CARGO_DISPATCHER_APC self -- @param Core.Set#SET_GROUP SetAPC @@ -55,104 +46,9 @@ AI_CARGO_DISPATCHER_APC.AICargoAPC = {} -- function AI_CARGO_DISPATCHER_APC:New( SetAPC, SetCargo, SetDeployZones ) - local self = BASE:Inherit( self, FSM:New() ) -- #AI_CARGO_DISPATCHER_APC - - self.SetAPC = SetAPC -- Core.Set#SET_GROUP - self.SetCargo = SetCargo -- Core.Set#SET_CARGO - self.SetDeployZones = SetDeployZones -- Core.Set#SET_ZONE - - self:SetStartState( "APC" ) - - self:AddTransition( "*", "Monitor", "*" ) - - self:AddTransition( "*", "Pickup", "*" ) - self:AddTransition( "*", "Loading", "*" ) - self:AddTransition( "*", "Loaded", "*" ) - - self:AddTransition( "*", "Deploy", "*" ) - self:AddTransition( "*", "Unloading", "*" ) - self:AddTransition( "*", "Unloaded", "*" ) - - self.PickupTimeInterval = 120 - self.DeployRadiusInner = 200 - self.DeployRadiusOuter = 500 - - return self -end - - ---- The Start trigger event, which actually takes action at the specified time interval. --- @param #AI_CARGO_DISPATCHER_APC self --- @param Wrapper.Group#GROUP APC --- @return #AI_CARGO_DISPATCHER_APC -function AI_CARGO_DISPATCHER_APC:onafterMonitor() - - for APCGroupName, APC in pairs( self.SetAPC:GetSet() ) do - local APC = APC -- Wrapper.Group#GROUP - local AICargoAPC = self.AICargoAPC[APC] - if not AICargoAPC then - -- ok, so this APC does not have yet an AI_CARGO_APC object... - -- let's create one and also declare the Loaded and UnLoaded handlers. - self.AICargoAPC[APC] = AI_CARGO_APC:New( APC, self.SetCargo, self.CombatRadius ) - AICargoAPC = self.AICargoAPC[APC] - - function AICargoAPC.OnAfterPickup( AICargoAPC, APC ) - self.AICargoAPC = AICargoAPC - self:Pickup( APC ) - end - - function AICargoAPC.OnAfterLoad( AICargoAPC, APC ) - self.AICargoAPC = AICargoAPC - self:Load( APC ) - end - - function AICargoAPC.OnAfterLoaded( AICargoAPC, APC ) - self.AICargoAPC = AICargoAPC - self:Loaded( APC ) - end - - function AICargoAPC.OnAfterDeploy( AICargoAPC, APC ) - self.AICargoAPC = AICargoAPC - self:Deploy( APC ) - end - - function AICargoAPC.OnAfterUnload( AICargoAPC, APC ) - self.AICargoAPC = AICargoAPC - self:Unload( APC ) - end - - function AICargoAPC.OnAfterUnloaded( AICargoAPC, APC ) - self.AICargoAPC = AICargoAPC - self:Unloaded( APC ) - end - end - - -- The Pickup sequence ... - -- Check if this APC need to go and Pickup something... - if not AICargoAPC:IsTransporting() == true then - -- ok, so there is a free APC - -- now find the first cargo that is Unloaded - local FirstCargoUnloaded = self.SetCargo:FirstCargoUnLoaded() - if FirstCargoUnloaded then - AICargoAPC:Pickup( FirstCargoUnloaded:GetCoordinate() ) - break - end - end - end + local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:New( SetAPC, SetCargo, SetDeployZones ) ) -- #AI_CARGO_DISPATCHER_APC return self end - ---- Make a APC run for a cargo deploy action after the cargo has been loaded, by default. --- @param #AI_CARGO_DISPATCHER_APC self --- @param Wrapper.Group#GROUP APC --- @return #AI_CARGO_DISPATCHER_APC -function AI_CARGO_DISPATCHER_APC:OnAfterLoaded( APC ) - - self:Deploy( self.SetDeployZones:GetRandomZone():GetCoordinate():GetRandomCoordinateInRadius( self.DeployRadiusInner, self.DeployRadiusOuter ) ) - - return self -end - diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua new file mode 100644 index 000000000..4deaef1d9 --- /dev/null +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua @@ -0,0 +1,54 @@ +--- **AI** -- (R2.4) - Models the intelligent transportation of infantry and other cargo using Planes. +-- +-- === +-- +-- ### Author: **FlightControl** +-- +-- === +-- +-- @module AI_Cargo_Dispatcher_Airplane + +--- @type AI_CARGO_DISPATCHER_AIRPLANE +-- @extends AI.AI_Cargo_Dispatcher#AI_CARGO_DISPATCHER + + +--- # AI\_CARGO\_DISPATCHER\_AIRPLANE class, extends @{Core.Base#BASE} +-- +-- === +-- +-- AI\_CARGO\_DISPATCHER\_AIRPLANE 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. +-- Please consult the @{Cargo} module for more information. +-- +-- +-- +-- @field #AI_CARGO_DISPATCHER_AIRPLANE +AI_CARGO_DISPATCHER_AIRPLANE = { + ClassName = "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 +-- @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 ) +-- +function AI_CARGO_DISPATCHER_AIRPLANE:New( SetAirplane, SetCargo, SetDeployZones ) + + local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:New( SetAirplane, SetCargo, SetDeployZones ) ) -- #AI_CARGO_DISPATCHER_AIRPLANE + + return self +end + + diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua new file mode 100644 index 000000000..48b8bdd4c --- /dev/null +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua @@ -0,0 +1,54 @@ +--- **AI** -- (R2.4) - Models the intelligent transportation of infantry and other cargo using Helicopters. +-- +-- === +-- +-- ### Author: **FlightControl** +-- +-- === +-- +-- @module AI_Cargo_Dispatcher_Helicopter + +--- @type AI_CARGO_DISPATCHER_HELICOPTER +-- @extends AI.AI_Cargo_Dispatcher#AI_CARGO_DISPATCHER + + +--- # AI\_CARGO\_DISPATCHER\_HELICOPTER class, extends @{Core.Base#BASE} +-- +-- === +-- +-- AI\_CARGO\_DISPATCHER\_HELICOPTER brings a dynamic cargo handling capability for AI groups. +-- +-- Helicopters can be mobilized to intelligently transport infantry and other cargo within the simulation. +-- The AI\_CARGO\_DISPATCHER\_HELICOPTER module uses the @{Cargo} capabilities within the MOOSE framework. +-- CARGO derived objects must be declared within the mission to make the AI\_CARGO\_DISPATCHER\_HELICOPTER object recognize the cargo. +-- Please consult the @{Cargo} module for more information. +-- +-- +-- +-- @field #AI_CARGO_DISPATCHER_HELICOPTER +AI_CARGO_DISPATCHER_HELICOPTER = { + ClassName = "AI_CARGO_DISPATCHER_HELICOPTER", +} + +--- Creates a new AI_CARGO_DISPATCHER_HELICOPTER object. +-- @param #AI_CARGO_DISPATCHER_HELICOPTER self +-- @param Core.Set#SET_GROUP SetAPC +-- @param Core.Set#SET_CARGO SetCargo +-- @param Core.Set#SET_ZONE SetDeployZone +-- @return #AI_CARGO_DISPATCHER_HELICOPTER +-- @usage +-- +-- -- Create a new cargo dispatcher +-- SetHelicopter = SET_GROUP:New():FilterPrefixes( "Helicopter" ):FilterStart() +-- SetCargo = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart() +-- SetDeployZone = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart() +-- AICargoDispatcher = AI_CARGO_DISPATCHER_HELICOPTER:New( SetHelicopter, SetCargo ) +-- +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 + + return self +end + + diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index 501dd0e5e..c7580db68 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -1149,6 +1149,7 @@ function DATABASE:_RegisterTemplates() local ZoneName = ZoneData.name self.ZONENAMES[ZoneName] = ZoneName self.ZONES[ZoneName] = ZONE:New( ZoneName ) + self:I( "Added ZONE " .. ZoneName ) end return self diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index b8043328d..b29d1d6fa 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -4350,6 +4350,20 @@ function SET_CARGO:FirstCargoWithState( State ) return FirstCargo end +function SET_CARGO:FirstCargoWithStateAndNotDeployed( State ) + + local FirstCargo = nil + + for CargoName, Cargo in pairs( self.Set ) do + if Cargo:Is( State ) and not Cargo:IsDeployed() then + FirstCargo = Cargo + break + end + end + + return FirstCargo +end + --- Iterate the SET_CARGO while identifying the first @{Cargo#CARGO} that is UnLoaded. -- @param #SET_CARGO self @@ -4360,6 +4374,15 @@ function SET_CARGO:FirstCargoUnLoaded() end +--- Iterate the SET_CARGO while identifying the first @{Cargo#CARGO} that is UnLoaded and not Deployed. +-- @param #SET_CARGO self +-- @return Cargo.Cargo#CARGO The first @{Cargo#CARGO}. +function SET_CARGO:FirstCargoUnLoadedAndNotDeployed() + local FirstCargo = self:FirstCargoWithStateAndNotDeployed( "UnLoaded" ) + return FirstCargo +end + + --- Iterate the SET_CARGO while identifying the first @{Cargo#CARGO} that is Loaded. -- @param #SET_CARGO self -- @return Cargo.Cargo#CARGO The first @{Cargo#CARGO}. @@ -4588,7 +4611,7 @@ function SET_ZONE:GetRandomZone() local Index = self.Index local ZoneFound = nil - while not ZoneFound do + while not ZoneFound do local ZoneRandom = math.random( 1, #Index ) ZoneFound = self.Set[Index[ZoneRandom]] end diff --git a/Moose Setup/Moose.files b/Moose Setup/Moose.files index 90e550a13..ea44b6326 100644 --- a/Moose Setup/Moose.files +++ b/Moose Setup/Moose.files @@ -70,9 +70,12 @@ AI/AI_Cas.lua AI/AI_Bai.lua AI/AI_Formation.lua AI/AI_Cargo_APC.lua -AI/AI_Cargo_Dispatcher_APC.lua AI/AI_Cargo_Helicopter.lua AI/AI_Cargo_Airplane.lua +AI/AI_Cargo_Dispatcher.lua +AI/AI_Cargo_Dispatcher_APC.lua +AI/AI_Cargo_Dispatcher_Helicopter.lua +AI/AI_Cargo_Dispatcher_Airplane.lua Actions/Act_Assign.lua Actions/Act_Route.lua