mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'master' of https://github.com/nasgroup94/MOOSE
This commit is contained in:
commit
2b2acbe244
@ -1934,6 +1934,21 @@ function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, Offset)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Updates the current location from a @{Wrapper.Group}.
|
||||
-- @param #ZONE_UNIT self
|
||||
-- @param Wrapper.Group#GROUP Group (optional) Update from this Unit, if nil, update from the UNIT this zone is based on.
|
||||
-- @return self
|
||||
function ZONE_UNIT:UpdateFromUnit(Unit)
|
||||
if Unit and Unit:IsAlive() then
|
||||
local vec2 = Unit:GetVec2()
|
||||
self.LastVec2 = vec2
|
||||
elseif self.ZoneUNIT and self.ZoneUNIT:IsAlive() then
|
||||
local ZoneVec2 = self.ZoneUNIT:GetVec2()
|
||||
self.LastVec2 = ZoneVec2
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Returns the current location of the @{Wrapper.Unit#UNIT}.
|
||||
-- @param #ZONE_UNIT self
|
||||
@ -2071,6 +2086,22 @@ function ZONE_GROUP:GetVec2()
|
||||
return ZoneVec2
|
||||
end
|
||||
|
||||
--- Updates the current location from a @{Wrapper.Group}.
|
||||
-- @param #ZONE_GROUP self
|
||||
-- @param Wrapper.Group#GROUP Group (optional) Update from this Group, if nil, update from the GROUP this zone is based on.
|
||||
-- @return self
|
||||
function ZONE_GROUP:UpdateFromGroup(Group)
|
||||
if Group and Group:IsAlive() then
|
||||
local vec2 = Group:GetVec2()
|
||||
self.Vec2 = vec2
|
||||
elseif self._.ZoneGROUP and self._.ZoneGROUP:IsAlive() then
|
||||
local ZoneVec2 = self._.ZoneGROUP:GetVec2()
|
||||
self.Vec2 = ZoneVec2
|
||||
self._.ZoneVec2Cache = ZoneVec2
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Returns a random location within the zone of the @{Wrapper.Group}.
|
||||
-- @param #ZONE_GROUP self
|
||||
-- @return DCS#Vec2 The random location of the zone based on the @{Wrapper.Group} location.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
@ -12260,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
|
||||
|
||||
@ -1150,11 +1150,11 @@ function CSAR:_EventHandler(EventData)
|
||||
|
||||
local initdcscoord = nil
|
||||
local initcoord = nil
|
||||
if _event.id == EVENTS.Ejection then
|
||||
if _event.id == EVENTS.Ejection and _event.TgtDCSUnit then
|
||||
initdcscoord = _event.TgtDCSUnit:getPoint()
|
||||
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
||||
self:T({initdcscoord})
|
||||
else
|
||||
elseif _event.IniDCSUnit then
|
||||
initdcscoord = _event.IniDCSUnit:getPoint()
|
||||
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
||||
self:T({initdcscoord})
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
-- @module Ops.CTLD
|
||||
-- @image OPS_CTLD.jpg
|
||||
|
||||
-- Last Update July 2025
|
||||
-- Last Update Oct 2025
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -147,6 +147,7 @@ CTLD_CARGO = {
|
||||
Location = ZONE:New(Location)
|
||||
end
|
||||
self.Location = Location
|
||||
self.NoMoveToZone = false
|
||||
return self
|
||||
end
|
||||
|
||||
@ -783,6 +784,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)
|
||||
@ -1556,6 +1558,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
self.smokedistance = 2000
|
||||
self.movetroopstowpzone = true
|
||||
self.movetroopsdistance = 5000
|
||||
self.returntroopstobase = true -- if set to false, troops would stay after deployment inside a load zone.
|
||||
self.troopdropzoneradius = 100
|
||||
|
||||
self.VehicleMoveFormation = AI.Task.VehicleFormation.VEE
|
||||
@ -3676,7 +3679,7 @@ function CTLD:_UnloadTroops(Group, Unit)
|
||||
inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP)
|
||||
end
|
||||
if inzone then
|
||||
droppingatbase = true
|
||||
droppingatbase = self.returntroopstobase
|
||||
end
|
||||
-- check for hover unload
|
||||
local hoverunload = self:IsCorrectHover(Unit) --if true we\'re hovering in parameters
|
||||
@ -4513,7 +4516,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
|
||||
@ -4524,7 +4528,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
|
||||
@ -4536,7 +4541,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
|
||||
@ -4547,7 +4553,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
|
||||
@ -4559,14 +4566,15 @@ function CTLD:_RefreshF10Menus()
|
||||
end
|
||||
end
|
||||
else
|
||||
if self.usesubcats then
|
||||
if self.usesubcats == true then
|
||||
local subcatmenus = {}
|
||||
for catName, _ in pairs(self.subcats) do
|
||||
subcatmenus[catName] = MENU_GROUP:New(_group, catName, cratesmenu) -- fixed variable case
|
||||
end
|
||||
for _, cargoObj in pairs(self.Cargo_Crates) do
|
||||
if not cargoObj.DontShowInMenu then
|
||||
local txt = string.format("Crate %s (%dkg)", cargoObj.Name, cargoObj.PerCrateMass or 0)
|
||||
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
|
||||
@ -4575,7 +4583,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
|
||||
@ -4585,7 +4594,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
|
||||
@ -4594,7 +4604,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
|
||||
@ -5134,7 +5145,7 @@ function CTLD:_UnloadSingleTroopByID(Group, Unit, chunkID)
|
||||
inzone, zonename, zone, distance = self:IsUnitInZone(Unit, CTLD.CargoZoneType.SHIP)
|
||||
end
|
||||
if inzone then
|
||||
droppingatbase = true
|
||||
droppingatbase = self.returntroopstobase
|
||||
end
|
||||
|
||||
if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen(Unit:GetName()) then
|
||||
@ -5426,6 +5437,52 @@ 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
|
||||
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
|
||||
cargo:SetStaticTypeAndShape("Cargos",self.basetype)
|
||||
if TypeName then
|
||||
cargo:SetStaticTypeAndShape(Category,TypeName,ShapeName)
|
||||
end
|
||||
table.insert(self.Cargo_Crates,cargo)
|
||||
self.templateToCargoName = self.templateToCargoName or {}
|
||||
if type(Templates)=="table" then
|
||||
for _,t in pairs(Templates) do self.templateToCargoName[t] = Name end
|
||||
else
|
||||
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
|
||||
|
||||
--- 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".
|
||||
@ -5670,8 +5727,14 @@ function CTLD:AddCTLDZone(Name, Type, Color, Active, HasBeacon, Shiplength, Ship
|
||||
return self
|
||||
end
|
||||
end
|
||||
|
||||
local ctldzone = {} -- #CTLD.CargoZone
|
||||
|
||||
local exists = true
|
||||
local ctldzone = self:GetCTLDZone(Name, Type) -- #CTLD.CargoZone
|
||||
if not ctldzone then
|
||||
exists = false
|
||||
ctldzone = {}
|
||||
end
|
||||
|
||||
ctldzone.active = Active or false
|
||||
ctldzone.color = Color or SMOKECOLOR.Red
|
||||
ctldzone.name = Name or "NONE"
|
||||
@ -5697,11 +5760,56 @@ function CTLD:AddCTLDZone(Name, Type, Color, Active, HasBeacon, Shiplength, Ship
|
||||
ctldzone.shiplength = Shiplength or 100
|
||||
ctldzone.shipwidth = Shipwidth or 10
|
||||
end
|
||||
|
||||
self:AddZone(ctldzone)
|
||||
|
||||
if not exists then
|
||||
self:AddZone(ctldzone)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- User function - find #CTLD.CargoZone zone by name.
|
||||
-- @param #CTLD self
|
||||
-- @param #string Name Name of this zone.
|
||||
-- @param #string Type Type of this zone, #CTLD.CargoZoneType
|
||||
-- @return #CTLD.CargoZone self
|
||||
function CTLD:GetCTLDZone(Name, Type)
|
||||
|
||||
if Type == CTLD.CargoZoneType.LOAD then
|
||||
for _, z in pairs(self.pickupZones) do
|
||||
if z.name == Name then
|
||||
return z
|
||||
end
|
||||
end
|
||||
elseif Type == CTLD.CargoZoneType.DROP then
|
||||
for _, z in pairs(self.dropOffZones) do
|
||||
if z.name == Name then
|
||||
return z
|
||||
end
|
||||
end
|
||||
elseif Type == CTLD.CargoZoneType.SHIP then
|
||||
for _, z in pairs(self.shipZones) do
|
||||
if z.name == Name then
|
||||
return z
|
||||
end
|
||||
end
|
||||
elseif Type == CTLD.CargoZoneType.BEACON then
|
||||
for _, z in pairs(self.droppedBeacons) do
|
||||
if z.name == Name then
|
||||
return z
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, z in pairs(self.wpZones) do
|
||||
if z.name == Name then
|
||||
return z
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- User function - Creates and adds a #CTLD.CargoZone zone for this CTLD instance from an Airbase or FARP name.
|
||||
-- Zones of type LOAD: Players load crates and troops here.
|
||||
-- Zones of type DROP: Players can drop crates here. Note that troops can be unloaded anywhere.
|
||||
@ -7443,8 +7551,11 @@ end
|
||||
-- @return #CTLD self
|
||||
function CTLD:onafterCratesBuild(From, Event, To, Group, Unit, Vehicle)
|
||||
self:T({From, Event, To})
|
||||
if self.movetroopstowpzone then
|
||||
self:_MoveGroupToZone(Vehicle)
|
||||
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
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2330,6 +2330,16 @@ function UTILS.IsLoadingDoorOpen( unit_name )
|
||||
return true
|
||||
end
|
||||
|
||||
if type_name == "UH-60L_DAP" and (unit:getDrawArgumentValue(401) == 1 or unit:getDrawArgumentValue(402) == 1) then
|
||||
BASE:T(unit_name .. " cargo door is open")
|
||||
return true
|
||||
end
|
||||
|
||||
if type_name == "UH-60L_DAP" and (unit:getDrawArgumentValue(38) > 0 or unit:getDrawArgumentValue(400) == 1 ) then
|
||||
BASE:T(unit_name .. " front door(s) are open")
|
||||
return true
|
||||
end
|
||||
|
||||
if type_name == "AH-64D_BLK_II" then
|
||||
BASE:T(unit_name .. " front door(s) are open")
|
||||
return true -- no doors on this one ;)
|
||||
@ -4127,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)
|
||||
@ -4147,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<Wrapper.Static#STATIC> 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
|
||||
@ -4171,12 +4248,84 @@ 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)
|
||||
local groupData = {
|
||||
["visible"] = true,
|
||||
["hidden"] = false,
|
||||
["units"] = {},
|
||||
["y"] = 0, -- Group center latitude
|
||||
["x"] = 0, -- Group center longitude
|
||||
["name"] = Name,
|
||||
}
|
||||
local unitData = {
|
||||
["category"] = "Heliports",
|
||||
["type"] = STypeName, -- FARP type
|
||||
["y"] = 0, -- Latitude coordinate (meters)
|
||||
["x"] = 0, -- Longitude coordinate (meters)
|
||||
["name"] = Name,
|
||||
["heading"] = 0, -- Heading in radians
|
||||
["heliport_modulation"] = mod, -- 0 = AM, 1 = FM
|
||||
["heliport_frequency"] = freq, -- Radio frequency in MHz
|
||||
["heliport_callsign_id"] = callsign, -- Callsign ID
|
||||
["dead"] = false,
|
||||
["shape_name"] = SShapeName,
|
||||
["dynamicSpawn"] = DynamicSpawns,
|
||||
["allowHotStart"] = HotStart,
|
||||
}
|
||||
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)
|
||||
--]]
|
||||
local UnitTemplate = UTILS.DeepCopy(unitData)
|
||||
UnitTemplate.x = gridpoint.x
|
||||
UnitTemplate.y = gridpoint.y
|
||||
UnitTemplate.name = Name.."-"..id
|
||||
table.insert(groupData.units,UnitTemplate)
|
||||
if id==1 then
|
||||
groupData.x = gridpoint.x
|
||||
groupData.y = gridpoint.y
|
||||
end
|
||||
end
|
||||
--BASE:I("Spawning FARP")
|
||||
--UTILS.PrintTableToLog(groupData,1)
|
||||
local Static=coalition.addGroup(Country, -1, groupData)
|
||||
-- Currently DCS >= 2.8 does not trigger birth events if FARPS are spawned!
|
||||
-- We create such an event. The airbase is registered in Core.Event
|
||||
local Event = {
|
||||
id = EVENTS.Birth,
|
||||
time = timer.getTime(),
|
||||
initiator = Static
|
||||
}
|
||||
-- Create BIRTH event.
|
||||
world.onEvent(Event)
|
||||
|
||||
PopulateStorage(Name.."-1",liquids,equip,airframes)
|
||||
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"},
|
||||
@ -4210,29 +4359,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
|
||||
|
||||
@ -1574,6 +1574,17 @@ end
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Get the true airbase center as seen in the ME. The position returned by the dcs object is is wrong and often at the start of the runway.
|
||||
-- @return DCS#Vec2 The center of the true center of the airbase if it contains runways, otherwise the default DCS object position.
|
||||
function AIRBASE:GetVec2()
|
||||
local runways = self:GetRunways()
|
||||
if runways and #runways > 0 then
|
||||
return runways[1].center:GetVec2()
|
||||
end
|
||||
return self:GetCoordinate():GetVec2()
|
||||
end
|
||||
|
||||
--- Get the category of this airbase. This is only a debug function because DCS 2.9 incorrectly returns heliports as airdromes.
|
||||
-- @param #AIRBASE self
|
||||
function AIRBASE:_GetCategory()
|
||||
|
||||
@ -4163,7 +4163,7 @@ function CONTROLLABLE:OptionRestrictBurner( RestrictBurner )
|
||||
|
||||
end
|
||||
|
||||
--- Sets Controllable Option for A2A attack range for AIR FIGHTER units.
|
||||
--- [AIR] Sets Controllable Option for A2A attack range for AIR FIGHTER units.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param #number range Defines the range
|
||||
-- @return #CONTROLLABLE self
|
||||
@ -4188,6 +4188,66 @@ function CONTROLLABLE:OptionAAAttackRange( range )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- [GROUND/AAA] Sets Controllable Option for Ground AAA minimum firing height.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param #number meters The minimum height in meters.
|
||||
-- @return #CONTROLLABLE self
|
||||
function CONTROLLABLE:OptionAAAMinFiringHeightMeters(meters)
|
||||
self:F2( { self.ControllableName } )
|
||||
local meters = meters or 20
|
||||
local DCSControllable = self:GetDCSObject()
|
||||
if DCSControllable then
|
||||
local Controller = self:_GetController()
|
||||
if Controller then
|
||||
if self:IsGround() then
|
||||
self:SetOption(27, meters)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- [GROUND/AAA] Sets Controllable Option for Ground AAA maximum firing height.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param #number meters The maximum height in meters.
|
||||
-- @return #CONTROLLABLE self
|
||||
function CONTROLLABLE:OptionAAAMaxFiringHeightMeters(meters)
|
||||
self:F2( { self.ControllableName } )
|
||||
local meters = meters or 1000
|
||||
local DCSControllable = self:GetDCSObject()
|
||||
if DCSControllable then
|
||||
local Controller = self:_GetController()
|
||||
if Controller then
|
||||
if self:IsGround() then
|
||||
self:SetOption(29, meters)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- [GROUND/AAA] Sets Controllable Option for Ground AAA minimum firing height.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param #number feet The minimum height in feet.
|
||||
-- @return #CONTROLLABLE self
|
||||
function CONTROLLABLE:OptionAAAMinFiringHeightFeet(feet)
|
||||
self:F2( { self.ControllableName } )
|
||||
local feet = feet or 60
|
||||
return self:OptionAAAMinFiringHeightMeters(UTILS.FeetToMeters(feet))
|
||||
end
|
||||
|
||||
--- [GROUND/AAA] Sets Controllable Option for Ground AAA maximum firing height.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param #number feet The maximum height in feet.
|
||||
-- @return #CONTROLLABLE self
|
||||
function CONTROLLABLE:OptionAAAMaxFiringHeightfeet(feet)
|
||||
self:F2( { self.ControllableName } )
|
||||
local feet = feet or 3000
|
||||
return self:OptionAAAMaxFiringHeightMeters(UTILS.FeetToMeters(feet))
|
||||
end
|
||||
|
||||
--- Defines the range at which a GROUND unit/group is allowed to use its weapons automatically.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param #number EngageRange Engage range limit in percent (a number between 0 and 100). Default 100.
|
||||
|
||||
@ -108,6 +108,8 @@ DYNAMICCARGO.State = {
|
||||
-- @type DYNAMICCARGO.AircraftTypes
|
||||
DYNAMICCARGO.AircraftTypes = {
|
||||
["CH-47Fbl1"] = "CH-47Fbl1",
|
||||
["Mi-8MTV2"] = "CH-47Fbl1",
|
||||
["Mi-8MT"] = "CH-47Fbl1",
|
||||
}
|
||||
|
||||
--- Helo types possible.
|
||||
@ -120,17 +122,30 @@ DYNAMICCARGO.AircraftDimensions = {
|
||||
["length"] = 11,
|
||||
["ropelength"] = 30,
|
||||
},
|
||||
["Mi-8MTV2"] = {
|
||||
["width"] = 6,
|
||||
["height"] = 6,
|
||||
["length"] = 15,
|
||||
["ropelength"] = 30,
|
||||
},
|
||||
["Mi-8MT"] = {
|
||||
["width"] = 6,
|
||||
["height"] = 6,
|
||||
["length"] = 15,
|
||||
["ropelength"] = 30,
|
||||
},
|
||||
}
|
||||
|
||||
--- DYNAMICCARGO class version.
|
||||
-- @field #string version
|
||||
DYNAMICCARGO.version="0.0.7"
|
||||
DYNAMICCARGO.version="0.0.9"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: A lot...
|
||||
-- DONE: Added Mi-8 type and dimensions
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user