From 5fc3798c42e08b9cb50af92f7efd925560edab88 Mon Sep 17 00:00:00 2001 From: nasgroup94 Date: Tue, 21 Oct 2025 05:44:19 -0400 Subject: [PATCH 1/7] Update Airboss.lua Fixed possible bug where a player will get points deducted when getting a perfect groove time --- Moose Development/Moose/Ops/Airboss.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index 246e960d1..324a32a9d 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -12682,7 +12682,8 @@ function AIRBOSS:_LSOgrade( playerData ) local nL=count(G, '_')/2 local nS=count(G, '%(') local nN=N-nS-nL - + + if TIG=="_OK_" then nL = nL -1 --Circuit added to prevent grade deduction for perfect groove -- Groove time 15-18.99 sec for a unicorn. Or 60-65 for V/STOL unicorn. local Tgroove=playerData.Tgroove From 1644c1dc5ba629ba6ca6cd80e03df05d14022d9e Mon Sep 17 00:00:00 2001 From: nasgroup94 Date: Tue, 21 Oct 2025 16:49:51 -0400 Subject: [PATCH 2/7] fixes to goshawk AOA f14 AA and TIG bug --- Moose Development/Moose/Ops/Airboss.lua | 52 +++++++++++++++++++------ 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index 324a32a9d..f73fd7e24 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -5498,15 +5498,15 @@ function AIRBOSS:_GetAircraftAoA( playerData ) aoa.OnSpeedMin = self:_AoAUnit2Deg( playerData, 14.0 ) -- 14.17 --14.5 units -- VNAO Edit - Original value 14.5 aoa.Fast = self:_AoAUnit2Deg( playerData, 13.5 ) -- 13.33 --14.0 units -- VNAO Edit - Original value 14 aoa.FAST = self:_AoAUnit2Deg( playerData, 12.5 ) -- 11.67 --13.0 units -- VNAO Edit - Original value 13 - elseif goshawk then + elseif goshawk then -- These parameters tweaked by Circuit for new T45 flight model -- T-45C Goshawk parameters. - aoa.SLOW = 8.00 -- 19 - aoa.Slow = 7.75 -- 18 - aoa.OnSpeedMax = 7.25 -- 17.5 - aoa.OnSpeed = 7.00 -- 17 - aoa.OnSpeedMin = 6.75 -- 16.5 - aoa.Fast = 6.25 -- 16 - aoa.FAST = 6.00 -- 15 + aoa.SLOW = 9.5 --8.00 -- 19 + aoa.Slow = 9.25 --7.75 -- 18 + aoa.OnSpeedMax = 9.0 --7.25 -- 17.5 + aoa.OnSpeed = 8.5 --7.00 -- 17 + aoa.OnSpeedMin = 8.25 --6.75 -- 16.5 + aoa.Fast = 7.75 -- 6.25 -- 16 + aoa.FAST = 7.5 -- 6.00 -- 15 elseif skyhawk then -- A-4E-C Skyhawk parameters from https://forums.eagle.ru/showpost.php?p=3703467&postcount=390 -- Note that these are arbitrary UNITS and not degrees. We need a conversion formula! @@ -8150,7 +8150,11 @@ function AIRBOSS:_CheckPlayerStatus() local playerData = _playerData -- #AIRBOSS.PlayerData if playerData then - + local hornet = playerData.actype == AIRBOSS.AircraftCarrier.HORNET + or playerData.actype == AIRBOSS.AircraftCarrier.RHINOE + or playerData.actype == AIRBOSS.AircraftCarrier.RHINOF + or playerData.actype == AIRBOSS.AircraftCarrier.GROWLER + local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B -- Player unit. local unit = playerData.unit @@ -8161,8 +8165,8 @@ function AIRBOSS:_CheckPlayerStatus() -- TODO: This might cause problems if the CCA is set to be very small! if unit:IsInZone( self.zoneCCA ) then - -- VNAO Edit - Added wrapped up call to LSO grading - if playerData.step==AIRBOSS.PatternStep.WAKE then-- VNAO Edit - Added + -- VNAO Edit - Added wrapped up call to LSO grading Hornet + if playerData.step==AIRBOSS.PatternStep.WAKE and hornet then-- VNAO Edit - Added if math.abs(playerData.unit:GetRoll())>35 and math.abs(playerData.unit:GetRoll())<=40 then-- VNAO Edit - Added playerData.wrappedUpAtWakeLittle = true -- VNAO Edit - Added elseif math.abs(playerData.unit:GetRoll()) >40 and math.abs(playerData.unit:GetRoll())<=45 then-- VNAO Edit - Added @@ -8178,6 +8182,32 @@ function AIRBOSS:_CheckPlayerStatus() else -- VNAO Edit - Added end -- VNAO Edit - Added + if math.abs(playerData.unit:GetAoA())>= 15 then -- VNAO Edit - Added + playerData.AFU = true -- VNAO Edit - Added + elseif math.abs(playerData.unit:GetAoA())<= 5 then -- VNAO Edit - Added + playerData.AFU = true -- VNAO Edit - Added + else -- VNAO Edit - Added + end -- VNAO Edit - Added + end-- VNAO Edit - Added + + + -- VNAO Edit - Added wrapped up call to LSO grading Tomcat + if playerData.step==AIRBOSS.PatternStep.WAKE and tomcat then-- VNAO Edit - Added + if math.abs(playerData.unit:GetRoll())>35 and math.abs(playerData.unit:GetRoll())<=40 then-- VNAO Edit - Added + playerData.wrappedUpAtWakeLittle = true -- VNAO Edit - Added + elseif math.abs(playerData.unit:GetRoll()) >40 and math.abs(playerData.unit:GetRoll())<=45 then-- VNAO Edit - Added + playerData.wrappedUpAtWakeFull = true-- VNAO Edit - Added + elseif math.abs(playerData.unit:GetRoll()) >45 then-- VNAO Edit - Added + playerData.wrappedUpAtWakeUnderline = true -- VNAO Edit - Added + elseif math.abs(playerData.unit:GetRoll()) <12 and math.abs(playerData.unit:GetRoll()) >=5 then -- VNAO Edit - Added a new AA comment based on discussion with Lipps today, and going to replace the AA at the X with the original LUL comments + playerData.AAatWakeLittle = true -- VNAO Edit - Added + elseif math.abs(playerData.unit:GetRoll()) <5 and math.abs(playerData.unit:GetRoll()) >=2 then -- VNAO Edit - Added a new AA comment based on discussion with Lipps today, and going to replace the AA at the X with the original LUL comments + playerData.AAatWakeFull = true -- VNAO Edit - Added + elseif math.abs(playerData.unit:GetRoll()) <2 then -- VNAO Edit - Added a new AA comment based on discussion with Lipps today, and going to replace the AA at the X with the original LUL comments + playerData.AAatWakeUnderline = true -- VNAO Edit - Added + else -- VNAO Edit - Added + end -- VNAO Edit - Added + if math.abs(playerData.unit:GetAoA())>= 15 then -- VNAO Edit - Added playerData.AFU = true -- VNAO Edit - Added elseif math.abs(playerData.unit:GetAoA())<= 5 then -- VNAO Edit - Added From eb4e7b928191f57eefe71ecd9f8bffcf82abdcba Mon Sep 17 00:00:00 2001 From: Thomas <72444570+Applevangelist@users.noreply.github.com> Date: Wed, 22 Oct 2025 07:23:21 +0200 Subject: [PATCH 3/7] Revert "Minor fixes" --- Moose Development/Moose/Ops/Airboss.lua | 55 ++++++------------------- 1 file changed, 12 insertions(+), 43 deletions(-) diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index f73fd7e24..246e960d1 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -5498,15 +5498,15 @@ function AIRBOSS:_GetAircraftAoA( playerData ) aoa.OnSpeedMin = self:_AoAUnit2Deg( playerData, 14.0 ) -- 14.17 --14.5 units -- VNAO Edit - Original value 14.5 aoa.Fast = self:_AoAUnit2Deg( playerData, 13.5 ) -- 13.33 --14.0 units -- VNAO Edit - Original value 14 aoa.FAST = self:_AoAUnit2Deg( playerData, 12.5 ) -- 11.67 --13.0 units -- VNAO Edit - Original value 13 - elseif goshawk then -- These parameters tweaked by Circuit for new T45 flight model + elseif goshawk then -- T-45C Goshawk parameters. - aoa.SLOW = 9.5 --8.00 -- 19 - aoa.Slow = 9.25 --7.75 -- 18 - aoa.OnSpeedMax = 9.0 --7.25 -- 17.5 - aoa.OnSpeed = 8.5 --7.00 -- 17 - aoa.OnSpeedMin = 8.25 --6.75 -- 16.5 - aoa.Fast = 7.75 -- 6.25 -- 16 - aoa.FAST = 7.5 -- 6.00 -- 15 + aoa.SLOW = 8.00 -- 19 + aoa.Slow = 7.75 -- 18 + aoa.OnSpeedMax = 7.25 -- 17.5 + aoa.OnSpeed = 7.00 -- 17 + aoa.OnSpeedMin = 6.75 -- 16.5 + aoa.Fast = 6.25 -- 16 + aoa.FAST = 6.00 -- 15 elseif skyhawk then -- A-4E-C Skyhawk parameters from https://forums.eagle.ru/showpost.php?p=3703467&postcount=390 -- Note that these are arbitrary UNITS and not degrees. We need a conversion formula! @@ -8150,11 +8150,7 @@ function AIRBOSS:_CheckPlayerStatus() local playerData = _playerData -- #AIRBOSS.PlayerData if playerData then - local hornet = playerData.actype == AIRBOSS.AircraftCarrier.HORNET - or playerData.actype == AIRBOSS.AircraftCarrier.RHINOE - or playerData.actype == AIRBOSS.AircraftCarrier.RHINOF - or playerData.actype == AIRBOSS.AircraftCarrier.GROWLER - local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B + -- Player unit. local unit = playerData.unit @@ -8165,8 +8161,8 @@ function AIRBOSS:_CheckPlayerStatus() -- TODO: This might cause problems if the CCA is set to be very small! if unit:IsInZone( self.zoneCCA ) then - -- VNAO Edit - Added wrapped up call to LSO grading Hornet - if playerData.step==AIRBOSS.PatternStep.WAKE and hornet then-- VNAO Edit - Added + -- VNAO Edit - Added wrapped up call to LSO grading + if playerData.step==AIRBOSS.PatternStep.WAKE then-- VNAO Edit - Added if math.abs(playerData.unit:GetRoll())>35 and math.abs(playerData.unit:GetRoll())<=40 then-- VNAO Edit - Added playerData.wrappedUpAtWakeLittle = true -- VNAO Edit - Added elseif math.abs(playerData.unit:GetRoll()) >40 and math.abs(playerData.unit:GetRoll())<=45 then-- VNAO Edit - Added @@ -8182,32 +8178,6 @@ function AIRBOSS:_CheckPlayerStatus() else -- VNAO Edit - Added end -- VNAO Edit - Added - if math.abs(playerData.unit:GetAoA())>= 15 then -- VNAO Edit - Added - playerData.AFU = true -- VNAO Edit - Added - elseif math.abs(playerData.unit:GetAoA())<= 5 then -- VNAO Edit - Added - playerData.AFU = true -- VNAO Edit - Added - else -- VNAO Edit - Added - end -- VNAO Edit - Added - end-- VNAO Edit - Added - - - -- VNAO Edit - Added wrapped up call to LSO grading Tomcat - if playerData.step==AIRBOSS.PatternStep.WAKE and tomcat then-- VNAO Edit - Added - if math.abs(playerData.unit:GetRoll())>35 and math.abs(playerData.unit:GetRoll())<=40 then-- VNAO Edit - Added - playerData.wrappedUpAtWakeLittle = true -- VNAO Edit - Added - elseif math.abs(playerData.unit:GetRoll()) >40 and math.abs(playerData.unit:GetRoll())<=45 then-- VNAO Edit - Added - playerData.wrappedUpAtWakeFull = true-- VNAO Edit - Added - elseif math.abs(playerData.unit:GetRoll()) >45 then-- VNAO Edit - Added - playerData.wrappedUpAtWakeUnderline = true -- VNAO Edit - Added - elseif math.abs(playerData.unit:GetRoll()) <12 and math.abs(playerData.unit:GetRoll()) >=5 then -- VNAO Edit - Added a new AA comment based on discussion with Lipps today, and going to replace the AA at the X with the original LUL comments - playerData.AAatWakeLittle = true -- VNAO Edit - Added - elseif math.abs(playerData.unit:GetRoll()) <5 and math.abs(playerData.unit:GetRoll()) >=2 then -- VNAO Edit - Added a new AA comment based on discussion with Lipps today, and going to replace the AA at the X with the original LUL comments - playerData.AAatWakeFull = true -- VNAO Edit - Added - elseif math.abs(playerData.unit:GetRoll()) <2 then -- VNAO Edit - Added a new AA comment based on discussion with Lipps today, and going to replace the AA at the X with the original LUL comments - playerData.AAatWakeUnderline = true -- VNAO Edit - Added - else -- VNAO Edit - Added - end -- VNAO Edit - Added - if math.abs(playerData.unit:GetAoA())>= 15 then -- VNAO Edit - Added playerData.AFU = true -- VNAO Edit - Added elseif math.abs(playerData.unit:GetAoA())<= 5 then -- VNAO Edit - Added @@ -12712,8 +12682,7 @@ function AIRBOSS:_LSOgrade( playerData ) local nL=count(G, '_')/2 local nS=count(G, '%(') local nN=N-nS-nL - - if TIG=="_OK_" then nL = nL -1 --Circuit added to prevent grade deduction for perfect groove + -- Groove time 15-18.99 sec for a unicorn. Or 60-65 for V/STOL unicorn. local Tgroove=playerData.Tgroove From 8432f46e484daaec415537a5bbec3a3e51b2ab70 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Thu, 23 Oct 2025 08:10:22 +0200 Subject: [PATCH 4/7] #AIRBOSS - Fixed omission of magnetic in expected BRC call --- Moose Development/Moose/Ops/Airboss.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index 246e960d1..8b8644165 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -12230,7 +12230,7 @@ function AIRBOSS:GetHeadingIntoWind_new( vdeck, magnetic, coord ) -- Ship heading so cross wind is min for the given wind. -- local intowind = (540 + (windto - magvar + math.deg(theta) )) % 360 -- VNAO Edit: Using old heading into wind algorithm - local intowind = self:GetHeadingIntoWind_old(vdeck) -- VNAO Edit: Using old heading into wind algorithm + local intowind = self:GetHeadingIntoWind_old(vdeck,magnetic) -- VNAO Edit: Using old heading into wind algorithm return intowind, v end From 0f270a6a35ebcfe2430659092d934beeb495d489 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Thu, 23 Oct 2025 12:10:05 +0200 Subject: [PATCH 5/7] #UTILS - FARP helper - add options to spawn multiple pads --- Moose Development/Moose/Utilities/Utils.lua | 128 +++++++++++++++----- 1 file changed, 98 insertions(+), 30 deletions(-) diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 8c337b178..9d52ee972 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -4137,6 +4137,45 @@ function UTILS.LCGRandom() return UTILS.lcg.seed / UTILS.lcg.m end +--- Create a table of grid-points for n points. +-- @param #number startVec2 Starting DCS#Vec2 map coordinate, e.g. `{x=63598575,y=-63598575}` +-- @param #number n Number of points to generate. +-- @param #number spacingX Horizonzal spacing (meters). +-- @param #number spacingY Vertical spacing (meters). +-- @return #table Grid Table of DCS#Vec2 entries. +function UTILS.GenerateGridPoints(startVec2, n, spacingX, spacingY) + local points = {} + local gridSize = math.ceil(math.sqrt(n)) + local count = 0 + local n = n or 1 + local spacingX = spacingX or 100 + local spacingY = spacingY or 100 + local startX = startVec2.x or 100 + local startY = startVec2.y or 100 + + for row = 0, gridSize - 1 do + for col = 0, gridSize - 1 do + if count >= n then + break + end + + local point = { + x = startX + (col * spacingX), + y = startY + (row * spacingY) + } + + table.insert(points, point) + count = count + 1 + end + + if count >= n then + break + end + end + + return points +end + --- Spawns a new FARP of a defined type and coalition and functional statics (fuel depot, ammo storage, tent, windsock) around that FARP to make it operational. -- Adds vehicles from template if given. Fills the FARP warehouse with liquids and known materiels. -- References: [DCS Forum Topic](https://forum.dcs.world/topic/282989-farp-equipment-to-run-it) @@ -4157,10 +4196,38 @@ end -- @param #string F10Text Text to display on F10 map if given. Handy to post things like the ADF beacon Frequency, Callsign and ATC Frequency. -- @param #boolean DynamicSpawns If true, allow Dynamic Spawns from this FARP. -- @param #boolean HotStart If true and DynamicSpawns is true, allow hot starts for Dynamic Spawns from this FARP. +-- @param #number NumberPads If given, spawn this number of pads. +-- @param #number SpacingX For NumberPads > 1, space this many meters horizontally. Defaults to 100. +-- @param #number SpacingY For NumberPads > 1, space this many meters vertically. Defaults to 100. -- @return #list Table of spawned objects and vehicle object (if given). -- @return #string ADFBeaconName Name of the ADF beacon, to be able to remove/stop it later. -- @return #number MarkerID ID of the F10 Text, to be able to remove it later. -function UTILS.SpawnFARPAndFunctionalStatics(Name,Coordinate,FARPType,Coalition,Country,CallSign,Frequency,Modulation,ADF,SpawnRadius,VehicleTemplate,Liquids,Equipment,Airframes,F10Text,DynamicSpawns,HotStart) +function UTILS.SpawnFARPAndFunctionalStatics(Name,Coordinate,FARPType,Coalition,Country,CallSign,Frequency,Modulation,ADF,SpawnRadius,VehicleTemplate,Liquids,Equipment,Airframes,F10Text,DynamicSpawns,HotStart,NumberPads,SpacingX,SpacingY) + + local function PopulateStorage(Name,liquids,equip,airframes) + local newWH = STORAGE:New(Name) + if liquids and liquids > 0 then + -- Storage fill-up + newWH:SetLiquid(STORAGE.Liquid.DIESEL,liquids) -- kgs to tons + newWH:SetLiquid(STORAGE.Liquid.GASOLINE,liquids) + newWH:SetLiquid(STORAGE.Liquid.JETFUEL,liquids) + newWH:SetLiquid(STORAGE.Liquid.MW50,liquids) + end + + if equip and equip > 0 then + for cat,nitem in pairs(ENUMS.Storage.weapons) do + for name,item in pairs(nitem) do + newWH:SetItem(item,equip) + end + end + end + + if airframes and airframes > 0 then + for typename in pairs (CSAR.AircraftType) do + newWH:SetItem(typename,airframes) + end + end + end -- Set Defaults local farplocation = Coordinate @@ -4181,12 +4248,36 @@ function UTILS.SpawnFARPAndFunctionalStatics(Name,Coordinate,FARPType,Coalition, local Country = Country or (Coalition == coalition.side.BLUE and country.id.USA or country.id.RUSSIA) local ReturnObjects = {} - -- Spawn FARP - local newfarp = SPAWNSTATIC:NewFromType(STypeName,"Heliports",Country) -- "Invisible FARP" "FARP" - newfarp:InitShape(SShapeName) -- "invisiblefarp" "FARPS" - newfarp:InitFARP(callsign,freq,mod,DynamicSpawns,HotStart) - local spawnedfarp = newfarp:SpawnFromCoordinate(farplocation,0,Name) - table.insert(ReturnObjects,spawnedfarp) + -- many FARPs + local NumberPads = NumberPads or 1 + local SpacingX = SpacingX or 100 + local SpacingY = SpacingY or 100 + local FarpVec2 = Coordinate:GetVec2() + + if NumberPads > 1 then + local Grid = UTILS.GenerateGridPoints(FarpVec2, NumberPads, SpacingX, SpacingY) + for id,gridpoint in ipairs(Grid) do + -- Spawn FARP + local location = COORDINATE:NewFromVec2(gridpoint) + local newfarp = SPAWNSTATIC:NewFromType(STypeName,"Heliports",Country) -- "Invisible FARP" "FARP" + newfarp:InitShape(SShapeName) -- "invisiblefarp" "FARPS" + newfarp:InitFARP(callsign,freq,mod,DynamicSpawns,HotStart) + local spawnedfarp = newfarp:SpawnFromCoordinate(location,0,Name.."-"..id) + table.insert(ReturnObjects,spawnedfarp) + + PopulateStorage(Name.."-"..id,liquids,equip,airframes) + end + else + -- Spawn FARP + local newfarp = SPAWNSTATIC:NewFromType(STypeName,"Heliports",Country) -- "Invisible FARP" "FARP" + newfarp:InitShape(SShapeName) -- "invisiblefarp" "FARPS" + newfarp:InitFARP(callsign,freq,mod,DynamicSpawns,HotStart) + local spawnedfarp = newfarp:SpawnFromCoordinate(farplocation,0,Name) + table.insert(ReturnObjects,spawnedfarp) + + PopulateStorage(Name,liquids,equip,airframes) + end + -- Spawn Objects local FARPStaticObjectsNato = { ["FUEL"] = { TypeName = "FARP Fuel Depot", ShapeName = "GSM Rus", Category = "Fortifications"}, @@ -4220,29 +4311,6 @@ function UTILS.SpawnFARPAndFunctionalStatics(Name,Coordinate,FARPType,Coalition, table.insert(ReturnObjects,spawnedvehicle) end - local newWH = STORAGE:New(Name) - if liquids and liquids > 0 then - -- Storage fill-up - newWH:SetLiquid(STORAGE.Liquid.DIESEL,liquids) -- kgs to tons - newWH:SetLiquid(STORAGE.Liquid.GASOLINE,liquids) - newWH:SetLiquid(STORAGE.Liquid.JETFUEL,liquids) - newWH:SetLiquid(STORAGE.Liquid.MW50,liquids) - end - - if equip and equip > 0 then - for cat,nitem in pairs(ENUMS.Storage.weapons) do - for name,item in pairs(nitem) do - newWH:SetItem(item,equip) - end - end - end - - if airframes and airframes > 0 then - for typename in pairs (CSAR.AircraftType) do - newWH:SetItem(typename,airframes) - end - end - local ADFName if ADF and type(ADF) == "number" then local ADFFreq = ADF*1000 -- KHz to Hz From f3af0262dfa6dbd55970ab4a6aa5e22208b381ad Mon Sep 17 00:00:00 2001 From: leka1986 <83298840+leka1986@users.noreply.github.com> Date: Fri, 24 Oct 2025 14:02:06 +0200 Subject: [PATCH 6/7] Update CTLD.lua Added Crates amount to the menus and AddCratesCargoNoMove. --- Moose Development/Moose/Ops/CTLD.lua | 78 ++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 9 deletions(-) diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index 525f94b87..e9d413642 100644 --- a/Moose Development/Moose/Ops/CTLD.lua +++ b/Moose Development/Moose/Ops/CTLD.lua @@ -783,6 +783,7 @@ do -- my_ctld:AddCratesCargo("Humvee",{"Humvee"},CTLD_CARGO.Enum.VEHICLE,2,2775,10) -- -- additionally, you can limit **where** the stock is available (one location only!) - this one is available in a zone called "Vehicle Store". -- my_ctld:AddCratesCargo("Humvee",{"Humvee"},CTLD_CARGO.Enum.VEHICLE,2,2775,10,nil,nil,"Vehicle Store") +-- -- Tip: if you want the spawned/built group NOT to move to a MOVE zone, replace AddCratesCargo with AddCratesCargoNoMove (same parameters). -- -- -- add infantry unit called "Forward Ops Base" using template "FOB", of type FOB, size 4, i.e. needs four crates to be build: -- my_ctld:AddCratesCargo("Forward Ops Base",{"FOB"},CTLD_CARGO.Enum.FOB,4) @@ -4514,7 +4515,8 @@ function CTLD:_RefreshF10Menus() 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) + local needed = cargoObj:GetCratesNeeded() or 1 + local txt = string.format("%d crate%s %s (%dkg)",needed,needed==1 and "" or "s",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 @@ -4525,7 +4527,8 @@ function CTLD:_RefreshF10Menus() 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) + local needed = cargoObj:GetCratesNeeded() or 1 + local txt = string.format("%d crate%s %s (%dkg)",needed,needed==1 and "" or "s",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 @@ -4537,7 +4540,8 @@ function CTLD:_RefreshF10Menus() 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) + local needed = cargoObj:GetCratesNeeded() or 1 + local txt = string.format("%d crate%s %s (%dkg)",needed,needed==1 and "" or "s",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 @@ -4548,7 +4552,8 @@ function CTLD:_RefreshF10Menus() 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) + local needed = cargoObj:GetCratesNeeded() or 1 + local txt = string.format("%d crate%s %s (%dkg)",needed,needed==1 and "" or "s",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 @@ -4567,7 +4572,8 @@ function CTLD:_RefreshF10Menus() 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) + local needed = cargoObj:GetCratesNeeded() or 1 + local txt = string.format("%d crate%s %s (%dkg)", needed, needed==1 and "" or "s", 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 @@ -4576,7 +4582,8 @@ function CTLD:_RefreshF10Menus() 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) + local needed = cargoObj:GetCratesNeeded() or 1 + local txt = string.format("%d crate%s %s (%dkg)", needed, needed==1 and "" or "s", 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 @@ -4586,7 +4593,8 @@ function CTLD:_RefreshF10Menus() 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) + local needed = cargoObj:GetCratesNeeded() or 1 + local txt = string.format("%d crate%s %s (%dkg)", needed, needed==1 and "" or "s", 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 @@ -4595,7 +4603,8 @@ function CTLD:_RefreshF10Menus() 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) + local needed = cargoObj:GetCratesNeeded() or 1 + local txt = string.format("%d crate%s %s (%dkg)", needed, needed==1 and "" or "s", 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 @@ -5427,6 +5436,50 @@ function CTLD:AddCratesCargo(Name,Templates,Type,NoCrates,PerCrateMass,Stock,Sub return self end +--- Identical to AddCratesCargo, but registers the cargo so the spawned/built group does not move to MOVE zones. +--- User function - Add *generic* crate-type loadable as cargo. This type will create crates that need to be loaded, moved, dropped and built. +-- @param #CTLD self +-- @param #string Name Unique name of this type of cargo. E.g. "Humvee". +-- @param #table Templates Table of #string names of late activated Wrapper.Group#GROUP building this cargo. +-- @param #CTLD_CARGO.Enum Type Type of cargo. I.e. VEHICLE or FOB. VEHICLE will move to destination zones when dropped/build, FOB stays put. +-- @param #number NoCrates Number of crates needed to build this cargo. +-- @param #number PerCrateMass Mass in kg of each crate +-- @param #number Stock Number of buildable groups in stock. Nil for unlimited. +-- @param #string SubCategory Name of sub-category (optional). +-- @param #boolean DontShowInMenu (optional) If set to "true" this won't show up in the menu. +-- @param Core.Zone#ZONE Location (optional) If set, the cargo item is **only** available here. Can be a #ZONE object or the name of a zone as #string. +-- @param #string UnitTypes Unit type names (optional). If set, only these unit types can pick up the cargo, e.g. "UH-1H" or {"UH-1H","OH58D"}. +-- @param #string Category Static category name (optional). If set, spawn cargo crate with an alternate category type, e.g. "Cargos". +-- @param #string TypeName Static type name (optional). If set, spawn cargo crate with an alternate type shape, e.g. "iso_container". +-- @param #string ShapeName Static shape name (optional). If set, spawn cargo crate with an alternate type sub-shape, e.g. "iso_container_cargo". +-- @return #CTLD self +function CTLD:AddCratesCargoNoMove(Name,Templates,Type,NoCrates,PerCrateMass,Stock,SubCategory,DontShowInMenu,Location,UnitTypes,Category,TypeName,ShapeName) + self:T(self.lid .. " AddCratesCargoNoMove") + if not self:_CheckTemplates(Templates) then + self:E(self.lid .. "Crates Cargo for " .. Name .. " has missing template(s)!" ) + return self + end + self.CargoCounter = self.CargoCounter + 1 + -- Crates are not directly loadable + local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Templates,Type,false,false,NoCrates,nil,nil,PerCrateMass,Stock,SubCategory,DontShowInMenu,Location) + if UnitTypes then + cargo:AddUnitTypeName(UnitTypes) + end + cargo:SetStaticTypeAndShape("Cargos",self.basetype) + if TypeName then + cargo:SetStaticTypeAndShape(Category,TypeName,ShapeName) + end + table.insert(self.Cargo_Crates,cargo) + if SubCategory and self.usesubcats ~= true then self.usesubcats=true end + self.nomovetozone_templates = self.nomovetozone_templates or {} + if type(Templates)=="table" then + for _,t in pairs(Templates) do self.nomovetozone_templates[t] = true end + else + self.nomovetozone_templates[Templates] = true + end + return self +end + --- User function - Add *generic* static-type loadable as cargo. This type will create cargo that needs to be loaded, moved and dropped. -- @param #CTLD self -- @param #string Name Unique name of this type of cargo as set in the mission editor (note: UNIT name!), e.g. "Ammunition-1". @@ -7496,7 +7549,14 @@ end function CTLD:onafterCratesBuild(From, Event, To, Group, Unit, Vehicle) self:T({From, Event, To}) if self.movetroopstowpzone then - self:_MoveGroupToZone(Vehicle) + local gname = Vehicle and Vehicle:GetName() or nil + local block = false + if gname and self.nomovetozone_templates then + for t,_ in pairs(self.nomovetozone_templates) do + if gname==t or string.sub(gname,1,#t+1)==t.."-" then block = true break end + end + end + if not block then self:_MoveGroupToZone(Vehicle) end end return self end From 8c07573f8f02ca66905f935f7324b26a96ec8e61 Mon Sep 17 00:00:00 2001 From: leka1986 <83298840+leka1986@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:13:18 +0200 Subject: [PATCH 7/7] Update CTLD.lua --- Moose Development/Moose/Ops/CTLD.lua | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index e9d413642..3f844a1a8 100644 --- a/Moose Development/Moose/Ops/CTLD.lua +++ b/Moose Development/Moose/Ops/CTLD.lua @@ -119,6 +119,7 @@ CTLD_CARGO = { -- @param #boolean DontShowInMenu Show this item in menu or not (default: false == show it). -- @param Core.Zone#ZONE Location (optional) Where the cargo is available (one location only). -- @return #CTLD_CARGO self + function CTLD_CARGO:New(ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped, PerCrateMass, Stock, Subcategory, DontShowInMenu, Location) function CTLD_CARGO:New(ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped, PerCrateMass, Stock, Subcategory, DontShowInMenu, Location) -- Inherit everything from BASE class. local self=BASE:Inherit(self, BASE:New()) -- #CTLD_CARGO @@ -147,6 +148,7 @@ CTLD_CARGO = { Location = ZONE:New(Location) end self.Location = Location + self.NoMoveToZone = false return self end @@ -5460,8 +5462,8 @@ function CTLD:AddCratesCargoNoMove(Name,Templates,Type,NoCrates,PerCrateMass,Sto return self end self.CargoCounter = self.CargoCounter + 1 - -- Crates are not directly loadable local cargo = CTLD_CARGO:New(self.CargoCounter,Name,Templates,Type,false,false,NoCrates,nil,nil,PerCrateMass,Stock,SubCategory,DontShowInMenu,Location) + cargo.NoMoveToZone = true if UnitTypes then cargo:AddUnitTypeName(UnitTypes) end @@ -5470,13 +5472,15 @@ function CTLD:AddCratesCargoNoMove(Name,Templates,Type,NoCrates,PerCrateMass,Sto cargo:SetStaticTypeAndShape(Category,TypeName,ShapeName) end table.insert(self.Cargo_Crates,cargo) - if SubCategory and self.usesubcats ~= true then self.usesubcats=true end - self.nomovetozone_templates = self.nomovetozone_templates or {} + self.templateToCargoName = self.templateToCargoName or {} if type(Templates)=="table" then - for _,t in pairs(Templates) do self.nomovetozone_templates[t] = true end + for _,t in pairs(Templates) do self.templateToCargoName[t] = Name end else - self.nomovetozone_templates[Templates] = true + self.templateToCargoName[Templates] = Name end + self.nomovetozone_names = self.nomovetozone_names or {} + self.nomovetozone_names[Name] = true + if SubCategory and self.usesubcats ~= true then self.usesubcats=true end return self end @@ -7548,15 +7552,11 @@ end -- @return #CTLD self function CTLD:onafterCratesBuild(From, Event, To, Group, Unit, Vehicle) self:T({From, Event, To}) - if self.movetroopstowpzone then - local gname = Vehicle and Vehicle:GetName() or nil - local block = false - if gname and self.nomovetozone_templates then - for t,_ in pairs(self.nomovetozone_templates) do - if gname==t or string.sub(gname,1,#t+1)==t.."-" then block = true break end - end + if self.movetroopstowpzone and Vehicle then + local cg = self:GetGenericCargoObjectFromGroupName(Vehicle:GetName()) + if not (cg and (cg.NoMoveToZone or (self.nomovetozone_names and self.nomovetozone_names[cg:GetName()]))) then + self:_MoveGroupToZone(Vehicle) end - if not block then self:_MoveGroupToZone(Vehicle) end end return self end