Update CTLD.lua

Fixed so the Engineer can remove all the items when he is building from an airdrop.

Added a function that I use, CanGetCrates, it's a check before getting it if the conditions are met.

Added small fixes where calling FindCratesNearBy would remove the units when it's called by the function RemoveCratesNearBy when it was checking the surroundings and it should ignore what is inside. In the case of C-130 and the CH-47.

Added how many crates are dropped when getting statics.

Expanded OnAfterTroopsRTB to accept chunk, ie the number of units which is returned.
This commit is contained in:
leka1986
2026-01-05 03:43:28 +01:00
committed by GitHub
parent 3cfaa60ebb
commit 3504797147
+104 -80
View File
@@ -193,6 +193,7 @@ CTLD_CARGO = {
-- @param Wrapper.Unit#UNIT Unit -- @param Wrapper.Unit#UNIT Unit
-- @return #boolean Outcome -- @return #boolean Outcome
function CTLD_CARGO:UnitCanCarry(Unit) function CTLD_CARGO:UnitCanCarry(Unit)
if not Unit then return false end
if self.TypeNames == nil then return true end if self.TypeNames == nil then return true end
local typename = Unit:GetTypeName() or "none" local typename = Unit:GetTypeName() or "none"
if self.TypeNames[typename] then if self.TypeNames[typename] then
@@ -3137,6 +3138,17 @@ function CTLD:_AddCrateQuantityMenus(Group, Unit, parentMenu, cargoObj, stockSum
return self return self
end end
--- User overrideable function to determine if a unit can get crates.
-- @param #CTLD self
-- @param Wrapper.Group#GROUP Group
-- @param Wrapper.Unit#UNIT Unit
-- @param #table Config Configuration entry for the unit.
-- @param #number quantity Number of crate sets requested.
-- @param #boolean quiet If true, do not send messages to the user.
function CTLD:CanGetUnits(Group, Unit, Config, quantity, quiet)
return true
end
--- (Internal) Spawn a “Get units” entry for a C-130J-30 at load zone. --- (Internal) Spawn a “Get units” entry for a C-130J-30 at load zone.
-- @param #CTLD self -- @param #CTLD self
-- @param Wrapper.Group#GROUP Group -- @param Wrapper.Group#GROUP Group
@@ -3167,6 +3179,9 @@ function CTLD:_C130GetUnits(Group, Unit, Name)
self:_SendMessage("You are not close enough to a logistics zone!",10,false,Group) self:_SendMessage("You are not close enough to a logistics zone!",10,false,Group)
return self return self
end end
if not self:CanGetUnits(Group, Unit, cfg, 1, false) then
return self
end
local coord = Unit:GetCoordinate() or Group:GetCoordinate() local coord = Unit:GetCoordinate() or Group:GetCoordinate()
local capabilities = self:_GetUnitCapabilities(Unit) local capabilities = self:_GetUnitCapabilities(Unit)
@@ -3514,9 +3529,9 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppress
Cargo:RemoveStock(requestedSets) Cargo:RemoveStock(requestedSets)
self:_RefreshCrateQuantityMenus(Group, Unit, Cargo) self:_RefreshCrateQuantityMenus(Group, Unit, Cargo)
end end
local text = string.format("Crates for %s have been positioned near you!",cratename) local text = string.format("%d crates for %s have been positioned near you!",number,cratename)
if drop then if drop then
text = string.format("Crates for %s have been dropped!",cratename) text = string.format("%d crates for %s have been dropped!",number,cratename)
self:__CratesDropped(1, Group, Unit, droppedcargo) self:__CratesDropped(1, Group, Unit, droppedcargo)
else else
if not quiet then if not quiet then
@@ -3612,7 +3627,7 @@ end
function CTLD:_ListCratesNearby( _group, _unit) function CTLD:_ListCratesNearby( _group, _unit)
self:T(self.lid .. " _ListCratesNearby") self:T(self.lid .. " _ListCratesNearby")
local finddist = self.CrateDistance or 35 local finddist = self.CrateDistance or 35
local crates,number,loadedbygc,indexgc = self:_FindCratesNearby(_group,_unit, finddist,true,true) -- #table local crates,number,loadedbygc,indexgc = self:_FindCratesNearby(_group,_unit, finddist,true,true,true) -- #table
if number > 0 or indexgc > 0 then if number > 0 or indexgc > 0 then
local text = REPORT:New("Crates Found Nearby:") local text = REPORT:New("Crates Found Nearby:")
text:Add("------------------------------------------------------------") text:Add("------------------------------------------------------------")
@@ -3711,7 +3726,7 @@ end
function CTLD:_RemoveCratesNearby(_group, _unit) function CTLD:_RemoveCratesNearby(_group, _unit)
self:T(self.lid.." _RemoveCratesNearby") self:T(self.lid.." _RemoveCratesNearby")
local finddist=self.CrateDistance or 35 local finddist=self.CrateDistance or 35
local crates,number=self:_FindCratesNearby(_group,_unit,finddist,true,true) local crates,number=self:_FindCratesNearby(_group,_unit,finddist,true,true,true)
if number>0 then if number>0 then
local removedIDs={} local removedIDs={}
local text=REPORT:New("Removing Crates Found Nearby:") local text=REPORT:New("Removing Crates Found Nearby:")
@@ -3824,7 +3839,7 @@ function CTLD:_FindCratesNearby( _group, _unit, _dist, _ignoreweight, ignoretype
self:T(self.lid .. " Loading restricted: " .. tostring(restricted)) self:T(self.lid .. " Loading restricted: " .. tostring(restricted))
local staticpos = static:GetCoordinate() --or dcsunitpos local staticpos = static:GetCoordinate() --or dcsunitpos
local cando = cargo:UnitCanCarry(_unit) local cando = cargo:UnitCanCarry(_unit)
if ignoretype == true then cando = true end if ignoretype == true then cando = true restricted = false end
self:T(self.lid .. " Unit can carry: " .. tostring(cando)) self:T(self.lid .. " Unit can carry: " .. tostring(cando))
--- Testing --- Testing
local distance=self:_GetDistance(location,staticpos) local distance=self:_GetDistance(location,staticpos)
@@ -4618,7 +4633,7 @@ function CTLD:_BuildCrates(Group, Unit,Engineering,MultiDrop)
finddist=self.EngineerSearch finddist=self.EngineerSearch
finddist=self.EngineerSearch finddist=self.EngineerSearch
end end
local crates,number = self:_FindCratesNearby(Group,Unit, finddist,true,true) -- #table local crates,number = self:_FindCratesNearby(Group,Unit,finddist,true,true,not Engineering) -- #table
local buildables = {} local buildables = {}
local foundbuilds = false local foundbuilds = false
local canbuild = false local canbuild = false
@@ -6411,9 +6426,11 @@ function CTLD:_RefreshDropCratesMenu(Group, Unit)
-- @param Wrapper.Unit#UNIT Unit The calling unit. -- @param Wrapper.Unit#UNIT Unit The calling unit.
-- @param #number chunkID the Cargo ID -- @param #number chunkID the Cargo ID
-- @return #CTLD self -- @return #CTLD self
function CTLD:_UnloadSingleTroopByID(Group, Unit, chunkID) function CTLD:_UnloadSingleTroopByID(Group, Unit, chunkID, qty)
self:T(self.lid .. " _UnloadSingleTroopByID chunkID=" .. tostring(chunkID)) self:T(self.lid .. " _UnloadSingleTroopByID chunkID=" .. tostring(chunkID))
qty = qty or 1
local droppingatbase = false local droppingatbase = false
local inzone, zonename, zone, distance = self:IsUnitInZone(Unit, CTLD.CargoZoneType.LOAD) local inzone, zonename, zone, distance = self:IsUnitInZone(Unit, CTLD.CargoZoneType.LOAD)
if not inzone then if not inzone then
@@ -6453,77 +6470,76 @@ function CTLD:_UnloadSingleTroopByID(Group, Unit, chunkID)
end end
-- Drop the FIRST cargo in that chunk -- Drop the FIRST cargo in that chunk
local foundCargo = chunk[1] for n = 1, qty do
if not foundCargo then local foundCargo = chunk[1]
self:_SendMessage(string.format("No troop cargo at chunk %d!", chunkID), 10, false, Group) if not foundCargo then break end
if not self.debug then return self end
return self
end
local cType = foundCargo:GetType() local cType = foundCargo:GetType()
local name = foundCargo:GetName() or "none" local name = foundCargo:GetName() or "none"
local tmpl = foundCargo:GetTemplates() or {} local tmpl = foundCargo:GetTemplates() or {}
local zoneradius = self.troopdropzoneradius or 100 local zoneradius = self.troopdropzoneradius or 100
local factor = 1 local factor = 1
if isHerc then
factor = foundCargo:GetCratesNeeded() or 1
zoneradius = Unit:GetVelocityMPS() or 100
end
local zone = ZONE_GROUP:New(string.format("Unload zone-%s", unitName), Group, zoneradius * factor)
local randomcoord = zone:GetRandomCoordinate(10, 30 * factor)
local heading = Group:GetHeading() or 0
if grounded or hoverunload then
randomcoord = Group:GetCoordinate()
local Angle = (heading + 270) % 360
if isHerc or isHook then
Angle = (heading + 180) % 360
end
local offset = hoverunload and self.TroopUnloadDistHover or self.TroopUnloadDistGround
if isHerc then if isHerc then
offset = self.TroopUnloadDistGroundHerc or 25 factor = foundCargo:GetCratesNeeded() or 1
zoneradius = Unit:GetVelocityMPS() or 100
end end
if isHook then local zone = ZONE_GROUP:New(string.format("Unload zone-%s", unitName), Group, zoneradius * factor)
offset = self.TroopUnloadDistGroundHook or 15 local randomcoord = zone:GetRandomCoordinate(10, 30 * factor)
if hoverunload and self.TroopUnloadDistHoverHook then local heading = Group:GetHeading() or 0
offset = self.TroopUnloadDistHoverHook or 5
if grounded or hoverunload then
randomcoord = Group:GetCoordinate()
local Angle = (heading + 270) % 360
if isHerc or isHook then
Angle = (heading + 180) % 360
end end
local offset = hoverunload and self.TroopUnloadDistHover or self.TroopUnloadDistGround
if isHerc then
offset = self.TroopUnloadDistGroundHerc or 25
end
if isHook then
offset = self.TroopUnloadDistGroundHook or 15
if hoverunload and self.TroopUnloadDistHoverHook then
offset = self.TroopUnloadDistHoverHook or 5
end
end
randomcoord:Translate(offset, Angle, nil, true)
end end
randomcoord:Translate(offset, Angle, nil, true)
end
local tempcount = 0 local tempcount = 0
if isHook then if isHook then
tempcount = self.ChinookTroopCircleRadius or 5 tempcount = self.ChinookTroopCircleRadius or 5
end end
for _, _template in pairs(tmpl) do for _, _template in pairs(tmpl) do
self.TroopCounter = self.TroopCounter + 1 self.TroopCounter = self.TroopCounter + 1
tempcount = tempcount + 1 tempcount = tempcount + 1
local alias = string.format("%s-%d", _template, math.random(1,100000)) local alias = string.format("%s-%d", _template, math.random(1,100000))
local rad = 2.5 + (tempcount * 2) local rad = 2.5 + (tempcount * 2)
local Positions = self:_GetUnitPositions(randomcoord, rad, heading, _template) local Positions = self:_GetUnitPositions(randomcoord, rad, heading, _template)
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template, alias) self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template, alias)
:InitDelayOff() :InitDelayOff()
:InitSetUnitAbsolutePositions(Positions) :InitSetUnitAbsolutePositions(Positions)
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits) :InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits)
:OnSpawnGroup(function(grp) grp.spawntime = timer.getTime() end) :OnSpawnGroup(function(grp) grp.spawntime = timer.getTime() end)
:SpawnFromVec2(randomcoord:GetVec2()) :SpawnFromVec2(randomcoord:GetVec2())
self:__TroopsDeployed(1, Group, Unit, self.DroppedTroops[self.TroopCounter], cType) self:__TroopsDeployed(1, Group, Unit, self.DroppedTroops[self.TroopCounter], cType)
end end
foundCargo:SetWasDropped(true) foundCargo:SetWasDropped(true)
if cType == CTLD_CARGO.Enum.ENGINEERS then if cType == CTLD_CARGO.Enum.ENGINEERS then
self.Engineers = self.Engineers + 1 self.Engineers = self.Engineers + 1
local grpname = self.DroppedTroops[self.TroopCounter]:GetName() local grpname = self.DroppedTroops[self.TroopCounter]:GetName()
self.EngineersInField[self.Engineers] = CTLD_ENGINEERING:New(name, grpname) self.EngineersInField[self.Engineers] = CTLD_ENGINEERING:New(name, grpname)
self:_SendMessage(string.format("Dropped Engineers %s into action!", name), 10, false, Group) self:_SendMessage(string.format("Dropped Engineers %s into action!", name), 10, false, Group)
else else
self:_SendMessage(string.format("Dropped Troops %s into action!", name), 10, false, Group) self:_SendMessage(string.format("Dropped Troops %s into action!", name), 10, false, Group)
end end
table.remove(chunk, 1) table.remove(chunk, 1)
if #chunk == 0 then if #chunk == 0 then
self.TroopsIDToChunk[chunkID] = nil self.TroopsIDToChunk[chunkID] = nil
break
end
end end
else else
@@ -6533,7 +6549,8 @@ function CTLD:_UnloadSingleTroopByID(Group, Unit, chunkID)
if self.TroopsIDToChunk and self.TroopsIDToChunk[chunkID] then if self.TroopsIDToChunk and self.TroopsIDToChunk[chunkID] then
local chunk = self.TroopsIDToChunk[chunkID] local chunk = self.TroopsIDToChunk[chunkID]
if #chunk > 0 then for n = 1, qty do
if #chunk == 0 then break end
local firstObj = chunk[1] local firstObj = chunk[1]
local cName = firstObj:GetName() local cName = firstObj:GetName()
local gentroops = self.Cargo_Troops local gentroops = self.Cargo_Troops
@@ -6548,9 +6565,9 @@ function CTLD:_UnloadSingleTroopByID(Group, Unit, chunkID)
end end
firstObj:SetWasDropped(true) firstObj:SetWasDropped(true)
table.remove(chunk, 1) table.remove(chunk, 1)
if #chunk == 0 then end
self.TroopsIDToChunk[chunkID] = nil if #chunk == 0 then
end self.TroopsIDToChunk[chunkID] = nil
end end
end end
end end
@@ -6625,15 +6642,22 @@ function CTLD:_RefreshDropTroopsMenu(Group, Unit)
for tName, objList in pairs(troopsByName) do for tName, objList in pairs(troopsByName) do
table.sort(objList, function(a,b) return a:GetID() < b:GetID() end) table.sort(objList, function(a,b) return a:GetID() < b:GetID() end)
local count = #objList local count = #objList
if count > 0 then
local chunkID = objList[1]:GetID()
self.TroopsIDToChunk[chunkID] = objList
local chunkID = objList[1]:GetID() local label = string.format("Drop %s (%d)", tName, count)
self.TroopsIDToChunk[chunkID] = objList if count == 1 then
MENU_GROUP_COMMAND:New(theGroup, label, dropTroopsMenu, self._UnloadSingleTroopByID, self, theGroup, theUnit, chunkID, 1)
local label = string.format("Drop %s (%d)", tName, count) else
MENU_GROUP_COMMAND:New(theGroup, label, dropTroopsMenu, self._UnloadSingleTroopByID, self, theGroup, theUnit, chunkID) local parentMenu = MENU_GROUP:New(theGroup, label, dropTroopsMenu)
for q = 1, count do
MENU_GROUP_COMMAND:New(theGroup, string.format("Drop (%d) %s", q, tName), parentMenu, self._UnloadSingleTroopByID, self, theGroup, theUnit, chunkID, q)
end
end
end
end end
end end
--- [Internal] Function to check if a template exists in the mission. --- [Internal] Function to check if a template exists in the mission.
-- @param #CTLD self -- @param #CTLD self
-- @param #table temptable Table of string names -- @param #table temptable Table of string names