mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'develop' into FF/Develop
This commit is contained in:
@@ -82,11 +82,11 @@ AI_CARGO_APC = {
|
|||||||
|
|
||||||
--- Creates a new AI_CARGO_APC object.
|
--- Creates a new AI_CARGO_APC object.
|
||||||
-- @param #AI_CARGO_APC self
|
-- @param #AI_CARGO_APC self
|
||||||
-- @param Wrapper.Group#GROUP CargoCarrier
|
-- @param Wrapper.Group#GROUP APC
|
||||||
-- @param Core.Set#SET_CARGO CargoSet
|
-- @param Core.Set#SET_CARGO CargoSet
|
||||||
-- @param #number CombatRadius
|
-- @param #number CombatRadius
|
||||||
-- @return #AI_CARGO_APC
|
-- @return #AI_CARGO_APC
|
||||||
function AI_CARGO_APC:New( CargoCarrier, CargoSet, CombatRadius )
|
function AI_CARGO_APC:New( APC, CargoSet, CombatRadius )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- #AI_CARGO_APC
|
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- #AI_CARGO_APC
|
||||||
|
|
||||||
@@ -189,7 +189,8 @@ function AI_CARGO_APC:New( CargoCarrier, CargoSet, CombatRadius )
|
|||||||
|
|
||||||
self:__Monitor( 1 )
|
self:__Monitor( 1 )
|
||||||
|
|
||||||
self:SetCarrier( CargoCarrier )
|
|
||||||
|
self:SetCarrier( APC )
|
||||||
self.Transporting = false
|
self.Transporting = false
|
||||||
self.Relocating = false
|
self.Relocating = false
|
||||||
|
|
||||||
|
|||||||
@@ -9,66 +9,115 @@
|
|||||||
-- @module AI_Cargo_Dispatcher
|
-- @module AI_Cargo_Dispatcher
|
||||||
|
|
||||||
--- @type AI_CARGO_DISPATCHER
|
--- @type AI_CARGO_DISPATCHER
|
||||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
|
|
||||||
--- # AI\_CARGO\_DISPATCHER class, extends @{Core.Base#BASE}
|
--- # AI\_CARGO\_DISPATCHER class, extends @{Core.Fsm#FSM}
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- AI\_CARGO\_DISPATCHER brings a dynamic cargo handling capability for AI groups.
|
-- 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.
|
-- 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.
|
-- The AI\_CARGO\_DISPATCHER module uses the @{Cargo} capabilities within the MOOSE framework, to enable Carrier GROUP objects
|
||||||
|
-- to transport @{Cargo} towards several deploy zones.
|
||||||
-- CARGO derived objects must be declared within the mission to make the AI\_CARGO\_DISPATCHER object recognize the cargo.
|
-- 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.
|
-- Please consult the @{Cargo} module for more information.
|
||||||
--
|
--
|
||||||
|
-- ## 1. AI\_CARGO\_DISPATCHER constructor
|
||||||
|
--
|
||||||
|
-- * @{#AI_CARGO_DISPATCHER.New}(): Creates a new AI\_CARGO\_DISPATCHER object.
|
||||||
--
|
--
|
||||||
|
-- ## 2. AI\_CARGO\_DISPATCHER is a FSM
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- ### 2.1. AI\_CARGO\_DISPATCHER States
|
||||||
|
--
|
||||||
|
-- * **Monitoring**: The process is dispatching.
|
||||||
|
-- * **Idle**: The process is idle.
|
||||||
|
--
|
||||||
|
-- ### 2.2. AI\_CARGO\_DISPATCHER Events
|
||||||
|
--
|
||||||
|
-- * **Monitor**: Monitor and take action.
|
||||||
|
-- * **Start**: Start the transport process.
|
||||||
|
-- * **Stop**: Stop the transport process.
|
||||||
|
-- * **Pickup**: Pickup cargo.
|
||||||
|
-- * **Load**: Load the cargo.
|
||||||
|
-- * **Loaded**: Flag that the cargo is loaded.
|
||||||
|
-- * **Deploy**: Deploy cargo to a location.
|
||||||
|
-- * **Unload**: Unload the cargo.
|
||||||
|
-- * **Unloaded**: Flag that the cargo is unloaded.
|
||||||
|
-- * **Home**: A Carrier is going home.
|
||||||
|
--
|
||||||
|
-- ## 3. Set the pickup parameters.
|
||||||
|
--
|
||||||
|
-- Several parameters can be set to pickup cargo:
|
||||||
|
--
|
||||||
|
-- * @{#AI_CARGO_DISPATCHER.SetPickupRadius}(): Sets or randomizes the pickup location for the carrier around the cargo coordinate in a radius defined an outer and optional inner radius.
|
||||||
|
-- * @{#AI_CARGO_DISPATCHER.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.SetDeployRadius}(): Sets or randomizes the deploy location for the carrier around the cargo coordinate in a radius defined an outer and an optional inner radius.
|
||||||
|
-- * @{#AI_CARGO_DISPATCHER.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 Carriers will move when there isn't any cargo left for pickup.
|
||||||
|
-- Use @{#AI_CARGO_DISPATCHER.SetHomeZone}() to specify the home zone.
|
||||||
|
--
|
||||||
|
-- If no home zone is specified, the carriers will wait near the deploy zone for a new pickup command.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
-- @field #AI_CARGO_DISPATCHER
|
-- @field #AI_CARGO_DISPATCHER
|
||||||
AI_CARGO_DISPATCHER = {
|
AI_CARGO_DISPATCHER = {
|
||||||
ClassName = "AI_CARGO_DISPATCHER",
|
ClassName = "AI_CARGO_DISPATCHER",
|
||||||
SetAPC = nil,
|
SetCarrier = nil,
|
||||||
SetDeployZones = nil,
|
SetDeployZones = nil,
|
||||||
AI_CARGO_APC = {}
|
AI_Cargo = {},
|
||||||
|
PickupCargo = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
--- @type AI_CARGO_DISPATCHER.AI_CARGO_APC
|
--- @field #AI_CARGO_DISPATCHER.AI_Cargo
|
||||||
-- @map <Wrapper.Group#GROUP, AI.AI_Cargo_APC#AI_CARGO_APC>
|
|
||||||
|
|
||||||
--- @field #AI_CARGO_DISPATCHER.AI_CARGO_APC
|
|
||||||
AI_CARGO_DISPATCHER.AI_Cargo = {}
|
AI_CARGO_DISPATCHER.AI_Cargo = {}
|
||||||
|
|
||||||
--- @field #AI_CARGO_DISPATCHER.PickupCargo
|
--- @field #AI_CARGO_DISPATCHER.PickupCargo
|
||||||
AI_CARGO_DISPATCHER.PickupCargo = {}
|
AI_CARGO_DISPATCHER.PickupCargo = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Creates a new AI_CARGO_DISPATCHER object.
|
--- Creates a new AI_CARGO_DISPATCHER object.
|
||||||
-- @param #AI_CARGO_DISPATCHER self
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
-- @param Core.Set#SET_GROUP SetAPC
|
-- @param Core.Set#SET_GROUP SetCarrier
|
||||||
-- @param Core.Set#SET_CARGO SetCargo
|
-- @param Core.Set#SET_CARGO SetCargo
|
||||||
-- @param Core.Set#SET_ZONE SetDeployZone
|
-- @param Core.Set#SET_ZONE SetDeployZone
|
||||||
-- @return #AI_CARGO_DISPATCHER
|
-- @return #AI_CARGO_DISPATCHER
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
-- -- Create a new cargo dispatcher
|
-- -- Create a new cargo dispatcher
|
||||||
-- SetAPC = SET_GROUP:New():FilterPrefixes( "APC" ):FilterStart()
|
-- SetCarrier = SET_GROUP:New():FilterPrefixes( "APC" ):FilterStart()
|
||||||
-- SetCargo = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart()
|
-- SetCargo = 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( SetAPC, SetCargo, SetDeployZone )
|
-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZone )
|
||||||
--
|
--
|
||||||
function AI_CARGO_DISPATCHER:New( SetAPC, SetCargo, SetDeployZones )
|
function AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZones )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, FSM:New() ) -- #AI_CARGO_DISPATCHER
|
local self = BASE:Inherit( self, FSM:New() ) -- #AI_CARGO_DISPATCHER
|
||||||
|
|
||||||
self.SetAPC = SetAPC -- 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.SetDeployZones = SetDeployZones -- Core.Set#SET_ZONE
|
||||||
|
|
||||||
self:SetStartState( "Dispatch" )
|
self:SetStartState( "Idle" )
|
||||||
|
|
||||||
|
self:AddTransition( "Monitoring", "Monitor", "Monitoring" )
|
||||||
|
|
||||||
|
self:AddTransition( "Idle", "Start", "Monitoring" )
|
||||||
|
self:AddTransition( "Monitoring", "Stop", "Idle" )
|
||||||
|
|
||||||
self:AddTransition( "*", "Monitor", "*" )
|
|
||||||
|
|
||||||
self:AddTransition( "*", "Pickup", "*" )
|
self:AddTransition( "*", "Pickup", "*" )
|
||||||
self:AddTransition( "*", "Loading", "*" )
|
self:AddTransition( "*", "Loading", "*" )
|
||||||
@@ -84,8 +133,16 @@ function AI_CARGO_DISPATCHER:New( SetAPC, SetCargo, SetDeployZones )
|
|||||||
self.DeployRadiusInner = 200
|
self.DeployRadiusInner = 200
|
||||||
self.DeployRadiusOuter = 500
|
self.DeployRadiusOuter = 500
|
||||||
|
|
||||||
|
self.PickupCargo = {}
|
||||||
self.CarrierHome = {}
|
self.CarrierHome = {}
|
||||||
|
|
||||||
|
-- Put a Dead event handler on SetCarrier, to ensure that when a carrier is destroyed, that all internal parameters are reset.
|
||||||
|
function SetCarrier.OnAfterRemoved( SetCarrier, From, Event, To, CarrierName, Carrier )
|
||||||
|
self:F( { Carrier = Carrier:GetName() } )
|
||||||
|
self.PickupCargo[Carrier] = nil
|
||||||
|
self.CarrierHome[Carrier] = nil
|
||||||
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -99,7 +156,7 @@ end
|
|||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
-- -- Create a new cargo dispatcher
|
-- -- Create a new cargo dispatcher
|
||||||
-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetAPC, SetCargo, SetDeployZone )
|
-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZone )
|
||||||
--
|
--
|
||||||
-- -- Set the home coordinate
|
-- -- Set the home coordinate
|
||||||
-- local HomeZone = ZONE:New( "Home" )
|
-- local HomeZone = ZONE:New( "Home" )
|
||||||
@@ -113,71 +170,192 @@ function AI_CARGO_DISPATCHER:SetHomeZone( HomeZone )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Sets or randomizes the pickup location for the carrier around the cargo coordinate in a radius defined an outer and optional inner radius.
|
||||||
|
-- This radius is influencing the location where the carrier will land to pickup the cargo.
|
||||||
|
-- There are two aspects that are very important to remember and take into account:
|
||||||
|
--
|
||||||
|
-- - Ensure that the outer and inner radius are within reporting radius set by the cargo.
|
||||||
|
-- For example, if the cargo has a reporting radius of 400 meters, and the outer and inner radius is set to 500 and 450 respectively,
|
||||||
|
-- then no cargo will be loaded!!!
|
||||||
|
-- - Also take care of the potential cargo position and possible reasons to crash the carrier. This is especially important
|
||||||
|
-- for locations which are crowded with other objects, like in the middle of villages or cities.
|
||||||
|
-- So, for the best operation of cargo operations, always ensure that the cargo is located at open spaces.
|
||||||
|
--
|
||||||
|
-- The default radius is 0, so the center. In case of a polygon zone, a random location will be selected as the center in the zone.
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
-- @param #number OuterRadius The outer radius in meters around the cargo coordinate.
|
||||||
|
-- @param #number InnerRadius (optional) The inner radius in meters around the cargo coordinate.
|
||||||
|
-- @return #AI_CARGO_DISPATCHER
|
||||||
|
-- @usage
|
||||||
|
--
|
||||||
|
-- -- Create a new cargo dispatcher
|
||||||
|
-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZone )
|
||||||
|
--
|
||||||
|
-- -- Set the carrier to land within a band around the cargo coordinate between 500 and 300 meters!
|
||||||
|
-- AICargoDispatcher:SetPickupRadius( 500, 300 )
|
||||||
|
--
|
||||||
|
function AI_CARGO_DISPATCHER:SetPickupRadius( OuterRadius, InnerRadius )
|
||||||
|
|
||||||
|
OuterRadius = OuterRadius or 0
|
||||||
|
InnerRadius = InnerRadius or OuterRadius
|
||||||
|
|
||||||
|
self.PickupOuterRadius = OuterRadius
|
||||||
|
self.PickupInnerRadius = InnerRadius
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set the speed or randomizes the speed in km/h to pickup the cargo.
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
-- @param #number MaxSpeed (optional) The maximum speed to move to the cargo pickup location.
|
||||||
|
-- @param #number MinSpeed The minimum speed to move to the cargo pickup location.
|
||||||
|
-- @return #AI_CARGO_DISPATCHER
|
||||||
|
-- @usage
|
||||||
|
--
|
||||||
|
-- -- Create a new cargo dispatcher
|
||||||
|
-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZone )
|
||||||
|
--
|
||||||
|
-- -- Set the minimum pickup speed to be 100 km/h and the maximum speed to be 200 km/h.
|
||||||
|
-- AICargoDispatcher:SetPickupSpeed( 200, 100 )
|
||||||
|
--
|
||||||
|
function AI_CARGO_DISPATCHER:SetPickupSpeed( MaxSpeed, MinSpeed )
|
||||||
|
|
||||||
|
MaxSpeed = MaxSpeed or 999
|
||||||
|
MinSpeed = MinSpeed or MaxSpeed
|
||||||
|
|
||||||
|
self.PickupMinSpeed = MinSpeed
|
||||||
|
self.PickupMaxSpeed = MaxSpeed
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Sets or randomizes the deploy location for the carrier around the cargo coordinate in a radius defined an outer and an optional inner radius.
|
||||||
|
-- This radius is influencing the location where the carrier will land to deploy the cargo.
|
||||||
|
-- There is an aspect that is very important to remember and take into account:
|
||||||
|
--
|
||||||
|
-- - Take care of the potential cargo position and possible reasons to crash the carrier. This is especially important
|
||||||
|
-- for locations which are crowded with other objects, like in the middle of villages or cities.
|
||||||
|
-- So, for the best operation of cargo operations, always ensure that the cargo is located at open spaces.
|
||||||
|
--
|
||||||
|
-- The default radius is 0, so the center. In case of a polygon zone, a random location will be selected as the center in the zone.
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
-- @param #number OuterRadius The outer radius in meters around the cargo coordinate.
|
||||||
|
-- @param #number InnerRadius (optional) The inner radius in meters around the cargo coordinate.
|
||||||
|
-- @return #AI_CARGO_DISPATCHER
|
||||||
|
-- @usage
|
||||||
|
--
|
||||||
|
-- -- Create a new cargo dispatcher
|
||||||
|
-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZone )
|
||||||
|
--
|
||||||
|
-- -- Set the carrier to land within a band around the cargo coordinate between 500 and 300 meters!
|
||||||
|
-- AICargoDispatcher:SetDeployRadius( 500, 300 )
|
||||||
|
--
|
||||||
|
function AI_CARGO_DISPATCHER:SetDeployRadius( OuterRadius, InnerRadius )
|
||||||
|
|
||||||
|
OuterRadius = OuterRadius or 0
|
||||||
|
InnerRadius = InnerRadius or OuterRadius
|
||||||
|
|
||||||
|
self.DeployOuterRadius = OuterRadius
|
||||||
|
self.DeployInnerRadius = InnerRadius
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Sets or randomizes the speed in km/h to deploy the cargo.
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
-- @param #number MaxSpeed The maximum speed to move to the cargo deploy location.
|
||||||
|
-- @param #number MinSpeed (optional) The minimum speed to move to the cargo deploy location.
|
||||||
|
-- @return #AI_CARGO_DISPATCHER
|
||||||
|
-- @usage
|
||||||
|
--
|
||||||
|
-- -- Create a new cargo dispatcher
|
||||||
|
-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZone )
|
||||||
|
--
|
||||||
|
-- -- Set the minimum deploy speed to be 100 km/h and the maximum speed to be 200 km/h.
|
||||||
|
-- AICargoDispatcher:SetDeploySpeed( 200, 100 )
|
||||||
|
--
|
||||||
|
function AI_CARGO_DISPATCHER:SetDeploySpeed( MaxSpeed, MinSpeed )
|
||||||
|
|
||||||
|
MaxSpeed = MaxSpeed or 999
|
||||||
|
MinSpeed = MinSpeed or MaxSpeed
|
||||||
|
|
||||||
|
self.DeployMinSpeed = MinSpeed
|
||||||
|
self.DeployMaxSpeed = MaxSpeed
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- The Start trigger event, which actually takes action at the specified time interval.
|
--- The Start trigger event, which actually takes action at the specified time interval.
|
||||||
-- @param #AI_CARGO_DISPATCHER self
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
-- @param Wrapper.Group#GROUP APC
|
|
||||||
-- @return #AI_CARGO_DISPATCHER
|
|
||||||
function AI_CARGO_DISPATCHER:onafterMonitor()
|
function AI_CARGO_DISPATCHER:onafterMonitor()
|
||||||
|
|
||||||
for APCGroupName, Carrier in pairs( self.SetAPC:GetSet() ) do
|
for CarrierGroupName, Carrier in pairs( self.SetCarrier:GetSet() ) do
|
||||||
local Carrier = Carrier -- Wrapper.Group#GROUP
|
local Carrier = Carrier -- Wrapper.Group#GROUP
|
||||||
local AI_Cargo = self.AI_Cargo[Carrier]
|
local AI_Cargo = self.AI_Cargo[Carrier]
|
||||||
if not AI_Cargo then
|
if not AI_Cargo then
|
||||||
|
|
||||||
-- ok, so this APC does not have yet an AI_CARGO_APC object...
|
-- ok, so this Carrier does not have yet an AI_CARGO handling object...
|
||||||
-- let's create one and also declare the Loaded and UnLoaded handlers.
|
-- let's create one and also declare the Loaded and UnLoaded handlers.
|
||||||
self.AI_Cargo[Carrier] = self:AICargo( Carrier, self.SetCargo, self.CombatRadius )
|
self.AI_Cargo[Carrier] = self:AICargo( Carrier, self.SetCargo, self.CombatRadius )
|
||||||
AI_Cargo = self.AI_Cargo[Carrier]
|
AI_Cargo = self.AI_Cargo[Carrier]
|
||||||
|
|
||||||
function AI_Cargo.OnAfterPickup( AI_Cargo, APC, From, Event, To, Cargo )
|
function AI_Cargo.OnAfterPickup( AI_Cargo, Carrier, From, Event, To, Cargo )
|
||||||
self:Pickup( APC, Cargo )
|
self:Pickup( Carrier, Cargo )
|
||||||
end
|
end
|
||||||
|
|
||||||
function AI_Cargo.OnAfterLoad( AI_Cargo, APC )
|
function AI_Cargo.OnAfterLoad( AI_Cargo, Carrier )
|
||||||
self:Loading( APC )
|
self:Loading( Carrier )
|
||||||
end
|
end
|
||||||
|
|
||||||
function AI_Cargo.OnAfterLoaded( AI_Cargo, APC, From, Event, To, Cargo )
|
function AI_Cargo.OnAfterLoaded( AI_Cargo, Carrier, From, Event, To, Cargo )
|
||||||
self:Loaded( APC, Cargo )
|
self:Loaded( Carrier, Cargo )
|
||||||
end
|
end
|
||||||
|
|
||||||
function AI_Cargo.OnAfterDeploy( AI_Cargo, APC )
|
function AI_Cargo.OnAfterDeploy( AI_Cargo, Carrier )
|
||||||
self:Deploy( APC )
|
self:Deploy( Carrier )
|
||||||
end
|
end
|
||||||
|
|
||||||
function AI_Cargo.OnAfterUnload( AI_Cargo, APC )
|
function AI_Cargo.OnAfterUnload( AI_Cargo, Carrier )
|
||||||
self:Unloading( APC )
|
self:Unloading( Carrier )
|
||||||
end
|
end
|
||||||
|
|
||||||
function AI_Cargo.OnAfterUnloaded( AI_Cargo, APC )
|
function AI_Cargo.OnAfterUnloaded( AI_Cargo, Carrier )
|
||||||
self:Unloaded( APC )
|
self:Unloaded( Carrier )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- The Pickup sequence ...
|
-- The Pickup sequence ...
|
||||||
-- Check if this APC need to go and Pickup something...
|
-- Check if this Carrier need to go and Pickup something...
|
||||||
self:I( { IsTransporting = AI_Cargo:IsTransporting() } )
|
self:I( { IsTransporting = AI_Cargo:IsTransporting() } )
|
||||||
if AI_Cargo:IsTransporting() == false then
|
if AI_Cargo:IsTransporting() == false then
|
||||||
-- ok, so there is a free APC
|
-- ok, so there is a free Carrier
|
||||||
-- now find the first cargo that is Unloaded
|
-- now find the first cargo that is Unloaded
|
||||||
|
|
||||||
local PickupCargo = nil
|
local PickupCargo = nil
|
||||||
|
|
||||||
for CargoName, Cargo in pairs( self.SetCargo:GetSet() ) do
|
for CargoName, Cargo in pairs( self.SetCargo:GetSet() ) do
|
||||||
local Cargo = Cargo -- Cargo.Cargo#CARGO
|
local Cargo = Cargo -- Cargo.Cargo#CARGO
|
||||||
self:F( { Cargo = Cargo:GetName(), UnLoaded = Cargo:IsUnLoaded(), Deployed = Cargo:IsDeployed(), PickupCargo = self.PickupCargo[Cargo] ~= nil } )
|
self:F( { Cargo = Cargo:GetName(), UnLoaded = Cargo:IsUnLoaded(), Deployed = Cargo:IsDeployed(), PickupCargo = self.PickupCargo[Carrier] ~= nil } )
|
||||||
if Cargo:IsUnLoaded() and not Cargo:IsDeployed() then
|
if Cargo:IsUnLoaded() and not Cargo:IsDeployed() then
|
||||||
local CargoVec2 = { x = Cargo:GetX(), y = Cargo:GetY() }
|
local CargoCoordinate = Cargo:GetCoordinate()
|
||||||
local LocationFound = false
|
local CoordinateFree = true
|
||||||
for APC, Vec2 in pairs( self.PickupCargo ) do
|
for CarrierPickup, Coordinate in pairs( self.PickupCargo ) do
|
||||||
if Vec2.x == CargoVec2.x and Vec2.y == CargoVec2.y then
|
if CarrierPickup:IsAlive() == true then
|
||||||
LocationFound = true
|
if CargoCoordinate:Get2DDistance( Coordinate ) <= 25 then
|
||||||
break
|
CoordinateFree = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.PickupCargo[CarrierPickup] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if LocationFound == false then
|
if CoordinateFree == true then
|
||||||
self.PickupCargo[Carrier] = CargoVec2
|
self.PickupCargo[Carrier] = CargoCoordinate
|
||||||
PickupCargo = Cargo
|
PickupCargo = Cargo
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
@@ -185,13 +363,14 @@ function AI_CARGO_DISPATCHER:onafterMonitor()
|
|||||||
end
|
end
|
||||||
if PickupCargo then
|
if PickupCargo then
|
||||||
self.CarrierHome[Carrier] = nil
|
self.CarrierHome[Carrier] = nil
|
||||||
AI_Cargo:Pickup( PickupCargo:GetCoordinate() )
|
local PickupCoordinate = PickupCargo:GetCoordinate():GetRandomCoordinateInRadius( self.PickupOuterRadius, self.PickupInnerRadius )
|
||||||
|
AI_Cargo:Pickup( PickupCoordinate, math.random( self.PickupMinSpeed, self.PickupMaxSpeed ) )
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
if self.HomeZone then
|
if self.HomeZone then
|
||||||
if not self.CarrierHome[Carrier] then
|
if not self.CarrierHome[Carrier] then
|
||||||
self.CarrierHome[Carrier] = true
|
self.CarrierHome[Carrier] = true
|
||||||
AI_Cargo:Home( self.HomeZone:GetRandomPointVec2() )
|
AI_Cargo:__Home( 60, self.HomeZone:GetRandomPointVec2() )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -199,35 +378,90 @@ function AI_CARGO_DISPATCHER:onafterMonitor()
|
|||||||
end
|
end
|
||||||
|
|
||||||
self:__Monitor( self.MonitorTimeInterval )
|
self:__Monitor( self.MonitorTimeInterval )
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Start Handler OnBefore for AI_CARGO_DISPATCHER
|
||||||
|
-- @function [parent=#AI_CARGO_DISPATCHER] OnBeforeStart
|
||||||
--- 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 #AI_CARGO_DISPATCHER self
|
||||||
-- @param Wrapper.Group#GROUP APC
|
-- @param #string From
|
||||||
-- @return #AI_CARGO_DISPATCHER
|
-- @param #string Event
|
||||||
function AI_CARGO_DISPATCHER:onafterPickup( From, Event, To, APC, Cargo )
|
-- @param #string To
|
||||||
return self
|
-- @return #boolean
|
||||||
end
|
|
||||||
|
|
||||||
--- Make a APC run for a cargo deploy action after the cargo has been loaded, by default.
|
--- Start Handler OnAfter for AI_CARGO_DISPATCHER
|
||||||
|
-- @function [parent=#AI_CARGO_DISPATCHER] OnAfterStart
|
||||||
-- @param #AI_CARGO_DISPATCHER self
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
-- @param Wrapper.Group#GROUP APC
|
-- @param #string From
|
||||||
-- @return #AI_CARGO_DISPATCHER
|
-- @param #string Event
|
||||||
function AI_CARGO_DISPATCHER:OnAfterLoaded( From, Event, To, APC, Cargo )
|
-- @param #string To
|
||||||
|
|
||||||
self:I( { "Loaded Dispatcher", APC } )
|
--- Start Trigger for AI_CARGO_DISPATCHER
|
||||||
local RandomZone = self.SetDeployZones:GetRandomZone()
|
-- @function [parent=#AI_CARGO_DISPATCHER] Start
|
||||||
self:I( { RandomZone = RandomZone } )
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
|
||||||
|
--- Start Asynchronous Trigger for AI_CARGO_DISPATCHER
|
||||||
|
-- @function [parent=#AI_CARGO_DISPATCHER] __Start
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
function AI_CARGO_DISPATCHER:onafterStart( From, Event, To )
|
||||||
|
self:Monitor()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Stop Handler OnBefore for AI_CARGO_DISPATCHER
|
||||||
|
-- @function [parent=#AI_CARGO_DISPATCHER] OnBeforeStop
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Stop Handler OnAfter for AI_CARGO_DISPATCHER
|
||||||
|
-- @function [parent=#AI_CARGO_DISPATCHER] OnAfterStop
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
--- Stop Trigger for AI_CARGO_DISPATCHER
|
||||||
|
-- @function [parent=#AI_CARGO_DISPATCHER] Stop
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
|
||||||
|
--- Stop Asynchronous Trigger for AI_CARGO_DISPATCHER
|
||||||
|
-- @function [parent=#AI_CARGO_DISPATCHER] __Stop
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Make a Carrier run for a cargo deploy action after the cargo Pickup trigger has been initiated, by default.
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
-- @param From
|
||||||
|
-- @param Event
|
||||||
|
-- @param To
|
||||||
|
-- @param Wrapper.Group#GROUP Carrier
|
||||||
|
-- @param Cargo.Cargo#CARGO Cargo
|
||||||
|
-- @return #AI_CARGO_DISPATCHER
|
||||||
|
function AI_CARGO_DISPATCHER:OnAfterPickup( From, Event, To, Carrier, Cargo )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Make a Carrier run for a cargo deploy action after the cargo has been loaded, by default.
|
||||||
|
-- @param #AI_CARGO_DISPATCHER self
|
||||||
|
-- @param From
|
||||||
|
-- @param Event
|
||||||
|
-- @param To
|
||||||
|
-- @param Wrapper.Group#GROUP Carrier
|
||||||
|
-- @param Cargo.Cargo#CARGO Cargo
|
||||||
|
-- @return #AI_CARGO_DISPATCHER
|
||||||
|
function AI_CARGO_DISPATCHER:OnAfterLoaded( From, Event, To, Carrier, Cargo )
|
||||||
|
|
||||||
|
local DeployZone = self.SetDeployZones:GetRandomZone()
|
||||||
|
|
||||||
self.AI_Cargo[APC]:Deploy( RandomZone:GetCoordinate(), 70 )
|
local DeployCoordinate = DeployZone:GetCoordinate():GetRandomCoordinateInRadius( self.DeployOuterRadius, self.DeployInnerRadius )
|
||||||
|
self.AI_Cargo[Carrier]:Deploy( DeployCoordinate, math.random( self.DeployMinSpeed, self.DeployMaxSpeed ) )
|
||||||
|
|
||||||
self.PickupCargo[APC] = nil
|
self.PickupCargo[Carrier] = nil
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
--- # AI\_CARGO\_DISPATCHER\_APC class, extends @{Core.Base#BASE}
|
--- # AI\_CARGO\_DISPATCHER\_APC class, extends @{Core.Base#BASE}
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- AI\_CARGO\_DISPATCHER\_APC brings a dynamic cargo handling capability for AI groups.
|
-- AI\_CARGO\_DISPATCHER\_APC brings a dynamic cargo handling capability for AI groups.
|
||||||
@@ -23,7 +25,54 @@
|
|||||||
-- CARGO derived objects must be declared within the mission to make the AI\_CARGO\_DISPATCHER\_APC object recognize the cargo.
|
-- CARGO derived objects must be declared within the mission to make the AI\_CARGO\_DISPATCHER\_APC object recognize the cargo.
|
||||||
-- Please consult the @{Cargo} module for more information.
|
-- Please consult the @{Cargo} module for more information.
|
||||||
--
|
--
|
||||||
|
-- ## 1. AI\_CARGO\_DISPATCHER\_APC constructor
|
||||||
|
--
|
||||||
|
-- * @{#AI_CARGO_DISPATCHER\_APC.New}(): Creates a new AI\_CARGO\_DISPATCHER\_APC object.
|
||||||
--
|
--
|
||||||
|
-- ## 2. AI\_CARGO\_DISPATCHER\_APC is a FSM
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- ### 2.1. AI\_CARGO\_DISPATCHER\_APC States
|
||||||
|
--
|
||||||
|
-- * **Monitoring**: The process is dispatching.
|
||||||
|
-- * **Idle**: The process is idle.
|
||||||
|
--
|
||||||
|
-- ### 2.2. AI\_CARGO\_DISPATCHER\_APC Events
|
||||||
|
--
|
||||||
|
-- * **Monitor**: Monitor and take action.
|
||||||
|
-- * **Start**: Start the transport process.
|
||||||
|
-- * **Stop**: Stop the transport process.
|
||||||
|
-- * **Pickup**: Pickup cargo.
|
||||||
|
-- * **Load**: Load the cargo.
|
||||||
|
-- * **Loaded**: Flag that the cargo is loaded.
|
||||||
|
-- * **Deploy**: Deploy cargo to a location.
|
||||||
|
-- * **Unload**: Unload the cargo.
|
||||||
|
-- * **Unloaded**: Flag that the cargo is unloaded.
|
||||||
|
-- * **Home**: A APC is going home.
|
||||||
|
--
|
||||||
|
-- ## 3. Set the pickup parameters.
|
||||||
|
--
|
||||||
|
-- Several parameters can be set to pickup cargo:
|
||||||
|
--
|
||||||
|
-- * @{#AI_CARGO_DISPATCHER\_APC.SetPickupRadius}(): Sets or randomizes the pickup location for the APC around the cargo coordinate in a radius defined an outer and optional inner radius.
|
||||||
|
-- * @{#AI_CARGO_DISPATCHER\_APC.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\_APC.SetDeployRadius}(): Sets or randomizes the deploy location for the APC around the cargo coordinate in a radius defined an outer and an optional inner radius.
|
||||||
|
-- * @{#AI_CARGO_DISPATCHER\_APC.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 APCs will move when there isn't any cargo left for pickup.
|
||||||
|
-- Use @{#AI_CARGO_DISPATCHER\_APC.SetHomeZone}() to specify the home zone.
|
||||||
|
--
|
||||||
|
-- If no home zone is specified, the APCs will wait near the deploy zone for a new pickup command.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
--
|
--
|
||||||
-- @field #AI_CARGO_DISPATCHER_APC
|
-- @field #AI_CARGO_DISPATCHER_APC
|
||||||
AI_CARGO_DISPATCHER_APC = {
|
AI_CARGO_DISPATCHER_APC = {
|
||||||
@@ -32,25 +81,29 @@ AI_CARGO_DISPATCHER_APC = {
|
|||||||
|
|
||||||
--- Creates a new AI_CARGO_DISPATCHER_APC object.
|
--- Creates a new AI_CARGO_DISPATCHER_APC object.
|
||||||
-- @param #AI_CARGO_DISPATCHER_APC self
|
-- @param #AI_CARGO_DISPATCHER_APC self
|
||||||
-- @param Core.Set#SET_GROUP SetAPC
|
-- @param Core.Set#SET_GROUP SetAPC The collection of APC @{Group}s.
|
||||||
-- @param Core.Set#SET_CARGO SetCargo
|
-- @param Core.Set#SET_CARGO SetCargo The collection of @{Cargo} derived objects.
|
||||||
-- @param Core.Set#SET_ZONE SetDeployZone
|
-- @param Core.Set#SET_ZONE SetDeployZone The collection of deploy @{Zone}s, which are used to where the cargo will be deployed by the APCs.
|
||||||
|
-- @param #number CombatRadius The cargo will be unloaded from the APC and engage the enemy if the enemy is within CombatRadius range. The radius is in meters, the default value is 500 meters.
|
||||||
-- @return #AI_CARGO_DISPATCHER_APC
|
-- @return #AI_CARGO_DISPATCHER_APC
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
-- -- Create a new cargo dispatcher
|
-- -- Create a new cargo dispatcher for the set of APCs, with a combatradius of 500.
|
||||||
-- SetAPC = SET_GROUP:New():FilterPrefixes( "APC" ):FilterStart()
|
-- SetAPC = SET_GROUP:New():FilterPrefixes( "APC" ):FilterStart()
|
||||||
-- SetCargo = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart()
|
-- SetCargo = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart()
|
||||||
-- SetDeployZone = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart()
|
-- SetDeployZone = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart()
|
||||||
-- AICargoDispatcher = AI_CARGO_DISPATCHER_APC:New( SetAPC, SetCargo )
|
-- AICargoDispatcher = AI_CARGO_DISPATCHER_APC:New( SetAPC, SetCargo, SetDeployZone, 500 )
|
||||||
--
|
--
|
||||||
function AI_CARGO_DISPATCHER_APC:New( SetAPC, SetCargo, SetDeployZones )
|
function AI_CARGO_DISPATCHER_APC:New( SetAPC, SetCargo, SetDeployZones, CombatRadius )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:New( SetAPC, SetCargo, SetDeployZones ) ) -- #AI_CARGO_DISPATCHER_APC
|
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:New( SetAPC, SetCargo, SetDeployZones ) ) -- #AI_CARGO_DISPATCHER_APC
|
||||||
|
|
||||||
self.CombatRadius = 500
|
self.CombatRadius = CombatRadius or 500
|
||||||
|
|
||||||
self:Monitor( 1 )
|
self:SetDeploySpeed( 70, 120 )
|
||||||
|
self:SetPickupSpeed( 70, 120 )
|
||||||
|
self:SetPickupRadius( 0, 0 )
|
||||||
|
self:SetDeployRadius( 0, 0 )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--- **AI** -- (R2.4) - Models the intelligent transportation of infantry and other cargo using Helicopters.
|
--- **AI** -- (R2.4) - Models the intelligent transportation of infantry and other cargo using Helicopters.
|
||||||
--
|
--
|
||||||
|
-- The @{#AI_CARGO_DISPATCHER_HELICOPTER} classes implements the dynamic dispatching of cargo transportation tasks for helicopters.
|
||||||
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **FlightControl**
|
-- ### Author: **FlightControl**
|
||||||
@@ -12,18 +14,77 @@
|
|||||||
-- @extends AI.AI_Cargo_Dispatcher#AI_CARGO_DISPATCHER
|
-- @extends AI.AI_Cargo_Dispatcher#AI_CARGO_DISPATCHER
|
||||||
|
|
||||||
|
|
||||||
--- # AI\_CARGO\_DISPATCHER\_HELICOPTER class, extends @{Core.Base#BASE}
|
--- # AI\_CARGO\_DISPATCHER\_HELICOPTER class, extends @{AI.AI_Cargo_Dispatcher#AI_CARGO_DISPATCHER}
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- AI\_CARGO\_DISPATCHER\_HELICOPTER brings a dynamic cargo handling capability for AI groups.
|
-- AI\_CARGO\_DISPATCHER\_HELICOPTER brings a dynamic cargo handling capability for AI helicopter groups.
|
||||||
--
|
--
|
||||||
-- Helicopters can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- 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.
|
-- 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.
|
-- 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.
|
-- Please consult the @{Cargo} module for more information.
|
||||||
--
|
--
|
||||||
|
-- ---
|
||||||
--
|
--
|
||||||
|
-- ## 1. AI\_CARGO\_DISPATCHER\_HELICOPTER constructor
|
||||||
|
--
|
||||||
|
-- * @{#AI_CARGO_DISPATCHER\_HELICOPTER.New}(): Creates a new AI\_CARGO\_DISPATCHER\_HELICOPTER object.
|
||||||
|
--
|
||||||
|
-- ---
|
||||||
|
--
|
||||||
|
-- ## 2. AI\_CARGO\_DISPATCHER\_HELICOPTER is a FSM
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- ### 2.1. AI\_CARGO\_DISPATCHER\_HELICOPTER States
|
||||||
|
--
|
||||||
|
-- * **Monitoring**: The process is dispatching.
|
||||||
|
-- * **Idle**: The process is idle.
|
||||||
|
--
|
||||||
|
-- ### 2.2. AI\_CARGO\_DISPATCHER\_HELICOPTER Events
|
||||||
|
--
|
||||||
|
-- * **Monitor**: Monitor and take action.
|
||||||
|
-- * **Start**: Start the transport process.
|
||||||
|
-- * **Stop**: Stop the transport process.
|
||||||
|
-- * **Pickup**: Pickup cargo.
|
||||||
|
-- * **Load**: Load the cargo.
|
||||||
|
-- * **Loaded**: Flag that the cargo is loaded.
|
||||||
|
-- * **Deploy**: Deploy cargo to a location.
|
||||||
|
-- * **Unload**: Unload the cargo.
|
||||||
|
-- * **Unloaded**: Flag that the cargo is unloaded.
|
||||||
|
-- * **Home**: A Helicopter is going home.
|
||||||
|
--
|
||||||
|
-- ---
|
||||||
|
--
|
||||||
|
-- ## 3. Set the pickup parameters.
|
||||||
|
--
|
||||||
|
-- Several parameters can be set to pickup cargo:
|
||||||
|
--
|
||||||
|
-- * @{#AI_CARGO_DISPATCHER\_HELICOPTER.SetPickupRadius}(): Sets or randomizes the pickup location for the helicopter around the cargo coordinate in a radius defined an outer and optional inner radius.
|
||||||
|
-- * @{#AI_CARGO_DISPATCHER\_HELICOPTER.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\_HELICOPTER.SetDeployRadius}(): Sets or randomizes the deploy location for the helicopter around the cargo coordinate in a radius defined an outer and an optional inner radius.
|
||||||
|
-- * @{#AI_CARGO_DISPATCHER\_HELICOPTER.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 Helicopters will move when there isn't any cargo left for pickup.
|
||||||
|
-- Use @{#AI_CARGO_DISPATCHER\_HELICOPTER.SetHomeZone}() to specify the home zone.
|
||||||
|
--
|
||||||
|
-- If no home zone is specified, the helicopters will wait near the deploy zone for a new pickup command.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
--
|
--
|
||||||
-- @field #AI_CARGO_DISPATCHER_HELICOPTER
|
-- @field #AI_CARGO_DISPATCHER_HELICOPTER
|
||||||
AI_CARGO_DISPATCHER_HELICOPTER = {
|
AI_CARGO_DISPATCHER_HELICOPTER = {
|
||||||
@@ -32,9 +93,9 @@ AI_CARGO_DISPATCHER_HELICOPTER = {
|
|||||||
|
|
||||||
--- Creates a new AI_CARGO_DISPATCHER_HELICOPTER object.
|
--- Creates a new AI_CARGO_DISPATCHER_HELICOPTER object.
|
||||||
-- @param #AI_CARGO_DISPATCHER_HELICOPTER self
|
-- @param #AI_CARGO_DISPATCHER_HELICOPTER self
|
||||||
-- @param Core.Set#SET_GROUP SetHelicopter
|
-- @param Core.Set#SET_GROUP SetHelicopter The collection of Helicopter @{Group}s.
|
||||||
-- @param Core.Set#SET_CARGO SetCargo
|
-- @param Core.Set#SET_CARGO SetCargo The collection of @{Cargo} derived objects.
|
||||||
-- @param Core.Set#SET_ZONE SetDeployZone
|
-- @param Core.Set#SET_ZONE SetDeployZone The collection of deploy @{Zone}s, which are used to where the cargo will be deployed by the Helicopters.
|
||||||
-- @return #AI_CARGO_DISPATCHER_HELICOPTER
|
-- @return #AI_CARGO_DISPATCHER_HELICOPTER
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
@@ -48,8 +109,11 @@ function AI_CARGO_DISPATCHER_HELICOPTER:New( SetHelicopter, SetCargo, SetDeployZ
|
|||||||
|
|
||||||
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:New( SetHelicopter, SetCargo, SetDeployZones ) ) -- #AI_CARGO_DISPATCHER_HELICOPTER
|
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:New( SetHelicopter, SetCargo, SetDeployZones ) ) -- #AI_CARGO_DISPATCHER_HELICOPTER
|
||||||
|
|
||||||
self:Monitor( 1 )
|
self:SetDeploySpeed( 200, 150 )
|
||||||
|
self:SetPickupSpeed( 200, 150 )
|
||||||
|
self:SetPickupRadius( 0, 0 )
|
||||||
|
self:SetDeployRadius( 0, 0 )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ AI_CARGO_HELICOPTER = {
|
|||||||
Coordinate = nil -- Core.Point#COORDINATE,
|
Coordinate = nil -- Core.Point#COORDINATE,
|
||||||
}
|
}
|
||||||
|
|
||||||
AI_CARGO_HELICOPTER_QUEUE = {}
|
AI_CARGO_QUEUE = {}
|
||||||
|
|
||||||
--- Creates a new AI_CARGO_HELICOPTER object.
|
--- Creates a new AI_CARGO_HELICOPTER object.
|
||||||
-- @param #AI_CARGO_HELICOPTER self
|
-- @param #AI_CARGO_HELICOPTER self
|
||||||
@@ -114,6 +114,14 @@ function AI_CARGO_HELICOPTER:New( Helicopter, CargoSet )
|
|||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
|
|
||||||
|
|
||||||
|
-- We need to capture the Crash events for the helicopters.
|
||||||
|
-- The helicopter reference is used in the semaphore AI_CARGO_QUEUEU.
|
||||||
|
-- So, we need to unlock this when the helo is not anymore ...
|
||||||
|
Helicopter:HandleEvent( EVENTS.Crash,
|
||||||
|
function( Helicopter, EventData )
|
||||||
|
AI_CARGO_QUEUE[Helicopter] = nil
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
self:SetCarrier( Helicopter )
|
self:SetCarrier( Helicopter )
|
||||||
|
|
||||||
@@ -225,43 +233,31 @@ function AI_CARGO_HELICOPTER:onafterQueue( Helicopter, From, Event, To, Coordina
|
|||||||
|
|
||||||
local HelicopterInZone = false
|
local HelicopterInZone = false
|
||||||
|
|
||||||
--- @param Wrapper.Unit#UNIT ZoneUnit
|
if Helicopter and Helicopter:IsAlive() == true then
|
||||||
local function EvaluateZone( ZoneUnit )
|
|
||||||
|
|
||||||
if ZoneUnit:IsAlive() then
|
|
||||||
local ZoneUnitCategory = ZoneUnit:GetDesc().category
|
|
||||||
local ZoneGroup = ZoneUnit:GetGroup()
|
|
||||||
if ZoneUnitCategory == Unit.Category.HELICOPTER then
|
|
||||||
local State = ZoneGroup:GetState( ZoneGroup, "Landing" )
|
|
||||||
self:F({ZoneUnit=ZoneUnit:GetName(), State=State, UnitCategory = Unit.Category.HELICOPTER } )
|
|
||||||
if State == true then
|
|
||||||
HelicopterInZone = true
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
if Helicopter and Helicopter:IsAlive() then
|
|
||||||
|
|
||||||
local Distance = Coordinate:DistanceFromPointVec2( Helicopter:GetCoordinate() )
|
local Distance = Coordinate:DistanceFromPointVec2( Helicopter:GetCoordinate() )
|
||||||
|
|
||||||
if Distance > 300 then
|
if Distance > 500 then
|
||||||
self:__Queue( -10, Coordinate )
|
self:__Queue( -10, Coordinate )
|
||||||
else
|
else
|
||||||
|
|
||||||
-- This will search the zone and will call the local function "EvaluateZone", which passes a UNIT object.
|
local ZoneFree = true
|
||||||
local Zone = ZONE_RADIUS:New( "Deploy", Coordinate:GetVec2(), 300 )
|
|
||||||
Zone:SearchZone( EvaluateZone )
|
for Helicopter, ZoneQueue in pairs( AI_CARGO_QUEUE ) do
|
||||||
|
local ZoneQueue = ZoneQueue -- Core.Zone#ZONE_RADIUS
|
||||||
|
if ZoneQueue:IsCoordinateInZone( Coordinate ) then
|
||||||
|
ZoneFree = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
self:F({HelicopterInZone=HelicopterInZone})
|
self:F({ZoneFree=ZoneFree})
|
||||||
|
|
||||||
if HelicopterInZone == false then
|
if ZoneFree == true then
|
||||||
|
|
||||||
Helicopter:SetState( Helicopter, "Landing", true )
|
local ZoneQueue = ZONE_RADIUS:New( Helicopter:GetName(), Coordinate:GetVec2(), 100 )
|
||||||
|
|
||||||
|
AI_CARGO_QUEUE[Helicopter] = ZoneQueue
|
||||||
|
|
||||||
local Route = {}
|
local Route = {}
|
||||||
|
|
||||||
-- local CoordinateFrom = Helicopter:GetCoordinate()
|
-- local CoordinateFrom = Helicopter:GetCoordinate()
|
||||||
@@ -295,6 +291,8 @@ function AI_CARGO_HELICOPTER:onafterQueue( Helicopter, From, Event, To, Coordina
|
|||||||
self:__Queue( -10, Coordinate )
|
self:__Queue( -10, Coordinate )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
AI_CARGO_QUEUE[Helicopter] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -310,8 +308,6 @@ function AI_CARGO_HELICOPTER:onafterOrbit( Helicopter, From, Event, To, Coordina
|
|||||||
|
|
||||||
if Helicopter and Helicopter:IsAlive() then
|
if Helicopter and Helicopter:IsAlive() then
|
||||||
|
|
||||||
Helicopter:ClearState( Helicopter, "Landing" )
|
|
||||||
|
|
||||||
if not self:IsTransporting() then
|
if not self:IsTransporting() then
|
||||||
local Route = {}
|
local Route = {}
|
||||||
|
|
||||||
@@ -436,6 +432,7 @@ function AI_CARGO_HELICOPTER:onafterUnload( Helicopter, From, Event, To, Deploye
|
|||||||
local HelicopterUnit = HelicopterUnit -- Wrapper.Unit#UNIT
|
local HelicopterUnit = HelicopterUnit -- Wrapper.Unit#UNIT
|
||||||
for _, Cargo in pairs( HelicopterUnit:GetCargo() ) do
|
for _, Cargo in pairs( HelicopterUnit:GetCargo() ) do
|
||||||
Cargo:UnBoard()
|
Cargo:UnBoard()
|
||||||
|
Cargo:SetDeployed( true )
|
||||||
self:__Unboard( 10, Cargo, Deployed )
|
self:__Unboard( 10, Cargo, Deployed )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -483,7 +480,6 @@ function AI_CARGO_HELICOPTER:onbeforeUnloaded( Helicopter, From, Event, To, Carg
|
|||||||
if Deployed == true then
|
if Deployed == true then
|
||||||
for HelicopterUnit, Cargo in pairs( self.Helicopter_Cargo ) do
|
for HelicopterUnit, Cargo in pairs( self.Helicopter_Cargo ) do
|
||||||
local Cargo = Cargo -- Cargo.Cargo#CARGO
|
local Cargo = Cargo -- Cargo.Cargo#CARGO
|
||||||
Cargo:SetDeployed( true )
|
|
||||||
end
|
end
|
||||||
self.Helicopter_Cargo = {}
|
self.Helicopter_Cargo = {}
|
||||||
end
|
end
|
||||||
@@ -500,7 +496,9 @@ end
|
|||||||
-- @param Wrapper.Group#GROUP Helicopter
|
-- @param Wrapper.Group#GROUP Helicopter
|
||||||
function AI_CARGO_HELICOPTER:onafterUnloaded( Helicopter, From, Event, To, Cargo, Deployed )
|
function AI_CARGO_HELICOPTER:onafterUnloaded( Helicopter, From, Event, To, Cargo, Deployed )
|
||||||
|
|
||||||
self:Orbit( Helicopter:GetCoordinate(), 50 )
|
self:Orbit( Helicopter:GetCoordinate(), 50 )
|
||||||
|
|
||||||
|
AI_CARGO_QUEUE[Helicopter] = nil
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -515,7 +513,6 @@ function AI_CARGO_HELICOPTER:onafterPickup( Helicopter, From, Event, To, Coordin
|
|||||||
|
|
||||||
if Helicopter and Helicopter:IsAlive() ~= nil then
|
if Helicopter and Helicopter:IsAlive() ~= nil then
|
||||||
|
|
||||||
self:ScheduleOnce( 10, Helicopter.ClearState, Helicopter, Helicopter, "Landing" )
|
|
||||||
Helicopter:Activate()
|
Helicopter:Activate()
|
||||||
|
|
||||||
self.RoutePickup = true
|
self.RoutePickup = true
|
||||||
@@ -630,7 +627,7 @@ function AI_CARGO_HELICOPTER:onafterDeploy( Helicopter, From, Event, To, Coordin
|
|||||||
Route[#Route+1] = WaypointTo
|
Route[#Route+1] = WaypointTo
|
||||||
|
|
||||||
-- Now route the helicopter
|
-- Now route the helicopter
|
||||||
Helicopter:Route( Route, 1 )
|
Helicopter:Route( Route, 0 )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -690,7 +687,7 @@ function AI_CARGO_HELICOPTER:onafterHome( Helicopter, From, Event, To, Coordinat
|
|||||||
Route[#Route+1] = WaypointTo
|
Route[#Route+1] = WaypointTo
|
||||||
|
|
||||||
-- Now route the helicopter
|
-- Now route the helicopter
|
||||||
Helicopter:Route( Route, 1 )
|
Helicopter:Route( Route, 0 )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ function DATABASE:New()
|
|||||||
self:HandleEvent( EVENTS.Hit, self.AccountHits )
|
self:HandleEvent( EVENTS.Hit, self.AccountHits )
|
||||||
self:HandleEvent( EVENTS.NewCargo )
|
self:HandleEvent( EVENTS.NewCargo )
|
||||||
self:HandleEvent( EVENTS.DeleteCargo )
|
self:HandleEvent( EVENTS.DeleteCargo )
|
||||||
|
self:HandleEvent( EVENTS.NewZone )
|
||||||
|
self:HandleEvent( EVENTS.DeleteZone )
|
||||||
|
|
||||||
-- Follow alive players and clients
|
-- Follow alive players and clients
|
||||||
--self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) -- This is not working anymore!, handling this through the birth event.
|
--self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) -- This is not working anymore!, handling this through the birth event.
|
||||||
@@ -1085,6 +1087,31 @@ function DATABASE:OnEventDeleteCargo( EventData )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Handles the OnEventNewZone event.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
|
function DATABASE:OnEventNewZone( EventData )
|
||||||
|
self:F2( { EventData } )
|
||||||
|
|
||||||
|
if EventData.Zone then
|
||||||
|
self:AddZone( EventData.Zone )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Handles the OnEventDeleteZone.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
|
function DATABASE:OnEventDeleteZone( EventData )
|
||||||
|
self:F2( { EventData } )
|
||||||
|
|
||||||
|
if EventData.Zone then
|
||||||
|
self:DeleteZone( EventData.Zone.ZoneName )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Gets the player settings
|
--- Gets the player settings
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string PlayerName
|
-- @param #string PlayerName
|
||||||
|
|||||||
@@ -179,6 +179,8 @@ EVENT = {
|
|||||||
|
|
||||||
world.event.S_EVENT_NEW_CARGO = world.event.S_EVENT_MAX + 1000
|
world.event.S_EVENT_NEW_CARGO = world.event.S_EVENT_MAX + 1000
|
||||||
world.event.S_EVENT_DELETE_CARGO = world.event.S_EVENT_MAX + 1001
|
world.event.S_EVENT_DELETE_CARGO = world.event.S_EVENT_MAX + 1001
|
||||||
|
world.event.S_EVENT_NEW_ZONE = world.event.S_EVENT_MAX + 1002
|
||||||
|
world.event.S_EVENT_DELETE_ZONE = world.event.S_EVENT_MAX + 1003
|
||||||
|
|
||||||
--- The different types of events supported by MOOSE.
|
--- The different types of events supported by MOOSE.
|
||||||
-- Use this structure to subscribe to events using the @{Base#BASE.HandleEvent}() method.
|
-- Use this structure to subscribe to events using the @{Base#BASE.HandleEvent}() method.
|
||||||
@@ -209,6 +211,8 @@ EVENTS = {
|
|||||||
ShootingEnd = world.event.S_EVENT_SHOOTING_END,
|
ShootingEnd = world.event.S_EVENT_SHOOTING_END,
|
||||||
NewCargo = world.event.S_EVENT_NEW_CARGO,
|
NewCargo = world.event.S_EVENT_NEW_CARGO,
|
||||||
DeleteCargo = world.event.S_EVENT_DELETE_CARGO,
|
DeleteCargo = world.event.S_EVENT_DELETE_CARGO,
|
||||||
|
NewZone = world.event.S_EVENT_NEW_ZONE,
|
||||||
|
DeleteZone = world.event.S_EVENT_DELETE_ZONE,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- The Event structure
|
--- The Event structure
|
||||||
@@ -406,6 +410,16 @@ local _EVENTMETA = {
|
|||||||
Event = "OnEventDeleteCargo",
|
Event = "OnEventDeleteCargo",
|
||||||
Text = "S_EVENT_DELETE_CARGO"
|
Text = "S_EVENT_DELETE_CARGO"
|
||||||
},
|
},
|
||||||
|
[EVENTS.NewZone] = {
|
||||||
|
Order = 1,
|
||||||
|
Event = "OnEventNewZone",
|
||||||
|
Text = "S_EVENT_NEW_ZONE"
|
||||||
|
},
|
||||||
|
[EVENTS.DeleteZone] = {
|
||||||
|
Order = 1,
|
||||||
|
Event = "OnEventDeleteZone",
|
||||||
|
Text = "S_EVENT_DELETE_ZONE"
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -710,6 +724,36 @@ do -- Event Creation
|
|||||||
world.onEvent( Event )
|
world.onEvent( Event )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Creation of a New Zone Event.
|
||||||
|
-- @param #EVENT self
|
||||||
|
-- @param Core.Zone#ZONE_BASE Zone The Zone created.
|
||||||
|
function EVENT:CreateEventNewZone( Zone )
|
||||||
|
self:F( { Zone } )
|
||||||
|
|
||||||
|
local Event = {
|
||||||
|
id = EVENTS.NewZone,
|
||||||
|
time = timer.getTime(),
|
||||||
|
zone = Zone,
|
||||||
|
}
|
||||||
|
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creation of a Zone Deletion Event.
|
||||||
|
-- @param #EVENT self
|
||||||
|
-- @param Core.Zone#ZONE_BASE Zone The Zone created.
|
||||||
|
function EVENT:CreateEventDeleteZone( Zone )
|
||||||
|
self:F( { Zone } )
|
||||||
|
|
||||||
|
local Event = {
|
||||||
|
id = EVENTS.DeleteZone,
|
||||||
|
time = timer.getTime(),
|
||||||
|
zone = Zone,
|
||||||
|
}
|
||||||
|
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
--- Creation of a S_EVENT_PLAYER_ENTER_UNIT Event.
|
--- Creation of a S_EVENT_PLAYER_ENTER_UNIT Event.
|
||||||
-- @param #EVENT self
|
-- @param #EVENT self
|
||||||
-- @param Wrapper.Unit#UNIT PlayerUnit.
|
-- @param Wrapper.Unit#UNIT PlayerUnit.
|
||||||
@@ -873,6 +917,11 @@ function EVENT:onEvent( Event )
|
|||||||
Event.Cargo = Event.cargo
|
Event.Cargo = Event.cargo
|
||||||
Event.CargoName = Event.cargo.Name
|
Event.CargoName = Event.cargo.Name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if Event.zone then
|
||||||
|
Event.Zone = Event.zone
|
||||||
|
Event.ZoneName = Event.zone.ZoneName
|
||||||
|
end
|
||||||
|
|
||||||
local PriorityOrder = EventMeta.Order
|
local PriorityOrder = EventMeta.Order
|
||||||
local PriorityBegin = PriorityOrder == -1 and 5 or 1
|
local PriorityBegin = PriorityOrder == -1 and 5 or 1
|
||||||
|
|||||||
@@ -76,10 +76,35 @@ SET_BASE = {
|
|||||||
function SET_BASE:New( Database )
|
function SET_BASE:New( Database )
|
||||||
|
|
||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit( self, BASE:New() ) -- Core.Set#SET_BASE
|
local self = BASE:Inherit( self, FSM:New() ) -- Core.Set#SET_BASE
|
||||||
|
|
||||||
self.Database = Database
|
self.Database = Database
|
||||||
|
|
||||||
|
self:SetStartState( "Started" )
|
||||||
|
|
||||||
|
--- Added Handler OnAfter for SET_BASE
|
||||||
|
-- @function [parent=#SET_BASE] OnAfterAdded
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #string ObjectName The name of the object.
|
||||||
|
-- @param Object The object.
|
||||||
|
|
||||||
|
|
||||||
|
self:AddTransition( "*", "Added", "*" )
|
||||||
|
|
||||||
|
--- Removed Handler OnAfter for SET_BASE
|
||||||
|
-- @function [parent=#SET_BASE] OnAfterRemoved
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #string ObjectName The name of the object.
|
||||||
|
-- @param Object The object.
|
||||||
|
|
||||||
|
self:AddTransition( "*", "Removed", "*" )
|
||||||
|
|
||||||
self.YieldInterval = 10
|
self.YieldInterval = 10
|
||||||
self.TimeInterval = 0.001
|
self.TimeInterval = 0.001
|
||||||
|
|
||||||
@@ -148,7 +173,8 @@ end
|
|||||||
--- Removes a @{Base#BASE} object from the @{Set#SET_BASE} and derived classes, based on the Object Name.
|
--- Removes a @{Base#BASE} object from the @{Set#SET_BASE} and derived classes, based on the Object Name.
|
||||||
-- @param #SET_BASE self
|
-- @param #SET_BASE self
|
||||||
-- @param #string ObjectName
|
-- @param #string ObjectName
|
||||||
function SET_BASE:Remove( ObjectName )
|
-- @param NoTriggerEvent (optional) When `true`, the :Remove() method will not trigger a **Removed** event.
|
||||||
|
function SET_BASE:Remove( ObjectName, NoTriggerEvent )
|
||||||
self:F2( { ObjectName = ObjectName } )
|
self:F2( { ObjectName = ObjectName } )
|
||||||
|
|
||||||
local Object = self.Set[ObjectName]
|
local Object = self.Set[ObjectName]
|
||||||
@@ -161,9 +187,11 @@ function SET_BASE:Remove( ObjectName )
|
|||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- When NoTriggerEvent is true, then no Removed event will be triggered.
|
||||||
|
if not NoTriggerEvent then
|
||||||
|
self:Removed( ObjectName, Object )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -177,10 +205,12 @@ function SET_BASE:Add( ObjectName, Object )
|
|||||||
|
|
||||||
-- Ensure that the existing element is removed from the Set before a new one is inserted to the Set
|
-- Ensure that the existing element is removed from the Set before a new one is inserted to the Set
|
||||||
if self.Set[ObjectName] then
|
if self.Set[ObjectName] then
|
||||||
self:Remove( ObjectName )
|
self:Remove( ObjectName, true )
|
||||||
end
|
end
|
||||||
self.Set[ObjectName] = Object
|
self.Set[ObjectName] = Object
|
||||||
table.insert( self.Index, ObjectName )
|
table.insert( self.Index, ObjectName )
|
||||||
|
|
||||||
|
self:Added( ObjectName, Object )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Adds a @{Base#BASE} object in the @{Set#SET_BASE}, using the Object Name as the index.
|
--- Adds a @{Base#BASE} object in the @{Set#SET_BASE}, using the Object Name as the index.
|
||||||
@@ -425,7 +455,7 @@ end
|
|||||||
-- @param #SET_BASE self
|
-- @param #SET_BASE self
|
||||||
-- @param Core.Event#EVENTDATA Event
|
-- @param Core.Event#EVENTDATA Event
|
||||||
function SET_BASE:_EventOnDeadOrCrash( Event )
|
function SET_BASE:_EventOnDeadOrCrash( Event )
|
||||||
self:F3( { Event } )
|
self:F( { Event } )
|
||||||
|
|
||||||
if Event.IniDCSUnit then
|
if Event.IniDCSUnit then
|
||||||
local ObjectName, Object = self:FindInDatabase( Event )
|
local ObjectName, Object = self:FindInDatabase( Event )
|
||||||
@@ -675,6 +705,52 @@ end
|
|||||||
-- * @{#SET_GROUP.ForEachGroupPartlyInZone}: Iterate the SET_GROUP and call an iterator function for each **alive** GROUP presence partly in a @{Zone}, providing the GROUP and optional parameters to the called function.
|
-- * @{#SET_GROUP.ForEachGroupPartlyInZone}: Iterate the SET_GROUP and call an iterator function for each **alive** GROUP presence partly in a @{Zone}, providing the GROUP and optional parameters to the called function.
|
||||||
-- * @{#SET_GROUP.ForEachGroupNotInZone}: Iterate the SET_GROUP and call an iterator function for each **alive** GROUP presence not in a @{Zone}, providing the GROUP and optional parameters to the called function.
|
-- * @{#SET_GROUP.ForEachGroupNotInZone}: Iterate the SET_GROUP and call an iterator function for each **alive** GROUP presence not in a @{Zone}, providing the GROUP and optional parameters to the called function.
|
||||||
--
|
--
|
||||||
|
--
|
||||||
|
-- ## 5. SET_GROUP trigger events on the GROUP objects.
|
||||||
|
--
|
||||||
|
-- The SET is derived from the FSM class, which provides extra capabilities to track the contents of the GROUP objects in the SET_GROUP.
|
||||||
|
--
|
||||||
|
-- ### 5.1. When a GROUP object crashes or is dead, the SET_GROUP will trigger a **Dead** event.
|
||||||
|
--
|
||||||
|
-- You can handle the event using the OnBefore and OnAfter event handlers.
|
||||||
|
-- The event handlers need to have the paramters From, Event, To, GroupObject.
|
||||||
|
-- The GroupObject is the GROUP object that is dead and within the SET_GROUP, and is passed as a parameter to the event handler.
|
||||||
|
-- See the following example:
|
||||||
|
--
|
||||||
|
-- -- Create the SetCarrier SET_GROUP collection.
|
||||||
|
--
|
||||||
|
-- local SetHelicopter = SET_GROUP:New():FilterPrefixes( "Helicopter" ):FilterStart()
|
||||||
|
--
|
||||||
|
-- -- Put a Dead event handler on SetCarrier, to ensure that when a carrier is destroyed, that all internal parameters are reset.
|
||||||
|
--
|
||||||
|
-- function SetHelicopter:OnAfterDead( From, Event, To, GroupObject )
|
||||||
|
-- self:F( { GroupObject = GroupObject:GetName() } )
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- While this is a good example, there is a catch.
|
||||||
|
-- Imageine you want to execute the code above, the the self would need to be from the object declared outside (above) the OnAfterDead method.
|
||||||
|
-- So, the self would need to contain another object. Fortunately, this can be done, but you must use then the **`.`** notation for the method.
|
||||||
|
-- See the modified example:
|
||||||
|
--
|
||||||
|
-- -- Now we have a constructor of the class AI_CARGO_DISPATCHER, that receives the SetHelicopter as a parameter.
|
||||||
|
-- -- Within that constructor, we want to set an enclosed event handler OnAfterDead for SetHelicopter.
|
||||||
|
-- -- But within the OnAfterDead method, we want to refer to the self variable of the AI_CARGO_DISPATCHER.
|
||||||
|
--
|
||||||
|
-- function AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZones )
|
||||||
|
--
|
||||||
|
-- local self = BASE:Inherit( self, FSM:New() ) -- #AI_CARGO_DISPATCHER
|
||||||
|
--
|
||||||
|
-- -- Put a Dead event handler on SetCarrier, to ensure that when a carrier is destroyed, that all internal parameters are reset.
|
||||||
|
-- -- Note the "." notation, and the explicit declaration of SetHelicopter, which would be using the ":" notation the implicit self variable declaration.
|
||||||
|
--
|
||||||
|
-- function SetHelicopter.OnAfterDead( SetHelicopter, From, Event, To, GroupObject )
|
||||||
|
-- SetHelicopter:F( { GroupObject = GroupObject:GetName() } )
|
||||||
|
-- self.PickupCargo[GroupObject] = nil -- So here I clear the PickupCargo table entry of the self object AI_CARGO_DISPATCHER.
|
||||||
|
-- self.CarrierHome[GroupObject] = nil
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- end
|
||||||
|
--
|
||||||
-- ===
|
-- ===
|
||||||
-- @field #SET_GROUP SET_GROUP
|
-- @field #SET_GROUP SET_GROUP
|
||||||
SET_GROUP = {
|
SET_GROUP = {
|
||||||
@@ -946,7 +1022,7 @@ end
|
|||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
-- @param Core.Event#EVENTDATA Event
|
-- @param Core.Event#EVENTDATA Event
|
||||||
function SET_GROUP:_EventOnDeadOrCrash( Event )
|
function SET_GROUP:_EventOnDeadOrCrash( Event )
|
||||||
self:F3( { Event } )
|
self:F( { Event } )
|
||||||
|
|
||||||
if Event.IniDCSUnit then
|
if Event.IniDCSUnit then
|
||||||
local ObjectName, Object = self:FindInDatabase( Event )
|
local ObjectName, Object = self:FindInDatabase( Event )
|
||||||
@@ -1409,6 +1485,59 @@ do -- SET_UNIT
|
|||||||
--
|
--
|
||||||
-- * @{#SET_UNIT.GetTypeNames}(): Retrieve the type names of the @{Unit}s in the SET, delimited by a comma.
|
-- * @{#SET_UNIT.GetTypeNames}(): Retrieve the type names of the @{Unit}s in the SET, delimited by a comma.
|
||||||
--
|
--
|
||||||
|
-- ## 4. SET_UNIT iterators
|
||||||
|
--
|
||||||
|
-- Once the filters have been defined and the SET_UNIT has been built, you can iterate the SET_UNIT with the available iterator methods.
|
||||||
|
-- The iterator methods will walk the SET_UNIT set, and call for each element within the set a function that you provide.
|
||||||
|
-- The following iterator methods are currently available within the SET_UNIT:
|
||||||
|
--
|
||||||
|
-- * @{#SET_UNIT.ForEachUnit}: Calls a function for each alive group it finds within the SET_UNIT.
|
||||||
|
-- * @{#SET_UNIT.ForEachUnitInZone}: Iterate the SET_UNIT and call an iterator function for each **alive** UNIT object presence completely in a @{Zone}, providing the UNIT object and optional parameters to the called function.
|
||||||
|
-- * @{#SET_UNIT.ForEachUnitNotInZone}: Iterate the SET_UNIT and call an iterator function for each **alive** UNIT object presence not in a @{Zone}, providing the UNIT object and optional parameters to the called function.
|
||||||
|
--
|
||||||
|
-- ## 5. SET_UNIT trigger events on the UNIT objects.
|
||||||
|
--
|
||||||
|
-- The SET is derived from the FSM class, which provides extra capabilities to track the contents of the UNIT objects in the SET_UNIT.
|
||||||
|
--
|
||||||
|
-- ### 5.1. When a UNIT object crashes or is dead, the SET_UNIT will trigger a **Dead** event.
|
||||||
|
--
|
||||||
|
-- You can handle the event using the OnBefore and OnAfter event handlers.
|
||||||
|
-- The event handlers need to have the paramters From, Event, To, GroupObject.
|
||||||
|
-- The GroupObject is the UNIT object that is dead and within the SET_UNIT, and is passed as a parameter to the event handler.
|
||||||
|
-- See the following example:
|
||||||
|
--
|
||||||
|
-- -- Create the SetCarrier SET_UNIT collection.
|
||||||
|
--
|
||||||
|
-- local SetHelicopter = SET_UNIT:New():FilterPrefixes( "Helicopter" ):FilterStart()
|
||||||
|
--
|
||||||
|
-- -- Put a Dead event handler on SetCarrier, to ensure that when a carrier unit is destroyed, that all internal parameters are reset.
|
||||||
|
--
|
||||||
|
-- function SetHelicopter:OnAfterDead( From, Event, To, UnitObject )
|
||||||
|
-- self:F( { UnitObject = UnitObject:GetName() } )
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- While this is a good example, there is a catch.
|
||||||
|
-- Imageine you want to execute the code above, the the self would need to be from the object declared outside (above) the OnAfterDead method.
|
||||||
|
-- So, the self would need to contain another object. Fortunately, this can be done, but you must use then the **`.`** notation for the method.
|
||||||
|
-- See the modified example:
|
||||||
|
--
|
||||||
|
-- -- Now we have a constructor of the class AI_CARGO_DISPATCHER, that receives the SetHelicopter as a parameter.
|
||||||
|
-- -- Within that constructor, we want to set an enclosed event handler OnAfterDead for SetHelicopter.
|
||||||
|
-- -- But within the OnAfterDead method, we want to refer to the self variable of the AI_CARGO_DISPATCHER.
|
||||||
|
--
|
||||||
|
-- function ACLASS:New( SetCarrier, SetCargo, SetDeployZones )
|
||||||
|
--
|
||||||
|
-- local self = BASE:Inherit( self, FSM:New() ) -- #AI_CARGO_DISPATCHER
|
||||||
|
--
|
||||||
|
-- -- Put a Dead event handler on SetCarrier, to ensure that when a carrier is destroyed, that all internal parameters are reset.
|
||||||
|
-- -- Note the "." notation, and the explicit declaration of SetHelicopter, which would be using the ":" notation the implicit self variable declaration.
|
||||||
|
--
|
||||||
|
-- function SetHelicopter.OnAfterDead( SetHelicopter, From, Event, To, UnitObject )
|
||||||
|
-- SetHelicopter:F( { UnitObject = UnitObject:GetName() } )
|
||||||
|
-- self.array[UnitObject] = nil -- So here I clear the array table entry of the self object ACLASS.
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- end
|
||||||
-- ===
|
-- ===
|
||||||
-- @field #SET_UNIT SET_UNIT
|
-- @field #SET_UNIT SET_UNIT
|
||||||
SET_UNIT = {
|
SET_UNIT = {
|
||||||
@@ -1649,6 +1778,8 @@ do -- SET_UNIT
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Handles the Database to check on an event (birth) that the Object was added in the Database.
|
--- Handles the Database to check on an event (birth) that the Object was added in the Database.
|
||||||
-- This is required, because sometimes the _DATABASE birth event gets called later than the SET_BASE birth event!
|
-- This is required, because sometimes the _DATABASE birth event gets called later than the SET_BASE birth event!
|
||||||
@@ -4606,20 +4737,39 @@ end
|
|||||||
--- Get a random zone from the set.
|
--- Get a random zone from the set.
|
||||||
-- @param #SET_ZONE self
|
-- @param #SET_ZONE self
|
||||||
-- @return Core.Zone#ZONE_BASE The random Zone.
|
-- @return Core.Zone#ZONE_BASE The random Zone.
|
||||||
|
-- @return #nil if no zone in the collection.
|
||||||
function SET_ZONE:GetRandomZone()
|
function SET_ZONE:GetRandomZone()
|
||||||
|
|
||||||
local Index = self.Index
|
if self:Count() ~= 0 then
|
||||||
local ZoneFound = nil
|
|
||||||
|
|
||||||
while not ZoneFound do
|
|
||||||
local ZoneRandom = math.random( 1, #Index )
|
|
||||||
ZoneFound = self.Set[Index[ZoneRandom]]
|
|
||||||
end
|
|
||||||
|
|
||||||
return ZoneFound
|
local Index = self.Index
|
||||||
|
local ZoneFound = nil -- Core.Zone#ZONE_BASE
|
||||||
|
|
||||||
|
-- Loop until a zone has been found.
|
||||||
|
-- The :GetZoneMaybe() call will evaluate the probability for the zone to be selected.
|
||||||
|
-- If the zone is not selected, then nil is returned by :GetZoneMaybe() and the loop continues!
|
||||||
|
while not ZoneFound do
|
||||||
|
local ZoneRandom = math.random( 1, #Index )
|
||||||
|
ZoneFound = self.Set[Index[ZoneRandom]]:GetZoneMaybe()
|
||||||
|
end
|
||||||
|
|
||||||
|
return ZoneFound
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set a zone probability.
|
||||||
|
-- @param #SET_ZONE self
|
||||||
|
-- @param #string ZoneName The name of the zone.
|
||||||
|
function SET_ZONE:SetZoneProbability( ZoneName, ZoneProbability )
|
||||||
|
local Zone = self:FindZone( ZoneName )
|
||||||
|
Zone:SetZoneProbability( ZoneProbability )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Builds a set of zones of defined zone prefixes.
|
--- Builds a set of zones of defined zone prefixes.
|
||||||
-- All the zones starting with the given prefixes will be included within the set.
|
-- All the zones starting with the given prefixes will be included within the set.
|
||||||
@@ -4656,6 +4806,9 @@ function SET_ZONE:FilterStart()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self:HandleEvent( EVENTS.NewZone )
|
||||||
|
self:HandleEvent( EVENTS.DeleteZone )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -4726,3 +4879,41 @@ function SET_ZONE:IsIncludeObject( MZone )
|
|||||||
return MZoneInclude
|
return MZoneInclude
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Handles the OnEventNewZone event for the Set.
|
||||||
|
-- @param #SET_ZONE self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
|
function SET_ZONE:OnEventNewZone( EventData ) --R2.1
|
||||||
|
|
||||||
|
self:F( { "New Zone", EventData } )
|
||||||
|
|
||||||
|
if EventData.Zone then
|
||||||
|
if EventData.Zone and self:IsIncludeObject( EventData.Zone ) then
|
||||||
|
self:Add( EventData.Zone.ZoneName , EventData.Zone )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Handles the OnDead or OnCrash event for alive units set.
|
||||||
|
-- @param #SET_ZONE self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
|
function SET_ZONE:OnEventDeleteZone( EventData ) --R2.1
|
||||||
|
self:F3( { EventData } )
|
||||||
|
|
||||||
|
if EventData.Zone then
|
||||||
|
local Zone = _DATABASE:FindZone( EventData.Zone.ZoneName )
|
||||||
|
if Zone and Zone.ZoneName then
|
||||||
|
|
||||||
|
-- When cargo was deleted, it may probably be because of an S_EVENT_DEAD.
|
||||||
|
-- However, in the loading logic, an S_EVENT_DEAD is also generated after a Destroy() call.
|
||||||
|
-- And this is a problem because it will remove all entries from the SET_ZONEs.
|
||||||
|
-- To prevent this from happening, the Zone object has a flag NoDestroy.
|
||||||
|
-- When true, the SET_ZONE won't Remove the Zone object from the set.
|
||||||
|
-- This flag is switched off after the event handlers have been called in the EVENT class.
|
||||||
|
self:F( { ZoneNoDestroy=Zone.NoDestroy } )
|
||||||
|
if Zone.NoDestroy then
|
||||||
|
else
|
||||||
|
self:Remove( Zone.ZoneName )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -151,10 +151,16 @@ end
|
|||||||
-- @param Dcs.DCSTypes#Vec3 Vec3 The point to test.
|
-- @param Dcs.DCSTypes#Vec3 Vec3 The point to test.
|
||||||
-- @return #boolean true if the Vec3 is within the zone.
|
-- @return #boolean true if the Vec3 is within the zone.
|
||||||
function ZONE_BASE:IsVec3InZone( Vec3 )
|
function ZONE_BASE:IsVec3InZone( Vec3 )
|
||||||
self:F2( Vec3 )
|
|
||||||
|
|
||||||
local InZone = self:IsVec2InZone( { x = Vec3.x, y = Vec3.z } )
|
local InZone = self:IsVec2InZone( { x = Vec3.x, y = Vec3.z } )
|
||||||
|
return InZone
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns if a Coordinate is within the zone.
|
||||||
|
-- @param #ZONE_BASE self
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate The coordinate to test.
|
||||||
|
-- @return #boolean true if the coordinate is within the zone.
|
||||||
|
function ZONE_BASE:IsCoordinateInZone( Coordinate )
|
||||||
|
local InZone = self:IsVec2InZone( Coordinate:GetVec2() )
|
||||||
return InZone
|
return InZone
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -163,10 +169,7 @@ end
|
|||||||
-- @param Core.Point#POINT_VEC2 PointVec2 The PointVec2 to test.
|
-- @param Core.Point#POINT_VEC2 PointVec2 The PointVec2 to test.
|
||||||
-- @return #boolean true if the PointVec2 is within the zone.
|
-- @return #boolean true if the PointVec2 is within the zone.
|
||||||
function ZONE_BASE:IsPointVec2InZone( PointVec2 )
|
function ZONE_BASE:IsPointVec2InZone( PointVec2 )
|
||||||
self:F2( PointVec2 )
|
|
||||||
|
|
||||||
local InZone = self:IsVec2InZone( PointVec2:GetVec2() )
|
local InZone = self:IsVec2InZone( PointVec2:GetVec2() )
|
||||||
|
|
||||||
return InZone
|
return InZone
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -175,10 +178,7 @@ end
|
|||||||
-- @param Core.Point#POINT_VEC3 PointVec3 The PointVec3 to test.
|
-- @param Core.Point#POINT_VEC3 PointVec3 The PointVec3 to test.
|
||||||
-- @return #boolean true if the PointVec3 is within the zone.
|
-- @return #boolean true if the PointVec3 is within the zone.
|
||||||
function ZONE_BASE:IsPointVec3InZone( PointVec3 )
|
function ZONE_BASE:IsPointVec3InZone( PointVec3 )
|
||||||
self:F2( PointVec3 )
|
|
||||||
|
|
||||||
local InZone = self:IsPointVec2InZone( PointVec3 )
|
local InZone = self:IsPointVec2InZone( PointVec3 )
|
||||||
|
|
||||||
return InZone
|
return InZone
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -187,8 +187,6 @@ end
|
|||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @return #nil.
|
-- @return #nil.
|
||||||
function ZONE_BASE:GetVec2()
|
function ZONE_BASE:GetVec2()
|
||||||
self:F2( self.ZoneName )
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -324,7 +322,7 @@ end
|
|||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @param ZoneProbability A value between 0 and 1. 0 = 0% and 1 = 100% probability.
|
-- @param ZoneProbability A value between 0 and 1. 0 = 0% and 1 = 100% probability.
|
||||||
function ZONE_BASE:SetZoneProbability( ZoneProbability )
|
function ZONE_BASE:SetZoneProbability( ZoneProbability )
|
||||||
self:F2( ZoneProbability )
|
self:F( { self:GetName(), ZoneProbability = ZoneProbability } )
|
||||||
|
|
||||||
self.ZoneProbability = ZoneProbability or 1
|
self.ZoneProbability = ZoneProbability or 1
|
||||||
return self
|
return self
|
||||||
@@ -343,6 +341,27 @@ end
|
|||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @return #ZONE_BASE The zone is selected taking into account the randomization probability factor.
|
-- @return #ZONE_BASE The zone is selected taking into account the randomization probability factor.
|
||||||
-- @return #nil The zone is not selected taking into account the randomization probability factor.
|
-- @return #nil The zone is not selected taking into account the randomization probability factor.
|
||||||
|
-- @usage
|
||||||
|
--
|
||||||
|
-- local ZoneArray = { ZONE:New( "Zone1" ), ZONE:New( "Zone2" ) }
|
||||||
|
--
|
||||||
|
-- -- We set a zone probability of 70% to the first zone and 30% to the second zone.
|
||||||
|
-- ZoneArray[1]:SetZoneProbability( 0.5 )
|
||||||
|
-- ZoneArray[2]:SetZoneProbability( 0.5 )
|
||||||
|
--
|
||||||
|
-- local ZoneSelected = nil
|
||||||
|
--
|
||||||
|
-- while ZoneSelected == nil do
|
||||||
|
-- for _, Zone in pairs( ZoneArray ) do
|
||||||
|
-- ZoneSelected = Zone:GetZoneMaybe()
|
||||||
|
-- if ZoneSelected ~= nil then
|
||||||
|
-- break
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- -- The result should be that Zone1 would be more probable selected than Zone2.
|
||||||
|
--
|
||||||
function ZONE_BASE:GetZoneMaybe()
|
function ZONE_BASE:GetZoneMaybe()
|
||||||
self:F2()
|
self:F2()
|
||||||
|
|
||||||
@@ -1003,6 +1022,9 @@ function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius )
|
|||||||
self.ZoneUNIT = ZoneUNIT
|
self.ZoneUNIT = ZoneUNIT
|
||||||
self.LastVec2 = ZoneUNIT:GetVec2()
|
self.LastVec2 = ZoneUNIT:GetVec2()
|
||||||
|
|
||||||
|
-- Zone objects are added to the _DATABASE and SET_ZONE objects.
|
||||||
|
_EVENTDISPATCHER:CreateEventNewZone( self )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1091,6 +1113,9 @@ function ZONE_GROUP:New( ZoneName, ZoneGROUP, Radius )
|
|||||||
self:F( { ZoneName, ZoneGROUP:GetVec2(), Radius } )
|
self:F( { ZoneName, ZoneGROUP:GetVec2(), Radius } )
|
||||||
|
|
||||||
self._.ZoneGROUP = ZoneGROUP
|
self._.ZoneGROUP = ZoneGROUP
|
||||||
|
|
||||||
|
-- Zone objects are added to the _DATABASE and SET_ZONE objects.
|
||||||
|
_EVENTDISPATCHER:CreateEventNewZone( self )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user