mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
commit
1337815f05
@ -1517,6 +1517,36 @@ function FLIGHTGROUP:Status()
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- Track flight
|
||||||
|
---
|
||||||
|
if false then
|
||||||
|
|
||||||
|
for _,_element in pairs(self.elements) do
|
||||||
|
local element=_element --Ops.OpsGroup#OPSGROUP.Element
|
||||||
|
|
||||||
|
local unit=element.unit
|
||||||
|
|
||||||
|
if unit and unit:IsAlive() then
|
||||||
|
|
||||||
|
local vec3=unit:GetVec3()
|
||||||
|
|
||||||
|
if vec3 and element.pos then
|
||||||
|
|
||||||
|
local id=UTILS.GetMarkID()
|
||||||
|
|
||||||
|
trigger.action.lineToAll(-1, id, vec3, element.pos, {1,1,1,0.5}, 1)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
element.pos=vec3
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Fuel State
|
-- Fuel State
|
||||||
---
|
---
|
||||||
|
|||||||
@ -489,11 +489,17 @@ OPSGROUP.CargoStatus={
|
|||||||
--- Element cargo bay data.
|
--- Element cargo bay data.
|
||||||
-- @type OPSGROUP.MyCargo
|
-- @type OPSGROUP.MyCargo
|
||||||
-- @field #OPSGROUP group The cargo group.
|
-- @field #OPSGROUP group The cargo group.
|
||||||
|
-- @field #number storageType Type of storage.
|
||||||
|
-- @field #number storageAmount Amount of storage.
|
||||||
|
-- @field #number storageWeight Weight of storage item.
|
||||||
-- @field #boolean reserved If `true`, the cargo bay space is reserved but cargo has not actually been loaded yet.
|
-- @field #boolean reserved If `true`, the cargo bay space is reserved but cargo has not actually been loaded yet.
|
||||||
|
|
||||||
--- Cargo group data.
|
--- Cargo group data.
|
||||||
-- @type OPSGROUP.CargoGroup
|
-- @type OPSGROUP.CargoGroup
|
||||||
|
-- @field #number uid Unique ID of this cargo data.
|
||||||
|
-- @field #string type Type of cargo: "OPSGROUP" or "STORAGE".
|
||||||
-- @field #OPSGROUP opsgroup The cargo opsgroup.
|
-- @field #OPSGROUP opsgroup The cargo opsgroup.
|
||||||
|
-- @field Ops.OpsTransport#OPSTRANSPORT.Storage storage Storage data.
|
||||||
-- @field #boolean delivered If `true`, group was delivered.
|
-- @field #boolean delivered If `true`, group was delivered.
|
||||||
-- @field #boolean disembarkActivation If `true`, group is activated. If `false`, group is late activated.
|
-- @field #boolean disembarkActivation If `true`, group is activated. If `false`, group is late activated.
|
||||||
-- @field Core.Zone#ZONE disembarkZone Zone where this group is disembarked to.
|
-- @field Core.Zone#ZONE disembarkZone Zone where this group is disembarked to.
|
||||||
@ -2268,22 +2274,27 @@ end
|
|||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #number Delay Delay in seconds. Default now.
|
-- @param #number Delay Delay in seconds. Default now.
|
||||||
-- @param #number ExplosionPower (Optional) Explosion power in kg TNT. Default 100 kg.
|
-- @param #number ExplosionPower (Optional) Explosion power in kg TNT. Default 100 kg.
|
||||||
|
-- @param #string ElementName Name of the element that should be destroyed. Default is all elements.
|
||||||
-- @return #OPSGROUP self
|
-- @return #OPSGROUP self
|
||||||
function OPSGROUP:SelfDestruction(Delay, ExplosionPower)
|
function OPSGROUP:SelfDestruction(Delay, ExplosionPower, ElementName)
|
||||||
|
|
||||||
if Delay and Delay>0 then
|
if Delay and Delay>0 then
|
||||||
self:ScheduleOnce(Delay, OPSGROUP.SelfDestruction, self, 0, ExplosionPower)
|
self:ScheduleOnce(Delay, OPSGROUP.SelfDestruction, self, 0, ExplosionPower, ElementName)
|
||||||
else
|
else
|
||||||
|
|
||||||
-- Loop over all elements.
|
-- Loop over all elements.
|
||||||
for i,_element in pairs(self.elements) do
|
for i,_element in pairs(self.elements) do
|
||||||
local element=_element --#OPSGROUP.Element
|
local element=_element --#OPSGROUP.Element
|
||||||
|
|
||||||
|
if ElementName==nil or ElementName==element.name then
|
||||||
|
|
||||||
local unit=element.unit
|
local unit=element.unit
|
||||||
|
|
||||||
if unit and unit:IsAlive() then
|
if unit and unit:IsAlive() then
|
||||||
unit:Explode(ExplosionPower or 100)
|
unit:Explode(ExplosionPower or 100)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -5452,10 +5463,10 @@ function OPSGROUP:onafterMissionExecute(From, Event, To, Mission)
|
|||||||
if self.isFlightgroup then
|
if self.isFlightgroup then
|
||||||
if Mission.prohibitABExecute == true then
|
if Mission.prohibitABExecute == true then
|
||||||
self:SetProhibitAfterburner()
|
self:SetProhibitAfterburner()
|
||||||
self:I("Set prohibit AB")
|
self:T(self.lid.."Set prohibit AB")
|
||||||
elseif Mission.prohibitABExecute == false then
|
elseif Mission.prohibitABExecute == false then
|
||||||
self:SetAllowAfterburner()
|
self:SetAllowAfterburner()
|
||||||
self:T2("Set allow AB")
|
self:T2(self.lid.."Set allow AB")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -7446,36 +7457,55 @@ function OPSGROUP:onafterElementDead(From, Event, To, Element)
|
|||||||
|
|
||||||
-- Clear cargo bay of element.
|
-- Clear cargo bay of element.
|
||||||
for i=#Element.cargoBay,1,-1 do
|
for i=#Element.cargoBay,1,-1 do
|
||||||
local cargo=Element.cargoBay[i] --#OPSGROUP.MyCargo
|
local mycargo=Element.cargoBay[i] --#OPSGROUP.MyCargo
|
||||||
|
|
||||||
|
if mycargo.group then
|
||||||
|
|
||||||
-- Remove from cargo bay.
|
-- Remove from cargo bay.
|
||||||
self:_DelCargobay(cargo.group)
|
self:_DelCargobay(mycargo.group)
|
||||||
|
|
||||||
if cargo.group and not (cargo.group:IsDead() or cargo.group:IsStopped()) then
|
if mycargo.group and not (mycargo.group:IsDead() or mycargo.group:IsStopped()) then
|
||||||
|
|
||||||
-- Remove my carrier
|
-- Remove my carrier
|
||||||
cargo.group:_RemoveMyCarrier()
|
mycargo.group:_RemoveMyCarrier()
|
||||||
|
|
||||||
if cargo.reserved then
|
if mycargo.reserved then
|
||||||
|
|
||||||
-- This group was not loaded yet ==> Not cargo any more.
|
-- This group was not loaded yet ==> Not cargo any more.
|
||||||
cargo.group:_NewCargoStatus(OPSGROUP.CargoStatus.NOTCARGO)
|
mycargo.group:_NewCargoStatus(OPSGROUP.CargoStatus.NOTCARGO)
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
-- Carrier dead ==> cargo dead.
|
-- Carrier dead ==> cargo dead.
|
||||||
for _,cargoelement in pairs(cargo.group.elements) do
|
for _,cargoelement in pairs(mycargo.group.elements) do
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T2(self.lid.."Cargo element dead "..cargoelement.name)
|
self:T2(self.lid.."Cargo element dead "..cargoelement.name)
|
||||||
|
|
||||||
-- Trigger dead event.
|
-- Trigger dead event.
|
||||||
cargo.group:ElementDead(cargoelement)
|
mycargo.group:ElementDead(cargoelement)
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Add cargo to lost.
|
||||||
|
if self.cargoTZC then
|
||||||
|
for _,_cargo in pairs(self.cargoTZC.Cargos) do
|
||||||
|
local cargo=_cargo --#OPSGROUP.CargoGroup
|
||||||
|
if cargo.uid==mycargo.cargoUID then
|
||||||
|
cargo.storage.cargoLost=cargo.storage.cargoLost+mycargo.storageAmount
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Remove cargo from cargo bay.
|
||||||
|
self:_DelCargobayElement(Element, mycargo)
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -7972,7 +8002,12 @@ function OPSGROUP:_CheckCargoTransport()
|
|||||||
local element=_element --#OPSGROUP.Element
|
local element=_element --#OPSGROUP.Element
|
||||||
for _,_cargo in pairs(element.cargoBay) do
|
for _,_cargo in pairs(element.cargoBay) do
|
||||||
local cargo=_cargo --#OPSGROUP.MyCargo
|
local cargo=_cargo --#OPSGROUP.MyCargo
|
||||||
|
if cargo.group then
|
||||||
text=text..string.format("\n- %s in carrier %s, reserved=%s", tostring(cargo.group:GetName()), tostring(element.name), tostring(cargo.reserved))
|
text=text..string.format("\n- %s in carrier %s, reserved=%s", tostring(cargo.group:GetName()), tostring(element.name), tostring(cargo.reserved))
|
||||||
|
else
|
||||||
|
text=text..string.format("\n- storage %s=%d kg in carrier %s [UID=%s]",
|
||||||
|
tostring(cargo.storageType), tostring(cargo.storageAmount*cargo.storageWeight), tostring(element.name), tostring(cargo.cargoUID))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if text=="" then
|
if text=="" then
|
||||||
@ -7993,6 +8028,7 @@ function OPSGROUP:_CheckCargoTransport()
|
|||||||
text=text..string.format("\n[%d] UID=%d Status=%s: %s --> %s", i, transport.uid, transport:GetState(), pickupname, deployname)
|
text=text..string.format("\n[%d] UID=%d Status=%s: %s --> %s", i, transport.uid, transport:GetState(), pickupname, deployname)
|
||||||
for j,_cargo in pairs(transport:GetCargos()) do
|
for j,_cargo in pairs(transport:GetCargos()) do
|
||||||
local cargo=_cargo --#OPSGROUP.CargoGroup
|
local cargo=_cargo --#OPSGROUP.CargoGroup
|
||||||
|
if cargo.type==OPSTRANSPORT.CargoType.OPSGROUP then
|
||||||
local state=cargo.opsgroup:GetState()
|
local state=cargo.opsgroup:GetState()
|
||||||
local status=cargo.opsgroup.cargoStatus
|
local status=cargo.opsgroup.cargoStatus
|
||||||
local name=cargo.opsgroup.groupname
|
local name=cargo.opsgroup.groupname
|
||||||
@ -8000,6 +8036,9 @@ function OPSGROUP:_CheckCargoTransport()
|
|||||||
local carrierGroupname=carriergroup and carriergroup.groupname or "none"
|
local carrierGroupname=carriergroup and carriergroup.groupname or "none"
|
||||||
local carrierElementname=carrierelement and carrierelement.name or "none"
|
local carrierElementname=carrierelement and carrierelement.name or "none"
|
||||||
text=text..string.format("\n (%d) %s [%s]: %s, carrier=%s(%s), delivered=%s", j, name, state, status, carrierGroupname, carrierElementname, tostring(cargo.delivered))
|
text=text..string.format("\n (%d) %s [%s]: %s, carrier=%s(%s), delivered=%s", j, name, state, status, carrierGroupname, carrierElementname, tostring(cargo.delivered))
|
||||||
|
else
|
||||||
|
--TODO: STORAGE
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if text~="" then
|
if text~="" then
|
||||||
@ -8074,42 +8113,51 @@ function OPSGROUP:_CheckCargoTransport()
|
|||||||
-- Current pickup time.
|
-- Current pickup time.
|
||||||
local tloading=Time-self.Tloading
|
local tloading=Time-self.Tloading
|
||||||
|
|
||||||
--TODO: Check max loading time. If exceeded ==> abort transport.
|
--TODO: Check max loading time. If exceeded ==> abort transport. Time might depend on required cargos, because we need to give them time to arrive.
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(self.lid..string.format("Loading at %s [TZC UID=%d] for %s sec...", self.cargoTZC.PickupZone and self.cargoTZC.PickupZone:GetName() or "unknown", self.cargoTZC.uid, tloading))
|
self:T(self.lid..string.format("Loading at %s [TZC UID=%d] for %.1f sec...", self.cargoTZC.PickupZone and self.cargoTZC.PickupZone:GetName() or "unknown", self.cargoTZC.uid, tloading))
|
||||||
|
|
||||||
local boarding=false
|
local boarding=false
|
||||||
local gotcargo=false
|
local gotcargo=false
|
||||||
for _,_cargo in pairs(self.cargoTZC.Cargos) do
|
for _,_cargo in pairs(self.cargoTZC.Cargos) do
|
||||||
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
|
||||||
|
if cargo.type==OPSTRANSPORT.CargoType.OPSTRANPORT then
|
||||||
|
|
||||||
-- Check if anyone is still boarding.
|
-- Check if anyone is still boarding.
|
||||||
if cargo.opsgroup:IsBoarding(self.groupname) then
|
if cargo.opsgroup and cargo.opsgroup:IsBoarding(self.groupname) then
|
||||||
boarding=true
|
boarding=true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if we have any cargo to transport.
|
-- Check if we have any cargo to transport.
|
||||||
if cargo.opsgroup:IsLoaded(self.groupname) then
|
if cargo.opsgroup and cargo.opsgroup:IsLoaded(self.groupname) then
|
||||||
gotcargo=true
|
gotcargo=true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Get cargo if it is in the cargo bay of any carrier element.
|
||||||
|
local mycargo=self:_GetMyCargoBayFromUID(cargo.uid)
|
||||||
|
|
||||||
|
if mycargo and mycargo.storageAmount>0 then
|
||||||
|
gotcargo=true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Boarding finished ==> Transport cargo.
|
-- Boarding finished ==> Transport cargo.
|
||||||
if gotcargo and self.cargoTransport:_CheckRequiredCargos(self.cargoTZC, self) and not boarding then
|
if gotcargo and self.cargoTransport:_CheckRequiredCargos(self.cargoTZC, self) and not boarding then
|
||||||
self:T(self.lid.."Boarding finished ==> Loaded")
|
self:T(self.lid.."Boarding/loading finished ==> Loaded")
|
||||||
|
self.Tloading=nil
|
||||||
self:LoadingDone()
|
self:LoadingDone()
|
||||||
else
|
else
|
||||||
-- No cargo and no one 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.
|
||||||
self:Loading()
|
self:Loading()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- No cargo and no one is boarding ==> check again if we can make anyone board.
|
|
||||||
if not gotcargo and not boarding then
|
|
||||||
--self:Loading()
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif self:IsTransporting() then
|
elseif self:IsTransporting() then
|
||||||
|
|
||||||
-- Set time stamp.
|
-- Set time stamp.
|
||||||
@ -8136,6 +8184,8 @@ function OPSGROUP:_CheckCargoTransport()
|
|||||||
for _,_cargo in pairs(self.cargoTZC.Cargos) do
|
for _,_cargo in pairs(self.cargoTZC.Cargos) do
|
||||||
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
|
||||||
|
if cargo.type==OPSTRANSPORT.CargoType.OPSGROUP then
|
||||||
|
|
||||||
local carrierGroup=cargo.opsgroup:_GetMyCarrierGroup()
|
local carrierGroup=cargo.opsgroup:_GetMyCarrierGroup()
|
||||||
|
|
||||||
-- Check that this group is
|
-- Check that this group is
|
||||||
@ -8144,6 +8194,21 @@ function OPSGROUP:_CheckCargoTransport()
|
|||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
---
|
||||||
|
-- STORAGE
|
||||||
|
---
|
||||||
|
|
||||||
|
-- Get cargo if it is in the cargo bay of any carrier element.
|
||||||
|
local mycargo=self:_GetMyCargoBayFromUID(cargo.uid)
|
||||||
|
|
||||||
|
if mycargo and not cargo.delivered then
|
||||||
|
delivered=false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Unloading finished ==> pickup next batch or call it a day.
|
-- Unloading finished ==> pickup next batch or call it a day.
|
||||||
@ -8165,6 +8230,7 @@ function OPSGROUP:_CheckCargoTransport()
|
|||||||
local text=string.format("Carrier [%s]: %s --> %s", self.carrierStatus, pickupname, deployname)
|
local text=string.format("Carrier [%s]: %s --> %s", self.carrierStatus, pickupname, deployname)
|
||||||
for _,_cargo in pairs(self.cargoTransport:GetCargos(self.cargoTZC)) do
|
for _,_cargo in pairs(self.cargoTransport:GetCargos(self.cargoTZC)) do
|
||||||
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
if cargo.type==OPSTRANSPORT.CargoType.OPSGROUP then
|
||||||
local name=cargo.opsgroup:GetName()
|
local name=cargo.opsgroup:GetName()
|
||||||
local gstatus=cargo.opsgroup:GetState()
|
local gstatus=cargo.opsgroup:GetState()
|
||||||
local cstatus=cargo.opsgroup.cargoStatus
|
local cstatus=cargo.opsgroup.cargoStatus
|
||||||
@ -8173,6 +8239,9 @@ function OPSGROUP:_CheckCargoTransport()
|
|||||||
local carrierGroupname=carriergroup and carriergroup.groupname or "none"
|
local carrierGroupname=carriergroup and carriergroup.groupname or "none"
|
||||||
local carrierElementname=carrierelement and carrierelement.name or "none"
|
local carrierElementname=carrierelement and carrierelement.name or "none"
|
||||||
text=text..string.format("\n- %s (%.1f kg) [%s]: %s, carrier=%s (%s), delivered=%s", name, weight, gstatus, cstatus, carrierElementname, carrierGroupname, tostring(cargo.delivered))
|
text=text..string.format("\n- %s (%.1f kg) [%s]: %s, carrier=%s (%s), delivered=%s", name, weight, gstatus, cstatus, carrierElementname, carrierGroupname, tostring(cargo.delivered))
|
||||||
|
else
|
||||||
|
--TODO: Storage
|
||||||
|
end
|
||||||
end
|
end
|
||||||
self:I(self.lid..text)
|
self:I(self.lid..text)
|
||||||
end
|
end
|
||||||
@ -8217,6 +8286,8 @@ function OPSGROUP:_AddCargobay(CargoGroup, CarrierElement, Reserved)
|
|||||||
cargo.reserved=Reserved
|
cargo.reserved=Reserved
|
||||||
else
|
else
|
||||||
|
|
||||||
|
--cargo=self:_CreateMyCargo(CargoUID, CargoGroup)
|
||||||
|
|
||||||
cargo={} --#OPSGROUP.MyCargo
|
cargo={} --#OPSGROUP.MyCargo
|
||||||
cargo.group=CargoGroup
|
cargo.group=CargoGroup
|
||||||
cargo.reserved=Reserved
|
cargo.reserved=Reserved
|
||||||
@ -8244,6 +8315,95 @@ function OPSGROUP:_AddCargobay(CargoGroup, CarrierElement, Reserved)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add warehouse storage to cargo bay of a carrier.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #OPSGROUP.Element CarrierElement The element of the carrier.
|
||||||
|
-- @param #number CargoUID UID of the cargo data.
|
||||||
|
-- @param #string StorageType Storage type.
|
||||||
|
-- @param #number StorageAmount Storage amount.
|
||||||
|
-- @param #number StorageWeight Weight of a single storage item in kg.
|
||||||
|
function OPSGROUP:_AddCargobayStorage(CarrierElement, CargoUID, StorageType, StorageAmount, StorageWeight)
|
||||||
|
|
||||||
|
local MyCargo=self:_CreateMyCargo(CargoUID, nil, StorageType, StorageAmount, StorageWeight)
|
||||||
|
|
||||||
|
self:_AddMyCargoBay(MyCargo, CarrierElement)
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add OPSGROUP to cargo bay of a carrier.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #number CargoUID UID of the cargo data.
|
||||||
|
-- @param #OPSGROUP OpsGroup Cargo group.
|
||||||
|
-- @param #string StorageType Storage type.
|
||||||
|
-- @param #number StorageAmount Storage amount.
|
||||||
|
-- @param #number StorageWeight Weight of a single storage item in kg.
|
||||||
|
-- @return #OPSGROUP.MyCargo My cargo object.
|
||||||
|
function OPSGROUP:_CreateMyCargo(CargoUID, OpsGroup, StorageType, StorageAmount, StorageWeight)
|
||||||
|
|
||||||
|
local cargo={} --#OPSGROUP.MyCargo
|
||||||
|
|
||||||
|
cargo.cargoUID=CargoUID
|
||||||
|
cargo.group=OpsGroup
|
||||||
|
cargo.storageType=StorageType
|
||||||
|
cargo.storageAmount=StorageAmount
|
||||||
|
cargo.storageWeight=StorageWeight
|
||||||
|
cargo.reserved=false
|
||||||
|
|
||||||
|
return cargo
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Add storage to cargo bay of a carrier.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #OPSGROUP.MyCargo MyCargo My cargo.
|
||||||
|
-- @param #OPSGROUP.Element CarrierElement The element of the carrier.
|
||||||
|
function OPSGROUP:_AddMyCargoBay(MyCargo, CarrierElement)
|
||||||
|
|
||||||
|
table.insert(CarrierElement.cargoBay, MyCargo)
|
||||||
|
|
||||||
|
if not MyCargo.reserved then
|
||||||
|
|
||||||
|
-- Cargo weight.
|
||||||
|
local weight=0
|
||||||
|
|
||||||
|
if MyCargo.group then
|
||||||
|
weight=MyCargo.group:GetWeightTotal()
|
||||||
|
else
|
||||||
|
weight=MyCargo.storageAmount*MyCargo.storageWeight
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add weight to carrier.
|
||||||
|
self:AddWeightCargo(CarrierElement.name, weight)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get cargo bay data from a cargo data id.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #number uid Unique ID of cargo data.
|
||||||
|
-- @return #OPSGROUP.MyCargo Cargo My cargo.
|
||||||
|
-- @return #OPSGROUP.Element Element that has loaded the cargo.
|
||||||
|
function OPSGROUP:_GetMyCargoBayFromUID(uid)
|
||||||
|
|
||||||
|
for _,_element in pairs(self.elements) do
|
||||||
|
local element=_element --#OPSGROUP.Element
|
||||||
|
|
||||||
|
for i,_mycargo in pairs(element.cargoBay) do
|
||||||
|
local mycargo=_mycargo --#OPSGROUP.MyCargo
|
||||||
|
|
||||||
|
if mycargo.cargoUID and mycargo.cargoUID==uid then
|
||||||
|
return mycargo, element, i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil, nil, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get all groups currently loaded as cargo.
|
--- Get all groups currently loaded as cargo.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #string CarrierName (Optional) Only return cargo groups loaded into a particular carrier unit.
|
-- @param #string CarrierName (Optional) Only return cargo groups loaded into a particular carrier unit.
|
||||||
@ -8291,6 +8451,51 @@ function OPSGROUP:_GetCargobay(CargoGroup)
|
|||||||
return nil, nil, nil
|
return nil, nil, nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Remove OPSGROUP from cargo bay of a carrier.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #OPSGROUP.Element Element Cargo group.
|
||||||
|
-- @param #number CargoUID Cargo UID.
|
||||||
|
-- @return #OPSGROUP.MyCargo MyCargo My cargo data.
|
||||||
|
function OPSGROUP:_GetCargobayElement(Element, CargoUID)
|
||||||
|
self:T3({Element=Element, CargoUID=CargoUID})
|
||||||
|
|
||||||
|
for i,_mycargo in pairs(Element.cargoBay) do
|
||||||
|
local mycargo=_mycargo --#OPSGROUP.MyCargo
|
||||||
|
|
||||||
|
if mycargo.cargoUID and mycargo.cargoUID==CargoUID then
|
||||||
|
return mycargo
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove OPSGROUP from cargo bay of a carrier.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #OPSGROUP.Element Element Cargo group.
|
||||||
|
-- @param #OPSGROUP.MyCargo MyCargo My cargo data.
|
||||||
|
-- @return #boolean If `true`, cargo could be removed.
|
||||||
|
function OPSGROUP:_DelCargobayElement(Element, MyCargo)
|
||||||
|
|
||||||
|
for i,_mycargo in pairs(Element.cargoBay) do
|
||||||
|
local mycargo=_mycargo --#OPSGROUP.MyCargo
|
||||||
|
|
||||||
|
if mycargo.cargoUID and MyCargo.cargoUID and mycargo.cargoUID==MyCargo.cargoUID then
|
||||||
|
if MyCargo.group then
|
||||||
|
self:RedWeightCargo(Element.name, MyCargo.group:GetWeightTotal())
|
||||||
|
else
|
||||||
|
self:RedWeightCargo(Element.name, MyCargo.storageAmount*MyCargo.storageWeight)
|
||||||
|
end
|
||||||
|
table.remove(Element.cargoBay, i)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
--- Remove OPSGROUP from cargo bay of a carrier.
|
--- Remove OPSGROUP from cargo bay of a carrier.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #OPSGROUP CargoGroup Cargo group.
|
-- @param #OPSGROUP CargoGroup Cargo group.
|
||||||
@ -8385,11 +8590,13 @@ function OPSGROUP:_CheckDelivered(CargoTransport)
|
|||||||
for _,_cargo in pairs(CargoTransport:GetCargos()) do
|
for _,_cargo in pairs(CargoTransport:GetCargos()) do
|
||||||
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
|
||||||
if self:CanCargo(cargo.opsgroup) then
|
if self:CanCargo(cargo) then
|
||||||
|
|
||||||
if cargo.delivered then
|
if cargo.delivered then
|
||||||
-- This one is delivered.
|
-- This one is delivered.
|
||||||
elseif cargo.opsgroup==nil or cargo.opsgroup:IsDead() or cargo.opsgroup:IsStopped() then
|
elseif cargo.type==OPSTRANSPORT.CargoType.OPSGROUP and cargo.opsgroup==nil then
|
||||||
|
|
||||||
|
elseif cargo.type==OPSTRANSPORT.CargoType.OPSGROUP and (cargo.opsgroup:IsDead() or cargo.opsgroup:IsStopped()) then
|
||||||
-- This one is dead.
|
-- This one is dead.
|
||||||
else
|
else
|
||||||
done=false --Someone is not done!
|
done=false --Someone is not done!
|
||||||
@ -8419,13 +8626,13 @@ function OPSGROUP:_CheckGoPickup(CargoTransport)
|
|||||||
for _,_cargo in pairs(CargoTransport:GetCargos()) do
|
for _,_cargo in pairs(CargoTransport:GetCargos()) do
|
||||||
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
|
||||||
if self:CanCargo(cargo.opsgroup) then
|
if self:CanCargo(cargo) then
|
||||||
|
|
||||||
if cargo.delivered then
|
if cargo.delivered then
|
||||||
-- This one is delivered.
|
-- This one is delivered.
|
||||||
elseif cargo.opsgroup==nil or cargo.opsgroup:IsDead() or cargo.opsgroup:IsStopped() then
|
elseif cargo.type==OPSTRANSPORT.CargoType.OPSGROUP and (cargo.opsgroup==nil or cargo.opsgroup:IsDead() or cargo.opsgroup:IsStopped()) then
|
||||||
-- This one is dead.
|
-- This one is dead.
|
||||||
elseif cargo.opsgroup:IsLoaded(CargoTransport:_GetCarrierNames()) then
|
elseif cargo.type==OPSTRANSPORT.CargoType.OPSGROUP and (cargo.opsgroup:IsLoaded(CargoTransport:_GetCarrierNames())) then
|
||||||
-- This one is loaded into a(nother) carrier.
|
-- This one is loaded into a(nother) carrier.
|
||||||
else
|
else
|
||||||
done=false --Someone is not done!
|
done=false --Someone is not done!
|
||||||
@ -8650,8 +8857,11 @@ function OPSGROUP:GetWeightCargo(UnitName, IncludeReserved)
|
|||||||
for _,_cargo in pairs(element.cargoBay) do
|
for _,_cargo in pairs(element.cargoBay) do
|
||||||
local cargo=_cargo --#OPSGROUP.MyCargo
|
local cargo=_cargo --#OPSGROUP.MyCargo
|
||||||
if (not cargo.reserved) or (cargo.reserved==true and (IncludeReserved==true or IncludeReserved==nil)) then
|
if (not cargo.reserved) or (cargo.reserved==true and (IncludeReserved==true or IncludeReserved==nil)) then
|
||||||
local cargoweight=cargo.group:GetWeightTotal()
|
if cargo.group then
|
||||||
gewicht=gewicht+cargoweight
|
gewicht=gewicht+cargo.group:GetWeightTotal()
|
||||||
|
else
|
||||||
|
gewicht=gewicht+cargo.storageAmount*cargo.storageWeight
|
||||||
|
end
|
||||||
--self:I(self.lid..string.format("unit=%s (reserved=%s): cargo=%s weight=%d, total weight=%d", tostring(UnitName), tostring(IncludeReserved), cargo.group:GetName(), cargoweight, weight))
|
--self:I(self.lid..string.format("unit=%s (reserved=%s): cargo=%s weight=%d, total weight=%d", tostring(UnitName), tostring(IncludeReserved), cargo.group:GetName(), cargoweight, weight))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -8745,16 +8955,46 @@ function OPSGROUP:RedWeightCargo(UnitName, Weight)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get weight of warehouse storage to transport.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param Ops.OpsTransport#OPSTRANSPORT.Storage Storage
|
||||||
|
-- @param #boolean Total Get total weight. Otherweise the amount left to deliver (total-loaded-lost-delivered).
|
||||||
|
-- @param #boolean Reserved Reduce weight that is reserved.
|
||||||
|
-- @param #boolean Amount Return amount not weight.
|
||||||
|
-- @return #number Weight of cargo in kg or amount in number of items, if `Amount=true`.
|
||||||
|
function OPSGROUP:_GetWeightStorage(Storage, Total, Reserved, Amount)
|
||||||
|
|
||||||
|
local weight=Storage.cargoAmount
|
||||||
|
|
||||||
|
if not Total then
|
||||||
|
weight=weight-Storage.cargoLost-Storage.cargoLoaded-Storage.cargoDelivered
|
||||||
|
end
|
||||||
|
|
||||||
|
if Reserved then
|
||||||
|
weight=weight-Storage.cargoReserved
|
||||||
|
end
|
||||||
|
|
||||||
|
if not Amount then
|
||||||
|
weight=weight*Storage.cargoWeight
|
||||||
|
end
|
||||||
|
|
||||||
|
return weight
|
||||||
|
end
|
||||||
|
|
||||||
--- Check if the group can *in principle* be carrier of a cargo group. This checks the max cargo capacity of the group but *not* how much cargo is already loaded (if any).
|
--- Check if the group can *in principle* be carrier of a cargo group. This checks the max cargo capacity of the group but *not* how much cargo is already loaded (if any).
|
||||||
-- **Note** that the cargo group *cannot* be split into units, i.e. the largest cargo bay of any element of the group must be able to load the whole cargo group in one piece.
|
-- **Note** that the cargo group *cannot* be split into units, i.e. the largest cargo bay of any element of the group must be able to load the whole cargo group in one piece.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #OPSGROUP CargoGroup Cargo group, which needs a carrier.
|
-- @param Ops.OpsGroup#OPSGROUP.CargoGroup Cargo Cargo data, which needs a carrier.
|
||||||
-- @return #boolean If `true`, there is an element of the group that can load the whole cargo group.
|
-- @return #boolean If `true`, there is an element of the group that can load the whole cargo group.
|
||||||
function OPSGROUP:CanCargo(CargoGroup)
|
function OPSGROUP:CanCargo(Cargo)
|
||||||
|
|
||||||
if CargoGroup then
|
if Cargo then
|
||||||
|
|
||||||
local weight=CargoGroup:GetWeightTotal()
|
local weight=math.huge
|
||||||
|
|
||||||
|
if Cargo.type==OPSTRANSPORT.CargoType.OPSGROUP then
|
||||||
|
|
||||||
|
local weight=Cargo.opsgroup:GetWeightTotal()
|
||||||
|
|
||||||
for _,_element in pairs(self.elements) do
|
for _,_element in pairs(self.elements) do
|
||||||
local element=_element --#OPSGROUP.Element
|
local element=_element --#OPSGROUP.Element
|
||||||
@ -8763,31 +9003,58 @@ function OPSGROUP:CanCargo(CargoGroup)
|
|||||||
if element and element.status~=OPSGROUP.ElementStatus.DEAD and element.weightMaxCargo>=weight then
|
if element and element.status~=OPSGROUP.ElementStatus.DEAD and element.weightMaxCargo>=weight then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
---
|
||||||
|
-- STORAGE
|
||||||
|
---
|
||||||
|
|
||||||
|
-- Since storage cargo can be devided onto multiple carriers, we take the weight of a single cargo item (even 1 kg of fuel).
|
||||||
|
weight=Cargo.storage.cargoWeight
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Calculate cargo bay space.
|
||||||
|
local bay=0
|
||||||
|
for _,_element in pairs(self.elements) do
|
||||||
|
local element=_element --#OPSGROUP.Element
|
||||||
|
|
||||||
|
-- Check that element is not dead and has
|
||||||
|
if element and element.status~=OPSGROUP.ElementStatus.DEAD then
|
||||||
|
bay=bay+element.weightMaxCargo
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if cargo fits into cargo bay(s) of carrier group.
|
||||||
|
if bay>=weight then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Add weight to the internal cargo of an element of the group.
|
--- Find carrier for cargo by evaluating the free cargo bay storage.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #OPSGROUP CargoGroup Cargo group, which needs a carrier.
|
-- @param #number Weight Weight of cargo in kg.
|
||||||
-- @return #OPSGROUP.Element Carrier able to transport the cargo.
|
-- @return #OPSGROUP.Element Carrier able to transport the cargo.
|
||||||
function OPSGROUP:FindCarrierForCargo(CargoGroup)
|
function OPSGROUP:FindCarrierForCargo(Weight)
|
||||||
|
|
||||||
local weight=CargoGroup:GetWeightTotal()
|
|
||||||
|
|
||||||
for _,_element in pairs(self.elements) do
|
for _,_element in pairs(self.elements) do
|
||||||
local element=_element --#OPSGROUP.Element
|
local element=_element --#OPSGROUP.Element
|
||||||
|
|
||||||
local free=self:GetFreeCargobay(element.name)
|
local free=self:GetFreeCargobay(element.name)
|
||||||
|
|
||||||
if free>=weight then
|
if free>=Weight then
|
||||||
return element
|
return element
|
||||||
else
|
else
|
||||||
self:T3(self.lid..string.format("%s: Weight %d>%d free cargo bay", element.name, weight, free))
|
self:T3(self.lid..string.format("%s: Weight %d>%d free cargo bay", element.name, Weight, free))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -9068,6 +9335,36 @@ function OPSGROUP:onafterPickup(From, Event, To)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- On after "Loading" event.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #table Cargos Table of cargos.
|
||||||
|
-- @return #table Table of sorted cargos.
|
||||||
|
function OPSGROUP:_SortCargo(Cargos)
|
||||||
|
|
||||||
|
-- Sort results table wrt descending weight.
|
||||||
|
local function _sort(a, b)
|
||||||
|
local cargoA=a --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
local cargoB=b --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
local weightA=0
|
||||||
|
local weightB=0
|
||||||
|
if cargoA.opsgroup then
|
||||||
|
weightA=cargoA.opsgroup:GetWeightTotal()
|
||||||
|
else
|
||||||
|
weightA=self:_GetWeightStorage(cargoA.storage)
|
||||||
|
end
|
||||||
|
if cargoB.opsgroup then
|
||||||
|
weightB=cargoB.opsgroup:GetWeightTotal()
|
||||||
|
else
|
||||||
|
weightB=self:_GetWeightStorage(cargoB.storage)
|
||||||
|
end
|
||||||
|
return weightA>weightB
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(Cargos, _sort)
|
||||||
|
|
||||||
|
return Cargos
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- On after "Loading" event.
|
--- On after "Loading" event.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
@ -9079,32 +9376,30 @@ function OPSGROUP:onafterLoading(From, Event, To)
|
|||||||
-- Set carrier status.
|
-- Set carrier status.
|
||||||
self:_NewCarrierStatus(OPSGROUP.CarrierStatus.LOADING)
|
self:_NewCarrierStatus(OPSGROUP.CarrierStatus.LOADING)
|
||||||
|
|
||||||
-- Loading time stamp.
|
|
||||||
self.Tloading=timer.getAbsTime()
|
|
||||||
|
|
||||||
-- Get valid cargos of the TZC.
|
-- Get valid cargos of the TZC.
|
||||||
local cargos={}
|
local cargos={}
|
||||||
for _,_cargo in pairs(self.cargoTZC.Cargos) do
|
for _,_cargo in pairs(self.cargoTZC.Cargos) do
|
||||||
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
|
||||||
-- Check if this group can carry the cargo.
|
-- Check if this group can carry the cargo.
|
||||||
local canCargo=self:CanCargo(cargo.opsgroup)
|
local canCargo=self:CanCargo(cargo)
|
||||||
|
|
||||||
-- Check if this group is currently acting as carrier.
|
-- Check if this group is currently acting as carrier.
|
||||||
local isCarrier=cargo.opsgroup:IsPickingup() or cargo.opsgroup:IsLoading() or cargo.opsgroup:IsTransporting() or cargo.opsgroup:IsUnloading()
|
local isCarrier=false
|
||||||
|
|
||||||
|
|
||||||
-- Check if cargo is not already cargo.
|
-- Check if cargo is not already cargo.
|
||||||
local isNotCargo=cargo.opsgroup:IsNotCargo(true)
|
local isNotCargo=true
|
||||||
|
|
||||||
-- Check if cargo is holding or loaded
|
-- Check if cargo is holding or loaded
|
||||||
local isHolding=cargo.opsgroup:IsHolding() or cargo.opsgroup:IsLoaded()
|
local isHolding=cargo.type==OPSTRANSPORT.CargoType.OPSGROUP and (cargo.opsgroup:IsHolding() or cargo.opsgroup:IsLoaded()) or true
|
||||||
|
|
||||||
-- Check if cargo is in embark/pickup zone.
|
-- Check if cargo is in embark/pickup zone.
|
||||||
-- Added InUtero here, if embark zone is moving (ship) and cargo has been spawned late activated and its position is not updated. Not sure if that breaks something else!
|
-- Added InUtero here, if embark zone is moving (ship) and cargo has been spawned late activated and its position is not updated. Not sure if that breaks something else!
|
||||||
local inZone=cargo.opsgroup:IsInZone(self.cargoTZC.EmbarkZone) or cargo.opsgroup:IsInUtero()
|
local inZone=cargo.type==OPSTRANSPORT.CargoType.OPSGROUP and (cargo.opsgroup:IsInZone(self.cargoTZC.EmbarkZone) or cargo.opsgroup:IsInUtero()) or true
|
||||||
|
|
||||||
-- Check if cargo is currently on a mission.
|
-- Check if cargo is currently on a mission.
|
||||||
local isOnMission=cargo.opsgroup:IsOnMission()
|
local isOnMission=cargo.type==OPSTRANSPORT.CargoType.OPSGROUP and cargo.opsgroup:IsOnMission() or false
|
||||||
|
|
||||||
-- Check if current mission is using this ops transport.
|
-- Check if current mission is using this ops transport.
|
||||||
if isOnMission then
|
if isOnMission then
|
||||||
@ -9114,39 +9409,114 @@ function OPSGROUP:onafterLoading(From, Event, To)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local isAvail=true
|
||||||
|
if cargo.type==OPSTRANSPORT.CargoType.STORAGE then
|
||||||
|
local nAvail=cargo.storage.storageFrom:GetAmount(cargo.storage.cargoType)
|
||||||
|
if nAvail>0 then
|
||||||
|
isAvail=true
|
||||||
|
else
|
||||||
|
isAvail=false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
isCarrier=cargo.opsgroup:IsPickingup() or cargo.opsgroup:IsLoading() or cargo.opsgroup:IsTransporting() or cargo.opsgroup:IsUnloading()
|
||||||
|
isNotCargo=cargo.opsgroup:IsNotCargo(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
local isDead=cargo.type==OPSTRANSPORT.CargoType.OPSGROUP and cargo.opsgroup:IsDead() or false
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:T(self.lid..string.format("Loading: canCargo=%s, isCarrier=%s, isNotCargo=%s, isHolding=%s, isOnMission=%s",
|
self:T(self.lid..string.format("Loading: canCargo=%s, isCarrier=%s, isNotCargo=%s, isHolding=%s, isOnMission=%s",
|
||||||
tostring(canCargo), tostring(isCarrier), tostring(isNotCargo), tostring(isHolding), tostring(isOnMission)))
|
tostring(canCargo), tostring(isCarrier), tostring(isNotCargo), tostring(isHolding), tostring(isOnMission)))
|
||||||
|
|
||||||
-- TODO: Need a better :IsBusy() function or :IsReadyForMission() :IsReadyForBoarding() :IsReadyForTransport()
|
-- TODO: Need a better :IsBusy() function or :IsReadyForMission() :IsReadyForBoarding() :IsReadyForTransport()
|
||||||
if canCargo and inZone and isNotCargo and isHolding and (not (cargo.delivered or cargo.opsgroup:IsDead() or isCarrier or isOnMission)) then
|
if canCargo and inZone and isNotCargo and isHolding and isAvail and (not (cargo.delivered or isDead or isCarrier or isOnMission)) then
|
||||||
table.insert(cargos, cargo)
|
table.insert(cargos, cargo)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Sort results table wrt descending weight.
|
-- Sort cargos.
|
||||||
local function _sort(a, b)
|
self:_SortCargo(cargos)
|
||||||
local cargoA=a --Ops.OpsGroup#OPSGROUP.CargoGroup
|
|
||||||
local cargoB=b --Ops.OpsGroup#OPSGROUP.CargoGroup
|
|
||||||
return cargoA.opsgroup:GetWeightTotal()>cargoB.opsgroup:GetWeightTotal()
|
|
||||||
end
|
|
||||||
table.sort(cargos, _sort)
|
|
||||||
|
|
||||||
-- Loop over all cargos.
|
-- Loop over all cargos.
|
||||||
for _,_cargo in pairs(cargos) do
|
for _,_cargo in pairs(cargos) do
|
||||||
local cargo=_cargo --#OPSGROUP.CargoGroup
|
local cargo=_cargo --#OPSGROUP.CargoGroup
|
||||||
|
|
||||||
-- Find a carrier for this cargo.
|
local weight=nil
|
||||||
local carrier=self:FindCarrierForCargo(cargo.opsgroup)
|
if cargo.type==OPSTRANSPORT.CargoType.OPSGROUP then
|
||||||
|
|
||||||
if carrier then
|
weight=cargo.opsgroup:GetWeightTotal()
|
||||||
|
|
||||||
|
-- Find a carrier for this cargo.
|
||||||
|
local carrier=self:FindCarrierForCargo(weight)
|
||||||
|
|
||||||
-- Order cargo group to board the carrier.
|
-- Order cargo group to board the carrier.
|
||||||
|
if carrier then
|
||||||
cargo.opsgroup:Board(self, carrier)
|
cargo.opsgroup:Board(self, carrier)
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
---
|
||||||
|
-- STORAGE
|
||||||
|
---
|
||||||
|
|
||||||
|
-- Get weight of cargo that needs to be transported.
|
||||||
|
weight=self:_GetWeightStorage(cargo.storage, false)
|
||||||
|
|
||||||
|
-- Get amount that the warehouse currently has.
|
||||||
|
local Amount=cargo.storage.storageFrom:GetAmount(cargo.storage.cargoType)
|
||||||
|
local Weight=Amount*cargo.storage.cargoWeight
|
||||||
|
|
||||||
|
-- Make sure, we do not take more than the warehouse can provide.
|
||||||
|
weight=math.min(weight, Weight)
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:T(self.lid..string.format("Loading storage weight=%d kg (warehouse has %d kg)!", weight, Weight))
|
||||||
|
|
||||||
|
-- Loop over all elements of the carrier group.
|
||||||
|
for _,_element in pairs(self.elements) do
|
||||||
|
local element=_element --#OPSGROUP.Element
|
||||||
|
|
||||||
|
-- Get the free cargo space of the carrier.
|
||||||
|
local free=self:GetFreeCargobay(element.name)
|
||||||
|
|
||||||
|
-- Min of weight or bay.
|
||||||
|
local w=math.min(weight, free)
|
||||||
|
|
||||||
|
-- Check that weight is >0 and also greater that at least one item. We cannot transport half a missile.
|
||||||
|
if w>=cargo.storage.cargoWeight then
|
||||||
|
|
||||||
|
-- Calculate item amount.
|
||||||
|
local amount=math.floor(w/cargo.storage.cargoWeight)
|
||||||
|
|
||||||
|
-- Remove items from warehouse.
|
||||||
|
cargo.storage.storageFrom:RemoveAmount(cargo.storage.cargoType, amount)
|
||||||
|
|
||||||
|
-- Add amount to loaded cargo.
|
||||||
|
cargo.storage.cargoLoaded=cargo.storage.cargoLoaded+amount
|
||||||
|
|
||||||
|
-- Add cargo to cargo by of element.
|
||||||
|
self:_AddCargobayStorage(element, cargo.uid, cargo.storage.cargoType, amount, cargo.storage.cargoWeight)
|
||||||
|
|
||||||
|
-- Reduce weight for the next element (if any).
|
||||||
|
weight=weight-amount*cargo.storage.cargoWeight
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
local text=string.format("Element %s: loaded amount=%d (weight=%d) ==> left=%d kg", element.name, amount, amount*cargo.storage.cargoWeight, weight)
|
||||||
|
self:T(self.lid..text)
|
||||||
|
|
||||||
|
-- If no cargo left, break the loop.
|
||||||
|
if weight<=0 then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set (new) cargo status.
|
--- Set (new) cargo status.
|
||||||
@ -9323,6 +9693,8 @@ function OPSGROUP:onafterTransport(From, Event, To)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--env.info(string.format("FF Transport: Zone=%s inzone=%s, ready2deploy=%s", Zone:GetName(), tostring(inzone), tostring(ready2deploy)))
|
||||||
|
|
||||||
if inzone then
|
if inzone then
|
||||||
|
|
||||||
-- We are already in the deploy zone ==> wait and initiate unloading.
|
-- We are already in the deploy zone ==> wait and initiate unloading.
|
||||||
@ -9480,6 +9852,8 @@ function OPSGROUP:onafterUnloading(From, Event, To)
|
|||||||
for _,_cargo in pairs(self.cargoTZC.Cargos) do
|
for _,_cargo in pairs(self.cargoTZC.Cargos) do
|
||||||
local cargo=_cargo --#OPSGROUP.CargoGroup
|
local cargo=_cargo --#OPSGROUP.CargoGroup
|
||||||
|
|
||||||
|
if cargo.type==OPSTRANSPORT.CargoType.OPSGROUP then
|
||||||
|
|
||||||
-- Check that cargo is loaded into this group.
|
-- Check that cargo is loaded into this group.
|
||||||
-- NOTE: Could be that the element carriing this cargo group is DEAD, which would mean that the cargo group is also DEAD.
|
-- NOTE: Could be that the element carriing this cargo group is DEAD, which would mean that the cargo group is also DEAD.
|
||||||
if cargo.opsgroup:IsLoaded(self.groupname) and not cargo.opsgroup:IsDead() then
|
if cargo.opsgroup:IsLoaded(self.groupname) and not cargo.opsgroup:IsDead() then
|
||||||
@ -9617,6 +9991,67 @@ function OPSGROUP:onafterUnloading(From, Event, To)
|
|||||||
-- Not loaded or dead
|
-- Not loaded or dead
|
||||||
end
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
---
|
||||||
|
-- STORAGE
|
||||||
|
---
|
||||||
|
|
||||||
|
-- TODO: should proabaly move this check to the top to include OPSGROUPS as well?!
|
||||||
|
if not cargo.delivered then
|
||||||
|
|
||||||
|
for _,_element in pairs(self.elements) do
|
||||||
|
local element=_element --#OPSGROUP.Element
|
||||||
|
|
||||||
|
-- Get my cargo from cargo bay of element.
|
||||||
|
local mycargo=self:_GetCargobayElement(element, cargo.uid)
|
||||||
|
|
||||||
|
if mycargo then
|
||||||
|
-- Add cargo to warehouse storage.
|
||||||
|
cargo.storage.storageTo:AddAmount(mycargo.storageType, mycargo.storageAmount)
|
||||||
|
|
||||||
|
-- Add amount to delivered.
|
||||||
|
cargo.storage.cargoDelivered=cargo.storage.cargoDelivered+mycargo.storageAmount
|
||||||
|
|
||||||
|
-- Reduce loaded amount.
|
||||||
|
cargo.storage.cargoLoaded=cargo.storage.cargoLoaded-mycargo.storageAmount
|
||||||
|
|
||||||
|
-- Remove cargo from bay.
|
||||||
|
self:_DelCargobayElement(element, mycargo)
|
||||||
|
|
||||||
|
-- Debug info
|
||||||
|
self:T2(self.lid..string.format("Cargo loaded=%d, delivered=%d, lost=%d", cargo.storage.cargoLoaded, cargo.storage.cargoDelivered, cargo.storage.cargoLost))
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get amount that was delivered.
|
||||||
|
local amountToDeliver=self:_GetWeightStorage(cargo.storage, false, false, true)
|
||||||
|
|
||||||
|
-- Get total amount to be delivered.
|
||||||
|
local amountTotal=self:_GetWeightStorage(cargo.storage, true, false, true)
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
local text=string.format("Amount delivered=%d, total=%d", amountToDeliver, amountTotal)
|
||||||
|
self:T(self.lid..text)
|
||||||
|
|
||||||
|
if amountToDeliver<=0 then
|
||||||
|
|
||||||
|
-- Cargo was delivered (somehow).
|
||||||
|
cargo.delivered=true
|
||||||
|
|
||||||
|
-- Increase number of delivered cargos.
|
||||||
|
self.cargoTransport.Ndelivered=self.cargoTransport.Ndelivered+1
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
local text=string.format("Ndelivered=%d delivered=%s", self.cargoTransport.Ndelivered, tostring(cargo.delivered))
|
||||||
|
self:T(self.lid..text)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end -- loop over cargos
|
end -- loop over cargos
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -10047,7 +10482,7 @@ function OPSGROUP:onafterBoard(From, Event, To, CarrierGroup, Carrier)
|
|||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(self.lid..string.format("Group is loaded currently ==> Moving directly to new carrier - No Unload(), Disembart() events triggered!"))
|
self:T(self.lid..string.format("Group is loaded currently ==> Moving directly to new carrier - No Unload(), Disembart() events triggered!"))
|
||||||
|
|
||||||
-- Remove my carrier.
|
-- Remove old/current carrier.
|
||||||
self:_RemoveMyCarrier()
|
self:_RemoveMyCarrier()
|
||||||
|
|
||||||
-- Trigger Load event.
|
-- Trigger Load event.
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
--- **Ops** - Troop transport assignment for OPS groups.
|
--- **Ops** - Transport assignment for OPS groups and storage.
|
||||||
--
|
--
|
||||||
-- ## Main Features:
|
-- ## Main Features:
|
||||||
--
|
--
|
||||||
-- * Transport troops from A to B
|
-- * Transport troops from A to B
|
||||||
|
-- * Transport of warehouse storage (fuel, weapons and equipment)
|
||||||
-- * Supports ground, naval and airborne (airplanes and helicopters) units as carriers
|
-- * Supports ground, naval and airborne (airplanes and helicopters) units as carriers
|
||||||
-- * Use combined forces (ground, naval, air) to transport the troops
|
-- * Use combined forces (ground, naval, air) to transport the troops
|
||||||
-- * Additional FSM events to hook into and customize your mission design
|
-- * Additional FSM events to hook into and customize your mission design
|
||||||
@ -63,6 +64,7 @@
|
|||||||
-- @field Ops.Chief#CHIEF chief Chief of the transport.
|
-- @field Ops.Chief#CHIEF chief Chief of the transport.
|
||||||
-- @field Ops.OpsZone#OPSZONE opszone OPS zone.
|
-- @field Ops.OpsZone#OPSZONE opszone OPS zone.
|
||||||
-- @field #table requestID The ID of the queued warehouse request. Necessary to cancel the request if the transport was cancelled before the request is processed.
|
-- @field #table requestID The ID of the queued warehouse request. Necessary to cancel the request if the transport was cancelled before the request is processed.
|
||||||
|
-- @field #number cargocounter Running number to generate cargo UIDs.
|
||||||
--
|
--
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
@ -79,7 +81,7 @@
|
|||||||
-- * Cargo groups are **not** split and distributed into different carrier *units*. That means that the whole cargo group **must fit** into one of the carrier units.
|
-- * Cargo groups are **not** split and distributed into different carrier *units*. That means that the whole cargo group **must fit** into one of the carrier units.
|
||||||
-- * Cargo groups must be inside the pickup zones to be considered for loading. Groups not inside the pickup zone will not get the command to board.
|
-- * Cargo groups must be inside the pickup zones to be considered for loading. Groups not inside the pickup zone will not get the command to board.
|
||||||
--
|
--
|
||||||
-- # Constructor
|
-- # Troop Transport
|
||||||
--
|
--
|
||||||
-- A new cargo transport assignment is created with the @{#OPSTRANSPORT.New}() function
|
-- A new cargo transport assignment is created with the @{#OPSTRANSPORT.New}() function
|
||||||
--
|
--
|
||||||
@ -101,6 +103,30 @@
|
|||||||
--
|
--
|
||||||
-- You can also mix carrier types. For instance, you can assign the same transport to APCs and helicopters. Or to helicopters and airplanes.
|
-- You can also mix carrier types. For instance, you can assign the same transport to APCs and helicopters. Or to helicopters and airplanes.
|
||||||
--
|
--
|
||||||
|
-- # Storage Transport
|
||||||
|
--
|
||||||
|
-- An instance of the OPSTRANSPORT class is created similarly to the troop transport case. However, the first parameter is `nil` as not troops
|
||||||
|
-- are transported.
|
||||||
|
--
|
||||||
|
-- local storagetransport=OPSTRANSPORT:New(nil, PickupZone, DeployZone)
|
||||||
|
--
|
||||||
|
-- ## Defining Storage
|
||||||
|
--
|
||||||
|
-- The storage warehouses from which the cargo is taken and to which the cargo is delivered have to be specified
|
||||||
|
--
|
||||||
|
-- storagetransport:AddCargoStorage(berlinStorage, batumiStorage, STORAGE.Liquid.JETFUEL, 1000)
|
||||||
|
--
|
||||||
|
-- Here `berlinStorage` and `batumiStorage` are @{Wrapper.Storage#STORAGE} objects of DCS warehouses.
|
||||||
|
--
|
||||||
|
-- Furthermore, that type of cargo (liquids or weapons/equipment) and the amount has to be specified. If weapons/equipment is the cargo,
|
||||||
|
-- we also need to specify the weight per storage item as this cannot be retrieved from the DCS API and is not stored in any MOOSE database.
|
||||||
|
--
|
||||||
|
-- storagetransport:AddCargoStorage(berlinStorage, batumiStorage, ENUMS.Storage.weapons.bombs.Mk_82, 9, 230)
|
||||||
|
--
|
||||||
|
-- Finally, the transport is assigned to one or multiple groups, which carry out the transport
|
||||||
|
--
|
||||||
|
-- myopsgroup:AddOpsTransport(storagetransport)
|
||||||
|
--
|
||||||
-- # Examples
|
-- # Examples
|
||||||
--
|
--
|
||||||
-- A carrier group is assigned to transport infantry troops from zone "Zone Kobuleti X" to zone "Zone Alpha".
|
-- A carrier group is assigned to transport infantry troops from zone "Zone Kobuleti X" to zone "Zone Alpha".
|
||||||
@ -131,6 +157,7 @@ OPSTRANSPORT = {
|
|||||||
legions = {},
|
legions = {},
|
||||||
statusLegion = {},
|
statusLegion = {},
|
||||||
requestID = {},
|
requestID = {},
|
||||||
|
cargocounter = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Cargo transport status.
|
--- Cargo transport status.
|
||||||
@ -186,6 +213,27 @@ OPSTRANSPORT.Status={
|
|||||||
-- @field #number radius Radomization radius for waypoints in meters. Default 0 m.
|
-- @field #number radius Radomization radius for waypoints in meters. Default 0 m.
|
||||||
-- @field #boolean reverse If `true`, path is used in reversed order.
|
-- @field #boolean reverse If `true`, path is used in reversed order.
|
||||||
|
|
||||||
|
--- Storage data.
|
||||||
|
-- @type OPSTRANSPORT.Storage
|
||||||
|
-- @field Wrapper.Storage#STORAGE storageFrom Storage from.
|
||||||
|
-- @field Wrapper.Storage#STORAGE storageTo Storage To.
|
||||||
|
-- @field #string cargoType Type of cargo.
|
||||||
|
-- @field #number cargoAmount Amount of cargo that should be transported.
|
||||||
|
-- @field #number cargoReserved Amount of cargo that is reserved for a carrier group.
|
||||||
|
-- @field #number cargoDelivered Amount of cargo that has been delivered.
|
||||||
|
-- @field #number cargoLost Amount of cargo that was lost.
|
||||||
|
-- @field #number cargoLoaded Amount of cargo that is loading.
|
||||||
|
-- @field #number cargoWeight Weight of one single cargo item in kg. Default 1 kg.
|
||||||
|
|
||||||
|
--- Storage data.
|
||||||
|
-- @type OPSTRANSPORT.CargoType
|
||||||
|
-- @field #string OPSGROUP Cargo is an OPSGROUP.
|
||||||
|
-- @field #string STORAGE Cargo is storage of DCS warehouse.
|
||||||
|
OPSTRANSPORT.CargoType={
|
||||||
|
OPSGROUP="OPSGROUP",
|
||||||
|
STORAGE="STORAGE",
|
||||||
|
}
|
||||||
|
|
||||||
--- Generic transport condition.
|
--- Generic transport condition.
|
||||||
-- @type OPSTRANSPORT.Condition
|
-- @type OPSTRANSPORT.Condition
|
||||||
-- @field #function func Callback function to check for a condition. Should return a #boolean.
|
-- @field #function func Callback function to check for a condition. Should return a #boolean.
|
||||||
@ -196,7 +244,7 @@ _OPSTRANSPORTID=0
|
|||||||
|
|
||||||
--- Army Group version.
|
--- Army Group version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
OPSTRANSPORT.version="0.7.0"
|
OPSTRANSPORT.version="0.8.0"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@ -205,6 +253,7 @@ OPSTRANSPORT.version="0.7.0"
|
|||||||
-- TODO: Trains.
|
-- TODO: Trains.
|
||||||
-- TODO: Stop transport.
|
-- TODO: Stop transport.
|
||||||
-- TODO: Improve pickup and transport paths.
|
-- TODO: Improve pickup and transport paths.
|
||||||
|
-- DONE: Storage.
|
||||||
-- DONE: Disembark parameters per cargo group.
|
-- DONE: Disembark parameters per cargo group.
|
||||||
-- DONE: Special transport cohorts/legions. Similar to mission.
|
-- DONE: Special transport cohorts/legions. Similar to mission.
|
||||||
-- DONE: Cancel transport.
|
-- DONE: Cancel transport.
|
||||||
@ -576,6 +625,38 @@ function OPSTRANSPORT:AddCargoGroups(GroupSet, TransportZoneCombo, DisembarkActi
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add cargo warehouse storage to be transported. This adds items such as fuel, weapons and other equipment, which is to be transported
|
||||||
|
-- from one DCS warehouse to another.
|
||||||
|
-- For weapons and equipment, the weight per item has to be specified explicitly as these cannot be retrieved by the DCS API. For liquids the
|
||||||
|
-- default value of 1 kg per item should be used as the amount of liquid is already given in kg.
|
||||||
|
-- @param #OPSTRANSPORT self
|
||||||
|
-- @param Wrapper.Storage#STORAGE StorageFrom Storage warehouse from which the cargo is taken.
|
||||||
|
-- @param Wrapper.Storage#STORAGE StorageTo Storage warehouse to which the cargo is delivered.
|
||||||
|
-- @param #string CargoType Type of cargo, *e.g.* `"weapons.bombs.Mk_84"` or liquid type as #number.
|
||||||
|
-- @param #number CargoAmount Amount of cargo. Liquids in kg.
|
||||||
|
-- @param #number CargoWeight Weight of a single cargo item in kg. Default 1 kg.
|
||||||
|
-- @param #OPSTRANSPORT.TransportZoneCombo TransportZoneCombo Transport zone combo if other than default.
|
||||||
|
-- @return #OPSTRANSPORT self
|
||||||
|
function OPSTRANSPORT:AddCargoStorage(StorageFrom, StorageTo, CargoType, CargoAmount, CargoWeight, TransportZoneCombo)
|
||||||
|
|
||||||
|
-- Use default TZC if no transport zone combo is provided.
|
||||||
|
TransportZoneCombo=TransportZoneCombo or self.tzcDefault
|
||||||
|
|
||||||
|
-- Cargo data.
|
||||||
|
local cargo=self:_CreateCargoStorage(StorageFrom,StorageTo, CargoType, CargoAmount, CargoWeight, TransportZoneCombo)
|
||||||
|
|
||||||
|
if cargo then
|
||||||
|
|
||||||
|
-- Add total amount of ever assigned cargos.
|
||||||
|
self.Ncargo=self.Ncargo+1
|
||||||
|
|
||||||
|
-- Add to TZC table.
|
||||||
|
table.insert(TransportZoneCombo.Cargos, cargo)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set pickup zone.
|
--- Set pickup zone.
|
||||||
-- @param #OPSTRANSPORT self
|
-- @param #OPSTRANSPORT self
|
||||||
@ -1063,18 +1144,37 @@ end
|
|||||||
-- @return #table Cargo Ops groups. Can be and empty table `{}`.
|
-- @return #table Cargo Ops groups. Can be and empty table `{}`.
|
||||||
function OPSTRANSPORT:GetCargoOpsGroups(Delivered, Carrier, TransportZoneCombo)
|
function OPSTRANSPORT:GetCargoOpsGroups(Delivered, Carrier, TransportZoneCombo)
|
||||||
|
|
||||||
local cargos=self:GetCargos(TransportZoneCombo)
|
local cargos=self:GetCargos(TransportZoneCombo, Carrier, Delivered)
|
||||||
|
|
||||||
local opsgroups={}
|
local opsgroups={}
|
||||||
for _,_cargo in pairs(cargos) do
|
for _,_cargo in pairs(cargos) do
|
||||||
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
if Delivered==nil or cargo.delivered==Delivered then
|
if cargo.type=="OPSGROUP" then
|
||||||
if cargo.opsgroup and not (cargo.opsgroup:IsDead() or cargo.opsgroup:IsStopped()) then
|
if cargo.opsgroup and not (cargo.opsgroup:IsDead() or cargo.opsgroup:IsStopped()) then
|
||||||
if Carrier==nil or Carrier:CanCargo(cargo.opsgroup) then
|
|
||||||
table.insert(opsgroups, cargo.opsgroup)
|
table.insert(opsgroups, cargo.opsgroup)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return opsgroups
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get (all) cargo @{Ops.OpsGroup#OPSGROUP}s. Optionally, only delivered or undelivered groups can be returned.
|
||||||
|
-- @param #OPSTRANSPORT self
|
||||||
|
-- @param #boolean Delivered If `true`, only delivered groups are returned. If `false` only undelivered groups are returned. If `nil`, all groups are returned.
|
||||||
|
-- @param Ops.OpsGroup#OPSGROUP Carrier (Optional) Only count cargo groups that fit into the given carrier group. Current cargo is not a factor.
|
||||||
|
-- @param #OPSTRANSPORT.TransportZoneCombo TransportZoneCombo Transport zone combo.
|
||||||
|
-- @return #table Cargo Ops groups. Can be and empty table `{}`.
|
||||||
|
function OPSTRANSPORT:GetCargoStorages(Delivered, Carrier, TransportZoneCombo)
|
||||||
|
|
||||||
|
local cargos=self:GetCargos(TransportZoneCombo, Carrier, Delivered)
|
||||||
|
|
||||||
|
local opsgroups={}
|
||||||
|
for _,_cargo in pairs(cargos) do
|
||||||
|
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
if cargo.type=="STORAGE" then
|
||||||
|
table.insert(opsgroups, cargo.storage)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return opsgroups
|
return opsgroups
|
||||||
@ -1090,22 +1190,60 @@ end
|
|||||||
--- Get cargos.
|
--- Get cargos.
|
||||||
-- @param #OPSTRANSPORT self
|
-- @param #OPSTRANSPORT self
|
||||||
-- @param #OPSTRANSPORT.TransportZoneCombo TransportZoneCombo Transport zone combo.
|
-- @param #OPSTRANSPORT.TransportZoneCombo TransportZoneCombo Transport zone combo.
|
||||||
|
-- @param Ops.OpsGroup#OPSGROUP Carrier Specific carrier.
|
||||||
|
-- @param #boolean Delivered Delivered status.
|
||||||
-- @return #table Cargos.
|
-- @return #table Cargos.
|
||||||
function OPSTRANSPORT:GetCargos(TransportZoneCombo)
|
function OPSTRANSPORT:GetCargos(TransportZoneCombo, Carrier, Delivered)
|
||||||
|
|
||||||
|
local tczs=self.tzCombos
|
||||||
if TransportZoneCombo then
|
if TransportZoneCombo then
|
||||||
return TransportZoneCombo.Cargos
|
tczs={TransportZoneCombo}
|
||||||
else
|
end
|
||||||
|
|
||||||
local cargos={}
|
local cargos={}
|
||||||
for _,_tzc in pairs(self.tzCombos) do
|
for _,_tcz in pairs(tczs) do
|
||||||
local tzc=_tzc --#OPSTRANSPORT.TransportZoneCombo
|
local tcz=_tcz --#OPSTRANSPORT.TransportZoneCombo
|
||||||
for _,cargo in pairs(tzc.Cargos) do
|
for _,_cargo in pairs(tcz.Cargos) do
|
||||||
|
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
if Delivered==nil or cargo.delivered==Delivered then
|
||||||
|
if Carrier==nil or Carrier:CanCargo(cargo) then
|
||||||
table.insert(cargos, cargo)
|
table.insert(cargos, cargo)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return cargos
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return cargos
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get total weight.
|
||||||
|
-- @param #OPSTRANSPORT self
|
||||||
|
-- @param Ops.OpsGroup#OPSGROUP.CargoGroup Cargo Cargo data.
|
||||||
|
-- @param #boolean IncludeReserved Include reserved cargo.
|
||||||
|
-- @return #number Weight in kg.
|
||||||
|
function OPSTRANSPORT:GetCargoTotalWeight(Cargo, IncludeReserved)
|
||||||
|
|
||||||
|
local weight=0
|
||||||
|
|
||||||
|
if Cargo.type==OPSTRANSPORT.CargoType.OPSGROUP then
|
||||||
|
weight=Cargo.opsgroup:GetWeightTotal(nil, IncludeReserved)
|
||||||
|
else
|
||||||
|
if type(Cargo.storage.cargoType)=="number" then
|
||||||
|
if IncludeReserved then
|
||||||
|
return Cargo.storage.cargoAmount+Cargo.storage.cargoReserved
|
||||||
|
else
|
||||||
|
return Cargo.storage.cargoAmount
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if IncludeReserved then
|
||||||
|
return Cargo.storage.cargoAmount*100 -- Assume 100 kg per item
|
||||||
|
else
|
||||||
|
return (Cargo.storage.cargoAmount+Cargo.storage.cargoReserved)*100 -- Assume 100 kg per item
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return weight
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set transport start and stop time.
|
--- Set transport start and stop time.
|
||||||
@ -1642,11 +1780,18 @@ function OPSTRANSPORT:onafterStatusUpdate(From, Event, To)
|
|||||||
text=text..string.format("\nCargos:")
|
text=text..string.format("\nCargos:")
|
||||||
for _,_cargo in pairs(self:GetCargos()) do
|
for _,_cargo in pairs(self:GetCargos()) do
|
||||||
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
if cargo.type==OPSTRANSPORT.CargoType.OPSGROUP then
|
||||||
local carrier=cargo.opsgroup:_GetMyCarrierElement()
|
local carrier=cargo.opsgroup:_GetMyCarrierElement()
|
||||||
local name=carrier and carrier.name or "none"
|
local name=carrier and carrier.name or "none"
|
||||||
local cstate=carrier and carrier.status or "N/A"
|
local cstate=carrier and carrier.status or "N/A"
|
||||||
text=text..string.format("\n- %s: %s [%s], weight=%d kg, carrier=%s [%s], delivered=%s [UID=%s]",
|
text=text..string.format("\n- %s: %s [%s], weight=%d kg, carrier=%s [%s], delivered=%s [UID=%s]",
|
||||||
cargo.opsgroup:GetName(), cargo.opsgroup.cargoStatus:upper(), cargo.opsgroup:GetState(), cargo.opsgroup:GetWeightTotal(), name, cstate, tostring(cargo.delivered), tostring(cargo.opsgroup.cargoTransportUID))
|
cargo.opsgroup:GetName(), cargo.opsgroup.cargoStatus:upper(), cargo.opsgroup:GetState(), cargo.opsgroup:GetWeightTotal(), name, cstate, tostring(cargo.delivered), tostring(cargo.opsgroup.cargoTransportUID))
|
||||||
|
else
|
||||||
|
--TODO: Storage
|
||||||
|
local storage=cargo.storage
|
||||||
|
text=text..string.format("\n- storage type=%s: amount: total=%d loaded=%d, lost=%d, delivered=%d, delivered=%s [UID=%s]",
|
||||||
|
storage.cargoType, storage.cargoAmount, storage.cargoLoaded, storage.cargoLost, storage.cargoDelivered, tostring(cargo.delivered), tostring(cargo.uid))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
text=text..string.format("\nCarriers:")
|
text=text..string.format("\nCarriers:")
|
||||||
@ -1923,14 +2068,14 @@ function OPSTRANSPORT:_CheckDelivered()
|
|||||||
if cargo.delivered then
|
if cargo.delivered then
|
||||||
-- This one is delivered.
|
-- This one is delivered.
|
||||||
dead=false
|
dead=false
|
||||||
elseif cargo.opsgroup==nil then
|
elseif cargo.type==OPSTRANSPORT.CargoType.OPSGROUP and cargo.opsgroup==nil then
|
||||||
-- This one is nil?!
|
-- This one is nil?!
|
||||||
dead=false
|
dead=false
|
||||||
elseif cargo.opsgroup:IsDestroyed() then
|
elseif cargo.type==OPSTRANSPORT.CargoType.OPSGROUP and cargo.opsgroup:IsDestroyed() then
|
||||||
-- This one was destroyed.
|
-- This one was destroyed.
|
||||||
elseif cargo.opsgroup:IsDead() then
|
elseif cargo.type==OPSTRANSPORT.CargoType.OPSGROUP and cargo.opsgroup:IsDead() then
|
||||||
-- This one is dead.
|
-- This one is dead.
|
||||||
elseif cargo.opsgroup:IsStopped() then
|
elseif cargo.type==OPSTRANSPORT.CargoType.OPSGROUP and cargo.opsgroup:IsStopped() then
|
||||||
-- This one is stopped.
|
-- This one is stopped.
|
||||||
dead=false
|
dead=false
|
||||||
else
|
else
|
||||||
@ -2116,10 +2261,12 @@ function OPSTRANSPORT:_CreateCargoGroupData(group, TransportZoneCombo, Disembark
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.cargocounter=self.cargocounter+1
|
||||||
|
|
||||||
-- Create a new data item.
|
-- Create a new data item.
|
||||||
local cargo={} --Ops.OpsGroup#OPSGROUP.CargoGroup
|
local cargo={} --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
cargo.uid=self.cargocounter
|
||||||
|
cargo.type="OPSGROUP"
|
||||||
cargo.opsgroup=opsgroup
|
cargo.opsgroup=opsgroup
|
||||||
cargo.delivered=false
|
cargo.delivered=false
|
||||||
cargo.status="Unknown"
|
cargo.status="Unknown"
|
||||||
@ -2133,6 +2280,45 @@ function OPSTRANSPORT:_CreateCargoGroupData(group, TransportZoneCombo, Disembark
|
|||||||
return cargo
|
return cargo
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Create a cargo group data structure.
|
||||||
|
-- @param #OPSTRANSPORT self
|
||||||
|
-- @param Wrapper.Storage#STORAGE StorageFrom Storage from.
|
||||||
|
-- @param Wrapper.Storage#STORAGE StorageTo Storage to.
|
||||||
|
-- @param #string CargoType Type of cargo.
|
||||||
|
-- @param #number CargoAmount Total amount of cargo that should be transported. Liquids in kg.
|
||||||
|
-- @param #number CargoWeight Weight of a single cargo item in kg. Default 1 kg.
|
||||||
|
-- @param #OPSTRANSPORT.TransportZoneCombo TransportZoneCombo Transport zone combo.
|
||||||
|
-- @return Ops.OpsGroup#OPSGROUP.CargoGroup Cargo group data.
|
||||||
|
function OPSTRANSPORT:_CreateCargoStorage(StorageFrom, StorageTo, CargoType, CargoAmount, CargoWeight, TransportZoneCombo)
|
||||||
|
|
||||||
|
local storage={} --#OPSTRANSPORT.Storage
|
||||||
|
storage.storageFrom=StorageFrom
|
||||||
|
storage.storageTo=StorageTo
|
||||||
|
storage.cargoType=CargoType
|
||||||
|
storage.cargoAmount=CargoAmount
|
||||||
|
storage.cargoDelivered=0
|
||||||
|
storage.cargoLost=0
|
||||||
|
storage.cargoReserved=0
|
||||||
|
storage.cargoLoaded=0
|
||||||
|
storage.cargoWeight=CargoWeight or 1
|
||||||
|
|
||||||
|
self.cargocounter=self.cargocounter+1
|
||||||
|
|
||||||
|
-- Create a new data item.
|
||||||
|
local cargo={} --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
cargo.uid=self.cargocounter
|
||||||
|
cargo.type="STORAGE"
|
||||||
|
cargo.opsgroup=nil
|
||||||
|
cargo.storage=storage
|
||||||
|
cargo.delivered=false
|
||||||
|
cargo.status="Unknown"
|
||||||
|
cargo.tzcUID=TransportZoneCombo
|
||||||
|
cargo.disembarkZone=nil
|
||||||
|
cargo.disembarkCarriers=nil
|
||||||
|
|
||||||
|
return cargo
|
||||||
|
end
|
||||||
|
|
||||||
--- Count how many cargo groups are inside a zone.
|
--- Count how many cargo groups are inside a zone.
|
||||||
-- @param #OPSTRANSPORT self
|
-- @param #OPSTRANSPORT self
|
||||||
-- @param Core.Zone#ZONE Zone The zone object.
|
-- @param Core.Zone#ZONE Zone The zone object.
|
||||||
@ -2143,7 +2329,9 @@ end
|
|||||||
function OPSTRANSPORT:_CountCargosInZone(Zone, Delivered, Carrier, TransportZoneCombo)
|
function OPSTRANSPORT:_CountCargosInZone(Zone, Delivered, Carrier, TransportZoneCombo)
|
||||||
|
|
||||||
-- Get cargo ops groups.
|
-- Get cargo ops groups.
|
||||||
local cargos=self:GetCargoOpsGroups(Delivered, Carrier, TransportZoneCombo)
|
--local cargos=self:GetCargoOpsGroups(Delivered, Carrier, TransportZoneCombo)
|
||||||
|
|
||||||
|
local cargos=self:GetCargos(TransportZoneCombo, Carrier, Delivered)
|
||||||
|
|
||||||
--- Function to check if carrier is supposed to be disembarked to.
|
--- Function to check if carrier is supposed to be disembarked to.
|
||||||
local function iscarrier(_cargo)
|
local function iscarrier(_cargo)
|
||||||
@ -2185,22 +2373,33 @@ function OPSTRANSPORT:_CountCargosInZone(Zone, Delivered, Carrier, TransportZone
|
|||||||
|
|
||||||
local N=0
|
local N=0
|
||||||
for _,_cargo in pairs(cargos) do
|
for _,_cargo in pairs(cargos) do
|
||||||
local cargo=_cargo --Ops.OpsGroup#OPSGROUP
|
local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup
|
||||||
|
|
||||||
|
local isNotCargo=true
|
||||||
|
local isInZone=true
|
||||||
|
local isInUtero=true
|
||||||
|
|
||||||
|
if cargo.type==OPSTRANSPORT.CargoType.OPSGROUP then
|
||||||
|
local opsgroup=cargo.opsgroup
|
||||||
|
|
||||||
-- Is not cargo?
|
-- Is not cargo?
|
||||||
local isNotCargo=cargo:IsNotCargo(true)
|
isNotCargo=opsgroup:IsNotCargo(true)
|
||||||
if not isNotCargo then
|
if not isNotCargo then
|
||||||
isNotCargo=iscarrier(cargo)
|
isNotCargo=iscarrier(opsgroup)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Is in zone?
|
-- Is in zone?
|
||||||
local isInZone=cargo:IsInZone(Zone)
|
isInZone=opsgroup:IsInZone(Zone)
|
||||||
|
|
||||||
-- Is in utero?
|
-- Is in utero?
|
||||||
local isInUtero=cargo:IsInUtero()
|
isInUtero=opsgroup:IsInUtero()
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(self.lid..string.format("Cargo=%s: notcargo=%s, iscarrier=%s inzone=%s, inutero=%s", cargo:GetName(), tostring(cargo:IsNotCargo(true)), tostring(iscarrier(cargo)), tostring(isInZone), tostring(isInUtero)))
|
self:T(self.lid..string.format("Cargo=%s: notcargo=%s, iscarrier=%s inzone=%s, inutero=%s", opsgroup:GetName(), tostring(opsgroup:IsNotCargo(true)), tostring(iscarrier(opsgroup)), tostring(isInZone), tostring(isInUtero)))
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- We look for groups that are not cargo, in the zone or in utero.
|
-- We look for groups that are not cargo, in the zone or in utero.
|
||||||
if isNotCargo and (isInZone or isInUtero) then
|
if isNotCargo and (isInZone or isInUtero) then
|
||||||
|
|||||||
@ -900,6 +900,23 @@ function MSRS:_ExecCommand(command)
|
|||||||
timer.scheduleFunction(os.remove, filename, timer.getTime()+1)
|
timer.scheduleFunction(os.remove, filename, timer.getTime()+1)
|
||||||
timer.scheduleFunction(os.remove, filenvbs, timer.getTime()+1)
|
timer.scheduleFunction(os.remove, filenvbs, timer.getTime()+1)
|
||||||
|
|
||||||
|
elseif false then
|
||||||
|
|
||||||
|
-- Create a tmp file.
|
||||||
|
local filenvbs = os.getenv('TMP') .. "\\MSRS-"..STTS.uuid()..".vbs"
|
||||||
|
|
||||||
|
-- VBS script
|
||||||
|
local script = io.open(filenvbs, "w+")
|
||||||
|
script:write(string.format('Set oShell = CreateObject ("Wscript.Shell")\n'))
|
||||||
|
script:write(string.format('Dim strArgs\n'))
|
||||||
|
script:write(string.format('strArgs = "cmd /c %s"\n', filename))
|
||||||
|
script:write(string.format('oShell.Run strArgs, 0, false'))
|
||||||
|
script:close()
|
||||||
|
|
||||||
|
local runvbs=string.format('cscript.exe //Nologo //B "%s"', filenvbs)
|
||||||
|
|
||||||
|
-- Play file in 0.01 seconds
|
||||||
|
res=os.execute(runvbs)
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user