Skip to content

Commit

Permalink
Okay, fixed the problem with the crashing at the deploy zone.
Browse files Browse the repository at this point in the history
Also added methods to set and/or randomize the pickup speed, pickup radius, deploy speed, deploy radius.
  • Loading branch information
FlightControl-User committed May 13, 2018
1 parent 92a70d0 commit 0e0ab35
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 56 deletions.
145 changes: 133 additions & 12 deletions Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,125 @@ function AI_CARGO_DISPATCHER:SetHomeZone( HomeZone )
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( SetAPC, 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( SetAPC, 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( SetAPC, 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( SetAPC, 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.
-- @param #AI_CARGO_DISPATCHER self
Expand Down Expand Up @@ -168,30 +287,31 @@ function AI_CARGO_DISPATCHER:onafterMonitor()
local Cargo = Cargo -- Cargo.Cargo#CARGO
self:F( { Cargo = Cargo:GetName(), UnLoaded = Cargo:IsUnLoaded(), Deployed = Cargo:IsDeployed(), PickupCargo = self.PickupCargo[Cargo] ~= nil } )
if Cargo:IsUnLoaded() and not Cargo:IsDeployed() then
local CargoVec2 = { x = Cargo:GetX(), y = Cargo:GetY() }
local LocationFound = false
for APC, Vec2 in pairs( self.PickupCargo ) do
if Vec2.x == CargoVec2.x and Vec2.y == CargoVec2.y then
LocationFound = true
local CargoCoordinate = Cargo:GetCoordinate()
local CoordinateFree = true
for APC, Coordinate in pairs( self.PickupCargo ) do
if CargoCoordinate:Get2DDistance( Coordinate ) <= 25 then
CoordinateFree = false
break
end
end
if LocationFound == false then
self.PickupCargo[Carrier] = CargoVec2
if CoordinateFree == true then
self.PickupCargo[Carrier] = CargoCoordinate
PickupCargo = Cargo
break
end
end
end
if PickupCargo then
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
else
if self.HomeZone then
if not self.CarrierHome[Carrier] then
self.CarrierHome[Carrier] = true
AI_Cargo:Home( self.HomeZone:GetRandomPointVec2() )
AI_Cargo:__Home( 10, self.HomeZone:GetRandomPointVec2() )
end
end
end
Expand Down Expand Up @@ -220,10 +340,11 @@ end
function AI_CARGO_DISPATCHER:OnAfterLoaded( From, Event, To, APC, Cargo )

self:I( { "Loaded Dispatcher", APC } )
local RandomZone = self.SetDeployZones:GetRandomZone()
self:I( { RandomZone = RandomZone } )
local DeployZone = self.SetDeployZones:GetRandomZone()
self:I( { RandomZone = DeployZone } )

self.AI_Cargo[APC]:Deploy( RandomZone:GetCoordinate(), 70 )
local DeployCoordinate = DeployZone:GetCoordinate():GetRandomCoordinateInRadius( self.DeployOuterRadius, self.DeployInnerRadius )
self.AI_Cargo[APC]:Deploy( DeployCoordinate, math.random( self.DeployMinSpeed, self.DeployMaxSpeed ) )

self.PickupCargo[APC] = nil

Expand Down
5 changes: 5 additions & 0 deletions Moose Development/Moose/AI/AI_Cargo_Dispatcher_APC.lua
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ function AI_CARGO_DISPATCHER_APC:New( SetAPC, SetCargo, SetDeployZones )

self.CombatRadius = 500

self:SetDeploySpeed( 70, 120 )
self:SetPickupSpeed( 70, 120 )
self:SetPickupRadius( 0, 0 )
self:SetDeployRadius( 0, 0 )

self:Monitor( 1 )

return self
Expand Down
5 changes: 5 additions & 0 deletions Moose Development/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,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

self:SetDeploySpeed( 200, 150 )
self:SetPickupSpeed( 200, 150 )
self:SetPickupRadius( 0, 0 )
self:SetDeployRadius( 0, 0 )

self:Monitor( 1 )

return self
Expand Down
55 changes: 21 additions & 34 deletions Moose Development/Moose/AI/AI_Cargo_Helicopter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ AI_CARGO_HELICOPTER = {
Coordinate = nil -- Core.Point#COORDINATE,
}

AI_CARGO_HELICOPTER_QUEUE = {}
AI_CARGO_QUEUE = {}

--- Creates a new AI_CARGO_HELICOPTER object.
-- @param #AI_CARGO_HELICOPTER self
Expand Down Expand Up @@ -225,43 +225,31 @@ function AI_CARGO_HELICOPTER:onafterQueue( Helicopter, From, Event, To, Coordina

local HelicopterInZone = false

--- @param Wrapper.Unit#UNIT ZoneUnit
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() )

if Distance > 300 then
if Distance > 500 then
self:__Queue( -10, Coordinate )
else

-- This will search the zone and will call the local function "EvaluateZone", which passes a UNIT object.
local Zone = ZONE_RADIUS:New( "Deploy", Coordinate:GetVec2(), 300 )
Zone:SearchZone( EvaluateZone )
local ZoneFree = true

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 CoordinateFrom = Helicopter:GetCoordinate()
Expand Down Expand Up @@ -310,8 +298,6 @@ function AI_CARGO_HELICOPTER:onafterOrbit( Helicopter, From, Event, To, Coordina

if Helicopter and Helicopter:IsAlive() then

Helicopter:ClearState( Helicopter, "Landing" )

if not self:IsTransporting() then
local Route = {}

Expand Down Expand Up @@ -436,6 +422,7 @@ function AI_CARGO_HELICOPTER:onafterUnload( Helicopter, From, Event, To, Deploye
local HelicopterUnit = HelicopterUnit -- Wrapper.Unit#UNIT
for _, Cargo in pairs( HelicopterUnit:GetCargo() ) do
Cargo:UnBoard()
Cargo:SetDeployed( true )
self:__Unboard( 10, Cargo, Deployed )
end
end
Expand Down Expand Up @@ -483,7 +470,6 @@ function AI_CARGO_HELICOPTER:onbeforeUnloaded( Helicopter, From, Event, To, Carg
if Deployed == true then
for HelicopterUnit, Cargo in pairs( self.Helicopter_Cargo ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
Cargo:SetDeployed( true )
end
self.Helicopter_Cargo = {}
end
Expand All @@ -500,7 +486,9 @@ end
-- @param Wrapper.Group#GROUP Helicopter
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

Expand All @@ -515,7 +503,6 @@ function AI_CARGO_HELICOPTER:onafterPickup( Helicopter, From, Event, To, Coordin

if Helicopter and Helicopter:IsAlive() ~= nil then

self:ScheduleOnce( 10, Helicopter.ClearState, Helicopter, Helicopter, "Landing" )
Helicopter:Activate()

self.RoutePickup = true
Expand Down Expand Up @@ -690,7 +677,7 @@ function AI_CARGO_HELICOPTER:onafterHome( Helicopter, From, Event, To, Coordinat
Route[#Route+1] = WaypointTo

-- Now route the helicopter
Helicopter:Route( Route, 1 )
Helicopter:Route( Route, 0 )

end

Expand Down
18 changes: 8 additions & 10 deletions Moose Development/Moose/Core/Zone.lua
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,16 @@ end
-- @param Dcs.DCSTypes#Vec3 Vec3 The point to test.
-- @return #boolean true if the Vec3 is within the zone.
function ZONE_BASE:IsVec3InZone( Vec3 )
self:F2( Vec3 )

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
end

Expand All @@ -163,10 +169,7 @@ end
-- @param Core.Point#POINT_VEC2 PointVec2 The PointVec2 to test.
-- @return #boolean true if the PointVec2 is within the zone.
function ZONE_BASE:IsPointVec2InZone( PointVec2 )
self:F2( PointVec2 )

local InZone = self:IsVec2InZone( PointVec2:GetVec2() )

return InZone
end

Expand All @@ -175,10 +178,7 @@ end
-- @param Core.Point#POINT_VEC3 PointVec3 The PointVec3 to test.
-- @return #boolean true if the PointVec3 is within the zone.
function ZONE_BASE:IsPointVec3InZone( PointVec3 )
self:F2( PointVec3 )

local InZone = self:IsPointVec2InZone( PointVec3 )

return InZone
end

Expand All @@ -187,8 +187,6 @@ end
-- @param #ZONE_BASE self
-- @return #nil.
function ZONE_BASE:GetVec2()
self:F2( self.ZoneName )

return nil
end

Expand Down

0 comments on commit 0e0ab35

Please sign in to comment.