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!!)
|
||||
-- ### Repack addition for crates: **Raiden**
|
||||
-- ### Additional cool features: **Lekaa**
|
||||
--
|
||||
-- @module Ops.CTLD
|
||||
-- @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.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.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
|
||||
--
|
||||
@ -1412,7 +1414,7 @@ CTLD.FixedWingTypes = {
|
||||
|
||||
--- CTLD class version.
|
||||
-- @field #string version
|
||||
CTLD.version="1.2.33"
|
||||
CTLD.version="1.3.34"
|
||||
|
||||
--- Instantiate a new CTLD.
|
||||
-- @param #CTLD self
|
||||
@ -1591,6 +1593,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
self.subcats = {}
|
||||
self.subcatsTroop = {}
|
||||
self.showstockinmenuitems = false
|
||||
self.onestepmenu = false
|
||||
|
||||
-- disallow building in loadzones
|
||||
self.nobuildinloadzones = true
|
||||
@ -2913,10 +2916,10 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack)
|
||||
if drop then
|
||||
text = string.format("Crates for %s have been dropped!",cratename)
|
||||
self:__CratesDropped(1, Group, Unit, droppedcargo)
|
||||
end
|
||||
else
|
||||
self:_SendMessage(text, 10, false, Group)
|
||||
end
|
||||
self:_RefreshLoadCratesMenu(Group, Unit)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@ -3576,7 +3579,10 @@ end
|
||||
-- @param Wrapper.Unit#UNIT Unit
|
||||
-- @return #boolean Outcome
|
||||
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
|
||||
else
|
||||
return false
|
||||
@ -3766,7 +3772,6 @@ function CTLD:_UnloadCrates(Group, Unit)
|
||||
self:T(self.lid .. " _UnloadCrates")
|
||||
|
||||
if not self.dropcratesanywhere then -- #1570
|
||||
-- check if we are in DROP zone
|
||||
local inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.DROP)
|
||||
if not inzone then
|
||||
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
|
||||
-- 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 hoverunload = self:IsCorrectHover(Unit)
|
||||
local IsHerc = self:IsFixedWing(Unit)
|
||||
local IsHook = self:IsHook(Unit)
|
||||
if IsHerc and (not IsHook) then
|
||||
-- no hover but airdrop here
|
||||
hoverunload = self:IsCorrectFlightParameters(Unit)
|
||||
end
|
||||
-- check if we\'re landed
|
||||
local grounded = not self:IsUnitInAir(Unit)
|
||||
-- Get what we have loaded
|
||||
local unitname = Unit:GetName()
|
||||
if self.Loaded_Cargo[unitname] and (grounded or hoverunload) then
|
||||
local loadedcargo = self.Loaded_Cargo[unitname] or {} -- #CTLD.LoadedCargo
|
||||
-- looking for crate
|
||||
local loadedcargo = self.Loaded_Cargo[unitname] or {}
|
||||
local cargotable = loadedcargo.Cargo
|
||||
local droppedCount = {}
|
||||
local neededMap = {}
|
||||
for _,_cargo in pairs (cargotable) do
|
||||
local cargo = _cargo -- #CTLD_CARGO
|
||||
local type = cargo:GetType() -- #CTLD_CARGO.Enum
|
||||
local cargo = _cargo
|
||||
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
|
||||
-- unload crates
|
||||
self:_GetCrates(Group, Unit, cargo, 1, true)
|
||||
cargo:SetWasDropped(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
|
||||
-- cleanup load list
|
||||
local loaded = {} -- #CTLD.LoadedCargo
|
||||
end
|
||||
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.Cratesloaded = 0
|
||||
loaded.Cargo = {}
|
||||
|
||||
for _,_cargo in pairs (cargotable) do
|
||||
local cargo = _cargo -- #CTLD_CARGO
|
||||
local type = cargo:GetType() -- #CTLD_CARGO.Enum
|
||||
local cargo = _cargo
|
||||
local type = cargo:GetType()
|
||||
local size = cargo:GetCratesNeeded()
|
||||
if type == CTLD_CARGO.Enum.TROOPS or type == CTLD_CARGO.Enum.ENGINEERS then
|
||||
table.insert(loaded.Cargo,_cargo)
|
||||
@ -3845,7 +3864,8 @@ end
|
||||
-- @param Wrapper.Group#GROUP Group
|
||||
-- @param Wrapper.Unit#UNIT Unit
|
||||
-- @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")
|
||||
-- avoid users trying to build from flying Hercs
|
||||
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
|
||||
self:_CleanUpCrates(crates,build,number)
|
||||
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)
|
||||
self:_SendMessage(string.format("Build started, ready in %d seconds!",self.buildtime),15,false,Group)
|
||||
self:__CratesBuildStarted(1,Group,Unit)
|
||||
self:_RefreshDropTroopsMenu(Group,Unit)
|
||||
else
|
||||
self:_BuildObjectFromCrates(Group,Unit,build)
|
||||
self:_BuildObjectFromCrates(Group,Unit,build,false,nil,MultiDrop)
|
||||
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
|
||||
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
|
||||
return self
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return self
|
||||
self:_SendMessage("Nothing to pack at this distance pilot!",10,false,Group)
|
||||
return false
|
||||
end
|
||||
|
||||
--- (Internal) Function to repair nearby vehicles / FOBs
|
||||
@ -4082,7 +4104,8 @@ end
|
||||
-- @param #CTLD.Buildable 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)
|
||||
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")
|
||||
-- Spawn-a-crate-content
|
||||
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
|
||||
temptable = {temptable}
|
||||
end
|
||||
local zone = nil
|
||||
local zone = nil -- Core.Zone#ZONE_RADIUS
|
||||
if RepairLocation and not Repair then
|
||||
-- timed build
|
||||
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
|
||||
--local randomcoord = 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
|
||||
randomcoord = RepairLocation:GetVec2()
|
||||
end
|
||||
@ -4199,11 +4226,91 @@ function CTLD:_CleanUpCrates(Crates,Build,Number)
|
||||
return self
|
||||
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.
|
||||
-- @param #CTLD self
|
||||
-- @return #CTLD self
|
||||
function CTLD:_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
|
||||
local PlayerSet = self.PilotGroups
|
||||
@ -4314,7 +4421,6 @@ function CTLD:_RefreshF10Menus()
|
||||
local menutext = cargoObj.Name
|
||||
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)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -4341,11 +4447,65 @@ function CTLD:_RefreshF10Menus()
|
||||
|
||||
-- Build the “Get Crates” sub-menu items
|
||||
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
|
||||
local subcatmenus = {}
|
||||
for catName, _ in pairs(self.subcats) do
|
||||
subcatmenus[catName] = MENU_GROUP:New(_group, catName, cratesmenu) -- fixed variable case
|
||||
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)
|
||||
@ -4384,6 +4544,7 @@ function CTLD:_RefreshF10Menus()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local loadCratesMenu=MENU_GROUP:New(_group,"Load Crates",topcrates)
|
||||
_group.MyLoadCratesMenu=loadCratesMenu
|
||||
@ -4401,8 +4562,16 @@ function CTLD:_RefreshF10Menus()
|
||||
local removecratesmenu = MENU_GROUP:New(_group, "Remove crates", topcrates)
|
||||
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, "List crates nearby", topcrates, self._ListCratesNearby, self, _group, _unit)
|
||||
end
|
||||
|
||||
local uName = _unit:GetName()
|
||||
local loadedData = self.Loaded_Cargo[uName]
|
||||
@ -4423,8 +4592,6 @@ function CTLD:_RefreshF10Menus()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Misc sub‐menus
|
||||
-----------------------------------------------------
|
||||
@ -4482,27 +4649,35 @@ function CTLD:_RefreshLoadCratesMenu(Group, Unit)
|
||||
return
|
||||
end
|
||||
MENU_GROUP_COMMAND:New(Group,"Load ALL",Group.MyLoadCratesMenu,self._LoadCratesNearby,self,Group,Unit)
|
||||
|
||||
local cargoByName={}
|
||||
for _,crate in pairs(nearby) do
|
||||
local cName = crate:GetName()
|
||||
cargoByName[cName] = cargoByName[cName] or {}
|
||||
table.insert(cargoByName[cName], crate)
|
||||
local name=crate:GetName()
|
||||
cargoByName[name]=cargoByName[name] or{}
|
||||
table.insert(cargoByName[name],crate)
|
||||
end
|
||||
|
||||
for cName, cList in pairs(cargoByName) do
|
||||
local needed = cList[1]:GetCratesNeeded() or 1
|
||||
local found = #cList
|
||||
|
||||
local line
|
||||
if found >= needed then
|
||||
line = string.format("Load %s", cName)
|
||||
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
|
||||
local label
|
||||
if left>=needed then
|
||||
label=string.format("%d. Load %s",lineIndex,cName)
|
||||
i=i+needed
|
||||
else
|
||||
MENU_GROUP_COMMAND:New(Group, "Rescan?", Group.MyLoadCratesMenu, function() self:_RefreshLoadCratesMenu(Group, Unit) end)
|
||||
line = string.format("Load %s (%d/%d)", cName, found, needed)
|
||||
label=string.format("%d. Load %s (%d/%d)",lineIndex,cName,left,needed)
|
||||
i=#list+1
|
||||
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
|
||||
|
||||
|
||||
---
|
||||
-- Loads exactly `CratesNeeded` crates for one cargoName in range.
|
||||
@ -4745,6 +4920,7 @@ end
|
||||
-- @param Wrapper.Unit#UNIT Unit The calling unit.
|
||||
-- @return #CTLD self
|
||||
function CTLD:_RefreshDropCratesMenu(Group, Unit)
|
||||
|
||||
if not Group.CTLDTopmenu then return end
|
||||
local topCrates = Group.MyTopCratesMenu
|
||||
if not topCrates then return end
|
||||
@ -4780,7 +4956,15 @@ function CTLD:_RefreshDropCratesMenu(Group, Unit)
|
||||
return
|
||||
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)
|
||||
|
||||
self.CrateGroupList=self.CrateGroupList or{}
|
||||
self.CrateGroupList[Unit:GetName()]={}
|
||||
|
||||
@ -4815,6 +4999,52 @@ function CTLD:_RefreshDropCratesMenu(Group, Unit)
|
||||
lineIndex=lineIndex+1
|
||||
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.
|
||||
|
||||
@ -897,7 +897,7 @@ function UNIT:GetAmmunition()
|
||||
nAPshells = nAPshells + Nammo
|
||||
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
|
||||
end
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user