Merge branch 'FF/Ops' into FF/OpsDev

This commit is contained in:
Frank 2023-08-27 20:39:51 +02:00
commit 3ff374e1b9
11 changed files with 3059 additions and 411 deletions

View File

@ -35,6 +35,13 @@
-- * Validate the presence of objects in the SET. -- * Validate the presence of objects in the SET.
-- * Trigger events when objects in the SET change a zone presence. -- * Trigger events when objects in the SET change a zone presence.
-- --
-- ## Notes on `FilterPrefixes()`:
--
-- This filter always looks for a **partial match** somewhere in the given field. LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
-- Have a read through the following to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching).
-- For example, setting a filter like so `FilterPrefixes("Huey")` is perfectly all right, whilst `FilterPrefixes("UH-1H Al-Assad")` might not be due to the minus signs. A quick fix here is to use a dot (.)
-- in place of the special character, or escape it with a percentage sign (%), i.e. either `FilterPrefixes("UH.1H Al.Assad")` or `FilterPrefixes("UH%-1H Al%-Assad")` will give you the expected results.
--
-- === -- ===
-- --
-- ### Author: **FlightControl** -- ### Author: **FlightControl**
@ -940,7 +947,8 @@ do
-- * @{#SET_GROUP.FilterCoalitions}: Builds the SET_GROUP with the groups belonging to the coalition(s). -- * @{#SET_GROUP.FilterCoalitions}: Builds the SET_GROUP with the groups belonging to the coalition(s).
-- * @{#SET_GROUP.FilterCategories}: Builds the SET_GROUP with the groups belonging to the category(ies). -- * @{#SET_GROUP.FilterCategories}: Builds the SET_GROUP with the groups belonging to the category(ies).
-- * @{#SET_GROUP.FilterCountries}: Builds the SET_GROUP with the groups belonging to the country(ies). -- * @{#SET_GROUP.FilterCountries}: Builds the SET_GROUP with the groups belonging to the country(ies).
-- * @{#SET_GROUP.FilterPrefixes}: Builds the SET_GROUP with the groups *containing* the given string in the group name. **Attention!** Bad naming convention, as this not really filtering *prefixes*. -- * @{#SET_GROUP.FilterPrefixes}: Builds the SET_GROUP with the groups *containing* the given string in the group name. **Attention!** LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
-- * @{#SET_GROUP.FilterActive}: Builds the SET_GROUP with the groups that are only active. Groups that are inactive (late activation) won't be included in the set! -- * @{#SET_GROUP.FilterActive}: Builds the SET_GROUP with the groups that are only active. Groups that are inactive (late activation) won't be included in the set!
-- --
-- For the Category Filter, extra methods have been added: -- For the Category Filter, extra methods have been added:
@ -2052,7 +2060,8 @@ do -- SET_UNIT
-- * @{#SET_UNIT.FilterCategories}: Builds the SET_UNIT with the units belonging to the category(ies). -- * @{#SET_UNIT.FilterCategories}: Builds the SET_UNIT with the units belonging to the category(ies).
-- * @{#SET_UNIT.FilterTypes}: Builds the SET_UNIT with the units belonging to the unit type(s). -- * @{#SET_UNIT.FilterTypes}: Builds the SET_UNIT with the units belonging to the unit type(s).
-- * @{#SET_UNIT.FilterCountries}: Builds the SET_UNIT with the units belonging to the country(ies). -- * @{#SET_UNIT.FilterCountries}: Builds the SET_UNIT with the units belonging to the country(ies).
-- * @{#SET_UNIT.FilterPrefixes}: Builds the SET_UNIT with the units sharing the same string(s) in their name. **ATTENTION!** Bad naming convention as this *does not* only filter *prefixes*. -- * @{#SET_UNIT.FilterPrefixes}: Builds the SET_UNIT with the units sharing the same string(s) in their name. **Attention!** LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
-- * @{#SET_UNIT.FilterActive}: Builds the SET_UNIT with the units that are only active. Units that are inactive (late activation) won't be included in the set! -- * @{#SET_UNIT.FilterActive}: Builds the SET_UNIT with the units that are only active. Units that are inactive (late activation) won't be included in the set!
-- * @{#SET_UNIT.FilterZones}: Builds the SET_UNIT with the units within a @{Core.Zone#ZONE}. -- * @{#SET_UNIT.FilterZones}: Builds the SET_UNIT with the units within a @{Core.Zone#ZONE}.
-- --
@ -3231,7 +3240,8 @@ do -- SET_STATIC
-- * @{#SET_STATIC.FilterCategories}: Builds the SET_STATIC with the units belonging to the category(ies). -- * @{#SET_STATIC.FilterCategories}: Builds the SET_STATIC with the units belonging to the category(ies).
-- * @{#SET_STATIC.FilterTypes}: Builds the SET_STATIC with the units belonging to the unit type(s). -- * @{#SET_STATIC.FilterTypes}: Builds the SET_STATIC with the units belonging to the unit type(s).
-- * @{#SET_STATIC.FilterCountries}: Builds the SET_STATIC with the units belonging to the country(ies). -- * @{#SET_STATIC.FilterCountries}: Builds the SET_STATIC with the units belonging to the country(ies).
-- * @{#SET_STATIC.FilterPrefixes}: Builds the SET_STATIC with the units containing the same string(s) in their name. **ATTENTION** bad naming convention as this *does not** only filter *prefixes*. -- * @{#SET_STATIC.FilterPrefixes}: Builds the SET_STATIC with the units containing the same string(s) in their name. **Attention!** LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
-- * @{#SET_STATIC.FilterZones}: Builds the SET_STATIC with the units within a @{Core.Zone#ZONE}. -- * @{#SET_STATIC.FilterZones}: Builds the SET_STATIC with the units within a @{Core.Zone#ZONE}.
-- --
-- Once the filter criteria have been set for the SET_STATIC, you can start filtering using: -- Once the filter criteria have been set for the SET_STATIC, you can start filtering using:
@ -3988,7 +3998,8 @@ do -- SET_CLIENT
-- * @{#SET_CLIENT.FilterCategories}: Builds the SET_CLIENT with the clients belonging to the category(ies). -- * @{#SET_CLIENT.FilterCategories}: Builds the SET_CLIENT with the clients belonging to the category(ies).
-- * @{#SET_CLIENT.FilterTypes}: Builds the SET_CLIENT with the clients belonging to the client type(s). -- * @{#SET_CLIENT.FilterTypes}: Builds the SET_CLIENT with the clients belonging to the client type(s).
-- * @{#SET_CLIENT.FilterCountries}: Builds the SET_CLIENT with the clients belonging to the country(ies). -- * @{#SET_CLIENT.FilterCountries}: Builds the SET_CLIENT with the clients belonging to the country(ies).
-- * @{#SET_CLIENT.FilterPrefixes}: Builds the SET_CLIENT with the clients containing the same string(s) in their unit/pilot name. **ATTENTION!** Bad naming convention as this *does not* only filter *prefixes*. -- * @{#SET_CLIENT.FilterPrefixes}: Builds the SET_CLIENT with the clients containing the same string(s) in their unit/pilot name. **Attention!** LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
-- * @{#SET_CLIENT.FilterActive}: Builds the SET_CLIENT with the units that are only active. Units that are inactive (late activation) won't be included in the set! -- * @{#SET_CLIENT.FilterActive}: Builds the SET_CLIENT with the units that are only active. Units that are inactive (late activation) won't be included in the set!
-- * @{#SET_CLIENT.FilterZones}: Builds the SET_CLIENT with the clients within a @{Core.Zone#ZONE}. -- * @{#SET_CLIENT.FilterZones}: Builds the SET_CLIENT with the clients within a @{Core.Zone#ZONE}.
-- --
@ -4603,7 +4614,8 @@ do -- SET_PLAYER
-- * @{#SET_PLAYER.FilterCategories}: Builds the SET_PLAYER with the clients belonging to the category(ies). -- * @{#SET_PLAYER.FilterCategories}: Builds the SET_PLAYER with the clients belonging to the category(ies).
-- * @{#SET_PLAYER.FilterTypes}: Builds the SET_PLAYER with the clients belonging to the client type(s). -- * @{#SET_PLAYER.FilterTypes}: Builds the SET_PLAYER with the clients belonging to the client type(s).
-- * @{#SET_PLAYER.FilterCountries}: Builds the SET_PLAYER with the clients belonging to the country(ies). -- * @{#SET_PLAYER.FilterCountries}: Builds the SET_PLAYER with the clients belonging to the country(ies).
-- * @{#SET_PLAYER.FilterPrefixes}: Builds the SET_PLAYER with the clients sharing the same string(s) in their unit/pilot name. **ATTENTION** Bad naming convention as this *does not* only filter prefixes. -- * @{#SET_PLAYER.FilterPrefixes}: Builds the SET_PLAYER with the clients sharing the same string(s) in their unit/pilot name. **Attention!** LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
-- --
-- Once the filter criteria have been set for the SET_PLAYER, you can start filtering using: -- Once the filter criteria have been set for the SET_PLAYER, you can start filtering using:
-- --
@ -5380,7 +5392,8 @@ do -- SET_CARGO
-- Filter criteria are defined by: -- Filter criteria are defined by:
-- --
-- * @{#SET_CARGO.FilterCoalitions}: Builds the SET_CARGO with the cargos belonging to the coalition(s). -- * @{#SET_CARGO.FilterCoalitions}: Builds the SET_CARGO with the cargos belonging to the coalition(s).
-- * @{#SET_CARGO.FilterPrefixes}: Builds the SET_CARGO with the cargos containing the same string(s). **ATTENTION** Bad naming convention as this *does not* only filter *prefixes*. -- * @{#SET_CARGO.FilterPrefixes}: Builds the SET_CARGO with the cargos containing the same string(s). **Attention!** LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
-- * @{#SET_CARGO.FilterTypes}: Builds the SET_CARGO with the cargos belonging to the cargo type(s). -- * @{#SET_CARGO.FilterTypes}: Builds the SET_CARGO with the cargos belonging to the cargo type(s).
-- * @{#SET_CARGO.FilterCountries}: Builds the SET_CARGO with the cargos belonging to the country(ies). -- * @{#SET_CARGO.FilterCountries}: Builds the SET_CARGO with the cargos belonging to the country(ies).
-- --
@ -5802,7 +5815,8 @@ do -- SET_ZONE
-- You can set filter criteria to build the collection of zones in SET_ZONE. -- You can set filter criteria to build the collection of zones in SET_ZONE.
-- Filter criteria are defined by: -- Filter criteria are defined by:
-- --
-- * @{#SET_ZONE.FilterPrefixes}: Builds the SET_ZONE with the zones having a certain text pattern in their name. **ATTENTION!** Bad naming convention as this *does not* only filter *prefixes*. -- * @{#SET_ZONE.FilterPrefixes}: Builds the SET_ZONE with the zones having a certain text pattern in their name. **Attention!** LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
-- --
-- Once the filter criteria have been set for the SET_ZONE, you can start filtering using: -- Once the filter criteria have been set for the SET_ZONE, you can start filtering using:
-- --
@ -6171,7 +6185,8 @@ do -- SET_ZONE_GOAL
-- You can set filter criteria to build the collection of zones in SET_ZONE_GOAL. -- You can set filter criteria to build the collection of zones in SET_ZONE_GOAL.
-- Filter criteria are defined by: -- Filter criteria are defined by:
-- --
-- * @{#SET_ZONE_GOAL.FilterPrefixes}: Builds the SET_ZONE_GOAL with the zones having a certain text pattern in their name. **ATTENTION!** Bad naming convention as this *does not* only filter *prefixes*. -- * @{#SET_ZONE_GOAL.FilterPrefixes}: Builds the SET_ZONE_GOAL with the zones having a certain text pattern in their name. **Attention!** LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
-- --
-- Once the filter criteria have been set for the SET_ZONE_GOAL, you can start filtering using: -- Once the filter criteria have been set for the SET_ZONE_GOAL, you can start filtering using:
-- --
@ -6483,7 +6498,8 @@ do -- SET_OPSZONE
-- You can set filter criteria to build the collection of zones in SET_OPSZONE. -- You can set filter criteria to build the collection of zones in SET_OPSZONE.
-- Filter criteria are defined by: -- Filter criteria are defined by:
-- --
-- * @{#SET_OPSZONE.FilterPrefixes}: Builds the SET_OPSZONE with the zones having a certain text pattern in their name. **ATTENTION!** Bad naming convention as this *does not* only filter *prefixes*. -- * @{#SET_OPSZONE.FilterPrefixes}: Builds the SET_OPSZONE with the zones having a certain text pattern in their name. **Attention!** LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
-- --
-- Once the filter criteria have been set for the SET_OPSZONE, you can start filtering using: -- Once the filter criteria have been set for the SET_OPSZONE, you can start filtering using:
-- --
@ -6949,7 +6965,8 @@ do -- SET_OPSGROUP
-- * @{#SET_OPSGROUP.FilterCoalitions}: Builds the SET_OPSGROUP with the groups belonging to the coalition(s). -- * @{#SET_OPSGROUP.FilterCoalitions}: Builds the SET_OPSGROUP with the groups belonging to the coalition(s).
-- * @{#SET_OPSGROUP.FilterCategories}: Builds the SET_OPSGROUP with the groups belonging to the category(ies). -- * @{#SET_OPSGROUP.FilterCategories}: Builds the SET_OPSGROUP with the groups belonging to the category(ies).
-- * @{#SET_OPSGROUP.FilterCountries}: Builds the SET_OPSGROUP with the groups belonging to the country(ies). -- * @{#SET_OPSGROUP.FilterCountries}: Builds the SET_OPSGROUP with the groups belonging to the country(ies).
-- * @{#SET_OPSGROUP.FilterPrefixes}: Builds the SET_OPSGROUP with the groups *containing* the given string in the group name. **Attention!** Bad naming convention, as this not really filtering *prefixes*. -- * @{#SET_OPSGROUP.FilterPrefixes}: Builds the SET_OPSGROUP with the groups *containing* the given string in the group name. **Attention!** LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
-- * @{#SET_OPSGROUP.FilterActive}: Builds the SET_OPSGROUP with the groups that are only active. Groups that are inactive (late activation) won't be included in the set! -- * @{#SET_OPSGROUP.FilterActive}: Builds the SET_OPSGROUP with the groups that are only active. Groups that are inactive (late activation) won't be included in the set!
-- --
-- For the Category Filter, extra methods have been added: -- For the Category Filter, extra methods have been added:

View File

@ -833,6 +833,12 @@ do -- Warehouse
-- The warehouse class gives control over warehouses that exist in airbase objects. These warehouses can limit the aircraft, munitions, and fuel available to coalition aircraft. -- The warehouse class gives control over warehouses that exist in airbase objects. These warehouses can limit the aircraft, munitions, and fuel available to coalition aircraft.
-- @type Warehouse -- @type Warehouse
--- Get a warehouse by passing its name.
-- @function [parent=#Warehouse] getByName
-- @param #string Name Name of the warehouse.
-- @return #Warehouse The warehouse object.
--- Adds the passed amount of a given item to the warehouse. --- Adds the passed amount of a given item to the warehouse.
-- itemName is the typeName associated with the item: "weapons.missiles.AIM_54C_Mk47" -- itemName is the typeName associated with the item: "weapons.missiles.AIM_54C_Mk47"
-- A wsType table can also be used, however the last digit with wsTypes has been known to change. {4, 4, 7, 322} -- A wsType table can also be used, however the last digit with wsTypes has been known to change. {4, 4, 7, 322}

View File

@ -591,7 +591,7 @@ RANGE.MenuF10Root = nil
--- Range script version. --- Range script version.
-- @field #string version -- @field #string version
RANGE.version = "2.7.0" RANGE.version = "2.7.1"
-- TODO list: -- TODO list:
-- TODO: Verbosity level for messages. -- TODO: Verbosity level for messages.
@ -2044,6 +2044,7 @@ function RANGE:OnEventShot( EventData )
-- Attack parameters. -- Attack parameters.
local attackHdg=_unit:GetHeading() local attackHdg=_unit:GetHeading()
local attackAlt=_unit:GetHeight() local attackAlt=_unit:GetHeight()
attackAlt = UTILS.MetersToFeet(attackAlt)
local attackVel=_unit:GetVelocityKNOTS() local attackVel=_unit:GetVelocityKNOTS()
-- Tracking info and init of last bomb position. -- Tracking info and init of last bomb position.

View File

@ -46,6 +46,7 @@
-- === -- ===
-- --
-- ### Author: **funkyfranky** -- ### Author: **funkyfranky**
-- ### Additions for SRS and FARP: **applevangelist**
-- --
-- @module Ops.ATIS -- @module Ops.ATIS
-- @image OPS_ATIS.png -- @image OPS_ATIS.png
@ -615,7 +616,7 @@ _ATIS = {}
--- ATIS class version. --- ATIS class version.
-- @field #string version -- @field #string version
ATIS.version = "0.9.15" ATIS.version = "0.9.16"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -1278,7 +1279,8 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function ATIS:onafterStart( From, Event, To ) function ATIS:onafterStart( From, Event, To )
self:I("Airbase category is "..self.airbase:GetAirbaseCategory()) self:T({From, Event, To})
self:T("Airbase category is "..self.airbase:GetAirbaseCategory())
-- Check that this is an airdrome. -- Check that this is an airdrome.
if self.airbase:GetAirbaseCategory() == Airbase.Category.SHIP then if self.airbase:GetAirbaseCategory() == Airbase.Category.SHIP then
@ -1340,7 +1342,7 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function ATIS:onafterStatus( From, Event, To ) function ATIS:onafterStatus( From, Event, To )
self:T({From, Event, To})
-- Get FSM state. -- Get FSM state.
local fsmstate = self:GetState() local fsmstate = self:GetState()
@ -1362,7 +1364,7 @@ function ATIS:onafterStatus( From, Event, To )
self:T( self.lid .. text ) self:T( self.lid .. text )
if not self:Is("Stopped") then if not self:Is("Stopped") then
self:__Status( -60 ) self:__Status( 60 )
end end
end end
@ -1376,7 +1378,8 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function ATIS:onafterCheckQueue( From, Event, To ) function ATIS:onafterCheckQueue( From, Event, To )
self:T({From, Event, To})
if not self:Is("Stopped") then
if self.useSRS then if self.useSRS then
self:Broadcast() self:Broadcast()
@ -1392,9 +1395,9 @@ function ATIS:onafterCheckQueue( From, Event, To )
end end
if not self:Is("Stopped") then
-- Check back in 5 seconds. -- Check back in 5 seconds.
self:__CheckQueue( -math.abs( self.dTQueueCheck ) ) self:__CheckQueue( math.abs( self.dTQueueCheck ) )
end end
end end
@ -1404,7 +1407,7 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function ATIS:onafterBroadcast( From, Event, To ) function ATIS:onafterBroadcast( From, Event, To )
self:T({From, Event, To})
-- Get current coordinate. -- Get current coordinate.
local coord = self.airbase:GetCoordinate() local coord = self.airbase:GetCoordinate()
@ -2156,8 +2159,9 @@ function ATIS:onafterBroadcast( From, Event, To )
if not self.ATISforFARPs then if not self.ATISforFARPs then
-- Active runway. -- Active runway.
local subtitle
if runwayLanding then if runwayLanding then
local subtitle=string.format("Active runway %s", runwayLanding) subtitle=string.format("Active runway %s", runwayLanding)
if rwyLandingLeft==true then if rwyLandingLeft==true then
subtitle=subtitle.." Left" subtitle=subtitle.." Left"
elseif rwyLandingLeft==false then elseif rwyLandingLeft==false then
@ -2417,6 +2421,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param #string Text Report text. -- @param #string Text Report text.
function ATIS:onafterReport( From, Event, To, Text ) function ATIS:onafterReport( From, Event, To, Text )
self:T({From, Event, To})
self:T( self.lid .. string.format( "Report:\n%s", Text ) ) self:T( self.lid .. string.format( "Report:\n%s", Text ) )
if self.useSRS and self.msrs then if self.useSRS and self.msrs then

View File

@ -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.

View File

@ -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

View File

@ -104,7 +104,7 @@ PLAYERRECCE = {
ClassName = "PLAYERRECCE", ClassName = "PLAYERRECCE",
verbose = true, verbose = true,
lid = nil, lid = nil,
version = "0.0.17", version = "0.0.18",
ViewZone = {}, ViewZone = {},
ViewZoneVisual = {}, ViewZoneVisual = {},
ViewZoneLaser = {}, ViewZoneLaser = {},
@ -807,6 +807,7 @@ function PLAYERRECCE:_SetClientLaserCode(client,group,playername,code)
self.ClientMenus[playername]:Remove() self.ClientMenus[playername]:Remove()
self.ClientMenus[playername]=nil self.ClientMenus[playername]=nil
end end
self:_BuildMenus()
return self return self
end end
@ -829,6 +830,7 @@ function PLAYERRECCE:_SwitchOnStation(client,group,playername)
self.ClientMenus[playername]:Remove() self.ClientMenus[playername]:Remove()
self.ClientMenus[playername]=nil self.ClientMenus[playername]=nil
end end
self:_BuildMenus(client)
return self return self
end end
@ -851,6 +853,7 @@ function PLAYERRECCE:_SwitchSmoke(client,group,playername)
self.ClientMenus[playername]:Remove() self.ClientMenus[playername]:Remove()
self.ClientMenus[playername]=nil self.ClientMenus[playername]=nil
end end
self:_BuildMenus(client)
return self return self
end end
@ -873,6 +876,7 @@ function PLAYERRECCE:_SwitchLasing(client,group,playername)
self.ClientMenus[playername]:Remove() self.ClientMenus[playername]:Remove()
self.ClientMenus[playername]=nil self.ClientMenus[playername]=nil
end end
self:_BuildMenus(client)
return self return self
end end
@ -902,6 +906,7 @@ function PLAYERRECCE:_SwitchLasingDist(client,group,playername,mindist,maxdist)
self.ClientMenus[playername]:Remove() self.ClientMenus[playername]:Remove()
self.ClientMenus[playername]=nil self.ClientMenus[playername]=nil
end end
self:_BuildMenus(client)
return self return self
end end
@ -930,6 +935,8 @@ function PLAYERRECCE:_SmokeTargets(client,group,playername)
if cameraset:CountAlive() > 0 then if cameraset:CountAlive() > 0 then
self:__TargetsSmoked(-1,client,playername,cameraset) self:__TargetsSmoked(-1,client,playername,cameraset)
else
return self
end end
local highsmoke = self.SmokeColor.highsmoke local highsmoke = self.SmokeColor.highsmoke
@ -1068,7 +1075,7 @@ self:T(self.lid.."_ReportLaserTargets")
if number > 0 and self.AutoLase[playername] then if number > 0 and self.AutoLase[playername] then
local Settings = ( client and _DATABASE:GetPlayerSettings( playername ) ) or _SETTINGS local Settings = ( client and _DATABASE:GetPlayerSettings( playername ) ) or _SETTINGS
local target = self:_GetHVTTarget(targetset) -- the one we're lasing local target = self:_GetHVTTarget(targetset) -- the one we're lasing
local ThreatLevel = target:GetThreatLevel() local ThreatLevel = target:GetThreatLevel() or 1
local ThreatLevelText = "high" local ThreatLevelText = "high"
if ThreatLevel > 3 and ThreatLevel < 8 then if ThreatLevel > 3 and ThreatLevel < 8 then
ThreatLevelText = "medium" ThreatLevelText = "medium"
@ -1078,7 +1085,7 @@ self:T(self.lid.."_ReportLaserTargets")
local ThreatGraph = "[" .. string.rep( "", ThreatLevel ) .. string.rep( "", 10 - ThreatLevel ) .. "]: "..ThreatLevel local ThreatGraph = "[" .. string.rep( "", ThreatLevel ) .. string.rep( "", 10 - ThreatLevel ) .. "]: "..ThreatLevel
local report = REPORT:New("Lasing Report") local report = REPORT:New("Lasing Report")
report:Add(string.rep("-",15)) report:Add(string.rep("-",15))
report:Add("Target type: "..target:GetTypeName()) report:Add("Target type: "..target:GetTypeName() or "unknown")
report:Add("Threat Level: "..ThreatGraph.." ("..ThreatLevelText..")") report:Add("Threat Level: "..ThreatGraph.." ("..ThreatLevelText..")")
if not self.ReferencePoint then if not self.ReferencePoint then
report:Add("Location: "..client:GetCoordinate():ToStringBULLS(self.Coalition,Settings)) report:Add("Location: "..client:GetCoordinate():ToStringBULLS(self.Coalition,Settings))
@ -1088,14 +1095,14 @@ self:T(self.lid.."_ReportLaserTargets")
report:Add("Laser Code: "..self.UnitLaserCodes[playername] or 1688) report:Add("Laser Code: "..self.UnitLaserCodes[playername] or 1688)
report:Add(string.rep("-",15)) report:Add(string.rep("-",15))
local text = report:Text() local text = report:Text()
self:__TargetReport(-1,client,targetset,target,text) self:__TargetReport(1,client,targetset,target,text)
else else
local report = REPORT:New("Lasing Report") local report = REPORT:New("Lasing Report")
report:Add(string.rep("-",15)) report:Add(string.rep("-",15))
report:Add("N O T A R G E T S") report:Add("N O T A R G E T S")
report:Add(string.rep("-",15)) report:Add(string.rep("-",15))
local text = report:Text() local text = report:Text()
self:__TargetReport(-1,client,nil,nil,text) self:__TargetReport(1,client,nil,nil,text)
end end
return self return self
end end
@ -1130,25 +1137,27 @@ function PLAYERRECCE:_ReportVisualTargets(client,group,playername)
end end
report:Add(string.rep("-",15)) report:Add(string.rep("-",15))
local text = report:Text() local text = report:Text()
self:__TargetReport(-1,client,targetset,nil,text) self:__TargetReport(1,client,targetset,nil,text)
else else
local report = REPORT:New("Target Report") local report = REPORT:New("Target Report")
report:Add(string.rep("-",15)) report:Add(string.rep("-",15))
report:Add("N O T A R G E T S") report:Add("N O T A R G E T S")
report:Add(string.rep("-",15)) report:Add(string.rep("-",15))
local text = report:Text() local text = report:Text()
self:__TargetReport(-1,client,nil,nil,text) self:__TargetReport(1,client,nil,nil,text)
end end
return self return self
end end
--- [Internal] --- [Internal] Build Menus
-- @param #PLAYERRECCE self -- @param #PLAYERRECCE self
-- @param #PLAYERRECCE self -- @param Wrapper.Client#CLIENT Client (optional) Client object
function PLAYERRECCE:_BuildMenus() -- @return #PLAYERRECCE self
function PLAYERRECCE:_BuildMenus(Client)
self:T(self.lid.."_BuildMenus") self:T(self.lid.."_BuildMenus")
local clients = self.PlayerSet -- Core.Set#SET_CLIENT local clients = self.PlayerSet -- Core.Set#SET_CLIENT
local clientset = clients:GetSetObjects() local clientset = clients:GetSetObjects()
if Client then clientset = {Client} end
for _,_client in pairs(clientset) do for _,_client in pairs(clientset) do
local client = _client -- Wrapper.Client#CLIENT local client = _client -- Wrapper.Client#CLIENT
if client and client:IsAlive() then if client and client:IsAlive() then
@ -1156,7 +1165,7 @@ function PLAYERRECCE:_BuildMenus()
if not self.UnitLaserCodes[playername] then if not self.UnitLaserCodes[playername] then
self:_SetClientLaserCode(nil,nil,playername,1688) self:_SetClientLaserCode(nil,nil,playername,1688)
end end
if not self.SmokeOwn[playername] then if self.SmokeOwn[playername] == nil then
self.SmokeOwn[playername] = self.smokeownposition self.SmokeOwn[playername] = self.smokeownposition
end end
local group = client:GetGroup() local group = client:GetGroup()
@ -1919,7 +1928,7 @@ function PLAYERRECCE:onafterTargetReport(From, Event, To, Client, TargetSet, Tar
-- send message to AttackSet -- send message to AttackSet
for _,_client in pairs(self.AttackSet.Set) do for _,_client in pairs(self.AttackSet.Set) do
local client = _client -- Wrapper.Client#CLIENT local client = _client -- Wrapper.Client#CLIENT
if client and client:IsAlive() then if client and client:IsAlive() and client ~= Client then
MESSAGE:New(Text,45,self.Name or "FACA"):ToClient(client) MESSAGE:New(Text,45,self.Name or "FACA"):ToClient(client)
end end
end end

View File

@ -562,3 +562,578 @@ ENUMS.ReportingName =
Predator = "MQ-1A", Predator = "MQ-1A",
} }
} }
--- Enums for the STORAGE class for stores - which need to be in ""
-- @type ENUMS.Storage
-- @type ENUMS.Storage.weapons
ENUMS.Storage = {
weapons = {
missiles = {}, -- Missiles
bombs = {}, -- Bombs
nurs = {}, -- Rockets and unguided
containers = {}, -- Containers
droptanks = {}, -- Droptanks
adapters = {}, -- Adapter
torpedoes = {}, -- Torpedoes
}
}
ENUMS.Storage.weapons.nurs.SNEB_TYPE253_F1B = "weapons.nurs.SNEB_TYPE253_F1B"
ENUMS.Storage.weapons.missiles.P_24T = "weapons.missiles.P_24T"
ENUMS.Storage.weapons.bombs.BLU_3B_OLD = "weapons.bombs.BLU-3B_OLD"
ENUMS.Storage.weapons.missiles.AGM_154 = "weapons.missiles.AGM_154"
ENUMS.Storage.weapons.nurs.HYDRA_70_M151_M433 = "weapons.nurs.HYDRA_70_M151_M433"
ENUMS.Storage.weapons.bombs.SAM_Avenger_M1097_Skid_7090lb = "weapons.bombs.SAM Avenger M1097 Skid [7090lb]"
ENUMS.Storage.weapons.bombs.British_GP_250LB_Bomb_Mk5 = "weapons.bombs.British_GP_250LB_Bomb_Mk5"
ENUMS.Storage.weapons.containers.OV10_SMOKE = "weapons.containers.{OV10_SMOKE}"
ENUMS.Storage.weapons.bombs.BLU_4B_OLD = "weapons.bombs.BLU-4B_OLD"
ENUMS.Storage.weapons.bombs.FAB_500M54 = "weapons.bombs.FAB-500M54"
ENUMS.Storage.weapons.bombs.GBU_38 = "weapons.bombs.GBU_38"
ENUMS.Storage.weapons.containers.F_15E_AXQ_14_DATALINK = "weapons.containers.F-15E_AXQ-14_DATALINK"
ENUMS.Storage.weapons.bombs.BEER_BOMB = "weapons.bombs.BEER_BOMB"
ENUMS.Storage.weapons.bombs.P_50T = "weapons.bombs.P-50T"
ENUMS.Storage.weapons.nurs.C_8CM_GN = "weapons.nurs.C_8CM_GN"
ENUMS.Storage.weapons.bombs.FAB_500SL = "weapons.bombs.FAB-500SL"
ENUMS.Storage.weapons.bombs.KAB_1500Kr = "weapons.bombs.KAB_1500Kr"
ENUMS.Storage.weapons.bombs.two50_2 = "weapons.bombs.250-2"
ENUMS.Storage.weapons.droptanks.Spitfire_tank_1 = "weapons.droptanks.Spitfire_tank_1"
ENUMS.Storage.weapons.missiles.AGM_65G = "weapons.missiles.AGM_65G"
ENUMS.Storage.weapons.missiles.AGM_65A = "weapons.missiles.AGM_65A"
ENUMS.Storage.weapons.containers.Hercules_JATO = "weapons.containers.Hercules_JATO"
ENUMS.Storage.weapons.nurs.HYDRA_70_M259 = "weapons.nurs.HYDRA_70_M259"
ENUMS.Storage.weapons.missiles.AGM_84E = "weapons.missiles.AGM_84E"
ENUMS.Storage.weapons.bombs.AN_M30A1 = "weapons.bombs.AN_M30A1"
ENUMS.Storage.weapons.nurs.C_25 = "weapons.nurs.C_25"
ENUMS.Storage.weapons.containers.AV8BNA_ALQ164 = "weapons.containers.AV8BNA_ALQ164"
ENUMS.Storage.weapons.containers.lav_25 = "weapons.containers.lav-25"
ENUMS.Storage.weapons.missiles.P_60 = "weapons.missiles.P_60"
ENUMS.Storage.weapons.bombs.FAB_1500 = "weapons.bombs.FAB_1500"
ENUMS.Storage.weapons.droptanks.FuelTank_350L = "weapons.droptanks.FuelTank_350L"
ENUMS.Storage.weapons.bombs.AAA_Vulcan_M163_Skid_21577lb = "weapons.bombs.AAA Vulcan M163 Skid [21577lb]"
ENUMS.Storage.weapons.missiles.Kormoran = "weapons.missiles.Kormoran"
ENUMS.Storage.weapons.droptanks.HB_F14_EXT_DROPTANK_EMPTY = "weapons.droptanks.HB_F14_EXT_DROPTANK_EMPTY"
ENUMS.Storage.weapons.droptanks.FuelTank_150L = "weapons.droptanks.FuelTank_150L"
ENUMS.Storage.weapons.missiles.Rb_15F_for_A_I = "weapons.missiles.Rb 15F (for A.I.)"
ENUMS.Storage.weapons.missiles.RB75T = "weapons.missiles.RB75T"
ENUMS.Storage.weapons.missiles.Vikhr_M = "weapons.missiles.Vikhr_M"
ENUMS.Storage.weapons.nurs.FFAR_M156_WP = "weapons.nurs.FFAR M156 WP"
ENUMS.Storage.weapons.nurs.British_HE_60LBSAPNo2_3INCHNo1 = "weapons.nurs.British_HE_60LBSAPNo2_3INCHNo1"
ENUMS.Storage.weapons.missiles.DWS39_MJ2 = "weapons.missiles.DWS39_MJ2"
ENUMS.Storage.weapons.bombs.HEBOMBD = "weapons.bombs.HEBOMBD"
ENUMS.Storage.weapons.missiles.CATM_9M = "weapons.missiles.CATM_9M"
ENUMS.Storage.weapons.bombs.Mk_81 = "weapons.bombs.Mk_81"
ENUMS.Storage.weapons.droptanks.Drop_Tank_300_Liter = "weapons.droptanks.Drop_Tank_300_Liter"
ENUMS.Storage.weapons.containers.HMMWV_M1025 = "weapons.containers.HMMWV_M1025"
ENUMS.Storage.weapons.bombs.SAM_CHAPARRAL_Air_21624lb = "weapons.bombs.SAM CHAPARRAL Air [21624lb]"
ENUMS.Storage.weapons.missiles.AGM_154A = "weapons.missiles.AGM_154A"
ENUMS.Storage.weapons.bombs.Mk_84AIR_TP = "weapons.bombs.Mk_84AIR_TP"
ENUMS.Storage.weapons.bombs.GBU_31_V_3B = "weapons.bombs.GBU_31_V_3B"
ENUMS.Storage.weapons.nurs.C_8CM_WH = "weapons.nurs.C_8CM_WH"
ENUMS.Storage.weapons.missiles.Matra_Super_530D = "weapons.missiles.Matra Super 530D"
ENUMS.Storage.weapons.nurs.ARF8M3TPSM = "weapons.nurs.ARF8M3TPSM"
ENUMS.Storage.weapons.missiles.TGM_65H = "weapons.missiles.TGM_65H"
ENUMS.Storage.weapons.nurs.M8rocket = "weapons.nurs.M8rocket"
ENUMS.Storage.weapons.bombs.GBU_27 = "weapons.bombs.GBU_27"
ENUMS.Storage.weapons.missiles.AGR_20A = "weapons.missiles.AGR_20A"
ENUMS.Storage.weapons.missiles.LS_6_250 = "weapons.missiles.LS-6-250"
ENUMS.Storage.weapons.droptanks.M2KC_RPL_522_EMPTY = "weapons.droptanks.M2KC_RPL_522_EMPTY"
ENUMS.Storage.weapons.droptanks.M2KC_02_RPL541 = "weapons.droptanks.M2KC_02_RPL541"
ENUMS.Storage.weapons.missiles.AGM_45 = "weapons.missiles.AGM_45"
ENUMS.Storage.weapons.missiles.AGM_84A = "weapons.missiles.AGM_84A"
ENUMS.Storage.weapons.bombs.APC_BTR_80_Air_23936lb = "weapons.bombs.APC BTR-80 Air [23936lb]"
ENUMS.Storage.weapons.missiles.P_33E = "weapons.missiles.P_33E"
ENUMS.Storage.weapons.missiles.Ataka_9M120 = "weapons.missiles.Ataka_9M120"
ENUMS.Storage.weapons.bombs.MK76 = "weapons.bombs.MK76"
ENUMS.Storage.weapons.bombs.AB_250_2_SD_2 = "weapons.bombs.AB_250_2_SD_2"
ENUMS.Storage.weapons.missiles.Rb_05A = "weapons.missiles.Rb 05A"
ENUMS.Storage.weapons.bombs.ART_GVOZDIKA_34720lb = "weapons.bombs.ART GVOZDIKA [34720lb]"
ENUMS.Storage.weapons.bombs.Generic_Crate_20000lb = "weapons.bombs.Generic Crate [20000lb]"
ENUMS.Storage.weapons.bombs.FAB_100SV = "weapons.bombs.FAB_100SV"
ENUMS.Storage.weapons.bombs.BetAB_500 = "weapons.bombs.BetAB_500"
ENUMS.Storage.weapons.droptanks.M2KC_02_RPL541_EMPTY = "weapons.droptanks.M2KC_02_RPL541_EMPTY"
ENUMS.Storage.weapons.droptanks.PTB600_MIG15 = "weapons.droptanks.PTB600_MIG15"
ENUMS.Storage.weapons.missiles.Rb_24J = "weapons.missiles.Rb 24J"
ENUMS.Storage.weapons.nurs.C_8CM_BU = "weapons.nurs.C_8CM_BU"
ENUMS.Storage.weapons.nurs.SNEB_TYPE259E_F1B = "weapons.nurs.SNEB_TYPE259E_F1B"
ENUMS.Storage.weapons.nurs.WGr21 = "weapons.nurs.WGr21"
ENUMS.Storage.weapons.bombs.SAMP250HD = "weapons.bombs.SAMP250HD"
ENUMS.Storage.weapons.containers.alq_184long = "weapons.containers.alq-184long"
ENUMS.Storage.weapons.nurs.SNEB_TYPE259E_H1 = "weapons.nurs.SNEB_TYPE259E_H1"
ENUMS.Storage.weapons.bombs.British_SAP_250LB_Bomb_Mk5 = "weapons.bombs.British_SAP_250LB_Bomb_Mk5"
ENUMS.Storage.weapons.bombs.Transport_UAZ_469_Air_3747lb = "weapons.bombs.Transport UAZ-469 Air [3747lb]"
ENUMS.Storage.weapons.bombs.Mk_83CT = "weapons.bombs.Mk_83CT"
ENUMS.Storage.weapons.missiles.AIM_7P = "weapons.missiles.AIM-7P"
ENUMS.Storage.weapons.missiles.AT_6 = "weapons.missiles.AT_6"
ENUMS.Storage.weapons.nurs.SNEB_TYPE254_H1_GREEN = "weapons.nurs.SNEB_TYPE254_H1_GREEN"
ENUMS.Storage.weapons.nurs.SNEB_TYPE250_F1B = "weapons.nurs.SNEB_TYPE250_F1B"
ENUMS.Storage.weapons.containers.U22A = "weapons.containers.U22A"
ENUMS.Storage.weapons.bombs.British_GP_250LB_Bomb_Mk1 = "weapons.bombs.British_GP_250LB_Bomb_Mk1"
ENUMS.Storage.weapons.bombs.CBU_105 = "weapons.bombs.CBU_105"
ENUMS.Storage.weapons.droptanks.FW_190_Fuel_Tank = "weapons.droptanks.FW-190_Fuel-Tank"
ENUMS.Storage.weapons.missiles.X_58 = "weapons.missiles.X_58"
ENUMS.Storage.weapons.missiles.BK90_MJ1_MJ2 = "weapons.missiles.BK90_MJ1_MJ2"
ENUMS.Storage.weapons.missiles.TGM_65D = "weapons.missiles.TGM_65D"
ENUMS.Storage.weapons.containers.BRD_4_250 = "weapons.containers.BRD-4-250"
ENUMS.Storage.weapons.missiles.P_73 = "weapons.missiles.P_73"
ENUMS.Storage.weapons.bombs.AN_M66 = "weapons.bombs.AN_M66"
ENUMS.Storage.weapons.bombs.APC_LAV_25_Air_22520lb = "weapons.bombs.APC LAV-25 Air [22520lb]"
ENUMS.Storage.weapons.missiles.AIM_7MH = "weapons.missiles.AIM-7MH"
ENUMS.Storage.weapons.containers.MB339_TravelPod = "weapons.containers.MB339_TravelPod"
ENUMS.Storage.weapons.bombs.GBU_12 = "weapons.bombs.GBU_12"
ENUMS.Storage.weapons.bombs.SC_250_T3_J = "weapons.bombs.SC_250_T3_J"
ENUMS.Storage.weapons.missiles.KD_20 = "weapons.missiles.KD-20"
ENUMS.Storage.weapons.missiles.AGM_86C = "weapons.missiles.AGM_86C"
ENUMS.Storage.weapons.missiles.X_35 = "weapons.missiles.X_35"
ENUMS.Storage.weapons.bombs.MK106 = "weapons.bombs.MK106"
ENUMS.Storage.weapons.bombs.BETAB_500S = "weapons.bombs.BETAB-500S"
ENUMS.Storage.weapons.nurs.C_5 = "weapons.nurs.C_5"
ENUMS.Storage.weapons.nurs.S_24B = "weapons.nurs.S-24B"
ENUMS.Storage.weapons.bombs.British_MC_500LB_Bomb_Mk2 = "weapons.bombs.British_MC_500LB_Bomb_Mk2"
ENUMS.Storage.weapons.containers.ANAWW_13 = "weapons.containers.ANAWW_13"
ENUMS.Storage.weapons.droptanks.droptank_108_gal = "weapons.droptanks.droptank_108_gal"
ENUMS.Storage.weapons.droptanks.DFT_300_GAL_A4E_LR = "weapons.droptanks.DFT_300_GAL_A4E_LR"
ENUMS.Storage.weapons.bombs.CBU_87 = "weapons.bombs.CBU_87"
ENUMS.Storage.weapons.missiles.GAR_8 = "weapons.missiles.GAR-8"
ENUMS.Storage.weapons.bombs.BELOUGA = "weapons.bombs.BELOUGA"
ENUMS.Storage.weapons.containers.EclairM_33 = "weapons.containers.{EclairM_33}"
ENUMS.Storage.weapons.bombs.ART_2S9_NONA_Air_19140lb = "weapons.bombs.ART 2S9 NONA Air [19140lb]"
ENUMS.Storage.weapons.bombs.BR_250 = "weapons.bombs.BR_250"
ENUMS.Storage.weapons.bombs.IAB_500 = "weapons.bombs.IAB-500"
ENUMS.Storage.weapons.containers.AN_ASQ_228 = "weapons.containers.AN_ASQ_228"
ENUMS.Storage.weapons.missiles.P_27P = "weapons.missiles.P_27P"
ENUMS.Storage.weapons.bombs.SD_250_Stg = "weapons.bombs.SD_250_Stg"
ENUMS.Storage.weapons.missiles.R_530F_IR = "weapons.missiles.R_530F_IR"
ENUMS.Storage.weapons.bombs.British_SAP_500LB_Bomb_Mk5 = "weapons.bombs.British_SAP_500LB_Bomb_Mk5"
ENUMS.Storage.weapons.bombs.FAB_250M54 = "weapons.bombs.FAB-250M54"
ENUMS.Storage.weapons.containers.M2KC_AAF = "weapons.containers.{M2KC_AAF}"
ENUMS.Storage.weapons.missiles.CM_802AKG_AI = "weapons.missiles.CM-802AKG_AI"
ENUMS.Storage.weapons.bombs.CBU_103 = "weapons.bombs.CBU_103"
ENUMS.Storage.weapons.containers.US_M10_SMOKE_TANK_RED = "weapons.containers.{US_M10_SMOKE_TANK_RED}"
ENUMS.Storage.weapons.missiles.X_29T = "weapons.missiles.X_29T"
ENUMS.Storage.weapons.bombs.HEMTT_TFFT_34400lb = "weapons.bombs.HEMTT TFFT [34400lb]"
ENUMS.Storage.weapons.missiles.C_701IR = "weapons.missiles.C-701IR"
ENUMS.Storage.weapons.containers.fullCargoSeats = "weapons.containers.fullCargoSeats"
ENUMS.Storage.weapons.bombs.GBU_15_V_31_B = "weapons.bombs.GBU_15_V_31_B"
ENUMS.Storage.weapons.bombs.APC_M1043_HMMWV_Armament_Air_7023lb = "weapons.bombs.APC M1043 HMMWV Armament Air [7023lb]"
ENUMS.Storage.weapons.missiles.PL_5EII = "weapons.missiles.PL-5EII"
ENUMS.Storage.weapons.bombs.SC_250_T1_L2 = "weapons.bombs.SC_250_T1_L2"
ENUMS.Storage.weapons.torpedoes.mk46torp_name = "weapons.torpedoes.mk46torp_name"
ENUMS.Storage.weapons.containers.F_15E_AAQ_33_XR_ATP_SE = "weapons.containers.F-15E_AAQ-33_XR_ATP-SE"
ENUMS.Storage.weapons.missiles.AIM_7 = "weapons.missiles.AIM_7"
ENUMS.Storage.weapons.missiles.AGM_122 = "weapons.missiles.AGM_122"
ENUMS.Storage.weapons.bombs.HEBOMB = "weapons.bombs.HEBOMB"
ENUMS.Storage.weapons.bombs.CBU_97 = "weapons.bombs.CBU_97"
ENUMS.Storage.weapons.bombs.MK_81SE = "weapons.bombs.MK-81SE"
ENUMS.Storage.weapons.nurs.Zuni_127 = "weapons.nurs.Zuni_127"
ENUMS.Storage.weapons.containers.M2KC_AGF = "weapons.containers.{M2KC_AGF}"
ENUMS.Storage.weapons.droptanks.Hercules_ExtFuelTank = "weapons.droptanks.Hercules_ExtFuelTank"
ENUMS.Storage.weapons.containers.SMOKE_WHITE = "weapons.containers.{SMOKE_WHITE}"
ENUMS.Storage.weapons.droptanks.droptank_150_gal = "weapons.droptanks.droptank_150_gal"
ENUMS.Storage.weapons.nurs.HYDRA_70_WTU1B = "weapons.nurs.HYDRA_70_WTU1B"
ENUMS.Storage.weapons.missiles.GB_6_SFW = "weapons.missiles.GB-6-SFW"
ENUMS.Storage.weapons.missiles.KD_63 = "weapons.missiles.KD-63"
ENUMS.Storage.weapons.bombs.GBU_28 = "weapons.bombs.GBU_28"
ENUMS.Storage.weapons.nurs.C_8CM_YE = "weapons.nurs.C_8CM_YE"
ENUMS.Storage.weapons.droptanks.HB_F14_EXT_DROPTANK = "weapons.droptanks.HB_F14_EXT_DROPTANK"
ENUMS.Storage.weapons.missiles.Super_530F = "weapons.missiles.Super_530F"
ENUMS.Storage.weapons.missiles.Ataka_9M220 = "weapons.missiles.Ataka_9M220"
ENUMS.Storage.weapons.bombs.BDU_33 = "weapons.bombs.BDU_33"
ENUMS.Storage.weapons.bombs.British_GP_250LB_Bomb_Mk4 = "weapons.bombs.British_GP_250LB_Bomb_Mk4"
ENUMS.Storage.weapons.missiles.TOW = "weapons.missiles.TOW"
ENUMS.Storage.weapons.bombs.ATGM_M1045_HMMWV_TOW_Air_7183lb = "weapons.bombs.ATGM M1045 HMMWV TOW Air [7183lb]"
ENUMS.Storage.weapons.missiles.X_25MR = "weapons.missiles.X_25MR"
ENUMS.Storage.weapons.droptanks.fueltank230 = "weapons.droptanks.fueltank230"
ENUMS.Storage.weapons.droptanks.PTB_490C_MIG21 = "weapons.droptanks.PTB-490C-MIG21"
ENUMS.Storage.weapons.bombs.M1025_HMMWV_Air_6160lb = "weapons.bombs.M1025 HMMWV Air [6160lb]"
ENUMS.Storage.weapons.nurs.SNEB_TYPE254_F1B_GREEN = "weapons.nurs.SNEB_TYPE254_F1B_GREEN"
ENUMS.Storage.weapons.missiles.R_550 = "weapons.missiles.R_550"
ENUMS.Storage.weapons.bombs.KAB_1500LG = "weapons.bombs.KAB_1500LG"
ENUMS.Storage.weapons.missiles.AGM_84D = "weapons.missiles.AGM_84D"
ENUMS.Storage.weapons.missiles.YJ_83K = "weapons.missiles.YJ-83K"
ENUMS.Storage.weapons.missiles.AIM_54C_Mk47 = "weapons.missiles.AIM_54C_Mk47"
ENUMS.Storage.weapons.missiles.BRM_1_90MM = "weapons.missiles.BRM-1_90MM"
ENUMS.Storage.weapons.missiles.Ataka_9M120F = "weapons.missiles.Ataka_9M120F"
ENUMS.Storage.weapons.droptanks.Eleven00L_Tank = "weapons.droptanks.1100L Tank"
ENUMS.Storage.weapons.bombs.BAP_100 = "weapons.bombs.BAP_100"
ENUMS.Storage.weapons.adapters.lau_88 = "weapons.adapters.lau-88"
ENUMS.Storage.weapons.missiles.P_40T = "weapons.missiles.P_40T"
ENUMS.Storage.weapons.missiles.GB_6 = "weapons.missiles.GB-6"
ENUMS.Storage.weapons.bombs.FAB_250M54TU = "weapons.bombs.FAB-250M54TU"
ENUMS.Storage.weapons.missiles.DWS39_MJ1 = "weapons.missiles.DWS39_MJ1"
ENUMS.Storage.weapons.missiles.CM_802AKG = "weapons.missiles.CM-802AKG"
ENUMS.Storage.weapons.bombs.FAB_250 = "weapons.bombs.FAB_250"
ENUMS.Storage.weapons.missiles.C_802AK = "weapons.missiles.C_802AK"
ENUMS.Storage.weapons.bombs.SD_500_A = "weapons.bombs.SD_500_A"
ENUMS.Storage.weapons.bombs.GBU_32_V_2B = "weapons.bombs.GBU_32_V_2B"
ENUMS.Storage.weapons.containers.marder = "weapons.containers.marder"
ENUMS.Storage.weapons.missiles.ADM_141B = "weapons.missiles.ADM_141B"
ENUMS.Storage.weapons.bombs.ROCKEYE = "weapons.bombs.ROCKEYE"
ENUMS.Storage.weapons.missiles.BK90_MJ1 = "weapons.missiles.BK90_MJ1"
ENUMS.Storage.weapons.containers.BTR_80 = "weapons.containers.BTR-80"
ENUMS.Storage.weapons.bombs.SAM_ROLAND_ADS_34720lb = "weapons.bombs.SAM ROLAND ADS [34720lb]"
ENUMS.Storage.weapons.containers.wmd7 = "weapons.containers.wmd7"
ENUMS.Storage.weapons.missiles.C_701T = "weapons.missiles.C-701T"
ENUMS.Storage.weapons.missiles.AIM_7E_2 = "weapons.missiles.AIM-7E-2"
ENUMS.Storage.weapons.nurs.HVAR = "weapons.nurs.HVAR"
ENUMS.Storage.weapons.containers.HMMWV_M1043 = "weapons.containers.HMMWV_M1043"
ENUMS.Storage.weapons.droptanks.PTB_800_MIG21 = "weapons.droptanks.PTB-800-MIG21"
ENUMS.Storage.weapons.missiles.AGM_114 = "weapons.missiles.AGM_114"
ENUMS.Storage.weapons.bombs.APC_M1126_Stryker_ICV_29542lb = "weapons.bombs.APC M1126 Stryker ICV [29542lb]"
ENUMS.Storage.weapons.bombs.APC_M113_Air_21624lb = "weapons.bombs.APC M113 Air [21624lb]"
ENUMS.Storage.weapons.bombs.M_117 = "weapons.bombs.M_117"
ENUMS.Storage.weapons.missiles.AGM_65D = "weapons.missiles.AGM_65D"
ENUMS.Storage.weapons.droptanks.MB339_TT320_L = "weapons.droptanks.MB339_TT320_L"
ENUMS.Storage.weapons.missiles.AGM_86 = "weapons.missiles.AGM_86"
ENUMS.Storage.weapons.bombs.BDU_45LGB = "weapons.bombs.BDU_45LGB"
ENUMS.Storage.weapons.missiles.AGM_65H = "weapons.missiles.AGM_65H"
ENUMS.Storage.weapons.nurs.RS_82 = "weapons.nurs.RS-82"
ENUMS.Storage.weapons.nurs.SNEB_TYPE252_F1B = "weapons.nurs.SNEB_TYPE252_F1B"
ENUMS.Storage.weapons.bombs.BL_755 = "weapons.bombs.BL_755"
ENUMS.Storage.weapons.containers.F_15E_AAQ_28_LITENING = "weapons.containers.F-15E_AAQ-28_LITENING"
ENUMS.Storage.weapons.nurs.SNEB_TYPE256_F1B = "weapons.nurs.SNEB_TYPE256_F1B"
ENUMS.Storage.weapons.missiles.AGM_84H = "weapons.missiles.AGM_84H"
ENUMS.Storage.weapons.missiles.AIM_54 = "weapons.missiles.AIM_54"
ENUMS.Storage.weapons.missiles.X_31A = "weapons.missiles.X_31A"
ENUMS.Storage.weapons.bombs.KAB_500Kr = "weapons.bombs.KAB_500Kr"
ENUMS.Storage.weapons.containers.SPS_141_100 = "weapons.containers.SPS-141-100"
ENUMS.Storage.weapons.missiles.BK90_MJ2 = "weapons.missiles.BK90_MJ2"
ENUMS.Storage.weapons.missiles.Super_530D = "weapons.missiles.Super_530D"
ENUMS.Storage.weapons.bombs.CBU_52B = "weapons.bombs.CBU_52B"
ENUMS.Storage.weapons.droptanks.PTB_450 = "weapons.droptanks.PTB-450"
ENUMS.Storage.weapons.bombs.IFV_MCV_80_34720lb = "weapons.bombs.IFV MCV-80 [34720lb]"
ENUMS.Storage.weapons.containers.Two_c9 = "weapons.containers.2-c9"
ENUMS.Storage.weapons.missiles.AIM_9JULI = "weapons.missiles.AIM-9JULI"
ENUMS.Storage.weapons.droptanks.MB339_TT500_R = "weapons.droptanks.MB339_TT500_R"
ENUMS.Storage.weapons.nurs.C_8CM = "weapons.nurs.C_8CM"
ENUMS.Storage.weapons.containers.BARAX = "weapons.containers.BARAX"
ENUMS.Storage.weapons.missiles.P_40R = "weapons.missiles.P_40R"
ENUMS.Storage.weapons.missiles.YJ_12 = "weapons.missiles.YJ-12"
ENUMS.Storage.weapons.missiles.CM_802AKG = "weapons.missiles.CM_802AKG"
ENUMS.Storage.weapons.nurs.SNEB_TYPE254_H1_YELLOW = "weapons.nurs.SNEB_TYPE254_H1_YELLOW"
ENUMS.Storage.weapons.bombs.Durandal = "weapons.bombs.Durandal"
ENUMS.Storage.weapons.droptanks.i16_eft = "weapons.droptanks.i16_eft"
ENUMS.Storage.weapons.droptanks.AV8BNA_AERO1D_EMPTY = "weapons.droptanks.AV8BNA_AERO1D_EMPTY"
ENUMS.Storage.weapons.containers.Hercules_Battle_Station_TGP = "weapons.containers.Hercules_Battle_Station_TGP"
ENUMS.Storage.weapons.nurs.C_8CM_VT = "weapons.nurs.C_8CM_VT"
ENUMS.Storage.weapons.missiles.PL_12 = "weapons.missiles.PL-12"
ENUMS.Storage.weapons.missiles.R_3R = "weapons.missiles.R-3R"
ENUMS.Storage.weapons.bombs.GBU_54_V_1B = "weapons.bombs.GBU_54_V_1B"
ENUMS.Storage.weapons.droptanks.MB339_TT320_R = "weapons.droptanks.MB339_TT320_R"
ENUMS.Storage.weapons.bombs.RN_24 = "weapons.bombs.RN-24"
ENUMS.Storage.weapons.containers.Twoc6m = "weapons.containers.2c6m"
ENUMS.Storage.weapons.bombs.ARV_BRDM_2_Air_12320lb = "weapons.bombs.ARV BRDM-2 Air [12320lb]"
ENUMS.Storage.weapons.bombs.ARV_BRDM_2_Skid_12210lb = "weapons.bombs.ARV BRDM-2 Skid [12210lb]"
ENUMS.Storage.weapons.nurs.SNEB_TYPE251_F1B = "weapons.nurs.SNEB_TYPE251_F1B"
ENUMS.Storage.weapons.missiles.X_41 = "weapons.missiles.X_41"
ENUMS.Storage.weapons.containers.MIG21_SMOKE_WHITE = "weapons.containers.{MIG21_SMOKE_WHITE}"
ENUMS.Storage.weapons.bombs.MK_82AIR = "weapons.bombs.MK_82AIR"
ENUMS.Storage.weapons.missiles.R_530F_EM = "weapons.missiles.R_530F_EM"
ENUMS.Storage.weapons.bombs.SAMP400LD = "weapons.bombs.SAMP400LD"
ENUMS.Storage.weapons.bombs.FAB_50 = "weapons.bombs.FAB_50"
ENUMS.Storage.weapons.bombs.AB_250_2_SD_10A = "weapons.bombs.AB_250_2_SD_10A"
ENUMS.Storage.weapons.missiles.ADM_141A = "weapons.missiles.ADM_141A"
ENUMS.Storage.weapons.containers.KBpod = "weapons.containers.KBpod"
ENUMS.Storage.weapons.bombs.British_GP_500LB_Bomb_Mk4 = "weapons.bombs.British_GP_500LB_Bomb_Mk4"
ENUMS.Storage.weapons.missiles.AGM_65E = "weapons.missiles.AGM_65E"
ENUMS.Storage.weapons.containers.sa342_dipole_antenna = "weapons.containers.sa342_dipole_antenna"
ENUMS.Storage.weapons.bombs.OFAB_100_Jupiter = "weapons.bombs.OFAB-100 Jupiter"
ENUMS.Storage.weapons.nurs.SNEB_TYPE257_F1B = "weapons.nurs.SNEB_TYPE257_F1B"
ENUMS.Storage.weapons.missiles.Rb_04E_for_A_I = "weapons.missiles.Rb 04E (for A.I.)"
ENUMS.Storage.weapons.bombs.AN_M66A2 = "weapons.bombs.AN-M66A2"
ENUMS.Storage.weapons.missiles.P_27T = "weapons.missiles.P_27T"
ENUMS.Storage.weapons.droptanks.LNS_VIG_XTANK = "weapons.droptanks.LNS_VIG_XTANK"
ENUMS.Storage.weapons.missiles.R_55 = "weapons.missiles.R-55"
ENUMS.Storage.weapons.torpedoes.YU_6 = "weapons.torpedoes.YU-6"
ENUMS.Storage.weapons.bombs.British_MC_250LB_Bomb_Mk2 = "weapons.bombs.British_MC_250LB_Bomb_Mk2"
ENUMS.Storage.weapons.droptanks.PTB_120_F86F35 = "weapons.droptanks.PTB_120_F86F35"
ENUMS.Storage.weapons.missiles.PL_8B = "weapons.missiles.PL-8B"
ENUMS.Storage.weapons.droptanks.F_15E_Drop_Tank_Empty = "weapons.droptanks.F-15E_Drop_Tank_Empty"
ENUMS.Storage.weapons.nurs.British_HE_60LBFNo1_3INCHNo1 = "weapons.nurs.British_HE_60LBFNo1_3INCHNo1"
ENUMS.Storage.weapons.missiles.P_77 = "weapons.missiles.P_77"
ENUMS.Storage.weapons.torpedoes.LTF_5B = "weapons.torpedoes.LTF_5B"
ENUMS.Storage.weapons.missiles.R_3S = "weapons.missiles.R-3S"
ENUMS.Storage.weapons.nurs.SNEB_TYPE253_H1 = "weapons.nurs.SNEB_TYPE253_H1"
ENUMS.Storage.weapons.missiles.PL_8A = "weapons.missiles.PL-8A"
ENUMS.Storage.weapons.bombs.APC_BTR_82A_Skid_24888lb = "weapons.bombs.APC BTR-82A Skid [24888lb]"
ENUMS.Storage.weapons.containers.Sborka = "weapons.containers.Sborka"
ENUMS.Storage.weapons.missiles.AGM_65L = "weapons.missiles.AGM_65L"
ENUMS.Storage.weapons.missiles.X_28 = "weapons.missiles.X_28"
ENUMS.Storage.weapons.missiles.TGM_65G = "weapons.missiles.TGM_65G"
ENUMS.Storage.weapons.nurs.SNEB_TYPE257_H1 = "weapons.nurs.SNEB_TYPE257_H1"
ENUMS.Storage.weapons.missiles.RB75B = "weapons.missiles.RB75B"
ENUMS.Storage.weapons.missiles.X_25ML = "weapons.missiles.X_25ML"
ENUMS.Storage.weapons.droptanks.FPU_8A = "weapons.droptanks.FPU_8A"
ENUMS.Storage.weapons.bombs.BLG66 = "weapons.bombs.BLG66"
ENUMS.Storage.weapons.nurs.C_8CM_RD = "weapons.nurs.C_8CM_RD"
ENUMS.Storage.weapons.containers.EclairM_06 = "weapons.containers.{EclairM_06}"
ENUMS.Storage.weapons.bombs.RBK_500AO = "weapons.bombs.RBK_500AO"
ENUMS.Storage.weapons.missiles.AIM_9P = "weapons.missiles.AIM-9P"
ENUMS.Storage.weapons.bombs.British_GP_500LB_Bomb_Mk4_Short = "weapons.bombs.British_GP_500LB_Bomb_Mk4_Short"
ENUMS.Storage.weapons.containers.MB339_Vinten = "weapons.containers.MB339_Vinten"
ENUMS.Storage.weapons.missiles.Rb_15F = "weapons.missiles.Rb 15F"
ENUMS.Storage.weapons.nurs.ARAKM70BHE = "weapons.nurs.ARAKM70BHE"
ENUMS.Storage.weapons.bombs.AAA_Vulcan_M163_Air_21666lb = "weapons.bombs.AAA Vulcan M163 Air [21666lb]"
ENUMS.Storage.weapons.missiles.X_29L = "weapons.missiles.X_29L"
ENUMS.Storage.weapons.containers.F14_LANTIRN_TP = "weapons.containers.{F14-LANTIRN-TP}"
ENUMS.Storage.weapons.bombs.FAB_250_M62 = "weapons.bombs.FAB-250-M62"
ENUMS.Storage.weapons.missiles.AIM_120C = "weapons.missiles.AIM_120C"
ENUMS.Storage.weapons.bombs.EWR_SBORKA_Air_21624lb = "weapons.bombs.EWR SBORKA Air [21624lb]"
ENUMS.Storage.weapons.bombs.SAMP250LD = "weapons.bombs.SAMP250LD"
ENUMS.Storage.weapons.droptanks.Spitfire_slipper_tank = "weapons.droptanks.Spitfire_slipper_tank"
ENUMS.Storage.weapons.missiles.LS_6_500 = "weapons.missiles.LS-6-500"
ENUMS.Storage.weapons.bombs.GBU_31_V_4B = "weapons.bombs.GBU_31_V_4B"
ENUMS.Storage.weapons.droptanks.PTB400_MIG15 = "weapons.droptanks.PTB400_MIG15"
ENUMS.Storage.weapons.containers.m_113 = "weapons.containers.m-113"
ENUMS.Storage.weapons.bombs.SPG_M1128_Stryker_MGS_33036lb = "weapons.bombs.SPG M1128 Stryker MGS [33036lb]"
ENUMS.Storage.weapons.missiles.AIM_9L = "weapons.missiles.AIM-9L"
ENUMS.Storage.weapons.missiles.AIM_9X = "weapons.missiles.AIM_9X"
ENUMS.Storage.weapons.nurs.C_8 = "weapons.nurs.C_8"
ENUMS.Storage.weapons.bombs.SAM_CHAPARRAL_Skid_21516lb = "weapons.bombs.SAM CHAPARRAL Skid [21516lb]"
ENUMS.Storage.weapons.missiles.P_27TE = "weapons.missiles.P_27TE"
ENUMS.Storage.weapons.bombs.ODAB_500PM = "weapons.bombs.ODAB-500PM"
ENUMS.Storage.weapons.bombs.MK77mod1_WPN = "weapons.bombs.MK77mod1-WPN"
ENUMS.Storage.weapons.droptanks.PTB400_MIG19 = "weapons.droptanks.PTB400_MIG19"
ENUMS.Storage.weapons.torpedoes.Mark_46 = "weapons.torpedoes.Mark_46"
ENUMS.Storage.weapons.containers.rightSeat = "weapons.containers.rightSeat"
ENUMS.Storage.weapons.containers.US_M10_SMOKE_TANK_ORANGE = "weapons.containers.{US_M10_SMOKE_TANK_ORANGE}"
ENUMS.Storage.weapons.bombs.SAB_100MN = "weapons.bombs.SAB_100MN"
ENUMS.Storage.weapons.nurs.FFAR_Mk5_HEAT = "weapons.nurs.FFAR Mk5 HEAT"
ENUMS.Storage.weapons.bombs.IFV_TPZ_FUCH_33440lb = "weapons.bombs.IFV TPZ FUCH [33440lb]"
ENUMS.Storage.weapons.bombs.IFV_M2A2_Bradley_34720lb = "weapons.bombs.IFV M2A2 Bradley [34720lb]"
ENUMS.Storage.weapons.bombs.MK77mod0_WPN = "weapons.bombs.MK77mod0-WPN"
ENUMS.Storage.weapons.containers.ASO_2 = "weapons.containers.ASO-2"
ENUMS.Storage.weapons.bombs.Mk_84AIR_GP = "weapons.bombs.Mk_84AIR_GP"
ENUMS.Storage.weapons.nurs.S_24A = "weapons.nurs.S-24A"
ENUMS.Storage.weapons.bombs.RBK_250_275_AO_1SCH = "weapons.bombs.RBK_250_275_AO_1SCH"
ENUMS.Storage.weapons.bombs.Transport_Tigr_Skid_15730lb = "weapons.bombs.Transport Tigr Skid [15730lb]"
ENUMS.Storage.weapons.missiles.AIM_7F = "weapons.missiles.AIM-7F"
ENUMS.Storage.weapons.bombs.CBU_99 = "weapons.bombs.CBU_99"
ENUMS.Storage.weapons.bombs.LUU_2B = "weapons.bombs.LUU_2B"
ENUMS.Storage.weapons.bombs.FAB_500TA = "weapons.bombs.FAB-500TA"
ENUMS.Storage.weapons.missiles.AGR_20_M282 = "weapons.missiles.AGR_20_M282"
ENUMS.Storage.weapons.droptanks.MB339_FT330 = "weapons.droptanks.MB339_FT330"
ENUMS.Storage.weapons.bombs.SAMP125LD = "weapons.bombs.SAMP125LD"
ENUMS.Storage.weapons.missiles.X_25MP = "weapons.missiles.X_25MP"
ENUMS.Storage.weapons.nurs.SNEB_TYPE252_H1 = "weapons.nurs.SNEB_TYPE252_H1"
ENUMS.Storage.weapons.missiles.AGM_65F = "weapons.missiles.AGM_65F"
ENUMS.Storage.weapons.missiles.AIM_9P5 = "weapons.missiles.AIM-9P5"
ENUMS.Storage.weapons.bombs.Transport_Tigr_Air_15900lb = "weapons.bombs.Transport Tigr Air [15900lb]"
ENUMS.Storage.weapons.nurs.SNEB_TYPE254_H1_RED = "weapons.nurs.SNEB_TYPE254_H1_RED"
ENUMS.Storage.weapons.nurs.FFAR_Mk1_HE = "weapons.nurs.FFAR Mk1 HE"
ENUMS.Storage.weapons.nurs.SPRD_99 = "weapons.nurs.SPRD-99"
ENUMS.Storage.weapons.bombs.BIN_200 = "weapons.bombs.BIN_200"
ENUMS.Storage.weapons.bombs.BLU_4B_GROUP = "weapons.bombs.BLU_4B_GROUP"
ENUMS.Storage.weapons.bombs.GBU_24 = "weapons.bombs.GBU_24"
ENUMS.Storage.weapons.missiles.Rb_04E = "weapons.missiles.Rb 04E"
ENUMS.Storage.weapons.missiles.Rb_74 = "weapons.missiles.Rb 74"
ENUMS.Storage.weapons.containers.leftSeat = "weapons.containers.leftSeat"
ENUMS.Storage.weapons.bombs.LS_6_100 = "weapons.bombs.LS-6-100"
ENUMS.Storage.weapons.bombs.Transport_URAL_375_14815lb = "weapons.bombs.Transport URAL-375 [14815lb]"
ENUMS.Storage.weapons.containers.US_M10_SMOKE_TANK_GREEN = "weapons.containers.{US_M10_SMOKE_TANK_GREEN}"
ENUMS.Storage.weapons.missiles.X_22 = "weapons.missiles.X_22"
ENUMS.Storage.weapons.containers.FAS = "weapons.containers.FAS"
ENUMS.Storage.weapons.nurs.S_25_O = "weapons.nurs.S-25-O"
ENUMS.Storage.weapons.droptanks.para = "weapons.droptanks.para"
ENUMS.Storage.weapons.droptanks.F_15E_Drop_Tank = "weapons.droptanks.F-15E_Drop_Tank"
ENUMS.Storage.weapons.droptanks.M2KC_08_RPL541_EMPTY = "weapons.droptanks.M2KC_08_RPL541_EMPTY"
ENUMS.Storage.weapons.missiles.X_31P = "weapons.missiles.X_31P"
ENUMS.Storage.weapons.bombs.RBK_500U = "weapons.bombs.RBK_500U"
ENUMS.Storage.weapons.missiles.AIM_54A_Mk47 = "weapons.missiles.AIM_54A_Mk47"
ENUMS.Storage.weapons.droptanks.oiltank = "weapons.droptanks.oiltank"
ENUMS.Storage.weapons.missiles.AGM_154B = "weapons.missiles.AGM_154B"
ENUMS.Storage.weapons.containers.MB339_SMOKE_POD = "weapons.containers.MB339_SMOKE-POD"
ENUMS.Storage.weapons.containers.ECM_POD_L_175V = "weapons.containers.{ECM_POD_L_175V}"
ENUMS.Storage.weapons.droptanks.PTB_580G_F1 = "weapons.droptanks.PTB_580G_F1"
ENUMS.Storage.weapons.containers.EclairM_15 = "weapons.containers.{EclairM_15}"
ENUMS.Storage.weapons.containers.F_15E_AAQ_13_LANTIRN = "weapons.containers.F-15E_AAQ-13_LANTIRN"
ENUMS.Storage.weapons.droptanks.Eight00L_Tank_Empty = "weapons.droptanks.800L Tank Empty"
ENUMS.Storage.weapons.containers.One6c_hts_pod = "weapons.containers.16c_hts_pod"
ENUMS.Storage.weapons.bombs.AN_M81 = "weapons.bombs.AN-M81"
ENUMS.Storage.weapons.droptanks.Mosquito_Drop_Tank_100gal = "weapons.droptanks.Mosquito_Drop_Tank_100gal"
ENUMS.Storage.weapons.droptanks.Mosquito_Drop_Tank_50gal = "weapons.droptanks.Mosquito_Drop_Tank_50gal"
ENUMS.Storage.weapons.droptanks.DFT_150_GAL_A4E = "weapons.droptanks.DFT_150_GAL_A4E"
ENUMS.Storage.weapons.missiles.AIM_9 = "weapons.missiles.AIM_9"
ENUMS.Storage.weapons.bombs.IFV_BTR_D_Air_18040lb = "weapons.bombs.IFV BTR-D Air [18040lb]"
ENUMS.Storage.weapons.containers.EclairM_42 = "weapons.containers.{EclairM_42}"
ENUMS.Storage.weapons.bombs.KAB_1500T = "weapons.bombs.KAB_1500T"
ENUMS.Storage.weapons.droptanks.PTB_490_MIG21 = "weapons.droptanks.PTB-490-MIG21"
ENUMS.Storage.weapons.droptanks.PTB_200_F86F35 = "weapons.droptanks.PTB_200_F86F35"
ENUMS.Storage.weapons.droptanks.PTB760_MIG19 = "weapons.droptanks.PTB760_MIG19"
ENUMS.Storage.weapons.bombs.GBU_43_B_MOAB = "weapons.bombs.GBU-43/B(MOAB)"
ENUMS.Storage.weapons.torpedoes.G7A_T1 = "weapons.torpedoes.G7A_T1"
ENUMS.Storage.weapons.bombs.IFV_BMD_1_Air_18040lb = "weapons.bombs.IFV BMD-1 Air [18040lb]"
ENUMS.Storage.weapons.bombs.SAM_LINEBACKER_34720lb = "weapons.bombs.SAM LINEBACKER [34720lb]"
ENUMS.Storage.weapons.containers.ais_pod_t50_r = "weapons.containers.ais-pod-t50_r"
ENUMS.Storage.weapons.containers.CE2_SMOKE_WHITE = "weapons.containers.{CE2_SMOKE_WHITE}"
ENUMS.Storage.weapons.droptanks.fuel_tank_230 = "weapons.droptanks.fuel_tank_230"
ENUMS.Storage.weapons.droptanks.M2KC_RPL_522 = "weapons.droptanks.M2KC_RPL_522"
ENUMS.Storage.weapons.missiles.AGM_130 = "weapons.missiles.AGM_130"
ENUMS.Storage.weapons.droptanks.Eight00L_Tank = "weapons.droptanks.800L Tank"
ENUMS.Storage.weapons.bombs.IFV_BTR_D_Skid_17930lb = "weapons.bombs.IFV BTR-D Skid [17930lb]"
ENUMS.Storage.weapons.containers.bmp_1 = "weapons.containers.bmp-1"
ENUMS.Storage.weapons.bombs.GBU_31 = "weapons.bombs.GBU_31"
ENUMS.Storage.weapons.containers.aaq_28LEFT_litening = "weapons.containers.aaq-28LEFT litening"
ENUMS.Storage.weapons.missiles.Kh_66_Grom = "weapons.missiles.Kh-66_Grom"
ENUMS.Storage.weapons.containers.MIG21_SMOKE_RED = "weapons.containers.{MIG21_SMOKE_RED}"
ENUMS.Storage.weapons.containers.U22 = "weapons.containers.U22"
ENUMS.Storage.weapons.bombs.IFV_BMD_1_Skid_17930lb = "weapons.bombs.IFV BMD-1 Skid [17930lb]"
ENUMS.Storage.weapons.droptanks.Bidon = "weapons.droptanks.Bidon"
ENUMS.Storage.weapons.bombs.GBU_31_V_2B = "weapons.bombs.GBU_31_V_2B"
ENUMS.Storage.weapons.bombs.Mk_82Y = "weapons.bombs.Mk_82Y"
ENUMS.Storage.weapons.containers.pl5eii = "weapons.containers.pl5eii"
ENUMS.Storage.weapons.bombs.RBK_500U_OAB_2_5RT = "weapons.bombs.RBK_500U_OAB_2_5RT"
ENUMS.Storage.weapons.bombs.British_GP_500LB_Bomb_Mk5 = "weapons.bombs.British_GP_500LB_Bomb_Mk5"
ENUMS.Storage.weapons.containers.Eclair = "weapons.containers.{Eclair}"
ENUMS.Storage.weapons.nurs.S5MO_HEFRAG_FFAR = "weapons.nurs.S5MO_HEFRAG_FFAR"
ENUMS.Storage.weapons.bombs.BETAB_500M = "weapons.bombs.BETAB-500M"
ENUMS.Storage.weapons.bombs.Transport_M818_16000lb = "weapons.bombs.Transport M818 [16000lb]"
ENUMS.Storage.weapons.bombs.British_MC_250LB_Bomb_Mk1 = "weapons.bombs.British_MC_250LB_Bomb_Mk1"
ENUMS.Storage.weapons.nurs.SNEB_TYPE251_H1 = "weapons.nurs.SNEB_TYPE251_H1"
ENUMS.Storage.weapons.bombs.TYPE_200A = "weapons.bombs.TYPE-200A"
ENUMS.Storage.weapons.nurs.HYDRA_70_M151 = "weapons.nurs.HYDRA_70_M151"
ENUMS.Storage.weapons.bombs.IFV_BMP_3_32912lb = "weapons.bombs.IFV BMP-3 [32912lb]"
ENUMS.Storage.weapons.bombs.APC_MTLB_Air_26400lb = "weapons.bombs.APC MTLB Air [26400lb]"
ENUMS.Storage.weapons.nurs.HYDRA_70_M229 = "weapons.nurs.HYDRA_70_M229"
ENUMS.Storage.weapons.bombs.BDU_45 = "weapons.bombs.BDU_45"
ENUMS.Storage.weapons.bombs.OFAB_100_120TU = "weapons.bombs.OFAB-100-120TU"
ENUMS.Storage.weapons.missiles.AIM_9J = "weapons.missiles.AIM-9J"
ENUMS.Storage.weapons.nurs.ARF8M3API = "weapons.nurs.ARF8M3API"
ENUMS.Storage.weapons.bombs.BetAB_500ShP = "weapons.bombs.BetAB_500ShP"
ENUMS.Storage.weapons.nurs.C_8OFP2 = "weapons.nurs.C_8OFP2"
ENUMS.Storage.weapons.bombs.GBU_10 = "weapons.bombs.GBU_10"
ENUMS.Storage.weapons.bombs.APC_MTLB_Skid_26290lb = "weapons.bombs.APC MTLB Skid [26290lb]"
ENUMS.Storage.weapons.nurs.SNEB_TYPE254_F1B_RED = "weapons.nurs.SNEB_TYPE254_F1B_RED"
ENUMS.Storage.weapons.missiles.X_65 = "weapons.missiles.X_65"
ENUMS.Storage.weapons.missiles.R_550_M1 = "weapons.missiles.R_550_M1"
ENUMS.Storage.weapons.missiles.AGM_65K = "weapons.missiles.AGM_65K"
ENUMS.Storage.weapons.nurs.SNEB_TYPE254_F1B_YELLOW = "weapons.nurs.SNEB_TYPE254_F1B_YELLOW"
ENUMS.Storage.weapons.missiles.AGM_88 = "weapons.missiles.AGM_88"
ENUMS.Storage.weapons.nurs.C_8OM = "weapons.nurs.C_8OM"
ENUMS.Storage.weapons.bombs.SAM_ROLAND_LN_34720b = "weapons.bombs.SAM ROLAND LN [34720b]"
ENUMS.Storage.weapons.missiles.AIM_120 = "weapons.missiles.AIM_120"
ENUMS.Storage.weapons.missiles.HOT3_MBDA = "weapons.missiles.HOT3_MBDA"
ENUMS.Storage.weapons.missiles.R_13M = "weapons.missiles.R-13M"
ENUMS.Storage.weapons.missiles.AIM_54C_Mk60 = "weapons.missiles.AIM_54C_Mk60"
ENUMS.Storage.weapons.bombs.AAA_GEPARD_34720lb = "weapons.bombs.AAA GEPARD [34720lb]"
ENUMS.Storage.weapons.missiles.R_13M1 = "weapons.missiles.R-13M1"
ENUMS.Storage.weapons.bombs.APC_Cobra_Air_10912lb = "weapons.bombs.APC Cobra Air [10912lb]"
ENUMS.Storage.weapons.bombs.RBK_250 = "weapons.bombs.RBK_250"
ENUMS.Storage.weapons.bombs.SC_500_J = "weapons.bombs.SC_500_J"
ENUMS.Storage.weapons.missiles.AGM_114K = "weapons.missiles.AGM_114K"
ENUMS.Storage.weapons.missiles.ALARM = "weapons.missiles.ALARM"
ENUMS.Storage.weapons.bombs.Mk_83 = "weapons.bombs.Mk_83"
ENUMS.Storage.weapons.missiles.AGM_65B = "weapons.missiles.AGM_65B"
ENUMS.Storage.weapons.bombs.MK_82SNAKEYE = "weapons.bombs.MK_82SNAKEYE"
ENUMS.Storage.weapons.nurs.HYDRA_70_MK1 = "weapons.nurs.HYDRA_70_MK1"
ENUMS.Storage.weapons.bombs.BLG66_BELOUGA = "weapons.bombs.BLG66_BELOUGA"
ENUMS.Storage.weapons.containers.EclairM_51 = "weapons.containers.{EclairM_51}"
ENUMS.Storage.weapons.missiles.AIM_54A_Mk60 = "weapons.missiles.AIM_54A_Mk60"
ENUMS.Storage.weapons.droptanks.DFT_300_GAL_A4E = "weapons.droptanks.DFT_300_GAL_A4E"
ENUMS.Storage.weapons.bombs.ATGM_M1134_Stryker_30337lb = "weapons.bombs.ATGM M1134 Stryker [30337lb]"
ENUMS.Storage.weapons.bombs.BAT_120 = "weapons.bombs.BAT-120"
ENUMS.Storage.weapons.missiles.DWS39_MJ1_MJ2 = "weapons.missiles.DWS39_MJ1_MJ2"
ENUMS.Storage.weapons.containers.SPRD = "weapons.containers.SPRD"
ENUMS.Storage.weapons.bombs.BR_500 = "weapons.bombs.BR_500"
ENUMS.Storage.weapons.bombs.British_GP_500LB_Bomb_Mk1 = "weapons.bombs.British_GP_500LB_Bomb_Mk1"
ENUMS.Storage.weapons.bombs.BDU_50HD = "weapons.bombs.BDU_50HD"
ENUMS.Storage.weapons.missiles.RS2US = "weapons.missiles.RS2US"
ENUMS.Storage.weapons.bombs.IFV_BMP_2_25168lb = "weapons.bombs.IFV BMP-2 [25168lb]"
ENUMS.Storage.weapons.bombs.SAMP400HD = "weapons.bombs.SAMP400HD"
ENUMS.Storage.weapons.containers.Hercules_Battle_Station = "weapons.containers.Hercules_Battle_Station"
ENUMS.Storage.weapons.bombs.AN_M64 = "weapons.bombs.AN_M64"
ENUMS.Storage.weapons.containers.rearCargoSeats = "weapons.containers.rearCargoSeats"
ENUMS.Storage.weapons.bombs.Mk_82 = "weapons.bombs.Mk_82"
ENUMS.Storage.weapons.missiles.AKD_10 = "weapons.missiles.AKD-10"
ENUMS.Storage.weapons.bombs.BDU_50LGB = "weapons.bombs.BDU_50LGB"
ENUMS.Storage.weapons.missiles.SD_10 = "weapons.missiles.SD-10"
ENUMS.Storage.weapons.containers.IRDeflector = "weapons.containers.IRDeflector"
ENUMS.Storage.weapons.bombs.FAB_500 = "weapons.bombs.FAB_500"
ENUMS.Storage.weapons.bombs.KAB_500 = "weapons.bombs.KAB_500"
ENUMS.Storage.weapons.nurs.S_5M = "weapons.nurs.S-5M"
ENUMS.Storage.weapons.missiles.MICA_R = "weapons.missiles.MICA_R"
ENUMS.Storage.weapons.missiles.X_59M = "weapons.missiles.X_59M"
ENUMS.Storage.weapons.nurs.UG_90MM = "weapons.nurs.UG_90MM"
ENUMS.Storage.weapons.bombs.LYSBOMB = "weapons.bombs.LYSBOMB"
ENUMS.Storage.weapons.nurs.R4M = "weapons.nurs.R4M"
ENUMS.Storage.weapons.containers.dlpod_akg = "weapons.containers.dlpod_akg"
ENUMS.Storage.weapons.missiles.LD_10 = "weapons.missiles.LD-10"
ENUMS.Storage.weapons.bombs.SC_50 = "weapons.bombs.SC_50"
ENUMS.Storage.weapons.nurs.HYDRA_70_MK5 = "weapons.nurs.HYDRA_70_MK5"
ENUMS.Storage.weapons.bombs.FAB_100M = "weapons.bombs.FAB_100M"
ENUMS.Storage.weapons.missiles.Rb_24 = "weapons.missiles.Rb 24"
ENUMS.Storage.weapons.bombs.BDU_45B = "weapons.bombs.BDU_45B"
ENUMS.Storage.weapons.missiles.GB_6_HE = "weapons.missiles.GB-6-HE"
ENUMS.Storage.weapons.missiles.KD_63B = "weapons.missiles.KD-63B"
ENUMS.Storage.weapons.missiles.P_27PE = "weapons.missiles.P_27PE"
ENUMS.Storage.weapons.droptanks.PTB300_MIG15 = "weapons.droptanks.PTB300_MIG15"
ENUMS.Storage.weapons.bombs.Two50_3 = "weapons.bombs.250-3"
ENUMS.Storage.weapons.bombs.SC_500_L2 = "weapons.bombs.SC_500_L2"
ENUMS.Storage.weapons.containers.HMMWV_M1045 = "weapons.containers.HMMWV_M1045"
ENUMS.Storage.weapons.bombs.FAB_500M54TU = "weapons.bombs.FAB-500M54TU"
ENUMS.Storage.weapons.containers.US_M10_SMOKE_TANK_YELLOW = "weapons.containers.{US_M10_SMOKE_TANK_YELLOW}"
ENUMS.Storage.weapons.containers.EclairM_60 = "weapons.containers.{EclairM_60}"
ENUMS.Storage.weapons.bombs.SAB_250_200 = "weapons.bombs.SAB_250_200"
ENUMS.Storage.weapons.bombs.FAB_100 = "weapons.bombs.FAB_100"
ENUMS.Storage.weapons.bombs.KAB_500S = "weapons.bombs.KAB_500S"
ENUMS.Storage.weapons.missiles.AGM_45A = "weapons.missiles.AGM_45A"
ENUMS.Storage.weapons.missiles.Kh25MP_PRGS1VP = "weapons.missiles.Kh25MP_PRGS1VP"
ENUMS.Storage.weapons.nurs.S5M1_HEFRAG_FFAR = "weapons.nurs.S5M1_HEFRAG_FFAR"
ENUMS.Storage.weapons.containers.kg600 = "weapons.containers.kg600"
ENUMS.Storage.weapons.bombs.AN_M65 = "weapons.bombs.AN_M65"
ENUMS.Storage.weapons.bombs.AN_M57 = "weapons.bombs.AN_M57"
ENUMS.Storage.weapons.bombs.BLU_3B_GROUP = "weapons.bombs.BLU_3B_GROUP"
ENUMS.Storage.weapons.bombs.BAP_100 = "weapons.bombs.BAP-100"
ENUMS.Storage.weapons.containers.HEMTT = "weapons.containers.HEMTT"
ENUMS.Storage.weapons.bombs.British_MC_500LB_Bomb_Mk1_Short = "weapons.bombs.British_MC_500LB_Bomb_Mk1_Short"
ENUMS.Storage.weapons.nurs.ARAKM70BAP = "weapons.nurs.ARAKM70BAP"
ENUMS.Storage.weapons.missiles.AGM_119 = "weapons.missiles.AGM_119"
ENUMS.Storage.weapons.missiles.MMagicII = "weapons.missiles.MMagicII"
ENUMS.Storage.weapons.bombs.AB_500_1_SD_10A = "weapons.bombs.AB_500_1_SD_10A"
ENUMS.Storage.weapons.nurs.HYDRA_70_M282 = "weapons.nurs.HYDRA_70_M282"
ENUMS.Storage.weapons.droptanks.DFT_400_GAL_A4E = "weapons.droptanks.DFT_400_GAL_A4E"
ENUMS.Storage.weapons.nurs.HYDRA_70_M257 = "weapons.nurs.HYDRA_70_M257"
ENUMS.Storage.weapons.droptanks.AV8BNA_AERO1D = "weapons.droptanks.AV8BNA_AERO1D"
ENUMS.Storage.weapons.containers.US_M10_SMOKE_TANK_BLUE = "weapons.containers.{US_M10_SMOKE_TANK_BLUE}"
ENUMS.Storage.weapons.nurs.ARF8M3HEI = "weapons.nurs.ARF8M3HEI"
ENUMS.Storage.weapons.bombs.RN_28 = "weapons.bombs.RN-28"
ENUMS.Storage.weapons.bombs.Squad_30_x_Soldier_7950lb = "weapons.bombs.Squad 30 x Soldier [7950lb]"
ENUMS.Storage.weapons.containers.uaz_469 = "weapons.containers.uaz-469"
ENUMS.Storage.weapons.containers.Otokar_Cobra = "weapons.containers.Otokar_Cobra"
ENUMS.Storage.weapons.bombs.APC_BTR_82A_Air_24998lb = "weapons.bombs.APC BTR-82A Air [24998lb]"
ENUMS.Storage.weapons.nurs.HYDRA_70_M274 = "weapons.nurs.HYDRA_70_M274"
ENUMS.Storage.weapons.missiles.P_24R = "weapons.missiles.P_24R"
ENUMS.Storage.weapons.nurs.HYDRA_70_MK61 = "weapons.nurs.HYDRA_70_MK61"
ENUMS.Storage.weapons.missiles.Igla_1E = "weapons.missiles.Igla_1E"
ENUMS.Storage.weapons.missiles.C_802AK = "weapons.missiles.C-802AK"
ENUMS.Storage.weapons.nurs.C_24 = "weapons.nurs.C_24"
ENUMS.Storage.weapons.droptanks.M2KC_08_RPL541 = "weapons.droptanks.M2KC_08_RPL541"
ENUMS.Storage.weapons.nurs.C_13 = "weapons.nurs.C_13"
ENUMS.Storage.weapons.droptanks.droptank_110_gal = "weapons.droptanks.droptank_110_gal"
ENUMS.Storage.weapons.bombs.Mk_84 = "weapons.bombs.Mk_84"
ENUMS.Storage.weapons.missiles.Sea_Eagle = "weapons.missiles.Sea_Eagle"
ENUMS.Storage.weapons.droptanks.PTB_1200_F1 = "weapons.droptanks.PTB_1200_F1"
ENUMS.Storage.weapons.nurs.SNEB_TYPE256_H1 = "weapons.nurs.SNEB_TYPE256_H1"
ENUMS.Storage.weapons.containers.MATRA_PHIMAT = "weapons.containers.MATRA-PHIMAT"
ENUMS.Storage.weapons.containers.smoke_pod = "weapons.containers.smoke_pod"
ENUMS.Storage.weapons.containers.F_15E_AAQ_14_LANTIRN = "weapons.containers.F-15E_AAQ-14_LANTIRN"
ENUMS.Storage.weapons.containers.EclairM_24 = "weapons.containers.{EclairM_24}"
ENUMS.Storage.weapons.bombs.GBU_16 = "weapons.bombs.GBU_16"
ENUMS.Storage.weapons.nurs.HYDRA_70_M156 = "weapons.nurs.HYDRA_70_M156"
ENUMS.Storage.weapons.missiles.R_60 = "weapons.missiles.R-60"
ENUMS.Storage.weapons.containers.zsu_23_4 = "weapons.containers.zsu-23-4"
ENUMS.Storage.weapons.missiles.RB75 = "weapons.missiles.RB75"
ENUMS.Storage.weapons.missiles.Mistral = "weapons.missiles.Mistral"
ENUMS.Storage.weapons.droptanks.MB339_TT500_L = "weapons.droptanks.MB339_TT500_L"
ENUMS.Storage.weapons.bombs.SAM_SA_13_STRELA_21624lb = "weapons.bombs.SAM SA-13 STRELA [21624lb]"
ENUMS.Storage.weapons.bombs.SAM_Avenger_M1097_Air_7200lb = "weapons.bombs.SAM Avenger M1097 Air [7200lb]"
ENUMS.Storage.weapons.droptanks.Eleven00L_Tank_Empty = "weapons.droptanks.1100L Tank Empty"
ENUMS.Storage.weapons.bombs.AN_M88 = "weapons.bombs.AN-M88"
ENUMS.Storage.weapons.missiles.S_25L = "weapons.missiles.S_25L"
ENUMS.Storage.weapons.nurs.British_AP_25LBNo1_3INCHNo1 = "weapons.nurs.British_AP_25LBNo1_3INCHNo1"
ENUMS.Storage.weapons.bombs.BDU_50LD = "weapons.bombs.BDU_50LD"
ENUMS.Storage.weapons.bombs.AGM_62 = "weapons.bombs.AGM_62"
ENUMS.Storage.weapons.containers.US_M10_SMOKE_TANK_WHITE = "weapons.containers.{US_M10_SMOKE_TANK_WHITE}"
ENUMS.Storage.weapons.missiles.MICA_T = "weapons.missiles.MICA_T"
ENUMS.Storage.weapons.containers.HVAR_rocket = "weapons.containers.HVAR_rocket"

File diff suppressed because it is too large Load Diff

View File

@ -591,10 +591,10 @@ function POSITIONABLE:GetRandomVec3( Radius )
if Radius then if Radius then
local PositionableRandomVec3 = {} local PositionableRandomVec3 = {}
local angle = math.random() * math.pi * 2; local angle = math.random() * math.pi * 2
PositionableRandomVec3.x = PositionablePointVec3.x + math.cos( angle ) * math.random() * Radius; PositionableRandomVec3.x = PositionablePointVec3.x + math.cos( angle ) * math.random() * Radius
PositionableRandomVec3.y = PositionablePointVec3.y PositionableRandomVec3.y = PositionablePointVec3.y
PositionableRandomVec3.z = PositionablePointVec3.z + math.sin( angle ) * math.random() * Radius; PositionableRandomVec3.z = PositionablePointVec3.z + math.sin( angle ) * math.random() * Radius
self:T3( PositionableRandomVec3 ) self:T3( PositionableRandomVec3 )
return PositionableRandomVec3 return PositionableRandomVec3
@ -1769,6 +1769,93 @@ do -- Cargo
return self.__.CargoBayWeightLimit - CargoWeight return self.__.CargoBayWeightLimit - CargoWeight
end end
---
-- @field DefaultInfantryWeight
-- Abstract out the "XYZ*95" calculation in the Ground POSITIONABLE case, where the table
-- holds number of infantry that the vehicle could carry, instead of actual cargo weights.
POSITIONABLE.DefaultInfantryWeight = 95
---
-- @field CargoBayCapacityValues
-- @field CargoBayCapacityValues.Air
-- @field CargoBayCapacityValues.Naval
-- @field CargoBayCapacityValues.Ground
POSITIONABLE.CargoBayCapacityValues = {
["Air"] = {
-- C-17A
-- Wiki says: max=265,352, empty=128,140, payload=77,516 (134 troops, 1 M1 Abrams tank, 2 M2 Bradley or 3 Stryker)
-- DCS says: max=265,350, empty=125,645, fuel=132,405 ==> Cargo Bay=7300 kg with a full fuel load (lot of fuel!) and 73300 with half a fuel load.
--["C-17A"] = 35000, --77519 cannot be used, because it loads way too much apcs and infantry.
-- C-130:
-- DCS says: max=79,380, empty=36,400, fuel=10,415 kg ==> Cargo Bay=32,565 kg with fuel load.
-- Wiki says: max=70,307, empty=34,382, payload=19,000 kg (92 passengers, 2-3 Humvees or 2 M113s), max takeoff weight 70,037 kg.
-- Here we say two M113s should be transported. Each one weights 11,253 kg according to DCS. So the cargo weight should be 23,000 kg with a full load of fuel.
-- This results in a max takeoff weight of 69,815 kg (23,000+10,415+36,400), which is very close to the Wiki value of 70,037 kg.
["C_130"] = 70000,
},
["Naval"] = {
["Type_071"] = 245000,
["LHA_Tarawa"] = 500000,
["Ropucha_class"] = 150000,
["Dry_cargo_ship_1"] = 70000,
["Dry_cargo_ship_2"] = 70000,
["Higgins_boat"] = 3700, -- Higgins Boat can load 3700 kg of general cargo or 36 men (source wikipedia).
["USS_Samuel_Chase"] = 25000, -- Let's say 25 tons for now. Wiki says 33 Higgins boats, which would be 264 tons (can't be right!) and/or 578 troops.
["LST_Mk2"] = 2100000, -- Can carry 2100 tons according to wiki source!
["speedboat"] = 500, -- 500 kg ~ 5 persons
["Seawise_Giant"] =261000000, -- Gross tonnage is 261,000 tonns.
},
["Ground"] = {
["AAV7"] = 25*POSITIONABLE.DefaultInfantryWeight,
["Bedford_MWD"] = 8*POSITIONABLE.DefaultInfantryWeight, -- new by kappa
["Blitz_36_6700A"] = 10*POSITIONABLE.DefaultInfantryWeight, -- new by kappa
["BMD_1"] = 9*POSITIONABLE.DefaultInfantryWeight, -- IRL should be 4 passengers
["BMP_1"] = 8*POSITIONABLE.DefaultInfantryWeight,
["BMP_2"] = 7*POSITIONABLE.DefaultInfantryWeight,
["BMP_3"] = 8*POSITIONABLE.DefaultInfantryWeight, -- IRL should be 7+2 passengers
["Boman"] = 25*POSITIONABLE.DefaultInfantryWeight,
["BTR_80"] = 9*POSITIONABLE.DefaultInfantryWeight, -- IRL should be 7 passengers
["BTR_82A"] = 9*POSITIONABLE.DefaultInfantryWeight, -- new by kappa -- IRL should be 7 passengers
["BTR_D"] = 12*POSITIONABLE.DefaultInfantryWeight, -- IRL should be 10 passengers
["Cobra"] = 8*POSITIONABLE.DefaultInfantryWeight,
["Land_Rover_101_FC"] = 11*POSITIONABLE.DefaultInfantryWeight, -- new by kappa
["Land_Rover_109_S3"] = 7*POSITIONABLE.DefaultInfantryWeight, -- new by kappa
["LAV_25"] = 6*POSITIONABLE.DefaultInfantryWeight,
["M_2_Bradley"] = 6*POSITIONABLE.DefaultInfantryWeight,
["M1043_HMMWV_Armament"] = 4*POSITIONABLE.DefaultInfantryWeight,
["M1045_HMMWV_TOW"] = 4*POSITIONABLE.DefaultInfantryWeight,
["M1126_Stryker_ICV"] = 9*POSITIONABLE.DefaultInfantryWeight,
["M1134_Stryker_ATGM"] = 9*POSITIONABLE.DefaultInfantryWeight,
["M2A1_halftrack"] = 9*POSITIONABLE.DefaultInfantryWeight,
["M_113"] = 9*POSITIONABLE.DefaultInfantryWeight, -- IRL should be 11 passengers
["Marder"] = 6*POSITIONABLE.DefaultInfantryWeight,
["MCV_80"] = 9*POSITIONABLE.DefaultInfantryWeight, -- IRL should be 7 passengers
["MLRS_FDDM"] = 4*POSITIONABLE.DefaultInfantryWeight,
["MTLB"] = 25*POSITIONABLE.DefaultInfantryWeight, -- IRL should be 11 passengers
["GAZ_66"] = 8*POSITIONABLE.DefaultInfantryWeight,
["GAZ_3307"] = 12*POSITIONABLE.DefaultInfantryWeight,
["GAZ_3308"] = 14*POSITIONABLE.DefaultInfantryWeight,
["Grad_FDDM"] = 6*POSITIONABLE.DefaultInfantryWeight, -- new by kappa
["KAMAZ_Truck"] = 12*POSITIONABLE.DefaultInfantryWeight,
["KrAZ6322"] = 12*POSITIONABLE.DefaultInfantryWeight,
["M_818"] = 12*POSITIONABLE.DefaultInfantryWeight,
["Tigr_233036"] = 6*POSITIONABLE.DefaultInfantryWeight,
["TPZ"] = 10*POSITIONABLE.DefaultInfantryWeight, -- Fuchs
["UAZ_469"] = 4*POSITIONABLE.DefaultInfantryWeight, -- new by kappa
["Ural_375"] = 12*POSITIONABLE.DefaultInfantryWeight,
["Ural_4320_31"] = 14*POSITIONABLE.DefaultInfantryWeight,
["Ural_4320_APA_5D"] = 10*POSITIONABLE.DefaultInfantryWeight,
["Ural_4320T"] = 14*POSITIONABLE.DefaultInfantryWeight,
["ZBD04A"] = 7*POSITIONABLE.DefaultInfantryWeight, -- new by kappa
["VAB_Mephisto"] = 8*POSITIONABLE.DefaultInfantryWeight, -- new by Apple
["tt_KORD"] = 6*POSITIONABLE.DefaultInfantryWeight, -- 2.7.1 HL/TT
["tt_DSHK"] = 6*POSITIONABLE.DefaultInfantryWeight,
["HL_KORD"] = 6*POSITIONABLE.DefaultInfantryWeight,
["HL_DSHK"] = 6*POSITIONABLE.DefaultInfantryWeight,
["CCKW_353"] = 16*POSITIONABLE.DefaultInfantryWeight, --GMC CCKW 2½-ton 6×6 truck, estimating 16 soldiers,
}
}
--- Set Cargo Bay Weight Limit in kg. --- Set Cargo Bay Weight Limit in kg.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param #number WeightLimit (Optional) Weight limit in kg. If not given, the value is taken from the descriptors or hard coded. -- @param #number WeightLimit (Optional) Weight limit in kg. If not given, the value is taken from the descriptors or hard coded.
@ -1792,23 +1879,13 @@ do -- Cargo
-- Unit type name. -- Unit type name.
local TypeName=Desc.typeName or "Unknown Type" local TypeName=Desc.typeName or "Unknown Type"
TypeName = string.gsub(TypeName,"[%p%s]","_")
-- When an airplane or helicopter, we calculate the WeightLimit based on the descriptor. -- When an airplane or helicopter, we calculate the WeightLimit based on the descriptor.
if self:IsAir() then if self:IsAir() then
-- Max takeoff weight if DCS descriptors have unrealstic values. -- Max takeoff weight if DCS descriptors have unrealstic values.
local Weights = { local Weights = POSITIONABLE.CargoBayCapacityValues.Air
-- C-17A
-- Wiki says: max=265,352, empty=128,140, payload=77,516 (134 troops, 1 M1 Abrams tank, 2 M2 Bradley or 3 Stryker)
-- DCS says: max=265,350, empty=125,645, fuel=132,405 ==> Cargo Bay=7300 kg with a full fuel load (lot of fuel!) and 73300 with half a fuel load.
--["C-17A"] = 35000, --77519 cannot be used, because it loads way too much apcs and infantry.
-- C-130:
-- DCS says: max=79,380, empty=36,400, fuel=10,415 kg ==> Cargo Bay=32,565 kg with fuel load.
-- Wiki says: max=70,307, empty=34,382, payload=19,000 kg (92 passengers, 2-3 Humvees or 2 M113s), max takeoff weight 70,037 kg.
-- Here we say two M113s should be transported. Each one weights 11,253 kg according to DCS. So the cargo weight should be 23,000 kg with a full load of fuel.
-- This results in a max takeoff weight of 69,815 kg (23,000+10,415+36,400), which is very close to the Wiki value of 70,037 kg.
["C-130"] = 70000,
}
-- Max (takeoff) weight (empty+fuel+cargo weight). -- Max (takeoff) weight (empty+fuel+cargo weight).
local massMax= Desc.massMax or 0 local massMax= Desc.massMax or 0
@ -1843,75 +1920,16 @@ do -- Cargo
elseif self:IsShip() then elseif self:IsShip() then
-- Hard coded cargo weights in kg. -- Hard coded cargo weights in kg.
local Weights = { local Weights = POSITIONABLE.CargoBayCapacityValues.Naval
["Type_071"] = 245000,
["LHA_Tarawa"] = 500000,
["Ropucha-class"] = 150000,
["Dry-cargo ship-1"] = 70000,
["Dry-cargo ship-2"] = 70000,
["Higgins_boat"] = 3700, -- Higgins Boat can load 3700 kg of general cargo or 36 men (source wikipedia).
["USS_Samuel_Chase"] = 25000, -- Let's say 25 tons for now. Wiki says 33 Higgins boats, which would be 264 tons (can't be right!) and/or 578 troops.
["LST_Mk2"] = 2100000, -- Can carry 2100 tons according to wiki source!
["speedboat"] = 500, -- 500 kg ~ 5 persons
["Seawise_Giant"] =261000000, -- Gross tonnage is 261,000 tonns.
}
self.__.CargoBayWeightLimit = ( Weights[TypeName] or 50000 ) self.__.CargoBayWeightLimit = ( Weights[TypeName] or 50000 )
else else
-- Hard coded number of soldiers. -- Hard coded number of soldiers.
local Weights = { local Weights = POSITIONABLE.CargoBayCapacityValues.Ground
["AAV7"] = 25,
["Bedford_MWD"] = 8, -- new by kappa
["Blitz_36-6700A"] = 10, -- new by kappa
["BMD-1"] = 9, -- IRL should be 4 passengers
["BMP-1"] = 8,
["BMP-2"] = 7,
["BMP-3"] = 8, -- IRL should be 7+2 passengers
["Boman"] = 25,
["BTR-80"] = 9, -- IRL should be 7 passengers
["BTR-82A"] = 9, -- new by kappa -- IRL should be 7 passengers
["BTR_D"] = 12, -- IRL should be 10 passengers
["Cobra"] = 8,
["Land_Rover_101_FC"] = 11, -- new by kappa
["Land_Rover_109_S3"] = 7, -- new by kappa
["LAV-25"] = 6,
["M-2 Bradley"] = 6,
["M1043 HMMWV Armament"] = 4,
["M1045 HMMWV TOW"] = 4,
["M1126 Stryker ICV"] = 9,
["M1134 Stryker ATGM"] = 9,
["M2A1_halftrack"] = 9,
["M-113"] = 9, -- IRL should be 11 passengers
["Marder"] = 6,
["MCV-80"] = 9, -- IRL should be 7 passengers
["MLRS FDDM"] = 4,
["MTLB"] = 25, -- IRL should be 11 passengers
["GAZ-66"] = 8,
["GAZ-3307"] = 12,
["GAZ-3308"] = 14,
["Grad_FDDM"] = 6, -- new by kappa
["KAMAZ Truck"] = 12,
["KrAZ6322"] = 12,
["M 818"] = 12,
["Tigr_233036"] = 6,
["TPZ"] = 10, -- Fuchs
["UAZ-469"] = 4, -- new by kappa
["Ural-375"] = 12,
["Ural-4320-31"] = 14,
["Ural-4320 APA-5D"] = 10,
["Ural-4320T"] = 14,
["ZBD04A"] = 7, -- new by kappa
["VAB_Mephisto"] = 8, -- new by Apple
["tt_KORD"] = 6, -- 2.7.1 HL/TT
["tt_DSHK"] = 6,
["HL_KORD"] = 6,
["HL_DSHK"] = 6,
["CCKW_353"] = 16, --GMC CCKW 2½-ton 6×6 truck, estimating 16 soldiers
}
-- Assuming that each passenger weighs 95 kg on average. -- Assuming that each passenger weighs 95 kg on average.
local CargoBayWeightLimit = ( Weights[TypeName] or 0 ) * 95 local CargoBayWeightLimit = ( Weights[TypeName] or 0 )
self.__.CargoBayWeightLimit = CargoBayWeightLimit self.__.CargoBayWeightLimit = CargoBayWeightLimit
end end

View File

@ -336,6 +336,181 @@ function STORAGE:GetLiquidName(Type)
return name return name
end end
--- Adds the amount of a given type of aircraft, liquid, weapon currently present the warehouse.
-- @param #STORAGE self
-- @param #number Type Type of liquid or name of aircraft, weapon or equipment.
-- @param #number Amount Amount of given type to add. Liquids in kg.
-- @return #STORAGE self
function STORAGE:AddAmount(Type, Amount)
if type(Type)=="number" then
self:AddLiquid(Type, Amount)
else
self:AddItem(Type, Amount)
end
return self
end
--- Removes the amount of a given type of aircraft, liquid, weapon from the warehouse.
-- @param #STORAGE self
-- @param #number Type Type of liquid or name of aircraft, weapon or equipment.
-- @param #number Amount Amount of given type to remove. Liquids in kg.
-- @return #STORAGE self
function STORAGE:RemoveAmount(Type, Amount)
if type(Type)=="number" then
self:RemoveLiquid(Type, Amount)
else
self:RemoveItem(Type, Amount)
end
return self
end
--- Sets the amount of a given type of aircraft, liquid, weapon currently present the warehouse.
-- @param #STORAGE self
-- @param #number Type Type of liquid or name of aircraft, weapon or equipment.
-- @param #number Amount of given type. Liquids in kg.
-- @return #STORAGE self
function STORAGE:SetAmount(Type, Amount)
if type(Type)=="number" then
self:SetLiquid(Type, Amount)
else
self:SetItem(Type, Amount)
end
return self
end
--- Gets the amount of a given type of aircraft, liquid, weapon currently present the warehouse.
-- @param #STORAGE self
-- @param #number Type Type of liquid or name of aircraft, weapon or equipment.
-- @return #number Amount of given type. Liquids in kg.
function STORAGE:GetAmount(Type)
local N=0
if type(Type)=="number" then
N=self:GetLiquidAmount(Type)
else
N=self:GetItemAmount(Type)
end
return N
end
--- Returns whether a given type of aircraft, liquid, weapon is set to be unlimited.
-- @param #STORAGE self
-- @param #string Type Name of aircraft, weapon or equipment or type of liquid (as `#number`).
-- @return #boolen If `true` the given type is unlimited or `false` otherwise.
function STORAGE:IsUnlimited(Type)
-- Get current amount of type.
local N=self:GetAmount(Type)
local unlimited=false
if N>0 then
-- Remove one item.
self:RemoveAmount(Type, 1)
-- Get amount.
local n=self:GetAmount(Type)
-- If amount did not change, it is unlimited.
unlimited=n==N
-- Add item back.
if not unlimited then
self:AddAmount(Type, 1)
end
-- Debug info.
self:I(self.lid..string.format("Type=%s: unlimited=%s (N=%d n=%d)", tostring(Type), tostring(unlimited), N, n))
end
return unlimited
end
--- Returns whether a given type of aircraft, liquid, weapon is set to be limited.
-- @param #STORAGE self
-- @param #number Type Type of liquid or name of aircraft, weapon or equipment.
-- @return #boolen If `true` the given type is limited or `false` otherwise.
function STORAGE:IsLimited(Type)
local limited=not self:IsUnlimited(Type)
return limited
end
--- Returns whether aircraft are unlimited.
-- @param #STORAGE self
-- @return #boolen If `true` aircraft are unlimited or `false` otherwise.
function STORAGE:IsUnlimitedAircraft()
-- We test with a specific type but if it is unlimited, than all aircraft are.
local unlimited=self:IsUnlimited("A-10C")
return unlimited
end
--- Returns whether liquids are unlimited.
-- @param #STORAGE self
-- @return #boolen If `true` liquids are unlimited or `false` otherwise.
function STORAGE:IsUnlimitedLiquids()
-- We test with a specific type but if it is unlimited, than all are.
local unlimited=self:IsUnlimited(STORAGE.Liquid.DIESEL)
return unlimited
end
--- Returns whether weapons and equipment are unlimited.
-- @param #STORAGE self
-- @return #boolen If `true` weapons and equipment are unlimited or `false` otherwise.
function STORAGE:IsUnlimitedWeapons()
-- We test with a specific type but if it is unlimited, than all are.
local unlimited=self:IsUnlimited(ENUMS.Storage.weapons.bombs.Mk_82)
return unlimited
end
--- Returns whether aircraft are limited.
-- @param #STORAGE self
-- @return #boolen If `true` aircraft are limited or `false` otherwise.
function STORAGE:IsLimitedAircraft()
-- We test with a specific type but if it is limited, than all are.
local limited=self:IsLimited("A-10C")
return limited
end
--- Returns whether liquids are limited.
-- @param #STORAGE self
-- @return #boolen If `true` liquids are limited or `false` otherwise.
function STORAGE:IsLimitedLiquids()
-- We test with a specific type but if it is limited, than all are.
local limited=self:IsLimited(STORAGE.Liquid.DIESEL)
return limited
end
--- Returns whether weapons and equipment are limited.
-- @param #STORAGE self
-- @return #boolen If `true` liquids are limited or `false` otherwise.
function STORAGE:IsLimitedWeapons()
-- We test with a specific type but if it is limited, than all are.
local limited=self:IsLimited(ENUMS.Storage.weapons.bombs.Mk_82)
return limited
end
--- Returns a full itemized list of everything currently in a warehouse. If a category is set to unlimited then the table will be returned empty. --- Returns a full itemized list of everything currently in a warehouse. If a category is set to unlimited then the table will be returned empty.
-- @param #STORAGE self -- @param #STORAGE self