mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'develop' into FF/Ops
This commit is contained in:
@@ -46,7 +46,7 @@
|
||||
--
|
||||
-- ### Author: **funkyfranky**
|
||||
--
|
||||
-- @module Ops.Atis
|
||||
-- @module Ops.ATIS
|
||||
-- @image OPS_ATIS.png
|
||||
|
||||
--- ATIS class.
|
||||
@@ -122,7 +122,7 @@
|
||||
-- The @{#ATIS.New}(*airbasename*, *frequency*) creates a new ATIS object. The parameter *airbasename* is the name of the airbase or airport. Note that this has to be spelled exactly as in the DCS mission editor.
|
||||
-- The parameter *frequency* is the frequency the ATIS broadcasts in MHz.
|
||||
--
|
||||
-- Broadcasting is started via the @{#ATIS.Start}() function. The start can be delayed by useing @{#ATIS.__Start}(*delay*), where *delay* is the delay in seconds.
|
||||
-- Broadcasting is started via the @{#ATIS.Start}() function. The start can be delayed by using @{#ATIS.__Start}(*delay*), where *delay* is the delay in seconds.
|
||||
--
|
||||
-- ## Subtitles
|
||||
--
|
||||
@@ -1047,7 +1047,7 @@ end
|
||||
-- Or you make your life simple and just include the sign so you don't have to bother about East/West.
|
||||
--
|
||||
-- @param #ATIS self
|
||||
-- @param #number magvar Magnetic variation in degrees. Positive for easterly and negative for westerly variation. Default is magnatic declinaton of the used map, c.f. @{Utilities.UTils#UTILS.GetMagneticDeclination}.
|
||||
-- @param #number magvar Magnetic variation in degrees. Positive for easterly and negative for westerly variation. Default is magnatic declinaton of the used map, c.f. @{Utilities.Utils#UTILS.GetMagneticDeclination}.
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetMagneticDeclination( magvar )
|
||||
self.magvar = magvar or UTILS.GetMagneticDeclination()
|
||||
@@ -1258,16 +1258,16 @@ function ATIS:onafterStart( From, Event, To )
|
||||
-- Start radio queue.
|
||||
if not self.useSRS then
|
||||
self.radioqueue = RADIOQUEUE:New( self.frequency, self.modulation, string.format( "ATIS %s", self.airbasename ) )
|
||||
|
||||
|
||||
-- Send coordinate is airbase coord.
|
||||
self.radioqueue:SetSenderCoordinate( self.airbase:GetCoordinate() )
|
||||
|
||||
|
||||
-- Set relay unit if we have one.
|
||||
self.radioqueue:SetSenderUnitName( self.relayunitname )
|
||||
|
||||
|
||||
-- Set radio power.
|
||||
self.radioqueue:SetRadioPower( self.power )
|
||||
|
||||
|
||||
-- Init numbers.
|
||||
self.radioqueue:SetDigit( 0, ATIS.Sound.N0.filename, ATIS.Sound.N0.duration, self.soundpath )
|
||||
self.radioqueue:SetDigit( 1, ATIS.Sound.N1.filename, ATIS.Sound.N1.duration, self.soundpath )
|
||||
@@ -1279,11 +1279,11 @@ function ATIS:onafterStart( From, Event, To )
|
||||
self.radioqueue:SetDigit( 7, ATIS.Sound.N7.filename, ATIS.Sound.N7.duration, self.soundpath )
|
||||
self.radioqueue:SetDigit( 8, ATIS.Sound.N8.filename, ATIS.Sound.N8.duration, self.soundpath )
|
||||
self.radioqueue:SetDigit( 9, ATIS.Sound.N9.filename, ATIS.Sound.N9.duration, self.soundpath )
|
||||
|
||||
|
||||
-- Start radio queue.
|
||||
self.radioqueue:Start( 1, 0.1 )
|
||||
end
|
||||
|
||||
|
||||
-- Handle airbase capture
|
||||
-- Handle events.
|
||||
self:HandleEvent( EVENTS.BaseCaptured )
|
||||
@@ -1397,10 +1397,10 @@ function ATIS:onafterBroadcast( From, Event, To )
|
||||
qnh = Q / 100
|
||||
|
||||
end
|
||||
|
||||
|
||||
local mBarqnh = qnh
|
||||
local mBarqfe = qfe
|
||||
|
||||
|
||||
-- Convert to inHg.
|
||||
if self.PmmHg then
|
||||
qfe = UTILS.hPa2mmHg( qfe )
|
||||
|
||||
@@ -27,17 +27,17 @@
|
||||
-- **Supported Carriers:**
|
||||
--
|
||||
-- * [USS John C. Stennis](https://en.wikipedia.org/wiki/USS_John_C._Stennis) (CVN-74)
|
||||
-- * [USS Theodore Roosevelt](https://en.wikipedia.org/wiki/USS_Theodore_Roosevelt_(CVN-71)) (CVN-71) [Super Carrier Module]
|
||||
-- * [USS Abraham Lincoln](https://en.wikipedia.org/wiki/USS_Abraham_Lincoln_(CVN-72)) (CVN-72) [Super Carrier Module]
|
||||
-- * [USS George Washington](https://en.wikipedia.org/wiki/USS_George_Washington_(CVN-73)) (CVN-73) [Super Carrier Module]
|
||||
-- * [USS Theodore Roosevelt](https://en.wikipedia.org/wiki/USS_Theodore_Roosevelt_(CVN-71\)) (CVN-71) [Super Carrier Module]
|
||||
-- * [USS Abraham Lincoln](https://en.wikipedia.org/wiki/USS_Abraham_Lincoln_(CVN-72\)) (CVN-72) [Super Carrier Module]
|
||||
-- * [USS George Washington](https://en.wikipedia.org/wiki/USS_George_Washington_(CVN-73\)) (CVN-73) [Super Carrier Module]
|
||||
-- * [USS Harry S. Truman](https://en.wikipedia.org/wiki/USS_Harry_S._Truman) (CVN-75) [Super Carrier Module]
|
||||
-- * [USS Forrestal](https://en.wikipedia.org/wiki/USS_Forrestal_(CV-59)) (CV-59) [Heatblur Carrier Module]
|
||||
-- * [HMS Hermes](https://en.wikipedia.org/wiki/HMS_Hermes_(R12)) (R12) [**WIP**]
|
||||
-- * [HMS Invincible](https://en.wikipedia.org/wiki/HMS_Invincible_(R05) (R05) [**WIP**]
|
||||
-- * [USS Tarawa](https://en.wikipedia.org/wiki/USS_Tarawa_(LHA-1)) (LHA-1) [**WIP**]
|
||||
-- * [USS America](https://en.wikipedia.org/wiki/USS_America_(LHA-6)) (LHA-6) [**WIP**]
|
||||
-- * [USS Forrestal](https://en.wikipedia.org/wiki/USS_Forrestal_(CV-59\)) (CV-59) [Heatblur Carrier Module]
|
||||
-- * [HMS Hermes](https://en.wikipedia.org/wiki/HMS_Hermes_(R12\)) (R12) [**WIP**]
|
||||
-- * [HMS Invincible](https://en.wikipedia.org/wiki/HMS_Invincible_(R05\)) (R05) [**WIP**]
|
||||
-- * [USS Tarawa](https://en.wikipedia.org/wiki/USS_Tarawa_(LHA-1\)) (LHA-1) [**WIP**]
|
||||
-- * [USS America](https://en.wikipedia.org/wiki/USS_America_(LHA-6\)) (LHA-6) [**WIP**]
|
||||
-- * [Juan Carlos I](https://en.wikipedia.org/wiki/Spanish_amphibious_assault_ship_Juan_Carlos_I) (L61) [**WIP**]
|
||||
-- * [HMAS Canberra](https://en.wikipedia.org/wiki/HMAS_Canberra_(L02)) (L02) [**WIP**]
|
||||
-- * [HMAS Canberra](https://en.wikipedia.org/wiki/HMAS_Canberra_(L02\)) (L02) [**WIP**]
|
||||
--
|
||||
-- **Supported Aircraft:**
|
||||
--
|
||||
@@ -143,7 +143,7 @@
|
||||
-- @field Wrapper.Airbase#AIRBASE airbase Carrier airbase object.
|
||||
-- @field #table waypoints Waypoint coordinates of carrier.
|
||||
-- @field #number currentwp Current waypoint, i.e. the one that has been passed last.
|
||||
-- @field Core.Radio#BEACON beacon Carrier beacon for TACAN and ICLS.
|
||||
-- @field Core.Beacon#BEACON beacon Carrier beacon for TACAN and ICLS.
|
||||
-- @field #boolean TACANon Automatic TACAN is activated.
|
||||
-- @field #number TACANchannel TACAN channel.
|
||||
-- @field #string TACANmode TACAN mode, i.e. "X" or "Y".
|
||||
@@ -297,7 +297,7 @@
|
||||
--
|
||||
-- The flight that transitions form the holding pattern to the landing approach, it should leave the Marshal stack at the 3 position and make a left hand turn to the *Initial*
|
||||
-- position, which is 3 NM astern of the boat. Note that you need to be below 1300 feet to be registered in the initial zone.
|
||||
-- The altitude can be set via the function @{AIRBOSS.SetInitialMaxAlt}(*altitude*) function.
|
||||
-- The altitude can be set via the function @{#AIRBOSS.SetInitialMaxAlt}(*altitude*) function.
|
||||
-- As described below, the initial zone can be smoked or flared via the AIRBOSS F10 Help radio menu.
|
||||
--
|
||||
-- ### Landing Pattern
|
||||
@@ -762,7 +762,7 @@
|
||||
--
|
||||
-- ## Save Results
|
||||
--
|
||||
-- Saving asset data to file is achieved by the @{AIRBOSS.Save}(*path*, *filename*) function.
|
||||
-- Saving asset data to file is achieved by the @{#AIRBOSS.Save}(*path*, *filename*) function.
|
||||
--
|
||||
-- The parameter *path* specifies the path on the file system where the
|
||||
-- player grades are saved. If you do not specify a path, the file is saved your the DCS installation root directory if the **lfs** module is *not* desanizied or
|
||||
@@ -783,7 +783,7 @@
|
||||
--
|
||||
-- ### Automatic Saving
|
||||
--
|
||||
-- The player grades can be saved automatically after each graded player pass via the @{AIRBOSS.SetAutoSave}(*path*, *filename*) function. Again the parameters *path* and *filename* are optional.
|
||||
-- The player grades can be saved automatically after each graded player pass via the @{#AIRBOSS.SetAutoSave}(*path*, *filename*) function. Again the parameters *path* and *filename* are optional.
|
||||
-- In the simplest case, you desanitize the **lfs** module and just add
|
||||
--
|
||||
-- airbossStennis:SetAutoSave()
|
||||
@@ -821,7 +821,7 @@
|
||||
--
|
||||
-- ## Load Results
|
||||
--
|
||||
-- Loading player grades from file is achieved by the @{AIRBOSS.Load}(*path*, *filename*) function. The parameter *path* specifies the path on the file system where the
|
||||
-- Loading player grades from file is achieved by the @{#AIRBOSS.Load}(*path*, *filename*) function. The parameter *path* specifies the path on the file system where the
|
||||
-- data is loaded from. If you do not specify a path, the file is loaded from your the DCS installation root directory or, if **lfs** was desanitized from you "Saved Games\DCS" directory.
|
||||
-- The parameter *filename* is optional and defines the name of the file to load. By default this is automatically generated from the AIBOSS carrier name/alias, for example
|
||||
-- "Airboss-USS Stennis_LSOgrades.csv".
|
||||
@@ -1041,7 +1041,7 @@
|
||||
--
|
||||
-- AI groups that enter the CCA are usually guided to Marshal stack. However, due to DCS limitations they might not obey the landing task if they have another airfield as departure and/or destination in
|
||||
-- their mission task. Therefore, AI groups can be respawned when detected in the CCA. This should clear all other airfields and allow the aircraft to land on the carrier.
|
||||
-- This is achieved by the @{AIRBOSS.SetRespawnAI}() function.
|
||||
-- This is achieved by the @{#AIRBOSS.SetRespawnAI}() function.
|
||||
--
|
||||
-- ## Known Issues
|
||||
--
|
||||
@@ -10203,7 +10203,7 @@ function AIRBOSS:_GetWire( Lcoord, dc )
|
||||
|
||||
if self.Debug and false then
|
||||
|
||||
-- Wire position coodinates.
|
||||
-- Wire position coordinates.
|
||||
local wp1 = Scoord:Translate( w1, FB )
|
||||
local wp2 = Scoord:Translate( w2, FB )
|
||||
local wp3 = Scoord:Translate( w3, FB )
|
||||
@@ -11391,7 +11391,7 @@ end
|
||||
--- Get true (or magnetic) heading of carrier into the wind. This accounts for the angled runway.
|
||||
-- @param #AIRBOSS self
|
||||
-- @param #boolean magnetic If true, calculate magnetic heading. By default true heading is returned.
|
||||
-- @param Core.Point#COORDINATE coord (Optional) Coodinate from which heading is calculated. Default is current carrier position.
|
||||
-- @param Core.Point#COORDINATE coord (Optional) Coordinate from which heading is calculated. Default is current carrier position.
|
||||
-- @return #number Carrier heading in degrees.
|
||||
function AIRBOSS:GetHeadingIntoWind( magnetic, coord )
|
||||
|
||||
|
||||
@@ -2306,6 +2306,10 @@ function AUFTRAG:NewFromTarget(Target, MissionType)
|
||||
mission=self:NewBOMBING(Target, Altitude)
|
||||
elseif MissionType==AUFTRAG.Type.BOMBRUNWAY then
|
||||
mission=self:NewBOMBRUNWAY(Target, Altitude)
|
||||
elseif MissionType==AUFTRAG.Type.CAS then
|
||||
mission=self:NewCAS(ZONE_RADIUS:New(Target:GetName(),Target:GetVec2(),1000),Altitude,Speed,Target:GetAverageCoordinate(),Heading,Leg,TargetTypes)
|
||||
elseif MissionType==AUFTRAG.Type.CASENHANCED then
|
||||
mission=self:NewCASENHANCED(ZONE_RADIUS:New(Target:GetName(),Target:GetVec2(),1000),Altitude,Speed,RangeMax,NoEngageZoneSet,TargetTypes)
|
||||
elseif MissionType==AUFTRAG.Type.INTERCEPT then
|
||||
mission=self:NewINTERCEPT(Target)
|
||||
elseif MissionType==AUFTRAG.Type.SEAD then
|
||||
|
||||
@@ -497,7 +497,7 @@ do
|
||||
-- @field #AWACS
|
||||
AWACS = {
|
||||
ClassName = "AWACS", -- #string
|
||||
version = "0.2.45", -- #string
|
||||
version = "0.2.46", -- #string
|
||||
lid = "", -- #string
|
||||
coalition = coalition.side.BLUE, -- #number
|
||||
coalitiontxt = "blue", -- #string
|
||||
@@ -914,7 +914,7 @@ AWACS.TaskStatus = {
|
||||
--@field #boolean FromAI
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO-List 0.2.41
|
||||
-- TODO-List 0.2.42
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
--
|
||||
-- DONE - WIP - Player tasking, VID
|
||||
@@ -950,6 +950,7 @@ AWACS.TaskStatus = {
|
||||
-- DONE - Anchor Stack Management
|
||||
-- DONE - Shift Length AWACS/AI
|
||||
-- DONE - (WIP) Reporting
|
||||
-- DONE - Do not report non-airborne groups
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
@@ -2092,7 +2093,7 @@ function AWACS:_StartSettings(FlightGroup,Mission)
|
||||
self:Started()
|
||||
|
||||
elseif self.ShiftChangeAwacsRequested and self.AwacsMissionReplacement and self.AwacsMissionReplacement:GetName() == Mission:GetName() then
|
||||
self:I("Setting up Awacs Replacement")
|
||||
self:T("Setting up Awacs Replacement")
|
||||
-- manage AWACS Replacement
|
||||
AwacsFG:SetDefaultRadio(self.Frequency,self.Modulation,false)
|
||||
AwacsFG:SwitchRadio(self.Frequency,self.Modulation)
|
||||
@@ -2962,7 +2963,7 @@ end
|
||||
-- @param Wrapper.Group#GROUP Group Group to use
|
||||
-- @return #AWACS self
|
||||
function AWACS:_ShowAwacsInfo(Group)
|
||||
self:I(self.lid.."_ShowAwacsInfo")
|
||||
self:T(self.lid.."_ShowAwacsInfo")
|
||||
local report = REPORT:New("Info")
|
||||
report:Add("====================")
|
||||
report:Add(string.format("AWACS %s",self.callsigntxt))
|
||||
@@ -3738,7 +3739,7 @@ end
|
||||
-- @param #AWACS self
|
||||
-- @return #AWACS self
|
||||
function AWACS:_DeleteAnchorStackFromMarker(Name,Coord)
|
||||
self:I(self.lid.."_DeleteAnchorStackFromMarker")
|
||||
self:T(self.lid.."_DeleteAnchorStackFromMarker")
|
||||
if self.AnchorStacks:HasUniqueID(Name) and self.PlayerStationName == Name then
|
||||
local stack = self.AnchorStacks:ReadByID(Name) -- #AWACS.AnchorData
|
||||
local marker = stack.AnchorMarker
|
||||
@@ -3764,7 +3765,7 @@ end
|
||||
-- @param #AWACS self
|
||||
-- @return #AWACS self
|
||||
function AWACS:_MoveAnchorStackFromMarker(Name,Coord)
|
||||
self:I(self.lid.."_MoveAnchorStackFromMarker")
|
||||
self:T(self.lid.."_MoveAnchorStackFromMarker")
|
||||
if self.AnchorStacks:HasUniqueID(Name) and self.PlayerStationName == Name then
|
||||
local station = self.AnchorStacks:PullByID(Name) -- #AWACS.AnchorData
|
||||
local stationtag = string.format("Station: %s\nCoordinate: %s",Name,Coord:ToStringLLDDM())
|
||||
@@ -3791,7 +3792,7 @@ end
|
||||
-- @param #AWACS self
|
||||
-- @return #AWACS self
|
||||
function AWACS:_CreateAnchorStackFromMarker(Name,Coord)
|
||||
self:I(self.lid.."_CreateAnchorStackFromMarker")
|
||||
self:T(self.lid.."_CreateAnchorStackFromMarker")
|
||||
local AnchorStackOne = {} -- #AWACS.AnchorData
|
||||
AnchorStackOne.AnchorBaseAngels = self.AnchorBaseAngels
|
||||
AnchorStackOne.Anchors = FIFO:New() -- Utilities.FiFo#FIFO
|
||||
@@ -5112,7 +5113,7 @@ function AWACS:_CheckAICAPOnStation()
|
||||
self:_ConsistencyCheck()
|
||||
|
||||
local capmissions, alert5missions, interceptmissions = self:_CleanUpAIMissionStack()
|
||||
self:I("CAP="..capmissions.." ALERT5="..alert5missions.." Requested="..self.AIRequested)
|
||||
self:T("CAP="..capmissions.." ALERT5="..alert5missions.." Requested="..self.AIRequested)
|
||||
|
||||
if self.MaxAIonCAP > 0 then
|
||||
|
||||
@@ -5147,7 +5148,7 @@ function AWACS:_CheckAICAPOnStation()
|
||||
self.AIRequested = self.AIRequested + 1
|
||||
local selectedAW = AWS[(((self.AIRequested-1) % availableAWS)+1)]
|
||||
selectedAW:AddMission(mission)
|
||||
self:I("CAP="..capmissions.." ALERT5="..alert5missions.." Requested="..self.AIRequested)
|
||||
self:T("CAP="..capmissions.." ALERT5="..alert5missions.." Requested="..self.AIRequested)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5693,7 +5694,7 @@ function AWACS:onafterStart(From, Event, To)
|
||||
local MarkerOps = MARKEROPS_BASE:New("AWACS",{"Station","Delete","Move"})
|
||||
|
||||
local function Handler(Keywords,Coord,Text)
|
||||
self:I(Text)
|
||||
self:T(Text)
|
||||
for _,_word in pairs (Keywords) do
|
||||
if string.lower(_word) == "station" then
|
||||
-- get the station name from the text field
|
||||
@@ -5988,7 +5989,7 @@ end
|
||||
-- @param #string To
|
||||
-- @return #AWACS self
|
||||
function AWACS:onafterStatus(From, Event, To)
|
||||
self:I({From, Event, To})
|
||||
self:T({From, Event, To})
|
||||
|
||||
self:_SetClientMenus()
|
||||
|
||||
@@ -6232,16 +6233,20 @@ function AWACS:onafterNewCluster(From,Event,To,Cluster)
|
||||
for _,_contact in pairs (table) do
|
||||
local contact = _contact -- Ops.Intelligence#INTEL.Contact
|
||||
if contact and contact.group and contact.group:IsAlive() then
|
||||
return contact
|
||||
return contact, contact.group
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local Contact = GetFirstAliveContact(ContactTable) -- Ops.Intelligence#INTEL.Contact
|
||||
local Contact, Group = GetFirstAliveContact(ContactTable) -- Ops.Intelligence#INTEL.Contact
|
||||
|
||||
if not Contact then return self end
|
||||
|
||||
if Group and not Group:IsAirborne() then
|
||||
return self
|
||||
end
|
||||
|
||||
local targetset = SET_GROUP:New()
|
||||
-- SET for TARGET
|
||||
for _,_grp in pairs(ContactTable) do
|
||||
@@ -6316,7 +6321,7 @@ function AWACS:onafterNewContact(From,Event,To,Contact)
|
||||
for _gid,_mgroup in pairs(self.ManagedGrps) do
|
||||
local managedgroup = _mgroup -- #AWACS.ManagedGroup
|
||||
local group = managedgroup.Group
|
||||
if group and group:IsAlive() then
|
||||
if group and group:IsAlive() and group:IsAirborne() then
|
||||
-- contact distance
|
||||
local cpos = Contact.position or Contact.group:GetCoordinate() -- Core.Point#COORDINATE
|
||||
local mpos = group:GetCoordinate()
|
||||
@@ -6381,7 +6386,7 @@ function AWACS:onafterCheckRadioQueue(From,Event,To)
|
||||
self:T({RadioEntry})
|
||||
|
||||
if self.clientset:CountAlive() == 0 then
|
||||
self:I(self.lid.."No player connected.")
|
||||
self:T(self.lid.."No player connected.")
|
||||
self:__CheckRadioQueue(-5)
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **Ops** -- Combat Search and Rescue.
|
||||
--- **Ops** - Combat Search and Rescue.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **Ops** -- Combat Troops & Logistics Department.
|
||||
--- **Ops** - Combat Troops & Logistics Department.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@@ -699,6 +699,7 @@ do
|
||||
-- my_ctld.smokedistance = 2000 -- Only smoke or flare zones if requesting player unit is this far away (in meters)
|
||||
-- my_ctld.suppressmessages = false -- Set to true if you want to script your own messages.
|
||||
-- my_ctld.repairtime = 300 -- Number of seconds it takes to repair a unit.
|
||||
-- my_ctld.buildtime = 300 -- Number of seconds it takes to build a unit. Set to zero or nil to build instantly.
|
||||
-- my_ctld.cratecountry = country.id.GERMANY -- ID of crates. Will default to country.id.RUSSIA for RED coalition setups.
|
||||
-- my_ctld.allowcratepickupagain = true -- allow re-pickup crates that were dropped.
|
||||
-- my_ctld.enableslingload = false -- allow cargos to be slingloaded - might not work for all cargo types
|
||||
@@ -708,6 +709,7 @@ do
|
||||
-- my_ctld.basetype = "container_cargo" -- default shape of the cargo container
|
||||
-- my_ctld.droppedbeacontimeout = 600 -- dropped beacon lasts 10 minutes
|
||||
-- my_ctld.usesubcats = false -- use sub-category names for crates, adds an extra menu layer in "Get Crates", useful if you have > 10 crate types.
|
||||
-- my_ctld.placeCratesAhead = false -- place crates straight ahead of the helicopter, in a random way. If true, crates are more neatly sorted.
|
||||
--
|
||||
-- ## 2.1 User functions
|
||||
--
|
||||
@@ -1074,7 +1076,7 @@ CTLD.UnitTypes = {
|
||||
|
||||
--- CTLD class version.
|
||||
-- @field #string version
|
||||
CTLD.version="1.0.16"
|
||||
CTLD.version="1.0.17"
|
||||
|
||||
--- Instantiate a new CTLD.
|
||||
-- @param #CTLD self
|
||||
@@ -1212,8 +1214,9 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
-- message suppression
|
||||
self.suppressmessages = false
|
||||
|
||||
-- time to repair a unit/group
|
||||
-- time to repairor build a unit/group
|
||||
self.repairtime = 300
|
||||
self.buildtime = 300
|
||||
|
||||
-- place spawned crates in front of aircraft
|
||||
self.placeCratesAhead = false
|
||||
@@ -2807,7 +2810,13 @@ function CTLD:_BuildCrates(Group, Unit,Engineering)
|
||||
local build = _build -- #CTLD.Buildable
|
||||
if build.CanBuild then
|
||||
self:_CleanUpCrates(crates,build,number)
|
||||
self:_BuildObjectFromCrates(Group,Unit,build)
|
||||
if self.buildtime and self.buildtime > 0 then
|
||||
local buildtimer = TIMER:New(self._BuildObjectFromCrates,self,Group,Unit,build,false,Group:GetCoordinate())
|
||||
buildtimer:Start(self.buildtime)
|
||||
self:_SendMessage(string.format("Build started, ready in %d seconds!",self.buildtime),15,false,Group)
|
||||
else
|
||||
self:_BuildObjectFromCrates(Group,Unit,build)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2906,13 +2915,13 @@ end
|
||||
-- @param Wrapper.Group#UNIT Unit
|
||||
-- @param #CTLD.Buildable Build
|
||||
-- @param #boolean Repair If true this is a repair and not a new build
|
||||
-- @param Core.Point#COORDINATE Coordinate Location for repair (e.g. where the destroyed unit was)
|
||||
-- @param Core.Point#COORDINATE RepairLocation Location for repair (e.g. where the destroyed unit was)
|
||||
function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation)
|
||||
self:T(self.lid .. " _BuildObjectFromCrates")
|
||||
-- Spawn-a-crate-content
|
||||
if Group and Group:IsAlive() then
|
||||
local position = Unit:GetCoordinate() or Group:GetCoordinate()
|
||||
local unitname = Unit:GetName() or Group:GetName()
|
||||
if Group and Group:IsAlive() or (RepairLocation and not Repair) then
|
||||
--local position = Unit:GetCoordinate() or Group:GetCoordinate()
|
||||
--local unitname = Unit:GetName() or Group:GetName() or "Unknown"
|
||||
local name = Build.Name
|
||||
local ctype = Build.Type -- #CTLD_CARGO.Enum
|
||||
local canmove = false
|
||||
@@ -2924,7 +2933,13 @@ function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation)
|
||||
if type(temptable) == "string" then
|
||||
temptable = {temptable}
|
||||
end
|
||||
local zone = ZONE_GROUP:New(string.format("Unload zone-%s",unitname),Group,100)
|
||||
local zone = nil
|
||||
if RepairLocation and not Repair then
|
||||
-- timed build
|
||||
zone = ZONE_RADIUS:New(string.format("Build zone-%d",math.random(1,10000)),RepairLocation:GetVec2(),100)
|
||||
else
|
||||
zone = ZONE_GROUP:New(string.format("Unload zone-%d",math.random(1,10000)),Group,100)
|
||||
end
|
||||
--local randomcoord = zone:GetRandomCoordinate(35):GetVec2()
|
||||
local randomcoord = Build.Coord or zone:GetRandomCoordinate(35):GetVec2()
|
||||
if Repair then
|
||||
@@ -4895,7 +4910,7 @@ CTLD_HERCULES = {
|
||||
ClassName = "CTLD_HERCULES",
|
||||
lid = "",
|
||||
Name = "",
|
||||
Version = "0.0.1",
|
||||
Version = "0.0.2",
|
||||
}
|
||||
|
||||
--- Define cargo types.
|
||||
@@ -5306,7 +5321,7 @@ function CTLD_HERCULES:Cargo_Track(cargo, initiator)
|
||||
if self:Check_SurfaceType(cargo.Cargo_Contents) == 2 or self:Check_SurfaceType(cargo.Cargo_Contents) == 3 then
|
||||
cargo.Cargo_over_water = true--pallets gets destroyed in water
|
||||
end
|
||||
local dcsvec3 = self.ObjectTracker[cargo.Cargo_Contents.id_] -- last known position
|
||||
local dcsvec3 = self.ObjectTracker[cargo.Cargo_Contents.id_] or initiator:GetVec3() -- last known position
|
||||
self:T("SPAWNPOSITION: ")
|
||||
self:T({dcsvec3})
|
||||
local Vec2 = {
|
||||
@@ -5409,7 +5424,7 @@ function CTLD_HERCULES:Cargo_Initialize(Initiator, Cargo_Contents, Cargo_Type_na
|
||||
|
||||
local timer = TIMER:New(self.Cargo_Track,self,self.Cargo[self.j],Initiator)
|
||||
self.Cargo[self.j].scheduleFunctionID = timer
|
||||
timer:Start(5,2,600)
|
||||
timer:Start(1,1,600)
|
||||
|
||||
else
|
||||
-- no paras
|
||||
@@ -5434,7 +5449,7 @@ function CTLD_HERCULES:Cargo_Initialize(Initiator, Cargo_Contents, Cargo_Type_na
|
||||
|
||||
local timer = TIMER:New(self.Cargo_Track,self,self.Cargo[self.j],Initiator)
|
||||
self.Cargo[self.j].scheduleFunctionID = timer
|
||||
timer:Start(5,2,600)
|
||||
timer:Start(1,1,600)
|
||||
end
|
||||
end
|
||||
return self
|
||||
|
||||
@@ -2787,8 +2787,9 @@ function CHIEF:_GetMissionPerformanceFromTarget(Target)
|
||||
|
||||
-- Tanks
|
||||
|
||||
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.CAS, 100))
|
||||
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BAI, 80))
|
||||
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BAI, 100))
|
||||
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.CAS, 90))
|
||||
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.CASENHANCED, 90))
|
||||
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.GROUNDATTACK, 50))
|
||||
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.ARMORATTACK, 40))
|
||||
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.ARTY, 30))
|
||||
|
||||
@@ -467,7 +467,7 @@ function OPERATION:SetPhaseConditonOver(Phase, Condition)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add codition function when the given phase is over. Must return a `#boolean`.
|
||||
--- Add condition function when the given phase is over. Must return a `#boolean`.
|
||||
-- @param #OPERATION self
|
||||
-- @param #OPERATION.Phase Phase The phase.
|
||||
-- @param #function Function Function that needs to be `true`before the phase is over.
|
||||
@@ -739,6 +739,20 @@ function OPERATION:AddTarget(Target, Phase)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add Targets from operation.
|
||||
-- @param #OPERATION self
|
||||
-- @param #OPERATION.Phase Phase
|
||||
-- @return #table Targets Table of #TARGET objects
|
||||
function OPERATION:GetTargets(Phase)
|
||||
local N = {}
|
||||
for _,_target in pairs(self.targets) do
|
||||
local target=_target --Ops.Target#TARGET
|
||||
if target:IsAlive() and (Phase==nil or target.phase==Phase) then
|
||||
table.insert(N,target)
|
||||
end
|
||||
end
|
||||
return N
|
||||
end
|
||||
|
||||
--- Count targets alive.
|
||||
-- @param #OPERATION self
|
||||
@@ -896,7 +910,7 @@ function OPERATION:onafterStart(From, Event, To)
|
||||
|
||||
-- Debug message.
|
||||
self:T(self.lid..string.format("Starting Operation!"))
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
@@ -967,6 +981,8 @@ function OPERATION:onafterStatusUpdate(From, Event, To)
|
||||
|
||||
-- Next status update.
|
||||
self:__StatusUpdate(-30)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -978,7 +994,6 @@ end
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param #OPERATION.Phase Phase The new phase.
|
||||
function OPERATION:onafterPhaseNext(From, Event, To)
|
||||
|
||||
-- Get next phase.
|
||||
@@ -996,6 +1011,7 @@ function OPERATION:onafterPhaseNext(From, Event, To)
|
||||
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
@@ -1023,6 +1039,7 @@ function OPERATION:onafterPhaseChange(From, Event, To, Phase)
|
||||
-- Phase is active.
|
||||
self:SetPhaseStatus(Phase, OPERATION.PhaseStatus.ACTIVE)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- On after "BranchSwitch" event.
|
||||
@@ -1038,7 +1055,8 @@ function OPERATION:onafterBranchSwitch(From, Event, To, Branch)
|
||||
|
||||
-- Set active branch.
|
||||
self.branchActive=Branch
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- On after "Over" event.
|
||||
@@ -1062,7 +1080,9 @@ function OPERATION:onafterOver(From, Event, To)
|
||||
local phase=_phase --#OPERATION.Phase
|
||||
self:SetPhaseStatus(phase, OPERATION.PhaseStatus.OVER)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -11531,7 +11531,7 @@ end
|
||||
--- Set default Radio frequency and modulation.
|
||||
-- @param #OPSGROUP self
|
||||
-- @param #number Frequency Radio frequency in MHz. Default 251 MHz.
|
||||
-- @param #number Modulation Radio modulation. Default `radio.Modulation.AM`.
|
||||
-- @param #number Modulation Radio modulation. Default `radio.modulation.AM`.
|
||||
-- @param #boolean OffSwitch If true, radio is OFF by default.
|
||||
-- @return #OPSGROUP self
|
||||
function OPSGROUP:SetDefaultRadio(Frequency, Modulation, OffSwitch)
|
||||
@@ -11560,7 +11560,7 @@ end
|
||||
--- Turn radio on or switch frequency/modulation.
|
||||
-- @param #OPSGROUP self
|
||||
-- @param #number Frequency Radio frequency in MHz. Default is value set in `SetDefaultRadio` (usually 251 MHz).
|
||||
-- @param #number Modulation Radio modulation. Default is value set in `SetDefaultRadio` (usually `radio.Modulation.AM`).
|
||||
-- @param #number Modulation Radio modulation. Default is value set in `SetDefaultRadio` (usually `radio.modulation.AM`).
|
||||
-- @return #OPSGROUP self
|
||||
function OPSGROUP:SwitchRadio(Frequency, Modulation)
|
||||
|
||||
|
||||
@@ -654,7 +654,7 @@ function PLAYERTASK:onafterStatus(From, Event, To)
|
||||
|
||||
-- Check Target status
|
||||
local targetdead = false
|
||||
if self.Target:IsDead() or self.Target:IsDestroyed() then
|
||||
if self.Target:IsDead() or self.Target:IsDestroyed() or self.Target:CountTargets() == 0 then
|
||||
targetdead = true
|
||||
self:__Success(-2)
|
||||
status = "Success"
|
||||
@@ -918,6 +918,7 @@ do
|
||||
-- @field #boolean buddylasing
|
||||
-- @field Ops.PlayerRecce#PLAYERRECCE PlayerRecce
|
||||
-- @field #number Coalition
|
||||
-- @field Core.Menu#MENU_MISSION MenuParent
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
---
|
||||
@@ -1229,6 +1230,7 @@ PLAYERTASKCONTROLLER = {
|
||||
buddylasing = false,
|
||||
PlayerRecce = nil,
|
||||
Coalition = nil,
|
||||
MenuParent = nil,
|
||||
}
|
||||
|
||||
---
|
||||
@@ -1395,7 +1397,7 @@ PLAYERTASKCONTROLLER.Messages = {
|
||||
|
||||
--- PLAYERTASK class version.
|
||||
-- @field #string version
|
||||
PLAYERTASKCONTROLLER.version="0.1.43"
|
||||
PLAYERTASKCONTROLLER.version="0.1.45"
|
||||
|
||||
--- Create and run a new TASKCONTROLLER instance.
|
||||
-- @param #PLAYERTASKCONTROLLER self
|
||||
@@ -1472,6 +1474,9 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter)
|
||||
self:AddTransition("*", "TaskCancelled", "*")
|
||||
self:AddTransition("*", "TaskSuccess", "*")
|
||||
self:AddTransition("*", "TaskFailed", "*")
|
||||
self:AddTransition("*", "TaskTargetSmoked", "*")
|
||||
self:AddTransition("*", "TaskTargetFlared", "*")
|
||||
self:AddTransition("*", "TaskTargetIlluminated", "*")
|
||||
self:AddTransition("*", "TaskRepeatOnFailed", "*")
|
||||
self:AddTransition("*", "Stop", "Stopped")
|
||||
|
||||
@@ -1542,6 +1547,30 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter)
|
||||
-- @param #string To To state.
|
||||
-- @param Ops.PlayerTask#PLAYERTASK Task
|
||||
|
||||
--- On After "TaskTargetSmoked" event. Task smoked.
|
||||
-- @function [parent=#PLAYERTASKCONTROLLER] OnAfterTaskTargetSmoked
|
||||
-- @param #PLAYERTASKCONTROLLER self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Ops.PlayerTask#PLAYERTASK Task
|
||||
|
||||
--- On After "TaskTargetFlared" event. Task flared.
|
||||
-- @function [parent=#PLAYERTASKCONTROLLER] OnAfterTaskTargetFlared
|
||||
-- @param #PLAYERTASKCONTROLLER self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Ops.PlayerTask#PLAYERTASK Task
|
||||
|
||||
--- On After "TaskTargetIlluminated" event. Task illuminated.
|
||||
-- @function [parent=#PLAYERTASKCONTROLLER] OnAfterTaskTargetIlluminated
|
||||
-- @param #PLAYERTASKCONTROLLER self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Ops.PlayerTask#PLAYERTASK Task
|
||||
|
||||
end
|
||||
|
||||
--- [Internal] Init localization
|
||||
@@ -2768,7 +2797,8 @@ function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Group, Client, Task)
|
||||
if clientcount > 0 then
|
||||
for _,_name in pairs(clientlist) do
|
||||
if self.customcallsigns[_name] then
|
||||
_name = self.customcallsigns[_name]
|
||||
_name = self.customcallsigns[_name]
|
||||
_name = string.gsub(_name, "(%d) ","%1")
|
||||
end
|
||||
clienttxt = clienttxt .. _name .. ", "
|
||||
end
|
||||
@@ -2866,6 +2896,7 @@ function PLAYERTASKCONTROLLER:_SmokeTask(Group, Client)
|
||||
if self.UseSRS then
|
||||
self.SRSQueue:NewTransmission(text,nil,self.SRS,nil,2)
|
||||
end
|
||||
self:__TaskTargetSmoked(5,task)
|
||||
else
|
||||
text = self.gettext:GetEntry("NOACTIVETASK",self.locale)
|
||||
end
|
||||
@@ -2894,6 +2925,36 @@ function PLAYERTASKCONTROLLER:_FlareTask(Group, Client)
|
||||
if self.UseSRS then
|
||||
self.SRSQueue:NewTransmission(text,nil,self.SRS,nil,2)
|
||||
end
|
||||
self:__TaskTargetFlared(5,task)
|
||||
else
|
||||
text = self.gettext:GetEntry("NOACTIVETASK",self.locale)
|
||||
end
|
||||
if not self.NoScreenOutput then
|
||||
local m=MESSAGE:New(text,15,"Tasking"):ToClient(Client)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- [Internal] Illuminate task location
|
||||
-- @param #PLAYERTASKCONTROLLER self
|
||||
-- @param Wrapper.Group#GROUP Group
|
||||
-- @param Wrapper.Client#CLIENT Client
|
||||
-- @return #PLAYERTASKCONTROLLER self
|
||||
function PLAYERTASKCONTROLLER:_IlluminateTask(Group, Client)
|
||||
self:T(self.lid.."_IlluminateTask")
|
||||
local playername, ttsplayername = self:_GetPlayerName(Client)
|
||||
local text = ""
|
||||
if self.TasksPerPlayer:HasUniqueID(playername) then
|
||||
local task = self.TasksPerPlayer:ReadByID(playername) -- Ops.PlayerTask#PLAYERTASK
|
||||
task:FlareTarget()
|
||||
local textmark = self.gettext:GetEntry("FLARETASK",self.locale)
|
||||
text = string.format(textmark, ttsplayername, self.MenuName or self.Name, task.PlayerTaskNr)
|
||||
self:T(self.lid..text)
|
||||
--local m=MESSAGE:New(text,"10","Tasking"):ToAll()
|
||||
if self.UseSRS then
|
||||
self.SRSQueue:NewTransmission(text,nil,self.SRS,nil,2)
|
||||
end
|
||||
self:__TaskTargetIlluminated(5,task)
|
||||
else
|
||||
text = self.gettext:GetEntry("NOACTIVETASK",self.locale)
|
||||
end
|
||||
@@ -2909,7 +2970,7 @@ end
|
||||
-- @param Wrapper.Client#CLIENT Client
|
||||
-- @return #PLAYERTASKCONTROLLER self
|
||||
function PLAYERTASKCONTROLLER:_AbortTask(Group, Client)
|
||||
self:T(self.lid.."_FlareTask")
|
||||
self:T(self.lid.."_AbortTask")
|
||||
local playername, ttsplayername = self:_GetPlayerName(Client)
|
||||
local text = ""
|
||||
if self.TasksPerPlayer:HasUniqueID(playername) then
|
||||
@@ -3052,7 +3113,7 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess)
|
||||
end
|
||||
else
|
||||
-- 1) new player#
|
||||
topmenu = MENU_GROUP_DELAYED:New(group,menuname,nil)
|
||||
topmenu = MENU_GROUP_DELAYED:New(group,menuname,self.MenuParent)
|
||||
self.PlayerMenu[playername] = topmenu
|
||||
self.PlayerMenu[playername]:SetTag(timer.getAbsTime())
|
||||
end
|
||||
@@ -3077,6 +3138,10 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess)
|
||||
-- no smoking/flaring here if A2A or designer has set noflaresmokemenu to true
|
||||
local smoke = MENU_GROUP_COMMAND_DELAYED:New(group,menusmoke,active,self._SmokeTask,self,group,client)
|
||||
local flare = MENU_GROUP_COMMAND_DELAYED:New(group,menuflare,active,self._FlareTask,self,group,client)
|
||||
local IsNight = client:GetCoordinate():IsNight()
|
||||
if IsNight then
|
||||
local light = MENU_GROUP_COMMAND_DELAYED:New(group,menuflare,active,self._IlluminateTask,self,group,client)
|
||||
end
|
||||
end
|
||||
end
|
||||
local abort = MENU_GROUP_COMMAND_DELAYED:New(group,menuabort,active,self._AbortTask,self,group,client)
|
||||
@@ -3237,6 +3302,16 @@ function PLAYERTASKCONTROLLER:SetMenuName(Name)
|
||||
return self
|
||||
end
|
||||
|
||||
--- [User] Set the top menu to be a sub-menu of another MENU entry.
|
||||
-- @param #PLAYERTASKCONTROLLER self
|
||||
-- @param Core.Menu#MENU_MISSION Menu
|
||||
-- @return #PLAYERTASKCONTROLLER self
|
||||
function PLAYERTASKCONTROLLER:SetParentMenu(Menu)
|
||||
self:T(self.lid.."SetParentName")
|
||||
self.MenuParent = Menu
|
||||
return self
|
||||
end
|
||||
|
||||
--- [User] Set up INTEL detection
|
||||
-- @param #PLAYERTASKCONTROLLER self
|
||||
-- @param #string RecceName This name will be used to build a detection group set. All groups with this string somewhere in their group name will be added as Recce.
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
--
|
||||
-- * Manages target, number alive, life points, damage etc.
|
||||
-- * Events when targets are damaged or destroyed
|
||||
-- * Various target objects: UNIT, GROUP, STATIC, AIRBASE, COORDINATE, SET_GROUP, SET_UNIT, SET_SCENERY
|
||||
-- * Various target objects: UNIT, GROUP, STATIC, SCENERY, AIRBASE, COORDINATE, ZONE, SET_GROUP, SET_UNIT, SET_STATIC, SET_SCENERY, SET_ZONE
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **funkyfranky**
|
||||
-- ### Additions: **applevangelist**
|
||||
--
|
||||
-- @module Ops.Target
|
||||
-- @image OPS_Target.png
|
||||
|
||||
@@ -114,9 +116,11 @@ TARGET.Category={
|
||||
-- @type TARGET.ObjectStatus
|
||||
-- @field #string ALIVE Object is alive.
|
||||
-- @field #string DEAD Object is dead.
|
||||
-- @field #string DAMAGED Object is damaged.
|
||||
TARGET.ObjectStatus={
|
||||
ALIVE="Alive",
|
||||
DEAD="Dead",
|
||||
DAMAGED="Damaged",
|
||||
}
|
||||
|
||||
--- Resource.
|
||||
@@ -147,14 +151,14 @@ _TARGETID=0
|
||||
|
||||
--- TARGET class version.
|
||||
-- @field #string version
|
||||
TARGET.version="0.5.4"
|
||||
TARGET.version="0.5.5"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: Had cases where target life was 0 but target was not dead. Need to figure out why!
|
||||
-- TODO: Add pseudo functions.
|
||||
-- DONE: Add pseudo functions.
|
||||
-- DONE: Initial object can be nil.
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -163,7 +167,7 @@ TARGET.version="0.5.4"
|
||||
|
||||
--- Create a new TARGET object and start the FSM.
|
||||
-- @param #TARGET self
|
||||
-- @param #table TargetObject Target object.
|
||||
-- @param #table TargetObject Target object. Can be a: UNIT, GROUP, STATIC, SCENERY, AIRBASE, COORDINATE, ZONE, SET_GROUP, SET_UNIT, SET_STATIC, SET_SCENERY, SET_ZONE
|
||||
-- @return #TARGET self
|
||||
function TARGET:New(TargetObject)
|
||||
|
||||
@@ -204,7 +208,7 @@ function TARGET:New(TargetObject)
|
||||
self:AddTransition("*", "ObjectDestroyed", "*") -- A target object was destroyed.
|
||||
self:AddTransition("*", "ObjectDead", "*") -- A target object is dead (destroyed or despawned).
|
||||
|
||||
self:AddTransition("*", "Damaged", "*") -- Target was damaged.
|
||||
self:AddTransition("*", "Damaged", "Damaged") -- Target was damaged.
|
||||
self:AddTransition("*", "Destroyed", "Dead") -- Target was completely destroyed.
|
||||
self:AddTransition("*", "Dead", "Dead") -- Target is dead. Could be destroyed or despawned.
|
||||
|
||||
@@ -237,7 +241,51 @@ function TARGET:New(TargetObject)
|
||||
-- @function [parent=#TARGET] __Status
|
||||
-- @param #TARGET self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
|
||||
--- On After "ObjectDamaged" event. A (sub-) target object has been damaged, e.g. a UNIT of a GROUP, or an object of a SET
|
||||
-- @function [parent=#TARGET] OnAfterObjectDamaged
|
||||
-- @param #TARGET self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param #TARGET.Object Target Target object.
|
||||
|
||||
--- On After "ObjectDestroyed" event. A (sub-) target object has been destroyed, e.g. a UNIT of a GROUP, or an object of a SET
|
||||
-- @function [parent=#TARGET] OnAfterObjectDestroyed
|
||||
-- @param #TARGET self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param #TARGET.Object Target Target object.
|
||||
|
||||
--- On After "ObjectDead" event. A (sub-) target object is dead, e.g. a UNIT of a GROUP, or an object of a SET
|
||||
-- @function [parent=#TARGET] OnAfterObjectDead
|
||||
-- @param #TARGET self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param #TARGET.Object Target Target object.
|
||||
|
||||
--- On After "Damaged" event. The (whole) target object has been damaged.
|
||||
-- @function [parent=#TARGET] OnAfterDamaged
|
||||
-- @param #TARGET self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
|
||||
--- On After "ObjectDestroyed" event. The (whole) target object has been destroyed.
|
||||
-- @function [parent=#TARGET] OnAfterDestroyed
|
||||
-- @param #TARGET self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
|
||||
--- On After "ObjectDead" event. The (whole) target object is dead.
|
||||
-- @function [parent=#TARGET] OnAfterDead
|
||||
-- @param #TARGET self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
|
||||
-- Start.
|
||||
self:__Start(-1)
|
||||
@@ -254,17 +302,19 @@ end
|
||||
-- * GROUP
|
||||
-- * UNIT
|
||||
-- * STATIC
|
||||
-- * SCENERY
|
||||
-- * AIRBASE
|
||||
-- * COORDINATE
|
||||
-- * ZONE
|
||||
-- * SET_GROUP
|
||||
-- * SET_UNIT
|
||||
-- * SET_STATIC
|
||||
-- * SET_OPSGROUP
|
||||
-- * SET_SCENERY
|
||||
-- * SET_OPSGROUP
|
||||
-- * SET_ZONE
|
||||
--
|
||||
-- @param #TARGET self
|
||||
-- @param Wrapper.Positionable#POSITIONABLE Object The target GROUP, UNIT, STATIC, AIRBASE or COORDINATE.
|
||||
-- @param Wrapper.Positionable#POSITIONABLE Object The target UNIT, GROUP, STATIC, SCENERY, AIRBASE, COORDINATE, ZONE, SET_GROUP, SET_UNIT, SET_STATIC, SET_SCENERY, SET_ZONE
|
||||
function TARGET:AddObject(Object)
|
||||
|
||||
if Object:IsInstanceOf("SET_GROUP") or Object:IsInstanceOf("SET_UNIT") or Object:IsInstanceOf("SET_STATIC") or Object:IsInstanceOf("SET_SCENERY") or Object:IsInstanceOf("SET_OPSGROUP") then
|
||||
@@ -304,6 +354,7 @@ function TARGET:AddObject(Object)
|
||||
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set priority of the target.
|
||||
@@ -502,7 +553,7 @@ end
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function TARGET:onafterStart(From, Event, To)
|
||||
|
||||
self:T({From, Event, To})
|
||||
-- Short info.
|
||||
local text=string.format("Starting Target")
|
||||
self:T(self.lid..text)
|
||||
@@ -512,6 +563,7 @@ function TARGET:onafterStart(From, Event, To)
|
||||
self:HandleEvent(EVENTS.RemoveUnit, self.OnEventUnitDeadOrLost)
|
||||
|
||||
self:__Status(-1)
|
||||
return self
|
||||
end
|
||||
|
||||
--- On after "Status" event.
|
||||
@@ -521,7 +573,7 @@ end
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function TARGET:onafterStatus(From, Event, To)
|
||||
|
||||
self:T({From, Event, To})
|
||||
-- FSM state.
|
||||
local fsmstate=self:GetState()
|
||||
|
||||
@@ -530,18 +582,29 @@ function TARGET:onafterStatus(From, Event, To)
|
||||
for i,_target in pairs(self.targets) do
|
||||
local target=_target --#TARGET.Object
|
||||
|
||||
-- old life
|
||||
local life=target.Life
|
||||
|
||||
-- curr life
|
||||
target.Life=self:GetTargetLife(target)
|
||||
|
||||
-- TODO: special case ED bug > life **increases** after hits on SCENERY
|
||||
if target.Life > target.Life0 then
|
||||
local delta = 2*(target.Life-target.Life0)
|
||||
target.Life0 = target.Life0 + delta
|
||||
life = target.Life0
|
||||
self.life0 = self.life0+delta
|
||||
end
|
||||
|
||||
if target.Life<life then
|
||||
self:ObjectDamaged(target)
|
||||
target.Status = TARGET.ObjectStatus.DAMAGED
|
||||
self:ObjectDamaged(target)
|
||||
damaged=true
|
||||
end
|
||||
|
||||
if life==0 then
|
||||
self:I(self.lid..string.format("FF life is zero but no object dead event fired ==> object dead now for target object %s!", tostring(target.Name)))
|
||||
if life < 1 and (not target.Status == TARGET.ObjectStatus.DEAD) then
|
||||
self:E(self.lid..string.format("FF life is zero but no object dead event fired ==> object dead now for target object %s!", tostring(target.Name)))
|
||||
self:ObjectDead(target)
|
||||
damaged = true
|
||||
end
|
||||
|
||||
end
|
||||
@@ -554,7 +617,9 @@ function TARGET:onafterStatus(From, Event, To)
|
||||
-- Log output verbose=1.
|
||||
if self.verbose>=1 then
|
||||
local text=string.format("%s: Targets=%d/%d Life=%.1f/%.1f Damage=%.1f", fsmstate, self:CountTargets(), self.N0, self:GetLife(), self:GetLife0(), self:GetDamage())
|
||||
if damaged then
|
||||
if self:CountTargets() == 0 then
|
||||
text=text.." Dead!"
|
||||
elseif damaged then
|
||||
text=text.." Damaged!"
|
||||
end
|
||||
self:I(self.lid..text)
|
||||
@@ -570,11 +635,16 @@ function TARGET:onafterStatus(From, Event, To)
|
||||
end
|
||||
self:I(self.lid..text)
|
||||
end
|
||||
|
||||
|
||||
if self:CountTargets() == 0 then
|
||||
self:Dead()
|
||||
end
|
||||
|
||||
-- Update status again in 30 sec.
|
||||
if self:IsAlive() then
|
||||
self:__Status(-self.TStatus)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -588,10 +658,11 @@ end
|
||||
-- @param #string To To state.
|
||||
-- @param #TARGET.Object Target Target object.
|
||||
function TARGET:onafterObjectDamaged(From, Event, To, Target)
|
||||
|
||||
self:T({From, Event, To})
|
||||
-- Debug info.
|
||||
self:T(self.lid..string.format("Object %s damaged", Target.Name))
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- On after "ObjectDestroyed" event.
|
||||
@@ -601,7 +672,7 @@ end
|
||||
-- @param #string To To state.
|
||||
-- @param #TARGET.Object Target Target object.
|
||||
function TARGET:onafterObjectDestroyed(From, Event, To, Target)
|
||||
|
||||
self:T({From, Event, To})
|
||||
-- Debug message.
|
||||
self:T(self.lid..string.format("Object %s destroyed", Target.Name))
|
||||
|
||||
@@ -611,6 +682,7 @@ function TARGET:onafterObjectDestroyed(From, Event, To, Target)
|
||||
-- Call object dead event.
|
||||
self:ObjectDead(Target)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- On after "ObjectDead" event.
|
||||
@@ -620,7 +692,7 @@ end
|
||||
-- @param #string To To state.
|
||||
-- @param #TARGET.Object Target Target object.
|
||||
function TARGET:onafterObjectDead(From, Event, To, Target)
|
||||
|
||||
self:T({From, Event, To})
|
||||
-- Debug message.
|
||||
self:T(self.lid..string.format("Object %s dead", Target.Name))
|
||||
|
||||
@@ -653,8 +725,11 @@ function TARGET:onafterObjectDead(From, Event, To, Target)
|
||||
self:Dead()
|
||||
|
||||
end
|
||||
else
|
||||
self:Damaged()
|
||||
end
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- On after "Damaged" event.
|
||||
@@ -663,9 +738,11 @@ end
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function TARGET:onafterDamaged(From, Event, To)
|
||||
|
||||
self:T({From, Event, To})
|
||||
|
||||
self:T(self.lid..string.format("TARGET damaged"))
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- On after "Destroyed" event.
|
||||
@@ -674,11 +751,14 @@ end
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function TARGET:onafterDestroyed(From, Event, To)
|
||||
|
||||
|
||||
self:T({From, Event, To})
|
||||
|
||||
self:T(self.lid..string.format("TARGET destroyed"))
|
||||
|
||||
self:Dead()
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- On after "Dead" event.
|
||||
@@ -687,9 +767,11 @@ end
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function TARGET:onafterDead(From, Event, To)
|
||||
|
||||
self:T({From, Event, To})
|
||||
|
||||
self:T(self.lid..string.format("TARGET dead"))
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -707,7 +789,7 @@ function TARGET:OnEventUnitDeadOrLost(EventData)
|
||||
if self:IsElement(Name) and not self:IsCasualty(Name) then
|
||||
|
||||
-- Debug info.
|
||||
self:T3(self.lid..string.format("EVENT ID=%d: Unit %s dead or lost!", EventData.id, tostring(Name)))
|
||||
self:T(self.lid..string.format("EVENT ID=%d: Unit %s dead or lost!", EventData.id, tostring(Name)))
|
||||
|
||||
-- Add to the list of casualties.
|
||||
table.insert(self.casualties, Name)
|
||||
@@ -736,15 +818,19 @@ function TARGET:OnEventUnitDeadOrLost(EventData)
|
||||
|
||||
-- Debug message.
|
||||
self:T2(self.lid..string.format("EVENT ID=%d: target %s dead/lost ==> destroyed", EventData.id, tostring(target.Name)))
|
||||
|
||||
|
||||
target.Life = 0
|
||||
|
||||
-- Trigger object destroyed event.
|
||||
self:ObjectDestroyed(target)
|
||||
|
||||
|
||||
else
|
||||
|
||||
-- Debug message.
|
||||
self:T2(self.lid..string.format("EVENT ID=%d: target %s removed ==> dead", EventData.id, tostring(target.Name)))
|
||||
|
||||
|
||||
target.Life = 0
|
||||
|
||||
-- Trigger object dead event.
|
||||
self:ObjectDead(target)
|
||||
|
||||
@@ -755,7 +841,7 @@ function TARGET:OnEventUnitDeadOrLost(EventData)
|
||||
end -- Event belongs to this TARGET
|
||||
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -764,7 +850,7 @@ end
|
||||
|
||||
--- Create target data from a given object.
|
||||
-- @param #TARGET self
|
||||
-- @param Wrapper.Positionable#POSITIONABLE Object The target GROUP, UNIT, STATIC, AIRBASE or COORDINATE.
|
||||
-- @param Wrapper.Positionable#POSITIONABLE Object The target UNIT, GROUP, STATIC, SCENERY, AIRBASE, COORDINATE, ZONE, SET_GROUP, SET_UNIT, SET_STATIC, SET_SCENERY, SET_ZONE
|
||||
function TARGET:_AddObject(Object)
|
||||
|
||||
local target={} --#TARGET.Object
|
||||
@@ -848,8 +934,8 @@ function TARGET:_AddObject(Object)
|
||||
|
||||
target.Coordinate=scenery:GetCoordinate()
|
||||
|
||||
target.Life0=1
|
||||
target.Life=1
|
||||
target.Life0=scenery:GetLife0()
|
||||
target.Life=scenery:GetLife()
|
||||
|
||||
target.N0=target.N0+1
|
||||
|
||||
@@ -922,7 +1008,8 @@ function TARGET:_AddObject(Object)
|
||||
if self.category==nil then
|
||||
self.category=self:GetTargetCategory(target)
|
||||
end
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -991,8 +1078,9 @@ function TARGET:GetTargetLife(Target)
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.SCENERY then
|
||||
|
||||
if Target.Status==TARGET.ObjectStatus.ALIVE then
|
||||
return 1
|
||||
if Target.Object and Target.Object:IsAlive() then
|
||||
local life = Target.Object:GetLife()
|
||||
return life
|
||||
else
|
||||
return 0
|
||||
end
|
||||
@@ -1016,7 +1104,8 @@ function TARGET:GetTargetLife(Target)
|
||||
else
|
||||
self:E("ERROR: unknown target object type in GetTargetLife!")
|
||||
end
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Get current total life points. This is the sum of all target objects.
|
||||
@@ -1091,7 +1180,8 @@ function TARGET:GetTargetThreatLevelMax(Target)
|
||||
else
|
||||
self:E("ERROR: unknown target object type in GetTargetThreatLevel!")
|
||||
end
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
@@ -1380,6 +1470,11 @@ function TARGET:GetTargetName(Target)
|
||||
|
||||
return Zone:GetName()
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.SCENERY then
|
||||
|
||||
local Zone=Target.Object --Core.Zone#ZONE
|
||||
|
||||
return Zone:GetName()
|
||||
end
|
||||
|
||||
return "Unknown"
|
||||
@@ -1602,7 +1697,7 @@ function TARGET:GetObjective()
|
||||
|
||||
for _,_target in pairs(self.targets) do
|
||||
local target=_target --#TARGET.Object
|
||||
if target.Status==TARGET.ObjectStatus.ALIVE then
|
||||
if target.Status~=TARGET.ObjectStatus.DEAD then
|
||||
return target
|
||||
end
|
||||
end
|
||||
@@ -1662,7 +1757,7 @@ function TARGET:CountObjectives(Target)
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.SCENERY then
|
||||
|
||||
if Target.Status==TARGET.ObjectStatus.ALIVE then
|
||||
if Target.Status~=TARGET.ObjectStatus.DEAD then
|
||||
N=N+1
|
||||
end
|
||||
|
||||
@@ -1734,7 +1829,7 @@ function TARGET:IsCasualty(Name)
|
||||
end
|
||||
|
||||
for _,name in pairs(self.casualties) do
|
||||
if name==Name then
|
||||
if tostring(name)==tostring(Name) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user