Merge remote-tracking branch 'origin/master-ng' into branch

This commit is contained in:
Applevangelist
2026-02-26 12:52:36 +01:00
+350 -129
View File
@@ -1514,7 +1514,7 @@ CTLD.UnitTypeCapabilities = {
["C-130J-30"] = {type="C-130J-30", crates=true, troops=true, cratelimit = 7, trooplimit = 64, length = 35, cargoweightlimit = 21500}, -- 19t cargo, 64 paratroopers. ["C-130J-30"] = {type="C-130J-30", crates=true, troops=true, cratelimit = 7, trooplimit = 64, length = 35, cargoweightlimit = 21500}, -- 19t cargo, 64 paratroopers.
--Actually it's longer, but the center coord is off-center of the model. --Actually it's longer, but the center coord is off-center of the model.
["UH-60L"] = {type="UH-60L", crates=true, troops=true, cratelimit = 2, trooplimit = 20, length = 16, cargoweightlimit = 3500}, -- 4t cargo, 20 (unsec) seats ["UH-60L"] = {type="UH-60L", crates=true, troops=true, cratelimit = 2, trooplimit = 20, length = 16, cargoweightlimit = 3500}, -- 4t cargo, 20 (unsec) seats
["UH-60L_DAP"] = {type="UH-60L_DAP", crates=false, troops=true, cratelimit = 0, trooplimit = 2, length = 16, cargoweightlimit = 500}, -- UH-60L DAP is an attack helo but can do limited CSAR and CTLD ["UH-60L_DAP"] = {type="UH-60L_DAP", crates=false, troops=true, cratelimit = 2, trooplimit = 2, length = 16, cargoweightlimit = 3000}, -- UH-60L DAP is an attack helo but can do limited CSAR and CTLD
["MH-60R"] = {type="MH-60R", crates=true, troops=true, cratelimit = 2, trooplimit = 20, length = 16, cargoweightlimit = 3500}, -- 4t cargo, 20 (unsec) seats ["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 ["SH-60B"] = {type="SH-60B", crates=true, troops=true, cratelimit = 2, trooplimit = 20, length = 16, cargoweightlimit = 3500}, -- 4t cargo, 20 (unsec) seats
["AH-64D_BLK_II"] = {type="AH-64D_BLK_II", crates=false, troops=true, cratelimit = 0, trooplimit = 2, length = 17, cargoweightlimit = 200}, -- 2 ppl **outside** the helo ["AH-64D_BLK_II"] = {type="AH-64D_BLK_II", crates=false, troops=true, cratelimit = 0, trooplimit = 2, length = 17, cargoweightlimit = 200}, -- 2 ppl **outside** the helo
@@ -1647,6 +1647,9 @@ function CTLD:New(Coalition, Prefixes, Alias)
self.Cargo_Crates = {} self.Cargo_Crates = {}
self.Cargo_Troops = {} self.Cargo_Troops = {}
self.Cargo_Statics = {} self.Cargo_Statics = {}
self._troopsByName = {}
self._crateOrStaticByName = {}
self._cargoByTemplate = {}
self.Loaded_Cargo = {} self.Loaded_Cargo = {}
self.Spawned_Crates = {} self.Spawned_Crates = {}
self.Spawned_Cargo = {} self.Spawned_Cargo = {}
@@ -2419,9 +2422,9 @@ end
--- (Internal) Function to check if a unit is a C-130J --- (Internal) Function to check if a unit is a C-130J
-- @param #CTLD self -- @param #CTLD self
function CTLD:IsC130J(Unit) function CTLD:IsC130J(Unit, IgnoreUseC130Flag)
if not Unit then return false end if not Unit then return false end
if not self.UseC130LoadAndUnload then return false end if not IgnoreUseC130Flag and not self.UseC130LoadAndUnload then return false end
self.C130JUnits = self.C130JUnits or {} self.C130JUnits = self.C130JUnits or {}
local unitname = Unit:GetName() or "none" local unitname = Unit:GetName() or "none"
return self.C130JUnits[unitname] == true return self.C130JUnits[unitname] == true
@@ -2447,10 +2450,16 @@ end
-- @return #CTLD_CARGO Cargo object, nil if it cannot be found -- @return #CTLD_CARGO Cargo object, nil if it cannot be found
function CTLD:_FindTroopsCargoObject(Name) function CTLD:_FindTroopsCargoObject(Name)
self:T(self.lid .. " _FindTroopsCargoObject") self:T(self.lid .. " _FindTroopsCargoObject")
self._troopsByName = self._troopsByName or {}
local cached = self._troopsByName[Name]
if cached then
return cached
end
local cargo = nil local cargo = nil
for _,_cargo in pairs(self.Cargo_Troops)do for _,_cargo in pairs(self.Cargo_Troops)do
local cargo = _cargo -- #CTLD_CARGO local cargo = _cargo -- #CTLD_CARGO
if cargo.Name == Name then if cargo.Name == Name then
self._troopsByName[Name] = cargo
return cargo return cargo
end end
end end
@@ -2463,16 +2472,23 @@ end
-- @return #CTLD_CARGO Cargo object, nil if it cannot be found -- @return #CTLD_CARGO Cargo object, nil if it cannot be found
function CTLD:_FindCratesCargoObject(Name) function CTLD:_FindCratesCargoObject(Name)
self:T(self.lid .. " _FindCratesCargoObject") self:T(self.lid .. " _FindCratesCargoObject")
self._crateOrStaticByName = self._crateOrStaticByName or {}
local cached = self._crateOrStaticByName[Name]
if cached then
return cached
end
local cargo = nil local cargo = nil
for _,_cargo in pairs(self.Cargo_Crates)do for _,_cargo in pairs(self.Cargo_Crates)do
local cargo = _cargo -- #CTLD_CARGO local cargo = _cargo -- #CTLD_CARGO
if cargo.Name == Name then if cargo.Name == Name then
self._crateOrStaticByName[Name] = cargo
return cargo return cargo
end end
end end
for _,_cargo in pairs(self.Cargo_Statics)do for _,_cargo in pairs(self.Cargo_Statics)do
local cargo = _cargo -- #CTLD_CARGO local cargo = _cargo -- #CTLD_CARGO
if cargo.Name == Name then if cargo.Name == Name then
self._crateOrStaticByName[Name] = cargo
return cargo return cargo
end end
end end
@@ -2598,6 +2614,20 @@ function CTLD:PreloadCrates(Unit,Cratesname,NumberOfCrates)
return self return self
end end
--- (User) Hook to allow mission-specific troop restrictions.
-- Override this in your mission to perform custom checks (e.g. warehouse stock, role limits) before troops are loaded.
-- Return true to allow the request, or false to block it. When blocked, _LoadTroops and _LoadTroopsQuantity exit silently.
-- @param #CTLD self
-- @param Wrapper.Group#GROUP Group Requesting player group.
-- @param Wrapper.Unit#UNIT Unit Requesting unit.
-- @param #CTLD_CARGO Cargo Troop cargo type being requested.
-- @param #number quantity Number of troop sets requested.
-- @param #boolean Inject If true, this call originates from an inject/preload path.
-- @return #boolean Allow troop loading.
function CTLD:CanGetTroops(Group, Unit, Cargo, quantity, Inject)
return true
end
--- (Internal) Function to load troops into a heli. --- (Internal) Function to load troops into a heli.
-- @param #CTLD self -- @param #CTLD self
-- @param Wrapper.Group#GROUP Group -- @param Wrapper.Group#GROUP Group
@@ -2668,6 +2698,9 @@ function CTLD:_LoadTroops(Group, Unit, Cargotype, Inject)
self:_SendMessage("Sorry, that\'s too heavy to load!", 10, false, Group) self:_SendMessage("Sorry, that\'s too heavy to load!", 10, false, Group)
return return
else else
if not self:CanGetTroops(Group, Unit, Cargotype, 1, Inject) then
return self
end
self.CargoCounter = self.CargoCounter + 1 self.CargoCounter = self.CargoCounter + 1
local loadcargotype = CTLD_CARGO:New(self.CargoCounter, Cargotype.Name, Cargotype.Templates, cgotype, true, true, Cargotype.CratesNeeded,nil,nil,Cargotype.PerCrateMass) local loadcargotype = CTLD_CARGO:New(self.CargoCounter, Cargotype.Name, Cargotype.Templates, cgotype, true, true, Cargotype.CratesNeeded,nil,nil,Cargotype.PerCrateMass)
self:T({cargotype=loadcargotype}) self:T({cargotype=loadcargotype})
@@ -2987,6 +3020,8 @@ function CTLD:_LoadTroopsQuantity(Group, Unit, Cargo, quantity)
if not self.debug then return self end if not self.debug then return self end
end end
if not self:CanGetTroops(Group, Unit, Cargo, n, false) then return self end
local prevSuppress = self.suppressmessages local prevSuppress = self.suppressmessages
self.suppressmessages = true self.suppressmessages = true
for i = 1, n do for i = 1, n do
@@ -3141,26 +3176,40 @@ function CTLD:_AddCrateQuantityMenus(Group, Unit, parentMenu, cargoObj, stockSum
maxQuantity = maxMassSets maxQuantity = maxMassSets
end end
end end
if type(maxload)=="number"and maxload>0 and perCrateMass>0 then if type(maxload) == "number" and maxload > 0 and perCrateMass > 0 then
maxMassCrates=math.floor(maxload/perCrateMass) maxMassCrates = math.floor(maxload / perCrateMass)
end end
end end
self:T("_AddCrateQuantityMenus maxQuantity "..maxQuantity.." allowLoad "..tostring(allowLoad)) self:T("_AddCrateQuantityMenus maxQuantity "..maxQuantity.." allowLoad "..tostring(allowLoad))
if maxQuantity < 1 then if maxQuantity < 1 then
return self return self
end end
if maxQuantity == 1 then if maxQuantity == 1 then
self:T("_AddCrateQuantityMenus maxQuantity "..maxQuantity.." Menu for MaxQ=1 ".."parentMenu.MenuText = "..parentMenu.MenuText) self:T("_AddCrateQuantityMenus maxQuantity "..maxQuantity.." Menu for MaxQ=1 ".."parentMenu.MenuText = "..parentMenu.MenuText)
--parentMenu.MenuText
MENU_GROUP_COMMAND:New(Group, "Get", parentMenu, self._GetCrateQuantity, self, Group, Unit, cargoObj, 1)
local canLoad = (allowLoad and (not capacitySets or capacitySets >= 1) and (not maxMassSets or maxMassSets >= 1)) local canLoad = (allowLoad and (not capacitySets or capacitySets >= 1) and (not maxMassSets or maxMassSets >= 1))
local isHerc = self:IsC130J(Unit) local isHerc = self:IsC130J(Unit)
local isHook = self:IsHook(Unit)
local cgotype = cargoObj:GetType() or nil local cgotype = cargoObj:GetType() or nil
local suppressGetAndLoad = (self.enableChinookGCLoading == true) and isHook and (cgotype == CTLD_CARGO.Enum.STATIC) local suppressGetAndLoad = (self.enableChinookGCLoading == true) and (cgotype == CTLD_CARGO.Enum.STATIC)
local canPartiallyLoad=((not capacityCrates or capacityCrates>=1)and(not maxMassCrates or maxMassCrates>=1)) local canPartiallyLoad = ((not capacityCrates or capacityCrates >= 1) and (not maxMassCrates or maxMassCrates >= 1))
if suppressGetAndLoad or isHerc then
if canLoad then
MENU_GROUP_COMMAND:New(Group, "1", parentMenu, self._GetCrateQuantity, self, Group, Unit, cargoObj, 1)
else
local msg
if maxMassSets and (not capacitySets or capacitySets >= 1) and maxMassSets < 1 then
msg = "Weight limit reached"
else
msg = "Crate limit reached"
end
MENU_GROUP_COMMAND:New(Group, msg, parentMenu, self._SendMessage, self, msg, 10, false, Group)
end
return self
end
if canLoad and not isHerc and not suppressGetAndLoad then if canLoad and not isHerc and not suppressGetAndLoad then
MENU_GROUP_COMMAND:New(Group, "Get", parentMenu, self._GetCrateQuantity, self, Group, Unit, cargoObj, 1)
MENU_GROUP_COMMAND:New(Group, "Get and Load", parentMenu, self._GetAndLoad, self, Group, Unit, cargoObj, 1) MENU_GROUP_COMMAND:New(Group, "Get and Load", parentMenu, self._GetAndLoad, self, Group, Unit, cargoObj, 1)
else else
local msg local msg
@@ -3171,9 +3220,10 @@ function CTLD:_AddCrateQuantityMenus(Group, Unit, parentMenu, cargoObj, stockSum
msg = "Crate limit reached" msg = "Crate limit reached"
end end
MENU_GROUP_COMMAND:New(Group, msg, parentMenu, self._SendMessage, self, msg, 10, false, Group) MENU_GROUP_COMMAND:New(Group, msg, parentMenu, self._SendMessage, self, msg, 10, false, Group)
if canPartiallyLoad and (cgotype ~= CTLD_CARGO.Enum.STATIC) and (not suppressGetAndLoad) then if canPartiallyLoad and (cgotype ~= CTLD_CARGO.Enum.STATIC) and (not suppressGetAndLoad) then
MENU_GROUP_COMMAND:New(Group, "Partially load", parentMenu, self._GetAndLoad, self, Group, Unit, cargoObj, 1,true) MENU_GROUP_COMMAND:New(Group, "Get anyway", parentMenu, self._GetCrateQuantity, self, Group, Unit, cargoObj, 1)
MENU_GROUP_COMMAND:New(Group, "Partially load", parentMenu, self._GetAndLoad, self, Group, Unit, cargoObj, 1, true)
end end
end end
end end
@@ -3185,29 +3235,17 @@ function CTLD:_AddCrateQuantityMenus(Group, Unit, parentMenu, cargoObj, stockSum
self:T("_AddCrateQuantityMenus maxQuantity "..maxQuantity.." Menu for MaxQ>1") self:T("_AddCrateQuantityMenus maxQuantity "..maxQuantity.." Menu for MaxQ>1")
local label = tostring(quantity) local label = tostring(quantity)
self:T("_AddCrateQuantityMenus Label "..label) self:T("_AddCrateQuantityMenus Label "..label)
local qMenu = MENU_GROUP:New(Group, label, parentMenu)
MENU_GROUP_COMMAND:New(Group, "Get", qMenu, self._GetCrateQuantity, self, Group, Unit, cargoObj, quantity)
local canLoad = (allowLoad and (not capacitySets or capacitySets >= quantity) and (not maxMassSets or maxMassSets >= quantity)) local canLoad = (allowLoad and (not capacitySets or capacitySets >= quantity) and (not maxMassSets or maxMassSets >= quantity))
local isHerc = self:IsC130J(Unit) local isHerc = self:IsC130J(Unit)
local isHook = self:IsHook(Unit)
local cgotype = cargoObj:GetType() or nil local cgotype = cargoObj:GetType() or nil
local suppressGetAndLoad = (self.enableChinookGCLoading == true) and isHook and (cgotype == CTLD_CARGO.Enum.STATIC) local suppressGetAndLoad = (self.enableChinookGCLoading == true) and (cgotype == CTLD_CARGO.Enum.STATIC)
local canPartiallyLoad=((not capacityCrates or capacityCrates>=1)and(not maxMassCrates or maxMassCrates>=1))
if canLoad and not isHerc and not suppressGetAndLoad then if canLoad and not isHerc and not suppressGetAndLoad then
local qMenu = MENU_GROUP:New(Group, label, parentMenu)
MENU_GROUP_COMMAND:New(Group, "Get", qMenu, self._GetCrateQuantity, self, Group, Unit, cargoObj, quantity)
MENU_GROUP_COMMAND:New(Group, "Get and Load", qMenu, self._GetAndLoad, self, Group, Unit, cargoObj, quantity) MENU_GROUP_COMMAND:New(Group, "Get and Load", qMenu, self._GetAndLoad, self, Group, Unit, cargoObj, quantity)
else else
local msg MENU_GROUP_COMMAND:New(Group, label, parentMenu, self._GetCrateQuantity, self, Group, Unit, cargoObj, quantity)
if not isHerc and not suppressGetAndLoad then
if maxMassSets and (not capacitySets or capacitySets >= quantity) and maxMassSets < quantity then
msg = "Weight limit reached"
else
msg = "Crate limit reached"
end
MENU_GROUP_COMMAND:New(Group, msg, qMenu, self._SendMessage, self, msg, 10, false, Group)
if canPartiallyLoad and (cgotype ~= CTLD_CARGO.Enum.STATIC) and (not suppressGetAndLoad) then
MENU_GROUP_COMMAND:New(Group, "Partially load", qMenu, self._GetAndLoad, self, Group, Unit, cargoObj, quantity, true)
end
end
end end
end end
return self return self
@@ -3374,7 +3412,6 @@ end
function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppressGetEvent) function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppressGetEvent)
self:T(self.lid .. " _GetCrates") self:T(self.lid .. " _GetCrates")
-- check if we have stock
local perSet = Cargo:GetCratesNeeded() or 1 local perSet = Cargo:GetCratesNeeded() or 1
if perSet < 1 then perSet = 1 end if perSet < 1 then perSet = 1 end
local requestNumber = tonumber(number) local requestNumber = tonumber(number)
@@ -3387,10 +3424,9 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppress
local requestedSets = math.floor((requestNumber + perSet - 1) / perSet) local requestedSets = math.floor((requestNumber + perSet - 1) / perSet)
if requestedSets < 1 then requestedSets = 1 end if requestedSets < 1 then requestedSets = 1 end
if not drop and not pack then if not drop and not pack then
local cgoname = self:_GetCargoDisplayName(Cargo) local cgoname = Cargo:GetName()
local instock = Cargo:GetStock() local instock = Cargo:GetStock()
if type(instock) == "number" and tonumber(instock) <= 0 and tonumber(instock) ~= -1 then if type(instock) == "number" and tonumber(instock) <= 0 and tonumber(instock) ~= -1 then
-- nothing left over
self:_SendMessage(string.format("Sorry, we ran out of %s", cgoname), 10, false, Group) self:_SendMessage(string.format("Sorry, we ran out of %s", cgoname), 10, false, Group)
return false return false
end end
@@ -3405,16 +3441,15 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppress
local distance = nil local distance = nil
local zone = nil local zone = nil
if not drop and not pack then if not drop and not pack then
inzone = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD) inzone = self:IsUnitInZone(Unit, CTLD.CargoZoneType.LOAD)
if not inzone then if not inzone then
---@diagnostic disable-next-line: cast-local-type inzone, ship, zone, distance, width = self:IsUnitInZone(Unit, CTLD.CargoZoneType.SHIP)
inzone, ship, zone, distance, width = self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP)
end end
elseif drop and not pack then elseif drop and not pack then
if self.dropcratesanywhere then -- #1570 if self.dropcratesanywhere then -- #1570
inzone = true inzone = true
else else
inzone = self:IsUnitInZone(Unit,CTLD.CargoZoneType.DROP) inzone = self:IsUnitInZone(Unit, CTLD.CargoZoneType.DROP)
end end
elseif pack and not drop then elseif pack and not drop then
inzone = true inzone = true
@@ -3442,7 +3477,7 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppress
local capabilities = self:_GetUnitCapabilities(Unit) -- #CTLD.UnitTypeCapabilities local capabilities = self:_GetUnitCapabilities(Unit) -- #CTLD.UnitTypeCapabilities
local canloadcratesno = capabilities.cratelimit local canloadcratesno = capabilities.cratelimit
local loaddist = self.CrateDistance or 35 local loaddist = self.CrateDistance or 35
local nearcrates, numbernearby = self:_FindCratesNearby(Group,Unit,loaddist,true,true,true) -- to ignore what's inside local nearcrates, numbernearby = self:_FindCratesNearby(Group, Unit, loaddist, true, true, true)
if numbernearby >= canloadcratesno and not drop then if numbernearby >= canloadcratesno and not drop then
self:_SendMessage("There are enough crates nearby already! Take care of those first!", 10, false, Group) self:_SendMessage("There are enough crates nearby already! Take care of those first!", 10, false, Group)
return false return false
@@ -3454,6 +3489,7 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppress
-- spawn crates in front of helicopter -- spawn crates in front of helicopter
local IsHerc = self:IsFixedWing(Unit) -- Herc, Bronco and Hook load from behind local IsHerc = self:IsFixedWing(Unit) -- Herc, Bronco and Hook load from behind
local IsHook = self:IsHook(Unit) -- Herc, Bronco and Hook load from behind local IsHook = self:IsHook(Unit) -- Herc, Bronco and Hook load from behind
local IsHelo = Unit and Unit.IsHelicopter and Unit:IsHelicopter() or false
local IsTruck = Unit:IsGround() local IsTruck = Unit:IsGround()
local cargotype = Cargo -- Ops.CTLD#CTLD_CARGO local cargotype = Cargo -- Ops.CTLD#CTLD_CARGO
local number = requestNumber --#number local number = requestNumber --#number
@@ -3483,77 +3519,191 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppress
-- spawn behind the Herc -- spawn behind the Herc
addon = 180 addon = 180
end end
heading = (heading+addon)%360 heading = (heading + addon) % 360
local row = 1 local row = 1
local column = 1 local column = 1
local initialdist = IsHerc and 16 or (capabilities.length+2) -- initial spacing of the first crates local initialdist = IsHerc and 16 or (capabilities.length + 2)
local startpos = position:Translate(initialdist,heading) local startpos = position:Translate(initialdist, heading)
if self.placeCratesAhead == true then if self.placeCratesAhead == true then
cratedistance = initialdist cratedistance = initialdist
end end
-- loop crates needed local cratecoord = nil
local cratecoord = nil -- Core.Point#COORDINATE local shipdist = nil
for i=1,number do local shipoffset = nil
local cratealias = string.format("%s-%s-%d", cratename, cratetemplate, math.random(1,100000))
if not self.placeCratesAhead or drop == true then
cratedistance = (i-1)*2.5 + capabilities.length
if cratedistance > self.CrateDistance then cratedistance = self.CrateDistance end
-- altered heading logic
-- DONE: right standard deviation?
if self:IsUnitInAir(Unit) and self:IsFixedWing(Unit) then
rheading = math.random(20,60)
else
rheading = UTILS.RandomGaussian(0, 30, -90, 90, 100)
end
rheading=math.fmod((heading+rheading),360)
cratecoord = position:Translate(cratedistance,rheading)
else
cratedistance = (row-1)*6
rheading = 90
row = row+1
cratecoord = startpos:Translate(cratedistance,rheading)
if row > 4 then
row = 1
startpos:Translate(6,heading,nil,true)
end
end
--local cratevec2 = cratecoord:GetVec2() local FW_STEP_BY_TYPE = {
self.CrateCounter = self.CrateCounter + 1 cds_crate = 2.0,
cds_barrels = 2.0,
ammo_cargo = 1.0,
iso_container_small = 3.5,
iso_container = 3.5,
uh1h_cargo = 2.0,
container_cargo = 2.5,
}
local FW_WIDTH_BY_TYPE = { -- spacing between crates in the set.
cds_crate = 0.8,
cds_barrels = 0.8,
ammo_cargo = 0.4,
iso_container_small = 2.0,
iso_container = 2.0,
uh1h_cargo = 0.6,
container_cargo = 1.3,
}
local FW_ROW_GAP = 0.6
local FW_BATCH_ANGLE_PATTERN = { 0, -20, 20, -40, 40, -60, 60, -80, 80 }
local fwBatchState = nil
local fwBatchIndex = 0
local fwBatchKey = nil
if IsHerc or IsHelo then
self._fwBatchState = self._fwBatchState or {}
fwBatchKey = (Unit and Unit.GetName and Unit:GetName()) or "FW"
fwBatchState = self._fwBatchState[fwBatchKey] or { batch = 0 }
if (tonumber(numbernearby) or 0) <= 0 then
fwBatchState.batch = 0
end
fwBatchIndex = fwBatchState.batch or 0
end
local fwZeroAngleSetHeading = nil
local fwNonZeroAngleSetHeading = nil
for i = 1, number do
local currentAngleOffset = 0
local cratealias = string.format("%s-%d", cratename, math.random(1, 100000))
local CCat, CType, CShape = Cargo:GetStaticTypeAndShape() local CCat, CType, CShape = Cargo:GetStaticTypeAndShape()
local basetype = CType or self.basetype or "container_cargo" local basetype = CType or self.basetype or "container_cargo"
CCat = CCat or "Cargos" CCat = CCat or "Cargos"
if not isstatic and self:IsC130J(Unit) then
if not isstatic and self:IsC130J(Unit, true) then
if Cargo.C130TypeName then if Cargo.C130TypeName then
basetype = Cargo.C130TypeName basetype = Cargo.C130TypeName
elseif self.C130basetype and (not CType or CType == self.basetype) then elseif self.C130basetype and (not CType or CType == self.basetype) then
basetype = self.C130basetype basetype = self.C130basetype
end end
end end
if not self.placeCratesAhead or drop == true then
local step = (IsHerc or IsHelo) and (FW_STEP_BY_TYPE[basetype] or 2.6) or 1.6
if (IsHerc or IsHelo) and not drop then
local safeDistance = capabilities.length * 0.9
local maxDist = self.CrateDistance or 35
if safeDistance > maxDist then safeDistance = maxDist end
local angleIndex = (fwBatchIndex % #FW_BATCH_ANGLE_PATTERN) + 1
currentAngleOffset = FW_BATCH_ANGLE_PATTERN[angleIndex] or 0
local centerHeading = math.fmod((heading + currentAngleOffset), 360)
if math.abs(currentAngleOffset) >= 0.01 and not fwNonZeroAngleSetHeading then
fwNonZeroAngleSetHeading = centerHeading
end
local baseDistance = safeDistance
local crateWidth = FW_WIDTH_BY_TYPE[basetype] or step
local zeroAngle = math.abs(currentAngleOffset) < 0.01
local lateral = nil
local lateralHeading = nil
if zeroAngle then
local totalRowWidth = (number * crateWidth) + (math.max(0, number - 1) * FW_ROW_GAP)
local leftEdge = -(totalRowWidth / 2)
lateral = leftEdge + ((i - 1) * (crateWidth + FW_ROW_GAP)) + (crateWidth / 2)
if lateral >= 0 then
lateralHeading = math.fmod(centerHeading + 90, 360)
else
lateral = -lateral
lateralHeading = math.fmod(centerHeading + 270, 360)
end
else
lateral = (i - 1) * (crateWidth + FW_ROW_GAP)
if currentAngleOffset < 0 then
lateralHeading = math.fmod(centerHeading + 270, 360)
else
lateralHeading = math.fmod(centerHeading + 90, 360)
end
end
local maxLateralSq = (maxDist * maxDist) - (baseDistance * baseDistance)
if maxLateralSq < 0 then maxLateralSq = 0 end
local maxLateral = math.sqrt(maxLateralSq)
if lateral > maxLateral then
lateral = maxLateral
end
local baseCoord = position:Translate(baseDistance, centerHeading)
cratecoord = baseCoord:Translate(lateral, lateralHeading)
cratedistance = baseDistance
rheading = centerHeading
else
cratedistance = (i - 1) * step + capabilities.length
if cratedistance > self.CrateDistance then cratedistance = self.CrateDistance end
rheading = UTILS.RandomGaussian(0, 18, -55, 55, 100)
rheading = math.fmod((heading + rheading), 360)
cratecoord = position:Translate(cratedistance, rheading)
end
else
cratedistance = (row - 1) * 6
rheading = 90
row = row + 1
cratecoord = startpos:Translate(cratedistance, rheading)
if row > 4 then
row = 1
startpos:Translate(6, heading, nil, true)
end
end
self.CrateCounter = self.CrateCounter + 1
local crateSpawnHeading = 270
if (IsHerc or IsHelo) and not drop and cratecoord and type(ship) ~= "string" then
if math.abs(currentAngleOffset) < 0.01 then
if not fwZeroAngleSetHeading then
fwZeroAngleSetHeading = heading
end
crateSpawnHeading = fwZeroAngleSetHeading
else
crateSpawnHeading = fwNonZeroAngleSetHeading
end
end
if type(ship) == "string" then if type(ship) == "string" then
self:T("Spawning on ship "..ship) self:T("Spawning on ship "..ship)
local Ship = UNIT:FindByName(ship) local Ship = UNIT:FindByName(ship)
local shipcoord = Ship:GetCoordinate() local shipcoord = Ship:GetCoordinate()
local unitcoord = Unit:GetCoordinate() local unitcoord = Unit:GetCoordinate()
local dist = shipcoord:Get2DDistance(unitcoord) local dist = shipcoord:Get2DDistance(unitcoord)
dist = dist - (20 + math.random(1,10)) dist = dist - (20 + math.random(1, 10))
local width = width / 2 local halfwidth = (width or 20) / 2
local Offy = math.random(-width,width) local Offy = nil
local spawnstatic = SPAWNSTATIC:NewFromType(basetype,CCat,self.cratecountry) if i == 1 or shipdist == nil or shipoffset == nil then
:InitCargoMass(cgomass) Offy = math.random(-halfwidth, halfwidth)
:InitCargo(self.enableslingload) shipoffset = Offy
:InitLinkToUnit(Ship,dist,Offy,0) shipdist = dist
else
dist = shipdist
local step = math.max(1, math.min(3, halfwidth * 0.2))
local slot = i - 1
local ring = math.floor((slot + 1) / 2)
local sign = (slot % 2 == 1) and 1 or -1
Offy = shipoffset + (sign * ring * step)
if Offy > halfwidth then
Offy = halfwidth
elseif Offy < -halfwidth then
Offy = -halfwidth
end
end
local spawnstatic = SPAWNSTATIC:NewFromType(basetype, CCat, self.cratecountry)
:InitCargoMass(cgomass)
:InitCargo(self.enableslingload)
:InitLinkToUnit(Ship, dist, Offy, 0)
if CShape then if CShape then
spawnstatic:InitShape(CShape) spawnstatic:InitShape(CShape)
end end
if isstatic then if isstatic then
local map=cargotype:GetStaticResourceMap() local map = cargotype:GetStaticResourceMap()
spawnstatic.TemplateStaticUnit.resourcePayload = map spawnstatic.TemplateStaticUnit.resourcePayload = map
end end
self.Spawned_Crates[self.CrateCounter] = spawnstatic:Spawn(270,cratealias) self.Spawned_Crates[self.CrateCounter] = spawnstatic:Spawn(crateSpawnHeading, cratealias)
else else
local spawnstatic = SPAWNSTATIC:NewFromType(basetype,CCat,self.cratecountry) local spawnstatic = SPAWNSTATIC:NewFromType(basetype, CCat, self.cratecountry)
:InitCoordinate(cratecoord) :InitCoordinate(cratecoord)
:InitCargoMass(cgomass) :InitCargoMass(cgomass)
:InitCargo(self.enableslingload) :InitCargo(self.enableslingload)
@@ -3561,11 +3711,12 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppress
spawnstatic:InitShape(CShape) spawnstatic:InitShape(CShape)
end end
if isstatic then if isstatic then
local map=cargotype:GetStaticResourceMap() local map = cargotype:GetStaticResourceMap()
spawnstatic.TemplateStaticUnit.resourcePayload = map spawnstatic.TemplateStaticUnit.resourcePayload = map
end end
self.Spawned_Crates[self.CrateCounter] = spawnstatic:Spawn(270,cratealias) self.Spawned_Crates[self.CrateCounter] = spawnstatic:Spawn(crateSpawnHeading, cratealias)
end end
local templ = cargotype:GetTemplates() local templ = cargotype:GetTemplates()
local sorte = cargotype:GetType() local sorte = cargotype:GetType()
local subcat = cargotype.Subcategory local subcat = cargotype.Subcategory
@@ -3573,43 +3724,50 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppress
local realcargo = nil local realcargo = nil
if drop then if drop then
--CTLD_CARGO:New(ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped, PerCrateMass, Stock, Subcategory) --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) -- #CTLD_CARGO realcargo = CTLD_CARGO:New(self.CargoCounter, cratename, templ, sorte, true, false, cratesneeded, self.Spawned_Crates[self.CrateCounter], true, cargotype.PerCrateMass, nil, subcat)
realcargo:SetDisplayName(cargotype:GetDisplayName()) realcargo:SetDisplayName(cargotype:GetDisplayName())
local map=cargotype:GetStaticResourceMap() local map = cargotype:GetStaticResourceMap()
realcargo:SetStaticResourceMap(map) realcargo:SetStaticResourceMap(map)
local CCat3, CType3, CShape3 = cargotype:GetStaticTypeAndShape() local CCat3, CType3, CShape3 = cargotype:GetStaticTypeAndShape()
realcargo:SetStaticTypeAndShape(CCat3,CType3,CShape3) realcargo:SetStaticTypeAndShape(CCat3, CType3, CShape3)
if cargotype.TypeNames then if cargotype.TypeNames then
realcargo.TypeNames = UTILS.DeepCopy(cargotype.TypeNames) realcargo.TypeNames = UTILS.DeepCopy(cargotype.TypeNames)
end end
table.insert(droppedcargo,realcargo) table.insert(droppedcargo, realcargo)
else else
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,false,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],false,cargotype.PerCrateMass,nil,subcat) realcargo = CTLD_CARGO:New(self.CargoCounter, cratename, templ, sorte, false, false, cratesneeded, self.Spawned_Crates[self.CrateCounter], false, cargotype.PerCrateMass, nil, subcat)
realcargo:SetDisplayName(cargotype:GetDisplayName()) realcargo:SetDisplayName(cargotype:GetDisplayName())
local map=cargotype:GetStaticResourceMap() local map = cargotype:GetStaticResourceMap()
realcargo:SetStaticResourceMap(map) realcargo:SetStaticResourceMap(map)
if cargotype.TypeNames then if cargotype.TypeNames then
realcargo.TypeNames = UTILS.DeepCopy(cargotype.TypeNames) realcargo.TypeNames = UTILS.DeepCopy(cargotype.TypeNames)
end end
if self.UseC130LoadAndUnload and self:IsC130J(Unit) then if self.UseC130LoadAndUnload and self:IsC130J(Unit) then
realcargo:SetWasDropped(true,true) -- we mark here that the crates was dropped even though we just got them because of the herc. realcargo:SetWasDropped(true, true)
end end
end end
if not drop and not pack then if not drop and not pack then
table.insert(obtainedcargo, realcargo) table.insert(obtainedcargo, realcargo)
end end
local CCat4, CType4, CShape4 = cargotype:GetStaticTypeAndShape() local CCat4, CType4, CShape4 = cargotype:GetStaticTypeAndShape()
realcargo:SetStaticTypeAndShape(CCat4,CType4,CShape4) realcargo:SetStaticTypeAndShape(CCat4, CType4, CShape4)
table.insert(self.Spawned_Cargo, realcargo) table.insert(self.Spawned_Cargo, realcargo)
end end
if (IsHerc or IsHelo) and fwBatchState and fwBatchKey and not drop then
local maxBatches = #FW_BATCH_ANGLE_PATTERN
fwBatchState.batch = (fwBatchIndex + 1) % maxBatches
self._fwBatchState[fwBatchKey] = fwBatchState
end
if not (drop or pack) then if not (drop or pack) then
Cargo:RemoveStock(requestedSets) Cargo:RemoveStock(requestedSets)
self:_RefreshCrateQuantityMenus(Group, Unit, Cargo) self:_RefreshCrateQuantityMenus(Group, Unit, Cargo)
end end
local text = string.format("%d crates for %s have been positioned near you!",number,cratedisplayname) local text = string.format("%d crates for %s have been positioned near you!", number, cratedisplayname)
if drop then if drop then
text = string.format("%d crates for %s have been dropped!",number,cratedisplayname) text = string.format("%d crates for %s have been dropped!", number, cratedisplayname)
self:__CratesDropped(1, Group, Unit, droppedcargo) self:__CratesDropped(1, Group, Unit, droppedcargo)
else else
if not quiet then if not quiet then
@@ -3930,11 +4088,11 @@ function CTLD:_FindCratesNearby( _group, _unit, _dist, _ignoreweight, ignoretype
end end
end end
self:T(self.lid..string.format("Dist %dm/%dm | weight %dkg | maxloadable %dkg",distance,finddist,weight,maxloadable)) self:T(self.lid..string.format("Dist %dm/%dm | weight %dkg | maxloadable %dkg",distance,finddist,weight,maxloadable))
if distance<=finddist and(weight<=maxloadable or _ignoreweight)and restricted==false and cando==true and not hercInnerBlocked then if distance<=finddist and(weight<=maxloadable or _ignoreweight)and restricted==false and cando==true and not hercInnerBlocked then
index = index + 1 index = index + 1
table.insert(found, staticid, cargo) found[#found+1] = cargo
maxloadable = maxloadable - weight maxloadable = maxloadable - weight
end end
end end
end end
@@ -4081,22 +4239,21 @@ end
function CTLD:_CleanupTrackedCrates(crateIdsToRemove) function CTLD:_CleanupTrackedCrates(crateIdsToRemove)
local existingcrates = self.Spawned_Cargo -- #table local existingcrates = self.Spawned_Cargo -- #table
local newexcrates = {} local newexcrates = {}
local remove = {}
for _,_ID in pairs(crateIdsToRemove or {}) do
remove[_ID] = true
end
for _,_crate in pairs(existingcrates) do for _,_crate in pairs(existingcrates) do
local excrate = _crate -- #CTLD_CARGO local excrate = _crate -- #CTLD_CARGO
local ID = excrate:GetID() local ID = excrate:GetID()
local keep = true local keep = not remove[ID]
for _,_ID in pairs(crateIdsToRemove) do
if ID == _ID then
keep = false
end
end
-- remove destroyed crates here too -- remove destroyed crates here too
local static = _crate:GetPositionable() -- Wrapper.Static#STATIC -- crates local static = _crate:GetPositionable() -- Wrapper.Static#STATIC -- crates
if not static or not static:IsAlive() then if not static or not static:IsAlive() then
keep = false keep = false
end end
if keep then if keep then
table.insert(newexcrates,_crate) newexcrates[#newexcrates+1] = _crate
end end
end end
self.Spawned_Cargo = nil self.Spawned_Cargo = nil
@@ -6819,6 +6976,16 @@ function CTLD:AddTroopsCargo(Name,Templates,Type,NoTroops,PerTroopMass,Stock,Sub
-- Troops are directly loadable -- Troops are directly loadable
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Templates,Type,false,true,NoTroops,nil,nil,PerTroopMass,Stock, SubCategory) local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Templates,Type,false,true,NoTroops,nil,nil,PerTroopMass,Stock, SubCategory)
table.insert(self.Cargo_Troops,cargo) table.insert(self.Cargo_Troops,cargo)
self._troopsByName = self._troopsByName or {}
self._troopsByName[cargo.Name] = cargo
self._cargoByTemplate = self._cargoByTemplate or {}
local _template = cargo.Templates
if type(_template) == "table" then
_template = _template[1]
end
if type(_template) == "string" and _template ~= "" then
self._cargoByTemplate[_template] = cargo
end
if SubCategory and self.usesubcats ~= true then self.usesubcats=true end if SubCategory and self.usesubcats ~= true then self.usesubcats=true end
return self return self
end end
@@ -6916,6 +7083,16 @@ function CTLD:AddCratesCargo(Name,Templates,Type,NoCrates,PerCrateMass,Stock,Sub
end end
cargo.C130TypeName = C130TypeName cargo.C130TypeName = C130TypeName
table.insert(self.Cargo_Crates,cargo) table.insert(self.Cargo_Crates,cargo)
self._crateOrStaticByName = self._crateOrStaticByName or {}
self._crateOrStaticByName[cargo.Name] = cargo
self._cargoByTemplate = self._cargoByTemplate or {}
local _template = cargo.Templates
if type(_template) == "table" then
_template = _template[1]
end
if type(_template) == "string" and _template ~= "" then
self._cargoByTemplate[_template] = cargo
end
if SubCategory and self.usesubcats ~= true then self.usesubcats=true end if SubCategory and self.usesubcats ~= true then self.usesubcats=true end
return self return self
end end
@@ -6956,6 +7133,16 @@ function CTLD:AddCratesCargoNoMove(Name,Templates,Type,NoCrates,PerCrateMass,Sto
end end
cargo.C130TypeName = C130TypeName cargo.C130TypeName = C130TypeName
table.insert(self.Cargo_Crates,cargo) table.insert(self.Cargo_Crates,cargo)
self._crateOrStaticByName = self._crateOrStaticByName or {}
self._crateOrStaticByName[cargo.Name] = cargo
self._cargoByTemplate = self._cargoByTemplate or {}
local _template = cargo.Templates
if type(_template) == "table" then
_template = _template[1]
end
if type(_template) == "string" and _template ~= "" then
self._cargoByTemplate[_template] = cargo
end
self.templateToCargoName = self.templateToCargoName or {} self.templateToCargoName = self.templateToCargoName or {}
if type(Templates)=="table" then if type(Templates)=="table" then
for _,t in pairs(Templates) do self.templateToCargoName[t] = Name end for _,t in pairs(Templates) do self.templateToCargoName[t] = Name end
@@ -6982,7 +7169,7 @@ end
function CTLD:AddStaticsCargo(Name,Mass,Stock,SubCategory,DontShowInMenu,Location,UnitTypes,DisplayName) function CTLD:AddStaticsCargo(Name,Mass,Stock,SubCategory,DontShowInMenu,Location,UnitTypes,DisplayName)
self:T(self.lid .. " AddStaticsCargo") self:T(self.lid .. " AddStaticsCargo")
self.CargoCounter = self.CargoCounter + 1 self.CargoCounter = self.CargoCounter + 1
local type = CTLD_CARGO.Enum.STATIC local cargotype = CTLD_CARGO.Enum.STATIC
local template = STATIC:FindByName(Name,true):GetTypeName() local template = STATIC:FindByName(Name,true):GetTypeName()
local unittemplate = _DATABASE:GetStaticUnitTemplate(Name) local unittemplate = _DATABASE:GetStaticUnitTemplate(Name)
local ResourceMap = nil local ResourceMap = nil
@@ -6990,13 +7177,23 @@ function CTLD:AddStaticsCargo(Name,Mass,Stock,SubCategory,DontShowInMenu,Locatio
ResourceMap = UTILS.DeepCopy(unittemplate.resourcePayload) ResourceMap = UTILS.DeepCopy(unittemplate.resourcePayload)
end end
-- Crates are not directly loadable -- 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) local cargo = CTLD_CARGO:New(self.CargoCounter,Name,template,cargotype,false,false,1,nil,nil,Mass,Stock,SubCategory,DontShowInMenu,Location)
if UnitTypes then if UnitTypes then
cargo:AddUnitTypeName(UnitTypes) cargo:AddUnitTypeName(UnitTypes)
end end
cargo:SetDisplayName(DisplayName or Name) cargo:SetDisplayName(DisplayName or Name)
cargo:SetStaticResourceMap(ResourceMap) cargo:SetStaticResourceMap(ResourceMap)
table.insert(self.Cargo_Statics,cargo) table.insert(self.Cargo_Statics,cargo)
self._crateOrStaticByName = self._crateOrStaticByName or {}
self._crateOrStaticByName[cargo.Name] = cargo
self._cargoByTemplate = self._cargoByTemplate or {}
local _template = cargo.Templates
if type(_template) == "table" then
_template = _template[1]
end
if type(_template) == "string" and _template ~= "" then
self._cargoByTemplate[_template] = cargo
end
if SubCategory and self.usesubcats ~= true then self.usesubcats=true end if SubCategory and self.usesubcats ~= true then self.usesubcats=true end
return cargo return cargo
end end
@@ -7020,9 +7217,9 @@ end
function CTLD:AddStaticsCargoFromType(Name,TypeName,Mass,Stock,SubCategory,DontShowInMenu,Location,UnitTypes,Category,ShapeName,ResourceMap,DisplayName) function CTLD:AddStaticsCargoFromType(Name,TypeName,Mass,Stock,SubCategory,DontShowInMenu,Location,UnitTypes,Category,ShapeName,ResourceMap,DisplayName)
self:T(self.lid .. " AddStaticsCargoFromType") self:T(self.lid .. " AddStaticsCargoFromType")
self.CargoCounter = self.CargoCounter + 1 self.CargoCounter = self.CargoCounter + 1
local type = CTLD_CARGO.Enum.STATIC local cargotype = CTLD_CARGO.Enum.STATIC
local template = TypeName or self.basetype or "container_cargo" local template = TypeName or self.basetype or "container_cargo"
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,template,type,false,false,1,nil,nil,Mass,Stock,SubCategory,DontShowInMenu,Location) local cargo = CTLD_CARGO:New(self.CargoCounter,Name,template,cargotype,false,false,1,nil,nil,Mass,Stock,SubCategory,DontShowInMenu,Location)
if UnitTypes then if UnitTypes then
cargo:AddUnitTypeName(UnitTypes) cargo:AddUnitTypeName(UnitTypes)
end end
@@ -7033,6 +7230,16 @@ function CTLD:AddStaticsCargoFromType(Name,TypeName,Mass,Stock,SubCategory,DontS
end end
cargo:SetStaticResourceMap(ResourceMap) cargo:SetStaticResourceMap(ResourceMap)
table.insert(self.Cargo_Statics,cargo) table.insert(self.Cargo_Statics,cargo)
self._crateOrStaticByName = self._crateOrStaticByName or {}
self._crateOrStaticByName[cargo.Name] = cargo
self._cargoByTemplate = self._cargoByTemplate or {}
local _template = cargo.Templates
if type(_template) == "table" then
_template = _template[1]
end
if type(_template) == "string" and _template ~= "" then
self._cargoByTemplate[_template] = cargo
end
if SubCategory and self.usesubcats ~= true then self.usesubcats=true end if SubCategory and self.usesubcats ~= true then self.usesubcats=true end
return cargo return cargo
end end
@@ -7046,7 +7253,7 @@ end
function CTLD:GetStaticsCargoFromTemplate(Name,Mass,DisplayName) function CTLD:GetStaticsCargoFromTemplate(Name,Mass,DisplayName)
self:T(self.lid .. " GetStaticsCargoFromTemplate") self:T(self.lid .. " GetStaticsCargoFromTemplate")
self.CargoCounter = self.CargoCounter + 1 self.CargoCounter = self.CargoCounter + 1
local type = CTLD_CARGO.Enum.STATIC local cargotype = CTLD_CARGO.Enum.STATIC
local template = STATIC:FindByName(Name,true):GetTypeName() local template = STATIC:FindByName(Name,true):GetTypeName()
local unittemplate = _DATABASE:GetStaticUnitTemplate(Name) local unittemplate = _DATABASE:GetStaticUnitTemplate(Name)
local ResourceMap = nil local ResourceMap = nil
@@ -7054,7 +7261,7 @@ function CTLD:GetStaticsCargoFromTemplate(Name,Mass,DisplayName)
ResourceMap = UTILS.DeepCopy(unittemplate.resourcePayload) ResourceMap = UTILS.DeepCopy(unittemplate.resourcePayload)
end end
-- Crates are not directly loadable -- Crates are not directly loadable
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,template,type,false,false,1,nil,nil,Mass,1) local cargo = CTLD_CARGO:New(self.CargoCounter,Name,template,cargotype,false,false,1,nil,nil,Mass,1)
cargo:SetDisplayName(DisplayName or Name) cargo:SetDisplayName(DisplayName or Name)
cargo:SetStaticResourceMap(ResourceMap) cargo:SetStaticResourceMap(ResourceMap)
--table.insert(self.Cargo_Statics,cargo) --table.insert(self.Cargo_Statics,cargo)
@@ -7074,9 +7281,9 @@ end
function CTLD:GetStaticsCargoFromType(Name,TypeName,Mass,Category,ShapeName,ResourceMap,DisplayName) function CTLD:GetStaticsCargoFromType(Name,TypeName,Mass,Category,ShapeName,ResourceMap,DisplayName)
self:T(self.lid .. " GetStaticsCargoFromType") self:T(self.lid .. " GetStaticsCargoFromType")
self.CargoCounter = self.CargoCounter + 1 self.CargoCounter = self.CargoCounter + 1
local type = CTLD_CARGO.Enum.STATIC local cargotype = CTLD_CARGO.Enum.STATIC
local template = TypeName or self.basetype or "container_cargo" local template = TypeName or self.basetype or "container_cargo"
local cargo = CTLD_CARGO:New(self.CargoCounter,Name,template,type,false,false,1,nil,nil,Mass,1) local cargo = CTLD_CARGO:New(self.CargoCounter,Name,template,cargotype,false,false,1,nil,nil,Mass,1)
cargo:SetStaticTypeAndShape(Category or "Cargos", template, ShapeName) cargo:SetStaticTypeAndShape(Category or "Cargos", template, ShapeName)
cargo:SetDisplayName(DisplayName or Name) cargo:SetDisplayName(DisplayName or Name)
if ResourceMap then if ResourceMap then
@@ -7119,6 +7326,16 @@ function CTLD:AddCratesRepair(Name,Template,Type,NoCrates, PerCrateMass,Stock,Su
cargo:SetStaticTypeAndShape(Category,TypeName,ShapeName) cargo:SetStaticTypeAndShape(Category,TypeName,ShapeName)
end end
table.insert(self.Cargo_Crates,cargo) table.insert(self.Cargo_Crates,cargo)
self._crateOrStaticByName = self._crateOrStaticByName or {}
self._crateOrStaticByName[cargo.Name] = cargo
self._cargoByTemplate = self._cargoByTemplate or {}
local _template = cargo.Templates
if type(_template) == "table" then
_template = _template[1]
end
if type(_template) == "string" and _template ~= "" then
self._cargoByTemplate[_template] = cargo
end
return self return self
end end
@@ -8556,11 +8773,17 @@ end
template = string.gsub(GroupName,"#(%d+)$","") template = string.gsub(GroupName,"#(%d+)$","")
end end
template = string.gsub(template,"-(%d+)$","") template = string.gsub(template,"-(%d+)$","")
self._cargoByTemplate = self._cargoByTemplate or {}
local cached = self._cargoByTemplate[template]
if cached and cached.CargoType ~= CTLD_CARGO.Enum.REPAIR then
return cached
end
for k,v in pairs(self.Cargo_Troops) do for k,v in pairs(self.Cargo_Troops) do
local comparison = "" local comparison = ""
if type(v.Templates) == "string" then comparison = v.Templates else comparison = v.Templates[1] end if type(v.Templates) == "string" then comparison = v.Templates else comparison = v.Templates[1] end
if comparison == template then if comparison == template then
Cargotype = v Cargotype = v
self._cargoByTemplate[template] = v
break break
end end
end end
@@ -8570,6 +8793,7 @@ end
if type(v.Templates) == "string" then comparison = v.Templates else comparison = v.Templates[1] end if type(v.Templates) == "string" then comparison = v.Templates else comparison = v.Templates[1] end
if comparison == template and v.CargoType ~= CTLD_CARGO.Enum.REPAIR then if comparison == template and v.CargoType ~= CTLD_CARGO.Enum.REPAIR then
Cargotype = v Cargotype = v
self._cargoByTemplate[template] = v
break break
end end
end end
@@ -8994,23 +9218,20 @@ end
-- @return #CTLD self -- @return #CTLD self
function CTLD:onafterStatus(From, Event, To) function CTLD:onafterStatus(From, Event, To)
self:T({From, Event, To}) self:T({From, Event, To})
-- gather some stats
-- pilots
local pilots = 0
for _,_pilot in pairs (self.CtldUnits) do
pilots = pilots + 1
end
-- spawned cargo boxes curr in field
local boxes = 0
for _,_pilot in pairs (self.Spawned_Cargo) do
boxes = boxes + 1
end
local cc = self.CargoCounter
local tc = self.TroopCounter
if self.debug or self.verbose > 0 then if self.debug or self.verbose > 0 then
-- gather stats only when logging is enabled
local pilots = 0
for _,_pilot in pairs (self.CtldUnits) do
pilots = pilots + 1
end
local boxes = 0
for _,_pilot in pairs (self.Spawned_Cargo) do
boxes = boxes + 1
end
local cc = self.CargoCounter
local tc = self.TroopCounter
local text = string.format("%s Pilots %d | Live Crates %d |\nCargo Counter %d | Troop Counter %d", self.lid, pilots, boxes, cc, tc) local text = string.format("%s Pilots %d | Live Crates %d |\nCargo Counter %d | Troop Counter %d", self.lid, pilots, boxes, cc, tc)
local m = MESSAGE:New(text,10,"CTLD"):ToAll() local m = MESSAGE:New(text,10,"CTLD"):ToAll()
if self.verbose > 0 then if self.verbose > 0 then