Merge branch 'develop' into FF/Ops

This commit is contained in:
Frank
2025-09-28 20:48:52 +02:00
20 changed files with 485 additions and 117 deletions

View File

@@ -39,6 +39,8 @@
-- * [USS America](https://en.wikipedia.org/wiki/USS_America_\(LHA-6\)) (LHA-6)
-- * [Juan Carlos I](https://en.wikipedia.org/wiki/Spanish_amphibious_assault_ship_Juan_Carlos_I) (L61)
-- * [HMAS Canberra](https://en.wikipedia.org/wiki/HMAS_Canberra_\(L02\)) (L02)
-- * BONHOMMERICHARD [VWV Mod]
-- * ENTERPRISE66 [VWV Mod]
--
-- **Supported Aircraft:**
--
@@ -1317,6 +1319,10 @@ AIRBOSS.AircraftCarrier={
-- @field #string FORRESTAL USS Forrestal (CV-59) [Heatblur Carrier Module]
-- @field #string VINSON USS Carl Vinson (CVN-70) [Deprecated!]
-- @field #string ESSEX Essex class carrier (e.g. USS Yorktown (CV-10)) [Magnitude 3 Carrier Module]
-- @field #string BONHOMMERICHARD USS Bon Homme Richard carrier [VWV Mod]
-- @field #string ESSEXSCB125 Generic Essex class carrier with angled deck (SCB-125 upgrade) [VWV Mod]
-- @field #string ENTERPRISE66 USS Enterprise in the 1966 configuration [VWV Mod]
-- @field #string ENTERPRISEMODERN USS Enterprise in a modern configuration [Derived VWV Mod]
-- @field #string HERMES HMS Hermes (R12) [V/STOL Carrier]
-- @field #string INVINCIBLE HMS Invincible (R05) [V/STOL Carrier]
-- @field #string TARAWA USS Tarawa (LHA-1) [V/STOL Carrier]
@@ -1331,8 +1337,12 @@ AIRBOSS.CarrierType = {
TRUMAN = "CVN_75",
STENNIS = "Stennis",
FORRESTAL = "Forrestal",
ENTERPRISE66 = "USS Enterprise 1966",
ENTERPRISEMODERN = "cvn-65",
VINSON = "VINSON",
ESSEX = "Essex",
BONHOMMERICHARD = "USS Bon Homme Richard",
ESSEXSCB125 = "essex_scb125",
HERMES = "HERMES81",
INVINCIBLE = "hms_invincible",
TARAWA = "LHA_Tarawa",
@@ -1756,7 +1766,7 @@ AIRBOSS.MenuF10Root = nil
--- Airboss class version.
-- @field #string version
AIRBOSS.version = "1.4.1"
AIRBOSS.version = "1.4.2"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -2019,11 +2029,19 @@ function AIRBOSS:New( carriername, alias )
self:_InitNimitz()
elseif self.carriertype == AIRBOSS.CarrierType.FORRESTAL then
self:_InitForrestal()
elseif self.carriertype == AIRBOSS.CarrierType.ENTERPRISE66 then
self:_InitEnterprise()
elseif self.carriertype == AIRBOSS.CarrierType.ENTERPRISEMODERN then
self:_InitEnterprise()
elseif self.carriertype == AIRBOSS.CarrierType.VINSON then
-- Carl Vinson is legacy now.
self:_InitStennis()
elseif self.carriertype == AIRBOSS.CarrierType.ESSEX then
self:_InitEssex()
elseif self.carriertype == AIRBOSS.CarrierType.BONHOMMERICHARD then
self:_InitBonHommeRichard()
elseif self.carriertype == AIRBOSS.CarrierType.ESSEXSCB125 then
self:_InitEssexSCB125()
elseif self.carriertype == AIRBOSS.CarrierType.HERMES then
-- Hermes parameters.
self:_InitHermes()
@@ -3110,8 +3128,8 @@ function AIRBOSS:EnableSRS(PathToSRS,Port,Culture,Gender,Voice,GoogleCreds,Volum
self.SRS:SetCulture(Culture or "en-US")
--self.SRS:SetFrequencies(Frequencies)
self.SRS:SetGender(Gender or "male")
self.SRS:SetPath(PathToSRS)
self.SRS:SetPort(Port or 5002)
--self.SRS:SetPath(PathToSRS)
self.SRS:SetPort(Port or MSRS.port or 5002)
self.SRS:SetLabel(self.AirbossRadio.alias or "AIRBOSS")
self.SRS:SetCoordinate(self.carrier:GetCoordinate())
self.SRS:SetVolume(Volume or 1)
@@ -3122,7 +3140,10 @@ function AIRBOSS:EnableSRS(PathToSRS,Port,Culture,Gender,Voice,GoogleCreds,Volum
if Voice then
self.SRS:SetVoice(Voice)
end
self.SRS:SetVolume(Volume or 1.0)
if (not Voice) and self.SRS and self.SRS:GetProvider() == MSRS.Provider.GOOGLE then
self.SRS.voice = MSRS.poptions["gcloud"].voice or MSRS.Voices.Google.Standard.en_US_Standard_B
end
--self.SRS:SetVolume(Volume or 1.0)
-- SRSQUEUE
self.SRSQ = MSRSQUEUE:New("AIRBOSS")
self.SRSQ:SetTransmitOnlyWithPlayers(true)
@@ -4653,6 +4674,26 @@ function AIRBOSS:_InitForrestal()
end
--- Init parameters for Enterprise carrier.
-- @param #AIRBOSS self
function AIRBOSS:_InitEnterprise()
-- Using Forrestal as template
self:_InitForrestal()
self.carrierparam.sterndist = -164.30
self.carrierparam.deckheight = 19.52
self.carrierparam.totlength = 335
self.carrierparam.rwylength = 223
-- Wires.
self.carrierparam.wire1 = 57.7
self.carrierparam.wire2 = 69.6
self.carrierparam.wire3 = 79.5
self.carrierparam.wire4 = 90.0
end
--- Init parameters for Essec class carriers.
-- @param #AIRBOSS self
function AIRBOSS:_InitEssex()
@@ -4698,6 +4739,35 @@ function AIRBOSS:_InitEssex()
end
--- Init parameters for CVA-31 Bon Homme Richard carriers.
-- @param #AIRBOSS self
function AIRBOSS:_InitBonHommeRichard()
-- Init Essex as default
self:_InitEssex()
self.carrierparam.deckheight = 16.95
-- Landing runway.
-- from BHR EssexRunwayAndRoutes.lua
self.carrierparam.rwyangle = -11.4
self.carrierparam.rwylength = 97
self.carrierparam.rwywidth = 20
-- Wires.
self.carrierparam.wire1 = 40.4 -- Distance from stern to first wire. Original from Frank - 42
self.carrierparam.wire2 = 45
self.carrierparam.wire3 = 51
self.carrierparam.wire4 = 58.1
end
--- Init parameters for Generic Essex SC125 class carriers.
-- @param #AIRBOSS self
function AIRBOSS:_InitEssexSCB125()
-- Init Bon Homme Richard as default
self:_InitBonHommeRichard()
end
--- Init parameters for R12 HMS Hermes carrier.
-- @param #AIRBOSS self
function AIRBOSS:_InitHermes()

View File

@@ -1321,13 +1321,19 @@ end
-- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`.
-- @param #number Speed Orbit indicated airspeed in knots at the set altitude ASL. Default 350 KIAS.
-- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West).
-- @param #number Leg Length of race-track in NM. Default 10 NM.
-- @param #number Leg Length of race-track in NM. Default 10 NM. Set to 0 for a simple circular orbit.
-- @param #number RefuelSystem Refueling system (0=boom, 1=probe). This info is *only* for AIRWINGs so they launch the right tanker type.
-- @return #AUFTRAG self
function AUFTRAG:NewTANKER(Coordinate, Altitude, Speed, Heading, Leg, RefuelSystem)
local mission
if Leg == 0 then
mission=AUFTRAG:NewORBIT_CIRCLE(Coordinate,Altitude,Speed)
else
mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate,Altitude,Speed,Heading,Leg)
end
-- Create ORBIT first.
local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg)
--local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg)
-- Mission type TANKER.
mission.type=AUFTRAG.Type.TANKER

View File

@@ -2021,7 +2021,9 @@ function AWACS:SetAdditionalZone(Zone, Draw)
self.BorderZone = Zone
if self.debug then
Zone:DrawZone(self.coalition,{1,0.64,0},1,{1,0.64,0},0.2,1,true)
MARKER:New(Zone:GetCoordinate(),"Defensive Zone"):ToCoalition(self.coalition)
if self.AllowMarkers then
MARKER:New(Zone:GetCoordinate(),"Defensive Zone"):ToCoalition(self.coalition)
end
elseif Draw then
Zone:DrawZone(self.coalition,{1,0.64,0},1,{1,0.64,0},0.2,1,true)
end
@@ -2041,7 +2043,9 @@ function AWACS:SetRejectionZone(Zone,Draw)
--MARKER:New(Zone:GetCoordinate(),"Rejection Zone"):ToAll()
elseif self.debug then
Zone:DrawZone(self.coalition,{1,0.64,0},1,{1,0.64,0},0.2,1,true)
MARKER:New(Zone:GetCoordinate(),"Rejection Zone"):ToCoalition(self.coalition)
if self.AllowMarkers then
MARKER:New(Zone:GetCoordinate(),"Rejection Zone"):ToCoalition(self.coalition)
end
end
return self
end
@@ -4094,10 +4098,14 @@ function AWACS:_CreateAnchorStackFromMarker(Name,Coord)
if self.debug then
AnchorStackOne.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true)
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
else
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
end
self.AnchorStacks:Push(AnchorStackOne,newname)
@@ -4140,10 +4148,14 @@ function AWACS:_CreateAnchorStack()
--self.AnchorStacks:Flush()
AnchorStackOne.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true)
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
else
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
end
self.AnchorStacks:Push(AnchorStackOne,newname)
else
@@ -4167,10 +4179,14 @@ function AWACS:_CreateAnchorStack()
if self.debug then
AnchorStackOne.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true)
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
else
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
end
self.AnchorStacks:Push(AnchorStackOne,newname)
end
@@ -5102,10 +5118,14 @@ function AWACS:AddCAPAirWing(AirWing,Zone)
if self.debug then
AnchorStackOne.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true)
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
else
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
end
self.AnchorStacks:Push(AnchorStackOne,newname)
AirWing.HasOwnStation = true
@@ -5948,23 +5968,35 @@ function AWACS:onafterStart(From, Event, To)
self.OpsZone:DrawZone(self.coalition,{1,0,0},1,{1,0,0},0.2,5,true)
local AOCoordString = self.AOCoordinate:ToStringLLDDM()
local Rocktag = string.format("FEZ: %s\nBulls Coordinate: %s",self.AOName,AOCoordString)
MARKER:New(self.AOCoordinate,Rocktag):ToCoalition(self.coalition)
if self.AllowMarkers then
MARKER:New(self.AOCoordinate,Rocktag):ToCoalition(self.coalition)
end
self.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true)
local stationtag = string.format("Station: %s\nCoordinate: %s",self.StationZoneName,self.StationZone:GetCoordinate():ToStringLLDDM())
if not self.GCI then
MARKER:New(self.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
if self.AllowMarkers then
MARKER:New(self.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
self.OrbitZone:DrawZone(self.coalition,{0,1,0},1,{0,1,0},0.2,5,true)
MARKER:New(self.OrbitZone:GetCoordinate(),"AIC Orbit Zone"):ToCoalition(self.coalition)
if self.AllowMarkers then
MARKER:New(self.OrbitZone:GetCoordinate(),"AIC Orbit Zone"):ToCoalition(self.coalition)
end
end
else
local AOCoordString = self.AOCoordinate:ToStringLLDDM()
local Rocktag = string.format("FEZ: %s\nBulls Coordinate: %s",self.AOName,AOCoordString)
MARKER:New(self.AOCoordinate,Rocktag):ToCoalition(self.coalition)
if self.AllowMarkers then
MARKER:New(self.AOCoordinate,Rocktag):ToCoalition(self.coalition)
end
if not self.GCI then
MARKER:New(self.OrbitZone:GetCoordinate(),"AIC Orbit Zone"):ToCoalition(self.coalition)
if self.AllowMarkers then
MARKER:New(self.OrbitZone:GetCoordinate(),"AIC Orbit Zone"):ToCoalition(self.coalition)
end
end
local stationtag = string.format("Station: %s\nCoordinate: %s",self.StationZoneName,self.StationZone:GetCoordinate():ToStringLLDDM())
MARKER:New(self.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
if self.AllowMarkers then
MARKER:New(self.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
end
if not self.GCI then

View File

@@ -305,6 +305,7 @@ CSAR.AircraftType["Mi-24P"] = 8
CSAR.AircraftType["Mi-24V"] = 8
CSAR.AircraftType["Bell-47"] = 2
CSAR.AircraftType["UH-60L"] = 10
CSAR.AircraftType["UH-60L_DAP"] = 2
CSAR.AircraftType["AH-64D_BLK_II"] = 2
CSAR.AircraftType["Bronco-OV-10A"] = 2
CSAR.AircraftType["MH-60R"] = 10

View File

@@ -1396,6 +1396,7 @@ CTLD.UnitTypeCapabilities = {
["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64, length = 25, cargoweightlimit = 19000}, -- 19t cargo, 64 paratroopers.
--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_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
["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
["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
@@ -1417,7 +1418,7 @@ CTLD.FixedWingTypes = {
--- CTLD class version.
-- @field #string version
CTLD.version="1.3.37"
CTLD.version="1.3.38"
--- Instantiate a new CTLD.
-- @param #CTLD self
@@ -3328,6 +3329,7 @@ function CTLD:_LoadCratesNearby(Group, Unit)
self:_RefreshLoadCratesMenu(Group, Unit)
-- clean up real world crates
self:_CleanupTrackedCrates(crateidsloaded)
self:__CratesPickedUp(1, Group, Unit, loaded.Cargo)
end
end
return self
@@ -6930,6 +6932,7 @@ end
local alias = string.format("%s-%d", _template, math.random(1,100000))
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
:InitRandomizeUnits(randompositions,20,2)
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits)
:InitDelayOff()
:OnSpawnGroup(function(grp,TimeStamp) grp.spawntime = TimeStamp or timer.getTime() end,TimeStamp)
:SpawnFromVec2(randomcoord)
@@ -7083,12 +7086,14 @@ end
if canmove then
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
:InitRandomizeUnits(true,20,2)
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits)
:InitDelayOff()
:OnSpawnGroup(function(grp,TimeStamp) grp.spawntime = TimeStamp or timer.getTime() end,TimeStamp)
:SpawnFromVec2(randomcoord)
else -- don't random position of e.g. SAM units build as FOB
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
:InitDelayOff()
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits)
:OnSpawnGroup(function(grp,TimeStamp) grp.spawntime = TimeStamp or timer.getTime() end,TimeStamp)
:SpawnFromVec2(randomcoord)
end

View File

@@ -88,7 +88,7 @@ COHORT = {
--- COHORT class version.
-- @field #string version
COHORT.version="0.3.6"
COHORT.version="0.3.7"
--- Global variable to store the unique(!) cohort names
_COHORTNAMES={}
@@ -100,6 +100,7 @@ _COHORTNAMES={}
-- DONE: Create FLOTILLA class.
-- DONE: Added check for properties.
-- DONE: Make general so that PLATOON and SQUADRON can inherit this class.
-- DONE: Better setting of call signs.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
@@ -515,10 +516,12 @@ end
-- @param #COHORT self
-- @param #number Callsign Callsign from CALLSIGN.Aircraft, e.g. "Chevy" for CALLSIGN.Aircraft.CHEVY.
-- @param #number Index Callsign index, Chevy-**1**.
-- @param #string CallsignString (optional) Set this for tasks like TANKER, AWACS or KIOWA and the like, which have special names. E.g. "Darkstar" or "Roughneck".
-- @return #COHORT self
function COHORT:SetCallsign(Callsign, Index)
function COHORT:SetCallsign(Callsign, Index, CallsignString)
self.callsignName=Callsign
self.callsignIndex=Index
self.callsignClearName=CallsignString
self.callsign={}
self.callsign.NumberSquad=Callsign
self.callsign.NumberGroup=Index
@@ -679,7 +682,16 @@ end
function COHORT:GetCallsign(Asset)
if self.callsignName then
--[[
["callsign"] =
{
[2] = 1,
["name"] = "Darkstar11",
[3] = 1,
[1] = 5,
[4] = "Darkstar11",
}, -- end of ["callsign"]
]]
Asset.callsign={}
for i=1,Asset.nunits do
@@ -695,12 +707,16 @@ function COHORT:GetCallsign(Asset)
else
self.callsigncounter=self.callsigncounter+1
end
callsign["name"] = self.callsignClearName or UTILS.GetCallsignName(self.callsignName) or "None"
callsign["name"] = string.format("%s%d%d",callsign["name"],callsign[2],callsign[3])
callsign[4] = callsign["name"]
Asset.callsign[i]=callsign
self:T3({callsign=callsign})
--TODO: there is also a table entry .name, which is a string.
--DONE: there is also a table entry .name, which is a string.
--UTILS.PrintTableToLog(callsign)
end

View File

@@ -79,6 +79,7 @@
-- @field #number FuelLowThreshold
-- @field #number FuelCriticalThreshold
-- @field #boolean showpatrolpointmarks
-- @field #table EngageTargetTypes
-- @extends Core.Fsm#FSM
--- *“Airspeed, altitude, and brains. Two are always needed to successfully complete the flight.”* -- Unknown.
@@ -237,6 +238,7 @@ EASYGCICAP = {
FuelLowThreshold = 25,
FuelCriticalThreshold = 10,
showpatrolpointmarks = false,
EngageTargetTypes = {"Air"},
}
--- Internal Squadron data type
@@ -273,7 +275,7 @@ EASYGCICAP = {
--- EASYGCICAP class version.
-- @field #string version
EASYGCICAP.version="0.1.27"
EASYGCICAP.version="0.1.30"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@@ -330,6 +332,7 @@ function EASYGCICAP:New(Alias, AirbaseName, Coalition, EWRName)
self.FuelLowThreshold = 25
self.FuelCriticalThreshold = 10
self.showpatrolpointmarks = false
self.EngageTargetTypes = {"Air"}
-- Set some string id for output to DCS.log file.
self.lid=string.format("EASYGCICAP %s | ", self.alias)
@@ -608,6 +611,17 @@ function EASYGCICAP:SetCapStartTimeVariation(Start, End)
return self
end
--- Set which target types CAP flights will prefer to engage, defaults to {"Air"}
-- @param #EASYGCICAP self
-- @param #table types Table of comma separated #string entries, defaults to {"Air"} (everything that flies and is not a weapon). Useful other options are e.g. {"Bombers"}, {"Fighters"},
-- or {"Helicopters"} or combinations like {"Bombers", "Fighters", "UAVs"}. See [Hoggit Wiki](https://wiki.hoggitworld.com/view/DCS_enum_attributes).
-- @return #EASYGCICAP self
function EASYGCICAP:SetCAPEngageTargetTypes(types)
self.EngageTargetTypes = types or {"Air"}
return self
end
--- Add an AirWing to the manager
-- @param #EASYGCICAP self
-- @param #string Airbasename
@@ -706,6 +720,7 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
local NoGoZoneSet = self.NoGoZoneSet
local FuelLow = self.FuelLowThreshold or 25
local FuelCritical = self.FuelCriticalThreshold or 10
local EngageTypes = self.EngageTargetTypes or {"Air"}
function CAP_Wing:onbeforeFlightOnMission(From, Event, To, Flightgroup, Mission)
local flightgroup = Flightgroup -- Ops.FlightGroup#FLIGHTGROUP
@@ -720,7 +735,7 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
flightgroup:GetGroup():SetOptionLandingOverheadBreak()
if Mission.type ~= AUFTRAG.Type.TANKER and Mission.type ~= AUFTRAG.Type.AWACS and Mission.type ~= AUFTRAG.Type.RECON then
flightgroup:SetDetection(true)
flightgroup:SetEngageDetectedOn(engagerange,{"Air"},GoZoneSet,NoGoZoneSet)
flightgroup:SetEngageDetectedOn(engagerange,EngageTypes,GoZoneSet,NoGoZoneSet)
flightgroup:SetOutOfAAMRTB()
flightgroup:SetFuelLowRTB(true)
flightgroup:SetFuelLowThreshold(FuelLow)
@@ -1209,7 +1224,9 @@ function EASYGCICAP:_AddTankerSquadron(TemplateName, SquadName, AirbaseName, Air
Squadron_One:SetSkill(Skill or AI.Skill.AVERAGE)
Squadron_One:SetMissionRange(self.missionrange)
Squadron_One:SetRadio(Frequency,Modulation)
Squadron_One:AddTacanChannel(TACAN,TACAN)
if TACAN then
Squadron_One:AddTacanChannel(TACAN,TACAN)
end
local wing = self.wings[AirbaseName][1] -- Ops.Airwing#AIRWING

View File

@@ -1823,6 +1823,7 @@ function LEGION:_CreateFlightGroup(asset)
---
opsgroup=ARMYGROUP:New(asset.spawngroupname)
opsgroup:SetValidateAndRepositionGroundUnits(self.ValidateAndRepositionGroundUnits)
elseif self:IsFleet() then

View File

@@ -7847,8 +7847,13 @@ function OPSGROUP:_Spawn(Delay, Template)
-- Debug output.
self:T2({Template=Template})
if self:IsArmygroup() and self.ValidateAndRepositionGroundUnits then
UTILS.ValidateAndRepositionGroundUnits(Template.units)
end
-- Spawn new group.
self.group=_DATABASE:Spawn(Template)
self.group:SetValidateAndRepositionGroundUnits(self.ValidateAndRepositionGroundUnits)
--local countryID=self.group:GetCountry()
--local categoryID=self.group:GetCategory()
--local dcsgroup=coalition.addGroup(countryID, categoryID, Template)
@@ -13955,6 +13960,15 @@ function OPSGROUP:_GetDetectedTarget()
return targetgroup, targetdist
end
--- This function uses Disposition and other fallback logic to find better ground positions for ground units.
--- NOTE: This is not a spawn randomizer.
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
--- Uses UTILS.ValidateAndRepositionGroundUnits.
-- @param #boolean Enabled Enable/disable the feature.
function OPSGROUP:SetValidateAndRepositionGroundUnits(Enabled)
self.ValidateAndRepositionGroundUnits = Enabled
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@@ -98,7 +98,7 @@ PLAYERTASK = {
--- PLAYERTASK class version.
-- @field #string version
PLAYERTASK.version="0.1.27"
PLAYERTASK.version="0.1.28"
--- Generic task condition.
-- @type PLAYERTASK.Condition
@@ -387,6 +387,14 @@ function PLAYERTASK:_CheckCaptureOpsZoneSuccess(OpsZone, CaptureSquadGroupNamePr
return OpsZone:GetOwner() == Coalition and isClientInZone and isCaptureGroupInZone
end
--- [User] Override this function in order to implement custom logic if a player can join a task or not.
-- @param #PLAYERTASK self
-- @param Wrapper.Group#GROUP Group
-- @param Wrapper.Client#CLIENT Client
-- @return #boolean Outcome True if player can join the task, false if not
function PLAYERTASK:CanJoinTask(Group, Client)
return true
end
--- [Internal] Add a PLAYERTASKCONTROLLER for this task
-- @param #PLAYERTASK self
@@ -1227,7 +1235,10 @@ function PLAYERTASK:onafterFailed(From, Event, To)
self.TargetMarker:Remove()
end
self.FinalState = "Failed"
self:__Done(-1)
if self.TaskController then
self.TaskController:__TaskFailed(-1,self)
end
self:__Done(-1.5)
end
if self.TaskController.Scoring then
local clients,count = self:GetClientObjects()
@@ -3530,6 +3541,16 @@ function PLAYERTASKCONTROLLER:AddPlayerTaskToQueue(PlayerTask,Silent,TaskFilter)
return self
end
--- [User] Override this function in order to implement custom logic if a player can join a task or not.
-- @param #PLAYERTASKCONTROLLER self
-- @param Ops.PlayerTask#PLAYERTASK Task
-- @param Wrapper.Group#GROUP Group
-- @param Wrapper.Client#CLIENT Client
-- @return #boolean Outcome True if player can join the task, false if not
function PLAYERTASKCONTROLLER:CanJoinTask(Task, Group, Client)
return true
end
--- [Internal] Join a player to a task
-- @param #PLAYERTASKCONTROLLER self
-- @param Ops.PlayerTask#PLAYERTASK Task
@@ -3540,6 +3561,15 @@ end
function PLAYERTASKCONTROLLER:_JoinTask(Task, Force, Group, Client)
self:T({Force, Group, Client})
self:T(self.lid.."_JoinTask")
if not self:CanJoinTask(Task, Group, Client) then
return self
end
if not Task:CanJoinTask(Group, Client) then
return self
end
local force = false
if type(Force) == "boolean" then
force = Force