mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Merge remote-tracking branch 'origin/master' into develop
This commit is contained in:
commit
6791a0e704
@ -20,11 +20,12 @@
|
|||||||
--
|
--
|
||||||
-- ### Author: **Applevangelist** (Moose Version), ***Ciribob*** (original), Thanks to: Shadowze, Cammel (testing), bbirchnz (additional code!!)
|
-- ### Author: **Applevangelist** (Moose Version), ***Ciribob*** (original), Thanks to: Shadowze, Cammel (testing), bbirchnz (additional code!!)
|
||||||
-- ### Repack addition for crates: **Raiden**
|
-- ### Repack addition for crates: **Raiden**
|
||||||
|
-- ### Additional cool features: **Lekaa**
|
||||||
--
|
--
|
||||||
-- @module Ops.CTLD
|
-- @module Ops.CTLD
|
||||||
-- @image OPS_CTLD.jpg
|
-- @image OPS_CTLD.jpg
|
||||||
|
|
||||||
-- Last Update April 2025
|
-- Last Update May 2025
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -865,6 +866,7 @@ do
|
|||||||
-- my_ctld.TroopUnloadDistGroundHook = 15 -- On the ground, unload troops this far behind the Chinook
|
-- my_ctld.TroopUnloadDistGroundHook = 15 -- On the ground, unload troops this far behind the Chinook
|
||||||
-- my_ctld.TroopUnloadDistHoverHook = 5 -- When hovering, unload troops this far behind the Chinook
|
-- my_ctld.TroopUnloadDistHoverHook = 5 -- When hovering, unload troops this far behind the Chinook
|
||||||
-- my_ctld.showstockinmenuitems = false -- When set to true, the menu lines will also show the remaining items in stock (that is, if you set any), downside is that the menu for all will be build every 30 seconds anew.
|
-- my_ctld.showstockinmenuitems = false -- When set to true, the menu lines will also show the remaining items in stock (that is, if you set any), downside is that the menu for all will be build every 30 seconds anew.
|
||||||
|
-- my_ctld.onestepmenu = false -- When set to true, the menu will create Drop and build, Get and load, Pack and remove, Pack and load, Pack only. it will be a 1 step solution.
|
||||||
--
|
--
|
||||||
-- ## 2.1 CH-47 Chinook support
|
-- ## 2.1 CH-47 Chinook support
|
||||||
--
|
--
|
||||||
@ -1412,7 +1414,7 @@ CTLD.FixedWingTypes = {
|
|||||||
|
|
||||||
--- CTLD class version.
|
--- CTLD class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CTLD.version="1.2.33"
|
CTLD.version="1.3.34"
|
||||||
|
|
||||||
--- Instantiate a new CTLD.
|
--- Instantiate a new CTLD.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
@ -1591,6 +1593,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
|||||||
self.subcats = {}
|
self.subcats = {}
|
||||||
self.subcatsTroop = {}
|
self.subcatsTroop = {}
|
||||||
self.showstockinmenuitems = false
|
self.showstockinmenuitems = false
|
||||||
|
self.onestepmenu = false
|
||||||
|
|
||||||
-- disallow building in loadzones
|
-- disallow building in loadzones
|
||||||
self.nobuildinloadzones = true
|
self.nobuildinloadzones = true
|
||||||
@ -2913,10 +2916,10 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack)
|
|||||||
if drop then
|
if drop then
|
||||||
text = string.format("Crates for %s have been dropped!",cratename)
|
text = string.format("Crates for %s have been dropped!",cratename)
|
||||||
self:__CratesDropped(1, Group, Unit, droppedcargo)
|
self:__CratesDropped(1, Group, Unit, droppedcargo)
|
||||||
end
|
else
|
||||||
self:_SendMessage(text, 10, false, Group)
|
self:_SendMessage(text, 10, false, Group)
|
||||||
|
end
|
||||||
self:_RefreshLoadCratesMenu(Group, Unit)
|
self:_RefreshLoadCratesMenu(Group, Unit)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3576,7 +3579,10 @@ end
|
|||||||
-- @param Wrapper.Unit#UNIT Unit
|
-- @param Wrapper.Unit#UNIT Unit
|
||||||
-- @return #boolean Outcome
|
-- @return #boolean Outcome
|
||||||
function CTLD:IsHook(Unit)
|
function CTLD:IsHook(Unit)
|
||||||
if Unit and string.find(Unit:GetTypeName(),"CH.47") then
|
if not Unit then return false end
|
||||||
|
local typeName = Unit:GetTypeName()
|
||||||
|
if not typeName then return false end
|
||||||
|
if string.find(typeName, "CH.47") then
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
@ -3766,7 +3772,6 @@ function CTLD:_UnloadCrates(Group, Unit)
|
|||||||
self:T(self.lid .. " _UnloadCrates")
|
self:T(self.lid .. " _UnloadCrates")
|
||||||
|
|
||||||
if not self.dropcratesanywhere then -- #1570
|
if not self.dropcratesanywhere then -- #1570
|
||||||
-- check if we are in DROP zone
|
|
||||||
local inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.DROP)
|
local inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.DROP)
|
||||||
if not inzone then
|
if not inzone then
|
||||||
self:_SendMessage("You are not close enough to a drop zone!", 10, false, Group)
|
self:_SendMessage("You are not close enough to a drop zone!", 10, false, Group)
|
||||||
@ -3775,46 +3780,60 @@ function CTLD:_UnloadCrates(Group, Unit)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Door check
|
|
||||||
if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen(Unit:GetName()) then
|
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)
|
self:_SendMessage("You need to open the door(s) to drop cargo!", 10, false, Group)
|
||||||
if not self.debug then return self end
|
if not self.debug then return self end
|
||||||
end
|
end
|
||||||
-- check for hover unload
|
local hoverunload = self:IsCorrectHover(Unit)
|
||||||
local hoverunload = self:IsCorrectHover(Unit) --if true we\'re hovering in parameters
|
|
||||||
local IsHerc = self:IsFixedWing(Unit)
|
local IsHerc = self:IsFixedWing(Unit)
|
||||||
local IsHook = self:IsHook(Unit)
|
local IsHook = self:IsHook(Unit)
|
||||||
if IsHerc and (not IsHook) then
|
if IsHerc and (not IsHook) then
|
||||||
-- no hover but airdrop here
|
|
||||||
hoverunload = self:IsCorrectFlightParameters(Unit)
|
hoverunload = self:IsCorrectFlightParameters(Unit)
|
||||||
end
|
end
|
||||||
-- check if we\'re landed
|
|
||||||
local grounded = not self:IsUnitInAir(Unit)
|
local grounded = not self:IsUnitInAir(Unit)
|
||||||
-- Get what we have loaded
|
|
||||||
local unitname = Unit:GetName()
|
local unitname = Unit:GetName()
|
||||||
if self.Loaded_Cargo[unitname] and (grounded or hoverunload) then
|
if self.Loaded_Cargo[unitname] and (grounded or hoverunload) then
|
||||||
local loadedcargo = self.Loaded_Cargo[unitname] or {} -- #CTLD.LoadedCargo
|
local loadedcargo = self.Loaded_Cargo[unitname] or {}
|
||||||
-- looking for crate
|
|
||||||
local cargotable = loadedcargo.Cargo
|
local cargotable = loadedcargo.Cargo
|
||||||
|
local droppedCount = {}
|
||||||
|
local neededMap = {}
|
||||||
for _,_cargo in pairs (cargotable) do
|
for _,_cargo in pairs (cargotable) do
|
||||||
local cargo = _cargo -- #CTLD_CARGO
|
local cargo = _cargo
|
||||||
local type = cargo:GetType() -- #CTLD_CARGO.Enum
|
local type = cargo:GetType()
|
||||||
if type ~= CTLD_CARGO.Enum.TROOPS and type ~= CTLD_CARGO.Enum.ENGINEERS and type ~= CTLD_CARGO.Enum.GCLOADABLE and (not cargo:WasDropped() or self.allowcratepickupagain) then
|
if type ~= CTLD_CARGO.Enum.TROOPS and type ~= CTLD_CARGO.Enum.ENGINEERS and type ~= CTLD_CARGO.Enum.GCLOADABLE and (not cargo:WasDropped() or self.allowcratepickupagain) then
|
||||||
-- unload crates
|
|
||||||
self:_GetCrates(Group, Unit, cargo, 1, true)
|
self:_GetCrates(Group, Unit, cargo, 1, true)
|
||||||
cargo:SetWasDropped(true)
|
cargo:SetWasDropped(true)
|
||||||
cargo:SetHasMoved(true)
|
cargo:SetHasMoved(true)
|
||||||
|
local cname = cargo:GetName() or "Unknown"
|
||||||
|
droppedCount[cname] = (droppedCount[cname] or 0) + 1
|
||||||
|
if not neededMap[cname] then
|
||||||
|
neededMap[cname] = cargo:GetCratesNeeded() or 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- cleanup load list
|
end
|
||||||
local loaded = {} -- #CTLD.LoadedCargo
|
for cname,count in pairs(droppedCount) do
|
||||||
|
local needed = neededMap[cname] or 1
|
||||||
|
if needed > 1 then
|
||||||
|
local full = math.floor(count/needed)
|
||||||
|
local left = count % needed
|
||||||
|
if full > 0 and left == 0 then
|
||||||
|
self:_SendMessage(string.format("Dropped %d %s.",full,cname),10,false,Group)
|
||||||
|
elseif full > 0 and left > 0 then
|
||||||
|
self:_SendMessage(string.format("Dropped %d %s(s), with %d leftover crate(s).",full,cname,left),10,false,Group)
|
||||||
|
else
|
||||||
|
self:_SendMessage(string.format("Dropped %d/%d crate(s) of %s.",count,needed,cname),15,false,Group)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:_SendMessage(string.format("Dropped %d %s(s).",count,cname),10,false,Group)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local loaded = {}
|
||||||
loaded.Troopsloaded = 0
|
loaded.Troopsloaded = 0
|
||||||
loaded.Cratesloaded = 0
|
loaded.Cratesloaded = 0
|
||||||
loaded.Cargo = {}
|
loaded.Cargo = {}
|
||||||
|
|
||||||
for _,_cargo in pairs (cargotable) do
|
for _,_cargo in pairs (cargotable) do
|
||||||
local cargo = _cargo -- #CTLD_CARGO
|
local cargo = _cargo
|
||||||
local type = cargo:GetType() -- #CTLD_CARGO.Enum
|
local type = cargo:GetType()
|
||||||
local size = cargo:GetCratesNeeded()
|
local size = cargo:GetCratesNeeded()
|
||||||
if type == CTLD_CARGO.Enum.TROOPS or type == CTLD_CARGO.Enum.ENGINEERS then
|
if type == CTLD_CARGO.Enum.TROOPS or type == CTLD_CARGO.Enum.ENGINEERS then
|
||||||
table.insert(loaded.Cargo,_cargo)
|
table.insert(loaded.Cargo,_cargo)
|
||||||
@ -3838,14 +3857,15 @@ function CTLD:_UnloadCrates(Group, Unit)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (Internal) Function to build nearby crates.
|
--- (Internal) Function to build nearby crates.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
-- @param Wrapper.Group#GROUP Group
|
-- @param Wrapper.Group#GROUP Group
|
||||||
-- @param Wrapper.Unit#UNIT Unit
|
-- @param Wrapper.Unit#UNIT Unit
|
||||||
-- @param #boolean Engineering If true build is by an engineering team.
|
-- @param #boolean Engineering If true build is by an engineering team.
|
||||||
function CTLD:_BuildCrates(Group, Unit,Engineering)
|
-- @param #boolean MultiDrop If true and not engineering or FOB, vary position a bit.
|
||||||
|
function CTLD:_BuildCrates(Group, Unit,Engineering,MultiDrop)
|
||||||
self:T(self.lid .. " _BuildCrates")
|
self:T(self.lid .. " _BuildCrates")
|
||||||
-- avoid users trying to build from flying Hercs
|
-- avoid users trying to build from flying Hercs
|
||||||
if self:IsFixedWing(Unit) and self.enableFixedWing and not Engineering then
|
if self:IsFixedWing(Unit) and self.enableFixedWing and not Engineering then
|
||||||
@ -3939,12 +3959,13 @@ function CTLD:_BuildCrates(Group, Unit,Engineering)
|
|||||||
if build.CanBuild then
|
if build.CanBuild then
|
||||||
self:_CleanUpCrates(crates,build,number)
|
self:_CleanUpCrates(crates,build,number)
|
||||||
if self.buildtime and self.buildtime > 0 then
|
if self.buildtime and self.buildtime > 0 then
|
||||||
local buildtimer = TIMER:New(self._BuildObjectFromCrates,self,Group,Unit,build,false,Group:GetCoordinate())
|
local buildtimer = TIMER:New(self._BuildObjectFromCrates,self,Group,Unit,build,false,Group:GetCoordinate(),MultiDrop)
|
||||||
buildtimer:Start(self.buildtime)
|
buildtimer:Start(self.buildtime)
|
||||||
self:_SendMessage(string.format("Build started, ready in %d seconds!",self.buildtime),15,false,Group)
|
self:_SendMessage(string.format("Build started, ready in %d seconds!",self.buildtime),15,false,Group)
|
||||||
self:__CratesBuildStarted(1,Group,Unit)
|
self:__CratesBuildStarted(1,Group,Unit)
|
||||||
|
self:_RefreshDropTroopsMenu(Group,Unit)
|
||||||
else
|
else
|
||||||
self:_BuildObjectFromCrates(Group,Unit,build)
|
self:_BuildObjectFromCrates(Group,Unit,build,false,nil,MultiDrop)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -3983,13 +4004,14 @@ function CTLD:_PackCratesNearby(Group, Unit)
|
|||||||
_Group:Destroy() -- if a match is found destroy the Wrapper.Group#GROUP near the player
|
_Group:Destroy() -- if a match is found destroy the Wrapper.Group#GROUP near the player
|
||||||
self:_GetCrates(Group, Unit, _entry, nil, false, true) -- spawn the appropriate crates near the player
|
self:_GetCrates(Group, Unit, _entry, nil, false, true) -- spawn the appropriate crates near the player
|
||||||
self:_RefreshLoadCratesMenu(Group,Unit) -- call the refresher to show the crates in the menu
|
self:_RefreshLoadCratesMenu(Group,Unit) -- call the refresher to show the crates in the menu
|
||||||
return self
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return self
|
self:_SendMessage("Nothing to pack at this distance pilot!",10,false,Group)
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (Internal) Function to repair nearby vehicles / FOBs
|
--- (Internal) Function to repair nearby vehicles / FOBs
|
||||||
@ -4082,7 +4104,8 @@ end
|
|||||||
-- @param #CTLD.Buildable Build
|
-- @param #CTLD.Buildable Build
|
||||||
-- @param #boolean Repair If true this is a repair and not a new build
|
-- @param #boolean Repair If true this is a repair and not a new build
|
||||||
-- @param Core.Point#COORDINATE RepairLocation Location for repair (e.g. where the destroyed unit was)
|
-- @param Core.Point#COORDINATE RepairLocation Location for repair (e.g. where the destroyed unit was)
|
||||||
function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation)
|
-- @param #boolean MultiDrop if true and not a repair, vary location a bit if not a FOB
|
||||||
|
function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation,MultiDrop)
|
||||||
self:T(self.lid .. " _BuildObjectFromCrates")
|
self:T(self.lid .. " _BuildObjectFromCrates")
|
||||||
-- Spawn-a-crate-content
|
-- Spawn-a-crate-content
|
||||||
if Group and Group:IsAlive() or (RepairLocation and not Repair) then
|
if Group and Group:IsAlive() or (RepairLocation and not Repair) then
|
||||||
@ -4099,7 +4122,7 @@ function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation)
|
|||||||
if type(temptable) == "string" then
|
if type(temptable) == "string" then
|
||||||
temptable = {temptable}
|
temptable = {temptable}
|
||||||
end
|
end
|
||||||
local zone = nil
|
local zone = nil -- Core.Zone#ZONE_RADIUS
|
||||||
if RepairLocation and not Repair then
|
if RepairLocation and not Repair then
|
||||||
-- timed build
|
-- timed build
|
||||||
zone = ZONE_RADIUS:New(string.format("Build zone-%d",math.random(1,10000)),RepairLocation:GetVec2(),100)
|
zone = ZONE_RADIUS:New(string.format("Build zone-%d",math.random(1,10000)),RepairLocation:GetVec2(),100)
|
||||||
@ -4108,6 +4131,10 @@ function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation)
|
|||||||
end
|
end
|
||||||
--local randomcoord = zone:GetRandomCoordinate(35):GetVec2()
|
--local randomcoord = zone:GetRandomCoordinate(35):GetVec2()
|
||||||
local randomcoord = Build.Coord or zone:GetRandomCoordinate(35):GetVec2()
|
local randomcoord = Build.Coord or zone:GetRandomCoordinate(35):GetVec2()
|
||||||
|
if MultiDrop and (not Repair) and canmove then
|
||||||
|
-- coordinate may be the same, avoid
|
||||||
|
local randomcoord = zone:GetRandomCoordinate(35):GetVec2()
|
||||||
|
end
|
||||||
if Repair then
|
if Repair then
|
||||||
randomcoord = RepairLocation:GetVec2()
|
randomcoord = RepairLocation:GetVec2()
|
||||||
end
|
end
|
||||||
@ -4199,11 +4226,91 @@ function CTLD:_CleanUpCrates(Crates,Build,Number)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- (Internal) Helper - Drop **all** loaded crates nearby and build them.
|
||||||
|
-- @param Wrapper.Group#GROUP Group The calling group
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit The calling unit
|
||||||
|
function CTLD:_DropAndBuild(Group,Unit)
|
||||||
|
if self.nobuildinloadzones then
|
||||||
|
if self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD) then
|
||||||
|
self:_SendMessage("You cannot build in a loading area, Pilot!",10,false,Group)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self:_UnloadCrates(Group,Unit)
|
||||||
|
timer.scheduleFunction(function() self:_BuildCrates(Group,Unit,false,true) end,{},timer.getTime()+1)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- (Internal) Helper - Drop a **single** crate set and build it.
|
||||||
|
-- @param Wrapper.Group#GROUP Group The calling group
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit The calling unit
|
||||||
|
-- @param number setIndex Index of the crate-set to drop
|
||||||
|
function CTLD:_DropSingleAndBuild(Group,Unit,setIndex)
|
||||||
|
if self.nobuildinloadzones then
|
||||||
|
if self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD) then
|
||||||
|
self:_SendMessage("You cannot build in a loading area, Pilot!",10,false,Group)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self:_UnloadSingleCrateSet(Group,Unit,setIndex)
|
||||||
|
timer.scheduleFunction(function() self:_BuildCrates(Group,Unit,false) end,{},timer.getTime()+1)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- (Internal) Helper - Pack crates near the unit and load them.
|
||||||
|
-- @param Wrapper.Group#GROUP Group The calling group
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit The calling unit
|
||||||
|
function CTLD:_PackAndLoad(Group,Unit)
|
||||||
|
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)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
if not self:_PackCratesNearby(Group,Unit) then
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
timer.scheduleFunction(function() self:_LoadCratesNearby(Group,Unit) end,{},timer.getTime()+1)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- (Internal) Helper - Pack crates near the unit and then remove them.
|
||||||
|
-- @param Wrapper.Group#GROUP Group The calling group
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit The calling unit
|
||||||
|
function CTLD:_PackAndRemove(Group,Unit)
|
||||||
|
if not self:_PackCratesNearby(Group,Unit) then
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
timer.scheduleFunction(function() self:_RemoveCratesNearby(Group,Unit) end,{},timer.getTime()+1)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- (Internal) Helper - get and load in one step
|
||||||
|
-- @param Wrapper.Group#GROUP Group The calling group
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit The calling unit
|
||||||
|
function CTLD:_GetAndLoad(Group,Unit,cargoObj)
|
||||||
|
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)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
self:_GetCrates(Group,Unit,cargoObj)
|
||||||
|
|
||||||
|
timer.scheduleFunction(function() self:_LoadSingleCrateSet(Group,Unit,cargoObj.Name) end,{},timer.getTime()+1)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- @param Wrapper.Group#GROUP Group The player’s group that triggered the action
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit The unit performing the pack-and-load
|
||||||
|
function CTLD:_GetAllAndLoad(Group,Unit)
|
||||||
|
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)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
timer.scheduleFunction(function() self:_LoadCratesNearby(Group,Unit) end,{},timer.getTime()+1)
|
||||||
|
end
|
||||||
|
|
||||||
--- (Internal) Housekeeping - Function to refresh F10 menus.
|
--- (Internal) Housekeeping - Function to refresh F10 menus.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
-- @return #CTLD self
|
-- @return #CTLD self
|
||||||
function CTLD:_RefreshF10Menus()
|
function CTLD:_RefreshF10Menus()
|
||||||
self:T(self.lid .. " _RefreshF10Menus")
|
self:T(self.lid .. " _RefreshF10Menus")
|
||||||
|
self.onestepmenu = self.onestepmenu or false -- hybrid toggle (default = false)
|
||||||
|
|
||||||
-- 1) Gather all the pilot groups from our Set
|
-- 1) Gather all the pilot groups from our Set
|
||||||
local PlayerSet = self.PilotGroups
|
local PlayerSet = self.PilotGroups
|
||||||
@ -4314,7 +4421,6 @@ function CTLD:_RefreshF10Menus()
|
|||||||
local menutext = cargoObj.Name
|
local menutext = cargoObj.Name
|
||||||
if (stock >= 0) and (self.showstockinmenuitems == true) then menutext = menutext.." ["..stock.."]" end
|
if (stock >= 0) and (self.showstockinmenuitems == true) then menutext = menutext.." ["..stock.."]" end
|
||||||
MENU_GROUP_COMMAND:New(_group, menutext, troopsmenu, self._LoadTroops, self, _group, _unit, cargoObj)
|
MENU_GROUP_COMMAND:New(_group, menutext, troopsmenu, self._LoadTroops, self, _group, _unit, cargoObj)
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -4340,11 +4446,65 @@ function CTLD:_RefreshF10Menus()
|
|||||||
_group.MyTopCratesMenu = topcrates
|
_group.MyTopCratesMenu = topcrates
|
||||||
|
|
||||||
-- Build the “Get Crates” sub-menu items
|
-- Build the “Get Crates” sub-menu items
|
||||||
local cratesmenu = MENU_GROUP:New(_group, "Get Crates", topcrates)
|
local cratesmenu = MENU_GROUP:New(_group,"Get Crates",topcrates)
|
||||||
|
|
||||||
|
if self.onestepmenu then
|
||||||
|
if self.usesubcats then
|
||||||
|
local subcatmenus = {}
|
||||||
|
for catName,_ in pairs(self.subcats) do
|
||||||
|
subcatmenus[catName] = MENU_GROUP:New(_group,catName,cratesmenu)
|
||||||
|
end
|
||||||
|
for _,cargoObj in pairs(self.Cargo_Crates) do
|
||||||
|
if not cargoObj.DontShowInMenu then
|
||||||
|
local txt = string.format("Crate %s (%dkg)",cargoObj.Name,cargoObj.PerCrateMass or 0)
|
||||||
|
if cargoObj.Location then txt = txt.."[R]" end
|
||||||
|
local stock = cargoObj:GetStock()
|
||||||
|
if stock>=0 and self.showstockinmenuitems then txt = txt.."["..stock.."]" end
|
||||||
|
local mSet = MENU_GROUP:New(_group,txt,subcatmenus[cargoObj.Subcategory])
|
||||||
|
MENU_GROUP_COMMAND:New(_group,"Get and Load",mSet,self._GetAndLoad,self,_group,_unit,cargoObj)
|
||||||
|
MENU_GROUP_COMMAND:New(_group,"Get only",mSet,self._GetCrates,self,_group,_unit,cargoObj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _,cargoObj in pairs(self.Cargo_Statics) do
|
||||||
|
if not cargoObj.DontShowInMenu then
|
||||||
|
local txt = string.format("Crate %s (%dkg)",cargoObj.Name,cargoObj.PerCrateMass or 0)
|
||||||
|
if cargoObj.Location then txt = txt.."[R]" end
|
||||||
|
local stock = cargoObj:GetStock()
|
||||||
|
if stock>=0 and self.showstockinmenuitems then txt = txt.."["..stock.."]" end
|
||||||
|
local mSet = MENU_GROUP:New(_group,txt,subcatmenus[cargoObj.Subcategory])
|
||||||
|
MENU_GROUP_COMMAND:New(_group,"Get and Load",mSet,self._GetAndLoad,self,_group,_unit,cargoObj)
|
||||||
|
MENU_GROUP_COMMAND:New(_group,"Get only",mSet,self._GetCrates,self,_group,_unit,cargoObj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for _,cargoObj in pairs(self.Cargo_Crates) do
|
||||||
|
if not cargoObj.DontShowInMenu then
|
||||||
|
local txt = string.format("Crate %s (%dkg)",cargoObj.Name,cargoObj.PerCrateMass or 0)
|
||||||
|
if cargoObj.Location then txt = txt.."[R]" end
|
||||||
|
local stock = cargoObj:GetStock()
|
||||||
|
if stock>=0 and self.showstockinmenuitems then txt = txt.."["..stock.."]" end
|
||||||
|
local mSet = MENU_GROUP:New(_group,txt,cratesmenu)
|
||||||
|
MENU_GROUP_COMMAND:New(_group,"Get and Load",mSet,self._GetAndLoad,self,_group,_unit,cargoObj)
|
||||||
|
MENU_GROUP_COMMAND:New(_group,"Get only",mSet,self._GetCrates,self,_group,_unit,cargoObj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _,cargoObj in pairs(self.Cargo_Statics) do
|
||||||
|
if not cargoObj.DontShowInMenu then
|
||||||
|
local txt = string.format("Crate %s (%dkg)",cargoObj.Name,cargoObj.PerCrateMass or 0)
|
||||||
|
if cargoObj.Location then txt = txt.."[R]" end
|
||||||
|
local stock = cargoObj:GetStock()
|
||||||
|
if stock>=0 and self.showstockinmenuitems then txt = txt.."["..stock.."]" end
|
||||||
|
local mSet = MENU_GROUP:New(_group,txt,cratesmenu)
|
||||||
|
MENU_GROUP_COMMAND:New(_group,"Get and Load",mSet,self._GetAndLoad,self,_group,_unit,cargoObj)
|
||||||
|
MENU_GROUP_COMMAND:New(_group,"Get only",mSet,self._GetCrates,self,_group,_unit,cargoObj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
if self.usesubcats then
|
if self.usesubcats then
|
||||||
local subcatmenus = {}
|
local subcatmenus = {}
|
||||||
for catName, _ in pairs(self.subcats) do
|
for catName, _ in pairs(self.subcats) do
|
||||||
subcatmenus[catName] = MENU_GROUP:New(_group, catName, cratesmenu)
|
subcatmenus[catName] = MENU_GROUP:New(_group, catName, cratesmenu) -- fixed variable case
|
||||||
end
|
end
|
||||||
for _, cargoObj in pairs(self.Cargo_Crates) do
|
for _, cargoObj in pairs(self.Cargo_Crates) do
|
||||||
if not cargoObj.DontShowInMenu then
|
if not cargoObj.DontShowInMenu then
|
||||||
@ -4384,14 +4544,15 @@ function CTLD:_RefreshF10Menus()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local loadCratesMenu=MENU_GROUP:New(_group,"Load Crates",topcrates)
|
local loadCratesMenu=MENU_GROUP:New(_group,"Load Crates",topcrates)
|
||||||
_group.MyLoadCratesMenu=loadCratesMenu
|
_group.MyLoadCratesMenu=loadCratesMenu
|
||||||
MENU_GROUP_COMMAND:New(_group,"Load ALL",loadCratesMenu,self._LoadCratesNearby,self,_group,_unit)
|
MENU_GROUP_COMMAND:New(_group,"Load ALL",loadCratesMenu,self._LoadCratesNearby,self,_group,_unit)
|
||||||
MENU_GROUP_COMMAND:New(_group,"Show loadable crates",loadCratesMenu,self._RefreshLoadCratesMenu,self,_group,_unit)
|
MENU_GROUP_COMMAND:New(_group,"Show loadable crates",loadCratesMenu,self._RefreshLoadCratesMenu,self,_group,_unit)
|
||||||
|
|
||||||
local dropCratesMenu=MENU_GROUP:New(_group,"Drop Crates",topcrates)
|
local dropCratesMenu = MENU_GROUP:New(_group,"Drop Crates",topcrates)
|
||||||
topcrates.DropCratesMenu=dropCratesMenu
|
topcrates.DropCratesMenu = dropCratesMenu
|
||||||
|
|
||||||
if not self.nobuildmenu then
|
if not self.nobuildmenu then
|
||||||
MENU_GROUP_COMMAND:New(_group, "Build crates", topcrates, self._BuildCrates, self, _group, _unit)
|
MENU_GROUP_COMMAND:New(_group, "Build crates", topcrates, self._BuildCrates, self, _group, _unit)
|
||||||
@ -4401,8 +4562,16 @@ function CTLD:_RefreshF10Menus()
|
|||||||
local removecratesmenu = MENU_GROUP:New(_group, "Remove crates", topcrates)
|
local removecratesmenu = MENU_GROUP:New(_group, "Remove crates", topcrates)
|
||||||
MENU_GROUP_COMMAND:New(_group, "Remove crates nearby", removecratesmenu, self._RemoveCratesNearby, self, _group, _unit)
|
MENU_GROUP_COMMAND:New(_group, "Remove crates nearby", removecratesmenu, self._RemoveCratesNearby, self, _group, _unit)
|
||||||
|
|
||||||
|
if self.onestepmenu then
|
||||||
|
local mPack=MENU_GROUP:New(_group,"Pack crates",topcrates)
|
||||||
|
MENU_GROUP_COMMAND:New(_group,"Pack and Load",mPack,self._PackAndLoad,self,_group,_unit)
|
||||||
|
MENU_GROUP_COMMAND:New(_group,"Pack and Remove",mPack,self._PackAndRemove,self,_group,_unit)
|
||||||
|
MENU_GROUP_COMMAND:New(_group,"Pack only",mPack,self._PackCratesNearby,self,_group,_unit)
|
||||||
|
MENU_GROUP_COMMAND:New(_group, "List crates nearby", topcrates, self._ListCratesNearby, self, _group, _unit)
|
||||||
|
else
|
||||||
MENU_GROUP_COMMAND:New(_group, "Pack crates", topcrates, self._PackCratesNearby, self, _group, _unit)
|
MENU_GROUP_COMMAND:New(_group, "Pack crates", topcrates, self._PackCratesNearby, self, _group, _unit)
|
||||||
MENU_GROUP_COMMAND:New(_group, "List crates nearby", topcrates, self._ListCratesNearby, self, _group, _unit)
|
MENU_GROUP_COMMAND:New(_group, "List crates nearby", topcrates, self._ListCratesNearby, self, _group, _unit)
|
||||||
|
end
|
||||||
|
|
||||||
local uName = _unit:GetName()
|
local uName = _unit:GetName()
|
||||||
local loadedData = self.Loaded_Cargo[uName]
|
local loadedData = self.Loaded_Cargo[uName]
|
||||||
@ -4423,8 +4592,6 @@ function CTLD:_RefreshF10Menus()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
-- Misc sub‐menus
|
-- Misc sub‐menus
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
@ -4453,7 +4620,7 @@ function CTLD:_RefreshF10Menus()
|
|||||||
|
|
||||||
-- Mark we built the menu
|
-- Mark we built the menu
|
||||||
self.MenusDone[_unitName] = true
|
self.MenusDone[_unitName] = true
|
||||||
self:_RefreshLoadCratesMenu(_group, _unit)
|
self:_RefreshLoadCratesMenu(_group,_unit)
|
||||||
self:_RefreshDropCratesMenu(_group,_unit)
|
self:_RefreshDropCratesMenu(_group,_unit)
|
||||||
|
|
||||||
end -- if _group
|
end -- if _group
|
||||||
@ -4464,45 +4631,53 @@ function CTLD:_RefreshF10Menus()
|
|||||||
end -- for all pilot units
|
end -- for all pilot units
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (Internal) Function to refresh the menu for load crates. Triggered from land/getcrate/pack and more
|
--- (Internal) Function to refresh the menu for load crates. Triggered from land/getcrate/pack and more
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
-- @param Wrapper.Group#GROUP Group The calling group.
|
-- @param Wrapper.Group#GROUP Group The calling group.
|
||||||
-- @param Wrapper.Unit#UNIT Unit The calling unit.
|
-- @param Wrapper.Unit#UNIT Unit The calling unit.
|
||||||
-- @return #CTLD self
|
-- @return #CTLD self
|
||||||
function CTLD:_RefreshLoadCratesMenu(Group, Unit)
|
function CTLD:_RefreshLoadCratesMenu(Group,Unit)
|
||||||
if not Group.MyLoadCratesMenu then return end
|
if not Group.MyLoadCratesMenu then return end
|
||||||
Group.MyLoadCratesMenu:RemoveSubMenus()
|
Group.MyLoadCratesMenu:RemoveSubMenus()
|
||||||
|
|
||||||
local d = self.CrateDistance or 35
|
local d=self.CrateDistance or 35
|
||||||
local nearby, n = self:_FindCratesNearby(Group, Unit, d, true, true)
|
local nearby,n=self:_FindCratesNearby(Group,Unit,d,true,true)
|
||||||
if n == 0 then
|
if n==0 then
|
||||||
MENU_GROUP_COMMAND:New(Group, "No crates found! Rescan?", Group.MyLoadCratesMenu, function() self:_RefreshLoadCratesMenu(Group, Unit) end)
|
MENU_GROUP_COMMAND:New(Group,"No crates found! Rescan?",Group.MyLoadCratesMenu,function() self:_RefreshLoadCratesMenu(Group,Unit) end)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New(Group, "Load ALL", Group.MyLoadCratesMenu, self._LoadCratesNearby, self, Group, Unit)
|
MENU_GROUP_COMMAND:New(Group,"Load ALL",Group.MyLoadCratesMenu,self._LoadCratesNearby,self,Group,Unit)
|
||||||
local cargoByName = {}
|
|
||||||
for _, crate in pairs(nearby) do
|
local cargoByName={}
|
||||||
local cName = crate:GetName()
|
for _,crate in pairs(nearby) do
|
||||||
cargoByName[cName] = cargoByName[cName] or {}
|
local name=crate:GetName()
|
||||||
table.insert(cargoByName[cName], crate)
|
cargoByName[name]=cargoByName[name] or{}
|
||||||
|
table.insert(cargoByName[name],crate)
|
||||||
end
|
end
|
||||||
|
|
||||||
for cName, cList in pairs(cargoByName) do
|
local lineIndex=1
|
||||||
local needed = cList[1]:GetCratesNeeded() or 1
|
for cName,list in pairs(cargoByName) do
|
||||||
local found = #cList
|
local needed=list[1]:GetCratesNeeded() or 1
|
||||||
|
table.sort(list,function(a,b)return a:GetID()<b:GetID() end)
|
||||||
local line
|
local i=1
|
||||||
if found >= needed then
|
while i<=#list do
|
||||||
line = string.format("Load %s", cName)
|
local left=#list-i+1
|
||||||
|
local label
|
||||||
|
if left>=needed then
|
||||||
|
label=string.format("%d. Load %s",lineIndex,cName)
|
||||||
|
i=i+needed
|
||||||
else
|
else
|
||||||
MENU_GROUP_COMMAND:New(Group, "Rescan?", Group.MyLoadCratesMenu, function() self:_RefreshLoadCratesMenu(Group, Unit) end)
|
label=string.format("%d. Load %s (%d/%d)",lineIndex,cName,left,needed)
|
||||||
line = string.format("Load %s (%d/%d)", cName, found, needed)
|
i=#list+1
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New(Group, line, Group.MyLoadCratesMenu, self._LoadSingleCrateSet, self, Group, Unit, cName)
|
MENU_GROUP_COMMAND:New(Group,label,Group.MyLoadCratesMenu,self._LoadSingleCrateSet,self,Group,Unit,cName)
|
||||||
|
lineIndex=lineIndex+1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Loads exactly `CratesNeeded` crates for one cargoName in range.
|
-- Loads exactly `CratesNeeded` crates for one cargoName in range.
|
||||||
@ -4745,6 +4920,7 @@ end
|
|||||||
-- @param Wrapper.Unit#UNIT Unit The calling unit.
|
-- @param Wrapper.Unit#UNIT Unit The calling unit.
|
||||||
-- @return #CTLD self
|
-- @return #CTLD self
|
||||||
function CTLD:_RefreshDropCratesMenu(Group, Unit)
|
function CTLD:_RefreshDropCratesMenu(Group, Unit)
|
||||||
|
|
||||||
if not Group.CTLDTopmenu then return end
|
if not Group.CTLDTopmenu then return end
|
||||||
local topCrates = Group.MyTopCratesMenu
|
local topCrates = Group.MyTopCratesMenu
|
||||||
if not topCrates then return end
|
if not topCrates then return end
|
||||||
@ -4780,7 +4956,15 @@ function CTLD:_RefreshDropCratesMenu(Group, Unit)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
-- DEFAULT (“classic”) versus ONE-STEP behaviour
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
if not self.onestepmenu then
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
-- classic menu
|
||||||
|
--------------------------------------------------------------------
|
||||||
MENU_GROUP_COMMAND:New(Group,"Drop ALL crates",dropCratesMenu,self._UnloadCrates,self,Group,Unit)
|
MENU_GROUP_COMMAND:New(Group,"Drop ALL crates",dropCratesMenu,self._UnloadCrates,self,Group,Unit)
|
||||||
|
|
||||||
self.CrateGroupList=self.CrateGroupList or{}
|
self.CrateGroupList=self.CrateGroupList or{}
|
||||||
self.CrateGroupList[Unit:GetName()]={}
|
self.CrateGroupList[Unit:GetName()]={}
|
||||||
|
|
||||||
@ -4815,7 +4999,53 @@ function CTLD:_RefreshDropCratesMenu(Group, Unit)
|
|||||||
lineIndex=lineIndex+1
|
lineIndex=lineIndex+1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
else
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
-- one-step (enhanced) menu
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
local mAll=MENU_GROUP:New(Group,"Drop ALL crates",dropCratesMenu)
|
||||||
|
MENU_GROUP_COMMAND:New(Group,"Drop and build",mAll,self._DropAndBuild,self,Group,Unit)
|
||||||
|
MENU_GROUP_COMMAND:New(Group,"Drop only",mAll,self._UnloadCrates,self,Group,Unit)
|
||||||
|
|
||||||
|
self.CrateGroupList=self.CrateGroupList or{}
|
||||||
|
self.CrateGroupList[Unit:GetName()]={}
|
||||||
|
|
||||||
|
local lineIndex=1
|
||||||
|
for cName,list in pairs(cargoByName) do
|
||||||
|
local needed=list[1]:GetCratesNeeded() or 1
|
||||||
|
table.sort(list,function(a,b)return a:GetID()<b:GetID()end)
|
||||||
|
local i=1
|
||||||
|
while i<=#list do
|
||||||
|
local left=(#list-i+1)
|
||||||
|
if left>=needed then
|
||||||
|
local chunk={}
|
||||||
|
for n=i,i+needed-1 do
|
||||||
|
table.insert(chunk,list[n])
|
||||||
|
end
|
||||||
|
local label=string.format("%d. %s",lineIndex,cName)
|
||||||
|
table.insert(self.CrateGroupList[Unit:GetName()],chunk)
|
||||||
|
local setIndex=#self.CrateGroupList[Unit:GetName()]
|
||||||
|
local mSet=MENU_GROUP:New(Group,label,dropCratesMenu)
|
||||||
|
MENU_GROUP_COMMAND:New(Group,"Drop and build",mSet,self._DropSingleAndBuild,self,Group,Unit,setIndex)
|
||||||
|
MENU_GROUP_COMMAND:New(Group,"Drop only",mSet,self._UnloadSingleCrateSet,self,Group,Unit,setIndex)
|
||||||
|
i=i+needed
|
||||||
|
else
|
||||||
|
local chunk={}
|
||||||
|
for n=i,#list do
|
||||||
|
table.insert(chunk,list[n])
|
||||||
|
end
|
||||||
|
local label=string.format("%d. %s %d/%d",lineIndex,cName,left,needed)
|
||||||
|
table.insert(self.CrateGroupList[Unit:GetName()],chunk)
|
||||||
|
local setIndex=#self.CrateGroupList[Unit:GetName()]
|
||||||
|
MENU_GROUP_COMMAND:New(Group,label,dropCratesMenu,self._UnloadSingleCrateSet,self,Group,Unit,setIndex)
|
||||||
|
i=#list+1
|
||||||
|
end
|
||||||
|
lineIndex=lineIndex+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- (Internal) Function to unload a single Troop group by ID.
|
--- (Internal) Function to unload a single Troop group by ID.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
|
|||||||
@ -897,7 +897,7 @@ function UNIT:GetAmmunition()
|
|||||||
nAPshells = nAPshells + Nammo
|
nAPshells = nAPshells + Nammo
|
||||||
end
|
end
|
||||||
|
|
||||||
if ammotable[w].desc.typeName and string.find(ammotable[w].desc.typeName, "_HE", 1, true) then
|
if ammotable[w].desc.typeName and (string.find(ammotable[w].desc.typeName, "_HE", 1, true) or string.find(ammotable[w].desc.typeName, "HESH", 1, true)) then
|
||||||
nHEshells = nHEshells + Nammo
|
nHEshells = nHEshells + Nammo
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user