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:
commit
1d04f7c945
@ -1953,7 +1953,7 @@ local function refct_from_id(id) -- refct = refct_from_id(CTypeID)
|
|||||||
unsigned = refct.unsigned,
|
unsigned = refct.unsigned,
|
||||||
size = bit.band(bit.rshift(ctype.info, 16), 127),
|
size = bit.band(bit.rshift(ctype.info, 16), 127),
|
||||||
}
|
}
|
||||||
refct.bool, refct.const, refct.volatile, refct.unsigned = nil
|
refct.bool, refct.const, refct.volatile, refct.unsigned = nil, nil, nil, nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if CT[4] then -- Merge sibling attributes onto this type.
|
if CT[4] then -- Merge sibling attributes onto this type.
|
||||||
|
|||||||
@ -17,7 +17,9 @@
|
|||||||
|
|
||||||
--- The AI_A2A_CAP class implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}
|
--- The AI_A2A_CAP class implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}
|
||||||
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- The AI_A2A_CAP is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_CAP process can be started using the **Start** event.
|
-- The AI_A2A_CAP is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_CAP process can be started using the **Start** event.
|
||||||
|
|||||||
@ -32,7 +32,9 @@
|
|||||||
-- [DCS WORLD - MOOSE - A2A GCICAP - Build an automatic A2A Defense System](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl0S4KMNUUJpaUs6zZHjLKNx)
|
-- [DCS WORLD - MOOSE - A2A GCICAP - Build an automatic A2A Defense System](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl0S4KMNUUJpaUs6zZHjLKNx)
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # QUICK START GUIDE
|
-- # QUICK START GUIDE
|
||||||
--
|
--
|
||||||
-- There are basically two classes available to model an A2A defense system.
|
-- There are basically two classes available to model an A2A defense system.
|
||||||
|
|||||||
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The AI_A2A_GCI is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_GCI process can be started using the **Start** event.
|
-- The AI_A2A_GCI is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_GCI process can be started using the **Start** event.
|
||||||
--
|
--
|
||||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||||
|
|||||||
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}.
|
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- The AI_A2A_PATROL is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_PATROL process can be started using the **Start** event.
|
-- The AI_A2A_PATROL is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_PATROL process can be started using the **Start** event.
|
||||||
|
|||||||
@ -15,7 +15,9 @@
|
|||||||
-- @extends AI.AI_A2A_Engage#AI_A2A_Engage -- TODO: Documentation. This class does not exist, unable to determine what it extends.
|
-- @extends AI.AI_A2A_Engage#AI_A2A_Engage -- TODO: Documentation. This class does not exist, unable to determine what it extends.
|
||||||
|
|
||||||
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
|
|||||||
@ -18,6 +18,8 @@
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
-- Therefore, this class is considered to be deprecated
|
-- Therefore, this class is considered to be deprecated
|
||||||
--
|
--
|
||||||
|
|||||||
@ -36,6 +36,8 @@
|
|||||||
--
|
--
|
||||||
-- # QUICK START GUIDE
|
-- # QUICK START GUIDE
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The following class is available to model an A2G defense system.
|
-- The following class is available to model an A2G defense system.
|
||||||
--
|
--
|
||||||
-- AI_A2G_DISPATCHER is the main A2G defense class that models the A2G defense system.
|
-- AI_A2G_DISPATCHER is the main A2G defense class that models the A2G defense system.
|
||||||
|
|||||||
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
--- Implements the core functions to SEAD intruders. Use the Engage trigger to intercept intruders.
|
--- Implements the core functions to SEAD intruders. Use the Engage trigger to intercept intruders.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The AI_A2G_SEAD is assigned a @{Wrapper.Group} and this must be done before the AI_A2G_SEAD process can be started using the **Start** event.
|
-- The AI_A2G_SEAD is assigned a @{Wrapper.Group} and this must be done before the AI_A2G_SEAD process can be started using the **Start** event.
|
||||||
--
|
--
|
||||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
--- The AI_AIR class implements the core functions to operate an AI @{Wrapper.Group}.
|
--- The AI_AIR class implements the core functions to operate an AI @{Wrapper.Group}.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- # 1) AI_AIR constructor
|
-- # 1) AI_AIR constructor
|
||||||
--
|
--
|
||||||
|
|||||||
@ -36,6 +36,8 @@
|
|||||||
--
|
--
|
||||||
-- # QUICK START GUIDE
|
-- # QUICK START GUIDE
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The following class is available to model an AIR defense system.
|
-- The following class is available to model an AIR defense system.
|
||||||
--
|
--
|
||||||
-- AI_AIR_DISPATCHER is the main AIR defense class that models the AIR defense system.
|
-- AI_AIR_DISPATCHER is the main AIR defense class that models the AIR defense system.
|
||||||
|
|||||||
@ -13,12 +13,14 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- @type AI_AIR_ENGAGE
|
--- @type AI_AIR_ENGAGE
|
||||||
-- @extends AI.AI_AIR#AI_AIR
|
-- @extends AI.AI_AIR#AI_AIR
|
||||||
|
|
||||||
|
|
||||||
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The AI_AIR_ENGAGE is assigned a @{Wrapper.Group} and this must be done before the AI_AIR_ENGAGE process can be started using the **Start** event.
|
-- The AI_AIR_ENGAGE is assigned a @{Wrapper.Group} and this must be done before the AI_AIR_ENGAGE process can be started using the **Start** event.
|
||||||
--
|
--
|
||||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||||
|
|||||||
@ -15,6 +15,8 @@
|
|||||||
--- The AI_AIR_PATROL class implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group}
|
--- The AI_AIR_PATROL class implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group}
|
||||||
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- The AI_AIR_PATROL is assigned a @{Wrapper.Group} and this must be done before the AI_AIR_PATROL process can be started using the **Start** event.
|
-- The AI_AIR_PATROL is assigned a @{Wrapper.Group} and this must be done before the AI_AIR_PATROL process can be started using the **Start** event.
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- @type AI_AIR_SQUADRON
|
--- @type AI_AIR_SQUADRON
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
@ -21,6 +21,8 @@
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
-- Therefore, this class is considered to be deprecated
|
-- Therefore, this class is considered to be deprecated
|
||||||
--
|
--
|
||||||
|
|||||||
@ -38,6 +38,8 @@
|
|||||||
|
|
||||||
--- Implements the core functions to provide BattleGround Air Interdiction in an Engage @{Core.Zone} by an AIR @{Wrapper.Controllable} or @{Wrapper.Group}.
|
--- Implements the core functions to provide BattleGround Air Interdiction in an Engage @{Core.Zone} by an AIR @{Wrapper.Controllable} or @{Wrapper.Group}.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The AI_BAI_ZONE runs a process. It holds an AI in a Patrol Zone and when the AI is commanded to engage, it will fly to an Engage Zone.
|
-- The AI_BAI_ZONE runs a process. It holds an AI in a Patrol Zone and when the AI is commanded to engage, it will fly to an Engage Zone.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
|
|||||||
@ -33,8 +33,9 @@
|
|||||||
-- @field Wrapper.Group#GROUP Test
|
-- @field Wrapper.Group#GROUP Test
|
||||||
-- @extends Core.Fsm#FSM_SET
|
-- @extends Core.Fsm#FSM_SET
|
||||||
|
|
||||||
|
--- 
|
||||||
--- Monitors and manages as many replacement AI groups as there are
|
--
|
||||||
|
-- Monitors and manages as many replacement AI groups as there are
|
||||||
-- CLIENTS in a SET\_CLIENT collection, which are not occupied by human players.
|
-- CLIENTS in a SET\_CLIENT collection, which are not occupied by human players.
|
||||||
-- In other words, use AI_BALANCER to simulate human behaviour by spawning in replacement AI in multi player missions.
|
-- In other words, use AI_BALANCER to simulate human behaviour by spawning in replacement AI in multi player missions.
|
||||||
--
|
--
|
||||||
|
|||||||
@ -39,6 +39,8 @@
|
|||||||
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Controllable} or @{Wrapper.Group}
|
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Controllable} or @{Wrapper.Group}
|
||||||
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- The AI_CAP_ZONE is assigned a @{Wrapper.Group} and this must be done before the AI_CAP_ZONE process can be started using the **Start** event.
|
-- The AI_CAP_ZONE is assigned a @{Wrapper.Group} and this must be done before the AI_CAP_ZONE process can be started using the **Start** event.
|
||||||
|
|||||||
@ -38,6 +38,9 @@
|
|||||||
-- @extends AI.AI_Patrol#AI_PATROL_ZONE
|
-- @extends AI.AI_Patrol#AI_PATROL_ZONE
|
||||||
|
|
||||||
--- Implements the core functions to provide Close Air Support in an Engage @{Core.Zone} by an AIR @{Wrapper.Controllable} or @{Wrapper.Group}.
|
--- Implements the core functions to provide Close Air Support in an Engage @{Core.Zone} by an AIR @{Wrapper.Controllable} or @{Wrapper.Group}.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The AI_CAS_ZONE runs a process. It holds an AI in a Patrol Zone and when the AI is commanded to engage, it will fly to an Engage Zone.
|
-- The AI_CAS_ZONE runs a process. It holds an AI in a Patrol Zone and when the AI is commanded to engage, it will fly to an Engage Zone.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
|
|||||||
@ -9,12 +9,14 @@
|
|||||||
-- @module AI.AI_Cargo
|
-- @module AI.AI_Cargo
|
||||||
-- @image Cargo.JPG
|
-- @image Cargo.JPG
|
||||||
|
|
||||||
-- @type AI_CARGO
|
--- @type AI_CARGO
|
||||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||||
|
|
||||||
|
|
||||||
--- Base class for the dynamic cargo handling capability for AI groups.
|
--- Base class for the dynamic cargo handling capability for AI groups.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Carriers can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Carriers can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
-- The AI_CARGO module uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
-- The AI_CARGO module uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
||||||
-- CARGO derived objects must be declared within the mission to make the AI_CARGO object recognize the cargo.
|
-- CARGO derived objects must be declared within the mission to make the AI_CARGO object recognize the cargo.
|
||||||
|
|||||||
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
--- Brings a dynamic cargo handling capability for an AI vehicle group.
|
--- Brings a dynamic cargo handling capability for an AI vehicle group.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Armoured Personnel Carriers (APC), Trucks, Jeeps and other ground based carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Armoured Personnel Carriers (APC), Trucks, Jeeps and other ground based carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
--
|
--
|
||||||
-- The AI_CARGO_APC class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
-- The AI_CARGO_APC class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
|
|
||||||
--- Brings a dynamic cargo handling capability for an AI airplane group.
|
--- Brings a dynamic cargo handling capability for an AI airplane group.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- Airplane carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation between airbases.
|
-- Airplane carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation between airbases.
|
||||||
--
|
--
|
||||||
|
|||||||
@ -22,6 +22,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # The dispatcher concept.
|
-- # The dispatcher concept.
|
||||||
--
|
--
|
||||||
-- Carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
|
|||||||
@ -36,6 +36,8 @@
|
|||||||
|
|
||||||
--- A dynamic cargo transportation capability for AI groups.
|
--- A dynamic cargo transportation capability for AI groups.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Armoured Personnel APCs (APC), Trucks, Jeeps and other carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Armoured Personnel APCs (APC), Trucks, Jeeps and other carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
--
|
--
|
||||||
-- The AI_CARGO_DISPATCHER_APC module is derived from the AI_CARGO_DISPATCHER module.
|
-- The AI_CARGO_DISPATCHER_APC module is derived from the AI_CARGO_DISPATCHER module.
|
||||||
|
|||||||
@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
--- Brings a dynamic cargo handling capability for AI groups.
|
--- Brings a dynamic cargo handling capability for AI groups.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Airplanes can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Airplanes can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
--
|
--
|
||||||
-- The AI_CARGO_DISPATCHER_AIRPLANE module is derived from the AI_CARGO_DISPATCHER module.
|
-- The AI_CARGO_DISPATCHER_AIRPLANE module is derived from the AI_CARGO_DISPATCHER module.
|
||||||
|
|||||||
@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
--- A dynamic cargo handling capability for AI helicopter groups.
|
--- A dynamic cargo handling capability for AI helicopter groups.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Helicopters can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Helicopters can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
|
|||||||
@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
--- A dynamic cargo transportation capability for AI groups.
|
--- A dynamic cargo transportation capability for AI groups.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Naval vessels can be mobilized to semi-intelligently transport cargo within the simulation.
|
-- Naval vessels can be mobilized to semi-intelligently transport cargo within the simulation.
|
||||||
--
|
--
|
||||||
-- The AI_CARGO_DISPATCHER_SHIP module is derived from the AI_CARGO_DISPATCHER module.
|
-- The AI_CARGO_DISPATCHER_SHIP module is derived from the AI_CARGO_DISPATCHER module.
|
||||||
|
|||||||
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
--- Brings a dynamic cargo handling capability for an AI helicopter group.
|
--- Brings a dynamic cargo handling capability for an AI helicopter group.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Helicopter carriers can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
-- Helicopter carriers can be mobilized to intelligently transport infantry and other cargo within the simulation.
|
||||||
--
|
--
|
||||||
-- The AI_CARGO_HELICOPTER class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
-- The AI_CARGO_HELICOPTER class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
--- Brings a dynamic cargo handling capability for an AI naval group.
|
--- Brings a dynamic cargo handling capability for an AI naval group.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Naval ships can be utilized to transport cargo around the map following naval shipping lanes.
|
-- Naval ships can be utilized to transport cargo around the map following naval shipping lanes.
|
||||||
-- The AI_CARGO_SHIP class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
-- The AI_CARGO_SHIP class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
|
||||||
-- @{Cargo.Cargo} must be declared within the mission or warehouse to make the AI_CARGO_SHIP recognize the cargo.
|
-- @{Cargo.Cargo} must be declared within the mission or warehouse to make the AI_CARGO_SHIP recognize the cargo.
|
||||||
|
|||||||
@ -25,6 +25,8 @@
|
|||||||
--
|
--
|
||||||
-- Allows you to interact with escorting AI on your flight and take the lead.
|
-- Allows you to interact with escorting AI on your flight and take the lead.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Each escorting group can be commanded with a complete set of radio commands (radio menu in your flight, and then F10).
|
-- Each escorting group can be commanded with a complete set of radio commands (radio menu in your flight, and then F10).
|
||||||
--
|
--
|
||||||
-- The radio commands will vary according the category of the group. The richest set of commands are with helicopters and airPlanes.
|
-- The radio commands will vary according the category of the group. The richest set of commands are with helicopters and airPlanes.
|
||||||
|
|||||||
@ -23,6 +23,8 @@
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
-- Therefore, this class is considered to be deprecated
|
-- Therefore, this class is considered to be deprecated
|
||||||
--
|
--
|
||||||
|
|||||||
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
--- Models the assignment of AI escorts to player flights upon request using the radio menu.
|
--- Models the assignment of AI escorts to player flights upon request using the radio menu.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
|
|||||||
@ -25,6 +25,8 @@
|
|||||||
--
|
--
|
||||||
-- Allows you to interact with escorting AI on your flight and take the lead.
|
-- Allows you to interact with escorting AI on your flight and take the lead.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Each escorting group can be commanded with a complete set of radio commands (radio menu in your flight, and then F10).
|
-- Each escorting group can be commanded with a complete set of radio commands (radio menu in your flight, and then F10).
|
||||||
--
|
--
|
||||||
-- The radio commands will vary according the category of the group. The richest set of commands are with helicopters and airPlanes.
|
-- The radio commands will vary according the category of the group. The richest set of commands are with helicopters and airPlanes.
|
||||||
|
|||||||
@ -40,6 +40,8 @@
|
|||||||
|
|
||||||
|
|
||||||
--- Build large formations, make AI follow a @{Wrapper.Client#CLIENT} (player) leader or a @{Wrapper.Unit#UNIT} (AI) leader.
|
--- Build large formations, make AI follow a @{Wrapper.Client#CLIENT} (player) leader or a @{Wrapper.Unit#UNIT} (AI) leader.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- AI_FORMATION makes AI @{Wrapper.Group#GROUP}s fly in formation of various compositions.
|
-- AI_FORMATION makes AI @{Wrapper.Group#GROUP}s fly in formation of various compositions.
|
||||||
-- The AI_FORMATION class models formations in a different manner than the internal DCS formation logic!!!
|
-- The AI_FORMATION class models formations in a different manner than the internal DCS formation logic!!!
|
||||||
|
|||||||
@ -48,6 +48,8 @@
|
|||||||
|
|
||||||
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Controllable} or @{Wrapper.Group}.
|
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Controllable} or @{Wrapper.Group}.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- The AI_PATROL_ZONE is assigned a @{Wrapper.Group} and this must be done before the AI_PATROL_ZONE process can be started using the **Start** event.
|
-- The AI_PATROL_ZONE is assigned a @{Wrapper.Group} and this must be done before the AI_PATROL_ZONE process can be started using the **Start** event.
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
--- **Actions** - ACT_ACCOUNT_ classes **account for** (detect, count & report) various DCS events occurring on UNITs.
|
--- **Actions** - ACT_ACCOUNT_ classes **account for** (detect, count & report) various DCS events occurring on UNITs.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -8,9 +8,11 @@
|
|||||||
-- @image MOOSE.JPG
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
do -- ACT_ACCOUNT
|
do -- ACT_ACCOUNT
|
||||||
|
|
||||||
--- # @{#ACT_ACCOUNT} FSM class, extends @{Core.Fsm#FSM_PROCESS}
|
--- # @{#ACT_ACCOUNT} FSM class, extends @{Core.Fsm#FSM_PROCESS}
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- ## ACT_ACCOUNT state machine:
|
-- ## ACT_ACCOUNT state machine:
|
||||||
--
|
--
|
||||||
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
|
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
|
||||||
@ -133,7 +135,7 @@ do -- ACT_ACCOUNT
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
function ACT_ACCOUNT:onafterEvent( ProcessUnit, From, Event, To, Event )
|
function ACT_ACCOUNT:onafterEvent( ProcessUnit, From, Event, To )
|
||||||
|
|
||||||
self:__NoMore( 1 )
|
self:__NoMore( 1 )
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
--- (SP) (MP) (FSM) Accept or reject process for player (task) assignments.
|
--- (SP) (MP) (FSM) Accept or reject process for player (task) assignments.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- # @{#ACT_ASSIGN} FSM template class, extends @{Core.Fsm#FSM_PROCESS}
|
-- # @{#ACT_ASSIGN} FSM template class, extends @{Core.Fsm#FSM_PROCESS}
|
||||||
--
|
--
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
--- (SP) (MP) (FSM) Route AI or players through waypoints or to zones.
|
--- (SP) (MP) (FSM) Route AI or players through waypoints or to zones.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
-- ## ACT_ASSIST state machine:
|
-- ## ACT_ASSIST state machine:
|
||||||
--
|
--
|
||||||
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
|
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # @{#ACT_ROUTE} FSM class, extends @{Core.Fsm#FSM_PROCESS}
|
-- # @{#ACT_ROUTE} FSM class, extends @{Core.Fsm#FSM_PROCESS}
|
||||||
--
|
--
|
||||||
-- ## ACT_ROUTE state machine:
|
-- ## ACT_ROUTE state machine:
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # 1) MOOSE Cargo System.
|
-- # 1) MOOSE Cargo System.
|
||||||
--
|
--
|
||||||
-- #### Those who have used the mission editor, know that the DCS mission editor provides cargo facilities.
|
-- #### Those who have used the mission editor, know that the DCS mission editor provides cargo facilities.
|
||||||
|
|||||||
@ -22,6 +22,9 @@ do -- CARGO_CRATE
|
|||||||
-- @type CARGO_CRATE
|
-- @type CARGO_CRATE
|
||||||
-- @extends Cargo.Cargo#CARGO_REPRESENTABLE
|
-- @extends Cargo.Cargo#CARGO_REPRESENTABLE
|
||||||
|
|
||||||
|
---
|
||||||
|
-- 
|
||||||
|
--
|
||||||
--- Defines a cargo that is represented by a UNIT object within the simulator, and can be transported by a carrier.
|
--- Defines a cargo that is represented by a UNIT object within the simulator, and can be transported by a carrier.
|
||||||
-- Use the event functions as described above to Load, UnLoad, Board, UnBoard the CARGO\_CRATE objects to and from carriers.
|
-- Use the event functions as described above to Load, UnLoad, Board, UnBoard the CARGO\_CRATE objects to and from carriers.
|
||||||
--
|
--
|
||||||
|
|||||||
@ -26,6 +26,8 @@ do -- CARGO_GROUP
|
|||||||
-- @extends Cargo.Cargo#CARGO_REPORTABLE
|
-- @extends Cargo.Cargo#CARGO_REPORTABLE
|
||||||
|
|
||||||
--- Defines a cargo that is represented by a @{Wrapper.Group} object within the simulator.
|
--- Defines a cargo that is represented by a @{Wrapper.Group} object within the simulator.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
-- The cargo can be Loaded, UnLoaded, Boarded, UnBoarded to and from Carriers.
|
-- The cargo can be Loaded, UnLoaded, Boarded, UnBoarded to and from Carriers.
|
||||||
--
|
--
|
||||||
-- The above cargo classes are used by the following AI_CARGO_ classes to allow AI groups to transport cargo:
|
-- The above cargo classes are used by the following AI_CARGO_ classes to allow AI groups to transport cargo:
|
||||||
|
|||||||
@ -32,6 +32,8 @@ do -- CARGO_SLINGLOAD
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
-- Therefore, this class is considered to be deprecated
|
-- Therefore, this class is considered to be deprecated
|
||||||
--
|
--
|
||||||
|
|||||||
@ -30,6 +30,8 @@ do -- CARGO_UNIT
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
-- Therefore, this class is considered to be deprecated
|
-- Therefore, this class is considered to be deprecated
|
||||||
--
|
--
|
||||||
|
|||||||
@ -974,7 +974,7 @@ do -- Scheduling
|
|||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called.
|
-- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called.
|
||||||
-- @param #function SchedulerFunction The event function to be called when a timer event occurs. The event function needs to accept the parameters specified in SchedulerArguments.
|
-- @param #function SchedulerFunction The event function to be called when a timer event occurs. The event function needs to accept the parameters specified in SchedulerArguments.
|
||||||
-- @param #table ... Optional arguments that can be given as part of scheduler. The arguments need to be given as a table { param1, param 2, ... }.
|
-- @param ... Optional arguments that can be given as part of scheduler. The arguments need to be given as a table { param1, param 2, ... }.
|
||||||
-- @return #string The Schedule ID of the planned schedule.
|
-- @return #string The Schedule ID of the planned schedule.
|
||||||
function BASE:ScheduleOnce( Start, SchedulerFunction, ... )
|
function BASE:ScheduleOnce( Start, SchedulerFunction, ... )
|
||||||
|
|
||||||
|
|||||||
@ -872,6 +872,8 @@ end
|
|||||||
-- @return Wrapper.Group#GROUP The found GROUP.
|
-- @return Wrapper.Group#GROUP The found GROUP.
|
||||||
function DATABASE:FindGroup( GroupName )
|
function DATABASE:FindGroup( GroupName )
|
||||||
|
|
||||||
|
if type(GroupName) ~= "string" or GroupName == "" then return end
|
||||||
|
|
||||||
local GroupFound = self.GROUPS[GroupName]
|
local GroupFound = self.GROUPS[GroupName]
|
||||||
|
|
||||||
if GroupFound == nil and GroupName ~= nil and self.Templates.Groups[GroupName] == nil then
|
if GroupFound == nil and GroupName ~= nil and self.Templates.Groups[GroupName] == nil then
|
||||||
|
|||||||
@ -206,7 +206,7 @@ end
|
|||||||
function MESSAGE:ToGroup( Group, Settings )
|
function MESSAGE:ToGroup( Group, Settings )
|
||||||
self:F( Group.GroupName )
|
self:F( Group.GroupName )
|
||||||
|
|
||||||
if Group then
|
if Group and Group:IsAlive() then
|
||||||
|
|
||||||
if self.MessageType then
|
if self.MessageType then
|
||||||
local Settings = Settings or (Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() )) or _SETTINGS -- Core.Settings#SETTINGS
|
local Settings = Settings or (Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() )) or _SETTINGS -- Core.Settings#SETTINGS
|
||||||
@ -231,7 +231,7 @@ end
|
|||||||
function MESSAGE:ToUnit( Unit, Settings )
|
function MESSAGE:ToUnit( Unit, Settings )
|
||||||
self:F( Unit.IdentifiableName )
|
self:F( Unit.IdentifiableName )
|
||||||
|
|
||||||
if Unit then
|
if Unit and Unit:IsAlive() then
|
||||||
|
|
||||||
if self.MessageType then
|
if self.MessageType then
|
||||||
local Settings = Settings or ( Unit and _DATABASE:GetPlayerSettings( Unit:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
|
local Settings = Settings or ( Unit and _DATABASE:GetPlayerSettings( Unit:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
do -- COORDINATE
|
do -- COORDINATE
|
||||||
|
|
||||||
---
|
--- Coordinate class
|
||||||
-- @type COORDINATE
|
-- @type COORDINATE
|
||||||
-- @field #string ClassName Name of the class
|
-- @field #string ClassName Name of the class
|
||||||
-- @field #number x Component of the 3D vector.
|
-- @field #number x Component of the 3D vector.
|
||||||
@ -59,6 +59,10 @@ do -- COORDINATE
|
|||||||
-- * @{#COORDINATE.SmokeOrange}(): To smoke the point in orange.
|
-- * @{#COORDINATE.SmokeOrange}(): To smoke the point in orange.
|
||||||
-- * @{#COORDINATE.SmokeWhite}(): To smoke the point in white.
|
-- * @{#COORDINATE.SmokeWhite}(): To smoke the point in white.
|
||||||
-- * @{#COORDINATE.SmokeGreen}(): To smoke the point in green.
|
-- * @{#COORDINATE.SmokeGreen}(): To smoke the point in green.
|
||||||
|
-- * @{#COORDINATE.SetSmokeOffsetDirection}(): To set an offset point direction for smoke.
|
||||||
|
-- * @{#COORDINATE.SetSmokeOffsetDistance}(): To set an offset point distance for smoke.
|
||||||
|
-- * @{#COORDINATE.SwitchSmokeOffsetOn}(): To set an offset point for smoke to on.
|
||||||
|
-- * @{#COORDINATE.SwitchSmokeOffsetOff}(): To set an offset point for smoke to off.
|
||||||
--
|
--
|
||||||
-- ## 2.2) Flare
|
-- ## 2.2) Flare
|
||||||
--
|
--
|
||||||
@ -2118,14 +2122,112 @@ do -- COORDINATE
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Smokes the point in a color.
|
--- Create colored smoke the point. The smoke we last up to 5 min (DCS limitation) but you can optionally specify a shorter duration or stop it manually.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param Utilities.Utils#SMOKECOLOR SmokeColor
|
-- @param #number SmokeColor Color of smoke, e.g. `SMOKECOLOR.Green` for green smoke.
|
||||||
-- @param #string name (Optional) Name if you want to stop the smoke early (normal duration: 5mins)
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
function COORDINATE:Smoke( SmokeColor, name )
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
self:F2( { SmokeColor } )
|
-- @param #string Name (Optional) Name if you want to stop the smoke early (normal duration: 5mins)
|
||||||
self.firename = name or "Smoke-"..math.random(1,100000)
|
-- @param #boolean Offset (Optional) If true, offset the smokle a bit.
|
||||||
trigger.action.smoke( self:GetVec3(), SmokeColor, self.firename )
|
-- @param #number Direction (Optional) If Offset is true this is the direction of the offset, 1-359 (degrees). Default random.
|
||||||
|
-- @param #number Distance (Optional) If Offset is true this is the distance of the offset in meters. Default random 10-20.
|
||||||
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:Smoke( SmokeColor, Duration, Delay, Name, Offset,Direction,Distance)
|
||||||
|
self:F2( { SmokeColor, Name, Duration, Delay, Offset } )
|
||||||
|
|
||||||
|
SmokeColor=SmokeColor or SMOKECOLOR.Green
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
self:ScheduleOnce(Delay, COORDINATE.Smoke, self, SmokeColor, Duration, 0, Name, Direction,Distance)
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Create a name which is used to stop the smoke manually
|
||||||
|
self.firename = Name or "Smoke-"..math.random(1,100000)
|
||||||
|
|
||||||
|
-- Create smoke
|
||||||
|
if Offset or self.SmokeOffset then
|
||||||
|
local Angle = Direction or self:GetSmokeOffsetDirection()
|
||||||
|
local Distance = Distance or self:GetSmokeOffsetDistance()
|
||||||
|
local newpos = self:Translate(Distance,Angle,true,false)
|
||||||
|
local newvec3 = newpos:GetVec3()
|
||||||
|
trigger.action.smoke( newvec3, SmokeColor, self.firename )
|
||||||
|
else
|
||||||
|
trigger.action.smoke( self:GetVec3(), SmokeColor, self.firename )
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Stop smoke
|
||||||
|
if Duration and Duration>0 then
|
||||||
|
self:ScheduleOnce(Duration, COORDINATE.StopSmoke, self, self.firename )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the offset direction when using `COORDINATE:Smoke()`.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #number Direction in degrees.
|
||||||
|
function COORDINATE:GetSmokeOffsetDirection()
|
||||||
|
local direction = self.SmokeOffsetDirection or math.random(1,359)
|
||||||
|
return direction
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the offset direction when using `COORDINATE:Smoke()`.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number Direction (Optional) This is the direction of the offset, 1-359 (degrees). Default random.
|
||||||
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SetSmokeOffsetDirection(Direction)
|
||||||
|
if self then
|
||||||
|
self.SmokeOffsetDirection = Direction or math.random(1,359)
|
||||||
|
return self
|
||||||
|
else
|
||||||
|
COORDINATE.SmokeOffsetDirection = Direction or math.random(1,359)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the offset distance when using `COORDINATE:Smoke()`.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #number Distance Distance in meters.
|
||||||
|
function COORDINATE:GetSmokeOffsetDistance()
|
||||||
|
local distance = self.SmokeOffsetDistance or math.random(10,20)
|
||||||
|
return distance
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the offset distance when using `COORDINATE:Smoke()`.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number Distance (Optional) This is the distance of the offset in meters. Default random 10-20.
|
||||||
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SetSmokeOffsetDistance(Distance)
|
||||||
|
if self then
|
||||||
|
self.SmokeOffsetDistance = Distance or math.random(10,20)
|
||||||
|
return self
|
||||||
|
else
|
||||||
|
COORDINATE.SmokeOffsetDistance = Distance or math.random(10,20)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the offset on when using `COORDINATE:Smoke()`.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SwitchSmokeOffsetOn()
|
||||||
|
if self then
|
||||||
|
self.SmokeOffset = true
|
||||||
|
return self
|
||||||
|
else
|
||||||
|
COORDINATE.SmokeOffset = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the offset off when using `COORDINATE:Smoke()`.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SwitchSmokeOffsetOff()
|
||||||
|
if self then
|
||||||
|
self.SmokeOffset = false
|
||||||
|
return self
|
||||||
|
else
|
||||||
|
COORDINATE.SmokeOffset = false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Stops smoking the point in a color.
|
--- Stops smoking the point in a color.
|
||||||
@ -2137,49 +2239,83 @@ do -- COORDINATE
|
|||||||
|
|
||||||
--- Smoke the COORDINATE Green.
|
--- Smoke the COORDINATE Green.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
function COORDINATE:SmokeGreen()
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
self:F2()
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
self:Smoke( SMOKECOLOR.Green )
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SmokeGreen(Duration, Delay)
|
||||||
|
self:Smoke( SMOKECOLOR.Green, Duration, Delay )
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Smoke the COORDINATE Red.
|
--- Smoke the COORDINATE Red.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
function COORDINATE:SmokeRed()
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
self:F2()
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
self:Smoke( SMOKECOLOR.Red )
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SmokeRed(Duration, Delay)
|
||||||
|
self:Smoke( SMOKECOLOR.Red, Duration, Delay )
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Smoke the COORDINATE White.
|
--- Smoke the COORDINATE White.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
function COORDINATE:SmokeWhite()
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
self:F2()
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
self:Smoke( SMOKECOLOR.White )
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SmokeWhite(Duration, Delay)
|
||||||
|
self:Smoke( SMOKECOLOR.White, Duration, Delay )
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Smoke the COORDINATE Orange.
|
--- Smoke the COORDINATE Orange.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
function COORDINATE:SmokeOrange()
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
self:F2()
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
self:Smoke( SMOKECOLOR.Orange )
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SmokeOrange(Duration, Delay)
|
||||||
|
self:Smoke( SMOKECOLOR.Orange, Duration, Delay )
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Smoke the COORDINATE Blue.
|
--- Smoke the COORDINATE Blue.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
function COORDINATE:SmokeBlue()
|
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
|
||||||
self:F2()
|
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
|
||||||
self:Smoke( SMOKECOLOR.Blue )
|
-- @return #COORDINATE self
|
||||||
|
function COORDINATE:SmokeBlue(Duration, Delay)
|
||||||
|
self:Smoke( SMOKECOLOR.Blue, Duration, Delay )
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Big smoke and fire at the coordinate.
|
--- Big smoke and fire at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param Utilities.Utils#BIGSMOKEPRESET preset Smoke preset (1=small smoke and fire, 2=medium smoke and fire, 3=large smoke and fire, 4=huge smoke and fire, 5=small smoke, 6=medium smoke, 7=large smoke, 8=huge smoke).
|
-- @param #number Preset Smoke preset (1=small smoke and fire, 2=medium smoke and fire, 3=large smoke and fire, 4=huge smoke and fire, 5=small smoke, 6=medium smoke, 7=large smoke, 8=huge smoke).
|
||||||
-- @param #number density (Optional) Smoke density. Number in [0,...,1]. Default 0.5.
|
-- @param #number Density (Optional) Smoke density. Number in [0,...,1]. Default 0.5.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
function COORDINATE:BigSmokeAndFire( preset, density, name )
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
self:F2( { preset=preset, density=density } )
|
-- @param #string Name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
density=density or 0.5
|
-- @return #COORDINATE self
|
||||||
self.firename = name or "Fire-"..math.random(1,10000)
|
function COORDINATE:BigSmokeAndFire( Preset, Density, Duration, Delay, Name )
|
||||||
trigger.action.effectSmokeBig( self:GetVec3(), preset, density, self.firename )
|
self:F2( { preset=Preset, density=Density } )
|
||||||
|
|
||||||
|
Preset=Preset or BIGSMOKEPRESET.SmallSmokeAndFire
|
||||||
|
Density=Density or 0.5
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
self:ScheduleOnce(Delay, COORDINATE.BigSmokeAndFire, self, Preset, Density, Duration, 0, Name)
|
||||||
|
else
|
||||||
|
|
||||||
|
self.firename = Name or "Fire-"..math.random(1,10000)
|
||||||
|
|
||||||
|
trigger.action.effectSmokeBig( self:GetVec3(), Preset, Density, self.firename )
|
||||||
|
|
||||||
|
-- Stop smoke
|
||||||
|
if Duration and Duration>0 then
|
||||||
|
self:ScheduleOnce(Duration, COORDINATE.StopBigSmokeAndFire, self, self.firename )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Stop big smoke and fire at the coordinate.
|
--- Stop big smoke and fire at the coordinate.
|
||||||
@ -2192,82 +2328,98 @@ do -- COORDINATE
|
|||||||
|
|
||||||
--- Small smoke and fire at the coordinate.
|
--- Small smoke and fire at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number Density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
function COORDINATE:BigSmokeAndFireSmall( density, name )
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
self:F2( { density=density } )
|
-- @param #string Name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
density=density or 0.5
|
-- @return #COORDINATE self
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmokeAndFire, density, name)
|
function COORDINATE:BigSmokeAndFireSmall( Density, Duration, Delay, Name )
|
||||||
|
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmokeAndFire, Density, Duration, Delay, Name)
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Medium smoke and fire at the coordinate.
|
--- Medium smoke and fire at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeAndFireMedium( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeAndFireMedium( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmokeAndFire, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmokeAndFire, density, name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Large smoke and fire at the coordinate.
|
--- Large smoke and fire at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeAndFireLarge( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeAndFireLarge( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmokeAndFire, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmokeAndFire, density, name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Huge smoke and fire at the coordinate.
|
--- Huge smoke and fire at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeAndFireHuge( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeAndFireHuge( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmokeAndFire, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmokeAndFire, density, name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Small smoke at the coordinate.
|
--- Small smoke at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeSmall( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeSmall( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmoke, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmoke, density, name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Medium smoke at the coordinate.
|
--- Medium smoke at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeMedium( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeMedium( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmoke, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmoke, density, name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Large smoke at the coordinate.
|
--- Large smoke at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeLarge( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeLarge( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmoke, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmoke, density,name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Huge smoke at the coordinate.
|
--- Huge smoke at the coordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
|
||||||
|
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
|
||||||
|
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
|
||||||
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
|
||||||
function COORDINATE:BigSmokeHuge( density, name )
|
-- @return #COORDINATE self
|
||||||
self:F2( { density=density } )
|
function COORDINATE:BigSmokeHuge( Density, Duration, Delay, Name )
|
||||||
density=density or 0.5
|
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmoke, Density, Duration, Delay, Name)
|
||||||
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmoke, density,name)
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Flares the point in a color.
|
--- Flares the point in a color.
|
||||||
@ -2921,8 +3073,10 @@ do -- COORDINATE
|
|||||||
local sunrise=UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, true, Tdiff)
|
local sunrise=UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, true, Tdiff)
|
||||||
local sunset=UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, false, Tdiff)
|
local sunset=UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, false, Tdiff)
|
||||||
|
|
||||||
if sunrise == "N/R" then return false end
|
if type(sunrise) == "string" or type(sunset) == "string" then
|
||||||
if sunrise == "N/S" then return true end
|
if sunrise == "N/R" then return false end
|
||||||
|
if sunset == "N/S" then return true end
|
||||||
|
end
|
||||||
|
|
||||||
local time=UTILS.ClockToSeconds(clock)
|
local time=UTILS.ClockToSeconds(clock)
|
||||||
|
|
||||||
@ -2940,6 +3094,11 @@ do -- COORDINATE
|
|||||||
|
|
||||||
-- Todays sun set in sec.
|
-- Todays sun set in sec.
|
||||||
local sunset=self:GetSunset(true)
|
local sunset=self:GetSunset(true)
|
||||||
|
|
||||||
|
if type(sunrise) == "string" or type(sunset) == "string" then
|
||||||
|
if sunrise == "N/R" then return false end
|
||||||
|
if sunset == "N/S" then return true end
|
||||||
|
end
|
||||||
|
|
||||||
-- Seconds passed since midnight.
|
-- Seconds passed since midnight.
|
||||||
local time=UTILS.SecondsOfToday()
|
local time=UTILS.SecondsOfToday()
|
||||||
|
|||||||
@ -198,7 +198,7 @@ end -- env
|
|||||||
|
|
||||||
do -- radio
|
do -- radio
|
||||||
|
|
||||||
---@type radio
|
--@type radio
|
||||||
-- @field #radio.modulation modulation
|
-- @field #radio.modulation modulation
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
-- @module Functional.Mantis
|
-- @module Functional.Mantis
|
||||||
-- @image Functional.Mantis.jpg
|
-- @image Functional.Mantis.jpg
|
||||||
--
|
--
|
||||||
-- Last Update: Mar 2025
|
-- Last Update: May 2025
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **MANTIS** class, extends Core.Base#BASE
|
--- **MANTIS** class, extends Core.Base#BASE
|
||||||
@ -62,7 +62,9 @@
|
|||||||
-- @field #table FilterZones Table of Core.Zone#ZONE Zones Consider SAM groups in this zone(s) only for this MANTIS instance, must be handed as #table of Zone objects.
|
-- @field #table FilterZones Table of Core.Zone#ZONE Zones Consider SAM groups in this zone(s) only for this MANTIS instance, must be handed as #table of Zone objects.
|
||||||
-- @field #boolean SmokeDecoy If true, smoke short range SAM units as decoy if a plane is in firing range.
|
-- @field #boolean SmokeDecoy If true, smoke short range SAM units as decoy if a plane is in firing range.
|
||||||
-- @field #number SmokeDecoyColor Color to use, defaults to SMOKECOLOR.White
|
-- @field #number SmokeDecoyColor Color to use, defaults to SMOKECOLOR.White
|
||||||
-- @field #number checkcounter Counter for SAM Table refreshes
|
-- @field #number checkcounter Counter for SAM Table refreshes.
|
||||||
|
-- @field #number DLinkCacheTime Seconds after which cached contacts in DLink will decay.
|
||||||
|
-- @field #boolean logsamstatus Log SAM status in dcs.log every cycle if true
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
@ -74,10 +76,9 @@
|
|||||||
--
|
--
|
||||||
-- * Moose derived Modular, Automatic and Network capable Targeting and Interception System.
|
-- * Moose derived Modular, Automatic and Network capable Targeting and Interception System.
|
||||||
-- * Controls a network of SAM sites. Uses detection to switch on the SAM site closest to the enemy.
|
-- * Controls a network of SAM sites. Uses detection to switch on the SAM site closest to the enemy.
|
||||||
-- * **Automatic mode** (default since 0.8) will set-up your SAM site network automatically for you
|
-- * **Automatic mode** (default) will set-up your SAM site network automatically for you.
|
||||||
-- * **Classic mode** behaves like before
|
-- * Leverage evasiveness from SEAD, leverage attack range setting.
|
||||||
-- * Leverage evasiveness from SEAD, leverage attack range setting
|
-- * Automatic setup of SHORAD based on groups of the class "short-range".
|
||||||
-- * Automatic setup of SHORAD based on groups of the class "short-range"
|
|
||||||
--
|
--
|
||||||
-- # 0. Base considerations and naming conventions
|
-- # 0. Base considerations and naming conventions
|
||||||
--
|
--
|
||||||
@ -133,10 +134,10 @@
|
|||||||
--
|
--
|
||||||
-- # 0.1 Set-up in the mission editor
|
-- # 0.1 Set-up in the mission editor
|
||||||
--
|
--
|
||||||
-- Set up your SAM sites in the mission editor. Name the groups using a systematic approach like above.
|
-- Set up your SAM sites in the mission editor. Name the groups using a systematic approach like above.Can be e.g. AWACS or a combination of AWACS and Search Radars like e.g. EWR 1L13 etc.
|
||||||
-- Set up your EWR system in the mission editor. Name the groups using a systematic approach like above. Can be e.g. AWACS or a combination of AWACS and Search Radars like e.g. EWR 1L13 etc.
|
|
||||||
-- Search Radars usually have "SR" or "STR" in their names. Use the encyclopedia in the mission editor to inform yourself.
|
-- Search Radars usually have "SR" or "STR" in their names. Use the encyclopedia in the mission editor to inform yourself.
|
||||||
-- Set up your SHORAD systems. They need to be **close** to (i.e. around) the SAM sites to be effective. Use **one** group per SAM location. SA-15 TOR systems offer a good missile defense.
|
-- Set up your SHORAD systems. They need to be **close** to (i.e. around) the SAM sites to be effective. Use **one unit ** per group (multiple groups) for the SAM location.
|
||||||
|
-- Else, evasive manoevers might club up all defenders in one place. Red SA-15 TOR systems offer a good missile defense.
|
||||||
--
|
--
|
||||||
-- [optional] Set up your HQ. Can be any group, e.g. a command vehicle.
|
-- [optional] Set up your HQ. Can be any group, e.g. a command vehicle.
|
||||||
--
|
--
|
||||||
@ -188,7 +189,7 @@
|
|||||||
--
|
--
|
||||||
-- ## 2.1 Auto mode features
|
-- ## 2.1 Auto mode features
|
||||||
--
|
--
|
||||||
-- ### 2.1.1 You can now add Accept-, Reject- and Conflict-Zones to your setup, e.g. to consider borders or de-militarized zones:
|
-- ### 2.1.1 You can add Accept-, Reject- and Conflict-Zones to your setup, e.g. to consider borders or de-militarized zones:
|
||||||
--
|
--
|
||||||
-- -- Parameters are tables of Core.Zone#ZONE objects!
|
-- -- Parameters are tables of Core.Zone#ZONE objects!
|
||||||
-- -- This is effectively a 3-stage filter allowing for zone overlap. A coordinate is accepted first when
|
-- -- This is effectively a 3-stage filter allowing for zone overlap. A coordinate is accepted first when
|
||||||
@ -205,9 +206,6 @@
|
|||||||
-- ### 2.1.3 SHORAD/Point defense will automatically be added from SAM sites of type "point" or if the range is less than 5km or if the type is AAA.
|
-- ### 2.1.3 SHORAD/Point defense will automatically be added from SAM sites of type "point" or if the range is less than 5km or if the type is AAA.
|
||||||
--
|
--
|
||||||
-- ### 2.1.4 Advanced features
|
-- ### 2.1.4 Advanced features
|
||||||
--
|
|
||||||
-- -- Option to switch off auto mode **before** you start MANTIS (not recommended)
|
|
||||||
-- mybluemantis.automode = false
|
|
||||||
--
|
--
|
||||||
-- -- Option to set the scale of the activation range, i.e. don't activate at the fringes of max range, defaults below.
|
-- -- Option to set the scale of the activation range, i.e. don't activate at the fringes of max range, defaults below.
|
||||||
-- -- also see engagerange below.
|
-- -- also see engagerange below.
|
||||||
@ -220,6 +218,12 @@
|
|||||||
--
|
--
|
||||||
-- -- For some scenarios, like Cold War, it might be useful not to activate SAMs if friendly aircraft are around to avoid death by friendly fire.
|
-- -- For some scenarios, like Cold War, it might be useful not to activate SAMs if friendly aircraft are around to avoid death by friendly fire.
|
||||||
-- mybluemantis.checkforfriendlies = true
|
-- mybluemantis.checkforfriendlies = true
|
||||||
|
--
|
||||||
|
-- ### 2.1.6 Shoot & Scoot
|
||||||
|
--
|
||||||
|
-- -- Option to make the (driveable) SHORAD units drive around and shuffle positions
|
||||||
|
-- -- We use a SET_ZONE for that, number of zones to consider defaults to three, Random is true for random coordinates and Formation is e.g. "Vee".
|
||||||
|
-- mybluemantis:AddScootZones(ZoneSet, Number, Random, Formation)
|
||||||
--
|
--
|
||||||
-- # 3. Default settings [both modes unless stated otherwise]
|
-- # 3. Default settings [both modes unless stated otherwise]
|
||||||
--
|
--
|
||||||
@ -242,26 +246,8 @@
|
|||||||
-- E.g. mymantis:SetAdvancedMode( true, 90 )
|
-- E.g. mymantis:SetAdvancedMode( true, 90 )
|
||||||
--
|
--
|
||||||
-- Use this option if you want to make use of or allow advanced SEAD tactics.
|
-- Use this option if you want to make use of or allow advanced SEAD tactics.
|
||||||
--
|
|
||||||
-- # 5. Integrate SHORAD [classic mode, not necessary in automode, not recommended for manual setup]
|
|
||||||
--
|
|
||||||
-- You can also choose to integrate Mantis with @{Functional.Shorad#SHORAD} for protection against HARMs and AGMs manually. When SHORAD detects a missile fired at one of MANTIS' SAM sites, it will activate SHORAD systems in
|
|
||||||
-- the given defense checkradius around that SAM site. Create a SHORAD object first, then integrate with MANTIS like so:
|
|
||||||
--
|
|
||||||
-- local SamSet = SET_GROUP:New():FilterPrefixes("Blue SAM"):FilterCoalitions("blue"):FilterStart()
|
|
||||||
-- myshorad = SHORAD:New("BlueShorad", "Blue SHORAD", SamSet, 22000, 600, "blue")
|
|
||||||
-- -- now set up MANTIS
|
|
||||||
-- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
|
|
||||||
-- mymantis:AddShorad(myshorad,720)
|
|
||||||
-- mymantis:Start()
|
|
||||||
--
|
--
|
||||||
-- If you systematically name your SHORAD groups starting with "Blue SHORAD" you'll need exactly **one** SHORAD instance to manage all SHORAD groups.
|
-- # 5. Integrated SEAD
|
||||||
--
|
|
||||||
-- (Optionally) you can remove the link later on with
|
|
||||||
--
|
|
||||||
-- mymantis:RemoveShorad()
|
|
||||||
--
|
|
||||||
-- # 6. Integrated SEAD
|
|
||||||
--
|
--
|
||||||
-- MANTIS is using @{Functional.Sead#SEAD} internally to both detect and evade HARM attacks. No extra efforts needed to set this up!
|
-- MANTIS is using @{Functional.Sead#SEAD} internally to both detect and evade HARM attacks. No extra efforts needed to set this up!
|
||||||
-- Once a HARM attack is detected, MANTIS (via SEAD) will shut down the radars of the attacked SAM site and take evasive action by moving the SAM
|
-- Once a HARM attack is detected, MANTIS (via SEAD) will shut down the radars of the attacked SAM site and take evasive action by moving the SAM
|
||||||
@ -336,6 +322,8 @@ MANTIS = {
|
|||||||
SmokeDecoy = false,
|
SmokeDecoy = false,
|
||||||
SmokeDecoyColor = SMOKECOLOR.White,
|
SmokeDecoyColor = SMOKECOLOR.White,
|
||||||
checkcounter = 1,
|
checkcounter = 1,
|
||||||
|
DLinkCacheTime = 120,
|
||||||
|
logsamstatus = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Advanced state enumerator
|
--- Advanced state enumerator
|
||||||
@ -374,7 +362,7 @@ MANTIS.radiusscale[MANTIS.SamType.POINT] = 3
|
|||||||
MANTIS.SamData = {
|
MANTIS.SamData = {
|
||||||
["Hawk"] = { Range=35, Blindspot=0, Height=12, Type="Medium", Radar="Hawk" }, -- measures in km
|
["Hawk"] = { Range=35, Blindspot=0, Height=12, Type="Medium", Radar="Hawk" }, -- measures in km
|
||||||
["NASAMS"] = { Range=14, Blindspot=0, Height=7, Type="Short", Radar="NSAMS" }, -- AIM 120B
|
["NASAMS"] = { Range=14, Blindspot=0, Height=7, Type="Short", Radar="NSAMS" }, -- AIM 120B
|
||||||
["Patriot"] = { Range=99, Blindspot=0, Height=25, Type="Long", Radar="Patriot" },
|
["Patriot"] = { Range=99, Blindspot=0, Height=25, Type="Long", Radar="Patriot str" },
|
||||||
["Rapier"] = { Range=10, Blindspot=0, Height=3, Type="Short", Radar="rapier" },
|
["Rapier"] = { Range=10, Blindspot=0, Height=3, Type="Short", Radar="rapier" },
|
||||||
["SA-2"] = { Range=40, Blindspot=7, Height=25, Type="Medium", Radar="S_75M_Volhov" },
|
["SA-2"] = { Range=40, Blindspot=7, Height=25, Type="Medium", Radar="S_75M_Volhov" },
|
||||||
["SA-3"] = { Range=18, Blindspot=6, Height=18, Type="Short", Radar="5p73 s-125 ln" },
|
["SA-3"] = { Range=18, Blindspot=6, Height=18, Type="Short", Radar="5p73 s-125 ln" },
|
||||||
@ -382,7 +370,8 @@ MANTIS.SamData = {
|
|||||||
["SA-6"] = { Range=25, Blindspot=0, Height=8, Type="Medium", Radar="1S91" },
|
["SA-6"] = { Range=25, Blindspot=0, Height=8, Type="Medium", Radar="1S91" },
|
||||||
["SA-10"] = { Range=119, Blindspot=0, Height=18, Type="Long" , Radar="S-300PS 4"},
|
["SA-10"] = { Range=119, Blindspot=0, Height=18, Type="Long" , Radar="S-300PS 4"},
|
||||||
["SA-11"] = { Range=35, Blindspot=0, Height=20, Type="Medium", Radar="SA-11" },
|
["SA-11"] = { Range=35, Blindspot=0, Height=20, Type="Medium", Radar="SA-11" },
|
||||||
["Roland"] = { Range=5, Blindspot=0, Height=5, Type="Point", Radar="Roland" },
|
["Roland"] = { Range=6, Blindspot=0, Height=5, Type="Short", Radar="Roland" },
|
||||||
|
["Gepard"] = { Range=5, Blindspot=0, Height=4, Type="Point", Radar="Gepard" },
|
||||||
["HQ-7"] = { Range=12, Blindspot=0, Height=3, Type="Short", Radar="HQ-7" },
|
["HQ-7"] = { Range=12, Blindspot=0, Height=3, Type="Short", Radar="HQ-7" },
|
||||||
["SA-9"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="Strela", Point="true" },
|
["SA-9"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="Strela", Point="true" },
|
||||||
["SA-8"] = { Range=10, Blindspot=0, Height=5, Type="Short", Radar="Osa 9A33" },
|
["SA-8"] = { Range=10, Blindspot=0, Height=5, Type="Short", Radar="Osa 9A33" },
|
||||||
@ -393,6 +382,7 @@ MANTIS.SamData = {
|
|||||||
["Chaparral"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Chaparral" },
|
["Chaparral"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Chaparral" },
|
||||||
["Linebacker"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="Linebacker", Point="true" },
|
["Linebacker"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="Linebacker", Point="true" },
|
||||||
["Silkworm"] = { Range=90, Blindspot=1, Height=0.2, Type="Long", Radar="Silkworm" },
|
["Silkworm"] = { Range=90, Blindspot=1, Height=0.2, Type="Long", Radar="Silkworm" },
|
||||||
|
["HEMTT_C-RAM_Phalanx"] = { Range=2, Blindspot=0, Height=2, Type="Point", Radar="HEMTT_C-RAM_Phalanx", Point="true" },
|
||||||
-- units from HDS Mod, multi launcher options is tricky
|
-- units from HDS Mod, multi launcher options is tricky
|
||||||
["SA-10B"] = { Range=75, Blindspot=0, Height=18, Type="Medium" , Radar="SA-10B"},
|
["SA-10B"] = { Range=75, Blindspot=0, Height=18, Type="Medium" , Radar="SA-10B"},
|
||||||
["SA-17"] = { Range=50, Blindspot=3, Height=30, Type="Medium", Radar="SA-17" },
|
["SA-17"] = { Range=50, Blindspot=3, Height=30, Type="Medium", Radar="SA-17" },
|
||||||
@ -625,7 +615,8 @@ do
|
|||||||
self.advAwacs = false
|
self.advAwacs = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self:SetDLinkCacheTime()
|
||||||
|
|
||||||
-- Set the string id for output to DCS.log file.
|
-- Set the string id for output to DCS.log file.
|
||||||
self.lid=string.format("MANTIS %s | ", self.name)
|
self.lid=string.format("MANTIS %s | ", self.name)
|
||||||
|
|
||||||
@ -658,6 +649,8 @@ do
|
|||||||
table.insert(self.ewr_templates,awacs)
|
table.insert(self.ewr_templates,awacs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.logsamstatus = false
|
||||||
|
|
||||||
self:T({self.ewr_templates})
|
self:T({self.ewr_templates})
|
||||||
|
|
||||||
self.SAM_Group = SET_GROUP:New():FilterPrefixes(self.SAM_Templates_Prefix):FilterCoalitions(self.Coalition)
|
self.SAM_Group = SET_GROUP:New():FilterPrefixes(self.SAM_Templates_Prefix):FilterCoalitions(self.Coalition)
|
||||||
@ -689,7 +682,7 @@ do
|
|||||||
|
|
||||||
-- TODO Version
|
-- TODO Version
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
self.version="0.9.27"
|
self.version="0.9.30"
|
||||||
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
||||||
|
|
||||||
--- FSM Functions ---
|
--- FSM Functions ---
|
||||||
@ -1039,6 +1032,16 @@ do
|
|||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Function to set how long INTEL DLINK remembers contacts.
|
||||||
|
-- @param #MANTIS self
|
||||||
|
-- @param #number seconds Remember this many seconds, at least 5 seconds.
|
||||||
|
-- @return #MANTIS self
|
||||||
|
function MANTIS:SetDLinkCacheTime(seconds)
|
||||||
|
self.DLinkCacheTime = math.abs(seconds or 120)
|
||||||
|
if self.DLinkCacheTime < 5 then self.DLinkCacheTime = 5 end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Function to set the detection interval
|
--- Function to set the detection interval
|
||||||
-- @param #MANTIS self
|
-- @param #MANTIS self
|
||||||
@ -1431,7 +1434,9 @@ do
|
|||||||
--IntelTwo:SetClusterRadius(5000)
|
--IntelTwo:SetClusterRadius(5000)
|
||||||
IntelTwo:Start()
|
IntelTwo:Start()
|
||||||
|
|
||||||
local IntelDlink = INTEL_DLINK:New({IntelOne,IntelTwo},self.name.." DLINK",22,300)
|
local CacheTime = self.DLinkCacheTime or 120
|
||||||
|
local IntelDlink = INTEL_DLINK:New({IntelOne,IntelTwo},self.name.." DLINK",22,CacheTime)
|
||||||
|
|
||||||
IntelDlink:__Start(1)
|
IntelDlink:__Start(1)
|
||||||
|
|
||||||
self:SetUsingDLink(IntelDlink)
|
self:SetUsingDLink(IntelDlink)
|
||||||
@ -1493,7 +1498,7 @@ do
|
|||||||
elseif chm then
|
elseif chm then
|
||||||
SAMData = self.SamDataCH
|
SAMData = self.SamDataCH
|
||||||
end
|
end
|
||||||
--self:T("Looking to auto-match for "..grpname)
|
--self:I("Looking to auto-match for "..grpname)
|
||||||
for _,_unit in pairs(units) do
|
for _,_unit in pairs(units) do
|
||||||
local unit = _unit -- Wrapper.Unit#UNIT
|
local unit = _unit -- Wrapper.Unit#UNIT
|
||||||
local type = string.lower(unit:GetTypeName())
|
local type = string.lower(unit:GetTypeName())
|
||||||
@ -1694,7 +1699,9 @@ do
|
|||||||
local grpname = group:GetName()
|
local grpname = group:GetName()
|
||||||
local grpcoord = group:GetCoordinate()
|
local grpcoord = group:GetCoordinate()
|
||||||
local grprange, grpheight,type,blind = self:_GetSAMRange(grpname)
|
local grprange, grpheight,type,blind = self:_GetSAMRange(grpname)
|
||||||
local radaralive = group:IsSAM()
|
-- TODO the below might stop working at some point after some hours, needs testing
|
||||||
|
--local radaralive = group:IsSAM()
|
||||||
|
local radaralive = true
|
||||||
table.insert( SAM_Tbl, {grpname, grpcoord, grprange, grpheight, blind, type}) -- make the table lighter, as I don't really use the zone here
|
table.insert( SAM_Tbl, {grpname, grpcoord, grprange, grpheight, blind, type}) -- make the table lighter, as I don't really use the zone here
|
||||||
table.insert( SEAD_Grps, grpname )
|
table.insert( SEAD_Grps, grpname )
|
||||||
if type == MANTIS.SamType.LONG and radaralive then
|
if type == MANTIS.SamType.LONG and radaralive then
|
||||||
@ -1856,7 +1863,7 @@ do
|
|||||||
end --end alive
|
end --end alive
|
||||||
end --end check
|
end --end check
|
||||||
end --for loop
|
end --for loop
|
||||||
if self.debug or self.verbose then
|
if self.debug or self.verbose or self.logsamstatus then
|
||||||
for _,_status in pairs(self.SamStateTracker) do
|
for _,_status in pairs(self.SamStateTracker) do
|
||||||
if _status == "GREEN" then
|
if _status == "GREEN" then
|
||||||
instatusgreen=instatusgreen+1
|
instatusgreen=instatusgreen+1
|
||||||
@ -1877,8 +1884,9 @@ do
|
|||||||
-- @param #MANTIS self
|
-- @param #MANTIS self
|
||||||
-- @param Functional.Detection#DETECTION_AREAS detection Detection object
|
-- @param Functional.Detection#DETECTION_AREAS detection Detection object
|
||||||
-- @param #boolean dlink
|
-- @param #boolean dlink
|
||||||
|
-- @param #boolean reporttolog
|
||||||
-- @return #MANTIS self
|
-- @return #MANTIS self
|
||||||
function MANTIS:_Check(detection,dlink)
|
function MANTIS:_Check(detection,dlink,reporttolog)
|
||||||
self:T(self.lid .. "Check")
|
self:T(self.lid .. "Check")
|
||||||
--get detected set
|
--get detected set
|
||||||
local detset = detection:GetDetectedItemCoordinates()
|
local detset = detection:GetDetectedItemCoordinates()
|
||||||
@ -1905,7 +1913,8 @@ do
|
|||||||
local samset = self:_GetSAMTable() -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
|
local samset = self:_GetSAMTable() -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
|
||||||
instatusred, instatusgreen, activeshorads = self:_CheckLoop(samset,detset,dlink,self.maxclassic)
|
instatusred, instatusgreen, activeshorads = self:_CheckLoop(samset,detset,dlink,self.maxclassic)
|
||||||
end
|
end
|
||||||
if self.debug or self.verbose then
|
|
||||||
|
local function GetReport()
|
||||||
local statusreport = REPORT:New("\nMANTIS Status "..self.name)
|
local statusreport = REPORT:New("\nMANTIS Status "..self.name)
|
||||||
statusreport:Add("+-----------------------------+")
|
statusreport:Add("+-----------------------------+")
|
||||||
statusreport:Add(string.format("+ SAM in RED State: %2d",instatusred))
|
statusreport:Add(string.format("+ SAM in RED State: %2d",instatusred))
|
||||||
@ -1914,7 +1923,15 @@ do
|
|||||||
statusreport:Add(string.format("+ SHORAD active: %2d",activeshorads))
|
statusreport:Add(string.format("+ SHORAD active: %2d",activeshorads))
|
||||||
end
|
end
|
||||||
statusreport:Add("+-----------------------------+")
|
statusreport:Add("+-----------------------------+")
|
||||||
|
return statusreport
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.debug or self.verbose then
|
||||||
|
local statusreport = GetReport()
|
||||||
MESSAGE:New(statusreport:Text(),10):ToAll():ToLog()
|
MESSAGE:New(statusreport:Text(),10):ToAll():ToLog()
|
||||||
|
elseif reporttolog == true then
|
||||||
|
local statusreport = GetReport()
|
||||||
|
MESSAGE:New(statusreport:Text(),10):ToLog()
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -2022,7 +2039,7 @@ do
|
|||||||
self:T({From, Event, To})
|
self:T({From, Event, To})
|
||||||
-- check detection
|
-- check detection
|
||||||
if not self.state2flag then
|
if not self.state2flag then
|
||||||
self:_Check(self.Detection,self.DLink)
|
self:_Check(self.Detection,self.DLink,self.logsamstatus)
|
||||||
end
|
end
|
||||||
|
|
||||||
local EWRAlive = self:_CheckAnyEWRAlive()
|
local EWRAlive = self:_CheckAnyEWRAlive()
|
||||||
|
|||||||
@ -53,6 +53,8 @@
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE.
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE.
|
||||||
-- Therefore, this class is considered to be deprecated and superseded by the [Functional.Fox](https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Functional.Fox.html) class, which provides the same functionality.
|
-- Therefore, this class is considered to be deprecated and superseded by the [Functional.Fox](https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Functional.Fox.html) class, which provides the same functionality.
|
||||||
--
|
--
|
||||||
|
|||||||
@ -603,7 +603,7 @@ RANGE.MenuF10Root = nil
|
|||||||
|
|
||||||
--- Range script version.
|
--- Range script version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
RANGE.version = "2.8.0"
|
RANGE.version = "2.8.1"
|
||||||
|
|
||||||
-- TODO list:
|
-- TODO list:
|
||||||
-- TODO: Verbosity level for messages.
|
-- TODO: Verbosity level for messages.
|
||||||
@ -2032,10 +2032,10 @@ function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackV
|
|||||||
|
|
||||||
-- Smoke impact point of bomb.
|
-- Smoke impact point of bomb.
|
||||||
if playerData and playerData.smokebombimpact and insidezone then
|
if playerData and playerData.smokebombimpact and insidezone then
|
||||||
if playerData and playerData.delaysmoke then
|
if playerData.delaysmoke then
|
||||||
timer.scheduleFunction( self._DelayedSmoke, { coord = impactcoord, color = playerData.smokecolor }, timer.getTime() + self.TdelaySmoke )
|
impactcoord:Smoke(playerData.smokecolor, 30, self.TdelaySmoke)
|
||||||
else
|
else
|
||||||
impactcoord:Smoke( playerData.smokecolor )
|
impactcoord:Smoke(playerData.smokecolor, 30)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -2102,7 +2102,12 @@ function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackV
|
|||||||
result.attackHdg = attackHdg
|
result.attackHdg = attackHdg
|
||||||
result.attackVel = attackVel
|
result.attackVel = attackVel
|
||||||
result.attackAlt = attackAlt
|
result.attackAlt = attackAlt
|
||||||
result.date=os and os.date() or "n/a"
|
if os and os.date then
|
||||||
|
result.date=os.date()
|
||||||
|
else
|
||||||
|
self:E(self.lid.."os or os.date() not available")
|
||||||
|
result.date = "n/a"
|
||||||
|
end
|
||||||
|
|
||||||
-- Add to table.
|
-- Add to table.
|
||||||
table.insert( _results, result )
|
table.insert( _results, result )
|
||||||
@ -2635,13 +2640,6 @@ end
|
|||||||
-- Display Messages
|
-- Display Messages
|
||||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Start smoking a coordinate with a delay.
|
|
||||||
-- @param #table _args Argements passed.
|
|
||||||
function RANGE._DelayedSmoke( _args )
|
|
||||||
_args.coord:Smoke(_args.color)
|
|
||||||
--trigger.action.smoke( _args.coord:GetVec3(), _args.color )
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Display top 10 stafing results of a specific player.
|
--- Display top 10 stafing results of a specific player.
|
||||||
-- @param #RANGE self
|
-- @param #RANGE self
|
||||||
-- @param #string _unitName Name of the player unit.
|
-- @param #string _unitName Name of the player unit.
|
||||||
|
|||||||
@ -7,6 +7,8 @@
|
|||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
|
||||||
-- Therefore, this class is considered to be deprecated
|
-- Therefore, this class is considered to be deprecated
|
||||||
--
|
--
|
||||||
|
|||||||
@ -2798,7 +2798,7 @@ function ATIS:onafterBroadcast( From, Event, To )
|
|||||||
|
|
||||||
end
|
end
|
||||||
_RUNACT = subtitle
|
_RUNACT = subtitle
|
||||||
alltext = alltext .. ";\n" .. subtitle
|
--alltext = alltext .. ";\n" .. subtitle
|
||||||
|
|
||||||
-- Runway length.
|
-- Runway length.
|
||||||
if self.rwylength then
|
if self.rwylength then
|
||||||
|
|||||||
@ -1731,10 +1731,10 @@ AIRBOSS.Difficulty = {
|
|||||||
-- @field #table trapsheet Groove data table recorded every 0.5 seconds.
|
-- @field #table trapsheet Groove data table recorded every 0.5 seconds.
|
||||||
-- @field #boolean trapon If true, save trap sheets.
|
-- @field #boolean trapon If true, save trap sheets.
|
||||||
-- @field #string debriefschedulerID Debrief scheduler ID.
|
-- @field #string debriefschedulerID Debrief scheduler ID.
|
||||||
--
|
--
|
||||||
-- @field Sound.SRS#MSRS SRS
|
-- @field Sound.SRS#MSRS SRS
|
||||||
-- @field Sound.SRS#MSRSQUEUE SRSQ
|
-- @field Sound.SRS#MSRSQUEUE SRSQ
|
||||||
--
|
--
|
||||||
-- @extends #AIRBOSS.FlightGroup
|
-- @extends #AIRBOSS.FlightGroup
|
||||||
|
|
||||||
--- Main group level radio menu: F10 Other/Airboss.
|
--- Main group level radio menu: F10 Other/Airboss.
|
||||||
@ -1912,6 +1912,9 @@ function AIRBOSS:New( carriername, alias )
|
|||||||
-- Set max section members. Default 2.
|
-- Set max section members. Default 2.
|
||||||
self:SetMaxSectionSize()
|
self:SetMaxSectionSize()
|
||||||
|
|
||||||
|
-- Set max section distance. Default 100 meters.
|
||||||
|
self:SetMaxSectionDistance()
|
||||||
|
|
||||||
-- Set max flights per stack. Default is 2.
|
-- Set max flights per stack. Default is 2.
|
||||||
self:SetMaxFlightsPerStack()
|
self:SetMaxFlightsPerStack()
|
||||||
|
|
||||||
@ -2539,7 +2542,7 @@ function AIRBOSS:AddRecoveryWindow( starttime, stoptime, case, holdingoffset, tu
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
if Tstop <= Tnow then
|
if Tstop <= Tnow then
|
||||||
string.format( "WARNING: Recovery stop time %s already over. Tnow=%s! Recovery window rejected.", UTILS.SecondsToClock( Tstop ), UTILS.SecondsToClock( Tnow ) )
|
string.format( "WARNING: Recovery stop time %s already over. Tnow=%s! Recovery window rejected.", UTILS.SecondsToClock( Tstop ), UTILS.SecondsToClock( Tnow ) )
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3066,7 +3069,7 @@ end
|
|||||||
-- @param #number Port Port of the SRS server, defaults to 5002.
|
-- @param #number Port Port of the SRS server, defaults to 5002.
|
||||||
-- @param #string Culture (Optional, Airboss Culture) Culture, defaults to "en-US".
|
-- @param #string Culture (Optional, Airboss Culture) Culture, defaults to "en-US".
|
||||||
-- @param #string Gender (Optional, Airboss Gender) Gender, e.g. "male" or "female". Defaults to "male".
|
-- @param #string Gender (Optional, Airboss Gender) Gender, e.g. "male" or "female". Defaults to "male".
|
||||||
-- @param #string Voice (Optional, Airboss Voice) Set to use a specific voice. Will **override gender and culture** settings.
|
-- @param #string Voice (Optional, Airboss Voice) Set to use a specific voice. Will **override gender and culture** settings.
|
||||||
-- @param #string GoogleCreds (Optional) Path to Google credentials, e.g. "C:\\Program Files\\DCS-SimpleRadio-Standalone\\yourgooglekey.json".
|
-- @param #string GoogleCreds (Optional) Path to Google credentials, e.g. "C:\\Program Files\\DCS-SimpleRadio-Standalone\\yourgooglekey.json".
|
||||||
-- @param #number Volume (Optional) E.g. 0.75. Defaults to 1.0 (loudest).
|
-- @param #number Volume (Optional) E.g. 0.75. Defaults to 1.0 (loudest).
|
||||||
-- @param #table AltBackend (Optional) See MSRS for details.
|
-- @param #table AltBackend (Optional) See MSRS for details.
|
||||||
@ -3088,8 +3091,7 @@ function AIRBOSS:EnableSRS(PathToSRS,Port,Culture,Gender,Voice,GoogleCreds,Volum
|
|||||||
self.SRS:SetVolume(Volume or 1)
|
self.SRS:SetVolume(Volume or 1)
|
||||||
--self.SRS:SetModulations(Modulations)
|
--self.SRS:SetModulations(Modulations)
|
||||||
if GoogleCreds then
|
if GoogleCreds then
|
||||||
self.SRS:SetProviderOptionsGoogle(GoogleCreds,GoogleCreds)
|
self.SRS:SetGoogle(GoogleCreds)
|
||||||
self.SRS:SetProvider(MSRS.Provider.GOOGLE)
|
|
||||||
end
|
end
|
||||||
if Voice then
|
if Voice then
|
||||||
self.SRS:SetVoice(Voice)
|
self.SRS:SetVoice(Voice)
|
||||||
@ -3098,10 +3100,10 @@ function AIRBOSS:EnableSRS(PathToSRS,Port,Culture,Gender,Voice,GoogleCreds,Volum
|
|||||||
-- SRSQUEUE
|
-- SRSQUEUE
|
||||||
self.SRSQ = MSRSQUEUE:New("AIRBOSS")
|
self.SRSQ = MSRSQUEUE:New("AIRBOSS")
|
||||||
self.SRSQ:SetTransmitOnlyWithPlayers(true)
|
self.SRSQ:SetTransmitOnlyWithPlayers(true)
|
||||||
if not self.PilotRadio then
|
if not self.PilotRadio then
|
||||||
self:SetSRSPilotVoice()
|
self:SetSRSPilotVoice()
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set LSO radio frequency and modulation. Default frequency is 264 MHz AM.
|
--- Set LSO radio frequency and modulation. Default frequency is 264 MHz AM.
|
||||||
@ -3344,6 +3346,22 @@ function AIRBOSS:SetMaxSectionSize( nmax )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set maximum distance up to which section members are allowed (default: 100 meters).
|
||||||
|
-- @param #AIRBOSS self
|
||||||
|
-- @param #number dmax Max distance in meters (default 100 m). Minimum is 10 m, maximum is 5000 m.
|
||||||
|
-- @return #AIRBOSS self
|
||||||
|
function AIRBOSS:SetMaxSectionDistance( dmax )
|
||||||
|
if dmax then
|
||||||
|
if dmax < 10 then
|
||||||
|
dmax = 10
|
||||||
|
elseif dmax > 5000 then
|
||||||
|
dmax = 5000
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.maxsectiondistance = dmax or 100
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Set max number of flights per stack. All members of a section count as one "flight".
|
--- Set max number of flights per stack. All members of a section count as one "flight".
|
||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
-- @param #number nmax Number of max allowed flights per stack. Default is two. Minimum is one, maximum is 4.
|
-- @param #number nmax Number of max allowed flights per stack. Default is two. Minimum is one, maximum is 4.
|
||||||
@ -3623,7 +3641,6 @@ function AIRBOSS:onafterStart( From, Event, To )
|
|||||||
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._PlayerLeft )
|
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._PlayerLeft )
|
||||||
self:HandleEvent( EVENTS.MissionEnd )
|
self:HandleEvent( EVENTS.MissionEnd )
|
||||||
self:HandleEvent( EVENTS.RemoveUnit )
|
self:HandleEvent( EVENTS.RemoveUnit )
|
||||||
self:HandleEvent( EVENTS.UnitLost, self.OnEventRemoveUnit )
|
|
||||||
|
|
||||||
-- self.StatusScheduler=SCHEDULER:New(self)
|
-- self.StatusScheduler=SCHEDULER:New(self)
|
||||||
-- self.StatusScheduler:Schedule(self, self._Status, {}, 1, 0.5)
|
-- self.StatusScheduler:Schedule(self, self._Status, {}, 1, 0.5)
|
||||||
@ -8724,13 +8741,13 @@ function AIRBOSS:OnEventRemoveUnit( EventData )
|
|||||||
|
|
||||||
-- Nil checks.
|
-- Nil checks.
|
||||||
if EventData == nil then
|
if EventData == nil then
|
||||||
self:E( self.lid .. "ERROR: EventData=nil in event REMOVEUNIT!" )
|
self:T( self.lid .. "ERROR: EventData=nil in event REMOVEUNIT!" )
|
||||||
self:E( EventData )
|
self:T( EventData )
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if EventData.IniUnit == nil then
|
if EventData.IniUnit == nil then
|
||||||
self:E( self.lid .. "ERROR: EventData.IniUnit=nil in event REMOVEUNIT!" )
|
self:T( self.lid .. "ERROR: EventData.IniUnit=nil in event REMOVEUNIT!" )
|
||||||
self:E( EventData )
|
self:T( EventData )
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -11598,7 +11615,7 @@ function AIRBOSS:GetHeadingIntoWind_old( vdeck, magnetic, coord )
|
|||||||
local function adjustDegreesForWindSpeed(windSpeed)
|
local function adjustDegreesForWindSpeed(windSpeed)
|
||||||
local degreesAdjustment = 0
|
local degreesAdjustment = 0
|
||||||
-- the windspeeds are in m/s
|
-- the windspeeds are in m/s
|
||||||
|
|
||||||
-- +0 degrees at 15m/s = 37kts
|
-- +0 degrees at 15m/s = 37kts
|
||||||
-- +0 degrees at 14m/s = 35kts
|
-- +0 degrees at 14m/s = 35kts
|
||||||
-- +0 degrees at 13m/s = 33kts
|
-- +0 degrees at 13m/s = 33kts
|
||||||
@ -11613,7 +11630,7 @@ function AIRBOSS:GetHeadingIntoWind_old( vdeck, magnetic, coord )
|
|||||||
-- +20 degrees at 4m/s = 26kts
|
-- +20 degrees at 4m/s = 26kts
|
||||||
-- +20 degrees at 3m/s = 26kts
|
-- +20 degrees at 3m/s = 26kts
|
||||||
-- +30 degrees at 2m/s = 26kts 1s
|
-- +30 degrees at 2m/s = 26kts 1s
|
||||||
|
|
||||||
if windSpeed > 0 and windSpeed < 3 then
|
if windSpeed > 0 and windSpeed < 3 then
|
||||||
degreesAdjustment = 30
|
degreesAdjustment = 30
|
||||||
elseif windSpeed >= 3 and windSpeed < 5 then
|
elseif windSpeed >= 3 and windSpeed < 5 then
|
||||||
@ -11625,7 +11642,7 @@ function AIRBOSS:GetHeadingIntoWind_old( vdeck, magnetic, coord )
|
|||||||
elseif windSpeed >= 13 then
|
elseif windSpeed >= 13 then
|
||||||
degreesAdjustment = 0
|
degreesAdjustment = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
return degreesAdjustment
|
return degreesAdjustment
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -11684,60 +11701,60 @@ function AIRBOSS:GetHeadingIntoWind_new( vdeck, magnetic, coord )
|
|||||||
local h=self:GetHeading(magnetic)
|
local h=self:GetHeading(magnetic)
|
||||||
return h, math.min(vdeck, Vmax)
|
return h, math.min(vdeck, Vmax)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Convert wind speed to knots.
|
-- Convert wind speed to knots.
|
||||||
vwind=UTILS.MpsToKnots(vwind)
|
vwind=UTILS.MpsToKnots(vwind)
|
||||||
|
|
||||||
-- Wind to in knots.
|
-- Wind to in knots.
|
||||||
local windto=(windfrom+180)%360
|
local windto=(windfrom+180)%360
|
||||||
|
|
||||||
-- Offset angle in rad. We also define the rotation to be clock-wise, which requires a minus sign.
|
-- Offset angle in rad. We also define the rotation to be clock-wise, which requires a minus sign.
|
||||||
local alpha=math.rad(-Offset)
|
local alpha=math.rad(-Offset)
|
||||||
|
|
||||||
-- Constant.
|
-- Constant.
|
||||||
local C = math.sqrt(math.cos(alpha)^2 / math.sin(alpha)^2 + 1)
|
local C = math.sqrt(math.cos(alpha)^2 / math.sin(alpha)^2 + 1)
|
||||||
|
|
||||||
|
|
||||||
-- Upper limit of desired speed due to max boat speed.
|
-- Upper limit of desired speed due to max boat speed.
|
||||||
local vdeckMax=vwind + math.cos(alpha) * Vmax
|
local vdeckMax=vwind + math.cos(alpha) * Vmax
|
||||||
|
|
||||||
-- Lower limit of desired speed due to min boat speed.
|
-- Lower limit of desired speed due to min boat speed.
|
||||||
local vdeckMin=vwind + math.cos(alpha) * Vmin
|
local vdeckMin=vwind + math.cos(alpha) * Vmin
|
||||||
|
|
||||||
|
|
||||||
-- Speed of ship so it matches the desired speed.
|
-- Speed of ship so it matches the desired speed.
|
||||||
local v=0
|
local v=0
|
||||||
|
|
||||||
-- Angle wrt. to wind TO-direction
|
-- Angle wrt. to wind TO-direction
|
||||||
local theta=0
|
local theta=0
|
||||||
|
|
||||||
if vdeck>vdeckMax then
|
if vdeck>vdeckMax then
|
||||||
-- Boat cannot go fast enough
|
-- Boat cannot go fast enough
|
||||||
|
|
||||||
-- Set max speed.
|
-- Set max speed.
|
||||||
v=Vmax
|
v=Vmax
|
||||||
|
|
||||||
-- Calculate theta.
|
-- Calculate theta.
|
||||||
theta = math.asin(v/(vwind*C)) - math.asin(-1/C)
|
theta = math.asin(v/(vwind*C)) - math.asin(-1/C)
|
||||||
|
|
||||||
elseif vdeck<vdeckMin then
|
elseif vdeck<vdeckMin then
|
||||||
-- Boat cannot go slow enought
|
-- Boat cannot go slow enought
|
||||||
|
|
||||||
-- Set min speed.
|
-- Set min speed.
|
||||||
v=Vmin
|
v=Vmin
|
||||||
|
|
||||||
-- Calculatge theta.
|
-- Calculatge theta.
|
||||||
theta = math.asin(v/(vwind*C)) - math.asin(-1/C)
|
theta = math.asin(v/(vwind*C)) - math.asin(-1/C)
|
||||||
|
|
||||||
elseif vdeck*math.sin(alpha)>vwind then
|
elseif vdeck*math.sin(alpha)>vwind then
|
||||||
-- Too little wind
|
-- Too little wind
|
||||||
|
|
||||||
-- Set theta to 90°
|
-- Set theta to 90°
|
||||||
theta=math.pi/2
|
theta=math.pi/2
|
||||||
|
|
||||||
-- Set speed.
|
-- Set speed.
|
||||||
v = math.sqrt(vdeck^2 - vwind^2)
|
v = math.sqrt(vdeck^2 - vwind^2)
|
||||||
|
|
||||||
else
|
else
|
||||||
-- Normal case
|
-- Normal case
|
||||||
theta = math.asin(vdeck * math.sin(alpha) / vwind)
|
theta = math.asin(vdeck * math.sin(alpha) / vwind)
|
||||||
@ -11746,9 +11763,9 @@ function AIRBOSS:GetHeadingIntoWind_new( vdeck, magnetic, coord )
|
|||||||
|
|
||||||
-- Magnetic heading.
|
-- Magnetic heading.
|
||||||
local magvar= magnetic and self.magvar or 0
|
local magvar= magnetic and self.magvar or 0
|
||||||
|
|
||||||
-- Ship heading so cross wind is min for the given wind.
|
-- Ship heading so cross wind is min for the given wind.
|
||||||
local intowind = (540 + (windto - magvar + math.deg(theta) )) % 360
|
local intowind = (540 + (windto - magvar + math.deg(theta) )) % 360
|
||||||
|
|
||||||
return intowind, v
|
return intowind, v
|
||||||
end
|
end
|
||||||
@ -12206,7 +12223,7 @@ function AIRBOSS:_LSOgrade( playerData )
|
|||||||
-- Normal laning part at the beginning
|
-- Normal laning part at the beginning
|
||||||
local Gb = GXX .. " " .. GIM
|
local Gb = GXX .. " " .. GIM
|
||||||
|
|
||||||
-- Number of deviations that occurred at the the beginning of the landing (XX or IM). These are graded like in non-VTOL landings, i.e. on deviations is
|
-- Number of deviations that occurred at the the beginning of the landing (XX or IM). These are graded like in non-VTOL landings, i.e. on deviations is
|
||||||
local N=nXX+nIM
|
local N=nXX+nIM
|
||||||
local nL=count(Gb, '_')/2
|
local nL=count(Gb, '_')/2
|
||||||
local nS=count(Gb, '%(')
|
local nS=count(Gb, '%(')
|
||||||
@ -12224,7 +12241,7 @@ function AIRBOSS:_LSOgrade( playerData )
|
|||||||
|
|
||||||
if nL>0 or nLv>1 then
|
if nL>0 or nLv>1 then
|
||||||
-- Larger deviations at XX or IM or at least one larger deviation IC or AR==> "No grade" 2.0 points.
|
-- Larger deviations at XX or IM or at least one larger deviation IC or AR==> "No grade" 2.0 points.
|
||||||
-- In other words, we allow one larger deviation at IC+AR
|
-- In other words, we allow one larger deviation at IC+AR
|
||||||
grade="--"
|
grade="--"
|
||||||
points=2.0
|
points=2.0
|
||||||
elseif nN>0 or nNv>1 or nLv==1 then
|
elseif nN>0 or nNv>1 or nLv==1 then
|
||||||
@ -13720,7 +13737,7 @@ function AIRBOSS:CarrierTurnIntoWind( time, vdeck, uturn )
|
|||||||
local deltaH = self:_GetDeltaHeading( hdg, hiw )
|
local deltaH = self:_GetDeltaHeading( hdg, hiw )
|
||||||
|
|
||||||
-- Debug output
|
-- Debug output
|
||||||
self:I( self.lid .. string.format( "Carrier steaming into the wind (%.1f kts). Heading=%03d-->%03d (Delta=%.1f), Speed=%.1f knots, Distance=%.1f NM, Time=%d sec",
|
self:I( self.lid .. string.format( "Carrier steaming into the wind (%.1f kts). Heading=%03d-->%03d (Delta=%.1f), Speed=%.1f knots, Distance=%.1f NM, Time=%d sec",
|
||||||
UTILS.MpsToKnots( vwind ), hdg, hiw, deltaH, speedknots, distNM, speedknots, time ) )
|
UTILS.MpsToKnots( vwind ), hdg, hiw, deltaH, speedknots, distNM, speedknots, time ) )
|
||||||
|
|
||||||
-- Current coordinate.
|
-- Current coordinate.
|
||||||
@ -14932,12 +14949,12 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
if radio == nil or call == nil then
|
if radio == nil or call == nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.SRS then
|
if not self.SRS then
|
||||||
|
|
||||||
-- Create a new radio transmission item.
|
-- Create a new radio transmission item.
|
||||||
local transmission = {} -- #AIRBOSS.Radioitem
|
local transmission = {} -- #AIRBOSS.Radioitem
|
||||||
|
|
||||||
transmission.radio = radio
|
transmission.radio = radio
|
||||||
transmission.call = call
|
transmission.call = call
|
||||||
transmission.Tplay = timer.getAbsTime() + (delay or 0)
|
transmission.Tplay = timer.getAbsTime() + (delay or 0)
|
||||||
@ -14945,49 +14962,49 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
transmission.isplaying = false
|
transmission.isplaying = false
|
||||||
transmission.Tstarted = nil
|
transmission.Tstarted = nil
|
||||||
transmission.loud = loud and call.loud
|
transmission.loud = loud and call.loud
|
||||||
|
|
||||||
-- Player onboard number if sender has one.
|
-- Player onboard number if sender has one.
|
||||||
if self:_IsOnboard( call.modexsender ) then
|
if self:_IsOnboard( call.modexsender ) then
|
||||||
self:_Number2Radio( radio, call.modexsender, delay, 0.3, pilotcall )
|
self:_Number2Radio( radio, call.modexsender, delay, 0.3, pilotcall )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Play onboard number if receiver has one.
|
-- Play onboard number if receiver has one.
|
||||||
if self:_IsOnboard( call.modexreceiver ) then
|
if self:_IsOnboard( call.modexreceiver ) then
|
||||||
self:_Number2Radio( radio, call.modexreceiver, delay, 0.3, pilotcall )
|
self:_Number2Radio( radio, call.modexreceiver, delay, 0.3, pilotcall )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add transmission to the right queue.
|
-- Add transmission to the right queue.
|
||||||
local caller = ""
|
local caller = ""
|
||||||
if radio.alias == "LSO" then
|
if radio.alias == "LSO" then
|
||||||
|
|
||||||
table.insert( self.RQLSO, transmission )
|
table.insert( self.RQLSO, transmission )
|
||||||
|
|
||||||
caller = "LSOCall"
|
caller = "LSOCall"
|
||||||
|
|
||||||
-- Schedule radio queue checks.
|
-- Schedule radio queue checks.
|
||||||
if not self.RQLid then
|
if not self.RQLid then
|
||||||
self:T( self.lid .. string.format( "Starting LSO radio queue." ) )
|
self:T( self.lid .. string.format( "Starting LSO radio queue." ) )
|
||||||
self.RQLid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQLSO, "LSO" }, 0.02, 0.05 )
|
self.RQLid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQLSO, "LSO" }, 0.02, 0.05 )
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif radio.alias == "MARSHAL" then
|
elseif radio.alias == "MARSHAL" then
|
||||||
|
|
||||||
table.insert( self.RQMarshal, transmission )
|
table.insert( self.RQMarshal, transmission )
|
||||||
|
|
||||||
caller = "MarshalCall"
|
caller = "MarshalCall"
|
||||||
|
|
||||||
if not self.RQMid then
|
if not self.RQMid then
|
||||||
self:T( self.lid .. string.format( "Starting Marhal radio queue." ) )
|
self:T( self.lid .. string.format( "Starting Marhal radio queue." ) )
|
||||||
self.RQMid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQMarshal, "MARSHAL" }, 0.02, 0.05 )
|
self.RQMid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQMarshal, "MARSHAL" }, 0.02, 0.05 )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Append radio click sound at the end of the transmission.
|
-- Append radio click sound at the end of the transmission.
|
||||||
if click then
|
if click then
|
||||||
self:RadioTransmission( radio, self[caller].CLICK, false, delay )
|
self:RadioTransmission( radio, self[caller].CLICK, false, delay )
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
-- SRS transmission
|
-- SRS transmission
|
||||||
@ -14998,7 +15015,7 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
local voice = nil
|
local voice = nil
|
||||||
local gender = nil
|
local gender = nil
|
||||||
local culture = nil
|
local culture = nil
|
||||||
|
|
||||||
if radio.alias == "AIRBOSS" then
|
if radio.alias == "AIRBOSS" then
|
||||||
frequency = self.AirbossRadio.frequency
|
frequency = self.AirbossRadio.frequency
|
||||||
modulation = self.AirbossRadio.modulation
|
modulation = self.AirbossRadio.modulation
|
||||||
@ -15006,13 +15023,13 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
gender = self.AirbossRadio.gender
|
gender = self.AirbossRadio.gender
|
||||||
culture = self.AirbossRadio.culture
|
culture = self.AirbossRadio.culture
|
||||||
end
|
end
|
||||||
|
|
||||||
if radio.alias == "MARSHAL" then
|
if radio.alias == "MARSHAL" then
|
||||||
voice = self.MarshalRadio.voice
|
voice = self.MarshalRadio.voice
|
||||||
gender = self.MarshalRadio.gender
|
gender = self.MarshalRadio.gender
|
||||||
culture = self.MarshalRadio.culture
|
culture = self.MarshalRadio.culture
|
||||||
end
|
end
|
||||||
|
|
||||||
if radio.alias == "LSO" then
|
if radio.alias == "LSO" then
|
||||||
frequency = self.LSORadio.frequency
|
frequency = self.LSORadio.frequency
|
||||||
modulation = self.LSORadio.modulation
|
modulation = self.LSORadio.modulation
|
||||||
@ -15020,7 +15037,7 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
gender = self.LSORadio.gender
|
gender = self.LSORadio.gender
|
||||||
culture = self.LSORadio.culture
|
culture = self.LSORadio.culture
|
||||||
end
|
end
|
||||||
|
|
||||||
if pilotcall then
|
if pilotcall then
|
||||||
voice = self.PilotRadio.voice
|
voice = self.PilotRadio.voice
|
||||||
gender = self.PilotRadio.gender
|
gender = self.PilotRadio.gender
|
||||||
@ -15034,16 +15051,16 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
modulation = self.AirbossRadio.modulation
|
modulation = self.AirbossRadio.modulation
|
||||||
radio.alias = "AIRBOSS"
|
radio.alias = "AIRBOSS"
|
||||||
end
|
end
|
||||||
|
|
||||||
local volume = nil
|
local volume = nil
|
||||||
|
|
||||||
if loud then
|
if loud then
|
||||||
volume = 1.0
|
volume = 1.0
|
||||||
end
|
end
|
||||||
|
|
||||||
--local text = tostring(call.modexreceiver).."; "..radio.alias.."; "..call.subtitle
|
--local text = tostring(call.modexreceiver).."; "..radio.alias.."; "..call.subtitle
|
||||||
local text = call.subtitle
|
local text = call.subtitle
|
||||||
self:T(self.lid..text)
|
self:T(self.lid..text)
|
||||||
local srstext = self:_GetNiceSRSText(text)
|
local srstext = self:_GetNiceSRSText(text)
|
||||||
self.SRSQ:NewTransmission(srstext, call.duration, self.SRS, nil, 0.1, nil, call.subtitle, call.subduration, frequency, modulation, gender, culture, voice, volume, radio.alias)
|
self.SRSQ:NewTransmission(srstext, call.duration, self.SRS, nil, 0.1, nil, call.subtitle, call.subduration, frequency, modulation, gender, culture, voice, volume, radio.alias)
|
||||||
end
|
end
|
||||||
@ -15063,11 +15080,11 @@ function AIRBOSS:SetSRSPilotVoice( Voice, Gender, Culture )
|
|||||||
self.PilotRadio.voice = Voice or MSRS.Voices.Microsoft.David
|
self.PilotRadio.voice = Voice or MSRS.Voices.Microsoft.David
|
||||||
self.PilotRadio.gender = Gender or "male"
|
self.PilotRadio.gender = Gender or "male"
|
||||||
self.PilotRadio.culture = Culture or "en-US"
|
self.PilotRadio.culture = Culture or "en-US"
|
||||||
|
|
||||||
if (not Voice) and self.SRS and self.SRS:GetProvider() == MSRS.Provider.GOOGLE then
|
if (not Voice) and self.SRS and self.SRS:GetProvider() == MSRS.Provider.GOOGLE then
|
||||||
self.PilotRadio.voice = MSRS.Voices.Google.Standard.en_US_Standard_J
|
self.PilotRadio.voice = MSRS.Voices.Google.Standard.en_US_Standard_J
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -15381,44 +15398,44 @@ function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duratio
|
|||||||
-- SCHEDULER:New(nil, self.MessageToPlayer, {self, playerData, message, sender, receiver, duration, clear}, delay)
|
-- SCHEDULER:New(nil, self.MessageToPlayer, {self, playerData, message, sender, receiver, duration, clear}, delay)
|
||||||
self:ScheduleOnce( delay, self.MessageToPlayer, self, playerData, message, sender, receiver, duration, clear )
|
self:ScheduleOnce( delay, self.MessageToPlayer, self, playerData, message, sender, receiver, duration, clear )
|
||||||
else
|
else
|
||||||
|
|
||||||
if not self.SRS then
|
if not self.SRS then
|
||||||
-- Wait until previous sound finished.
|
-- Wait until previous sound finished.
|
||||||
local wait = 0
|
local wait = 0
|
||||||
|
|
||||||
-- Onboard number to get the attention.
|
-- Onboard number to get the attention.
|
||||||
if receiver == playerData.onboard then
|
if receiver == playerData.onboard then
|
||||||
|
|
||||||
-- Which voice over number to use.
|
-- Which voice over number to use.
|
||||||
if sender and (sender == "LSO" or sender == "MARSHAL" or sender == "AIRBOSS") then
|
if sender and (sender == "LSO" or sender == "MARSHAL" or sender == "AIRBOSS") then
|
||||||
|
|
||||||
-- User sound of board number.
|
-- User sound of board number.
|
||||||
wait = wait + self:_Number2Sound( playerData, sender, receiver )
|
wait = wait + self:_Number2Sound( playerData, sender, receiver )
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Negative.
|
-- Negative.
|
||||||
if string.find( text:lower(), "negative" ) then
|
if string.find( text:lower(), "negative" ) then
|
||||||
local filename = self:_RadioFilename( self.MarshalCall.NEGATIVE, false, "MARSHAL" )
|
local filename = self:_RadioFilename( self.MarshalCall.NEGATIVE, false, "MARSHAL" )
|
||||||
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
||||||
wait = wait + self.MarshalCall.NEGATIVE.duration
|
wait = wait + self.MarshalCall.NEGATIVE.duration
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Affirm.
|
-- Affirm.
|
||||||
if string.find( text:lower(), "affirm" ) then
|
if string.find( text:lower(), "affirm" ) then
|
||||||
local filename = self:_RadioFilename( self.MarshalCall.AFFIRMATIVE, false, "MARSHAL" )
|
local filename = self:_RadioFilename( self.MarshalCall.AFFIRMATIVE, false, "MARSHAL" )
|
||||||
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
||||||
wait = wait + self.MarshalCall.AFFIRMATIVE.duration
|
wait = wait + self.MarshalCall.AFFIRMATIVE.duration
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Roger.
|
-- Roger.
|
||||||
if string.find( text:lower(), "roger" ) then
|
if string.find( text:lower(), "roger" ) then
|
||||||
local filename = self:_RadioFilename( self.MarshalCall.ROGER, false, "MARSHAL" )
|
local filename = self:_RadioFilename( self.MarshalCall.ROGER, false, "MARSHAL" )
|
||||||
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
||||||
wait = wait + self.MarshalCall.ROGER.duration
|
wait = wait + self.MarshalCall.ROGER.duration
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Play click sound to end message.
|
-- Play click sound to end message.
|
||||||
if wait > 0 then
|
if wait > 0 then
|
||||||
local filename = self:_RadioFilename( self.MarshalCall.CLICK )
|
local filename = self:_RadioFilename( self.MarshalCall.CLICK )
|
||||||
@ -15431,7 +15448,7 @@ function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duratio
|
|||||||
local voice = self.MarshalRadio.voice
|
local voice = self.MarshalRadio.voice
|
||||||
local gender = self.MarshalRadio.gender
|
local gender = self.MarshalRadio.gender
|
||||||
local culture = self.MarshalRadio.culture
|
local culture = self.MarshalRadio.culture
|
||||||
|
|
||||||
if not sender then sender = "AIRBOSS" end
|
if not sender then sender = "AIRBOSS" end
|
||||||
|
|
||||||
if string.find(sender,"AIRBOSS" ) then
|
if string.find(sender,"AIRBOSS" ) then
|
||||||
@ -17049,7 +17066,7 @@ function AIRBOSS:_RemoveSectionMember( playerData, sectionmember )
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set all flights within 100 meters to be part of my section.
|
--- Set all flights within maxsectiondistance meters to be part of my section (default: 100 meters).
|
||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
-- @param #string _unitName Name of the player unit.
|
-- @param #string _unitName Name of the player unit.
|
||||||
function AIRBOSS:_SetSection( _unitName )
|
function AIRBOSS:_SetSection( _unitName )
|
||||||
@ -17067,7 +17084,7 @@ function AIRBOSS:_SetSection( _unitName )
|
|||||||
local mycoord = _unit:GetCoordinate()
|
local mycoord = _unit:GetCoordinate()
|
||||||
|
|
||||||
-- Max distance up to which section members are allowed.
|
-- Max distance up to which section members are allowed.
|
||||||
local dmax = 100
|
local dmax = self.maxsectiondistance
|
||||||
|
|
||||||
-- Check if player is in Marshal or pattern queue already.
|
-- Check if player is in Marshal or pattern queue already.
|
||||||
local text
|
local text
|
||||||
|
|||||||
@ -1403,6 +1403,8 @@ function AUFTRAG:NewINTERCEPT(Target)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- **[AIR]** Create a CAP mission.
|
--- **[AIR]** Create a CAP mission.
|
||||||
|
-- Assinged groups are tasked to execute a CAP mission. This consists of a DCS orbit task combined with an enroute "search and engage in zone" task.
|
||||||
|
-- **Note** that currently DCS only supports *circular* zones for the task.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @param Core.Zone#ZONE_RADIUS ZoneCAP Circular CAP zone. Detected targets in this zone will be engaged.
|
-- @param Core.Zone#ZONE_RADIUS ZoneCAP Circular CAP zone. Detected targets in this zone will be engaged.
|
||||||
-- @param #number Altitude Altitude at which to orbit in feet. Default is 10,000 ft.
|
-- @param #number Altitude Altitude at which to orbit in feet. Default is 10,000 ft.
|
||||||
@ -1717,7 +1719,7 @@ end
|
|||||||
|
|
||||||
--- **[AIR]** Create a STRIKE mission. Flight will attack the closest map object to the specified coordinate.
|
--- **[AIR]** Create a STRIKE mission. Flight will attack the closest map object to the specified coordinate.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @param Core.Point#COORDINATE Target The target coordinate. Can also be given as a GROUP, UNIT, STATIC or TARGET object.
|
-- @param Core.Point#COORDINATE Target The target coordinate. Can also be given as a GROUP, UNIT, STATIC, SET_GROUP, SET_UNIT, SET_STATIC or TARGET object.
|
||||||
-- @param #number Altitude Engage altitude in feet. Default 2000 ft.
|
-- @param #number Altitude Engage altitude in feet. Default 2000 ft.
|
||||||
-- @param #number EngageWeaponType Which weapon to use. Defaults to auto, ie ENUMS.WeaponFlag.Auto. See ENUMS.WeaponFlag for options.
|
-- @param #number EngageWeaponType Which weapon to use. Defaults to auto, ie ENUMS.WeaponFlag.Auto. See ENUMS.WeaponFlag for options.
|
||||||
-- @return #AUFTRAG self
|
-- @return #AUFTRAG self
|
||||||
@ -1749,7 +1751,7 @@ end
|
|||||||
--- **[AIR]** Create a BOMBING mission. Flight will drop bombs a specified coordinate.
|
--- **[AIR]** Create a BOMBING mission. Flight will drop bombs a specified coordinate.
|
||||||
-- See [DCS task bombing](https://wiki.hoggitworld.com/view/DCS_task_bombing).
|
-- See [DCS task bombing](https://wiki.hoggitworld.com/view/DCS_task_bombing).
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @param Core.Point#COORDINATE Target Target coordinate. Can also be specified as a GROUP, UNIT, STATIC or TARGET object.
|
-- @param Core.Point#COORDINATE Target Target coordinate. Can also be specified as a GROUP, UNIT, STATIC, SET_GROUP, SET_UNIT, SET_STATIC or TARGET object.
|
||||||
-- @param #number Altitude Engage altitude in feet. Default 25000 ft.
|
-- @param #number Altitude Engage altitude in feet. Default 25000 ft.
|
||||||
-- @param #number EngageWeaponType Which weapon to use. Defaults to auto, ie ENUMS.WeaponFlag.Auto. See ENUMS.WeaponFlag for options.
|
-- @param #number EngageWeaponType Which weapon to use. Defaults to auto, ie ENUMS.WeaponFlag.Auto. See ENUMS.WeaponFlag for options.
|
||||||
-- @return #AUFTRAG self
|
-- @return #AUFTRAG self
|
||||||
@ -6108,10 +6110,13 @@ function AUFTRAG:GetDCSMissionTask()
|
|||||||
-- BOMBING Mission --
|
-- BOMBING Mission --
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
local DCStask=CONTROLLABLE.TaskBombing(nil, self:GetTargetVec2(), self.engageAsGroup, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType, Divebomb)
|
local coords = self.engageTarget:GetCoordinates()
|
||||||
|
for _, coord in pairs(coords) do
|
||||||
|
local DCStask = CONTROLLABLE.TaskBombing(nil, coord:GetVec2(), self.engageAsGroup, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType)
|
||||||
|
|
||||||
|
table.insert(DCStasks, DCStask)
|
||||||
|
end
|
||||||
|
|
||||||
table.insert(DCStasks, DCStask)
|
|
||||||
|
|
||||||
elseif self.type==AUFTRAG.Type.STRAFING then
|
elseif self.type==AUFTRAG.Type.STRAFING then
|
||||||
|
|
||||||
----------------------
|
----------------------
|
||||||
@ -6311,9 +6316,12 @@ function AUFTRAG:GetDCSMissionTask()
|
|||||||
-- STRIKE Mission --
|
-- STRIKE Mission --
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
local DCStask=CONTROLLABLE.TaskAttackMapObject(nil, self:GetTargetVec2(), self.engageAsGroup, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType)
|
local coords = self.engageTarget:GetCoordinates()
|
||||||
|
for _, coord in pairs(coords) do
|
||||||
|
local DCStask=CONTROLLABLE.TaskAttackMapObject(nil, coord:GetVec2(), self.engageAsGroup, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType)
|
||||||
|
|
||||||
table.insert(DCStasks, DCStask)
|
table.insert(DCStasks, DCStask)
|
||||||
|
end
|
||||||
|
|
||||||
elseif self.type==AUFTRAG.Type.TANKER or self.type==AUFTRAG.Type.RECOVERYTANKER then
|
elseif self.type==AUFTRAG.Type.TANKER or self.type==AUFTRAG.Type.RECOVERYTANKER then
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
-- @image OPS_CSAR.jpg
|
-- @image OPS_CSAR.jpg
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Last Update Jan 2025
|
-- Last Update May 2025
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
||||||
@ -263,6 +263,7 @@ CSAR = {
|
|||||||
rescuedpilots = 0,
|
rescuedpilots = 0,
|
||||||
limitmaxdownedpilots = true,
|
limitmaxdownedpilots = true,
|
||||||
maxdownedpilots = 10,
|
maxdownedpilots = 10,
|
||||||
|
useFIFOLimitReplacement = false, -- If true, it will remove the oldest downed pilot when a new one is added, if the limit is reached.
|
||||||
allheligroupset = nil,
|
allheligroupset = nil,
|
||||||
topmenuname = "CSAR",
|
topmenuname = "CSAR",
|
||||||
ADFRadioPwr = 1000,
|
ADFRadioPwr = 1000,
|
||||||
@ -313,7 +314,7 @@ CSAR.AircraftType["CH-47Fbl1"] = 31
|
|||||||
|
|
||||||
--- CSAR class version.
|
--- CSAR class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CSAR.version="1.0.30"
|
CSAR.version="1.0.33"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- ToDo list
|
-- ToDo list
|
||||||
@ -468,7 +469,7 @@ function CSAR:New(Coalition, Template, Alias)
|
|||||||
-- added 1.0.15
|
-- added 1.0.15
|
||||||
self.allowbronco = false -- set to true to use the Bronco mod as a CSAR plane
|
self.allowbronco = false -- set to true to use the Bronco mod as a CSAR plane
|
||||||
|
|
||||||
self.ADFRadioPwr = 1000
|
self.ADFRadioPwr = 500
|
||||||
|
|
||||||
-- added 1.0.16
|
-- added 1.0.16
|
||||||
self.PilotWeight = 80
|
self.PilotWeight = 80
|
||||||
@ -1144,19 +1145,8 @@ function CSAR:_EventHandler(EventData)
|
|||||||
self:T("Double Ejection!")
|
self:T("Double Ejection!")
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-- limit no of pilots in the field.
|
|
||||||
if self.limitmaxdownedpilots and self:_ReachedPilotLimit() then
|
|
||||||
self:T("Maxed Downed Pilot!")
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- TODO: Over water check --- EVENTS.LandingAfterEjection NOT triggered by DCS, so handle csarUsePara = true case
|
|
||||||
-- might create dual pilots in edge cases
|
|
||||||
|
|
||||||
local wetfeet = false
|
|
||||||
|
|
||||||
local initdcscoord = nil
|
local initdcscoord = nil
|
||||||
local initcoord = nil
|
local initcoord = nil
|
||||||
if _event.id == EVENTS.Ejection then
|
if _event.id == EVENTS.Ejection then
|
||||||
@ -1168,6 +1158,36 @@ function CSAR:_EventHandler(EventData)
|
|||||||
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
||||||
self:T({initdcscoord})
|
self:T({initdcscoord})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Remove downed pilot if already exists to replace with new one.
|
||||||
|
if _event.IniPlayerName then
|
||||||
|
local PilotTable = self.downedPilots --#CSAR.DownedPilot
|
||||||
|
local _foundPilot = nil
|
||||||
|
for _,_pilot in pairs(PilotTable) do
|
||||||
|
if _pilot.player == _event.IniPlayerName and _pilot.alive == true then
|
||||||
|
_foundPilot = _pilot
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if _foundPilot then
|
||||||
|
self:T("Downed pilot already exists!")
|
||||||
|
_foundPilot.group:Destroy(false)
|
||||||
|
self:_RemoveNameFromDownedPilots(_foundPilot.name)
|
||||||
|
self:_CheckDownedPilotTable()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- limit no of pilots in the field.
|
||||||
|
if self.limitmaxdownedpilots and self:_ReachedPilotLimit() then
|
||||||
|
self:T("Maxed Downed Pilot!")
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- TODO: Over water check --- EVENTS.LandingAfterEjection NOT triggered by DCS, so handle csarUsePara = true case
|
||||||
|
-- might create dual pilots in edge cases
|
||||||
|
|
||||||
|
local wetfeet = false
|
||||||
|
|
||||||
--local surface = _unit:GetCoordinate():GetSurfaceType()
|
--local surface = _unit:GetCoordinate():GetSurfaceType()
|
||||||
local surface = initcoord:GetSurfaceType()
|
local surface = initcoord:GetSurfaceType()
|
||||||
@ -2116,56 +2136,50 @@ end
|
|||||||
--- (Internal) Determine distance to closest MASH.
|
--- (Internal) Determine distance to closest MASH.
|
||||||
-- @param #CSAR self
|
-- @param #CSAR self
|
||||||
-- @param Wrapper.Unit#UNIT _heli Helicopter #UNIT
|
-- @param Wrapper.Unit#UNIT _heli Helicopter #UNIT
|
||||||
-- @return #CSAR self
|
-- @return #number Distance in meters
|
||||||
|
-- @return #string MASH Name as string
|
||||||
function CSAR:_GetClosestMASH(_heli)
|
function CSAR:_GetClosestMASH(_heli)
|
||||||
self:T(self.lid .. " _GetClosestMASH")
|
self:T(self.lid .. " _GetClosestMASH")
|
||||||
local _mashset = self.mash -- Core.Set#SET_GROUP
|
local _mashset = self.mash -- Core.Set#SET_GROUP
|
||||||
local _mashes = _mashset:GetSetObjects() -- #table
|
local MashSets = {}
|
||||||
|
--local _mashes = _mashset.Set-- #table
|
||||||
|
table.insert(MashSets,_mashset.Set)
|
||||||
|
table.insert(MashSets,self.zonemashes.Set)
|
||||||
|
table.insert(MashSets,self.staticmashes.Set)
|
||||||
local _shortestDistance = -1
|
local _shortestDistance = -1
|
||||||
local _distance = 0
|
local _distance = 0
|
||||||
local _helicoord = _heli:GetCoordinate()
|
local _helicoord = _heli:GetCoordinate()
|
||||||
|
local MashName = nil
|
||||||
local function GetCloseAirbase(coordinate,Coalition,Category)
|
|
||||||
|
|
||||||
local a=coordinate:GetVec3()
|
|
||||||
local distmin=math.huge
|
|
||||||
local airbase=nil
|
|
||||||
for DCSairbaseID, DCSairbase in pairs(world.getAirbases(Coalition)) do
|
|
||||||
local b=DCSairbase:getPoint()
|
|
||||||
|
|
||||||
local c=UTILS.VecSubstract(a,b)
|
|
||||||
local dist=UTILS.VecNorm(c)
|
|
||||||
|
|
||||||
if dist<distmin and (Category==nil or Category==DCSairbase:getDesc().category) then
|
|
||||||
distmin=dist
|
|
||||||
airbase=DCSairbase
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
return distmin
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.allowFARPRescue then
|
if self.allowFARPRescue then
|
||||||
local position = _heli:GetCoordinate()
|
local position = _heli:GetCoordinate()
|
||||||
local afb,distance = position:GetClosestAirbase(nil,self.coalition)
|
local afb,distance = position:GetClosestAirbase(nil,self.coalition)
|
||||||
_shortestDistance = distance
|
_shortestDistance = distance
|
||||||
|
MashName = (afb ~= nil) and afb:GetName() or "Unknown"
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, _mashUnit in pairs(_mashes) do
|
for _,_mashes in pairs(MashSets) do
|
||||||
if _mashUnit and _mashUnit:IsAlive() then
|
for _, _mashUnit in pairs(_mashes or {}) do
|
||||||
local _mashcoord = _mashUnit:GetCoordinate()
|
local _mashcoord
|
||||||
_distance = self:_GetDistance(_helicoord, _mashcoord)
|
if _mashUnit and (not _mashUnit:IsInstanceOf("ZONE_BASE")) and _mashUnit:IsAlive() then
|
||||||
if _distance ~= nil and (_shortestDistance == -1 or _distance < _shortestDistance) then
|
_mashcoord = _mashUnit:GetCoordinate()
|
||||||
_shortestDistance = _distance
|
elseif _mashUnit and _mashUnit:IsInstanceOf("ZONE_BASE") then
|
||||||
end
|
_mashcoord = _mashUnit:GetCoordinate()
|
||||||
end
|
end
|
||||||
|
_distance = self:_GetDistance(_helicoord, _mashcoord)
|
||||||
|
if _distance ~= nil and (_shortestDistance == -1 or _distance < _shortestDistance) then
|
||||||
|
_shortestDistance = _distance
|
||||||
|
MashName = _mashUnit:GetName() or "Unknown"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if _shortestDistance ~= -1 then
|
if _shortestDistance ~= -1 then
|
||||||
return _shortestDistance
|
return _shortestDistance, MashName
|
||||||
else
|
else
|
||||||
return -1
|
return -1
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (Internal) Display onboarded rescued pilots.
|
--- (Internal) Display onboarded rescued pilots.
|
||||||
@ -2323,9 +2337,9 @@ end
|
|||||||
-- @param #CSAR self
|
-- @param #CSAR self
|
||||||
-- @param Wrapper.Group#GROUP _group Group #GROUP object.
|
-- @param Wrapper.Group#GROUP _group Group #GROUP object.
|
||||||
-- @param #number _freq Frequency to use
|
-- @param #number _freq Frequency to use
|
||||||
-- @param #string _name Beacon Name to use
|
-- @param #string BeaconName Beacon Name to use
|
||||||
-- @return #CSAR self
|
-- @return #CSAR self
|
||||||
function CSAR:_AddBeaconToGroup(_group, _freq, _name)
|
function CSAR:_AddBeaconToGroup(_group, _freq, BeaconName)
|
||||||
self:T(self.lid .. " _AddBeaconToGroup")
|
self:T(self.lid .. " _AddBeaconToGroup")
|
||||||
if self.CreateRadioBeacons == false then return end
|
if self.CreateRadioBeacons == false then return end
|
||||||
local _group = _group
|
local _group = _group
|
||||||
@ -2346,10 +2360,11 @@ function CSAR:_AddBeaconToGroup(_group, _freq, _name)
|
|||||||
if _radioUnit then
|
if _radioUnit then
|
||||||
local name = _radioUnit:GetName()
|
local name = _radioUnit:GetName()
|
||||||
local Frequency = _freq -- Freq in Hertz
|
local Frequency = _freq -- Freq in Hertz
|
||||||
local name = _radioUnit:GetName()
|
--local name = _radioUnit:GetName()
|
||||||
local Sound = "l10n/DEFAULT/"..self.radioSound
|
local Sound = "l10n/DEFAULT/"..self.radioSound
|
||||||
local vec3 = _radioUnit:GetVec3() or _radioUnit:GetPositionVec3() or {x=0,y=0,z=0}
|
local vec3 = _radioUnit:GetVec3() or _radioUnit:GetPositionVec3() or {x=0,y=0,z=0}
|
||||||
trigger.action.radioTransmission(Sound, vec3, 0, false, Frequency, self.ADFRadioPwr or 1000,_name) -- Beacon in MP only runs for exactly 30secs straight
|
self:I(self.lid..string.format("Added Radio Beacon %d Hertz | Name %s | Position {%d,%d,%d}",Frequency,BeaconName,vec3.x,vec3.y,vec3.z))
|
||||||
|
trigger.action.radioTransmission(Sound, vec3, 0, true, Frequency, self.ADFRadioPwr or 500,BeaconName) -- Beacon in MP only runs for exactly 30secs straight
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -2370,9 +2385,13 @@ function CSAR:_RefreshRadioBeacons()
|
|||||||
local group = pilot.group
|
local group = pilot.group
|
||||||
local frequency = pilot.frequency or 0 -- thanks to @Thrud
|
local frequency = pilot.frequency or 0 -- thanks to @Thrud
|
||||||
local bname = pilot.BeaconName or pilot.name..math.random(1,100000)
|
local bname = pilot.BeaconName or pilot.name..math.random(1,100000)
|
||||||
trigger.action.stopRadioTransmission(bname)
|
--trigger.action.stopRadioTransmission(bname)
|
||||||
if group and group:IsAlive() and frequency > 0 then
|
if group and group:IsAlive() and frequency > 0 then
|
||||||
self:_AddBeaconToGroup(group,frequency,bname)
|
--self:_AddBeaconToGroup(group,frequency,bname)
|
||||||
|
else
|
||||||
|
if frequency > 0 then
|
||||||
|
trigger.action.stopRadioTransmission(bname)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -2402,11 +2421,26 @@ function CSAR:_ReachedPilotLimit()
|
|||||||
local limit = self.maxdownedpilots
|
local limit = self.maxdownedpilots
|
||||||
local islimited = self.limitmaxdownedpilots
|
local islimited = self.limitmaxdownedpilots
|
||||||
local count = self:_CountActiveDownedPilots()
|
local count = self:_CountActiveDownedPilots()
|
||||||
if islimited and (count >= limit) then
|
if islimited and (count >= limit) then
|
||||||
return true
|
if self.useFIFOLimitReplacement then
|
||||||
else
|
local oldIndex = -1
|
||||||
return false
|
local oldDownedPilot = nil
|
||||||
end
|
for _index, _downedpilot in pairs(self.downedPilots) do
|
||||||
|
oldIndex = _index
|
||||||
|
oldDownedPilot = _downedpilot
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if oldDownedPilot then
|
||||||
|
oldDownedPilot.group:Destroy(false)
|
||||||
|
oldDownedPilot.alive = false
|
||||||
|
self:_CheckDownedPilotTable()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- User - Function to add onw SET_GROUP Set-up for pilot filtering and assignment.
|
--- User - Function to add onw SET_GROUP Set-up for pilot filtering and assignment.
|
||||||
@ -2454,9 +2488,10 @@ function CSAR:onafterStart(From, Event, To)
|
|||||||
|
|
||||||
self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart()
|
self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart()
|
||||||
|
|
||||||
local staticmashes = SET_STATIC:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterOnce()
|
self.staticmashes = SET_STATIC:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterOnce()
|
||||||
local zonemashes = SET_ZONE:New():FilterPrefixes(self.mashprefix):FilterOnce()
|
self.zonemashes = SET_ZONE:New():FilterPrefixes(self.mashprefix):FilterOnce()
|
||||||
|
|
||||||
|
--[[
|
||||||
if staticmashes:Count() > 0 then
|
if staticmashes:Count() > 0 then
|
||||||
for _,_mash in pairs(staticmashes.Set) do
|
for _,_mash in pairs(staticmashes.Set) do
|
||||||
self.mash:AddObject(_mash)
|
self.mash:AddObject(_mash)
|
||||||
@ -2464,10 +2499,13 @@ function CSAR:onafterStart(From, Event, To)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if zonemashes:Count() > 0 then
|
if zonemashes:Count() > 0 then
|
||||||
|
self:T("Adding zones to self.mash SET")
|
||||||
for _,_mash in pairs(zonemashes.Set) do
|
for _,_mash in pairs(zonemashes.Set) do
|
||||||
self.mash:AddObject(_mash)
|
self.mash:AddObject(_mash)
|
||||||
end
|
end
|
||||||
|
self:T("Objects in SET: "..self.mash:Count())
|
||||||
end
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
if not self.coordinate then
|
if not self.coordinate then
|
||||||
local csarhq = self.mash:GetRandom()
|
local csarhq = self.mash:GetRandom()
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -70,6 +70,7 @@
|
|||||||
-- @field #boolean DespawnAfterLanding
|
-- @field #boolean DespawnAfterLanding
|
||||||
-- @field #boolean DespawnAfterHolding
|
-- @field #boolean DespawnAfterHolding
|
||||||
-- @field #list<Ops.Auftrag#AUFTRAG> ListOfAuftrag
|
-- @field #list<Ops.Auftrag#AUFTRAG> ListOfAuftrag
|
||||||
|
-- @field #string defaulttakeofftype Take off type
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
--- *“Airspeed, altitude, and brains. Two are always needed to successfully complete the flight.”* -- Unknown.
|
--- *“Airspeed, altitude, and brains. Two are always needed to successfully complete the flight.”* -- Unknown.
|
||||||
@ -223,7 +224,8 @@ EASYGCICAP = {
|
|||||||
ReadyFlightGroups = {},
|
ReadyFlightGroups = {},
|
||||||
DespawnAfterLanding = false,
|
DespawnAfterLanding = false,
|
||||||
DespawnAfterHolding = true,
|
DespawnAfterHolding = true,
|
||||||
ListOfAuftrag = {}
|
ListOfAuftrag = {},
|
||||||
|
defaulttakeofftype = "hot",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Internal Squadron data type
|
--- Internal Squadron data type
|
||||||
@ -259,7 +261,7 @@ EASYGCICAP = {
|
|||||||
|
|
||||||
--- EASYGCICAP class version.
|
--- EASYGCICAP class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
EASYGCICAP.version="0.1.18"
|
EASYGCICAP.version="0.1.22"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@ -312,6 +314,7 @@ function EASYGCICAP:New(Alias, AirbaseName, Coalition, EWRName)
|
|||||||
self.DespawnAfterLanding = false
|
self.DespawnAfterLanding = false
|
||||||
self.DespawnAfterHolding = true
|
self.DespawnAfterHolding = true
|
||||||
self.ListOfAuftrag = {}
|
self.ListOfAuftrag = {}
|
||||||
|
self.defaulttakeofftype = "hot"
|
||||||
|
|
||||||
-- Set some string id for output to DCS.log file.
|
-- Set some string id for output to DCS.log file.
|
||||||
self.lid=string.format("EASYGCICAP %s | ", self.alias)
|
self.lid=string.format("EASYGCICAP %s | ", self.alias)
|
||||||
@ -400,6 +403,16 @@ function EASYGCICAP:SetDefaultRepeatOnFailure(Retries)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add default take off type for the airwings.
|
||||||
|
-- @param #EASYGCICAP self
|
||||||
|
-- @param #string Takeoff Can be "hot", "cold", or "air" - default is "hot".
|
||||||
|
-- @return #EASYGCICAP self
|
||||||
|
function EASYGCICAP:SetDefaultTakeOffType(Takeoff)
|
||||||
|
self:T(self.lid.."SetDefaultTakeOffType")
|
||||||
|
self.defaulttakeofftype = Takeoff or "hot"
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Set default CAP Speed in knots
|
--- Set default CAP Speed in knots
|
||||||
-- @param #EASYGCICAP self
|
-- @param #EASYGCICAP self
|
||||||
-- @param #number Speed Speed defaults to 300
|
-- @param #number Speed Speed defaults to 300
|
||||||
@ -569,6 +582,13 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
|||||||
local DespawnAfterLanding = self.DespawnAfterLanding
|
local DespawnAfterLanding = self.DespawnAfterLanding
|
||||||
local DespawnAfterHolding = self.DespawnAfterHolding
|
local DespawnAfterHolding = self.DespawnAfterHolding
|
||||||
|
|
||||||
|
-- Check STATIC name
|
||||||
|
local check = STATIC:FindByName(Airbasename,false)
|
||||||
|
if check == nil then
|
||||||
|
MESSAGE:New(self.lid.."There's no warehouse static on the map (wrong naming?) for airbase "..tostring(Airbasename).."!",30,"CHECK"):ToAllIf(self.debug):ToLog()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- Create Airwing
|
-- Create Airwing
|
||||||
local CAP_Wing = AIRWING:New(Airbasename,Alias)
|
local CAP_Wing = AIRWING:New(Airbasename,Alias)
|
||||||
CAP_Wing:SetVerbosityLevel(0)
|
CAP_Wing:SetVerbosityLevel(0)
|
||||||
@ -596,9 +616,8 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
|||||||
if #self.ManagedREC > 0 then
|
if #self.ManagedREC > 0 then
|
||||||
CAP_Wing:SetNumberRecon(1)
|
CAP_Wing:SetNumberRecon(1)
|
||||||
end
|
end
|
||||||
--local PatrolCoordinateKutaisi = ZONE:New(CapZoneName):GetCoordinate()
|
|
||||||
--CAP_Wing:AddPatrolPointCAP(PatrolCoordinateKutaisi,self.capalt,UTILS.KnotsToAltKIAS(self.capspeed,self.capalt),self.capdir,self.capleg)
|
CAP_Wing:SetTakeoffType(self.defaulttakeofftype)
|
||||||
CAP_Wing:SetTakeoffHot()
|
|
||||||
CAP_Wing:SetLowFuelThreshold(0.3)
|
CAP_Wing:SetLowFuelThreshold(0.3)
|
||||||
CAP_Wing.RandomAssetScore = math.random(50,100)
|
CAP_Wing.RandomAssetScore = math.random(50,100)
|
||||||
CAP_Wing:Start()
|
CAP_Wing:Start()
|
||||||
@ -606,6 +625,9 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
|||||||
local Intel = self.Intel
|
local Intel = self.Intel
|
||||||
|
|
||||||
local TankerInvisible = self.TankerInvisible
|
local TankerInvisible = self.TankerInvisible
|
||||||
|
local engagerange = self.engagerange
|
||||||
|
local GoZoneSet = self.GoZoneSet
|
||||||
|
local NoGoZoneSet = self.NoGoZoneSet
|
||||||
|
|
||||||
function CAP_Wing:onbeforeFlightOnMission(From, Event, To, Flightgroup, Mission)
|
function CAP_Wing:onbeforeFlightOnMission(From, Event, To, Flightgroup, Mission)
|
||||||
local flightgroup = Flightgroup -- Ops.FlightGroup#FLIGHTGROUP
|
local flightgroup = Flightgroup -- Ops.FlightGroup#FLIGHTGROUP
|
||||||
@ -619,7 +641,7 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
|||||||
flightgroup:GetGroup():SetOptionRadarUsingForContinousSearch()
|
flightgroup:GetGroup():SetOptionRadarUsingForContinousSearch()
|
||||||
if Mission.type ~= AUFTRAG.Type.TANKER and Mission.type ~= AUFTRAG.Type.AWACS and Mission.type ~= AUFTRAG.Type.RECON then
|
if Mission.type ~= AUFTRAG.Type.TANKER and Mission.type ~= AUFTRAG.Type.AWACS and Mission.type ~= AUFTRAG.Type.RECON then
|
||||||
flightgroup:SetDetection(true)
|
flightgroup:SetDetection(true)
|
||||||
flightgroup:SetEngageDetectedOn(self.engagerange,{"Air"},self.GoZoneSet,self.NoGoZoneSet)
|
flightgroup:SetEngageDetectedOn(engagerange,{"Air"},GoZoneSet,NoGoZoneSet)
|
||||||
flightgroup:SetOutOfAAMRTB()
|
flightgroup:SetOutOfAAMRTB()
|
||||||
if CapFormation then
|
if CapFormation then
|
||||||
flightgroup:GetGroup():SetOption(AI.Option.Air.id.FORMATION,CapFormation)
|
flightgroup:GetGroup():SetOption(AI.Option.Air.id.FORMATION,CapFormation)
|
||||||
@ -801,6 +823,11 @@ function EASYGCICAP:_SetCAPPatrolPoints()
|
|||||||
self:T(self.lid.."_SetCAPPatrolPoints")
|
self:T(self.lid.."_SetCAPPatrolPoints")
|
||||||
for _,_data in pairs(self.ManagedCP) do
|
for _,_data in pairs(self.ManagedCP) do
|
||||||
local data = _data --#EASYGCICAP.CapPoint
|
local data = _data --#EASYGCICAP.CapPoint
|
||||||
|
self:T("Airbasename = "..data.AirbaseName)
|
||||||
|
if not self.wings[data.AirbaseName] then
|
||||||
|
MESSAGE:New(self.lid.."You are trying to create a CAP point for which there is no wing! "..tostring(data.AirbaseName),30,"CHECK"):ToAllIf(self.debug):ToLog()
|
||||||
|
return
|
||||||
|
end
|
||||||
local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING
|
local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING
|
||||||
local Coordinate = data.Coordinate
|
local Coordinate = data.Coordinate
|
||||||
local Altitude = data.Altitude
|
local Altitude = data.Altitude
|
||||||
|
|||||||
@ -259,7 +259,7 @@ function FLIGHTGROUP:New(group)
|
|||||||
local self=BASE:Inherit(self, OPSGROUP:New(group)) -- #FLIGHTGROUP
|
local self=BASE:Inherit(self, OPSGROUP:New(group)) -- #FLIGHTGROUP
|
||||||
|
|
||||||
-- Set some string id for output to DCS.log file.
|
-- Set some string id for output to DCS.log file.
|
||||||
self.lid=string.format("FLIGHTGROUP %s | ", self.groupname)
|
self.lid=string.format("FLIGHTGROUP %s | ", self.groupname or "N/A")
|
||||||
|
|
||||||
-- Defaults
|
-- Defaults
|
||||||
self:SetDefaultROE()
|
self:SetDefaultROE()
|
||||||
@ -2002,6 +2002,9 @@ function FLIGHTGROUP:onafterElementAirborne(From, Event, To, Element)
|
|||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T2(self.lid..string.format("Element airborne %s", Element.name))
|
self:T2(self.lid..string.format("Element airborne %s", Element.name))
|
||||||
|
|
||||||
|
-- Set parking spot to free. Also for FC. This is usually done after taxiing but doing it here in case the group is teleported.
|
||||||
|
self:_SetElementParkingFree(Element)
|
||||||
|
|
||||||
-- Set element status.
|
-- Set element status.
|
||||||
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.AIRBORNE)
|
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.AIRBORNE)
|
||||||
|
|||||||
@ -2324,7 +2324,7 @@ INTEL_DLINK = {
|
|||||||
verbose = 0,
|
verbose = 0,
|
||||||
lid = nil,
|
lid = nil,
|
||||||
alias = nil,
|
alias = nil,
|
||||||
cachetime = 300,
|
cachetime = 120,
|
||||||
interval = 20,
|
interval = 20,
|
||||||
contacts = {},
|
contacts = {},
|
||||||
clusters = {},
|
clusters = {},
|
||||||
@ -2333,7 +2333,7 @@ INTEL_DLINK = {
|
|||||||
|
|
||||||
--- Version string
|
--- Version string
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
INTEL_DLINK.version = "0.0.1"
|
INTEL_DLINK.version = "0.0.2"
|
||||||
|
|
||||||
--- Function to instantiate a new object
|
--- Function to instantiate a new object
|
||||||
-- @param #INTEL_DLINK self
|
-- @param #INTEL_DLINK self
|
||||||
@ -2384,15 +2384,15 @@ function INTEL_DLINK:New(Intels, Alias, Interval, Cachetime)
|
|||||||
self.alias="SPECTRE"
|
self.alias="SPECTRE"
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Cache time
|
|
||||||
self.cachetime = Cachetime or 300
|
|
||||||
|
|
||||||
-- Interval
|
-- Interval
|
||||||
self.interval = Interval or 20
|
self.interval = Interval or 20
|
||||||
|
|
||||||
-- Set some string id for output to DCS.log file.
|
-- Set some string id for output to DCS.log file.
|
||||||
self.lid=string.format("INTEL_DLINK %s | ", self.alias)
|
self.lid=string.format("INTEL_DLINK %s | ", self.alias)
|
||||||
|
|
||||||
|
-- Cache time
|
||||||
|
self:SetDLinkCacheTime(Cachetime or 120)
|
||||||
|
|
||||||
-- Start State.
|
-- Start State.
|
||||||
self:SetStartState("Stopped")
|
self:SetStartState("Stopped")
|
||||||
|
|
||||||
@ -2477,6 +2477,16 @@ function INTEL_DLINK:onafterStart(From, Event, To)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Function to set how long INTEL DLINK remembers contacts.
|
||||||
|
-- @param #INTEL_DLINK self
|
||||||
|
-- @param #number seconds Remember this many seconds. Defaults to 180.
|
||||||
|
-- @return #INTEL_DLINK self
|
||||||
|
function INTEL_DLINK:SetDLinkCacheTime(seconds)
|
||||||
|
self.cachetime = math.abs(seconds or 120)
|
||||||
|
self:I(self.lid.."Caching for "..self.cachetime.." seconds.")
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Function to collect data from the various #INTEL
|
--- Function to collect data from the various #INTEL
|
||||||
-- @param #INTEL_DLINK self
|
-- @param #INTEL_DLINK self
|
||||||
-- @param #string From The From state
|
-- @param #string From The From state
|
||||||
|
|||||||
@ -5589,10 +5589,13 @@ function OPSGROUP:onafterUnpauseMission(From, Event, To)
|
|||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(self.lid..string.format("Unpausing mission %s [%s]", mission:GetName(), mission:GetType()))
|
self:T(self.lid..string.format("Unpausing mission %s [%s]", mission:GetName(), mission:GetType()))
|
||||||
|
|
||||||
|
-- Set state of mission, e.g. for not teleporting again
|
||||||
|
mission.unpaused=true
|
||||||
|
|
||||||
-- Start mission.
|
-- Start mission.
|
||||||
self:MissionStart(mission)
|
self:MissionStart(mission)
|
||||||
|
|
||||||
-- Remove mission from
|
-- Remove mission from pausedmissions queue
|
||||||
for i,mid in pairs(self.pausedmissions) do
|
for i,mid in pairs(self.pausedmissions) do
|
||||||
--self:T(self.lid..string.format("Checking paused mission", mid))
|
--self:T(self.lid..string.format("Checking paused mission", mid))
|
||||||
if mid==mission.auftragsnummer then
|
if mid==mission.auftragsnummer then
|
||||||
@ -6232,7 +6235,7 @@ function OPSGROUP:RouteToMission(mission, delay)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Check if group is mobile. Note that some immobile units report a speed of 1 m/s = 3.6 km/h.
|
-- Check if group is mobile. Note that some immobile units report a speed of 1 m/s = 3.6 km/h.
|
||||||
if self.speedMax<=3.6 or mission.teleport then
|
if (self.speedMax<=3.6 or mission.teleport) and not mission.unpaused then
|
||||||
|
|
||||||
-- Teleport to waypoint coordinate. Mission will not be paused.
|
-- Teleport to waypoint coordinate. Mission will not be paused.
|
||||||
self:Teleport(waypointcoord, nil, true)
|
self:Teleport(waypointcoord, nil, true)
|
||||||
|
|||||||
@ -53,7 +53,8 @@
|
|||||||
-- @field #number threatlevelCapture Threat level necessary to capture a zone.
|
-- @field #number threatlevelCapture Threat level necessary to capture a zone.
|
||||||
-- @field Core.Set#SET_UNIT ScanUnitSet Set of scanned units.
|
-- @field Core.Set#SET_UNIT ScanUnitSet Set of scanned units.
|
||||||
-- @field Core.Set#SET_GROUP ScanGroupSet Set of scanned groups.
|
-- @field Core.Set#SET_GROUP ScanGroupSet Set of scanned groups.
|
||||||
-- @extends Core.Fsm#FSM
|
-- @field #number UpdateSeconds Run status every this many seconds.
|
||||||
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
--- *Gentlemen, when the enemy is committed to a mistake we must not interrupt him too soon.* --- Horation Nelson
|
--- *Gentlemen, when the enemy is committed to a mistake we must not interrupt him too soon.* --- Horation Nelson
|
||||||
--
|
--
|
||||||
@ -77,6 +78,7 @@ OPSZONE = {
|
|||||||
Tnut = 0,
|
Tnut = 0,
|
||||||
chiefs = {},
|
chiefs = {},
|
||||||
Missions = {},
|
Missions = {},
|
||||||
|
UpdateSeconds = 120,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- OPSZONE.MISSION
|
--- OPSZONE.MISSION
|
||||||
@ -97,7 +99,7 @@ OPSZONE.ZoneType={
|
|||||||
|
|
||||||
--- OPSZONE class version.
|
--- OPSZONE class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
OPSZONE.version="0.6.1"
|
OPSZONE.version="0.6.2"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- ToDo list
|
-- ToDo list
|
||||||
@ -733,7 +735,8 @@ function OPSZONE:onafterStart(From, Event, To)
|
|||||||
self.timerStatus=self.timerStatus or TIMER:New(OPSZONE.Status, self)
|
self.timerStatus=self.timerStatus or TIMER:New(OPSZONE.Status, self)
|
||||||
|
|
||||||
-- Status update.
|
-- Status update.
|
||||||
self.timerStatus:Start(1, 120)
|
local EveryUpdateIn = self.UpdateSeconds or 120
|
||||||
|
self.timerStatus:Start(1, EveryUpdateIn)
|
||||||
|
|
||||||
-- Handle base captured event.
|
-- Handle base captured event.
|
||||||
if self.airbase then
|
if self.airbase then
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
-- ===
|
-- ===
|
||||||
-- @module Ops.PlayerTask
|
-- @module Ops.PlayerTask
|
||||||
-- @image OPS_PlayerTask.jpg
|
-- @image OPS_PlayerTask.jpg
|
||||||
-- @date Last Update Jan 2025
|
-- @date Last Update May 2025
|
||||||
|
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -98,7 +98,7 @@ PLAYERTASK = {
|
|||||||
|
|
||||||
--- PLAYERTASK class version.
|
--- PLAYERTASK class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
PLAYERTASK.version="0.1.25"
|
PLAYERTASK.version="0.1.27"
|
||||||
|
|
||||||
--- Generic task condition.
|
--- Generic task condition.
|
||||||
-- @type PLAYERTASK.Condition
|
-- @type PLAYERTASK.Condition
|
||||||
@ -556,6 +556,7 @@ end
|
|||||||
-- @param #PLAYERTASK self
|
-- @param #PLAYERTASK self
|
||||||
-- @param #SET_BASE CaptureSquadGroupNamePrefix The prefix of the group name that needs to capture the zone.
|
-- @param #SET_BASE CaptureSquadGroupNamePrefix The prefix of the group name that needs to capture the zone.
|
||||||
-- @param #number Coalition The coalition that needs to capture the zone.
|
-- @param #number Coalition The coalition that needs to capture the zone.
|
||||||
|
-- @param #boolean CheckClientInZone If true, a CLIENT assigned to this task also needs to be in the zone for the task to be successful.
|
||||||
-- @return #PLAYERTASK self
|
-- @return #PLAYERTASK self
|
||||||
-- @usage
|
-- @usage
|
||||||
-- -- We can use either STATIC, SET_STATIC, SCENERY or SET_SCENERY as target objects.
|
-- -- We can use either STATIC, SET_STATIC, SCENERY or SET_SCENERY as target objects.
|
||||||
@ -570,20 +571,20 @@ end
|
|||||||
--
|
--
|
||||||
-- -- We set CaptureSquadGroupNamePrefix the group name prefix as set in the ME or the spawn of the group that need to be present at the OpsZone like a capture squad,
|
-- -- We set CaptureSquadGroupNamePrefix the group name prefix as set in the ME or the spawn of the group that need to be present at the OpsZone like a capture squad,
|
||||||
-- -- and set the capturing Coalition in order to trigger a successful task.
|
-- -- and set the capturing Coalition in order to trigger a successful task.
|
||||||
-- mytask:AddOpsZoneCaptureSuccessCondition("capture-squad", coalition.side.BLUE)
|
-- mytask:AddOpsZoneCaptureSuccessCondition("capture-squad", coalition.side.BLUE, false)
|
||||||
--
|
--
|
||||||
-- playerTaskManager:AddPlayerTaskToQueue(mytask)
|
-- playerTaskManager:AddPlayerTaskToQueue(mytask)
|
||||||
function PLAYERTASK:AddOpsZoneCaptureSuccessCondition(CaptureSquadGroupNamePrefix, Coalition)
|
function PLAYERTASK:AddOpsZoneCaptureSuccessCondition(CaptureSquadGroupNamePrefix, Coalition, CheckClientInZone)
|
||||||
local task = self
|
local task = self
|
||||||
task:AddConditionSuccess(
|
task:AddConditionSuccess(
|
||||||
function(target)
|
function(target)
|
||||||
if target:IsInstanceOf("OPSZONE") then
|
if target:IsInstanceOf("OPSZONE") then
|
||||||
return task:_CheckCaptureOpsZoneSuccess(target, CaptureSquadGroupNamePrefix, Coalition, true)
|
return task:_CheckCaptureOpsZoneSuccess(target, CaptureSquadGroupNamePrefix, Coalition, CheckClientInZone or true)
|
||||||
elseif target:IsInstanceOf("SET_OPSZONE") then
|
elseif target:IsInstanceOf("SET_OPSZONE") then
|
||||||
local successes = 0
|
local successes = 0
|
||||||
local isClientInZone = false
|
local isClientInZone = false
|
||||||
target:ForEachZone(function(opszone)
|
target:ForEachZone(function(opszone)
|
||||||
if task:_CheckCaptureOpsZoneSuccess(opszone, CaptureSquadGroupNamePrefix, Coalition) then
|
if task:_CheckCaptureOpsZoneSuccess(opszone, CaptureSquadGroupNamePrefix, Coalition, CheckClientInZone or true) then
|
||||||
successes = successes + 1
|
successes = successes + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -979,6 +980,12 @@ function PLAYERTASK:onafterStatus(From, Event, To)
|
|||||||
|
|
||||||
if status == "Stopped" then return self end
|
if status == "Stopped" then return self end
|
||||||
|
|
||||||
|
-- update marker in case target is moving
|
||||||
|
if self.TargetMarker then
|
||||||
|
local coordinate = self.Target:GetCoordinate()
|
||||||
|
self.TargetMarker:UpdateCoordinate(coordinate,0.5)
|
||||||
|
end
|
||||||
|
|
||||||
-- Check Target status
|
-- Check Target status
|
||||||
local targetdead = false
|
local targetdead = false
|
||||||
|
|
||||||
@ -1902,7 +1909,7 @@ PLAYERTASKCONTROLLER.Messages = {
|
|||||||
|
|
||||||
--- PLAYERTASK class version.
|
--- PLAYERTASK class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
PLAYERTASKCONTROLLER.version="0.1.69"
|
PLAYERTASKCONTROLLER.version="0.1.70"
|
||||||
|
|
||||||
--- Create and run a new TASKCONTROLLER instance.
|
--- Create and run a new TASKCONTROLLER instance.
|
||||||
-- @param #PLAYERTASKCONTROLLER self
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
@ -1944,7 +1951,7 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter)
|
|||||||
self.taskinfomenu = false
|
self.taskinfomenu = false
|
||||||
self.activehasinfomenu = false
|
self.activehasinfomenu = false
|
||||||
self.MenuName = nil
|
self.MenuName = nil
|
||||||
self.menuitemlimit = 5
|
self.menuitemlimit = 6
|
||||||
self.holdmenutime = 30
|
self.holdmenutime = 30
|
||||||
|
|
||||||
self.MarkerReadOnly = false
|
self.MarkerReadOnly = false
|
||||||
@ -2415,7 +2422,7 @@ function PLAYERTASKCONTROLLER:EnablePrecisionBombing(FlightGroup,LaserCode,Holdi
|
|||||||
end
|
end
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
self:E(self.lid.."No FLIGHTGROUP object passed or FLIGHTGROUP is not alive!")
|
self:E(self.lid.."No OPSGROUP/SET_OPSGROUP object passed or object is not alive!")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self.autolase = nil
|
self.autolase = nil
|
||||||
@ -2574,7 +2581,7 @@ function PLAYERTASKCONTROLLER:SetMenuOptions(InfoMenu,ItemLimit,HoldTime)
|
|||||||
if self.activehasinfomenu then
|
if self.activehasinfomenu then
|
||||||
self:EnableTaskInfoMenu()
|
self:EnableTaskInfoMenu()
|
||||||
end
|
end
|
||||||
self.menuitemlimit = ItemLimit or 5
|
self.menuitemlimit = ItemLimit+1 or 6
|
||||||
self.holdmenutime = HoldTime or 30
|
self.holdmenutime = HoldTime or 30
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -3479,7 +3486,7 @@ end
|
|||||||
-- @param #PLAYERTASKCONTROLLER self
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
-- @param Ops.PlayerTask#PLAYERTASK PlayerTask
|
-- @param Ops.PlayerTask#PLAYERTASK PlayerTask
|
||||||
-- @param #boolean Silent If true, make no "has new task" announcement
|
-- @param #boolean Silent If true, make no "has new task" announcement
|
||||||
-- @param #boolen TaskFilter If true, apply the white/black-list task filters here, also
|
-- @param #boolean TaskFilter If true, apply the white/black-list task filters here, also
|
||||||
-- @return #PLAYERTASKCONTROLLER self
|
-- @return #PLAYERTASKCONTROLLER self
|
||||||
-- @usage
|
-- @usage
|
||||||
-- Example to create a PLAYERTASK of type CTLD and give Players 10 minutes to complete:
|
-- Example to create a PLAYERTASK of type CTLD and give Players 10 minutes to complete:
|
||||||
@ -3703,6 +3710,7 @@ function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Task, Group, Client)
|
|||||||
else
|
else
|
||||||
CoordText = Coordinate:ToStringA2A(Client,nil,self.ShowMagnetic)
|
CoordText = Coordinate:ToStringA2A(Client,nil,self.ShowMagnetic)
|
||||||
end
|
end
|
||||||
|
--self:I("CoordText = "..CoordText)
|
||||||
-- Threat Level
|
-- Threat Level
|
||||||
local ThreatLevel = task.Target:GetThreatLevelMax()
|
local ThreatLevel = task.Target:GetThreatLevelMax()
|
||||||
--local ThreatLevelText = "high"
|
--local ThreatLevelText = "high"
|
||||||
@ -3837,7 +3845,8 @@ function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Task, Group, Client)
|
|||||||
Text = string.gsub(Text,"9","niner")
|
Text = string.gsub(Text,"9","niner")
|
||||||
CoordText = "MGRS;"..Text
|
CoordText = "MGRS;"..Text
|
||||||
if self.PathToGoogleKey then
|
if self.PathToGoogleKey then
|
||||||
CoordText = string.format("<say-as interpret-as='characters'>%s</say-as>",CoordText)
|
--CoordText = string.format("<say-as interpret-as=\'characters\'>%s</say-as>",CoordText)
|
||||||
|
--doesn't seem to work any longer
|
||||||
end
|
end
|
||||||
--self:I(self.lid.." | ".. CoordText)
|
--self:I(self.lid.." | ".. CoordText)
|
||||||
end
|
end
|
||||||
@ -3855,10 +3864,12 @@ function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Task, Group, Client)
|
|||||||
CoordText = string.gsub(ttstext," BR, "," Bee, Arr, ")
|
CoordText = string.gsub(ttstext," BR, "," Bee, Arr, ")
|
||||||
end
|
end
|
||||||
elseif task:HasFreetext() then
|
elseif task:HasFreetext() then
|
||||||
|
|
||||||
-- add tts freetext
|
-- add tts freetext
|
||||||
local brieftxt = self.gettext:GetEntry("BRIEFING",self.locale)
|
local brieftxt = self.gettext:GetEntry("BRIEFING",self.locale)
|
||||||
ttstext = ttstext .. string.format("; %s: ",brieftxt)..task:GetFreetextTTS()
|
ttstext = ttstext .. string.format("; %s: ",brieftxt)..task:GetFreetextTTS()
|
||||||
end
|
end
|
||||||
|
--self:I("**** TTS Text ****\n"..ttstext.."\n*****")
|
||||||
self.SRSQueue:NewTransmission(ttstext,nil,self.SRS,nil,2)
|
self.SRSQueue:NewTransmission(ttstext,nil,self.SRS,nil,2)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -4357,7 +4368,7 @@ function PLAYERTASKCONTROLLER:SwitchDetectStatics(OnOff)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [User] Add accept zone to INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
--- [User] Add an accept zone to INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
||||||
-- @param #PLAYERTASKCONTROLLER self
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
-- @param Core.Zone#ZONE AcceptZone Add a zone to the accept zone set.
|
-- @param Core.Zone#ZONE AcceptZone Add a zone to the accept zone set.
|
||||||
-- @return #PLAYERTASKCONTROLLER self
|
-- @return #PLAYERTASKCONTROLLER self
|
||||||
@ -4371,7 +4382,7 @@ function PLAYERTASKCONTROLLER:AddAcceptZone(AcceptZone)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [User] Add accept SET_ZONE to INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
--- [User] Add an accept SET_ZONE to INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
||||||
-- @param #PLAYERTASKCONTROLLER self
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
-- @param Core.Set#SET_ZONE AcceptZoneSet Add a SET_ZONE to the accept zone set.
|
-- @param Core.Set#SET_ZONE AcceptZoneSet Add a SET_ZONE to the accept zone set.
|
||||||
-- @return #PLAYERTASKCONTROLLER self
|
-- @return #PLAYERTASKCONTROLLER self
|
||||||
@ -4385,7 +4396,7 @@ function PLAYERTASKCONTROLLER:AddAcceptZoneSet(AcceptZoneSet)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [User] Add reject zone to INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
--- [User] Add a reject zone to INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
||||||
-- @param #PLAYERTASKCONTROLLER self
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
-- @param Core.Zone#ZONE RejectZone Add a zone to the reject zone set.
|
-- @param Core.Zone#ZONE RejectZone Add a zone to the reject zone set.
|
||||||
-- @return #PLAYERTASKCONTROLLER self
|
-- @return #PLAYERTASKCONTROLLER self
|
||||||
@ -4399,7 +4410,7 @@ function PLAYERTASKCONTROLLER:AddRejectZone(RejectZone)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [User] Add reject SET_ZONE to INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
--- [User] Add a reject SET_ZONE to INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
||||||
-- @param #PLAYERTASKCONTROLLER self
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
-- @param Core.Set#SET_ZONE RejectZoneSet Add a zone to the reject zone set.
|
-- @param Core.Set#SET_ZONE RejectZoneSet Add a zone to the reject zone set.
|
||||||
-- @return #PLAYERTASKCONTROLLER self
|
-- @return #PLAYERTASKCONTROLLER self
|
||||||
@ -4413,9 +4424,37 @@ function PLAYERTASKCONTROLLER:AddRejectZoneSet(RejectZoneSet)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [User] Remove accept zone from INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
--- [User] Add a conflict zone to INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
||||||
-- @param #PLAYERTASKCONTROLLER self
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
-- @param Core.Zone#ZONE AcceptZone Add a zone to the accept zone set.
|
-- @param Core.Zone#ZONE ConflictZone Add a zone to the conflict zone set.
|
||||||
|
-- @return #PLAYERTASKCONTROLLER self
|
||||||
|
function PLAYERTASKCONTROLLER:AddConflictZone(ConflictZone)
|
||||||
|
self:T(self.lid.."AddConflictZone")
|
||||||
|
if self.Intel then
|
||||||
|
self.Intel:AddConflictZone(ConflictZone)
|
||||||
|
else
|
||||||
|
self:E(self.lid.."*****NO detection has been set up (yet)!")
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [User] Add a conflict SET_ZONE to INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
||||||
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
|
-- @param Core.Set#SET_ZONE ConflictZoneSet Add a zone to the conflict zone set.
|
||||||
|
-- @return #PLAYERTASKCONTROLLER self
|
||||||
|
function PLAYERTASKCONTROLLER:AddConflictZoneSet(ConflictZoneSet)
|
||||||
|
self:T(self.lid.."AddConflictZoneSet")
|
||||||
|
if self.Intel then
|
||||||
|
self.Intel.conflictzoneset:AddSet(ConflictZoneSet)
|
||||||
|
else
|
||||||
|
self:E(self.lid.."*****NO detection has been set up (yet)!")
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [User] Remove an accept zone from INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
||||||
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
|
-- @param Core.Zone#ZONE AcceptZone Remove this zone from the accept zone set.
|
||||||
-- @return #PLAYERTASKCONTROLLER self
|
-- @return #PLAYERTASKCONTROLLER self
|
||||||
function PLAYERTASKCONTROLLER:RemoveAcceptZone(AcceptZone)
|
function PLAYERTASKCONTROLLER:RemoveAcceptZone(AcceptZone)
|
||||||
self:T(self.lid.."RemoveAcceptZone")
|
self:T(self.lid.."RemoveAcceptZone")
|
||||||
@ -4427,11 +4466,11 @@ function PLAYERTASKCONTROLLER:RemoveAcceptZone(AcceptZone)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [User] Remove reject zone from INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
--- [User] Remove a reject zone from INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
||||||
-- @param #PLAYERTASKCONTROLLER self
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
-- @param Core.Zone#ZONE RejectZone Add a zone to the reject zone set.
|
-- @param Core.Zone#ZONE RejectZone Remove this zone from the reject zone set.
|
||||||
-- @return #PLAYERTASKCONTROLLER self
|
-- @return #PLAYERTASKCONTROLLER self
|
||||||
function PLAYERTASKCONTROLLER:RemoveRejectZoneSet(RejectZone)
|
function PLAYERTASKCONTROLLER:RemoveRejectZone(RejectZone)
|
||||||
self:T(self.lid.."RemoveRejectZone")
|
self:T(self.lid.."RemoveRejectZone")
|
||||||
if self.Intel then
|
if self.Intel then
|
||||||
self.Intel:RemoveRejectZone(RejectZone)
|
self.Intel:RemoveRejectZone(RejectZone)
|
||||||
@ -4441,6 +4480,20 @@ function PLAYERTASKCONTROLLER:RemoveRejectZoneSet(RejectZone)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [User] Remove a conflict zone from INTEL detection. You need to set up detection with @{#PLAYERTASKCONTROLLER.SetupIntel}() **before** using this.
|
||||||
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
|
-- @param Core.Zone#ZONE ConflictZone Remove this zone from the conflict zone set.
|
||||||
|
-- @return #PLAYERTASKCONTROLLER self
|
||||||
|
function PLAYERTASKCONTROLLER:RemoveConflictZone(ConflictZone)
|
||||||
|
self:T(self.lid.."RemoveConflictZone")
|
||||||
|
if self.Intel then
|
||||||
|
self.Intel:RemoveConflictZone(ConflictZone)
|
||||||
|
else
|
||||||
|
self:E(self.lid.."*****NO detection has been set up (yet)!")
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- [User] Set the top menu name to a custom string.
|
--- [User] Set the top menu name to a custom string.
|
||||||
-- @param #PLAYERTASKCONTROLLER self
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
-- @param #string Name The name to use as the top menu designation.
|
-- @param #string Name The name to use as the top menu designation.
|
||||||
|
|||||||
@ -1715,6 +1715,26 @@ function TARGET:GetAverageCoordinate()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get coordinates of all targets. (e.g. for a SET_STATIC)
|
||||||
|
-- @param #TARGET self
|
||||||
|
-- @return #table Table with coordinates of all targets.
|
||||||
|
function TARGET:GetCoordinates()
|
||||||
|
local coordinates={}
|
||||||
|
|
||||||
|
for _,_target in pairs(self.targets) do
|
||||||
|
local target=_target --#TARGET.Object
|
||||||
|
|
||||||
|
local coordinate=self:GetTargetCoordinate(target)
|
||||||
|
if coordinate then
|
||||||
|
table.insert(coordinates, coordinate)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return coordinates
|
||||||
|
end
|
||||||
|
|
||||||
--- Get heading of target.
|
--- Get heading of target.
|
||||||
-- @param #TARGET self
|
-- @param #TARGET self
|
||||||
-- @return #number Heading of the target in degrees.
|
-- @return #number Heading of the target in degrees.
|
||||||
@ -1968,6 +1988,21 @@ function TARGET:GetObject(RefCoordinate, Coalitions)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get all target objects.
|
||||||
|
-- @param #TARGET self
|
||||||
|
-- @return #table List of target objects.
|
||||||
|
function TARGET:GetObjects()
|
||||||
|
local objects={}
|
||||||
|
|
||||||
|
for _,_target in pairs(self.targets) do
|
||||||
|
local target=_target --#TARGET.Object
|
||||||
|
|
||||||
|
table.insert(objects, target.Object)
|
||||||
|
end
|
||||||
|
|
||||||
|
return objects
|
||||||
|
end
|
||||||
|
|
||||||
--- Count alive objects.
|
--- Count alive objects.
|
||||||
-- @param #TARGET self
|
-- @param #TARGET self
|
||||||
-- @param #TARGET.Object Target Target objective.
|
-- @param #TARGET.Object Target Target objective.
|
||||||
|
|||||||
@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
|
|
||||||
--- Governs multiple missions, the tasking and the reporting.
|
--- Governs multiple missions, the tasking and the reporting.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- Command centers govern missions, communicates the task assignments between human players of the coalition, and manages the menu flow.
|
-- Command centers govern missions, communicates the task assignments between human players of the coalition, and manages the menu flow.
|
||||||
-- It can assign a random task to a player when requested.
|
-- It can assign a random task to a player when requested.
|
||||||
|
|||||||
@ -5,6 +5,8 @@
|
|||||||
-- The @{#DETECTION_MANAGER} class defines the core functions to report detected objects to groups.
|
-- The @{#DETECTION_MANAGER} class defines the core functions to report detected objects to groups.
|
||||||
-- Reportings can be done in several manners, and it is up to the derived classes if DETECTION_MANAGER to model the reporting behaviour.
|
-- Reportings can be done in several manners, and it is up to the derived classes if DETECTION_MANAGER to model the reporting behaviour.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 1.1) DETECTION_MANAGER constructor:
|
-- 1.1) DETECTION_MANAGER constructor:
|
||||||
-- -----------------------------------
|
-- -----------------------------------
|
||||||
-- * @{#DETECTION_MANAGER.New}(): Create a new DETECTION_MANAGER instance.
|
-- * @{#DETECTION_MANAGER.New}(): Create a new DETECTION_MANAGER instance.
|
||||||
|
|||||||
@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
--- Models goals to be achieved and can contain multiple tasks to be executed to achieve the goals.
|
--- Models goals to be achieved and can contain multiple tasks to be executed to achieve the goals.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- A mission contains multiple tasks and can be of different task types.
|
-- A mission contains multiple tasks and can be of different task types.
|
||||||
-- These tasks need to be assigned to human players to be executed.
|
-- These tasks need to be assigned to human players to be executed.
|
||||||
--
|
--
|
||||||
|
|||||||
@ -12,6 +12,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- # 1) Tasking from a player perspective.
|
-- # 1) Tasking from a player perspective.
|
||||||
--
|
--
|
||||||
-- Tasking can be controlled by using the "other" menu in the radio menu of the player group.
|
-- Tasking can be controlled by using the "other" menu in the radio menu of the player group.
|
||||||
|
|||||||
@ -18,6 +18,8 @@
|
|||||||
---
|
---
|
||||||
-- # TASKINFO class, extends @{Core.Base#BASE}
|
-- # TASKINFO class, extends @{Core.Base#BASE}
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- ## The TASKINFO class implements the methods to contain information and display information of a task.
|
-- ## The TASKINFO class implements the methods to contain information and display information of a task.
|
||||||
--
|
--
|
||||||
-- # Developer Note
|
-- # Developer Note
|
||||||
|
|||||||
@ -20,6 +20,9 @@ do -- TASK_A2A
|
|||||||
|
|
||||||
--- Defines Air To Air tasks for a @{Core.Set} of Target Units,
|
--- Defines Air To Air tasks for a @{Core.Set} of Target Units,
|
||||||
-- based on the tasking capabilities defined in @{Tasking.Task#TASK}.
|
-- based on the tasking capabilities defined in @{Tasking.Task#TASK}.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The TASK_A2A is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
|
-- The TASK_A2A is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
|
||||||
--
|
--
|
||||||
-- * **None**: Start of the process
|
-- * **None**: Start of the process
|
||||||
|
|||||||
@ -30,6 +30,8 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
|
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
|
||||||
|
|
||||||
--- Orchestrates the dynamic dispatching of tasks upon groups of detected units determined a @{Core.Set} of EWR installation groups.
|
--- Orchestrates the dynamic dispatching of tasks upon groups of detected units determined a @{Core.Set} of EWR installation groups.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
|
|||||||
@ -20,6 +20,9 @@ do -- TASK_A2G
|
|||||||
|
|
||||||
--- The TASK_A2G class defines Air To Ground tasks for a @{Core.Set} of Target Units,
|
--- The TASK_A2G class defines Air To Ground tasks for a @{Core.Set} of Target Units,
|
||||||
-- based on the tasking capabilities defined in @{Tasking.Task#TASK}.
|
-- based on the tasking capabilities defined in @{Tasking.Task#TASK}.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The TASK_A2G is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
|
-- The TASK_A2G is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
|
||||||
--
|
--
|
||||||
-- * **None**: Start of the process
|
-- * **None**: Start of the process
|
||||||
|
|||||||
@ -33,6 +33,8 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
|
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
|
||||||
|
|
||||||
--- Orchestrates dynamic **A2G Task Dispatching** based on the detection results of a linked @{Functional.Detection} object.
|
--- Orchestrates dynamic **A2G Task Dispatching** based on the detection results of a linked @{Functional.Detection} object.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- It uses the Tasking System within the MOOSE framework, which is a multi-player Tasking Orchestration system.
|
-- It uses the Tasking System within the MOOSE framework, which is a multi-player Tasking Orchestration system.
|
||||||
-- It provides a truly dynamic battle environment for pilots and ground commanders to engage upon,
|
-- It provides a truly dynamic battle environment for pilots and ground commanders to engage upon,
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- ## Test Missions:
|
-- ## Test Missions:
|
||||||
--
|
--
|
||||||
-- Test missions can be located on the main GITHUB site.
|
-- Test missions can be located on the main GITHUB site.
|
||||||
@ -1176,7 +1178,7 @@ do -- TASK_CARGO
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
---@param Color Might be SMOKECOLOR.Blue, SMOKECOLOR.Red SMOKECOLOR.Orange, SMOKECOLOR.White or SMOKECOLOR.Green
|
--@param Color Might be SMOKECOLOR.Blue, SMOKECOLOR.Red SMOKECOLOR.Orange, SMOKECOLOR.White or SMOKECOLOR.Green
|
||||||
function TASK_CARGO:SetSmokeColor(SmokeColor)
|
function TASK_CARGO:SetSmokeColor(SmokeColor)
|
||||||
-- Makes sure Coloe is set
|
-- Makes sure Coloe is set
|
||||||
if SmokeColor == nil then
|
if SmokeColor == nil then
|
||||||
|
|||||||
@ -76,6 +76,8 @@ do -- TASK_CAPTURE_DISPATCHER
|
|||||||
|
|
||||||
--- Implements the dynamic dispatching of capture zone tasks.
|
--- Implements the dynamic dispatching of capture zone tasks.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The **TASK_CAPTURE_DISPATCHER** allows you to setup various tasks for let human
|
-- The **TASK_CAPTURE_DISPATCHER** allows you to setup various tasks for let human
|
||||||
-- players capture zones in a co-operation effort.
|
-- players capture zones in a co-operation effort.
|
||||||
--
|
--
|
||||||
|
|||||||
@ -20,6 +20,8 @@ do -- TASK_ZONE_GOAL
|
|||||||
|
|
||||||
--- # TASK_ZONE_GOAL class, extends @{Tasking.Task#TASK}
|
--- # TASK_ZONE_GOAL class, extends @{Tasking.Task#TASK}
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- The TASK_ZONE_GOAL class defines the task to protect or capture a protection zone.
|
-- The TASK_ZONE_GOAL class defines the task to protect or capture a protection zone.
|
||||||
-- The TASK_ZONE_GOAL is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
|
-- The TASK_ZONE_GOAL is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
|
||||||
--
|
--
|
||||||
|
|||||||
@ -44,6 +44,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- Please read through the @{Tasking.Task_CARGO} process to understand the mechanisms of tasking and cargo tasking and handling.
|
-- Please read through the @{Tasking.Task_CARGO} process to understand the mechanisms of tasking and cargo tasking and handling.
|
||||||
--
|
--
|
||||||
-- The cargo will be a downed pilot, which is located somwhere on the battlefield. Use the menus system and facilities to
|
-- The cargo will be a downed pilot, which is located somwhere on the battlefield. Use the menus system and facilities to
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
--
|
--
|
||||||
-- The **TASK_CARGO_DISPATCHER** allows you to setup various tasks for let human
|
-- The **TASK_CARGO_DISPATCHER** allows you to setup various tasks for let human
|
||||||
-- players transport cargo as part of a task.
|
-- players transport cargo as part of a task.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
-- The cargo dispatcher will implement for you mechanisms to create cargo transportation tasks:
|
-- The cargo dispatcher will implement for you mechanisms to create cargo transportation tasks:
|
||||||
--
|
--
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
--- **Tasking** - Models tasks for players to transport cargo.
|
--- **Tasking** - Models tasks for players to transport cargo.
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- **Specific features:**
|
-- **Specific features:**
|
||||||
--
|
--
|
||||||
-- * Creates a task to transport #Cargo.Cargo to and between deployment zones.
|
-- * Creates a task to transport #Cargo.Cargo to and between deployment zones.
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
-- 1) @{Tasking.Task_Manager#TASK_MANAGER} class, extends @{Core.Fsm#FSM}
|
-- 1) @{Tasking.Task_Manager#TASK_MANAGER} class, extends @{Core.Fsm#FSM}
|
||||||
-- ===
|
-- ===
|
||||||
-- The @{Tasking.Task_Manager#TASK_MANAGER} class defines the core functions to report tasks to groups.
|
-- The @{Tasking.Task_Manager#TASK_MANAGER} class defines the core functions to report tasks to groups.
|
||||||
|
|||||||
@ -12,27 +12,35 @@
|
|||||||
-- @module Utilities.Utils
|
-- @module Utilities.Utils
|
||||||
-- @image MOOSE.JPG
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
---
|
--- Smoke color enum `trigger.smokeColor`.
|
||||||
-- @type SMOKECOLOR
|
-- @type SMOKECOLOR
|
||||||
-- @field Green
|
-- @field #number Green Green smoke (0)
|
||||||
-- @field Red
|
-- @field #number Red Red smoke (1)
|
||||||
-- @field White
|
-- @field #number White White smoke (2)
|
||||||
-- @field Orange
|
-- @field #number Orange Orange smoke (3)
|
||||||
-- @field Blue
|
-- @field #number Blue Blue smoke (4)
|
||||||
|
|
||||||
SMOKECOLOR = trigger.smokeColor -- #SMOKECOLOR
|
SMOKECOLOR = trigger.smokeColor -- #SMOKECOLOR
|
||||||
|
|
||||||
---
|
--- Flare colur enum `trigger.flareColor`.
|
||||||
-- @type FLARECOLOR
|
-- @type FLARECOLOR
|
||||||
-- @field Green
|
-- @field #number Green (0)
|
||||||
-- @field Red
|
-- @field #number Red Red flare (1)
|
||||||
-- @field White
|
-- @field #number White White flare (2)
|
||||||
-- @field Yellow
|
-- @field #number Yellow Yellow flare (3)
|
||||||
|
|
||||||
FLARECOLOR = trigger.flareColor -- #FLARECOLOR
|
FLARECOLOR = trigger.flareColor -- #FLARECOLOR
|
||||||
|
|
||||||
--- Big smoke preset enum.
|
--- Big smoke preset enum.
|
||||||
-- @type BIGSMOKEPRESET
|
-- @type BIGSMOKEPRESET
|
||||||
|
-- @field #number SmallSmokeAndFire Small moke and fire (1)
|
||||||
|
-- @field #number MediumSmokeAndFire Medium smoke and fire (2)
|
||||||
|
-- @field #number LargeSmokeAndFire Large smoke and fire (3)
|
||||||
|
-- @field #number HugeSmokeAndFire Huge smoke and fire (4)
|
||||||
|
-- @field #number SmallSmoke Small smoke (5)
|
||||||
|
-- @field #number MediumSmoke Medium smoke (6)
|
||||||
|
-- @field #number LargeSmoke Large smoke (7)
|
||||||
|
-- @field #number HugeSmoke Huge smoke (8)
|
||||||
BIGSMOKEPRESET = {
|
BIGSMOKEPRESET = {
|
||||||
SmallSmokeAndFire=1,
|
SmallSmokeAndFire=1,
|
||||||
MediumSmokeAndFire=2,
|
MediumSmokeAndFire=2,
|
||||||
@ -351,7 +359,7 @@ end
|
|||||||
-- @return #string Table as a string.
|
-- @return #string Table as a string.
|
||||||
UTILS.OneLineSerialize = function( tbl ) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function
|
UTILS.OneLineSerialize = function( tbl ) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function
|
||||||
|
|
||||||
lookup_table = {}
|
local lookup_table = {}
|
||||||
|
|
||||||
local function _Serialize( tbl )
|
local function _Serialize( tbl )
|
||||||
|
|
||||||
@ -490,7 +498,7 @@ end
|
|||||||
|
|
||||||
--- Counts the number of elements in a table.
|
--- Counts the number of elements in a table.
|
||||||
-- @param #table T Table to count
|
-- @param #table T Table to count
|
||||||
-- @return #int Number of elements in the table
|
-- @return #number Number of elements in the table
|
||||||
function UTILS.TableLength(T)
|
function UTILS.TableLength(T)
|
||||||
local count = 0
|
local count = 0
|
||||||
for _ in pairs(T or {}) do count = count + 1 end
|
for _ in pairs(T or {}) do count = count + 1 end
|
||||||
@ -1905,6 +1913,13 @@ end
|
|||||||
function UTILS.GetReportingName(Typename)
|
function UTILS.GetReportingName(Typename)
|
||||||
|
|
||||||
local typename = string.lower(Typename)
|
local typename = string.lower(Typename)
|
||||||
|
|
||||||
|
-- special cases - Shark and Manstay have "A-50" in the name
|
||||||
|
if string.find(typename,"ka-50",1,true) then
|
||||||
|
return "Shark"
|
||||||
|
elseif string.find(typename,"a-50",1,true) then
|
||||||
|
return "Mainstay"
|
||||||
|
end
|
||||||
|
|
||||||
for name, value in pairs(ENUMS.ReportingName.NATO) do
|
for name, value in pairs(ENUMS.ReportingName.NATO) do
|
||||||
local svalue = string.lower(value)
|
local svalue = string.lower(value)
|
||||||
@ -2137,9 +2152,9 @@ function UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, Rising, Tlocal)
|
|||||||
local cosH = (cos(zenith) - (sinDec * sin(latitude))) / (cosDec * cos(latitude))
|
local cosH = (cos(zenith) - (sinDec * sin(latitude))) / (cosDec * cos(latitude))
|
||||||
|
|
||||||
if rising and cosH > 1 then
|
if rising and cosH > 1 then
|
||||||
return "N/S" -- The sun never rises on this location on the specified date
|
return "N/R" -- The sun never rises on this location on the specified date
|
||||||
elseif cosH < -1 then
|
elseif cosH < -1 then
|
||||||
return "N/R" -- The sun never sets on this location on the specified date
|
return "N/S" -- The sun never sets on this location on the specified date
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Finish calculating H and convert into hours
|
-- Finish calculating H and convert into hours
|
||||||
|
|||||||
@ -513,6 +513,7 @@ AIRBASE.TheChannel = {
|
|||||||
-- * AIRBASE.Syria.Hatzor
|
-- * AIRBASE.Syria.Hatzor
|
||||||
-- * AIRBASE.Syria.Palmashim
|
-- * AIRBASE.Syria.Palmashim
|
||||||
-- * AIRBASE.Syria.Tel_Nof
|
-- * AIRBASE.Syria.Tel_Nof
|
||||||
|
-- * AIRBASE.Syria.Marka
|
||||||
--
|
--
|
||||||
--@field Syria
|
--@field Syria
|
||||||
AIRBASE.Syria={
|
AIRBASE.Syria={
|
||||||
@ -586,6 +587,7 @@ AIRBASE.Syria={
|
|||||||
["Hatzor"] = "Hatzor",
|
["Hatzor"] = "Hatzor",
|
||||||
["Palmashim"] = "Palmashim",
|
["Palmashim"] = "Palmashim",
|
||||||
["Tel_Nof"] = "Tel Nof",
|
["Tel_Nof"] = "Tel Nof",
|
||||||
|
["Marka"] = "Marka",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Airbases of the Mariana Islands map:
|
--- Airbases of the Mariana Islands map:
|
||||||
@ -790,9 +792,14 @@ AIRBASE.Sinai = {
|
|||||||
-- * AIRBASE.Kola.Vidsel
|
-- * AIRBASE.Kola.Vidsel
|
||||||
-- * AIRBASE.Kola.Vuojarvi
|
-- * AIRBASE.Kola.Vuojarvi
|
||||||
-- * AIRBASE.Kola.Andoya
|
-- * AIRBASE.Kola.Andoya
|
||||||
-- * AIRBASE.Kola.Alakourtti
|
-- * AIRBASE.Kola.Alakurtti
|
||||||
-- * AIRBASE.Kola.Kittila
|
-- * AIRBASE.Kola.Kittila
|
||||||
-- * AIRBASE.Kola.Bardufoss
|
-- * AIRBASE.Kola.Bardufoss
|
||||||
|
-- * AIRBASE.Kola.Alta
|
||||||
|
-- * AIRBASE.Kola.Sodankyla
|
||||||
|
-- * AIRBASE.Kola.Enontekio
|
||||||
|
-- * AIRBASE.Kola.Evenes
|
||||||
|
-- * AIRBASE.Kola.Hosio
|
||||||
--
|
--
|
||||||
-- @field Kola
|
-- @field Kola
|
||||||
AIRBASE.Kola = {
|
AIRBASE.Kola = {
|
||||||
@ -815,9 +822,14 @@ AIRBASE.Kola = {
|
|||||||
["Vidsel"] = "Vidsel",
|
["Vidsel"] = "Vidsel",
|
||||||
["Vuojarvi"] = "Vuojarvi",
|
["Vuojarvi"] = "Vuojarvi",
|
||||||
["Andoya"] = "Andoya",
|
["Andoya"] = "Andoya",
|
||||||
["Alakourtti"] = "Alakourtti",
|
["Alakurtti"] = "Alakurtti",
|
||||||
["Kittila"] = "Kittila",
|
["Kittila"] = "Kittila",
|
||||||
["Bardufoss"] = "Bardufoss",
|
["Bardufoss"] = "Bardufoss",
|
||||||
|
["Alta"] = "Alta",
|
||||||
|
["Sodankyla"] = "Sodankyla",
|
||||||
|
["Enontekio"] = "Enontekio",
|
||||||
|
["Evenes"] = "Evenes",
|
||||||
|
["Hosio"] = "Hosio",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Airbases of the Afghanistan map
|
--- Airbases of the Afghanistan map
|
||||||
|
|||||||
@ -912,15 +912,18 @@ function GROUP:GetVelocityVec3()
|
|||||||
|
|
||||||
if DCSGroup and DCSGroup:isExist() then
|
if DCSGroup and DCSGroup:isExist() then
|
||||||
local GroupUnits = DCSGroup:getUnits()
|
local GroupUnits = DCSGroup:getUnits()
|
||||||
local GroupCount = #GroupUnits
|
local GroupCount = 0
|
||||||
|
|
||||||
local VelocityVec3 = { x = 0, y = 0, z = 0 }
|
local VelocityVec3 = { x = 0, y = 0, z = 0 }
|
||||||
|
|
||||||
for _, DCSUnit in pairs( GroupUnits ) do
|
for _, DCSUnit in pairs( GroupUnits ) do
|
||||||
local UnitVelocityVec3 = DCSUnit:getVelocity()
|
if DCSUnit:isExist() and DCSUnit:isActive() then
|
||||||
VelocityVec3.x = VelocityVec3.x + UnitVelocityVec3.x
|
local UnitVelocityVec3 = DCSUnit:getVelocity()
|
||||||
VelocityVec3.y = VelocityVec3.y + UnitVelocityVec3.y
|
VelocityVec3.x = VelocityVec3.x + UnitVelocityVec3.x
|
||||||
VelocityVec3.z = VelocityVec3.z + UnitVelocityVec3.z
|
VelocityVec3.y = VelocityVec3.y + UnitVelocityVec3.y
|
||||||
|
VelocityVec3.z = VelocityVec3.z + UnitVelocityVec3.z
|
||||||
|
GroupCount = GroupCount + 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
VelocityVec3.x = VelocityVec3.x / GroupCount
|
VelocityVec3.x = VelocityVec3.x / GroupCount
|
||||||
@ -1754,11 +1757,13 @@ function GROUP:GetMaxVelocity()
|
|||||||
|
|
||||||
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
|
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
|
||||||
|
|
||||||
local UnitVelocityVec3 = UnitData:getVelocity()
|
if UnitData:isExist() and UnitData:isActive() then
|
||||||
local UnitVelocity = math.abs( UnitVelocityVec3.x ) + math.abs( UnitVelocityVec3.y ) + math.abs( UnitVelocityVec3.z )
|
local UnitVelocityVec3 = UnitData:getVelocity()
|
||||||
|
local UnitVelocity = math.abs( UnitVelocityVec3.x ) + math.abs( UnitVelocityVec3.y ) + math.abs( UnitVelocityVec3.z )
|
||||||
|
|
||||||
if UnitVelocity > GroupVelocityMax then
|
if UnitVelocity > GroupVelocityMax then
|
||||||
GroupVelocityMax = UnitVelocity
|
GroupVelocityMax = UnitVelocity
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -897,7 +897,7 @@ function UNIT:GetAmmunition()
|
|||||||
nAPshells = nAPshells + Nammo
|
nAPshells = nAPshells + Nammo
|
||||||
end
|
end
|
||||||
|
|
||||||
if ammotable[w].desc.typeName and string.find(ammotable[w].desc.typeName, "_HE", 1, true) then
|
if ammotable[w].desc.typeName and (string.find(ammotable[w].desc.typeName, "_HE", 1, true) or string.find(ammotable[w].desc.typeName, "HESH", 1, true)) then
|
||||||
nHEshells = nHEshells + Nammo
|
nHEshells = nHEshells + Nammo
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1107,7 +1107,6 @@ function UNIT:GetUnits()
|
|||||||
|
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
Units[1] = UNIT:Find(DCSUnit)
|
Units[1] = UNIT:Find(DCSUnit)
|
||||||
- self:T3(Units)
|
|
||||||
return Units
|
return Units
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user