mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
1080 lines
26 KiB
Lua
1080 lines
26 KiB
Lua
--- CARGO Classes
|
|
-- @module CARGO
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--- Clients are those Groups defined within the Mission Editor that have the skillset defined as "Client" or "Player".
|
|
-- These clients are defined within the Mission Orchestration Framework (MOF)
|
|
|
|
CARGOS = {}
|
|
|
|
|
|
CARGO_ZONE = {
|
|
ClassName="CARGO_ZONE",
|
|
CargoZoneName = '',
|
|
CargoHostUnitName = '',
|
|
SIGNAL = {
|
|
TYPE = {
|
|
SMOKE = { ID = 1, TEXT = "smoke" },
|
|
FLARE = { ID = 2, TEXT = "flare" }
|
|
},
|
|
COLOR = {
|
|
GREEN = { ID = 1, TRIGGERCOLOR = trigger.smokeColor.Green, TEXT = "A green" },
|
|
RED = { ID = 2, TRIGGERCOLOR = trigger.smokeColor.Red, TEXT = "A red" },
|
|
WHITE = { ID = 3, TRIGGERCOLOR = trigger.smokeColor.White, TEXT = "A white" },
|
|
ORANGE = { ID = 4, TRIGGERCOLOR = trigger.smokeColor.Orange, TEXT = "An orange" },
|
|
BLUE = { ID = 5, TRIGGERCOLOR = trigger.smokeColor.Blue, TEXT = "A blue" },
|
|
YELLOW = { ID = 6, TRIGGERCOLOR = trigger.flareColor.Yellow, TEXT = "A yellow" }
|
|
}
|
|
}
|
|
}
|
|
|
|
--- Creates a new zone where cargo can be collected or deployed.
|
|
-- The zone functionality is useful to smoke or indicate routes for cargo pickups or deployments.
|
|
-- Provide the zone name as declared in the mission file into the CargoZoneName in the :New method.
|
|
-- An optional parameter is the CargoHostName, which is a Group declared with Late Activation switched on in the mission file.
|
|
-- The CargoHostName is the "host" of the cargo zone:
|
|
--
|
|
-- * It will smoke the zone position when a client is approaching the zone.
|
|
-- * Depending on the cargo type, it will assist in the delivery of the cargo by driving to and from the client.
|
|
--
|
|
-- @param #CARGO_ZONE self
|
|
-- @param #string CargoZoneName The name of the zone as declared within the mission editor.
|
|
-- @param #string CargoHostName The name of the Group "hosting" the zone. The Group MUST NOT be a static, and must be a "mobile" unit.
|
|
function CARGO_ZONE:New( CargoZoneName, CargoHostName ) local self = BASE:Inherit( self, ZONE:New( CargoZoneName ) )
|
|
self:F( { CargoZoneName, CargoHostName } )
|
|
|
|
self.CargoZoneName = CargoZoneName
|
|
self.SignalHeight = 2
|
|
--self.CargoZone = trigger.misc.getZone( CargoZoneName )
|
|
|
|
|
|
if CargoHostName then
|
|
self.CargoHostName = CargoHostName
|
|
end
|
|
|
|
self:T( self.CargoZoneName )
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO_ZONE:Spawn()
|
|
self:F( self.CargoHostName )
|
|
|
|
if self.CargoHostName then -- Only spawn a host in the zone when there is one given as a parameter in the New function.
|
|
if self.CargoHostSpawn then
|
|
local CargoHostGroup = self.CargoHostSpawn:GetGroupFromIndex()
|
|
if CargoHostGroup and CargoHostGroup:IsAlive() then
|
|
else
|
|
self.CargoHostSpawn:ReSpawn( 1 )
|
|
end
|
|
else
|
|
self:T( "Initialize CargoHostSpawn" )
|
|
self.CargoHostSpawn = SPAWN:New( self.CargoHostName ):Limit( 1, 1 )
|
|
self.CargoHostSpawn:ReSpawn( 1 )
|
|
end
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO_ZONE:GetHostUnit()
|
|
self:F( self )
|
|
|
|
if self.CargoHostName then
|
|
|
|
-- A Host has been given, signal the host
|
|
local CargoHostGroup = self.CargoHostSpawn:GetGroupFromIndex()
|
|
local CargoHostUnit
|
|
if CargoHostGroup and CargoHostGroup:IsAlive() then
|
|
CargoHostUnit = CargoHostGroup:GetUnit(1)
|
|
else
|
|
CargoHostUnit = StaticObject.getByName( self.CargoHostName )
|
|
end
|
|
|
|
return CargoHostUnit
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
function CARGO_ZONE:ReportCargosToClient( Client, CargoType )
|
|
self:F()
|
|
|
|
local SignalUnit = self:GetHostUnit()
|
|
|
|
if SignalUnit then
|
|
|
|
local SignalUnitTypeName = SignalUnit:getTypeName()
|
|
|
|
local HostMessage = ""
|
|
|
|
local IsCargo = false
|
|
for CargoID, Cargo in pairs( CARGOS ) do
|
|
if Cargo.CargoType == Task.CargoType then
|
|
if Cargo:IsStatusNone() then
|
|
HostMessage = HostMessage .. " - " .. Cargo.CargoName .. " - " .. Cargo.CargoType .. " (" .. Cargo.Weight .. "kg)" .. "\n"
|
|
IsCargo = true
|
|
end
|
|
end
|
|
end
|
|
|
|
if not IsCargo then
|
|
HostMessage = "No Cargo Available."
|
|
end
|
|
|
|
Client:Message( HostMessage, 20, SignalUnitTypeName .. ": Reporting Cargo", 10 )
|
|
end
|
|
end
|
|
|
|
|
|
function CARGO_ZONE:Signal()
|
|
self:F()
|
|
|
|
local Signalled = false
|
|
|
|
if self.SignalType then
|
|
|
|
if self.CargoHostName then
|
|
|
|
-- A Host has been given, signal the host
|
|
|
|
local SignalUnit = self:GetHostUnit()
|
|
|
|
if SignalUnit then
|
|
|
|
self:T( 'Signalling Unit' )
|
|
local SignalVehiclePos = SignalUnit:GetPointVec3()
|
|
SignalVehiclePos.y = SignalVehiclePos.y + 2
|
|
|
|
if self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.SMOKE.ID then
|
|
|
|
trigger.action.smoke( SignalVehiclePos, self.SignalColor.TRIGGERCOLOR )
|
|
Signalled = true
|
|
|
|
elseif self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.FLARE.ID then
|
|
|
|
trigger.action.signalFlare( SignalVehiclePos, self.SignalColor.TRIGGERCOLOR , 0 )
|
|
Signalled = false
|
|
|
|
end
|
|
end
|
|
|
|
else
|
|
|
|
local ZonePointVec3 = self:GetPointVec3( self.SignalHeight ) -- Get the zone position + the landheight + 2 meters
|
|
|
|
if self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.SMOKE.ID then
|
|
|
|
trigger.action.smoke( ZonePointVec3, self.SignalColor.TRIGGERCOLOR )
|
|
Signalled = true
|
|
|
|
elseif self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.FLARE.ID then
|
|
trigger.action.signalFlare( ZonePointVec3, self.SignalColor.TRIGGERCOLOR, 0 )
|
|
Signalled = false
|
|
|
|
end
|
|
end
|
|
end
|
|
|
|
return Signalled
|
|
|
|
end
|
|
|
|
function CARGO_ZONE:WhiteSmoke( SignalHeight )
|
|
self:F()
|
|
|
|
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE
|
|
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.WHITE
|
|
|
|
if SignalHeight then
|
|
self.SignalHeight = SignalHeight
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO_ZONE:BlueSmoke( SignalHeight )
|
|
self:F()
|
|
|
|
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE
|
|
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.BLUE
|
|
|
|
if SignalHeight then
|
|
self.SignalHeight = SignalHeight
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO_ZONE:RedSmoke( SignalHeight )
|
|
self:F()
|
|
|
|
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE
|
|
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.RED
|
|
|
|
if SignalHeight then
|
|
self.SignalHeight = SignalHeight
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO_ZONE:OrangeSmoke( SignalHeight )
|
|
self:F()
|
|
|
|
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE
|
|
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.ORANGE
|
|
|
|
if SignalHeight then
|
|
self.SignalHeight = SignalHeight
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO_ZONE:GreenSmoke( SignalHeight )
|
|
self:F()
|
|
|
|
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE
|
|
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.GREEN
|
|
|
|
if SignalHeight then
|
|
self.SignalHeight = SignalHeight
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
|
|
function CARGO_ZONE:WhiteFlare( SignalHeight )
|
|
self:F()
|
|
|
|
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE
|
|
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.WHITE
|
|
|
|
if SignalHeight then
|
|
self.SignalHeight = SignalHeight
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO_ZONE:RedFlare( SignalHeight )
|
|
self:F()
|
|
|
|
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE
|
|
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.RED
|
|
|
|
if SignalHeight then
|
|
self.SignalHeight = SignalHeight
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO_ZONE:GreenFlare( SignalHeight )
|
|
self:F()
|
|
|
|
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE
|
|
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.GREEN
|
|
|
|
if SignalHeight then
|
|
self.SignalHeight = SignalHeight
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO_ZONE:YellowFlare( SignalHeight )
|
|
self:F()
|
|
|
|
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE
|
|
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.YELLOW
|
|
|
|
if SignalHeight then
|
|
self.SignalHeight = SignalHeight
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
|
|
function CARGO_ZONE:GetCargoHostUnit()
|
|
self:F( self )
|
|
|
|
if self.CargoHostSpawn then
|
|
local CargoHostGroup = self.CargoHostSpawn:GetGroupFromIndex(1)
|
|
if CargoHostGroup and CargoHostGroup:IsAlive() then
|
|
local CargoHostUnit = CargoHostGroup:GetUnit(1)
|
|
if CargoHostUnit and CargoHostUnit:IsAlive() then
|
|
return CargoHostUnit
|
|
end
|
|
end
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
function CARGO_ZONE:GetCargoZoneName()
|
|
self:F()
|
|
|
|
return self.CargoZoneName
|
|
end
|
|
|
|
CARGO = {
|
|
ClassName = "CARGO",
|
|
STATUS = {
|
|
NONE = 0,
|
|
LOADED = 1,
|
|
UNLOADED = 2,
|
|
LOADING = 3
|
|
},
|
|
CargoClient = nil
|
|
}
|
|
|
|
--- Add Cargo to the mission... Cargo functionality needs to be reworked a bit, so this is still under construction. I need to make a CARGO Class...
|
|
function CARGO:New( CargoType, CargoName, CargoWeight ) local self = BASE:Inherit( self, BASE:New() )
|
|
self:F( { CargoType, CargoName, CargoWeight } )
|
|
|
|
|
|
self.CargoType = CargoType
|
|
self.CargoName = CargoName
|
|
self.CargoWeight = CargoWeight
|
|
|
|
self:StatusNone()
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO:Spawn( Client )
|
|
self:F()
|
|
|
|
return self
|
|
|
|
end
|
|
|
|
function CARGO:IsNear( Client, LandingZone )
|
|
self:F()
|
|
|
|
local Near = true
|
|
|
|
return Near
|
|
|
|
end
|
|
|
|
|
|
function CARGO:IsLoadingToClient()
|
|
self:F()
|
|
|
|
if self:IsStatusLoading() then
|
|
return self.CargoClient
|
|
end
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
function CARGO:IsLoadedInClient()
|
|
self:F()
|
|
|
|
if self:IsStatusLoaded() then
|
|
return self.CargoClient
|
|
end
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
function CARGO:UnLoad( Client, TargetZoneName )
|
|
self:F()
|
|
|
|
self:StatusUnLoaded()
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO:OnBoard( Client, LandingZone )
|
|
self:F()
|
|
|
|
local Valid = true
|
|
|
|
self.CargoClient = Client
|
|
local ClientUnit = Client:GetClientGroupDCSUnit()
|
|
|
|
return Valid
|
|
end
|
|
|
|
function CARGO:OnBoarded( Client, LandingZone )
|
|
self:F()
|
|
|
|
local OnBoarded = true
|
|
|
|
return OnBoarded
|
|
end
|
|
|
|
function CARGO:Load( Client )
|
|
self:F()
|
|
|
|
self:StatusLoaded( Client )
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO:IsLandingRequired()
|
|
self:F()
|
|
return true
|
|
end
|
|
|
|
function CARGO:IsSlingLoad()
|
|
self:F()
|
|
return false
|
|
end
|
|
|
|
|
|
function CARGO:StatusNone()
|
|
self:F()
|
|
|
|
self.CargoClient = nil
|
|
self.CargoStatus = CARGO.STATUS.NONE
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO:StatusLoading( Client )
|
|
self:F()
|
|
|
|
self.CargoClient = Client
|
|
self.CargoStatus = CARGO.STATUS.LOADING
|
|
self:T( "Cargo " .. self.CargoName .. " loading to Client: " .. self.CargoClient:GetClientGroupName() )
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO:StatusLoaded( Client )
|
|
self:F()
|
|
|
|
self.CargoClient = Client
|
|
self.CargoStatus = CARGO.STATUS.LOADED
|
|
self:T( "Cargo " .. self.CargoName .. " loaded in Client: " .. self.CargoClient:GetClientGroupName() )
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO:StatusUnLoaded()
|
|
self:F()
|
|
|
|
self.CargoClient = nil
|
|
self.CargoStatus = CARGO.STATUS.UNLOADED
|
|
|
|
return self
|
|
end
|
|
|
|
|
|
function CARGO:IsStatusNone()
|
|
self:F()
|
|
|
|
return self.CargoStatus == CARGO.STATUS.NONE
|
|
end
|
|
|
|
function CARGO:IsStatusLoading()
|
|
self:F()
|
|
|
|
return self.CargoStatus == CARGO.STATUS.LOADING
|
|
end
|
|
|
|
function CARGO:IsStatusLoaded()
|
|
self:F()
|
|
|
|
return self.CargoStatus == CARGO.STATUS.LOADED
|
|
end
|
|
|
|
function CARGO:IsStatusUnLoaded()
|
|
self:F()
|
|
|
|
return self.CargoStatus == CARGO.STATUS.UNLOADED
|
|
end
|
|
|
|
|
|
CARGO_GROUP = {
|
|
ClassName = "CARGO_GROUP"
|
|
}
|
|
|
|
|
|
function CARGO_GROUP:New( CargoType, CargoName, CargoWeight, CargoGroupTemplate, CargoZone ) local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) )
|
|
self:F( { CargoType, CargoName, CargoWeight, CargoGroupTemplate, CargoZone } )
|
|
|
|
self.CargoSpawn = SPAWN:NewWithAlias( CargoGroupTemplate, CargoName )
|
|
self.CargoZone = CargoZone
|
|
|
|
CARGOS[self.CargoName] = self
|
|
|
|
return self
|
|
|
|
end
|
|
|
|
function CARGO_GROUP:Spawn( Client )
|
|
self:F( { Client } )
|
|
|
|
local SpawnCargo = true
|
|
|
|
if self:IsStatusNone() then
|
|
local CargoGroup = Group.getByName( self.CargoName )
|
|
if CargoGroup and CargoGroup:isExist() then
|
|
SpawnCargo = false
|
|
end
|
|
|
|
elseif self:IsStatusLoading() then
|
|
|
|
local Client = self:IsLoadingToClient()
|
|
if Client and Client:GetDCSGroup() then
|
|
SpawnCargo = false
|
|
else
|
|
local CargoGroup = Group.getByName( self.CargoName )
|
|
if CargoGroup and CargoGroup:isExist() then
|
|
SpawnCargo = false
|
|
end
|
|
end
|
|
|
|
elseif self:IsStatusLoaded() then
|
|
|
|
local ClientLoaded = self:IsLoadedInClient()
|
|
-- Now test if another Client is alive (not this one), and it has the CARGO, then this cargo does not need to be initialized and spawned.
|
|
if ClientLoaded and ClientLoaded ~= Client then
|
|
local ClientGroup = Client:GetDCSGroup()
|
|
if ClientLoaded:GetClientGroupDCSUnit() and ClientLoaded:GetClientGroupDCSUnit():isExist() then
|
|
SpawnCargo = false
|
|
else
|
|
self:StatusNone()
|
|
end
|
|
else
|
|
-- Same Client, but now in initialize, so set back the status to None.
|
|
self:StatusNone()
|
|
end
|
|
|
|
elseif self:IsStatusUnLoaded() then
|
|
|
|
SpawnCargo = false
|
|
|
|
end
|
|
|
|
if SpawnCargo then
|
|
if self.CargoZone:GetCargoHostUnit() then
|
|
--- ReSpawn the Cargo from the CargoHost
|
|
self.CargoGroupName = self.CargoSpawn:SpawnFromUnit( self.CargoZone:GetCargoHostUnit(), 60, 30, 1 ):GetName()
|
|
else
|
|
--- ReSpawn the Cargo in the CargoZone without a host ...
|
|
self:T( self.CargoZone )
|
|
self.CargoGroupName = self.CargoSpawn:SpawnInZone( self.CargoZone, true, 1 ):GetName()
|
|
end
|
|
self:StatusNone()
|
|
end
|
|
|
|
self:T( { self.CargoGroupName, CARGOS[self.CargoName].CargoGroupName } )
|
|
|
|
return self
|
|
end
|
|
|
|
function CARGO_GROUP:IsNear( Client, LandingZone )
|
|
self:F()
|
|
|
|
local Near = false
|
|
|
|
if self.CargoGroupName then
|
|
local CargoGroup = Group.getByName( self.CargoGroupName )
|
|
if routines.IsPartOfGroupInRadius( CargoGroup, Client:GetPositionVec3(), 250 ) then
|
|
Near = true
|
|
end
|
|
end
|
|
|
|
return Near
|
|
|
|
end
|
|
|
|
|
|
function CARGO_GROUP:OnBoard( Client, LandingZone, OnBoardSide )
|
|
self:F()
|
|
|
|
local Valid = true
|
|
|
|
local ClientUnit = Client:GetClientGroupDCSUnit()
|
|
|
|
local CarrierPos = ClientUnit:getPoint()
|
|
local CarrierPosMove = ClientUnit:getPoint()
|
|
local CarrierPosOnBoard = ClientUnit:getPoint()
|
|
|
|
local CargoGroup = Group.getByName( self.CargoGroupName )
|
|
|
|
local CargoUnit = CargoGroup:getUnit(1)
|
|
local CargoPos = CargoUnit:getPoint()
|
|
|
|
self.CargoInAir = CargoUnit:inAir()
|
|
|
|
self:T( self.CargoInAir )
|
|
|
|
-- Only move the group to the carrier when the cargo is not in the air
|
|
-- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea).
|
|
if not self.CargoInAir then
|
|
|
|
local Points = {}
|
|
|
|
self:T( 'CargoPos x = ' .. CargoPos.x .. " z = " .. CargoPos.z )
|
|
self:T( 'CarrierPosMove x = ' .. CarrierPosMove.x .. " z = " .. CarrierPosMove.z )
|
|
|
|
Points[#Points+1] = routines.ground.buildWP( CargoPos, "Cone", 10 )
|
|
|
|
self:T( 'Points[1] x = ' .. Points[1].x .. " y = " .. Points[1].y )
|
|
|
|
if OnBoardSide == nil then
|
|
OnBoardSide = CLIENT.ONBOARDSIDE.NONE
|
|
end
|
|
|
|
if OnBoardSide == CLIENT.ONBOARDSIDE.LEFT then
|
|
|
|
self:T( "TransportCargoOnBoard: Onboarding LEFT" )
|
|
CarrierPosMove.z = CarrierPosMove.z - 25
|
|
CarrierPosOnBoard.z = CarrierPosOnBoard.z - 5
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
|
|
|
|
elseif OnBoardSide == CLIENT.ONBOARDSIDE.RIGHT then
|
|
|
|
self:T( "TransportCargoOnBoard: Onboarding RIGHT" )
|
|
CarrierPosMove.z = CarrierPosMove.z + 25
|
|
CarrierPosOnBoard.z = CarrierPosOnBoard.z + 5
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
|
|
|
|
elseif OnBoardSide == CLIENT.ONBOARDSIDE.BACK then
|
|
|
|
self:T( "TransportCargoOnBoard: Onboarding BACK" )
|
|
CarrierPosMove.x = CarrierPosMove.x - 25
|
|
CarrierPosOnBoard.x = CarrierPosOnBoard.x - 5
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
|
|
|
|
elseif OnBoardSide == CLIENT.ONBOARDSIDE.FRONT then
|
|
|
|
self:T( "TransportCargoOnBoard: Onboarding FRONT" )
|
|
CarrierPosMove.x = CarrierPosMove.x + 25
|
|
CarrierPosOnBoard.x = CarrierPosOnBoard.x + 5
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
|
|
|
|
elseif OnBoardSide == CLIENT.ONBOARDSIDE.NONE then
|
|
|
|
self:T( "TransportCargoOnBoard: Onboarding CENTRAL" )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPos, "Cone", 10 )
|
|
|
|
end
|
|
self:T( "TransportCargoOnBoard: Routing " .. self.CargoGroupName )
|
|
|
|
--routines.scheduleFunction( routines.goRoute, { self.CargoGroupName, Points}, timer.getTime() + 4 )
|
|
SCHEDULER:New( self, routines.goRoute, { self.CargoGroupName, Points}, 4 )
|
|
end
|
|
|
|
self:StatusLoading( Client )
|
|
|
|
return Valid
|
|
|
|
end
|
|
|
|
|
|
function CARGO_GROUP:OnBoarded( Client, LandingZone )
|
|
self:F()
|
|
|
|
local OnBoarded = false
|
|
|
|
local CargoGroup = Group.getByName( self.CargoGroupName )
|
|
|
|
if not self.CargoInAir then
|
|
if routines.IsPartOfGroupInRadius( CargoGroup, Client:GetPositionVec3(), 25 ) then
|
|
CargoGroup:destroy()
|
|
self:StatusLoaded( Client )
|
|
OnBoarded = true
|
|
end
|
|
else
|
|
CargoGroup:destroy()
|
|
self:StatusLoaded( Client )
|
|
OnBoarded = true
|
|
end
|
|
|
|
return OnBoarded
|
|
end
|
|
|
|
|
|
function CARGO_GROUP:UnLoad( Client, TargetZoneName )
|
|
self:F()
|
|
|
|
self:T( 'self.CargoName = ' .. self.CargoName )
|
|
|
|
local CargoGroup = self.CargoSpawn:SpawnFromUnit( Client:GetClientGroupUnit(), 60, 30 )
|
|
|
|
self.CargoGroupName = CargoGroup:GetName()
|
|
self:T( 'self.CargoGroupName = ' .. self.CargoGroupName )
|
|
|
|
CargoGroup:TaskRouteToZone( ZONE:New( TargetZoneName ), true )
|
|
|
|
self:StatusUnLoaded()
|
|
|
|
return self
|
|
end
|
|
|
|
|
|
CARGO_PACKAGE = {
|
|
ClassName = "CARGO_PACKAGE"
|
|
}
|
|
|
|
|
|
function CARGO_PACKAGE:New( CargoType, CargoName, CargoWeight, CargoClient ) local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) )
|
|
self:F( { CargoType, CargoName, CargoWeight, CargoClient } )
|
|
|
|
self.CargoClient = CargoClient
|
|
|
|
CARGOS[self.CargoName] = self
|
|
|
|
return self
|
|
|
|
end
|
|
|
|
|
|
function CARGO_PACKAGE:Spawn( Client )
|
|
self:F( { self, Client } )
|
|
|
|
-- this needs to be checked thoroughly
|
|
|
|
local CargoClientGroup = self.CargoClient:GetDCSGroup()
|
|
if not CargoClientGroup then
|
|
if not self.CargoClientSpawn then
|
|
self.CargoClientSpawn = SPAWN:New( self.CargoClient:GetClientGroupName() ):Limit( 1, 1 )
|
|
end
|
|
self.CargoClientSpawn:ReSpawn( 1 )
|
|
end
|
|
|
|
local SpawnCargo = true
|
|
|
|
if self:IsStatusNone() then
|
|
|
|
elseif self:IsStatusLoading() or self:IsStatusLoaded() then
|
|
|
|
local CargoClientLoaded = self:IsLoadedInClient()
|
|
if CargoClientLoaded and CargoClientLoaded:GetDCSGroup() then
|
|
SpawnCargo = false
|
|
end
|
|
|
|
elseif self:IsStatusUnLoaded() then
|
|
|
|
SpawnCargo = false
|
|
|
|
else
|
|
|
|
end
|
|
|
|
if SpawnCargo then
|
|
self:StatusLoaded( self.CargoClient )
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
|
|
function CARGO_PACKAGE:IsNear( Client, LandingZone )
|
|
self:F()
|
|
|
|
local Near = false
|
|
|
|
if self.CargoClient and self.CargoClient:GetDCSGroup() then
|
|
self:T( self.CargoClient.ClientName )
|
|
self:T( 'Client Exists.' )
|
|
|
|
if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), Client:GetPositionVec3(), 150 ) then
|
|
Near = true
|
|
end
|
|
end
|
|
|
|
return Near
|
|
|
|
end
|
|
|
|
|
|
function CARGO_PACKAGE:OnBoard( Client, LandingZone, OnBoardSide )
|
|
self:F()
|
|
|
|
local Valid = true
|
|
|
|
local ClientUnit = Client:GetClientGroupDCSUnit()
|
|
|
|
local CarrierPos = ClientUnit:getPoint()
|
|
local CarrierPosMove = ClientUnit:getPoint()
|
|
local CarrierPosOnBoard = ClientUnit:getPoint()
|
|
local CarrierPosMoveAway = ClientUnit:getPoint()
|
|
|
|
local CargoHostGroup = self.CargoClient:GetDCSGroup()
|
|
local CargoHostName = self.CargoClient:GetDCSGroup():getName()
|
|
|
|
local CargoHostUnits = CargoHostGroup:getUnits()
|
|
local CargoPos = CargoHostUnits[1]:getPoint()
|
|
|
|
local Points = {}
|
|
|
|
self:T( 'CargoPos x = ' .. CargoPos.x .. " z = " .. CargoPos.z )
|
|
self:T( 'CarrierPosMove x = ' .. CarrierPosMove.x .. " z = " .. CarrierPosMove.z )
|
|
|
|
Points[#Points+1] = routines.ground.buildWP( CargoPos, "Cone", 10 )
|
|
|
|
self:T( 'Points[1] x = ' .. Points[1].x .. " y = " .. Points[1].y )
|
|
|
|
if OnBoardSide == nil then
|
|
OnBoardSide = CLIENT.ONBOARDSIDE.NONE
|
|
end
|
|
|
|
if OnBoardSide == CLIENT.ONBOARDSIDE.LEFT then
|
|
|
|
self:T( "TransportCargoOnBoard: Onboarding LEFT" )
|
|
CarrierPosMove.z = CarrierPosMove.z - 25
|
|
CarrierPosOnBoard.z = CarrierPosOnBoard.z - 5
|
|
CarrierPosMoveAway.z = CarrierPosMoveAway.z - 20
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMoveAway, "Cone", 10 )
|
|
|
|
elseif OnBoardSide == CLIENT.ONBOARDSIDE.RIGHT then
|
|
|
|
self:T( "TransportCargoOnBoard: Onboarding RIGHT" )
|
|
CarrierPosMove.z = CarrierPosMove.z + 25
|
|
CarrierPosOnBoard.z = CarrierPosOnBoard.z + 5
|
|
CarrierPosMoveAway.z = CarrierPosMoveAway.z + 20
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMoveAway, "Cone", 10 )
|
|
|
|
elseif OnBoardSide == CLIENT.ONBOARDSIDE.BACK then
|
|
|
|
self:T( "TransportCargoOnBoard: Onboarding BACK" )
|
|
CarrierPosMove.x = CarrierPosMove.x - 25
|
|
CarrierPosOnBoard.x = CarrierPosOnBoard.x - 5
|
|
CarrierPosMoveAway.x = CarrierPosMoveAway.x - 20
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMoveAway, "Cone", 10 )
|
|
|
|
elseif OnBoardSide == CLIENT.ONBOARDSIDE.FRONT then
|
|
|
|
self:T( "TransportCargoOnBoard: Onboarding FRONT" )
|
|
CarrierPosMove.x = CarrierPosMove.x + 25
|
|
CarrierPosOnBoard.x = CarrierPosOnBoard.x + 5
|
|
CarrierPosMoveAway.x = CarrierPosMoveAway.x + 20
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMoveAway, "Cone", 10 )
|
|
|
|
elseif OnBoardSide == CLIENT.ONBOARDSIDE.NONE then
|
|
|
|
self:T( "TransportCargoOnBoard: Onboarding FRONT" )
|
|
CarrierPosMove.x = CarrierPosMove.x + 25
|
|
CarrierPosOnBoard.x = CarrierPosOnBoard.x + 5
|
|
CarrierPosMoveAway.x = CarrierPosMoveAway.x + 20
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
|
|
Points[#Points+1] = routines.ground.buildWP( CarrierPosMoveAway, "Cone", 10 )
|
|
|
|
end
|
|
self:T( "Routing " .. CargoHostName )
|
|
|
|
SCHEDULER:New( self, routines.goRoute, { CargoHostName, Points }, 4 )
|
|
|
|
return Valid
|
|
|
|
end
|
|
|
|
|
|
function CARGO_PACKAGE:OnBoarded( Client, LandingZone )
|
|
self:F()
|
|
|
|
local OnBoarded = false
|
|
|
|
if self.CargoClient and self.CargoClient:GetDCSGroup() then
|
|
if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), self.CargoClient:GetPositionVec3(), 10 ) then
|
|
|
|
-- Switch Cargo from self.CargoClient to Client ... Each cargo can have only one client. So assigning the new client for the cargo is enough.
|
|
self:StatusLoaded( Client )
|
|
|
|
-- All done, onboarded the Cargo to the new Client.
|
|
OnBoarded = true
|
|
end
|
|
end
|
|
|
|
return OnBoarded
|
|
end
|
|
|
|
|
|
function CARGO_PACKAGE:UnLoad( Client, TargetZoneName )
|
|
self:F()
|
|
|
|
self:T( 'self.CargoName = ' .. self.CargoName )
|
|
--self:T( 'self.CargoHostName = ' .. self.CargoHostName )
|
|
|
|
--self.CargoSpawn:FromCarrier( Client:GetDCSGroup(), TargetZoneName, self.CargoHostName )
|
|
self:StatusUnLoaded()
|
|
|
|
return Cargo
|
|
end
|
|
|
|
|
|
CARGO_SLINGLOAD = {
|
|
ClassName = "CARGO_SLINGLOAD"
|
|
}
|
|
|
|
|
|
function CARGO_SLINGLOAD:New( CargoType, CargoName, CargoWeight, CargoZone, CargoHostName, CargoCountryID )
|
|
local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) )
|
|
self:F( { CargoType, CargoName, CargoWeight, CargoZone, CargoHostName, CargoCountryID } )
|
|
|
|
self.CargoHostName = CargoHostName
|
|
|
|
-- Cargo will be initialized around the CargoZone position.
|
|
self.CargoZone = CargoZone
|
|
|
|
self.CargoCount = 0
|
|
self.CargoStaticName = string.format( "%s#%03d", self.CargoName, self.CargoCount )
|
|
|
|
-- The country ID needs to be correctly set.
|
|
self.CargoCountryID = CargoCountryID
|
|
|
|
CARGOS[self.CargoName] = self
|
|
|
|
return self
|
|
|
|
end
|
|
|
|
|
|
function CARGO_SLINGLOAD:IsLandingRequired()
|
|
self:F()
|
|
return false
|
|
end
|
|
|
|
|
|
function CARGO_SLINGLOAD:IsSlingLoad()
|
|
self:F()
|
|
return true
|
|
end
|
|
|
|
|
|
function CARGO_SLINGLOAD:Spawn( Client )
|
|
self:F( { self, Client } )
|
|
|
|
local Zone = trigger.misc.getZone( self.CargoZone )
|
|
|
|
local ZonePos = {}
|
|
ZonePos.x = Zone.point.x + math.random( Zone.radius / 2 * -1, Zone.radius / 2 )
|
|
ZonePos.y = Zone.point.z + math.random( Zone.radius / 2 * -1, Zone.radius / 2 )
|
|
|
|
self:T( "Cargo Location = " .. ZonePos.x .. ", " .. ZonePos.y )
|
|
|
|
--[[
|
|
-- This does not work in 1.5.2.
|
|
CargoStatic = StaticObject.getByName( self.CargoName )
|
|
if CargoStatic then
|
|
CargoStatic:destroy()
|
|
end
|
|
--]]
|
|
|
|
CargoStatic = StaticObject.getByName( self.CargoStaticName )
|
|
|
|
if CargoStatic and CargoStatic:isExist() then
|
|
CargoStatic:destroy()
|
|
end
|
|
|
|
-- I need to make every time a new cargo due to bugs in 1.5.2.
|
|
|
|
self.CargoCount = self.CargoCount + 1
|
|
self.CargoStaticName = string.format( "%s#%03d", self.CargoName, self.CargoCount )
|
|
|
|
local CargoTemplate = {
|
|
["category"] = "Cargo",
|
|
["shape_name"] = "ab-212_cargo",
|
|
["type"] = "Cargo1",
|
|
["x"] = ZonePos.x,
|
|
["y"] = ZonePos.y,
|
|
["mass"] = self.CargoWeight,
|
|
["name"] = self.CargoStaticName,
|
|
["canCargo"] = true,
|
|
["heading"] = 0,
|
|
}
|
|
|
|
coalition.addStaticObject( self.CargoCountryID, CargoTemplate )
|
|
|
|
-- end
|
|
|
|
return self
|
|
end
|
|
|
|
|
|
function CARGO_SLINGLOAD:IsNear( Client, LandingZone )
|
|
self:F()
|
|
|
|
local Near = false
|
|
|
|
return Near
|
|
end
|
|
|
|
|
|
function CARGO_SLINGLOAD:IsInLandingZone( Client, LandingZone )
|
|
self:F()
|
|
|
|
local Near = false
|
|
|
|
local CargoStaticUnit = StaticObject.getByName( self.CargoName )
|
|
if CargoStaticUnit then
|
|
if routines.IsStaticInZones( CargoStaticUnit, LandingZone ) then
|
|
Near = true
|
|
end
|
|
end
|
|
|
|
return Near
|
|
end
|
|
|
|
|
|
function CARGO_SLINGLOAD:OnBoard( Client, LandingZone, OnBoardSide )
|
|
self:F()
|
|
|
|
local Valid = true
|
|
|
|
|
|
return Valid
|
|
end
|
|
|
|
|
|
function CARGO_SLINGLOAD:OnBoarded( Client, LandingZone )
|
|
self:F()
|
|
|
|
local OnBoarded = false
|
|
|
|
local CargoStaticUnit = StaticObject.getByName( self.CargoName )
|
|
if CargoStaticUnit then
|
|
if not routines.IsStaticInZones( CargoStaticUnit, LandingZone ) then
|
|
OnBoarded = true
|
|
end
|
|
end
|
|
|
|
return OnBoarded
|
|
end
|
|
|
|
|
|
function CARGO_SLINGLOAD:UnLoad( Client, TargetZoneName )
|
|
self:F()
|
|
|
|
self:T( 'self.CargoName = ' .. self.CargoName )
|
|
self:T( 'self.CargoGroupName = ' .. self.CargoGroupName )
|
|
|
|
self:StatusUnLoaded()
|
|
|
|
return Cargo
|
|
end
|