mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43ab4d5f38 | ||
|
|
0427c0d3a7 | ||
|
|
014750ea7f | ||
|
|
e4bbfce314 | ||
|
|
359429b17e | ||
|
|
6001f6abda | ||
|
|
fd9b5d8d16 | ||
|
|
b6f184388a | ||
|
|
d8471698ab | ||
|
|
6204cecbbd | ||
|
|
ddeca49916 | ||
|
|
d8dcf37886 | ||
|
|
5ae41a208b | ||
|
|
0462d900e6 | ||
|
|
0f962461e1 | ||
|
|
aadc03c38d | ||
|
|
683fa13bb2 | ||
|
|
e4408a964d | ||
|
|
f97f33ab59 | ||
|
|
f59102ee09 | ||
|
|
e42e4e1ddf | ||
|
|
a30079c45b | ||
|
|
50ffd9aba6 | ||
|
|
936fec1f49 | ||
|
|
9625d87dd5 | ||
|
|
802139205c | ||
|
|
fb918cb2a4 | ||
|
|
abb4de46d7 | ||
|
|
dce9631399 | ||
|
|
6c773786d2 | ||
|
|
8939963187 | ||
|
|
f9747d1c4c | ||
|
|
60a3d3409e | ||
|
|
b72124c0d9 | ||
|
|
d51e761b26 | ||
|
|
1445ef61a0 | ||
|
|
dfe2ed2a98 | ||
|
|
be87103b53 | ||
|
|
2fb460c4bb | ||
|
|
216ea230a8 | ||
|
|
90096163ee | ||
|
|
cd178d6a8c | ||
|
|
2aa0b5ddfb | ||
|
|
37f819458a | ||
|
|
168f4301d2 | ||
|
|
d5a406c60f | ||
|
|
cb16210577 | ||
|
|
8c0e0de45f | ||
|
|
3524cba4ef | ||
|
|
5f8d1cf5b0 | ||
|
|
846aa823d4 | ||
|
|
68298fc585 | ||
|
|
e9d75f6d94 | ||
|
|
8fa5277417 | ||
|
|
231f1f236d | ||
|
|
ece0a46f97 | ||
|
|
2c9b0b8376 | ||
|
|
a798f2d61c | ||
|
|
ae08c87822 | ||
|
|
ae880e9d1c | ||
|
|
101d2e1de5 | ||
|
|
f6b7708567 | ||
|
|
051286acd1 |
@@ -34,11 +34,12 @@ local _TraceClassMethod = {}
|
|||||||
|
|
||||||
local _ClassID = 0
|
local _ClassID = 0
|
||||||
|
|
||||||
---
|
--- Base class of everything
|
||||||
-- @type BASE
|
-- @type BASE
|
||||||
-- @field ClassName The name of the class.
|
-- @field #string ClassName The name of the class.
|
||||||
-- @field ClassID The ID number of the class.
|
-- @field #number ClassID The ID number of the class.
|
||||||
-- @field ClassNameAndID The name of the class concatenated with the ID number of the class.
|
-- @field #string ClassNameAndID The name of the class concatenated with the ID number of the class.
|
||||||
|
-- @field Core.Scheduler#SCHEDULER Scheduler The scheduler object.
|
||||||
|
|
||||||
--- BASE class
|
--- BASE class
|
||||||
--
|
--
|
||||||
@@ -210,14 +211,6 @@ BASE._ = {
|
|||||||
Schedules = {}, --- Contains the Schedulers Active
|
Schedules = {}, --- Contains the Schedulers Active
|
||||||
}
|
}
|
||||||
|
|
||||||
--- The Formation Class
|
|
||||||
-- @type FORMATION
|
|
||||||
-- @field Cone A cone formation.
|
|
||||||
FORMATION = {
|
|
||||||
Cone = "Cone",
|
|
||||||
Vee = "Vee",
|
|
||||||
}
|
|
||||||
|
|
||||||
--- BASE constructor.
|
--- BASE constructor.
|
||||||
--
|
--
|
||||||
-- This is an example how to use the BASE:New() constructor in a new class definition when inheriting from BASE.
|
-- This is an example how to use the BASE:New() constructor in a new class definition when inheriting from BASE.
|
||||||
@@ -1416,7 +1409,7 @@ function BASE:E( Arguments )
|
|||||||
|
|
||||||
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, UTILS.BasicSerialize( Arguments ) ) )
|
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, UTILS.BasicSerialize( Arguments ) ) )
|
||||||
else
|
else
|
||||||
env.info( string.format( "%1s:%30s%05d(%s)", "E", self.ClassName, self.ClassID, BASE:_Serialize(Arguments) ) )
|
env.info( string.format( "%1s:%30s%05d(%s)", "E", self.ClassName, self.ClassID, UTILS.BasicSerialize(Arguments) ) )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1443,7 +1436,7 @@ function BASE:I( Arguments )
|
|||||||
|
|
||||||
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "I", self.ClassName, self.ClassID, Function, UTILS.BasicSerialize( Arguments ) ) )
|
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "I", self.ClassName, self.ClassID, Function, UTILS.BasicSerialize( Arguments ) ) )
|
||||||
else
|
else
|
||||||
env.info( string.format( "%1s:%30s%05d(%s)", "I", self.ClassName, self.ClassID, BASE:_Serialize(Arguments)) )
|
env.info( string.format( "%1s:%30s%05d(%s)", "I", self.ClassName, self.ClassID, UTILS.BasicSerialize(Arguments)) )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -211,10 +211,9 @@ function DATABASE:AddStatic( DCSStaticName )
|
|||||||
|
|
||||||
if not self.STATICS[DCSStaticName] then
|
if not self.STATICS[DCSStaticName] then
|
||||||
self.STATICS[DCSStaticName] = STATIC:Register( DCSStaticName )
|
self.STATICS[DCSStaticName] = STATIC:Register( DCSStaticName )
|
||||||
return self.STATICS[DCSStaticName]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
return self.STATICS[DCSStaticName]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -224,12 +223,11 @@ function DATABASE:DeleteStatic( DCSStaticName )
|
|||||||
self.STATICS[DCSStaticName] = nil
|
self.STATICS[DCSStaticName] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Finds a STATIC based on the StaticName.
|
--- Finds a STATIC based on the Static Name.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string StaticName
|
-- @param #string StaticName Name of the static object.
|
||||||
-- @return Wrapper.Static#STATIC The found STATIC.
|
-- @return Wrapper.Static#STATIC The found STATIC.
|
||||||
function DATABASE:FindStatic( StaticName )
|
function DATABASE:FindStatic( StaticName )
|
||||||
|
|
||||||
local StaticFound = self.STATICS[StaticName]
|
local StaticFound = self.STATICS[StaticName]
|
||||||
return StaticFound
|
return StaticFound
|
||||||
end
|
end
|
||||||
@@ -241,9 +239,8 @@ end
|
|||||||
function DATABASE:AddDynamicCargo( Name )
|
function DATABASE:AddDynamicCargo( Name )
|
||||||
if not self.DYNAMICCARGO[Name] then
|
if not self.DYNAMICCARGO[Name] then
|
||||||
self.DYNAMICCARGO[Name] = DYNAMICCARGO:Register(Name)
|
self.DYNAMICCARGO[Name] = DYNAMICCARGO:Register(Name)
|
||||||
return self.DYNAMICCARGO[Name]
|
|
||||||
end
|
end
|
||||||
return nil
|
return self.DYNAMICCARGO[Name]
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Finds a DYNAMICCARGO based on the Dynamic Cargo Name.
|
--- Finds a DYNAMICCARGO based on the Dynamic Cargo Name.
|
||||||
@@ -1582,12 +1579,29 @@ end
|
|||||||
-- @param DCS#Airbase airbase Airbase.
|
-- @param DCS#Airbase airbase Airbase.
|
||||||
-- @return #DATABASE self
|
-- @return #DATABASE self
|
||||||
function DATABASE:_RegisterAirbase(airbase)
|
function DATABASE:_RegisterAirbase(airbase)
|
||||||
|
|
||||||
|
local IsSyria = UTILS.GetDCSMap() == "Syria" and true or false
|
||||||
|
local countHSyria = 0
|
||||||
|
|
||||||
if airbase then
|
if airbase then
|
||||||
|
|
||||||
-- Get the airbase name.
|
-- Get the airbase name.
|
||||||
local DCSAirbaseName = airbase:getName()
|
local DCSAirbaseName = airbase:getName()
|
||||||
|
|
||||||
|
-- DCS 2.9.8.1107 added 143 helipads all named H with the same object ID ..
|
||||||
|
if IsSyria and DCSAirbaseName == "H" and countHSyria > 0 then
|
||||||
|
--[[
|
||||||
|
local p = airbase:getPosition().p
|
||||||
|
local mgrs = COORDINATE:New(p.x,p.z,p.y):ToStringMGRS()
|
||||||
|
self:I("Airbase on Syria map named H @ "..mgrs)
|
||||||
|
countHSyria = countHSyria + 1
|
||||||
|
if countHSyria > 1 then return self end
|
||||||
|
--]]
|
||||||
|
return self
|
||||||
|
elseif IsSyria and DCSAirbaseName == "H" and countHSyria == 0 then
|
||||||
|
countHSyria = countHSyria + 1
|
||||||
|
end
|
||||||
|
|
||||||
-- This gave the incorrect value to be inserted into the airdromeID for DCS 2.5.6. Is fixed now.
|
-- This gave the incorrect value to be inserted into the airdromeID for DCS 2.5.6. Is fixed now.
|
||||||
local airbaseID=airbase:getID()
|
local airbaseID=airbase:getID()
|
||||||
|
|
||||||
|
|||||||
@@ -1329,6 +1329,7 @@ function EVENT:onEvent( Event )
|
|||||||
end
|
end
|
||||||
|
|
||||||
Event.IniDCSGroupName = Event.IniUnit and Event.IniUnit.GroupName or ""
|
Event.IniDCSGroupName = Event.IniUnit and Event.IniUnit.GroupName or ""
|
||||||
|
Event.IniGroupName=Event.IniDCSGroupName --At least set the group name because group might not exist any more
|
||||||
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
||||||
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
||||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
@@ -1371,7 +1372,7 @@ function EVENT:onEvent( Event )
|
|||||||
-- Scenery
|
-- Scenery
|
||||||
---
|
---
|
||||||
Event.IniDCSUnit = Event.initiator
|
Event.IniDCSUnit = Event.initiator
|
||||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
Event.IniDCSUnitName = Event.IniDCSUnit.getName and Event.IniDCSUnit:getName() or "Scenery no name "..math.random(1,20000)
|
||||||
Event.IniUnitName = Event.IniDCSUnitName
|
Event.IniUnitName = Event.IniDCSUnitName
|
||||||
Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator )
|
Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator )
|
||||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||||
@@ -1473,11 +1474,13 @@ function EVENT:onEvent( Event )
|
|||||||
-- SCENERY
|
-- SCENERY
|
||||||
---
|
---
|
||||||
Event.TgtDCSUnit = Event.target
|
Event.TgtDCSUnit = Event.target
|
||||||
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName()
|
Event.TgtDCSUnitName = Event.TgtDCSUnit.getName and Event.TgtDCSUnit.getName() or nil
|
||||||
Event.TgtUnitName = Event.TgtDCSUnitName
|
if Event.TgtDCSUnitName~=nil then
|
||||||
Event.TgtUnit = SCENERY:Register( Event.TgtDCSUnitName, Event.target )
|
Event.TgtUnitName = Event.TgtDCSUnitName
|
||||||
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
|
Event.TgtUnit = SCENERY:Register( Event.TgtDCSUnitName, Event.target )
|
||||||
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
|
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
|
||||||
|
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -108,26 +108,30 @@ function MARKEROPS_BASE:New(Tagname,Keywords,Casesensitive)
|
|||||||
--- On after "MarkAdded" event. Triggered when a Marker is added to the F10 map.
|
--- On after "MarkAdded" event. Triggered when a Marker is added to the F10 map.
|
||||||
-- @function [parent=#MARKEROPS_BASE] OnAfterMarkAdded
|
-- @function [parent=#MARKEROPS_BASE] OnAfterMarkAdded
|
||||||
-- @param #MARKEROPS_BASE self
|
-- @param #MARKEROPS_BASE self
|
||||||
-- @param #string From The From state
|
-- @param #string From The From state.
|
||||||
-- @param #string Event The Event called
|
-- @param #string Event The Event called.
|
||||||
-- @param #string To The To state
|
-- @param #string To The To state.
|
||||||
-- @param #string Text The text on the marker
|
-- @param #string Text The text on the marker.
|
||||||
-- @param #table Keywords Table of matching keywords found in the Event text
|
-- @param #table Keywords Table of matching keywords found in the Event text.
|
||||||
-- @param Core.Point#COORDINATE Coord Coordinate of the marker.
|
-- @param Core.Point#COORDINATE Coord Coordinate of the marker.
|
||||||
-- @param #number MarkerID Id of this marker
|
-- @param #number MarkerID Id of this marker.
|
||||||
-- @param #number CoalitionNumber Coalition of the marker creator
|
-- @param #number CoalitionNumber Coalition of the marker creator.
|
||||||
|
-- @param #string PlayerName Name of the player creating/changing the mark. nil if it cannot be obtained.
|
||||||
|
-- @param Core.Event#EVENTDATA EventData the event data table.
|
||||||
|
|
||||||
--- On after "MarkChanged" event. Triggered when a Marker is changed on the F10 map.
|
--- On after "MarkChanged" event. Triggered when a Marker is changed on the F10 map.
|
||||||
-- @function [parent=#MARKEROPS_BASE] OnAfterMarkChanged
|
-- @function [parent=#MARKEROPS_BASE] OnAfterMarkChanged
|
||||||
-- @param #MARKEROPS_BASE self
|
-- @param #MARKEROPS_BASE self
|
||||||
-- @param #string From The From state
|
-- @param #string From The From state.
|
||||||
-- @param #string Event The Event called
|
-- @param #string Event The Event called.
|
||||||
-- @param #string To The To state
|
-- @param #string To The To state.
|
||||||
-- @param #string Text The text on the marker
|
-- @param #string Text The text on the marker.
|
||||||
-- @param #table Keywords Table of matching keywords found in the Event text
|
-- @param #table Keywords Table of matching keywords found in the Event text.
|
||||||
-- @param Core.Point#COORDINATE Coord Coordinate of the marker.
|
-- @param Core.Point#COORDINATE Coord Coordinate of the marker.
|
||||||
-- @param #number MarkerID Id of this marker
|
-- @param #number MarkerID Id of this marker.
|
||||||
-- @param #number CoalitionNumber Coalition of the marker creator
|
-- @param #number CoalitionNumber Coalition of the marker creator.
|
||||||
|
-- @param #string PlayerName Name of the player creating/changing the mark. nil if it cannot be obtained.
|
||||||
|
-- @param Core.Event#EVENTDATA EventData the event data table
|
||||||
|
|
||||||
--- On after "MarkDeleted" event. Triggered when a Marker is deleted from the F10 map.
|
--- On after "MarkDeleted" event. Triggered when a Marker is deleted from the F10 map.
|
||||||
-- @function [parent=#MARKEROPS_BASE] OnAfterMarkDeleted
|
-- @function [parent=#MARKEROPS_BASE] OnAfterMarkDeleted
|
||||||
@@ -167,7 +171,7 @@ function MARKEROPS_BASE:OnEventMark(Event)
|
|||||||
if Eventtext~=nil then
|
if Eventtext~=nil then
|
||||||
if self:_MatchTag(Eventtext) then
|
if self:_MatchTag(Eventtext) then
|
||||||
local matchtable = self:_MatchKeywords(Eventtext)
|
local matchtable = self:_MatchKeywords(Eventtext)
|
||||||
self:MarkAdded(Eventtext,matchtable,coord,Event.idx,coalition)
|
self:MarkAdded(Eventtext,matchtable,coord,Event.idx,coalition,Event.PlayerName,Event)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif Event.id==world.event.S_EVENT_MARK_CHANGE then
|
elseif Event.id==world.event.S_EVENT_MARK_CHANGE then
|
||||||
@@ -177,7 +181,7 @@ function MARKEROPS_BASE:OnEventMark(Event)
|
|||||||
if Eventtext~=nil then
|
if Eventtext~=nil then
|
||||||
if self:_MatchTag(Eventtext) then
|
if self:_MatchTag(Eventtext) then
|
||||||
local matchtable = self:_MatchKeywords(Eventtext)
|
local matchtable = self:_MatchKeywords(Eventtext)
|
||||||
self:MarkChanged(Eventtext,matchtable,coord,Event.idx,coalition)
|
self:MarkChanged(Eventtext,matchtable,coord,Event.idx,coalition,Event.PlayerName,Event)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif Event.id==world.event.S_EVENT_MARK_REMOVED then
|
elseif Event.id==world.event.S_EVENT_MARK_REMOVED then
|
||||||
|
|||||||
@@ -75,35 +75,37 @@ MESSAGE.Type = {
|
|||||||
|
|
||||||
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{#MESSAGE.ToClient} or @{#MESSAGE.ToCoalition} or @{#MESSAGE.ToAll} to send these Messages to the respective recipients.
|
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{#MESSAGE.ToClient} or @{#MESSAGE.ToCoalition} or @{#MESSAGE.ToAll} to send these Messages to the respective recipients.
|
||||||
-- @param self
|
-- @param self
|
||||||
-- @param #string MessageText is the text of the Message.
|
-- @param #string Text is the text of the Message.
|
||||||
-- @param #number MessageDuration is a number in seconds of how long the MESSAGE should be shown on the display panel.
|
-- @param #number Duration Duration in seconds how long the message text is shown.
|
||||||
-- @param #string MessageCategory (optional) is a string expressing the "category" of the Message. The category will be shown as the first text in the message followed by a ": ".
|
-- @param #string Category (Optional) String expressing the "category" of the Message. The category will be shown as the first text in the message followed by a ": ".
|
||||||
-- @param #boolean ClearScreen (optional) Clear all previous messages if true.
|
-- @param #boolean ClearScreen (optional) Clear all previous messages if true.
|
||||||
-- @return #MESSAGE
|
-- @return #MESSAGE self
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
-- -- Create a series of new Messages.
|
-- -- Create a series of new Messages.
|
||||||
-- -- MessageAll is meant to be sent to all players, for 25 seconds, and is classified as "Score".
|
-- -- MessageAll is meant to be sent to all players, for 25 seconds, and is classified as "Score".
|
||||||
-- -- MessageRED is meant to be sent to the RED players only, for 10 seconds, and is classified as "End of Mission", with ID "Win".
|
-- -- MessageRED is meant to be sent to the RED players only, for 10 seconds, and is classified as "End of Mission", with ID "Win".
|
||||||
-- -- MessageClient1 is meant to be sent to a Client, for 25 seconds, and is classified as "Score", with ID "Score".
|
-- -- MessageClient1 is meant to be sent to a Client, for 25 seconds, and is classified as "Score", with ID "Score".
|
||||||
-- -- MessageClient1 is meant to be sent to a Client, for 25 seconds, and is classified as "Score", with ID "Score".
|
-- -- MessageClient1 is meant to be sent to a Client, for 25 seconds, and is classified as "Score", with ID "Score".
|
||||||
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", 25, "End of Mission" )
|
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", 25, "End of Mission" )
|
||||||
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", 25, "Penalty" )
|
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", 25, "Penalty" )
|
||||||
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", 25, "Score" )
|
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", 25, "Score" )
|
||||||
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", 25, "Score")
|
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", 25, "Score")
|
||||||
--
|
--
|
||||||
function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen )
|
function MESSAGE:New( Text, Duration, Category, ClearScreen )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
self:F( { MessageText, MessageDuration, MessageCategory } )
|
|
||||||
|
self:F( { Text, Duration, Category } )
|
||||||
|
|
||||||
self.MessageType = nil
|
self.MessageType = nil
|
||||||
|
|
||||||
-- When no MessageCategory is given, we don't show it as a title...
|
-- When no MessageCategory is given, we don't show it as a title...
|
||||||
if MessageCategory and MessageCategory ~= "" then
|
if Category and Category ~= "" then
|
||||||
if MessageCategory:sub( -1 ) ~= "\n" then
|
if Category:sub( -1 ) ~= "\n" then
|
||||||
self.MessageCategory = MessageCategory .. ": "
|
self.MessageCategory = Category .. ": "
|
||||||
else
|
else
|
||||||
self.MessageCategory = MessageCategory:sub( 1, -2 ) .. ":\n"
|
self.MessageCategory = Category:sub( 1, -2 ) .. ":\n"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self.MessageCategory = ""
|
self.MessageCategory = ""
|
||||||
@@ -114,9 +116,9 @@ function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen
|
|||||||
self.ClearScreen = ClearScreen
|
self.ClearScreen = ClearScreen
|
||||||
end
|
end
|
||||||
|
|
||||||
self.MessageDuration = MessageDuration or 5
|
self.MessageDuration = Duration or 5
|
||||||
self.MessageTime = timer.getTime()
|
self.MessageTime = timer.getTime()
|
||||||
self.MessageText = MessageText:gsub( "^\n", "", 1 ):gsub( "\n$", "", 1 )
|
self.MessageText = Text:gsub( "^\n", "", 1 ):gsub( "\n$", "", 1 )
|
||||||
|
|
||||||
self.MessageSent = false
|
self.MessageSent = false
|
||||||
self.MessageGroup = false
|
self.MessageGroup = false
|
||||||
|
|||||||
@@ -1709,7 +1709,7 @@ do
|
|||||||
|
|
||||||
--- Iterate the SET_GROUP and return true if all the @{Wrapper.Group#GROUP} are completely in the @{Core.Zone#ZONE}
|
--- Iterate the SET_GROUP and return true if all the @{Wrapper.Group#GROUP} are completely in the @{Core.Zone#ZONE}
|
||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
-- @param Core.Zone#ZONE ZoneObject The Zone to be tested for.
|
-- @param Core.Zone#ZONE Zone The Zone to be tested for.
|
||||||
-- @return #boolean true if all the @{Wrapper.Group#GROUP} are completely in the @{Core.Zone#ZONE}, false otherwise
|
-- @return #boolean true if all the @{Wrapper.Group#GROUP} are completely in the @{Core.Zone#ZONE}, false otherwise
|
||||||
-- @usage
|
-- @usage
|
||||||
-- local MyZone = ZONE:New("Zone1")
|
-- local MyZone = ZONE:New("Zone1")
|
||||||
@@ -1756,7 +1756,7 @@ do
|
|||||||
|
|
||||||
--- Iterate the SET_GROUP and return true if at least one of the @{Wrapper.Group#GROUP} is completely inside the @{Core.Zone#ZONE}
|
--- Iterate the SET_GROUP and return true if at least one of the @{Wrapper.Group#GROUP} is completely inside the @{Core.Zone#ZONE}
|
||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
-- @param Core.Zone#ZONE ZoneObject The Zone to be tested for.
|
-- @param Core.Zone#ZONE Zone The Zone to be tested for.
|
||||||
-- @return #boolean true if at least one of the @{Wrapper.Group#GROUP} is completely inside the @{Core.Zone#ZONE}, false otherwise.
|
-- @return #boolean true if at least one of the @{Wrapper.Group#GROUP} is completely inside the @{Core.Zone#ZONE}, false otherwise.
|
||||||
-- @usage
|
-- @usage
|
||||||
-- local MyZone = ZONE:New("Zone1")
|
-- local MyZone = ZONE:New("Zone1")
|
||||||
@@ -1781,7 +1781,7 @@ do
|
|||||||
|
|
||||||
--- Iterate the SET_GROUP and return true if at least one @{#UNIT} of one @{Wrapper.Group#GROUP} of the @{#SET_GROUP} is in @{Core.Zone}
|
--- Iterate the SET_GROUP and return true if at least one @{#UNIT} of one @{Wrapper.Group#GROUP} of the @{#SET_GROUP} is in @{Core.Zone}
|
||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
-- @param Core.Zone#ZONE ZoneObject The Zone to be tested for.
|
-- @param Core.Zone#ZONE Zone The Zone to be tested for.
|
||||||
-- @return #boolean true if at least one of the @{Wrapper.Group#GROUP} is partly or completely inside the @{Core.Zone#ZONE}, false otherwise.
|
-- @return #boolean true if at least one of the @{Wrapper.Group#GROUP} is partly or completely inside the @{Core.Zone#ZONE}, false otherwise.
|
||||||
-- @usage
|
-- @usage
|
||||||
-- local MyZone = ZONE:New("Zone1")
|
-- local MyZone = ZONE:New("Zone1")
|
||||||
@@ -1807,7 +1807,7 @@ do
|
|||||||
--- Iterate the SET_GROUP and return true if at least one @{Wrapper.Group#GROUP} of the @{#SET_GROUP} is partly in @{Core.Zone}.
|
--- Iterate the SET_GROUP and return true if at least one @{Wrapper.Group#GROUP} of the @{#SET_GROUP} is partly in @{Core.Zone}.
|
||||||
-- Will return false if a @{Wrapper.Group#GROUP} is fully in the @{Core.Zone}
|
-- Will return false if a @{Wrapper.Group#GROUP} is fully in the @{Core.Zone}
|
||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
-- @param Core.Zone#ZONE ZoneObject The Zone to be tested for.
|
-- @param Core.Zone#ZONE Zone The Zone to be tested for.
|
||||||
-- @return #boolean true if at least one of the @{Wrapper.Group#GROUP} is partly or completely inside the @{Core.Zone#ZONE}, false otherwise.
|
-- @return #boolean true if at least one of the @{Wrapper.Group#GROUP} is partly or completely inside the @{Core.Zone#ZONE}, false otherwise.
|
||||||
-- @usage
|
-- @usage
|
||||||
-- local MyZone = ZONE:New("Zone1")
|
-- local MyZone = ZONE:New("Zone1")
|
||||||
@@ -1842,7 +1842,7 @@ do
|
|||||||
-- This could also be achieved with `not SET_GROUP:AnyPartlyInZone(Zone)`, but it's easier for the
|
-- This could also be achieved with `not SET_GROUP:AnyPartlyInZone(Zone)`, but it's easier for the
|
||||||
-- mission designer to add a dedicated method
|
-- mission designer to add a dedicated method
|
||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
-- @param Core.Zone#ZONE ZoneObject The Zone to be tested for.
|
-- @param Core.Zone#ZONE Zone The Zone to be tested for.
|
||||||
-- @return #boolean true if no @{Wrapper.Group#GROUP} is inside the @{Core.Zone#ZONE} in any way, false otherwise.
|
-- @return #boolean true if no @{Wrapper.Group#GROUP} is inside the @{Core.Zone#ZONE} in any way, false otherwise.
|
||||||
-- @usage
|
-- @usage
|
||||||
-- local MyZone = ZONE:New("Zone1")
|
-- local MyZone = ZONE:New("Zone1")
|
||||||
@@ -1869,7 +1869,7 @@ do
|
|||||||
-- That could easily be done with SET_GROUP:ForEachGroupCompletelyInZone(), but this function
|
-- That could easily be done with SET_GROUP:ForEachGroupCompletelyInZone(), but this function
|
||||||
-- provides an easy to use shortcut...
|
-- provides an easy to use shortcut...
|
||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
-- @param Core.Zone#ZONE ZoneObject The Zone to be tested for.
|
-- @param Core.Zone#ZONE Zone The Zone to be tested for.
|
||||||
-- @return #number the number of GROUPs completely in the Zone
|
-- @return #number the number of GROUPs completely in the Zone
|
||||||
-- @usage
|
-- @usage
|
||||||
-- local MyZone = ZONE:New("Zone1")
|
-- local MyZone = ZONE:New("Zone1")
|
||||||
@@ -1891,7 +1891,7 @@ do
|
|||||||
|
|
||||||
--- Iterate the SET_GROUP and count how many UNITs are completely in the Zone
|
--- Iterate the SET_GROUP and count how many UNITs are completely in the Zone
|
||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
-- @param Core.Zone#ZONE ZoneObject The Zone to be tested for.
|
-- @param Core.Zone#ZONE Zone The Zone to be tested for.
|
||||||
-- @return #number the number of GROUPs completely in the Zone
|
-- @return #number the number of GROUPs completely in the Zone
|
||||||
-- @usage
|
-- @usage
|
||||||
-- local MyZone = ZONE:New("Zone1")
|
-- local MyZone = ZONE:New("Zone1")
|
||||||
@@ -2706,7 +2706,7 @@ do -- SET_UNIT
|
|||||||
|
|
||||||
--- Check if no element of the SET_UNIT is in the Zone.
|
--- Check if no element of the SET_UNIT is in the Zone.
|
||||||
-- @param #SET_UNIT self
|
-- @param #SET_UNIT self
|
||||||
-- @param Core.Zone#ZONE ZoneObject The Zone to be tested for.
|
-- @param Core.Zone#ZONE Zone The Zone to be tested for.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
function SET_UNIT:IsNotInZone( Zone )
|
function SET_UNIT:IsNotInZone( Zone )
|
||||||
|
|
||||||
@@ -3746,7 +3746,7 @@ do -- SET_STATIC
|
|||||||
|
|
||||||
--- Check if no element of the SET_STATIC is in the Zone.
|
--- Check if no element of the SET_STATIC is in the Zone.
|
||||||
-- @param #SET_STATIC self
|
-- @param #SET_STATIC self
|
||||||
-- @param Core.Zone#ZONE ZoneObject The Zone to be tested for.
|
-- @param Core.Zone#ZONE Zone The Zone to be tested for.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
function SET_STATIC:IsNotInZone( Zone )
|
function SET_STATIC:IsNotInZone( Zone )
|
||||||
|
|
||||||
@@ -7936,22 +7936,31 @@ do -- SET_OPSGROUP
|
|||||||
--- Handles the OnBirth event for the Set.
|
--- Handles the OnBirth event for the Set.
|
||||||
-- @param #SET_OPSGROUP self
|
-- @param #SET_OPSGROUP self
|
||||||
-- @param Core.Event#EVENTDATA Event Event data.
|
-- @param Core.Event#EVENTDATA Event Event data.
|
||||||
function SET_OPSGROUP:_EventOnBirth( Event )
|
function SET_OPSGROUP:_EventOnBirth(Event)
|
||||||
--self:F3( { Event } )
|
--self:F3( { Event } )
|
||||||
|
|
||||||
if Event.IniDCSUnit and Event.IniDCSGroup then
|
if Event.IniDCSUnit and Event.IniDCSGroup then
|
||||||
local DCSgroup=Event.IniDCSGroup --DCS#Group
|
local DCSgroup = Event.IniDCSGroup --DCS#Group
|
||||||
|
|
||||||
if DCSgroup:getInitialSize() == DCSgroup:getSize() then -- This seems to be not a good check as even for the first birth event, getSize returns the total number of units in the group.
|
-- group:CountAliveUnits() alternative as this fails for Respawn/Teleport
|
||||||
|
local CountAliveActive = 0
|
||||||
local groupname, group = self:AddInDatabase( Event )
|
for index, data in pairs(DCSgroup:getUnits()) do
|
||||||
|
if data:isExist() and data:isActive() then
|
||||||
if group and group:CountAliveUnits()==DCSgroup:getInitialSize() then
|
CountAliveActive = CountAliveActive + 1
|
||||||
if group and self:IsIncludeObject( group ) then
|
end
|
||||||
self:Add( groupname, group )
|
end
|
||||||
end
|
|
||||||
|
if DCSgroup:getInitialSize() == DCSgroup:getSize() then
|
||||||
|
|
||||||
|
local groupname, group = self:AddInDatabase(Event)
|
||||||
|
|
||||||
|
-- group:CountAliveUnits() alternative
|
||||||
|
if group and CountAliveActive == DCSgroup:getInitialSize() then
|
||||||
|
if group and self:IsIncludeObject(group) then
|
||||||
|
self:Add(groupname, group)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -8355,14 +8364,17 @@ do -- SET_SCENERY
|
|||||||
-- @param #SET_SCENERY self
|
-- @param #SET_SCENERY self
|
||||||
-- @return Core.Point#COORDINATE The center coordinate of all the objects in the set.
|
-- @return Core.Point#COORDINATE The center coordinate of all the objects in the set.
|
||||||
function SET_SCENERY:GetCoordinate()
|
function SET_SCENERY:GetCoordinate()
|
||||||
|
--[[
|
||||||
local Coordinate = COORDINATE:New({0,0,0})
|
local Coordinate = COORDINATE:New({0,0,0})
|
||||||
|
|
||||||
local Item = self:GetRandomSurely()
|
local Item = self:GetRandomSurely()
|
||||||
|
|
||||||
if Item then
|
if Item then
|
||||||
Coordinate:GetCoordinate()
|
Coordinate:GetCoordinate()
|
||||||
end
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local Coordinate = self:GetFirst():GetCoordinate()
|
||||||
|
|
||||||
local x1 = Coordinate.x
|
local x1 = Coordinate.x
|
||||||
local x2 = Coordinate.x
|
local x2 = Coordinate.x
|
||||||
|
|||||||
@@ -1226,7 +1226,7 @@ end
|
|||||||
-- @param Core.Point#COORDINATE Coordinate The position to spawn from
|
-- @param Core.Point#COORDINATE Coordinate The position to spawn from
|
||||||
-- @return #SPAWN self
|
-- @return #SPAWN self
|
||||||
function SPAWN:InitPositionCoordinate(Coordinate)
|
function SPAWN:InitPositionCoordinate(Coordinate)
|
||||||
self:T2( { self.SpawnTemplatePrefix, Coordinate:GetVec2()} )
|
--self:T2( { self.SpawnTemplatePrefix, Coordinate:GetVec2()} )
|
||||||
self:InitPositionVec2(Coordinate:GetVec2())
|
self:InitPositionVec2(Coordinate:GetVec2())
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1236,10 +1236,10 @@ end
|
|||||||
-- @param DCS#Vec2 Vec2 The position to spawn from
|
-- @param DCS#Vec2 Vec2 The position to spawn from
|
||||||
-- @return #SPAWN self
|
-- @return #SPAWN self
|
||||||
function SPAWN:InitPositionVec2(Vec2)
|
function SPAWN:InitPositionVec2(Vec2)
|
||||||
self:T2( { self.SpawnTemplatePrefix, Vec2} )
|
--self:T2( { self.SpawnTemplatePrefix, Vec2} )
|
||||||
self.SpawnInitPosition = Vec2
|
self.SpawnInitPosition = Vec2
|
||||||
self.SpawnFromNewPosition = true
|
self.SpawnFromNewPosition = true
|
||||||
self:T2("MaxGroups:"..self.SpawnMaxGroups)
|
--self:T2("MaxGroups:"..self.SpawnMaxGroups)
|
||||||
for SpawnGroupID = 1, self.SpawnMaxGroups do
|
for SpawnGroupID = 1, self.SpawnMaxGroups do
|
||||||
self:_SetInitialPosition( SpawnGroupID )
|
self:_SetInitialPosition( SpawnGroupID )
|
||||||
end
|
end
|
||||||
@@ -1334,7 +1334,7 @@ function SPAWN:InitCleanUp( SpawnCleanUpInterval )
|
|||||||
self.SpawnCleanUpTimeStamps = {}
|
self.SpawnCleanUpTimeStamps = {}
|
||||||
|
|
||||||
local SpawnGroup, SpawnCursor = self:GetFirstAliveGroup()
|
local SpawnGroup, SpawnCursor = self:GetFirstAliveGroup()
|
||||||
self:T2( { "CleanUp Scheduler:", SpawnGroup } )
|
--self:T2( { "CleanUp Scheduler:", SpawnGroup } )
|
||||||
|
|
||||||
self.CleanUpScheduler = SCHEDULER:New( self, self._SpawnCleanUpScheduler, {}, 1, SpawnCleanUpInterval, 0.2 )
|
self.CleanUpScheduler = SCHEDULER:New( self, self._SpawnCleanUpScheduler, {}, 1, SpawnCleanUpInterval, 0.2 )
|
||||||
return self
|
return self
|
||||||
@@ -1367,7 +1367,7 @@ function SPAWN:InitArray( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY )
|
|||||||
local SpawnYIndex = 0
|
local SpawnYIndex = 0
|
||||||
|
|
||||||
for SpawnGroupID = 1, self.SpawnMaxGroups do
|
for SpawnGroupID = 1, self.SpawnMaxGroups do
|
||||||
self:T2( { SpawnX, SpawnY, SpawnXIndex, SpawnYIndex } )
|
--self:T2( { SpawnX, SpawnY, SpawnXIndex, SpawnYIndex } )
|
||||||
|
|
||||||
self.SpawnGroups[SpawnGroupID].Visible = true
|
self.SpawnGroups[SpawnGroupID].Visible = true
|
||||||
self.SpawnGroups[SpawnGroupID].Spawned = false
|
self.SpawnGroups[SpawnGroupID].Spawned = false
|
||||||
@@ -1391,7 +1391,7 @@ function SPAWN:InitArray( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY )
|
|||||||
self.SpawnGroups[SpawnGroupID].Visible = true
|
self.SpawnGroups[SpawnGroupID].Visible = true
|
||||||
|
|
||||||
self:HandleEvent( EVENTS.Birth, self._OnBirth )
|
self:HandleEvent( EVENTS.Birth, self._OnBirth )
|
||||||
--self:HandleEvent( EVENTS.Dead, self._OnDeadOrCrash )
|
self:HandleEvent( EVENTS.Dead, self._OnDeadOrCrash )
|
||||||
self:HandleEvent( EVENTS.Crash, self._OnDeadOrCrash )
|
self:HandleEvent( EVENTS.Crash, self._OnDeadOrCrash )
|
||||||
self:HandleEvent( EVENTS.RemoveUnit, self._OnDeadOrCrash )
|
self:HandleEvent( EVENTS.RemoveUnit, self._OnDeadOrCrash )
|
||||||
self:HandleEvent( EVENTS.UnitLost, self._OnDeadOrCrash )
|
self:HandleEvent( EVENTS.UnitLost, self._OnDeadOrCrash )
|
||||||
@@ -1591,7 +1591,7 @@ end
|
|||||||
-- @param #string SpawnIndex The index of the group to be spawned.
|
-- @param #string SpawnIndex The index of the group to be spawned.
|
||||||
-- @return Wrapper.Group#GROUP The group that was spawned. You can use this group for further actions.
|
-- @return Wrapper.Group#GROUP The group that was spawned. You can use this group for further actions.
|
||||||
function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
|
function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
|
||||||
|
--[[
|
||||||
local set = SET_GROUP:New():FilterAlive():FilterPrefixes({self.SpawnTemplatePrefix, self.SpawnAliasPrefix}):FilterOnce()
|
local set = SET_GROUP:New():FilterAlive():FilterPrefixes({self.SpawnTemplatePrefix, self.SpawnAliasPrefix}):FilterOnce()
|
||||||
local aliveunits = 0
|
local aliveunits = 0
|
||||||
set:ForEachGroupAlive(
|
set:ForEachGroupAlive(
|
||||||
@@ -1602,12 +1602,12 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
|
|||||||
|
|
||||||
if aliveunits ~= self.AliveUnits then
|
if aliveunits ~= self.AliveUnits then
|
||||||
self.AliveUnits = aliveunits
|
self.AliveUnits = aliveunits
|
||||||
self:T2("***** self.AliveUnits accounting failure! Corrected! *****")
|
--self:T2("***** self.AliveUnits accounting failure! Corrected! *****")
|
||||||
end
|
end
|
||||||
|
|
||||||
set= nil
|
set= nil
|
||||||
|
--]]
|
||||||
self:T2( { SpawnTemplatePrefix = self.SpawnTemplatePrefix, SpawnIndex = SpawnIndex, AliveUnits = self.AliveUnits, SpawnMaxGroups = self.SpawnMaxGroups } )
|
--self:T2( { SpawnTemplatePrefix = self.SpawnTemplatePrefix, SpawnIndex = SpawnIndex, AliveUnits = self.AliveUnits, SpawnMaxGroups = self.SpawnMaxGroups } )
|
||||||
|
|
||||||
if self:_GetSpawnIndex( SpawnIndex ) then
|
if self:_GetSpawnIndex( SpawnIndex ) then
|
||||||
|
|
||||||
@@ -1622,12 +1622,12 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
|
|||||||
|
|
||||||
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
|
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
|
||||||
local SpawnZone = self.SpawnGroups[self.SpawnIndex].SpawnZone
|
local SpawnZone = self.SpawnGroups[self.SpawnIndex].SpawnZone
|
||||||
self:T2( SpawnTemplate.name )
|
--self:T2( SpawnTemplate.name )
|
||||||
|
|
||||||
if SpawnTemplate then
|
if SpawnTemplate then
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:New( SpawnTemplate.route.points[1].x, SpawnTemplate.route.points[1].alt, SpawnTemplate.route.points[1].y )
|
local PointVec3 = POINT_VEC3:New( SpawnTemplate.route.points[1].x, SpawnTemplate.route.points[1].alt, SpawnTemplate.route.points[1].y )
|
||||||
self:T2( { "Current point of ", self.SpawnTemplatePrefix, PointVec3 } )
|
--self:T2( { "Current point of ", self.SpawnTemplatePrefix, PointVec3 } )
|
||||||
|
|
||||||
-- If RandomizePosition, then Randomize the formation in the zone band, keeping the template.
|
-- If RandomizePosition, then Randomize the formation in the zone band, keeping the template.
|
||||||
if self.SpawnRandomizePosition then
|
if self.SpawnRandomizePosition then
|
||||||
@@ -1639,7 +1639,7 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
|
|||||||
for UnitID = 1, #SpawnTemplate.units do
|
for UnitID = 1, #SpawnTemplate.units do
|
||||||
SpawnTemplate.units[UnitID].x = SpawnTemplate.units[UnitID].x + (RandomVec2.x - CurrentX)
|
SpawnTemplate.units[UnitID].x = SpawnTemplate.units[UnitID].x + (RandomVec2.x - CurrentX)
|
||||||
SpawnTemplate.units[UnitID].y = SpawnTemplate.units[UnitID].y + (RandomVec2.y - CurrentY)
|
SpawnTemplate.units[UnitID].y = SpawnTemplate.units[UnitID].y + (RandomVec2.y - CurrentY)
|
||||||
self:T2( 'SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
--self:T2( 'SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1660,13 +1660,13 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if (not inZone) then
|
if (not inZone) then
|
||||||
self:T2("Could not place unit within zone and within radius!")
|
--self:T2("Could not place unit within zone and within radius!")
|
||||||
RandomVec2 = SpawnZone:GetRandomVec2()
|
RandomVec2 = SpawnZone:GetRandomVec2()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
SpawnTemplate.units[UnitID].x = RandomVec2.x
|
SpawnTemplate.units[UnitID].x = RandomVec2.x
|
||||||
SpawnTemplate.units[UnitID].y = RandomVec2.y
|
SpawnTemplate.units[UnitID].y = RandomVec2.y
|
||||||
self:T2( 'SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
--self:T2( 'SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1887,6 +1887,7 @@ end
|
|||||||
|
|
||||||
--- Spawns new groups at varying time intervals.
|
--- Spawns new groups at varying time intervals.
|
||||||
-- This is useful if you want to have continuity within your missions of certain (AI) groups to be present (alive) within your missions.
|
-- This is useful if you want to have continuity within your missions of certain (AI) groups to be present (alive) within your missions.
|
||||||
|
-- **WARNING** - Setting a very low SpawnTime heavily impacts your mission performance and CPU time, it is NOT useful to check the alive state of an object every split second! Be reasonable and stay at 15 seconds and above!
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param #number SpawnTime The time interval defined in seconds between each new spawn of new groups.
|
-- @param #number SpawnTime The time interval defined in seconds between each new spawn of new groups.
|
||||||
-- @param #number SpawnTimeVariation The variation to be applied on the defined time interval between each new spawn.
|
-- @param #number SpawnTimeVariation The variation to be applied on the defined time interval between each new spawn.
|
||||||
@@ -1909,6 +1910,14 @@ function SPAWN:SpawnScheduled( SpawnTime, SpawnTimeVariation, WithDelay )
|
|||||||
local SpawnTime = SpawnTime or 60
|
local SpawnTime = SpawnTime or 60
|
||||||
local SpawnTimeVariation = SpawnTimeVariation or 0.5
|
local SpawnTimeVariation = SpawnTimeVariation or 0.5
|
||||||
|
|
||||||
|
-- Noob catch
|
||||||
|
if SpawnTime < 15 then
|
||||||
|
self:E("****SPAWN SCHEDULED****\nWARNING - Setting a very low SpawnTime heavily impacts your mission performance and CPU time, it is NOT useful to check the alive state of an object every "..tostring(SpawnTime).." seconds.\nSetting to 15 second intervals.\n*****")
|
||||||
|
SpawnTime = 15
|
||||||
|
end
|
||||||
|
|
||||||
|
if SpawnTimeVariation > 1 or SpawnTimeVariation < 0 then SpawnTimeVariation = 0.5 end
|
||||||
|
|
||||||
if SpawnTime ~= nil and SpawnTimeVariation ~= nil then
|
if SpawnTime ~= nil and SpawnTimeVariation ~= nil then
|
||||||
local InitialDelay = 0
|
local InitialDelay = 0
|
||||||
if WithDelay or self.DelayOnOff == true then
|
if WithDelay or self.DelayOnOff == true then
|
||||||
@@ -2024,7 +2033,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
|
|
||||||
-- Get position of airbase.
|
-- Get position of airbase.
|
||||||
local PointVec3 = SpawnAirbase:GetCoordinate()
|
local PointVec3 = SpawnAirbase:GetCoordinate()
|
||||||
self:T2( PointVec3 )
|
--self:T2( PointVec3 )
|
||||||
|
|
||||||
-- Set take off type. Default is hot.
|
-- Set take off type. Default is hot.
|
||||||
Takeoff = Takeoff or SPAWN.Takeoff.Hot
|
Takeoff = Takeoff or SPAWN.Takeoff.Hot
|
||||||
@@ -2053,7 +2062,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
--self:F( { GroupAlive = GroupAlive } )
|
--self:F( { GroupAlive = GroupAlive } )
|
||||||
|
|
||||||
-- Debug output
|
-- Debug output
|
||||||
self:T2( { "Current point of ", self.SpawnTemplatePrefix, SpawnAirbase } )
|
--self:T2( { "Current point of ", self.SpawnTemplatePrefix, SpawnAirbase } )
|
||||||
|
|
||||||
-- Template group, unit and its attributes.
|
-- Template group, unit and its attributes.
|
||||||
local TemplateGroup = GROUP:FindByName( self.SpawnTemplatePrefix )
|
local TemplateGroup = GROUP:FindByName( self.SpawnTemplatePrefix )
|
||||||
@@ -2102,7 +2111,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
|
|
||||||
-- Check if we spawn on ground.
|
-- Check if we spawn on ground.
|
||||||
local spawnonground = not (Takeoff == SPAWN.Takeoff.Air)
|
local spawnonground = not (Takeoff == SPAWN.Takeoff.Air)
|
||||||
self:T2( { spawnonground = spawnonground, TOtype = Takeoff, TOair = Takeoff == SPAWN.Takeoff.Air } )
|
--self:T2( { spawnonground = spawnonground, TOtype = Takeoff, TOair = Takeoff == SPAWN.Takeoff.Air } )
|
||||||
|
|
||||||
-- Check where we actually spawn if we spawn on ground.
|
-- Check where we actually spawn if we spawn on ground.
|
||||||
local spawnonship = false
|
local spawnonship = false
|
||||||
@@ -2156,7 +2165,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
-- Number of free parking spots at the airbase.
|
-- Number of free parking spots at the airbase.
|
||||||
if spawnonship or spawnonfarp or spawnonrunway then
|
if spawnonship or spawnonfarp or spawnonrunway then
|
||||||
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
||||||
self:T2( string.format( "Group %s is spawned on farp/ship/runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
--self:T2( string.format( "Group %s is spawned on farp/ship/runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||||
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
||||||
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
||||||
--[[
|
--[[
|
||||||
@@ -2169,18 +2178,18 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
if ishelo then
|
if ishelo then
|
||||||
if termtype == nil then
|
if termtype == nil then
|
||||||
-- Helo is spawned. Try exclusive helo spots first.
|
-- Helo is spawned. Try exclusive helo spots first.
|
||||||
self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterOnly ) )
|
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterOnly ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterOnly, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterOnly, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
if nfree < nunits then
|
if nfree < nunits then
|
||||||
-- Not enough helo ports. Let's try also other terminal types.
|
-- Not enough helo ports. Let's try also other terminal types.
|
||||||
self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterUsable ) )
|
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterUsable ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterUsable, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterUsable, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- No terminal type specified. We try all spots except shelters.
|
-- No terminal type specified. We try all spots except shelters.
|
||||||
self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), termtype ) )
|
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), termtype ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
@@ -2189,23 +2198,23 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
if termtype == nil then
|
if termtype == nil then
|
||||||
if isbomber or istransport or istanker or isawacs then
|
if isbomber or istransport or istanker or isawacs then
|
||||||
-- First we fill the potentially bigger spots.
|
-- First we fill the potentially bigger spots.
|
||||||
self:T2( string.format( "Transport/bomber group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.OpenBig ) )
|
--self:T2( string.format( "Transport/bomber group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.OpenBig ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.OpenBig, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.OpenBig, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
if nfree < nunits then
|
if nfree < nunits then
|
||||||
-- Now we try the smaller ones.
|
-- Now we try the smaller ones.
|
||||||
self:T2( string.format( "Transport/bomber group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.OpenMedOrBig ) )
|
--self:T2( string.format( "Transport/bomber group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.OpenMedOrBig ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.OpenMedOrBig, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.OpenMedOrBig, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:T2( string.format( "Fighter group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.FighterAircraft ) )
|
--self:T2( string.format( "Fighter group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.FighterAircraft ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.FighterAircraft, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.FighterAircraft, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- Terminal type explicitly given.
|
-- Terminal type explicitly given.
|
||||||
self:T2( string.format( "Plane group %s is at %s using terminal type %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), tostring( termtype ) ) )
|
--self:T2( string.format( "Plane group %s is at %s using terminal type %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), tostring( termtype ) ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
@@ -2215,12 +2224,12 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
-- Debug: Get parking data.
|
-- Debug: Get parking data.
|
||||||
--[[
|
--[[
|
||||||
local parkingdata=SpawnAirbase:GetParkingSpotsTable(termtype)
|
local parkingdata=SpawnAirbase:GetParkingSpotsTable(termtype)
|
||||||
self:T2(string.format("Parking at %s, terminal type %s:", SpawnAirbase:GetName(), tostring(termtype)))
|
--self:T2(string.format("Parking at %s, terminal type %s:", SpawnAirbase:GetName(), tostring(termtype)))
|
||||||
for _,_spot in pairs(parkingdata) do
|
for _,_spot in pairs(parkingdata) do
|
||||||
self:T2(string.format("%s, Termin Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %4d",
|
--self:T2(string.format("%s, Termin Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %4d",
|
||||||
SpawnAirbase:GetName(), _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy))
|
SpawnAirbase:GetName(), _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy))
|
||||||
end
|
end
|
||||||
self:T2(string.format("%s at %s: free parking spots = %d - number of units = %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), nfree, nunits))
|
--self:T2(string.format("%s at %s: free parking spots = %d - number of units = %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), nfree, nunits))
|
||||||
]]
|
]]
|
||||||
|
|
||||||
-- Set this to true if not enough spots are available for emergency air start.
|
-- Set this to true if not enough spots are available for emergency air start.
|
||||||
@@ -2315,7 +2324,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
SpawnTemplate.parked = true
|
SpawnTemplate.parked = true
|
||||||
|
|
||||||
for UnitID = 1, nunits do
|
for UnitID = 1, nunits do
|
||||||
self:T2( 'Before Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
--self:T2( 'Before Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||||
|
|
||||||
-- Template of the current unit.
|
-- Template of the current unit.
|
||||||
local UnitTemplate = SpawnTemplate.units[UnitID]
|
local UnitTemplate = SpawnTemplate.units[UnitID]
|
||||||
@@ -2333,7 +2342,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
-- Ships and FARPS seem to have a build in queue.
|
-- Ships and FARPS seem to have a build in queue.
|
||||||
if spawnonship or spawnonfarp or spawnonrunway then
|
if spawnonship or spawnonfarp or spawnonrunway then
|
||||||
|
|
||||||
self:T2( string.format( "Group %s spawning at farp, ship or runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
--self:T2( string.format( "Group %s spawning at farp, ship or runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||||
|
|
||||||
-- Spawn on ship. We take only the position of the ship.
|
-- Spawn on ship. We take only the position of the ship.
|
||||||
SpawnTemplate.units[UnitID].x = PointVec3.x -- TX
|
SpawnTemplate.units[UnitID].x = PointVec3.x -- TX
|
||||||
@@ -2342,7 +2351,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
self:T2( string.format( "Group %s spawning at airbase %s on parking spot id %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), parkingindex[UnitID] ) )
|
--self:T2( string.format( "Group %s spawning at airbase %s on parking spot id %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), parkingindex[UnitID] ) )
|
||||||
|
|
||||||
-- Get coordinates of parking spot.
|
-- Get coordinates of parking spot.
|
||||||
SpawnTemplate.units[UnitID].x = parkingspots[UnitID].x
|
SpawnTemplate.units[UnitID].x = parkingspots[UnitID].x
|
||||||
@@ -2354,7 +2363,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
self:T2( string.format( "Group %s spawning in air at %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
--self:T2( string.format( "Group %s spawning in air at %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||||
|
|
||||||
-- Spawn in air as requested initially. Original template orientation is perserved, altitude is already correctly set.
|
-- Spawn in air as requested initially. Original template orientation is perserved, altitude is already correctly set.
|
||||||
SpawnTemplate.units[UnitID].x = TX
|
SpawnTemplate.units[UnitID].x = TX
|
||||||
@@ -2371,9 +2380,9 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Debug output.
|
-- Debug output.
|
||||||
self:T2( string.format( "Group %s unit number %d: Parking = %s", self.SpawnTemplatePrefix, UnitID, tostring( UnitTemplate.parking ) ) )
|
--self:T2( string.format( "Group %s unit number %d: Parking = %s", self.SpawnTemplatePrefix, UnitID, tostring( UnitTemplate.parking ) ) )
|
||||||
self:T2( string.format( "Group %s unit number %d: Parking ID = %s", self.SpawnTemplatePrefix, UnitID, tostring( UnitTemplate.parking_id ) ) )
|
--self:T2( string.format( "Group %s unit number %d: Parking ID = %s", self.SpawnTemplatePrefix, UnitID, tostring( UnitTemplate.parking_id ) ) )
|
||||||
self:T2( 'After Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
--self:T2( 'After Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2451,10 +2460,10 @@ function SPAWN:SpawnAtParkingSpot( Airbase, Spots, Takeoff )
|
|||||||
-- Get parking spot data.
|
-- Get parking spot data.
|
||||||
local spot = Airbase:GetParkingSpotData( TerminalID )
|
local spot = Airbase:GetParkingSpotData( TerminalID )
|
||||||
|
|
||||||
self:T2( { spot = spot } )
|
--self:T2( { spot = spot } )
|
||||||
|
|
||||||
if spot and spot.Free then
|
if spot and spot.Free then
|
||||||
self:T2( string.format( "Adding parking spot ID=%d TermType=%d", spot.TerminalID, spot.TerminalType ) )
|
--self:T2( string.format( "Adding parking spot ID=%d TermType=%d", spot.TerminalID, spot.TerminalType ) )
|
||||||
table.insert( Parkingdata, spot )
|
table.insert( Parkingdata, spot )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2486,7 +2495,7 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
|
|
||||||
-- Get position of airbase.
|
-- Get position of airbase.
|
||||||
local PointVec3 = SpawnAirbase:GetCoordinate()
|
local PointVec3 = SpawnAirbase:GetCoordinate()
|
||||||
self:T2( PointVec3 )
|
--self:T2( PointVec3 )
|
||||||
|
|
||||||
-- Set take off type. Default is hot.
|
-- Set take off type. Default is hot.
|
||||||
local Takeoff = SPAWN.Takeoff.Cold
|
local Takeoff = SPAWN.Takeoff.Cold
|
||||||
@@ -2502,7 +2511,7 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
local GroupAlive = self:GetGroupFromIndex( SpawnIndex )
|
local GroupAlive = self:GetGroupFromIndex( SpawnIndex )
|
||||||
|
|
||||||
-- Debug output
|
-- Debug output
|
||||||
self:T2( { "Current point of ", self.SpawnTemplatePrefix, SpawnAirbase } )
|
--self:T2( { "Current point of ", self.SpawnTemplatePrefix, SpawnAirbase } )
|
||||||
|
|
||||||
-- Template group, unit and its attributes.
|
-- Template group, unit and its attributes.
|
||||||
local TemplateGroup = GROUP:FindByName( self.SpawnTemplatePrefix )
|
local TemplateGroup = GROUP:FindByName( self.SpawnTemplatePrefix )
|
||||||
@@ -2546,7 +2555,7 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
|
|
||||||
-- Check if we spawn on ground.
|
-- Check if we spawn on ground.
|
||||||
local spawnonground = not (Takeoff == SPAWN.Takeoff.Air)
|
local spawnonground = not (Takeoff == SPAWN.Takeoff.Air)
|
||||||
self:T2( { spawnonground = spawnonground, TOtype = Takeoff, TOair = Takeoff == SPAWN.Takeoff.Air } )
|
--self:T2( { spawnonground = spawnonground, TOtype = Takeoff, TOair = Takeoff == SPAWN.Takeoff.Air } )
|
||||||
|
|
||||||
-- Check where we actually spawn if we spawn on ground.
|
-- Check where we actually spawn if we spawn on ground.
|
||||||
local spawnonship = false
|
local spawnonship = false
|
||||||
@@ -2588,7 +2597,7 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
-- Number of free parking spots at the airbase.
|
-- Number of free parking spots at the airbase.
|
||||||
if spawnonship or spawnonfarp or spawnonrunway then
|
if spawnonship or spawnonfarp or spawnonrunway then
|
||||||
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
||||||
self:T2( string.format( "Group %s is spawned on farp/ship/runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
--self:T2( string.format( "Group %s is spawned on farp/ship/runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||||
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
||||||
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
||||||
--[[
|
--[[
|
||||||
@@ -2601,18 +2610,18 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
if ishelo then
|
if ishelo then
|
||||||
if termtype == nil then
|
if termtype == nil then
|
||||||
-- Helo is spawned. Try exclusive helo spots first.
|
-- Helo is spawned. Try exclusive helo spots first.
|
||||||
self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterOnly ) )
|
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterOnly ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterOnly, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterOnly, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
if nfree < nunits then
|
if nfree < nunits then
|
||||||
-- Not enough helo ports. Let's try also other terminal types.
|
-- Not enough helo ports. Let's try also other terminal types.
|
||||||
self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterUsable ) )
|
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterUsable ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterUsable, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterUsable, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- No terminal type specified. We try all spots except shelters.
|
-- No terminal type specified. We try all spots except shelters.
|
||||||
self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), termtype ) )
|
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), termtype ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
@@ -2624,23 +2633,23 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
-- TODO: Some attributes are "Helicopters", "Bombers", "Transports", "Battleplanes". Need to check it out.
|
-- TODO: Some attributes are "Helicopters", "Bombers", "Transports", "Battleplanes". Need to check it out.
|
||||||
if isbomber or istransport then
|
if isbomber or istransport then
|
||||||
-- First we fill the potentially bigger spots.
|
-- First we fill the potentially bigger spots.
|
||||||
self:T2( string.format( "Transport/bomber group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.OpenBig ) )
|
--self:T2( string.format( "Transport/bomber group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.OpenBig ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.OpenBig, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.OpenBig, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
if nfree < nunits then
|
if nfree < nunits then
|
||||||
-- Now we try the smaller ones.
|
-- Now we try the smaller ones.
|
||||||
self:T2( string.format( "Transport/bomber group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.OpenMedOrBig ) )
|
--self:T2( string.format( "Transport/bomber group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.OpenMedOrBig ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.OpenMedOrBig, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.OpenMedOrBig, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:T2( string.format( "Fighter group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.FighterAircraft ) )
|
--self:T2( string.format( "Fighter group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.FighterAircraft ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.FighterAircraft, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.FighterAircraft, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- Terminal type explicitly given.
|
-- Terminal type explicitly given.
|
||||||
self:T2( string.format( "Plane group %s is at %s using terminal type %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), tostring( termtype ) ) )
|
--self:T2( string.format( "Plane group %s is at %s using terminal type %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), tostring( termtype ) ) )
|
||||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||||
nfree = #spots
|
nfree = #spots
|
||||||
end
|
end
|
||||||
@@ -2650,12 +2659,12 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
-- Debug: Get parking data.
|
-- Debug: Get parking data.
|
||||||
--[[
|
--[[
|
||||||
local parkingdata=SpawnAirbase:GetParkingSpotsTable(termtype)
|
local parkingdata=SpawnAirbase:GetParkingSpotsTable(termtype)
|
||||||
self:T2(string.format("Parking at %s, terminal type %s:", SpawnAirbase:GetName(), tostring(termtype)))
|
--self:T2(string.format("Parking at %s, terminal type %s:", SpawnAirbase:GetName(), tostring(termtype)))
|
||||||
for _,_spot in pairs(parkingdata) do
|
for _,_spot in pairs(parkingdata) do
|
||||||
self:T2(string.format("%s, Termin Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %4d",
|
--self:T2(string.format("%s, Termin Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %4d",
|
||||||
SpawnAirbase:GetName(), _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy))
|
SpawnAirbase:GetName(), _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy))
|
||||||
end
|
end
|
||||||
self:T2(string.format("%s at %s: free parking spots = %d - number of units = %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), nfree, nunits))
|
--self:T2(string.format("%s at %s: free parking spots = %d - number of units = %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), nfree, nunits))
|
||||||
]]
|
]]
|
||||||
|
|
||||||
-- Set this to true if not enough spots are available for emergency air start.
|
-- Set this to true if not enough spots are available for emergency air start.
|
||||||
@@ -2733,7 +2742,7 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
-- Ships and FARPS seem to have a build in queue.
|
-- Ships and FARPS seem to have a build in queue.
|
||||||
if spawnonship or spawnonfarp or spawnonrunway then
|
if spawnonship or spawnonfarp or spawnonrunway then
|
||||||
|
|
||||||
self:T2( string.format( "Group %s spawning at farp, ship or runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
--self:T2( string.format( "Group %s spawning at farp, ship or runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||||
|
|
||||||
-- Spawn on ship. We take only the position of the ship.
|
-- Spawn on ship. We take only the position of the ship.
|
||||||
SpawnTemplate.units[UnitID].x = PointVec3.x -- TX
|
SpawnTemplate.units[UnitID].x = PointVec3.x -- TX
|
||||||
@@ -2742,7 +2751,7 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
self:T2( string.format( "Group %s spawning at airbase %s on parking spot id %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), parkingindex[UnitID] ) )
|
--self:T2( string.format( "Group %s spawning at airbase %s on parking spot id %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), parkingindex[UnitID] ) )
|
||||||
|
|
||||||
-- Get coordinates of parking spot.
|
-- Get coordinates of parking spot.
|
||||||
SpawnTemplate.units[UnitID].x = parkingspots[UnitID].x
|
SpawnTemplate.units[UnitID].x = parkingspots[UnitID].x
|
||||||
@@ -2754,7 +2763,7 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
self:T2( string.format( "Group %s spawning in air at %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
--self:T2( string.format( "Group %s spawning in air at %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||||
|
|
||||||
-- Spawn in air as requested initially. Original template orientation is perserved, altitude is already correctly set.
|
-- Spawn in air as requested initially. Original template orientation is perserved, altitude is already correctly set.
|
||||||
SpawnTemplate.units[UnitID].x = TX
|
SpawnTemplate.units[UnitID].x = TX
|
||||||
@@ -2771,9 +2780,9 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Debug output.
|
-- Debug output.
|
||||||
self:T2( string.format( "Group %s unit number %d: Parking = %s", self.SpawnTemplatePrefix, UnitID, tostring( UnitTemplate.parking ) ) )
|
--self:T2( string.format( "Group %s unit number %d: Parking = %s", self.SpawnTemplatePrefix, UnitID, tostring( UnitTemplate.parking ) ) )
|
||||||
self:T2( string.format( "Group %s unit number %d: Parking ID = %s", self.SpawnTemplatePrefix, UnitID, tostring( UnitTemplate.parking_id ) ) )
|
--self:T2( string.format( "Group %s unit number %d: Parking ID = %s", self.SpawnTemplatePrefix, UnitID, tostring( UnitTemplate.parking_id ) ) )
|
||||||
self:T2( 'After Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
--self:T2( 'After Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2871,7 +2880,7 @@ function SPAWN:SpawnFromVec3( Vec3, SpawnIndex )
|
|||||||
--self:F( { self.SpawnTemplatePrefix, Vec3, SpawnIndex } )
|
--self:F( { self.SpawnTemplatePrefix, Vec3, SpawnIndex } )
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:NewFromVec3( Vec3 )
|
local PointVec3 = POINT_VEC3:NewFromVec3( Vec3 )
|
||||||
self:T2( PointVec3 )
|
--self:T2( PointVec3 )
|
||||||
|
|
||||||
if SpawnIndex then
|
if SpawnIndex then
|
||||||
else
|
else
|
||||||
@@ -2884,7 +2893,7 @@ function SPAWN:SpawnFromVec3( Vec3, SpawnIndex )
|
|||||||
|
|
||||||
if SpawnTemplate then
|
if SpawnTemplate then
|
||||||
|
|
||||||
self:T2( { "Current point of ", self.SpawnTemplatePrefix, Vec3 } )
|
--self:T2( { "Current point of ", self.SpawnTemplatePrefix, Vec3 } )
|
||||||
|
|
||||||
local TemplateHeight = SpawnTemplate.route and SpawnTemplate.route.points[1].alt or nil
|
local TemplateHeight = SpawnTemplate.route and SpawnTemplate.route.points[1].alt or nil
|
||||||
|
|
||||||
@@ -2909,7 +2918,7 @@ function SPAWN:SpawnFromVec3( Vec3, SpawnIndex )
|
|||||||
if SpawnTemplate.CategoryID ~= Group.Category.SHIP then
|
if SpawnTemplate.CategoryID ~= Group.Category.SHIP then
|
||||||
SpawnTemplate.units[UnitID].alt = Vec3.y or TemplateHeight
|
SpawnTemplate.units[UnitID].alt = Vec3.y or TemplateHeight
|
||||||
end
|
end
|
||||||
self:T2( 'After Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
--self:T2( 'After Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||||
end
|
end
|
||||||
SpawnTemplate.route.points[1].x = Vec3.x
|
SpawnTemplate.route.points[1].x = Vec3.x
|
||||||
SpawnTemplate.route.points[1].y = Vec3.z
|
SpawnTemplate.route.points[1].y = Vec3.z
|
||||||
@@ -3168,10 +3177,10 @@ function SPAWN:SpawnGroupName( SpawnIndex )
|
|||||||
|
|
||||||
if SpawnIndex then
|
if SpawnIndex then
|
||||||
local SpawnName = string.format( '%s#%03d', SpawnPrefix, SpawnIndex )
|
local SpawnName = string.format( '%s#%03d', SpawnPrefix, SpawnIndex )
|
||||||
self:T2( SpawnName )
|
--self:T2( SpawnName )
|
||||||
return SpawnName
|
return SpawnName
|
||||||
else
|
else
|
||||||
self:T2( SpawnPrefix )
|
--self:T2( SpawnPrefix )
|
||||||
return SpawnPrefix
|
return SpawnPrefix
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -3499,7 +3508,7 @@ function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex ) -- R2.2
|
|||||||
if SpawnInitKeepUnitIFF == false then
|
if SpawnInitKeepUnitIFF == false then
|
||||||
UnitPrefix, Rest = string.match( SpawnTemplate.units[UnitID].name, "^([^#]+)#?" ):gsub( "^%s*(.-)%s*$", "%1" )
|
UnitPrefix, Rest = string.match( SpawnTemplate.units[UnitID].name, "^([^#]+)#?" ):gsub( "^%s*(.-)%s*$", "%1" )
|
||||||
SpawnTemplate.units[UnitID].name = string.format( '%s#%03d-%02d', UnitPrefix, SpawnIndex, UnitID )
|
SpawnTemplate.units[UnitID].name = string.format( '%s#%03d-%02d', UnitPrefix, SpawnIndex, UnitID )
|
||||||
self:T2( { UnitPrefix, Rest } )
|
--self:T2( { UnitPrefix, Rest } )
|
||||||
--else
|
--else
|
||||||
--UnitPrefix=SpawnTemplate.units[UnitID].name
|
--UnitPrefix=SpawnTemplate.units[UnitID].name
|
||||||
end
|
end
|
||||||
@@ -3713,7 +3722,7 @@ function SPAWN:_RandomizeRoute( SpawnIndex )
|
|||||||
SpawnTemplate.route.points[t].alt = nil
|
SpawnTemplate.route.points[t].alt = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T2( 'SpawnTemplate.route.points[' .. t .. '].x = ' .. SpawnTemplate.route.points[t].x .. ', SpawnTemplate.route.points[' .. t .. '].y = ' .. SpawnTemplate.route.points[t].y )
|
--self:T2( 'SpawnTemplate.route.points[' .. t .. '].x = ' .. SpawnTemplate.route.points[t].x .. ', SpawnTemplate.route.points[' .. t .. '].y = ' .. SpawnTemplate.route.points[t].y )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -3756,15 +3765,15 @@ end
|
|||||||
-- @param #number SpawnIndex
|
-- @param #number SpawnIndex
|
||||||
-- @return #SPAWN self
|
-- @return #SPAWN self
|
||||||
function SPAWN:_SetInitialPosition( SpawnIndex )
|
function SPAWN:_SetInitialPosition( SpawnIndex )
|
||||||
self:T2( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnRandomizeZones } )
|
--self:T2( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnRandomizeZones } )
|
||||||
|
|
||||||
if self.SpawnFromNewPosition then
|
if self.SpawnFromNewPosition then
|
||||||
|
|
||||||
self:T2( "Preparing Spawn at Vec2 ", self.SpawnInitPosition )
|
--self:T2( "Preparing Spawn at Vec2 ", self.SpawnInitPosition )
|
||||||
|
|
||||||
local SpawnVec2 = self.SpawnInitPosition
|
local SpawnVec2 = self.SpawnInitPosition
|
||||||
|
|
||||||
self:T2( { SpawnVec2 = SpawnVec2 } )
|
--self:T2( { SpawnVec2 = SpawnVec2 } )
|
||||||
|
|
||||||
local SpawnTemplate = self.SpawnGroups[SpawnIndex].SpawnTemplate
|
local SpawnTemplate = self.SpawnGroups[SpawnIndex].SpawnTemplate
|
||||||
|
|
||||||
@@ -3774,11 +3783,11 @@ function SPAWN:_SetInitialPosition( SpawnIndex )
|
|||||||
SpawnTemplate.route.points[1].x = SpawnTemplate.route.points[1].x or 0
|
SpawnTemplate.route.points[1].x = SpawnTemplate.route.points[1].x or 0
|
||||||
SpawnTemplate.route.points[1].y = SpawnTemplate.route.points[1].y or 0
|
SpawnTemplate.route.points[1].y = SpawnTemplate.route.points[1].y or 0
|
||||||
|
|
||||||
self:T2( { Route = SpawnTemplate.route } )
|
--self:T2( { Route = SpawnTemplate.route } )
|
||||||
|
|
||||||
for UnitID = 1, #SpawnTemplate.units do
|
for UnitID = 1, #SpawnTemplate.units do
|
||||||
local UnitTemplate = SpawnTemplate.units[UnitID]
|
local UnitTemplate = SpawnTemplate.units[UnitID]
|
||||||
self:T2( 'Before Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. UnitTemplate.y )
|
--self:T2( 'Before Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. UnitTemplate.y )
|
||||||
local SX = UnitTemplate.x
|
local SX = UnitTemplate.x
|
||||||
local SY = UnitTemplate.y
|
local SY = UnitTemplate.y
|
||||||
local BX = SpawnTemplate.route.points[1].x
|
local BX = SpawnTemplate.route.points[1].x
|
||||||
@@ -3789,7 +3798,7 @@ function SPAWN:_SetInitialPosition( SpawnIndex )
|
|||||||
UnitTemplate.y = TY
|
UnitTemplate.y = TY
|
||||||
-- TODO: Manage altitude based on landheight...
|
-- TODO: Manage altitude based on landheight...
|
||||||
-- SpawnTemplate.units[UnitID].alt = SpawnVec2:
|
-- SpawnTemplate.units[UnitID].alt = SpawnVec2:
|
||||||
self:T2( 'After Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. UnitTemplate.y )
|
--self:T2( 'After Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. UnitTemplate.y )
|
||||||
end
|
end
|
||||||
|
|
||||||
SpawnTemplate.route.points[1].x = SpawnVec2.x
|
SpawnTemplate.route.points[1].x = SpawnVec2.x
|
||||||
@@ -3812,26 +3821,26 @@ function SPAWN:_RandomizeZones( SpawnIndex )
|
|||||||
if self.SpawnRandomizeZones then
|
if self.SpawnRandomizeZones then
|
||||||
local SpawnZone = nil -- Core.Zone#ZONE_BASE
|
local SpawnZone = nil -- Core.Zone#ZONE_BASE
|
||||||
while not SpawnZone do
|
while not SpawnZone do
|
||||||
self:T2( { SpawnZoneTableCount = #self.SpawnZoneTable, self.SpawnZoneTable } )
|
--self:T2( { SpawnZoneTableCount = #self.SpawnZoneTable, self.SpawnZoneTable } )
|
||||||
local ZoneID = math.random( #self.SpawnZoneTable )
|
local ZoneID = math.random( #self.SpawnZoneTable )
|
||||||
self:T2( ZoneID )
|
--self:T2( ZoneID )
|
||||||
SpawnZone = self.SpawnZoneTable[ZoneID]:GetZoneMaybe()
|
SpawnZone = self.SpawnZoneTable[ZoneID]:GetZoneMaybe()
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T2( "Preparing Spawn in Zone", SpawnZone:GetName() )
|
--self:T2( "Preparing Spawn in Zone", SpawnZone:GetName() )
|
||||||
|
|
||||||
local SpawnVec2 = SpawnZone:GetRandomVec2()
|
local SpawnVec2 = SpawnZone:GetRandomVec2()
|
||||||
|
|
||||||
self:T2( { SpawnVec2 = SpawnVec2 } )
|
--self:T2( { SpawnVec2 = SpawnVec2 } )
|
||||||
|
|
||||||
local SpawnTemplate = self.SpawnGroups[SpawnIndex].SpawnTemplate
|
local SpawnTemplate = self.SpawnGroups[SpawnIndex].SpawnTemplate
|
||||||
self.SpawnGroups[SpawnIndex].SpawnZone = SpawnZone
|
self.SpawnGroups[SpawnIndex].SpawnZone = SpawnZone
|
||||||
|
|
||||||
self:T2( { Route = SpawnTemplate.route } )
|
--self:T2( { Route = SpawnTemplate.route } )
|
||||||
|
|
||||||
for UnitID = 1, #SpawnTemplate.units do
|
for UnitID = 1, #SpawnTemplate.units do
|
||||||
local UnitTemplate = SpawnTemplate.units[UnitID]
|
local UnitTemplate = SpawnTemplate.units[UnitID]
|
||||||
self:T2( 'Before Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. UnitTemplate.y )
|
--self:T2( 'Before Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. UnitTemplate.y )
|
||||||
local SX = UnitTemplate.x
|
local SX = UnitTemplate.x
|
||||||
local SY = UnitTemplate.y
|
local SY = UnitTemplate.y
|
||||||
local BX = SpawnTemplate.route.points[1].x
|
local BX = SpawnTemplate.route.points[1].x
|
||||||
@@ -3842,7 +3851,7 @@ function SPAWN:_RandomizeZones( SpawnIndex )
|
|||||||
UnitTemplate.y = TY
|
UnitTemplate.y = TY
|
||||||
-- TODO: Manage altitude based on landheight...
|
-- TODO: Manage altitude based on landheight...
|
||||||
-- SpawnTemplate.units[UnitID].alt = SpawnVec2:
|
-- SpawnTemplate.units[UnitID].alt = SpawnVec2:
|
||||||
self:T2( 'After Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. UnitTemplate.y )
|
--self:T2( 'After Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. UnitTemplate.y )
|
||||||
end
|
end
|
||||||
SpawnTemplate.x = SpawnVec2.x
|
SpawnTemplate.x = SpawnVec2.x
|
||||||
SpawnTemplate.y = SpawnVec2.y
|
SpawnTemplate.y = SpawnVec2.y
|
||||||
@@ -3897,11 +3906,11 @@ end
|
|||||||
-- @param #number SpawnIndex Spawn index.
|
-- @param #number SpawnIndex Spawn index.
|
||||||
-- @return #number self.SpawnIndex
|
-- @return #number self.SpawnIndex
|
||||||
function SPAWN:_GetSpawnIndex( SpawnIndex )
|
function SPAWN:_GetSpawnIndex( SpawnIndex )
|
||||||
self:T2( { template=self.SpawnTemplatePrefix, SpawnIndex=SpawnIndex, SpawnMaxGroups=self.SpawnMaxGroups, SpawnMaxUnitsAlive=self.SpawnMaxUnitsAlive, AliveUnits=self.AliveUnits, TemplateUnits=#self.SpawnTemplate.units } )
|
--self:T2( { template=self.SpawnTemplatePrefix, SpawnIndex=SpawnIndex, SpawnMaxGroups=self.SpawnMaxGroups, SpawnMaxUnitsAlive=self.SpawnMaxUnitsAlive, AliveUnits=self.AliveUnits, TemplateUnits=#self.SpawnTemplate.units } )
|
||||||
|
|
||||||
if (self.SpawnMaxGroups == 0) or (SpawnIndex <= self.SpawnMaxGroups) then
|
if (self.SpawnMaxGroups == 0) or (SpawnIndex <= self.SpawnMaxGroups) then
|
||||||
if (self.SpawnMaxUnitsAlive == 0) or (self.AliveUnits + #self.SpawnTemplate.units <= self.SpawnMaxUnitsAlive) or self.UnControlled == true then
|
if (self.SpawnMaxUnitsAlive == 0) or (self.AliveUnits + #self.SpawnTemplate.units <= self.SpawnMaxUnitsAlive) or self.UnControlled == true then
|
||||||
self:T2( { SpawnCount = self.SpawnCount, SpawnIndex = SpawnIndex } )
|
--self:T2( { SpawnCount = self.SpawnCount, SpawnIndex = SpawnIndex } )
|
||||||
if SpawnIndex and SpawnIndex >= self.SpawnCount + 1 then
|
if SpawnIndex and SpawnIndex >= self.SpawnCount + 1 then
|
||||||
self.SpawnCount = self.SpawnCount + 1
|
self.SpawnCount = self.SpawnCount + 1
|
||||||
SpawnIndex = self.SpawnCount
|
SpawnIndex = self.SpawnCount
|
||||||
@@ -3932,22 +3941,57 @@ function SPAWN:_OnBirth( EventData )
|
|||||||
if SpawnGroup then
|
if SpawnGroup then
|
||||||
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
|
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
|
||||||
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
|
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
|
||||||
self:T2( { "Birth Event:", EventPrefix, self.SpawnTemplatePrefix } )
|
--self:T2( { "Birth Event:", EventPrefix, self.SpawnTemplatePrefix } )
|
||||||
if EventPrefix == self.SpawnTemplatePrefix or (self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix) then
|
if EventPrefix == self.SpawnTemplatePrefix or (self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix) then
|
||||||
self.AliveUnits = self.AliveUnits + 1
|
self.AliveUnits = self.AliveUnits + 1
|
||||||
self:T2( "Alive Units: " .. self.AliveUnits )
|
--self:T2( "Alive Units: " .. self.AliveUnits )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @param #SPAWN self
|
||||||
|
-- @return #number count
|
||||||
|
function SPAWN:_CountAliveUnits()
|
||||||
|
local count = 0
|
||||||
|
--self:I("self.SpawnAliasPrefix="..tostring(self.SpawnAliasPrefix).." | self.SpawnTemplatePrefix="..tostring(self.SpawnTemplatePrefix))
|
||||||
|
if self.SpawnAliasPrefix then
|
||||||
|
if not self.SpawnAliasPrefixEscaped then self.SpawnAliasPrefixEscaped = string.gsub(self.SpawnAliasPrefix,"[%p%s]",".") end
|
||||||
|
--self:I("self.SpawnAliasPrefixEscaped="..tostring(self.SpawnAliasPrefixEscaped))
|
||||||
|
local SpawnAliasPrefix = self.SpawnAliasPrefixEscaped
|
||||||
|
local agroups = GROUP:FindAllByMatching(SpawnAliasPrefix)
|
||||||
|
for _,_grp in pairs(agroups) do
|
||||||
|
--self:I("Group Name = " .. _grp:GetName())
|
||||||
|
local game = self:_GetPrefixFromGroupName(_grp.GroupName)
|
||||||
|
--self:I("Game = "..game)
|
||||||
|
--self:I("Count = ".._grp:CountAliveUnits())
|
||||||
|
if game and game == self.SpawnAliasPrefix then
|
||||||
|
count = count + _grp:CountAliveUnits()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not self.SpawnTemplatePrefixEscaped then self.SpawnTemplatePrefixEscaped = string.gsub(self.SpawnTemplatePrefix,"[%p%s]",".") end
|
||||||
|
local SpawnTemplatePrefix = self.SpawnTemplatePrefixEscaped
|
||||||
|
local groups = GROUP:FindAllByMatching(SpawnTemplatePrefix)
|
||||||
|
for _,_grp in pairs(groups) do
|
||||||
|
local game = self:_GetPrefixFromGroupName(_grp.GroupName)
|
||||||
|
if game and game == self.SpawnTemplatePrefix then
|
||||||
|
count = count + _grp:CountAliveUnits()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.AliveUnits = count
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
function SPAWN:_OnDeadOrCrash( EventData )
|
function SPAWN:_OnDeadOrCrash( EventData )
|
||||||
self:T2( "Dead or crash event ID "..tostring(EventData.id or 0))
|
--self:I( "Dead or crash event ID "..tostring(EventData.id or 0))
|
||||||
self:T2( "Dead or crash event for "..tostring(EventData.IniUnitName or "none") )
|
--self:I( "Dead or crash event for "..tostring(EventData.IniUnitName or "none") )
|
||||||
|
|
||||||
--if EventData.id == EVENTS.Dead then return end
|
--if EventData.id == EVENTS.Dead then return end
|
||||||
|
|
||||||
@@ -3959,12 +4003,14 @@ function SPAWN:_OnDeadOrCrash( EventData )
|
|||||||
local EventPrefix = self:_GetPrefixFromGroupName(unit.GroupName)
|
local EventPrefix = self:_GetPrefixFromGroupName(unit.GroupName)
|
||||||
|
|
||||||
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
|
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
|
||||||
self:T2( { "Dead event: " .. EventPrefix } )
|
--self:I(string.format("EventPrefix = %s | SpawnAliasPrefix = %s | Old AliveUnits = %d",EventPrefix or "",self.SpawnAliasPrefix or "",self.AliveUnits or 0))
|
||||||
self:T2(string.format("EventPrefix = %s | SpawnAliasPrefix = %s | Old AliveUnits = %d",EventPrefix or "",self.SpawnAliasPrefix or "",self.AliveUnits or 0))
|
|
||||||
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) and self.AliveUnits > 0 then
|
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) and self.AliveUnits > 0 then
|
||||||
self.AliveUnits = self.AliveUnits - 1
|
--self:I( { "Dead event: " .. EventPrefix } )
|
||||||
|
--self.AliveUnits = self.AliveUnits - 1
|
||||||
|
self:ScheduleOnce(1,self._CountAliveUnits,self)
|
||||||
|
--self.AliveUnits = self:_CountAliveUnits()
|
||||||
|
--self:I( "New Alive Units: " .. self.AliveUnits )
|
||||||
end
|
end
|
||||||
self:T2( "New Alive Units: " .. self.AliveUnits )
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -3980,9 +4026,9 @@ function SPAWN:_OnTakeOff( EventData )
|
|||||||
if SpawnGroup then
|
if SpawnGroup then
|
||||||
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
|
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
|
||||||
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
|
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
|
||||||
self:T2( { "TakeOff event: " .. EventPrefix } )
|
--self:T2( { "TakeOff event: " .. EventPrefix } )
|
||||||
if EventPrefix == self.SpawnTemplatePrefix or (self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix) then
|
if EventPrefix == self.SpawnTemplatePrefix or (self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix) then
|
||||||
self:T2( "self.Landed = false" )
|
--self:T2( "self.Landed = false" )
|
||||||
SpawnGroup:SetState( SpawnGroup, "Spawn_Landed", false )
|
SpawnGroup:SetState( SpawnGroup, "Spawn_Landed", false )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -4000,13 +4046,13 @@ function SPAWN:_OnLand( EventData )
|
|||||||
if SpawnGroup then
|
if SpawnGroup then
|
||||||
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
|
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
|
||||||
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
|
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
|
||||||
self:T2( { "Land event: " .. EventPrefix } )
|
--self:T2( { "Land event: " .. EventPrefix } )
|
||||||
if EventPrefix == self.SpawnTemplatePrefix or (self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix) then
|
if EventPrefix == self.SpawnTemplatePrefix or (self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix) then
|
||||||
-- TODO: Check if this is the last unit of the group that lands.
|
-- TODO: Check if this is the last unit of the group that lands.
|
||||||
SpawnGroup:SetState( SpawnGroup, "Spawn_Landed", true )
|
SpawnGroup:SetState( SpawnGroup, "Spawn_Landed", true )
|
||||||
if self.RepeatOnLanding then
|
if self.RepeatOnLanding then
|
||||||
local SpawnGroupIndex = self:GetSpawnIndexFromGroup( SpawnGroup )
|
local SpawnGroupIndex = self:GetSpawnIndexFromGroup( SpawnGroup )
|
||||||
self:T2( { "Landed:", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
|
--self:T2( { "Landed:", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
|
||||||
-- self:ReSpawn( SpawnGroupIndex )
|
-- self:ReSpawn( SpawnGroupIndex )
|
||||||
-- Delay respawn by three seconds due to DCS 2.5.4.26368 OB bug https://github.com/FlightControl-Master/MOOSE/issues/1076
|
-- Delay respawn by three seconds due to DCS 2.5.4.26368 OB bug https://github.com/FlightControl-Master/MOOSE/issues/1076
|
||||||
-- Bug was initially only for engine shutdown event but after ED "fixed" it, it now happens on landing events.
|
-- Bug was initially only for engine shutdown event but after ED "fixed" it, it now happens on landing events.
|
||||||
@@ -4029,13 +4075,13 @@ function SPAWN:_OnEngineShutDown( EventData )
|
|||||||
if SpawnGroup then
|
if SpawnGroup then
|
||||||
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
|
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
|
||||||
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
|
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
|
||||||
self:T2( { "EngineShutdown event: " .. EventPrefix } )
|
--self:T2( { "EngineShutdown event: " .. EventPrefix } )
|
||||||
if EventPrefix == self.SpawnTemplatePrefix or (self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix) then
|
if EventPrefix == self.SpawnTemplatePrefix or (self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix) then
|
||||||
-- todo: test if on the runway
|
-- todo: test if on the runway
|
||||||
local Landed = SpawnGroup:GetState( SpawnGroup, "Spawn_Landed" )
|
local Landed = SpawnGroup:GetState( SpawnGroup, "Spawn_Landed" )
|
||||||
if Landed and self.RepeatOnEngineShutDown then
|
if Landed and self.RepeatOnEngineShutDown then
|
||||||
local SpawnGroupIndex = self:GetSpawnIndexFromGroup( SpawnGroup )
|
local SpawnGroupIndex = self:GetSpawnIndexFromGroup( SpawnGroup )
|
||||||
self:T2( { "EngineShutDown: ", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
|
--self:T2( { "EngineShutDown: ", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
|
||||||
-- self:ReSpawn( SpawnGroupIndex )
|
-- self:ReSpawn( SpawnGroupIndex )
|
||||||
-- Delay respawn by three seconds due to DCS 2.5.4 OB bug https://github.com/FlightControl-Master/MOOSE/issues/1076
|
-- Delay respawn by three seconds due to DCS 2.5.4 OB bug https://github.com/FlightControl-Master/MOOSE/issues/1076
|
||||||
SCHEDULER:New( nil, self.ReSpawn, { self, SpawnGroupIndex }, 3 )
|
SCHEDULER:New( nil, self.ReSpawn, { self, SpawnGroupIndex }, 3 )
|
||||||
@@ -4064,7 +4110,7 @@ function SPAWN:_SpawnCleanUpScheduler()
|
|||||||
--self:F( { "CleanUp Scheduler:", self.SpawnTemplatePrefix } )
|
--self:F( { "CleanUp Scheduler:", self.SpawnTemplatePrefix } )
|
||||||
|
|
||||||
local SpawnGroup, SpawnCursor = self:GetFirstAliveGroup()
|
local SpawnGroup, SpawnCursor = self:GetFirstAliveGroup()
|
||||||
self:T2( { "CleanUp Scheduler:", SpawnGroup, SpawnCursor } )
|
--self:T2( { "CleanUp Scheduler:", SpawnGroup, SpawnCursor } )
|
||||||
|
|
||||||
local IsHelo = false
|
local IsHelo = false
|
||||||
|
|
||||||
@@ -4081,7 +4127,7 @@ function SPAWN:_SpawnCleanUpScheduler()
|
|||||||
|
|
||||||
self.SpawnCleanUpTimeStamps[SpawnUnitName] = self.SpawnCleanUpTimeStamps[SpawnUnitName] or {}
|
self.SpawnCleanUpTimeStamps[SpawnUnitName] = self.SpawnCleanUpTimeStamps[SpawnUnitName] or {}
|
||||||
local Stamp = self.SpawnCleanUpTimeStamps[SpawnUnitName]
|
local Stamp = self.SpawnCleanUpTimeStamps[SpawnUnitName]
|
||||||
self:T2( { SpawnUnitName, Stamp } )
|
--self:T2( { SpawnUnitName, Stamp } )
|
||||||
|
|
||||||
if Stamp.Vec2 then
|
if Stamp.Vec2 then
|
||||||
if (SpawnUnit:InAir() == false and SpawnUnit:GetVelocityKMH() < 1) or IsHelo then
|
if (SpawnUnit:InAir() == false and SpawnUnit:GetVelocityKMH() < 1) or IsHelo then
|
||||||
@@ -4089,7 +4135,7 @@ function SPAWN:_SpawnCleanUpScheduler()
|
|||||||
if (Stamp.Vec2.x == NewVec2.x and Stamp.Vec2.y == NewVec2.y) or (SpawnUnit:GetLife() <= 1) then
|
if (Stamp.Vec2.x == NewVec2.x and Stamp.Vec2.y == NewVec2.y) or (SpawnUnit:GetLife() <= 1) then
|
||||||
-- If the plane is not moving or dead , and is on the ground, assign it with a timestamp...
|
-- If the plane is not moving or dead , and is on the ground, assign it with a timestamp...
|
||||||
if Stamp.Time + self.SpawnCleanUpInterval < timer.getTime() then
|
if Stamp.Time + self.SpawnCleanUpInterval < timer.getTime() then
|
||||||
self:T2( { "CleanUp Scheduler:", "ReSpawning:", SpawnGroup:GetName() } )
|
--self:T2( { "CleanUp Scheduler:", "ReSpawning:", SpawnGroup:GetName() } )
|
||||||
--self:ReSpawn( SpawnCursor )
|
--self:ReSpawn( SpawnCursor )
|
||||||
SCHEDULER:New( nil, self.ReSpawn, { self, SpawnCursor }, 3 )
|
SCHEDULER:New( nil, self.ReSpawn, { self, SpawnCursor }, 3 )
|
||||||
Stamp.Vec2 = nil
|
Stamp.Vec2 = nil
|
||||||
@@ -4118,7 +4164,7 @@ function SPAWN:_SpawnCleanUpScheduler()
|
|||||||
|
|
||||||
SpawnGroup, SpawnCursor = self:GetNextAliveGroup( SpawnCursor )
|
SpawnGroup, SpawnCursor = self:GetNextAliveGroup( SpawnCursor )
|
||||||
|
|
||||||
self:T2( { "CleanUp Scheduler:", SpawnGroup, SpawnCursor } )
|
--self:T2( { "CleanUp Scheduler:", SpawnGroup, SpawnCursor } )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -535,12 +535,6 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
|
|||||||
-- Name of the spawned static.
|
-- Name of the spawned static.
|
||||||
Template.name = self.InitStaticName or string.format("%s#%05d", self.SpawnTemplatePrefix, self.SpawnIndex)
|
Template.name = self.InitStaticName or string.format("%s#%05d", self.SpawnTemplatePrefix, self.SpawnIndex)
|
||||||
|
|
||||||
-- Add and register the new static.
|
|
||||||
local mystatic=_DATABASE:AddStatic(Template.name)
|
|
||||||
|
|
||||||
-- Debug output.
|
|
||||||
self:T(Template)
|
|
||||||
|
|
||||||
-- Add static to the game.
|
-- Add static to the game.
|
||||||
local Static=nil --DCS#StaticObject
|
local Static=nil --DCS#StaticObject
|
||||||
|
|
||||||
@@ -577,12 +571,28 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
|
|||||||
self:T("Spawning Static")
|
self:T("Spawning Static")
|
||||||
self:T2({Template=Template})
|
self:T2({Template=Template})
|
||||||
Static=coalition.addStaticObject(CountryID, Template)
|
Static=coalition.addStaticObject(CountryID, Template)
|
||||||
|
|
||||||
|
if Static then
|
||||||
|
self:T(string.format("Succesfully spawned static object \"%s\" ID=%d", Static:getName(), Static:getID()))
|
||||||
|
--[[
|
||||||
|
local static=StaticObject.getByName(Static:getName())
|
||||||
|
if static then
|
||||||
|
env.info(string.format("FF got static from StaticObject.getByName"))
|
||||||
|
else
|
||||||
|
env.error(string.format("FF error did NOT get static from StaticObject.getByName"))
|
||||||
|
end ]]
|
||||||
|
else
|
||||||
|
self:E(string.format("ERROR: DCS static object \"%s\" is nil!", tostring(Template.name)))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Add and register the new static.
|
||||||
|
local mystatic=_DATABASE:AddStatic(Template.name)
|
||||||
|
|
||||||
-- If there is a SpawnFunction hook defined, call it.
|
-- If there is a SpawnFunction hook defined, call it.
|
||||||
if self.SpawnFunctionHook then
|
if self.SpawnFunctionHook then
|
||||||
-- delay calling this for .3 seconds so that it hopefully comes after the BIRTH event of the group.
|
-- delay calling this for .3 seconds so that it hopefully comes after the BIRTH event of the group.
|
||||||
self:ScheduleOnce(0.3,self.SpawnFunctionHook,mystatic, unpack(self.SpawnFunctionArguments))
|
self:ScheduleOnce(0.3, self.SpawnFunctionHook, mystatic, unpack(self.SpawnFunctionArguments))
|
||||||
end
|
end
|
||||||
|
|
||||||
return mystatic
|
return mystatic
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ do -- world
|
|||||||
-- @field #world.event event [https://wiki.hoggitworld.com/view/DCS_enum_world](https://wiki.hoggitworld.com/view/DCS_enum_world)
|
-- @field #world.event event [https://wiki.hoggitworld.com/view/DCS_enum_world](https://wiki.hoggitworld.com/view/DCS_enum_world)
|
||||||
-- @field #world.BirthPlace BirthPlace The birthplace enumerator is used to define where an aircraft or helicopter has spawned in association with birth events.
|
-- @field #world.BirthPlace BirthPlace The birthplace enumerator is used to define where an aircraft or helicopter has spawned in association with birth events.
|
||||||
-- @field #world.VolumeType VolumeType The volumeType enumerator defines the types of 3d geometery used within the [world.searchObjects](https://wiki.hoggitworld.com/view/DCS_func_searchObjects) function.
|
-- @field #world.VolumeType VolumeType The volumeType enumerator defines the types of 3d geometery used within the [world.searchObjects](https://wiki.hoggitworld.com/view/DCS_func_searchObjects) function.
|
||||||
|
-- @field #world.weather weather Weather functions for fog etc.
|
||||||
|
|
||||||
--- The world singleton contains functions centered around two different but extremely useful functions.
|
--- The world singleton contains functions centered around two different but extremely useful functions.
|
||||||
-- * Events and event handlers are all governed within world.
|
-- * Events and event handlers are all governed within world.
|
||||||
@@ -132,6 +133,36 @@ do -- world
|
|||||||
-- @function [parent=#world] getAirbases
|
-- @function [parent=#world] getAirbases
|
||||||
-- @param #number coalitionId The coalition side number ID. Default is all airbases are returned.
|
-- @param #number coalitionId The coalition side number ID. Default is all airbases are returned.
|
||||||
-- @return #table Table of DCS airbase objects.
|
-- @return #table Table of DCS airbase objects.
|
||||||
|
|
||||||
|
|
||||||
|
--- Weather functions.
|
||||||
|
-- @type world.weather
|
||||||
|
|
||||||
|
--- Fog animation data structure.
|
||||||
|
-- @type world.FogAnimation
|
||||||
|
-- @field #number time
|
||||||
|
-- @field #number visibility
|
||||||
|
-- @field #number thickness
|
||||||
|
|
||||||
|
--- Returns the current fog thickness.
|
||||||
|
-- @function [parent=#world.weather] getFogThickness Returns the fog thickness.
|
||||||
|
-- @return #number Fog thickness in meters. If there is no fog, zero is returned.
|
||||||
|
|
||||||
|
--- Sets the fog thickness instantly. Any current fog animation is discarded.
|
||||||
|
-- @function [parent=#world.weather] setFogThickness
|
||||||
|
-- @param #number thickness Fog thickness in meters. Set to zero to disable fog.
|
||||||
|
|
||||||
|
--- Returns the current fog visibility distance.
|
||||||
|
-- @function [parent=#world.weather] getFogVisibilityDistance Returns the current maximum visibility distance in meters. Returns zero if fog is not present.
|
||||||
|
|
||||||
|
--- Instantly sets the maximum visibility distance of fog at sea level when looking at the horizon. Any current fog animation is discarded. Set zero to disable the fog.
|
||||||
|
-- @function [parent=#world.weather] setFogVisibilityDistance
|
||||||
|
-- @param #number visibility Max fog visibility in meters. Set to zero to disable fog.
|
||||||
|
|
||||||
|
--- Sets fog animation keys. Time is set in seconds and relative to the current simulation time, where time=0 is the current moment.
|
||||||
|
-- Time must be increasing. Previous animation is always discarded despite the data being correct.
|
||||||
|
-- @function [parent=#world.weather] setFogAnimation
|
||||||
|
-- @param #world.FogAnimation animation List of fog animations
|
||||||
|
|
||||||
end -- world
|
end -- world
|
||||||
|
|
||||||
@@ -407,7 +438,7 @@ do -- coalition
|
|||||||
-- @param #table groupData Group data table.
|
-- @param #table groupData Group data table.
|
||||||
-- @return DCS#Group The spawned Group object.
|
-- @return DCS#Group The spawned Group object.
|
||||||
|
|
||||||
--- Dynamically spawns a static object. See [hoggit](https://wiki.hoggitworld.com/view/DCS_func_addGroup)
|
--- Dynamically spawns a static object. See [hoggit](https://wiki.hoggitworld.com/view/DCS_func_addStaticObject)
|
||||||
-- @function [parent=#coalition] addStaticObject
|
-- @function [parent=#coalition] addStaticObject
|
||||||
-- @param #number countryId Id of the country.
|
-- @param #number countryId Id of the country.
|
||||||
-- @param #table groupData Group data table.
|
-- @param #table groupData Group data table.
|
||||||
@@ -420,6 +451,7 @@ end -- coalition
|
|||||||
|
|
||||||
do -- Types
|
do -- Types
|
||||||
|
|
||||||
|
--- Descriptors.
|
||||||
-- @type Desc
|
-- @type Desc
|
||||||
-- @field #number speedMax0 Max speed in meters/second at zero altitude.
|
-- @field #number speedMax0 Max speed in meters/second at zero altitude.
|
||||||
-- @field #number massEmpty Empty mass in kg.
|
-- @field #number massEmpty Empty mass in kg.
|
||||||
@@ -1013,14 +1045,16 @@ do -- Spot
|
|||||||
end -- Spot
|
end -- Spot
|
||||||
|
|
||||||
do -- Controller
|
do -- Controller
|
||||||
|
|
||||||
--- Controller is an object that performs A.I.-tasks. Other words controller is an instance of A.I.. Controller stores current main task, active enroute tasks and behavior options. Controller performs commands. Please, read DCS A-10C GUI Manual EN.pdf chapter "Task Planning for Unit Groups", page 91 to understand A.I. system of DCS:A-10C.
|
--- Controller is an object that performs A.I.-tasks. Other words controller is an instance of A.I.. Controller stores current main task, active enroute tasks and behavior options. Controller performs commands. Please, read DCS A-10C GUI Manual EN.pdf chapter "Task Planning for Unit Groups", page 91 to understand A.I. system of DCS:A-10C.
|
||||||
--
|
--
|
||||||
-- This class has 2 types of functions:
|
-- This class has 2 types of functions:
|
||||||
--
|
--
|
||||||
-- * Tasks
|
-- * Tasks
|
||||||
-- * Commands: Commands are instant actions those required zero time to perform. Commands may be used both for control unit/group behavior and control game mechanics.
|
-- * Commands: Commands are instant actions those required zero time to perform. Commands may be used both for control unit/group behavior and control game mechanics.
|
||||||
|
--
|
||||||
-- @type Controller
|
-- @type Controller
|
||||||
-- @field #Controller.Detection Detection Enum contains identifiers of surface types.
|
-- @field #Controller.Detection Detection Enum contains identifiers of surface types.
|
||||||
|
|
||||||
--- Enables and disables the controller.
|
--- Enables and disables the controller.
|
||||||
-- Note: Now it works only for ground / naval groups!
|
-- Note: Now it works only for ground / naval groups!
|
||||||
@@ -1079,18 +1113,18 @@ do -- Controller
|
|||||||
|
|
||||||
-- Detection
|
-- Detection
|
||||||
|
|
||||||
--- Enum contains identifiers of surface types.
|
--- Enum containing detection types.
|
||||||
-- @type Controller.Detection
|
-- @type Controller.Detection
|
||||||
-- @field VISUAL
|
-- @field #number VISUAL Visual detection. Numeric value 1.
|
||||||
-- @field OPTIC
|
-- @field #number OPTIC Optical detection. Numeric value 2.
|
||||||
-- @field RADAR
|
-- @field #number RADAR Radar detection. Numeric value 4.
|
||||||
-- @field IRST
|
-- @field #number IRST Infra-red search and track detection. Numeric value 8.
|
||||||
-- @field RWR
|
-- @field #number RWR Radar Warning Receiver detection. Numeric value 16.
|
||||||
-- @field DLINK
|
-- @field #number DLINK Data link detection. Numeric value 32.
|
||||||
|
|
||||||
--- Detected target.
|
--- Detected target.
|
||||||
-- @type DetectedTarget
|
-- @type Controller.DetectedTarget
|
||||||
-- @field Wrapper.Object#Object object The target
|
-- @field DCS#Object object The target
|
||||||
-- @field #boolean visible The target is visible
|
-- @field #boolean visible The target is visible
|
||||||
-- @field #boolean type The target type is known
|
-- @field #boolean type The target type is known
|
||||||
-- @field #boolean distance Distance to the target is known
|
-- @field #boolean distance Distance to the target is known
|
||||||
@@ -1103,9 +1137,9 @@ do -- Controller
|
|||||||
-- @param #Controller.Detection detection Controller.Detection detection1, Controller.Detection detection2, ... Controller.Detection detectionN
|
-- @param #Controller.Detection detection Controller.Detection detection1, Controller.Detection detection2, ... Controller.Detection detectionN
|
||||||
-- @return #boolean detected True if the target is detected.
|
-- @return #boolean detected True if the target is detected.
|
||||||
-- @return #boolean visible Has effect only if detected is true. True if the target is visible now.
|
-- @return #boolean visible Has effect only if detected is true. True if the target is visible now.
|
||||||
|
-- @return #boolean type Has effect only if detected is true. True if the target type is known.
|
||||||
|
-- @return #boolean distance Has effect only if detected is true. True if the distance to the target is known.
|
||||||
-- @return #ModelTime lastTime Has effect only if visible is false. Last time when target was seen.
|
-- @return #ModelTime lastTime Has effect only if visible is false. Last time when target was seen.
|
||||||
-- @return #boolean type Has effect only if detected is true. True if the target type is known.
|
|
||||||
-- @return #boolean distance Has effect only if detected is true. True if the distance to the target is known.
|
|
||||||
-- @return #Vec3 lastPos Has effect only if visible is false. Last position of the target when it was seen.
|
-- @return #Vec3 lastPos Has effect only if visible is false. Last position of the target when it was seen.
|
||||||
-- @return #Vec3 lastVel Has effect only if visible is false. Last velocity of the target when it was seen.
|
-- @return #Vec3 lastVel Has effect only if visible is false. Last velocity of the target when it was seen.
|
||||||
|
|
||||||
@@ -1131,6 +1165,7 @@ end -- Controller
|
|||||||
|
|
||||||
do -- Unit
|
do -- Unit
|
||||||
|
|
||||||
|
--- Unit.
|
||||||
-- @type Unit
|
-- @type Unit
|
||||||
-- @extends #CoalitionObject
|
-- @extends #CoalitionObject
|
||||||
-- @field ID Identifier of an unit. It assigned to an unit by the Mission Editor automatically.
|
-- @field ID Identifier of an unit. It assigned to an unit by the Mission Editor automatically.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
-- ### Author: FlightControl - Framework Design & Programming
|
-- ### Author: FlightControl - Framework Design & Programming
|
||||||
-- ### Refactoring to use the Runway auto-detection: Applevangelist
|
-- ### Refactoring to use the Runway auto-detection: Applevangelist
|
||||||
-- @date August 2022
|
-- @date August 2022
|
||||||
-- Last Update Nov 2023
|
-- Last Update Oct 2024
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@@ -721,14 +721,18 @@ function ATC_GROUND_UNIVERSAL:_AirbaseMonitor()
|
|||||||
|
|
||||||
if NotInRunwayZone then
|
if NotInRunwayZone then
|
||||||
|
|
||||||
|
local Taxi = Client:GetState( self, "Taxi" )
|
||||||
|
|
||||||
if IsOnGround then
|
if IsOnGround then
|
||||||
local Taxi = Client:GetState( self, "Taxi" )
|
|
||||||
self:T( Taxi )
|
self:T( Taxi )
|
||||||
if Taxi == false then
|
if Taxi == false then
|
||||||
local Velocity = VELOCITY:New( AirbaseMeta.KickSpeed or self.KickSpeed )
|
local Velocity = VELOCITY:New( AirbaseMeta.KickSpeed or self.KickSpeed )
|
||||||
Client:Message( "Welcome to " .. AirbaseID .. ". The maximum taxiing speed is " ..
|
Client:Message( "Welcome to " .. AirbaseID .. ". The maximum taxiing speed is " ..
|
||||||
Velocity:ToString() , 20, "ATC" )
|
Velocity:ToString() , 20, "ATC" )
|
||||||
Client:SetState( self, "Taxi", true )
|
Client:SetState( self, "Taxi", true )
|
||||||
|
Client:SetState( self, "Speeding", false )
|
||||||
|
Client:SetState( self, "Warnings", 0 )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: GetVelocityKMH function usage
|
-- TODO: GetVelocityKMH function usage
|
||||||
@@ -737,7 +741,7 @@ function ATC_GROUND_UNIVERSAL:_AirbaseMonitor()
|
|||||||
local IsAboveRunway = Client:IsAboveRunway()
|
local IsAboveRunway = Client:IsAboveRunway()
|
||||||
self:T( {IsAboveRunway, IsOnGround, Velocity:Get() })
|
self:T( {IsAboveRunway, IsOnGround, Velocity:Get() })
|
||||||
|
|
||||||
if IsOnGround then
|
if IsOnGround and not Taxi then
|
||||||
local Speeding = false
|
local Speeding = false
|
||||||
if AirbaseMeta.MaximumKickSpeed then
|
if AirbaseMeta.MaximumKickSpeed then
|
||||||
if Velocity:Get() > AirbaseMeta.MaximumKickSpeed then
|
if Velocity:Get() > AirbaseMeta.MaximumKickSpeed then
|
||||||
@@ -749,15 +753,17 @@ function ATC_GROUND_UNIVERSAL:_AirbaseMonitor()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if Speeding == true then
|
if Speeding == true then
|
||||||
MESSAGE:New( "Penalty! Player " .. Client:GetPlayerName() ..
|
--MESSAGE:New( "Penalty! Player " .. Client:GetPlayerName() ..
|
||||||
" has been kicked, due to a severe airbase traffic rule violation ...", 10, "ATC" ):ToAll()
|
-- " has been kicked, due to a severe airbase traffic rule violation ...", 10, "ATC" ):ToAll()
|
||||||
Client:Destroy()
|
--Client:Destroy()
|
||||||
Client:SetState( self, "Speeding", false )
|
Client:SetState( self, "Speeding", true )
|
||||||
Client:SetState( self, "Warnings", 0 )
|
local SpeedingWarnings = Client:GetState( self, "Warnings" )
|
||||||
|
Client:SetState( self, "Warnings", SpeedingWarnings + 1 )
|
||||||
|
Client:Message( "Warning " .. SpeedingWarnings .. "/3! Airbase traffic rule violation! Slow down now! Your speed is " ..
|
||||||
|
Velocity:ToString(), 5, "ATC" )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if IsOnGround then
|
if IsOnGround then
|
||||||
|
|
||||||
local Speeding = false
|
local Speeding = false
|
||||||
@@ -1035,23 +1041,23 @@ end
|
|||||||
-- The following airbases are monitored at the Nevada region.
|
-- The following airbases are monitored at the Nevada region.
|
||||||
-- Use the @{Wrapper.Airbase#AIRBASE.Nevada} enumeration to select the airbases to be monitored.
|
-- Use the @{Wrapper.Airbase#AIRBASE.Nevada} enumeration to select the airbases to be monitored.
|
||||||
--
|
--
|
||||||
-- * `AIRBASE.Nevada.Beatty_Airport`
|
-- * `AIRBASE.Nevada.Beatty`
|
||||||
-- * `AIRBASE.Nevada.Boulder_City_Airport`
|
-- * `AIRBASE.Nevada.Boulder_City`
|
||||||
-- * `AIRBASE.Nevada.Creech_AFB`
|
-- * `AIRBASE.Nevada.Creech`
|
||||||
-- * `AIRBASE.Nevada.Echo_Bay`
|
-- * `AIRBASE.Nevada.Echo_Bay`
|
||||||
-- * `AIRBASE.Nevada.Groom_Lake_AFB`
|
-- * `AIRBASE.Nevada.Groom_Lake`
|
||||||
-- * `AIRBASE.Nevada.Henderson_Executive_Airport`
|
-- * `AIRBASE.Nevada.Henderson_Executive`
|
||||||
-- * `AIRBASE.Nevada.Jean_Airport`
|
-- * `AIRBASE.Nevada.Jean`
|
||||||
-- * `AIRBASE.Nevada.Laughlin_Airport`
|
-- * `AIRBASE.Nevada.Laughlin`
|
||||||
-- * `AIRBASE.Nevada.Lincoln_County`
|
-- * `AIRBASE.Nevada.Lincoln_County`
|
||||||
-- * `AIRBASE.Nevada.McCarran_International_Airport`
|
-- * `AIRBASE.Nevada.McCarran_International`
|
||||||
-- * `AIRBASE.Nevada.Mesquite`
|
-- * `AIRBASE.Nevada.Mesquite`
|
||||||
-- * `AIRBASE.Nevada.Mina_Airport`
|
-- * `AIRBASE.Nevada.Mina`
|
||||||
-- * `AIRBASE.Nevada.Nellis_AFB`
|
-- * `AIRBASE.Nevada.Nellis`
|
||||||
-- * `AIRBASE.Nevada.North_Las_Vegas`
|
-- * `AIRBASE.Nevada.North_Las_Vegas`
|
||||||
-- * `AIRBASE.Nevada.Pahute_Mesa_Airstrip`
|
-- * `AIRBASE.Nevada.Pahute_Mesa`
|
||||||
-- * `AIRBASE.Nevada.Tonopah_Airport`
|
-- * `AIRBASE.Nevada.Tonopah`
|
||||||
-- * `AIRBASE.Nevada.Tonopah_Test_Range_Airfield`
|
-- * `AIRBASE.Nevada.Tonopah_Test_Range`
|
||||||
--
|
--
|
||||||
-- # Installation
|
-- # Installation
|
||||||
--
|
--
|
||||||
@@ -1088,10 +1094,10 @@ end
|
|||||||
--
|
--
|
||||||
-- -- Monitor specific airbases.
|
-- -- Monitor specific airbases.
|
||||||
-- ATC_Ground = ATC_GROUND_NEVADA:New(
|
-- ATC_Ground = ATC_GROUND_NEVADA:New(
|
||||||
-- { AIRBASE.Nevada.Laughlin_Airport,
|
-- { AIRBASE.Nevada.Laughlin,
|
||||||
-- AIRBASE.Nevada.Lincoln_County,
|
-- AIRBASE.Nevada.Lincoln_County,
|
||||||
-- AIRBASE.Nevada.North_Las_Vegas,
|
-- AIRBASE.Nevada.North_Las_Vegas,
|
||||||
-- AIRBASE.Nevada.McCarran_International_Airport
|
-- AIRBASE.Nevada.McCarran_International
|
||||||
-- }
|
-- }
|
||||||
-- )
|
-- )
|
||||||
--
|
--
|
||||||
@@ -1330,33 +1336,33 @@ end
|
|||||||
-- The following airbases are monitored at the PersianGulf region.
|
-- The following airbases are monitored at the PersianGulf region.
|
||||||
-- Use the @{Wrapper.Airbase#AIRBASE.PersianGulf} enumeration to select the airbases to be monitored.
|
-- Use the @{Wrapper.Airbase#AIRBASE.PersianGulf} enumeration to select the airbases to be monitored.
|
||||||
--
|
--
|
||||||
-- * `AIRBASE.PersianGulf.Abu_Musa_Island_Airport`
|
-- * `AIRBASE.PersianGulf.Abu_Musa_Island`
|
||||||
-- * `AIRBASE.PersianGulf.Al_Dhafra_AB`
|
-- * `AIRBASE.PersianGulf.Al_Dhafra_AFB`
|
||||||
-- * `AIRBASE.PersianGulf.Al_Maktoum_Intl`
|
-- * `AIRBASE.PersianGulf.Al_Maktoum_Intl`
|
||||||
-- * `AIRBASE.PersianGulf.Al_Minhad_AB`
|
-- * `AIRBASE.PersianGulf.Al_Minhad_AFB`
|
||||||
-- * `AIRBASE.PersianGulf.Bandar_Abbas_Intl`
|
-- * `AIRBASE.PersianGulf.Bandar_Abbas_Intl`
|
||||||
-- * `AIRBASE.PersianGulf.Bandar_Lengeh`
|
-- * `AIRBASE.PersianGulf.Bandar_Lengeh`
|
||||||
-- * `AIRBASE.PersianGulf.Dubai_Intl`
|
-- * `AIRBASE.PersianGulf.Dubai_Intl`
|
||||||
-- * `AIRBASE.PersianGulf.Fujairah_Intl`
|
-- * `AIRBASE.PersianGulf.Fujairah_Intl`
|
||||||
-- * `AIRBASE.PersianGulf.Havadarya`
|
-- * `AIRBASE.PersianGulf.Havadarya`
|
||||||
-- * `AIRBASE.PersianGulf.Kerman_Airport`
|
-- * `AIRBASE.PersianGulf.Kerman`
|
||||||
-- * `AIRBASE.PersianGulf.Khasab`
|
-- * `AIRBASE.PersianGulf.Khasab`
|
||||||
-- * `AIRBASE.PersianGulf.Lar_Airbase`
|
-- * `AIRBASE.PersianGulf.Lar`
|
||||||
-- * `AIRBASE.PersianGulf.Qeshm_Island`
|
-- * `AIRBASE.PersianGulf.Qeshm_Island`
|
||||||
-- * `AIRBASE.PersianGulf.Sharjah_Intl`
|
-- * `AIRBASE.PersianGulf.Sharjah_Intl`
|
||||||
-- * `AIRBASE.PersianGulf.Shiraz_International_Airport`
|
-- * `AIRBASE.PersianGulf.Shiraz_Intl`
|
||||||
-- * `AIRBASE.PersianGulf.Sir_Abu_Nuayr`
|
-- * `AIRBASE.PersianGulf.Sir_Abu_Nuayr`
|
||||||
-- * `AIRBASE.PersianGulf.Sirri_Island`
|
-- * `AIRBASE.PersianGulf.Sirri_Island`
|
||||||
-- * `AIRBASE.PersianGulf.Tunb_Island_AFB`
|
-- * `AIRBASE.PersianGulf.Tunb_Island_AFB`
|
||||||
-- * `AIRBASE.PersianGulf.Tunb_Kochak`
|
-- * `AIRBASE.PersianGulf.Tunb_Kochak`
|
||||||
-- * `AIRBASE.PersianGulf.Sas_Al_Nakheel_Airport`
|
-- * `AIRBASE.PersianGulf.Sas_Al_Nakheel`
|
||||||
-- * `AIRBASE.PersianGulf.Bandar_e_Jask_airfield`
|
-- * `AIRBASE.PersianGulf.Bandar_e_Jask`
|
||||||
-- * `AIRBASE.PersianGulf.Abu_Dhabi_International_Airport`
|
-- * `AIRBASE.PersianGulf.Abu_Dhabi_Intl`
|
||||||
-- * `AIRBASE.PersianGulf.Al_Bateen_Airport`
|
-- * `AIRBASE.PersianGulf.Al_Bateen`
|
||||||
-- * `AIRBASE.PersianGulf.Kish_International_Airport`
|
-- * `AIRBASE.PersianGulf.Kish_Intl`
|
||||||
-- * `AIRBASE.PersianGulf.Al_Ain_International_Airport`
|
-- * `AIRBASE.PersianGulf.Al_Ain_Intl`
|
||||||
-- * `AIRBASE.PersianGulf.Lavan_Island_Airport`
|
-- * `AIRBASE.PersianGulf.Lavan_Island`
|
||||||
-- * `AIRBASE.PersianGulf.Jiroft_Airport`
|
-- * `AIRBASE.PersianGulf.Jiroft`
|
||||||
--
|
--
|
||||||
-- # Installation
|
-- # Installation
|
||||||
--
|
--
|
||||||
@@ -1391,8 +1397,8 @@ end
|
|||||||
-- AirbasePoliceCaucasus = ATC_GROUND_PERSIANGULF:New()
|
-- AirbasePoliceCaucasus = ATC_GROUND_PERSIANGULF:New()
|
||||||
--
|
--
|
||||||
-- ATC_Ground = ATC_GROUND_PERSIANGULF:New(
|
-- ATC_Ground = ATC_GROUND_PERSIANGULF:New(
|
||||||
-- { AIRBASE.PersianGulf.Kerman_Airport,
|
-- { AIRBASE.PersianGulf.Kerman,
|
||||||
-- AIRBASE.PersianGulf.Al_Minhad_AB
|
-- AIRBASE.PersianGulf.Al_Minhad_AFB
|
||||||
-- }
|
-- }
|
||||||
-- )
|
-- )
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -652,7 +652,7 @@ do -- DETECTION_BASE
|
|||||||
|
|
||||||
if DetectedObject:isExist() then
|
if DetectedObject:isExist() then
|
||||||
|
|
||||||
local TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity = DetectionUnit:IsTargetDetected(
|
local TargetIsDetected, TargetIsVisible, TargetKnowType, TargetKnowDistance, TargetLastTime, TargetLastPos, TargetLastVelocity = DetectionUnit:IsTargetDetected(
|
||||||
DetectedObject,
|
DetectedObject,
|
||||||
self.DetectVisual,
|
self.DetectVisual,
|
||||||
self.DetectOptical,
|
self.DetectOptical,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
-- @module Functional.Mantis
|
-- @module Functional.Mantis
|
||||||
-- @image Functional.Mantis.jpg
|
-- @image Functional.Mantis.jpg
|
||||||
--
|
--
|
||||||
-- Last Update: July 2024
|
-- Last Update: Sep 2024
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **MANTIS** class, extends Core.Base#BASE
|
--- **MANTIS** class, extends Core.Base#BASE
|
||||||
@@ -439,27 +439,50 @@ MANTIS.SamDataSMA = {
|
|||||||
-- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range)
|
-- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range)
|
||||||
-- @field #string Radar Radar typename on unit level (used as key)
|
-- @field #string Radar Radar typename on unit level (used as key)
|
||||||
MANTIS.SamDataCH = {
|
MANTIS.SamDataCH = {
|
||||||
-- units from CH (Military Assets by Currenthill)
|
-- units from CH (Military Assets by Currenthill)
|
||||||
-- https://www.currenthill.com/
|
-- https://www.currenthill.com/
|
||||||
-- group name MUST contain CHM to ID launcher type correctly!
|
-- group name MUST contain CHM to ID launcher type correctly!
|
||||||
["2S38 CH"] = { Range=8, Blindspot=0.5, Height=6, Type="Short", Radar="2S38" },
|
["2S38 CHM"] = { Range=8, Blindspot=0.5, Height=6, Type="Short", Radar="2S38" },
|
||||||
["PantsirS1 CH"] = { Range=20, Blindspot=1.2, Height=15, Type="Short", Radar="PantsirS1" },
|
["PantsirS1 CHM"] = { Range=20, Blindspot=1.2, Height=15, Type="Short", Radar="PantsirS1" },
|
||||||
["PantsirS2 CH"] = { Range=30, Blindspot=1.2, Height=18, Type="Medium", Radar="PantsirS2" },
|
["PantsirS2 CHM"] = { Range=30, Blindspot=1.2, Height=18, Type="Medium", Radar="PantsirS2" },
|
||||||
["PGL-625 CH"] = { Range=10, Blindspot=0.5, Height=5, Type="Short", Radar="PGL_625" },
|
["PGL-625 CHM"] = { Range=10, Blindspot=0.5, Height=5, Type="Short", Radar="PGL_625" },
|
||||||
["HQ-17A CH"] = { Range=20, Blindspot=1.5, Height=10, Type="Short", Radar="HQ17A" },
|
["HQ-17A CHM"] = { Range=20, Blindspot=1.5, Height=10, Type="Short", Radar="HQ17A" },
|
||||||
["M903PAC2 CH"] = { Range=160, Blindspot=3, Height=24.5, Type="Long", Radar="MIM104_M903_PAC2" },
|
["M903PAC2 CHM"] = { Range=160, Blindspot=3, Height=24.5, Type="Long", Radar="MIM104_M903_PAC2" },
|
||||||
["M903PAC3 CH"] = { Range=120, Blindspot=1, Height=40, Type="Long", Radar="MIM104_M903_PAC3" },
|
["M903PAC3 CHM"] = { Range=120, Blindspot=1, Height=40, Type="Long", Radar="MIM104_M903_PAC3" },
|
||||||
["TorM2 CH"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2" },
|
["TorM2 CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2" },
|
||||||
["TorM2K CH"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2K" },
|
["TorM2K CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2K" },
|
||||||
["TorM2M CH"] = { Range=16, Blindspot=1, Height=10, Type="Short", Radar="TorM2M" },
|
["TorM2M CHM"] = { Range=16, Blindspot=1, Height=10, Type="Short", Radar="TorM2M" },
|
||||||
["NASAMS3-AMRAAMER CH"] = { Range=50, Blindspot=2, Height=35.7, Type="Medium", Radar="CH_NASAMS3_LN_AMRAAM_ER" },
|
["NASAMS3-AMRAAMER CHM"] = { Range=50, Blindspot=2, Height=35.7, Type="Medium", Radar="CH_NASAMS3_LN_AMRAAM_ER" },
|
||||||
["NASAMS3-AIM9X2 CH"] = { Range=20, Blindspot=0.2, Height=18, Type="Short", Radar="CH_NASAMS3_LN_AIM9X2" },
|
["NASAMS3-AIM9X2 CHM"] = { Range=20, Blindspot=0.2, Height=18, Type="Short", Radar="CH_NASAMS3_LN_AIM9X2" },
|
||||||
["C-RAM CH"] = { Range=2, Blindspot=0, Height=2, Type="Short", Radar="CH_Centurion_C_RAM" },
|
["C-RAM CHM"] = { Range=2, Blindspot=0, Height=2, Type="Short", Radar="CH_Centurion_C_RAM" },
|
||||||
["PGZ-09 CH"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="CH_PGZ09" },
|
["PGZ-09 CHM"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="CH_PGZ09" },
|
||||||
["S350-9M100 CH"] = { Range=15, Blindspot=1.5, Height=8, Type="Short", Radar="CH_S350_50P6_9M100" },
|
["S350-9M100 CHM"] = { Range=15, Blindspot=1.5, Height=8, Type="Short", Radar="CH_S350_50P6_9M100" },
|
||||||
["S350-9M96D CH"] = { Range=150, Blindspot=2.5, Height=30, Type="Long", Radar="CH_S350_50P6_9M96D" },
|
["S350-9M96D CHM"] = { Range=150, Blindspot=2.5, Height=30, Type="Long", Radar="CH_S350_50P6_9M96D" },
|
||||||
["LAV-AD CH"] = { Range=8, Blindspot=0.2, Height=4.8, Type="Short", Radar="CH_LAVAD" },
|
["LAV-AD CHM"] = { Range=8, Blindspot=0.2, Height=4.8, Type="Short", Radar="CH_LAVAD" },
|
||||||
["HQ-22 CH"] = { Range=170, Blindspot=5, Height=27, Type="Long", Radar="CH_HQ22_LN" },
|
["HQ-22 CHM"] = { Range=170, Blindspot=5, Height=27, Type="Long", Radar="CH_HQ22_LN" },
|
||||||
|
["PGZ-95 CHM"] = { Range=2, Blindspot=0, Height=2, Type="Short", Radar="CH_PGZ95" },
|
||||||
|
["LD-3000 CHM"] = { Range=3, Blindspot=0, Height=3, Type="Short", Radar="CH_LD3000_stationary" },
|
||||||
|
["LD-3000M CHM"] = { Range=3, Blindspot=0, Height=3, Type="Short", Radar="CH_LD3000" },
|
||||||
|
["FlaRakRad CHM"] = { Range=8, Blindspot=1.5, Height=6, Type="Short", Radar="HQ17A" },
|
||||||
|
["IRIS-T SLM CHM"] = { Range=40, Blindspot=0.5, Height=20, Type="Medium", Radar="CH_IRIST_SLM" },
|
||||||
|
["M903PAC2KAT1 CHM"] = { Range=160, Blindspot=3, Height=24.5, Type="Long", Radar="CH_MIM104_M903_PAC2_KAT1" },
|
||||||
|
["Skynex CHM"] = { Range=3.5, Blindspot=0, Height=3.5, Type="Short", Radar="CH_SkynexHX" },
|
||||||
|
["Skyshield CHM"] = { Range=3.5, Blindspot=0, Height=3.5, Type="Short", Radar="CH_Skyshield_Gun" },
|
||||||
|
["WieselOzelot CHM"] = { Range=8, Blindspot=0.2, Height=4.8, Type="Short", Radar="CH_Wiesel2Ozelot" },
|
||||||
|
["BukM3-9M317M CHM"] = { Range=70, Blindspot=0.25, Height=35, Type="Medium", Radar="CH_BukM3_9A317M" },
|
||||||
|
["BukM3-9M317MA CHM"] = { Range=70, Blindspot=0.25, Height=35, Type="Medium", Radar="CH_BukM3_9A317MA" },
|
||||||
|
["SkySabre CHM"] = { Range=30, Blindspot=0.5, Height=10, Type="Medium", Radar="CH_SkySabreLN" },
|
||||||
|
["Stormer CHM"] = { Range=7.5, Blindspot=0.3, Height=7, Type="Short", Radar="CH_StormerHVM" },
|
||||||
|
["THAAD CHM"] = { Range=200, Blindspot=40, Height=150, Type="Long", Radar="CH_THAAD_M1120" },
|
||||||
|
["USInfantryFIM92K CHM"] = { Range=8, Blindspot=0.2, Height=4.8, Type="Short", Radar="CH_USInfantry_FIM92" },
|
||||||
|
["RBS98M CHM"] = { Range=20, Blindspot=0, Height=8, Type="Short", Radar="RBS-98" },
|
||||||
|
["RBS70 CHM"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="RBS-70" },
|
||||||
|
["RBS90 CHM"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="RBS-90" },
|
||||||
|
["RBS103A CHM"] = { Range=150, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_Rb103A" },
|
||||||
|
["RBS103B CHM"] = { Range=35, Blindspot=0, Height=36, Type="Medium", Radar="LvS-103_Lavett103_Rb103B" },
|
||||||
|
["RBS103AM CHM"] = { Range=150, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103A" },
|
||||||
|
["RBS103BM CHM"] = { Range=35, Blindspot=0, Height=36, Type="Medium", Radar="LvS-103_Lavett103_HX_Rb103B" },
|
||||||
|
["Lvkv9040M CHM"] = { Range=4, Blindspot=0, Height=2.5, Type="Short", Radar="LvKv9040" },
|
||||||
}
|
}
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
@@ -640,7 +663,7 @@ do
|
|||||||
|
|
||||||
-- TODO Version
|
-- TODO Version
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
self.version="0.8.18"
|
self.version="0.8.20"
|
||||||
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
||||||
|
|
||||||
--- FSM Functions ---
|
--- FSM Functions ---
|
||||||
@@ -1396,7 +1419,7 @@ do
|
|||||||
-- @return #string type Long, medium or short range
|
-- @return #string type Long, medium or short range
|
||||||
-- @return #number blind "blind" spot
|
-- @return #number blind "blind" spot
|
||||||
function MANTIS:_GetSAMDataFromUnits(grpname,mod,sma,chm)
|
function MANTIS:_GetSAMDataFromUnits(grpname,mod,sma,chm)
|
||||||
self:T(self.lid.."_GetSAMRangeFromUnits")
|
self:T(self.lid.."_GetSAMDataFromUnits")
|
||||||
local found = false
|
local found = false
|
||||||
local range = self.checkradius
|
local range = self.checkradius
|
||||||
local height = 3000
|
local height = 3000
|
||||||
@@ -1449,7 +1472,7 @@ do
|
|||||||
-- @return #string type Long, medium or short range
|
-- @return #string type Long, medium or short range
|
||||||
-- @return #number blind "blind" spot
|
-- @return #number blind "blind" spot
|
||||||
function MANTIS:_GetSAMRange(grpname)
|
function MANTIS:_GetSAMRange(grpname)
|
||||||
self:T(self.lid.."_GetSAMRange")
|
self:T(self.lid.."_GetSAMRange for "..tostring(grpname))
|
||||||
local range = self.checkradius
|
local range = self.checkradius
|
||||||
local height = 3000
|
local height = 3000
|
||||||
local type = MANTIS.SamType.MEDIUM
|
local type = MANTIS.SamType.MEDIUM
|
||||||
@@ -1466,9 +1489,9 @@ do
|
|||||||
elseif string.find(grpname,"CHM",1,true) then
|
elseif string.find(grpname,"CHM",1,true) then
|
||||||
CHMod = true
|
CHMod = true
|
||||||
end
|
end
|
||||||
if self.automode then
|
--if self.automode then
|
||||||
for idx,entry in pairs(self.SamData) do
|
for idx,entry in pairs(self.SamData) do
|
||||||
--self:I("ID = " .. idx)
|
self:T("ID = " .. idx)
|
||||||
if string.find(grpname,idx,1,true) then
|
if string.find(grpname,idx,1,true) then
|
||||||
local _entry = entry -- #MANTIS.SamData
|
local _entry = entry -- #MANTIS.SamData
|
||||||
type = _entry.Type
|
type = _entry.Type
|
||||||
@@ -1476,18 +1499,21 @@ do
|
|||||||
range = _entry.Range * 1000 * radiusscale -- max firing range
|
range = _entry.Range * 1000 * radiusscale -- max firing range
|
||||||
height = _entry.Height * 1000 -- max firing height
|
height = _entry.Height * 1000 -- max firing height
|
||||||
blind = _entry.Blindspot
|
blind = _entry.Blindspot
|
||||||
--self:I("Matching Groupname = " .. grpname .. " Range= " .. range)
|
self:T("Matching Groupname = " .. grpname .. " Range= " .. range)
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
--end
|
||||||
-- secondary filter if not found
|
-- secondary filter if not found
|
||||||
if (not found and self.automode) or HDSmod or SMAMod or CHMod then
|
if (not found) or HDSmod or SMAMod or CHMod then
|
||||||
range, height, type = self:_GetSAMDataFromUnits(grpname,HDSmod,SMAMod,CHMod)
|
range, height, type = self:_GetSAMDataFromUnits(grpname,HDSmod,SMAMod,CHMod)
|
||||||
elseif not found then
|
elseif not found then
|
||||||
self:E(self.lid .. string.format("*****Could not match radar data for %s! Will default to midrange values!",grpname))
|
self:E(self.lid .. string.format("*****Could not match radar data for %s! Will default to midrange values!",grpname))
|
||||||
end
|
end
|
||||||
|
if string.find(grpname,"SHORAD",1,true) then
|
||||||
|
type = MANTIS.SamType.SHORT -- force short on match
|
||||||
|
end
|
||||||
return range, height, type, blind
|
return range, height, type, blind
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1651,6 +1677,10 @@ do
|
|||||||
function MANTIS:_CheckLoop(samset,detset,dlink,limit)
|
function MANTIS:_CheckLoop(samset,detset,dlink,limit)
|
||||||
self:T(self.lid .. "CheckLoop " .. #detset .. " Coordinates")
|
self:T(self.lid .. "CheckLoop " .. #detset .. " Coordinates")
|
||||||
local switchedon = 0
|
local switchedon = 0
|
||||||
|
local statusreport = REPORT:New("\nMANTIS Status")
|
||||||
|
local instatusred = 0
|
||||||
|
local instatusgreen = 0
|
||||||
|
local SEADactive = 0
|
||||||
for _,_data in pairs (samset) do
|
for _,_data in pairs (samset) do
|
||||||
local samcoordinate = _data[2]
|
local samcoordinate = _data[2]
|
||||||
local name = _data[1]
|
local name = _data[1]
|
||||||
@@ -1673,7 +1703,7 @@ do
|
|||||||
elseif (not self.UseEmOnOff) and switchedon < limit then
|
elseif (not self.UseEmOnOff) and switchedon < limit then
|
||||||
samgroup:OptionAlarmStateRed()
|
samgroup:OptionAlarmStateRed()
|
||||||
switchedon = switchedon + 1
|
switchedon = switchedon + 1
|
||||||
switch = true
|
switch = true
|
||||||
end
|
end
|
||||||
if self.SamStateTracker[name] ~= "RED" and switch then
|
if self.SamStateTracker[name] ~= "RED" and switch then
|
||||||
self:__RedState(1,samgroup)
|
self:__RedState(1,samgroup)
|
||||||
@@ -1691,7 +1721,7 @@ do
|
|||||||
-- debug output
|
-- debug output
|
||||||
if (self.debug or self.verbose) and switch then
|
if (self.debug or self.verbose) and switch then
|
||||||
local text = string.format("SAM %s in alarm state RED!", name)
|
local text = string.format("SAM %s in alarm state RED!", name)
|
||||||
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
--local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug
|
||||||
if self.verbose then self:I(self.lid..text) end
|
if self.verbose then self:I(self.lid..text) end
|
||||||
end
|
end
|
||||||
end --end alive
|
end --end alive
|
||||||
@@ -1709,12 +1739,26 @@ do
|
|||||||
end
|
end
|
||||||
if self.debug or self.verbose then
|
if self.debug or self.verbose then
|
||||||
local text = string.format("SAM %s in alarm state GREEN!", name)
|
local text = string.format("SAM %s in alarm state GREEN!", name)
|
||||||
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
--local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
||||||
if self.verbose then self:I(self.lid..text) end
|
if self.verbose then self:I(self.lid..text) end
|
||||||
end
|
end
|
||||||
end --end alive
|
end --end alive
|
||||||
end --end check
|
end --end check
|
||||||
end --for for loop
|
end --for loop
|
||||||
|
if self.debug then
|
||||||
|
for _,_status in pairs(self.SamStateTracker) do
|
||||||
|
if _status == "GREEN" then
|
||||||
|
instatusgreen=instatusgreen+1
|
||||||
|
elseif _status == "RED" then
|
||||||
|
instatusred=instatusred+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
statusreport:Add("+-----------------------------+")
|
||||||
|
statusreport:Add(string.format("+ SAM in RED State: %2d",instatusred))
|
||||||
|
statusreport:Add(string.format("+ SAM in GREEN State: %2d",instatusgreen))
|
||||||
|
statusreport:Add("+-----------------------------+")
|
||||||
|
MESSAGE:New(statusreport:Text(),10,nil,true):ToAll():ToLog()
|
||||||
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1828,7 +1872,7 @@ do
|
|||||||
end
|
end
|
||||||
--]]
|
--]]
|
||||||
if self.autoshorad then
|
if self.autoshorad then
|
||||||
self.Shorad = SHORAD:New(self.name.."-SHORAD",self.name.."-SHORAD",self.SAM_Group,self.ShoradActDistance,self.ShoradTime,self.coalition,self.UseEmOnOff)
|
self.Shorad = SHORAD:New(self.name.."-SHORAD","SHORAD",self.SAM_Group,self.ShoradActDistance,self.ShoradTime,self.coalition,self.UseEmOnOff)
|
||||||
self.Shorad:SetDefenseLimits(80,95)
|
self.Shorad:SetDefenseLimits(80,95)
|
||||||
self.ShoradLink = true
|
self.ShoradLink = true
|
||||||
self.Shorad.Groupset=self.ShoradGroupSet
|
self.Shorad.Groupset=self.ShoradGroupSet
|
||||||
|
|||||||
@@ -2987,7 +2987,7 @@ function RANGE:_DisplayBombTargets( _unitname )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self:_DisplayMessageToGroup( _unit, _text, 120, true, true, _multiplayer )
|
self:_DisplayMessageToGroup( _unit, _text, 150, true, true, _multiplayer )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -3453,10 +3453,10 @@ function RANGE:_AddF10Commands( _unitName )
|
|||||||
-- Range menu
|
-- Range menu
|
||||||
local _rangePath = MENU_GROUP:New( group, self.rangename, _rootMenu )
|
local _rangePath = MENU_GROUP:New( group, self.rangename, _rootMenu )
|
||||||
|
|
||||||
local _statsPath = MENU_GROUP:New( group, "Statistics", _rangePath )
|
|
||||||
local _markPath = MENU_GROUP:New( group, "Mark Targets", _rangePath )
|
|
||||||
local _settingsPath = MENU_GROUP:New( group, "My Settings", _rangePath )
|
|
||||||
local _infoPath = MENU_GROUP:New( group, "Range Info", _rangePath )
|
local _infoPath = MENU_GROUP:New( group, "Range Info", _rangePath )
|
||||||
|
local _markPath = MENU_GROUP:New( group, "Mark Targets", _rangePath )
|
||||||
|
local _statsPath = MENU_GROUP:New( group, "Statistics", _rangePath )
|
||||||
|
local _settingsPath = MENU_GROUP:New( group, "My Settings", _rangePath )
|
||||||
|
|
||||||
-- F10/On the Range/<Range Name>/My Settings/
|
-- F10/On the Range/<Range Name>/My Settings/
|
||||||
local _mysmokePath = MENU_GROUP:New( group, "Smoke Color", _settingsPath )
|
local _mysmokePath = MENU_GROUP:New( group, "Smoke Color", _settingsPath )
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
--
|
--
|
||||||
-- ### Authors: **applevangelist**, **FlightControl**
|
-- ### Authors: **applevangelist**, **FlightControl**
|
||||||
--
|
--
|
||||||
-- Last Update: Dec 2023
|
-- Last Update: Oct 2024
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@@ -28,6 +28,16 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
-- @type SEAD
|
-- @type SEAD
|
||||||
|
-- @field #string ClassName The Class Name.
|
||||||
|
-- @field #table TargetSkill Table of target skills.
|
||||||
|
-- @field #table SEADGroupPrefixes Table of SEAD prefixes.
|
||||||
|
-- @field #table SuppressedGroups Table of currently suppressed groups.
|
||||||
|
-- @field #number EngagementRange Engagement Range.
|
||||||
|
-- @field #number Padding Padding in seconds.
|
||||||
|
-- @field #function CallBack Callback function for suppression plans.
|
||||||
|
-- @field #boolean UseCallBack Switch for callback function to be used.
|
||||||
|
-- @field #boolean debug Debug switch.
|
||||||
|
-- @field #boolen WeaponTrack Track switch, if true track weapon speed for 30 secs.
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
--- Make SAM sites execute evasive and defensive behaviour when being fired upon.
|
--- Make SAM sites execute evasive and defensive behaviour when being fired upon.
|
||||||
@@ -56,10 +66,11 @@ SEAD = {
|
|||||||
SEADGroupPrefixes = {},
|
SEADGroupPrefixes = {},
|
||||||
SuppressedGroups = {},
|
SuppressedGroups = {},
|
||||||
EngagementRange = 75, -- default 75% engagement range Feature Request #1355
|
EngagementRange = 75, -- default 75% engagement range Feature Request #1355
|
||||||
Padding = 10,
|
Padding = 15,
|
||||||
CallBack = nil,
|
CallBack = nil,
|
||||||
UseCallBack = false,
|
UseCallBack = false,
|
||||||
debug = false,
|
debug = false,
|
||||||
|
WeaponTrack = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Missile enumerators
|
--- Missile enumerators
|
||||||
@@ -144,7 +155,7 @@ function SEAD:New( SEADGroupPrefixes, Padding )
|
|||||||
self:AddTransition("*", "ManageEvasion", "*")
|
self:AddTransition("*", "ManageEvasion", "*")
|
||||||
self:AddTransition("*", "CalculateHitZone", "*")
|
self:AddTransition("*", "CalculateHitZone", "*")
|
||||||
|
|
||||||
self:I("*** SEAD - Started Version 0.4.6")
|
self:I("*** SEAD - Started Version 0.4.8")
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -371,7 +382,7 @@ function SEAD:onafterManageEvasion(From,Event,To,_targetskill,_targetgroup,SEADP
|
|||||||
reach = wpndata[1] * 1.1
|
reach = wpndata[1] * 1.1
|
||||||
local mach = wpndata[2]
|
local mach = wpndata[2]
|
||||||
wpnspeed = math.floor(mach * 340.29)
|
wpnspeed = math.floor(mach * 340.29)
|
||||||
if Weapon then
|
if Weapon and Weapon:GetSpeed() > 0 then
|
||||||
wpnspeed = Weapon:GetSpeed()
|
wpnspeed = Weapon:GetSpeed()
|
||||||
self:T(string.format("*** SEAD - Weapon Speed from WEAPON: %f m/s",wpnspeed))
|
self:T(string.format("*** SEAD - Weapon Speed from WEAPON: %f m/s",wpnspeed))
|
||||||
end
|
end
|
||||||
@@ -452,22 +463,30 @@ end
|
|||||||
-- @return #SEAD self
|
-- @return #SEAD self
|
||||||
function SEAD:HandleEventShot( EventData )
|
function SEAD:HandleEventShot( EventData )
|
||||||
self:T( { EventData.id } )
|
self:T( { EventData.id } )
|
||||||
local SEADPlane = EventData.IniUnit -- Wrapper.Unit#UNIT
|
|
||||||
local SEADGroup = EventData.IniGroup -- Wrapper.Group#GROUP
|
|
||||||
local SEADPlanePos = SEADPlane:GetCoordinate() -- Core.Point#COORDINATE
|
|
||||||
local SEADUnit = EventData.IniDCSUnit
|
|
||||||
local SEADUnitName = EventData.IniDCSUnitName
|
|
||||||
local SEADWeapon = EventData.Weapon -- Identify the weapon fired
|
|
||||||
local SEADWeaponName = EventData.WeaponName -- return weapon type
|
|
||||||
|
|
||||||
local WeaponWrapper = WEAPON:New(EventData.Weapon)
|
|
||||||
--local SEADWeaponSpeed = WeaponWrapper:GetSpeed() -- mps
|
|
||||||
|
|
||||||
self:T( "*** SEAD - Missile Launched = " .. SEADWeaponName)
|
local SEADWeapon = EventData.Weapon -- Identify the weapon fired
|
||||||
--self:T({ SEADWeapon })
|
local SEADWeaponName = EventData.WeaponName or "None" -- return weapon type
|
||||||
|
|
||||||
if self:_CheckHarms(SEADWeaponName) then
|
if self:_CheckHarms(SEADWeaponName) then
|
||||||
|
local SEADPlane = EventData.IniUnit -- Wrapper.Unit#UNIT
|
||||||
|
|
||||||
|
if not SEADPlane then return self end -- case IniUnit is empty
|
||||||
|
|
||||||
|
local SEADGroup = EventData.IniGroup -- Wrapper.Group#GROUP
|
||||||
|
local SEADPlanePos = SEADPlane:GetCoordinate() -- Core.Point#COORDINATE
|
||||||
|
local SEADUnit = EventData.IniDCSUnit
|
||||||
|
local SEADUnitName = EventData.IniDCSUnitName
|
||||||
|
|
||||||
|
local WeaponWrapper = WEAPON:New(EventData.Weapon) -- Wrapper.Weapon#WEAPON
|
||||||
|
|
||||||
|
self:T( "*** SEAD - Missile Launched = " .. SEADWeaponName)
|
||||||
|
|
||||||
self:T( '*** SEAD - Weapon Match' )
|
self:T( '*** SEAD - Weapon Match' )
|
||||||
|
if self.WeaponTrack == true then
|
||||||
|
WeaponWrapper:SetFuncTrack(function(weapon) env.info(string.format("*** Weapon Speed: %d m/s",weapon:GetSpeed() or -1)) end)
|
||||||
|
WeaponWrapper:StartTrack(0.1)
|
||||||
|
WeaponWrapper:StopTrack(30)
|
||||||
|
end
|
||||||
local _targetskill = "Random"
|
local _targetskill = "Random"
|
||||||
local _targetgroupname = "none"
|
local _targetgroupname = "none"
|
||||||
local _target = EventData.Weapon:getTarget() -- Identify target
|
local _target = EventData.Weapon:getTarget() -- Identify target
|
||||||
@@ -520,7 +539,7 @@ function SEAD:HandleEventShot( EventData )
|
|||||||
end
|
end
|
||||||
if SEADGroupFound == true then -- yes we are being attacked
|
if SEADGroupFound == true then -- yes we are being attacked
|
||||||
if string.find(SEADWeaponName,"ADM_141",1,true) then
|
if string.find(SEADWeaponName,"ADM_141",1,true) then
|
||||||
self:__ManageEvasion(2,_targetskill,_targetgroup,SEADPlanePos,SEADWeaponName,SEADGroup,0,WeaponWrapper)
|
self:__ManageEvasion(2,_targetskill,_targetgroup,SEADPlanePos,SEADWeaponName,SEADGroup,2,WeaponWrapper)
|
||||||
else
|
else
|
||||||
self:ManageEvasion(_targetskill,_targetgroup,SEADPlanePos,SEADWeaponName,SEADGroup,0,WeaponWrapper)
|
self:ManageEvasion(_targetskill,_targetgroup,SEADPlanePos,SEADWeaponName,SEADGroup,0,WeaponWrapper)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8433,12 +8433,14 @@ function WAREHOUSE:_GetAttribute(group)
|
|||||||
local attribute=WAREHOUSE.Attribute.OTHER_UNKNOWN --#WAREHOUSE.Attribute
|
local attribute=WAREHOUSE.Attribute.OTHER_UNKNOWN --#WAREHOUSE.Attribute
|
||||||
|
|
||||||
if group then
|
if group then
|
||||||
|
|
||||||
|
local groupCat=group:GetCategory()
|
||||||
|
|
||||||
-----------
|
-----------
|
||||||
--- Air ---
|
--- Air ---
|
||||||
-----------
|
-----------
|
||||||
-- Planes
|
-- Planes
|
||||||
local transportplane=group:HasAttribute("Transports") and group:HasAttribute("Planes")
|
local transportplane=group:HasAttribute("Transports") and group:HasAttribute("Planes") and groupCat==Group.Category.AIRPLANE
|
||||||
local awacs=group:HasAttribute("AWACS")
|
local awacs=group:HasAttribute("AWACS")
|
||||||
local fighter=group:HasAttribute("Fighters") or group:HasAttribute("Interceptors") or group:HasAttribute("Multirole fighters") or (group:HasAttribute("Bombers") and not group:HasAttribute("Strategic bombers"))
|
local fighter=group:HasAttribute("Fighters") or group:HasAttribute("Interceptors") or group:HasAttribute("Multirole fighters") or (group:HasAttribute("Bombers") and not group:HasAttribute("Strategic bombers"))
|
||||||
local bomber=group:HasAttribute("Strategic bombers")
|
local bomber=group:HasAttribute("Strategic bombers")
|
||||||
@@ -8593,7 +8595,6 @@ end
|
|||||||
-- @param #WAREHOUSE.Queueitem qitem Item of queue to be removed.
|
-- @param #WAREHOUSE.Queueitem qitem Item of queue to be removed.
|
||||||
-- @param #table queue The queue from which the item should be deleted.
|
-- @param #table queue The queue from which the item should be deleted.
|
||||||
function WAREHOUSE:_DeleteQueueItem(qitem, queue)
|
function WAREHOUSE:_DeleteQueueItem(qitem, queue)
|
||||||
self:F({qitem=qitem, queue=queue})
|
|
||||||
|
|
||||||
for i=1,#queue do
|
for i=1,#queue do
|
||||||
local _item=queue[i] --#WAREHOUSE.Queueitem
|
local _item=queue[i] --#WAREHOUSE.Queueitem
|
||||||
|
|||||||
@@ -291,7 +291,7 @@
|
|||||||
-- ## Nevada: Nellis AFB
|
-- ## Nevada: Nellis AFB
|
||||||
--
|
--
|
||||||
-- -- ATIS Nellis AFB on 270.10 MHz AM.
|
-- -- ATIS Nellis AFB on 270.10 MHz AM.
|
||||||
-- atisNellis=ATIS:New(AIRBASE.Nevada.Nellis_AFB, 270.1)
|
-- atisNellis=ATIS:New(AIRBASE.Nevada.Nellis, 270.1)
|
||||||
-- atisNellis:SetRadioRelayUnitName("Radio Relay Nellis")
|
-- atisNellis:SetRadioRelayUnitName("Radio Relay Nellis")
|
||||||
-- atisNellis:SetActiveRunway("21L")
|
-- atisNellis:SetActiveRunway("21L")
|
||||||
-- atisNellis:SetTowerFrequencies({327.000, 132.550})
|
-- atisNellis:SetTowerFrequencies({327.000, 132.550})
|
||||||
@@ -302,7 +302,7 @@
|
|||||||
-- ## Persian Gulf: Abu Dhabi International Airport
|
-- ## Persian Gulf: Abu Dhabi International Airport
|
||||||
--
|
--
|
||||||
-- -- ATIS Abu Dhabi International on 125.1 MHz AM.
|
-- -- ATIS Abu Dhabi International on 125.1 MHz AM.
|
||||||
-- atisAbuDhabi=ATIS:New(AIRBASE.PersianGulf.Abu_Dhabi_International_Airport, 125.1)
|
-- atisAbuDhabi=ATIS:New(AIRBASE.PersianGulf.Abu_Dhabi_Intl, 125.1)
|
||||||
-- atisAbuDhabi:SetRadioRelayUnitName("Radio Relay Abu Dhabi International Airport")
|
-- atisAbuDhabi:SetRadioRelayUnitName("Radio Relay Abu Dhabi International Airport")
|
||||||
-- atisAbuDhabi:SetMetricUnits()
|
-- atisAbuDhabi:SetMetricUnits()
|
||||||
-- atisAbuDhabi:SetActiveRunway("L")
|
-- atisAbuDhabi:SetActiveRunway("L")
|
||||||
@@ -498,6 +498,9 @@ ATIS.Alphabet = {
|
|||||||
-- @field #number Syria +5° (East).
|
-- @field #number Syria +5° (East).
|
||||||
-- @field #number MarianaIslands +2° (East).
|
-- @field #number MarianaIslands +2° (East).
|
||||||
-- @field #number SinaiMap +5° (East).
|
-- @field #number SinaiMap +5° (East).
|
||||||
|
-- @field #number Kola +15° (East).
|
||||||
|
-- @field #number Afghanistan +3° (East).
|
||||||
|
-- @field #number Iraq +4.4° (East).
|
||||||
ATIS.RunwayM2T = {
|
ATIS.RunwayM2T = {
|
||||||
Caucasus = 0,
|
Caucasus = 0,
|
||||||
Nevada = 12,
|
Nevada = 12,
|
||||||
@@ -508,6 +511,9 @@ ATIS.RunwayM2T = {
|
|||||||
MarianaIslands = 2,
|
MarianaIslands = 2,
|
||||||
Falklands = 12,
|
Falklands = 12,
|
||||||
SinaiMap = 5,
|
SinaiMap = 5,
|
||||||
|
Kola = 15,
|
||||||
|
Afghanistan = 3,
|
||||||
|
Iraq=4.4
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Whether ICAO phraseology is used for ATIS broadcasts.
|
--- Whether ICAO phraseology is used for ATIS broadcasts.
|
||||||
@@ -521,6 +527,9 @@ ATIS.RunwayM2T = {
|
|||||||
-- @field #boolean MarianaIslands true.
|
-- @field #boolean MarianaIslands true.
|
||||||
-- @field #boolean Falklands true.
|
-- @field #boolean Falklands true.
|
||||||
-- @field #boolean SinaiMap true.
|
-- @field #boolean SinaiMap true.
|
||||||
|
-- @field #boolean Kola true.
|
||||||
|
-- @field #boolean Afghanistan true.
|
||||||
|
-- @field #boolean Iraq true.
|
||||||
ATIS.ICAOPhraseology = {
|
ATIS.ICAOPhraseology = {
|
||||||
Caucasus = true,
|
Caucasus = true,
|
||||||
Nevada = false,
|
Nevada = false,
|
||||||
@@ -531,6 +540,9 @@ ATIS.ICAOPhraseology = {
|
|||||||
MarianaIslands = true,
|
MarianaIslands = true,
|
||||||
Falklands = true,
|
Falklands = true,
|
||||||
SinaiMap = true,
|
SinaiMap = true,
|
||||||
|
Kola = true,
|
||||||
|
Afghanistan = true,
|
||||||
|
Iraq = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Nav point data.
|
--- Nav point data.
|
||||||
@@ -619,83 +631,83 @@ ATIS.ICAOPhraseology = {
|
|||||||
-- @field #ATIS.Soundfile TACANChannel
|
-- @field #ATIS.Soundfile TACANChannel
|
||||||
-- @field #ATIS.Soundfile VORFrequency
|
-- @field #ATIS.Soundfile VORFrequency
|
||||||
ATIS.Sound = {
|
ATIS.Sound = {
|
||||||
ActiveRunway = { filename = "ActiveRunway.ogg", duration = 0.99 },
|
ActiveRunway = { filename = "ActiveRunway.ogg", duration = 0.85 },
|
||||||
ActiveRunwayDeparture = { filename = "ActiveRunwayDeparture.ogg", duration = 0.99 },
|
ActiveRunwayDeparture = { filename = "ActiveRunwayDeparture.ogg", duration = 1.50 },
|
||||||
ActiveRunwayArrival = { filename = "ActiveRunwayArrival.ogg", duration = 0.99 },
|
ActiveRunwayArrival = { filename = "ActiveRunwayArrival.ogg", duration = 1.38 },
|
||||||
AdviceOnInitial = { filename = "AdviceOnInitial.ogg", duration = 3.00 },
|
AdviceOnInitial = { filename = "AdviceOnInitial.ogg", duration = 2.98 },
|
||||||
Airport = { filename = "Airport.ogg", duration = 0.66 },
|
Airport = { filename = "Airport.ogg", duration = 0.55 },
|
||||||
Altimeter = { filename = "Altimeter.ogg", duration = 0.68 },
|
Altimeter = { filename = "Altimeter.ogg", duration = 0.91 },
|
||||||
At = { filename = "At.ogg", duration = 0.41 },
|
At = { filename = "At.ogg", duration = 0.32 },
|
||||||
CloudBase = { filename = "CloudBase.ogg", duration = 0.82 },
|
CloudBase = { filename = "CloudBase.ogg", duration = 0.69 },
|
||||||
CloudCeiling = { filename = "CloudCeiling.ogg", duration = 0.61 },
|
CloudCeiling = { filename = "CloudCeiling.ogg", duration = 0.53 },
|
||||||
CloudsBroken = { filename = "CloudsBroken.ogg", duration = 1.07 },
|
CloudsBroken = { filename = "CloudsBroken.ogg", duration = 0.81 },
|
||||||
CloudsFew = { filename = "CloudsFew.ogg", duration = 0.99 },
|
CloudsFew = { filename = "CloudsFew.ogg", duration = 0.74 },
|
||||||
CloudsNo = { filename = "CloudsNo.ogg", duration = 1.01 },
|
CloudsNo = { filename = "CloudsNo.ogg", duration = 0.69},
|
||||||
CloudsNotAvailable = { filename = "CloudsNotAvailable.ogg", duration = 2.35 },
|
CloudsNotAvailable = { filename = "CloudsNotAvailable.ogg", duration = 2.64 },
|
||||||
CloudsOvercast = { filename = "CloudsOvercast.ogg", duration = 0.83 },
|
CloudsOvercast = { filename = "CloudsOvercast.ogg", duration = 0.82 },
|
||||||
CloudsScattered = { filename = "CloudsScattered.ogg", duration = 1.18 },
|
CloudsScattered = { filename = "CloudsScattered.ogg", duration = 0.89 },
|
||||||
Decimal = { filename = "Decimal.ogg", duration = 0.54 },
|
Decimal = { filename = "Decimal.ogg", duration = 0.71 },
|
||||||
DegreesCelsius = { filename = "DegreesCelsius.ogg", duration = 1.27 },
|
DegreesCelsius = { filename = "DegreesCelsius.ogg", duration = 1.08 },
|
||||||
DegreesFahrenheit = { filename = "DegreesFahrenheit.ogg", duration = 1.23 },
|
DegreesFahrenheit = { filename = "DegreesFahrenheit.ogg", duration = 1.07 },
|
||||||
DewPoint = { filename = "DewPoint.ogg", duration = 0.65 },
|
DewPoint = { filename = "DewPoint.ogg", duration = 0.59 },
|
||||||
Dust = { filename = "Dust.ogg", duration = 0.54 },
|
Dust = { filename = "Dust.ogg", duration = 0.37 },
|
||||||
Elevation = { filename = "Elevation.ogg", duration = 0.78 },
|
Elevation = { filename = "Elevation.ogg", duration = 0.92 },
|
||||||
EndOfInformation = { filename = "EndOfInformation.ogg", duration = 1.15 },
|
EndOfInformation = { filename = "EndOfInformation.ogg", duration = 1.24 },
|
||||||
Feet = { filename = "Feet.ogg", duration = 0.45 },
|
Feet = { filename = "Feet.ogg", duration = 0.34 },
|
||||||
Fog = { filename = "Fog.ogg", duration = 0.47 },
|
Fog = { filename = "Fog.ogg", duration = 0.41 },
|
||||||
Gusting = { filename = "Gusting.ogg", duration = 0.55 },
|
Gusting = { filename = "Gusting.ogg", duration = 0.58 },
|
||||||
HectoPascal = { filename = "HectoPascal.ogg", duration = 1.15 },
|
HectoPascal = { filename = "HectoPascal.ogg", duration = 0.92 },
|
||||||
Hundred = { filename = "Hundred.ogg", duration = 0.47 },
|
Hundred = { filename = "Hundred.ogg", duration = 0.53 },
|
||||||
InchesOfMercury = { filename = "InchesOfMercury.ogg", duration = 1.16 },
|
|
||||||
Information = { filename = "Information.ogg", duration = 0.85 },
|
|
||||||
Kilometers = { filename = "Kilometers.ogg", duration = 0.78 },
|
|
||||||
Knots = { filename = "Knots.ogg", duration = 0.59 },
|
|
||||||
Left = { filename = "Left.ogg", duration = 0.54 },
|
|
||||||
MegaHertz = { filename = "MegaHertz.ogg", duration = 0.87 },
|
|
||||||
Meters = { filename = "Meters.ogg", duration = 0.59 },
|
|
||||||
MetersPerSecond = { filename = "MetersPerSecond.ogg", duration = 1.14 },
|
|
||||||
Miles = { filename = "Miles.ogg", duration = 0.60 },
|
|
||||||
MillimetersOfMercury = { filename = "MillimetersOfMercury.ogg", duration = 1.53 },
|
|
||||||
Minus = { filename = "Minus.ogg", duration = 0.64 },
|
|
||||||
N0 = { filename = "N-0.ogg", duration = 0.55 },
|
|
||||||
N1 = { filename = "N-1.ogg", duration = 0.41 },
|
|
||||||
N2 = { filename = "N-2.ogg", duration = 0.37 },
|
|
||||||
N3 = { filename = "N-3.ogg", duration = 0.41 },
|
|
||||||
N4 = { filename = "N-4.ogg", duration = 0.37 },
|
|
||||||
N5 = { filename = "N-5.ogg", duration = 0.43 },
|
|
||||||
N6 = { filename = "N-6.ogg", duration = 0.55 },
|
|
||||||
N7 = { filename = "N-7.ogg", duration = 0.43 },
|
|
||||||
N8 = { filename = "N-8.ogg", duration = 0.38 },
|
|
||||||
N9 = { filename = "N-9.ogg", duration = 0.55 },
|
|
||||||
NauticalMiles = { filename = "NauticalMiles.ogg", duration = 1.04 },
|
|
||||||
None = { filename = "None.ogg", duration = 0.43 },
|
|
||||||
QFE = { filename = "QFE.ogg", duration = 0.63 },
|
|
||||||
QNH = { filename = "QNH.ogg", duration = 0.71 },
|
|
||||||
Rain = { filename = "Rain.ogg", duration = 0.41 },
|
|
||||||
Right = { filename = "Right.ogg", duration = 0.44 },
|
|
||||||
Snow = { filename = "Snow.ogg", duration = 0.48 },
|
|
||||||
SnowStorm = { filename = "SnowStorm.ogg", duration = 0.82 },
|
|
||||||
StatuteMiles = { filename = "StatuteMiles.ogg", duration = 1.15 },
|
|
||||||
SunriseAt = { filename = "SunriseAt.ogg", duration = 0.92 },
|
|
||||||
SunsetAt = { filename = "SunsetAt.ogg", duration = 0.95 },
|
|
||||||
Temperature = { filename = "Temperature.ogg", duration = 0.64 },
|
|
||||||
Thousand = { filename = "Thousand.ogg", duration = 0.55 },
|
|
||||||
ThunderStorm = { filename = "ThunderStorm.ogg", duration = 0.81 },
|
|
||||||
TimeLocal = { filename = "TimeLocal.ogg", duration = 0.90 },
|
|
||||||
TimeZulu = { filename = "TimeZulu.ogg", duration = 0.86 },
|
|
||||||
TowerFrequency = { filename = "TowerFrequency.ogg", duration = 1.19 },
|
|
||||||
Visibilty = { filename = "Visibility.ogg", duration = 0.79 },
|
|
||||||
WeatherPhenomena = { filename = "WeatherPhenomena.ogg", duration = 1.07 },
|
|
||||||
WindFrom = { filename = "WindFrom.ogg", duration = 0.60 },
|
|
||||||
ILSFrequency = { filename = "ILSFrequency.ogg", duration = 1.30 },
|
ILSFrequency = { filename = "ILSFrequency.ogg", duration = 1.30 },
|
||||||
InnerNDBFrequency = { filename = "InnerNDBFrequency.ogg", duration = 1.56 },
|
InchesOfMercury = { filename = "InchesOfMercury.ogg", duration = 1.26 },
|
||||||
OuterNDBFrequency = { filename = "OuterNDBFrequency.ogg", duration = 1.59 },
|
Information = { filename = "Information.ogg", duration = 0.99 },
|
||||||
RunwayLength = { filename = "RunwayLength.ogg", duration = 0.91 },
|
InnerNDBFrequency = { filename = "InnerNDBFrequency.ogg", duration = 1.69 },
|
||||||
VORFrequency = { filename = "VORFrequency.ogg", duration = 1.38 },
|
Kilometers = { filename = "Kilometers.ogg", duration = 0.93 },
|
||||||
TACANChannel = { filename = "TACANChannel.ogg", duration = 0.88 },
|
Knots = { filename = "Knots.ogg", duration = 0.46 },
|
||||||
PRMGChannel = { filename = "PRMGChannel.ogg", duration = 1.18 },
|
Left = { filename = "Left.ogg", duration = 0.41 },
|
||||||
RSBNChannel = { filename = "RSBNChannel.ogg", duration = 1.14 },
|
MegaHertz = { filename = "MegaHertz.ogg", duration = 0.83 },
|
||||||
Zulu = { filename = "Zulu.ogg", duration = 0.62 },
|
Meters = { filename = "Meters.ogg", duration = 0.55 },
|
||||||
|
MetersPerSecond = { filename = "MetersPerSecond.ogg", duration = 1.03 },
|
||||||
|
Miles = { filename = "Miles.ogg", duration = 0.44 },
|
||||||
|
MillimetersOfMercury = { filename = "MillimetersOfMercury.ogg", duration = 1.59 },
|
||||||
|
Minus = { filename = "Minus.ogg", duration = 0.55 },
|
||||||
|
N0 = { filename = "N-0.ogg", duration = 0.52 },
|
||||||
|
N1 = { filename = "N-1.ogg", duration = 0.35 },
|
||||||
|
N2 = { filename = "N-2.ogg", duration = 0.41 },
|
||||||
|
N3 = { filename = "N-3.ogg", duration = 0.34 },
|
||||||
|
N4 = { filename = "N-4.ogg", duration = 0.37 },
|
||||||
|
N5 = { filename = "N-5.ogg", duration = 0.40 },
|
||||||
|
N6 = { filename = "N-6.ogg", duration = 0.46 },
|
||||||
|
N7 = { filename = "N-7.ogg", duration = 0.52 },
|
||||||
|
N8 = { filename = "N-8.ogg", duration = 0.36 },
|
||||||
|
N9 = { filename = "N-9.ogg", duration = 0.51 },
|
||||||
|
NauticalMiles = { filename = "NauticalMiles.ogg", duration = 0.93 },
|
||||||
|
None = { filename = "None.ogg", duration = 0.33 },
|
||||||
|
OuterNDBFrequency = { filename = "OuterNDBFrequency.ogg", duration = 1.70 },
|
||||||
|
PRMGChannel = { filename = "PRMGChannel.ogg", duration = 1.27 },
|
||||||
|
QFE = { filename = "QFE.ogg", duration = 0.90 },
|
||||||
|
QNH = { filename = "QNH.ogg", duration = 0.94 },
|
||||||
|
Rain = { filename = "Rain.ogg", duration = 0.35 },
|
||||||
|
Right = { filename = "Right.ogg", duration = 0.31 },
|
||||||
|
RSBNChannel = { filename = "RSBNChannel.ogg", duration = 1.26 },
|
||||||
|
RunwayLength = { filename = "RunwayLength.ogg", duration = 0.81 },
|
||||||
|
Snow = { filename = "Snow.ogg", duration = 0.40 },
|
||||||
|
SnowStorm = { filename = "SnowStorm.ogg", duration = 0.73 },
|
||||||
|
StatuteMiles = { filename = "StatuteMiles.ogg", duration = 0.90 },
|
||||||
|
SunriseAt = { filename = "SunriseAt.ogg", duration = 0.82 },
|
||||||
|
SunsetAt = { filename = "SunsetAt.ogg", duration = 0.87 },
|
||||||
|
TACANChannel = { filename = "TACANChannel.ogg", duration = 0.81 },
|
||||||
|
Temperature = { filename = "Temperature.ogg", duration = 0.70 },
|
||||||
|
Thousand = { filename = "Thousand.ogg", duration = 0.58 },
|
||||||
|
ThunderStorm = { filename = "ThunderStorm.ogg", duration = 0.79 },
|
||||||
|
TimeLocal = { filename = "TimeLocal.ogg", duration = 0.83 },
|
||||||
|
TimeZulu = { filename = "TimeZulu.ogg", duration = 0.83 },
|
||||||
|
TowerFrequency = { filename = "TowerFrequency.ogg", duration = 1.05 },
|
||||||
|
Visibilty = { filename = "Visibility.ogg", duration = 1.16 },
|
||||||
|
VORFrequency = { filename = "VORFrequency.ogg", duration = 1.28 },
|
||||||
|
WeatherPhenomena = { filename = "WeatherPhenomena.ogg", duration = 1.09 },
|
||||||
|
WindFrom = { filename = "WindFrom.ogg", duration = 0.63 },
|
||||||
|
Zulu = { filename = "Zulu.ogg", duration = 0.51 },
|
||||||
}
|
}
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -954,7 +966,7 @@ _ATIS = {}
|
|||||||
|
|
||||||
--- ATIS class version.
|
--- ATIS class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
ATIS.version = "1.0.0"
|
ATIS.version = "1.0.1"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@@ -2080,34 +2092,32 @@ function ATIS:onafterBroadcast( From, Event, To )
|
|||||||
---------------
|
---------------
|
||||||
|
|
||||||
-- Get mission weather info. Most of this is static.
|
-- Get mission weather info. Most of this is static.
|
||||||
local clouds, visibility, turbulence, fog, dust, static = self:GetMissionWeather()
|
local clouds, visibility, turbulence, dustdens, static = self:GetMissionWeather()
|
||||||
|
|
||||||
-- Check that fog is actually "thick" enough to reach the airport. If an airport is in the mountains, fog might not affect it as it is measured from sea level.
|
local dust=false
|
||||||
if fog and fog.thickness < height + 25 then
|
local fog=false
|
||||||
fog = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Dust only up to 1500 ft = 457 m ASL.
|
|
||||||
if dust and height + 25 > UTILS.FeetToMeters( 1500 ) then
|
|
||||||
dust = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
------------------
|
------------------
|
||||||
--- Visibility ---
|
--- Visibility ---
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
-- Get min visibility.
|
if dustdens then
|
||||||
local visibilitymin = visibility
|
|
||||||
|
-- Dust only up to 1500 ft = 457 m ASL.
|
||||||
if fog then
|
if UTILS.FeetToMeters( 1500 )> height+25 then
|
||||||
if fog.visibility < visibilitymin then
|
dust=true
|
||||||
visibilitymin = fog.visibility
|
visibility=math.min(visibility, dustdens)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
else -- As of DCS 2.9.10.3948 (December 2024), fog and dust are mutually exclusive!
|
||||||
if dust then
|
|
||||||
if dust < visibilitymin then
|
-- Get current fog visibility and thickness
|
||||||
visibilitymin = dust
|
local fvis=world.weather.getFogVisibilityDistance()
|
||||||
|
local fheight=world.weather.getFogThickness()
|
||||||
|
|
||||||
|
if fvis>0 and fheight>height+25 then
|
||||||
|
fog=true
|
||||||
|
visibility=math.min(visibility, fvis)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2115,7 +2125,7 @@ function ATIS:onafterBroadcast( From, Event, To )
|
|||||||
|
|
||||||
if self.metric then
|
if self.metric then
|
||||||
-- Visibility in km.
|
-- Visibility in km.
|
||||||
local reportedviz = UTILS.Round( visibilitymin / 1000 )
|
local reportedviz = UTILS.Round( visibility / 1000 )
|
||||||
-- max reported visibility 9999 m
|
-- max reported visibility 9999 m
|
||||||
if reportedviz > 10 then
|
if reportedviz > 10 then
|
||||||
reportedviz = 10
|
reportedviz = 10
|
||||||
@@ -2123,7 +2133,7 @@ function ATIS:onafterBroadcast( From, Event, To )
|
|||||||
VISIBILITY = string.format( "%d", reportedviz )
|
VISIBILITY = string.format( "%d", reportedviz )
|
||||||
else
|
else
|
||||||
-- max reported visibility 10 NM
|
-- max reported visibility 10 NM
|
||||||
local reportedviz = UTILS.Round( UTILS.MetersToSM( visibilitymin ) )
|
local reportedviz = UTILS.Round( UTILS.MetersToSM( visibility ) )
|
||||||
if reportedviz > 10 then
|
if reportedviz > 10 then
|
||||||
reportedviz = 10
|
reportedviz = 10
|
||||||
end
|
end
|
||||||
@@ -3350,28 +3360,13 @@ function ATIS:GetMissionWeather()
|
|||||||
dust = weather.dust_density
|
dust = weather.dust_density
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Fog
|
|
||||||
--[[
|
|
||||||
["enable_fog"] = false,
|
|
||||||
["fog"] =
|
|
||||||
{
|
|
||||||
["thickness"] = 0,
|
|
||||||
["visibility"] = 25,
|
|
||||||
}, -- end of ["fog"]
|
|
||||||
]]
|
|
||||||
local fog = nil
|
|
||||||
if weather.enable_fog == true then
|
|
||||||
fog = weather.fog
|
|
||||||
end
|
|
||||||
|
|
||||||
self:T( "FF weather:" )
|
self:T( "FF weather:" )
|
||||||
self:T( { clouds = clouds } )
|
self:T( { clouds = clouds } )
|
||||||
self:T( { visibility = visibility } )
|
self:T( { visibility = visibility } )
|
||||||
self:T( { turbulence = turbulence } )
|
self:T( { turbulence = turbulence } )
|
||||||
self:T( { fog = fog } )
|
|
||||||
self:T( { dust = dust } )
|
self:T( { dust = dust } )
|
||||||
self:T( { static = static } )
|
self:T( { static = static } )
|
||||||
return clouds, visibility, turbulence, fog, dust, static
|
return clouds, visibility, turbulence, dust, static
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get thousands of a number.
|
--- Get thousands of a number.
|
||||||
|
|||||||
@@ -3614,7 +3614,7 @@ function AIRBOSS:onafterStart( From, Event, To )
|
|||||||
|
|
||||||
-- Handle events.
|
-- Handle events.
|
||||||
self:HandleEvent( EVENTS.Birth )
|
self:HandleEvent( EVENTS.Birth )
|
||||||
self:HandleEvent( EVENTS.Land )
|
self:HandleEvent( EVENTS.RunwayTouch )
|
||||||
self:HandleEvent( EVENTS.EngineShutdown )
|
self:HandleEvent( EVENTS.EngineShutdown )
|
||||||
self:HandleEvent( EVENTS.Takeoff )
|
self:HandleEvent( EVENTS.Takeoff )
|
||||||
self:HandleEvent( EVENTS.Crash )
|
self:HandleEvent( EVENTS.Crash )
|
||||||
@@ -4379,7 +4379,7 @@ function AIRBOSS:onafterStop( From, Event, To )
|
|||||||
|
|
||||||
-- Unhandle events.
|
-- Unhandle events.
|
||||||
self:UnHandleEvent( EVENTS.Birth )
|
self:UnHandleEvent( EVENTS.Birth )
|
||||||
self:UnHandleEvent( EVENTS.Land )
|
self:UnHandleEvent( EVENTS.RunwayTouch )
|
||||||
self:UnHandleEvent( EVENTS.EngineShutdown )
|
self:UnHandleEvent( EVENTS.EngineShutdown )
|
||||||
self:UnHandleEvent( EVENTS.Takeoff )
|
self:UnHandleEvent( EVENTS.Takeoff )
|
||||||
self:UnHandleEvent( EVENTS.Crash )
|
self:UnHandleEvent( EVENTS.Crash )
|
||||||
@@ -8289,7 +8289,7 @@ end
|
|||||||
--- Airboss event handler for event land.
|
--- Airboss event handler for event land.
|
||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
function AIRBOSS:OnEventLand( EventData )
|
function AIRBOSS:OnEventRunwayTouch( EventData )
|
||||||
self:F3( { eventland = EventData } )
|
self:F3( { eventland = EventData } )
|
||||||
|
|
||||||
-- Nil checks.
|
-- Nil checks.
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ CSAR.AircraftType["AH-64D_BLK_II"] = 2
|
|||||||
CSAR.AircraftType["Bronco-OV-10A"] = 2
|
CSAR.AircraftType["Bronco-OV-10A"] = 2
|
||||||
CSAR.AircraftType["MH-60R"] = 10
|
CSAR.AircraftType["MH-60R"] = 10
|
||||||
CSAR.AircraftType["OH-6A"] = 2
|
CSAR.AircraftType["OH-6A"] = 2
|
||||||
CSAR.AircraftType["OH-58D"] = 2
|
CSAR.AircraftType["OH58D"] = 2
|
||||||
CSAR.AircraftType["CH-47Fbl1"] = 31
|
CSAR.AircraftType["CH-47Fbl1"] = 31
|
||||||
|
|
||||||
--- CSAR class version.
|
--- CSAR class version.
|
||||||
@@ -841,9 +841,9 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla
|
|||||||
local BeaconName
|
local BeaconName
|
||||||
|
|
||||||
if _playerName then
|
if _playerName then
|
||||||
BeaconName = _unitName..math.random(1,10000)
|
|
||||||
elseif _unitName then
|
|
||||||
BeaconName = _playerName..math.random(1,10000)
|
BeaconName = _playerName..math.random(1,10000)
|
||||||
|
elseif _unitName then
|
||||||
|
BeaconName = _unitName..math.random(1,10000)
|
||||||
else
|
else
|
||||||
BeaconName = "Ghost-1-1"..math.random(1,10000)
|
BeaconName = "Ghost-1-1"..math.random(1,10000)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
-- @module Ops.CTLD
|
-- @module Ops.CTLD
|
||||||
-- @image OPS_CTLD.jpg
|
-- @image OPS_CTLD.jpg
|
||||||
|
|
||||||
-- Last Update Sep 2024
|
-- Last Update Dec 2024
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -836,6 +836,9 @@ do
|
|||||||
-- my_ctld.enableChinookGCLoading = true -- this will effectively suppress the crate load and drop for CTLD_CARGO.Enum.STATIc types for CTLD for the Chinook
|
-- my_ctld.enableChinookGCLoading = true -- this will effectively suppress the crate load and drop for CTLD_CARGO.Enum.STATIc types for CTLD for the Chinook
|
||||||
-- my_ctld.TroopUnloadDistGround = 5 -- If hovering, spawn dropped troops this far away in meters from the helo
|
-- my_ctld.TroopUnloadDistGround = 5 -- If hovering, spawn dropped troops this far away in meters from the helo
|
||||||
-- my_ctld.TroopUnloadDistHover = 1.5 -- If grounded, spawn dropped troops this far away in meters from the helo
|
-- my_ctld.TroopUnloadDistHover = 1.5 -- If grounded, spawn dropped troops this far away in meters from the helo
|
||||||
|
-- my_ctld.TroopUnloadDistGroundHerc = 25 -- On the ground, unload troops this far behind the Hercules
|
||||||
|
-- my_ctld.TroopUnloadDistGroundHook = 15 -- On the ground, unload troops this far behind the Chinook
|
||||||
|
-- my_ctld.TroopUnloadDistHoverHook = 5 -- When hovering, unload troops this far behind the Chinook
|
||||||
--
|
--
|
||||||
-- ## 2.1 CH-47 Chinook support
|
-- ## 2.1 CH-47 Chinook support
|
||||||
--
|
--
|
||||||
@@ -895,7 +898,7 @@ do
|
|||||||
-- ["Bronco-OV-10A"] = {type="Bronco-OV-10A", crates= false, troops=true, cratelimit = 0, trooplimit = 5, length = 13, cargoweightlimit = 1450},
|
-- ["Bronco-OV-10A"] = {type="Bronco-OV-10A", crates= false, troops=true, cratelimit = 0, trooplimit = 5, length = 13, cargoweightlimit = 1450},
|
||||||
-- ["Bronco-OV-10A"] = {type="Bronco-OV-10A", crates= false, troops=true, cratelimit = 0, trooplimit = 5, length = 13, cargoweightlimit = 1450},
|
-- ["Bronco-OV-10A"] = {type="Bronco-OV-10A", crates= false, troops=true, cratelimit = 0, trooplimit = 5, length = 13, cargoweightlimit = 1450},
|
||||||
-- ["OH-6A"] = {type="OH-6A", crates=false, troops=true, cratelimit = 0, trooplimit = 4, length = 7, cargoweightlimit = 550},
|
-- ["OH-6A"] = {type="OH-6A", crates=false, troops=true, cratelimit = 0, trooplimit = 4, length = 7, cargoweightlimit = 550},
|
||||||
-- ["OH-58D"] = {type="OH58D", crates=false, troops=false, cratelimit = 0, trooplimit = 0, length = 14, cargoweightlimit = 400},
|
-- ["OH58D"] = {type="OH58D", crates=false, troops=false, cratelimit = 0, trooplimit = 0, length = 14, cargoweightlimit = 400},
|
||||||
-- ["CH-47Fbl1"] = {type="CH-47Fbl1", crates=true, troops=true, cratelimit = 4, trooplimit = 31, length = 20, cargoweightlimit = 8000},
|
-- ["CH-47Fbl1"] = {type="CH-47Fbl1", crates=true, troops=true, cratelimit = 4, trooplimit = 31, length = 20, cargoweightlimit = 8000},
|
||||||
--
|
--
|
||||||
-- ### 2.2.2 Activate and deactivate zones
|
-- ### 2.2.2 Activate and deactivate zones
|
||||||
@@ -1233,6 +1236,9 @@ CTLD = {
|
|||||||
DynamicCargo = {},
|
DynamicCargo = {},
|
||||||
ChinookTroopCircleRadius = 5,
|
ChinookTroopCircleRadius = 5,
|
||||||
TroopUnloadDistGround = 5,
|
TroopUnloadDistGround = 5,
|
||||||
|
TroopUnloadDistGroundHerc = 25,
|
||||||
|
TroopUnloadDistGroundHook = 15,
|
||||||
|
TroopUnloadDistHoverHook = 5,
|
||||||
TroopUnloadDistHover = 1.5,
|
TroopUnloadDistHover = 1.5,
|
||||||
UserSetGroup = nil,
|
UserSetGroup = nil,
|
||||||
}
|
}
|
||||||
@@ -1272,6 +1278,12 @@ CTLD.RadioModulation = {
|
|||||||
FM = 1,
|
FM = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- Loaded Cargo
|
||||||
|
-- @type CTLD.LoadedCargo
|
||||||
|
-- @field #number Troopsloaded
|
||||||
|
-- @field #number Cratesloaded
|
||||||
|
-- @field #table Cargo Table of #CTLD_CARGO objects
|
||||||
|
|
||||||
--- Zone Info.
|
--- Zone Info.
|
||||||
-- @type CTLD.CargoZone
|
-- @type CTLD.CargoZone
|
||||||
-- @field #string name Name of Zone.
|
-- @field #string name Name of Zone.
|
||||||
@@ -1333,13 +1345,13 @@ CTLD.UnitTypeCapabilities = {
|
|||||||
["AH-64D_BLK_II"] = {type="AH-64D_BLK_II", crates=false, troops=true, cratelimit = 0, trooplimit = 2, length = 17, cargoweightlimit = 200}, -- 2 ppl **outside** the helo
|
["AH-64D_BLK_II"] = {type="AH-64D_BLK_II", crates=false, troops=true, cratelimit = 0, trooplimit = 2, length = 17, cargoweightlimit = 200}, -- 2 ppl **outside** the helo
|
||||||
["Bronco-OV-10A"] = {type="Bronco-OV-10A", crates= false, troops=true, cratelimit = 0, trooplimit = 5, length = 13, cargoweightlimit = 1450},
|
["Bronco-OV-10A"] = {type="Bronco-OV-10A", crates= false, troops=true, cratelimit = 0, trooplimit = 5, length = 13, cargoweightlimit = 1450},
|
||||||
["OH-6A"] = {type="OH-6A", crates=false, troops=true, cratelimit = 0, trooplimit = 4, length = 7, cargoweightlimit = 550},
|
["OH-6A"] = {type="OH-6A", crates=false, troops=true, cratelimit = 0, trooplimit = 4, length = 7, cargoweightlimit = 550},
|
||||||
["OH-58D"] = {type="OH58D", crates=false, troops=false, cratelimit = 0, trooplimit = 0, length = 14, cargoweightlimit = 400},
|
["OH58D"] = {type="OH58D", crates=false, troops=false, cratelimit = 0, trooplimit = 0, length = 14, cargoweightlimit = 400},
|
||||||
["CH-47Fbl1"] = {type="CH-47Fbl1", crates=true, troops=true, cratelimit = 4, trooplimit = 31, length = 20, cargoweightlimit = 10800},
|
["CH-47Fbl1"] = {type="CH-47Fbl1", crates=true, troops=true, cratelimit = 4, trooplimit = 31, length = 20, cargoweightlimit = 10800},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- CTLD class version.
|
--- CTLD class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CTLD.version="1.1.16"
|
CTLD.version="1.1.20"
|
||||||
|
|
||||||
--- Instantiate a new CTLD.
|
--- Instantiate a new CTLD.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
@@ -2425,6 +2437,7 @@ end
|
|||||||
local nearestGroup = nil
|
local nearestGroup = nil
|
||||||
local nearestGroupIndex = -1
|
local nearestGroupIndex = -1
|
||||||
local nearestDistance = 10000000
|
local nearestDistance = 10000000
|
||||||
|
local maxdistance = 0
|
||||||
local nearestList = {}
|
local nearestList = {}
|
||||||
local distancekeys = {}
|
local distancekeys = {}
|
||||||
local extractdistance = self.CrateDistance * self.ExtractFactor
|
local extractdistance = self.CrateDistance * self.ExtractFactor
|
||||||
@@ -2436,8 +2449,14 @@ end
|
|||||||
nearestGroup = v
|
nearestGroup = v
|
||||||
nearestGroupIndex = k
|
nearestGroupIndex = k
|
||||||
nearestDistance = distance
|
nearestDistance = distance
|
||||||
|
if math.floor(distance) > maxdistance then maxdistance = math.floor(distance) end
|
||||||
|
if nearestList[math.floor(distance)] then
|
||||||
|
distance = maxdistance+1
|
||||||
|
maxdistance = distance
|
||||||
|
end
|
||||||
table.insert(nearestList, math.floor(distance), v)
|
table.insert(nearestList, math.floor(distance), v)
|
||||||
distancekeys[#distancekeys+1] = math.floor(distance)
|
distancekeys[#distancekeys+1] = math.floor(distance)
|
||||||
|
--self:I(string.format("Adding group %s distance %dm",nearestGroup:GetName(),distance))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2490,7 +2509,7 @@ end
|
|||||||
nearestGroup.ExtractTime = timer.getTime()
|
nearestGroup.ExtractTime = timer.getTime()
|
||||||
local loadcargotype = CTLD_CARGO:New(self.CargoCounter, Cargotype.Name, Cargotype.Templates, Cargotype.CargoType, true, true, Cargotype.CratesNeeded,nil,nil,Cargotype.PerCrateMass)
|
local loadcargotype = CTLD_CARGO:New(self.CargoCounter, Cargotype.Name, Cargotype.Templates, Cargotype.CargoType, true, true, Cargotype.CratesNeeded,nil,nil,Cargotype.PerCrateMass)
|
||||||
self:T({cargotype=loadcargotype})
|
self:T({cargotype=loadcargotype})
|
||||||
local running = math.floor(nearestDistance / 4)+10 -- time run to helo plus boarding
|
local running = math.floor(nearestDistance / 4)+20 -- time run to helo plus boarding
|
||||||
loaded.Troopsloaded = loaded.Troopsloaded + troopsize
|
loaded.Troopsloaded = loaded.Troopsloaded + troopsize
|
||||||
table.insert(loaded.Cargo,loadcargotype)
|
table.insert(loaded.Cargo,loadcargotype)
|
||||||
self.Loaded_Cargo[unitname] = loaded
|
self.Loaded_Cargo[unitname] = loaded
|
||||||
@@ -2505,26 +2524,32 @@ end
|
|||||||
local Angle = math.floor((heading+160)%360)
|
local Angle = math.floor((heading+160)%360)
|
||||||
Point = coord:Translate(8,Angle):GetVec2()
|
Point = coord:Translate(8,Angle):GetVec2()
|
||||||
if Point then
|
if Point then
|
||||||
nearestGroup:RouteToVec2(Point,4)
|
nearestGroup:RouteToVec2(Point,5)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- clean up:
|
-- clean up:
|
||||||
if type(Cargotype.Templates) == "table" and Cargotype.Templates[2] then
|
local hassecondaries = false
|
||||||
|
if type(Cargotype.Templates) == "table" and Cargotype.Templates[2] then
|
||||||
for _,_key in pairs (Cargotype.Templates) do
|
for _,_key in pairs (Cargotype.Templates) do
|
||||||
table.insert(secondarygroups,_key)
|
table.insert(secondarygroups,_key)
|
||||||
|
hassecondaries = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
nearestGroup:Destroy(false,running)
|
local destroytimer = math.random(10,20)
|
||||||
|
--self:I("Destroying Group "..nearestGroup:GetName().." in "..destroytimer.." seconds!")
|
||||||
|
nearestGroup:Destroy(false,destroytimer)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- clean up secondary groups
|
-- clean up secondary groups
|
||||||
for _,_name in pairs(secondarygroups) do
|
if hassecondaries == true then
|
||||||
for _,_group in pairs(nearestList) do
|
for _,_name in pairs(secondarygroups) do
|
||||||
if _group and _group:IsAlive() then
|
for _,_group in pairs(nearestList) do
|
||||||
local groupname = string.match(_group:GetName(), "(.+)-(.+)$")
|
if _group and _group:IsAlive() then
|
||||||
if _name == groupname then
|
local groupname = string.match(_group:GetName(), "(.+)-(.+)$")
|
||||||
_group:Destroy(false,15)
|
if _name == groupname then
|
||||||
|
_group:Destroy(false,15)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -3408,8 +3433,8 @@ function CTLD:_GetUnitPositions(Coordinate,Radius,Heading,Template)
|
|||||||
local template = _DATABASE:GetGroupTemplate(Template)
|
local template = _DATABASE:GetGroupTemplate(Template)
|
||||||
--UTILS.PrintTableToLog(template)
|
--UTILS.PrintTableToLog(template)
|
||||||
local numbertroops = #template.units
|
local numbertroops = #template.units
|
||||||
local slightshift = math.abs(math.random(0,200)/100)
|
local slightshift = math.abs(math.random(1,500)/100)
|
||||||
local newcenter = Coordinate:Translate(Radius+slightshift,((Heading+270)%360))
|
local newcenter = Coordinate:Translate(Radius+slightshift,((Heading+270+math.random(1,10))%360))
|
||||||
for i=1,360,math.floor(360/numbertroops) do
|
for i=1,360,math.floor(360/numbertroops) do
|
||||||
local phead = ((Heading+270+i)%360)
|
local phead = ((Heading+270+i)%360)
|
||||||
local post = newcenter:Translate(Radius,phead)
|
local post = newcenter:Translate(Radius,phead)
|
||||||
@@ -3484,7 +3509,15 @@ function CTLD:_UnloadTroops(Group, Unit)
|
|||||||
randomcoord = Group:GetCoordinate()
|
randomcoord = Group:GetCoordinate()
|
||||||
-- slightly left from us
|
-- slightly left from us
|
||||||
local Angle = (heading+270)%360
|
local Angle = (heading+270)%360
|
||||||
|
if IsHerc or IsHook then Angle = (heading+180)%360 end
|
||||||
local offset = hoverunload and self.TroopUnloadDistHover or self.TroopUnloadDistGround
|
local offset = hoverunload and self.TroopUnloadDistHover or self.TroopUnloadDistGround
|
||||||
|
if IsHerc then offset = self.TroopUnloadDistGroundHerc or 25 end
|
||||||
|
if IsHook then
|
||||||
|
offset = self.TroopUnloadDistGroundHook or 15
|
||||||
|
if self.TroopUnloadDistHoverHook then
|
||||||
|
offset = self.TroopUnloadDistHoverHook or 5
|
||||||
|
end
|
||||||
|
end
|
||||||
randomcoord:Translate(offset,Angle,nil,true)
|
randomcoord:Translate(offset,Angle,nil,true)
|
||||||
end
|
end
|
||||||
local tempcount = 0
|
local tempcount = 0
|
||||||
@@ -3494,7 +3527,7 @@ function CTLD:_UnloadTroops(Group, Unit)
|
|||||||
self.TroopCounter = self.TroopCounter + 1
|
self.TroopCounter = self.TroopCounter + 1
|
||||||
tempcount = tempcount+1
|
tempcount = tempcount+1
|
||||||
local alias = string.format("%s-%d", _template, math.random(1,100000))
|
local alias = string.format("%s-%d", _template, math.random(1,100000))
|
||||||
local rad = 2.5+tempcount
|
local rad = 2.5+(tempcount*2)
|
||||||
local Positions = self:_GetUnitPositions(randomcoord,rad,heading,_template)
|
local Positions = self:_GetUnitPositions(randomcoord,rad,heading,_template)
|
||||||
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
|
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
|
||||||
--:InitRandomizeUnits(true,20,2)
|
--:InitRandomizeUnits(true,20,2)
|
||||||
@@ -4269,7 +4302,7 @@ end
|
|||||||
-- @param #string SubCategory Name of sub-category (optional).
|
-- @param #string SubCategory Name of sub-category (optional).
|
||||||
-- @param #boolean DontShowInMenu (optional) If set to "true" this won't show up in the menu.
|
-- @param #boolean DontShowInMenu (optional) If set to "true" this won't show up in the menu.
|
||||||
-- @param Core.Zone#ZONE Location (optional) If set, the cargo item is **only** available here. Can be a #ZONE object or the name of a zone as #string.
|
-- @param Core.Zone#ZONE Location (optional) If set, the cargo item is **only** available here. Can be a #ZONE object or the name of a zone as #string.
|
||||||
-- @param #string UnitTypes Unit type names (optional). If set, only these unit types can pick up the cargo, e.g. "UH-1H" or {"UH-1H","OH-58D"}.
|
-- @param #string UnitTypes Unit type names (optional). If set, only these unit types can pick up the cargo, e.g. "UH-1H" or {"UH-1H","OH58D"}.
|
||||||
-- @param #string Category Static category name (optional). If set, spawn cargo crate with an alternate category type, e.g. "Cargos".
|
-- @param #string Category Static category name (optional). If set, spawn cargo crate with an alternate category type, e.g. "Cargos".
|
||||||
-- @param #string TypeName Static type name (optional). If set, spawn cargo crate with an alternate type shape, e.g. "iso_container".
|
-- @param #string TypeName Static type name (optional). If set, spawn cargo crate with an alternate type shape, e.g. "iso_container".
|
||||||
-- @param #string ShapeName Static shape name (optional). If set, spawn cargo crate with an alternate type sub-shape, e.g. "iso_container_cargo".
|
-- @param #string ShapeName Static shape name (optional). If set, spawn cargo crate with an alternate type sub-shape, e.g. "iso_container_cargo".
|
||||||
@@ -4353,7 +4386,7 @@ end
|
|||||||
-- @param #string SubCategory Name of the sub-category (optional).
|
-- @param #string SubCategory Name of the sub-category (optional).
|
||||||
-- @param #boolean DontShowInMenu (optional) If set to "true" this won't show up in the menu.
|
-- @param #boolean DontShowInMenu (optional) If set to "true" this won't show up in the menu.
|
||||||
-- @param Core.Zone#ZONE Location (optional) If set, the cargo item is **only** available here. Can be a #ZONE object or the name of a zone as #string.
|
-- @param Core.Zone#ZONE Location (optional) If set, the cargo item is **only** available here. Can be a #ZONE object or the name of a zone as #string.
|
||||||
-- @param #string UnitTypes Unit type names (optional). If set, only these unit types can pick up the cargo, e.g. "UH-1H" or {"UH-1H","OH-58D"}
|
-- @param #string UnitTypes Unit type names (optional). If set, only these unit types can pick up the cargo, e.g. "UH-1H" or {"UH-1H","OH58D"}
|
||||||
-- @param #string Category Static category name (optional). If set, spawn cargo crate with an alternate category type, e.g. "Cargos".
|
-- @param #string Category Static category name (optional). If set, spawn cargo crate with an alternate category type, e.g. "Cargos".
|
||||||
-- @param #string TypeName Static type name (optional). If set, spawn cargo crate with an alternate type shape, e.g. "iso_container".
|
-- @param #string TypeName Static type name (optional). If set, spawn cargo crate with an alternate type shape, e.g. "iso_container".
|
||||||
-- @param #string ShapeName Static shape name (optional). If set, spawn cargo crate with an alternate type sub-shape, e.g. "iso_container_cargo".
|
-- @param #string ShapeName Static shape name (optional). If set, spawn cargo crate with an alternate type sub-shape, e.g. "iso_container_cargo".
|
||||||
@@ -5356,6 +5389,27 @@ end
|
|||||||
return Stock
|
return Stock
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- User - Query the cargo loaded from a specific unit
|
||||||
|
-- @param #CTLD self
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit The (client) unit to query.
|
||||||
|
-- @return #number Troopsloaded
|
||||||
|
-- @return #number Cratesloaded
|
||||||
|
-- @return #table Cargo Table of #CTLD_CARGO objects
|
||||||
|
function CTLD:GetLoadedCargo(Unit)
|
||||||
|
local Troops = 0
|
||||||
|
local Crates = 0
|
||||||
|
local Cargo = {}
|
||||||
|
if Unit and Unit:IsAlive() then
|
||||||
|
local name = Unit:GetName()
|
||||||
|
if self.Loaded_Cargo[name] then
|
||||||
|
Troops = self.Loaded_Cargo[name].Troopsloaded or 0
|
||||||
|
Crates = self.Loaded_Cargo[name].Cratesloaded or 0
|
||||||
|
Cargo = self.Loaded_Cargo[name].Cargo or {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Troops, Crates, Cargo
|
||||||
|
end
|
||||||
|
|
||||||
--- User - function to get a table of statics cargo in stock
|
--- User - function to get a table of statics cargo in stock
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
-- @return #table Table Table of Stock, indexed by cargo type name
|
-- @return #table Table Table of Stock, indexed by cargo type name
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
-- @field #table poptions Provider options. Each element is a data structure of type `MSRS.ProvierOptions`.
|
-- @field #table poptions Provider options. Each element is a data structure of type `MSRS.ProvierOptions`.
|
||||||
-- @field #string provider Provider of TTS (win, gcloud, azure, amazon).
|
-- @field #string provider Provider of TTS (win, gcloud, azure, amazon).
|
||||||
-- @field #string backend Backend used as interface to SRS (MSRS.Backend.SRSEXE or MSRS.Backend.GRPC).
|
-- @field #string backend Backend used as interface to SRS (MSRS.Backend.SRSEXE or MSRS.Backend.GRPC).
|
||||||
|
-- @field #boolean UsePowerShell Use PowerShell to execute the command and not cmd.exe
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
--- *It is a very sad thing that nowadays there is so little useless information.* - Oscar Wilde
|
--- *It is a very sad thing that nowadays there is so little useless information.* - Oscar Wilde
|
||||||
@@ -256,11 +257,12 @@ MSRS = {
|
|||||||
ConfigFilePath = "Config\\",
|
ConfigFilePath = "Config\\",
|
||||||
ConfigLoaded = false,
|
ConfigLoaded = false,
|
||||||
poptions = {},
|
poptions = {},
|
||||||
|
UsePowerShell = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- MSRS class version.
|
--- MSRS class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
MSRS.version="0.3.0"
|
MSRS.version="0.3.3"
|
||||||
|
|
||||||
--- Voices
|
--- Voices
|
||||||
-- @type MSRS.Voices
|
-- @type MSRS.Voices
|
||||||
@@ -588,7 +590,7 @@ function MSRS:SetBackendSRSEXE()
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Set the default backend.
|
--- Set the default backend.
|
||||||
-- @param #MSRS self
|
-- @param #string Backend
|
||||||
function MSRS.SetDefaultBackend(Backend)
|
function MSRS.SetDefaultBackend(Backend)
|
||||||
MSRS.backend=Backend or MSRS.Backend.SRSEXE
|
MSRS.backend=Backend or MSRS.Backend.SRSEXE
|
||||||
end
|
end
|
||||||
@@ -1375,20 +1377,25 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp
|
|||||||
modus=modus:gsub("1", "FM")
|
modus=modus:gsub("1", "FM")
|
||||||
|
|
||||||
-- Command.
|
-- Command.
|
||||||
|
local pwsh = string.format('Start-Process -WindowStyle Hidden -WorkingDirectory \"%s\" -FilePath \"%s\" -ArgumentList \'-f "%s" -m "%s" -c %s -p %s -n "%s" -v "%.1f"', path, exe, freqs, modus, coal, port, label,volume )
|
||||||
|
|
||||||
local command=string.format('"%s\\%s" -f "%s" -m "%s" -c %s -p %s -n "%s" -v "%.1f"', path, exe, freqs, modus, coal, port, label,volume)
|
local command=string.format('"%s\\%s" -f "%s" -m "%s" -c %s -p %s -n "%s" -v "%.1f"', path, exe, freqs, modus, coal, port, label,volume)
|
||||||
|
|
||||||
-- Set voice or gender/culture.
|
-- Set voice or gender/culture.
|
||||||
if voice then
|
if voice and self.UsePowerShell ~= true then
|
||||||
-- Use a specific voice (no need for gender and/or culture.
|
-- Use a specific voice (no need for gender and/or culture.
|
||||||
command=command..string.format(" --voice=\"%s\"", tostring(voice))
|
command=command..string.format(" --voice=\"%s\"", tostring(voice))
|
||||||
|
pwsh=pwsh..string.format(" --voice=\"%s\"", tostring(voice))
|
||||||
else
|
else
|
||||||
-- Add gender.
|
-- Add gender.
|
||||||
if gender and gender~="female" then
|
if gender and gender~="female" then
|
||||||
command=command..string.format(" -g %s", tostring(gender))
|
command=command..string.format(" -g %s", tostring(gender))
|
||||||
|
pwsh=pwsh..string.format(" -g %s", tostring(gender))
|
||||||
end
|
end
|
||||||
-- Add culture.
|
-- Add culture.
|
||||||
if culture and culture~="en-GB" then
|
if culture and culture~="en-GB" then
|
||||||
command=command..string.format(" -l %s", tostring(culture))
|
command=command..string.format(" -l %s", tostring(culture))
|
||||||
|
pwsh=pwsh..string.format(" -l %s", tostring(culture))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1396,12 +1403,14 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp
|
|||||||
if coordinate then
|
if coordinate then
|
||||||
local lat,lon,alt=self:_GetLatLongAlt(coordinate)
|
local lat,lon,alt=self:_GetLatLongAlt(coordinate)
|
||||||
command=command..string.format(" -L %.4f -O %.4f -A %d", lat, lon, alt)
|
command=command..string.format(" -L %.4f -O %.4f -A %d", lat, lon, alt)
|
||||||
|
pwsh=pwsh..string.format(" -L %.4f -O %.4f -A %d", lat, lon, alt)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set provider options
|
-- Set provider options
|
||||||
if self.provider==MSRS.Provider.GOOGLE then
|
if self.provider==MSRS.Provider.GOOGLE then
|
||||||
local pops=self:GetProviderOptions()
|
local pops=self:GetProviderOptions()
|
||||||
command=command..string.format(' --ssml -G "%s"', pops.credentials)
|
command=command..string.format(' --ssml -G "%s"', pops.credentials)
|
||||||
|
pwsh=pwsh..string.format(' --ssml -G "%s"', pops.credentials)
|
||||||
elseif self.provider==MSRS.Provider.WINDOWS then
|
elseif self.provider==MSRS.Provider.WINDOWS then
|
||||||
-- Nothing to do.
|
-- Nothing to do.
|
||||||
else
|
else
|
||||||
@@ -1415,8 +1424,12 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp
|
|||||||
|
|
||||||
-- Debug output.
|
-- Debug output.
|
||||||
self:T("MSRS command from _GetCommand="..command)
|
self:T("MSRS command from _GetCommand="..command)
|
||||||
|
|
||||||
return command
|
if self.UsePowerShell == true then
|
||||||
|
return pwsh
|
||||||
|
else
|
||||||
|
return command
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Execute SRS command to play sound using the `DCS-SR-ExternalAudio.exe`.
|
--- Execute SRS command to play sound using the `DCS-SR-ExternalAudio.exe`.
|
||||||
@@ -1424,7 +1437,7 @@ end
|
|||||||
-- @param #string command Command to executer
|
-- @param #string command Command to executer
|
||||||
-- @return #number Return value of os.execute() command.
|
-- @return #number Return value of os.execute() command.
|
||||||
function MSRS:_ExecCommand(command)
|
function MSRS:_ExecCommand(command)
|
||||||
self:F( {command=command} )
|
self:T2( {command=command} )
|
||||||
|
|
||||||
-- Skip this function if _GetCommand was not able to find the executable
|
-- Skip this function if _GetCommand was not able to find the executable
|
||||||
if string.find(command, "CommandNotFound") then return 0 end
|
if string.find(command, "CommandNotFound") then return 0 end
|
||||||
@@ -1432,7 +1445,13 @@ function MSRS:_ExecCommand(command)
|
|||||||
local batContent = command.." && exit"
|
local batContent = command.." && exit"
|
||||||
-- Create a tmp file.
|
-- Create a tmp file.
|
||||||
local filename=os.getenv('TMP').."\\MSRS-"..MSRS.uuid()..".bat"
|
local filename=os.getenv('TMP').."\\MSRS-"..MSRS.uuid()..".bat"
|
||||||
|
|
||||||
|
if self.UsePowerShell == true then
|
||||||
|
filename=os.getenv('TMP').."\\MSRS-"..MSRS.uuid()..".ps1"
|
||||||
|
batContent = command .. "\'"
|
||||||
|
self:I({batContent=batContent})
|
||||||
|
end
|
||||||
|
|
||||||
local script=io.open(filename, "w+")
|
local script=io.open(filename, "w+")
|
||||||
script:write(batContent)
|
script:write(batContent)
|
||||||
script:close()
|
script:close()
|
||||||
@@ -1441,7 +1460,7 @@ function MSRS:_ExecCommand(command)
|
|||||||
self:T("MSRS batch content: "..batContent)
|
self:T("MSRS batch content: "..batContent)
|
||||||
|
|
||||||
local res=nil
|
local res=nil
|
||||||
if true then
|
if self.UsePowerShell ~= true then
|
||||||
|
|
||||||
-- Create a tmp file.
|
-- Create a tmp file.
|
||||||
local filenvbs = os.getenv('TMP') .. "\\MSRS-"..MSRS.uuid()..".vbs"
|
local filenvbs = os.getenv('TMP') .. "\\MSRS-"..MSRS.uuid()..".vbs"
|
||||||
@@ -1469,23 +1488,20 @@ function MSRS:_ExecCommand(command)
|
|||||||
timer.scheduleFunction(os.remove, filenvbs, timer.getTime()+1)
|
timer.scheduleFunction(os.remove, filenvbs, timer.getTime()+1)
|
||||||
self:T("MSRS vbs and batch file removed")
|
self:T("MSRS vbs and batch file removed")
|
||||||
|
|
||||||
elseif false then
|
elseif self.UsePowerShell == true then
|
||||||
|
|
||||||
-- Create a tmp file.
|
|
||||||
local filenvbs = os.getenv('TMP') .. "\\MSRS-"..MSRS.uuid()..".vbs"
|
|
||||||
|
|
||||||
-- VBS script
|
|
||||||
local script = io.open(filenvbs, "w+")
|
|
||||||
script:write(string.format('Set oShell = CreateObject ("Wscript.Shell")\n'))
|
|
||||||
script:write(string.format('Dim strArgs\n'))
|
|
||||||
script:write(string.format('strArgs = "cmd /c %s"\n', filename))
|
|
||||||
script:write(string.format('oShell.Run strArgs, 0, false'))
|
|
||||||
script:close()
|
|
||||||
|
|
||||||
local runvbs=string.format('cscript.exe //Nologo //B "%s"', filenvbs)
|
|
||||||
|
|
||||||
|
local pwsh = string.format('start /min "" powershell.exe -ExecutionPolicy Unrestricted -WindowStyle Hidden -Command "%s"',filename)
|
||||||
|
--env.info("[MSRS] TextToSpeech Command :\n" .. pwsh.."\n")
|
||||||
|
|
||||||
|
if string.len(pwsh) > 255 then
|
||||||
|
self:E("[MSRS] - pwsh string too long")
|
||||||
|
end
|
||||||
|
|
||||||
-- Play file in 0.01 seconds
|
-- Play file in 0.01 seconds
|
||||||
res=os.execute(runvbs)
|
res=os.execute(pwsh)
|
||||||
|
|
||||||
|
-- Remove file in 1 second.
|
||||||
|
timer.scheduleFunction(os.remove, filename, timer.getTime()+1)
|
||||||
|
|
||||||
else
|
else
|
||||||
-- Play command.
|
-- Play command.
|
||||||
|
|||||||
@@ -1195,18 +1195,18 @@ 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.M134_MiniGun_Left_Door = {4,15,46,174}
|
||||||
ENUMS.Storage.weapons.UH1H.M60_MG_Left_Door = {4,15,46,176}
|
ENUMS.Storage.weapons.UH1H.M60_MG_Left_Door = {4,15,46,176}
|
||||||
-- Kiowa
|
-- Kiowa
|
||||||
ENUMS.Storage.weapons.OH58.FIM92 = {4,4,7,446}
|
ENUMS.Storage.weapons.OH58.FIM92 = {4,4,7,449}
|
||||||
ENUMS.Storage.weapons.OH58.MG_M3P100 = {4,15,46,2578}
|
ENUMS.Storage.weapons.OH58.MG_M3P100 = {4,15,46,2608}
|
||||||
ENUMS.Storage.weapons.OH58.MG_M3P200 = {4,15,46,2577}
|
ENUMS.Storage.weapons.OH58.MG_M3P200 = {4,15,46,2607}
|
||||||
ENUMS.Storage.weapons.OH58.MG_M3P300 = {4,15,46,2576}
|
ENUMS.Storage.weapons.OH58.MG_M3P300 = {4,15,46,2606}
|
||||||
ENUMS.Storage.weapons.OH58.MG_M3P400 = {4,15,46,2575}
|
ENUMS.Storage.weapons.OH58.MG_M3P400 = {4,15,46,2605}
|
||||||
ENUMS.Storage.weapons.OH58.MG_M3P500 = {4,15,46,2574}
|
ENUMS.Storage.weapons.OH58.MG_M3P500 = {4,15,46,2604}
|
||||||
ENUMS.Storage.weapons.OH58.Smk_Grenade_Blue = {4,5,9,484}
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Blue = {4,5,9,486}
|
||||||
ENUMS.Storage.weapons.OH58.Smk_Grenade_Green = {4,5,9,485}
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Green = {4,5,9,487}
|
||||||
ENUMS.Storage.weapons.OH58.Smk_Grenade_Red = {4,5,9,483}
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Red = {4,5,9,485}
|
||||||
ENUMS.Storage.weapons.OH58.Smk_Grenade_Violet = {4,5,9,486}
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Violet = {4,5,9,488}
|
||||||
ENUMS.Storage.weapons.OH58.Smk_Grenade_White = {4,5,9,488}
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_White = {4,5,9,490}
|
||||||
ENUMS.Storage.weapons.OH58.Smk_Grenade_Yellow = {4,5,9,487}
|
ENUMS.Storage.weapons.OH58.Smk_Grenade_Yellow = {4,5,9,489}
|
||||||
-- Apache
|
-- Apache
|
||||||
ENUMS.Storage.weapons.AH64D.AN_APG78 = {4,15,44,2138}
|
ENUMS.Storage.weapons.AH64D.AN_APG78 = {4,15,44,2138}
|
||||||
ENUMS.Storage.weapons.AH64D.Internal_Aux_FuelTank = {1,3,43,1700}
|
ENUMS.Storage.weapons.AH64D.Internal_Aux_FuelTank = {1,3,43,1700}
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ BIGSMOKEPRESET = {
|
|||||||
-- @field #string Falklands South Atlantic map.
|
-- @field #string Falklands South Atlantic map.
|
||||||
-- @field #string Sinai Sinai map.
|
-- @field #string Sinai Sinai map.
|
||||||
-- @field #string Kola Kola map.
|
-- @field #string Kola Kola map.
|
||||||
|
-- @field #string Afghanistan Afghanistan map
|
||||||
|
-- @field #string Iraq Iraq map
|
||||||
DCSMAP = {
|
DCSMAP = {
|
||||||
Caucasus="Caucasus",
|
Caucasus="Caucasus",
|
||||||
NTTR="Nevada",
|
NTTR="Nevada",
|
||||||
@@ -68,6 +70,7 @@ DCSMAP = {
|
|||||||
Sinai="SinaiMap",
|
Sinai="SinaiMap",
|
||||||
Kola="Kola",
|
Kola="Kola",
|
||||||
Afghanistan="Afghanistan",
|
Afghanistan="Afghanistan",
|
||||||
|
Iraq="Iraq"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1786,6 +1789,8 @@ function UTILS.GetMagneticDeclination(map)
|
|||||||
declination=15
|
declination=15
|
||||||
elseif map==DCSMAP.Afghanistan then
|
elseif map==DCSMAP.Afghanistan then
|
||||||
declination=3
|
declination=3
|
||||||
|
elseif map==DCSMAP.Iraq then
|
||||||
|
declination=4.4
|
||||||
else
|
else
|
||||||
declination=0
|
declination=0
|
||||||
end
|
end
|
||||||
@@ -2315,9 +2320,9 @@ function UTILS.IsLoadingDoorOpen( unit_name )
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
if type_name == "OH-58D" and (unit:getDrawArgumentValue(35) > 0 or unit:getDrawArgumentValue(421) == -1) then
|
if type_name == "OH58D" then
|
||||||
BASE:T(unit_name .. " cargo door is open")
|
BASE:T(unit_name .. " front door(s) are open")
|
||||||
return true
|
return true -- no doors on this one ;)
|
||||||
end
|
end
|
||||||
|
|
||||||
if type_name == "CH-47Fbl1" and (unit:getDrawArgumentValue(86) > 0.5) then
|
if type_name == "CH-47Fbl1" and (unit:getDrawArgumentValue(86) > 0.5) then
|
||||||
@@ -2523,7 +2528,7 @@ end
|
|||||||
--- Function to save an object to a file
|
--- Function to save an object to a file
|
||||||
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
|
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
|
||||||
-- @param #string Filename The name of the file. Existing file will be overwritten.
|
-- @param #string Filename The name of the file. Existing file will be overwritten.
|
||||||
-- @param #table Data The LUA data structure to save. This will be e.g. a table of text lines with an \\n at the end of each line.
|
-- @param #string Data The data structure to save. This will be e.g. a string of text lines with an \\n at the end of each line.
|
||||||
-- @return #boolean outcome True if saving is possible, else false.
|
-- @return #boolean outcome True if saving is possible, else false.
|
||||||
function UTILS.SaveToFile(Path,Filename,Data)
|
function UTILS.SaveToFile(Path,Filename,Data)
|
||||||
-- Thanks to @FunkyFranky
|
-- Thanks to @FunkyFranky
|
||||||
|
|||||||
@@ -63,6 +63,11 @@
|
|||||||
-- To be able to distinguish easily in your code the difference between a AIRBASE API call and a DCS Airbase API call,
|
-- To be able to distinguish easily in your code the difference between a AIRBASE API call and a DCS Airbase API call,
|
||||||
-- the first letter of the method is also capitalized. So, by example, the DCS Airbase method DCSWrapper.Airbase#Airbase.getName()
|
-- the first letter of the method is also capitalized. So, by example, the DCS Airbase method DCSWrapper.Airbase#Airbase.getName()
|
||||||
-- is implemented in the AIRBASE class as @{#AIRBASE.GetName}().
|
-- is implemented in the AIRBASE class as @{#AIRBASE.GetName}().
|
||||||
|
--
|
||||||
|
-- ## Note on the "H" heli pads in the Syria map:
|
||||||
|
--
|
||||||
|
-- As of the time of writing (Oct 2024, DCS DCS 2.9.8.1107), these 143 objects have the **same name and object ID**, which makes them unusable in Moose, e.g. you cannot find a specific one for spawning etc.
|
||||||
|
-- Waiting for Ugra and ED to fix this issue.
|
||||||
--
|
--
|
||||||
-- @field #AIRBASE AIRBASE
|
-- @field #AIRBASE AIRBASE
|
||||||
AIRBASE = {
|
AIRBASE = {
|
||||||
@@ -248,6 +253,9 @@ AIRBASE.Nevada = {
|
|||||||
-- * AIRBASE.Normandy.Villacoublay
|
-- * AIRBASE.Normandy.Villacoublay
|
||||||
-- * AIRBASE.Normandy.Vrigny
|
-- * AIRBASE.Normandy.Vrigny
|
||||||
-- * AIRBASE.Normandy.West_Malling
|
-- * AIRBASE.Normandy.West_Malling
|
||||||
|
-- * AIRBASE.Normandy.Eastchurch
|
||||||
|
-- * AIRBASE.Normandy.Headcorn
|
||||||
|
-- * AIRBASE.Normandy.Hawkinge
|
||||||
--
|
--
|
||||||
-- @field Normandy
|
-- @field Normandy
|
||||||
AIRBASE.Normandy = {
|
AIRBASE.Normandy = {
|
||||||
@@ -330,6 +338,9 @@ AIRBASE.Normandy = {
|
|||||||
["Villacoublay"] = "Villacoublay",
|
["Villacoublay"] = "Villacoublay",
|
||||||
["Vrigny"] = "Vrigny",
|
["Vrigny"] = "Vrigny",
|
||||||
["West_Malling"] = "West Malling",
|
["West_Malling"] = "West Malling",
|
||||||
|
["Eastchurch"] = "Eastchurch",
|
||||||
|
["Headcorn"] = "Headcorn",
|
||||||
|
["Hawkinge"] = "Hawkinge",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Airbases of the Persion Gulf Map:
|
--- Airbases of the Persion Gulf Map:
|
||||||
@@ -450,6 +461,7 @@ AIRBASE.TheChannel = {
|
|||||||
-- * AIRBASE.Syria.Gaziantep
|
-- * AIRBASE.Syria.Gaziantep
|
||||||
-- * AIRBASE.Syria.Gazipasa
|
-- * AIRBASE.Syria.Gazipasa
|
||||||
-- * AIRBASE.Syria.Gecitkale
|
-- * AIRBASE.Syria.Gecitkale
|
||||||
|
-- * AIRBASE.Syria.H
|
||||||
-- * AIRBASE.Syria.H3
|
-- * AIRBASE.Syria.H3
|
||||||
-- * AIRBASE.Syria.H3_Northwest
|
-- * AIRBASE.Syria.H3_Northwest
|
||||||
-- * AIRBASE.Syria.H3_Southwest
|
-- * AIRBASE.Syria.H3_Southwest
|
||||||
@@ -497,6 +509,10 @@ AIRBASE.TheChannel = {
|
|||||||
-- * AIRBASE.Syria.Tha_lah
|
-- * AIRBASE.Syria.Tha_lah
|
||||||
-- * AIRBASE.Syria.Tiyas
|
-- * AIRBASE.Syria.Tiyas
|
||||||
-- * AIRBASE.Syria.Wujah_Al_Hajar
|
-- * AIRBASE.Syria.Wujah_Al_Hajar
|
||||||
|
-- * AIRBASE.Syria.Ben_Gurion
|
||||||
|
-- * AIRBASE.Syria.Hatzor
|
||||||
|
-- * AIRBASE.Syria.Palmashim
|
||||||
|
-- * AIRBASE.Syria.Tel_Nof
|
||||||
--
|
--
|
||||||
--@field Syria
|
--@field Syria
|
||||||
AIRBASE.Syria={
|
AIRBASE.Syria={
|
||||||
@@ -518,6 +534,7 @@ AIRBASE.Syria={
|
|||||||
["Gaziantep"] = "Gaziantep",
|
["Gaziantep"] = "Gaziantep",
|
||||||
["Gazipasa"] = "Gazipasa",
|
["Gazipasa"] = "Gazipasa",
|
||||||
["Gecitkale"] = "Gecitkale",
|
["Gecitkale"] = "Gecitkale",
|
||||||
|
["H"] = "H",
|
||||||
["H3"] = "H3",
|
["H3"] = "H3",
|
||||||
["H3_Northwest"] = "H3 Northwest",
|
["H3_Northwest"] = "H3 Northwest",
|
||||||
["H3_Southwest"] = "H3 Southwest",
|
["H3_Southwest"] = "H3 Southwest",
|
||||||
@@ -565,6 +582,10 @@ AIRBASE.Syria={
|
|||||||
["Tha_lah"] = "Tha'lah",
|
["Tha_lah"] = "Tha'lah",
|
||||||
["Tiyas"] = "Tiyas",
|
["Tiyas"] = "Tiyas",
|
||||||
["Wujah_Al_Hajar"] = "Wujah Al Hajar",
|
["Wujah_Al_Hajar"] = "Wujah Al Hajar",
|
||||||
|
["Ben_Gurion"] = "Ben Gurion",
|
||||||
|
["Hatzor"] = "Hatzor",
|
||||||
|
["Palmashim"] = "Palmashim",
|
||||||
|
["Tel_Nof"] = "Tel Nof",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Airbases of the Mariana Islands map:
|
--- Airbases of the Mariana Islands map:
|
||||||
@@ -752,12 +773,14 @@ AIRBASE.Sinai = {
|
|||||||
--
|
--
|
||||||
-- * AIRBASE.Kola.Banak
|
-- * AIRBASE.Kola.Banak
|
||||||
-- * AIRBASE.Kola.Bodo
|
-- * AIRBASE.Kola.Bodo
|
||||||
|
-- * AIRBASE.Kola.Ivalo
|
||||||
-- * AIRBASE.Kola.Jokkmokk
|
-- * AIRBASE.Kola.Jokkmokk
|
||||||
-- * AIRBASE.Kola.Kalixfors
|
-- * AIRBASE.Kola.Kalixfors
|
||||||
-- * AIRBASE.Kola.Kallax
|
-- * AIRBASE.Kola.Kallax
|
||||||
-- * AIRBASE.Kola.Kemi_Tornio
|
-- * AIRBASE.Kola.Kemi_Tornio
|
||||||
-- * AIRBASE.Kola.Kirkenes
|
-- * AIRBASE.Kola.Kirkenes
|
||||||
-- * AIRBASE.Kola.Kiruna
|
-- * AIRBASE.Kola.Kiruna
|
||||||
|
-- * AIRBASE.Kola.Kuusamo
|
||||||
-- * AIRBASE.Kola.Monchegorsk
|
-- * AIRBASE.Kola.Monchegorsk
|
||||||
-- * AIRBASE.Kola.Murmansk_International
|
-- * AIRBASE.Kola.Murmansk_International
|
||||||
-- * AIRBASE.Kola.Olenya
|
-- * AIRBASE.Kola.Olenya
|
||||||
@@ -766,25 +789,31 @@ AIRBASE.Sinai = {
|
|||||||
-- * AIRBASE.Kola.Severomorsk_3
|
-- * AIRBASE.Kola.Severomorsk_3
|
||||||
-- * AIRBASE.Kola.Vidsel
|
-- * AIRBASE.Kola.Vidsel
|
||||||
-- * AIRBASE.Kola.Vuojarvi
|
-- * AIRBASE.Kola.Vuojarvi
|
||||||
--
|
-- * AIRBASE.Kola.Andoya
|
||||||
|
-- * AIRBASE.Kola.Alakourtti
|
||||||
|
--
|
||||||
-- @field Kola
|
-- @field Kola
|
||||||
AIRBASE.Kola = {
|
AIRBASE.Kola = {
|
||||||
["Banak"] = "Banak",
|
["Banak"] = "Banak",
|
||||||
["Bodo"] = "Bodo",
|
["Bodo"] = "Bodo",
|
||||||
|
["Ivalo"] = "Ivalo",
|
||||||
["Jokkmokk"] = "Jokkmokk",
|
["Jokkmokk"] = "Jokkmokk",
|
||||||
["Kalixfors"] = "Kalixfors",
|
["Kalixfors"] = "Kalixfors",
|
||||||
|
["Kallax"] = "Kallax",
|
||||||
["Kemi_Tornio"] = "Kemi Tornio",
|
["Kemi_Tornio"] = "Kemi Tornio",
|
||||||
|
["Kirkenes"] = "Kirkenes",
|
||||||
["Kiruna"] = "Kiruna",
|
["Kiruna"] = "Kiruna",
|
||||||
|
["Kuusamo"] = "Kuusamo",
|
||||||
["Monchegorsk"] = "Monchegorsk",
|
["Monchegorsk"] = "Monchegorsk",
|
||||||
["Murmansk_International"] = "Murmansk International",
|
["Murmansk_International"] = "Murmansk International",
|
||||||
["Olenya"] = "Olenya",
|
["Olenya"] = "Olenya",
|
||||||
["Rovaniemi"] = "Rovaniemi",
|
["Rovaniemi"] = "Rovaniemi",
|
||||||
["Severomorsk_1"] = "Severomorsk-1",
|
["Severomorsk_1"] = "Severomorsk-1",
|
||||||
["Severomorsk_3"] = "Severomorsk-3",
|
["Severomorsk_3"] = "Severomorsk-3",
|
||||||
["Vuojarvi"] = "Vuojarvi",
|
|
||||||
["Kirkenes"] = "Kirkenes",
|
|
||||||
["Kallax"] = "Kallax",
|
|
||||||
["Vidsel"] = "Vidsel",
|
["Vidsel"] = "Vidsel",
|
||||||
|
["Vuojarvi"] = "Vuojarvi",
|
||||||
|
["Andoya"] = "Andoya",
|
||||||
|
["Alakourtti"] = "Alakourtti",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Airbases of the Afghanistan map
|
--- Airbases of the Afghanistan map
|
||||||
@@ -824,6 +853,39 @@ AIRBASE.Afghanistan = {
|
|||||||
["Tarinkot"] = "Tarinkot",
|
["Tarinkot"] = "Tarinkot",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- Airbases of the Iraq map
|
||||||
|
--
|
||||||
|
-- * `AIRBASE.Iraq.Baghdad_International_Airport` Baghdad International Airport
|
||||||
|
-- * `AIRBASE.Iraq.Sulaimaniyah_International_Airport` Sulaimaniyah International Airport
|
||||||
|
-- * `AIRBASE.Iraq.Al_Sahra_Airport` Al-Sahra Airport
|
||||||
|
-- * `AIRBASE.Iraq.Erbil_International_Airport` Erbil International Airport
|
||||||
|
-- * `AIRBASE.Iraq.Al_Taji_Airport` Al-Taji Airport
|
||||||
|
-- * `AIRBASE.Iraq.Al_Asad_Airbase` Al-Asad Airbase
|
||||||
|
-- * `AIRBASE.Iraq.Al_Salam_Airbase` Al-Salam Airbase
|
||||||
|
-- * `AIRBASE.Iraq.Balad_Airbase` Balad Airbase
|
||||||
|
-- * `AIRBASE.Iraq.Kirkuk_International_Airport` Kirkuk International Airport
|
||||||
|
-- * `AIRBASE.Iraq.Bashur_Airport` Bashur Airport
|
||||||
|
-- * `AIRBASE.Iraq.Al_Taquddum_Airport` Al-Taquddum Airport
|
||||||
|
-- * `AIRBASE.Iraq.Qayyarah_Airfield_West` Qayyarah Airfield West
|
||||||
|
-- * `AIRBASE.Iraq.K1_Base` K1 Base
|
||||||
|
--
|
||||||
|
-- @field Iraq
|
||||||
|
AIRBASE.Iraq = {
|
||||||
|
["Baghdad_International_Airport"] = "Baghdad International Airport",
|
||||||
|
["Sulaimaniyah_International_Airport"] = "Sulaimaniyah International Airport",
|
||||||
|
["Al_Sahra_Airport"] = "Al-Sahra Airport",
|
||||||
|
["Erbil_International_Airport"] = "Erbil International Airport",
|
||||||
|
["Al_Taji_Airport"] = "Al-Taji Airport",
|
||||||
|
["Al_Asad_Airbase"] = "Al-Asad Airbase",
|
||||||
|
["Al_Salam_Airbase"] = "Al-Salam Airbase",
|
||||||
|
["Balad_Airbase"] = "Balad Airbase",
|
||||||
|
["Kirkuk_International_Airport"] = "Kirkuk International Airport",
|
||||||
|
["Bashur_Airport"] = "Bashur Airport",
|
||||||
|
["Al_Taquddum_Airport"] = "Al-Taquddum Airport",
|
||||||
|
["Qayyarah_Airfield_West"] = "Qayyarah Airfield West",
|
||||||
|
["K1_Base"] = "K1 Base",
|
||||||
|
}
|
||||||
|
|
||||||
--- AIRBASE.ParkingSpot ".Coordinate, ".TerminalID", ".TerminalType", ".TOAC", ".Free", ".TerminalID0", ".DistToRwy".
|
--- AIRBASE.ParkingSpot ".Coordinate, ".TerminalID", ".TerminalType", ".TOAC", ".Free", ".TerminalID0", ".DistToRwy".
|
||||||
-- @type AIRBASE.ParkingSpot
|
-- @type AIRBASE.ParkingSpot
|
||||||
-- @field Core.Point#COORDINATE Coordinate Coordinate of the parking spot.
|
-- @field Core.Point#COORDINATE Coordinate Coordinate of the parking spot.
|
||||||
@@ -926,7 +988,7 @@ function AIRBASE:Register(AirbaseName)
|
|||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
--self:I({airbase=AirbaseName, descriptors=self.descriptors})
|
--self:I({airbase=AirbaseName, descriptors=self.descriptors})
|
||||||
|
|
||||||
-- Category.
|
-- Category.
|
||||||
self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME
|
self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME
|
||||||
|
|
||||||
@@ -937,22 +999,22 @@ function AIRBASE:Register(AirbaseName)
|
|||||||
--end
|
--end
|
||||||
|
|
||||||
-- Set category.
|
-- Set category.
|
||||||
if self.category==Airbase.Category.AIRDROME then
|
if self.category==Airbase.Category.AIRDROME then
|
||||||
self.isAirdrome=true
|
self.isAirdrome=true
|
||||||
elseif self.category==Airbase.Category.HELIPAD then
|
elseif self.category==Airbase.Category.HELIPAD or self.descriptors.typeName=="FARP_SINGLE_01" then
|
||||||
|
self.isHelipad=true
|
||||||
|
elseif self.category==Airbase.Category.SHIP then
|
||||||
|
self.isShip=true
|
||||||
|
-- DCS bug: Oil rigs and gas platforms have category=2 (ship). Also they cannot be retrieved by coalition.getStaticObjects()
|
||||||
|
if self.descriptors.typeName=="Oil rig" or self.descriptors.typeName=="Ga" then
|
||||||
self.isHelipad=true
|
self.isHelipad=true
|
||||||
elseif self.category==Airbase.Category.SHIP then
|
self.isShip=false
|
||||||
self.isShip=true
|
self.category=Airbase.Category.HELIPAD
|
||||||
-- DCS bug: Oil rigs and gas platforms have category=2 (ship). Also they cannot be retrieved by coalition.getStaticObjects()
|
_DATABASE:AddStatic(AirbaseName)
|
||||||
if self.descriptors.typeName=="Oil rig" or self.descriptors.typeName=="Ga" then
|
|
||||||
self.isHelipad=true
|
|
||||||
self.isShip=false
|
|
||||||
self.category=Airbase.Category.HELIPAD
|
|
||||||
_DATABASE:AddStatic(AirbaseName)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
self:E("ERROR: Unknown airbase category!")
|
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
self:E("ERROR: Unknown airbase category!")
|
||||||
|
end
|
||||||
|
|
||||||
-- Init Runways.
|
-- Init Runways.
|
||||||
self:_InitRunways()
|
self:_InitRunways()
|
||||||
|
|||||||
@@ -902,7 +902,11 @@ function CONTROLLABLE:CommandEPLRS( SwitchOnOff, Delay )
|
|||||||
groupId = self:GetID(),
|
groupId = self:GetID(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--if self:IsGround() then
|
||||||
|
--CommandEPLRS.params.groupId = self:GetID()
|
||||||
|
--end
|
||||||
|
|
||||||
if Delay and Delay > 0 then
|
if Delay and Delay > 0 then
|
||||||
SCHEDULER:New( nil, self.CommandEPLRS, { self, SwitchOnOff }, Delay )
|
SCHEDULER:New( nil, self.CommandEPLRS, { self, SwitchOnOff }, Delay )
|
||||||
else
|
else
|
||||||
@@ -937,7 +941,7 @@ function CONTROLLABLE:CommandSetUnlimitedFuel(OnOff, Delay)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set radio frequency. See [DCS command EPLRS](https://wiki.hoggitworld.com/view/DCS_command_setFrequency)
|
--- Set radio frequency. See [DCS command SetFrequency](https://wiki.hoggitworld.com/view/DCS_command_setFrequency)
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @param #number Frequency Radio frequency in MHz.
|
-- @param #number Frequency Radio frequency in MHz.
|
||||||
-- @param #number Modulation Radio modulation. Default `radio.modulation.AM`.
|
-- @param #number Modulation Radio modulation. Default `radio.modulation.AM`.
|
||||||
@@ -956,7 +960,7 @@ function CONTROLLABLE:CommandSetFrequency( Frequency, Modulation, Power, Delay )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if Delay and Delay > 0 then
|
if Delay and Delay > 0 then
|
||||||
SCHEDULER:New( nil, self.CommandSetFrequency, { self, Frequency, Modulation, Power } )
|
SCHEDULER:New( nil, self.CommandSetFrequency, { self, Frequency, Modulation, Power },Delay )
|
||||||
else
|
else
|
||||||
self:SetCommand( CommandSetFrequency )
|
self:SetCommand( CommandSetFrequency )
|
||||||
end
|
end
|
||||||
@@ -964,7 +968,7 @@ function CONTROLLABLE:CommandSetFrequency( Frequency, Modulation, Power, Delay )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- [AIR] Set radio frequency. See [DCS command EPLRS](https://wiki.hoggitworld.com/view/DCS_command_setFrequencyForUnit)
|
--- [AIR] Set radio frequency. See [DCS command SetFrequencyForUnit](https://wiki.hoggitworld.com/view/DCS_command_setFrequencyForUnit)
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @param #number Frequency Radio frequency in MHz.
|
-- @param #number Frequency Radio frequency in MHz.
|
||||||
-- @param #number Modulation Radio modulation. Default `radio.modulation.AM`.
|
-- @param #number Modulation Radio modulation. Default `radio.modulation.AM`.
|
||||||
@@ -983,7 +987,7 @@ function CONTROLLABLE:CommandSetFrequencyForUnit(Frequency,Modulation,Power,Unit
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
if Delay and Delay>0 then
|
if Delay and Delay>0 then
|
||||||
SCHEDULER:New(nil,self.CommandSetFrequencyForUnit,{self,Frequency,Modulation,Power,UnitID})
|
SCHEDULER:New(nil,self.CommandSetFrequencyForUnit,{self,Frequency,Modulation,Power,UnitID},Delay)
|
||||||
else
|
else
|
||||||
self:SetCommand(CommandSetFrequencyForUnit)
|
self:SetCommand(CommandSetFrequencyForUnit)
|
||||||
end
|
end
|
||||||
@@ -1009,7 +1013,11 @@ function CONTROLLABLE:TaskEPLRS( SwitchOnOff, idx )
|
|||||||
groupId = self:GetID(),
|
groupId = self:GetID(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--if self:IsGround() then
|
||||||
|
--CommandEPLRS.params.groupId = self:GetID()
|
||||||
|
--end
|
||||||
|
|
||||||
return self:TaskWrappedAction( CommandEPLRS, idx or 1 )
|
return self:TaskWrappedAction( CommandEPLRS, idx or 1 )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2997,7 +3005,7 @@ function CONTROLLABLE:GetDetectedTargets( DetectVisual, DetectOptical, DetectRad
|
|||||||
if DCSControllable then
|
if DCSControllable then
|
||||||
|
|
||||||
local DetectionVisual = (DetectVisual and DetectVisual == true) and Controller.Detection.VISUAL or nil
|
local DetectionVisual = (DetectVisual and DetectVisual == true) and Controller.Detection.VISUAL or nil
|
||||||
local DetectionOptical = (DetectOptical and DetectOptical == true) and Controller.Detection.OPTICAL or nil
|
local DetectionOptical = (DetectOptical and DetectOptical == true) and Controller.Detection.OPTIC or nil
|
||||||
local DetectionRadar = (DetectRadar and DetectRadar == true) and Controller.Detection.RADAR or nil
|
local DetectionRadar = (DetectRadar and DetectRadar == true) and Controller.Detection.RADAR or nil
|
||||||
local DetectionIRST = (DetectIRST and DetectIRST == true) and Controller.Detection.IRST or nil
|
local DetectionIRST = (DetectIRST and DetectIRST == true) and Controller.Detection.IRST or nil
|
||||||
local DetectionRWR = (DetectRWR and DetectRWR == true) and Controller.Detection.RWR or nil
|
local DetectionRWR = (DetectRWR and DetectRWR == true) and Controller.Detection.RWR or nil
|
||||||
@@ -3031,26 +3039,27 @@ function CONTROLLABLE:GetDetectedTargets( DetectVisual, DetectOptical, DetectRad
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Check if a target is detected.
|
--- Check if a DCS object (unit or static) is detected by the controllable.
|
||||||
|
-- Note that after a target is detected it remains "detected" for a certain amount of time, even if the controllable cannot "see" the target any more with it's sensors.
|
||||||
-- The optional parametes specify the detection methods that can be applied.
|
-- The optional parametes specify the detection methods that can be applied.
|
||||||
|
--
|
||||||
-- If **no** detection method is given, the detection will use **all** the available methods by default.
|
-- If **no** detection method is given, the detection will use **all** the available methods by default.
|
||||||
-- If **at least one** detection method is specified, only the methods set to *true* will be used.
|
-- If **at least one** detection method is specified, only the methods set to *true* will be used.
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @param DCS#Object DCSObject The DCS object that is checked.
|
-- @param DCS#Object DCSObject The DCS object that is checked.
|
||||||
-- @param #CONTROLLABLE self
|
|
||||||
-- @param #boolean DetectVisual (Optional) If *false*, do not include visually detected targets.
|
-- @param #boolean DetectVisual (Optional) If *false*, do not include visually detected targets.
|
||||||
-- @param #boolean DetectOptical (Optional) If *false*, do not include optically detected targets.
|
-- @param #boolean DetectOptical (Optional) If *false*, do not include optically detected targets.
|
||||||
-- @param #boolean DetectRadar (Optional) If *false*, do not include targets detected by radar.
|
-- @param #boolean DetectRadar (Optional) If *false*, do not include targets detected by radar.
|
||||||
-- @param #boolean DetectIRST (Optional) If *false*, do not include targets detected by IRST.
|
-- @param #boolean DetectIRST (Optional) If *false*, do not include targets detected by IRST.
|
||||||
-- @param #boolean DetectRWR (Optional) If *false*, do not include targets detected by RWR.
|
-- @param #boolean DetectRWR (Optional) If *false*, do not include targets detected by RWR.
|
||||||
-- @param #boolean DetectDLINK (Optional) If *false*, do not include targets detected by data link.
|
-- @param #boolean DetectDLINK (Optional) If *false*, do not include targets detected by data link.
|
||||||
-- @return #boolean True if target is detected.
|
-- @return #boolean `true` if target is detected.
|
||||||
-- @return #boolean True if target is visible by line of sight.
|
-- @return #boolean `true` if target is *currently* visible by line of sight. Target must be detected (first parameter returns `true`).
|
||||||
-- @return #number Mission time when target was detected.
|
-- @return #boolean `true` if target type is known. Target must be detected (first parameter returns `true`).
|
||||||
-- @return #boolean True if target type is known.
|
-- @return #boolean `true` if distance to target is known. Target must be detected (first parameter returns `true`).
|
||||||
-- @return #boolean True if distance to target is known.
|
-- @return #number Mission time in seconds when target was last detected. Only present if the target is currently not visible (second parameter returns `false`) otherwise `nil` is returned.
|
||||||
-- @return DCS#Vec3 Last known position vector of the target.
|
-- @return DCS#Vec3 Last known position vector of the target. Only present if the target is currently not visible (second parameter returns `false`) otherwise `nil` is returned.
|
||||||
-- @return DCS#Vec3 Last known velocity vector of the target.
|
-- @return DCS#Vec3 Last known velocity vector of the target. Only present if the target is currently not visible (second parameter returns `false`) otherwise `nil` is returned.
|
||||||
function CONTROLLABLE:IsTargetDetected( DCSObject, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK )
|
function CONTROLLABLE:IsTargetDetected( DCSObject, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK )
|
||||||
self:F2( self.ControllableName )
|
self:F2( self.ControllableName )
|
||||||
|
|
||||||
@@ -3059,7 +3068,7 @@ function CONTROLLABLE:IsTargetDetected( DCSObject, DetectVisual, DetectOptical,
|
|||||||
if DCSControllable then
|
if DCSControllable then
|
||||||
|
|
||||||
local DetectionVisual = (DetectVisual and DetectVisual == true) and Controller.Detection.VISUAL or nil
|
local DetectionVisual = (DetectVisual and DetectVisual == true) and Controller.Detection.VISUAL or nil
|
||||||
local DetectionOptical = (DetectOptical and DetectOptical == true) and Controller.Detection.OPTICAL or nil
|
local DetectionOptical = (DetectOptical and DetectOptical == true) and Controller.Detection.OPTIC or nil
|
||||||
local DetectionRadar = (DetectRadar and DetectRadar == true) and Controller.Detection.RADAR or nil
|
local DetectionRadar = (DetectRadar and DetectRadar == true) and Controller.Detection.RADAR or nil
|
||||||
local DetectionIRST = (DetectIRST and DetectIRST == true) and Controller.Detection.IRST or nil
|
local DetectionIRST = (DetectIRST and DetectIRST == true) and Controller.Detection.IRST or nil
|
||||||
local DetectionRWR = (DetectRWR and DetectRWR == true) and Controller.Detection.RWR or nil
|
local DetectionRWR = (DetectRWR and DetectRWR == true) and Controller.Detection.RWR or nil
|
||||||
@@ -3067,10 +3076,10 @@ function CONTROLLABLE:IsTargetDetected( DCSObject, DetectVisual, DetectOptical,
|
|||||||
|
|
||||||
local Controller = self:_GetController()
|
local Controller = self:_GetController()
|
||||||
|
|
||||||
local TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity
|
local TargetIsDetected, TargetIsVisible, TargetKnowType, TargetKnowDistance, TargetLastTime, TargetLastPos, TargetLastVelocity
|
||||||
= Controller:isTargetDetected( DCSObject, DetectionVisual, DetectionOptical, DetectionRadar, DetectionIRST, DetectionRWR, DetectionDLINK )
|
= Controller:isTargetDetected( DCSObject, DetectionVisual, DetectionOptical, DetectionRadar, DetectionIRST, DetectionRWR, DetectionDLINK )
|
||||||
|
|
||||||
return TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity
|
return TargetIsDetected, TargetIsVisible, TargetKnowType, TargetKnowDistance, TargetLastTime, TargetLastPos, TargetLastVelocity
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -3078,6 +3087,7 @@ end
|
|||||||
|
|
||||||
--- Check if a certain UNIT is detected by the controllable.
|
--- Check if a certain UNIT is detected by the controllable.
|
||||||
-- The optional parametes specify the detection methods that can be applied.
|
-- The optional parametes specify the detection methods that can be applied.
|
||||||
|
--
|
||||||
-- If **no** detection method is given, the detection will use **all** the available methods by default.
|
-- If **no** detection method is given, the detection will use **all** the available methods by default.
|
||||||
-- If **at least one** detection method is specified, only the methods set to *true* will be used.
|
-- If **at least one** detection method is specified, only the methods set to *true* will be used.
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
@@ -3088,13 +3098,13 @@ end
|
|||||||
-- @param #boolean DetectIRST (Optional) If *false*, do not include targets detected by IRST.
|
-- @param #boolean DetectIRST (Optional) If *false*, do not include targets detected by IRST.
|
||||||
-- @param #boolean DetectRWR (Optional) If *false*, do not include targets detected by RWR.
|
-- @param #boolean DetectRWR (Optional) If *false*, do not include targets detected by RWR.
|
||||||
-- @param #boolean DetectDLINK (Optional) If *false*, do not include targets detected by data link.
|
-- @param #boolean DetectDLINK (Optional) If *false*, do not include targets detected by data link.
|
||||||
-- @return #boolean True if target is detected.
|
-- @return #boolean `true` if target is detected.
|
||||||
-- @return #boolean True if target is visible by line of sight.
|
-- @return #boolean `true` if target is *currently* visible by line of sight. Target must be detected (first parameter returns `true`).
|
||||||
-- @return #number Mission time when target was detected.
|
-- @return #boolean `true` if target type is known. Target must be detected (first parameter returns `true`).
|
||||||
-- @return #boolean True if target type is known.
|
-- @return #boolean `true` if distance to target is known. Target must be detected (first parameter returns `true`).
|
||||||
-- @return #boolean True if distance to target is known.
|
-- @return #number Mission time in seconds when target was last detected. Only present if the target is currently not visible (second parameter returns `false`) otherwise `nil` is returned.
|
||||||
-- @return DCS#Vec3 Last known position vector of the target.
|
-- @return DCS#Vec3 Last known position vector of the target. Only present if the target is currently not visible (second parameter returns `false`) otherwise `nil` is returned.
|
||||||
-- @return DCS#Vec3 Last known velocity vector of the target.
|
-- @return DCS#Vec3 Last known velocity vector of the target. Only present if the target is currently not visible (second parameter returns `false`) otherwise `nil` is returned.
|
||||||
function CONTROLLABLE:IsUnitDetected( Unit, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK )
|
function CONTROLLABLE:IsUnitDetected( Unit, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK )
|
||||||
self:F2( self.ControllableName )
|
self:F2( self.ControllableName )
|
||||||
|
|
||||||
|
|||||||
@@ -458,7 +458,7 @@ function DYNAMICCARGO:_UpdatePosition()
|
|||||||
self:T(self.lid.." AGL: "..agl or -1)
|
self:T(self.lid.." AGL: "..agl or -1)
|
||||||
local isunloaded = true
|
local isunloaded = true
|
||||||
local client
|
local client
|
||||||
local playername
|
local playername = self.Owner
|
||||||
if count > 0 and (agl > 0 or self.testing) then
|
if count > 0 and (agl > 0 or self.testing) then
|
||||||
self:T(self.lid.." Possible alive helos: "..count or -1)
|
self:T(self.lid.." Possible alive helos: "..count or -1)
|
||||||
if agl ~= 0 or self.testing then
|
if agl ~= 0 or self.testing then
|
||||||
@@ -470,6 +470,11 @@ function DYNAMICCARGO:_UpdatePosition()
|
|||||||
self.Owner = playername
|
self.Owner = playername
|
||||||
_DATABASE:CreateEventDynamicCargoUnloaded(self)
|
_DATABASE:CreateEventDynamicCargoUnloaded(self)
|
||||||
end
|
end
|
||||||
|
elseif count > 0 and agl == 0 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
|
end
|
||||||
self.LastPosition = pos
|
self.LastPosition = pos
|
||||||
|
|||||||
@@ -360,7 +360,7 @@ 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
|
--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 )
|
||||||
@@ -369,14 +369,14 @@ function GROUP:GetDCSObject()
|
|||||||
self.LastCallDCSObject = timer.getTime()
|
self.LastCallDCSObject = timer.getTime()
|
||||||
self.DCSObject = DCSGroup
|
self.DCSObject = DCSGroup
|
||||||
return DCSGroup
|
return DCSGroup
|
||||||
else
|
-- else
|
||||||
self.DCSObject = nil
|
-- self.DCSObject = nil
|
||||||
self.LastCallDCSObject = nil
|
-- self.LastCallDCSObject = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
--else
|
||||||
return self.DCSObject
|
--return self.DCSObject
|
||||||
end
|
--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)))
|
--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
|
||||||
@@ -485,20 +485,24 @@ function GROUP:Destroy( GenerateEvent, delay )
|
|||||||
self:ScheduleOnce(delay, GROUP.Destroy, self, GenerateEvent)
|
self:ScheduleOnce(delay, GROUP.Destroy, self, GenerateEvent)
|
||||||
else
|
else
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
--local DCSGroup = self:GetDCSObject()
|
||||||
|
local DCSGroup = Group.getByName( self.GroupName )
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
|
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
|
||||||
if GenerateEvent and GenerateEvent == true then
|
if GenerateEvent and GenerateEvent == true then
|
||||||
if self:IsAir() then
|
if self:IsAir() then
|
||||||
self:CreateEventCrash( timer.getTime(), UnitData )
|
self:CreateEventCrash( timer.getTime(), UnitData )
|
||||||
|
--self:ScheduleOnce(1,self.CreateEventCrash,self,timer.getTime(),UnitData)
|
||||||
else
|
else
|
||||||
self:CreateEventDead( timer.getTime(), UnitData )
|
self:CreateEventDead( timer.getTime(), UnitData )
|
||||||
|
--self:ScheduleOnce(1,self.CreateEventDead,self,timer.getTime(),UnitData)
|
||||||
end
|
end
|
||||||
elseif GenerateEvent == false then
|
elseif GenerateEvent == false then
|
||||||
-- Do nothing!
|
-- Do nothing!
|
||||||
else
|
else
|
||||||
self:CreateEventRemoveUnit( timer.getTime(), UnitData )
|
self:CreateEventRemoveUnit( timer.getTime(), UnitData )
|
||||||
|
--self:ScheduleOnce(1,self.CreateEventRemoveUnit,self,timer.getTime(),UnitData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
USERFLAG:New( self:GetName() ):Set( 100 )
|
USERFLAG:New( self:GetName() ):Set( 100 )
|
||||||
@@ -1985,15 +1989,11 @@ end
|
|||||||
-- - @{#GROUP.InitHeight}: Set the height for the units in meters for the respawned group. (This is applicable for air units).
|
-- - @{#GROUP.InitHeight}: Set the height for the units in meters for the respawned group. (This is applicable for air units).
|
||||||
-- - @{#GROUP.InitRandomizeHeading}: Randomize the headings for the units within the respawned group.
|
-- - @{#GROUP.InitRandomizeHeading}: Randomize the headings for the units within the respawned group.
|
||||||
-- - @{#GROUP.InitZone}: Set the respawn @{Core.Zone} for the respawned group.
|
-- - @{#GROUP.InitZone}: Set the respawn @{Core.Zone} for the respawned group.
|
||||||
-- - @{#GROUP.InitRandomizeZones}: Randomize the respawn @{Core.Zone} between one of the @{Core.Zone}s given for the respawned group.
|
|
||||||
-- - @{#GROUP.InitRandomizePositionZone}: Randomize the positions of the units of the respawned group within the @{Core.Zone}.
|
-- - @{#GROUP.InitRandomizePositionZone}: Randomize the positions of the units of the respawned group within the @{Core.Zone}.
|
||||||
-- - @{#GROUP.InitRandomizePositionRadius}: Randomize the positions of the units of the respawned group in a circle band.
|
-- - @{#GROUP.InitRandomizePositionRadius}: Randomize the positions of the units of the respawned group in a circle band.
|
||||||
-- - @{#GROUP.InitRandomizeTemplates}: Randomize the Template for the respawned group.
|
|
||||||
--
|
|
||||||
--
|
--
|
||||||
-- Notes:
|
-- Notes:
|
||||||
--
|
--
|
||||||
-- - When InitZone or InitRandomizeZones is not used, the position of the respawned group will be its current position.
|
|
||||||
-- - The current alive group will always be destroyed and respawned using the template definition.
|
-- - The current alive group will always be destroyed and respawned using the template definition.
|
||||||
--
|
--
|
||||||
-- @param Wrapper.Group#GROUP self
|
-- @param Wrapper.Group#GROUP self
|
||||||
@@ -2015,10 +2015,24 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
end
|
end
|
||||||
return h
|
return h
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function TransFormRoute(Template,OldPos,NewPos)
|
||||||
|
if Template.route and Template.route.points then
|
||||||
|
for _,_point in ipairs(Template.route.points) do
|
||||||
|
--self:I(string.format("Point x = %f Point y = %f",_point.x,_point.y))
|
||||||
|
_point.x = _point.x - OldPos.x + NewPos.x
|
||||||
|
_point.y = _point.y - OldPos.y + NewPos.y
|
||||||
|
--self:I(string.format("Point x = %f Point y = %f",_point.x,_point.y))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Template
|
||||||
|
end
|
||||||
|
|
||||||
-- First check if group is alive.
|
-- First check if group is alive.
|
||||||
if self:IsAlive() then
|
if self:IsAlive() then
|
||||||
|
|
||||||
|
local OldPos = self:GetVec2()
|
||||||
|
|
||||||
-- Respawn zone.
|
-- Respawn zone.
|
||||||
local Zone = self.InitRespawnZone -- Core.Zone#ZONE
|
local Zone = self.InitRespawnZone -- Core.Zone#ZONE
|
||||||
|
|
||||||
@@ -2031,6 +2045,8 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
-- X, Y
|
-- X, Y
|
||||||
Template.x = Vec3.x
|
Template.x = Vec3.x
|
||||||
Template.y = Vec3.z
|
Template.y = Vec3.z
|
||||||
|
|
||||||
|
local NewPos = { x = Vec3.x, y = Vec3.z }
|
||||||
|
|
||||||
--Template.x = nil
|
--Template.x = nil
|
||||||
--Template.y = nil
|
--Template.y = nil
|
||||||
@@ -2085,11 +2101,13 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
-- Set heading.
|
-- Set heading.
|
||||||
Template.units[UnitID].heading = _Heading(self.InitRespawnHeading and self.InitRespawnHeading or GroupUnit:GetHeading())
|
Template.units[UnitID].heading = _Heading(self.InitRespawnHeading and self.InitRespawnHeading or GroupUnit:GetHeading())
|
||||||
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
|
||||||
|
|
||||||
|
Template = TransFormRoute(Template,OldPos,NewPos)
|
||||||
|
|
||||||
elseif Reset==false then -- Reset=false or nil
|
elseif Reset==false then -- Reset=false or nil
|
||||||
|
|
||||||
@@ -2128,11 +2146,13 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
|
|
||||||
-- Heading
|
-- Heading
|
||||||
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
|
||||||
|
|
||||||
|
Template = TransFormRoute(Template,OldPos,NewPos)
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
local units=self:GetUnits()
|
local units=self:GetUnits()
|
||||||
@@ -2181,10 +2201,11 @@ 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})
|
--UTILS.PrintTableToLog(Template)
|
||||||
|
|
||||||
-- Spawn new group.
|
-- Spawn new group.
|
||||||
_DATABASE:Spawn(Template)
|
self:ScheduleOnce(0.1,_DATABASE.Spawn,_DATABASE,Template)
|
||||||
|
--_DATABASE:Spawn(Template)
|
||||||
|
|
||||||
-- Reset events.
|
-- Reset events.
|
||||||
self:ResetEvents()
|
self:ResetEvents()
|
||||||
@@ -2192,6 +2213,29 @@ function GROUP:Respawn( Template, Reset )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Respawn the @{Wrapper.Group} at a @{Core.Point#COORDINATE}.
|
||||||
|
-- The method will setup the new group template according the Init(Respawn) settings provided for the group.
|
||||||
|
-- These settings can be provided by calling the relevant Init...() methods of the Group prior.
|
||||||
|
--
|
||||||
|
-- - @{#GROUP.InitHeading}: Set the heading for the units in degrees within the respawned group.
|
||||||
|
-- - @{#GROUP.InitHeight}: Set the height for the units in meters for the respawned group. (This is applicable for air units).
|
||||||
|
-- - @{#GROUP.InitRandomizeHeading}: Randomize the headings for the units within the respawned group.
|
||||||
|
-- - @{#GROUP.InitRandomizePositionZone}: Randomize the positions of the units of the respawned group within the @{Core.Zone}.
|
||||||
|
-- - @{#GROUP.InitRandomizePositionRadius}: Randomize the positions of the units of the respawned group in a circle band.
|
||||||
|
--
|
||||||
|
-- Notes:
|
||||||
|
--
|
||||||
|
-- - When no coordinate is given, the position of the respawned group will be its current position.
|
||||||
|
-- - The current alive group will always be destroyed first.
|
||||||
|
-- - The new group will have all of its original units and health restored.
|
||||||
|
--
|
||||||
|
-- @param Wrapper.Group#GROUP self
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate Where to respawn the group. Can be handed as a @{Core.Zone#ZONE_BASE} object.
|
||||||
|
-- @return Wrapper.Group#GROUP self
|
||||||
|
function GROUP:Teleport(Coordinate)
|
||||||
|
self:InitZone(Coordinate)
|
||||||
|
return self:Respawn(nil,false)
|
||||||
|
end
|
||||||
|
|
||||||
--- Respawn a group at an airbase.
|
--- Respawn a group at an airbase.
|
||||||
-- Note that the group has to be on parking spots at the airbase already in order for this to work.
|
-- Note that the group has to be on parking spots at the airbase already in order for this to work.
|
||||||
@@ -2333,8 +2377,11 @@ end
|
|||||||
-- @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 )
|
||||||
|
if _DATABASE.Templates.Groups[self.GroupName].Template and _DATABASE.Templates.Groups[self.GroupName].Template.route and _DATABASE.Templates.Groups[self.GroupName].Template.route.points then
|
||||||
return UTILS.DeepCopy( _DATABASE.Templates.Groups[self.GroupName].Template.route.points )
|
return UTILS.DeepCopy( _DATABASE.Templates.Groups[self.GroupName].Template.route.points )
|
||||||
|
else
|
||||||
|
return {}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Return the route of a group by using the global _DATABASE object (an instance of @{Core.Database#DATABASE}).
|
--- Return the route of a group by using the global _DATABASE object (an instance of @{Core.Database#DATABASE}).
|
||||||
@@ -2926,8 +2973,10 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @param #boolean ShortCallsign Return a shortened customized callsign, i.e. "Ghostrider 9" and not "Ghostrider 9 1"
|
-- @param #boolean ShortCallsign Return a shortened customized callsign, i.e. "Ghostrider 9" and not "Ghostrider 9 1"
|
||||||
-- @param #boolean Keepnumber (Player only) Return customized callsign, incl optional numbers at the end, e.g. "Aerial 1-1#Ghostrider 109" results in "Ghostrider 109", if you want to e.g. use historical US Navy Callsigns
|
-- @param #boolean Keepnumber (Player only) Return customized callsign, incl optional numbers at the end, e.g. "Aerial 1-1#Ghostrider 109" results in "Ghostrider 109", if you want to e.g. use historical US Navy Callsigns
|
||||||
-- @param #table CallsignTranslations Table to translate between DCS standard callsigns and bespoke ones. Overrides personal/parsed callsigns if set
|
-- @param #table CallsignTranslations (Optional) Table to translate between DCS standard callsigns and bespoke ones. Overrides personal/parsed callsigns if set
|
||||||
-- callsigns from playername or group name.
|
-- callsigns from playername or group name.
|
||||||
|
-- @param #func CustomFunction (Optional) For player names only(!). If given, this function will return the callsign. Needs to take the groupname and the playername as first arguments.
|
||||||
|
-- @param #arg ... (Optional) Comma separated arguments to add to the CustomFunction call after groupname and playername.
|
||||||
-- @return #string Callsign
|
-- @return #string Callsign
|
||||||
-- @usage
|
-- @usage
|
||||||
-- -- suppose there are three groups with one (client) unit each:
|
-- -- suppose there are three groups with one (client) unit each:
|
||||||
@@ -2948,8 +2997,12 @@ end
|
|||||||
-- -- Apollo for Slot 2 or Apollo 403 if Keepnumber is set
|
-- -- Apollo for Slot 2 or Apollo 403 if Keepnumber is set
|
||||||
-- -- Apollo for Slot 3
|
-- -- Apollo for Slot 3
|
||||||
-- -- Bengal-4 for Slot 4
|
-- -- Bengal-4 for Slot 4
|
||||||
|
--
|
||||||
function GROUP:GetCustomCallSign(ShortCallsign,Keepnumber,CallsignTranslations)
|
-- -- Using a custom function (for player units **only**):
|
||||||
|
-- -- Imagine your playernames are looking like so: "[Squadname] | Cpt Apple" and you only want to have the last word as callsign, i.e. "Apple" here. Then this custom function will return this:
|
||||||
|
-- local callsign = mygroup:GetCustomCallSign(true,false,nil,function(groupname,playername) return string.match(playername,"([%a]+)$") end)
|
||||||
|
--
|
||||||
|
function GROUP:GetCustomCallSign(ShortCallsign,Keepnumber,CallsignTranslations,CustomFunction,...)
|
||||||
--self:I("GetCustomCallSign")
|
--self:I("GetCustomCallSign")
|
||||||
|
|
||||||
local callsign = "Ghost 1"
|
local callsign = "Ghost 1"
|
||||||
@@ -2963,7 +3016,14 @@ function GROUP:GetCustomCallSign(ShortCallsign,Keepnumber,CallsignTranslations)
|
|||||||
local callnumbermajor = string.char(string.byte(callnumber,1)) -- 9
|
local callnumbermajor = string.char(string.byte(callnumber,1)) -- 9
|
||||||
local callnumberminor = string.char(string.byte(callnumber,2)) -- 1
|
local callnumberminor = string.char(string.byte(callnumber,2)) -- 1
|
||||||
local personalized = false
|
local personalized = false
|
||||||
|
local playername = IsPlayer == true and self:GetPlayerName() or shortcallsign
|
||||||
|
|
||||||
|
if CustomFunction and IsPlayer then
|
||||||
|
local arguments = arg or {}
|
||||||
|
local callsign = CustomFunction(groupname,playername,unpack(arguments))
|
||||||
|
return callsign
|
||||||
|
end
|
||||||
|
|
||||||
-- prioritize bespoke callsigns over parsing, prefer parsing over default callsigns
|
-- prioritize bespoke callsigns over parsing, prefer parsing over default callsigns
|
||||||
if CallsignTranslations and CallsignTranslations[callsignroot] then
|
if CallsignTranslations and CallsignTranslations[callsignroot] then
|
||||||
callsignroot = CallsignTranslations[callsignroot]
|
callsignroot = CallsignTranslations[callsignroot]
|
||||||
@@ -2975,9 +3035,9 @@ function GROUP:GetCustomCallSign(ShortCallsign,Keepnumber,CallsignTranslations)
|
|||||||
shortcallsign = string.match(groupname,"#%s*([%a]+)") or "Ghost" -- Ghostrider
|
shortcallsign = string.match(groupname,"#%s*([%a]+)") or "Ghost" -- Ghostrider
|
||||||
end
|
end
|
||||||
personalized = true
|
personalized = true
|
||||||
elseif IsPlayer and string.find(self:GetPlayerName(),"|") then
|
elseif IsPlayer and string.find(playername,"|") then
|
||||||
-- personalized flight name in group naming
|
-- personalized flight name in group naming
|
||||||
shortcallsign = string.match(self:GetPlayerName(),"|%s*([%a]+)") or string.match(self:GetPlayerName(),"|%s*([%d]+)") or "Ghost" -- Ghostrider
|
shortcallsign = string.match(playername,"|%s*([%a]+)") or string.match(self:GetPlayerName(),"|%s*([%d]+)") or "Ghost" -- Ghostrider
|
||||||
personalized = true
|
personalized = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ do
|
|||||||
-- @field #NET
|
-- @field #NET
|
||||||
NET = {
|
NET = {
|
||||||
ClassName = "NET",
|
ClassName = "NET",
|
||||||
Version = "0.1.3",
|
Version = "0.1.4",
|
||||||
BlockTime = 600,
|
BlockTime = 600,
|
||||||
BlockedPilots = {},
|
BlockedPilots = {},
|
||||||
BlockedUCIDs = {},
|
BlockedUCIDs = {},
|
||||||
@@ -67,6 +67,9 @@ function NET:New()
|
|||||||
self.KnownPilots = {}
|
self.KnownPilots = {}
|
||||||
self:SetBlockMessage()
|
self:SetBlockMessage()
|
||||||
self:SetUnblockMessage()
|
self:SetUnblockMessage()
|
||||||
|
self.BlockedSides = {}
|
||||||
|
self.BlockedSides[1] = false
|
||||||
|
self.BlockedSides[2] = false
|
||||||
|
|
||||||
-- Start State.
|
-- Start State.
|
||||||
self:SetStartState("Stopped")
|
self:SetStartState("Stopped")
|
||||||
@@ -160,11 +163,12 @@ end
|
|||||||
-- @param #string PlayerSlot
|
-- @param #string PlayerSlot
|
||||||
-- @return #boolean IsBlocked
|
-- @return #boolean IsBlocked
|
||||||
function NET:IsAnyBlocked(UCID,Name,PlayerID,PlayerSide,PlayerSlot)
|
function NET:IsAnyBlocked(UCID,Name,PlayerID,PlayerSide,PlayerSlot)
|
||||||
|
self:T({UCID,Name,PlayerID,PlayerSide,PlayerSlot})
|
||||||
local blocked = false
|
local blocked = false
|
||||||
local TNow = timer.getTime()
|
local TNow = timer.getTime()
|
||||||
-- UCID
|
-- UCID
|
||||||
if UCID and self.BlockedUCIDs[UCID] and TNow < self.BlockedUCIDs[UCID] then
|
if UCID and self.BlockedUCIDs[UCID] and TNow < self.BlockedUCIDs[UCID] then
|
||||||
return true
|
blocked = true
|
||||||
end
|
end
|
||||||
-- ID/Name
|
-- ID/Name
|
||||||
if PlayerID and not Name then
|
if PlayerID and not Name then
|
||||||
@@ -172,16 +176,18 @@ function NET:IsAnyBlocked(UCID,Name,PlayerID,PlayerSide,PlayerSlot)
|
|||||||
end
|
end
|
||||||
-- Name
|
-- Name
|
||||||
if Name and self.BlockedPilots[Name] and TNow < self.BlockedPilots[Name] then
|
if Name and self.BlockedPilots[Name] and TNow < self.BlockedPilots[Name] then
|
||||||
return true
|
blocked = true
|
||||||
end
|
end
|
||||||
-- Side
|
-- Side
|
||||||
if PlayerSide and self.BlockedSides[PlayerSide] and TNow < self.BlockedSides[PlayerSide] then
|
self:T({time = self.BlockedSides[PlayerSide]})
|
||||||
return true
|
if PlayerSide and type(self.BlockedSides[PlayerSide]) == "number" and TNow < self.BlockedSides[PlayerSide] then
|
||||||
|
blocked = true
|
||||||
end
|
end
|
||||||
-- Slot
|
-- Slot
|
||||||
if PlayerSlot and self.BlockedSlots[PlayerSlot] and TNow < self.BlockedSlots[PlayerSlot] then
|
if PlayerSlot and self.BlockedSlots[PlayerSlot] and TNow < self.BlockedSlots[PlayerSlot] then
|
||||||
return true
|
blocked = true
|
||||||
end
|
end
|
||||||
|
self:T("IsAnyBlocked: "..tostring(blocked))
|
||||||
return blocked
|
return blocked
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -200,19 +206,27 @@ function NET:_EventHandler(EventData)
|
|||||||
local ucid = self:GetPlayerUCID(nil,name) or "none"
|
local ucid = self:GetPlayerUCID(nil,name) or "none"
|
||||||
local PlayerID = self:GetPlayerIDByName(name) or "none"
|
local PlayerID = self:GetPlayerIDByName(name) or "none"
|
||||||
local PlayerSide, PlayerSlot = self:GetSlot(data.IniUnit)
|
local PlayerSide, PlayerSlot = self:GetSlot(data.IniUnit)
|
||||||
|
if not PlayerSide then PlayerSide = EventData.IniCoalition end
|
||||||
|
if not PlayerSlot then PlayerSlot = EventData.IniUnit:GetID() end
|
||||||
local TNow = timer.getTime()
|
local TNow = timer.getTime()
|
||||||
|
|
||||||
self:T(self.lid.."Event for: "..name.." | UCID: "..ucid)
|
self:T(self.lid.."Event for: "..name.." | UCID: "..ucid .. " | ID/SIDE/SLOT "..PlayerID.."/"..PlayerSide.."/"..PlayerSlot)
|
||||||
|
|
||||||
-- Joining
|
-- Joining
|
||||||
if data.id == EVENTS.PlayerEnterUnit or data.id == EVENTS.PlayerEnterAircraft then
|
if data.id == EVENTS.PlayerEnterUnit or data.id == EVENTS.PlayerEnterAircraft then
|
||||||
self:T(self.lid.."Pilot Joining: "..name.." | UCID: "..ucid.." | Event ID: "..data.id)
|
self:T(self.lid.."Pilot Joining: "..name.." | UCID: "..ucid.." | Event ID: "..data.id)
|
||||||
-- Check for blockages
|
-- Check for blockages
|
||||||
local blocked = self:IsAnyBlocked(ucid,name,PlayerID,PlayerSide,PlayerSlot)
|
local blocked = self:IsAnyBlocked(ucid,name,PlayerID,PlayerSide,PlayerSlot)
|
||||||
|
if blocked and PlayerID then -- and tonumber(PlayerID) ~= 1 then
|
||||||
if blocked and PlayerID and tonumber(PlayerID) ~= 1 then
|
self:T("Player blocked")
|
||||||
-- block pilot
|
-- block pilot
|
||||||
local outcome = net.force_player_slot(tonumber(PlayerID), 0, '' )
|
local outcome = net.force_player_slot(tonumber(PlayerID), PlayerSide, data.IniUnit:GetID() )
|
||||||
|
self:T({Blocked_worked=outcome})
|
||||||
|
if outcome == false then
|
||||||
|
local unit = data.IniUnit
|
||||||
|
local sched = TIMER:New(unit.Destroy,unit,3):Start(3)
|
||||||
|
self:__PlayerBlocked(5,unit,name,1)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
local client = CLIENT:FindByPlayerName(name) or data.IniUnit
|
local client = CLIENT:FindByPlayerName(name) or data.IniUnit
|
||||||
if not self.KnownPilots[name] or (self.KnownPilots[name] and TNow-self.KnownPilots[name].timestamp > 3) then
|
if not self.KnownPilots[name] or (self.KnownPilots[name] and TNow-self.KnownPilots[name].timestamp > 3) then
|
||||||
@@ -225,6 +239,7 @@ function NET:_EventHandler(EventData)
|
|||||||
slot = PlayerSlot,
|
slot = PlayerSlot,
|
||||||
timestamp = TNow,
|
timestamp = TNow,
|
||||||
}
|
}
|
||||||
|
--UTILS.PrintTableToLog(self.KnownPilots[name])
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -350,11 +365,10 @@ end
|
|||||||
|
|
||||||
--- Block a specific coalition side, does NOT automatically kick all players of that side or kick out joined players
|
--- Block a specific coalition side, does NOT automatically kick all players of that side or kick out joined players
|
||||||
-- @param #NET self
|
-- @param #NET self
|
||||||
-- @param #number side The side to block - 1 : Red, 2 : Blue
|
-- @param #number Side The side to block - 1 : Red, 2 : Blue
|
||||||
-- @param #number Seconds Seconds (optional) Number of seconds the player has to wait before rejoining.
|
-- @param #number Seconds Seconds (optional) Number of seconds the player has to wait before rejoining.
|
||||||
-- @return #NET self
|
-- @return #NET self
|
||||||
function NET:BlockSide(Side,Seconds)
|
function NET:BlockSide(Side,Seconds)
|
||||||
self:T({Side,Seconds})
|
|
||||||
local addon = Seconds or self.BlockTime
|
local addon = Seconds or self.BlockTime
|
||||||
if Side == 1 or Side == 2 then
|
if Side == 1 or Side == 2 then
|
||||||
self.BlockedSides[Side] = timer.getTime()+addon
|
self.BlockedSides[Side] = timer.getTime()+addon
|
||||||
@@ -367,10 +381,9 @@ end
|
|||||||
-- @param #number Seconds Seconds (optional) Number of seconds the player has to wait before rejoining.
|
-- @param #number Seconds Seconds (optional) Number of seconds the player has to wait before rejoining.
|
||||||
-- @return #NET self
|
-- @return #NET self
|
||||||
function NET:UnblockSide(Side,Seconds)
|
function NET:UnblockSide(Side,Seconds)
|
||||||
self:T({Side,Seconds})
|
|
||||||
local addon = Seconds or self.BlockTime
|
local addon = Seconds or self.BlockTime
|
||||||
if Side == 1 or Side == 2 then
|
if Side == 1 or Side == 2 then
|
||||||
self.BlockedSides[Side] = nil
|
self.BlockedSides[Side] = false
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -485,8 +498,11 @@ end
|
|||||||
-- @param Wrapper.Client#CLIENT Client The client
|
-- @param Wrapper.Client#CLIENT Client The client
|
||||||
-- @return #number PlayerID or nil
|
-- @return #number PlayerID or nil
|
||||||
function NET:GetPlayerIDFromClient(Client)
|
function NET:GetPlayerIDFromClient(Client)
|
||||||
|
self:T("GetPlayerIDFromClient")
|
||||||
|
self:T({Client=Client})
|
||||||
if Client then
|
if Client then
|
||||||
local name = Client:GetPlayerName()
|
local name = Client:GetPlayerName()
|
||||||
|
self:T({name=name})
|
||||||
local id = self:GetPlayerIDByName(name)
|
local id = self:GetPlayerIDByName(name)
|
||||||
return id
|
return id
|
||||||
else
|
else
|
||||||
@@ -682,16 +698,19 @@ end
|
|||||||
-- @return #number SideID i.e. 0 : spectators, 1 : Red, 2 : Blue
|
-- @return #number SideID i.e. 0 : spectators, 1 : Red, 2 : Blue
|
||||||
-- @return #number SlotID
|
-- @return #number SlotID
|
||||||
function NET:GetSlot(Client)
|
function NET:GetSlot(Client)
|
||||||
|
self:T("NET.GetSlot")
|
||||||
local PlayerID = self:GetPlayerIDFromClient(Client)
|
local PlayerID = self:GetPlayerIDFromClient(Client)
|
||||||
|
self:T("NET.GetSlot PlayerID = "..tostring(PlayerID))
|
||||||
if PlayerID then
|
if PlayerID then
|
||||||
local side,slot = net.get_slot(tonumber(PlayerID))
|
local side,slot = net.get_slot(tonumber(PlayerID))
|
||||||
|
self:T("NET.GetSlot side, slot = "..tostring(side)..","..tostring(slot))
|
||||||
return side,slot
|
return side,slot
|
||||||
else
|
else
|
||||||
return nil,nil
|
return nil,nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Force the slot for a specific client.
|
--- Force the slot for a specific client. If this returns false, it didn't work via `net` (which is ALWAYS the case as of Nov 2024)!
|
||||||
-- @param #NET self
|
-- @param #NET self
|
||||||
-- @param Wrapper.Client#CLIENT Client The client
|
-- @param Wrapper.Client#CLIENT Client The client
|
||||||
-- @param #number SideID i.e. 0 : spectators, 1 : Red, 2 : Blue
|
-- @param #number SideID i.e. 0 : spectators, 1 : Red, 2 : Blue
|
||||||
@@ -699,19 +718,22 @@ end
|
|||||||
-- @return #boolean Success
|
-- @return #boolean Success
|
||||||
function NET:ForceSlot(Client,SideID,SlotID)
|
function NET:ForceSlot(Client,SideID,SlotID)
|
||||||
local PlayerID = self:GetPlayerIDFromClient(Client)
|
local PlayerID = self:GetPlayerIDFromClient(Client)
|
||||||
if PlayerID and tonumber(PlayerID) ~= 1 then
|
local SlotID = SlotID or Client:GetID()
|
||||||
return net.force_player_slot(tonumber(PlayerID), SideID, SlotID or '' )
|
if PlayerID then -- and tonumber(PlayerID) ~= 1 then
|
||||||
|
return net.force_player_slot(tonumber(PlayerID), SideID, SlotID )
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Force a client back to spectators.
|
--- Force a client back to spectators. If this returns false, it didn't work via `net` (which is ALWAYS the case as of Nov 2024)!
|
||||||
-- @param #NET self
|
-- @param #NET self
|
||||||
-- @param Wrapper.Client#CLIENT Client The client
|
-- @param Wrapper.Client#CLIENT Client The client
|
||||||
-- @return #boolean Succes
|
-- @return #boolean Succes
|
||||||
function NET:ReturnToSpectators(Client)
|
function NET:ReturnToSpectators(Client)
|
||||||
local outcome = self:ForceSlot(Client,0)
|
local outcome = self:ForceSlot(Client,0)
|
||||||
|
-- workaround
|
||||||
|
local sched = TIMER:New(Client.Destroy,Client,1):Start(1)
|
||||||
return outcome
|
return outcome
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -781,7 +803,7 @@ function NET:onafterStatus(From,Event,To)
|
|||||||
local function HouseHold(tavolo)
|
local function HouseHold(tavolo)
|
||||||
local TNow = timer.getTime()
|
local TNow = timer.getTime()
|
||||||
for _,entry in pairs (tavolo) do
|
for _,entry in pairs (tavolo) do
|
||||||
if entry >= TNow then entry = nil end
|
if type(entry) == "number" and entry >= TNow then entry = false end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ function STATIC:Register( StaticName )
|
|||||||
if DCSStatic then
|
if DCSStatic then
|
||||||
local Life0 = DCSStatic:getLife() or 1
|
local Life0 = DCSStatic:getLife() or 1
|
||||||
self.Life0 = Life0
|
self.Life0 = Life0
|
||||||
|
else
|
||||||
|
self:E(string.format("Static object %s does not exist!", tostring(self.StaticName)))
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|||||||
@@ -240,7 +240,9 @@ end
|
|||||||
-- @return DCS#Unit The DCS Group.
|
-- @return DCS#Unit The DCS Group.
|
||||||
function UNIT:GetDCSObject()
|
function UNIT:GetDCSObject()
|
||||||
|
|
||||||
if (not self.LastCallDCSObject) or (self.LastCallDCSObject and timer.getTime() - self.LastCallDCSObject > 1) then
|
-- FF: Added checks that DCSObject exists because otherwise there were problems when respawning the unit right after it was initially spawned (e.g. teleport in OPSGROUP).
|
||||||
|
-- Got "Unit does not exit" after coalition.addGroup() when trying to access unit data because LastCallDCSObject<=1.
|
||||||
|
if (not self.LastCallDCSObject) or (self.LastCallDCSObject and timer.getTime()-self.LastCallDCSObject>1) or (self.DCSObject==nil) or (self.DCSObject:isExist()==false) then
|
||||||
|
|
||||||
-- Get DCS group.
|
-- Get DCS group.
|
||||||
local DCSUnit = Unit.getByName( self.UnitName )
|
local DCSUnit = Unit.getByName( self.UnitName )
|
||||||
|
|||||||
@@ -385,24 +385,26 @@ function WEAPON:GetTarget()
|
|||||||
|
|
||||||
--Target name
|
--Target name
|
||||||
local name=object:getName()
|
local name=object:getName()
|
||||||
|
|
||||||
-- Debug info.
|
if name then
|
||||||
self:T(self.lid..string.format("Got Target Object %s, category=%d", object:getName(), category))
|
|
||||||
|
-- Debug info.
|
||||||
if category==Object.Category.UNIT then
|
self:T(self.lid..string.format("Got Target Object %s, category=%d", name, category))
|
||||||
|
|
||||||
target=UNIT:FindByName(name)
|
if category==Object.Category.UNIT then
|
||||||
|
|
||||||
elseif category==Object.Category.STATIC then
|
target=UNIT:FindByName(name)
|
||||||
|
|
||||||
target=STATIC:FindByName(name, false)
|
elseif category==Object.Category.STATIC then
|
||||||
|
|
||||||
elseif category==Object.Category.SCENERY then
|
target=STATIC:FindByName(name, false)
|
||||||
self:E(self.lid..string.format("ERROR: Scenery target not implemented yet!"))
|
|
||||||
else
|
elseif category==Object.Category.SCENERY then
|
||||||
self:E(self.lid..string.format("ERROR: Object category=%d is not implemented yet!", category))
|
self:E(self.lid..string.format("ERROR: Scenery target not implemented yet!"))
|
||||||
|
else
|
||||||
|
self:E(self.lid..string.format("ERROR: Object category=%d is not implemented yet!", category))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user