mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge remote-tracking branch 'origin/master' into develop
This commit is contained in:
commit
50bbea327b
@ -1211,6 +1211,43 @@ function DATABASE:_RegisterStaticTemplate( StaticTemplate, CoalitionID, Category
|
||||
return self
|
||||
end
|
||||
|
||||
--- Get a generic static cargo group template from scratch for dynamic cargo spawns register. Does not register the template!
|
||||
-- @param #DATABASE self
|
||||
-- @param #string Name Name of the static.
|
||||
-- @param #string Typename Typename of the static. Defaults to "container_cargo".
|
||||
-- @param #number Mass Mass of the static. Defaults to 0.
|
||||
-- @param #number Coalition Coalition of the static. Defaults to coalition.side.BLUE.
|
||||
-- @param #number Country Country of the static. Defaults to country.id.GERMANY.
|
||||
-- @return #table Static template table.
|
||||
function DATABASE:_GetGenericStaticCargoGroupTemplate(Name,Typename,Mass,Coalition,Country)
|
||||
local StaticTemplate = {}
|
||||
StaticTemplate.name = Name or "None"
|
||||
StaticTemplate.units = { [1] = {
|
||||
name = Name,
|
||||
resourcePayload = {
|
||||
["weapons"] = {},
|
||||
["aircrafts"] = {},
|
||||
["gasoline"] = 0,
|
||||
["diesel"] = 0,
|
||||
["methanol_mixture"] = 0,
|
||||
["jet_fuel"] = 0,
|
||||
},
|
||||
["mass"] = Mass or 0,
|
||||
["category"] = "Cargos",
|
||||
["canCargo"] = true,
|
||||
["type"] = Typename or "container_cargo",
|
||||
["rate"] = 100,
|
||||
["y"] = 0,
|
||||
["x"] = 0,
|
||||
["heading"] = 0,
|
||||
}}
|
||||
StaticTemplate.CategoryID = "static"
|
||||
StaticTemplate.CoalitionID = Coalition or coalition.side.BLUE
|
||||
StaticTemplate.CountryID = Country or country.id.GERMANY
|
||||
UTILS.PrintTableToLog(StaticTemplate)
|
||||
return StaticTemplate
|
||||
end
|
||||
|
||||
--- Get static group template.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string StaticName Name of the static.
|
||||
|
||||
@ -199,6 +199,7 @@
|
||||
--
|
||||
-- * @{#SPAWN.InitRepeat}() or @{#SPAWN.InitRepeatOnLanding}(): This method is used to re-spawn automatically the same group after it has landed.
|
||||
-- * @{#SPAWN.InitRepeatOnEngineShutDown}(): This method is used to re-spawn automatically the same group after it has landed and it shuts down the engines at the ramp.
|
||||
-- * @{#SPAWN.StopRepeat}(): This method is used to stop the repeater.
|
||||
--
|
||||
-- ### Link-16 Datalink STN and SADL IDs (limited at the moment to F15/16/18/AWACS/Tanker/B1B, but not the F15E for clients, SADL A10CII only)
|
||||
--
|
||||
@ -1411,6 +1412,30 @@ function SPAWN:InitArray( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Stop the SPAWN InitRepeat function (EVENT handler for takeoff, land and engine shutdown)
|
||||
-- @param #SPAWN self
|
||||
-- @return #SPAWN self
|
||||
-- @usage
|
||||
-- local spawn = SPAWN:New("Template Group")
|
||||
-- :InitRepeatOnEngineShutDown()
|
||||
-- local plane = spawn:Spawn() -- it is important that we keep the SPAWN object and do not overwrite it with the resulting GROUP object by just calling :Spawn()
|
||||
--
|
||||
-- -- later on
|
||||
-- spawn:StopRepeat()
|
||||
function SPAWN:StopRepeat()
|
||||
if self.Repeat then
|
||||
self:UnHandleEvent(EVENTS.Takeoff)
|
||||
self:UnHandleEvent(EVENTS.Land)
|
||||
end
|
||||
if self.RepeatOnEngineShutDown then
|
||||
self:UnHandleEvent(EVENTS.EngineShutdown)
|
||||
end
|
||||
self.Repeat = false
|
||||
self.RepeatOnEngineShutDown = false
|
||||
self.RepeatOnLanding = false
|
||||
return self
|
||||
end
|
||||
|
||||
do -- AI methods
|
||||
|
||||
--- Turns the AI On or Off for the @{Wrapper.Group} when spawning.
|
||||
|
||||
@ -189,6 +189,7 @@ function SPAWNSTATIC:NewFromType(StaticType, StaticCategory, CountryID)
|
||||
self.InitStaticCategory=StaticCategory
|
||||
self.CountryID=CountryID or country.id.USA
|
||||
self.SpawnTemplatePrefix=self.InitStaticType
|
||||
self.TemplateStaticUnit = {}
|
||||
|
||||
self.InitStaticCoordinate=COORDINATE:New(0, 0, 0)
|
||||
self.InitStaticHeading=0
|
||||
@ -196,6 +197,61 @@ function SPAWNSTATIC:NewFromType(StaticType, StaticCategory, CountryID)
|
||||
return self
|
||||
end
|
||||
|
||||
--- (Internal/Cargo) Init the resource table for STATIC object that should be spawned containing storage objects.
|
||||
-- NOTE that you have to init many other parameters as the resources.
|
||||
-- @param #SPAWNSTATIC self
|
||||
-- @param #number CombinedWeight The weight this cargo object should have (some have fixed weights!), defaults to 1kg.
|
||||
-- @return #SPAWNSTATIC self
|
||||
function SPAWNSTATIC:_InitResourceTable(CombinedWeight)
|
||||
if not self.TemplateStaticUnit.resourcePayload then
|
||||
self.TemplateStaticUnit.resourcePayload = {
|
||||
["weapons"] = {},
|
||||
["aircrafts"] = {},
|
||||
["gasoline"] = 0,
|
||||
["diesel"] = 0,
|
||||
["methanol_mixture"] = 0,
|
||||
["jet_fuel"] = 0,
|
||||
}
|
||||
end
|
||||
self:InitCargo(true)
|
||||
self:InitCargoMass(CombinedWeight or 1)
|
||||
return self
|
||||
end
|
||||
|
||||
--- (User/Cargo) Add to resource table for STATIC object that should be spawned containing storage objects. Inits the object table if necessary and sets it to be cargo for helicopters.
|
||||
-- @param #SPAWNSTATIC self
|
||||
-- @param #string Type Type of cargo. Known types are: STORAGE.Type.WEAPONS, STORAGE.Type.LIQUIDS, STORAGE.Type.AIRCRAFT. Liquids are fuel.
|
||||
-- @param #string Name Name of the cargo type. Liquids can be STORAGE.LiquidName.JETFUEL, STORAGE.LiquidName.GASOLINE, STORAGE.LiquidName.MW50 and STORAGE.LiquidName.DIESEL. The currently available weapon items are available in the `ENUMS.Storage.weapons`, e.g. `ENUMS.Storage.weapons.bombs.Mk_82Y`. Aircraft go by their typename.
|
||||
-- @param #number Amount of tons (liquids) or number (everything else) to add.
|
||||
-- @param #number CombinedWeight Combined weight to be set to this static cargo object. NOTE - some static cargo objects have fixed weights!
|
||||
-- @return #SPAWNSTATIC self
|
||||
function SPAWNSTATIC:AddCargoResource(Type,Name,Amount,CombinedWeight)
|
||||
if not self.TemplateStaticUnit.resourcePayload then
|
||||
self:_InitResourceTable(CombinedWeight)
|
||||
end
|
||||
if Type == STORAGE.Type.LIQUIDS and type(Name) == "string" then
|
||||
self.TemplateStaticUnit.resourcePayload[Name] = Amount
|
||||
else
|
||||
self.TemplateStaticUnit.resourcePayload[Type] = {
|
||||
[Name] = {
|
||||
["amount"] = Amount,
|
||||
}
|
||||
}
|
||||
end
|
||||
UTILS.PrintTableToLog(self.TemplateStaticUnit)
|
||||
return self
|
||||
end
|
||||
|
||||
--- (User/Cargo) Resets resource table to zero for STATIC object that should be spawned containing storage objects. Inits the object table if necessary and sets it to be cargo for helicopters.
|
||||
-- Handy if you spawn from cargo statics which have resources already set.
|
||||
-- @param #SPAWNSTATIC self
|
||||
-- @return #SPAWNSTATIC self
|
||||
function SPAWNSTATIC:ResetCargoResources()
|
||||
self.TemplateStaticUnit.resourcePayload = nil
|
||||
self:_InitResourceTable()
|
||||
return self
|
||||
end
|
||||
|
||||
--- Initialize heading of the spawned static.
|
||||
-- @param #SPAWNSTATIC self
|
||||
-- @param Core.Point#COORDINATE Coordinate Position where the static is spawned.
|
||||
@ -317,6 +373,25 @@ function SPAWNSTATIC:InitLinkToUnit(Unit, OffsetX, OffsetY, OffsetAngle)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Allows to place a CallFunction hook when a new static spawns.
|
||||
-- The provided method will be called when a new group is spawned, including its given parameters.
|
||||
-- The first parameter of the SpawnFunction is the @{Wrapper.Static#STATIC} that was spawned.
|
||||
-- @param #SPAWNSTATIC self
|
||||
-- @param #function SpawnCallBackFunction The function to be called when a group spawns.
|
||||
-- @param SpawnFunctionArguments A random amount of arguments to be provided to the function when the group spawns.
|
||||
-- @return #SPAWNSTATIC self
|
||||
function SPAWNSTATIC:OnSpawnStatic( SpawnCallBackFunction, ... )
|
||||
self:F( "OnSpawnStatic" )
|
||||
|
||||
self.SpawnFunctionHook = SpawnCallBackFunction
|
||||
self.SpawnFunctionArguments = {}
|
||||
if arg then
|
||||
self.SpawnFunctionArguments = arg
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Spawn a new STATIC object.
|
||||
-- @param #SPAWNSTATIC self
|
||||
-- @param #number Heading (Optional) The heading of the static, which is a number in degrees from 0 to 360. Default is the heading of the template.
|
||||
@ -488,7 +563,7 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
|
||||
-- ED's dirty way to spawn FARPS.
|
||||
Static=coalition.addGroup(CountryID, -1, TemplateGroup)
|
||||
|
||||
-- Currently DCS 2.8 does not trigger birth events if FAPRS are spawned!
|
||||
-- Currently DCS 2.8 does not trigger birth events if FARPS are spawned!
|
||||
-- We create such an event. The airbase is registered in Core.Event
|
||||
local Event = {
|
||||
id = EVENTS.Birth,
|
||||
@ -504,5 +579,11 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
|
||||
Static=coalition.addStaticObject(CountryID, Template)
|
||||
end
|
||||
|
||||
-- If there is a SpawnFunction hook defined, call it.
|
||||
if self.SpawnFunctionHook then
|
||||
-- delay calling this for .3 seconds so that it hopefully comes after the BIRTH event of the group.
|
||||
self:ScheduleOnce(0.3,self.SpawnFunctionHook,mystatic, unpack(self.SpawnFunctionArguments))
|
||||
end
|
||||
|
||||
return mystatic
|
||||
end
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
--- **Functional** - Manage and track client slots easily to add your own client-based menus and modules to.
|
||||
--
|
||||
-- The @{#CLIENTWATCH} class adds a simplified way to create scripts and menus for individual clients. Instead of creating large algorithms and juggling multiple event handlers, you can simply provide one or more prefixes to the class and use the callback functions on spawn, despawn, and any aircraft related events to script to your hearts content.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ## Features:
|
||||
@ -10,50 +12,29 @@
|
||||
-- * More reliable aircraft lost events for when DCS thinks the aircraft id dead but a dead event fails to trigger
|
||||
-- * Easily manage clients spawned in dynamic slots
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ## Missions:
|
||||
--
|
||||
-- ## [MOOSE - ALL Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS)
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- The @{#CLIENTWATCH} class adds a simplified way to create scripts and menus for individual clients. Instead of creating large algorithms and juggling multiple event handlers, you can simply provide one or more prefixes to the class and use the callback functions on spawn, despawn, and any aircraft related events to script to your hearts content.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # YouTube Channel
|
||||
--
|
||||
-- ### [MOOSE YouTube Channel](https://www.youtube.com/channel/UCjrA9j5LQoWsG4SpS8i79Qg)
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **Statua**
|
||||
--
|
||||
-- ### Contributions: **FlightControl**: Wrapper.CLIENT
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ====
|
||||
-- @module Functional.ClientWatch
|
||||
-- @image ClientWatch.JPG
|
||||
-- @image clientwatch.jpg
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- CLIENTWATCH class
|
||||
-- @type CLIENTWATCH
|
||||
-- @field #string ClassName Name of the class.
|
||||
-- @field #boolean Debug Write Debug messages to DCS log file and send Debug messages to all players.
|
||||
-- @field #string lid String for DCS log file.
|
||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||
--
|
||||
|
||||
--- Manage and track client slots easily to add your own client-based menus and modules to.
|
||||
--
|
||||
-- ## Creating a new instance
|
||||
--
|
||||
-- To start, you must first create a new instance of the client manager and provide it with either a Wrapper.Client#CLIENT object, a string prefix of the unit name, or a table of string prefixes for unit names. These are used to capture the client unit when it spawns and apply your scripted functions to it. Only fixed wing and rotary wing aircraft controlled by players can be used by this class.
|
||||
|
||||
---
|
||||
-- **This will not work if the client aircraft is alive!**
|
||||
--
|
||||
-- ### Examples
|
||||
@ -135,24 +116,30 @@
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
--
|
||||
-- @field #CLIENTWATCH
|
||||
|
||||
CLIENTWATCHTools = {}
|
||||
CLIENTWATCH = {}
|
||||
CLIENTWATCH.ClassName = "CLIENTWATCH"
|
||||
CLIENTWATCH.Debug = false
|
||||
CLIENTWATCH.lid = nil
|
||||
|
||||
--- CLIENTWATCH version.
|
||||
-- @field #number version
|
||||
CLIENTWATCH.version="1.0.0"
|
||||
-- @type CLIENTWATCHTools
|
||||
-- @field #table Unit Wrapper.UNIT of the cient object
|
||||
-- @field #table Group Wrapper.GROUP of the cient object
|
||||
-- @field #table Client Wrapper.CLIENT of the cient object
|
||||
-- @field #string PlayerName Name of the player controlling the client object
|
||||
-- @field #string UnitName Name of the unit that is the client object
|
||||
-- @field #string GroupName Name of the group the client object belongs to
|
||||
CLIENTWATCHTools = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
--- CLIENTWATCH version
|
||||
-- @field #string version
|
||||
CLIENTWATCH.version="1.0.1"
|
||||
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Creates a new instance of CLIENTWATCH to add scripts to. Can be used multiple times with the same client/prefixes if you need it for multiple scripts.
|
||||
-- @param #CLIENTWATCH self
|
||||
-- @param Provide either a Wrapper.Client#CLIENT of the client you want to use, a #string prefix of the DCS UNIT name, or a #table of #string prefixes for multiple DCS UNIT names
|
||||
-- @param #string, #table, or Wrapper.Client#CLIENT client Takes multiple inputs. If provided a #string, it will watch for clients whos UNIT NAME or GROUP NAME matches part of the #string as a prefix. You can also provide it with a #table containing multiple #string prefixes. Lastly, you can provide it with a Wrapper.Client#CLIENT of the specific client you want to apply this to.
|
||||
-- @return #CLIENTWATCH self
|
||||
function CLIENTWATCH:New(client)
|
||||
--Init FSM
|
||||
@ -160,6 +147,15 @@ function CLIENTWATCH:New(client)
|
||||
self:SetStartState( "Idle" )
|
||||
self:AddTransition( "*", "Spawn", "*" )
|
||||
|
||||
--- User function for OnAfter "Spawn" event.
|
||||
-- @function [parent=#CLIENTWATCH] OnAfterSpawn
|
||||
-- @param #CLIENTWATCH self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param #table clientObject Custom object that handles events and stores Moose object data. See top documentation for more details.
|
||||
|
||||
--Set up spawn tracking
|
||||
if type(client) == "table" or type(client) == "string" then
|
||||
if type(client) == "table" then
|
||||
@ -169,11 +165,14 @@ function CLIENTWATCH:New(client)
|
||||
self.ClientName = client:GetName()
|
||||
self:HandleEvent(EVENTS.Birth)
|
||||
function self:OnEventBirth(eventdata)
|
||||
if self.ClientName == eventdata.IniUnitName and eventdata.IniCategory <= 1 then
|
||||
if self.Debug then UTILS.PrintTableToLog(eventdata) end
|
||||
if eventdata.IniCategory and eventdata.IniCategory <= 1 then
|
||||
if self.ClientName == eventdata.IniUnitName then
|
||||
local clientObject = CLIENTWATCHTools:_newClient(eventdata)
|
||||
self:Spawn(clientObject)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--STRING TABLE
|
||||
else
|
||||
@ -188,8 +187,10 @@ function CLIENTWATCH:New(client)
|
||||
if tableValid then
|
||||
self:HandleEvent(EVENTS.Birth)
|
||||
function self:OnEventBirth(eventdata)
|
||||
if self.Debug then UTILS.PrintTableToLog(eventdata) end
|
||||
for _,entry in pairs(client) do
|
||||
if string.match(eventdata.IniUnitName,entry) and eventdata.IniCategory == 1 then
|
||||
if eventdata.IniCategory and eventdata.IniCategory <= 1 then
|
||||
if string.match(eventdata.IniUnitName,entry) or string.match(eventdata.IniGroupName,entry) then
|
||||
local clientObject = CLIENTWATCHTools:_newClient(eventdata)
|
||||
self:Spawn(clientObject)
|
||||
break
|
||||
@ -198,17 +199,21 @@ function CLIENTWATCH:New(client)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
|
||||
--SOLO STRING
|
||||
self:HandleEvent(EVENTS.Birth)
|
||||
function self:OnEventBirth(eventdata)
|
||||
if string.match(eventdata.IniUnitName,client) and eventdata.IniCategory == 1 then
|
||||
if self.Debug then UTILS.PrintTableToLog(eventdata) end
|
||||
if eventdata.IniCategory and eventdata.IniCategory <= 1 then
|
||||
if string.match(eventdata.IniUnitName,client) or string.match(eventdata.IniGroupName,client) then
|
||||
local clientObject = CLIENTWATCHTools:_newClient(eventdata)
|
||||
self:Spawn(clientObject)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
self:E({"The base handler failed to start because param1 is not a CLIENT object or a prefix string!",param1 = client})
|
||||
return nil
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
-- @module Ops.CTLD
|
||||
-- @image OPS_CTLD.jpg
|
||||
|
||||
-- Last Update July 2024
|
||||
-- Last Update Aug 2024
|
||||
|
||||
do
|
||||
|
||||
@ -46,6 +46,7 @@ do
|
||||
-- @field #string Subcategory Sub-category name.
|
||||
-- @field #boolean DontShowInMenu Show this item in menu or not.
|
||||
-- @field Core.Zone#ZONE Location Location (if set) where to get this cargo item.
|
||||
-- @field #table ResourceMap Resource Map information table if it has been set for static cargo items.
|
||||
-- @extends Core.Base#BASE
|
||||
|
||||
---
|
||||
@ -122,6 +123,7 @@ CTLD_CARGO = {
|
||||
self.Mark = nil
|
||||
self.Subcategory = Subcategory or "Other"
|
||||
self.DontShowInMenu = DontShowInMenu or false
|
||||
self.ResourceMap = nil
|
||||
if type(Location) == "string" then
|
||||
Location = ZONE:New(Location)
|
||||
end
|
||||
@ -129,6 +131,22 @@ CTLD_CARGO = {
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add Resource Map information table
|
||||
-- @param #CTLD_CARGO self
|
||||
-- @param #table ResourceMap
|
||||
-- @return #CTLD_CARGO self
|
||||
function CTLD_CARGO:SetStaticResourceMap(ResourceMap)
|
||||
self.ResourceMap = ResourceMap
|
||||
return self
|
||||
end
|
||||
|
||||
--- Get Resource Map information table
|
||||
-- @param #CTLD_CARGO self
|
||||
-- @return #table ResourceMap
|
||||
function CTLD_CARGO:GetStaticResourceMap()
|
||||
return self.ResourceMap
|
||||
end
|
||||
|
||||
--- Query Location.
|
||||
-- @param #CTLD_CARGO self
|
||||
-- @return Core.Zone#ZONE location or `nil` if not set
|
||||
@ -752,10 +770,37 @@ do
|
||||
-- my_ctld.nobuildmenu = false -- if set to true effectively enforces to have engineers build/repair stuff for you.
|
||||
-- my_ctld.RadioSound = "beacon.ogg" -- -- this sound will be hearable if you tune in the beacon frequency. Add the sound file to your miz.
|
||||
-- my_ctld.RadioSoundFC3 = "beacon.ogg" -- this sound will be hearable by FC3 users (actually all UHF radios); change to something like "beaconsilent.ogg" and add the sound file to your miz if you don't want to annoy FC3 pilots.
|
||||
-- my_ctld.enableChinhookGCLoading = true -- this will effectively suppress the crate load and drop menus for CTLD for the Chinhook
|
||||
--
|
||||
-- ## 2.1 User functions
|
||||
-- ## 2.1 CH-47 Chinhook support
|
||||
--
|
||||
-- ### 2.1.1 Adjust or add chopper unit-type capabilities
|
||||
-- The Chinhook comes with the option to use the ground crew menu to load and unload cargo into the Helicopter itself for better immersion. As well, it can sling-load cargo from ground. The cargo you can actually **create**
|
||||
-- from this menu is limited to contain items from the airbase or FARP's resources warehouse and can take a number of shapes (static shapes in the category of cargo) independent of their contents. If you unload this
|
||||
-- kind of cargo with the ground crew, the contents will be "absorbed" into the airbase or FARP you landed at, and the cargo static will be removed after ca 2 mins.
|
||||
--
|
||||
-- ## 2.1.1 Moose CTLD created crate cargo
|
||||
--
|
||||
-- Given the correct shape, Moose created cargo can be either loaded with the ground crew or via the F10 CTLD menu. **It is strongly recommend to either use the ground crew or CTLD to load/unload cargo**. Mix and match will not work here.
|
||||
-- Static shapes loadable *into* the Chinhook are at the time of writing:
|
||||
--
|
||||
-- * Ammo crate (type "ammo_cargo")
|
||||
-- * M117 bomb crate (type name "m117_cargo")
|
||||
-- * Dual shell fuel barrels (type name "barrels")
|
||||
-- * UH-1H net (type name "uh1h_cargo")
|
||||
--
|
||||
-- All other kinds of cargo can be sling-loaded.
|
||||
--
|
||||
-- ## 2.1.2 Recommended settings
|
||||
--
|
||||
-- my_ctld.basetype = "ammo_cargo"
|
||||
-- my_ctld.forcehoverload = false -- no hover autoload, leads to cargo complications with ground crew created cargo items
|
||||
-- my_ctld.pilotmustopendoors = true -- crew must open back loading door 50% (horizontal) or more
|
||||
-- my_ctld.enableslingload = true -- will set cargo items as sling-loadable
|
||||
-- my_ctld.enableChinhookGCLoading = true -- will effectively suppress the crate load and drop menus for CTLD for the Chinhook
|
||||
--
|
||||
-- ## 2.2 User functions
|
||||
--
|
||||
-- ### 2.2.1 Adjust or add chopper unit-type capabilities
|
||||
--
|
||||
-- Use this function to adjust what a heli type can or cannot do:
|
||||
--
|
||||
@ -780,8 +825,12 @@ do
|
||||
-- ["MH-60R"] = {type="MH-60R", crates=true, troops=true, cratelimit = 2, trooplimit = 20, length = 16, cargoweightlimit = 3500}, -- 4t cargo, 20 (unsec) seats
|
||||
-- ["SH-60B"] = {type="SH-60B", crates=true, troops=true, cratelimit = 2, trooplimit = 20, length = 16, cargoweightlimit = 3500}, -- 4t cargo, 20 (unsec) seats
|
||||
-- ["Bronco-OV-10A"] = {type="Bronco-OV-10A", crates= false, troops=true, cratelimit = 0, trooplimit = 5, length = 13, cargoweightlimit = 1450},
|
||||
-- ["Bronco-OV-10A"] = {type="Bronco-OV-10A", crates= false, troops=true, cratelimit = 0, trooplimit = 5, length = 13, cargoweightlimit = 1450},
|
||||
-- ["OH-6A"] = {type="OH-6A", crates=false, troops=true, cratelimit = 0, trooplimit = 4, length = 7, cargoweightlimit = 550},
|
||||
-- ["OH-58D"] = {type="OH58D", crates=false, troops=false, cratelimit = 0, trooplimit = 0, length = 14, cargoweightlimit = 400},
|
||||
-- ["CH-47Fbl1"] = {type="CH-47Fbl1", crates=true, troops=true, cratelimit = 4, trooplimit = 31, length = 20, cargoweightlimit = 8000},
|
||||
--
|
||||
-- ### 2.1.2 Activate and deactivate zones
|
||||
-- ### 2.2.2 Activate and deactivate zones
|
||||
--
|
||||
-- Activate a zone:
|
||||
--
|
||||
@ -793,7 +842,7 @@ do
|
||||
-- -- Deactivate zone called Name of type #CTLD.CargoZoneType ZoneType:
|
||||
-- my_ctld:DeactivateZone(Name,CTLD.CargoZoneType.DROP)
|
||||
--
|
||||
-- ## 2.1.3 Limit and manage available resources
|
||||
-- ## 2.2.3 Limit and manage available resources
|
||||
--
|
||||
-- When adding generic cargo types, you can effectively limit how many units can be dropped/build by the players, e.g.
|
||||
--
|
||||
@ -1251,12 +1300,12 @@ CTLD.UnitTypeCapabilities = {
|
||||
["Bronco-OV-10A"] = {type="Bronco-OV-10A", crates= false, troops=true, cratelimit = 0, trooplimit = 5, length = 13, cargoweightlimit = 1450},
|
||||
["OH-6A"] = {type="OH-6A", crates=false, troops=true, cratelimit = 0, trooplimit = 4, length = 7, cargoweightlimit = 550},
|
||||
["OH-58D"] = {type="OH58D", crates=false, troops=false, cratelimit = 0, trooplimit = 0, length = 14, cargoweightlimit = 400},
|
||||
["CH-47Fbl1"] = {type="CH-47Fbl1", crates=true, troops=true, cratelimit = 4, trooplimit = 31, length = 30, cargoweightlimit = 8000},
|
||||
["CH-47Fbl1"] = {type="CH-47Fbl1", crates=true, troops=true, cratelimit = 4, trooplimit = 31, length = 20, cargoweightlimit = 8000},
|
||||
}
|
||||
|
||||
--- CTLD class version.
|
||||
-- @field #string version
|
||||
CTLD.version="1.0.56"
|
||||
CTLD.version="1.0.58"
|
||||
|
||||
--- Instantiate a new CTLD.
|
||||
-- @param #CTLD self
|
||||
@ -1435,6 +1484,9 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
self.movecratesbeforebuild = true
|
||||
self.surfacetypes = {land.SurfaceType.LAND,land.SurfaceType.ROAD,land.SurfaceType.RUNWAY,land.SurfaceType.SHALLOW_WATER}
|
||||
|
||||
-- Chinhook
|
||||
self.enableChinhookGCLoading = true
|
||||
|
||||
local AliaS = string.gsub(self.alias," ","_")
|
||||
self.filename = string.format("CTLD_%s_Persist.csv",AliaS)
|
||||
|
||||
@ -1592,7 +1644,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
-- @param Wrapper.Group#GROUP Group Group Object.
|
||||
-- @param Wrapper.Unit#UNIT Unit Unit Object.
|
||||
-- @param #string ZoneName Name of the Zone where the Troops have been RTB'd.
|
||||
-- @param Core.Zone#ZONE_RADIUS ZoneObject of the Zone where the Troops have been RTB'd.
|
||||
-- @param Core.Zone#ZONE_Radius ZoneObject of the Zone where the Troops have been RTB'd.
|
||||
|
||||
--- FSM Function OnAfterTroopsPickedUp.
|
||||
-- @function [parent=#CTLD] OnAfterTroopsPickedUp
|
||||
@ -1719,8 +1771,6 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Group#GROUP Group Group Object.
|
||||
-- @param Wrapper.Unit#UNIT Unit Unit Object.
|
||||
-- @param #string ZoneName Name of the Zone where the Troops have been RTB'd.
|
||||
-- @param Core.Zone#ZONE_RADIUS ZoneObject of the Zone where the Troops have been RTB'd.
|
||||
|
||||
--- FSM Function OnAfterLoad.
|
||||
-- @function [parent=#CTLD] OnAfterLoad
|
||||
@ -1827,7 +1877,7 @@ end
|
||||
-- @param #CTLD self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function CTLD:_EventHandler(EventData)
|
||||
self:T(string.format("%s Event = %d",self.lid, EventData.id))
|
||||
self:I(string.format("%s Event = %d",self.lid, EventData.id))
|
||||
local event = EventData -- Core.Event#EVENTDATA
|
||||
if event.id == EVENTS.PlayerEnterAircraft or event.id == EVENTS.PlayerEnterUnit then
|
||||
local _coalition = event.IniCoalition
|
||||
@ -1851,12 +1901,37 @@ function CTLD:_EventHandler(EventData)
|
||||
self:_RefreshF10Menus()
|
||||
end
|
||||
return
|
||||
elseif event.id == EVENTS.PlayerLeaveUnit then
|
||||
elseif event.id == EVENTS.PlayerLeaveUnit or event.id == EVENTS.UnitLost then
|
||||
-- remove from pilot table
|
||||
local unitname = event.IniUnitName or "none"
|
||||
self.CtldUnits[unitname] = nil
|
||||
self.Loaded_Cargo[unitname] = nil
|
||||
self.MenusDone[unitname] = nil
|
||||
elseif event.id == EVENTS.Birth and event.IniObjectCategory == 6 and string.match(event.IniUnitName,".+|%d%d:%d%d|PKG%d+") then
|
||||
--UTILS.PrintTableToLog(event)
|
||||
---------------
|
||||
-- New dynamic cargo system Handling
|
||||
--------------
|
||||
local function RegisterDynamicCargo()
|
||||
local static = _DATABASE:AddStatic(event.IniUnitName)
|
||||
if static then
|
||||
static.DCSCargoObject = event.IniDCSUnit
|
||||
local Mass = event.IniDCSUnit:getCargoWeight()
|
||||
local country = event.IniDCSUnit:getCountry()
|
||||
local template = _DATABASE:_GetGenericStaticCargoGroupTemplate(event.IniUnitName,event.IniTypeName,Mass,event.IniCoalition,country)
|
||||
_DATABASE:_RegisterStaticTemplate(template,event.IniCoalition,"static",country)
|
||||
self:I("**** Ground crew created static cargo added: "..event.IniUnitName .." | Weight in kgs: "..Mass)
|
||||
local cargotype = self:AddStaticsCargo(event.IniUnitName,Mass,1,nil,true)
|
||||
self.CrateCounter = self.CrateCounter + 1
|
||||
self.Spawned_Crates[self.CrateCounter] = static
|
||||
cargotype.Positionable = static
|
||||
table.insert(self.Spawned_Cargo, cargotype)
|
||||
end
|
||||
end
|
||||
self:ScheduleOnce(0.5,RegisterDynamicCargo)
|
||||
---------------
|
||||
-- End new dynamic cargo system Handling
|
||||
--------------
|
||||
end
|
||||
return self
|
||||
end
|
||||
@ -2422,7 +2497,8 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack)
|
||||
return self
|
||||
end
|
||||
-- spawn crates in front of helicopter
|
||||
local IsHerc = self:IsHercules(Unit) -- Herc
|
||||
local IsHerc = self:IsHercules(Unit) -- Herc, Bronco and Hook load from behind
|
||||
local IsHook = self:IsHook(Unit) -- Herc, Bronco and Hook load from behind
|
||||
local cargotype = Cargo -- Ops.CTLD#CTLD_CARGO
|
||||
local number = number or cargotype:GetCratesNeeded() --#number
|
||||
local cratesneeded = cargotype:GetCratesNeeded() --#number
|
||||
@ -2444,7 +2520,7 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack)
|
||||
local rheading = 0
|
||||
local angleOffNose = 0
|
||||
local addon = 0
|
||||
if IsHerc then
|
||||
if IsHerc or IsHook then
|
||||
-- spawn behind the Herc
|
||||
addon = 180
|
||||
end
|
||||
@ -2494,17 +2570,25 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack)
|
||||
dist = dist - (20 + math.random(1,10))
|
||||
local width = width / 2
|
||||
local Offy = math.random(-width,width)
|
||||
self.Spawned_Crates[self.CrateCounter] = SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
|
||||
local spawnstatic = SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
|
||||
:InitCargoMass(cgomass)
|
||||
:InitCargo(self.enableslingload)
|
||||
:InitLinkToUnit(Ship,dist,Offy,0)
|
||||
:Spawn(270,cratealias)
|
||||
if isstatic then
|
||||
local map=cargotype:GetStaticResourceMap()
|
||||
spawnstatic.TemplateStaticUnit.resourcePayload = map
|
||||
end
|
||||
self.Spawned_Crates[self.CrateCounter] = spawnstatic:Spawn(270,cratealias)
|
||||
else
|
||||
self.Spawned_Crates[self.CrateCounter] = SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
|
||||
local spawnstatic = SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
|
||||
:InitCoordinate(cratecoord)
|
||||
:InitCargoMass(cgomass)
|
||||
:InitCargo(self.enableslingload)
|
||||
:Spawn(270,cratealias)
|
||||
if isstatic then
|
||||
local map=cargotype:GetStaticResourceMap()
|
||||
spawnstatic.TemplateStaticUnit.resourcePayload = map
|
||||
end
|
||||
self.Spawned_Crates[self.CrateCounter] = spawnstatic:Spawn(270,cratealias)
|
||||
end
|
||||
local templ = cargotype:GetTemplates()
|
||||
local sorte = cargotype:GetType()
|
||||
@ -2514,9 +2598,13 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack)
|
||||
if drop then
|
||||
--CTLD_CARGO:New(ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped, PerCrateMass, Stock, Subcategory)
|
||||
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,true,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],true,cargotype.PerCrateMass,nil,subcat)
|
||||
local map=cargotype:GetStaticResourceMap()
|
||||
realcargo:SetStaticResourceMap(map)
|
||||
table.insert(droppedcargo,realcargo)
|
||||
else
|
||||
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,false,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],false,cargotype.PerCrateMass,nil,subcat)
|
||||
local map=cargotype:GetStaticResourceMap()
|
||||
realcargo:SetStaticResourceMap(map)
|
||||
end
|
||||
table.insert(self.Spawned_Cargo, realcargo)
|
||||
end
|
||||
@ -2566,14 +2654,18 @@ function CTLD:InjectStatics(Zone, Cargo, RandomCoord)
|
||||
basetype = cratetemplate
|
||||
end
|
||||
self.CrateCounter = self.CrateCounter + 1
|
||||
self.Spawned_Crates[self.CrateCounter] = SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
|
||||
local spawnstatic = SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry)
|
||||
:InitCargoMass(cgomass)
|
||||
:InitCargo(self.enableslingload)
|
||||
:InitCoordinate(cratecoord)
|
||||
:Spawn(270,cratealias)
|
||||
if isstatic then
|
||||
local map = cargotype:GetStaticResourceMap()
|
||||
spawnstatic.TemplateStaticUnit.resourcePayload = map
|
||||
end
|
||||
self.Spawned_Crates[self.CrateCounter] = spawnstatic:Spawn(270,cratealias)
|
||||
local templ = cargotype:GetTemplates()
|
||||
local sorte = cargotype:GetType()
|
||||
self.CargoCounter = self.CargoCounter + 1
|
||||
--self.CargoCounter = self.CargoCounter + 1
|
||||
cargotype.Positionable = self.Spawned_Crates[self.CrateCounter]
|
||||
table.insert(self.Spawned_Cargo, cargotype)
|
||||
return self
|
||||
@ -2600,8 +2692,8 @@ end
|
||||
function CTLD:_ListCratesNearby( _group, _unit)
|
||||
self:T(self.lid .. " _ListCratesNearby")
|
||||
local finddist = self.CrateDistance or 35
|
||||
local crates,number = self:_FindCratesNearby(_group,_unit, finddist,true) -- #table
|
||||
if number > 0 then
|
||||
local crates,number,loadedbygc,indexgc = self:_FindCratesNearby(_group,_unit, finddist,true) -- #table
|
||||
if number > 0 or indexgc > 0 then
|
||||
local text = REPORT:New("Crates Found Nearby:")
|
||||
text:Add("------------------------------------------------------------")
|
||||
for _,_entry in pairs (crates) do
|
||||
@ -2618,6 +2710,19 @@ function CTLD:_ListCratesNearby( _group, _unit)
|
||||
text:Add(" N O N E")
|
||||
end
|
||||
text:Add("------------------------------------------------------------")
|
||||
if indexgc > 0 then
|
||||
text:Add("Probably ground crew loaded (F8)")
|
||||
for _,_entry in pairs (loadedbygc) do
|
||||
local entry = _entry -- #CTLD_CARGO
|
||||
local name = entry:GetName() --#string
|
||||
local dropped = entry:WasDropped()
|
||||
if dropped then
|
||||
text:Add(string.format("Dropped crate for %s, %dkg",name, entry.PerCrateMass))
|
||||
else
|
||||
text:Add(string.format("Crate for %s, %dkg",name, entry.PerCrateMass))
|
||||
end
|
||||
end
|
||||
end
|
||||
self:_SendMessage(text:Text(), 30, true, _group)
|
||||
else
|
||||
self:_SendMessage(string.format("No (loadable) crates within %d meters!",finddist), 10, false, _group)
|
||||
@ -2691,8 +2796,10 @@ end
|
||||
-- @param Wrapper.Unit#UNIT _unit Unit
|
||||
-- @param #number _dist Distance
|
||||
-- @param #boolean _ignoreweight Find everything in range, ignore loadable weight
|
||||
-- @return #table Table of crates
|
||||
-- @return #table Crates Table of crates
|
||||
-- @return #number Number Number of crates found
|
||||
-- @return #table CratesGC Table of crates possibly loaded by GC
|
||||
-- @return #number NumberGC Number of crates possibly loaded by GC
|
||||
function CTLD:_FindCratesNearby( _group, _unit, _dist, _ignoreweight)
|
||||
self:T(self.lid .. " _FindCratesNearby")
|
||||
local finddist = _dist
|
||||
@ -2700,7 +2807,9 @@ function CTLD:_FindCratesNearby( _group, _unit, _dist, _ignoreweight)
|
||||
local existingcrates = self.Spawned_Cargo -- #table
|
||||
-- cycle
|
||||
local index = 0
|
||||
local indexg = 0
|
||||
local found = {}
|
||||
local LoadedbyGC = {}
|
||||
local loadedmass = 0
|
||||
local unittype = "none"
|
||||
local capabilities = {}
|
||||
@ -2713,20 +2822,47 @@ function CTLD:_FindCratesNearby( _group, _unit, _dist, _ignoreweight)
|
||||
for _,_cargoobject in pairs (existingcrates) do
|
||||
local cargo = _cargoobject -- #CTLD_CARGO
|
||||
local static = cargo:GetPositionable() -- Wrapper.Static#STATIC -- crates
|
||||
local staticid = cargo:GetID()
|
||||
local weight = cargo:GetMass() -- weight in kgs of this cargo
|
||||
local staticid = cargo:GetID()
|
||||
self:T(self.lid .. " Found cargo mass: " .. weight)
|
||||
if static and static:IsAlive() then
|
||||
local staticpos = static:GetCoordinate()
|
||||
local cargoalive = false -- TODO dyn cargo spawn workaround
|
||||
local dcsunit = nil
|
||||
local dcsunitpos = nil
|
||||
if static.DCSCargoObject then
|
||||
dcsunit = Unit.getByName(static.StaticName)
|
||||
if dcsunit then
|
||||
cargoalive = dcsunit:isExist() ~= nil and true or false
|
||||
end
|
||||
if cargoalive == true then
|
||||
local dcsvec3 = dcsunit:getPoint() or dcsunit:getPosition().p or {x=0,y=0,z=0}
|
||||
self:I({dcsvec3 = dcsunit:getPoint(), dcspos = dcsunit:getPosition().p})
|
||||
if dcsvec3 then
|
||||
dcsunitpos = COORDINATE:New(dcsvec3.x,dcsvec3.z,dcsvec3.y)
|
||||
end
|
||||
end
|
||||
end
|
||||
if static and (static:IsAlive() or cargoalive) then
|
||||
local staticpos = static:GetCoordinate() or dcsunitpos
|
||||
--- Testing
|
||||
local landheight = staticpos:GetLandHeight()
|
||||
local agl = staticpos.y-landheight
|
||||
agl = UTILS.Round(agl,2)
|
||||
local GCloaded = agl > 0 and true or false
|
||||
--- Testing
|
||||
local distance = self:_GetDistance(location,staticpos)
|
||||
if distance <= finddist and static and (weight <= maxloadable or _ignoreweight) then
|
||||
self:I({name=static:GetName(),agl=agl,GCloaded=GCloaded,distance=string.format("%.2f",distance or 0)})
|
||||
if (not GCloaded) and distance <= finddist and static and (weight <= maxloadable or _ignoreweight) then
|
||||
index = index + 1
|
||||
table.insert(found, staticid, cargo)
|
||||
maxloadable = maxloadable - weight
|
||||
end
|
||||
if GCloaded == true and distance < 10 and static then
|
||||
indexg = indexg + 1
|
||||
table.insert(LoadedbyGC,staticid, cargo)
|
||||
end
|
||||
end
|
||||
return found, index
|
||||
end
|
||||
return found, index, LoadedbyGC, indexg
|
||||
end
|
||||
|
||||
--- (Internal) Function to get and load nearby crates.
|
||||
@ -2748,6 +2884,13 @@ function CTLD:_LoadCratesNearby(Group, Unit)
|
||||
local cratelimit = capabilities.cratelimit -- #number
|
||||
local grounded = not self:IsUnitInAir(Unit)
|
||||
local canhoverload = self:CanHoverLoad(Unit)
|
||||
|
||||
-- Door check
|
||||
if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen(Unit:GetName()) then
|
||||
self:_SendMessage("You need to open the door(s) to load cargo!", 10, false, Group)
|
||||
if not self.debug then return self end
|
||||
end
|
||||
|
||||
--- cases -------------------------------
|
||||
-- Chopper can\'t do crates - bark & return
|
||||
-- Chopper can do crates -
|
||||
@ -2925,7 +3068,9 @@ function CTLD:_ListCargo(Group, Unit)
|
||||
local loadedcargo = self.Loaded_Cargo[unitname] or {} -- #CTLD.LoadedCargo
|
||||
local loadedmass = self:_GetUnitCargoMass(Unit) -- #number
|
||||
local maxloadable = self:_GetMaxLoadableMass(Unit)
|
||||
if self.Loaded_Cargo[unitname] then
|
||||
local finddist = self.CrateDistance or 35
|
||||
local _,_,loadedgc,loadedno = self:_FindCratesNearby(Group,Unit,finddist,true)
|
||||
if self.Loaded_Cargo[unitname] or loadedno > 0 then
|
||||
local no_troops = loadedcargo.Troopsloaded or 0
|
||||
local no_crates = loadedcargo.Cratesloaded or 0
|
||||
local cargotable = loadedcargo.Cargo or {} -- #table
|
||||
@ -2947,7 +3092,7 @@ function CTLD:_ListCargo(Group, Unit)
|
||||
report:Add("------------------------------------------------------------")
|
||||
report:Add(" -- CRATES --")
|
||||
local cratecount = 0
|
||||
for _,_cargo in pairs(cargotable) do
|
||||
for _,_cargo in pairs(cargotable or {}) do
|
||||
local cargo = _cargo -- #CTLD_CARGO
|
||||
local type = cargo:GetType() -- #CTLD_CARGO.Enum
|
||||
if (type ~= CTLD_CARGO.Enum.TROOPS and type ~= CTLD_CARGO.Enum.ENGINEERS) and (not cargo:WasDropped() or self.allowcratepickupagain) then
|
||||
@ -2958,6 +3103,18 @@ function CTLD:_ListCargo(Group, Unit)
|
||||
if cratecount == 0 then
|
||||
report:Add(" N O N E")
|
||||
end
|
||||
if loadedno > 0 then
|
||||
report:Add("------------------------------------------------------------")
|
||||
report:Add(" -- CRATES loaded via F8 --")
|
||||
for _,_cargo in pairs(loadedgc or {}) do
|
||||
local cargo = _cargo -- #CTLD_CARGO
|
||||
local type = cargo:GetType() -- #CTLD_CARGO.Enum
|
||||
if (type ~= CTLD_CARGO.Enum.TROOPS and type ~= CTLD_CARGO.Enum.ENGINEERS) then
|
||||
report:Add(string.format("Crate: %s size 1",cargo:GetName()))
|
||||
loadedmass = loadedmass + cargo:GetMass()
|
||||
end
|
||||
end
|
||||
end
|
||||
report:Add("------------------------------------------------------------")
|
||||
report:Add("Total Mass: ".. loadedmass .. " kg. Loadable: "..maxloadable.." kg.")
|
||||
local text = report:Text()
|
||||
@ -3062,7 +3219,7 @@ function CTLD:_ListInventory(Group, Unit)
|
||||
return self
|
||||
end
|
||||
|
||||
--- (Internal) Function to check if a unit is a Hercules C-130.
|
||||
--- (Internal) Function to check if a unit is a Hercules C-130 or a Bronco.
|
||||
-- @param #CTLD self
|
||||
-- @param Wrapper.Unit#UNIT Unit
|
||||
-- @return #boolean Outcome
|
||||
@ -3074,6 +3231,17 @@ function CTLD:IsHercules(Unit)
|
||||
end
|
||||
end
|
||||
|
||||
--- (Internal) Function to check if a unit is a CH-47
|
||||
-- @param #CTLD self
|
||||
-- @param Wrapper.Unit#UNIT Unit
|
||||
-- @return #boolean Outcome
|
||||
function CTLD:IsHook(Unit)
|
||||
if string.find(Unit:GetTypeName(),"CH.47") then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
--- (Internal) Function to set troops positions of a template to a nice circle
|
||||
-- @param #CTLD self
|
||||
@ -3127,7 +3295,8 @@ function CTLD:_UnloadTroops(Group, Unit)
|
||||
-- check for hover unload
|
||||
local hoverunload = self:IsCorrectHover(Unit) --if true we\'re hovering in parameters
|
||||
local IsHerc = self:IsHercules(Unit)
|
||||
if IsHerc then
|
||||
local IsHook = self:IsHook(Unit)
|
||||
if IsHerc and (not IsHook) then
|
||||
-- no hover but airdrop here
|
||||
hoverunload = self:IsCorrectFlightParameters(Unit)
|
||||
end
|
||||
@ -3256,10 +3425,16 @@ function CTLD:_UnloadCrates(Group, Unit)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Door check
|
||||
if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen(Unit:GetName()) then
|
||||
self:_SendMessage("You need to open the door(s) to drop cargo!", 10, false, Group)
|
||||
if not self.debug then return self end
|
||||
end
|
||||
-- check for hover unload
|
||||
local hoverunload = self:IsCorrectHover(Unit) --if true we\'re hovering in parameters
|
||||
local IsHerc = self:IsHercules(Unit)
|
||||
if IsHerc then
|
||||
local IsHook = self:IsHook(Unit)
|
||||
if IsHerc and (not IsHook) then
|
||||
-- no hover but airdrop here
|
||||
hoverunload = self:IsCorrectFlightParameters(Unit)
|
||||
end
|
||||
@ -3726,6 +3901,8 @@ function CTLD:_RefreshF10Menus()
|
||||
local capabilities = self:_GetUnitCapabilities(_unit) -- #CTLD.UnitTypeCapabilities
|
||||
local cantroops = capabilities.troops
|
||||
local cancrates = capabilities.crates
|
||||
local isHook = self:IsHook(_unit)
|
||||
local nohookswitch = not (isHook and self.enableChinhookGCLoading)
|
||||
-- top menu
|
||||
local topmenu = MENU_GROUP:New(_group,"CTLD",nil)
|
||||
local toptroops = nil
|
||||
@ -3783,7 +3960,9 @@ function CTLD:_RefreshF10Menus()
|
||||
end
|
||||
-- sub menu crates management
|
||||
if cancrates then
|
||||
if nohookswitch then
|
||||
local loadmenu = MENU_GROUP_COMMAND:New(_group,"Load crates",topcrates, self._LoadCratesNearby, self, _group, _unit)
|
||||
end
|
||||
local cratesmenu = MENU_GROUP:New(_group,"Get Crates",topcrates)
|
||||
local packmenu = MENU_GROUP_COMMAND:New(_group, "Pack crates", topcrates, self._PackCratesNearby, self, _group, _unit)
|
||||
local removecratesmenu = MENU_GROUP:New(_group, "Remove crates", topcrates)
|
||||
@ -3851,11 +4030,14 @@ function CTLD:_RefreshF10Menus()
|
||||
end
|
||||
listmenu = MENU_GROUP_COMMAND:New(_group,"List crates nearby",topcrates, self._ListCratesNearby, self, _group, _unit)
|
||||
local removecrates = MENU_GROUP_COMMAND:New(_group,"Remove crates nearby",removecratesmenu, self._RemoveCratesNearby, self, _group, _unit)
|
||||
local unloadmenu = MENU_GROUP_COMMAND:New(_group,"Drop crates",topcrates, self._UnloadCrates, self, _group, _unit)
|
||||
local unloadmenu
|
||||
if nohookswitch then
|
||||
unloadmenu = MENU_GROUP_COMMAND:New(_group,"Drop crates",topcrates, self._UnloadCrates, self, _group, _unit)
|
||||
end
|
||||
if not self.nobuildmenu then
|
||||
local buildmenu = MENU_GROUP_COMMAND:New(_group,"Build crates",topcrates, self._BuildCrates, self, _group, _unit)
|
||||
local repairmenu = MENU_GROUP_COMMAND:New(_group,"Repair",topcrates, self._RepairCrates, self, _group, _unit):Refresh()
|
||||
else
|
||||
elseif unloadmenu then
|
||||
unloadmenu:Refresh()
|
||||
end
|
||||
end
|
||||
@ -3948,15 +4130,22 @@ end
|
||||
-- @param #string SubCategory Name of sub-category (optional).
|
||||
-- @param #boolean DontShowInMenu (optional) If set to "true" this won't show up in the menu.
|
||||
-- @param Core.Zone#ZONE Location (optional) If set, the cargo item is **only** available here. Can be a #ZONE object or the name of a zone as #string.
|
||||
-- @return #CTLD_CARGO CargoObject
|
||||
function CTLD:AddStaticsCargo(Name,Mass,Stock,SubCategory,DontShowInMenu,Location)
|
||||
self:T(self.lid .. " AddStaticsCargo")
|
||||
self.CargoCounter = self.CargoCounter + 1
|
||||
local type = CTLD_CARGO.Enum.STATIC
|
||||
local template = STATIC:FindByName(Name,true):GetTypeName()
|
||||
local unittemplate = _DATABASE:GetStaticUnitTemplate(Name)
|
||||
local ResourceMap = nil
|
||||
if unittemplate and unittemplate.resourcePayload then
|
||||
ResourceMap = UTILS.DeepCopy(unittemplate.resourcePayload)
|
||||
end
|
||||
-- Crates are not directly loadable
|
||||
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,template,type,false,false,1,nil,nil,Mass,Stock,SubCategory,DontShowInMenu,Location)
|
||||
cargo:SetStaticResourceMap(ResourceMap)
|
||||
table.insert(self.Cargo_Statics,cargo)
|
||||
return self
|
||||
return cargo
|
||||
end
|
||||
|
||||
--- User function - Get a *generic* static-type loadable as #CTLD_CARGO object.
|
||||
@ -3969,8 +4158,14 @@ function CTLD:GetStaticsCargoFromTemplate(Name,Mass)
|
||||
self.CargoCounter = self.CargoCounter + 1
|
||||
local type = CTLD_CARGO.Enum.STATIC
|
||||
local template = STATIC:FindByName(Name,true):GetTypeName()
|
||||
local unittemplate = _DATABASE:GetStaticUnitTemplate(Name)
|
||||
local ResourceMap = nil
|
||||
if unittemplate and unittemplate.resourcePayload then
|
||||
ResourceMap = UTILS.DeepCopy(unittemplate.resourcePayload)
|
||||
end
|
||||
-- Crates are not directly loadable
|
||||
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,template,type,false,false,1,nil,nil,Mass,1)
|
||||
cargo:SetStaticResourceMap(ResourceMap)
|
||||
--table.insert(self.Cargo_Statics,cargo)
|
||||
return cargo
|
||||
end
|
||||
@ -5337,6 +5532,8 @@ end
|
||||
self:HandleEvent(EVENTS.PlayerEnterAircraft, self._EventHandler)
|
||||
self:HandleEvent(EVENTS.PlayerEnterUnit, self._EventHandler)
|
||||
self:HandleEvent(EVENTS.PlayerLeaveUnit, self._EventHandler)
|
||||
self:HandleEvent(EVENTS.UnitLost, self._EventHandler)
|
||||
self:HandleEvent(EVENTS.Birth, self._EventHandler)
|
||||
self:__Status(-5)
|
||||
|
||||
-- AutoSave
|
||||
@ -5600,7 +5797,7 @@ end
|
||||
-- @param Wrapper.Group#GROUP Group Group Object.
|
||||
-- @param Wrapper.Unit#UNIT Unit Unit Object.
|
||||
-- @param #string ZoneName Name of the Zone where the Troops have been RTB'd.
|
||||
-- @param Core.Zone#ZONE_RADIUS ZoneObject of the Zone where the Troops have been RTB'd.
|
||||
-- @param Core.Zone#ZONE_Radius ZoneObject of the Zone where the Troops have been RTB'd.
|
||||
-- @return #CTLD self
|
||||
function CTLD:onbeforeTroopsRTB(From, Event, To, Group, Unit, ZoneName, ZoneObject)
|
||||
self:T({From, Event, To})
|
||||
@ -5949,6 +6146,8 @@ end
|
||||
injectstatic = CTLD_CARGO:New(nil,cargoname,cargotemplates,cargotype,true,true,size,nil,true,mass)
|
||||
elseif cargotype == CTLD_CARGO.Enum.STATIC or cargotype == CTLD_CARGO.Enum.REPAIR then
|
||||
injectstatic = CTLD_CARGO:New(nil,cargoname,cargotemplates,cargotype,true,true,size,nil,true,mass)
|
||||
local map=cargotype:GetStaticResourceMap()
|
||||
injectstatic:SetStaticResourceMap(map)
|
||||
end
|
||||
if injectstatic then
|
||||
self:InjectStatics(dropzone,injectstatic)
|
||||
@ -6304,6 +6503,8 @@ function CTLD_HERCULES:Cargo_SpawnDroppedAsCargo(_name, _pos)
|
||||
|
||||
self.CTLD.Spawned_Crates[self.CTLD.CrateCounter] = theStatic
|
||||
local newCargo = CTLD_CARGO:New(self.CTLD.CargoCounter, theCargo.Name, theCargo.Templates, theCargo.CargoType, true, false, theCargo.CratesNeeded, self.CTLD.Spawned_Crates[self.CTLD.CrateCounter], true, theCargo.PerCrateMass, nil, theCargo.Subcategory)
|
||||
local map=theCargo:GetStaticResourceMap()
|
||||
newCargo:SetStaticResourceMap(map)
|
||||
table.insert(self.CTLD.Spawned_Cargo, newCargo)
|
||||
|
||||
newCargo:SetWasDropped(true)
|
||||
@ -6334,8 +6535,6 @@ function CTLD_HERCULES:Cargo_SpawnObjects(Cargo_Drop_initiator,Cargo_Drop_Direct
|
||||
|
||||
if offload_cargo == true or ParatrooperGroupSpawn == true then
|
||||
if ParatrooperGroupSpawn == true then
|
||||
--self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 0)
|
||||
--self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 5)
|
||||
self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 10)
|
||||
else
|
||||
self:Cargo_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country)
|
||||
|
||||
@ -2320,7 +2320,7 @@ function UTILS.IsLoadingDoorOpen( unit_name )
|
||||
return true
|
||||
end
|
||||
|
||||
if type_name == "CH-47Fbl1" and (unit:getDrawArgumentValue(86) > 0) then
|
||||
if type_name == "CH-47Fbl1" and (unit:getDrawArgumentValue(86) > 0.5) then
|
||||
BASE:T(unit_name .. " rear cargo door is open")
|
||||
return true
|
||||
end
|
||||
|
||||
@ -721,11 +721,12 @@ AIRBASE.Sinai = {
|
||||
--- Airbases of the Kola map
|
||||
--
|
||||
-- * AIRBASE.Kola.Banak
|
||||
-- * AIRBASE.Kola.Bas_100
|
||||
-- * AIRBASE.Kola.Bodo
|
||||
-- * AIRBASE.Kola.Jokkmokk
|
||||
-- * AIRBASE.Kola.Kalixfors
|
||||
-- * AIRBASE.Kola.Kallax
|
||||
-- * AIRBASE.Kola.Kemi_Tornio
|
||||
-- * AIRBASE.Kola.Kirkenes
|
||||
-- * AIRBASE.Kola.Kiruna
|
||||
-- * AIRBASE.Kola.Monchegorsk
|
||||
-- * AIRBASE.Kola.Murmansk_International
|
||||
@ -733,11 +734,12 @@ AIRBASE.Sinai = {
|
||||
-- * AIRBASE.Kola.Rovaniemi
|
||||
-- * AIRBASE.Kola.Severomorsk_1
|
||||
-- * AIRBASE.Kola.Severomorsk_3
|
||||
-- * AIRBASE.Kola.Vidsel
|
||||
-- * AIRBASE.Kola.Vuojarvi
|
||||
--
|
||||
-- @field Kola
|
||||
AIRBASE.Kola = {
|
||||
["Banak"] = "Banak",
|
||||
["Bas_100"] = "Bas 100",
|
||||
["Bodo"] = "Bodo",
|
||||
["Jokkmokk"] = "Jokkmokk",
|
||||
["Kalixfors"] = "Kalixfors",
|
||||
@ -749,6 +751,10 @@ AIRBASE.Kola = {
|
||||
["Rovaniemi"] = "Rovaniemi",
|
||||
["Severomorsk_1"] = "Severomorsk-1",
|
||||
["Severomorsk_3"] = "Severomorsk-3",
|
||||
["Vuojarvi"] = "Vuojarvi",
|
||||
["Kirkenes"] = "Kirkenes",
|
||||
["Kallax"] = "Kallax",
|
||||
["Vidsel"] = "Vidsel",
|
||||
}
|
||||
|
||||
--- Airbases of the Afghanistan map
|
||||
|
||||
@ -330,3 +330,26 @@ function STATIC:FindAllByMatching( Pattern )
|
||||
|
||||
return GroupsFound
|
||||
end
|
||||
|
||||
--- Get the Wrapper.Storage#STORAGE object of an static if it is used as cargo and has been set up as storage object.
|
||||
-- @param #STATIC self
|
||||
-- @return Wrapper.Storage#STORAGE Storage or `nil` if not fund or set up.
|
||||
function STATIC:GetStaticStorage()
|
||||
local name = self:GetName()
|
||||
local storage = STORAGE:NewFromStaticCargo(name)
|
||||
return storage
|
||||
end
|
||||
|
||||
--- Get the Cargo Weight of a static object in kgs. Returns -1 if not found.
|
||||
-- @param #STATIC self
|
||||
-- @return #number Mass Weight in kgs.
|
||||
function STATIC:GetCargoWeight()
|
||||
local DCSObject = StaticObject.getByName(self.StaticName )
|
||||
local mass = -1
|
||||
if DCSObject then
|
||||
mass = DCSObject:getCargoWeight() or 0
|
||||
local masstxt = DCSObject:getCargoDisplayName() or "none"
|
||||
--BASE:I("GetCargoWeight "..tostring(mass).." MassText "..masstxt)
|
||||
end
|
||||
return mass
|
||||
end
|
||||
|
||||
@ -147,9 +147,33 @@ STORAGE.Liquid = {
|
||||
DIESEL = 3,
|
||||
}
|
||||
|
||||
--- Liquid Names for the static cargo resource table.
|
||||
-- @type STORAGE.LiquidName
|
||||
-- @field #number JETFUEL "jet_fuel".
|
||||
-- @field #number GASOLINE "gasoline".
|
||||
-- @field #number MW50 "methanol_mixture".
|
||||
-- @field #number DIESEL "diesel".
|
||||
STORAGE.LiquidName = {
|
||||
GASOLINE = "gasoline",
|
||||
DIESEL = "diesel",
|
||||
MW50 = "methanol_mixture",
|
||||
JETFUEL = "jet_fuel",
|
||||
}
|
||||
|
||||
--- Storage types.
|
||||
-- @type STORAGE.Type
|
||||
-- @field #number WEAPONS weapons.
|
||||
-- @field #number LIQUIDS liquids. Also see #list<#STORAGE.Liquid> for types of liquids.
|
||||
-- @field #number AIRCRAFT aircraft.
|
||||
STORAGE.Type = {
|
||||
WEAPONS = "weapons",
|
||||
LIQUIDS = "liquids",
|
||||
AIRCRAFT = "aircrafts",
|
||||
}
|
||||
|
||||
--- STORAGE class version.
|
||||
-- @field #string version
|
||||
STORAGE.version="0.0.2"
|
||||
STORAGE.version="0.0.3"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user