mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-08-17 20:56:08 +00:00
Compare commits
114 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d6d9c9d8cf | |||
| 7f572a1a9b | |||
| 68007306b3 | |||
| 0c3f97370c | |||
| d62025dfe0 | |||
| 6bc766e95f | |||
| 07009630c6 | |||
| c2aeb1ebcd | |||
| 865042a843 | |||
| 6243137d4c | |||
| f00d0dc871 | |||
| 8695953d5a | |||
| 6afb68390b | |||
| d6adcdf8bd | |||
| 8151700ad7 | |||
| 2c192fba30 | |||
| 97f11c93bb | |||
| a3102a7381 | |||
| d41b5e8ede | |||
| a45856c925 | |||
| f531fdaa70 | |||
| f4b2f07656 | |||
| 81f8e84ca4 | |||
| f7e64d98bc | |||
| d74de11b8b | |||
| 4380c1be2e | |||
| 30f2097d7a | |||
| db2d4e97a6 | |||
| f903844059 | |||
| b4653be54e | |||
| 68b2b452cc | |||
| e2b6efde7a | |||
| 668d120d60 | |||
| 3eea17bc76 | |||
| 2894bcc833 | |||
| 7543f31c85 | |||
| ff52197707 | |||
| 56d84e7b25 | |||
| b025abaa88 | |||
| ed2d3d856b | |||
| dac637f360 | |||
| 1e5c3a3c21 | |||
| 861588205a | |||
| 37d5b6a0fc | |||
| 4d3fb2990e | |||
| c58a954d18 | |||
| cce878e759 | |||
| 0d481afa16 | |||
| 2dbad7cb1b | |||
| 016875d724 | |||
| 7a0fa629b5 | |||
| 5df0d60135 | |||
| aee7bd8bb6 | |||
| e77d61c4cb | |||
| b1a40407b3 | |||
| 504142c585 | |||
| 0496571c92 | |||
| 62a0adce5a | |||
| d1a1be1a9e | |||
| 80011f4e4e | |||
| 80df849d18 | |||
| c2933b6bed | |||
| fc4ba9f21d | |||
| e74c79b5d6 | |||
| f738ddfca8 | |||
| 5bbd122fa4 | |||
| af45b0d709 | |||
| 928c20c867 | |||
| 4bd36a4786 | |||
| e746617139 | |||
| 3105f7407d | |||
| 2f568bca17 | |||
| ad7dba6fac | |||
| 9efe0fe243 | |||
| 2836d7a40f | |||
| f1bf62e3c1 | |||
| a560d65ce7 | |||
| 9de3cb73f7 | |||
| 757cc86a68 | |||
| aeb1664134 | |||
| 2af1483724 | |||
| b7702ab933 | |||
| cc14f82e85 | |||
| f23dd0a5dd | |||
| 5aea17e20e | |||
| 8336b744bb | |||
| ad9eaea010 | |||
| 9c47e35d54 | |||
| 284a770daa | |||
| 16030d4fa1 | |||
| 37d2dd17d7 | |||
| ccd190a8b1 | |||
| 36bf2436b6 | |||
| 19f6a8d8f6 | |||
| b8e09afcce | |||
| 24264bd885 | |||
| ed690ee6e9 | |||
| 872bb3d775 | |||
| c0dcd12ada | |||
| d36cd8e284 | |||
| 5d98672de5 | |||
| eab643268f | |||
| e2fa1f992b | |||
| 9356794112 | |||
| bb865aef38 | |||
| 35c24810f9 | |||
| 875b5fb34d | |||
| 19187bcb14 | |||
| ebe6e9fb9f | |||
| a54944b021 | |||
| 5f7f75b1c9 | |||
| bc9938d08a | |||
| 59963e152d | |||
| b77f179acc |
@@ -3895,10 +3895,14 @@ do -- AI_A2G_DISPATCHER
|
|||||||
|
|
||||||
if Squadron then
|
if Squadron then
|
||||||
local FirstUnit = AttackSetUnit:GetRandomSurely()
|
local FirstUnit = AttackSetUnit:GetRandomSurely()
|
||||||
|
if FirstUnit then
|
||||||
local Coordinate = FirstUnit:GetCoordinate() -- Core.Point#COORDINATE
|
local Coordinate = FirstUnit:GetCoordinate() -- Core.Point#COORDINATE
|
||||||
if self.SetSendPlayerMessages then
|
if self.SetSendPlayerMessages then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", on route to ground target at " .. Coordinate:ToStringA2G( DefenderGroup ), DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", on route to ground target at " .. Coordinate:ToStringA2G( DefenderGroup ), DefenderGroup )
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
self:GetParent(self).onafterEngageRoute( self, DefenderGroup, From, Event, To, AttackSetUnit )
|
self:GetParent(self).onafterEngageRoute( self, DefenderGroup, From, Event, To, AttackSetUnit )
|
||||||
end
|
end
|
||||||
@@ -4785,3 +4789,4 @@ end
|
|||||||
end
|
end
|
||||||
self:T({Squadron = Squadron.Name,SquadronResourceCount = Squadron.ResourceCount})
|
self:T({Squadron = Squadron.Name,SquadronResourceCount = Squadron.ResourceCount})
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
-- @module AI.AI_Air
|
-- @module AI.AI_Air
|
||||||
-- @image MOOSE.JPG
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
|
---
|
||||||
-- @type AI_AIR
|
-- @type AI_AIR
|
||||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
-- @module Core.Base
|
-- @module Core.Base
|
||||||
-- @image Core_Base.JPG
|
-- @image Core_Base.JPG
|
||||||
|
|
||||||
local _TraceOnOff = true
|
local _TraceOnOff = false -- default to no tracing
|
||||||
local _TraceLevel = 1
|
local _TraceLevel = 1
|
||||||
local _TraceAll = false
|
local _TraceAll = false
|
||||||
local _TraceClass = {}
|
local _TraceClass = {}
|
||||||
@@ -742,6 +742,30 @@ do -- Event Handling
|
|||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
|
--- Occurs when a player creates a dynamic cargo object from the F8 ground crew menu.
|
||||||
|
-- *** NOTE *** this is a workarounf for DCS not creating these events as of Aug 2024.
|
||||||
|
-- @function [parent=#BASE] OnEventNewDynamicCargo
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
|
--- Occurs when a player loads a dynamic cargo object with the F8 ground crew menu into a helo.
|
||||||
|
-- *** NOTE *** this is a workarounf for DCS not creating these events as of Aug 2024.
|
||||||
|
-- @function [parent=#BASE] OnEventDynamicCargoLoaded
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
|
--- Occurs when a player unloads a dynamic cargo object with the F8 ground crew menu from a helo.
|
||||||
|
-- *** NOTE *** this is a workarounf for DCS not creating these events as of Aug 2024.
|
||||||
|
-- @function [parent=#BASE] OnEventDynamicCargoUnloaded
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
|
--- Occurs when a dynamic cargo crate is removed.
|
||||||
|
-- *** NOTE *** this is a workarounf for DCS not creating these events as of Aug 2024.
|
||||||
|
-- @function [parent=#BASE] OnEventDynamicCargoRemoved
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Creation of a Birth Event.
|
--- Creation of a Birth Event.
|
||||||
@@ -863,6 +887,62 @@ end
|
|||||||
world.onEvent(Event)
|
world.onEvent(Event)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Creation of a S_EVENT_NEW_DYNAMIC_CARGO event.
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||||
|
function BASE:CreateEventNewDynamicCargo(DynamicCargo)
|
||||||
|
self:F({DynamicCargo})
|
||||||
|
local Event = {
|
||||||
|
id = EVENTS.NewDynamicCargo,
|
||||||
|
time = timer.getTime(),
|
||||||
|
dynamiccargo = DynamicCargo,
|
||||||
|
initiator = DynamicCargo:GetDCSObject(),
|
||||||
|
}
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creation of a S_EVENT_DYNAMIC_CARGO_LOADED event.
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||||
|
function BASE:CreateEventDynamicCargoLoaded(DynamicCargo)
|
||||||
|
self:F({DynamicCargo})
|
||||||
|
local Event = {
|
||||||
|
id = EVENTS.DynamicCargoLoaded,
|
||||||
|
time = timer.getTime(),
|
||||||
|
dynamiccargo = DynamicCargo,
|
||||||
|
initiator = DynamicCargo:GetDCSObject(),
|
||||||
|
}
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creation of a S_EVENT_DYNAMIC_CARGO_UNLOADED event.
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||||
|
function BASE:CreateEventDynamicCargoUnloaded(DynamicCargo)
|
||||||
|
self:F({DynamicCargo})
|
||||||
|
local Event = {
|
||||||
|
id = EVENTS.DynamicCargoUnloaded,
|
||||||
|
time = timer.getTime(),
|
||||||
|
dynamiccargo = DynamicCargo,
|
||||||
|
initiator = DynamicCargo:GetDCSObject(),
|
||||||
|
}
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creation of a S_EVENT_DYNAMIC_CARGO_REMOVED event.
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||||
|
function BASE:CreateEventDynamicCargoRemoved(DynamicCargo)
|
||||||
|
self:F({DynamicCargo})
|
||||||
|
local Event = {
|
||||||
|
id = EVENTS.DynamicCargoRemoved,
|
||||||
|
time = timer.getTime(),
|
||||||
|
dynamiccargo = DynamicCargo,
|
||||||
|
initiator = DynamicCargo:GetDCSObject(),
|
||||||
|
}
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
--- The main event handling function... This function captures all events generated for the class.
|
--- The main event handling function... This function captures all events generated for the class.
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param DCS#Event event
|
-- @param DCS#Event event
|
||||||
@@ -1200,7 +1280,7 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:F( Arguments )
|
function BASE:F( Arguments )
|
||||||
|
|
||||||
if BASE.Debug and _TraceOnOff then
|
if BASE.Debug and _TraceOnOff == true then
|
||||||
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
@@ -1215,7 +1295,7 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:F2( Arguments )
|
function BASE:F2( Arguments )
|
||||||
|
|
||||||
if BASE.Debug and _TraceOnOff then
|
if BASE.Debug and _TraceOnOff == true and _TraceLevel >= 2 then
|
||||||
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
@@ -1230,7 +1310,7 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:F3( Arguments )
|
function BASE:F3( Arguments )
|
||||||
|
|
||||||
if BASE.Debug and _TraceOnOff then
|
if BASE.Debug and _TraceOnOff == true and _TraceLevel >= 3 then
|
||||||
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
@@ -1274,7 +1354,7 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:T( Arguments )
|
function BASE:T( Arguments )
|
||||||
|
|
||||||
if BASE.Debug and _TraceOnOff then
|
if BASE.Debug and _TraceOnOff == true then
|
||||||
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
@@ -1289,7 +1369,7 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:T2( Arguments )
|
function BASE:T2( Arguments )
|
||||||
|
|
||||||
if BASE.Debug and _TraceOnOff then
|
if BASE.Debug and _TraceOnOff == true and _TraceLevel >= 2 then
|
||||||
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
@@ -1304,7 +1384,7 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:T3( Arguments )
|
function BASE:T3( Arguments )
|
||||||
|
|
||||||
if BASE.Debug and _TraceOnOff then
|
if BASE.Debug and _TraceOnOff == true and _TraceLevel >= 3 then
|
||||||
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
-- * Manage database of hits to units and statics.
|
-- * Manage database of hits to units and statics.
|
||||||
-- * Manage database of destroys of units and statics.
|
-- * Manage database of destroys of units and statics.
|
||||||
-- * Manage database of @{Core.Zone#ZONE_BASE} objects.
|
-- * Manage database of @{Core.Zone#ZONE_BASE} objects.
|
||||||
|
-- * Manage database of @{Wrapper.DynamicCargo#DYNAMICCARGO} objects alive in the mission.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@@ -39,6 +40,7 @@
|
|||||||
-- @field #table STORAGES DCS warehouse storages.
|
-- @field #table STORAGES DCS warehouse storages.
|
||||||
-- @field #table STNS Used Link16 octal numbers for F16/15/18/AWACS planes.
|
-- @field #table STNS Used Link16 octal numbers for F16/15/18/AWACS planes.
|
||||||
-- @field #table SADL Used Link16 octal numbers for A10/C-II planes.
|
-- @field #table SADL Used Link16 octal numbers for A10/C-II planes.
|
||||||
|
-- @field #table DYNAMICCARGO Dynamic Cargo objects.
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
--- Contains collections of wrapper objects defined within MOOSE that reflect objects within the simulator.
|
--- Contains collections of wrapper objects defined within MOOSE that reflect objects within the simulator.
|
||||||
@@ -54,6 +56,7 @@
|
|||||||
-- * PLAYERS
|
-- * PLAYERS
|
||||||
-- * CARGOS
|
-- * CARGOS
|
||||||
-- * STORAGES (DCS warehouses)
|
-- * STORAGES (DCS warehouses)
|
||||||
|
-- * DYNAMICCARGO
|
||||||
--
|
--
|
||||||
-- On top, for internal MOOSE administration purposes, the DATABASE administers the Unit and Group TEMPLATES as defined within the Mission Editor.
|
-- On top, for internal MOOSE administration purposes, the DATABASE administers the Unit and Group TEMPLATES as defined within the Mission Editor.
|
||||||
--
|
--
|
||||||
@@ -97,6 +100,7 @@ DATABASE = {
|
|||||||
STORAGES = {},
|
STORAGES = {},
|
||||||
STNS={},
|
STNS={},
|
||||||
SADL={},
|
SADL={},
|
||||||
|
DYNAMICCARGO={},
|
||||||
}
|
}
|
||||||
|
|
||||||
local _DATABASECoalition =
|
local _DATABASECoalition =
|
||||||
@@ -143,6 +147,8 @@ function DATABASE:New()
|
|||||||
self:HandleEvent( EVENTS.DeleteZone )
|
self:HandleEvent( EVENTS.DeleteZone )
|
||||||
--self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) -- This is not working anymore!, handling this through the birth event.
|
--self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) -- This is not working anymore!, handling this through the birth event.
|
||||||
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit )
|
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit )
|
||||||
|
-- DCS 2.9.7 Moose own dynamic cargo events
|
||||||
|
self:HandleEvent( EVENTS.DynamicCargoRemoved, self._EventOnDynamicCargoRemoved)
|
||||||
|
|
||||||
self:_RegisterTemplates()
|
self:_RegisterTemplates()
|
||||||
self:_RegisterGroupsAndUnits()
|
self:_RegisterGroupsAndUnits()
|
||||||
@@ -174,15 +180,19 @@ end
|
|||||||
-- @return Wrapper.Unit#UNIT The added unit.
|
-- @return Wrapper.Unit#UNIT The added unit.
|
||||||
function DATABASE:AddUnit( DCSUnitName, force )
|
function DATABASE:AddUnit( DCSUnitName, force )
|
||||||
|
|
||||||
if not self.UNITS[DCSUnitName] or force == true then
|
local DCSunitName = DCSUnitName
|
||||||
|
|
||||||
|
if type(DCSunitName) == "number" then DCSunitName = string.format("%d",DCSUnitName) end
|
||||||
|
|
||||||
|
if not self.UNITS[DCSunitName] or force == true then
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T( { "Add UNIT:", DCSUnitName } )
|
self:T( { "Add UNIT:", DCSunitName } )
|
||||||
|
|
||||||
-- Register unit
|
-- Register unit
|
||||||
self.UNITS[DCSUnitName]=UNIT:Register(DCSUnitName)
|
self.UNITS[DCSunitName]=UNIT:Register(DCSunitName)
|
||||||
end
|
end
|
||||||
|
|
||||||
return self.UNITS[DCSUnitName]
|
return self.UNITS[DCSunitName]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -224,6 +234,34 @@ function DATABASE:FindStatic( StaticName )
|
|||||||
return StaticFound
|
return StaticFound
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add a DynamicCargo to the database.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param #string Name Name of the dynamic cargo.
|
||||||
|
-- @return Wrapper.DynamicCargo#DYNAMICCARGO The dynamic cargo object.
|
||||||
|
function DATABASE:AddDynamicCargo( Name )
|
||||||
|
if not self.DYNAMICCARGO[Name] then
|
||||||
|
self.DYNAMICCARGO[Name] = DYNAMICCARGO:Register(Name)
|
||||||
|
return self.DYNAMICCARGO[Name]
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Finds a DYNAMICCARGO based on the Dynamic Cargo Name.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param #string DynamicCargoName
|
||||||
|
-- @return Wrapper.DynamicCargo#DYNAMICCARGO The found DYNAMICCARGO.
|
||||||
|
function DATABASE:FindDynamicCargo( DynamicCargoName )
|
||||||
|
local StaticFound = self.DYNAMICCARGO[DynamicCargoName]
|
||||||
|
return StaticFound
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Deletes a DYNAMICCARGO from the DATABASE based on the Dynamic Cargo Name.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
function DATABASE:DeleteDynamicCargo( DynamicCargoName )
|
||||||
|
self.DYNAMICCARGO[DynamicCargoName] = nil
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Adds a Airbase based on the Airbase Name in the DATABASE.
|
--- Adds a Airbase based on the Airbase Name in the DATABASE.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string AirbaseName The name of the airbase.
|
-- @param #string AirbaseName The name of the airbase.
|
||||||
@@ -819,11 +857,15 @@ end
|
|||||||
-- @return Wrapper.Client#CLIENT The client object.
|
-- @return Wrapper.Client#CLIENT The client object.
|
||||||
function DATABASE:AddClient( ClientName, Force )
|
function DATABASE:AddClient( ClientName, Force )
|
||||||
|
|
||||||
if not self.CLIENTS[ClientName] or Force == true then
|
local DCSUnitName = ClientName
|
||||||
self.CLIENTS[ClientName] = CLIENT:Register( ClientName )
|
|
||||||
|
if type(DCSUnitName) == "number" then DCSUnitName = string.format("%d",ClientName) end
|
||||||
|
|
||||||
|
if not self.CLIENTS[DCSUnitName] or Force == true then
|
||||||
|
self.CLIENTS[DCSUnitName] = CLIENT:Register( DCSUnitName )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self.CLIENTS[ClientName]
|
return self.CLIENTS[DCSUnitName]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -864,8 +906,10 @@ end
|
|||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
function DATABASE:AddPlayer( UnitName, PlayerName )
|
function DATABASE:AddPlayer( UnitName, PlayerName )
|
||||||
|
|
||||||
|
if type(UnitName) == "number" then UnitName = string.format("%d",UnitName) end
|
||||||
|
|
||||||
if PlayerName then
|
if PlayerName then
|
||||||
self:T( { "Add player for unit:", UnitName, PlayerName } )
|
self:I( { "Add player for unit:", UnitName, PlayerName } )
|
||||||
self.PLAYERS[PlayerName] = UnitName
|
self.PLAYERS[PlayerName] = UnitName
|
||||||
self.PLAYERUNITS[PlayerName] = self:FindUnit( UnitName )
|
self.PLAYERUNITS[PlayerName] = self:FindUnit( UnitName )
|
||||||
self.PLAYERSJOINED[PlayerName] = PlayerName
|
self.PLAYERSJOINED[PlayerName] = PlayerName
|
||||||
@@ -873,6 +917,21 @@ function DATABASE:AddPlayer( UnitName, PlayerName )
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get a PlayerName by UnitName from PLAYERS in DATABASE.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @return #string PlayerName
|
||||||
|
-- @return Wrapper.Unit#UNIT PlayerUnit
|
||||||
|
function DATABASE:_FindPlayerNameByUnitName(UnitName)
|
||||||
|
if UnitName then
|
||||||
|
for playername,unitname in pairs(self.PLAYERS) do
|
||||||
|
if unitname == UnitName and self.PLAYERUNITS[playername] and self.PLAYERUNITS[playername]:IsAlive() then
|
||||||
|
return playername, self.PLAYERUNITS[playername]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Deletes a player from the DATABASE based on the Player Name.
|
--- Deletes a player from the DATABASE based on the Player Name.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
function DATABASE:DeletePlayer( UnitName, PlayerName )
|
function DATABASE:DeletePlayer( UnitName, PlayerName )
|
||||||
@@ -1244,7 +1303,7 @@ function DATABASE:_GetGenericStaticCargoGroupTemplate(Name,Typename,Mass,Coaliti
|
|||||||
StaticTemplate.CategoryID = "static"
|
StaticTemplate.CategoryID = "static"
|
||||||
StaticTemplate.CoalitionID = Coalition or coalition.side.BLUE
|
StaticTemplate.CoalitionID = Coalition or coalition.side.BLUE
|
||||||
StaticTemplate.CountryID = Country or country.id.GERMANY
|
StaticTemplate.CountryID = Country or country.id.GERMANY
|
||||||
UTILS.PrintTableToLog(StaticTemplate)
|
--UTILS.PrintTableToLog(StaticTemplate)
|
||||||
return StaticTemplate
|
return StaticTemplate
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1324,7 +1383,7 @@ function DATABASE:GetCoalitionFromClientTemplate( ClientName )
|
|||||||
if self.Templates.ClientsByName[ClientName] then
|
if self.Templates.ClientsByName[ClientName] then
|
||||||
return self.Templates.ClientsByName[ClientName].CoalitionID
|
return self.Templates.ClientsByName[ClientName].CoalitionID
|
||||||
end
|
end
|
||||||
self:E("ERROR: Template does not exist for client "..tostring(ClientName))
|
self:E("WARNING: Template does not exist for client "..tostring(ClientName))
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1336,7 +1395,7 @@ function DATABASE:GetCategoryFromClientTemplate( ClientName )
|
|||||||
if self.Templates.ClientsByName[ClientName] then
|
if self.Templates.ClientsByName[ClientName] then
|
||||||
return self.Templates.ClientsByName[ClientName].CategoryID
|
return self.Templates.ClientsByName[ClientName].CategoryID
|
||||||
end
|
end
|
||||||
self:E("ERROR: Template does not exist for client "..tostring(ClientName))
|
self:E("WARNING: Template does not exist for client "..tostring(ClientName))
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1348,7 +1407,7 @@ function DATABASE:GetCountryFromClientTemplate( ClientName )
|
|||||||
if self.Templates.ClientsByName[ClientName] then
|
if self.Templates.ClientsByName[ClientName] then
|
||||||
return self.Templates.ClientsByName[ClientName].CountryID
|
return self.Templates.ClientsByName[ClientName].CountryID
|
||||||
end
|
end
|
||||||
self:E("ERROR: Template does not exist for client "..tostring(ClientName))
|
self:E("WARNING: Template does not exist for client "..tostring(ClientName))
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1417,7 +1476,7 @@ function DATABASE:_RegisterDynamicGroup(Groupname)
|
|||||||
|
|
||||||
-- Add unit.
|
-- Add unit.
|
||||||
self:I(string.format("Register Unit: %s", tostring(DCSUnitName)))
|
self:I(string.format("Register Unit: %s", tostring(DCSUnitName)))
|
||||||
self:AddUnit( DCSUnitName, true )
|
self:AddUnit( tostring(DCSUnitName), true )
|
||||||
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -1568,7 +1627,7 @@ end
|
|||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param Core.Event#EVENTDATA Event
|
-- @param Core.Event#EVENTDATA Event
|
||||||
function DATABASE:_EventOnBirth( Event )
|
function DATABASE:_EventOnBirth( Event )
|
||||||
self:F( { Event } )
|
self:T( { Event } )
|
||||||
|
|
||||||
if Event.IniDCSUnit then
|
if Event.IniDCSUnit then
|
||||||
|
|
||||||
@@ -1577,6 +1636,16 @@ function DATABASE:_EventOnBirth( Event )
|
|||||||
-- Add static object to DB.
|
-- Add static object to DB.
|
||||||
self:AddStatic( Event.IniDCSUnitName )
|
self:AddStatic( Event.IniDCSUnitName )
|
||||||
|
|
||||||
|
elseif Event.IniObjectCategory == Object.Category.CARGO and string.match(Event.IniUnitName,".+|%d%d:%d%d|PKG%d+") then
|
||||||
|
|
||||||
|
-- Add dynamic cargo object to DB
|
||||||
|
|
||||||
|
local cargo = self:AddDynamicCargo(Event.IniDCSUnitName)
|
||||||
|
|
||||||
|
self:I(string.format("Adding dynamic cargo %s", tostring(Event.IniDCSUnitName)))
|
||||||
|
|
||||||
|
self:CreateEventNewDynamicCargo( cargo )
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
if Event.IniObjectCategory == Object.Category.UNIT then
|
if Event.IniObjectCategory == Object.Category.UNIT then
|
||||||
@@ -1762,6 +1831,15 @@ function DATABASE:_EventOnPlayerEnterUnit( Event )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Handles the OnDynamicCargoRemoved event to clean the active dynamic cargo table.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param Core.Event#EVENTDATA Event
|
||||||
|
function DATABASE:_EventOnDynamicCargoRemoved( Event )
|
||||||
|
self:T( { Event } )
|
||||||
|
if Event.IniDynamicCargoName then
|
||||||
|
self:DeleteDynamicCargo(Event.IniDynamicCargoName)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- Handles the OnPlayerLeaveUnit event to clean the active players table.
|
--- Handles the OnPlayerLeaveUnit event to clean the active players table.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
|
|||||||
@@ -194,6 +194,11 @@ world.event.S_EVENT_NEW_ZONE_GOAL = world.event.S_EVENT_MAX + 1004
|
|||||||
world.event.S_EVENT_DELETE_ZONE_GOAL = world.event.S_EVENT_MAX + 1005
|
world.event.S_EVENT_DELETE_ZONE_GOAL = world.event.S_EVENT_MAX + 1005
|
||||||
world.event.S_EVENT_REMOVE_UNIT = world.event.S_EVENT_MAX + 1006
|
world.event.S_EVENT_REMOVE_UNIT = world.event.S_EVENT_MAX + 1006
|
||||||
world.event.S_EVENT_PLAYER_ENTER_AIRCRAFT = world.event.S_EVENT_MAX + 1007
|
world.event.S_EVENT_PLAYER_ENTER_AIRCRAFT = world.event.S_EVENT_MAX + 1007
|
||||||
|
-- dynamic cargo
|
||||||
|
world.event.S_EVENT_NEW_DYNAMIC_CARGO = world.event.S_EVENT_MAX + 1008
|
||||||
|
world.event.S_EVENT_DYNAMIC_CARGO_LOADED = world.event.S_EVENT_MAX + 1009
|
||||||
|
world.event.S_EVENT_DYNAMIC_CARGO_UNLOADED = world.event.S_EVENT_MAX + 1010
|
||||||
|
world.event.S_EVENT_DYNAMIC_CARGO_REMOVED = world.event.S_EVENT_MAX + 1011
|
||||||
|
|
||||||
|
|
||||||
--- The different types of events supported by MOOSE.
|
--- The different types of events supported by MOOSE.
|
||||||
@@ -276,6 +281,11 @@ EVENTS = {
|
|||||||
SimulationUnfreeze = world.event.S_EVENT_SIMULATION_UNFREEZE or -1,
|
SimulationUnfreeze = world.event.S_EVENT_SIMULATION_UNFREEZE or -1,
|
||||||
HumanAircraftRepairStart = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_START or -1,
|
HumanAircraftRepairStart = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_START or -1,
|
||||||
HumanAircraftRepairFinish = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH or -1,
|
HumanAircraftRepairFinish = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH or -1,
|
||||||
|
-- dynamic cargo
|
||||||
|
NewDynamicCargo = world.event.S_EVENT_NEW_DYNAMIC_CARGO or -1,
|
||||||
|
DynamicCargoLoaded = world.event.S_EVENT_DYNAMIC_CARGO_LOADED or -1,
|
||||||
|
DynamicCargoUnloaded = world.event.S_EVENT_DYNAMIC_CARGO_UNLOADED or -1,
|
||||||
|
DynamicCargoRemoved = world.event.S_EVENT_DYNAMIC_CARGO_REMOVED or -1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -334,6 +344,9 @@ EVENTS = {
|
|||||||
--
|
--
|
||||||
-- @field Core.Zone#ZONE Zone The zone object.
|
-- @field Core.Zone#ZONE Zone The zone object.
|
||||||
-- @field #string ZoneName The name of the zone.
|
-- @field #string ZoneName The name of the zone.
|
||||||
|
--
|
||||||
|
-- @field Wrapper.DynamicCargo#DYNAMICCARGO IniDynamicCargo The dynamic cargo object.
|
||||||
|
-- @field #string IniDynamicCargoName The dynamic cargo unit name.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -731,6 +744,31 @@ local _EVENTMETA = {
|
|||||||
Event = "OnEventHumanAircraftRepairFinish",
|
Event = "OnEventHumanAircraftRepairFinish",
|
||||||
Text = "S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH"
|
Text = "S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH"
|
||||||
},
|
},
|
||||||
|
-- dynamic cargo
|
||||||
|
[EVENTS.NewDynamicCargo] = {
|
||||||
|
Order = 1,
|
||||||
|
Side = "I",
|
||||||
|
Event = "OnEventNewDynamicCargo",
|
||||||
|
Text = "S_EVENT_NEW_DYNAMIC_CARGO"
|
||||||
|
},
|
||||||
|
[EVENTS.DynamicCargoLoaded] = {
|
||||||
|
Order = 1,
|
||||||
|
Side = "I",
|
||||||
|
Event = "OnEventDynamicCargoLoaded",
|
||||||
|
Text = "S_EVENT_DYNAMIC_CARGO_LOADED"
|
||||||
|
},
|
||||||
|
[EVENTS.DynamicCargoUnloaded] = {
|
||||||
|
Order = 1,
|
||||||
|
Side = "I",
|
||||||
|
Event = "OnEventDynamicCargoUnloaded",
|
||||||
|
Text = "S_EVENT_DYNAMIC_CARGO_UNLOADED"
|
||||||
|
},
|
||||||
|
[EVENTS.DynamicCargoRemoved] = {
|
||||||
|
Order = 1,
|
||||||
|
Side = "I",
|
||||||
|
Event = "OnEventDynamicCargoRemoved",
|
||||||
|
Text = "S_EVENT_DYNAMIC_CARGO_REMOVED"
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1147,6 +1185,62 @@ do -- Event Creation
|
|||||||
world.onEvent( Event )
|
world.onEvent( Event )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Creation of a S_EVENT_NEW_DYNAMIC_CARGO event.
|
||||||
|
-- @param #EVENT self
|
||||||
|
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||||
|
function EVENT:CreateEventNewDynamicCargo(DynamicCargo)
|
||||||
|
self:F({DynamicCargo})
|
||||||
|
local Event = {
|
||||||
|
id = EVENTS.NewDynamicCargo,
|
||||||
|
time = timer.getTime(),
|
||||||
|
dynamiccargo = DynamicCargo,
|
||||||
|
initiator = DynamicCargo:GetDCSObject(),
|
||||||
|
}
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creation of a S_EVENT_DYNAMIC_CARGO_LOADED event.
|
||||||
|
-- @param #EVENT self
|
||||||
|
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||||
|
function EVENT:CreateEventDynamicCargoLoaded(DynamicCargo)
|
||||||
|
self:F({DynamicCargo})
|
||||||
|
local Event = {
|
||||||
|
id = EVENTS.DynamicCargoLoaded,
|
||||||
|
time = timer.getTime(),
|
||||||
|
dynamiccargo = DynamicCargo,
|
||||||
|
initiator = DynamicCargo:GetDCSObject(),
|
||||||
|
}
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creation of a S_EVENT_DYNAMIC_CARGO_UNLOADED event.
|
||||||
|
-- @param #EVENT self
|
||||||
|
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||||
|
function EVENT:CreateEventDynamicCargoUnloaded(DynamicCargo)
|
||||||
|
self:F({DynamicCargo})
|
||||||
|
local Event = {
|
||||||
|
id = EVENTS.DynamicCargoUnloaded,
|
||||||
|
time = timer.getTime(),
|
||||||
|
dynamiccargo = DynamicCargo,
|
||||||
|
initiator = DynamicCargo:GetDCSObject(),
|
||||||
|
}
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creation of a S_EVENT_DYNAMIC_CARGO_REMOVED event.
|
||||||
|
-- @param #EVENT self
|
||||||
|
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||||
|
function EVENT:CreateEventDynamicCargoRemoved(DynamicCargo)
|
||||||
|
self:F({DynamicCargo})
|
||||||
|
local Event = {
|
||||||
|
id = EVENTS.DynamicCargoRemoved,
|
||||||
|
time = timer.getTime(),
|
||||||
|
dynamiccargo = DynamicCargo,
|
||||||
|
initiator = DynamicCargo:GetDCSObject(),
|
||||||
|
}
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Main event function.
|
--- Main event function.
|
||||||
@@ -1261,7 +1355,13 @@ function EVENT:onEvent( Event )
|
|||||||
Event.IniDCSUnit = Event.initiator
|
Event.IniDCSUnit = Event.initiator
|
||||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||||
Event.IniUnitName = Event.IniDCSUnitName
|
Event.IniUnitName = Event.IniDCSUnitName
|
||||||
|
if string.match(Event.IniUnitName,".+|%d%d:%d%d|PKG%d+") then
|
||||||
|
Event.IniDynamicCargo = DYNAMICCARGO:FindByName(Event.IniUnitName)
|
||||||
|
Event.IniDynamicCargoName = Event.IniUnitName
|
||||||
|
Event.IniPlayerName = string.match(Event.IniUnitName,"^(.+)|%d%d:%d%d|PKG%d+")
|
||||||
|
else
|
||||||
Event.IniUnit = CARGO:FindByName( Event.IniDCSUnitName )
|
Event.IniUnit = CARGO:FindByName( Event.IniDCSUnitName )
|
||||||
|
end
|
||||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||||
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||||
@@ -1382,7 +1482,7 @@ function EVENT:onEvent( Event )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Weapon.
|
-- Weapon.
|
||||||
if Event.weapon and type(Event.weapon) == "table" then
|
if Event.weapon and type(Event.weapon) == "table" and Event.weapon.isExist and Event.weapon:isExist() then
|
||||||
Event.Weapon = Event.weapon
|
Event.Weapon = Event.weapon
|
||||||
Event.WeaponName = Event.weapon:isExist() and Event.weapon:getTypeName() or "Unknown Weapon"
|
Event.WeaponName = Event.weapon:isExist() and Event.weapon:getTypeName() or "Unknown Weapon"
|
||||||
Event.WeaponUNIT = CLIENT:Find( Event.Weapon, '', true ) -- Sometimes, the weapon is a player unit!
|
Event.WeaponUNIT = CLIENT:Find( Event.Weapon, '', true ) -- Sometimes, the weapon is a player unit!
|
||||||
@@ -1426,6 +1526,15 @@ function EVENT:onEvent( Event )
|
|||||||
Event.CargoName = Event.cargo.Name
|
Event.CargoName = Event.cargo.Name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Dynamic cargo Object
|
||||||
|
if Event.dynamiccargo then
|
||||||
|
Event.IniDynamicCargo = Event.dynamiccargo
|
||||||
|
Event.IniDynamicCargoName = Event.IniDynamicCargo.StaticName
|
||||||
|
if Event.IniDynamicCargo.Owner or Event.IniUnitName then
|
||||||
|
Event.IniPlayerName = Event.IniDynamicCargo.Owner or string.match(Event.IniUnitName or "None|00:00|PKG00","^(.+)|%d%d:%d%d|PKG%d+")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Zone object.
|
-- Zone object.
|
||||||
if Event.zone then
|
if Event.zone then
|
||||||
Event.Zone = Event.zone
|
Event.Zone = Event.zone
|
||||||
|
|||||||
@@ -2669,9 +2669,9 @@ do -- COORDINATE
|
|||||||
local date=UTILS.GetDCSMissionDate()
|
local date=UTILS.GetDCSMissionDate()
|
||||||
|
|
||||||
-- Debug output.
|
-- Debug output.
|
||||||
--self:I(string.format("Sun rise at lat=%.3f long=%.3f on %s (DayOfYear=%d): %s (%d sec of the day) (GMT %d)", Latitude, Longitude, date, DayOfYear, tostring(UTILS.SecondsToClock(sunrise)), sunrise, Tdiff))
|
--self:I(string.format("Sun rise at lat=%.3f long=%.3f on %s (DayOfYear=%d): %s (%s sec of the day) (GMT %d)", Latitude, Longitude, date, DayOfYear, tostring(UTILS.SecondsToClock(sunrise)), tonumber(sunrise) or "0", Tdiff))
|
||||||
|
|
||||||
if InSeconds then
|
if InSeconds or type(sunrise) == "string" then
|
||||||
return sunrise
|
return sunrise
|
||||||
else
|
else
|
||||||
return UTILS.SecondsToClock(sunrise, true)
|
return UTILS.SecondsToClock(sunrise, true)
|
||||||
@@ -2837,9 +2837,9 @@ do -- COORDINATE
|
|||||||
local date=UTILS.GetDCSMissionDate()
|
local date=UTILS.GetDCSMissionDate()
|
||||||
|
|
||||||
-- Debug output.
|
-- Debug output.
|
||||||
--self:I(string.format("Sun set at lat=%.3f long=%.3f on %s (DayOfYear=%d): %s (%d sec of the day) (GMT %d)", Latitude, Longitude, date, DayOfYear, tostring(UTILS.SecondsToClock(sunrise)), sunrise, Tdiff))
|
--self:I(string.format("Sun set at lat=%.3f long=%.3f on %s (DayOfYear=%d): %s (%s sec of the day) (GMT %d)", Latitude, Longitude, date, DayOfYear, tostring(UTILS.SecondsToClock(sunrise)), tostring(sunrise) or "0", Tdiff))
|
||||||
|
|
||||||
if InSeconds then
|
if InSeconds or type(sunrise) == "string" then
|
||||||
return sunrise
|
return sunrise
|
||||||
else
|
else
|
||||||
return UTILS.SecondsToClock(sunrise, true)
|
return UTILS.SecondsToClock(sunrise, true)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -144,7 +144,7 @@ ZONE_BASE = {
|
|||||||
-- @return #ZONE_BASE self
|
-- @return #ZONE_BASE self
|
||||||
function ZONE_BASE:New( ZoneName )
|
function ZONE_BASE:New( ZoneName )
|
||||||
local self = BASE:Inherit( self, FSM:New() )
|
local self = BASE:Inherit( self, FSM:New() )
|
||||||
self:F( ZoneName )
|
--self:F( ZoneName )
|
||||||
|
|
||||||
self.ZoneName = ZoneName
|
self.ZoneName = ZoneName
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ end
|
|||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @return #string The name of the zone.
|
-- @return #string The name of the zone.
|
||||||
function ZONE_BASE:GetName()
|
function ZONE_BASE:GetName()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
return self.ZoneName
|
return self.ZoneName
|
||||||
end
|
end
|
||||||
@@ -167,7 +167,7 @@ end
|
|||||||
-- @param #string ZoneName The name of the zone.
|
-- @param #string ZoneName The name of the zone.
|
||||||
-- @return #ZONE_BASE
|
-- @return #ZONE_BASE
|
||||||
function ZONE_BASE:SetName( ZoneName )
|
function ZONE_BASE:SetName( ZoneName )
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
self.ZoneName = ZoneName
|
self.ZoneName = ZoneName
|
||||||
end
|
end
|
||||||
@@ -177,7 +177,7 @@ end
|
|||||||
-- @param DCS#Vec2 Vec2 The Vec2 to test.
|
-- @param DCS#Vec2 Vec2 The Vec2 to test.
|
||||||
-- @return #boolean true if the Vec2 is within the zone.
|
-- @return #boolean true if the Vec2 is within the zone.
|
||||||
function ZONE_BASE:IsVec2InZone( Vec2 )
|
function ZONE_BASE:IsVec2InZone( Vec2 )
|
||||||
self:F2( Vec2 )
|
--self:F2( Vec2 )
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@@ -232,13 +232,13 @@ end
|
|||||||
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
||||||
-- @return Core.Point#POINT_VEC2 The PointVec2 of the zone.
|
-- @return Core.Point#POINT_VEC2 The PointVec2 of the zone.
|
||||||
function ZONE_BASE:GetPointVec2()
|
function ZONE_BASE:GetPointVec2()
|
||||||
self:F2( self.ZoneName )
|
--self:F2( self.ZoneName )
|
||||||
|
|
||||||
local Vec2 = self:GetVec2()
|
local Vec2 = self:GetVec2()
|
||||||
|
|
||||||
local PointVec2 = POINT_VEC2:NewFromVec2( Vec2 )
|
local PointVec2 = POINT_VEC2:NewFromVec2( Vec2 )
|
||||||
|
|
||||||
self:T2( { PointVec2 } )
|
--self:T2( { PointVec2 } )
|
||||||
|
|
||||||
return PointVec2
|
return PointVec2
|
||||||
end
|
end
|
||||||
@@ -248,7 +248,7 @@ end
|
|||||||
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
||||||
-- @return DCS#Vec3 The Vec3 of the zone.
|
-- @return DCS#Vec3 The Vec3 of the zone.
|
||||||
function ZONE_BASE:GetVec3( Height )
|
function ZONE_BASE:GetVec3( Height )
|
||||||
self:F2( self.ZoneName )
|
--self:F2( self.ZoneName )
|
||||||
|
|
||||||
Height = Height or 0
|
Height = Height or 0
|
||||||
|
|
||||||
@@ -256,7 +256,7 @@ function ZONE_BASE:GetVec3( Height )
|
|||||||
|
|
||||||
local Vec3 = { x = Vec2.x, y = Height and Height or land.getHeight( self:GetVec2() ), z = Vec2.y }
|
local Vec3 = { x = Vec2.x, y = Height and Height or land.getHeight( self:GetVec2() ), z = Vec2.y }
|
||||||
|
|
||||||
self:T2( { Vec3 } )
|
--self:T2( { Vec3 } )
|
||||||
|
|
||||||
return Vec3
|
return Vec3
|
||||||
end
|
end
|
||||||
@@ -266,13 +266,13 @@ end
|
|||||||
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
||||||
-- @return Core.Point#POINT_VEC3 The PointVec3 of the zone.
|
-- @return Core.Point#POINT_VEC3 The PointVec3 of the zone.
|
||||||
function ZONE_BASE:GetPointVec3( Height )
|
function ZONE_BASE:GetPointVec3( Height )
|
||||||
self:F2( self.ZoneName )
|
--self:F2( self.ZoneName )
|
||||||
|
|
||||||
local Vec3 = self:GetVec3( Height )
|
local Vec3 = self:GetVec3( Height )
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:NewFromVec3( Vec3 )
|
local PointVec3 = POINT_VEC3:NewFromVec3( Vec3 )
|
||||||
|
|
||||||
self:T2( { PointVec3 } )
|
--self:T2( { PointVec3 } )
|
||||||
|
|
||||||
return PointVec3
|
return PointVec3
|
||||||
end
|
end
|
||||||
@@ -282,7 +282,7 @@ end
|
|||||||
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
||||||
-- @return Core.Point#COORDINATE The Coordinate of the zone.
|
-- @return Core.Point#COORDINATE The Coordinate of the zone.
|
||||||
function ZONE_BASE:GetCoordinate( Height ) --R2.1
|
function ZONE_BASE:GetCoordinate( Height ) --R2.1
|
||||||
self:F2(self.ZoneName)
|
--self:F2(self.ZoneName)
|
||||||
|
|
||||||
local Vec3 = self:GetVec3( Height )
|
local Vec3 = self:GetVec3( Height )
|
||||||
|
|
||||||
@@ -363,7 +363,7 @@ end
|
|||||||
--- Bound the zone boundaries with a tires.
|
--- Bound the zone boundaries with a tires.
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
function ZONE_BASE:BoundZone()
|
function ZONE_BASE:BoundZone()
|
||||||
self:F2()
|
--self:F2()
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set draw coalition of zone.
|
--- Set draw coalition of zone.
|
||||||
@@ -510,7 +510,7 @@ end
|
|||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @param Utilities.Utils#SMOKECOLOR SmokeColor The smoke color.
|
-- @param Utilities.Utils#SMOKECOLOR SmokeColor The smoke color.
|
||||||
function ZONE_BASE:SmokeZone( SmokeColor )
|
function ZONE_BASE:SmokeZone( SmokeColor )
|
||||||
self:F2( SmokeColor )
|
--self:F2( SmokeColor )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -519,7 +519,7 @@ end
|
|||||||
-- @param #number ZoneProbability A value between 0 and 1. 0 = 0% and 1 = 100% probability.
|
-- @param #number ZoneProbability A value between 0 and 1. 0 = 0% and 1 = 100% probability.
|
||||||
-- @return #ZONE_BASE self
|
-- @return #ZONE_BASE self
|
||||||
function ZONE_BASE:SetZoneProbability( ZoneProbability )
|
function ZONE_BASE:SetZoneProbability( ZoneProbability )
|
||||||
self:F( { self:GetName(), ZoneProbability = ZoneProbability } )
|
--self:F( { self:GetName(), ZoneProbability = ZoneProbability } )
|
||||||
|
|
||||||
self.ZoneProbability = ZoneProbability or 1
|
self.ZoneProbability = ZoneProbability or 1
|
||||||
return self
|
return self
|
||||||
@@ -529,7 +529,7 @@ end
|
|||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @return #number A value between 0 and 1. 0 = 0% and 1 = 100% probability.
|
-- @return #number A value between 0 and 1. 0 = 0% and 1 = 100% probability.
|
||||||
function ZONE_BASE:GetZoneProbability()
|
function ZONE_BASE:GetZoneProbability()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
return self.ZoneProbability
|
return self.ZoneProbability
|
||||||
end
|
end
|
||||||
@@ -560,7 +560,7 @@ end
|
|||||||
-- -- The result should be that Zone1 would be more probable selected than Zone2.
|
-- -- The result should be that Zone1 would be more probable selected than Zone2.
|
||||||
--
|
--
|
||||||
function ZONE_BASE:GetZoneMaybe()
|
function ZONE_BASE:GetZoneMaybe()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local Randomization = math.random()
|
local Randomization = math.random()
|
||||||
if Randomization <= self.ZoneProbability then
|
if Randomization <= self.ZoneProbability then
|
||||||
@@ -791,7 +791,7 @@ function ZONE_RADIUS:New( ZoneName, Vec2, Radius, DoNotRegisterZone )
|
|||||||
|
|
||||||
-- Inherit ZONE_BASE.
|
-- Inherit ZONE_BASE.
|
||||||
local self = BASE:Inherit( self, ZONE_BASE:New( ZoneName ) ) -- #ZONE_RADIUS
|
local self = BASE:Inherit( self, ZONE_BASE:New( ZoneName ) ) -- #ZONE_RADIUS
|
||||||
self:F( { ZoneName, Vec2, Radius } )
|
--self:F( { ZoneName, Vec2, Radius } )
|
||||||
|
|
||||||
self.Radius = Radius
|
self.Radius = Radius
|
||||||
self.Vec2 = Vec2
|
self.Vec2 = Vec2
|
||||||
@@ -947,7 +947,7 @@ end
|
|||||||
-- @param #number AddOffSet (optional) The angle to be added for the smoking start position.
|
-- @param #number AddOffSet (optional) The angle to be added for the smoking start position.
|
||||||
-- @return #ZONE_RADIUS self
|
-- @return #ZONE_RADIUS self
|
||||||
function ZONE_RADIUS:SmokeZone( SmokeColor, Points, AddHeight, AngleOffset )
|
function ZONE_RADIUS:SmokeZone( SmokeColor, Points, AddHeight, AngleOffset )
|
||||||
self:F2( SmokeColor )
|
--self:F2( SmokeColor )
|
||||||
|
|
||||||
local Point = {}
|
local Point = {}
|
||||||
local Vec2 = self:GetVec2()
|
local Vec2 = self:GetVec2()
|
||||||
@@ -978,7 +978,7 @@ end
|
|||||||
-- @param #number AddHeight (optional) The height to be added for the smoke.
|
-- @param #number AddHeight (optional) The height to be added for the smoke.
|
||||||
-- @return #ZONE_RADIUS self
|
-- @return #ZONE_RADIUS self
|
||||||
function ZONE_RADIUS:FlareZone( FlareColor, Points, Azimuth, AddHeight )
|
function ZONE_RADIUS:FlareZone( FlareColor, Points, Azimuth, AddHeight )
|
||||||
self:F2( { FlareColor, Azimuth } )
|
--self:F2( { FlareColor, Azimuth } )
|
||||||
|
|
||||||
local Point = {}
|
local Point = {}
|
||||||
local Vec2 = self:GetVec2()
|
local Vec2 = self:GetVec2()
|
||||||
@@ -1004,9 +1004,9 @@ end
|
|||||||
-- @param #ZONE_RADIUS self
|
-- @param #ZONE_RADIUS self
|
||||||
-- @return DCS#Distance The radius of the zone.
|
-- @return DCS#Distance The radius of the zone.
|
||||||
function ZONE_RADIUS:GetRadius()
|
function ZONE_RADIUS:GetRadius()
|
||||||
self:F2( self.ZoneName )
|
--self:F2( self.ZoneName )
|
||||||
|
|
||||||
self:T2( { self.Radius } )
|
--self:T2( { self.Radius } )
|
||||||
|
|
||||||
return self.Radius
|
return self.Radius
|
||||||
end
|
end
|
||||||
@@ -1016,10 +1016,10 @@ end
|
|||||||
-- @param DCS#Distance Radius The radius of the zone.
|
-- @param DCS#Distance Radius The radius of the zone.
|
||||||
-- @return DCS#Distance The radius of the zone.
|
-- @return DCS#Distance The radius of the zone.
|
||||||
function ZONE_RADIUS:SetRadius( Radius )
|
function ZONE_RADIUS:SetRadius( Radius )
|
||||||
self:F2( self.ZoneName )
|
--self:F2( self.ZoneName )
|
||||||
|
|
||||||
self.Radius = Radius
|
self.Radius = Radius
|
||||||
self:T2( { self.Radius } )
|
--self:T2( { self.Radius } )
|
||||||
|
|
||||||
return self.Radius
|
return self.Radius
|
||||||
end
|
end
|
||||||
@@ -1028,9 +1028,9 @@ end
|
|||||||
-- @param #ZONE_RADIUS self
|
-- @param #ZONE_RADIUS self
|
||||||
-- @return DCS#Vec2 The location of the zone.
|
-- @return DCS#Vec2 The location of the zone.
|
||||||
function ZONE_RADIUS:GetVec2()
|
function ZONE_RADIUS:GetVec2()
|
||||||
self:F2( self.ZoneName )
|
--self:F2( self.ZoneName )
|
||||||
|
|
||||||
self:T2( { self.Vec2 } )
|
--self:T2( { self.Vec2 } )
|
||||||
|
|
||||||
return self.Vec2
|
return self.Vec2
|
||||||
end
|
end
|
||||||
@@ -1040,11 +1040,11 @@ end
|
|||||||
-- @param DCS#Vec2 Vec2 The new location of the zone.
|
-- @param DCS#Vec2 Vec2 The new location of the zone.
|
||||||
-- @return DCS#Vec2 The new location of the zone.
|
-- @return DCS#Vec2 The new location of the zone.
|
||||||
function ZONE_RADIUS:SetVec2( Vec2 )
|
function ZONE_RADIUS:SetVec2( Vec2 )
|
||||||
self:F2( self.ZoneName )
|
--self:F2( self.ZoneName )
|
||||||
|
|
||||||
self.Vec2 = Vec2
|
self.Vec2 = Vec2
|
||||||
|
|
||||||
self:T2( { self.Vec2 } )
|
--self:T2( { self.Vec2 } )
|
||||||
|
|
||||||
return self.Vec2
|
return self.Vec2
|
||||||
end
|
end
|
||||||
@@ -1054,14 +1054,14 @@ end
|
|||||||
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
||||||
-- @return DCS#Vec3 The point of the zone.
|
-- @return DCS#Vec3 The point of the zone.
|
||||||
function ZONE_RADIUS:GetVec3( Height )
|
function ZONE_RADIUS:GetVec3( Height )
|
||||||
self:F2( { self.ZoneName, Height } )
|
--self:F2( { self.ZoneName, Height } )
|
||||||
|
|
||||||
Height = Height or 0
|
Height = Height or 0
|
||||||
local Vec2 = self:GetVec2()
|
local Vec2 = self:GetVec2()
|
||||||
|
|
||||||
local Vec3 = { x = Vec2.x, y = land.getHeight( self:GetVec2() ) + Height, z = Vec2.y }
|
local Vec3 = { x = Vec2.x, y = land.getHeight( self:GetVec2() ) + Height, z = Vec2.y }
|
||||||
|
|
||||||
self:T2( { Vec3 } )
|
--self:T2( { Vec3 } )
|
||||||
|
|
||||||
return Vec3
|
return Vec3
|
||||||
end
|
end
|
||||||
@@ -1138,7 +1138,7 @@ function ZONE_RADIUS:Scan( ObjectCategories, UnitCategories )
|
|||||||
|
|
||||||
self.ScanData.Units[ZoneObject] = ZoneObject
|
self.ScanData.Units[ZoneObject] = ZoneObject
|
||||||
|
|
||||||
self:F2( { Name = ZoneObject:getName(), Coalition = CoalitionDCSUnit } )
|
--self:F2( { Name = ZoneObject:getName(), Coalition = CoalitionDCSUnit } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1149,7 +1149,7 @@ function ZONE_RADIUS:Scan( ObjectCategories, UnitCategories )
|
|||||||
self.ScanData.Scenery[SceneryType] = self.ScanData.Scenery[SceneryType] or {}
|
self.ScanData.Scenery[SceneryType] = self.ScanData.Scenery[SceneryType] or {}
|
||||||
self.ScanData.Scenery[SceneryType][SceneryName] = SCENERY:Register( tostring(SceneryName), ZoneObject)
|
self.ScanData.Scenery[SceneryType][SceneryName] = SCENERY:Register( tostring(SceneryName), ZoneObject)
|
||||||
table.insert(self.ScanData.SceneryTable,self.ScanData.Scenery[SceneryType][SceneryName] )
|
table.insert(self.ScanData.SceneryTable,self.ScanData.Scenery[SceneryType][SceneryName] )
|
||||||
self:T( { SCENERY = self.ScanData.Scenery[SceneryType][SceneryName] } )
|
--self:T( { SCENERY = self.ScanData.Scenery[SceneryType][SceneryName] } )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1409,7 +1409,7 @@ function ZONE_RADIUS:SearchZone( EvaluateFunction, ObjectCategories )
|
|||||||
local ZoneCoord = self:GetCoordinate()
|
local ZoneCoord = self:GetCoordinate()
|
||||||
local ZoneRadius = self:GetRadius()
|
local ZoneRadius = self:GetRadius()
|
||||||
|
|
||||||
self:F({ZoneCoord = ZoneCoord, ZoneRadius = ZoneRadius, ZoneCoordLL = ZoneCoord:ToStringLLDMS()})
|
--self:F({ZoneCoord = ZoneCoord, ZoneRadius = ZoneRadius, ZoneCoordLL = ZoneCoord:ToStringLLDMS()})
|
||||||
|
|
||||||
local SphereSearch = {
|
local SphereSearch = {
|
||||||
id = world.VolumeType.SPHERE,
|
id = world.VolumeType.SPHERE,
|
||||||
@@ -1436,7 +1436,7 @@ end
|
|||||||
-- @param DCS#Vec2 Vec2 The location to test.
|
-- @param DCS#Vec2 Vec2 The location to test.
|
||||||
-- @return #boolean true if the location is within the zone.
|
-- @return #boolean true if the location is within the zone.
|
||||||
function ZONE_RADIUS:IsVec2InZone( Vec2 )
|
function ZONE_RADIUS:IsVec2InZone( Vec2 )
|
||||||
self:F2( Vec2 )
|
--self:F2( Vec2 )
|
||||||
|
|
||||||
if not Vec2 then return false end
|
if not Vec2 then return false end
|
||||||
|
|
||||||
@@ -1456,7 +1456,7 @@ end
|
|||||||
-- @param DCS#Vec3 Vec3 The point to test.
|
-- @param DCS#Vec3 Vec3 The point to test.
|
||||||
-- @return #boolean true if the point is within the zone.
|
-- @return #boolean true if the point is within the zone.
|
||||||
function ZONE_RADIUS:IsVec3InZone( Vec3 )
|
function ZONE_RADIUS:IsVec3InZone( Vec3 )
|
||||||
self:F2( Vec3 )
|
--self:F2( Vec3 )
|
||||||
if not Vec3 then return false end
|
if not Vec3 then return false end
|
||||||
local InZone = self:IsVec2InZone( { x = Vec3.x, y = Vec3.z } )
|
local InZone = self:IsVec2InZone( { x = Vec3.x, y = Vec3.z } )
|
||||||
|
|
||||||
@@ -1521,11 +1521,11 @@ end
|
|||||||
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
||||||
-- @return Core.Point#POINT_VEC2 The @{Core.Point#POINT_VEC2} object reflecting the random 3D location within the zone.
|
-- @return Core.Point#POINT_VEC2 The @{Core.Point#POINT_VEC2} object reflecting the random 3D location within the zone.
|
||||||
function ZONE_RADIUS:GetRandomPointVec2( inner, outer )
|
function ZONE_RADIUS:GetRandomPointVec2( inner, outer )
|
||||||
self:F( self.ZoneName, inner, outer )
|
--self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2( inner, outer ) )
|
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2( inner, outer ) )
|
||||||
|
|
||||||
self:T3( { PointVec2 } )
|
--self:T3( { PointVec2 } )
|
||||||
|
|
||||||
return PointVec2
|
return PointVec2
|
||||||
end
|
end
|
||||||
@@ -1536,11 +1536,11 @@ end
|
|||||||
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
||||||
-- @return DCS#Vec3 The random location within the zone.
|
-- @return DCS#Vec3 The random location within the zone.
|
||||||
function ZONE_RADIUS:GetRandomVec3( inner, outer )
|
function ZONE_RADIUS:GetRandomVec3( inner, outer )
|
||||||
self:F( self.ZoneName, inner, outer )
|
--self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
local Vec2 = self:GetRandomVec2( inner, outer )
|
local Vec2 = self:GetRandomVec2( inner, outer )
|
||||||
|
|
||||||
self:T3( { x = Vec2.x, y = self.y, z = Vec2.y } )
|
--self:T3( { x = Vec2.x, y = self.y, z = Vec2.y } )
|
||||||
|
|
||||||
return { x = Vec2.x, y = self.y, z = Vec2.y }
|
return { x = Vec2.x, y = self.y, z = Vec2.y }
|
||||||
end
|
end
|
||||||
@@ -1552,11 +1552,11 @@ end
|
|||||||
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
||||||
-- @return Core.Point#POINT_VEC3 The @{Core.Point#POINT_VEC3} object reflecting the random 3D location within the zone.
|
-- @return Core.Point#POINT_VEC3 The @{Core.Point#POINT_VEC3} object reflecting the random 3D location within the zone.
|
||||||
function ZONE_RADIUS:GetRandomPointVec3( inner, outer )
|
function ZONE_RADIUS:GetRandomPointVec3( inner, outer )
|
||||||
self:F( self.ZoneName, inner, outer )
|
--self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2( inner, outer ) )
|
local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2( inner, outer ) )
|
||||||
|
|
||||||
self:T3( { PointVec3 } )
|
--self:T3( { PointVec3 } )
|
||||||
|
|
||||||
return PointVec3
|
return PointVec3
|
||||||
end
|
end
|
||||||
@@ -1685,7 +1685,7 @@ function ZONE_RADIUS:GetRandomCoordinateWithoutBuildings(inner,outer,distance,ma
|
|||||||
|
|
||||||
T1=timer.getTime()
|
T1=timer.getTime()
|
||||||
|
|
||||||
self:T(string.format("Found a coordinate: %s | Iterations: %d | Time: %.3f",tostring(found),iterations,T1-T0))
|
--self:T(string.format("Found a coordinate: %s | Iterations: %d | Time: %.3f",tostring(found),iterations,T1-T0))
|
||||||
|
|
||||||
if found then return rcoord else return nil end
|
if found then return rcoord else return nil end
|
||||||
|
|
||||||
@@ -1754,7 +1754,7 @@ function ZONE:New( ZoneName )
|
|||||||
|
|
||||||
-- Create a new ZONE_RADIUS.
|
-- Create a new ZONE_RADIUS.
|
||||||
local self=BASE:Inherit( self, ZONE_RADIUS:New(ZoneName, {x=Zone.point.x, y=Zone.point.z}, Zone.radius, true))
|
local self=BASE:Inherit( self, ZONE_RADIUS:New(ZoneName, {x=Zone.point.x, y=Zone.point.z}, Zone.radius, true))
|
||||||
self:F(ZoneName)
|
--self:F(ZoneName)
|
||||||
|
|
||||||
-- Color of zone.
|
-- Color of zone.
|
||||||
self.Color={1, 0, 0, 0.15}
|
self.Color={1, 0, 0, 0.15}
|
||||||
@@ -1824,7 +1824,7 @@ function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, Offset)
|
|||||||
self.relative_to_unit = Offset.relative_to_unit or false
|
self.relative_to_unit = Offset.relative_to_unit or false
|
||||||
end
|
end
|
||||||
|
|
||||||
self:F( { ZoneName, ZoneUNIT:GetVec2(), Radius } )
|
--self:F( { ZoneName, ZoneUNIT:GetVec2(), Radius } )
|
||||||
|
|
||||||
self.ZoneUNIT = ZoneUNIT
|
self.ZoneUNIT = ZoneUNIT
|
||||||
self.LastVec2 = ZoneUNIT:GetVec2()
|
self.LastVec2 = ZoneUNIT:GetVec2()
|
||||||
@@ -1840,7 +1840,7 @@ end
|
|||||||
-- @param #ZONE_UNIT self
|
-- @param #ZONE_UNIT self
|
||||||
-- @return DCS#Vec2 The location of the zone based on the @{Wrapper.Unit#UNIT}location and the offset, if any.
|
-- @return DCS#Vec2 The location of the zone based on the @{Wrapper.Unit#UNIT}location and the offset, if any.
|
||||||
function ZONE_UNIT:GetVec2()
|
function ZONE_UNIT:GetVec2()
|
||||||
self:F2( self.ZoneName )
|
--self:F2( self.ZoneName )
|
||||||
|
|
||||||
local ZoneVec2 = self.ZoneUNIT:GetVec2()
|
local ZoneVec2 = self.ZoneUNIT:GetVec2()
|
||||||
if ZoneVec2 then
|
if ZoneVec2 then
|
||||||
@@ -1873,7 +1873,7 @@ function ZONE_UNIT:GetVec2()
|
|||||||
return self.LastVec2
|
return self.LastVec2
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T2( { ZoneVec2 } )
|
--self:T2( { ZoneVec2 } )
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
@@ -1882,7 +1882,7 @@ end
|
|||||||
-- @param #ZONE_UNIT self
|
-- @param #ZONE_UNIT self
|
||||||
-- @return DCS#Vec2 The random location within the zone.
|
-- @return DCS#Vec2 The random location within the zone.
|
||||||
function ZONE_UNIT:GetRandomVec2()
|
function ZONE_UNIT:GetRandomVec2()
|
||||||
self:F( self.ZoneName )
|
--self:F( self.ZoneName )
|
||||||
|
|
||||||
local RandomVec2 = {}
|
local RandomVec2 = {}
|
||||||
--local Vec2 = self.ZoneUNIT:GetVec2() -- FF: This does not take care of the new offset feature!
|
--local Vec2 = self.ZoneUNIT:GetVec2() -- FF: This does not take care of the new offset feature!
|
||||||
@@ -1896,7 +1896,7 @@ function ZONE_UNIT:GetRandomVec2()
|
|||||||
RandomVec2.x = Vec2.x + math.cos( angle ) * math.random() * self:GetRadius();
|
RandomVec2.x = Vec2.x + math.cos( angle ) * math.random() * self:GetRadius();
|
||||||
RandomVec2.y = Vec2.y + math.sin( angle ) * math.random() * self:GetRadius();
|
RandomVec2.y = Vec2.y + math.sin( angle ) * math.random() * self:GetRadius();
|
||||||
|
|
||||||
self:T( { RandomVec2 } )
|
--self:T( { RandomVec2 } )
|
||||||
|
|
||||||
return RandomVec2
|
return RandomVec2
|
||||||
end
|
end
|
||||||
@@ -1906,7 +1906,7 @@ end
|
|||||||
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
|
||||||
-- @return DCS#Vec3 The point of the zone.
|
-- @return DCS#Vec3 The point of the zone.
|
||||||
function ZONE_UNIT:GetVec3( Height )
|
function ZONE_UNIT:GetVec3( Height )
|
||||||
self:F2( self.ZoneName )
|
--self:F2( self.ZoneName )
|
||||||
|
|
||||||
Height = Height or 0
|
Height = Height or 0
|
||||||
|
|
||||||
@@ -1914,7 +1914,7 @@ function ZONE_UNIT:GetVec3( Height )
|
|||||||
|
|
||||||
local Vec3 = { x = Vec2.x, y = land.getHeight( self:GetVec2() ) + Height, z = Vec2.y }
|
local Vec3 = { x = Vec2.x, y = land.getHeight( self:GetVec2() ) + Height, z = Vec2.y }
|
||||||
|
|
||||||
self:T2( { Vec3 } )
|
--self:T2( { Vec3 } )
|
||||||
|
|
||||||
return Vec3
|
return Vec3
|
||||||
end
|
end
|
||||||
@@ -1940,7 +1940,7 @@ ZONE_GROUP = {
|
|||||||
-- @return #ZONE_GROUP self
|
-- @return #ZONE_GROUP self
|
||||||
function ZONE_GROUP:New( ZoneName, ZoneGROUP, Radius )
|
function ZONE_GROUP:New( ZoneName, ZoneGROUP, Radius )
|
||||||
local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneGROUP:GetVec2(), Radius, true ) )
|
local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneGROUP:GetVec2(), Radius, true ) )
|
||||||
self:F( { ZoneName, ZoneGROUP:GetVec2(), Radius } )
|
--self:F( { ZoneName, ZoneGROUP:GetVec2(), Radius } )
|
||||||
|
|
||||||
self._.ZoneGROUP = ZoneGROUP
|
self._.ZoneGROUP = ZoneGROUP
|
||||||
self._.ZoneVec2Cache = self._.ZoneGROUP:GetVec2()
|
self._.ZoneVec2Cache = self._.ZoneGROUP:GetVec2()
|
||||||
@@ -1956,7 +1956,7 @@ end
|
|||||||
-- @param #ZONE_GROUP self
|
-- @param #ZONE_GROUP self
|
||||||
-- @return DCS#Vec2 The location of the zone based on the @{Wrapper.Group} location.
|
-- @return DCS#Vec2 The location of the zone based on the @{Wrapper.Group} location.
|
||||||
function ZONE_GROUP:GetVec2()
|
function ZONE_GROUP:GetVec2()
|
||||||
self:F( self.ZoneName )
|
--self:F( self.ZoneName )
|
||||||
|
|
||||||
local ZoneVec2 = nil
|
local ZoneVec2 = nil
|
||||||
|
|
||||||
@@ -1967,7 +1967,7 @@ function ZONE_GROUP:GetVec2()
|
|||||||
ZoneVec2 = self._.ZoneVec2Cache
|
ZoneVec2 = self._.ZoneVec2Cache
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T( { ZoneVec2 } )
|
--self:T( { ZoneVec2 } )
|
||||||
|
|
||||||
return ZoneVec2
|
return ZoneVec2
|
||||||
end
|
end
|
||||||
@@ -1976,7 +1976,7 @@ end
|
|||||||
-- @param #ZONE_GROUP self
|
-- @param #ZONE_GROUP self
|
||||||
-- @return DCS#Vec2 The random location of the zone based on the @{Wrapper.Group} location.
|
-- @return DCS#Vec2 The random location of the zone based on the @{Wrapper.Group} location.
|
||||||
function ZONE_GROUP:GetRandomVec2()
|
function ZONE_GROUP:GetRandomVec2()
|
||||||
self:F( self.ZoneName )
|
--self:F( self.ZoneName )
|
||||||
|
|
||||||
local Point = {}
|
local Point = {}
|
||||||
local Vec2 = self._.ZoneGROUP:GetVec2()
|
local Vec2 = self._.ZoneGROUP:GetVec2()
|
||||||
@@ -1985,7 +1985,7 @@ function ZONE_GROUP:GetRandomVec2()
|
|||||||
Point.x = Vec2.x + math.cos( angle ) * math.random() * self:GetRadius();
|
Point.x = Vec2.x + math.cos( angle ) * math.random() * self:GetRadius();
|
||||||
Point.y = Vec2.y + math.sin( angle ) * math.random() * self:GetRadius();
|
Point.y = Vec2.y + math.sin( angle ) * math.random() * self:GetRadius();
|
||||||
|
|
||||||
self:T( { Point } )
|
--self:T( { Point } )
|
||||||
|
|
||||||
return Point
|
return Point
|
||||||
end
|
end
|
||||||
@@ -1996,11 +1996,11 @@ end
|
|||||||
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
||||||
-- @return Core.Point#POINT_VEC2 The @{Core.Point#POINT_VEC2} object reflecting the random 3D location within the zone.
|
-- @return Core.Point#POINT_VEC2 The @{Core.Point#POINT_VEC2} object reflecting the random 3D location within the zone.
|
||||||
function ZONE_GROUP:GetRandomPointVec2( inner, outer )
|
function ZONE_GROUP:GetRandomPointVec2( inner, outer )
|
||||||
self:F( self.ZoneName, inner, outer )
|
--self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
|
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
|
||||||
|
|
||||||
self:T3( { PointVec2 } )
|
--self:T3( { PointVec2 } )
|
||||||
|
|
||||||
return PointVec2
|
return PointVec2
|
||||||
end
|
end
|
||||||
@@ -2183,7 +2183,7 @@ function ZONE_POLYGON_BASE:New( ZoneName, PointsArray )
|
|||||||
|
|
||||||
-- Inherit ZONE_BASE.
|
-- Inherit ZONE_BASE.
|
||||||
local self = BASE:Inherit( self, ZONE_BASE:New( ZoneName ) )
|
local self = BASE:Inherit( self, ZONE_BASE:New( ZoneName ) )
|
||||||
self:F( { ZoneName, PointsArray } )
|
--self:F( { ZoneName, PointsArray } )
|
||||||
|
|
||||||
if PointsArray then
|
if PointsArray then
|
||||||
|
|
||||||
@@ -2351,7 +2351,7 @@ end
|
|||||||
-- @param #ZONE_POLYGON_BASE self
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
-- @return DCS#Vec2 The location of the zone based on the @{Wrapper.Group} location.
|
-- @return DCS#Vec2 The location of the zone based on the @{Wrapper.Group} location.
|
||||||
function ZONE_POLYGON_BASE:GetVec2()
|
function ZONE_POLYGON_BASE:GetVec2()
|
||||||
self:F( self.ZoneName )
|
--self:F( self.ZoneName )
|
||||||
|
|
||||||
local Bounds = self:GetBoundingSquare()
|
local Bounds = self:GetBoundingSquare()
|
||||||
|
|
||||||
@@ -2434,9 +2434,9 @@ end
|
|||||||
-- @param #ZONE_POLYGON_BASE self
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
-- @return #ZONE_POLYGON_BASE self
|
-- @return #ZONE_POLYGON_BASE self
|
||||||
function ZONE_POLYGON_BASE:Flush()
|
function ZONE_POLYGON_BASE:Flush()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
self:F( { Polygon = self.ZoneName, Coordinates = self._.Polygon } )
|
--self:F( { Polygon = self.ZoneName, Coordinates = self._.Polygon } )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -2455,7 +2455,7 @@ function ZONE_POLYGON_BASE:BoundZone( UnBound )
|
|||||||
j = #self._.Polygon
|
j = #self._.Polygon
|
||||||
|
|
||||||
while i <= #self._.Polygon do
|
while i <= #self._.Polygon do
|
||||||
self:T( { i, j, self._.Polygon[i], self._.Polygon[j] } )
|
--self:T( { i, j, self._.Polygon[i], self._.Polygon[j] } )
|
||||||
|
|
||||||
local DeltaX = self._.Polygon[j].x - self._.Polygon[i].x
|
local DeltaX = self._.Polygon[j].x - self._.Polygon[i].x
|
||||||
local DeltaY = self._.Polygon[j].y - self._.Polygon[i].y
|
local DeltaY = self._.Polygon[j].y - self._.Polygon[i].y
|
||||||
@@ -2707,7 +2707,7 @@ end
|
|||||||
-- @param #number Segments (Optional) Number of segments within boundary line. Default 10.
|
-- @param #number Segments (Optional) Number of segments within boundary line. Default 10.
|
||||||
-- @return #ZONE_POLYGON_BASE self
|
-- @return #ZONE_POLYGON_BASE self
|
||||||
function ZONE_POLYGON_BASE:SmokeZone( SmokeColor, Segments )
|
function ZONE_POLYGON_BASE:SmokeZone( SmokeColor, Segments )
|
||||||
self:F2( SmokeColor )
|
--self:F2( SmokeColor )
|
||||||
|
|
||||||
Segments=Segments or 10
|
Segments=Segments or 10
|
||||||
|
|
||||||
@@ -2715,7 +2715,7 @@ function ZONE_POLYGON_BASE:SmokeZone( SmokeColor, Segments )
|
|||||||
local j=#self._.Polygon
|
local j=#self._.Polygon
|
||||||
|
|
||||||
while i <= #self._.Polygon do
|
while i <= #self._.Polygon do
|
||||||
self:T( { i, j, self._.Polygon[i], self._.Polygon[j] } )
|
--self:T( { i, j, self._.Polygon[i], self._.Polygon[j] } )
|
||||||
|
|
||||||
local DeltaX = self._.Polygon[j].x - self._.Polygon[i].x
|
local DeltaX = self._.Polygon[j].x - self._.Polygon[i].x
|
||||||
local DeltaY = self._.Polygon[j].y - self._.Polygon[i].y
|
local DeltaY = self._.Polygon[j].y - self._.Polygon[i].y
|
||||||
@@ -2740,7 +2740,7 @@ end
|
|||||||
-- @param #number AddHeight (optional) The height to be added for the smoke.
|
-- @param #number AddHeight (optional) The height to be added for the smoke.
|
||||||
-- @return #ZONE_POLYGON_BASE self
|
-- @return #ZONE_POLYGON_BASE self
|
||||||
function ZONE_POLYGON_BASE:FlareZone( FlareColor, Segments, Azimuth, AddHeight )
|
function ZONE_POLYGON_BASE:FlareZone( FlareColor, Segments, Azimuth, AddHeight )
|
||||||
self:F2(FlareColor)
|
--self:F2(FlareColor)
|
||||||
|
|
||||||
Segments=Segments or 10
|
Segments=Segments or 10
|
||||||
|
|
||||||
@@ -2750,7 +2750,7 @@ function ZONE_POLYGON_BASE:FlareZone( FlareColor, Segments, Azimuth, AddHeight )
|
|||||||
local j=#self._.Polygon
|
local j=#self._.Polygon
|
||||||
|
|
||||||
while i <= #self._.Polygon do
|
while i <= #self._.Polygon do
|
||||||
self:T( { i, j, self._.Polygon[i], self._.Polygon[j] } )
|
--self:T( { i, j, self._.Polygon[i], self._.Polygon[j] } )
|
||||||
|
|
||||||
local DeltaX = self._.Polygon[j].x - self._.Polygon[i].x
|
local DeltaX = self._.Polygon[j].x - self._.Polygon[i].x
|
||||||
local DeltaY = self._.Polygon[j].y - self._.Polygon[i].y
|
local DeltaY = self._.Polygon[j].y - self._.Polygon[i].y
|
||||||
@@ -2773,7 +2773,7 @@ end
|
|||||||
-- @param DCS#Vec2 Vec2 The location to test.
|
-- @param DCS#Vec2 Vec2 The location to test.
|
||||||
-- @return #boolean true if the location is within the zone.
|
-- @return #boolean true if the location is within the zone.
|
||||||
function ZONE_POLYGON_BASE:IsVec2InZone( Vec2 )
|
function ZONE_POLYGON_BASE:IsVec2InZone( Vec2 )
|
||||||
self:F2( Vec2 )
|
--self:F2( Vec2 )
|
||||||
if not Vec2 then return false end
|
if not Vec2 then return false end
|
||||||
local Next
|
local Next
|
||||||
local Prev
|
local Prev
|
||||||
@@ -2783,18 +2783,18 @@ function ZONE_POLYGON_BASE:IsVec2InZone( Vec2 )
|
|||||||
Prev = #self._.Polygon
|
Prev = #self._.Polygon
|
||||||
|
|
||||||
while Next <= #self._.Polygon do
|
while Next <= #self._.Polygon do
|
||||||
self:T( { Next, Prev, self._.Polygon[Next], self._.Polygon[Prev] } )
|
--self:T( { Next, Prev, self._.Polygon[Next], self._.Polygon[Prev] } )
|
||||||
if ( ( ( self._.Polygon[Next].y > Vec2.y ) ~= ( self._.Polygon[Prev].y > Vec2.y ) ) and
|
if ( ( ( self._.Polygon[Next].y > Vec2.y ) ~= ( self._.Polygon[Prev].y > Vec2.y ) ) and
|
||||||
( Vec2.x < ( self._.Polygon[Prev].x - self._.Polygon[Next].x ) * ( Vec2.y - self._.Polygon[Next].y ) / ( self._.Polygon[Prev].y - self._.Polygon[Next].y ) + self._.Polygon[Next].x )
|
( Vec2.x < ( self._.Polygon[Prev].x - self._.Polygon[Next].x ) * ( Vec2.y - self._.Polygon[Next].y ) / ( self._.Polygon[Prev].y - self._.Polygon[Next].y ) + self._.Polygon[Next].x )
|
||||||
) then
|
) then
|
||||||
InPolygon = not InPolygon
|
InPolygon = not InPolygon
|
||||||
end
|
end
|
||||||
self:T2( { InPolygon = InPolygon } )
|
--self:T2( { InPolygon = InPolygon } )
|
||||||
Prev = Next
|
Prev = Next
|
||||||
Next = Next + 1
|
Next = Next + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T( { InPolygon = InPolygon } )
|
--self:T( { InPolygon = InPolygon } )
|
||||||
return InPolygon
|
return InPolygon
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2803,7 +2803,7 @@ end
|
|||||||
-- @param DCS#Vec3 Vec3 The point to test.
|
-- @param DCS#Vec3 Vec3 The point to test.
|
||||||
-- @return #boolean true if the point is within the zone.
|
-- @return #boolean true if the point is within the zone.
|
||||||
function ZONE_POLYGON_BASE:IsVec3InZone( Vec3 )
|
function ZONE_POLYGON_BASE:IsVec3InZone( Vec3 )
|
||||||
self:F2( Vec3 )
|
--self:F2( Vec3 )
|
||||||
|
|
||||||
if not Vec3 then return false end
|
if not Vec3 then return false end
|
||||||
|
|
||||||
@@ -2838,11 +2838,11 @@ end
|
|||||||
-- @param #ZONE_POLYGON_BASE self
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
-- @return @{Core.Point#POINT_VEC2}
|
-- @return @{Core.Point#POINT_VEC2}
|
||||||
function ZONE_POLYGON_BASE:GetRandomPointVec2()
|
function ZONE_POLYGON_BASE:GetRandomPointVec2()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
|
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
|
||||||
|
|
||||||
self:T2( PointVec2 )
|
--self:T2( PointVec2 )
|
||||||
|
|
||||||
return PointVec2
|
return PointVec2
|
||||||
end
|
end
|
||||||
@@ -2851,11 +2851,11 @@ end
|
|||||||
-- @param #ZONE_POLYGON_BASE self
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
-- @return @{Core.Point#POINT_VEC3}
|
-- @return @{Core.Point#POINT_VEC3}
|
||||||
function ZONE_POLYGON_BASE:GetRandomPointVec3()
|
function ZONE_POLYGON_BASE:GetRandomPointVec3()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2() )
|
local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2() )
|
||||||
|
|
||||||
self:T2( PointVec3 )
|
--self:T2( PointVec3 )
|
||||||
|
|
||||||
return PointVec3
|
return PointVec3
|
||||||
end
|
end
|
||||||
@@ -2865,11 +2865,11 @@ end
|
|||||||
-- @param #ZONE_POLYGON_BASE self
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
-- @return Core.Point#COORDINATE
|
-- @return Core.Point#COORDINATE
|
||||||
function ZONE_POLYGON_BASE:GetRandomCoordinate()
|
function ZONE_POLYGON_BASE:GetRandomCoordinate()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local Coordinate = COORDINATE:NewFromVec2( self:GetRandomVec2() )
|
local Coordinate = COORDINATE:NewFromVec2( self:GetRandomVec2() )
|
||||||
|
|
||||||
self:T2( Coordinate )
|
--self:T2( Coordinate )
|
||||||
|
|
||||||
return Coordinate
|
return Coordinate
|
||||||
end
|
end
|
||||||
@@ -2886,7 +2886,7 @@ function ZONE_POLYGON_BASE:GetBoundingSquare()
|
|||||||
local y2 = self._.Polygon[1].y
|
local y2 = self._.Polygon[1].y
|
||||||
|
|
||||||
for i = 2, #self._.Polygon do
|
for i = 2, #self._.Polygon do
|
||||||
self:T2( { self._.Polygon[i], x1, y1, x2, y2 } )
|
--self:T2( { self._.Polygon[i], x1, y1, x2, y2 } )
|
||||||
x1 = ( x1 > self._.Polygon[i].x ) and self._.Polygon[i].x or x1
|
x1 = ( x1 > self._.Polygon[i].x ) and self._.Polygon[i].x or x1
|
||||||
x2 = ( x2 < self._.Polygon[i].x ) and self._.Polygon[i].x or x2
|
x2 = ( x2 < self._.Polygon[i].x ) and self._.Polygon[i].x or x2
|
||||||
y1 = ( y1 > self._.Polygon[i].y ) and self._.Polygon[i].y or y1
|
y1 = ( y1 > self._.Polygon[i].y ) and self._.Polygon[i].y or y1
|
||||||
@@ -2909,7 +2909,7 @@ function ZONE_POLYGON_BASE:GetBoundingVec2()
|
|||||||
local y2 = self._.Polygon[1].y
|
local y2 = self._.Polygon[1].y
|
||||||
|
|
||||||
for i = 2, #self._.Polygon do
|
for i = 2, #self._.Polygon do
|
||||||
self:T2( { self._.Polygon[i], x1, y1, x2, y2 } )
|
--self:T2( { self._.Polygon[i], x1, y1, x2, y2 } )
|
||||||
x1 = ( x1 > self._.Polygon[i].x ) and self._.Polygon[i].x or x1
|
x1 = ( x1 > self._.Polygon[i].x ) and self._.Polygon[i].x or x1
|
||||||
x2 = ( x2 < self._.Polygon[i].x ) and self._.Polygon[i].x or x2
|
x2 = ( x2 < self._.Polygon[i].x ) and self._.Polygon[i].x or x2
|
||||||
y1 = ( y1 > self._.Polygon[i].y ) and self._.Polygon[i].y or y1
|
y1 = ( y1 > self._.Polygon[i].y ) and self._.Polygon[i].y or y1
|
||||||
@@ -2948,7 +2948,7 @@ function ZONE_POLYGON_BASE:Boundary(Coalition, Color, Radius, Alpha, Segments, C
|
|||||||
Limit = #self._.Polygon
|
Limit = #self._.Polygon
|
||||||
end
|
end
|
||||||
while i <= #self._.Polygon do
|
while i <= #self._.Polygon do
|
||||||
self:T( { i, j, self._.Polygon[i], self._.Polygon[j] } )
|
--self:T( { i, j, self._.Polygon[i], self._.Polygon[j] } )
|
||||||
if j ~= Limit then
|
if j ~= Limit then
|
||||||
local DeltaX = self._.Polygon[j].x - self._.Polygon[i].x
|
local DeltaX = self._.Polygon[j].x - self._.Polygon[i].x
|
||||||
local DeltaY = self._.Polygon[j].y - self._.Polygon[i].y
|
local DeltaY = self._.Polygon[j].y - self._.Polygon[i].y
|
||||||
@@ -3019,7 +3019,7 @@ function ZONE_POLYGON:New( ZoneName, ZoneGroup )
|
|||||||
local GroupPoints = ZoneGroup:GetTaskRoute()
|
local GroupPoints = ZoneGroup:GetTaskRoute()
|
||||||
|
|
||||||
local self = BASE:Inherit( self, ZONE_POLYGON_BASE:New( ZoneName, GroupPoints ) )
|
local self = BASE:Inherit( self, ZONE_POLYGON_BASE:New( ZoneName, GroupPoints ) )
|
||||||
self:F( { ZoneName, ZoneGroup, self._.Polygon } )
|
--self:F( { ZoneName, ZoneGroup, self._.Polygon } )
|
||||||
|
|
||||||
-- Zone objects are added to the _DATABASE and SET_ZONE objects.
|
-- Zone objects are added to the _DATABASE and SET_ZONE objects.
|
||||||
_EVENTDISPATCHER:CreateEventNewZone( self )
|
_EVENTDISPATCHER:CreateEventNewZone( self )
|
||||||
@@ -3035,7 +3035,7 @@ end
|
|||||||
function ZONE_POLYGON:NewFromPointsArray( ZoneName, PointsArray )
|
function ZONE_POLYGON:NewFromPointsArray( ZoneName, PointsArray )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, ZONE_POLYGON_BASE:New( ZoneName, PointsArray ) )
|
local self = BASE:Inherit( self, ZONE_POLYGON_BASE:New( ZoneName, PointsArray ) )
|
||||||
self:F( { ZoneName, self._.Polygon } )
|
--self:F( { ZoneName, self._.Polygon } )
|
||||||
|
|
||||||
-- Zone objects are added to the _DATABASE and SET_ZONE objects.
|
-- Zone objects are added to the _DATABASE and SET_ZONE objects.
|
||||||
_EVENTDISPATCHER:CreateEventNewZone( self )
|
_EVENTDISPATCHER:CreateEventNewZone( self )
|
||||||
@@ -3055,7 +3055,7 @@ function ZONE_POLYGON:NewFromGroupName( GroupName )
|
|||||||
local GroupPoints = ZoneGroup:GetTaskRoute()
|
local GroupPoints = ZoneGroup:GetTaskRoute()
|
||||||
|
|
||||||
local self = BASE:Inherit( self, ZONE_POLYGON_BASE:New( GroupName, GroupPoints ) )
|
local self = BASE:Inherit( self, ZONE_POLYGON_BASE:New( GroupName, GroupPoints ) )
|
||||||
self:F( { GroupName, ZoneGroup, self._.Polygon } )
|
--self:F( { GroupName, ZoneGroup, self._.Polygon } )
|
||||||
|
|
||||||
-- Zone objects are added to the _DATABASE and SET_ZONE objects.
|
-- Zone objects are added to the _DATABASE and SET_ZONE objects.
|
||||||
_EVENTDISPATCHER:CreateEventNewZone( self )
|
_EVENTDISPATCHER:CreateEventNewZone( self )
|
||||||
@@ -3221,7 +3221,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
|
|||||||
|
|
||||||
self.ScanData.Units[ZoneObject] = ZoneObject
|
self.ScanData.Units[ZoneObject] = ZoneObject
|
||||||
|
|
||||||
self:F2( { Name = ZoneObject:getName(), Coalition = CoalitionDCSUnit } )
|
--self:F2( { Name = ZoneObject:getName(), Coalition = CoalitionDCSUnit } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -3232,7 +3232,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
|
|||||||
self.ScanData.Scenery[SceneryType] = self.ScanData.Scenery[SceneryType] or {}
|
self.ScanData.Scenery[SceneryType] = self.ScanData.Scenery[SceneryType] or {}
|
||||||
self.ScanData.Scenery[SceneryType][SceneryName] = SCENERY:Register( SceneryName, ZoneObject )
|
self.ScanData.Scenery[SceneryType][SceneryName] = SCENERY:Register( SceneryName, ZoneObject )
|
||||||
table.insert(self.ScanData.SceneryTable,self.ScanData.Scenery[SceneryType][SceneryName])
|
table.insert(self.ScanData.SceneryTable,self.ScanData.Scenery[SceneryType][SceneryName])
|
||||||
self:T( { SCENERY = self.ScanData.Scenery[SceneryType][SceneryName] } )
|
--self:T( { SCENERY = self.ScanData.Scenery[SceneryType][SceneryName] } )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -3573,7 +3573,7 @@ do -- ZONE_ELASTIC
|
|||||||
function ZONE_ELASTIC:Update(Delay, Draw)
|
function ZONE_ELASTIC:Update(Delay, Draw)
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(string.format("Updating ZONE_ELASTIC %s", tostring(self.ZoneName)))
|
--self:T(string.format("Updating ZONE_ELASTIC %s", tostring(self.ZoneName)))
|
||||||
|
|
||||||
-- Copy all points.
|
-- Copy all points.
|
||||||
local points=UTILS.DeepCopy(self.points or {})
|
local points=UTILS.DeepCopy(self.points or {})
|
||||||
@@ -3987,7 +3987,7 @@ do -- ZONE_AIRBASE
|
|||||||
-- @param #ZONE_AIRBASE self
|
-- @param #ZONE_AIRBASE self
|
||||||
-- @return DCS#Vec2 The location of the zone based on the AIRBASE location.
|
-- @return DCS#Vec2 The location of the zone based on the AIRBASE location.
|
||||||
function ZONE_AIRBASE:GetVec2()
|
function ZONE_AIRBASE:GetVec2()
|
||||||
self:F( self.ZoneName )
|
--self:F( self.ZoneName )
|
||||||
|
|
||||||
local ZoneVec2 = nil
|
local ZoneVec2 = nil
|
||||||
|
|
||||||
@@ -3998,7 +3998,7 @@ do -- ZONE_AIRBASE
|
|||||||
ZoneVec2 = self._.ZoneVec2Cache
|
ZoneVec2 = self._.ZoneVec2Cache
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T( { ZoneVec2 } )
|
--self:T( { ZoneVec2 } )
|
||||||
|
|
||||||
return ZoneVec2
|
return ZoneVec2
|
||||||
end
|
end
|
||||||
@@ -4009,11 +4009,11 @@ do -- ZONE_AIRBASE
|
|||||||
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
||||||
-- @return Core.Point#POINT_VEC2 The @{Core.Point#POINT_VEC2} object reflecting the random 3D location within the zone.
|
-- @return Core.Point#POINT_VEC2 The @{Core.Point#POINT_VEC2} object reflecting the random 3D location within the zone.
|
||||||
function ZONE_AIRBASE:GetRandomPointVec2( inner, outer )
|
function ZONE_AIRBASE:GetRandomPointVec2( inner, outer )
|
||||||
self:F( self.ZoneName, inner, outer )
|
--self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
|
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
|
||||||
|
|
||||||
self:T3( { PointVec2 } )
|
--self:T3( { PointVec2 } )
|
||||||
|
|
||||||
return PointVec2
|
return PointVec2
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
--
|
--
|
||||||
-- ====
|
-- ====
|
||||||
-- @module Functional.ClientWatch
|
-- @module Functional.ClientWatch
|
||||||
-- @image ClientWatch.JPG
|
-- @image clientwatch.jpg
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
--- CLIENTWATCH class
|
--- CLIENTWATCH class
|
||||||
@@ -28,6 +28,8 @@
|
|||||||
-- @field #string ClassName Name of the class.
|
-- @field #string ClassName Name of the class.
|
||||||
-- @field #boolean Debug Write Debug messages to DCS log file and send Debug messages to all players.
|
-- @field #boolean Debug Write Debug messages to DCS log file and send Debug messages to all players.
|
||||||
-- @field #string lid String for DCS log file.
|
-- @field #string lid String for DCS log file.
|
||||||
|
-- @field #number FilterCoalition If not nil, will only activate for aircraft of the given coalition value.
|
||||||
|
-- @field #number FilterCategory If not nil, will only activate for aircraft of the given category value.
|
||||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||||
|
|
||||||
--- Manage and track client slots easily to add your own client-based menus and modules to.
|
--- Manage and track client slots easily to add your own client-based menus and modules to.
|
||||||
@@ -66,7 +68,7 @@
|
|||||||
--
|
--
|
||||||
-- -- Create an instance with a client unit prefix and send them a message when they spawn
|
-- -- Create an instance with a client unit prefix and send them a message when they spawn
|
||||||
-- local clientInstance = CLIENTWATCH:New("Rotary")
|
-- local clientInstance = CLIENTWATCH:New("Rotary")
|
||||||
-- function clientInstance:OnAfterSpawn(From,Event,To,ClientObject)
|
-- function clientInstance:OnAfterSpawn(From,Event,To,ClientObject,EventData)
|
||||||
-- MESSAGE:New("Welcome to your aircraft!",10):ToUnit(ClientObject.Unit)
|
-- MESSAGE:New("Welcome to your aircraft!",10):ToUnit(ClientObject.Unit)
|
||||||
-- end
|
-- end
|
||||||
--
|
--
|
||||||
@@ -108,7 +110,7 @@
|
|||||||
--
|
--
|
||||||
-- -- Show a message to player when they take damage from a weapon
|
-- -- Show a message to player when they take damage from a weapon
|
||||||
-- local clientInstance = CLIENTWATCH:New("Rotary")
|
-- local clientInstance = CLIENTWATCH:New("Rotary")
|
||||||
-- function clientInstance:OnAfterSpawn(From,Event,To,ClientObject)
|
-- function clientInstance:OnAfterSpawn(From,Event,To,ClientObject,EventData)
|
||||||
-- function ClientObject:OnAfterHit(From,Event,To,EventData)
|
-- function ClientObject:OnAfterHit(From,Event,To,EventData)
|
||||||
-- local typeShooter = EventData.IniTypeName
|
-- local typeShooter = EventData.IniTypeName
|
||||||
-- local nameWeapon = EventData.weapon_name
|
-- local nameWeapon = EventData.weapon_name
|
||||||
@@ -120,6 +122,7 @@
|
|||||||
CLIENTWATCH = {}
|
CLIENTWATCH = {}
|
||||||
CLIENTWATCH.ClassName = "CLIENTWATCH"
|
CLIENTWATCH.ClassName = "CLIENTWATCH"
|
||||||
CLIENTWATCH.Debug = false
|
CLIENTWATCH.Debug = false
|
||||||
|
CLIENTWATCH.DebugEventData = false
|
||||||
CLIENTWATCH.lid = nil
|
CLIENTWATCH.lid = nil
|
||||||
|
|
||||||
-- @type CLIENTWATCHTools
|
-- @type CLIENTWATCHTools
|
||||||
@@ -139,7 +142,10 @@ CLIENTWATCH.version="1.0.1"
|
|||||||
|
|
||||||
--- Creates a new instance of CLIENTWATCH to add scripts to. Can be used multiple times with the same client/prefixes if you need it for multiple scripts.
|
--- Creates a new instance of CLIENTWATCH to add scripts to. Can be used multiple times with the same client/prefixes if you need it for multiple scripts.
|
||||||
-- @param #CLIENTWATCH self
|
-- @param #CLIENTWATCH self
|
||||||
-- @param #string, #table, or Wrapper.Client#CLIENT client Takes multiple inputs. If provided a #string, it will watch for clients whos UNIT NAME or GROUP NAME matches part of the #string as a prefix. You can also provide it with a #table containing multiple #string prefixes. Lastly, you can provide it with a Wrapper.Client#CLIENT of the specific client you want to apply this to.
|
-- @param #string Will watch for clients whos UNIT NAME or GROUP NAME matches part of the #string as a prefix.
|
||||||
|
-- @param #table Put strings in a table to use multiple prefixes for the above method.
|
||||||
|
-- @param Wrapper.Client#CLIENT Provide a Moose CLIENT object to apply to that specific aircraft slot (static slots only!)
|
||||||
|
-- @param #nil Leave blank to activate for ALL CLIENTS
|
||||||
-- @return #CLIENTWATCH self
|
-- @return #CLIENTWATCH self
|
||||||
function CLIENTWATCH:New(client)
|
function CLIENTWATCH:New(client)
|
||||||
--Init FSM
|
--Init FSM
|
||||||
@@ -147,6 +153,9 @@ function CLIENTWATCH:New(client)
|
|||||||
self:SetStartState( "Idle" )
|
self:SetStartState( "Idle" )
|
||||||
self:AddTransition( "*", "Spawn", "*" )
|
self:AddTransition( "*", "Spawn", "*" )
|
||||||
|
|
||||||
|
self.FilterCoalition = nil
|
||||||
|
self.FilterCategory = nil
|
||||||
|
|
||||||
--- User function for OnAfter "Spawn" event.
|
--- User function for OnAfter "Spawn" event.
|
||||||
-- @function [parent=#CLIENTWATCH] OnAfterSpawn
|
-- @function [parent=#CLIENTWATCH] OnAfterSpawn
|
||||||
-- @param #CLIENTWATCH self
|
-- @param #CLIENTWATCH self
|
||||||
@@ -155,27 +164,50 @@ function CLIENTWATCH:New(client)
|
|||||||
-- @param #string Event Event.
|
-- @param #string Event Event.
|
||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
-- @param #table clientObject Custom object that handles events and stores Moose object data. See top documentation for more details.
|
-- @param #table clientObject Custom object that handles events and stores Moose object data. See top documentation for more details.
|
||||||
|
-- @param #table eventdata Data from EVENTS.Birth.
|
||||||
|
|
||||||
--Set up spawn tracking
|
--Set up spawn tracking
|
||||||
if type(client) == "table" or type(client) == "string" then
|
if not client then
|
||||||
|
if self.Debug then self:I({"New client instance created. ClientType = All clients"}) end
|
||||||
|
self:HandleEvent(EVENTS.Birth)
|
||||||
|
function self:OnEventBirth(eventdata)
|
||||||
|
if (eventdata.IniCategory == 0 or eventdata.IniCategory == 1) and eventdata.IniPlayerName
|
||||||
|
and (not self.FilterCoalition or self.FilterCoalition == eventdata.IniCoalition)
|
||||||
|
and (not self.FilterCategory or self.FilterCategory == eventdata.IniCategory) then
|
||||||
|
if self.Debug then
|
||||||
|
self:I({"Client spawned in.",IniCategory = eventdata.IniCategory})
|
||||||
|
end
|
||||||
|
local clientWatchDebug = self.Debug
|
||||||
|
local clientObject = CLIENTWATCHTools:_newClient(clientWatchDebug,eventdata)
|
||||||
|
self:Spawn(clientObject,eventdata)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif type(client) == "table" or type(client) == "string" then
|
||||||
if type(client) == "table" then
|
if type(client) == "table" then
|
||||||
|
|
||||||
--CLIENT TABLE
|
--CLIENT TABLE
|
||||||
if client.ClassName == "CLIENT" then
|
if client.ClassName == "CLIENT" then
|
||||||
|
if self.Debug then self:I({"New client instance created. ClientType = Wrapper.CLIENT",client}) end
|
||||||
self.ClientName = client:GetName()
|
self.ClientName = client:GetName()
|
||||||
self:HandleEvent(EVENTS.Birth)
|
self:HandleEvent(EVENTS.Birth)
|
||||||
function self:OnEventBirth(eventdata)
|
function self:OnEventBirth(eventdata)
|
||||||
if self.Debug then UTILS.PrintTableToLog(eventdata) end
|
if (eventdata.IniCategory == 0 or eventdata.IniCategory == 1) and eventdata.IniPlayerName
|
||||||
if eventdata.IniCategory and eventdata.IniCategory <= 1 then
|
and (not self.FilterCoalition or self.FilterCoalition == eventdata.IniCoalition)
|
||||||
|
and (not self.FilterCategory or self.FilterCategory == eventdata.IniCategory) then
|
||||||
if self.ClientName == eventdata.IniUnitName then
|
if self.ClientName == eventdata.IniUnitName then
|
||||||
local clientObject = CLIENTWATCHTools:_newClient(eventdata)
|
if self.Debug then
|
||||||
self:Spawn(clientObject)
|
self:I({"Client spawned in.",IniCategory = eventdata.IniCategory})
|
||||||
|
end
|
||||||
|
local clientWatchDebug = self.Debug
|
||||||
|
local clientObject = CLIENTWATCHTools:_newClient(clientWatchDebug,eventdata)
|
||||||
|
self:Spawn(clientObject,eventdata)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--STRING TABLE
|
--STRING TABLE
|
||||||
else
|
else
|
||||||
|
if self.Debug then self:I({"New client instance created. ClientType = Multiple Prefixes",client}) end
|
||||||
local tableValid = true
|
local tableValid = true
|
||||||
for _,entry in pairs(client) do
|
for _,entry in pairs(client) do
|
||||||
if type(entry) ~= "string" then
|
if type(entry) ~= "string" then
|
||||||
@@ -187,12 +219,17 @@ function CLIENTWATCH:New(client)
|
|||||||
if tableValid then
|
if tableValid then
|
||||||
self:HandleEvent(EVENTS.Birth)
|
self:HandleEvent(EVENTS.Birth)
|
||||||
function self:OnEventBirth(eventdata)
|
function self:OnEventBirth(eventdata)
|
||||||
if self.Debug then UTILS.PrintTableToLog(eventdata) end
|
|
||||||
for _,entry in pairs(client) do
|
for _,entry in pairs(client) do
|
||||||
if eventdata.IniCategory and eventdata.IniCategory <= 1 then
|
if (eventdata.IniCategory == 0 or eventdata.IniCategory == 1) and eventdata.IniPlayerName
|
||||||
|
and (not self.FilterCoalition or self.FilterCoalition == eventdata.IniCoalition)
|
||||||
|
and (not self.FilterCategory or self.FilterCategory == eventdata.IniCategory) then
|
||||||
if string.match(eventdata.IniUnitName,entry) or string.match(eventdata.IniGroupName,entry) then
|
if string.match(eventdata.IniUnitName,entry) or string.match(eventdata.IniGroupName,entry) then
|
||||||
local clientObject = CLIENTWATCHTools:_newClient(eventdata)
|
if self.Debug then
|
||||||
self:Spawn(clientObject)
|
self:I({"Client spawned in.",IniCategory = eventdata.IniCategory})
|
||||||
|
end
|
||||||
|
local clientWatchDebug = self.Debug
|
||||||
|
local clientObject = CLIENTWATCHTools:_newClient(clientWatchDebug,eventdata)
|
||||||
|
self:Spawn(clientObject,eventdata)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -201,15 +238,21 @@ function CLIENTWATCH:New(client)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
if self.Debug then self:I({"New client instance created. ClientType = Single Prefix",client}) end
|
||||||
|
|
||||||
--SOLO STRING
|
--SOLO STRING
|
||||||
self:HandleEvent(EVENTS.Birth)
|
self:HandleEvent(EVENTS.Birth)
|
||||||
function self:OnEventBirth(eventdata)
|
function self:OnEventBirth(eventdata)
|
||||||
if self.Debug then UTILS.PrintTableToLog(eventdata) end
|
if (eventdata.IniCategory == 0 or eventdata.IniCategory == 1) and eventdata.IniPlayerName
|
||||||
if eventdata.IniCategory and eventdata.IniCategory <= 1 then
|
and (not self.FilterCoalition or self.FilterCoalition == eventdata.IniCoalition)
|
||||||
|
and (not self.FilterCategory or self.FilterCategory == eventdata.IniCategory) then
|
||||||
if string.match(eventdata.IniUnitName,client) or string.match(eventdata.IniGroupName,client) then
|
if string.match(eventdata.IniUnitName,client) or string.match(eventdata.IniGroupName,client) then
|
||||||
local clientObject = CLIENTWATCHTools:_newClient(eventdata)
|
if self.Debug then
|
||||||
self:Spawn(clientObject)
|
self:I({"Client spawned in.",IniCategory = eventdata.IniCategory})
|
||||||
|
end
|
||||||
|
local clientWatchDebug = self.Debug
|
||||||
|
local clientObject = CLIENTWATCHTools:_newClient(clientWatchDebug,eventdata)
|
||||||
|
self:Spawn(clientObject,eventdata)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -222,13 +265,41 @@ function CLIENTWATCH:New(client)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Filter out all clients not belonging to the provided coalition
|
||||||
|
-- @param #CLIENTWATCH self
|
||||||
|
-- @param #number Coalition number (1 = red, 2 = blue)
|
||||||
|
-- @param #string Coalition string ('red' or 'blue')
|
||||||
|
function CLIENTWATCH:FilterByCoalition(value)
|
||||||
|
if value == 1 or value == "red" then
|
||||||
|
self.FilterCoalition = 1
|
||||||
|
else
|
||||||
|
self.FilterCoalition = 2
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Filter out all clients that are not of the given category
|
||||||
|
-- @param #CLIENTWATCH self
|
||||||
|
-- @param #number Category number (0 = airplane, 1 = helicopter)
|
||||||
|
-- @param #string Category string ('airplane' or 'helicopter')
|
||||||
|
function CLIENTWATCH:FilterByCategory(value)
|
||||||
|
if value == 1 or value == "helicopter" then
|
||||||
|
self.FilterCategory = 1
|
||||||
|
else
|
||||||
|
self.FilterCategory = 0
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Internal function for creating a new client on birth. Do not use!!!.
|
--- Internal function for creating a new client on birth. Do not use!!!.
|
||||||
-- @param #CLIENTWATCHTools self
|
-- @param #CLIENTWATCHTools self
|
||||||
-- @param #EVENTS.Birth EventData
|
-- @param #EVENTS.Birth EventData
|
||||||
-- @return #CLIENTWATCHTools self
|
-- @return #CLIENTWATCHTools self
|
||||||
function CLIENTWATCHTools:_newClient(eventdata)
|
function CLIENTWATCHTools:_newClient(clientWatchDebug,eventdata)
|
||||||
--Init FSM
|
--Init FSM
|
||||||
local self=BASE:Inherit(self, FSM:New())
|
local self=BASE:Inherit(self, FSM:New())
|
||||||
self:SetStartState( "Alive" )
|
self:SetStartState( "Alive" )
|
||||||
@@ -299,78 +370,130 @@ function CLIENTWATCHTools:_newClient(eventdata)
|
|||||||
|
|
||||||
function self:OnEventHit(EventData)
|
function self:OnEventHit(EventData)
|
||||||
if EventData.TgtUnitName == self.UnitName then
|
if EventData.TgtUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered hit event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:Hit(EventData)
|
self:Hit(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventKill(EventData)
|
function self:OnEventKill(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered kill event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:Kill(EventData)
|
self:Kill(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventScore(EventData)
|
function self:OnEventScore(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered score event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:Score(EventData)
|
self:Score(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventShot(EventData)
|
function self:OnEventShot(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered shot event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:Shot(EventData)
|
self:Shot(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventShootingStart(EventData)
|
function self:OnEventShootingStart(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered shooting start event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:ShootingStart(EventData)
|
self:ShootingStart(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventShootingEnd(EventData)
|
function self:OnEventShootingEnd(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered shooting end event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:ShootingEnd(EventData)
|
self:ShootingEnd(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventLand(EventData)
|
function self:OnEventLand(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered land event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:Land(EventData)
|
self:Land(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventTakeoff(EventData)
|
function self:OnEventTakeoff(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered takeoff event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:Takeoff(EventData)
|
self:Takeoff(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventRunwayTakeoff(EventData)
|
function self:OnEventRunwayTakeoff(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered runway takeoff event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:RunwayTakeoff(EventData)
|
self:RunwayTakeoff(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventRunwayTouch(EventData)
|
function self:OnEventRunwayTouch(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered runway touch event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:RunwayTouch(EventData)
|
self:RunwayTouch(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventRefueling(EventData)
|
function self:OnEventRefueling(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered refueling event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:Refueling(EventData)
|
self:Refueling(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventRefuelingStop(EventData)
|
function self:OnEventRefuelingStop(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered refueling event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:RefuelingStop(EventData)
|
self:RefuelingStop(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventPlayerLeaveUnit(EventData)
|
function self:OnEventPlayerLeaveUnit(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered leave unit event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:PlayerLeaveUnit(EventData)
|
self:PlayerLeaveUnit(EventData)
|
||||||
self._deadRoutine()
|
self._deadRoutine()
|
||||||
end
|
end
|
||||||
@@ -378,6 +501,10 @@ function CLIENTWATCHTools:_newClient(eventdata)
|
|||||||
|
|
||||||
function self:OnEventCrash(EventData)
|
function self:OnEventCrash(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered crash event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:Crash(EventData)
|
self:Crash(EventData)
|
||||||
self._deadRoutine()
|
self._deadRoutine()
|
||||||
end
|
end
|
||||||
@@ -385,6 +512,10 @@ function CLIENTWATCHTools:_newClient(eventdata)
|
|||||||
|
|
||||||
function self:OnEventDead(EventData)
|
function self:OnEventDead(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered dead event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:Dead(EventData)
|
self:Dead(EventData)
|
||||||
self._deadRoutine()
|
self._deadRoutine()
|
||||||
end
|
end
|
||||||
@@ -392,6 +523,10 @@ function CLIENTWATCHTools:_newClient(eventdata)
|
|||||||
|
|
||||||
function self:OnEventPilotDead(EventData)
|
function self:OnEventPilotDead(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered pilot dead event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:PilotDead(EventData)
|
self:PilotDead(EventData)
|
||||||
self._deadRoutine()
|
self._deadRoutine()
|
||||||
end
|
end
|
||||||
@@ -399,6 +534,10 @@ function CLIENTWATCHTools:_newClient(eventdata)
|
|||||||
|
|
||||||
function self:OnEventUnitLost(EventData)
|
function self:OnEventUnitLost(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered unit lost event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:UnitLost(EventData)
|
self:UnitLost(EventData)
|
||||||
self._deadRoutine()
|
self._deadRoutine()
|
||||||
end
|
end
|
||||||
@@ -406,6 +545,10 @@ function CLIENTWATCHTools:_newClient(eventdata)
|
|||||||
|
|
||||||
function self:OnEventEjection(EventData)
|
function self:OnEventEjection(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered ejection event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:Ejection(EventData)
|
self:Ejection(EventData)
|
||||||
self._deadRoutine()
|
self._deadRoutine()
|
||||||
end
|
end
|
||||||
@@ -413,6 +556,10 @@ function CLIENTWATCHTools:_newClient(eventdata)
|
|||||||
|
|
||||||
function self:OnEventHumanFailure(EventData)
|
function self:OnEventHumanFailure(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered human failure event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:HumanFailure(EventData)
|
self:HumanFailure(EventData)
|
||||||
if not self.Unit:IsAlive() then
|
if not self.Unit:IsAlive() then
|
||||||
self._deadRoutine()
|
self._deadRoutine()
|
||||||
@@ -422,42 +569,70 @@ function CLIENTWATCHTools:_newClient(eventdata)
|
|||||||
|
|
||||||
function self:OnEventHumanAircraftRepairFinish(EventData)
|
function self:OnEventHumanAircraftRepairFinish(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered repair finished event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:HumanAircraftRepairFinish(EventData)
|
self:HumanAircraftRepairFinish(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventHumanAircraftRepairStart(EventData)
|
function self:OnEventHumanAircraftRepairStart(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered repair start event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:HumanAircraftRepairStart(EventData)
|
self:HumanAircraftRepairStart(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventEngineShutdown(EventData)
|
function self:OnEventEngineShutdown(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered engine shutdown event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:EngineShutdown(EventData)
|
self:EngineShutdown(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventEngineStartup(EventData)
|
function self:OnEventEngineStartup(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered engine startup event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:EngineStartup(EventData)
|
self:EngineStartup(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventWeaponAdd(EventData)
|
function self:OnEventWeaponAdd(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered weapon add event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:WeaponAdd(EventData)
|
self:WeaponAdd(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventWeaponDrop(EventData)
|
function self:OnEventWeaponDrop(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered weapon drop event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:WeaponDrop(EventData)
|
self:WeaponDrop(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:OnEventWeaponRearm(EventData)
|
function self:OnEventWeaponRearm(EventData)
|
||||||
if EventData.IniUnitName == self.UnitName then
|
if EventData.IniUnitName == self.UnitName then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client triggered weapon rearm event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
|
||||||
|
end
|
||||||
self:WeaponRearm(EventData)
|
self:WeaponRearm(EventData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -466,6 +641,9 @@ function CLIENTWATCHTools:_newClient(eventdata)
|
|||||||
--Fallback timer
|
--Fallback timer
|
||||||
self.FallbackTimer = TIMER:New(function()
|
self.FallbackTimer = TIMER:New(function()
|
||||||
if not self.Unit:IsAlive() then
|
if not self.Unit:IsAlive() then
|
||||||
|
if clientWatchDebug then
|
||||||
|
self:I({"Client is registered as dead without an event trigger. Running fallback dead routine.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
|
||||||
|
end
|
||||||
self._deadRoutine()
|
self._deadRoutine()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
@@ -473,6 +651,7 @@ function CLIENTWATCHTools:_newClient(eventdata)
|
|||||||
|
|
||||||
--Stop event handlers and trigger Despawn
|
--Stop event handlers and trigger Despawn
|
||||||
function self._deadRoutine()
|
function self._deadRoutine()
|
||||||
|
if clientWatchDebug then self:I({"Client dead routine triggered. Shutting down tracking...",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName}) end
|
||||||
self:UnHandleEvent( EVENTS.Hit )
|
self:UnHandleEvent( EVENTS.Hit )
|
||||||
self:UnHandleEvent( EVENTS.Kill )
|
self:UnHandleEvent( EVENTS.Kill )
|
||||||
self:UnHandleEvent( EVENTS.Score )
|
self:UnHandleEvent( EVENTS.Score )
|
||||||
@@ -503,6 +682,6 @@ function CLIENTWATCHTools:_newClient(eventdata)
|
|||||||
self:Despawn()
|
self:Despawn()
|
||||||
end
|
end
|
||||||
|
|
||||||
self:I({"CLIENT SPAWN EVENT", PlayerName = self.PlayerName, UnitName = self.UnitName, GroupName = self.GroupName})
|
self:I({"Detected client spawn and applied internal functions and events.", PlayerName = self.PlayerName, UnitName = self.UnitName, GroupName = self.GroupName})
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -596,6 +596,7 @@ do -- DETECTION_BASE
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---
|
||||||
-- @param #DETECTION_BASE self
|
-- @param #DETECTION_BASE self
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
@@ -615,7 +616,7 @@ do -- DETECTION_BASE
|
|||||||
self:T( { "DetectionGroup is Alive", Detection:GetName() } )
|
self:T( { "DetectionGroup is Alive", Detection:GetName() } )
|
||||||
|
|
||||||
local DetectionGroupName = Detection:GetName()
|
local DetectionGroupName = Detection:GetName()
|
||||||
local DetectionUnit = Detection:GetUnit( 1 )
|
local DetectionUnit = Detection:GetFirstUnitAlive()
|
||||||
|
|
||||||
local DetectedUnits = {}
|
local DetectedUnits = {}
|
||||||
|
|
||||||
@@ -632,7 +633,7 @@ do -- DETECTION_BASE
|
|||||||
--self:T(UTILS.PrintTableToLog(DetectedTargets))
|
--self:T(UTILS.PrintTableToLog(DetectedTargets))
|
||||||
|
|
||||||
|
|
||||||
for DetectionObjectID, Detection in pairs( DetectedTargets ) do
|
for DetectionObjectID, Detection in pairs( DetectedTargets or {}) do
|
||||||
local DetectedObject = Detection.object -- DCS#Object
|
local DetectedObject = Detection.object -- DCS#Object
|
||||||
|
|
||||||
if DetectedObject and DetectedObject:isExist() and DetectedObject.id_ < 50000000 then -- and ( DetectedObject:getCategory() == Object.Category.UNIT or DetectedObject:getCategory() == Object.Category.STATIC ) then
|
if DetectedObject and DetectedObject:isExist() and DetectedObject.id_ < 50000000 then -- and ( DetectedObject:getCategory() == Object.Category.UNIT or DetectedObject:getCategory() == Object.Category.STATIC ) then
|
||||||
@@ -645,7 +646,7 @@ do -- DETECTION_BASE
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for DetectionObjectName, DetectedObjectData in pairs( self.DetectedObjects ) do
|
for DetectionObjectName, DetectedObjectData in pairs( self.DetectedObjects or {}) do
|
||||||
|
|
||||||
local DetectedObject = DetectedObjectData.Object
|
local DetectedObject = DetectedObjectData.Object
|
||||||
|
|
||||||
|
|||||||
@@ -1340,7 +1340,7 @@ end
|
|||||||
-- @return #RANGE self
|
-- @return #RANGE self
|
||||||
function RANGE:SetSoundfilesPath( path )
|
function RANGE:SetSoundfilesPath( path )
|
||||||
self.soundpath = tostring( path or "Range Soundfiles/" )
|
self.soundpath = tostring( path or "Range Soundfiles/" )
|
||||||
self:I( self.lid .. string.format( "Setting sound files path to %s", self.soundpath ) )
|
self:T2( self.lid .. string.format( "Setting sound files path to %s", self.soundpath ) )
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1636,9 +1636,9 @@ function RANGE:AddBombingTargetUnit( unit, goodhitrange, randommove )
|
|||||||
|
|
||||||
-- Debug or error output.
|
-- Debug or error output.
|
||||||
if _isstatic == true then
|
if _isstatic == true then
|
||||||
self:I( self.lid .. string.format( "Adding STATIC bombing target %s with good hit range %d. Random move = %s.", name, goodhitrange, tostring( randommove ) ) )
|
self:T( self.lid .. string.format( "Adding STATIC bombing target %s with good hit range %d. Random move = %s.", name, goodhitrange, tostring( randommove ) ) )
|
||||||
elseif _isstatic == false then
|
elseif _isstatic == false then
|
||||||
self:I( self.lid .. string.format( "Adding UNIT bombing target %s with good hit range %d. Random move = %s.", name, goodhitrange, tostring( randommove ) ) )
|
self:T( self.lid .. string.format( "Adding UNIT bombing target %s with good hit range %d. Random move = %s.", name, goodhitrange, tostring( randommove ) ) )
|
||||||
else
|
else
|
||||||
self:E( self.lid .. string.format( "ERROR! No bombing target with name %s could be found. Carefully check all UNIT and STATIC names defined in the mission editor!", name ) )
|
self:E( self.lid .. string.format( "ERROR! No bombing target with name %s could be found. Carefully check all UNIT and STATIC names defined in the mission editor!", name ) )
|
||||||
end
|
end
|
||||||
@@ -1706,7 +1706,7 @@ function RANGE:AddBombingTargetScenery( scenery, goodhitrange)
|
|||||||
|
|
||||||
-- Debug or error output.
|
-- Debug or error output.
|
||||||
if name then
|
if name then
|
||||||
self:I( self.lid .. string.format( "Adding SCENERY bombing target %s with good hit range %d", name, goodhitrange) )
|
self:T( self.lid .. string.format( "Adding SCENERY bombing target %s with good hit range %d", name, goodhitrange) )
|
||||||
else
|
else
|
||||||
self:E( self.lid .. string.format( "ERROR! No bombing target with name %s could be found!", name ) )
|
self:E( self.lid .. string.format( "ERROR! No bombing target with name %s could be found!", name ) )
|
||||||
end
|
end
|
||||||
@@ -1811,7 +1811,7 @@ function RANGE:OnEventBirth( EventData )
|
|||||||
if not EventData.IniPlayerName then return end
|
if not EventData.IniPlayerName then return end
|
||||||
|
|
||||||
local _unitName = EventData.IniUnitName
|
local _unitName = EventData.IniUnitName
|
||||||
local _unit, _playername = self:_GetPlayerUnitAndName( _unitName )
|
local _unit, _playername = self:_GetPlayerUnitAndName( _unitName, EventData.IniPlayerName )
|
||||||
|
|
||||||
self:T3( self.lid .. "BIRTH: unit = " .. tostring( EventData.IniUnitName ) )
|
self:T3( self.lid .. "BIRTH: unit = " .. tostring( EventData.IniUnitName ) )
|
||||||
self:T3( self.lid .. "BIRTH: group = " .. tostring( EventData.IniGroupName ) )
|
self:T3( self.lid .. "BIRTH: group = " .. tostring( EventData.IniGroupName ) )
|
||||||
@@ -1968,6 +1968,8 @@ end
|
|||||||
-- @param #number attackVel Attack velocity.
|
-- @param #number attackVel Attack velocity.
|
||||||
function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackVel)
|
function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackVel)
|
||||||
|
|
||||||
|
if not playerData then return end
|
||||||
|
|
||||||
-- Get closet target to last position.
|
-- Get closet target to last position.
|
||||||
local _closetTarget = nil -- #RANGE.BombTarget
|
local _closetTarget = nil -- #RANGE.BombTarget
|
||||||
local _distance = nil
|
local _distance = nil
|
||||||
@@ -1984,13 +1986,13 @@ function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackV
|
|||||||
-- Coordinate of impact point.
|
-- Coordinate of impact point.
|
||||||
local impactcoord = weapon:GetImpactCoordinate()
|
local impactcoord = weapon:GetImpactCoordinate()
|
||||||
|
|
||||||
-- Check if impact happened in range zone.
|
-- Check if impact happened in range zone.+
|
||||||
local insidezone = self.rangezone:IsCoordinateInZone( impactcoord )
|
local insidezone = self.rangezone:IsCoordinateInZone( impactcoord )
|
||||||
|
|
||||||
|
|
||||||
-- Smoke impact point of bomb.
|
-- Smoke impact point of bomb.
|
||||||
if playerData.smokebombimpact and insidezone then
|
if playerData and playerData.smokebombimpact and insidezone then
|
||||||
if playerData.delaysmoke then
|
if playerData and playerData.delaysmoke then
|
||||||
timer.scheduleFunction( self._DelayedSmoke, { coord = impactcoord, color = playerData.smokecolor }, timer.getTime() + self.TdelaySmoke )
|
timer.scheduleFunction( self._DelayedSmoke, { coord = impactcoord, color = playerData.smokecolor }, timer.getTime() + self.TdelaySmoke )
|
||||||
else
|
else
|
||||||
impactcoord:Smoke( playerData.smokecolor )
|
impactcoord:Smoke( playerData.smokecolor )
|
||||||
@@ -2115,7 +2117,7 @@ function RANGE:OnEventShot( EventData )
|
|||||||
local _unitName = EventData.IniUnitName
|
local _unitName = EventData.IniUnitName
|
||||||
|
|
||||||
-- Get player unit and name.
|
-- Get player unit and name.
|
||||||
local _unit, _playername = self:_GetPlayerUnitAndName( _unitName )
|
local _unit, _playername = self:_GetPlayerUnitAndName( _unitName, EventData.IniPlayerName )
|
||||||
|
|
||||||
-- Distance Player-to-Range. Set this to larger value than the threshold.
|
-- Distance Player-to-Range. Set this to larger value than the threshold.
|
||||||
local dPR = self.BombtrackThreshold * 2
|
local dPR = self.BombtrackThreshold * 2
|
||||||
@@ -2127,11 +2129,13 @@ function RANGE:OnEventShot( EventData )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Only track if distance player to range is < 25 km. Also check that a player shot. No need to track AI weapons.
|
-- Only track if distance player to range is < 25 km. Also check that a player shot. No need to track AI weapons.
|
||||||
if _track and dPR <= self.BombtrackThreshold and _unit and _playername then
|
if _track and dPR <= self.BombtrackThreshold and _unit and _playername and self.PlayerSettings[_playername] then
|
||||||
|
|
||||||
-- Player data.
|
-- Player data.
|
||||||
local playerData = self.PlayerSettings[_playername] -- #RANGE.PlayerData
|
local playerData = self.PlayerSettings[_playername] -- #RANGE.PlayerData
|
||||||
|
|
||||||
|
if not playerData then return end
|
||||||
|
|
||||||
-- Attack parameters.
|
-- Attack parameters.
|
||||||
local attackHdg=_unit:GetHeading()
|
local attackHdg=_unit:GetHeading()
|
||||||
local attackAlt=_unit:GetHeight()
|
local attackAlt=_unit:GetHeight()
|
||||||
@@ -2192,7 +2196,7 @@ function RANGE:onafterStatus( From, Event, To )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Check range status.
|
-- Check range status.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2393,7 +2397,7 @@ function RANGE:onafterSave( From, Event, To )
|
|||||||
if f then
|
if f then
|
||||||
f:write( data )
|
f:write( data )
|
||||||
f:close()
|
f:close()
|
||||||
self:I( self.lid .. string.format( "Saving player results to file %s", tostring( filename ) ) )
|
self:T( self.lid .. string.format( "Saving player results to file %s", tostring( filename ) ) )
|
||||||
else
|
else
|
||||||
self:E( self.lid .. string.format( "ERROR: Could not save results to file %s", tostring( filename ) ) )
|
self:E( self.lid .. string.format( "ERROR: Could not save results to file %s", tostring( filename ) ) )
|
||||||
end
|
end
|
||||||
@@ -2472,7 +2476,7 @@ function RANGE:onafterLoad( From, Event, To )
|
|||||||
|
|
||||||
-- Info message.
|
-- Info message.
|
||||||
local text = string.format( "Loading player bomb results from file %s", filename )
|
local text = string.format( "Loading player bomb results from file %s", filename )
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
-- Load asset data from file.
|
-- Load asset data from file.
|
||||||
local data = _loadfile( filename )
|
local data = _loadfile( filename )
|
||||||
@@ -2845,7 +2849,7 @@ function RANGE:_DisplayRangeInfo( _unitname )
|
|||||||
|
|
||||||
-- Check if we have a player.
|
-- Check if we have a player.
|
||||||
if unit and playername then
|
if unit and playername then
|
||||||
self:I(playername)
|
--self:I(playername)
|
||||||
-- Message text.
|
-- Message text.
|
||||||
local text = ""
|
local text = ""
|
||||||
|
|
||||||
@@ -4099,8 +4103,8 @@ end
|
|||||||
-- @return Wrapper.Unit#UNIT Unit of player.
|
-- @return Wrapper.Unit#UNIT Unit of player.
|
||||||
-- @return #string Name of the player.
|
-- @return #string Name of the player.
|
||||||
-- @return #boolean If true, group has > 1 player in it
|
-- @return #boolean If true, group has > 1 player in it
|
||||||
function RANGE:_GetPlayerUnitAndName( _unitName )
|
function RANGE:_GetPlayerUnitAndName( _unitName, PlayerName )
|
||||||
self:F2( _unitName )
|
--self:I( _unitName )
|
||||||
|
|
||||||
if _unitName ~= nil then
|
if _unitName ~= nil then
|
||||||
|
|
||||||
@@ -4109,9 +4113,9 @@ function RANGE:_GetPlayerUnitAndName( _unitName )
|
|||||||
-- Get DCS unit from its name.
|
-- Get DCS unit from its name.
|
||||||
local DCSunit = Unit.getByName( _unitName )
|
local DCSunit = Unit.getByName( _unitName )
|
||||||
|
|
||||||
if DCSunit then
|
if DCSunit and DCSunit.getPlayerName then
|
||||||
|
|
||||||
local playername = DCSunit:getPlayerName()
|
local playername = DCSunit:getPlayerName() or PlayerName or "None"
|
||||||
local unit = UNIT:Find( DCSunit )
|
local unit = UNIT:Find( DCSunit )
|
||||||
|
|
||||||
self:T2( { DCSunit = DCSunit, unit = unit, playername = playername } )
|
self:T2( { DCSunit = DCSunit, unit = unit, playername = playername } )
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6732,7 +6732,7 @@ end
|
|||||||
-- @param Wrapper.Group#GROUP deadgroup Group of unit that died.
|
-- @param Wrapper.Group#GROUP deadgroup Group of unit that died.
|
||||||
-- @param #WAREHOUSE.Pendingitem request Request that needs to be updated.
|
-- @param #WAREHOUSE.Pendingitem request Request that needs to be updated.
|
||||||
function WAREHOUSE:_UnitDead(deadunit, deadgroup, request)
|
function WAREHOUSE:_UnitDead(deadunit, deadgroup, request)
|
||||||
self:F(self.lid.."FF unit dead "..deadunit:GetName())
|
--self:F(self.lid.."FF unit dead "..deadunit:GetName())
|
||||||
|
|
||||||
-- Find opsgroup.
|
-- Find opsgroup.
|
||||||
local opsgroup=_DATABASE:FindOpsGroup(deadgroup)
|
local opsgroup=_DATABASE:FindOpsGroup(deadgroup)
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Marker.lua' )
|
|||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Weapon.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Weapon.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Net.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Net.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Storage.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Storage.lua' )
|
||||||
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/DynamicCargo.lua' )
|
||||||
|
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Cargo/Cargo.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Cargo/Cargo.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Cargo/CargoUnit.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Cargo/CargoUnit.lua' )
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ __Moose.Include( 'Wrapper\\Marker.lua' )
|
|||||||
__Moose.Include( 'Wrapper\\Net.lua' )
|
__Moose.Include( 'Wrapper\\Net.lua' )
|
||||||
__Moose.Include( 'Wrapper\\Weapon.lua' )
|
__Moose.Include( 'Wrapper\\Weapon.lua' )
|
||||||
__Moose.Include( 'Wrapper\\Storage.lua' )
|
__Moose.Include( 'Wrapper\\Storage.lua' )
|
||||||
|
__Moose.Include( 'Wrapper\\DynamicCargo.lua' )
|
||||||
|
|
||||||
__Moose.Include( 'Cargo\\Cargo.lua' )
|
__Moose.Include( 'Cargo\\Cargo.lua' )
|
||||||
__Moose.Include( 'Cargo\\CargoUnit.lua' )
|
__Moose.Include( 'Cargo\\CargoUnit.lua' )
|
||||||
@@ -81,6 +82,7 @@ __Moose.Include( 'Functional\\AICSAR.lua' )
|
|||||||
__Moose.Include( 'Functional\\AmmoTruck.lua' )
|
__Moose.Include( 'Functional\\AmmoTruck.lua' )
|
||||||
__Moose.Include( 'Functional\\Tiresias.lua' )
|
__Moose.Include( 'Functional\\Tiresias.lua' )
|
||||||
__Moose.Include( 'Functional\\Stratego.lua' )
|
__Moose.Include( 'Functional\\Stratego.lua' )
|
||||||
|
__Moose.Include( 'Functional\\ClientWatch.lua' )
|
||||||
|
|
||||||
__Moose.Include( 'Ops\\Airboss.lua' )
|
__Moose.Include( 'Ops\\Airboss.lua' )
|
||||||
__Moose.Include( 'Ops\\RecoveryTanker.lua' )
|
__Moose.Include( 'Ops\\RecoveryTanker.lua' )
|
||||||
|
|||||||
@@ -882,6 +882,66 @@ ATIS.Messages = {
|
|||||||
FARP = "Farp",
|
FARP = "Farp",
|
||||||
DELIMITER = "Punto", -- decimal delimiter
|
DELIMITER = "Punto", -- decimal delimiter
|
||||||
},
|
},
|
||||||
|
-- French messages thanks to @Wojtech and Bing
|
||||||
|
FR = {
|
||||||
|
HOURS = "Heures",
|
||||||
|
TIME = "Temps",
|
||||||
|
NOCLOUDINFO = "Informations sur la couverture nuageuse non disponibles",
|
||||||
|
OVERCAST = "Ciel couvert",
|
||||||
|
BROKEN = "Nuages fragmentés",
|
||||||
|
SCATTERED = "Nuages épars",
|
||||||
|
FEWCLOUDS = "Nuages rares",
|
||||||
|
NOCLOUDS = "Clair",
|
||||||
|
AIRPORT = "Aéroport",
|
||||||
|
INFORMATION ="Information",
|
||||||
|
SUNRISEAT = "Levé du soleil à %s heure locale",
|
||||||
|
SUNSETAT = "Couché du soleil à %s heure locale",
|
||||||
|
WINDFROMMS = "Vent du %s pour %s mètres par seconde",
|
||||||
|
WINDFROMKNOTS = "Vent du %s pour %s noeuds",
|
||||||
|
GUSTING = "Rafale de vent",
|
||||||
|
VISIKM = "Visibilité %s kilomètres",
|
||||||
|
VISISM = "Visibilité %s Miles",
|
||||||
|
RAIN = "Pluie",
|
||||||
|
TSTORM = "Orage",
|
||||||
|
SNOW = "Neige",
|
||||||
|
SSTROM = "Tempête de neige",
|
||||||
|
FOG = "Brouillard",
|
||||||
|
DUST = "Poussière",
|
||||||
|
PHENOMENA = "Phénomène météorologique",
|
||||||
|
CLOUDBASEM = "Couverture nuageuse de %s à %s mètres",
|
||||||
|
CLOUDBASEFT = "Couverture nuageuse de %s à %s pieds",
|
||||||
|
TEMPERATURE = "Température",
|
||||||
|
DEWPOINT = "Point de rosée",
|
||||||
|
ALTIMETER = "Altimètre",
|
||||||
|
ACTIVERUN = "Décollages piste",
|
||||||
|
ACTIVELANDING = "Atterrissages piste",
|
||||||
|
LEFT = "Gauche",
|
||||||
|
RIGHT = "Droite",
|
||||||
|
RWYLENGTH = "Longueur de piste",
|
||||||
|
METERS = "Mètre",
|
||||||
|
FEET = "Pieds",
|
||||||
|
ELEVATION = "Hauteur",
|
||||||
|
TOWERFREQ = "Fréquences de la tour",
|
||||||
|
ILSFREQ = "Fréquences ILS",
|
||||||
|
OUTERNDB = "Fréquences Outer NDB",
|
||||||
|
INNERNDB = "Fréquences Inner NDB",
|
||||||
|
VORFREQ = "Fréquences VOR",
|
||||||
|
VORFREQTTS = "Fréquences V O R",
|
||||||
|
TACANCH = "Canal TACAN %d",
|
||||||
|
RSBNCH = "Canal RSBN",
|
||||||
|
PRMGCH = "Canal PRMG",
|
||||||
|
ADVISE = "Informez le contrôle que vous avez copié l'information",
|
||||||
|
STATUTE = "Statute Miles",
|
||||||
|
DEGREES = "Degré celcius",
|
||||||
|
FAHRENHEIT = "Degré Fahrenheit",
|
||||||
|
INCHHG = "Pouces de mercure",
|
||||||
|
MMHG = "Millimètres de mercure",
|
||||||
|
HECTO = "Hectopascals",
|
||||||
|
METERSPER = "Mètres par seconde",
|
||||||
|
TACAN = "TAKAN",
|
||||||
|
FARP = "FARPE",
|
||||||
|
DELIMITER = "Décimal", -- decimal delimiter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -1061,7 +1121,7 @@ end
|
|||||||
-- @return #ATIS self
|
-- @return #ATIS self
|
||||||
function ATIS:_InitLocalization()
|
function ATIS:_InitLocalization()
|
||||||
self:T(self.lid.."_InitLocalization")
|
self:T(self.lid.."_InitLocalization")
|
||||||
self.gettext = TEXTANDSOUND:New("AWACS","en") -- Core.TextAndSound#TEXTANDSOUND
|
self.gettext = TEXTANDSOUND:New("ATIS","en") -- Core.TextAndSound#TEXTANDSOUND
|
||||||
self.locale = "en"
|
self.locale = "en"
|
||||||
for locale,table in pairs(self.Messages) do
|
for locale,table in pairs(self.Messages) do
|
||||||
local Locale = string.lower(tostring(locale))
|
local Locale = string.lower(tostring(locale))
|
||||||
@@ -1975,18 +2035,26 @@ function ATIS:onafterBroadcast( From, Event, To )
|
|||||||
|
|
||||||
local hours = self.gettext:GetEntry("HOURS",self.locale)
|
local hours = self.gettext:GetEntry("HOURS",self.locale)
|
||||||
local sunrise = coord:GetSunrise()
|
local sunrise = coord:GetSunrise()
|
||||||
|
--self:I(sunrise)
|
||||||
|
local SUNRISE = "no time"
|
||||||
|
if tostring(sunrise) ~= "N/S" and tostring(sunrise) ~= "N/R" then
|
||||||
sunrise = UTILS.Split( sunrise, ":" )
|
sunrise = UTILS.Split( sunrise, ":" )
|
||||||
local SUNRISE = string.format( "%s%s", sunrise[1], sunrise[2] )
|
SUNRISE = string.format( "%s%s", sunrise[1], sunrise[2] )
|
||||||
if self.useSRS then
|
if self.useSRS then
|
||||||
SUNRISE = string.format( "%s %s %s", sunrise[1], sunrise[2], hours )
|
SUNRISE = string.format( "%s %s %s", sunrise[1], sunrise[2], hours )
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local sunset = coord:GetSunset()
|
local sunset = coord:GetSunset()
|
||||||
|
--self:I(sunset)
|
||||||
|
local SUNSET = "no time"
|
||||||
|
if tostring(sunset) ~= "N/S" and tostring(sunset) ~= "N/R" then
|
||||||
sunset = UTILS.Split( sunset, ":" )
|
sunset = UTILS.Split( sunset, ":" )
|
||||||
local SUNSET = string.format( "%s%s", sunset[1], sunset[2] )
|
SUNSET = string.format( "%s%s", sunset[1], sunset[2] )
|
||||||
if self.useSRS then
|
if self.useSRS then
|
||||||
SUNSET = string.format( "%s %s %s", sunset[1], sunset[2], hours )
|
SUNSET = string.format( "%s %s %s", sunset[1], sunset[2], hours )
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---------------------------------
|
---------------------------------
|
||||||
--- Temperature and Dew Point ---
|
--- Temperature and Dew Point ---
|
||||||
@@ -2100,6 +2168,39 @@ function ATIS:onafterBroadcast( From, Event, To )
|
|||||||
else
|
else
|
||||||
precepitation = 3 -- snow
|
precepitation = 3 -- snow
|
||||||
end
|
end
|
||||||
|
elseif cloudspreset:find( "RainyPreset4" ) then
|
||||||
|
-- Overcast + Rain
|
||||||
|
clouddens = 5
|
||||||
|
if temperature > 5 then
|
||||||
|
precepitation = 1 -- rain
|
||||||
|
else
|
||||||
|
precepitation = 3 -- snow
|
||||||
|
end
|
||||||
|
elseif cloudspreset:find( "RainyPreset5" ) then
|
||||||
|
-- Overcast + Rain
|
||||||
|
clouddens = 5
|
||||||
|
if temperature > 5 then
|
||||||
|
precepitation = 1 -- rain
|
||||||
|
else
|
||||||
|
precepitation = 3 -- snow
|
||||||
|
end
|
||||||
|
elseif cloudspreset:find( "RainyPreset6" ) then
|
||||||
|
-- Overcast + Rain
|
||||||
|
clouddens = 5
|
||||||
|
if temperature > 5 then
|
||||||
|
precepitation = 1 -- rain
|
||||||
|
else
|
||||||
|
precepitation = 3 -- snow
|
||||||
|
end
|
||||||
|
-- NEWRAINPRESET4
|
||||||
|
elseif cloudspreset:find( "NEWRAINPRESET4" ) then
|
||||||
|
-- Overcast + Rain
|
||||||
|
clouddens = 5
|
||||||
|
if temperature > 5 then
|
||||||
|
precepitation = 1 -- rain
|
||||||
|
else
|
||||||
|
precepitation = 3 -- snow
|
||||||
|
end
|
||||||
elseif cloudspreset:find( "RainyPreset" ) then
|
elseif cloudspreset:find( "RainyPreset" ) then
|
||||||
-- Overcast + Rain
|
-- Overcast + Rain
|
||||||
clouddens = 9
|
clouddens = 9
|
||||||
|
|||||||
@@ -14680,7 +14680,7 @@ function AIRBOSS:_GetPlayerUnitAndName( _unitName )
|
|||||||
-- Get DCS unit from its name.
|
-- Get DCS unit from its name.
|
||||||
local DCSunit = Unit.getByName( _unitName )
|
local DCSunit = Unit.getByName( _unitName )
|
||||||
|
|
||||||
if DCSunit then
|
if DCSunit and DCSunit.getPlayerName then
|
||||||
|
|
||||||
-- Get player name if any.
|
-- Get player name if any.
|
||||||
local playername = DCSunit:getPlayerName()
|
local playername = DCSunit:getPlayerName()
|
||||||
@@ -15651,7 +15651,7 @@ function AIRBOSS:_Number2Sound( playerData, sender, number, delay )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Split string into characters.
|
-- Split string into characters.
|
||||||
local numbers = _split( number )
|
local numbers = _split( tostring(number) )
|
||||||
|
|
||||||
local wait = 0
|
local wait = 0
|
||||||
for i = 1, #numbers do
|
for i = 1, #numbers do
|
||||||
@@ -15719,7 +15719,7 @@ function AIRBOSS:_Number2Radio( radio, number, delay, interval, pilotcall )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Split string into characters.
|
-- Split string into characters.
|
||||||
local numbers = _split( number )
|
local numbers = _split( tostring(number) )
|
||||||
|
|
||||||
local wait = 0
|
local wait = 0
|
||||||
for i = 1, #numbers do
|
for i = 1, #numbers do
|
||||||
@@ -18087,7 +18087,7 @@ function AIRBOSS:_MarkCaseZones( _unitName, flare )
|
|||||||
self:_GetZoneArcIn( case ):FlareZone( FLARECOLOR.White, 45 )
|
self:_GetZoneArcIn( case ):FlareZone( FLARECOLOR.White, 45 )
|
||||||
text = text .. "\n* arc turn in with WHITE flares"
|
text = text .. "\n* arc turn in with WHITE flares"
|
||||||
self:_GetZoneArcOut( case ):FlareZone( FLARECOLOR.White, 45 )
|
self:_GetZoneArcOut( case ):FlareZone( FLARECOLOR.White, 45 )
|
||||||
text = text .. "\n* arc trun out with WHITE flares"
|
text = text .. "\n* arc turn out with WHITE flares"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -18139,7 +18139,7 @@ function AIRBOSS:_MarkCaseZones( _unitName, flare )
|
|||||||
self:_GetZoneArcIn( case ):SmokeZone( SMOKECOLOR.Blue, 45 )
|
self:_GetZoneArcIn( case ):SmokeZone( SMOKECOLOR.Blue, 45 )
|
||||||
text = text .. "\n* arc turn in with BLUE smoke"
|
text = text .. "\n* arc turn in with BLUE smoke"
|
||||||
self:_GetZoneArcOut( case ):SmokeZone( SMOKECOLOR.Blue, 45 )
|
self:_GetZoneArcOut( case ):SmokeZone( SMOKECOLOR.Blue, 45 )
|
||||||
text = text .. "\n* arc trun out with BLUE smoke"
|
text = text .. "\n* arc turn out with BLUE smoke"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
-- @image OPS_CSAR.jpg
|
-- @image OPS_CSAR.jpg
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Last Update July 2024
|
-- Last Update Sep 2024
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
-- @field #string lid Class id string for output to DCS log file.
|
-- @field #string lid Class id string for output to DCS log file.
|
||||||
-- @field #number coalition Coalition side number, e.g. `coalition.side.RED`.
|
-- @field #number coalition Coalition side number, e.g. `coalition.side.RED`.
|
||||||
-- @field Core.Set#SET_GROUP allheligroupset Set of CSAR heli groups.
|
-- @field Core.Set#SET_GROUP allheligroupset Set of CSAR heli groups.
|
||||||
|
-- @field Core.Set#SET_GROUP UserSetGroup Set of CSAR heli groups as designed by the mission designer (if any set).
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
--- *Combat search and rescue (CSAR) are search and rescue operations that are carried out during war that are within or near combat zones.* (Wikipedia)
|
--- *Combat search and rescue (CSAR) are search and rescue operations that are carried out during war that are within or near combat zones.* (Wikipedia)
|
||||||
@@ -116,8 +117,17 @@
|
|||||||
-- mycsar.topmenuname = "CSAR" -- set the menu entry name
|
-- mycsar.topmenuname = "CSAR" -- set the menu entry name
|
||||||
-- mycsar.ADFRadioPwr = 1000 -- ADF Beacons sending with 1KW as default
|
-- mycsar.ADFRadioPwr = 1000 -- ADF Beacons sending with 1KW as default
|
||||||
-- mycsar.PilotWeight = 80 -- Loaded pilots weigh 80kgs each
|
-- mycsar.PilotWeight = 80 -- Loaded pilots weigh 80kgs each
|
||||||
|
-- mycsar.AllowIRStrobe = false -- Allow a menu item to request an IR strobe to find a downed pilot at night (requires NVGs to see it).
|
||||||
|
-- mycsar.IRStrobeRuntime = 300 -- If an IR Strobe is activated, it runs for 300 seconds (5 mins).
|
||||||
--
|
--
|
||||||
-- ## 2.1 SRS Features and Other Features
|
-- ## 2.1 Create own SET_GROUP to manage CTLD Pilot groups
|
||||||
|
--
|
||||||
|
-- -- Parameter: Set The SET_GROUP object created by the mission designer/user to represent the CSAR pilot groups.
|
||||||
|
-- -- Needs to be set before starting the CSAR instance.
|
||||||
|
-- local myset = SET_GROUP:New():FilterPrefixes("Helikopter"):FilterCoalitions("red"):FilterStart()
|
||||||
|
-- mycsar:SetOwnSetPilotGroups(myset)
|
||||||
|
--
|
||||||
|
-- ## 2.2 SRS Features and Other Features
|
||||||
--
|
--
|
||||||
-- mycsar.useSRS = false -- Set true to use FF\'s SRS integration
|
-- mycsar.useSRS = false -- Set true to use FF\'s SRS integration
|
||||||
-- mycsar.SRSPath = "C:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your SRS installation -- server(!)
|
-- mycsar.SRSPath = "C:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your SRS installation -- server(!)
|
||||||
@@ -136,6 +146,7 @@
|
|||||||
-- mycsar.csarUsePara = false -- If set to true, will use the LandingAfterEjection Event instead of Ejection. Requires mycsar.enableForAI to be set to true. --shagrat
|
-- mycsar.csarUsePara = false -- If set to true, will use the LandingAfterEjection Event instead of Ejection. Requires mycsar.enableForAI to be set to true. --shagrat
|
||||||
-- mycsar.wetfeettemplate = "man in floating thingy" -- if you use a mod to have a pilot in a rescue float, put the template name in here for wet feet spawns. Note: in conjunction with csarUsePara this might create dual ejected pilots in edge cases.
|
-- mycsar.wetfeettemplate = "man in floating thingy" -- if you use a mod to have a pilot in a rescue float, put the template name in here for wet feet spawns. Note: in conjunction with csarUsePara this might create dual ejected pilots in edge cases.
|
||||||
-- mycsar.allowbronco = false -- set to true to use the Bronco mod as a CSAR plane
|
-- mycsar.allowbronco = false -- set to true to use the Bronco mod as a CSAR plane
|
||||||
|
-- mycsar.CreateRadioBeacons = true -- set to false to disallow creating ADF radio beacons.
|
||||||
--
|
--
|
||||||
-- ## 3. Results
|
-- ## 3. Results
|
||||||
--
|
--
|
||||||
@@ -256,6 +267,10 @@ CSAR = {
|
|||||||
topmenuname = "CSAR",
|
topmenuname = "CSAR",
|
||||||
ADFRadioPwr = 1000,
|
ADFRadioPwr = 1000,
|
||||||
PilotWeight = 80,
|
PilotWeight = 80,
|
||||||
|
CreateRadioBeacons = true,
|
||||||
|
UserSetGroup = nil,
|
||||||
|
AllowIRStrobe = false,
|
||||||
|
IRStrobeRuntime = 300,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Downed pilots info.
|
--- Downed pilots info.
|
||||||
@@ -272,6 +287,7 @@ CSAR = {
|
|||||||
-- @field #number timestamp Timestamp for approach process.
|
-- @field #number timestamp Timestamp for approach process.
|
||||||
-- @field #boolean alive Group is alive or dead/rescued.
|
-- @field #boolean alive Group is alive or dead/rescued.
|
||||||
-- @field #boolean wetfeet Group is spawned over (deep) water.
|
-- @field #boolean wetfeet Group is spawned over (deep) water.
|
||||||
|
-- @field #string BeaconName Name of radio beacon - if any.
|
||||||
|
|
||||||
--- All slot / Limit settings
|
--- All slot / Limit settings
|
||||||
-- @type CSAR.AircraftType
|
-- @type CSAR.AircraftType
|
||||||
@@ -297,7 +313,7 @@ CSAR.AircraftType["CH-47Fbl1"] = 31
|
|||||||
|
|
||||||
--- CSAR class version.
|
--- CSAR class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CSAR.version="1.0.26"
|
CSAR.version="1.0.29"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- ToDo list
|
-- ToDo list
|
||||||
@@ -457,6 +473,9 @@ function CSAR:New(Coalition, Template, Alias)
|
|||||||
-- added 1.0.16
|
-- added 1.0.16
|
||||||
self.PilotWeight = 80
|
self.PilotWeight = 80
|
||||||
|
|
||||||
|
-- Own SET_GROUP if any
|
||||||
|
self.UserSetGroup = nil
|
||||||
|
|
||||||
-- WARNING - here\'ll be dragons
|
-- WARNING - here\'ll be dragons
|
||||||
-- for this to work you need to de-sanitize your mission environment in <DCS root>\Scripts\MissionScripting.lua
|
-- for this to work you need to de-sanitize your mission environment in <DCS root>\Scripts\MissionScripting.lua
|
||||||
-- needs SRS => 1.9.6 to work (works on the *server* side)
|
-- needs SRS => 1.9.6 to work (works on the *server* side)
|
||||||
@@ -634,7 +653,7 @@ end
|
|||||||
-- @param #string Playername Name of Player (if applicable)
|
-- @param #string Playername Name of Player (if applicable)
|
||||||
-- @param #boolean Wetfeet Ejected over water
|
-- @param #boolean Wetfeet Ejected over water
|
||||||
-- @return #CSAR self.
|
-- @return #CSAR self.
|
||||||
function CSAR:_CreateDownedPilotTrack(Group,Groupname,Side,OriginalUnit,Description,Typename,Frequency,Playername,Wetfeet)
|
function CSAR:_CreateDownedPilotTrack(Group,Groupname,Side,OriginalUnit,Description,Typename,Frequency,Playername,Wetfeet,BeaconName)
|
||||||
self:T({"_CreateDownedPilotTrack",Groupname,Side,OriginalUnit,Description,Typename,Frequency,Playername})
|
self:T({"_CreateDownedPilotTrack",Groupname,Side,OriginalUnit,Description,Typename,Frequency,Playername})
|
||||||
|
|
||||||
-- create new entry
|
-- create new entry
|
||||||
@@ -642,7 +661,7 @@ function CSAR:_CreateDownedPilotTrack(Group,Groupname,Side,OriginalUnit,Descript
|
|||||||
DownedPilot.desc = Description or ""
|
DownedPilot.desc = Description or ""
|
||||||
DownedPilot.frequency = Frequency or 0
|
DownedPilot.frequency = Frequency or 0
|
||||||
DownedPilot.index = self.downedpilotcounter
|
DownedPilot.index = self.downedpilotcounter
|
||||||
DownedPilot.name = Groupname or ""
|
DownedPilot.name = Groupname or Playername or ""
|
||||||
DownedPilot.originalUnit = OriginalUnit or ""
|
DownedPilot.originalUnit = OriginalUnit or ""
|
||||||
DownedPilot.player = Playername or ""
|
DownedPilot.player = Playername or ""
|
||||||
DownedPilot.side = Side or 0
|
DownedPilot.side = Side or 0
|
||||||
@@ -651,6 +670,7 @@ function CSAR:_CreateDownedPilotTrack(Group,Groupname,Side,OriginalUnit,Descript
|
|||||||
DownedPilot.timestamp = 0
|
DownedPilot.timestamp = 0
|
||||||
DownedPilot.alive = true
|
DownedPilot.alive = true
|
||||||
DownedPilot.wetfeet = Wetfeet or false
|
DownedPilot.wetfeet = Wetfeet or false
|
||||||
|
DownedPilot.BeaconName = BeaconName
|
||||||
|
|
||||||
-- Add Pilot
|
-- Add Pilot
|
||||||
local PilotTable = self.downedPilots
|
local PilotTable = self.downedPilots
|
||||||
@@ -737,7 +757,6 @@ function CSAR:_SpawnPilotInField(country,point,frequency,wetfeet)
|
|||||||
:NewWithAlias(template,alias)
|
:NewWithAlias(template,alias)
|
||||||
:InitCoalition(coalition)
|
:InitCoalition(coalition)
|
||||||
:InitCountry(country)
|
:InitCountry(country)
|
||||||
--:InitAIOnOff(pilotcacontrol)
|
|
||||||
:InitDelayOff()
|
:InitDelayOff()
|
||||||
:SpawnFromCoordinate(point)
|
:SpawnFromCoordinate(point)
|
||||||
|
|
||||||
@@ -819,8 +838,18 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local BeaconName
|
||||||
|
|
||||||
|
if _playerName then
|
||||||
|
BeaconName = _unitName..math.random(1,10000)
|
||||||
|
elseif _unitName then
|
||||||
|
BeaconName = _playerName..math.random(1,10000)
|
||||||
|
else
|
||||||
|
BeaconName = "Ghost-1-1"..math.random(1,10000)
|
||||||
|
end
|
||||||
|
|
||||||
if (_freq and _freq ~= 0) then --shagrat only add beacon if _freq is NOT 0
|
if (_freq and _freq ~= 0) then --shagrat only add beacon if _freq is NOT 0
|
||||||
self:_AddBeaconToGroup(_spawnedGroup, _freq)
|
self:_AddBeaconToGroup(_spawnedGroup, _freq, BeaconName)
|
||||||
end
|
end
|
||||||
|
|
||||||
self:_AddSpecialOptions(_spawnedGroup)
|
self:_AddSpecialOptions(_spawnedGroup)
|
||||||
@@ -845,7 +874,7 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla
|
|||||||
|
|
||||||
local _GroupName = _spawnedGroup:GetName() or _alias
|
local _GroupName = _spawnedGroup:GetName() or _alias
|
||||||
|
|
||||||
self:_CreateDownedPilotTrack(_spawnedGroup,_GroupName,_coalition,_unitName,_text,_typeName,_freq,_playerName,wetfeet)
|
self:_CreateDownedPilotTrack(_spawnedGroup,_GroupName,_coalition,_unitName,_text,_typeName,_freq,_playerName,wetfeet,BeaconName)
|
||||||
|
|
||||||
self:_InitSARForPilot(_spawnedGroup, _unitName, _freq, noMessage, _playerName) --shagrat use unitName to have the aircraft callsign / descriptive "name" etc.
|
self:_InitSARForPilot(_spawnedGroup, _unitName, _freq, noMessage, _playerName) --shagrat use unitName to have the aircraft callsign / descriptive "name" etc.
|
||||||
|
|
||||||
@@ -963,7 +992,6 @@ end
|
|||||||
-- @param Core.Point#COORDINATE Point
|
-- @param Core.Point#COORDINATE Point
|
||||||
-- @param #number Coalition Coalition.
|
-- @param #number Coalition Coalition.
|
||||||
-- @param #string Description (optional) Description.
|
-- @param #string Description (optional) Description.
|
||||||
-- @param #boolean addBeacon (optional) yes or no.
|
|
||||||
-- @param #boolean Nomessage (optional) If true, don\'t send a message to SAR.
|
-- @param #boolean Nomessage (optional) If true, don\'t send a message to SAR.
|
||||||
-- @param #string Unitname (optional) Name of the lost unit.
|
-- @param #string Unitname (optional) Name of the lost unit.
|
||||||
-- @param #string Typename (optional) Type of plane.
|
-- @param #string Typename (optional) Type of plane.
|
||||||
@@ -1793,9 +1821,6 @@ function CSAR:_DisplayMessageToSAR(_unit, _text, _time, _clear, _speak, _overrid
|
|||||||
end
|
end
|
||||||
_text = string.gsub(_text,"km"," kilometer")
|
_text = string.gsub(_text,"km"," kilometer")
|
||||||
_text = string.gsub(_text,"nm"," nautical miles")
|
_text = string.gsub(_text,"nm"," nautical miles")
|
||||||
--self.msrs:SetVoice(self.SRSVoice)
|
|
||||||
--self.SRSQueue:NewTransmission(_text,nil,self.msrs,nil,1)
|
|
||||||
--self:I("Voice = "..self.SRSVoice)
|
|
||||||
self.SRSQueue:NewTransmission(_text,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,self.SRSVoice,volume,label,coord)
|
self.SRSQueue:NewTransmission(_text,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,self.SRSVoice,volume,label,coord)
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
@@ -1856,7 +1881,7 @@ function CSAR:_DisplayActiveSAR(_unitName)
|
|||||||
else
|
else
|
||||||
distancetext = string.format("%.1fkm", _distance/1000.0)
|
distancetext = string.format("%.1fkm", _distance/1000.0)
|
||||||
end
|
end
|
||||||
if _value.frequency == 0 then--shagrat insert CASEVAC without Frequency
|
if _value.frequency == 0 or self.CreateRadioBeacons == false then--shagrat insert CASEVAC without Frequency
|
||||||
table.insert(_csarList, { dist = _distance, msg = string.format("%s at %s - %s ", _value.desc, _coordinatesText, distancetext) })
|
table.insert(_csarList, { dist = _distance, msg = string.format("%s at %s - %s ", _value.desc, _coordinatesText, distancetext) })
|
||||||
else
|
else
|
||||||
table.insert(_csarList, { dist = _distance, msg = string.format("%s at %s - %.2f KHz ADF - %s ", _value.desc, _coordinatesText, _value.frequency / 1000, distancetext) })
|
table.insert(_csarList, { dist = _distance, msg = string.format("%s at %s - %.2f KHz ADF - %s ", _value.desc, _coordinatesText, _value.frequency / 1000, distancetext) })
|
||||||
@@ -1941,7 +1966,7 @@ function CSAR:_SignalFlare(_unitName)
|
|||||||
else
|
else
|
||||||
_distance = string.format("%.1fkm",_closest.distance/1000)
|
_distance = string.format("%.1fkm",_closest.distance/1000)
|
||||||
end
|
end
|
||||||
local _msg = string.format("%s - Popping signal flare at your %s o\'clock. Distance %s", self:_GetCustomCallSign(_unitName), _clockDir, _distance)
|
local _msg = string.format("%s - Firing signal flare at your %s o\'clock. Distance %s", self:_GetCustomCallSign(_unitName), _clockDir, _distance)
|
||||||
self:_DisplayMessageToSAR(_heli, _msg, self.messageTime, false, true, true)
|
self:_DisplayMessageToSAR(_heli, _msg, self.messageTime, false, true, true)
|
||||||
|
|
||||||
local _coord = _closest.pilot:GetCoordinate()
|
local _coord = _closest.pilot:GetCoordinate()
|
||||||
@@ -1975,7 +2000,7 @@ function CSAR:_DisplayToAllSAR(_message, _side, _messagetime,ToSRS,ToScreen)
|
|||||||
if self.msrs:GetProvider() == MSRS.Provider.WINDOWS then
|
if self.msrs:GetProvider() == MSRS.Provider.WINDOWS then
|
||||||
voice = self.CSARVoiceMS or MSRS.Voices.Microsoft.Hedda
|
voice = self.CSARVoiceMS or MSRS.Voices.Microsoft.Hedda
|
||||||
end
|
end
|
||||||
self:F("Voice = "..voice)
|
--self:F("Voice = "..voice)
|
||||||
self.SRSQueue:NewTransmission(_message,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,voice,volume,label,self.coordinate)
|
self.SRSQueue:NewTransmission(_message,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,voice,volume,label,self.coordinate)
|
||||||
end
|
end
|
||||||
if ToScreen == true or ToScreen == nil then
|
if ToScreen == true or ToScreen == nil then
|
||||||
@@ -1989,6 +2014,41 @@ function CSAR:_DisplayToAllSAR(_message, _side, _messagetime,ToSRS,ToScreen)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---(Internal) Request IR Strobe at closest downed pilot.
|
||||||
|
--@param #CSAR self
|
||||||
|
--@param #string _unitName Name of the helicopter
|
||||||
|
function CSAR:_ReqIRStrobe( _unitName )
|
||||||
|
self:T(self.lid .. " _ReqIRStrobe")
|
||||||
|
local _heli = self:_GetSARHeli(_unitName)
|
||||||
|
if _heli == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local smokedist = 8000
|
||||||
|
if smokedist < self.approachdist_far then smokedist = self.approachdist_far end
|
||||||
|
local _closest = self:_GetClosestDownedPilot(_heli)
|
||||||
|
if _closest ~= nil and _closest.pilot ~= nil and _closest.distance > 0 and _closest.distance < smokedist then
|
||||||
|
local _clockDir = self:_GetClockDirection(_heli, _closest.pilot)
|
||||||
|
local _distance = string.format("%.1fkm",_closest.distance/1000)
|
||||||
|
if _SETTINGS:IsImperial() then
|
||||||
|
_distance = string.format("%.1fnm",UTILS.MetersToNM(_closest.distance))
|
||||||
|
else
|
||||||
|
_distance = string.format("%.1fkm",_closest.distance/1000)
|
||||||
|
end
|
||||||
|
local _msg = string.format("%s - IR Strobe active at your %s o\'clock. Distance %s", self:_GetCustomCallSign(_unitName), _clockDir, _distance)
|
||||||
|
self:_DisplayMessageToSAR(_heli, _msg, self.messageTime, false, true, true)
|
||||||
|
_closest.pilot:NewIRMarker(true,self.IRStrobeRuntime or 300)
|
||||||
|
else
|
||||||
|
local _distance = string.format("%.1fkm",smokedist/1000)
|
||||||
|
if _SETTINGS:IsImperial() then
|
||||||
|
_distance = string.format("%.1fnm",UTILS.MetersToNM(smokedist))
|
||||||
|
else
|
||||||
|
_distance = string.format("%.1fkm",smokedist/1000)
|
||||||
|
end
|
||||||
|
self:_DisplayMessageToSAR(_heli, string.format("No Pilots within %s",_distance), self.messageTime, false, false, true)
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
---(Internal) Request smoke at closest downed pilot.
|
---(Internal) Request smoke at closest downed pilot.
|
||||||
--@param #CSAR self
|
--@param #CSAR self
|
||||||
--@param #string _unitName Name of the helicopter
|
--@param #string _unitName Name of the helicopter
|
||||||
@@ -2140,7 +2200,12 @@ function CSAR:_AddMedevacMenuItem()
|
|||||||
local _rootMenu1 = MENU_GROUP_COMMAND:New(_group,"List Active CSAR",_rootPath, self._DisplayActiveSAR,self,_unitName)
|
local _rootMenu1 = MENU_GROUP_COMMAND:New(_group,"List Active CSAR",_rootPath, self._DisplayActiveSAR,self,_unitName)
|
||||||
local _rootMenu2 = MENU_GROUP_COMMAND:New(_group,"Check Onboard",_rootPath, self._CheckOnboard,self,_unitName)
|
local _rootMenu2 = MENU_GROUP_COMMAND:New(_group,"Check Onboard",_rootPath, self._CheckOnboard,self,_unitName)
|
||||||
local _rootMenu3 = MENU_GROUP_COMMAND:New(_group,"Request Signal Flare",_rootPath, self._SignalFlare,self,_unitName)
|
local _rootMenu3 = MENU_GROUP_COMMAND:New(_group,"Request Signal Flare",_rootPath, self._SignalFlare,self,_unitName)
|
||||||
local _rootMenu4 = MENU_GROUP_COMMAND:New(_group,"Request Smoke",_rootPath, self._Reqsmoke,self,_unitName):Refresh()
|
local _rootMenu4 = MENU_GROUP_COMMAND:New(_group,"Request Smoke",_rootPath, self._Reqsmoke,self,_unitName)
|
||||||
|
if self.AllowIRStrobe then
|
||||||
|
local _rootMenu5 = MENU_GROUP_COMMAND:New(_group,"Request IR Strobe",_rootPath, self._ReqIRStrobe,self,_unitName):Refresh()
|
||||||
|
else
|
||||||
|
_rootMenu4:Refresh()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -2231,9 +2296,13 @@ 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
|
||||||
function CSAR:_AddBeaconToGroup(_group, _freq)
|
-- @param #string _name Beacon Name to use
|
||||||
|
-- @return #CSAR self
|
||||||
|
function CSAR:_AddBeaconToGroup(_group, _freq, _name)
|
||||||
self:T(self.lid .. " _AddBeaconToGroup")
|
self:T(self.lid .. " _AddBeaconToGroup")
|
||||||
|
if self.CreateRadioBeacons == false then return end
|
||||||
local _group = _group
|
local _group = _group
|
||||||
|
|
||||||
if _group == nil then
|
if _group == nil then
|
||||||
--return frequency to pool of available
|
--return frequency to pool of available
|
||||||
for _i, _current in ipairs(self.UsedVHFFrequencies) do
|
for _i, _current in ipairs(self.UsedVHFFrequencies) do
|
||||||
@@ -2253,17 +2322,19 @@ function CSAR:_AddBeaconToGroup(_group, _freq)
|
|||||||
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..math.random(1,10000)) -- Beacon in MP only runs for exactly 30secs straight
|
trigger.action.radioTransmission(Sound, vec3, 0, false, Frequency, self.ADFRadioPwr or 1000,_name) -- Beacon in MP only runs for exactly 30secs straight
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (Internal) Helper function to (re-)add beacon to downed pilot.
|
--- (Internal) Helper function to (re-)add beacon to downed pilot.
|
||||||
-- @param #CSAR self
|
-- @param #CSAR self
|
||||||
-- @param #table _args Arguments
|
-- @return #CSAR self
|
||||||
function CSAR:_RefreshRadioBeacons()
|
function CSAR:_RefreshRadioBeacons()
|
||||||
self:T(self.lid .. " _RefreshRadioBeacons")
|
self:T(self.lid .. " _RefreshRadioBeacons")
|
||||||
|
if self.CreateRadioBeacons == false then return end
|
||||||
if self:_CountActiveDownedPilots() > 0 then
|
if self:_CountActiveDownedPilots() > 0 then
|
||||||
local PilotTable = self.downedPilots
|
local PilotTable = self.downedPilots
|
||||||
for _,_pilot in pairs (PilotTable) do
|
for _,_pilot in pairs (PilotTable) do
|
||||||
@@ -2271,8 +2342,10 @@ function CSAR:_RefreshRadioBeacons()
|
|||||||
local pilot = _pilot -- #CSAR.DownedPilot
|
local pilot = _pilot -- #CSAR.DownedPilot
|
||||||
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)
|
||||||
|
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)
|
self:_AddBeaconToGroup(group,frequency,bname)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -2309,6 +2382,16 @@ function CSAR:_ReachedPilotLimit()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- User - Function to add onw SET_GROUP Set-up for pilot filtering and assignment.
|
||||||
|
-- Needs to be set before starting the CSAR instance.
|
||||||
|
-- @param #CSAR self
|
||||||
|
-- @param Core.Set#SET_GROUP Set The SET_GROUP object created by the mission designer/user to represent the CSAR pilot groups.
|
||||||
|
-- @return #CSAR self
|
||||||
|
function CSAR:SetOwnSetPilotGroups(Set)
|
||||||
|
self.UserSetGroup = Set
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
------------------------------
|
------------------------------
|
||||||
--- FSM internal Functions ---
|
--- FSM internal Functions ---
|
||||||
------------------------------
|
------------------------------
|
||||||
@@ -2330,7 +2413,9 @@ function CSAR:onafterStart(From, Event, To)
|
|||||||
self:HandleEvent(EVENTS.PlayerEnterUnit, self._EventHandler)
|
self:HandleEvent(EVENTS.PlayerEnterUnit, self._EventHandler)
|
||||||
self:HandleEvent(EVENTS.PilotDead, self._EventHandler)
|
self:HandleEvent(EVENTS.PilotDead, self._EventHandler)
|
||||||
|
|
||||||
if self.allowbronco then
|
if self.UserSetGroup then
|
||||||
|
self.allheligroupset = self.UserSetGroup
|
||||||
|
elseif self.allowbronco then
|
||||||
local prefixes = self.csarPrefix or {}
|
local prefixes = self.csarPrefix or {}
|
||||||
self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(prefixes):FilterStart()
|
self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(prefixes):FilterStart()
|
||||||
elseif self.useprefix then
|
elseif self.useprefix then
|
||||||
@@ -2339,7 +2424,9 @@ function CSAR:onafterStart(From, Event, To)
|
|||||||
else
|
else
|
||||||
self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterCategoryHelicopter():FilterStart()
|
self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterCategoryHelicopter():FilterStart()
|
||||||
end
|
end
|
||||||
|
|
||||||
self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart() -- currently only GROUP objects, maybe support STATICs also?
|
self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart() -- currently only GROUP objects, maybe support STATICs also?
|
||||||
|
|
||||||
if not self.coordinate then
|
if not self.coordinate then
|
||||||
local csarhq = self.mash:GetRandom()
|
local csarhq = self.mash:GetRandom()
|
||||||
if csarhq then
|
if csarhq then
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -34,6 +34,7 @@
|
|||||||
-- @field Ops.Commander#COMMANDER commander Commander of assigned legions.
|
-- @field Ops.Commander#COMMANDER commander Commander of assigned legions.
|
||||||
-- @field #number Nsuccess Number of successful missions.
|
-- @field #number Nsuccess Number of successful missions.
|
||||||
-- @field #number Nfailure Number of failed mission.
|
-- @field #number Nfailure Number of failed mission.
|
||||||
|
-- @field #table assetNumbers Asset numbers. Each entry is a table of data type `#CHIEF.AssetNumber`.
|
||||||
-- @extends Ops.Intel#INTEL
|
-- @extends Ops.Intel#INTEL
|
||||||
|
|
||||||
--- *In preparing for battle I have always found that plans are useless, but planning is indispensable* -- Dwight D Eisenhower
|
--- *In preparing for battle I have always found that plans are useless, but planning is indispensable* -- Dwight D Eisenhower
|
||||||
@@ -331,7 +332,7 @@ CHIEF.Strategy = {
|
|||||||
|
|
||||||
--- CHIEF class version.
|
--- CHIEF class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CHIEF.version="0.6.0"
|
CHIEF.version="0.6.1"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@@ -1284,8 +1285,10 @@ end
|
|||||||
--
|
--
|
||||||
-- Empty:
|
-- Empty:
|
||||||
--
|
--
|
||||||
-- * `AUFTRAG.Type.ONGURAD` with Nmin=1 and Nmax=1 assets, Attribute=`GROUP.Attribute.GROUND_TANK`.
|
-- * `AUFTRAG.Type.ONGURAD` with Nmin=0 and Nmax=1 assets, Attribute=`GROUP.Attribute.GROUND_TANK`.
|
||||||
|
-- * `AUFTRAG.Type.ONGURAD` with Nmin=0 and Nmax=1 assets, Attribute=`GROUP.Attribute.GROUND_IFV`.
|
||||||
-- * `AUFTRAG.Type.ONGUARD` with Nmin=1 and Nmax=3 assets, Attribute=`GROUP.Attribute.GROUND_INFANTRY`.
|
-- * `AUFTRAG.Type.ONGUARD` with Nmin=1 and Nmax=3 assets, Attribute=`GROUP.Attribute.GROUND_INFANTRY`.
|
||||||
|
-- * `AUFTRAG.Type.OPSTRANSPORT` with Nmin=0 and Nmax=1 assets, Attribute=`GROUP.Attribute.AIR_TRANSPORTHELO` or `GROUP.Attribute.GROUND_APC`. This asset is used to transport the infantry groups.
|
||||||
--
|
--
|
||||||
-- Resources can be created with the @{#CHIEF.CreateResource} and @{#CHIEF.AddToResource} functions.
|
-- Resources can be created with the @{#CHIEF.CreateResource} and @{#CHIEF.AddToResource} functions.
|
||||||
--
|
--
|
||||||
@@ -3033,10 +3036,13 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Recruite infantry assets.
|
-- Recruite infantry assets.
|
||||||
|
self:T(self.lid..string.format("Recruiting assets for zone %s", StratZone.opszone:GetName()))
|
||||||
self:T(self.lid.."Missiontype="..MissionType)
|
self:T(self.lid.."Missiontype="..MissionType)
|
||||||
self:T({categories=Categories})
|
self:T({categories=Categories})
|
||||||
self:T({attributes=Attributes})
|
self:T({attributes=Attributes})
|
||||||
self:T({properties=Properties})
|
self:T({properties=Properties})
|
||||||
|
|
||||||
|
|
||||||
local recruited, assets, legions=LEGION.RecruitCohortAssets(Cohorts, MissionType, nil, NassetsMin, NassetsMax, TargetVec2, nil, RangeMax, nil, nil, nil, nil, Categories, Attributes, Properties)
|
local recruited, assets, legions=LEGION.RecruitCohortAssets(Cohorts, MissionType, nil, NassetsMin, NassetsMax, TargetVec2, nil, RangeMax, nil, nil, nil, nil, Categories, Attributes, Properties)
|
||||||
|
|
||||||
if recruited then
|
if recruited then
|
||||||
@@ -3052,9 +3058,12 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
|
|||||||
local TargetCoord = TargetZone:GetCoordinate()
|
local TargetCoord = TargetZone:GetCoordinate()
|
||||||
|
|
||||||
-- First check if we need a transportation.
|
-- First check if we need a transportation.
|
||||||
local transport=nil
|
local transport=nil --Ops.OpsTransport#OPSTRANSPORT
|
||||||
|
local Ntransports=0
|
||||||
if Resource.carrierNmin and Resource.carrierNmax and Resource.carrierNmax>0 then
|
if Resource.carrierNmin and Resource.carrierNmax and Resource.carrierNmax>0 then
|
||||||
|
|
||||||
|
self:T(self.lid..string.format("Recruiting carrier assets: Nmin=%s, Nmax=%s", tostring(Resource.carrierNmin), tostring(Resource.carrierNmax)))
|
||||||
|
|
||||||
-- Filter only those assets that shall be transported.
|
-- Filter only those assets that shall be transported.
|
||||||
local cargoassets=CHIEF._FilterAssets(assets, Resource.Categories, Resource.Attributes, Resource.Properties)
|
local cargoassets=CHIEF._FilterAssets(assets, Resource.Categories, Resource.Attributes, Resource.Properties)
|
||||||
|
|
||||||
@@ -3064,6 +3073,10 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
|
|||||||
recruited, transport=LEGION.AssignAssetsForTransport(self.commander, self.commander.legions, cargoassets,
|
recruited, transport=LEGION.AssignAssetsForTransport(self.commander, self.commander.legions, cargoassets,
|
||||||
Resource.carrierNmin, Resource.carrierNmax, TargetZone, nil, Resource.carrierCategories, Resource.carrierAttributes, Resource.carrierProperties)
|
Resource.carrierNmin, Resource.carrierNmax, TargetZone, nil, Resource.carrierCategories, Resource.carrierAttributes, Resource.carrierProperties)
|
||||||
|
|
||||||
|
Ntransports=transport~=nil and #transport.assets or 0
|
||||||
|
|
||||||
|
self:T(self.lid..string.format("Recruited %d transport carrier assets success=%s", Ntransports, tostring(recruited)))
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -3076,7 +3089,7 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Debug messgage.
|
-- Debug message
|
||||||
self:T2(self.lid..string.format("Recruited %d assets for mission %s", #assets, MissionType))
|
self:T2(self.lid..string.format("Recruited %d assets for mission %s", #assets, MissionType))
|
||||||
|
|
||||||
|
|
||||||
@@ -3224,10 +3237,13 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
|
|||||||
-- Attach mission to ops zone.
|
-- Attach mission to ops zone.
|
||||||
StratZone.opszone:_AddMission(self.coalition, MissionType, mission)
|
StratZone.opszone:_AddMission(self.coalition, MissionType, mission)
|
||||||
|
|
||||||
|
mission:SetName(string.format("Stratzone %s-%d", StratZone.opszone:GetName(), mission.auftragsnummer))
|
||||||
|
|
||||||
-- Attach mission to resource.
|
-- Attach mission to resource.
|
||||||
Resource.mission=mission
|
Resource.mission=mission
|
||||||
|
|
||||||
if transport then
|
-- Check if transport assets could be allocated. If carrier Nmin=0 and 0 assets could be allocated, transport would still be created but not usefull obviously
|
||||||
|
if transport and Ntransports>0 then
|
||||||
-- Attach OPS transport to mission.
|
-- Attach OPS transport to mission.
|
||||||
mission.opstransport=transport
|
mission.opstransport=transport
|
||||||
-- Set ops zone to transport.
|
-- Set ops zone to transport.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2619,6 +2619,8 @@ function LEGION._CohortCan(Cohort, MissionType, Categories, Attributes, Properti
|
|||||||
local RangeMax = RangeMax or 0
|
local RangeMax = RangeMax or 0
|
||||||
local InRange=(RangeMax and math.max(RangeMax, Rmax) or Rmax) >= TargetDistance
|
local InRange=(RangeMax and math.max(RangeMax, Rmax) or Rmax) >= TargetDistance
|
||||||
|
|
||||||
|
--env.info(string.format("Range TargetDist=%.1f Rmax=%.1f RangeMax=%.1f InRange=%s", TargetDistance, Rmax, RangeMax, tostring(InRange)))
|
||||||
|
|
||||||
return InRange
|
return InRange
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2785,6 +2787,8 @@ function LEGION.RecruitCohortAssets(Cohorts, MissionTypeRecruit, MissionTypeOpt,
|
|||||||
-- Check if cohort can do the mission.
|
-- Check if cohort can do the mission.
|
||||||
local can=LEGION._CohortCan(cohort, MissionTypeRecruit, Categories, Attributes, Properties, WeaponTypes, TargetVec2, RangeMax, RefuelSystem, CargoWeight, MaxWeight)
|
local can=LEGION._CohortCan(cohort, MissionTypeRecruit, Categories, Attributes, Properties, WeaponTypes, TargetVec2, RangeMax, RefuelSystem, CargoWeight, MaxWeight)
|
||||||
|
|
||||||
|
--env.info(string.format("RecruitCohortAssets %s Cohort=%s can=%s", MissionTypeRecruit, cohort:GetName(), tostring(can)))
|
||||||
|
|
||||||
-- Check OnDuty, capable, in range and refueling type (if TANKER).
|
-- Check OnDuty, capable, in range and refueling type (if TANKER).
|
||||||
if can then
|
if can then
|
||||||
|
|
||||||
@@ -2800,6 +2804,12 @@ function LEGION.RecruitCohortAssets(Cohorts, MissionTypeRecruit, MissionTypeOpt,
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Break if no assets could be found
|
||||||
|
if #Assets==0 then
|
||||||
|
--env.info(string.format("LEGION.RecruitCohortAssets: No assets could be recruited for mission type %s [Nmin=%s, Nmax=%s]", MissionTypeRecruit, tostring(NreqMin), tostring(NreqMax)))
|
||||||
|
return false, {}, {}
|
||||||
|
end
|
||||||
|
|
||||||
-- Now we have a long list with assets.
|
-- Now we have a long list with assets.
|
||||||
LEGION._OptimizeAssetSelection(Assets, MissionTypeOpt, TargetVec2, false, TotalWeight)
|
LEGION._OptimizeAssetSelection(Assets, MissionTypeOpt, TargetVec2, false, TotalWeight)
|
||||||
|
|
||||||
|
|||||||
@@ -271,11 +271,11 @@ MSRS.Voices = {
|
|||||||
["David"] = "Microsoft David Desktop", -- en-US
|
["David"] = "Microsoft David Desktop", -- en-US
|
||||||
["Zira"] = "Microsoft Zira Desktop", -- en-US
|
["Zira"] = "Microsoft Zira Desktop", -- en-US
|
||||||
["Hortense"] = "Microsoft Hortense Desktop", --fr-FR
|
["Hortense"] = "Microsoft Hortense Desktop", --fr-FR
|
||||||
["de-DE-Hedda"] = "Microsoft Hedda Desktop", -- de-DE
|
["de_DE_Hedda"] = "Microsoft Hedda Desktop", -- de-DE
|
||||||
["en-GB-Hazel"] = "Microsoft Hazel Desktop", -- en-GB
|
["en_GB_Hazel"] = "Microsoft Hazel Desktop", -- en-GB
|
||||||
["en-US-David"] = "Microsoft David Desktop", -- en-US
|
["en_US_David"] = "Microsoft David Desktop", -- en-US
|
||||||
["en-US-Zira"] = "Microsoft Zira Desktop", -- en-US
|
["en_US_Zira"] = "Microsoft Zira Desktop", -- en-US
|
||||||
["fr-FR-Hortense"] = "Microsoft Hortense Desktop", --fr-FR
|
["fr_FR_Hortense"] = "Microsoft Hortense Desktop", --fr-FR
|
||||||
},
|
},
|
||||||
MicrosoftGRPC = { -- en-US/GB voices only as of Jan 2024, working ones if using gRPC and MS, if voice packs are installed
|
MicrosoftGRPC = { -- en-US/GB voices only as of Jan 2024, working ones if using gRPC and MS, if voice packs are installed
|
||||||
--["Hedda"] = "Hedda", -- de-DE
|
--["Hedda"] = "Hedda", -- de-DE
|
||||||
@@ -305,7 +305,6 @@ MSRS.Voices = {
|
|||||||
["en_IN_Ravi"] = "Ravi", --en-IN
|
["en_IN_Ravi"] = "Ravi", --en-IN
|
||||||
["en_IN_Heera"] = "Heera", --en-IN
|
["en_IN_Heera"] = "Heera", --en-IN
|
||||||
["en_IR_Sean"] = "Sean", --en-IR
|
["en_IR_Sean"] = "Sean", --en-IR
|
||||||
--]]
|
|
||||||
},
|
},
|
||||||
Google = {
|
Google = {
|
||||||
Standard = {
|
Standard = {
|
||||||
|
|||||||
@@ -580,6 +580,18 @@ ENUMS.Link16Power = {
|
|||||||
--- Enums for the STORAGE class for stores - which need to be in ""
|
--- Enums for the STORAGE class for stores - which need to be in ""
|
||||||
-- @type ENUMS.Storage
|
-- @type ENUMS.Storage
|
||||||
-- @type ENUMS.Storage.weapons
|
-- @type ENUMS.Storage.weapons
|
||||||
|
-- @type ENUMS.Storage.weapons.missiles
|
||||||
|
-- @type ENUMS.Storage.weapons.bombs
|
||||||
|
-- @type ENUMS.Storage.weapons.nurs
|
||||||
|
-- @type ENUMS.Storage.weapons.containers
|
||||||
|
-- @type ENUMS.Storage.weapons.droptanks
|
||||||
|
-- @type ENUMS.Storage.weapons.adapters
|
||||||
|
-- @type ENUMS.Storage.weapons.torpedoes
|
||||||
|
-- @type ENUMS.Storage.weapons.Gazelle
|
||||||
|
-- @type ENUMS.Storage.weapons.CH47
|
||||||
|
-- @type ENUMS.Storage.weapons.OH58
|
||||||
|
-- @type ENUMS.Storage.weapons.UH1H
|
||||||
|
-- @type ENUMS.Storage.weapons.AH64D
|
||||||
ENUMS.Storage = {
|
ENUMS.Storage = {
|
||||||
weapons = {
|
weapons = {
|
||||||
missiles = {}, -- Missiles
|
missiles = {}, -- Missiles
|
||||||
@@ -589,6 +601,11 @@ ENUMS.Storage = {
|
|||||||
droptanks = {}, -- Droptanks
|
droptanks = {}, -- Droptanks
|
||||||
adapters = {}, -- Adapter
|
adapters = {}, -- Adapter
|
||||||
torpedoes = {}, -- Torpedoes
|
torpedoes = {}, -- Torpedoes
|
||||||
|
Gazelle = {}, -- Gazelle specifics
|
||||||
|
CH47 = {}, -- Chinook specifics
|
||||||
|
OH58 = {}, -- Kiowa specifics
|
||||||
|
UH1H = {}, -- Huey specifics
|
||||||
|
AH64D = {}, -- Huey specifics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1149,3 +1166,74 @@ ENUMS.Storage.weapons.bombs.AGM_62 = "weapons.bombs.AGM_62"
|
|||||||
ENUMS.Storage.weapons.containers.US_M10_SMOKE_TANK_WHITE = "weapons.containers.{US_M10_SMOKE_TANK_WHITE}"
|
ENUMS.Storage.weapons.containers.US_M10_SMOKE_TANK_WHITE = "weapons.containers.{US_M10_SMOKE_TANK_WHITE}"
|
||||||
ENUMS.Storage.weapons.missiles.MICA_T = "weapons.missiles.MICA_T"
|
ENUMS.Storage.weapons.missiles.MICA_T = "weapons.missiles.MICA_T"
|
||||||
ENUMS.Storage.weapons.containers.HVAR_rocket = "weapons.containers.HVAR_rocket"
|
ENUMS.Storage.weapons.containers.HVAR_rocket = "weapons.containers.HVAR_rocket"
|
||||||
|
-- Gazelle
|
||||||
|
ENUMS.Storage.weapons.Gazelle.HMP400_100RDS = {4,15,46,1771}
|
||||||
|
ENUMS.Storage.weapons.Gazelle.HMP400_200RDS = {4,15,46,1770}
|
||||||
|
ENUMS.Storage.weapons.Gazelle.HMP400_400RDS = {4,15,46,1769}
|
||||||
|
ENUMS.Storage.weapons.Gazelle.GIAT_M261_AP = {4,15,46,1768}
|
||||||
|
ENUMS.Storage.weapons.Gazelle.GIAT_M261_SAPHEI = {4,15,46,1767}
|
||||||
|
ENUMS.Storage.weapons.Gazelle.GIAT_M261_HE = {4,15,46,1766}
|
||||||
|
ENUMS.Storage.weapons.Gazelle.GIAT_M261_HEAP = {4,15,46,1765}
|
||||||
|
ENUMS.Storage.weapons.Gazelle.GIAT_M261_APHE = {4,15,46,1764}
|
||||||
|
ENUMS.Storage.weapons.Gazelle.GAZELLE_IR_DEFLECTOR = {4,15,47,680}
|
||||||
|
ENUMS.Storage.weapons.Gazelle.GAZELLE_FAS_SANDFILTER = {4,15,47,679}
|
||||||
|
-- Chinook
|
||||||
|
ENUMS.Storage.weapons.CH47.CH47_PORT_M60D = {4,15,46,2476}
|
||||||
|
ENUMS.Storage.weapons.CH47.CH47_STBD_M60D = {4,15,46,2477}
|
||||||
|
ENUMS.Storage.weapons.CH47.CH47_AFT_M60D = {4,15,46,2478}
|
||||||
|
ENUMS.Storage.weapons.CH47.CH47_PORT_M134D = {4,15,46,2482}
|
||||||
|
ENUMS.Storage.weapons.CH47.CH47_STBD_M134D = {4,15,46,2483}
|
||||||
|
ENUMS.Storage.weapons.CH47.CH47_AFT_M3M = {4,15,46,2484}
|
||||||
|
ENUMS.Storage.weapons.CH47.CH47_PORT_M240H = {4,15,46,2479}
|
||||||
|
ENUMS.Storage.weapons.CH47.CH47_STBD_M240H = {4,15,46,2480}
|
||||||
|
ENUMS.Storage.weapons.CH47.CH47_AFT_M240H = {4,15,46,2481}
|
||||||
|
-- Huey
|
||||||
|
ENUMS.Storage.weapons.UH1H.M134_MiniGun_Right = {4,15,46,161}
|
||||||
|
ENUMS.Storage.weapons.UH1H.M134_MiniGun_Left = {4,15,46,160}
|
||||||
|
ENUMS.Storage.weapons.UH1H.M134_MiniGun_Right_Door = {4,15,46,175}
|
||||||
|
ENUMS.Storage.weapons.UH1H.M60_MG_Right_Door = {4,15,46,177}
|
||||||
|
ENUMS.Storage.weapons.UH1H.M134_MiniGun_Left_Door = {4,15,46,174}
|
||||||
|
ENUMS.Storage.weapons.UH1H.M60_MG_Left_Door = {4,15,46,176}
|
||||||
|
-- Kiowa
|
||||||
|
ENUMS.Storage.weapons.OH58.FIM92 = {4,4,7,446}
|
||||||
|
ENUMS.Storage.weapons.OH58.MG_M3P100 = {4,15,46,2578}
|
||||||
|
ENUMS.Storage.weapons.OH58.MG_M3P200 = {4,15,46,2577}
|
||||||
|
ENUMS.Storage.weapons.OH58.MG_M3P300 = {4,15,46,2576}
|
||||||
|
ENUMS.Storage.weapons.OH58.MG_M3P400 = {4,15,46,2575}
|
||||||
|
ENUMS.Storage.weapons.OH58.MG_M3P500 = {4,15,46,2574}
|
||||||
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Blue = {4,5,9,484}
|
||||||
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Green = {4,5,9,485}
|
||||||
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Red = {4,5,9,483}
|
||||||
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Violet = {4,5,9,486}
|
||||||
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_White = {4,5,9,488}
|
||||||
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Yellow = {4,5,9,487}
|
||||||
|
-- Apache
|
||||||
|
ENUMS.Storage.weapons.AH64D.AN_APG78 = {4,15,44,2138}
|
||||||
|
ENUMS.Storage.weapons.AH64D.Internal_Aux_FuelTank = {1,3,43,1700}
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @type ENUMS.FARPType
|
||||||
|
-- @field #string FARP
|
||||||
|
-- @field #string INVISIBLE
|
||||||
|
-- @field #string HELIPADSINGLE
|
||||||
|
-- @field #string PADSINGLE
|
||||||
|
ENUMS.FARPType = {
|
||||||
|
FARP = "FARP",
|
||||||
|
INVISIBLE = "INVISIBLE",
|
||||||
|
HELIPADSINGLE = "HELIPADSINGLE",
|
||||||
|
PADSINGLE = "PADSINGLE",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @type ENUMS.FARPObjectTypeNamesAndShape
|
||||||
|
-- @field #string FARP
|
||||||
|
-- @field #string INVISIBLE
|
||||||
|
-- @field #string HELIPADSINGLE
|
||||||
|
-- @field #string PADSINGLE
|
||||||
|
ENUMS.FARPObjectTypeNamesAndShape ={
|
||||||
|
[ENUMS.FARPType.FARP] = { TypeName="FARP", ShapeName="FARPS"},
|
||||||
|
[ENUMS.FARPType.INVISIBLE] = { TypeName="Invisible FARP", ShapeName="invisiblefarp"},
|
||||||
|
[ENUMS.FARPType.HELIPADSINGLE] = { TypeName="SINGLE_HELIPAD", ShapeName="FARP"},
|
||||||
|
[ENUMS.FARPType.PADSINGLE] = { TypeName="FARP_SINGLE_01", ShapeName="FARP_SINGLE_01"},
|
||||||
|
}
|
||||||
|
|||||||
@@ -1221,7 +1221,7 @@ function UTILS.SecondsToClock(seconds, short)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Seconds
|
-- Seconds
|
||||||
local seconds = tonumber(seconds)
|
local seconds = tonumber(seconds) or 0
|
||||||
|
|
||||||
-- Seconds of this day.
|
-- Seconds of this day.
|
||||||
local _seconds=seconds%(60*60*24)
|
local _seconds=seconds%(60*60*24)
|
||||||
@@ -2122,9 +2122,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/R" -- The sun never rises on this location on the specified date
|
return "N/S" -- The sun never rises on this location on the specified date
|
||||||
elseif cosH < -1 then
|
elseif cosH < -1 then
|
||||||
return "N/S" -- The sun never sets on this location on the specified date
|
return "N/R" -- 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
|
||||||
@@ -2353,14 +2353,16 @@ function UTILS.GenerateVHFrequencies()
|
|||||||
|
|
||||||
-- known and sorted map-wise NDBs in kHz
|
-- known and sorted map-wise NDBs in kHz
|
||||||
local _skipFrequencies = {
|
local _skipFrequencies = {
|
||||||
214,274,291.5,295,297.5,
|
214,243,264,273,274,288,291.5,295,297.5,
|
||||||
300.5,304,305,307,309.5,311,312,312.5,316,
|
300.5,304,305,307,309.5,310,311,312,312.5,316,317,
|
||||||
320,324,328,329,330,332,336,337,
|
320,323,324,325,326,328,329,330,332,335,336,337,
|
||||||
342,343,348,351,352,353,358,
|
340,342,343,346,348,351,352,353,358,
|
||||||
363,365,368,372.5,374,
|
360,363,364,365,368,372.5,373,374,
|
||||||
380,381,384,385,389,395,396,
|
380,381,384,385,387,389,391,395,396,399,
|
||||||
414,420,430,432,435,440,450,455,462,470,485,
|
403,404,410,412,414,418,420,423,
|
||||||
507,515,520,525,528,540,550,560,570,577,580,
|
430,432,435,440,445,
|
||||||
|
450,455,462,470,485,490,
|
||||||
|
507,515,520,525,528,540,550,560,563,570,577,580,595,
|
||||||
602,625,641,662,670,680,682,690,
|
602,625,641,662,670,680,682,690,
|
||||||
705,720,722,730,735,740,745,750,770,795,
|
705,720,722,730,735,740,745,750,770,795,
|
||||||
822,830,862,866,
|
822,830,862,866,
|
||||||
@@ -4090,3 +4092,110 @@ function UTILS.LCGRandom()
|
|||||||
UTILS.lcg.seed = (UTILS.lcg.a * UTILS.lcg.seed + UTILS.lcg.c) % UTILS.lcg.m
|
UTILS.lcg.seed = (UTILS.lcg.a * UTILS.lcg.seed + UTILS.lcg.c) % UTILS.lcg.m
|
||||||
return UTILS.lcg.seed / UTILS.lcg.m
|
return UTILS.lcg.seed / UTILS.lcg.m
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Spawns a new FARP of a defined type and coalition and functional statics (fuel depot, ammo storage, tent, windsock) around that FARP to make it operational.
|
||||||
|
-- Adds vehicles from template if given. Fills the FARP warehouse with liquids and known materiels.
|
||||||
|
-- References: [DCS Forum Topic](https://forum.dcs.world/topic/282989-farp-equipment-to-run-it)
|
||||||
|
-- @param #string Name Name of this FARP installation. Must be unique.
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate Where to spawn the FARP.
|
||||||
|
-- @param #string FARPType Type of FARP, can be one of the known types ENUMS.FARPType.FARP, ENUMS.FARPType.INVISIBLE, ENUMS.FARPType.HELIPADSINGLE, ENUMS.FARPType.PADSINGLE. Defaults to ENUMS.FARPType.FARP.
|
||||||
|
-- @param #number Coalition Coalition of this FARP, i.e. coalition.side.BLUE or coalition.side.RED, defaults to coalition.side.BLUE.
|
||||||
|
-- @param #number Country Country of this FARP, defaults to country.id.USA (blue) or country.id.RUSSIA (red).
|
||||||
|
-- @param #number CallSign Callsign of the FARP ATC, defaults to CALLSIGN.FARP.Berlin.
|
||||||
|
-- @param #number Frequency Frequency of the FARP ATC Radio, defaults to 127.5 (MHz).
|
||||||
|
-- @param #number Modulation Modulation of the FARP ATC Radio, defaults to radio.modulation.AM.
|
||||||
|
-- @param #number ADF ADF Beacon (FM) Frequency in KHz, e.g. 428. If not nil, creates an VHF/FM ADF Beacon for this FARP. Requires a sound called "beacon.ogg" to be in the mission (trigger "sound to" ...)
|
||||||
|
-- @param #number SpawnRadius Radius of the FARP, i.e. where the FARP objects will be placed in meters, not more than 150m away. Defaults to 100.
|
||||||
|
-- @param #string VehicleTemplate, template name for additional vehicles. Can be nil for no additional vehicles.
|
||||||
|
-- @param #number Liquids Tons of fuel to be added initially to the FARP. Defaults to 10 (tons). Set to 0 for no fill.
|
||||||
|
-- @param #number Equipment Number of equipment items per known item to be added initially to the FARP. Defaults to 10 (items). Set to 0 for no fill.
|
||||||
|
-- @return #list<Wrapper.Static#STATIC> Table of spawned objects and vehicle object (if given).
|
||||||
|
-- @return #string ADFBeaconName Name of the ADF beacon, to be able to remove/stop it later.
|
||||||
|
function UTILS.SpawnFARPAndFunctionalStatics(Name,Coordinate,FARPType,Coalition,Country,CallSign,Frequency,Modulation,ADF,SpawnRadius,VehicleTemplate,Liquids,Equipment)
|
||||||
|
|
||||||
|
-- Set Defaults
|
||||||
|
local farplocation = Coordinate
|
||||||
|
local farptype = FARPType or ENUMS.FARPType.FARP
|
||||||
|
local Coalition = Coalition or coalition.side.BLUE
|
||||||
|
local callsign = CallSign or CALLSIGN.FARP.Berlin
|
||||||
|
local freq = Frequency or 127.5
|
||||||
|
local mod = Modulation or radio.modulation.AM
|
||||||
|
local radius = SpawnRadius or 100
|
||||||
|
if radius < 0 or radius > 150 then radius = 100 end
|
||||||
|
local liquids = Liquids or 10
|
||||||
|
liquids = liquids * 1000 -- tons to kg
|
||||||
|
local equip = Equipment or 10
|
||||||
|
local statictypes = ENUMS.FARPObjectTypeNamesAndShape[farptype] or {TypeName="FARP", ShapeName="FARPS"}
|
||||||
|
local STypeName = statictypes.TypeName
|
||||||
|
local SShapeName = statictypes.ShapeName
|
||||||
|
local Country = Country or (Coalition == coalition.side.BLUE and country.id.USA or country.id.RUSSIA)
|
||||||
|
local ReturnObjects = {}
|
||||||
|
|
||||||
|
-- Spawn FARP
|
||||||
|
local newfarp = SPAWNSTATIC:NewFromType(STypeName,"Heliports",Country) -- "Invisible FARP" "FARP"
|
||||||
|
newfarp:InitShape(SShapeName) -- "invisiblefarp" "FARPS"
|
||||||
|
newfarp:InitFARP(callsign,freq,mod)
|
||||||
|
local spawnedfarp = newfarp:SpawnFromCoordinate(farplocation,0,Name)
|
||||||
|
table.insert(ReturnObjects,spawnedfarp)
|
||||||
|
-- Spawn Objects
|
||||||
|
local FARPStaticObjectsNato = {
|
||||||
|
["FUEL"] = { TypeName = "FARP Fuel Depot", ShapeName = "GSM Rus", Category = "Fortifications"},
|
||||||
|
["AMMO"] = { TypeName = "FARP Ammo Dump Coating", ShapeName = "SetkaKP", Category = "Fortifications"},
|
||||||
|
["TENT"] = { TypeName = "FARP Tent", ShapeName = "PalatkaB", Category = "Fortifications"},
|
||||||
|
["WINDSOCK"] = { TypeName = "Windsock", ShapeName = "H-Windsock_RW", Category = "Fortifications"},
|
||||||
|
}
|
||||||
|
|
||||||
|
local farpobcount = 0
|
||||||
|
for _name,_object in pairs(FARPStaticObjectsNato) do
|
||||||
|
local objloc = farplocation:Translate(radius,farpobcount*30)
|
||||||
|
local heading = objloc:HeadingTo(farplocation)
|
||||||
|
local newobject = SPAWNSTATIC:NewFromType(_object.TypeName,_object.Category,Country)
|
||||||
|
newobject:InitShape(_object.ShapeName)
|
||||||
|
newobject:InitHeading(heading)
|
||||||
|
newobject:SpawnFromCoordinate(objloc,farpobcount*30,_name.." - "..Name)
|
||||||
|
table.insert(ReturnObjects,newobject)
|
||||||
|
farpobcount = farpobcount + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Vehicle if any
|
||||||
|
if VehicleTemplate and type(VehicleTemplate) == "string" then
|
||||||
|
local vcoordinate = farplocation:Translate(radius,farpobcount*30)
|
||||||
|
local heading = vcoordinate:HeadingTo(farplocation)
|
||||||
|
local vehicles = SPAWN:NewWithAlias(VehicleTemplate,"FARP Vehicles - "..Name)
|
||||||
|
vehicles:InitGroupHeading(heading)
|
||||||
|
vehicles:InitCountry(Country)
|
||||||
|
vehicles:InitCoalition(Coalition)
|
||||||
|
vehicles:InitDelayOff()
|
||||||
|
local spawnedvehicle = vehicles:SpawnFromCoordinate(vcoordinate)
|
||||||
|
table.insert(ReturnObjects,spawnedvehicle)
|
||||||
|
end
|
||||||
|
|
||||||
|
local newWH = STORAGE:New(Name)
|
||||||
|
if liquids and liquids > 0 then
|
||||||
|
-- Storage fill-up
|
||||||
|
newWH:SetLiquid(STORAGE.Liquid.DIESEL,liquids) -- kgs to tons
|
||||||
|
newWH:SetLiquid(STORAGE.Liquid.GASOLINE,liquids)
|
||||||
|
newWH:SetLiquid(STORAGE.Liquid.JETFUEL,liquids)
|
||||||
|
newWH:SetLiquid(STORAGE.Liquid.MW50,liquids)
|
||||||
|
end
|
||||||
|
|
||||||
|
if equip and equip > 0 then
|
||||||
|
for cat,nitem in pairs(ENUMS.Storage.weapons) do
|
||||||
|
for name,item in pairs(nitem) do
|
||||||
|
newWH:SetItem(item,equip)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ADFName
|
||||||
|
if ADF and type(ADF) == "number" then
|
||||||
|
local ADFFreq = ADF*1000 -- KHz to Hz
|
||||||
|
local Sound = "l10n/DEFAULT/beacon.ogg"
|
||||||
|
local vec3 = farplocation:GetVec3()
|
||||||
|
ADFName = Name .. " ADF "..tostring(ADF).."KHz"
|
||||||
|
--BASE:I(string.format("Adding FARP Beacon %d KHz Name %s",ADF,ADFName))
|
||||||
|
trigger.action.radioTransmission(Sound, vec3, 0, true, ADFFreq, 250, ADFName)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ReturnObjects, ADFName
|
||||||
|
end
|
||||||
|
|||||||
@@ -176,6 +176,9 @@
|
|||||||
-- ## 5.5) Air-2-Air missile attack range:
|
-- ## 5.5) Air-2-Air missile attack range:
|
||||||
-- * @{#CONTROLLABLE.OptionAAAttackRange}(): Defines the usage of A2A missiles against possible targets.
|
-- * @{#CONTROLLABLE.OptionAAAttackRange}(): Defines the usage of A2A missiles against possible targets.
|
||||||
--
|
--
|
||||||
|
-- # 6) [GROUND] IR Maker Beacons for GROUPs and UNITs
|
||||||
|
-- * @{#CONTROLLABLE:NewIRMarker}(): Create a blinking IR Marker on a GROUP or UNIT.
|
||||||
|
--
|
||||||
-- @field #CONTROLLABLE
|
-- @field #CONTROLLABLE
|
||||||
CONTROLLABLE = {
|
CONTROLLABLE = {
|
||||||
ClassName = "CONTROLLABLE",
|
ClassName = "CONTROLLABLE",
|
||||||
@@ -5619,3 +5622,128 @@ function CONTROLLABLE:PatrolRaceTrack(Point1, Point2, Altitude, Speed, Formation
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- IR Marker courtesy Florian Brinker (fbrinker)
|
||||||
|
|
||||||
|
--- [GROUND] Create and enable a new IR Marker for the given controllable UNIT or GROUP.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @param #boolean EnableImmediately (Optionally) If true start up the IR Marker immediately. Else you need to call `myobject:EnableIRMarker()` later on.
|
||||||
|
-- @param #number Runtime (Optionally) Run this IR Marker for the given number of seconds, then stop. Use in conjunction with EnableImmediately.
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:NewIRMarker(EnableImmediately, Runtime)
|
||||||
|
--sefl:F("NewIRMarker")
|
||||||
|
if self.ClassName == "GROUP" then
|
||||||
|
self.IRMarkerGroup = true
|
||||||
|
self.IRMarkerUnit = false
|
||||||
|
elseif self.ClassName == "UNIT" then
|
||||||
|
self.IRMarkerGroup = false
|
||||||
|
self.IRMarkerUnit = true
|
||||||
|
end
|
||||||
|
|
||||||
|
self.spot = nil
|
||||||
|
self.timer = nil
|
||||||
|
self.stoptimer = nil
|
||||||
|
|
||||||
|
if EnableImmediately and EnableImmediately == true then
|
||||||
|
self:EnableIRMarker(Runtime)
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [GROUND] Enable the IR marker.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @param #number Runtime (Optionally) Run this IR Marker for the given number of seconds, then stop. Else run until you call `myobject:DisableIRMarker()`.
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:EnableIRMarker(Runtime)
|
||||||
|
--sefl:F("EnableIRMarker")
|
||||||
|
if self.IRMarkerGroup == nil then
|
||||||
|
self:NewIRMarker(true,Runtime)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if (self.IRMarkerGroup == true) then
|
||||||
|
self:EnableIRMarkerForGroup()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self.timer = TIMER:New(CONTROLLABLE._MarkerBlink, self)
|
||||||
|
self.timer:Start(nil, 1 - math.random(1, 5) / 10 / 2, Runtime) -- start randomized
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [GROUND] Disable the IR marker.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:DisableIRMarker()
|
||||||
|
--sefl:F("DisableIRMarker")
|
||||||
|
if (self.IRMarkerGroup == true) then
|
||||||
|
self:DisableIRMarkerForGroup()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.spot then
|
||||||
|
self.spot:destroy()
|
||||||
|
self.spot = nil
|
||||||
|
if self.timer and self.timer:IsRunning() then
|
||||||
|
self.timer:Stop()
|
||||||
|
self.timer = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [GROUND] Enable the IR markers for a whole group.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:EnableIRMarkerForGroup()
|
||||||
|
--sefl:F("EnableIRMarkerForGroup")
|
||||||
|
if self.ClassName == "GROUP" then
|
||||||
|
local units = self:GetUnits() or {}
|
||||||
|
for _,_unit in pairs(units) do
|
||||||
|
_unit:EnableIRMarker()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [GROUND] Disable the IR markers for a whole group.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:DisableIRMarkerForGroup()
|
||||||
|
--sefl:F("DisableIRMarkerForGroup")
|
||||||
|
if self.ClassName == "GROUP" then
|
||||||
|
local units = self:GetUnits() or {}
|
||||||
|
for _,_unit in pairs(units) do
|
||||||
|
_unit:DisableIRMarker()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [Internal] This method is called by the scheduler after enabling the IR marker.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:_MarkerBlink()
|
||||||
|
--sefl:F("_MarkerBlink")
|
||||||
|
if self:IsAlive() ~= true then
|
||||||
|
self:DisableIRMarker()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self.timer.dT = 1 - (math.random(1, 2) / 10 / 2) -- randomize the blinking by a small amount
|
||||||
|
|
||||||
|
local _, _, unitBBHeight, _ = self:GetObjectSize()
|
||||||
|
local unitPos = self:GetPositionVec3()
|
||||||
|
|
||||||
|
self.spot = Spot.createInfraRed(
|
||||||
|
self.DCSUnit,
|
||||||
|
{ x = 0, y = (unitBBHeight + 1), z = 0 },
|
||||||
|
{ x = unitPos.x, y = (unitPos.y + unitBBHeight), z = unitPos.z }
|
||||||
|
)
|
||||||
|
|
||||||
|
local offTimer = TIMER:New(function() if self.spot then self.spot:destroy() end end)
|
||||||
|
offTimer:Start(0.5)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|||||||
@@ -0,0 +1,501 @@
|
|||||||
|
--- **Wrapper** - Dynamic Cargo create from the F8 menu.
|
||||||
|
--
|
||||||
|
-- ## Main Features:
|
||||||
|
--
|
||||||
|
-- * Convenient access to DCS API functions
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ## Example Missions:
|
||||||
|
--
|
||||||
|
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_Demos/tree/master/Wrapper/Storage).
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **Applevangelist**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
-- @module Wrapper.DynamicCargo
|
||||||
|
-- @image Wrapper_Storage.png
|
||||||
|
|
||||||
|
|
||||||
|
--- DYNAMICCARGO class.
|
||||||
|
-- @type DYNAMICCARGO
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field #number verbose Verbosity level.
|
||||||
|
-- @field #string lid Class id string for output to DCS log file.
|
||||||
|
-- @field Wrapper.Storage#STORAGE warehouse The STORAGE object.
|
||||||
|
-- @field #string version.
|
||||||
|
-- @field #string CargoState.
|
||||||
|
-- @field #table DCS#Vec3 LastPosition.
|
||||||
|
-- @field #number Interval Check Interval. 20 secs default.
|
||||||
|
-- @field #boolean testing
|
||||||
|
-- @field Core.Timer#TIMER timer Timmer to run intervals
|
||||||
|
-- @field #string Owner The playername who has created, loaded or unloaded this cargo. Depends on state.
|
||||||
|
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||||
|
|
||||||
|
--- *The capitalist cannot store labour-power in warehouses after he has bought it, as he may do with the raw material.* -- Karl Marx
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- # The DYNAMICCARGO Concept
|
||||||
|
--
|
||||||
|
-- The DYNAMICCARGO class offers an easy-to-use wrapper interface to all DCS API functions of DCS dynamically spawned cargo crates.
|
||||||
|
-- We named the class DYNAMICCARGO, because the name WAREHOUSE is already taken by another MOOSE class..
|
||||||
|
--
|
||||||
|
-- # Constructor
|
||||||
|
--
|
||||||
|
-- @field #DYNAMICCARGO
|
||||||
|
DYNAMICCARGO = {
|
||||||
|
ClassName = "DYNAMICCARGO",
|
||||||
|
verbose = 0,
|
||||||
|
testing = false,
|
||||||
|
Interval = 10,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Liquid types.
|
||||||
|
-- @type DYNAMICCARGO.Liquid
|
||||||
|
-- @field #number JETFUEL Jet fuel (0).
|
||||||
|
-- @field #number GASOLINE Aviation gasoline (1).
|
||||||
|
-- @field #number MW50 MW50 (2).
|
||||||
|
-- @field #number DIESEL Diesel (3).
|
||||||
|
DYNAMICCARGO.Liquid = {
|
||||||
|
JETFUEL = 0,
|
||||||
|
GASOLINE = 1,
|
||||||
|
MW50 = 2,
|
||||||
|
DIESEL = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Liquid Names for the static cargo resource table.
|
||||||
|
-- @type DYNAMICCARGO.LiquidName
|
||||||
|
-- @field #number JETFUEL "jet_fuel".
|
||||||
|
-- @field #number GASOLINE "gasoline".
|
||||||
|
-- @field #number MW50 "methanol_mixture".
|
||||||
|
-- @field #number DIESEL "diesel".
|
||||||
|
DYNAMICCARGO.LiquidName = {
|
||||||
|
GASOLINE = "gasoline",
|
||||||
|
DIESEL = "diesel",
|
||||||
|
MW50 = "methanol_mixture",
|
||||||
|
JETFUEL = "jet_fuel",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Storage types.
|
||||||
|
-- @type DYNAMICCARGO.Type
|
||||||
|
-- @field #number WEAPONS weapons.
|
||||||
|
-- @field #number LIQUIDS liquids. Also see #list<#DYNAMICCARGO.Liquid> for types of liquids.
|
||||||
|
-- @field #number AIRCRAFT aircraft.
|
||||||
|
DYNAMICCARGO.Type = {
|
||||||
|
WEAPONS = "weapons",
|
||||||
|
LIQUIDS = "liquids",
|
||||||
|
AIRCRAFT = "aircrafts",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- State types
|
||||||
|
-- @type DYNAMICCARGO.State
|
||||||
|
-- @field #string NEW
|
||||||
|
-- @field #string LOADED
|
||||||
|
-- @field #string UNLOADED
|
||||||
|
-- @field #string REMOVED
|
||||||
|
DYNAMICCARGO.State = {
|
||||||
|
NEW = "NEW",
|
||||||
|
LOADED = "LOADED",
|
||||||
|
UNLOADED = "UNLOADED",
|
||||||
|
REMOVED = "REMOVED",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Helo types possible.
|
||||||
|
-- @type DYNAMICCARGO.AircraftTypes
|
||||||
|
DYNAMICCARGO.AircraftTypes = {
|
||||||
|
["CH-47Fbl1"] = "CH-47Fbl1",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Helo types possible.
|
||||||
|
-- @type DYNAMICCARGO.AircraftDimensions
|
||||||
|
DYNAMICCARGO.AircraftDimensions = {
|
||||||
|
-- CH-47 model start coordinate is quite exactly in the middle of the model, so half values here
|
||||||
|
["CH-47Fbl1"] = {
|
||||||
|
["width"] = 4,
|
||||||
|
["height"] = 6,
|
||||||
|
["length"] = 11,
|
||||||
|
["ropelength"] = 30,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
--- DYNAMICCARGO class version.
|
||||||
|
-- @field #string version
|
||||||
|
DYNAMICCARGO.version="0.0.5"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- TODO list
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- TODO: A lot...
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Constructor
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Create a new DYNAMICCARGO object from the DCS static cargo object.
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @param #string CargoName Name of the Cargo.
|
||||||
|
-- @return #DYNAMICCARGO self
|
||||||
|
function DYNAMICCARGO:Register(CargoName)
|
||||||
|
|
||||||
|
-- Inherit everything from a BASE class.
|
||||||
|
local self=BASE:Inherit(self, POSITIONABLE:New(CargoName)) -- #DYNAMICCARGO
|
||||||
|
|
||||||
|
self.StaticName = CargoName
|
||||||
|
|
||||||
|
self.LastPosition = self:GetCoordinate()
|
||||||
|
|
||||||
|
self.CargoState = DYNAMICCARGO.State.NEW
|
||||||
|
|
||||||
|
self.Interval = DYNAMICCARGO.Interval or 10
|
||||||
|
|
||||||
|
local DCSObject = self:GetDCSObject()
|
||||||
|
|
||||||
|
if DCSObject then
|
||||||
|
local warehouse = STORAGE:NewFromDynamicCargo(CargoName)
|
||||||
|
self.warehouse = warehouse
|
||||||
|
end
|
||||||
|
|
||||||
|
self.lid = string.format("DYNAMICCARGO %s", CargoName)
|
||||||
|
|
||||||
|
self.Owner = string.match(CargoName,"^(.+)|%d%d:%d%d|PKG%d+") or "None"
|
||||||
|
|
||||||
|
self.timer = TIMER:New(DYNAMICCARGO._UpdatePosition,self)
|
||||||
|
self.timer:Start(self.Interval,self.Interval)
|
||||||
|
|
||||||
|
if not _DYNAMICCARGO_HELOS then
|
||||||
|
_DYNAMICCARGO_HELOS = SET_CLIENT:New():FilterAlive():FilterFunction(DYNAMICCARGO._FilterHeloTypes):FilterStart()
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.testing then
|
||||||
|
BASE:TraceOn()
|
||||||
|
BASE:TraceClass("DYNAMICCARGO")
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get DCS object.
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return DCS static object
|
||||||
|
function DYNAMICCARGO:GetDCSObject()
|
||||||
|
local DCSStatic = Unit.getByName( self.StaticName )
|
||||||
|
if DCSStatic then
|
||||||
|
return DCSStatic
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- User API Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Get last known owner name of this DYNAMICCARGO
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return #string Owner
|
||||||
|
function DYNAMICCARGO:GetLastOwner()
|
||||||
|
return self.Owner
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns true if the cargo is new and has never been loaded into a Helo.
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return #boolean Outcome
|
||||||
|
function DYNAMICCARGO:IsNew()
|
||||||
|
if self.CargoState and self.CargoState == DYNAMICCARGO.State.NEW then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns true if the cargo been loaded into a Helo.
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return #boolean Outcome
|
||||||
|
function DYNAMICCARGO:IsLoaded()
|
||||||
|
if self.CargoState and self.CargoState == DYNAMICCARGO.State.LOADED then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns true if the cargo has been unloaded from a Helo.
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return #boolean Outcome
|
||||||
|
function DYNAMICCARGO:IsUnloaded()
|
||||||
|
if self.CargoState and self.CargoState == DYNAMICCARGO.State.REMOVED then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns true if the cargo has been removed.
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return #boolean Outcome
|
||||||
|
function DYNAMICCARGO:IsRemoved()
|
||||||
|
if self.CargoState and self.CargoState == DYNAMICCARGO.State.UNLOADED then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [CTLD] Get number of crates this DYNAMICCARGO consists of. Always one.
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return #number crate number, always one
|
||||||
|
function DYNAMICCARGO:GetCratesNeeded()
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [CTLD] Get this DYNAMICCARGO drop state. True if DYNAMICCARGO.State.UNLOADED
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return #boolean Dropped
|
||||||
|
function DYNAMICCARGO:WasDropped()
|
||||||
|
return self.CargoState == DYNAMICCARGO.State.UNLOADED and true or false
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [CTLD] Get CTLD_CARGO.Enum type of this DYNAMICCARGO
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return #string Type, only one at the moment is CTLD_CARGO.Enum.GCLOADABLE
|
||||||
|
function DYNAMICCARGO:GetType()
|
||||||
|
return CTLD_CARGO.Enum.GCLOADABLE
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Find last known position of this DYNAMICCARGO
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return DCS#Vec3 Position in 3D space
|
||||||
|
function DYNAMICCARGO:GetLastPosition()
|
||||||
|
return self.LastPosition
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Find current state of this DYNAMICCARGO
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return string The current state
|
||||||
|
function DYNAMICCARGO:GetState()
|
||||||
|
return self.CargoState
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Find a DYNAMICCARGO in the **_DATABASE** using the name associated with it.
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @param #string Name The dynamic cargo name
|
||||||
|
-- @return #DYNAMICCARGO self
|
||||||
|
function DYNAMICCARGO:FindByName( Name )
|
||||||
|
local storage = _DATABASE:FindDynamicCargo( Name )
|
||||||
|
return storage
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Find the first(!) DYNAMICCARGO matching using patterns. Note that this is **a lot** slower than `:FindByName()`!
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @param #string Pattern The pattern to look for. Refer to [LUA patterns](http://www.easyuo.com/openeuo/wiki/index.php/Lua_Patterns_and_Captures_\(Regular_Expressions\)) for regular expressions in LUA.
|
||||||
|
-- @return #DYNAMICCARGO The DYNAMICCARGO.
|
||||||
|
-- @usage
|
||||||
|
-- -- Find a dynamic cargo with a partial dynamic cargo name
|
||||||
|
-- local grp = DYNAMICCARGO:FindByMatching( "Apple" )
|
||||||
|
-- -- will return e.g. a dynamic cargo named "Apple|08:00|PKG08"
|
||||||
|
--
|
||||||
|
-- -- using a pattern
|
||||||
|
-- local grp = DYNAMICCARGO:FindByMatching( ".%d.%d$" )
|
||||||
|
-- -- will return the first dynamic cargo found ending in "-1-1" to "-9-9", but not e.g. "-10-1"
|
||||||
|
function DYNAMICCARGO:FindByMatching( Pattern )
|
||||||
|
local GroupFound = nil
|
||||||
|
|
||||||
|
for name,static in pairs(_DATABASE.DYNAMICCARGO) do
|
||||||
|
if string.match(name, Pattern ) then
|
||||||
|
GroupFound = static
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return GroupFound
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Find all DYNAMICCARGO objects matching using patterns. Note that this is **a lot** slower than `:FindByName()`!
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @param #string Pattern The pattern to look for. Refer to [LUA patterns](http://www.easyuo.com/openeuo/wiki/index.php/Lua_Patterns_and_Captures_\(Regular_Expressions\)) for regular expressions in LUA.
|
||||||
|
-- @return #table Groups Table of matching #DYNAMICCARGO objects found
|
||||||
|
-- @usage
|
||||||
|
-- -- Find all dynamic cargo with a partial dynamic cargo name
|
||||||
|
-- local grptable = DYNAMICCARGO:FindAllByMatching( "Apple" )
|
||||||
|
-- -- will return all dynamic cargos with "Apple" in the name
|
||||||
|
--
|
||||||
|
-- -- using a pattern
|
||||||
|
-- local grp = DYNAMICCARGO:FindAllByMatching( ".%d.%d$" )
|
||||||
|
-- -- will return the all dynamic cargos found ending in "-1-1" to "-9-9", but not e.g. "-10-1" or "-1-10"
|
||||||
|
function DYNAMICCARGO:FindAllByMatching( Pattern )
|
||||||
|
local GroupsFound = {}
|
||||||
|
|
||||||
|
for name,static in pairs(_DATABASE.DYNAMICCARGO) do
|
||||||
|
if string.match(name, Pattern ) then
|
||||||
|
GroupsFound[#GroupsFound+1] = static
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return GroupsFound
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the #STORAGE object from this dynamic cargo.
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return Wrapper.Storage#STORAGE Storage The #STORAGE object
|
||||||
|
function DYNAMICCARGO:GetStorageObject()
|
||||||
|
return self.warehouse
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the weight in kgs from this dynamic cargo.
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return #number Weight in kgs.
|
||||||
|
function DYNAMICCARGO:GetCargoWeight()
|
||||||
|
local DCSObject = self:GetDCSObject()
|
||||||
|
if DCSObject then
|
||||||
|
local weight = DCSObject:getCargoWeight()
|
||||||
|
return weight
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the cargo display name from this dynamic cargo.
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return #string The display name
|
||||||
|
function DYNAMICCARGO:GetCargoDisplayName()
|
||||||
|
local DCSObject = self:GetDCSObject()
|
||||||
|
if DCSObject then
|
||||||
|
local weight = DCSObject:getCargoDisplayName()
|
||||||
|
return weight
|
||||||
|
else
|
||||||
|
return self.StaticName
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Private Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- [Internal] _Get Possible Player Helo Nearby
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @param Core.Point#COORDINATE pos
|
||||||
|
-- @param #boolean loading If true measure distance for loading else for unloading
|
||||||
|
-- @return #boolean Success
|
||||||
|
-- @return Wrapper.Client#CLIENT Helo
|
||||||
|
-- @return #string PlayerName
|
||||||
|
function DYNAMICCARGO:_GetPossibleHeloNearby(pos,loading)
|
||||||
|
local set = _DYNAMICCARGO_HELOS:GetAliveSet()
|
||||||
|
local success = false
|
||||||
|
local Helo = nil
|
||||||
|
local Playername = nil
|
||||||
|
for _,_helo in pairs (set or {}) do
|
||||||
|
local helo = _helo -- Wrapper.Client#CLIENT
|
||||||
|
local name = helo:GetPlayerName() or _DATABASE:_FindPlayerNameByUnitName(helo:GetName()) or "None"
|
||||||
|
self:T(self.lid.." Checking: "..name)
|
||||||
|
local hpos = helo:GetCoordinate()
|
||||||
|
-- TODO Unloading via sling load?
|
||||||
|
--local inair = hpos.y-hpos:GetLandHeight() > 4.5 and true or false -- Standard FARP is 4.5m
|
||||||
|
local inair = helo:InAir()
|
||||||
|
self:T(self.lid.." InAir: AGL/InAir: "..hpos.y-hpos:GetLandHeight().."/"..tostring(inair))
|
||||||
|
local typename = helo:GetTypeName()
|
||||||
|
if hpos and typename and inair == false then
|
||||||
|
local dimensions = DYNAMICCARGO.AircraftDimensions[typename]
|
||||||
|
if dimensions then
|
||||||
|
local delta2D = hpos:Get2DDistance(pos)
|
||||||
|
local delta3D = hpos:Get3DDistance(pos)
|
||||||
|
if self.testing then
|
||||||
|
self:T(string.format("Cargo relative position: 2D %dm | 3D %dm",delta2D,delta3D))
|
||||||
|
self:T(string.format("Helo dimension: length %dm | width %dm | rope %dm",dimensions.length,dimensions.width,dimensions.ropelength))
|
||||||
|
end
|
||||||
|
if loading~=true and delta2D > dimensions.length or delta2D > dimensions.width or delta3D > dimensions.ropelength then
|
||||||
|
success = true
|
||||||
|
Helo = helo
|
||||||
|
Playername = name
|
||||||
|
end
|
||||||
|
if loading == true and delta2D < dimensions.length or delta2D < dimensions.width or delta3D < dimensions.ropelength then
|
||||||
|
success = true
|
||||||
|
Helo = helo
|
||||||
|
Playername = name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return success,Helo,Playername
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [Internal] Update internal states.
|
||||||
|
-- @param #DYNAMICCARGO self
|
||||||
|
-- @return #DYNAMICCARGO self
|
||||||
|
function DYNAMICCARGO:_UpdatePosition()
|
||||||
|
self:T(self.lid.." _UpdatePositionAndState")
|
||||||
|
if self:IsAlive() then
|
||||||
|
local pos = self:GetCoordinate()
|
||||||
|
if self.testing then
|
||||||
|
self:T(string.format("Cargo position: x=%d, y=%d, z=%d",pos.x,pos.y,pos.z))
|
||||||
|
self:T(string.format("Last position: x=%d, y=%d, z=%d",self.LastPosition.x,self.LastPosition.y,self.LastPosition.z))
|
||||||
|
end
|
||||||
|
if UTILS.Round(UTILS.VecDist3D(pos,self.LastPosition),2) > 0.5 then
|
||||||
|
---------------
|
||||||
|
-- LOAD Cargo
|
||||||
|
---------------
|
||||||
|
if self.CargoState == DYNAMICCARGO.State.NEW then
|
||||||
|
local isloaded, client, playername = self:_GetPossibleHeloNearby(pos,true)
|
||||||
|
self:T(self.lid.." moved! NEW -> LOADED by "..tostring(playername))
|
||||||
|
self.CargoState = DYNAMICCARGO.State.LOADED
|
||||||
|
self.Owner = playername
|
||||||
|
_DATABASE:CreateEventDynamicCargoLoaded(self)
|
||||||
|
---------------
|
||||||
|
-- UNLOAD Cargo
|
||||||
|
---------------
|
||||||
|
elseif self.CargoState == DYNAMICCARGO.State.LOADED then
|
||||||
|
-- TODO add checker if we are in flight somehow
|
||||||
|
-- ensure not just the helo is moving
|
||||||
|
local count = _DYNAMICCARGO_HELOS:CountAlive()
|
||||||
|
-- Testing
|
||||||
|
local landheight = pos:GetLandHeight()
|
||||||
|
local agl = pos.y-landheight
|
||||||
|
agl = UTILS.Round(agl,2)
|
||||||
|
self:T(self.lid.." AGL: "..agl or -1)
|
||||||
|
local isunloaded = true
|
||||||
|
local client
|
||||||
|
local playername
|
||||||
|
if count > 0 and (agl > 0 or self.testing) then
|
||||||
|
self:T(self.lid.." Possible alive helos: "..count or -1)
|
||||||
|
if agl ~= 0 or self.testing then
|
||||||
|
isunloaded, client, playername = self:_GetPossibleHeloNearby(pos,false)
|
||||||
|
end
|
||||||
|
if isunloaded then
|
||||||
|
self:T(self.lid.." moved! LOADED -> UNLOADED by "..tostring(playername))
|
||||||
|
self.CargoState = DYNAMICCARGO.State.UNLOADED
|
||||||
|
self.Owner = playername
|
||||||
|
_DATABASE:CreateEventDynamicCargoUnloaded(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.LastPosition = pos
|
||||||
|
end
|
||||||
|
else
|
||||||
|
---------------
|
||||||
|
-- REMOVED Cargo
|
||||||
|
---------------
|
||||||
|
if self.timer and self.timer:IsRunning() then self.timer:Stop() end
|
||||||
|
self:T(self.lid.." dead! " ..self.CargoState.."-> REMOVED")
|
||||||
|
self.CargoState = DYNAMICCARGO.State.REMOVED
|
||||||
|
_DATABASE:CreateEventDynamicCargoRemoved(self)
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [Internal] Track helos for loaded/unloaded decision making.
|
||||||
|
-- @param Wrapper.Client#CLIENT client
|
||||||
|
-- @return #boolean IsIn
|
||||||
|
function DYNAMICCARGO._FilterHeloTypes(client)
|
||||||
|
if not client then return false end
|
||||||
|
local typename = client:GetTypeName()
|
||||||
|
local isinclude = DYNAMICCARGO.AircraftTypes[typename] ~= nil and true or false
|
||||||
|
return isinclude
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -360,14 +360,25 @@ end
|
|||||||
-- @return DCS#Group The DCS Group.
|
-- @return DCS#Group The DCS Group.
|
||||||
function GROUP:GetDCSObject()
|
function GROUP:GetDCSObject()
|
||||||
|
|
||||||
|
if (not self.LastCallDCSObject) or (self.LastCallDCSObject and timer.getTime() - self.LastCallDCSObject > 1) then
|
||||||
|
|
||||||
-- Get DCS group.
|
-- Get DCS group.
|
||||||
local DCSGroup = Group.getByName( self.GroupName )
|
local DCSGroup = Group.getByName( self.GroupName )
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
|
self.LastCallDCSObject = timer.getTime()
|
||||||
|
self.DCSObject = DCSGroup
|
||||||
return DCSGroup
|
return DCSGroup
|
||||||
|
else
|
||||||
|
self.DCSObject = nil
|
||||||
|
self.LastCallDCSObject = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T2(string.format("ERROR: Could not get DCS group object of group %s because DCS object could not be found!", tostring(self.GroupName)))
|
else
|
||||||
|
return self.DCSObject
|
||||||
|
end
|
||||||
|
|
||||||
|
--self:E(string.format("ERROR: Could not get DCS group object of group %s because DCS object could not be found!", tostring(self.GroupName)))
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -375,7 +386,7 @@ end
|
|||||||
-- @param Wrapper.Positionable#POSITIONABLE self
|
-- @param Wrapper.Positionable#POSITIONABLE self
|
||||||
-- @return DCS#Position The 3D position vectors of the POSITIONABLE or #nil if the groups not existing or alive.
|
-- @return DCS#Position The 3D position vectors of the POSITIONABLE or #nil if the groups not existing or alive.
|
||||||
function GROUP:GetPositionVec3() -- Overridden from POSITIONABLE:GetPositionVec3()
|
function GROUP:GetPositionVec3() -- Overridden from POSITIONABLE:GetPositionVec3()
|
||||||
self:F2( self.PositionableName )
|
--self:F2( self.PositionableName )
|
||||||
|
|
||||||
local DCSPositionable = self:GetDCSObject()
|
local DCSPositionable = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -383,7 +394,7 @@ function GROUP:GetPositionVec3() -- Overridden from POSITIONABLE:GetPositionVec3
|
|||||||
local unit = DCSPositionable:getUnits()[1]
|
local unit = DCSPositionable:getUnits()[1]
|
||||||
if unit then
|
if unit then
|
||||||
local PositionablePosition = unit:getPosition().p
|
local PositionablePosition = unit:getPosition().p
|
||||||
self:T3( PositionablePosition )
|
--self:T3( PositionablePosition )
|
||||||
return PositionablePosition
|
return PositionablePosition
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -403,7 +414,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #boolean `true` if the group is alive *and* active, `false` if the group is alive but inactive or `#nil` if the group does not exist anymore.
|
-- @return #boolean `true` if the group is alive *and* active, `false` if the group is alive but inactive or `#nil` if the group does not exist anymore.
|
||||||
function GROUP:IsAlive()
|
function GROUP:IsAlive()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject() -- DCS#Group
|
local DCSGroup = self:GetDCSObject() -- DCS#Group
|
||||||
|
|
||||||
@@ -412,7 +423,7 @@ function GROUP:IsAlive()
|
|||||||
local DCSUnit = DCSGroup:getUnit(1) -- DCS#Unit
|
local DCSUnit = DCSGroup:getUnit(1) -- DCS#Unit
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
local GroupIsAlive = DCSUnit:isActive()
|
local GroupIsAlive = DCSUnit:isActive()
|
||||||
self:T3( GroupIsAlive )
|
--self:T3( GroupIsAlive )
|
||||||
return GroupIsAlive
|
return GroupIsAlive
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -425,7 +436,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #boolean `true` if group is activated or `#nil` The group is not existing or alive.
|
-- @return #boolean `true` if group is activated or `#nil` The group is not existing or alive.
|
||||||
function GROUP:IsActive()
|
function GROUP:IsActive()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject() -- DCS#Group
|
local DCSGroup = self:GetDCSObject() -- DCS#Group
|
||||||
|
|
||||||
@@ -468,7 +479,7 @@ end
|
|||||||
-- Ship:Destroy( false ) -- Don't generate an event upon destruction.
|
-- Ship:Destroy( false ) -- Don't generate an event upon destruction.
|
||||||
--
|
--
|
||||||
function GROUP:Destroy( GenerateEvent, delay )
|
function GROUP:Destroy( GenerateEvent, delay )
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
if delay and delay>0 then
|
if delay and delay>0 then
|
||||||
self:ScheduleOnce(delay, GROUP.Destroy, self, GenerateEvent)
|
self:ScheduleOnce(delay, GROUP.Destroy, self, GenerateEvent)
|
||||||
@@ -511,12 +522,12 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return DCS#Group.Category The category ID.
|
-- @return DCS#Group.Category The category ID.
|
||||||
function GROUP:GetCategory()
|
function GROUP:GetCategory()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local GroupCategory = DCSGroup:getCategory()
|
local GroupCategory = DCSGroup:getCategory()
|
||||||
self:T3( GroupCategory )
|
--self:T3( GroupCategory )
|
||||||
return GroupCategory
|
return GroupCategory
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -527,7 +538,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship, Train.
|
-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship, Train.
|
||||||
function GROUP:GetCategoryName()
|
function GROUP:GetCategoryName()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
@@ -539,7 +550,7 @@ function GROUP:GetCategoryName()
|
|||||||
[Group.Category.TRAIN] = "Train",
|
[Group.Category.TRAIN] = "Train",
|
||||||
}
|
}
|
||||||
local GroupCategory = DCSGroup:getCategory()
|
local GroupCategory = DCSGroup:getCategory()
|
||||||
self:T3( GroupCategory )
|
--self:T3( GroupCategory )
|
||||||
|
|
||||||
return CategoryNames[GroupCategory]
|
return CategoryNames[GroupCategory]
|
||||||
end
|
end
|
||||||
@@ -547,20 +558,22 @@ function GROUP:GetCategoryName()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns the coalition of the DCS Group.
|
--- Returns the coalition of the DCS Group.
|
||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return DCS#coalition.side The coalition side of the DCS Group.
|
-- @return DCS#coalition.side The coalition side of the DCS Group.
|
||||||
function GROUP:GetCoalition()
|
function GROUP:GetCoalition()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
if self.GroupCoalition ~= nil then
|
||||||
|
return self.GroupCoalition
|
||||||
|
else
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local GroupCoalition = DCSGroup:getCoalition()
|
local GroupCoalition = DCSGroup:getCoalition()
|
||||||
self:T3( GroupCoalition )
|
--self:T3( GroupCoalition )
|
||||||
|
self.GroupCoalition = GroupCoalition
|
||||||
return GroupCoalition
|
return GroupCoalition
|
||||||
end
|
end
|
||||||
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -568,12 +581,12 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return DCS#country.id The country identifier or nil if the DCS Group is not existing or alive.
|
-- @return DCS#country.id The country identifier or nil if the DCS Group is not existing or alive.
|
||||||
function GROUP:GetCountry()
|
function GROUP:GetCountry()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local GroupCountry = DCSGroup:getUnit(1):getCountry()
|
local GroupCountry = DCSGroup:getUnit(1):getCountry()
|
||||||
self:T3( GroupCountry )
|
--self:T3( GroupCountry )
|
||||||
return GroupCountry
|
return GroupCountry
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -625,7 +638,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #number Speed in km/h.
|
-- @return #number Speed in km/h.
|
||||||
function GROUP:GetSpeedMax()
|
function GROUP:GetSpeedMax()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
@@ -658,7 +671,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #number Range in meters.
|
-- @return #number Range in meters.
|
||||||
function GROUP:GetRange()
|
function GROUP:GetRange()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
@@ -689,7 +702,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #table of Wrapper.Unit#UNIT objects, indexed by number.
|
-- @return #table of Wrapper.Unit#UNIT objects, indexed by number.
|
||||||
function GROUP:GetUnits()
|
function GROUP:GetUnits()
|
||||||
self:F2( { self.GroupName } )
|
--self:F2( { self.GroupName } )
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
@@ -706,7 +719,7 @@ function GROUP:GetUnits()
|
|||||||
Units[#Units+1]=unit
|
Units[#Units+1]=unit
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self:T3( Units )
|
--self:T3( Units )
|
||||||
return Units
|
return Units
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -717,7 +730,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #list<Wrapper.Unit#UNIT> The list of player occupied @{Wrapper.Unit} objects of the @{Wrapper.Group}.
|
-- @return #list<Wrapper.Unit#UNIT> The list of player occupied @{Wrapper.Unit} objects of the @{Wrapper.Group}.
|
||||||
function GROUP:GetPlayerUnits()
|
function GROUP:GetPlayerUnits()
|
||||||
self:F2( { self.GroupName } )
|
--self:F2( { self.GroupName } )
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
@@ -729,7 +742,7 @@ function GROUP:GetPlayerUnits()
|
|||||||
Units[#Units+1] = PlayerUnit
|
Units[#Units+1] = PlayerUnit
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self:T3( Units )
|
--self:T3( Units )
|
||||||
return Units
|
return Units
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -828,7 +841,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #number Number of alive units. If DCS group is nil, 0 is returned.
|
-- @return #number Number of alive units. If DCS group is nil, 0 is returned.
|
||||||
function GROUP:CountAliveUnits()
|
function GROUP:CountAliveUnits()
|
||||||
self:F3( { self.GroupName } )
|
--self:F3( { self.GroupName } )
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
@@ -850,7 +863,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return Wrapper.Unit#UNIT First unit alive.
|
-- @return Wrapper.Unit#UNIT First unit alive.
|
||||||
function GROUP:GetFirstUnitAlive()
|
function GROUP:GetFirstUnitAlive()
|
||||||
self:F3({self.GroupName})
|
--self:F3({self.GroupName})
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
@@ -870,7 +883,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return Wrapper.Unit#UNIT First unit or nil if it does not exist.
|
-- @return Wrapper.Unit#UNIT First unit or nil if it does not exist.
|
||||||
function GROUP:GetFirstUnit()
|
function GROUP:GetFirstUnit()
|
||||||
self:F3({self.GroupName})
|
--self:F3({self.GroupName})
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
@@ -885,7 +898,7 @@ end
|
|||||||
-- @param Wrapper.Group#GROUP self
|
-- @param Wrapper.Group#GROUP self
|
||||||
-- @return DCS#Vec3 The velocity Vec3 vector or `#nil` if the GROUP is not existing or alive.
|
-- @return DCS#Vec3 The velocity Vec3 vector or `#nil` if the GROUP is not existing or alive.
|
||||||
function GROUP:GetVelocityVec3()
|
function GROUP:GetVelocityVec3()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -919,7 +932,7 @@ end
|
|||||||
-- @param #boolean FromGround Measure from the ground or from sea level (ASL). Provide **true** for measuring from the ground (AGL). **false** or **nil** if you measure from sea level.
|
-- @param #boolean FromGround Measure from the ground or from sea level (ASL). Provide **true** for measuring from the ground (AGL). **false** or **nil** if you measure from sea level.
|
||||||
-- @return #number The altitude of the group or nil if is not existing or alive.
|
-- @return #number The altitude of the group or nil if is not existing or alive.
|
||||||
function GROUP:GetAltitude(FromGround)
|
function GROUP:GetAltitude(FromGround)
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
return self:GetHeight(FromGround)
|
return self:GetHeight(FromGround)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -928,7 +941,7 @@ end
|
|||||||
-- @param #boolean FromGround Measure from the ground or from sea level (ASL). Provide **true** for measuring from the ground (AGL). **false** or **nil** if you measure from sea level.
|
-- @param #boolean FromGround Measure from the ground or from sea level (ASL). Provide **true** for measuring from the ground (AGL). **false** or **nil** if you measure from sea level.
|
||||||
-- @return #number The height of the group or nil if is not existing or alive.
|
-- @return #number The height of the group or nil if is not existing or alive.
|
||||||
function GROUP:GetHeight( FromGround )
|
function GROUP:GetHeight( FromGround )
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -964,12 +977,12 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #number The DCS Group initial size.
|
-- @return #number The DCS Group initial size.
|
||||||
function GROUP:GetInitialSize()
|
function GROUP:GetInitialSize()
|
||||||
self:F3( { self.GroupName } )
|
--self:F3( { self.GroupName } )
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local GroupInitialSize = DCSGroup:getInitialSize()
|
local GroupInitialSize = DCSGroup:getInitialSize()
|
||||||
self:T3( GroupInitialSize )
|
--self:T3( GroupInitialSize )
|
||||||
return GroupInitialSize
|
return GroupInitialSize
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -981,12 +994,12 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #table The DCS Units.
|
-- @return #table The DCS Units.
|
||||||
function GROUP:GetDCSUnits()
|
function GROUP:GetDCSUnits()
|
||||||
self:F2( { self.GroupName } )
|
--self:F2( { self.GroupName } )
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local DCSUnits = DCSGroup:getUnits()
|
local DCSUnits = DCSGroup:getUnits()
|
||||||
self:T3( DCSUnits )
|
--self:T3( DCSUnits )
|
||||||
return DCSUnits
|
return DCSUnits
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -999,7 +1012,7 @@ end
|
|||||||
-- @param #number delay Delay in seconds, before the group is activated.
|
-- @param #number delay Delay in seconds, before the group is activated.
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:Activate(delay)
|
function GROUP:Activate(delay)
|
||||||
self:F2( { self.GroupName } )
|
--self:F2( { self.GroupName } )
|
||||||
if delay and delay>0 then
|
if delay and delay>0 then
|
||||||
self:ScheduleOnce(delay, GROUP.Activate, self)
|
self:ScheduleOnce(delay, GROUP.Activate, self)
|
||||||
else
|
else
|
||||||
@@ -1008,18 +1021,32 @@ function GROUP:Activate(delay)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Deactivates an activated GROUP.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @param #number delay Delay in seconds, before the group is activated.
|
||||||
|
-- @return #GROUP self
|
||||||
|
function GROUP:Deactivate(delay)
|
||||||
|
--self:F2( { self.GroupName } )
|
||||||
|
if delay and delay>0 then
|
||||||
|
self:ScheduleOnce(delay, GROUP.Deactivate, self)
|
||||||
|
else
|
||||||
|
trigger.action.deactivateGroup( self:GetDCSObject() )
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Gets the type name of the group.
|
--- Gets the type name of the group.
|
||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #string The type name of the group.
|
-- @return #string The type name of the group.
|
||||||
function GROUP:GetTypeName()
|
function GROUP:GetTypeName()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local GroupTypeName = DCSGroup:getUnit(1):getTypeName()
|
local GroupTypeName = DCSGroup:getUnit(1):getTypeName()
|
||||||
self:T3( GroupTypeName )
|
--self:T3( GroupTypeName )
|
||||||
return( GroupTypeName )
|
return( GroupTypeName )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1030,13 +1057,13 @@ end
|
|||||||
--@param #GROUP self
|
--@param #GROUP self
|
||||||
--@return #string NatoReportingName or "Bogey" if unknown.
|
--@return #string NatoReportingName or "Bogey" if unknown.
|
||||||
function GROUP:GetNatoReportingName()
|
function GROUP:GetNatoReportingName()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local GroupTypeName = DCSGroup:getUnit(1):getTypeName()
|
local GroupTypeName = DCSGroup:getUnit(1):getTypeName()
|
||||||
self:T3( GroupTypeName )
|
--self:T3( GroupTypeName )
|
||||||
return UTILS.GetReportingName(GroupTypeName)
|
return UTILS.GetReportingName(GroupTypeName)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1048,13 +1075,13 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #string The player name of the group.
|
-- @return #string The player name of the group.
|
||||||
function GROUP:GetPlayerName()
|
function GROUP:GetPlayerName()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local PlayerName = DCSGroup:getUnit(1):getPlayerName()
|
local PlayerName = DCSGroup:getUnit(1):getPlayerName()
|
||||||
self:T3( PlayerName )
|
--self:T3( PlayerName )
|
||||||
return( PlayerName )
|
return( PlayerName )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1066,13 +1093,13 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #string The CallSign of the first DCS Unit of the DCS Group.
|
-- @return #string The CallSign of the first DCS Unit of the DCS Group.
|
||||||
function GROUP:GetCallsign()
|
function GROUP:GetCallsign()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local GroupCallSign = DCSGroup:getUnit(1):getCallsign()
|
local GroupCallSign = DCSGroup:getUnit(1):getCallsign()
|
||||||
self:T3( GroupCallSign )
|
--self:T3( GroupCallSign )
|
||||||
return GroupCallSign
|
return GroupCallSign
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1149,13 +1176,13 @@ end
|
|||||||
-- @return Core.Point#POINT_VEC2 The 2D point vector of the first DCS Unit of the GROUP.
|
-- @return Core.Point#POINT_VEC2 The 2D point vector of the first DCS Unit of the GROUP.
|
||||||
-- @return #nil The first UNIT is not existing or alive.
|
-- @return #nil The first UNIT is not existing or alive.
|
||||||
function GROUP:GetPointVec2()
|
function GROUP:GetPointVec2()
|
||||||
self:F2(self.GroupName)
|
--self:F2(self.GroupName)
|
||||||
|
|
||||||
local FirstUnit = self:GetUnit(1)
|
local FirstUnit = self:GetUnit(1)
|
||||||
|
|
||||||
if FirstUnit then
|
if FirstUnit then
|
||||||
local FirstUnitPointVec2 = FirstUnit:GetPointVec2()
|
local FirstUnitPointVec2 = FirstUnit:GetPointVec2()
|
||||||
self:T3(FirstUnitPointVec2)
|
--self:T3(FirstUnitPointVec2)
|
||||||
return FirstUnitPointVec2
|
return FirstUnitPointVec2
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1237,13 +1264,13 @@ end
|
|||||||
-- @usage
|
-- @usage
|
||||||
-- -- If Radius is ignored, returns the DCS#Vec3 of first UNIT of the GROUP
|
-- -- If Radius is ignored, returns the DCS#Vec3 of first UNIT of the GROUP
|
||||||
function GROUP:GetRandomVec3(Radius)
|
function GROUP:GetRandomVec3(Radius)
|
||||||
self:F2(self.GroupName)
|
--self:F2(self.GroupName)
|
||||||
|
|
||||||
local FirstUnit = self:GetUnit(1)
|
local FirstUnit = self:GetUnit(1)
|
||||||
|
|
||||||
if FirstUnit then
|
if FirstUnit then
|
||||||
local FirstUnitRandomPointVec3 = FirstUnit:GetRandomVec3(Radius)
|
local FirstUnitRandomPointVec3 = FirstUnit:GetRandomVec3(Radius)
|
||||||
self:T3(FirstUnitRandomPointVec3)
|
--self:T3(FirstUnitRandomPointVec3)
|
||||||
return FirstUnitRandomPointVec3
|
return FirstUnitRandomPointVec3
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1256,9 +1283,9 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #number Mean heading of the GROUP in degrees or #nil The first UNIT is not existing or alive.
|
-- @return #number Mean heading of the GROUP in degrees or #nil The first UNIT is not existing or alive.
|
||||||
function GROUP:GetHeading()
|
function GROUP:GetHeading()
|
||||||
self:F2(self.GroupName)
|
--self:F2(self.GroupName)
|
||||||
|
|
||||||
self:F2(self.GroupName)
|
--self:F2(self.GroupName)
|
||||||
|
|
||||||
local GroupSize = self:GetSize()
|
local GroupSize = self:GetSize()
|
||||||
local HeadingAccumulator = 0
|
local HeadingAccumulator = 0
|
||||||
@@ -1287,7 +1314,7 @@ end
|
|||||||
-- @return #number The fuel state of the unit with the least amount of fuel.
|
-- @return #number The fuel state of the unit with the least amount of fuel.
|
||||||
-- @return Wrapper.Unit#UNIT reference to #Unit object for further processing.
|
-- @return Wrapper.Unit#UNIT reference to #Unit object for further processing.
|
||||||
function GROUP:GetFuelMin()
|
function GROUP:GetFuelMin()
|
||||||
self:F3(self.ControllableName)
|
--self:F3(self.ControllableName)
|
||||||
|
|
||||||
if not self:GetDCSObject() then
|
if not self:GetDCSObject() then
|
||||||
BASE:E( { "Cannot GetFuel", Group = self, Alive = self:IsAlive() } )
|
BASE:E( { "Cannot GetFuel", Group = self, Alive = self:IsAlive() } )
|
||||||
@@ -1318,7 +1345,7 @@ end
|
|||||||
-- @return #number The relative amount of fuel (from 0.0 to 1.0).
|
-- @return #number The relative amount of fuel (from 0.0 to 1.0).
|
||||||
-- @return #nil The GROUP is not existing or alive.
|
-- @return #nil The GROUP is not existing or alive.
|
||||||
function GROUP:GetFuelAvg()
|
function GROUP:GetFuelAvg()
|
||||||
self:F( self.ControllableName )
|
--self:F( self.ControllableName )
|
||||||
|
|
||||||
local DCSControllable = self:GetDCSObject()
|
local DCSControllable = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -1328,7 +1355,7 @@ function GROUP:GetFuelAvg()
|
|||||||
for UnitID, UnitData in pairs( self:GetUnits() ) do
|
for UnitID, UnitData in pairs( self:GetUnits() ) do
|
||||||
local Unit = UnitData -- Wrapper.Unit#UNIT
|
local Unit = UnitData -- Wrapper.Unit#UNIT
|
||||||
local UnitFuel = Unit:GetFuel() or 0
|
local UnitFuel = Unit:GetFuel() or 0
|
||||||
self:F( { Fuel = UnitFuel } )
|
--self:F( { Fuel = UnitFuel } )
|
||||||
TotalFuel = TotalFuel + UnitFuel
|
TotalFuel = TotalFuel + UnitFuel
|
||||||
end
|
end
|
||||||
local GroupFuel = TotalFuel / GroupSize
|
local GroupFuel = TotalFuel / GroupSize
|
||||||
@@ -1358,7 +1385,7 @@ end
|
|||||||
-- @return #number Number of missiles left.
|
-- @return #number Number of missiles left.
|
||||||
-- @return #number Number of artillery shells left (with explosive mass, included in shells; shells can also be machine gun ammo)
|
-- @return #number Number of artillery shells left (with explosive mass, included in shells; shells can also be machine gun ammo)
|
||||||
function GROUP:GetAmmunition()
|
function GROUP:GetAmmunition()
|
||||||
self:F( self.ControllableName )
|
--self:F( self.ControllableName )
|
||||||
|
|
||||||
local DCSControllable = self:GetDCSObject()
|
local DCSControllable = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -1429,7 +1456,7 @@ end
|
|||||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
||||||
-- @return #boolean Returns true if the Group is completely within the @{Core.Zone#ZONE_BASE}
|
-- @return #boolean Returns true if the Group is completely within the @{Core.Zone#ZONE_BASE}
|
||||||
function GROUP:IsCompletelyInZone( Zone )
|
function GROUP:IsCompletelyInZone( Zone )
|
||||||
self:F2( { self.GroupName, Zone } )
|
--self:F2( { self.GroupName, Zone } )
|
||||||
|
|
||||||
if not self:IsAlive() then return false end
|
if not self:IsAlive() then return false end
|
||||||
|
|
||||||
@@ -1449,7 +1476,7 @@ end
|
|||||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
||||||
-- @return #boolean Returns true if the Group is partially within the @{Core.Zone#ZONE_BASE}
|
-- @return #boolean Returns true if the Group is partially within the @{Core.Zone#ZONE_BASE}
|
||||||
function GROUP:IsPartlyInZone( Zone )
|
function GROUP:IsPartlyInZone( Zone )
|
||||||
self:F2( { self.GroupName, Zone } )
|
--self:F2( { self.GroupName, Zone } )
|
||||||
|
|
||||||
local IsOneUnitInZone = false
|
local IsOneUnitInZone = false
|
||||||
local IsOneUnitOutsideZone = false
|
local IsOneUnitOutsideZone = false
|
||||||
@@ -1485,7 +1512,7 @@ end
|
|||||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
||||||
-- @return #boolean Returns true if the Group is not within the @{Core.Zone#ZONE_BASE}
|
-- @return #boolean Returns true if the Group is not within the @{Core.Zone#ZONE_BASE}
|
||||||
function GROUP:IsNotInZone( Zone )
|
function GROUP:IsNotInZone( Zone )
|
||||||
self:F2( { self.GroupName, Zone } )
|
--self:F2( { self.GroupName, Zone } )
|
||||||
|
|
||||||
if not self:IsAlive() then return true end
|
if not self:IsAlive() then return true end
|
||||||
|
|
||||||
@@ -1521,7 +1548,7 @@ end
|
|||||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
||||||
-- @return #number The number of UNITs that are in the @{Core.Zone}
|
-- @return #number The number of UNITs that are in the @{Core.Zone}
|
||||||
function GROUP:CountInZone( Zone )
|
function GROUP:CountInZone( Zone )
|
||||||
self:F2( {self.GroupName, Zone} )
|
--self:F2( {self.GroupName, Zone} )
|
||||||
local Count = 0
|
local Count = 0
|
||||||
|
|
||||||
if not self:IsAlive() then return Count end
|
if not self:IsAlive() then return Count end
|
||||||
@@ -1541,13 +1568,13 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #boolean Air category evaluation result.
|
-- @return #boolean Air category evaluation result.
|
||||||
function GROUP:IsAir()
|
function GROUP:IsAir()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local IsAirResult = DCSGroup:getCategory() == Group.Category.AIRPLANE or DCSGroup:getCategory() == Group.Category.HELICOPTER
|
local IsAirResult = DCSGroup:getCategory() == Group.Category.AIRPLANE or DCSGroup:getCategory() == Group.Category.HELICOPTER
|
||||||
self:T3( IsAirResult )
|
--self:T3( IsAirResult )
|
||||||
return IsAirResult
|
return IsAirResult
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1558,13 +1585,13 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #boolean true if DCS Group contains Helicopters.
|
-- @return #boolean true if DCS Group contains Helicopters.
|
||||||
function GROUP:IsHelicopter()
|
function GROUP:IsHelicopter()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local GroupCategory = DCSGroup:getCategory()
|
local GroupCategory = DCSGroup:getCategory()
|
||||||
self:T2( GroupCategory )
|
--self:T2( GroupCategory )
|
||||||
return GroupCategory == Group.Category.HELICOPTER
|
return GroupCategory == Group.Category.HELICOPTER
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1575,13 +1602,13 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #boolean true if DCS Group contains AirPlanes.
|
-- @return #boolean true if DCS Group contains AirPlanes.
|
||||||
function GROUP:IsAirPlane()
|
function GROUP:IsAirPlane()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local GroupCategory = DCSGroup:getCategory()
|
local GroupCategory = DCSGroup:getCategory()
|
||||||
self:T2( GroupCategory )
|
--self:T2( GroupCategory )
|
||||||
return GroupCategory == Group.Category.AIRPLANE
|
return GroupCategory == Group.Category.AIRPLANE
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1592,13 +1619,13 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #boolean true if DCS Group contains Ground troops.
|
-- @return #boolean true if DCS Group contains Ground troops.
|
||||||
function GROUP:IsGround()
|
function GROUP:IsGround()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local GroupCategory = DCSGroup:getCategory()
|
local GroupCategory = DCSGroup:getCategory()
|
||||||
self:T2( GroupCategory )
|
--self:T2( GroupCategory )
|
||||||
return GroupCategory == Group.Category.GROUND
|
return GroupCategory == Group.Category.GROUND
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1609,13 +1636,13 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #boolean true if DCS Group contains Ships.
|
-- @return #boolean true if DCS Group contains Ships.
|
||||||
function GROUP:IsShip()
|
function GROUP:IsShip()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local GroupCategory = DCSGroup:getCategory()
|
local GroupCategory = DCSGroup:getCategory()
|
||||||
self:T2( GroupCategory )
|
--self:T2( GroupCategory )
|
||||||
return GroupCategory == Group.Category.SHIP
|
return GroupCategory == Group.Category.SHIP
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1627,7 +1654,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #boolean All units on the ground result.
|
-- @return #boolean All units on the ground result.
|
||||||
function GROUP:AllOnGround()
|
function GROUP:AllOnGround()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -1640,7 +1667,7 @@ function GROUP:AllOnGround()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T3( AllOnGroundResult )
|
--self:T3( AllOnGroundResult )
|
||||||
return AllOnGroundResult
|
return AllOnGroundResult
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1695,7 +1722,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #number Maximum velocity found.
|
-- @return #number Maximum velocity found.
|
||||||
function GROUP:GetMaxVelocity()
|
function GROUP:GetMaxVelocity()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -1723,7 +1750,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #number Minimum height found.
|
-- @return #number Minimum height found.
|
||||||
function GROUP:GetMinHeight()
|
function GROUP:GetMinHeight()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -1751,7 +1778,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #number Maximum height found.
|
-- @return #number Maximum height found.
|
||||||
function GROUP:GetMaxHeight()
|
function GROUP:GetMaxHeight()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -1893,7 +1920,7 @@ end
|
|||||||
-- @param Core.Point#COORDINATE coordinate Coordinate where the group should be respawned.
|
-- @param Core.Point#COORDINATE coordinate Coordinate where the group should be respawned.
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:InitCoordinate(coordinate)
|
function GROUP:InitCoordinate(coordinate)
|
||||||
self:F({coordinate=coordinate})
|
--self:F({coordinate=coordinate})
|
||||||
self.InitCoord=coordinate
|
self.InitCoord=coordinate
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1903,7 +1930,7 @@ end
|
|||||||
-- @param #boolean switch If true (or nil), enables the radio comms. If false, disables the radio for the spawned group.
|
-- @param #boolean switch If true (or nil), enables the radio comms. If false, disables the radio for the spawned group.
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:InitRadioCommsOnOff(switch)
|
function GROUP:InitRadioCommsOnOff(switch)
|
||||||
self:F({switch=switch})
|
--self:F({switch=switch})
|
||||||
if switch==true or switch==nil then
|
if switch==true or switch==nil then
|
||||||
self.InitRespawnRadio=true
|
self.InitRespawnRadio=true
|
||||||
else
|
else
|
||||||
@@ -1917,7 +1944,7 @@ end
|
|||||||
-- @param #number frequency The frequency in MHz.
|
-- @param #number frequency The frequency in MHz.
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:InitRadioFrequency(frequency)
|
function GROUP:InitRadioFrequency(frequency)
|
||||||
self:F({frequency=frequency})
|
--self:F({frequency=frequency})
|
||||||
|
|
||||||
self.InitRespawnFreq=frequency
|
self.InitRespawnFreq=frequency
|
||||||
|
|
||||||
@@ -1929,7 +1956,7 @@ end
|
|||||||
-- @param #string modulation Either "FM" or "AM". If no value is given, modulation is set to AM.
|
-- @param #string modulation Either "FM" or "AM". If no value is given, modulation is set to AM.
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:InitRadioModulation(modulation)
|
function GROUP:InitRadioModulation(modulation)
|
||||||
self:F({modulation=modulation})
|
--self:F({modulation=modulation})
|
||||||
if modulation and modulation:lower()=="fm" then
|
if modulation and modulation:lower()=="fm" then
|
||||||
self.InitRespawnModu=radio.modulation.FM
|
self.InitRespawnModu=radio.modulation.FM
|
||||||
else
|
else
|
||||||
@@ -1943,7 +1970,7 @@ end
|
|||||||
-- @param #string modex Tail number of the first unit.
|
-- @param #string modex Tail number of the first unit.
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:InitModex(modex)
|
function GROUP:InitModex(modex)
|
||||||
self:F({modex=modex})
|
--self:F({modex=modex})
|
||||||
if modex then
|
if modex then
|
||||||
self.InitRespawnModex=tonumber(modex)
|
self.InitRespawnModex=tonumber(modex)
|
||||||
end
|
end
|
||||||
@@ -2009,7 +2036,7 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
--Template.y = nil
|
--Template.y = nil
|
||||||
|
|
||||||
-- Debug number of units.
|
-- Debug number of units.
|
||||||
self:F( #Template.units )
|
--self:F( #Template.units )
|
||||||
|
|
||||||
-- Reset position etc?
|
-- Reset position etc?
|
||||||
if Reset == true then
|
if Reset == true then
|
||||||
@@ -2017,10 +2044,10 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
-- Loop over units in group.
|
-- Loop over units in group.
|
||||||
for UnitID, UnitData in pairs( self:GetUnits() ) do
|
for UnitID, UnitData in pairs( self:GetUnits() ) do
|
||||||
local GroupUnit = UnitData -- Wrapper.Unit#UNIT
|
local GroupUnit = UnitData -- Wrapper.Unit#UNIT
|
||||||
self:F(GroupUnit:GetName())
|
--self:F(GroupUnit:GetName())
|
||||||
|
|
||||||
if GroupUnit:IsAlive() then
|
if GroupUnit:IsAlive() then
|
||||||
self:I("FF Alive")
|
--self:I("FF Alive")
|
||||||
|
|
||||||
-- Get unit position vector.
|
-- Get unit position vector.
|
||||||
local GroupUnitVec3 = GroupUnit:GetVec3()
|
local GroupUnitVec3 = GroupUnit:GetVec3()
|
||||||
@@ -2060,7 +2087,7 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
Template.units[UnitID].psi = -Template.units[UnitID].heading
|
Template.units[UnitID].psi = -Template.units[UnitID].heading
|
||||||
|
|
||||||
-- Debug.
|
-- Debug.
|
||||||
self:F( { UnitID, Template.units[UnitID], Template.units[UnitID] } )
|
--self:F( { UnitID, Template.units[UnitID], Template.units[UnitID] } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2069,7 +2096,7 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
-- Loop over template units.
|
-- Loop over template units.
|
||||||
for UnitID, TemplateUnitData in pairs( Template.units ) do
|
for UnitID, TemplateUnitData in pairs( Template.units ) do
|
||||||
|
|
||||||
self:F( "Reset" )
|
--self:F( "Reset" )
|
||||||
|
|
||||||
-- Position from template.
|
-- Position from template.
|
||||||
local GroupUnitVec3 = { x = TemplateUnitData.x, y = TemplateUnitData.alt, z = TemplateUnitData.y }
|
local GroupUnitVec3 = { x = TemplateUnitData.x, y = TemplateUnitData.alt, z = TemplateUnitData.y }
|
||||||
@@ -2103,7 +2130,7 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
Template.units[UnitID].heading = self.InitRespawnHeading and self.InitRespawnHeading or TemplateUnitData.heading
|
Template.units[UnitID].heading = self.InitRespawnHeading and self.InitRespawnHeading or TemplateUnitData.heading
|
||||||
|
|
||||||
-- Debug.
|
-- Debug.
|
||||||
self:F( { UnitID, Template.units[UnitID], Template.units[UnitID] } )
|
--self:F( { UnitID, Template.units[UnitID], Template.units[UnitID] } )
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -2154,7 +2181,7 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
-- Destroy old group. Dont trigger any dead/crash events since this is a respawn.
|
-- Destroy old group. Dont trigger any dead/crash events since this is a respawn.
|
||||||
self:Destroy(false)
|
self:Destroy(false)
|
||||||
|
|
||||||
self:T({Template=Template})
|
--self:T({Template=Template})
|
||||||
|
|
||||||
-- Spawn new group.
|
-- Spawn new group.
|
||||||
_DATABASE:Spawn(Template)
|
_DATABASE:Spawn(Template)
|
||||||
@@ -2175,7 +2202,7 @@ end
|
|||||||
-- @param #boolean Uncontrolled (Optional) If true, spawn in uncontrolled state.
|
-- @param #boolean Uncontrolled (Optional) If true, spawn in uncontrolled state.
|
||||||
-- @return Wrapper.Group#GROUP Group spawned at airbase or nil if group could not be spawned.
|
-- @return Wrapper.Group#GROUP Group spawned at airbase or nil if group could not be spawned.
|
||||||
function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) -- R2.4
|
function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) -- R2.4
|
||||||
self:F2( { SpawnTemplate, Takeoff, Uncontrolled} )
|
--self:F2( { SpawnTemplate, Takeoff, Uncontrolled} )
|
||||||
|
|
||||||
if self and self:IsAlive() then
|
if self and self:IsAlive() then
|
||||||
|
|
||||||
@@ -2183,7 +2210,7 @@ function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) --
|
|||||||
local airbase=self:GetCoordinate():GetClosestAirbase()
|
local airbase=self:GetCoordinate():GetClosestAirbase()
|
||||||
|
|
||||||
if airbase then
|
if airbase then
|
||||||
self:F2("Closest airbase = "..airbase:GetName())
|
--self:F2("Closest airbase = "..airbase:GetName())
|
||||||
else
|
else
|
||||||
self:E("ERROR: could not find closest airbase!")
|
self:E("ERROR: could not find closest airbase!")
|
||||||
return nil
|
return nil
|
||||||
@@ -2234,7 +2261,7 @@ function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) --
|
|||||||
local Parkingspot, TermialID, Distance=unit:GetCoordinate():GetClosestParkingSpot(airbase)
|
local Parkingspot, TermialID, Distance=unit:GetCoordinate():GetClosestParkingSpot(airbase)
|
||||||
|
|
||||||
--Parkingspot:MarkToAll("parking spot")
|
--Parkingspot:MarkToAll("parking spot")
|
||||||
self:T2(string.format("Closest parking spot distance = %s, terminal ID=%s", tostring(Distance), tostring(TermialID)))
|
--self:T2(string.format("Closest parking spot distance = %s, terminal ID=%s", tostring(Distance), tostring(TermialID)))
|
||||||
|
|
||||||
-- Get unit coordinates for respawning position.
|
-- Get unit coordinates for respawning position.
|
||||||
local uc=unit:GetCoordinate()
|
local uc=unit:GetCoordinate()
|
||||||
@@ -2296,7 +2323,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #table The MissionTemplate
|
-- @return #table The MissionTemplate
|
||||||
function GROUP:GetTaskMission()
|
function GROUP:GetTaskMission()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
return UTILS.DeepCopy( _DATABASE.Templates.Groups[self.GroupName].Template )
|
return UTILS.DeepCopy( _DATABASE.Templates.Groups[self.GroupName].Template )
|
||||||
end
|
end
|
||||||
@@ -2305,7 +2332,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #table The mission route defined by points.
|
-- @return #table The mission route defined by points.
|
||||||
function GROUP:GetTaskRoute()
|
function GROUP:GetTaskRoute()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
return UTILS.DeepCopy( _DATABASE.Templates.Groups[self.GroupName].Template.route.points )
|
return UTILS.DeepCopy( _DATABASE.Templates.Groups[self.GroupName].Template.route.points )
|
||||||
end
|
end
|
||||||
@@ -2317,7 +2344,7 @@ end
|
|||||||
-- @param #boolean Randomize Randomization of the route, when true.
|
-- @param #boolean Randomize Randomization of the route, when true.
|
||||||
-- @param #number Radius When randomization is on, the randomization is within the radius.
|
-- @param #number Radius When randomization is on, the randomization is within the radius.
|
||||||
function GROUP:CopyRoute( Begin, End, Randomize, Radius )
|
function GROUP:CopyRoute( Begin, End, Randomize, Radius )
|
||||||
self:F2( { Begin, End } )
|
--self:F2( { Begin, End } )
|
||||||
|
|
||||||
local Points = {}
|
local Points = {}
|
||||||
|
|
||||||
@@ -2329,7 +2356,7 @@ function GROUP:CopyRoute( Begin, End, Randomize, Radius )
|
|||||||
GroupName = self:GetName()
|
GroupName = self:GetName()
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T3( { GroupName } )
|
--self:T3( { GroupName } )
|
||||||
|
|
||||||
local Template = _DATABASE.Templates.Groups[GroupName].Template
|
local Template = _DATABASE.Templates.Groups[GroupName].Template
|
||||||
|
|
||||||
@@ -2375,7 +2402,7 @@ function GROUP:CalculateThreatLevelA2G()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T3( MaxThreatLevelA2G )
|
--self:T3( MaxThreatLevelA2G )
|
||||||
return MaxThreatLevelA2G
|
return MaxThreatLevelA2G
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2402,7 +2429,7 @@ end
|
|||||||
-- @param Wrapper.Group#GROUP self
|
-- @param Wrapper.Group#GROUP self
|
||||||
-- @return #boolean true if in the first unit of the group is in the air or #nil if the GROUP is not existing or not alive.
|
-- @return #boolean true if in the first unit of the group is in the air or #nil if the GROUP is not existing or not alive.
|
||||||
function GROUP:InAir()
|
function GROUP:InAir()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -2410,7 +2437,7 @@ function GROUP:InAir()
|
|||||||
local DCSUnit = DCSGroup:getUnit(1)
|
local DCSUnit = DCSGroup:getUnit(1)
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
local GroupInAir = DCSGroup:getUnit(1):inAir()
|
local GroupInAir = DCSGroup:getUnit(1):inAir()
|
||||||
self:T3( GroupInAir )
|
--self:T3( GroupInAir )
|
||||||
return GroupInAir
|
return GroupInAir
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -2423,7 +2450,7 @@ end
|
|||||||
-- @param #boolean AllUnits (Optional) If true, check whether all units of the group are airborne.
|
-- @param #boolean AllUnits (Optional) If true, check whether all units of the group are airborne.
|
||||||
-- @return #boolean True if at least one (optionally all) unit(s) is(are) airborne or false otherwise. Nil if no unit exists or is alive.
|
-- @return #boolean True if at least one (optionally all) unit(s) is(are) airborne or false otherwise. Nil if no unit exists or is alive.
|
||||||
function GROUP:IsAirborne(AllUnits)
|
function GROUP:IsAirborne(AllUnits)
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
|
|
||||||
-- Get all units of the group.
|
-- Get all units of the group.
|
||||||
local units=self:GetUnits()
|
local units=self:GetUnits()
|
||||||
@@ -2634,7 +2661,7 @@ do -- Route methods
|
|||||||
-- @param #number Speed (optional) The Speed, if no Speed is given, 80% of maximum Speed of the group is selected.
|
-- @param #number Speed (optional) The Speed, if no Speed is given, 80% of maximum Speed of the group is selected.
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:RouteRTB( RTBAirbase, Speed )
|
function GROUP:RouteRTB( RTBAirbase, Speed )
|
||||||
self:F( { RTBAirbase:GetName(), Speed } )
|
--self:F( { RTBAirbase:GetName(), Speed } )
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -2660,7 +2687,7 @@ do -- Route methods
|
|||||||
--local Points={PointFrom, PointAirbase, PointLanding}
|
--local Points={PointFrom, PointAirbase, PointLanding}
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T3(Points)
|
--self:T3(Points)
|
||||||
|
|
||||||
-- Get group template.
|
-- Get group template.
|
||||||
local Template=self:GetTemplate()
|
local Template=self:GetTemplate()
|
||||||
@@ -2756,7 +2783,7 @@ do -- Players
|
|||||||
end
|
end
|
||||||
|
|
||||||
if HasPlayers == true then
|
if HasPlayers == true then
|
||||||
self:F2( PlayerNames )
|
--self:F2( PlayerNames )
|
||||||
return PlayerNames
|
return PlayerNames
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2790,7 +2817,7 @@ end
|
|||||||
-- @param #boolean switch If true, emission is enabled. If false, emission is disabled.
|
-- @param #boolean switch If true, emission is enabled. If false, emission is disabled.
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:EnableEmission(switch)
|
function GROUP:EnableEmission(switch)
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
local switch = switch or false
|
local switch = switch or false
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
@@ -2817,7 +2844,7 @@ end
|
|||||||
-- @param #boolean switch If true, Invisible is enabled. If false, Invisible is disabled.
|
-- @param #boolean switch If true, Invisible is enabled. If false, Invisible is disabled.
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:CommandSetInvisible(switch)
|
function GROUP:CommandSetInvisible(switch)
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
if switch==nil then
|
if switch==nil then
|
||||||
switch=false
|
switch=false
|
||||||
end
|
end
|
||||||
@@ -2839,7 +2866,7 @@ end
|
|||||||
-- @param #boolean switch If true, Immortal is enabled. If false, Immortal is disabled.
|
-- @param #boolean switch If true, Immortal is enabled. If false, Immortal is disabled.
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:CommandSetImmortal(switch)
|
function GROUP:CommandSetImmortal(switch)
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
if switch==nil then
|
if switch==nil then
|
||||||
switch=false
|
switch=false
|
||||||
end
|
end
|
||||||
@@ -2852,7 +2879,7 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #string Skill String of skill name.
|
-- @return #string Skill String of skill name.
|
||||||
function GROUP:GetSkill()
|
function GROUP:GetSkill()
|
||||||
self:F2( self.GroupName )
|
--self:F2( self.GroupName )
|
||||||
local unit = self:GetUnit(1)
|
local unit = self:GetUnit(1)
|
||||||
local name = unit:GetName()
|
local name = unit:GetName()
|
||||||
local skill = _DATABASE.Templates.Units[name].Template.skill or "Random"
|
local skill = _DATABASE.Templates.Units[name].Template.skill or "Random"
|
||||||
|
|||||||
@@ -528,6 +528,7 @@ function NET:SendChatToPlayer(Message, ToPlayer, FromPlayer)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[ not in 2.97 MSE any longer
|
||||||
--- Load a specific mission.
|
--- Load a specific mission.
|
||||||
-- @param #NET self
|
-- @param #NET self
|
||||||
-- @param #string Path and Mission
|
-- @param #string Path and Mission
|
||||||
@@ -550,6 +551,7 @@ function NET:LoadNextMission()
|
|||||||
outcome = net.load_next_mission()
|
outcome = net.load_next_mission()
|
||||||
return outcome
|
return outcome
|
||||||
end
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
--- Return a table of players currently connected to the server.
|
--- Return a table of players currently connected to the server.
|
||||||
-- @param #NET self
|
-- @param #NET self
|
||||||
|
|||||||
@@ -1853,6 +1853,7 @@ do -- Cargo
|
|||||||
["HL_KORD"] = 6*POSITIONABLE.DefaultInfantryWeight,
|
["HL_KORD"] = 6*POSITIONABLE.DefaultInfantryWeight,
|
||||||
["HL_DSHK"] = 6*POSITIONABLE.DefaultInfantryWeight,
|
["HL_DSHK"] = 6*POSITIONABLE.DefaultInfantryWeight,
|
||||||
["CCKW_353"] = 16*POSITIONABLE.DefaultInfantryWeight, --GMC CCKW 2½-ton 6×6 truck, estimating 16 soldiers,
|
["CCKW_353"] = 16*POSITIONABLE.DefaultInfantryWeight, --GMC CCKW 2½-ton 6×6 truck, estimating 16 soldiers,
|
||||||
|
["MaxxPro_MRAP"] = 7*POSITIONABLE.DefaultInfantryWeight,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,6 +226,26 @@ function STORAGE:NewFromStaticCargo(StaticCargoName)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Create a new STORAGE object from an DCS static cargo object.
|
||||||
|
-- @param #STORAGE self
|
||||||
|
-- @param #string DynamicCargoName Unit name of the dynamic cargo.
|
||||||
|
-- @return #STORAGE self
|
||||||
|
function STORAGE:NewFromDynamicCargo(DynamicCargoName)
|
||||||
|
|
||||||
|
-- Inherit everything from BASE class.
|
||||||
|
local self=BASE:Inherit(self, BASE:New()) -- #STORAGE
|
||||||
|
|
||||||
|
self.airbase=Unit.getByName(DynamicCargoName)
|
||||||
|
|
||||||
|
if Airbase.getWarehouse then
|
||||||
|
self.warehouse=Warehouse.getCargoAsWarehouse(self.airbase)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.lid = string.format("STORAGE %s", DynamicCargoName)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Airbases only - Find a STORAGE in the **_DATABASE** using the name associated airbase.
|
--- Airbases only - Find a STORAGE in the **_DATABASE** using the name associated airbase.
|
||||||
-- @param #STORAGE self
|
-- @param #STORAGE self
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ function UNIT:Name()
|
|||||||
return self.UnitName
|
return self.UnitName
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
--- Get the DCS unit object.
|
--- Get the DCS unit object.
|
||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return DCS#Unit The DCS unit object.
|
-- @return DCS#Unit The DCS unit object.
|
||||||
@@ -230,10 +231,34 @@ function UNIT:GetDCSObject()
|
|||||||
return DCSUnit
|
return DCSUnit
|
||||||
end
|
end
|
||||||
|
|
||||||
--if self.DCSUnit then
|
return nil
|
||||||
--return self.DCSUnit
|
end
|
||||||
--end
|
--]]
|
||||||
|
|
||||||
|
--- Returns the DCS Unit.
|
||||||
|
-- @param #UNIT self
|
||||||
|
-- @return DCS#Unit The DCS Group.
|
||||||
|
function UNIT:GetDCSObject()
|
||||||
|
|
||||||
|
if (not self.LastCallDCSObject) or (self.LastCallDCSObject and timer.getTime() - self.LastCallDCSObject > 1) then
|
||||||
|
|
||||||
|
-- Get DCS group.
|
||||||
|
local DCSUnit = Unit.getByName( self.UnitName )
|
||||||
|
|
||||||
|
if DCSUnit then
|
||||||
|
self.LastCallDCSObject = timer.getTime()
|
||||||
|
self.DCSObject = DCSUnit
|
||||||
|
return DCSUnit
|
||||||
|
else
|
||||||
|
self.DCSObject = nil
|
||||||
|
self.LastCallDCSObject = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
return self.DCSObject
|
||||||
|
end
|
||||||
|
|
||||||
|
--self:E(string.format("ERROR: Could not get DCS group object of group %s because DCS object could not be found!", tostring(self.UnitName)))
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -243,7 +268,7 @@ end
|
|||||||
-- @return #number The height of the group or nil if is not existing or alive.
|
-- @return #number The height of the group or nil if is not existing or alive.
|
||||||
function UNIT:GetAltitude(FromGround)
|
function UNIT:GetAltitude(FromGround)
|
||||||
|
|
||||||
local DCSUnit = Unit.getByName( self.UnitName )
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
local altitude = 0
|
local altitude = 0
|
||||||
@@ -273,12 +298,12 @@ end
|
|||||||
-- @param #number Heading The heading of the unit respawn.
|
-- @param #number Heading The heading of the unit respawn.
|
||||||
function UNIT:ReSpawnAt( Coordinate, Heading )
|
function UNIT:ReSpawnAt( Coordinate, Heading )
|
||||||
|
|
||||||
self:T( self:Name() )
|
--self:T( self:Name() )
|
||||||
local SpawnGroupTemplate = UTILS.DeepCopy( _DATABASE:GetGroupTemplateFromUnitName( self:Name() ) )
|
local SpawnGroupTemplate = UTILS.DeepCopy( _DATABASE:GetGroupTemplateFromUnitName( self:Name() ) )
|
||||||
self:T( SpawnGroupTemplate )
|
--self:T( SpawnGroupTemplate )
|
||||||
|
|
||||||
local SpawnGroup = self:GetGroup()
|
local SpawnGroup = self:GetGroup()
|
||||||
self:T( { SpawnGroup = SpawnGroup } )
|
--self:T( { SpawnGroup = SpawnGroup } )
|
||||||
|
|
||||||
if SpawnGroup then
|
if SpawnGroup then
|
||||||
|
|
||||||
@@ -286,10 +311,10 @@ function UNIT:ReSpawnAt( Coordinate, Heading )
|
|||||||
SpawnGroupTemplate.x = Coordinate.x
|
SpawnGroupTemplate.x = Coordinate.x
|
||||||
SpawnGroupTemplate.y = Coordinate.z
|
SpawnGroupTemplate.y = Coordinate.z
|
||||||
|
|
||||||
self:F( #SpawnGroupTemplate.units )
|
--self:F( #SpawnGroupTemplate.units )
|
||||||
for UnitID, UnitData in pairs( SpawnGroup:GetUnits() or {} ) do
|
for UnitID, UnitData in pairs( SpawnGroup:GetUnits() or {} ) do
|
||||||
local GroupUnit = UnitData -- #UNIT
|
local GroupUnit = UnitData -- #UNIT
|
||||||
self:F( GroupUnit:GetName() )
|
--self:F( GroupUnit:GetName() )
|
||||||
if GroupUnit:IsAlive() then
|
if GroupUnit:IsAlive() then
|
||||||
local GroupUnitVec3 = GroupUnit:GetVec3()
|
local GroupUnitVec3 = GroupUnit:GetVec3()
|
||||||
local GroupUnitHeading = GroupUnit:GetHeading()
|
local GroupUnitHeading = GroupUnit:GetHeading()
|
||||||
@@ -297,23 +322,23 @@ function UNIT:ReSpawnAt( Coordinate, Heading )
|
|||||||
SpawnGroupTemplate.units[UnitID].x = GroupUnitVec3.x
|
SpawnGroupTemplate.units[UnitID].x = GroupUnitVec3.x
|
||||||
SpawnGroupTemplate.units[UnitID].y = GroupUnitVec3.z
|
SpawnGroupTemplate.units[UnitID].y = GroupUnitVec3.z
|
||||||
SpawnGroupTemplate.units[UnitID].heading = GroupUnitHeading
|
SpawnGroupTemplate.units[UnitID].heading = GroupUnitHeading
|
||||||
self:F( { UnitID, SpawnGroupTemplate.units[UnitID], SpawnGroupTemplate.units[UnitID] } )
|
--self:F( { UnitID, SpawnGroupTemplate.units[UnitID], SpawnGroupTemplate.units[UnitID] } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for UnitTemplateID, UnitTemplateData in pairs( SpawnGroupTemplate.units ) do
|
for UnitTemplateID, UnitTemplateData in pairs( SpawnGroupTemplate.units ) do
|
||||||
self:T( { UnitTemplateData.name, self:Name() } )
|
--self:T( { UnitTemplateData.name, self:Name() } )
|
||||||
SpawnGroupTemplate.units[UnitTemplateID].unitId = nil
|
SpawnGroupTemplate.units[UnitTemplateID].unitId = nil
|
||||||
if UnitTemplateData.name == self:Name() then
|
if UnitTemplateData.name == self:Name() then
|
||||||
self:T("Adjusting")
|
--self:T("Adjusting")
|
||||||
SpawnGroupTemplate.units[UnitTemplateID].alt = Coordinate.y
|
SpawnGroupTemplate.units[UnitTemplateID].alt = Coordinate.y
|
||||||
SpawnGroupTemplate.units[UnitTemplateID].x = Coordinate.x
|
SpawnGroupTemplate.units[UnitTemplateID].x = Coordinate.x
|
||||||
SpawnGroupTemplate.units[UnitTemplateID].y = Coordinate.z
|
SpawnGroupTemplate.units[UnitTemplateID].y = Coordinate.z
|
||||||
SpawnGroupTemplate.units[UnitTemplateID].heading = Heading
|
SpawnGroupTemplate.units[UnitTemplateID].heading = Heading
|
||||||
self:F( { UnitTemplateID, SpawnGroupTemplate.units[UnitTemplateID], SpawnGroupTemplate.units[UnitTemplateID] } )
|
--self:F( { UnitTemplateID, SpawnGroupTemplate.units[UnitTemplateID], SpawnGroupTemplate.units[UnitTemplateID] } )
|
||||||
else
|
else
|
||||||
self:F( SpawnGroupTemplate.units[UnitTemplateID].name )
|
--self:F( SpawnGroupTemplate.units[UnitTemplateID].name )
|
||||||
local GroupUnit = UNIT:FindByName( SpawnGroupTemplate.units[UnitTemplateID].name ) -- #UNIT
|
local GroupUnit = UNIT:FindByName( SpawnGroupTemplate.units[UnitTemplateID].name ) -- #UNIT
|
||||||
if GroupUnit and GroupUnit:IsAlive() then
|
if GroupUnit and GroupUnit:IsAlive() then
|
||||||
local GroupUnitVec3 = GroupUnit:GetVec3()
|
local GroupUnitVec3 = GroupUnit:GetVec3()
|
||||||
@@ -324,7 +349,7 @@ function UNIT:ReSpawnAt( Coordinate, Heading )
|
|||||||
UnitTemplateData.heading = GroupUnitHeading
|
UnitTemplateData.heading = GroupUnitHeading
|
||||||
else
|
else
|
||||||
if SpawnGroupTemplate.units[UnitTemplateID].name ~= self:Name() then
|
if SpawnGroupTemplate.units[UnitTemplateID].name ~= self:Name() then
|
||||||
self:T("nilling")
|
--self:T("nilling")
|
||||||
SpawnGroupTemplate.units[UnitTemplateID].delete = true
|
SpawnGroupTemplate.units[UnitTemplateID].delete = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -336,7 +361,7 @@ function UNIT:ReSpawnAt( Coordinate, Heading )
|
|||||||
while i <= #SpawnGroupTemplate.units do
|
while i <= #SpawnGroupTemplate.units do
|
||||||
|
|
||||||
local UnitTemplateData = SpawnGroupTemplate.units[i]
|
local UnitTemplateData = SpawnGroupTemplate.units[i]
|
||||||
self:T( UnitTemplateData.name )
|
--self:T( UnitTemplateData.name )
|
||||||
|
|
||||||
if UnitTemplateData.delete then
|
if UnitTemplateData.delete then
|
||||||
table.remove( SpawnGroupTemplate.units, i )
|
table.remove( SpawnGroupTemplate.units, i )
|
||||||
@@ -347,7 +372,7 @@ function UNIT:ReSpawnAt( Coordinate, Heading )
|
|||||||
|
|
||||||
SpawnGroupTemplate.groupId = nil
|
SpawnGroupTemplate.groupId = nil
|
||||||
|
|
||||||
self:T( SpawnGroupTemplate )
|
--self:T( SpawnGroupTemplate )
|
||||||
|
|
||||||
_DATABASE:Spawn( SpawnGroupTemplate )
|
_DATABASE:Spawn( SpawnGroupTemplate )
|
||||||
end
|
end
|
||||||
@@ -358,7 +383,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #boolean `true` if Unit is activated. `nil` The DCS Unit is not existing or alive.
|
-- @return #boolean `true` if Unit is activated. `nil` The DCS Unit is not existing or alive.
|
||||||
function UNIT:IsActive()
|
function UNIT:IsActive()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -395,7 +420,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #boolean Returns `true` if Unit is alive and active, `false` if it exists but is not active and `nil` if the object does not exist or DCS `isExist` function returns false.
|
-- @return #boolean Returns `true` if Unit is alive and active, `false` if it exists but is not active and `nil` if the object does not exist or DCS `isExist` function returns false.
|
||||||
function UNIT:IsAlive()
|
function UNIT:IsAlive()
|
||||||
self:F3( self.UnitName )
|
--self:F3( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject() -- DCS#Unit
|
local DCSUnit = self:GetDCSObject() -- DCS#Unit
|
||||||
|
|
||||||
@@ -418,7 +443,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #string The Callsign of the Unit.
|
-- @return #string The Callsign of the Unit.
|
||||||
function UNIT:GetCallsign()
|
function UNIT:GetCallsign()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -430,7 +455,7 @@ function UNIT:GetCallsign()
|
|||||||
return UnitCallSign
|
return UnitCallSign
|
||||||
end
|
end
|
||||||
|
|
||||||
self:F( self.ClassName .. " " .. self.UnitName .. " not found!" )
|
--self:F( self.ClassName .. " " .. self.UnitName .. " not found!" )
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -477,7 +502,7 @@ end
|
|||||||
-- @return #string Player Name
|
-- @return #string Player Name
|
||||||
-- @return #nil The DCS Unit is not existing or alive.
|
-- @return #nil The DCS Unit is not existing or alive.
|
||||||
function UNIT:GetPlayerName()
|
function UNIT:GetPlayerName()
|
||||||
self:F( self.UnitName )
|
--self:F( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject() -- DCS#Unit
|
local DCSUnit = self:GetDCSObject() -- DCS#Unit
|
||||||
|
|
||||||
@@ -551,7 +576,7 @@ end
|
|||||||
-- @return #number The Unit number.
|
-- @return #number The Unit number.
|
||||||
-- @return #nil The DCS Unit is not existing or alive.
|
-- @return #nil The DCS Unit is not existing or alive.
|
||||||
function UNIT:GetNumber()
|
function UNIT:GetNumber()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -568,7 +593,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #number Speed in km/h.
|
-- @return #number Speed in km/h.
|
||||||
function UNIT:GetSpeedMax()
|
function UNIT:GetSpeedMax()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local Desc = self:GetDesc()
|
local Desc = self:GetDesc()
|
||||||
|
|
||||||
@@ -585,7 +610,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #number Range in meters.
|
-- @return #number Range in meters.
|
||||||
function UNIT:GetRange()
|
function UNIT:GetRange()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local Desc = self:GetDesc()
|
local Desc = self:GetDesc()
|
||||||
|
|
||||||
@@ -607,7 +632,7 @@ end
|
|||||||
-- @return #boolean If true, unit is refuelable (checks for the attribute "Refuelable").
|
-- @return #boolean If true, unit is refuelable (checks for the attribute "Refuelable").
|
||||||
-- @return #number Refueling system (if any): 0=boom, 1=probe.
|
-- @return #number Refueling system (if any): 0=boom, 1=probe.
|
||||||
function UNIT:IsRefuelable()
|
function UNIT:IsRefuelable()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local refuelable=self:HasAttribute("Refuelable")
|
local refuelable=self:HasAttribute("Refuelable")
|
||||||
|
|
||||||
@@ -626,7 +651,7 @@ end
|
|||||||
-- @return #boolean If true, unit is a tanker (checks for the attribute "Tankers").
|
-- @return #boolean If true, unit is a tanker (checks for the attribute "Tankers").
|
||||||
-- @return #number Refueling system (if any): 0=boom, 1=probe.
|
-- @return #number Refueling system (if any): 0=boom, 1=probe.
|
||||||
function UNIT:IsTanker()
|
function UNIT:IsTanker()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local tanker=self:HasAttribute("Tankers")
|
local tanker=self:HasAttribute("Tankers")
|
||||||
|
|
||||||
@@ -725,7 +750,7 @@ end
|
|||||||
-- @param Wrapper.Unit#UNIT self
|
-- @param Wrapper.Unit#UNIT self
|
||||||
-- @return Wrapper.Group#GROUP The Group of the Unit or `nil` if the unit does not exist.
|
-- @return Wrapper.Group#GROUP The Group of the Unit or `nil` if the unit does not exist.
|
||||||
function UNIT:GetGroup()
|
function UNIT:GetGroup()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
local UnitGroup = GROUP:FindByName(self.GroupName)
|
local UnitGroup = GROUP:FindByName(self.GroupName)
|
||||||
if UnitGroup then
|
if UnitGroup then
|
||||||
return UnitGroup
|
return UnitGroup
|
||||||
@@ -749,13 +774,13 @@ end
|
|||||||
-- @return #string The name of the DCS Unit.
|
-- @return #string The name of the DCS Unit.
|
||||||
-- @return #nil The DCS Unit is not existing or alive.
|
-- @return #nil The DCS Unit is not existing or alive.
|
||||||
function UNIT:GetPrefix()
|
function UNIT:GetPrefix()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
local UnitPrefix = string.match( self.UnitName, ".*#" ):sub( 1, -2 )
|
local UnitPrefix = string.match( self.UnitName, ".*#" ):sub( 1, -2 )
|
||||||
self:T3( UnitPrefix )
|
--self:T3( UnitPrefix )
|
||||||
return UnitPrefix
|
return UnitPrefix
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -766,7 +791,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return DCS#Unit.Ammo Table with ammuntion of the unit (or nil). This can be a complex table!
|
-- @return DCS#Unit.Ammo Table with ammuntion of the unit (or nil). This can be a complex table!
|
||||||
function UNIT:GetAmmo()
|
function UNIT:GetAmmo()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
--local status, unitammo = pcall(
|
--local status, unitammo = pcall(
|
||||||
@@ -958,7 +983,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return DCS#Unit.Sensors Table of sensors.
|
-- @return DCS#Unit.Sensors Table of sensors.
|
||||||
function UNIT:GetSensors()
|
function UNIT:GetSensors()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -977,7 +1002,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #boolean returns true if the unit has specified types of sensors. This function is more preferable than Unit.getSensors() if you don't want to get information about all the unit's sensors, and just want to check if the unit has specified types of sensors.
|
-- @return #boolean returns true if the unit has specified types of sensors. This function is more preferable than Unit.getSensors() if you don't want to get information about all the unit's sensors, and just want to check if the unit has specified types of sensors.
|
||||||
function UNIT:HasSensors( ... )
|
function UNIT:HasSensors( ... )
|
||||||
self:F2( arg )
|
--self:F2( arg )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -993,7 +1018,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #boolean returns true if the unit is SEADable.
|
-- @return #boolean returns true if the unit is SEADable.
|
||||||
function UNIT:HasSEAD()
|
function UNIT:HasSEAD()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -1021,7 +1046,7 @@ end
|
|||||||
-- @return #boolean Indicates if at least one of the unit's radar(s) is on.
|
-- @return #boolean Indicates if at least one of the unit's radar(s) is on.
|
||||||
-- @return DCS#Object The object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target.
|
-- @return DCS#Object The object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target.
|
||||||
function UNIT:GetRadar()
|
function UNIT:GetRadar()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -1037,7 +1062,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #number The relative amount of fuel (from 0.0 to 1.0) or *nil* if the DCS Unit is not existing or alive.
|
-- @return #number The relative amount of fuel (from 0.0 to 1.0) or *nil* if the DCS Unit is not existing or alive.
|
||||||
function UNIT:GetFuel()
|
function UNIT:GetFuel()
|
||||||
self:F3( self.UnitName )
|
--self:F3( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -1054,14 +1079,14 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #list<Wrapper.Unit#UNIT> A list of one @{Wrapper.Unit}.
|
-- @return #list<Wrapper.Unit#UNIT> A list of one @{Wrapper.Unit}.
|
||||||
function UNIT:GetUnits()
|
function UNIT:GetUnits()
|
||||||
self:F3( { self.UnitName } )
|
--self:F3( { self.UnitName } )
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
local Units = {}
|
local Units = {}
|
||||||
|
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
Units[1] = UNIT:Find( DCSUnit )
|
Units[1] = UNIT:Find( DCSUnit )
|
||||||
self:T3( Units )
|
-self:T3( Units )
|
||||||
return Units
|
return Units
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1073,7 +1098,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #number The Unit's health value or -1 if unit does not exist any more.
|
-- @return #number The Unit's health value or -1 if unit does not exist any more.
|
||||||
function UNIT:GetLife()
|
function UNIT:GetLife()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -1089,7 +1114,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #number The Unit's initial health value or 0 if unit does not exist any more.
|
-- @return #number The Unit's initial health value or 0 if unit does not exist any more.
|
||||||
function UNIT:GetLife0()
|
function UNIT:GetLife0()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -1105,7 +1130,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #number The Unit's relative health value, i.e. a number in [0,1] or -1 if unit does not exist any more.
|
-- @return #number The Unit's relative health value, i.e. a number in [0,1] or -1 if unit does not exist any more.
|
||||||
function UNIT:GetLifeRelative()
|
function UNIT:GetLifeRelative()
|
||||||
self:F2(self.UnitName)
|
--self:F2(self.UnitName)
|
||||||
|
|
||||||
if self and self:IsAlive() then
|
if self and self:IsAlive() then
|
||||||
local life0=self:GetLife0()
|
local life0=self:GetLife0()
|
||||||
@@ -1120,7 +1145,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #number The Unit's relative health value, i.e. a number in [0,1] or 1 if unit does not exist any more.
|
-- @return #number The Unit's relative health value, i.e. a number in [0,1] or 1 if unit does not exist any more.
|
||||||
function UNIT:GetDamageRelative()
|
function UNIT:GetDamageRelative()
|
||||||
self:F2(self.UnitName)
|
--self:F2(self.UnitName)
|
||||||
|
|
||||||
if self and self:IsAlive() then
|
if self and self:IsAlive() then
|
||||||
return 1-self:GetLifeRelative()
|
return 1-self:GetLifeRelative()
|
||||||
@@ -1158,7 +1183,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #number Unit category from `getDesc().category`.
|
-- @return #number Unit category from `getDesc().category`.
|
||||||
function UNIT:GetUnitCategory()
|
function UNIT:GetUnitCategory()
|
||||||
self:F3( self.UnitName )
|
--self:F3( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
@@ -1172,7 +1197,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship
|
-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship
|
||||||
function UNIT:GetCategoryName()
|
function UNIT:GetCategoryName()
|
||||||
self:F3( self.UnitName )
|
--self:F3( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
@@ -1184,7 +1209,7 @@ function UNIT:GetCategoryName()
|
|||||||
[Unit.Category.STRUCTURE] = "Structure",
|
[Unit.Category.STRUCTURE] = "Structure",
|
||||||
}
|
}
|
||||||
local UnitCategory = DCSUnit:getDesc().category
|
local UnitCategory = DCSUnit:getDesc().category
|
||||||
self:T3( UnitCategory )
|
--self:T3( UnitCategory )
|
||||||
|
|
||||||
return CategoryNames[UnitCategory]
|
return CategoryNames[UnitCategory]
|
||||||
end
|
end
|
||||||
@@ -1412,7 +1437,7 @@ end
|
|||||||
-- @return true If the other DCS Unit is within the radius of the 2D point of the DCS Unit.
|
-- @return true If the other DCS Unit is within the radius of the 2D point of the DCS Unit.
|
||||||
-- @return #nil The DCS Unit is not existing or alive.
|
-- @return #nil The DCS Unit is not existing or alive.
|
||||||
function UNIT:OtherUnitInRadius( AwaitUnit, Radius )
|
function UNIT:OtherUnitInRadius( AwaitUnit, Radius )
|
||||||
self:F2( { self.UnitName, AwaitUnit.UnitName, Radius } )
|
--self:F2( { self.UnitName, AwaitUnit.UnitName, Radius } )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
@@ -1421,10 +1446,10 @@ function UNIT:OtherUnitInRadius( AwaitUnit, Radius )
|
|||||||
local AwaitUnitVec3 = AwaitUnit:GetVec3()
|
local AwaitUnitVec3 = AwaitUnit:GetVec3()
|
||||||
|
|
||||||
if (((UnitVec3.x - AwaitUnitVec3.x)^2 + (UnitVec3.z - AwaitUnitVec3.z)^2)^0.5 <= Radius) then
|
if (((UnitVec3.x - AwaitUnitVec3.x)^2 + (UnitVec3.z - AwaitUnitVec3.z)^2)^0.5 <= Radius) then
|
||||||
self:T3( "true" )
|
--self:T3( "true" )
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
self:T3( "false" )
|
--self:T3( "false" )
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1442,17 +1467,17 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #boolean IsFriendly evaluation result.
|
-- @return #boolean IsFriendly evaluation result.
|
||||||
function UNIT:IsFriendly( FriendlyCoalition )
|
function UNIT:IsFriendly( FriendlyCoalition )
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
local UnitCoalition = DCSUnit:getCoalition()
|
local UnitCoalition = DCSUnit:getCoalition()
|
||||||
self:T3( { UnitCoalition, FriendlyCoalition } )
|
--self:T3( { UnitCoalition, FriendlyCoalition } )
|
||||||
|
|
||||||
local IsFriendlyResult = ( UnitCoalition == FriendlyCoalition )
|
local IsFriendlyResult = ( UnitCoalition == FriendlyCoalition )
|
||||||
|
|
||||||
self:F( IsFriendlyResult )
|
--self:F( IsFriendlyResult )
|
||||||
return IsFriendlyResult
|
return IsFriendlyResult
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1464,17 +1489,17 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #boolean Ship category evaluation result.
|
-- @return #boolean Ship category evaluation result.
|
||||||
function UNIT:IsShip()
|
function UNIT:IsShip()
|
||||||
self:F2()
|
--self:F2()
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
local UnitDescriptor = DCSUnit:getDesc()
|
local UnitDescriptor = DCSUnit:getDesc()
|
||||||
self:T3( { UnitDescriptor.category, Unit.Category.SHIP } )
|
--self:T3( { UnitDescriptor.category, Unit.Category.SHIP } )
|
||||||
|
|
||||||
local IsShipResult = ( UnitDescriptor.category == Unit.Category.SHIP )
|
local IsShipResult = ( UnitDescriptor.category == Unit.Category.SHIP )
|
||||||
|
|
||||||
self:T3( IsShipResult )
|
--self:T3( IsShipResult )
|
||||||
return IsShipResult
|
return IsShipResult
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1486,7 +1511,7 @@ end
|
|||||||
-- @param #boolean NoHeloCheck If true, no additonal checks for helos are performed.
|
-- @param #boolean NoHeloCheck If true, no additonal checks for helos are performed.
|
||||||
-- @return #boolean Return true if in the air or #nil if the UNIT is not existing or alive.
|
-- @return #boolean Return true if in the air or #nil if the UNIT is not existing or alive.
|
||||||
function UNIT:InAir(NoHeloCheck)
|
function UNIT:InAir(NoHeloCheck)
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
-- Get DCS unit object.
|
-- Get DCS unit object.
|
||||||
local DCSUnit = self:GetDCSObject() --DCS#Unit
|
local DCSUnit = self:GetDCSObject() --DCS#Unit
|
||||||
@@ -1500,7 +1525,7 @@ function UNIT:InAir(NoHeloCheck)
|
|||||||
local UnitCategory = DCSUnit:getDesc().category
|
local UnitCategory = DCSUnit:getDesc().category
|
||||||
|
|
||||||
-- If DCS says that it is in air, check if this is really the case, since we might have landed on a building where inAir()=true but actually is not.
|
-- If DCS says that it is in air, check if this is really the case, since we might have landed on a building where inAir()=true but actually is not.
|
||||||
-- This is a workaround since DCS currently does not acknoledge that helos land on buildings.
|
-- This is a workaround since DCS currently does not acknowledge that helos land on buildings.
|
||||||
-- Note however, that the velocity check will fail if the ground is moving, e.g. on an aircraft carrier!
|
-- Note however, that the velocity check will fail if the ground is moving, e.g. on an aircraft carrier!
|
||||||
if UnitInAir==true and UnitCategory == Unit.Category.HELICOPTER and (not NoHeloCheck) then
|
if UnitInAir==true and UnitCategory == Unit.Category.HELICOPTER and (not NoHeloCheck) then
|
||||||
local VelocityVec3 = DCSUnit:getVelocity()
|
local VelocityVec3 = DCSUnit:getVelocity()
|
||||||
@@ -1513,7 +1538,7 @@ function UNIT:InAir(NoHeloCheck)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T3( UnitInAir )
|
--self:T3( UnitInAir )
|
||||||
return UnitInAir
|
return UnitInAir
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1708,7 +1733,7 @@ end
|
|||||||
-- @param #boolean switch If true, emission is enabled. If false, emission is disabled.
|
-- @param #boolean switch If true, emission is enabled. If false, emission is disabled.
|
||||||
-- @return #UNIT self
|
-- @return #UNIT self
|
||||||
function UNIT:EnableEmission(switch)
|
function UNIT:EnableEmission(switch)
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
|
|
||||||
local switch = switch or false
|
local switch = switch or false
|
||||||
|
|
||||||
@@ -1727,9 +1752,12 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #string Skill String of skill name.
|
-- @return #string Skill String of skill name.
|
||||||
function UNIT:GetSkill()
|
function UNIT:GetSkill()
|
||||||
self:F2( self.UnitName )
|
--self:F2( self.UnitName )
|
||||||
local name = self.UnitName
|
local name = self.UnitName
|
||||||
local skill = _DATABASE.Templates.Units[name].Template.skill or "Random"
|
local skill = "Random"
|
||||||
|
if _DATABASE.Templates.Units[name] and _DATABASE.Templates.Units[name].Template and _DATABASE.Templates.Units[name].Template.skill then
|
||||||
|
skill = _DATABASE.Templates.Units[name].Template.skill or "Random"
|
||||||
|
end
|
||||||
return skill
|
return skill
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1740,7 +1768,7 @@ end
|
|||||||
-- @return #string VCN Voice Callsign Number or nil if not set/capable.
|
-- @return #string VCN Voice Callsign Number or nil if not set/capable.
|
||||||
-- @return #string Lead If true, unit is Flight Lead, else false or nil.
|
-- @return #string Lead If true, unit is Flight Lead, else false or nil.
|
||||||
function UNIT:GetSTN()
|
function UNIT:GetSTN()
|
||||||
self:F2(self.UnitName)
|
--self:F2(self.UnitName)
|
||||||
local STN = nil -- STN/TN
|
local STN = nil -- STN/TN
|
||||||
local VCL = nil -- VoiceCallsignLabel
|
local VCL = nil -- VoiceCallsignLabel
|
||||||
local VCN = nil -- VoiceCallsignNumber
|
local VCN = nil -- VoiceCallsignNumber
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ Wrapper/Marker.lua
|
|||||||
Wrapper/Weapon.lua
|
Wrapper/Weapon.lua
|
||||||
Wrapper/Net.lua
|
Wrapper/Net.lua
|
||||||
Wrapper/Storage.lua
|
Wrapper/Storage.lua
|
||||||
|
Wrapper/DynamicCargo.lua
|
||||||
|
|
||||||
Functional/Scoring.lua
|
Functional/Scoring.lua
|
||||||
Functional/CleanUp.lua
|
Functional/CleanUp.lua
|
||||||
|
|||||||
Reference in New Issue
Block a user