OPS Cargo

This commit is contained in:
Frank 2021-02-06 09:41:24 +01:00
parent 7d83c251a8
commit 8bb9f0d7c0
3 changed files with 504 additions and 94 deletions

View File

@ -1745,10 +1745,9 @@ do -- COORDINATE
--- Creates an explosion at the point of a certain intensity. --- Creates an explosion at the point of a certain intensity.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #number ExplosionIntensity Intensity of the explosion in kg TNT. Default 100 kg. -- @param #number ExplosionIntensity Intensity of the explosion in kg TNT. Default 100 kg.
-- @param #number Delay Delay before explosion in seconds. -- @param #number Delay (Optional) Delay before explosion is triggered in seconds.
-- @return #COORDINATE self -- @return #COORDINATE self
function COORDINATE:Explosion( ExplosionIntensity, Delay ) function COORDINATE:Explosion( ExplosionIntensity, Delay )
self:F2( { ExplosionIntensity } )
ExplosionIntensity=ExplosionIntensity or 100 ExplosionIntensity=ExplosionIntensity or 100
if Delay and Delay>0 then if Delay and Delay>0 then
self:ScheduleOnce(Delay, self.Explosion, self, ExplosionIntensity) self:ScheduleOnce(Delay, self.Explosion, self, ExplosionIntensity)
@ -1760,11 +1759,17 @@ do -- COORDINATE
--- Creates an illumination bomb at the point. --- Creates an illumination bomb at the point.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #number power Power of illumination bomb in Candela. -- @param #number Power Power of illumination bomb in Candela. Default 1000 cd.
-- @param #number Delay (Optional) Delay before bomb is ignited in seconds.
-- @return #COORDINATE self -- @return #COORDINATE self
function COORDINATE:IlluminationBomb(power) function COORDINATE:IlluminationBomb(Power, Delay)
self:F2() Power=Power or 1000
trigger.action.illuminationBomb( self:GetVec3(), power ) if Delay and Delay>0 then
self:ScheduleOnce(Delay, self.IlluminationBomb, self, Power)
else
trigger.action.illuminationBomb(self:GetVec3(), Power)
end
return self
end end

View File

@ -31,10 +31,6 @@
--- FLIGHTGROUP class. --- FLIGHTGROUP class.
-- @type FLIGHTGROUP -- @type FLIGHTGROUP
-- @field Wrapper.Airbase#AIRBASE homebase The home base of the flight group.
-- @field Wrapper.Airbase#AIRBASE destbase The destination base of the flight group.
-- @field Core.Zone#ZONE homezone The home zone of the flight group. Set when spawn happens in air.
-- @field Core.Zone#ZONE destzone The destination zone of the flight group. Set when final waypoint is in air.
-- @field #string actype Type name of the aircraft. -- @field #string actype Type name of the aircraft.
-- @field #number rangemax Max range in km. -- @field #number rangemax Max range in km.
-- @field #number ceiling Max altitude the aircraft can fly at in meters. -- @field #number ceiling Max altitude the aircraft can fly at in meters.
@ -690,10 +686,17 @@ function FLIGHTGROUP:StartUncontrolled(delay)
self:ScheduleOnce(delay, FLIGHTGROUP.StartUncontrolled, self) self:ScheduleOnce(delay, FLIGHTGROUP.StartUncontrolled, self)
else else
if self:IsAlive() then local alive=self:IsAlive()
--TODO: check Alive==true and Alive==false ==> Activate first
self:T(self.lid.."Starting uncontrolled group") if alive~=nil then
self.group:StartUncontrolled(delay) -- Check if group is already active.
local _delay=0
if alive==false then
self:Activate()
_delay=1
end
self:I(self.lid.."Starting uncontrolled group")
self.group:StartUncontrolled(_delay)
self.isUncontrolled=true self.isUncontrolled=true
else else
self:E(self.lid.."ERROR: Could not start uncontrolled group as it is NOT alive!") self:E(self.lid.."ERROR: Could not start uncontrolled group as it is NOT alive!")
@ -1443,17 +1446,20 @@ function FLIGHTGROUP:onafterElementLanded(From, Event, To, Element, airbase)
else else
-- Set element status.
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.LANDED, airbase)
-- Helos with skids land directly on parking spots. -- Helos with skids land directly on parking spots.
if self.isHelo then if self.isHelo then
local Spot=self:GetParkingSpot(Element, 10, airbase) local Spot=self:GetParkingSpot(Element, 10, airbase)
if Spot then
self:_SetElementParkingAt(Element, Spot) self:_SetElementParkingAt(Element, Spot)
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.ARRIVED)
end end
-- Set element status. end
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.LANDED, airbase)
end end
end end
@ -1469,6 +1475,7 @@ end
function FLIGHTGROUP:onafterElementArrived(From, Event, To, Element, airbase, Parking) function FLIGHTGROUP:onafterElementArrived(From, Event, To, Element, airbase, Parking)
self:T(self.lid..string.format("Element arrived %s at %s airbase using parking spot %d", Element.name, airbase and airbase:GetName() or "unknown", Parking and Parking.TerminalID or -99)) self:T(self.lid..string.format("Element arrived %s at %s airbase using parking spot %d", Element.name, airbase and airbase:GetName() or "unknown", Parking and Parking.TerminalID or -99))
-- Set element parking.
self:_SetElementParkingAt(Element, Parking) self:_SetElementParkingAt(Element, Parking)
-- Set element status. -- Set element status.
@ -1662,8 +1669,21 @@ end
function FLIGHTGROUP:onafterAirborne(From, Event, To) function FLIGHTGROUP:onafterAirborne(From, Event, To)
self:T(self.lid..string.format("Flight airborne")) self:T(self.lid..string.format("Flight airborne"))
-- No current airbase any more.
self.currbase=nil
if self.isAI then if self.isAI then
if self:IsTransporting() then
env.info("FF transporting land at airbase ")
local airbase=self.cargoTransport.deployzone:GetAirbase()
self:LandAtAirbase(airbase)
elseif self:IsPickingup() then
env.info("FF pickingup land at airbase ")
local airbase=self.cargoTransport.pickupzone:GetAirbase()
self:LandAtAirbase(airbase)
else
self:_CheckGroupDone(1) self:_CheckGroupDone(1)
end
else else
self:_UpdateMenu() self:_UpdateMenu()
end end
@ -1715,7 +1735,6 @@ function FLIGHTGROUP:onafterLandedAt(From, Event, To)
end end
--- On after "Arrived" event. --- On after "Arrived" event.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @param #string From From state. -- @param #string From From state.
@ -1801,6 +1820,13 @@ function FLIGHTGROUP:onafterArrived(From, Event, To)
-- Reset. -- Reset.
self.isLandingAtAirbase=nil self.isLandingAtAirbase=nil
-- Init (un-)loading process.
if self:IsPickingup() then
self:__Loading(-1)
elseif self:IsTransporting() then
self:__Deploy(-1)
end
else else
-- Depawn after 5 min. Important to trigger dead events before DCS despawns on its own without any notification. -- Depawn after 5 min. Important to trigger dead events before DCS despawns on its own without any notification.
self:Despawn(5*60) self:Despawn(5*60)
@ -2032,6 +2058,9 @@ function FLIGHTGROUP:_CheckGroupDone(delay)
-- Number of mission remaining. -- Number of mission remaining.
local nMissions=self:CountRemainingMissison() local nMissions=self:CountRemainingMissison()
-- Number of cargo transports remaining.
local nTransports=self:CountRemainingTransports()
-- Final waypoint passed? -- Final waypoint passed?
if self.passedfinalwp then if self.passedfinalwp then
@ -2039,7 +2068,7 @@ function FLIGHTGROUP:_CheckGroupDone(delay)
if self.currentmission==nil and self.taskcurrent==0 then if self.currentmission==nil and self.taskcurrent==0 then
-- Number of remaining tasks/missions? -- Number of remaining tasks/missions?
if nTasks==0 and nMissions==0 then if nTasks==0 and nMissions==0 and nTransports==0 then
local destbase=self.destbase or self.homebase local destbase=self.destbase or self.homebase
local destzone=self.destzone or self.homezone local destzone=self.destzone or self.homezone
@ -2201,6 +2230,9 @@ end
-- @param #number SpeedLand Landing speed in knots. Default 170 kts. -- @param #number SpeedLand Landing speed in knots. Default 170 kts.
function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand) function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand)
-- Set current airbase.
self.currbase=airbase
-- Defaults: -- Defaults:
SpeedTo=SpeedTo or UTILS.KmphToKnots(self.speedCruise) SpeedTo=SpeedTo or UTILS.KmphToKnots(self.speedCruise)
SpeedHold=SpeedHold or (self.isHelo and 80 or 250) SpeedHold=SpeedHold or (self.isHelo and 80 or 250)
@ -2287,10 +2319,10 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand)
local pland=airbase:GetCoordinate():Translate(x2, runway.heading-180):SetAltitude(h2) local pland=airbase:GetCoordinate():Translate(x2, runway.heading-180):SetAltitude(h2)
wp[#wp+1]=pland:WaypointAirLanding(UTILS.KnotsToKmph(SpeedLand), airbase, {}, "Landing") wp[#wp+1]=pland:WaypointAirLanding(UTILS.KnotsToKmph(SpeedLand), airbase, {}, "Landing")
elseif airbase:IsShip() then elseif airbase:IsShip() or airbase:IsHelipad() then
--- ---
-- Ship -- Ship or Helipad
--- ---
local pland=airbase:GetCoordinate() local pland=airbase:GetCoordinate()
@ -2714,6 +2746,8 @@ function FLIGHTGROUP:onafterStop(From, Event, To)
end end
self.currbase=nil
-- Handle events: -- Handle events:
self:UnHandleEvent(EVENTS.Birth) self:UnHandleEvent(EVENTS.Birth)
self:UnHandleEvent(EVENTS.EngineStartup) self:UnHandleEvent(EVENTS.EngineStartup)
@ -3542,13 +3576,22 @@ end
-- @return Wrapper.Airbase#AIRBASE.ParkingSpot Parking spot or nil if no spot is within distance threshold. -- @return Wrapper.Airbase#AIRBASE.ParkingSpot Parking spot or nil if no spot is within distance threshold.
function FLIGHTGROUP:GetParkingSpot(element, maxdist, airbase) function FLIGHTGROUP:GetParkingSpot(element, maxdist, airbase)
-- Coordinate of unit landed
local coord=element.unit:GetCoordinate() local coord=element.unit:GetCoordinate()
-- Airbase.
airbase=airbase or self:GetClosestAirbase() --coord:GetClosestAirbase(nil, self:GetCoalition()) airbase=airbase or self:GetClosestAirbase() --coord:GetClosestAirbase(nil, self:GetCoalition())
-- TODO: replace by airbase.parking if AIRBASE is updated. -- TODO: replace by airbase.parking if AIRBASE is updated.
local parking=airbase:GetParkingSpotsTable() local parking=airbase:GetParkingSpotsTable()
-- If airbase is ship, translate parking coords. Alternatively, we just move the coordinate of the unit to the origin of the map, which is way more efficient.
if airbase and airbase:IsShip() then
coord.x=0
coord.z=0
maxdist=100
end
local spot=nil --Wrapper.Airbase#AIRBASE.ParkingSpot local spot=nil --Wrapper.Airbase#AIRBASE.ParkingSpot
local dist=nil local dist=nil
local distmin=math.huge local distmin=math.huge

View File

@ -33,6 +33,11 @@
-- @field #boolean isGround If true, group is some ground unit. -- @field #boolean isGround If true, group is some ground unit.
-- @field #table waypoints Table of waypoints. -- @field #table waypoints Table of waypoints.
-- @field #table waypoints0 Table of initial waypoints. -- @field #table waypoints0 Table of initial waypoints.
-- @field Wrapper.Airbase#AIRBASE homebase The home base of the flight group.
-- @field Wrapper.Airbase#AIRBASE destbase The destination base of the flight group.
-- @field Wrapper.Airbase#AIRBASE currbase The current airbase of the flight group, i.e. where it is currently located or landing at.
-- @field Core.Zone#ZONE homezone The home zone of the flight group. Set when spawn happens in air.
-- @field Core.Zone#ZONE destzone The destination zone of the flight group. Set when final waypoint is in air.
-- @field #number currentwp Current waypoint index. This is the index of the last passed waypoint. -- @field #number currentwp Current waypoint index. This is the index of the last passed waypoint.
-- @field #boolean adinfinitum Resume route at first waypoint when final waypoint is reached. -- @field #boolean adinfinitum Resume route at first waypoint when final waypoint is reached.
-- @field #table taskqueue Queue of tasks. -- @field #table taskqueue Queue of tasks.
@ -99,6 +104,7 @@
-- @field #OPSGROUP.Element carrier Carrier the group is loaded into as cargo. -- @field #OPSGROUP.Element carrier Carrier the group is loaded into as cargo.
-- @field #OPSGROUP carrierGroup Carrier group transporting this group as cargo. -- @field #OPSGROUP carrierGroup Carrier group transporting this group as cargo.
-- @field #table cargoqueue Table containing cargo groups to be transported. -- @field #table cargoqueue Table containing cargo groups to be transported.
-- @field #table cargoBay Table containing OPSGROUP loaded into this group.
-- @field #OPSGROUP.CargoTransport cargoTransport Current cargo transport assignment. -- @field #OPSGROUP.CargoTransport cargoTransport Current cargo transport assignment.
-- @field #string cargoStatus Cargo status of this group acting as cargo. -- @field #string cargoStatus Cargo status of this group acting as cargo.
-- @field #string carrierStatus Carrier status of this group acting as cargo carrier. -- @field #string carrierStatus Carrier status of this group acting as cargo carrier.
@ -158,6 +164,7 @@ OPSGROUP = {
Nkills = 0, Nkills = 0,
weaponData = {}, weaponData = {},
cargoqueue = {}, cargoqueue = {},
cargoBay = {},
} }
@ -396,11 +403,23 @@ OPSGROUP.CargoStatus={
DELIVERED="delivered", DELIVERED="delivered",
} }
--- Cargo transport status.
-- @type OPSGROUP.TransportStatus
-- @field #string PLANNING Planning state.
-- @field #string SCHEDULED Transport is scheduled in the cargo queue.
-- @field #string EXECUTING Transport is being executed.
-- @field #string DELIVERED Transport was delivered.
OPSGROUP.TransportStatus={
PLANNING="planning",
SCHEDULED="scheduled",
EXECUTING="executing",
DELIVERED="delivered",
}
--- Cargo transport data. --- Cargo transport data.
-- @type OPSGROUP.CargoTransport -- @type OPSGROUP.CargoTransport
-- @field #table cargos Cargos. Each element is a @{#OPSGROUP.Cargo}. -- @field #table cargos Cargos. Each element is a @{#OPSGROUP.Cargo}.
-- @field #string status Status of the carrier. See @{#OPSGROUP.CarrierStatus}. -- @field #string status Status of the transport. See @{#OPSGROUP.TransportStatus}.
-- @field #number prio Priority of this transport. Should be a number between 0 (high prio) and 100 (low prio). -- @field #number prio Priority of this transport. Should be a number between 0 (high prio) and 100 (low prio).
-- @field #number importance Importance of this transport. Smaller=higher. -- @field #number importance Importance of this transport. Smaller=higher.
-- @field #number Tstart Start time in abs. seconds. -- @field #number Tstart Start time in abs. seconds.
@ -408,6 +427,7 @@ OPSGROUP.CargoStatus={
-- @field Core.Zone#ZONE deployzone Zone where the cargo is dropped off. -- @field Core.Zone#ZONE deployzone Zone where the cargo is dropped off.
-- @field Core.Zone#ZONE embarkzone (Optional) Zone where the cargo is supposed to embark. Default is the pickup zone. -- @field Core.Zone#ZONE embarkzone (Optional) Zone where the cargo is supposed to embark. Default is the pickup zone.
-- @field Core.Zone#ZONE disembarkzone (Optional) Zone where the cargo is disembarked. Default is the deploy zone. -- @field Core.Zone#ZONE disembarkzone (Optional) Zone where the cargo is disembarked. Default is the deploy zone.
-- @field #OPSGROUP carrierGroup The new carrier group.
--- Cargo group data. --- Cargo group data.
-- @type OPSGROUP.CargoGroup -- @type OPSGROUP.CargoGroup
@ -1420,6 +1440,27 @@ function OPSGROUP:SelfDestruction(Delay, ExplosionPower)
end end
--- Check if this is a FLIGHTGROUP.
-- @param #OPSGROUP self
-- @return #boolean If true, this is an airplane or helo group.
function OPSGROUP:IsFlightgroup()
return self.isFlightgroup
end
--- Check if this is a ARMYGROUP.
-- @param #OPSGROUP self
-- @return #boolean If true, this is a ground group.
function OPSGROUP:IsArmygroup()
return self.isArmygroup
end
--- Check if this is a NAVYGROUP.
-- @param #OPSGROUP self
-- @return #boolean If true, this is a ship group.
function OPSGROUP:IsNavygroup()
return self.isNavygroup
end
--- Check if group is exists. --- Check if group is exists.
-- @param #OPSGROUP self -- @param #OPSGROUP self
@ -2076,13 +2117,18 @@ function OPSGROUP:OnEventBirth(EventData)
-- Set homebase if not already set. -- Set homebase if not already set.
if self.isFlightgroup then if self.isFlightgroup then
if EventData.Place then if EventData.Place then
self.homebase=self.homebase or EventData.Place self.homebase=self.homebase or EventData.Place
self.currbase=EventData.Place
else
self.currbase=nil
end end
if self.homebase and not self.destbase then if self.homebase and not self.destbase then
self.destbase=self.homebase self.destbase=self.homebase
end end
self:T(self.lid..string.format("EVENT: Element %s born at airbase %s==> spawned", unitname, self.homebase and self.homebase:GetName() or "unknown")) self:T(self.lid..string.format("EVENT: Element %s born at airbase %s==> spawned", unitname, self.homebase and self.homebase:GetName() or "unknown"))
else else
self:T3(self.lid..string.format("EVENT: Element %s born ==> spawned", unitname)) self:T3(self.lid..string.format("EVENT: Element %s born ==> spawned", unitname))
@ -2929,6 +2975,28 @@ function OPSGROUP:CountRemainingMissison()
return N return N
end end
--- Count remaining cargo transport assignments.
-- @param #OPSGROUP self
-- @return #number Number of unfinished transports in the queue.
function OPSGROUP:CountRemainingTransports()
local N=0
-- Loop over mission queue.
for _,_transport in pairs(self.cargoqueue) do
local transport=_transport --#OPSGROUP.CargoTransport
-- Count not delivered (executing or scheduled) assignments.
if transport and transport.status~=OPSGROUP.TransportStatus.DELIVERED then
N=N+1
end
end
return N
end
--- Get next mission. --- Get next mission.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @return Ops.Auftrag#AUFTRAG Next mission or *nil*. -- @return Ops.Auftrag#AUFTRAG Next mission or *nil*.
@ -4485,6 +4553,31 @@ function OPSGROUP:_CheckCargoTransport()
-- Abs. missin time in seconds. -- Abs. missin time in seconds.
local Time=timer.getAbsTime() local Time=timer.getAbsTime()
-- Cargo queue info.
local text="Cargo bay:"
for cargogroupname, carriername in pairs(self.cargoBay) do
text=text..string.format("\n- %s in carrier %s", tostring(cargogroupname), tostring(carriername))
end
self:I(self.lid..text)
-- Cargo queue info.
local text="Cargo queue:"
for i,_transport in pairs(self.cargoqueue) do
local transport=_transport --#OPSGROUP.CargoTransport
text=text..string.format("\n[%d] UID=%d Status=%s: %s --> %s", i, transport.uid, transport.status, transport.pickupzone:GetName(), transport.deployzone:GetName())
for j,_cargo in pairs(transport.cargos) do
local cargo=_cargo --#OPSGROUP.CargoGroup
local state=cargo.opsgroup:GetState()
local status=cargo.opsgroup.cargoStatus
local name=cargo.opsgroup.groupname
local carriergroup=cargo.opsgroup.carrierGroup and cargo.opsgroup.carrierGroup.groupname or "N/A"
local carrierelement=cargo.opsgroup.carrier and cargo.opsgroup.carrier.name or "N/A"
text=text..string.format("\n (%d) %s [%s]: %s, carrier=%s(%s), delivered=%s", j, name, state, status, carriergroup, carrierelement, tostring(cargo.delivered))
end
end
self:I(self.lid..text)
if self.cargoTransport then if self.cargoTransport then
-- TODO: Check if this group can actually transport any cargo. -- TODO: Check if this group can actually transport any cargo.
@ -4505,7 +4598,7 @@ function OPSGROUP:_CheckCargoTransport()
end end
if done then if done then
self.cargoTransport.status="Delivered" self.cargoTransport.status=OPSGROUP.TransportStatus.DELIVERED
end end
end end
@ -4539,7 +4632,8 @@ function OPSGROUP:_CheckCargoTransport()
for _,_cargotransport in pairs(self.cargoqueue) do for _,_cargotransport in pairs(self.cargoqueue) do
local cargotransport=_cargotransport --#OPSGROUP.CargoTransport local cargotransport=_cargotransport --#OPSGROUP.CargoTransport
if Time>=cargotransport.Tstart and cargotransport.status~="Delivered" and (cargotransport.importance==nil or cargotransport.importance<=vip) then if Time>=cargotransport.Tstart and cargotransport.status==OPSGROUP.TransportStatus.SCHEDULED and (cargotransport.importance==nil or cargotransport.importance<=vip) then
cargotransport.status=OPSGROUP.TransportStatus.EXECUTING
self.cargoTransport=cargotransport self.cargoTransport=cargotransport
break break
end end
@ -4560,7 +4654,9 @@ function OPSGROUP:_CheckCargoTransport()
local gstatus=cargo.opsgroup:GetState() local gstatus=cargo.opsgroup:GetState()
local cstatus=cargo.opsgroup.cargoStatus local cstatus=cargo.opsgroup.cargoStatus
local weight=cargo.opsgroup:GetWeightTotal() local weight=cargo.opsgroup:GetWeightTotal()
text=text..string.format("\n- %s (%.1f kg) [%s]: %s delivered=%s", name, weight, gstatus, cstatus, tostring(cargo.delivered)) local carriername=cargo.opsgroup.carrier and cargo.opsgroup.carrier.name or "none"
local carriergroup=cargo.opsgroup.carrierGroup and cargo.opsgroup.carrierGroup.groupname or "none"
text=text..string.format("\n- %s (%.1f kg) [%s]: %s, carrier=%s (%s), delivered=%s", name, weight, gstatus, cstatus, carriername, carriergroup, tostring(cargo.delivered))
end end
self:I(self.lid..text) self:I(self.lid..text)
end end
@ -4577,13 +4673,15 @@ function OPSGROUP:_CheckCargoTransport()
elseif self:IsPickingup() then elseif self:IsPickingup() then
self:I(self.lid.."Picking up...") -- Debug Info.
self:T(self.lid.."Picking up...")
--TODO: Check if there is still cargo left. Maybe someone else already picked it up or it got destroyed. --TODO: Check if there is still cargo left. Maybe someone else already picked it up or it got destroyed.
elseif self:IsLoading() then elseif self:IsLoading() then
self:I(self.lid.."Loading...") self:I(self.lid.."Loading...")
self.Tloading=self.Tloading or Time
local boarding=false local boarding=false
local gotcargo=false local gotcargo=false
@ -4608,14 +4706,15 @@ function OPSGROUP:_CheckCargoTransport()
self:Loaded() self:Loaded()
end end
-- No cargo and noone is boarding ==> check again if we can make anyone board. -- No cargo and no one is boarding ==> check again if we can make anyone board.
if not gotcargo and not boarding then if not gotcargo and not boarding then
self:Loading() self:Loading()
end end
elseif self:IsTransporting() then elseif self:IsTransporting() then
self:I(self.lid.."Transporting (nothing to do)") -- Debug info.
self:T(self.lid.."Transporting (nothing to do)")
elseif self:IsUnloading() then elseif self:IsUnloading() then
@ -4642,6 +4741,8 @@ function OPSGROUP:_CheckCargoTransport()
end end
-- TODO: Remove delivered transports from cargo queue!
return self return self
end end
@ -4655,16 +4756,39 @@ end
-- @param #string ClockStart Start time in format "HH:MM(:SS)(+D)", e.g. "13:05:30" or "08:30+1". Can also be given as a `#number`, in which case it is interpreted as relative amount in seconds from now on. -- @param #string ClockStart Start time in format "HH:MM(:SS)(+D)", e.g. "13:05:30" or "08:30+1". Can also be given as a `#number`, in which case it is interpreted as relative amount in seconds from now on.
-- @param Core.Zone#ZONE Embarkzone (Optional) Zone where the cargo is going to be embarked into the transport. By default is goes to the assigned carrier unit. -- @param Core.Zone#ZONE Embarkzone (Optional) Zone where the cargo is going to be embarked into the transport. By default is goes to the assigned carrier unit.
-- @param Core.Zone#ZONE Disembarkzone (Optional) Zone where the cargo disembarks to (is spawned after unloaded). Default is anywhere in the deploy zone. -- @param Core.Zone#ZONE Disembarkzone (Optional) Zone where the cargo disembarks to (is spawned after unloaded). Default is anywhere in the deploy zone.
-- @param #OPSGROUP NewCarrierGroup (Optional) The OPSGROUP where the cargo is directly loaded into.
-- @return #OPSGROUP.CargoTransport Cargo transport. -- @return #OPSGROUP.CargoTransport Cargo transport.
function OPSGROUP:AddCargoTransport(GroupSet, Pickupzone, Deployzone, Prio, Importance, ClockStart, Embarkzone, Disembarkzone) function OPSGROUP:AddCargoTransport(GroupSet, Pickupzone, Deployzone, Prio, Importance, ClockStart, Embarkzone, Disembarkzone, NewCarrierGroup)
local cargotransport=self:CreateCargoTransport(GroupSet, Pickupzone, Deployzone, Prio, Importance, ClockStart, Embarkzone, Disembarkzone) -- Create a new cargo transport assignment.
local cargotransport=self:CreateCargoTransport(GroupSet, Pickupzone, Deployzone, Prio, Importance, ClockStart, Embarkzone, Disembarkzone, NewCarrierGroup)
-- Set state to SCHEDULED.
cargotransport.status=OPSGROUP.TransportStatus.SCHEDULED
--Add to cargo queue
table.insert(self.cargoqueue, cargotransport) table.insert(self.cargoqueue, cargotransport)
return cargotransport return cargotransport
end end
--- Delete a cargo transport assignment from the cargo queue
-- @param #OPSGROUP self
-- @param #OPSGROUP.CargoTransport CargoTransport Cargo transport do be deleted.
-- @return #OPSGROUP self
function OPSGROUP:DelCargoTransport(CargoTransport)
for i,_transport in pairs(self.cargoqueue) do
local transport=_transport --#OPSGROUP.CargoTransport
if transport.uid==CargoTransport.uid then
table.remove(self.cargoqueue, i)
return self
end
end
return self
end
--- Create a cargo transport assignment. --- Create a cargo transport assignment.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @param Core.Set#SET_GROUP GroupSet Set of groups to be transported. Can also be a single @{Wrapper.Group#GROUP} or @{Ops.OpsGroup#OPSGROUP} object. -- @param Core.Set#SET_GROUP GroupSet Set of groups to be transported. Can also be a single @{Wrapper.Group#GROUP} or @{Ops.OpsGroup#OPSGROUP} object.
@ -4675,8 +4799,9 @@ end
-- @param #string ClockStart Start time in format "HH:MM:SS+D", e.g. "13:05:30" or "08:30+1". Can also be passed as a `#number` in which case it is interpreted as relative amount in seconds from now on. -- @param #string ClockStart Start time in format "HH:MM:SS+D", e.g. "13:05:30" or "08:30+1". Can also be passed as a `#number` in which case it is interpreted as relative amount in seconds from now on.
-- @param Core.Zone#ZONE Embarkzone (Optional) Zone where the cargo is going to be embarked into the transport. By default is goes to the assigned carrier unit. -- @param Core.Zone#ZONE Embarkzone (Optional) Zone where the cargo is going to be embarked into the transport. By default is goes to the assigned carrier unit.
-- @param Core.Zone#ZONE Disembarkzone (Optional) Zone where the cargo disembarks to (is spawned after unloaded). Default is anywhere in the deploy zone. -- @param Core.Zone#ZONE Disembarkzone (Optional) Zone where the cargo disembarks to (is spawned after unloaded). Default is anywhere in the deploy zone.
-- @param #OPSGROUP NewCarrierGroup (Optional) The OPSGROUP where the cargo is directly loaded into.
-- @return #OPSGROUP.CargoTransport Cargo transport. -- @return #OPSGROUP.CargoTransport Cargo transport.
function OPSGROUP:CreateCargoTransport(GroupSet, Pickupzone, Deployzone, Prio, Importance, ClockStart, Embarkzone, Disembarkzone) function OPSGROUP:CreateCargoTransport(GroupSet, Pickupzone, Deployzone, Prio, Importance, ClockStart, Embarkzone, Disembarkzone, NewCarrierGroup)
-- Current mission time. -- Current mission time.
local Tnow=timer.getAbsTime() local Tnow=timer.getAbsTime()
@ -4691,15 +4816,16 @@ function OPSGROUP:CreateCargoTransport(GroupSet, Pickupzone, Deployzone, Prio, I
-- Data structure. -- Data structure.
local transport={} --#OPSGROUP.CargoTransport local transport={} --#OPSGROUP.CargoTransport
transport.uid=1
transport.status=OPSGROUP.TransportStatus.PLANNING
transport.pickupzone=Pickupzone transport.pickupzone=Pickupzone
transport.deployzone=Deployzone transport.deployzone=Deployzone
transport.uid=1
transport.status="Planning"
transport.embarkzone=Embarkzone or Pickupzone transport.embarkzone=Embarkzone or Pickupzone
transport.disembarkzone=Disembarkzone or Deployzone transport.disembarkzone=Disembarkzone or Deployzone
transport.prio=Prio or 50 transport.prio=Prio or 50
transport.importance=Importance transport.importance=Importance
transport.Tstart=Tstart transport.Tstart=Tstart
transport.carrierGroup=NewCarrierGroup
transport.cargos={} transport.cargos={}
-- Check type of GroupSet provided. -- Check type of GroupSet provided.
@ -4795,6 +4921,26 @@ function OPSGROUP:GetWeightTotal(UnitName)
return weight return weight
end end
--- Get free cargo bay weight.
-- @param #OPSGROUP self
-- @param #string UnitName Name of the unit. Default is of the whole group.
-- @return #number Total weight in kg.
function OPSGROUP:GetFreeCargobay(UnitName)
local Free=0
for _,_element in pairs(self.elements) do
local element=_element --#OPSGROUP.Element
if (UnitName==nil or UnitName==element.name) and element.status~=OPSGROUP.ElementStatus.DEAD then
local free=element.weightMaxCargo-element.weightCargo
Free=Free+free
end
end
return Free
end
--- Get weight of the internal cargo the group is carriing right now. --- Get weight of the internal cargo the group is carriing right now.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @param #string UnitName Name of the unit. Default is of the whole group. -- @param #string UnitName Name of the unit. Default is of the whole group.
@ -4851,6 +4997,24 @@ function OPSGROUP:RedWeightCargo(UnitName, Weight)
return self return self
end end
--- Add weight to the internal cargo of an element of the group.
-- @param #OPSGROUP self
-- @param #OPSGROUP CargoGroup Cargo group, which needs a carrier.
-- @return #OPSGROUP.Element Carrier able to transport the cargo.
function OPSGROUP:FindCarrierForCargo(CargoGroup)
local weight=CargoGroup:GetWeightTotal()
for _,element in pairs(self.elements) do
local free=self:GetFreeCargobay(element.name)
if free>=weight then
return element
end
end
return nil
end
--- On after "Pickup" event. --- On after "Pickup" event.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @param #string From From state. -- @param #string From From state.
@ -4867,7 +5031,26 @@ function OPSGROUP:onafterPickup(From, Event, To, Zone)
-- Check if already in the pickup zone. -- Check if already in the pickup zone.
local inzone=Zone:IsCoordinateInZone(self:GetCoordinate()) local inzone=Zone:IsCoordinateInZone(self:GetCoordinate())
if inzone then local airbasePickup=nil --Wrapper.Airbase#AIRBASE
if Zone and Zone:IsInstanceOf("ZONE_AIRBASE") then
airbasePickup=Zone:GetAirbase()
end
-- Check if group is already ready for loading.
local ready4loading=false
if self:IsArmygroup() or self:IsNavygroup() then
ready4loading=inzone
else
-- Aircraft is already parking at the pickup airbase.
ready4loading=self.currbase and self.currbase:GetName()==Zone:GetName() and self:IsParking()
-- If a helo is landed in the zone, we also are ready for loading.
if ready4loading==false and self.isHelo and self:IsLandedAt() and inzone then
ready4loading=true
end
end
if ready4loading then
-- We are already in the pickup zone ==> initiate loading. -- We are already in the pickup zone ==> initiate loading.
self:Loading() self:Loading()
@ -4879,12 +5062,40 @@ function OPSGROUP:onafterPickup(From, Event, To, Zone)
-- Add waypoint. -- Add waypoint.
if self.isFlightgroup then if self.isFlightgroup then
if self.isHelo then
---
-- Pickup at airbase
---
if airbasePickup then
local airbaseCurrent=self.currbase
if airbaseCurrent then
-- Activate uncontrolled group.
if self:IsParking() then
self:StartUncontrolled()
end
else
-- Order group to land at an airbase.
self:LandAtAirbase(airbasePickup)
end
elseif self.isHelo or self.isVTOL then
---
-- Helo or VTOL can also land in a zone
---
-- If this is a helo and no ZONE_AIRBASE was given, we make the helo land in the pickup zone.
Coordinate:SetAltitude(200) Coordinate:SetAltitude(200)
local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate) local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate)
waypoint.detour=true waypoint.detour=true
else else
--TODO: airplane! pickup at airbase. check if already at airbase or make plane go there. self:E(self.lid.."ERROR: Carrier aircraft cannot land in Pickup zone! Specify a ZONE_AIRBASE as pickup zone")
end end
elseif self.isNavygroup then elseif self.isNavygroup then
local waypoint=NAVYGROUP.AddWaypoint(self, Coordinate) local waypoint=NAVYGROUP.AddWaypoint(self, Coordinate)
@ -4910,6 +5121,9 @@ function OPSGROUP:onafterLoading(From, Event, To)
-- Set carrier status. -- Set carrier status.
self.carrierStatus=OPSGROUP.CarrierStatus.LOADING self.carrierStatus=OPSGROUP.CarrierStatus.LOADING
-- Loading time stamp.
self.Tloading=timer.getAbsTime()
-- Create a temp array and monitor the free cargo space for each element. -- Create a temp array and monitor the free cargo space for each element.
local cargobay={} local cargobay={}
for _,_element in pairs(self.elements) do for _,_element in pairs(self.elements) do
@ -4934,8 +5148,6 @@ function OPSGROUP:onafterLoading(From, Event, To)
for _,_cargo in pairs(self.cargoTransport.cargos) do for _,_cargo in pairs(self.cargoTransport.cargos) do
local cargo=_cargo --#OPSGROUP.CargoGroup local cargo=_cargo --#OPSGROUP.CargoGroup
env.info("FF trying cargo!")
if cargo.opsgroup:IsNotCargo() and not cargo.delivered then if cargo.opsgroup:IsNotCargo() and not cargo.delivered then
-- Check if cargo is in pickup zone. -- Check if cargo is in pickup zone.
@ -4944,16 +5156,12 @@ function OPSGROUP:onafterLoading(From, Event, To)
-- First check if cargo is not delivered yet. -- First check if cargo is not delivered yet.
if inzone then if inzone then
env.info("FF trying cargo 2!")
local weight=cargo.opsgroup:GetWeightTotal() local weight=cargo.opsgroup:GetWeightTotal()
local carrier=_findCarrier(weight) local carrier=_findCarrier(weight)
if carrier then if carrier then
env.info("FF trying cargo3!")
-- Decrease free cargo bay. -- Decrease free cargo bay.
cargobay[carrier.name]=cargobay[carrier.name]-weight cargobay[carrier.name]=cargobay[carrier.name]-weight
@ -4961,7 +5169,6 @@ function OPSGROUP:onafterLoading(From, Event, To)
cargo.opsgroup.cargoStatus=OPSGROUP.CargoStatus.ASSIGNED cargo.opsgroup.cargoStatus=OPSGROUP.CargoStatus.ASSIGNED
-- Order cargo group to board the carrier. -- Order cargo group to board the carrier.
env.info("FF order group to board carrier")
cargo.opsgroup:Board(self, carrier) cargo.opsgroup:Board(self, carrier)
else else
@ -4975,7 +5182,13 @@ function OPSGROUP:onafterLoading(From, Event, To)
end end
else else
env.info("FF cargo already cargo or delivered") env.info("FF cargo already cargo or delivered")
if not cargo.delivered then
end
end end
end end
@ -4988,21 +5201,33 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
-- @param #OPSGROUP CargoGroup The OPSGROUP loaded as cargo. -- @param #OPSGROUP CargoGroup The OPSGROUP loaded as cargo.
function OPSGROUP:onafterLoad(From, Event, To, CargoGroup) -- @param #OPSGROUP.Element Carrier The carrier element/unit.
env.info("FF load") function OPSGROUP:onafterLoad(From, Event, To, CargoGroup, Carrier)
-- Debug info.
self:I(self.lid..string.format("Loading group %s", tostring(CargoGroup.groupname)))
local weight=CargoGroup:GetWeightTotal() -- Carrier element.
local carrier=Carrier or CargoGroup.carrier --#OPSGROUP.Element
local carrier=CargoGroup.carrier
-- No carrier provided.
if not carrier then
-- Try to find a carrier manually.
carrier=self:FindCarrierForCargo(CargoGroup)
end
if carrier then if carrier then
-- Cargo weight.
local weight=CargoGroup:GetWeightTotal()
-- Add weight to carrier. -- Add weight to carrier.
self:AddWeightCargo(carrier.name, weight) self:AddWeightCargo(carrier.name, weight)
-- Embark ==> Loaded -- Fill cargo bay.
CargoGroup:Embark(carrier) self.cargoBay[CargoGroup.groupname]=carrier.name
-- Embark ==> Loaded.
CargoGroup:Embark(self, carrier)
else else
self:E(self.lid.."ERROR: Cargo has no carrier on Load event!") self:E(self.lid.."ERROR: Cargo has no carrier on Load event!")
@ -5042,9 +5267,30 @@ function OPSGROUP:onafterTransport(From, Event, To, Zone)
-- Set carrier status. -- Set carrier status.
self.carrierStatus=OPSGROUP.CarrierStatus.TRANSPORTING self.carrierStatus=OPSGROUP.CarrierStatus.TRANSPORTING
--TODO: This is all very similar to the onafterPickup() function. Could make it general.
-- Check if already in deploy zone. -- Check if already in deploy zone.
local inzone=Zone:IsCoordinateInZone(self:GetCoordinate()) local inzone=Zone:IsCoordinateInZone(self:GetCoordinate())
local airbaseDeploy=nil --Wrapper.Airbase#AIRBASE
if Zone and Zone:IsInstanceOf("ZONE_AIRBASE") then
airbaseDeploy=Zone:GetAirbase()
end
-- Check if group is already ready for loading.
local ready2deploy=false
if self:IsArmygroup() or self:IsNavygroup() then
ready2deploy=inzone
else
-- Aircraft is already parking at the pickup airbase.
ready2deploy=self.currbase and self.currbase:GetName()==Zone:GetName() and self:IsParking()
-- If a helo is landed in the zone, we also are ready for loading.
if ready2deploy==false and self.isHelo and self:IsLandedAt() and inzone then
ready2deploy=true
end
end
if inzone then if inzone then
-- We are already in the pickup zone ==> initiate loading. -- We are already in the pickup zone ==> initiate loading.
@ -5052,27 +5298,59 @@ function OPSGROUP:onafterTransport(From, Event, To, Zone)
else else
-- Get a random coordinate in the pickup zone and let the carrier go there. -- Get a random coordinate in the deploy zone and let the carrier go there.
local Coordinate=Zone:GetRandomCoordinate() local Coordinate=Zone:GetRandomCoordinate()
-- Set waypoint. -- Add waypoint.
if self.isFlightgroup then if self.isFlightgroup then
-- FLIGHTGROUP
if self.isHelo then ---
Coordinate:SetAltitude(200) -- Deploy at airbase
local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate, Speed, AfterWaypointWithID, Altitude, Updateroute) ---
waypoint.detour=true
else if airbaseDeploy then
-- TODO: airplane! let plane fly to airbase.
local airbaseCurrent=self.currbase
if airbaseCurrent then
-- Activate uncontrolled group.
if self:IsParking() then
self:StartUncontrolled()
end end
elseif self.isArmygroup then
-- ARMYGROUP else
local waypoint=ARMYGROUP.AddWaypoint(self, Coordinate, Speed, AfterWaypointWithID, Formation, Updateroute) -- Order group to land at an airbase.
self:LandAtAirbase(airbaseDeploy)
end
elseif self.isHelo or self.isVTOL then
---
-- Helo or VTOL can also land in a zone
---
-- If this is a helo and no ZONE_AIRBASE was given, we make the helo land in the pickup zone.
Coordinate:SetAltitude(200)
local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate)
waypoint.detour=true waypoint.detour=true
else
self:E(self.lid.."ERROR: Carrier aircraft cannot land in Deploy zone! Specify a ZONE_AIRBASE as deploy zone")
end
elseif self.isArmygroup then
-- ARMYGROUP
local waypoint=ARMYGROUP.AddWaypoint(self, Coordinate)
waypoint.detour=true
elseif self.isNavygroup then elseif self.isNavygroup then
-- NAVYGROUP -- NAVYGROUP
local waypoint=NAVYGROUP.AddWaypoint(self, Coordinate) local waypoint=NAVYGROUP.AddWaypoint(self, Coordinate)
waypoint.detour=true waypoint.detour=true
end end
end end
@ -5100,21 +5378,42 @@ function OPSGROUP:onafterDeploy(From, Event, To, Zone)
env.info("FF deploy cargo "..cargo.opsgroup:GetName()) env.info("FF deploy cargo "..cargo.opsgroup:GetName())
-- Deploy or disembark zone.
local zone=Zone or self.cargoTransport.disembarkzone --Core.Zone#ZONE local zone=Zone or self.cargoTransport.disembarkzone --Core.Zone#ZONE
--if zone:IsCoordinateInZone(self:GetCoordinate()) then -- New carrier group.
local carrierGroup=self.cargoTransport.carrierGroup
-- Cargo was delivered (somehow).
cargo.delivered=true
if carrierGroup then
local carrier=carrierGroup:FindCarrierForCargo(cargo.opsgroup)
if carrier then
self:Unload(cargo.opsgroup)
carrierGroup:Load(cargo.opsgroup, carrier)
else
env.info("ERROR: No element of the group can take this cargo!")
end
elseif zone:IsInstanceOf("ZONE_AIRBASE") and zone:GetAirbase():IsShip() then
--
env.info("ERROR: Deploy/disembark zone is a ZONE_AIRBASE of a ship! Where to put the cargo? Dumping into the sea, sorry!")
else
-- Random coordinate in
local Coordinate=zone:GetRandomCoordinate() local Coordinate=zone:GetRandomCoordinate()
local Heading=math.random(0,359) local Heading=math.random(0,359)
-- Cargo was delivered.
cargo.delivered=true
-- Unload. -- Unload.
env.info("FF unload cargo "..cargo.opsgroup:GetName()) env.info("FF unload cargo "..cargo.opsgroup:GetName())
self:Unload(cargo.opsgroup, Coordinate, Heading) self:Unload(cargo.opsgroup, Coordinate, Heading)
--end end
end end
@ -5122,6 +5421,19 @@ function OPSGROUP:onafterDeploy(From, Event, To, Zone)
end end
--- On before "Unload" event.
-- @param #OPSGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #OPSGROUP OpsGroup The OPSGROUP loaded as cargo.
-- @param Core.Point#COORDINATE Coordinate Coordinate were the group is unloaded to.
-- @param #number Heading Heading of group.
function OPSGROUP:onbeforeUnload(From, Event, To, OpsGroup, Coordinate, Heading)
--TODO: Add check if CargoGroup is cargo of this carrier.
return true
end
--- On after "Unload" event. Carrier unloads a cargo group from its cargo bay. --- On after "Unload" event. Carrier unloads a cargo group from its cargo bay.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @param #string From From state. -- @param #string From From state.
@ -5132,9 +5444,33 @@ end
-- @param #number Heading Heading of group. -- @param #number Heading Heading of group.
function OPSGROUP:onafterUnload(From, Event, To, OpsGroup, Coordinate, Heading) function OPSGROUP:onafterUnload(From, Event, To, OpsGroup, Coordinate, Heading)
--TODO: Add check if CargoGroup is cargo of this carrier. -- Not in cargo bay any more.
if OpsGroup:IsInUtero() then self.cargoBay[OpsGroup.groupname]=nil
if Coordinate then
---
-- Respawn at a coordinate.
---
OpsGroup:Unboard(Coordinate, Heading) OpsGroup:Unboard(Coordinate, Heading)
else
---
-- Just remove from this carrier.
---
-- Set cargo status.
OpsGroup.cargoStatus=OPSGROUP.CargoStatus.NOTCARGO
-- Reduce carrier weight.
local weight=OpsGroup:GetWeightTotal()
self:RedWeightCargo(OpsGroup.carrier.name, weight)
-- No carrier.
OpsGroup.carrier=nil
OpsGroup.carrierGroup=nil
end end
end end
@ -5146,7 +5482,8 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param Core.Zone#ZONE Zone Deploy zone. -- @param Core.Zone#ZONE Zone Deploy zone.
function OPSGROUP:onafterUnloaded(From, Event, To) function OPSGROUP:onafterUnloaded(From, Event, To)
env.info("FF unloaded") -- Debug info
self:I(self.lid.."Cargo unloaded..")
-- Cancel landedAt task. -- Cancel landedAt task.
if self.isFlightgroup and self:IsLandedAt() then if self.isFlightgroup and self:IsLandedAt() then
@ -5154,6 +5491,7 @@ function OPSGROUP:onafterUnloaded(From, Event, To)
self:TaskCancel(Task) self:TaskCancel(Task)
end end
-- Check if there is still cargo to pickup.
local pickup=false local pickup=false
for _,_cargo in pairs(self.cargoTransport.cargos) do for _,_cargo in pairs(self.cargoTransport.cargos) do
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
@ -5169,15 +5507,30 @@ function OPSGROUP:onafterUnloaded(From, Event, To)
if pickup then if pickup then
env.info("FF cargo left ==> pickup") -- Pickup the next batch.
self:I(self.lid.."Still cargo left ==> pickup")
self:Pickup(self.cargoTransport.pickupzone) self:Pickup(self.cargoTransport.pickupzone)
else else
-- Debug info.
self:I(self.lid..string.format("New carrier status %s --> %s", self.carrierStatus, OPSGROUP.CarrierStatus.NOTCARRIER))
-- This is not a carrier anymore.
self.carrierStatus=OPSGROUP.CarrierStatus.NOTCARRIER
-- No current transport assignment. -- No current transport assignment.
self.cargoTransport=nil self.cargoTransport=nil
env.info("FF all delivered ==> check group done") -- Startup uncontrolled aircraft to allow it to go back.
if self:IsFlightgroup() then
if self:IsUncontrolled() then
self:StartUncontrolled()
end
end
-- Check group done.
self:I(self.lid.."All cargo delivered ==> check group done")
self:_CheckGroupDone(0.1) self:_CheckGroupDone(0.1)
end end
@ -5238,8 +5591,9 @@ end
-- @param #string From From state. -- @param #string From From state.
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
-- @param #OPSGROUP.Element Carrier The OPSGROUP element -- @param #OPSGROUP CarrierGroup The carrier OPSGROUP.
function OPSGROUP:onafterEmbark(From, Event, To, Carrier) -- @param #OPSGROUP.Element Carrier The OPSGROUP element carriing this group.
function OPSGROUP:onafterEmbark(From, Event, To, CarrierGroup, Carrier)
-- Debug info. -- Debug info.
self:I(self.lid..string.format("New cargo status %s --> %s", self.cargoStatus, OPSGROUP.CargoStatus.LOADED)) self:I(self.lid..string.format("New cargo status %s --> %s", self.cargoStatus, OPSGROUP.CargoStatus.LOADED))
@ -5252,11 +5606,14 @@ function OPSGROUP:onafterEmbark(From, Event, To, Carrier)
end end
self.waypoints={} self.waypoints={}
-- Despawn this group.
self:Despawn(0, true)
-- Set carrier (again). -- Set carrier (again).
self.carrier=Carrier self.carrier=Carrier
self.carrierGroup=CarrierGroup
-- Despawn this group.
if self:IsAlive() then
self:Despawn(0, true)
end
end end
@ -5267,10 +5624,21 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param Core.Point#COORDINATE Coordinate Coordinate were the group is unloaded to. Can also be a DCS#Vec3 object. -- @param Core.Point#COORDINATE Coordinate Coordinate were the group is unloaded to. Can also be a DCS#Vec3 object.
-- @param #number Heading Heading the group has in degrees. Default is last known heading of the group. -- @param #number Heading Heading the group has in degrees. Default is last known heading of the group.
function OPSGROUP:onafterUnboard(From, Event, To, Coordinate, Heading) -- @param #number Delay Delay in seconds, before the group is respawned.
function OPSGROUP:onafterUnboard(From, Event, To, Coordinate, Heading, Delay)
-- Debug info. -- Debug info.
self:I(self.lid..string.format("New cargo status %s --> %s", self.cargoStatus, OPSGROUP.CargoStatus.NOTCARGO)) self:I(self.lid..string.format("New cargo status %s --> %s", self.cargoStatus, OPSGROUP.CargoStatus.NOTCARGO))
-- Set cargo status.
self.cargoStatus=OPSGROUP.CargoStatus.NOTCARGO
-- Reduce carrier weight.
local weight=self:GetWeightTotal()
self.carrierGroup:RedWeightCargo(self.carrier.name, weight)
-- No carrier.
self.carrier=nil
self.carrierGroup=nil
-- Template for the respawned group. -- Template for the respawned group.
local Template=UTILS.DeepCopy(self.template) --DCS#Template local Template=UTILS.DeepCopy(self.template) --DCS#Template
@ -5302,17 +5670,8 @@ function OPSGROUP:onafterUnboard(From, Event, To, Coordinate, Heading)
end end
-- Reduce carrier weight.
local weight=self:GetWeightTotal()
self.carrierGroup:RedWeightCargo(self.carrier.name, weight)
-- Set cargo status.
self.cargoStatus=OPSGROUP.CargoStatus.NOTCARGO
self.carrier=nil
self.carrierGroup=nil
-- Respawn group. -- Respawn group.
self:_Respawn(0, Template) self:_Respawn(Delay or 0, Template)
end end
@ -5522,7 +5881,9 @@ function OPSGROUP:_CheckGroupDone(delay)
local speed=self:GetSpeedToWaypoint(i) local speed=self:GetSpeedToWaypoint(i)
-- Start route at first waypoint. -- Start route at first waypoint.
self:UpdateRoute(i, speed) --self:UpdateRoute(i, speed)
self:Cruise(speed)
self:T(self.lid..string.format("Adinfinitum=TRUE ==> Goto WP index=%d at speed=%d knots", i, speed)) self:T(self.lid..string.format("Adinfinitum=TRUE ==> Goto WP index=%d at speed=%d knots", i, speed))
@ -5556,7 +5917,8 @@ function OPSGROUP:_CheckGroupDone(delay)
if #self.waypoints>0 then if #self.waypoints>0 then
self:T(self.lid..string.format("NOT Passed final WP, #WP>0 ==> Update Route")) self:T(self.lid..string.format("NOT Passed final WP, #WP>0 ==> Update Route"))
self:UpdateRoute() --self:UpdateRoute()
self:Cruise()
else else
self:E(self.lid..string.format("WARNING: No waypoints left! Commanding a Full Stop")) self:E(self.lid..string.format("WARNING: No waypoints left! Commanding a Full Stop"))
self:__FullStop(-1) self:__FullStop(-1)