mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-07-22 11:34:04 +00:00
Compare commits
138 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e0a5727ac5 | |||
| 7587119843 | |||
| a5880b89c1 | |||
| b33890ff03 | |||
| 1be2c92a5c | |||
| 4c8a17fe57 | |||
| 64dea17982 | |||
| b1f86c702d | |||
| 1a9540d0d4 | |||
| cdfaac527c | |||
| 4e3bf9969b | |||
| 74c16bd4f0 | |||
| 55e048b322 | |||
| b31fb7ece3 | |||
| 149e3421d9 | |||
| 338ec34604 | |||
| 3d79a16d3a | |||
| efa08c1280 | |||
| 589e65963f | |||
| af4f20af67 | |||
| b1b8630d21 | |||
| 98ed7d50c1 | |||
| 4ba81cb8bc | |||
| 626b12f486 | |||
| 36c0297344 | |||
| 8c60a8c678 | |||
| 6829d75464 | |||
| 867f919d5f | |||
| f769a0deb5 | |||
| 4efd71e36a | |||
| 7e9dd9deff | |||
| fed9174bcb | |||
| b6ea6606fc | |||
| 9963c737a3 | |||
| 5005203206 | |||
| a3455855b8 | |||
| 73d3ed119c | |||
| d1e4dd3fe9 | |||
| 23112c9954 | |||
| 9326cfad1c | |||
| 23c59d906f | |||
| cc62655ffe | |||
| b8e114101b | |||
| 401e9d9e8e | |||
| f083b77390 | |||
| db3bc3742e | |||
| 9b1a3e4894 | |||
| bf10196662 | |||
| 6c32aa6044 | |||
| edf70e971c | |||
| 7c5af54473 | |||
| a0420e1cb6 | |||
| 2aa9b91ce5 | |||
| 27bd27a2e5 | |||
| 8e219c5877 | |||
| fdc19a6898 | |||
| d3ebf023fb | |||
| 3d1dcd78a3 | |||
| d40c559d2d | |||
| 9cda1b88ea | |||
| 09f99b9a74 | |||
| ff5205e686 | |||
| ebd105f80d | |||
| cc8a4e0bad | |||
| 5f70e2d6b1 | |||
| 95f38fbf55 | |||
| aec3466f13 | |||
| 696630fe4d | |||
| 47aa524677 | |||
| 79f03c164c | |||
| ca7d3a48a7 | |||
| 2556dbe145 | |||
| af1e9546e5 | |||
| 3203a22668 | |||
| b69ac2f86f | |||
| 0d410f3e55 | |||
| cbe6756330 | |||
| 07045be32b | |||
| 52a2132463 | |||
| 9272b1f18c | |||
| b84880c0dd | |||
| a9be18b284 | |||
| 93178df67f | |||
| f34bf1e052 | |||
| e159eb83b7 | |||
| 2581836058 | |||
| d9651e1dea | |||
| 0347f185a5 | |||
| 5e2218de38 | |||
| 6db5441bb1 | |||
| 13b7e43729 | |||
| a72f7298d0 | |||
| 801cc105da | |||
| f186b4bd58 | |||
| 79f13fa6ae | |||
| d38fc4ec8f | |||
| ba1575d674 | |||
| 391182e23f | |||
| 6d5fb64fde | |||
| 5df1fb88f1 | |||
| 2e4d4f056a | |||
| a9ceda4edd | |||
| e76fd23396 | |||
| 7df1eb963f | |||
| aff1d3c7db | |||
| d15f6cdb44 | |||
| c59b668eec | |||
| 4620a83317 | |||
| 87d0c4e9d4 | |||
| 74361f6a3a | |||
| b82b882e02 | |||
| 347783d4b7 | |||
| 0b2f07ca6c | |||
| 7c5d5543e0 | |||
| 3d10716b1f | |||
| c48a7d4400 | |||
| 79130d4fe2 | |||
| aebb6ac0db | |||
| 3eb910b47e | |||
| 6223b8e1a7 | |||
| 533a4dfa6c | |||
| dbc752253b | |||
| 7f074781f4 | |||
| ab77fcbc1f | |||
| 56520092c3 | |||
| 252a1b0761 | |||
| 51e5f53965 | |||
| b0976d1613 | |||
| a737ca71e6 | |||
| 1071300a7f | |||
| 2490958090 | |||
| b78b76e579 | |||
| efff22fc18 | |||
| 4b27e92210 | |||
| f2063f41f6 | |||
| 12241e931a | |||
| 4cb6debef8 | |||
| efe4bf3912 |
@@ -736,6 +736,12 @@ do -- Event Handling
|
|||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
|
--- Occurs when an option is changed for an AI group.
|
||||||
|
-- The event identifies the initiating group, but does not provide the option ID or value.
|
||||||
|
-- @function [parent=#BASE] OnEventGroupChangeOption
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs when a player creates a dynamic cargo object from the F8 ground crew menu.
|
--- Occurs when a player creates a dynamic cargo object from the F8 ground crew menu.
|
||||||
-- *** NOTE *** this is a workarounf for DCS not creating these events as of Aug 2024.
|
-- *** NOTE *** this is a workarounf for DCS not creating these events as of Aug 2024.
|
||||||
-- @function [parent=#BASE] OnEventNewDynamicCargo
|
-- @function [parent=#BASE] OnEventNewDynamicCargo
|
||||||
@@ -855,7 +861,7 @@ end
|
|||||||
-- @param DCS#Time EventTime The time stamp of the event.
|
-- @param DCS#Time EventTime The time stamp of the event.
|
||||||
-- @param DCS#Object Initiator The initiating object of the event.
|
-- @param DCS#Object Initiator The initiating object of the event.
|
||||||
function BASE:CreateEventTakeoff( EventTime, Initiator )
|
function BASE:CreateEventTakeoff( EventTime, Initiator )
|
||||||
self:F( { EventTime, Initiator } )
|
--self:F( { EventTime, Initiator } )
|
||||||
|
|
||||||
local Event = {
|
local Event = {
|
||||||
id = world.event.S_EVENT_TAKEOFF,
|
id = world.event.S_EVENT_TAKEOFF,
|
||||||
@@ -881,6 +887,22 @@ end
|
|||||||
world.onEvent(Event)
|
world.onEvent(Event)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Creation of a `S_EVENT_GROUP_CHANGE_OPTION` event.
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param DCS#Time EventTime The time stamp of the event.
|
||||||
|
-- @param DCS#Group Initiator The initiating group of the event.
|
||||||
|
function BASE:CreateEventGroupChangeOption( EventTime, Initiator )
|
||||||
|
self:F( { EventTime, Initiator } )
|
||||||
|
|
||||||
|
local Event = {
|
||||||
|
id = EVENTS.GroupChangeOption,
|
||||||
|
time = EventTime,
|
||||||
|
initiator = Initiator,
|
||||||
|
}
|
||||||
|
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
--- Creation of a S_EVENT_NEW_DYNAMIC_CARGO event.
|
--- Creation of a S_EVENT_NEW_DYNAMIC_CARGO event.
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||||
|
|||||||
@@ -1380,12 +1380,12 @@ function DATABASE:_RegisterDynamicGroup(Groupname)
|
|||||||
local DCSUnitName = DCSUnit:getName()
|
local DCSUnitName = DCSUnit:getName()
|
||||||
|
|
||||||
-- Add unit.
|
-- Add unit.
|
||||||
self:I(string.format("Register Unit: %s", tostring(DCSUnitName)))
|
self:T(string.format("Register Unit: %s", tostring(DCSUnitName)))
|
||||||
self:AddUnit( tostring(DCSUnitName), true )
|
self:AddUnit( tostring(DCSUnitName), true )
|
||||||
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:E({"Group does not exist: ", DCSGroup})
|
self:T({"Group does not exist: ", DCSGroup})
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1488,27 +1488,28 @@ end
|
|||||||
-- @return #DATABASE self
|
-- @return #DATABASE self
|
||||||
function DATABASE:_RegisterAirbase(airbase)
|
function DATABASE:_RegisterAirbase(airbase)
|
||||||
|
|
||||||
local IsSyria = UTILS.GetDCSMap() == "Syria" and true or false
|
--local IsSyria = UTILS.GetDCSMap() == "Syria" and true or false
|
||||||
local countHSyria = 0
|
--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 ..
|
--[[ 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
|
if IsSyria and DCSAirbaseName == "H" and countHSyria > 0 then
|
||||||
--[[
|
--
|
||||||
local p = airbase:getPosition().p
|
local p = airbase:getPosition().p
|
||||||
local mgrs = COORDINATE:New(p.x,p.z,p.y):ToStringMGRS()
|
local mgrs = COORDINATE:New(p.x,p.z,p.y):ToStringMGRS()
|
||||||
self:I("Airbase on Syria map named H @ "..mgrs)
|
self:I("Airbase on Syria map named H @ "..mgrs)
|
||||||
countHSyria = countHSyria + 1
|
countHSyria = countHSyria + 1
|
||||||
if countHSyria > 1 then return self end
|
if countHSyria > 1 then return self end
|
||||||
--]]
|
--
|
||||||
return self
|
return self
|
||||||
elseif IsSyria and DCSAirbaseName == "H" and countHSyria == 0 then
|
elseif IsSyria and DCSAirbaseName == "H" and countHSyria == 0 then
|
||||||
countHSyria = countHSyria + 1
|
countHSyria = countHSyria + 1
|
||||||
end
|
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()
|
||||||
|
|||||||
@@ -278,6 +278,7 @@ EVENTS = {
|
|||||||
SimulationUnfreeze = world.event.S_EVENT_SIMULATION_UNFREEZE or -1,
|
SimulationUnfreeze = world.event.S_EVENT_SIMULATION_UNFREEZE or -1,
|
||||||
HumanAircraftRepairStart = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_START or -1,
|
HumanAircraftRepairStart = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_START or -1,
|
||||||
HumanAircraftRepairFinish = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH or -1,
|
HumanAircraftRepairFinish = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH or -1,
|
||||||
|
GroupChangeOption = world.event.S_EVENT_GROUP_CHANGE_OPTION or -1,
|
||||||
-- dynamic cargo
|
-- dynamic cargo
|
||||||
NewDynamicCargo = world.event.S_EVENT_NEW_DYNAMIC_CARGO or -1,
|
NewDynamicCargo = world.event.S_EVENT_NEW_DYNAMIC_CARGO or -1,
|
||||||
DynamicCargoLoaded = world.event.S_EVENT_DYNAMIC_CARGO_LOADED or -1,
|
DynamicCargoLoaded = world.event.S_EVENT_DYNAMIC_CARGO_LOADED or -1,
|
||||||
@@ -291,23 +292,25 @@ EVENTS = {
|
|||||||
--
|
--
|
||||||
-- * A (Object.Category.)UNIT : A UNIT object type is involved in the Event.
|
-- * A (Object.Category.)UNIT : A UNIT object type is involved in the Event.
|
||||||
-- * A (Object.Category.)STATIC : A STATIC object type is involved in the Event.
|
-- * A (Object.Category.)STATIC : A STATIC object type is involved in the Event.
|
||||||
|
-- * A GROUP : A DCS Group object is involved in the Event.
|
||||||
--
|
--
|
||||||
-- @type EVENTDATA
|
-- @type EVENTDATA
|
||||||
-- @field #number id The identifier of the event.
|
-- @field #number id The identifier of the event.
|
||||||
--
|
--
|
||||||
-- @field DCS#Unit initiator (UNIT/STATIC/SCENERY) The initiating @{DCS#Unit} or @{DCS#StaticObject}.
|
-- @field DCS#Unit initiator (UNIT/STATIC/SCENERY/GROUP) The initiating @{DCS#Unit} or @{DCS#StaticObject}. For `S_EVENT_GROUP_CHANGE_OPTION`, this is a DCS Group.
|
||||||
-- @field DCS#Object.Category IniObjectCategory (UNIT/STATIC/SCENERY) The initiator object category ( Object.Category.UNIT or Object.Category.STATIC ).
|
-- @field DCS#Object.Category IniObjectCategory (UNIT/STATIC/SCENERY) The initiator object category ( Object.Category.UNIT or Object.Category.STATIC ).
|
||||||
-- @field DCS#Unit IniDCSUnit (UNIT/STATIC) The initiating @{DCS#Unit} or @{DCS#StaticObject}.
|
-- @field DCS#Unit IniDCSUnit (UNIT/STATIC) The initiating @{DCS#Unit} or @{DCS#StaticObject}.
|
||||||
-- @field #string IniDCSUnitName (UNIT/STATIC) The initiating Unit name.
|
-- @field #string IniDCSUnitName (UNIT/STATIC) The initiating Unit name.
|
||||||
-- @field Wrapper.Unit#UNIT IniUnit (UNIT/STATIC) The initiating MOOSE wrapper @{Wrapper.Unit#UNIT} of the initiator Unit object.
|
-- @field Wrapper.Unit#UNIT IniUnit (UNIT/STATIC) The initiating MOOSE wrapper @{Wrapper.Unit#UNIT} of the initiator Unit object.
|
||||||
-- @field #string IniUnitName (UNIT/STATIC) The initiating UNIT name (same as IniDCSUnitName).
|
-- @field #string IniUnitName (UNIT/STATIC) The initiating UNIT name (same as IniDCSUnitName).
|
||||||
-- @field DCS#Group IniDCSGroup (UNIT) The initiating {DCSGroup#Group}.
|
-- @field DCS#Group IniDCSGroup (UNIT/GROUP) The initiating @{DCS#Group}.
|
||||||
-- @field #string IniDCSGroupName (UNIT) The initiating Group name.
|
-- @field #string IniDCSGroupName (UNIT/GROUP) The initiating Group name.
|
||||||
-- @field Wrapper.Group#GROUP IniGroup (UNIT) The initiating MOOSE wrapper @{Wrapper.Group#GROUP} of the initiator Group object.
|
-- @field Wrapper.Group#GROUP IniGroup (UNIT/GROUP) The initiating MOOSE wrapper @{Wrapper.Group#GROUP} of the initiator Group object.
|
||||||
-- @field #string IniGroupName UNIT) The initiating GROUP name (same as IniDCSGroupName).
|
-- @field #string IniGroupName (UNIT/GROUP) The initiating GROUP name (same as IniDCSGroupName).
|
||||||
|
-- @field DCS#Group.Category IniGroupCategory (GROUP) The category of the initiating group.
|
||||||
-- @field #string IniPlayerName (UNIT) The name of the initiating player in case the Unit is a client or player slot.
|
-- @field #string IniPlayerName (UNIT) The name of the initiating player in case the Unit is a client or player slot.
|
||||||
-- @field #string IniPlayerUCID (UNIT) The UCID of the initiating player in case the Unit is a client or player slot and on a multi-player server.
|
-- @field #string IniPlayerUCID (UNIT) The UCID of the initiating player in case the Unit is a client or player slot and on a multi-player server.
|
||||||
-- @field DCS#coalition.side IniCoalition (UNIT) The coalition of the initiator.
|
-- @field DCS#coalition.side IniCoalition (UNIT/GROUP) The coalition of the initiator.
|
||||||
-- @field DCS#Unit.Category IniCategory (UNIT) The category of the initiator.
|
-- @field DCS#Unit.Category IniCategory (UNIT) The category of the initiator.
|
||||||
-- @field #string IniTypeName (UNIT) The type name of the initiator.
|
-- @field #string IniTypeName (UNIT) The type name of the initiator.
|
||||||
--
|
--
|
||||||
@@ -734,6 +737,12 @@ local _EVENTMETA = {
|
|||||||
Side = "I",
|
Side = "I",
|
||||||
Event = "OnEventHumanAircraftRepairFinish",
|
Event = "OnEventHumanAircraftRepairFinish",
|
||||||
Text = "S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH"
|
Text = "S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH"
|
||||||
|
},
|
||||||
|
[EVENTS.GroupChangeOption] = {
|
||||||
|
Order = 1,
|
||||||
|
Side = "I",
|
||||||
|
Event = "OnEventGroupChangeOption",
|
||||||
|
Text = "S_EVENT_GROUP_CHANGE_OPTION"
|
||||||
},
|
},
|
||||||
-- dynamic cargo
|
-- dynamic cargo
|
||||||
[EVENTS.NewDynamicCargo] = {
|
[EVENTS.NewDynamicCargo] = {
|
||||||
@@ -1234,7 +1243,16 @@ function EVENT:onEvent( Event )
|
|||||||
|
|
||||||
if Event.initiator then
|
if Event.initiator then
|
||||||
|
|
||||||
Event.IniObjectCategory = Object.getCategory(Event.initiator)
|
if Event.id == EVENTS.GroupChangeOption then
|
||||||
|
Event.IniDCSGroup = Event.initiator
|
||||||
|
Event.IniDCSGroupName = Group.getName(Event.initiator)
|
||||||
|
Event.IniGroupName = Event.IniDCSGroupName
|
||||||
|
Event.IniGroup = GROUP:FindByName(Event.IniDCSGroupName)
|
||||||
|
Event.IniCoalition = Group.getCoalition(Event.initiator)
|
||||||
|
Event.IniGroupCategory = Group.getCategory(Event.initiator)
|
||||||
|
else
|
||||||
|
Event.IniObjectCategory = Object.getCategory(Event.initiator)
|
||||||
|
end
|
||||||
|
|
||||||
if Event.IniObjectCategory == Object.Category.STATIC then
|
if Event.IniObjectCategory == Object.Category.STATIC then
|
||||||
---
|
---
|
||||||
@@ -1453,7 +1471,12 @@ function EVENT:onEvent( Event )
|
|||||||
-- Weapon.
|
-- Weapon.
|
||||||
if Event.weapon and type(Event.weapon) == "table" and Event.weapon.isExist and Event.weapon:isExist() then
|
if Event.weapon and type(Event.weapon) == "table" and Event.weapon.isExist and Event.weapon:isExist() then
|
||||||
Event.Weapon = Event.weapon
|
Event.Weapon = Event.weapon
|
||||||
Event.WeaponName = Event.weapon:isExist() and Event.weapon:getTypeName() or "Unknown Weapon"
|
if Event.weapon_name == "ZELL Booster" then
|
||||||
|
Event.WeaponName = "ZELL Booster"
|
||||||
|
else
|
||||||
|
Event.WeaponName = Event.weapon:isExist() and Event.weapon.getTypeName and Event.weapon:getTypeName() or "Unknown Weapon"
|
||||||
|
end
|
||||||
|
if Event.weapon_name == "ZELL Booster" then Event.WeaponName = "ZELL Booster" end
|
||||||
Event.WeaponUNIT = CLIENT:Find( Event.Weapon, '', true ) -- Sometimes, the weapon is a player unit!
|
Event.WeaponUNIT = CLIENT:Find( Event.Weapon, '', true ) -- Sometimes, the weapon is a player unit!
|
||||||
Event.WeaponPlayerName = Event.WeaponUNIT and Event.Weapon.getPlayerName and Event.Weapon:getPlayerName()
|
Event.WeaponPlayerName = Event.WeaponUNIT and Event.Weapon.getPlayerName and Event.Weapon:getPlayerName()
|
||||||
--Event.WeaponPlayerName = Event.WeaponUNIT and Event.Weapon:getPlayerName()
|
--Event.WeaponPlayerName = Event.WeaponUNIT and Event.Weapon:getPlayerName()
|
||||||
|
|||||||
@@ -869,10 +869,21 @@ do
|
|||||||
local MenuTable = {}
|
local MenuTable = {}
|
||||||
for MenuText, Menu in pairs( self.Menus or {} ) do
|
for MenuText, Menu in pairs( self.Menus or {} ) do
|
||||||
local tag = Menu.MenuTag or math.random(1,10000)
|
local tag = Menu.MenuTag or math.random(1,10000)
|
||||||
MenuTable[#MenuTable+1] = {Tag=tag, Enty=Menu}
|
MenuTable[#MenuTable+1] = {Tag=tag, Entry=Menu}
|
||||||
end
|
end
|
||||||
table.sort(MenuTable, function (k1, k2) return k1.tag < k2.tag end )
|
local function SortTable(k1,k2)
|
||||||
for _, Menu in pairs( MenuTable ) do
|
if not k1 then
|
||||||
|
if not k2 then return true else return false end
|
||||||
|
elseif not k2 then
|
||||||
|
if not k1 then return true else return false end
|
||||||
|
else
|
||||||
|
return (k1.Tag or 15) <= (k2.Tag or 15)
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
table.sort(MenuTable, SortTable)
|
||||||
|
--table.sort(MenuTable, function (k1, k2) return (k1.tag or 15) <= (k2.tag or 15) end )
|
||||||
|
for _, Menu in ipairs( MenuTable ) do
|
||||||
Menu.Entry:Refresh()
|
Menu.Entry:Refresh()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -375,3 +375,13 @@ function SCHEDULEDISPATCHER:NoTrace( Scheduler )
|
|||||||
Scheduler.ShowTrace = false
|
Scheduler.ShowTrace = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Helper for memory cleanup for self stopping schedulers
|
||||||
|
-- @param #SCHEDULEDISPATCHER self
|
||||||
|
-- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object.
|
||||||
|
-- @param #string CallID (Optional) Scheduler Call ID.
|
||||||
|
function SCHEDULEDISPATCHER:_Reclaim( Scheduler, CallID )
|
||||||
|
self:Stop( Scheduler, CallID ) -- remove DCS timer, nil ScheduleID
|
||||||
|
if self.Schedule[Scheduler] then self.Schedule[Scheduler][CallID] = nil end
|
||||||
|
self.ObjectSchedulers[CallID] = nil
|
||||||
|
self.PersistentSchedulers[CallID] = nil
|
||||||
|
end
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ do -- SET_BASE
|
|||||||
-- @field #table List Unused table.
|
-- @field #table List Unused table.
|
||||||
-- @field Core.Scheduler#SCHEDULER CallScheduler
|
-- @field Core.Scheduler#SCHEDULER CallScheduler
|
||||||
-- @field #SET_BASE.Filters Filter Filters
|
-- @field #SET_BASE.Filters Filter Filters
|
||||||
-- @field #booleaen filterNoRegex If true, FilterPrefix ignores special characters and evaluates plain string.
|
-- @field #boolean filterNoRegex If true, FilterPrefix ignores special characters and evaluates plain string. Defaults to false.
|
||||||
|
-- @field #boolean filterReplaceDash If true then if filterNoRegex is false, replace dashes with regex pattern friendly pattern. Defaults to true
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
--- The @{Core.Set#SET_BASE} class defines the core functions that define a collection of objects.
|
--- The @{Core.Set#SET_BASE} class defines the core functions that define a collection of objects.
|
||||||
@@ -102,6 +103,7 @@ do -- SET_BASE
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
filterNoRegex=false,
|
filterNoRegex=false,
|
||||||
|
filterReplaceDash=true,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Filters
|
--- Filters
|
||||||
@@ -256,7 +258,8 @@ do -- SET_BASE
|
|||||||
-- @return #boolean Returns `true`, if the pattern is contained in the name and false otherwise.
|
-- @return #boolean Returns `true`, if the pattern is contained in the name and false otherwise.
|
||||||
function SET_BASE:_SearchPattern(Name, Pattern, NoRegex, ReplaceDash)
|
function SET_BASE:_SearchPattern(Name, Pattern, NoRegex, ReplaceDash)
|
||||||
NoRegex=NoRegex or self.filterNoRegex
|
NoRegex=NoRegex or self.filterNoRegex
|
||||||
if ReplaceDash==true then
|
ReplaceDash=ReplaceDash or self.filterReplaceDash
|
||||||
|
if ReplaceDash==true and NoRegex ~= true then
|
||||||
-- Not sure why "-" is replaced by "%-" ?! - So we can still match group names with a dash in them
|
-- Not sure why "-" is replaced by "%-" ?! - So we can still match group names with a dash in them
|
||||||
-- reason is that the string is interpreted as a pattern and "-" is a special character then. For interpreting it as a string, fourth parameter needs to be set to true.
|
-- reason is that the string is interpreted as a pattern and "-" is a special character then. For interpreting it as a string, fourth parameter needs to be set to true.
|
||||||
Pattern=Pattern:gsub("-", "%%-")
|
Pattern=Pattern:gsub("-", "%%-")
|
||||||
@@ -265,6 +268,16 @@ do -- SET_BASE
|
|||||||
return contain
|
return contain
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Set Regex Options for FilterPrefix function.
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||||
|
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||||
|
-- @return #SET_BASE self
|
||||||
|
function SET_BASE:FilterSetRegex(NoRegex,ReplaceDash)
|
||||||
|
if NoRegex ~= nil then self.filterNoRegex = NoRegex end
|
||||||
|
self.filterReplaceDash = ReplaceDash or true
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Gets the Set.
|
--- Gets the Set.
|
||||||
-- @param #SET_BASE self
|
-- @param #SET_BASE self
|
||||||
@@ -1198,6 +1211,20 @@ do
|
|||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
-- @return #SET_GROUP self
|
-- @return #SET_GROUP self
|
||||||
|
|
||||||
|
---Set Regex Options for FilterPrefix function.
|
||||||
|
-- @function [parent=#SET_GROUP] FilterSetRegex
|
||||||
|
-- @param #SET_GROUP self
|
||||||
|
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||||
|
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||||
|
-- @return #SET_GROUP self
|
||||||
|
|
||||||
|
--- Builds a set of objects of same coalitions.
|
||||||
|
-- Possible current coalitions are red, blue and neutral.
|
||||||
|
-- @function [parent=#SET_GROUP] FilterCoalitions
|
||||||
|
-- @param #SET_GROUP self
|
||||||
|
-- @param #string Coalitions Can take the following values: "red", "blue", "neutral" and coalition.side.RED, coalition.side.BLUE,coalition.side.NEUTRAL
|
||||||
|
-- @param #boolean Clear If `true`, clear any previously defined filters.
|
||||||
|
-- @return #SET_GROUP self
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2116,7 +2143,7 @@ do
|
|||||||
if self.Filter.GroupPrefixes and MGroupInclude then
|
if self.Filter.GroupPrefixes and MGroupInclude then
|
||||||
local MGroupPrefix = false
|
local MGroupPrefix = false
|
||||||
for GroupPrefixId, GroupPrefix in pairs(self.Filter.GroupPrefixes) do
|
for GroupPrefixId, GroupPrefix in pairs(self.Filter.GroupPrefixes) do
|
||||||
if self:_SearchPattern(MGroup:GetName(), GroupPrefix, false, true) then
|
if self:_SearchPattern(MGroup:GetName(), GroupPrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||||
MGroupPrefix = true
|
MGroupPrefix = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -2337,6 +2364,26 @@ do -- SET_UNIT
|
|||||||
-- @param #SET_UNIT self
|
-- @param #SET_UNIT self
|
||||||
-- @return #SET_UNIT self
|
-- @return #SET_UNIT self
|
||||||
|
|
||||||
|
--- Filter the set once
|
||||||
|
-- @function [parent=#SET_UNIT] FilterOnce
|
||||||
|
-- @param #SET_UNIT self
|
||||||
|
-- @return #SET_UNIT self
|
||||||
|
|
||||||
|
---Set Regex Options for FilterPrefix function.
|
||||||
|
-- @function [parent=#SET_UNIT] FilterSetRegex
|
||||||
|
-- @param #SET_UNIT self
|
||||||
|
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||||
|
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||||
|
-- @return #SET_UNIT self
|
||||||
|
|
||||||
|
--- Builds a set of objects of same coalitions.
|
||||||
|
-- Possible current coalitions are red, blue and neutral.
|
||||||
|
-- @function [parent=#SET_UNIT] FilterCoalitions
|
||||||
|
-- @param #SET_UNIT self
|
||||||
|
-- @param #string Coalitions Can take the following values: "red", "blue", "neutral" and coalition.side.RED, coalition.side.BLUE,coalition.side.NEUTRAL
|
||||||
|
-- @param #boolean Clear If `true`, clear any previously defined filters.
|
||||||
|
-- @return #SET_UNIT self
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -3348,7 +3395,7 @@ do -- SET_UNIT
|
|||||||
if self.Filter.UnitPrefixes and MUnitInclude then
|
if self.Filter.UnitPrefixes and MUnitInclude then
|
||||||
local MUnitPrefix = false
|
local MUnitPrefix = false
|
||||||
for UnitPrefixId, UnitPrefix in pairs(self.Filter.UnitPrefixes) do
|
for UnitPrefixId, UnitPrefix in pairs(self.Filter.UnitPrefixes) do
|
||||||
if self:_SearchPattern(MUnit:GetName(), UnitPrefix, false, true) then
|
if self:_SearchPattern(MUnit:GetName(), UnitPrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||||
MUnitPrefix = true
|
MUnitPrefix = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -3545,6 +3592,26 @@ do -- SET_STATIC
|
|||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.STATICS)) -- Core.Set#SET_STATIC
|
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.STATICS)) -- Core.Set#SET_STATIC
|
||||||
|
|
||||||
|
--- Filter the set once
|
||||||
|
-- @function [parent=#SET_STATIC] FilterOnce
|
||||||
|
-- @param #SET_STATIC self
|
||||||
|
-- @return #SET_STATIC self
|
||||||
|
|
||||||
|
---Set Regex Options for FilterPrefix function.
|
||||||
|
-- @function [parent=#SET_STATIC] FilterSetRegex
|
||||||
|
-- @param #SET_STATIC self
|
||||||
|
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||||
|
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||||
|
-- @return #SET_STATIC self
|
||||||
|
|
||||||
|
--- Builds a set of objects of same coalitions.
|
||||||
|
-- Possible current coalitions are red, blue and neutral.
|
||||||
|
-- @function [parent=#SET_STATIC] FilterCoalitions
|
||||||
|
-- @param #SET_STATIC self
|
||||||
|
-- @param #string Coalitions Can take the following values: "red", "blue", "neutral" and coalition.side.RED, coalition.side.BLUE,coalition.side.NEUTRAL
|
||||||
|
-- @param #boolean Clear If `true`, clear any previously defined filters.
|
||||||
|
-- @return #SET_STATIC self
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -4119,7 +4186,7 @@ do -- SET_STATIC
|
|||||||
if self.Filter.StaticPrefixes then
|
if self.Filter.StaticPrefixes then
|
||||||
local MStaticPrefix = false
|
local MStaticPrefix = false
|
||||||
for StaticPrefixId, StaticPrefix in pairs(self.Filter.StaticPrefixes) do
|
for StaticPrefixId, StaticPrefix in pairs(self.Filter.StaticPrefixes) do
|
||||||
if self:_SearchPattern(MStatic:GetName(), StaticPrefix, false, true) then
|
if self:_SearchPattern(MStatic:GetName(), StaticPrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||||
MStaticPrefix = true
|
MStaticPrefix = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -4304,6 +4371,26 @@ do -- SET_CLIENT
|
|||||||
|
|
||||||
self:FilterActive(false)
|
self:FilterActive(false)
|
||||||
|
|
||||||
|
--- Filter the set once
|
||||||
|
-- @function [parent=#SET_CLIENT] FilterOnce
|
||||||
|
-- @param #SET_CLIENT self
|
||||||
|
-- @return #SET_CLIENT self
|
||||||
|
|
||||||
|
---Set Regex Options for FilterPrefix function.
|
||||||
|
-- @function [parent=#SET_CLIENT] FilterSetRegex
|
||||||
|
-- @param #SET_CLIENT self
|
||||||
|
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||||
|
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||||
|
-- @return #SET_CLIENT self
|
||||||
|
|
||||||
|
--- Builds a set of objects of same coalitions.
|
||||||
|
-- Possible current coalitions are red, blue and neutral.
|
||||||
|
-- @function [parent=#SET_CLIENT] FilterCoalitions
|
||||||
|
-- @param #SET_CLIENT self
|
||||||
|
-- @param #string Coalitions Can take the following values: "red", "blue", "neutral" and coalition.side.RED, coalition.side.BLUE,coalition.side.NEUTRAL
|
||||||
|
-- @param #boolean Clear If `true`, clear any previously defined filters.
|
||||||
|
-- @return #SET_CLIENT self
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -4902,7 +4989,7 @@ do -- SET_CLIENT
|
|||||||
if self.Filter.ClientPrefixes and MClientInclude then
|
if self.Filter.ClientPrefixes and MClientInclude then
|
||||||
local MClientPrefix = false
|
local MClientPrefix = false
|
||||||
for ClientPrefixId, ClientPrefix in pairs(self.Filter.ClientPrefixes) do
|
for ClientPrefixId, ClientPrefix in pairs(self.Filter.ClientPrefixes) do
|
||||||
if self:_SearchPattern(MClient.UnitName, ClientPrefix) then
|
if self:_SearchPattern(MClient.UnitName, ClientPrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||||
MClientPrefix = true
|
MClientPrefix = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -4926,7 +5013,7 @@ do -- SET_CLIENT
|
|||||||
local playername = MClient:GetPlayerName() or "Unknown"
|
local playername = MClient:GetPlayerName() or "Unknown"
|
||||||
--self:T(playername)
|
--self:T(playername)
|
||||||
for _,_Playername in pairs(self.Filter.Playernames) do
|
for _,_Playername in pairs(self.Filter.Playernames) do
|
||||||
if playername and self:_SearchPattern(playername,_Playername) then
|
if playername and self:_SearchPattern(playername,_Playername,self.filterNoRegex, self.filterReplaceDash) then
|
||||||
MClientPlayername = true
|
MClientPlayername = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -4939,7 +5026,7 @@ do -- SET_CLIENT
|
|||||||
local callsign = MClient:GetCallsign()
|
local callsign = MClient:GetCallsign()
|
||||||
--self:I(callsign)
|
--self:I(callsign)
|
||||||
for _,_Callsign in pairs(self.Filter.Callsigns) do
|
for _,_Callsign in pairs(self.Filter.Callsigns) do
|
||||||
if callsign and self:_SearchPattern(callsign,_Callsign, true) then
|
if callsign and self:_SearchPattern(callsign,_Callsign, self.filterNoRegex, self.filterReplaceDash) then
|
||||||
MClientCallsigns = true
|
MClientCallsigns = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -5360,7 +5447,7 @@ do -- SET_PLAYER
|
|||||||
if self.Filter.ClientPrefixes then
|
if self.Filter.ClientPrefixes then
|
||||||
local MClientPrefix = false
|
local MClientPrefix = false
|
||||||
for ClientPrefixId, ClientPrefix in pairs(self.Filter.ClientPrefixes) do
|
for ClientPrefixId, ClientPrefix in pairs(self.Filter.ClientPrefixes) do
|
||||||
if self:_SearchPattern(MClient.UnitName,ClientPrefix) then
|
if self:_SearchPattern(MClient.UnitName,ClientPrefix,self.filterNoRegex, self.filterReplaceDash) then
|
||||||
MClientPrefix = true
|
MClientPrefix = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -5831,6 +5918,18 @@ do -- SET_ZONE
|
|||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.ZONES))
|
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.ZONES))
|
||||||
|
|
||||||
|
--- Filter the set once
|
||||||
|
-- @function [parent=#SET_ZONE] FilterOnce
|
||||||
|
-- @param #SET_ZONE self
|
||||||
|
-- @return #SET_ZONE self
|
||||||
|
|
||||||
|
---Set Regex Options for FilterPrefix function.
|
||||||
|
-- @function [parent=#SET_ZONE] FilterSetRegex
|
||||||
|
-- @param #SET_ZONE self
|
||||||
|
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||||
|
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||||
|
-- @return #SET_ZONE self
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -6068,7 +6167,7 @@ do -- SET_ZONE
|
|||||||
if self.Filter.Prefixes then
|
if self.Filter.Prefixes then
|
||||||
local MZonePrefix = false
|
local MZonePrefix = false
|
||||||
for ZonePrefixId, ZonePrefix in pairs(self.Filter.Prefixes) do
|
for ZonePrefixId, ZonePrefix in pairs(self.Filter.Prefixes) do
|
||||||
if self:_SearchPattern(MZoneName, ZonePrefix, false, true) then
|
if self:_SearchPattern(MZoneName, ZonePrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||||
MZonePrefix = true
|
MZonePrefix = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -6577,7 +6676,7 @@ do -- SET_ZONE_GOAL
|
|||||||
if self.Filter.Prefixes then
|
if self.Filter.Prefixes then
|
||||||
local MZonePrefix = false
|
local MZonePrefix = false
|
||||||
for ZonePrefixId, ZonePrefix in pairs(self.Filter.Prefixes) do
|
for ZonePrefixId, ZonePrefix in pairs(self.Filter.Prefixes) do
|
||||||
if self:_SearchPattern(MZoneName, ZonePrefix, false, true) then
|
if self:_SearchPattern(MZoneName, ZonePrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||||
MZonePrefix = true
|
MZonePrefix = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -6714,6 +6813,18 @@ do -- SET_OPSZONE
|
|||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.OPSZONES))
|
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.OPSZONES))
|
||||||
|
|
||||||
|
--- Filter the set once
|
||||||
|
-- @function [parent=#SET_OPSZONE] FilterOnce
|
||||||
|
-- @param #SET_OPSZONE self
|
||||||
|
-- @return #SET_OPSZONE self
|
||||||
|
|
||||||
|
---Set Regex Options for FilterPrefix function.
|
||||||
|
-- @function [parent=#SET_OPSZONE] FilterSetRegex
|
||||||
|
-- @param #SET_OPSZONE self
|
||||||
|
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||||
|
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||||
|
-- @return #SET_OPSZONE self
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -6938,7 +7049,7 @@ do -- SET_OPSZONE
|
|||||||
for ZonePrefixId, ZonePrefix in pairs(self.Filter.Prefixes) do
|
for ZonePrefixId, ZonePrefix in pairs(self.Filter.Prefixes) do
|
||||||
|
|
||||||
-- Prefix
|
-- Prefix
|
||||||
if self:_SearchPattern(MZoneName, ZonePrefix, false, true) then
|
if self:_SearchPattern(MZoneName, ZonePrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||||
MZonePrefix = true
|
MZonePrefix = true
|
||||||
break --Break the loop as we found the prefix.
|
break --Break the loop as we found the prefix.
|
||||||
end
|
end
|
||||||
@@ -7732,7 +7843,7 @@ function SET_OPSGROUP:_EventOnBirth(Event)
|
|||||||
local MGroupPrefix = false
|
local MGroupPrefix = false
|
||||||
|
|
||||||
for GroupPrefixId, GroupPrefix in pairs(self.Filter.GroupPrefixes) do
|
for GroupPrefixId, GroupPrefix in pairs(self.Filter.GroupPrefixes) do
|
||||||
if self:_SearchPattern(MGroup:GetName(), GroupPrefix, false, true) then
|
if self:_SearchPattern(MGroup:GetName(), GroupPrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||||
MGroupPrefix = true
|
MGroupPrefix = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -8066,7 +8177,7 @@ do -- SET_SCENERY
|
|||||||
if self.Filter.Prefixes then
|
if self.Filter.Prefixes then
|
||||||
local MSceneryPrefix = false
|
local MSceneryPrefix = false
|
||||||
for ZonePrefixId, ZonePrefix in pairs(self.Filter.Prefixes) do
|
for ZonePrefixId, ZonePrefix in pairs(self.Filter.Prefixes) do
|
||||||
if self:_SearchPattern(MSceneryName, ZonePrefix, false, true) then
|
if self:_SearchPattern(MSceneryName, ZonePrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||||
MSceneryPrefix = true
|
MSceneryPrefix = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -8290,6 +8401,18 @@ do -- SET_DYNAMICCARGO
|
|||||||
--- Inherits from BASE
|
--- Inherits from BASE
|
||||||
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.DYNAMICCARGO)) -- Core.Set#SET_DYNAMICCARGO
|
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.DYNAMICCARGO)) -- Core.Set#SET_DYNAMICCARGO
|
||||||
|
|
||||||
|
--- Filter the set once
|
||||||
|
-- @function [parent=#SET_DYNAMICCARGO] FilterOnce
|
||||||
|
-- @param #SET_DYNAMICCARGO self
|
||||||
|
-- @return #SET_DYNAMICCARGO self
|
||||||
|
|
||||||
|
---Set Regex Options for FilterPrefix function.
|
||||||
|
-- @function [parent=#SET_DYNAMICCARGO] FilterSetRegex
|
||||||
|
-- @param #SET_DYNAMICCARGO self
|
||||||
|
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||||
|
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||||
|
-- @return #SET_DYNAMICCARGO self
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -8337,7 +8460,7 @@ do -- SET_DYNAMICCARGO
|
|||||||
if self.Filter.StaticPrefixes then
|
if self.Filter.StaticPrefixes then
|
||||||
local DCargoPrefix = false
|
local DCargoPrefix = false
|
||||||
for StaticPrefixId, StaticPrefix in pairs(self.Filter.StaticPrefixes) do
|
for StaticPrefixId, StaticPrefix in pairs(self.Filter.StaticPrefixes) do
|
||||||
if self:_SearchPattern(DCargo:GetName(), StaticPrefix, false, true) then
|
if self:_SearchPattern(DCargo:GetName(), StaticPrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||||
DCargoPrefix = true
|
DCargoPrefix = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -8505,7 +8628,7 @@ do -- SET_DYNAMICCARGO
|
|||||||
function SET_DYNAMICCARGO:FilterCurrentOwner(PlayerName)
|
function SET_DYNAMICCARGO:FilterCurrentOwner(PlayerName)
|
||||||
self:FilterFunction(
|
self:FilterFunction(
|
||||||
function(cargo)
|
function(cargo)
|
||||||
if cargo and cargo.Owner and self:_SearchPattern(cargo.Owner, PlayerName, true) then
|
if cargo and cargo.Owner and self:_SearchPattern(cargo.Owner, PlayerName, self.filterNoRegex, self.filterReplaceDash) then
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -1184,6 +1184,7 @@ end
|
|||||||
|
|
||||||
--- This method provides the functionality to randomize the spawning of the Groups at a given list of zones of different types.
|
--- This method provides the functionality to randomize the spawning of the Groups at a given list of zones of different types.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
|
-- @param #table SpawnZoneTable A table with @{Core.Zone} objects. If nil or empty, the method returns self without effect.
|
||||||
-- @param #table SpawnZoneTable A table with @{Core.Zone} objects. If this table is given, then each spawn will be executed within the given list of @{Core.Zone}s objects.
|
-- @param #table SpawnZoneTable A table with @{Core.Zone} objects. If this table is given, then each spawn will be executed within the given list of @{Core.Zone}s objects.
|
||||||
-- @param #boolean RandomizePositionInZone If nil or true, also the position inside the selected random zone will be randomized. Set to false to use the center of the zone.
|
-- @param #boolean RandomizePositionInZone If nil or true, also the position inside the selected random zone will be randomized. Set to false to use the center of the zone.
|
||||||
-- @return #SPAWN self
|
-- @return #SPAWN self
|
||||||
@@ -1201,6 +1202,9 @@ end
|
|||||||
function SPAWN:InitRandomizeZones( SpawnZoneTable, RandomizePositionInZone )
|
function SPAWN:InitRandomizeZones( SpawnZoneTable, RandomizePositionInZone )
|
||||||
--self:F( { self.SpawnTemplatePrefix, SpawnZoneTable } )
|
--self:F( { self.SpawnTemplatePrefix, SpawnZoneTable } )
|
||||||
|
|
||||||
|
if not SpawnZoneTable then
|
||||||
|
return self
|
||||||
|
end
|
||||||
local temptable = {}
|
local temptable = {}
|
||||||
for _,_temp in pairs(SpawnZoneTable) do
|
for _,_temp in pairs(SpawnZoneTable) do
|
||||||
temptable[#temptable+1] = _temp
|
temptable[#temptable+1] = _temp
|
||||||
@@ -2149,6 +2153,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
local parkingspots = {}
|
local parkingspots = {}
|
||||||
local parkingindex = {}
|
local parkingindex = {}
|
||||||
local spots
|
local spots
|
||||||
|
local useexplicitspots = false
|
||||||
|
|
||||||
-- Spawn happens on ground, i.e. at an airbase, a FARP or a ship.
|
-- Spawn happens on ground, i.e. at an airbase, a FARP or a ship.
|
||||||
if spawnonground and not SpawnTemplate.parked then
|
if spawnonground and not SpawnTemplate.parked then
|
||||||
@@ -2178,15 +2183,41 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
local scanscenery = false
|
local scanscenery = false
|
||||||
local verysafe = false
|
local verysafe = false
|
||||||
|
|
||||||
|
-- Use exact parking data when provided, otherwise let helicopters on ships/FARPs
|
||||||
|
-- use the smarter parking search before falling back to the procedural queue path.
|
||||||
-- Number of free parking spots at the airbase.
|
-- Number of free parking spots at the airbase.
|
||||||
if autoparking then
|
if Parkingdata~=nil then
|
||||||
|
-- Parking data explicitly set by user as input parameter.
|
||||||
|
nfree = #Parkingdata
|
||||||
|
spots = Parkingdata
|
||||||
|
useexplicitspots = true
|
||||||
|
elseif autoparking and AirbaseCategory == Airbase.Category.HELIPAD and ishelo then
|
||||||
|
if termtype == nil then
|
||||||
|
-- Helo is spawned. Try exclusive helo spots first.
|
||||||
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, AIRBASE.TerminalType.HelicopterOnly, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, nil )
|
||||||
|
nfree = #spots
|
||||||
|
if nfree < nunits then
|
||||||
|
-- Not enough helo ports. Let's try also other terminal types.
|
||||||
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, AIRBASE.TerminalType.HelicopterUsable, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, nil )
|
||||||
|
nfree = #spots
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Terminal type explicitly given.
|
||||||
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, nil )
|
||||||
|
nfree = #spots
|
||||||
|
end
|
||||||
|
|
||||||
|
if nfree >= nunits then
|
||||||
|
useexplicitspots = true
|
||||||
|
else
|
||||||
|
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
||||||
|
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
||||||
|
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
||||||
|
end
|
||||||
|
elseif autoparking 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.
|
||||||
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
||||||
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
||||||
elseif Parkingdata~=nil then
|
|
||||||
-- Parking data explicitly set by user as input parameter. (This was commented out for some unknown reason. But I need it this way.)
|
|
||||||
nfree=#Parkingdata
|
|
||||||
spots=Parkingdata
|
|
||||||
else
|
else
|
||||||
if ishelo then
|
if ishelo then
|
||||||
if termtype == nil then
|
if termtype == nil then
|
||||||
@@ -2238,7 +2269,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
local _notenough = false
|
local _notenough = false
|
||||||
|
|
||||||
-- Need to differentiate some cases again.
|
-- Need to differentiate some cases again.
|
||||||
if autoparking then
|
if autoparking and not useexplicitspots then
|
||||||
|
|
||||||
-- On free spot required in these cases.
|
-- On free spot required in these cases.
|
||||||
if nfree >= 1 then
|
if nfree >= 1 then
|
||||||
@@ -2271,6 +2302,10 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if useexplicitspots and parkingspots[1] then
|
||||||
|
PointVec3 = parkingspots[1]
|
||||||
|
end
|
||||||
|
|
||||||
-- Not enough spots ==> Prepare airstart.
|
-- Not enough spots ==> Prepare airstart.
|
||||||
if _notenough then
|
if _notenough then
|
||||||
|
|
||||||
@@ -2297,8 +2332,14 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
Takeoff = GROUP.Takeoff.Air
|
Takeoff = GROUP.Takeoff.Air
|
||||||
spawnonground = false
|
spawnonground = false
|
||||||
else
|
else
|
||||||
|
if not Takeoff == GROUP.Takeoff.Runway then
|
||||||
self:E( string.format( "WARNING: Group %s has no parking spots at %s ==> No emergency air start or uncontrolled spawning ==> No spawn!", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
self:E( string.format( "WARNING: Group %s has no parking spots at %s ==> No emergency air start or uncontrolled spawning ==> No spawn!", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||||
return nil
|
return nil
|
||||||
|
else
|
||||||
|
Takeoff = GROUP.Takeoff.Runway
|
||||||
|
spawnonground = false
|
||||||
|
self:E( string.format( "WARNING: Group %s set to runway spawning at %s, this only works in Single Player!", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2339,7 +2380,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
if spawnonground then
|
if spawnonground then
|
||||||
|
|
||||||
-- Ships and FARPS seem to have a build in queue.
|
-- Ships and FARPS seem to have a build in queue.
|
||||||
if autoparking then
|
if autoparking and not useexplicitspots then
|
||||||
|
|
||||||
-- 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
|
||||||
@@ -2357,7 +2398,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
-- 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 preserved, altitude is already correctly set.
|
||||||
SpawnTemplate.units[UnitID].x = TX
|
SpawnTemplate.units[UnitID].x = TX
|
||||||
SpawnTemplate.units[UnitID].y = TY
|
SpawnTemplate.units[UnitID].y = TY
|
||||||
SpawnTemplate.units[UnitID].alt = PointVec3.y
|
SpawnTemplate.units[UnitID].alt = PointVec3.y
|
||||||
@@ -2390,7 +2431,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
if Takeoff == GROUP.Takeoff.Air then
|
if Takeoff == GROUP.Takeoff.Air then
|
||||||
for UnitID, UnitSpawned in pairs( GroupSpawned:GetUnits() ) do
|
for UnitID, UnitSpawned in pairs( GroupSpawned:GetUnits() ) do
|
||||||
--SCHEDULER:New( nil, BASE.CreateEventTakeoff, { GroupSpawned, timer.getTime(), UnitSpawned:GetDCSObject() }, 5 ) --No need to create a new SCHEDULER instance every time!
|
--SCHEDULER:New( nil, BASE.CreateEventTakeoff, { GroupSpawned, timer.getTime(), UnitSpawned:GetDCSObject() }, 5 ) --No need to create a new SCHEDULER instance every time!
|
||||||
self:ScheduleOnce(5, BASE.CreateEventTakeoff, {GroupSpawned, timer.getTime(), UnitSpawned:GetDCSObject()})
|
self:ScheduleOnce(5, BASE.CreateEventTakeoff, GroupSpawned, timer.getTime(), UnitSpawned:GetDCSObject())
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2582,21 +2623,51 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
local scanscenery = false
|
local scanscenery = false
|
||||||
local verysafe = false
|
local verysafe = false
|
||||||
|
|
||||||
-- Number of free parking spots at the airbase.
|
-- Use exact parking data when provided, otherwise let helicopters on FARPs
|
||||||
if spawnonship or spawnonfarp or spawnonrunway then
|
-- use the smarter parking search before falling back to the procedural queue path.
|
||||||
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
local useexplicitspots = false
|
||||||
--self:T2( string.format( "Group %s is spawned on farp/ship/runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
|
||||||
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
-- Number of free parking spots at the airbase.
|
||||||
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
if Parkingdata~=nil then
|
||||||
--[[
|
-- Parking data explicitly set by user as input parameter.
|
||||||
elseif Parkingdata~=nil then
|
nfree = #Parkingdata
|
||||||
-- Parking data explicitly set by user as input parameter.
|
spots = Parkingdata
|
||||||
nfree=#Parkingdata
|
useexplicitspots = true
|
||||||
spots=Parkingdata
|
elseif spawnonfarp and ishelo then
|
||||||
]]
|
|
||||||
else
|
|
||||||
if ishelo then
|
|
||||||
if termtype == nil then
|
if termtype == nil then
|
||||||
|
-- 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 ) )
|
||||||
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterOnly, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, nil )
|
||||||
|
nfree = #spots
|
||||||
|
if nfree < nunits then
|
||||||
|
-- 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 ) )
|
||||||
|
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterUsable, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, nil )
|
||||||
|
nfree = #spots
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Terminal type explicitly given.
|
||||||
|
--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, nil )
|
||||||
|
nfree = #spots
|
||||||
|
end
|
||||||
|
|
||||||
|
if nfree >= nunits then
|
||||||
|
useexplicitspots = true
|
||||||
|
else
|
||||||
|
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
||||||
|
--self:T2( string.format( "Group %s is spawned on farp %s using procedural spots.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||||
|
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
||||||
|
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
||||||
|
end
|
||||||
|
elseif spawnonship or spawnonfarp or spawnonrunway then
|
||||||
|
-- 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() ) )
|
||||||
|
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
||||||
|
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
||||||
|
else
|
||||||
|
if ishelo 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 )
|
||||||
@@ -2659,7 +2730,7 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
|||||||
local _notenough = false
|
local _notenough = false
|
||||||
|
|
||||||
-- Need to differentiate some cases again.
|
-- Need to differentiate some cases again.
|
||||||
if spawnonship or spawnonfarp or spawnonrunway then
|
if (spawnonship or spawnonfarp or spawnonrunway) and not useexplicitspots then
|
||||||
|
|
||||||
-- On free spot required in these cases.
|
-- On free spot required in these cases.
|
||||||
if nfree >= 1 then
|
if nfree >= 1 then
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ do -- world
|
|||||||
-- @field S_EVENT_SIMULATION_UNFREEZE = 58
|
-- @field S_EVENT_SIMULATION_UNFREEZE = 58
|
||||||
-- @field S_EVENT_HUMAN_AIRCRAFT_REPAIR_START = 59
|
-- @field S_EVENT_HUMAN_AIRCRAFT_REPAIR_START = 59
|
||||||
-- @field S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH = 60
|
-- @field S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH = 60
|
||||||
-- @field S_EVENT_MAX = 61
|
-- @field S_EVENT_GROUP_CHANGE_OPTION = 61
|
||||||
|
-- @field S_EVENT_MAX = 62
|
||||||
|
|
||||||
--- The birthplace enumerator is used to define where an aircraft or helicopter has spawned in association with birth events.
|
--- The birthplace enumerator is used to define where an aircraft or helicopter has spawned in association with birth events.
|
||||||
-- @type world.BirthPlace
|
-- @type world.BirthPlace
|
||||||
|
|||||||
@@ -1848,7 +1848,7 @@ do -- DETECTION_BASE
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Validate if the detected item is locked.
|
--- Validate if the detected item is locked (not in the radar sense, though!).
|
||||||
-- @param #DETECTION_BASE self
|
-- @param #DETECTION_BASE self
|
||||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
@@ -1858,7 +1858,7 @@ do -- DETECTION_BASE
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Lock a detected item.
|
--- Lock a detected item (not in the radar sense, though!).
|
||||||
-- @param #DETECTION_BASE self
|
-- @param #DETECTION_BASE self
|
||||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
||||||
-- @return #DETECTION_BASE
|
-- @return #DETECTION_BASE
|
||||||
@@ -1869,7 +1869,7 @@ do -- DETECTION_BASE
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Unlock a detected item.
|
--- Unlock a detected item (not in the radar sense, though!).
|
||||||
-- @param #DETECTION_BASE self
|
-- @param #DETECTION_BASE self
|
||||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
||||||
-- @return #DETECTION_BASE
|
-- @return #DETECTION_BASE
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -795,15 +795,20 @@ do
|
|||||||
local tgtgrp1 = self.Samset:FindNearestGroupFromPointVec2(tgtcoord)
|
local tgtgrp1 = self.Samset:FindNearestGroupFromPointVec2(tgtcoord)
|
||||||
local tgtcoord1 = tgtgrp1:GetCoordinate()
|
local tgtcoord1 = tgtgrp1:GetCoordinate()
|
||||||
local tgtgrp2 = self.Groupset:FindNearestGroupFromPointVec2(tgtcoord)
|
local tgtgrp2 = self.Groupset:FindNearestGroupFromPointVec2(tgtcoord)
|
||||||
local tgtcoord2 = tgtgrp2:GetCoordinate()
|
if tgtgrp2 then
|
||||||
local dist1 = tgtcoord:Get2DDistance(tgtcoord1)
|
local tgtcoord2 = tgtgrp2:GetCoordinate()
|
||||||
local dist2 = tgtcoord:Get2DDistance(tgtcoord2)
|
local dist1 = tgtcoord:Get2DDistance(tgtcoord1)
|
||||||
|
local dist2 = tgtcoord:Get2DDistance(tgtcoord2)
|
||||||
|
|
||||||
if dist1 < dist2 then
|
if dist1 < dist2 then
|
||||||
targetunit = tgtgrp1
|
targetunit = tgtgrp1
|
||||||
targetcat = Object.Category.UNIT
|
targetcat = Object.Category.UNIT
|
||||||
|
else
|
||||||
|
targetunit = tgtgrp2
|
||||||
|
targetcat = Object.Category.UNIT
|
||||||
|
end
|
||||||
else
|
else
|
||||||
targetunit = tgtgrp2
|
targetunit = tgtgrp1
|
||||||
targetcat = Object.Category.UNIT
|
targetcat = Object.Category.UNIT
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1485,7 +1485,7 @@ function SUPPRESSION:onafterStop(Controllable, From, Event, To)
|
|||||||
|
|
||||||
local text=string.format("Stopping SUPPRESSION for group %s", self.Controllable:GetName())
|
local text=string.format("Stopping SUPPRESSION for group %s", self.Controllable:GetName())
|
||||||
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
||||||
sefl:T(self.lid..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
-- Clear all pending schedules
|
-- Clear all pending schedules
|
||||||
self.CallScheduler:Clear()
|
self.CallScheduler:Clear()
|
||||||
|
|||||||
@@ -4097,7 +4097,7 @@ function WAREHOUSE:_RegisterAsset(group, ngroups, forceattribute, forcecargobay,
|
|||||||
-- Get name of template group.
|
-- Get name of template group.
|
||||||
local templategroupname=group:GetName()
|
local templategroupname=group:GetName()
|
||||||
local unit = group:GetUnit(1)
|
local unit = group:GetUnit(1)
|
||||||
local Descriptors= (unit and unit:IsAlive()) and unit:GetDesc() or {}
|
local Descriptors= (unit and unit:IsAlive()~=nil) and unit:GetDesc() or {}
|
||||||
local Category=group:GetCategory()
|
local Category=group:GetCategory()
|
||||||
local TypeName=group:GetTypeName() or "none"
|
local TypeName=group:GetTypeName() or "none"
|
||||||
local SpeedMax=group:GetSpeedMax()
|
local SpeedMax=group:GetSpeedMax()
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/Squadron.lua' )
|
|||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/Target.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/Target.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/EasyGCICAP.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/EasyGCICAP.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/EasyA2G.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/EasyA2G.lua' )
|
||||||
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/TARS.lua' )
|
||||||
|
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Shapes/ShapeBase.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Shapes/ShapeBase.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Shapes/Circle.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Shapes/Circle.lua' )
|
||||||
|
|||||||
@@ -2717,17 +2717,27 @@ function AIRBOSS:DeleteRecoveryWindow( Window, Delay )
|
|||||||
self:ScheduleOnce( Delay, self.DeleteRecoveryWindow, self, Window )
|
self:ScheduleOnce( Delay, self.DeleteRecoveryWindow, self, Window )
|
||||||
else
|
else
|
||||||
|
|
||||||
for i, _recovery in pairs( self.recoverytimes ) do
|
if not Window then
|
||||||
local recovery = _recovery -- #AIRBOSS.Recovery
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if Window and Window.ID == recovery.ID then
|
-- If this window is currently open, stop recovery first. Mark it OVER so the
|
||||||
if Window.OPEN then
|
-- recovery time check cannot re-open it before/while we remove it.
|
||||||
-- Window is currently open.
|
if Window.OPEN then
|
||||||
self:RecoveryStop()
|
Window.OPEN = false
|
||||||
else
|
Window.OVER = true
|
||||||
table.remove( self.recoverytimes, i )
|
if self:IsRecovering() then
|
||||||
end
|
self:RecoveryStop()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Remove the window from the queue by its unique ID. Iterate over a numerically
|
||||||
|
-- indexed copy of the keys and remove via ipairs-safe reverse loop so that the
|
||||||
|
-- removal does not corrupt traversal (the window may appear once).
|
||||||
|
for i = #self.recoverytimes, 1, -1 do
|
||||||
|
local recovery = self.recoverytimes[i] -- #AIRBOSS.Recovery
|
||||||
|
if recovery and recovery.ID == Window.ID then
|
||||||
|
table.remove( self.recoverytimes, i )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -4078,15 +4088,23 @@ function AIRBOSS:_CheckRecoveryTimes()
|
|||||||
if self:IsRecovering() then
|
if self:IsRecovering() then
|
||||||
-- Carrier is already recovering.
|
-- Carrier is already recovering.
|
||||||
state = "in progress"
|
state = "in progress"
|
||||||
else
|
elseif not recovery.OVER then
|
||||||
-- Start recovery.
|
-- Start recovery. Only if the window has not already been closed/cancelled.
|
||||||
|
-- The OVER guard prevents a window that was stopped manually (e.g. via the
|
||||||
|
-- Skipper "Stop Recovery" menu) from being immediately re-opened on the next
|
||||||
|
-- status tick while its [START,STOP) range is still active.
|
||||||
self:RecoveryStart( recovery.CASE, recovery.OFFSET )
|
self:RecoveryStart( recovery.CASE, recovery.OFFSET )
|
||||||
state = "starting now"
|
state = "starting now"
|
||||||
recovery.OPEN = true
|
recovery.OPEN = true
|
||||||
|
else
|
||||||
|
-- Window was already closed/cancelled within its active time range.
|
||||||
|
state = "cancelled"
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set current recovery window.
|
-- Set current recovery window (unless this window has been cancelled).
|
||||||
currwindow = recovery
|
if not recovery.OVER then
|
||||||
|
currwindow = recovery
|
||||||
|
end
|
||||||
|
|
||||||
else -- Stop time HAS passed.
|
else -- Stop time HAS passed.
|
||||||
|
|
||||||
@@ -4183,13 +4201,16 @@ function AIRBOSS:_CheckRecoveryTimes()
|
|||||||
-- Time into the wind 1 day or if longer recovery time + the 5 min early.
|
-- Time into the wind 1 day or if longer recovery time + the 5 min early.
|
||||||
local t = math.max( nextwindow.STOP - nextwindow.START + self.dTturn, 60 * 60 * 24 )
|
local t = math.max( nextwindow.STOP - nextwindow.START + self.dTturn, 60 * 60 * 24 )
|
||||||
|
|
||||||
-- Recovery wind on deck in knots.
|
-- Recovery wind on deck in knots.
|
||||||
|
-- NOTE: Do NOT clamp the desired wind-over-deck (WOD) to the carrier's max hull
|
||||||
|
-- speed here. WOD = carrier speed + headwind, so a WOD target above the hull's
|
||||||
|
-- top speed is achievable whenever there is wind. CarrierTurnIntoWind ->
|
||||||
|
-- GetHeadingIntoWind already converts the WOD target into the required hull
|
||||||
|
-- speed and caps THAT at the carrier's max speed (Vmax) internally. Clamping the
|
||||||
|
-- WOD target itself capped achievable WOD at ~30 kts (the supercarrier's max
|
||||||
|
-- hull speed) even in strong wind, which made high-WOD recovery windows fall
|
||||||
|
-- short of their requested value.
|
||||||
local v = UTILS.KnotsToMps( nextwindow.SPEED )
|
local v = UTILS.KnotsToMps( nextwindow.SPEED )
|
||||||
|
|
||||||
-- Check that we do not go above max possible speed.
|
|
||||||
local vmax = self.carrier:GetSpeedMax() / 3.6 -- convert to m/s
|
|
||||||
v = math.min( v, vmax )
|
|
||||||
|
|
||||||
-- Route carrier into the wind. Sets self.turnintowind=true
|
-- Route carrier into the wind. Sets self.turnintowind=true
|
||||||
self:CarrierTurnIntoWind( t, v, uturn )
|
self:CarrierTurnIntoWind( t, v, uturn )
|
||||||
|
|
||||||
@@ -4361,11 +4382,20 @@ function AIRBOSS:onafterRecoveryStop( From, Event, To )
|
|||||||
self:CarrierResumeRoute( coord )
|
self:CarrierResumeRoute( coord )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Delete current recovery window if open.
|
-- Mark the current recovery window closed and cancelled, then remove it from the
|
||||||
if self.recoverywindow and self.recoverywindow.OPEN == true then
|
-- queue. We do NOT gate this on Window.OPEN: that flag is only set by
|
||||||
|
-- _CheckRecoveryTimes (not by RecoveryStart), and the recovery time check nils and
|
||||||
|
-- rebuilds self.recoverywindow every status tick, so OPEN is not a reliable signal
|
||||||
|
-- here. Setting OVER=true is what actually prevents the window from being re-opened
|
||||||
|
-- on the next tick while its [START,STOP) range is still active.
|
||||||
|
--
|
||||||
|
-- The removal is deferred by one tick (Delay>0) so it does not mutate the
|
||||||
|
-- recoverytimes table while _CheckRecoveryTimes may be iterating over it (the natural
|
||||||
|
-- close path calls RecoveryStop() from inside that loop).
|
||||||
|
if self.recoverywindow then
|
||||||
self.recoverywindow.OPEN = false
|
self.recoverywindow.OPEN = false
|
||||||
self.recoverywindow.OVER = true
|
self.recoverywindow.OVER = true
|
||||||
self:DeleteRecoveryWindow( self.recoverywindow )
|
self:DeleteRecoveryWindow( self.recoverywindow, 1 )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check recovery windows. This sets self.recoverywindow to the next window.
|
-- Check recovery windows. This sets self.recoverywindow to the next window.
|
||||||
@@ -12903,6 +12933,14 @@ function AIRBOSS:_LSOgrade( playerData )
|
|||||||
-- Circuit edit only take points awary from a 1 wire if there are more than 4 other deviations
|
-- Circuit edit only take points awary from a 1 wire if there are more than 4 other deviations
|
||||||
if playerData.wire == 1 and points >= 3 and N > 4 then
|
if playerData.wire == 1 and points >= 3 and N > 4 then
|
||||||
points = points -1
|
points = points -1
|
||||||
|
-- We also need to change the grade based on the new points.
|
||||||
|
if points == 4 then
|
||||||
|
grade = "OK"
|
||||||
|
elseif points == 3 then
|
||||||
|
grade = "(OK)"
|
||||||
|
elseif points == 2 then
|
||||||
|
grade = "--"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
env.info("Returning: " .. grade .. " " .. points .. " " .. G)
|
env.info("Returning: " .. grade .. " " .. points .. " " .. G)
|
||||||
|
|||||||
@@ -6466,7 +6466,13 @@ function AUFTRAG:GetDCSMissionTask(MissionGroup)
|
|||||||
-- ESCORT Mission --
|
-- ESCORT Mission --
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
local DCStask=CONTROLLABLE.TaskEscort(nil, self.engageTarget:GetObject(), self.escortVec3, nil, self.engageMaxDistance, self.engageTargetTypes)
|
local FollowGroup=self.engageTarget:GetObject()
|
||||||
|
local DCStask=nil
|
||||||
|
if next(self.engageTargetTypes)==nil then
|
||||||
|
DCStask=FollowGroup:TaskFollow(FollowGroup, self.escortVec3)
|
||||||
|
else
|
||||||
|
DCStask=CONTROLLABLE.TaskEscort(nil, FollowGroup, self.escortVec3, nil, self.engageMaxDistance, self.engageTargetTypes)
|
||||||
|
end
|
||||||
|
|
||||||
table.insert(DCStasks, DCStask)
|
table.insert(DCStasks, DCStask)
|
||||||
|
|
||||||
@@ -6610,7 +6616,7 @@ function AUFTRAG:GetDCSMissionTask(MissionGroup)
|
|||||||
local SeadUnitSet = SET_UNIT:New()
|
local SeadUnitSet = SET_UNIT:New()
|
||||||
for _,_unit in pairs (ScanUnitSet.Set) do
|
for _,_unit in pairs (ScanUnitSet.Set) do
|
||||||
local unit = _unit -- Wrapper.Unit#UNTI
|
local unit = _unit -- Wrapper.Unit#UNTI
|
||||||
if unit and unit:IsAlive() and unit:HasSEAD() then
|
if unit and unit:IsAlive() and unit.HasSEAD and unit:HasSEAD() then
|
||||||
self:T("Adding UNIT for SEAD: "..unit:GetName())
|
self:T("Adding UNIT for SEAD: "..unit:GetName())
|
||||||
local task = CONTROLLABLE.TaskAttackUnit(nil,unit,GroupAttack,AI.Task.WeaponExpend.ALL,1,Direction,self.engageAltitude,2956984318)
|
local task = CONTROLLABLE.TaskAttackUnit(nil,unit,GroupAttack,AI.Task.WeaponExpend.ALL,1,Direction,self.engageAltitude,2956984318)
|
||||||
table.insert(DCStasks, task)
|
table.insert(DCStasks, task)
|
||||||
|
|||||||
@@ -504,6 +504,9 @@ CSAR.AircraftType["OH58D"] = 2
|
|||||||
CSAR.AircraftType["CH-47Fbl1"] = 31
|
CSAR.AircraftType["CH-47Fbl1"] = 31
|
||||||
CSAR.AircraftType["AH-6J"] = 2
|
CSAR.AircraftType["AH-6J"] = 2
|
||||||
CSAR.AircraftType["MH-6J"] = 2
|
CSAR.AircraftType["MH-6J"] = 2
|
||||||
|
CSAR.AircraftType["Ka-50_3"] = 0
|
||||||
|
CSAR.AircraftType["Ka-50"] = 0
|
||||||
|
CSAR.AircraftType["AV8BNA"] = 0
|
||||||
|
|
||||||
--- CSAR class version.
|
--- CSAR class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
@@ -2538,8 +2541,11 @@ function CSAR:_AddMedevacMenuItem()
|
|||||||
if _unit then
|
if _unit then
|
||||||
--self:T("Unitname ".._unit:GetName().." IsAlive "..tostring(_unit:IsAlive()).." IsPlayer "..tostring(_unit:IsPlayer()))
|
--self:T("Unitname ".._unit:GetName().." IsAlive "..tostring(_unit:IsAlive()).." IsPlayer "..tostring(_unit:IsPlayer()))
|
||||||
if _unit:IsAlive() and _unit:IsPlayer() then
|
if _unit:IsAlive() and _unit:IsPlayer() then
|
||||||
local unitName = _unit:GetName()
|
local _maxUnits = self.AircraftType[_unit:GetTypeName()]
|
||||||
_UnitList[unitName] = unitName
|
if _maxUnits == nil or _maxUnits > 0 then
|
||||||
|
local unitName = _unit:GetName()
|
||||||
|
_UnitList[unitName] = unitName
|
||||||
|
end
|
||||||
end -- end isAlive
|
end -- end isAlive
|
||||||
end -- end if _unit
|
end -- end if _unit
|
||||||
end -- end for
|
end -- end for
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,7 @@
|
|||||||
--
|
--
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
-- Date: September 2023
|
-- Date: September 2023
|
||||||
-- Last Update: Mar 2026
|
-- Last Update: June 2026
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--
|
--
|
||||||
--- **Ops** - Easy GCI & CAP Manager
|
--- **Ops** - Easy GCI & CAP Manager
|
||||||
@@ -135,6 +135,7 @@
|
|||||||
-- local mywing = EASYGCICAP:New("Blue CAP Operations",AIRBASE.Caucasus.Kutaisi,"blue","Blue EWR")
|
-- local mywing = EASYGCICAP:New("Blue CAP Operations",AIRBASE.Caucasus.Kutaisi,"blue","Blue EWR")
|
||||||
--
|
--
|
||||||
-- -- Add a CAP patrol point belonging to our airbase, we'll be at 30k ft doing 400 kn, initial direction 90 degrees (East), leg 20NM
|
-- -- Add a CAP patrol point belonging to our airbase, we'll be at 30k ft doing 400 kn, initial direction 90 degrees (East), leg 20NM
|
||||||
|
-- -- NOTE - Skip this function and do not create CAP Points if you want GCI behaviour only.
|
||||||
-- mywing:AddPatrolPointCAP(AIRBASE.Caucasus.Kutaisi,ZONE:FindByName("Blue Zone 1"):GetCoordinate(),30000,400,90,20)
|
-- mywing:AddPatrolPointCAP(AIRBASE.Caucasus.Kutaisi,ZONE:FindByName("Blue Zone 1"):GetCoordinate(),30000,400,90,20)
|
||||||
--
|
--
|
||||||
-- -- Add a Squadron with template "Blue Sq1 M2000c", 20 airframes, skill good, Modex starting with 102 and skin "Vendee Jeanne"
|
-- -- Add a Squadron with template "Blue Sq1 M2000c", 20 airframes, skill good, Modex starting with 102 and skin "Vendee Jeanne"
|
||||||
@@ -190,9 +191,10 @@
|
|||||||
-- * @{#EASYGCICAP.SetDefaultResurrection}: Set how many seconds the AirWing stays inoperable after the AirWing STATIC HQ ist destroyed, default 900 secs.
|
-- * @{#EASYGCICAP.SetDefaultResurrection}: Set how many seconds the AirWing stays inoperable after the AirWing STATIC HQ ist destroyed, default 900 secs.
|
||||||
-- * @{#EASYGCICAP.SetDefaultCAPSpeed}: Set how many knots the CAP flights should do (will be altitude corrected), default 300 kn.
|
-- * @{#EASYGCICAP.SetDefaultCAPSpeed}: Set how many knots the CAP flights should do (will be altitude corrected), default 300 kn.
|
||||||
-- * @{#EASYGCICAP.SetDefaultCAPAlt}: Set at which altitude (ASL) the CAP planes will fly, default 25,000 ft.
|
-- * @{#EASYGCICAP.SetDefaultCAPAlt}: Set at which altitude (ASL) the CAP planes will fly, default 25,000 ft.
|
||||||
|
-- * @{#EASYGCICAP.SetDefaultINTERCEPTAlt}: Set at which altitude (ASL) the Intercept planes will fly, default 25,000 ft.
|
||||||
-- * @{#EASYGCICAP.SetDefaultCAPDirection}: Set the initial direction from the CAP point the planes will fly in degrees, default is 90°.
|
-- * @{#EASYGCICAP.SetDefaultCAPDirection}: Set the initial direction from the CAP point the planes will fly in degrees, default is 90°.
|
||||||
-- * @{#EASYGCICAP.SetDefaultCAPLeg}: Set the length of the CAP leg, default is 15 NM.
|
-- * @{#EASYGCICAP.SetDefaultCAPLeg}: Set the length of the CAP leg, default is 15 NM.
|
||||||
-- * @{#EASYGCICAP.SetDefaultCAPGrouping}: Set how many planes will be spawned per mission (CVAP/GCI), defaults to 2.
|
-- * @{#EASYGCICAP.SetDefaultCAPGrouping}: Set how many planes will be spawned per mission (CAP/GCI), defaults to 2.
|
||||||
-- * @{#EASYGCICAP.SetDefaultMissionRange}: Set how many NM the planes can go from the home base, defaults to 100.
|
-- * @{#EASYGCICAP.SetDefaultMissionRange}: Set how many NM the planes can go from the home base, defaults to 100.
|
||||||
-- * @{#EASYGCICAP.SetDefaultNumberAlert5Standby}: Set how many planes will be spawned on cold standby (Alert5), default 2.
|
-- * @{#EASYGCICAP.SetDefaultNumberAlert5Standby}: Set how many planes will be spawned on cold standby (Alert5), default 2.
|
||||||
-- * @{#EASYGCICAP.SetDefaultEngageRange}: Set max engage range for CAP flights if they detect intruders, defaults to 50.
|
-- * @{#EASYGCICAP.SetDefaultEngageRange}: Set max engage range for CAP flights if they detect intruders, defaults to 50.
|
||||||
@@ -286,7 +288,7 @@ EASYGCICAP = {
|
|||||||
|
|
||||||
--- EASYGCICAP class version.
|
--- EASYGCICAP class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
EASYGCICAP.version="0.1.35"
|
EASYGCICAP.version="0.1.38"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
--
|
--
|
||||||
@@ -587,6 +589,17 @@ function EASYGCICAP:SetDefaultCAPAlt(Altitude)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set default INTERCEPT Altitude in feet
|
||||||
|
-- @param #EASYGCICAP self
|
||||||
|
-- @param #number Altitude (Optional) Altitude defaults to 25000
|
||||||
|
-- @return #EASYGCICAP self
|
||||||
|
function EASYGCICAP:SetDefaultINTERCEPTAlt(Altitude)
|
||||||
|
self:T(self.lid.."SetDefaultINTERCEPTAlt")
|
||||||
|
self.interceptalt = Altitude or 25000
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
--
|
||||||
|
|
||||||
--- Set default CAP lieg initial direction in degrees
|
--- Set default CAP lieg initial direction in degrees
|
||||||
-- @param #EASYGCICAP self
|
-- @param #EASYGCICAP self
|
||||||
-- @param #number Direction (Optional) Direction defaults to 90 (East)
|
-- @param #number Direction (Optional) Direction defaults to 90 (East)
|
||||||
@@ -754,6 +767,15 @@ end
|
|||||||
function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
||||||
self:T(self.lid.."_AddAirwing "..Airbasename)
|
self:T(self.lid.."_AddAirwing "..Airbasename)
|
||||||
|
|
||||||
|
-- Gather Some Stats
|
||||||
|
local function counttable(tbl)
|
||||||
|
local count = 0
|
||||||
|
for _,_data in pairs(tbl) do
|
||||||
|
count = count + 1
|
||||||
|
end
|
||||||
|
return count
|
||||||
|
end
|
||||||
|
|
||||||
local CapFormation = self.CapFormation
|
local CapFormation = self.CapFormation
|
||||||
local DespawnAfterLanding = self.DespawnAfterLanding
|
local DespawnAfterLanding = self.DespawnAfterLanding
|
||||||
local DespawnAfterHolding = self.DespawnAfterHolding
|
local DespawnAfterHolding = self.DespawnAfterHolding
|
||||||
@@ -772,7 +794,11 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
|||||||
CAP_Wing:SetMarker(false)
|
CAP_Wing:SetMarker(false)
|
||||||
CAP_Wing:SetAirbase(AIRBASE:FindByName(Airbasename))
|
CAP_Wing:SetAirbase(AIRBASE:FindByName(Airbasename))
|
||||||
CAP_Wing:SetRespawnAfterDestroyed()
|
CAP_Wing:SetRespawnAfterDestroyed()
|
||||||
CAP_Wing:SetNumberCAP(self.capgrouping)
|
|
||||||
|
--- #DONE avoid wings with no CAP points starting CAP anyhow; AirWing uses this to start CAP and creates points when there are none.
|
||||||
|
if counttable(self.ManagedCP) >0 then
|
||||||
|
CAP_Wing:SetNumberCAP(self.capgrouping)
|
||||||
|
end
|
||||||
CAP_Wing:SetCapCloseRaceTrack(true)
|
CAP_Wing:SetCapCloseRaceTrack(true)
|
||||||
|
|
||||||
if self.showpatrolpointmarks then
|
if self.showpatrolpointmarks then
|
||||||
@@ -854,16 +880,18 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if self.noalert5 > 0 then
|
if self.noalert5 > 0 then
|
||||||
local alert
|
for i=1,self.noalert5 do
|
||||||
if self.ClassName == "EASYGCICAP" then
|
local alert
|
||||||
alert = AUFTRAG:NewALERT5(AUFTRAG.Type.INTERCEPT)
|
if self.ClassName == "EASYGCICAP" then
|
||||||
elseif self.ClassName == "EASYA2G" then
|
alert = AUFTRAG:NewALERT5(AUFTRAG.Type.INTERCEPT)
|
||||||
alert = AUFTRAG:NewALERT5(AUFTRAG.Type.BAI)
|
elseif self.ClassName == "EASYA2G" then
|
||||||
|
alert = AUFTRAG:NewALERT5(AUFTRAG.Type.BAI)
|
||||||
|
end
|
||||||
|
alert:SetRequiredAssets(self.capgrouping)
|
||||||
|
alert:SetRepeat(99)
|
||||||
|
CAP_Wing:AddMission(alert)
|
||||||
|
table.insert(self.ListOfAuftrag,alert)
|
||||||
end
|
end
|
||||||
alert:SetRequiredAssets(self.noalert5)
|
|
||||||
alert:SetRepeat(99)
|
|
||||||
CAP_Wing:AddMission(alert)
|
|
||||||
table.insert(self.ListOfAuftrag,alert)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self.wings[Airbasename] = { CAP_Wing, AIRBASE:FindByName(Airbasename):GetZone(), Airbasename }
|
self.wings[Airbasename] = { CAP_Wing, AIRBASE:FindByName(Airbasename):GetZone(), Airbasename }
|
||||||
@@ -1037,7 +1065,7 @@ function EASYGCICAP:_SetCAPPatrolPoints()
|
|||||||
MESSAGE:New(self.lid.."You are trying to create a CAP point for which there is no wing! "..tostring(data.AirbaseName),30,"CHECK"):ToAllIf(self.debug):ToLog()
|
MESSAGE:New(self.lid.."You are trying to create a CAP point for which there is no wing! "..tostring(data.AirbaseName),30,"CHECK"):ToAllIf(self.debug):ToLog()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING
|
local Wing = self.wings[data.AirbaseName][1] -- Ops.AirWing#AIRWING
|
||||||
local Coordinate = data.Coordinate
|
local Coordinate = data.Coordinate
|
||||||
local Altitude = data.Altitude
|
local Altitude = data.Altitude
|
||||||
local Speed = data.Speed
|
local Speed = data.Speed
|
||||||
@@ -1503,6 +1531,7 @@ function EASYGCICAP:_AssignIntercept(Cluster)
|
|||||||
local overhead = self.overhead
|
local overhead = self.overhead
|
||||||
local capspeed = self.capspeed + 100
|
local capspeed = self.capspeed + 100
|
||||||
local capalt = self.capalt
|
local capalt = self.capalt
|
||||||
|
local interalt = self.interceptalt or self.capalt
|
||||||
local maxsize = self.maxinterceptsize
|
local maxsize = self.maxinterceptsize
|
||||||
local repeatsonfailure = self.repeatsonfailure
|
local repeatsonfailure = self.repeatsonfailure
|
||||||
|
|
||||||
@@ -1590,6 +1619,7 @@ function EASYGCICAP:_AssignIntercept(Cluster)
|
|||||||
:SetRepeatOnFailure(repeats)
|
:SetRepeatOnFailure(repeats)
|
||||||
:SetMissionSpeed(UTILS.KnotsToAltKIAS(capspeed,capalt))
|
:SetMissionSpeed(UTILS.KnotsToAltKIAS(capspeed,capalt))
|
||||||
:SetMissionAltitude(capalt)
|
:SetMissionAltitude(capalt)
|
||||||
|
:SetEngageAltitude(interalt)
|
||||||
|
|
||||||
if nogozoneset:Count() > 0 then
|
if nogozoneset:Count() > 0 then
|
||||||
InterceptAuftrag:AddConditionSuccess(
|
InterceptAuftrag:AddConditionSuccess(
|
||||||
@@ -1835,9 +1865,10 @@ function EASYGCICAP:onafterRestart(From,Event,To)
|
|||||||
-- self.wings[Airbasename] = { CAP_Wing, AIRBASE:FindByName(Airbasename):GetZone(), Airbasename }
|
-- self.wings[Airbasename] = { CAP_Wing, AIRBASE:FindByName(Airbasename):GetZone(), Airbasename }
|
||||||
for _,_wing in pairs(self.wings or {}) do
|
for _,_wing in pairs(self.wings or {}) do
|
||||||
for _,_aw in pairs(_wing) do
|
for _,_aw in pairs(_wing) do
|
||||||
_wing[1]:Start()
|
_wing[1]:Restart()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
self:__Status(5)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1270,6 +1270,15 @@ function INTEL:_UpdateContact(Contact)
|
|||||||
else
|
else
|
||||||
Contact.maneuvering = false
|
Contact.maneuvering = false
|
||||||
end
|
end
|
||||||
|
local typename = Contact.group:GetTypeName()
|
||||||
|
local base_rcs = INTEL.RCS_Table[typename]
|
||||||
|
|
||||||
|
if not base_rcs then
|
||||||
|
-- Fallback: category default
|
||||||
|
local cat = Contact.group:GetCategory()
|
||||||
|
base_rcs = (cat and INTEL.RCS_CategoryDefault[cat]) or INTEL.RCS_Reference
|
||||||
|
end
|
||||||
|
Contact.rcs = base_rcs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2581,7 +2581,7 @@ end
|
|||||||
-- @return #boolean Returns `true` if given cohort can meet all requirements.
|
-- @return #boolean Returns `true` if given cohort can meet all requirements.
|
||||||
function LEGION._CohortCan(Cohort, MissionType, Categories, Attributes, Properties, WeaponTypes, TargetVec2, RangeMax, RefuelSystem, CargoWeight, MaxWeight, RangeMin)
|
function LEGION._CohortCan(Cohort, MissionType, Categories, Attributes, Properties, WeaponTypes, TargetVec2, RangeMax, RefuelSystem, CargoWeight, MaxWeight, RangeMin)
|
||||||
|
|
||||||
RangeMin = RangeMin or 0
|
RangeMin = RangeMin or -1
|
||||||
|
|
||||||
--- Function to check category.
|
--- Function to check category.
|
||||||
local function CheckCategory(_cohort)
|
local function CheckCategory(_cohort)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -61,24 +61,21 @@
|
|||||||
--
|
--
|
||||||
-- # The MSRS Concept
|
-- # The MSRS Concept
|
||||||
--
|
--
|
||||||
-- This class allows to broadcast sound files or text via Simple Radio Standalone (SRS).
|
-- This class allows to broadcast sound files or text to speech via Simple Radio Standalone (SRS).
|
||||||
--
|
--
|
||||||
-- ## Prerequisites
|
-- ## Prerequisites
|
||||||
--
|
--
|
||||||
-- * This script needs SRS version >= 1.9.6
|
|
||||||
-- * You need to de-sanitize os, io and lfs in the missionscripting.lua
|
-- * You need to de-sanitize os, io and lfs in the missionscripting.lua
|
||||||
-- * Optional: DCS-gRPC as backend to communicate with SRS (via infra)
|
-- * Optional but recommended: HOUND TTS as backend to communicate with SRS (via plugin)
|
||||||
-- * Optional: HOUNDTTS as backend to communicate with SRS (via infra)
|
-- * Optional: DCS-gRPC as backend to communicate with SRS (via plugin)
|
||||||
--
|
--
|
||||||
-- ## Knwon Issues
|
-- ## Known Issues
|
||||||
--
|
--
|
||||||
-- ### Pop-up Window
|
-- ### Pop-up Window (with backend windows)
|
||||||
--
|
--
|
||||||
-- The text-to-speech conversion of SRS is done via an external exe file. When this file is called, a windows `cmd` window is briefly opended. That puts DCS out of focus, which is annoying,
|
-- The text-to-speech conversion of SRS is done via an external exe file. When this file is called, a windows `cmd` window is briefly opended. That puts DCS out of focus, which is annoying,
|
||||||
-- expecially in VR but unavoidable (if you have a solution, please feel free to share!).
|
-- expecially in VR, but unavoidable unless you use HOUD or gRPC as backends.
|
||||||
--
|
--
|
||||||
-- NOTE that this is not an issue if the mission is running on a server.
|
|
||||||
-- Also NOTE that using DCS-gRPC and Hound-TTS as backend create no pop-up window.
|
|
||||||
--
|
--
|
||||||
-- # Play Sound Files
|
-- # Play Sound Files
|
||||||
--
|
--
|
||||||
@@ -137,16 +134,17 @@
|
|||||||
--
|
--
|
||||||
-- See @{#MSRS.LoadConfigFile} for details on how to set this up.
|
-- See @{#MSRS.LoadConfigFile} for details on how to set this up.
|
||||||
--
|
--
|
||||||
-- ## TTS Providers
|
-- ## TTS (text-to-speech) Providers
|
||||||
--
|
--
|
||||||
-- The default provider for generating speech from text is the native Windows TTS service. Note that you need to install the voices you want to use.
|
-- The **currently recommended** backend is HOUND TTS (no pop-ups), which has a wide variety of TTS providers.
|
||||||
|
-- The *default* provider for generating speech from text is the native Windows TTS service. Note that you need to install the voices you want to use.
|
||||||
--
|
--
|
||||||
-- **Pro-Tip** - use the command line with power shell to call `DCS-SR-ExternalAudio.exe` - it will tell you what is missing
|
-- **Pro-Tip** - use the command line with power shell to call `DCS-SR-ExternalAudio.exe` - it will tell you what is missing
|
||||||
-- and also the Google Console error, in case you have missed a step in setting up your Google TTS.
|
-- and also the Google Console error, in case you have missed a step in setting up your Google TTS.
|
||||||
-- For example, `.\DCS-SR-ExternalAudio.exe -t "Text Message" -f 255 -m AM -c 2 -s 2 -z -G "Path_To_You_Google.Json"`
|
-- For example, `.\DCS-SR-ExternalAudio.exe -t "Text Message" -f 255 -m AM -c 2 -s 2 -z -G "Path_To_You_Google.Json"`
|
||||||
-- plays a message on 255 MHz AM for the blue coalition in-game.
|
-- plays a message on 255 MHz AM for the blue coalition in-game.
|
||||||
--
|
--
|
||||||
-- ### Google
|
-- ### Google (best speech synthesis)
|
||||||
--
|
--
|
||||||
-- In order to use Google Cloud for TTS you need to use @{#MSRS.SetProvider} and @{#MSRS.SetProviderOptionsGoogle} functions:
|
-- In order to use Google Cloud for TTS you need to use @{#MSRS.SetProvider} and @{#MSRS.SetProviderOptionsGoogle} functions:
|
||||||
--
|
--
|
||||||
@@ -162,7 +160,7 @@
|
|||||||
-- For more information on setting up a cloud account, visit: https://cloud.google.com/text-to-speech
|
-- For more information on setting up a cloud account, visit: https://cloud.google.com/text-to-speech
|
||||||
-- Google's supported SSML reference: https://cloud.google.com/text-to-speech/docs/ssml
|
-- Google's supported SSML reference: https://cloud.google.com/text-to-speech/docs/ssml
|
||||||
--
|
--
|
||||||
-- ### Amazon Web Service [Only DCS-gRPC backend]
|
-- ### Amazon Web Service [Only HOUDN and DCS-gRPC backend]
|
||||||
--
|
--
|
||||||
-- In order to use Amazon Web Service (AWS) for TTS you need to use @{#MSRS.SetProvider} and @{#MSRS.SetProviderOptionsAmazon} functions:
|
-- In order to use Amazon Web Service (AWS) for TTS you need to use @{#MSRS.SetProvider} and @{#MSRS.SetProviderOptionsAmazon} functions:
|
||||||
--
|
--
|
||||||
@@ -173,7 +171,7 @@
|
|||||||
--
|
--
|
||||||
-- You can set the voice to use with AWS via @{#MSRS.SetVoiceAmazon}.
|
-- You can set the voice to use with AWS via @{#MSRS.SetVoiceAmazon}.
|
||||||
--
|
--
|
||||||
-- ### Microsoft Azure [Only DCS-gRPC backend]
|
-- ### Microsoft Azure [Only HOUND and DCS-gRPC backend]
|
||||||
--
|
--
|
||||||
-- In order to use Microsoft Azure for TTS you need to use @{#MSRS.SetProvider} and @{#MSRS.SetProviderOptionsAzure} functions:
|
-- In order to use Microsoft Azure for TTS you need to use @{#MSRS.SetProvider} and @{#MSRS.SetProviderOptionsAzure} functions:
|
||||||
--
|
--
|
||||||
@@ -184,6 +182,12 @@
|
|||||||
--
|
--
|
||||||
-- You can set the voice to use with Azure via @{#MSRS.SetVoiceAzure}.
|
-- You can set the voice to use with Azure via @{#MSRS.SetVoiceAzure}.
|
||||||
--
|
--
|
||||||
|
-- ### Piper, OpenAI and further provider options [Only HOUND backend]
|
||||||
|
--
|
||||||
|
-- You can use further providers with HOUND TTS as a backend, see [Hound-TTS](https://github.com/uriba107/HoundTTS/releases) for setup.
|
||||||
|
--
|
||||||
|
-- msrs:SetProvider(MSRS.Provider.PIPER) -- e.g. for piper
|
||||||
|
--
|
||||||
-- ## Backend
|
-- ## Backend
|
||||||
--
|
--
|
||||||
-- The default interface to SRS is via calling the 'DCS-SR-ExternalAudio.exe'. As noted above, this has the unavoidable drawback that a pop-up briefly appears
|
-- The default interface to SRS is via calling the 'DCS-SR-ExternalAudio.exe'. As noted above, this has the unavoidable drawback that a pop-up briefly appears
|
||||||
@@ -191,13 +195,13 @@
|
|||||||
--
|
--
|
||||||
-- ## Hound TTS as an alternative to 'DCS-SR-ExternalAudio.exe' for TTS
|
-- ## Hound TTS as an alternative to 'DCS-SR-ExternalAudio.exe' for TTS
|
||||||
--
|
--
|
||||||
-- An alternative interface to SRS is [Hound-TTS](https://github.com/uriba107/HoundTTS/releases). This does not call an exe file and therefore avoids the annoying pop-up window.
|
-- the recommended alternative interface to SRS is [Hound-TTS](https://github.com/uriba107/HoundTTS/releases). This does not call an exe file and therefore avoids the annoying pop-up window.
|
||||||
-- In addition to Windows and Google cloud, it also offers Piper local voice creation and others as providers for TTS.
|
-- In addition to Windows and Google cloud, it also offers Piper local voice creation and others as providers for TTS.
|
||||||
--
|
--
|
||||||
-- Use @{#MSRS.SetDefaultBackendHound} to enable [Hound-TTS](https://github.com/uriba107/HoundTTS/releases) as an alternate backend.
|
-- Use @{#MSRS.SetDefaultBackendHound} to enable [Hound-TTS](https://github.com/uriba107/HoundTTS/releases) as an alternate backend.
|
||||||
-- This can be useful if the popup should be avoided or to use Piper or others for TTS. Please note, only text-to-speech is supported and it it cannot be used to transmit audio files.
|
-- This can be useful if the popup should be avoided or to use Piper or others for TTS. Please note, only text-to-speech is supported and it it cannot be used to transmit audio files.
|
||||||
--
|
--
|
||||||
-- Hound TTS must be installed and configured per the [Hound TTS](https://github.com/uriba107/HoundTTS#installation) prior to use.
|
-- Hound TTS must be installed and configured per the [Hound TTS](https://github.com/uriba107/HoundTTS#installation) GitHub prior to use.
|
||||||
-- If a cloud TTS provider is being used, the API key(s) must be set as per the documentation.
|
-- If a cloud TTS provider is being used, the API key(s) must be set as per the documentation.
|
||||||
-- Hound TTS can be used both with DCS dedicated server and regular DCS installations.
|
-- Hound TTS can be used both with DCS dedicated server and regular DCS installations.
|
||||||
--
|
--
|
||||||
@@ -280,7 +284,7 @@ MSRS = {
|
|||||||
|
|
||||||
--- MSRS class version.
|
--- MSRS class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
MSRS.version="0.3.5"
|
MSRS.version="0.3.7"
|
||||||
|
|
||||||
--- Voices
|
--- Voices
|
||||||
-- @type MSRS.Voices
|
-- @type MSRS.Voices
|
||||||
@@ -731,14 +735,16 @@ MSRS.Backend = {
|
|||||||
-- @field #string AZURE Microsoft Azure (`azure`). Only possible with DCS-gRPC backend.
|
-- @field #string AZURE Microsoft Azure (`azure`). Only possible with DCS-gRPC backend.
|
||||||
-- @field #string AMAZON Amazon Web Service (`aws`). Only possible with DCS-gRPC backend.
|
-- @field #string AMAZON Amazon Web Service (`aws`). Only possible with DCS-gRPC backend.
|
||||||
-- @field #string PIPER Piper local voice service. Only possible with Hound-TTS backend.
|
-- @field #string PIPER Piper local voice service. Only possible with Hound-TTS backend.
|
||||||
-- @field #string KITTEN Kitten voice server. Only possible with Hound-TTS backend.
|
-- @field #string KITTEN Kitten voice server. Only possible with Hound-TTS backend. Superseded by OpenAI
|
||||||
|
-- @field #string OPENAI OpenAI voice server. Only possible with Hound-TTS backend.
|
||||||
MSRS.Provider = {
|
MSRS.Provider = {
|
||||||
WINDOWS = "win",
|
WINDOWS = "win",
|
||||||
GOOGLE = "gcloud",
|
GOOGLE = "gcloud",
|
||||||
AZURE = "azure",
|
AZURE = "azure",
|
||||||
AMAZON = "aws",
|
AMAZON = "aws",
|
||||||
PIPER = "piper",
|
PIPER = "piper",
|
||||||
KITTEN = "kitten",
|
KITTEN = "openai",
|
||||||
|
OPENAI = "openai",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Function for UUID.
|
--- Function for UUID.
|
||||||
@@ -1471,6 +1477,15 @@ function MSRS:SetTTSProviderKitten()
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Use OpenAI to provide text-to-speech. Only supported if used in combination with Hound-TTS as backend.
|
||||||
|
-- @param #MSRS self
|
||||||
|
-- @return #MSRS self
|
||||||
|
function MSRS:SetTTSProviderOpenAI()
|
||||||
|
self:F()
|
||||||
|
self:SetProvider(MSRS.Provider.OPENAI)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Print SRS help to DCS log file.
|
--- Print SRS help to DCS log file.
|
||||||
-- @param #MSRS self
|
-- @param #MSRS self
|
||||||
-- @return #MSRS self
|
-- @return #MSRS self
|
||||||
@@ -2088,19 +2103,16 @@ function MSRS:_HoundTextToSpeech(Message,Frequencies,Modulations,Volume,Label,Co
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
Frequencies = UTILS.EnsureTable(Frequencies)
|
Frequencies = UTILS.EnsureTable(Frequencies or self.frequencies)
|
||||||
Modulations = UTILS.EnsureTable(Modulations)
|
Modulations = UTILS.EnsureTable(Modulations or self.modulations)
|
||||||
|
|
||||||
local ffs = {}
|
local ffs = {}
|
||||||
for _,_f in pairs(Frequencies or self.frequencies) do
|
for _,_f in pairs(Frequencies) do
|
||||||
table.insert(ffs,string.format("%.1f",_f))
|
table.insert(ffs,string.format("%.3f",_f))
|
||||||
end
|
end
|
||||||
|
|
||||||
local freqs = table.concat(ffs, ",")
|
local freqs = table.concat(ffs, ",")
|
||||||
|
local modus = table.concat(Modulations, ",")
|
||||||
|
|
||||||
|
|
||||||
local modus = table.concat(Modulations or self.modulations, ",")
|
|
||||||
|
|
||||||
local coal=Coalition or self.coalition
|
local coal=Coalition or self.coalition
|
||||||
local gender=Gender or self.gender
|
local gender=Gender or self.gender
|
||||||
@@ -2202,7 +2214,7 @@ function MSRS:_HoundTestTone(Frequencies, Modulations, Coalition)
|
|||||||
|
|
||||||
local ffs = {}
|
local ffs = {}
|
||||||
for _,_f in pairs(Frequencies or self.frequencies) do
|
for _,_f in pairs(Frequencies or self.frequencies) do
|
||||||
table.insert(ffs,string.format("%.1f",_f))
|
table.insert(ffs,string.format("%.3f",_f))
|
||||||
end
|
end
|
||||||
|
|
||||||
local freqs = table.concat(ffs, ",")
|
local freqs = table.concat(ffs, ",")
|
||||||
@@ -2258,6 +2270,71 @@ function MSRS._HoundTranslate(Message,Parameters,CallbackFunction)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Create and run a radio jammer for a number of seconds on given frequencies. Requires HOUND backend v0.2.0-beta5 or better.
|
||||||
|
-- @param #MSRS self
|
||||||
|
-- @param #table Frequencies The table of frequencies to use.
|
||||||
|
-- @param #table Modulations The table of modulations to use.
|
||||||
|
-- @param #number Coalition (Optional) The coalition to use. Defaults to previously set coalition on this instance.
|
||||||
|
-- @param #string Noisetype (Optional) One of "white" (default) | "chirp" | "harsh" | "jam".
|
||||||
|
-- @param #number Volume (Optional) Volume 0.0–1.0 (default 1.0).
|
||||||
|
-- @param #number Seconds (Optional) How long in seconds this jammer runs. Defaults to 30 seconds.
|
||||||
|
-- @param #string Label (Optional) The label to use, defaults to "MSRS".
|
||||||
|
-- @param DCS#Vec3 Vec3 (Optional) Vec3 of the sender's position.
|
||||||
|
-- @param #boolean Encrypt (Optional) If true, use the SRS encrypt option.
|
||||||
|
-- @param #number EncKey (Optional) If encrypt is true, use this encrypt key.
|
||||||
|
-- @return #number ID The Jammer ID to switch the jamming off again with `MSRS.RadioJammerOff()`
|
||||||
|
function MSRS:RadioJammerOn(Frequencies, Modulations, Coalition, Noisetype, Volume, Seconds, Label, Vec3, Encrypt, EncKey)
|
||||||
|
self:T(self.lid.."RadioJammerOn")
|
||||||
|
|
||||||
|
Frequencies = UTILS.EnsureTable(Frequencies)
|
||||||
|
Modulations = UTILS.EnsureTable(Modulations)
|
||||||
|
|
||||||
|
local ffs = {}
|
||||||
|
for _,_f in pairs(Frequencies or self.frequencies) do
|
||||||
|
table.insert(ffs,string.format("%.3f",_f))
|
||||||
|
end
|
||||||
|
|
||||||
|
local freqs = table.concat(ffs, ",")
|
||||||
|
local modus = table.concat(Modulations or self.modulations, ",")
|
||||||
|
-- Replace modulation
|
||||||
|
modus=modus:gsub("0", "AM")
|
||||||
|
modus=modus:gsub("1", "FM")
|
||||||
|
|
||||||
|
local coal=Coalition or self.coalition or coalition.side.RED
|
||||||
|
local secs = Seconds or 30
|
||||||
|
|
||||||
|
local TransmissionP = {}
|
||||||
|
local ProviderP = {}
|
||||||
|
|
||||||
|
TransmissionP.transmitter = "srs"
|
||||||
|
TransmissionP.freqs = freqs
|
||||||
|
TransmissionP.modulations = modus
|
||||||
|
TransmissionP.coalition = coal or self.coalition -- number 0=spectator, 1=red, 2=blue
|
||||||
|
TransmissionP.name = Label or self.Label -- string client name shown in SRS
|
||||||
|
TransmissionP.point = Vec3 -- DCS Vec3 (optional) — initial transmitter position
|
||||||
|
TransmissionP.encrypt = Encrypt -- bool
|
||||||
|
TransmissionP.encKey = EncKey -- number 0–255
|
||||||
|
|
||||||
|
ProviderP.noiseType = Noisetype or "white"
|
||||||
|
ProviderP.volume = Volume or 1
|
||||||
|
|
||||||
|
local ID = HoundTTS.TransmitNoise(TransmissionP, ProviderP)
|
||||||
|
|
||||||
|
self.NoiseID = ID
|
||||||
|
|
||||||
|
self:ScheduleOnce(secs,MSRS.RadioJammerOff,self,ID)
|
||||||
|
|
||||||
|
return ID
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Switch off a running Jammer using its ID.
|
||||||
|
-- @param #MSRS self
|
||||||
|
-- @param #number ID
|
||||||
|
function MSRS:RadioJammerOff(ID)
|
||||||
|
return HoundTTS.KillSession(ID or self.NoiseID)
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Config File
|
-- Config File
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -523,7 +523,7 @@ ENUMS.ReportingName =
|
|||||||
Tornado = "Tornado",
|
Tornado = "Tornado",
|
||||||
-- Transport / Bomber / Others
|
-- Transport / Bomber / Others
|
||||||
Atlas = "A400",
|
Atlas = "A400",
|
||||||
Lancer = "B1-B",
|
Lancer = "B-1B",
|
||||||
Stratofortress = "B-52H",
|
Stratofortress = "B-52H",
|
||||||
Herc = "C-130",
|
Herc = "C-130",
|
||||||
Hercules = "C-130J-30",
|
Hercules = "C-130J-30",
|
||||||
@@ -568,7 +568,7 @@ ENUMS.ReportingName =
|
|||||||
Apache = "AH-64",
|
Apache = "AH-64",
|
||||||
Chinook = "CH-47",
|
Chinook = "CH-47",
|
||||||
Sea_Stallion = "CH-53",
|
Sea_Stallion = "CH-53",
|
||||||
Kiowa = "OH-58",
|
Kiowa = "OH58D",
|
||||||
Seahawk = "SH-60",
|
Seahawk = "SH-60",
|
||||||
Blackhawk = "UH-60",
|
Blackhawk = "UH-60",
|
||||||
Sea_King = "S-61",
|
Sea_King = "S-61",
|
||||||
@@ -2126,6 +2126,47 @@ ENUMS.Storage.weapons.containers.UH60_GAU19_RIGHT = 'weapons.containers.{UH60_GA
|
|||||||
ENUMS.Storage.weapons.containers.UH60_M230_RIGHT = 'weapons.containers.{UH60_M230_RIGHT}'
|
ENUMS.Storage.weapons.containers.UH60_M230_RIGHT = 'weapons.containers.{UH60_M230_RIGHT}'
|
||||||
ENUMS.Storage.weapons.containers.UH60L_M2_GUNNER = 'weapons.containers.{UH60L_M2_GUNNER}'
|
ENUMS.Storage.weapons.containers.UH60L_M2_GUNNER = 'weapons.containers.{UH60L_M2_GUNNER}'
|
||||||
|
|
||||||
|
|
||||||
|
ENUMS.Storage.weapons.adapters.GD_F100_SUU_13 = 'weapons.adapters.GD_F100_SUU-13'
|
||||||
|
ENUMS.Storage.weapons.containers.GPU_5_POD = 'weapons.containers.{GPU_5_POD}'
|
||||||
|
ENUMS.Storage.weapons.bombs.BOLT_117 = 'weapons.bombs.BOLT-117'
|
||||||
|
ENUMS.Storage.weapons.shells.F100_M39_20_TP_T = 'weapons.shells.F100_M39_20_TP_T'
|
||||||
|
ENUMS.Storage.weapons.gunmounts.M_39_F_100 = 'weapons.gunmounts.M-39 F-100'
|
||||||
|
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_275_L = 'weapons.droptanks.GD_F100_TANK_275_L'
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU_4B_R_GROUP_R = 'weapons.bombs.BLU-4B_R_GROUP_R'
|
||||||
|
ENUMS.Storage.weapons.containers.F100_CAMERA_P2 = 'weapons.containers.F100_CAMERA_P2'
|
||||||
|
ENUMS.Storage.weapons.containers.HB_ORD_SUU_7 = 'weapons.containers.HB_ORD_SUU_7'
|
||||||
|
ENUMS.Storage.weapons.adapters.SidewinderPylon = 'weapons.adapters.SidewinderPylon'
|
||||||
|
ENUMS.Storage.weapons.adapters.apu_470 = 'weapons.adapters.apu_470'
|
||||||
|
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_335_R = 'weapons.droptanks.GD_F100_TANK_335_R'
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU_3B_R_GROUP_R = 'weapons.bombs.BLU-3B_R_GROUP_R'
|
||||||
|
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_335_L = 'weapons.droptanks.GD_F100_TANK_335_L'
|
||||||
|
ENUMS.Storage.weapons.adapters.mbdz_u2t = 'weapons.adapters.mbdz_u2t'
|
||||||
|
ENUMS.Storage.weapons.containers.ZellRocket = 'weapons.containers.ZellRocket'
|
||||||
|
ENUMS.Storage.weapons.containers.apu_73 = 'weapons.containers.apu-73'
|
||||||
|
ENUMS.Storage.weapons.gunmounts.GAU_13 = 'weapons.gunmounts.GAU-13'
|
||||||
|
ENUMS.Storage.weapons.shells.F100_M39_20_TP = 'weapons.shells.F100_M39_20_TP'
|
||||||
|
ENUMS.Storage.weapons.shells.F100_M39_20_API = 'weapons.shells.F100_M39_20_API'
|
||||||
|
ENUMS.Storage.weapons.adapters.bdz_umk2b = 'weapons.adapters.bdz_umk2b'
|
||||||
|
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_450 = 'weapons.droptanks.GD_F100_TANK_450'
|
||||||
|
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_275_R = 'weapons.droptanks.GD_F100_TANK_275_R'
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU_18_B_GROUP = 'weapons.bombs.BLU-18/B_GROUP'
|
||||||
|
ENUMS.Storage.weapons.containers.ZELL_Booster = 'weapons.containers.ZELL Booster'
|
||||||
|
ENUMS.Storage.weapons.adapters.apu_60 = 'weapons.adapters.apu_60'
|
||||||
|
ENUMS.Storage.weapons.gunmounts.GPU_5_POD = 'weapons.gunmounts.{GPU_5_POD}'
|
||||||
|
ENUMS.Storage.weapons.containers.F100_CAMERA_KA71A = 'weapons.containers.F100_CAMERA_KA71A'
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU_3_R_GROUP_R = 'weapons.bombs.BLU-3_R_GROUP_R'
|
||||||
|
ENUMS.Storage.weapons.shells.F100_M39_20_HEI = 'weapons.shells.F100_M39_20_HEI'
|
||||||
|
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_200 = 'weapons.droptanks.GD_F100_TANK_200'
|
||||||
|
ENUMS.Storage.weapons.adapters.apu_73 = 'weapons.adapters.apu-73'
|
||||||
|
ENUMS.Storage.weapons.gunmounts.AKAN_NO_TRC = 'weapons.gunmounts.AKAN_NO_TRC'
|
||||||
|
ENUMS.Storage.weapons.gunmounts.AKAN = 'weapons.gunmounts.AKAN'
|
||||||
|
ENUMS.Storage.weapons.shells.F100_M39_20_HEI_T = 'weapons.shells.F100_M39_20_HEI_T'
|
||||||
|
ENUMS.Storage.weapons.shells.F100_M39_20_API_T = 'weapons.shells.F100_M39_20_API_T'
|
||||||
|
ENUMS.Storage.weapons.containers.GD_F100_STRIKE_CAMERA = 'weapons.containers.GD_F100_STRIKE_CAMERA'
|
||||||
|
ENUMS.Storage.weapons.bombs.BLU_49_B = 'weapons.bombs.BLU-49/B'
|
||||||
|
ENUMS.Storage.weapons.containers.GD_F100_SUU_13 = 'weapons.containers.GD_F100_SUU-13'
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @type ENUMS.FARPType
|
-- @type ENUMS.FARPType
|
||||||
-- @field #string FARP
|
-- @field #string FARP
|
||||||
|
|||||||
@@ -2379,6 +2379,11 @@ function UTILS.IsLoadingDoorOpen( unit_name )
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if type_name == "Ka-50_3" and unit:getDrawArgumentValue(38) == 1 then
|
||||||
|
BASE:T(unit_name .. " cockpit door is open")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
if type_name=="C-130J-30" and (unit:getDrawArgumentValue(86)==1)then
|
if type_name=="C-130J-30" and (unit:getDrawArgumentValue(86)==1)then
|
||||||
BASE:T(unit_name.." rear doors are open")
|
BASE:T(unit_name.." rear doors are open")
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
-- @field #boolean isAirdrome Airbase is an airdrome.
|
-- @field #boolean isAirdrome Airbase is an airdrome.
|
||||||
-- @field #boolean isHelipad Airbase is a helipad.
|
-- @field #boolean isHelipad Airbase is a helipad.
|
||||||
-- @field #boolean isShip Airbase is a ship.
|
-- @field #boolean isShip Airbase is a ship.
|
||||||
|
-- @field #boolean isZell Airbase is a ZELL Booster.
|
||||||
-- @field #table parking Parking spot data.
|
-- @field #table parking Parking spot data.
|
||||||
-- @field #table parkingByID Parking spot data table with ID as key.
|
-- @field #table parkingByID Parking spot data table with ID as key.
|
||||||
-- @field #table parkingWhitelist List of parking spot terminal IDs considered for spawning.
|
-- @field #table parkingWhitelist List of parking spot terminal IDs considered for spawning.
|
||||||
@@ -458,115 +459,420 @@ AIRBASE.TheChannel = {
|
|||||||
|
|
||||||
--- Airbases of the Syria map
|
--- Airbases of the Syria map
|
||||||
--
|
--
|
||||||
-- * `AIRBASE.Syria.Abu_al_Duhur` Abu al-Duhur
|
-- * AIRBASE.Syria.Abu_al_Duhur
|
||||||
-- * `AIRBASE.Syria.Adana_Sakirpasa` Adana Sakirpasa
|
-- * AIRBASE.Syria.Adana_Sakirpasa
|
||||||
-- * `AIRBASE.Syria.Akrotiri` Akrotiri
|
-- * AIRBASE.Syria.Adiyaman
|
||||||
-- * `AIRBASE.Syria.Al_Qusayr` Al Qusayr
|
-- * AIRBASE.Syria.Akrotiri
|
||||||
-- * `AIRBASE.Syria.Al_Dumayr` Al-Dumayr
|
-- * AIRBASE.Syria.Al_Dumayr
|
||||||
-- * `AIRBASE.Syria.Aleppo` Aleppo
|
-- * AIRBASE.Syria.Al_Qusayr
|
||||||
-- * `AIRBASE.Syria.An_Nasiriyah` An Nasiriyah
|
-- * AIRBASE.Syria.Aleppo
|
||||||
-- * `AIRBASE.Syria.At_Tanf` At Tanf
|
-- * AIRBASE.Syria.An_Nasiriyah
|
||||||
-- * `AIRBASE.Syria.Bassel_Al_Assad` Bassel Al-Assad
|
-- * AIRBASE.Syria.At_Tanf
|
||||||
-- * `AIRBASE.Syria.Beirut_Rafic_Hariri` Beirut-Rafic Hariri
|
-- * AIRBASE.Syria.Bassel_Al_Assad
|
||||||
-- * `AIRBASE.Syria.Ben_Gurion` Ben Gurion
|
-- * AIRBASE.Syria.Beirut_Rafic_Hariri
|
||||||
-- * `AIRBASE.Syria.Damascus` Damascus
|
-- * AIRBASE.Syria.Ben_Gurion
|
||||||
-- * `AIRBASE.Syria.Deir_ez_Zor` Deir ez-Zor
|
-- * AIRBASE.Syria.Chukurova
|
||||||
-- * `AIRBASE.Syria.Ercan` Ercan
|
-- * AIRBASE.Syria.Damascus
|
||||||
-- * `AIRBASE.Syria.Eyn_Shemer` Eyn Shemer
|
-- * AIRBASE.Syria.Deir_ez_Zor
|
||||||
-- * `AIRBASE.Syria.Gaziantep` Gaziantep
|
-- * AIRBASE.Syria.Diyarbakir
|
||||||
-- * `AIRBASE.Syria.Gazipasa` Gazipasa
|
-- * AIRBASE.Syria.Ercan
|
||||||
-- * `AIRBASE.Syria.Gecitkale` Gecitkale
|
-- * AIRBASE.Syria.Eyn_Shemer
|
||||||
-- * `AIRBASE.Syria.H` H
|
-- * AIRBASE.Syria.Gaziantep
|
||||||
-- * `AIRBASE.Syria.H3` H3
|
-- * AIRBASE.Syria.Gazipasa
|
||||||
-- * `AIRBASE.Syria.H3_Northwest` H3 Northwest
|
-- * AIRBASE.Syria.Gecitkale
|
||||||
-- * `AIRBASE.Syria.H3_Southwest` H3 Southwest
|
-- * AIRBASE.Syria.Gulechoba
|
||||||
-- * `AIRBASE.Syria.H4` H4
|
-- * AIRBASE.Syria.H3
|
||||||
-- * `AIRBASE.Syria.Haifa` Haifa
|
-- * AIRBASE.Syria.H3_Northwest
|
||||||
-- * `AIRBASE.Syria.Hama` Hama
|
-- * AIRBASE.Syria.H3_Southwest
|
||||||
-- * `AIRBASE.Syria.Hatay` Hatay
|
-- * AIRBASE.Syria.H4
|
||||||
-- * `AIRBASE.Syria.Hatzor` Hatzor
|
-- * AIRBASE.Syria.H4_Emergency
|
||||||
-- * `AIRBASE.Syria.Herzliya` Herzliya
|
-- * AIRBASE.Syria.HC01
|
||||||
-- * `AIRBASE.Syria.Incirlik` Incirlik
|
-- * AIRBASE.Syria.HC02
|
||||||
-- * `AIRBASE.Syria.Jirah` Jirah
|
-- * AIRBASE.Syria.HC03
|
||||||
-- * `AIRBASE.Syria.Khalkhalah` Khalkhalah
|
-- * AIRBASE.Syria.HC04
|
||||||
-- * `AIRBASE.Syria.Kharab_Ishk` Kharab Ishk
|
-- * AIRBASE.Syria.HC05
|
||||||
-- * `AIRBASE.Syria.King_Abdullah_II` King Abdullah II
|
-- * AIRBASE.Syria.HC06
|
||||||
-- * `AIRBASE.Syria.King_Hussein_Air_College` King Hussein Air College
|
-- * AIRBASE.Syria.HI01
|
||||||
-- * `AIRBASE.Syria.Kingsfield` Kingsfield
|
-- * AIRBASE.Syria.HI02
|
||||||
-- * `AIRBASE.Syria.Kiryat_Shmona` Kiryat Shmona
|
-- * AIRBASE.Syria.HI03
|
||||||
-- * `AIRBASE.Syria.Kuweires` Kuweires
|
-- * AIRBASE.Syria.HI05
|
||||||
-- * `AIRBASE.Syria.Lakatamia` Lakatamia
|
-- * AIRBASE.Syria.HI06
|
||||||
-- * `AIRBASE.Syria.Larnaca` Larnaca
|
-- * AIRBASE.Syria.HI07
|
||||||
-- * `AIRBASE.Syria.Marj_Ruhayyil` Marj Ruhayyil
|
-- * AIRBASE.Syria.HI08
|
||||||
-- * `AIRBASE.Syria.Marj_as_Sultan_North` Marj as Sultan North
|
-- * AIRBASE.Syria.HI09
|
||||||
-- * `AIRBASE.Syria.Marj_as_Sultan_South` Marj as Sultan South
|
-- * AIRBASE.Syria.HI11
|
||||||
-- * `AIRBASE.Syria.Marka` Marka
|
-- * AIRBASE.Syria.HI12
|
||||||
-- * `AIRBASE.Syria.Megiddo` Megiddo
|
-- * AIRBASE.Syria.HI13
|
||||||
-- * `AIRBASE.Syria.Mezzeh` Mezzeh
|
-- * AIRBASE.Syria.HI14
|
||||||
-- * `AIRBASE.Syria.Minakh` Minakh
|
-- * AIRBASE.Syria.HI15
|
||||||
-- * `AIRBASE.Syria.Muwaffaq_Salti` Muwaffaq Salti
|
-- * AIRBASE.Syria.HI16
|
||||||
-- * `AIRBASE.Syria.Naqoura` Naqoura
|
-- * AIRBASE.Syria.HI17
|
||||||
-- * `AIRBASE.Syria.Nicosia` Nicosia
|
-- * AIRBASE.Syria.HI18
|
||||||
-- * `AIRBASE.Syria.Palmachim` Palmachim
|
-- * AIRBASE.Syria.HI20
|
||||||
-- * `AIRBASE.Syria.Palmyra` Palmyra
|
-- * AIRBASE.Syria.HI21
|
||||||
-- * `AIRBASE.Syria.Paphos` Paphos
|
-- * AIRBASE.Syria.HI22
|
||||||
-- * `AIRBASE.Syria.Pinarbashi` Pinarbashi
|
-- * AIRBASE.Syria.HI23
|
||||||
-- * `AIRBASE.Syria.Prince_Hassan` Prince Hassan
|
-- * AIRBASE.Syria.HI24
|
||||||
-- * `AIRBASE.Syria.Qabr_as_Sitt` Qabr as Sitt
|
-- * AIRBASE.Syria.HI25
|
||||||
-- * `AIRBASE.Syria.Ramat_David` Ramat David
|
-- * AIRBASE.Syria.HI26
|
||||||
-- * `AIRBASE.Syria.Rayak` Rayak
|
-- * AIRBASE.Syria.HJ01
|
||||||
-- * `AIRBASE.Syria.Rene_Mouawad` Rene Mouawad
|
-- * AIRBASE.Syria.HJ02
|
||||||
-- * `AIRBASE.Syria.Rosh_Pina` Rosh Pina
|
-- * AIRBASE.Syria.HJ03
|
||||||
-- * `AIRBASE.Syria.Ruwayshid` Ruwayshid
|
-- * AIRBASE.Syria.HJ04
|
||||||
-- * `AIRBASE.Syria.Sanliurfa` Sanliurfa
|
-- * AIRBASE.Syria.HL01
|
||||||
-- * `AIRBASE.Syria.Sayqal` Sayqal
|
-- * AIRBASE.Syria.HL02
|
||||||
-- * `AIRBASE.Syria.Shayrat` Shayrat
|
-- * AIRBASE.Syria.HL03
|
||||||
-- * `AIRBASE.Syria.Tabqa` Tabqa
|
-- * AIRBASE.Syria.HL04
|
||||||
-- * `AIRBASE.Syria.Taftanaz` Taftanaz
|
-- * AIRBASE.Syria.HL05
|
||||||
-- * `AIRBASE.Syria.Tal_Siman` Tal Siman
|
-- * AIRBASE.Syria.HL06
|
||||||
-- * `AIRBASE.Syria.Tel_Nof` Tel Nof
|
-- * AIRBASE.Syria.HL07
|
||||||
-- * `AIRBASE.Syria.Tha_lah` Tha'lah
|
-- * AIRBASE.Syria.HL08
|
||||||
-- * `AIRBASE.Syria.Tiyas` Tiyas
|
-- * AIRBASE.Syria.HL09
|
||||||
-- * `AIRBASE.Syria.Wujah_Al_Hajar` Wujah Al Hajar
|
-- * AIRBASE.Syria.HL10
|
||||||
|
-- * AIRBASE.Syria.HL11
|
||||||
|
-- * AIRBASE.Syria.HL12
|
||||||
|
-- * AIRBASE.Syria.HL13
|
||||||
|
-- * AIRBASE.Syria.HMed00
|
||||||
|
-- * AIRBASE.Syria.HMed01
|
||||||
|
-- * AIRBASE.Syria.HMed02
|
||||||
|
-- * AIRBASE.Syria.HMed03
|
||||||
|
-- * AIRBASE.Syria.HMed04
|
||||||
|
-- * AIRBASE.Syria.HMed05
|
||||||
|
-- * AIRBASE.Syria.HMed06
|
||||||
|
-- * AIRBASE.Syria.HMed07
|
||||||
|
-- * AIRBASE.Syria.HMed08
|
||||||
|
-- * AIRBASE.Syria.HMed09
|
||||||
|
-- * AIRBASE.Syria.HMed10
|
||||||
|
-- * AIRBASE.Syria.HMed11
|
||||||
|
-- * AIRBASE.Syria.HMed12
|
||||||
|
-- * AIRBASE.Syria.HMed13
|
||||||
|
-- * AIRBASE.Syria.HMed14
|
||||||
|
-- * AIRBASE.Syria.HMed15
|
||||||
|
-- * AIRBASE.Syria.HMed16
|
||||||
|
-- * AIRBASE.Syria.HMed17
|
||||||
|
-- * AIRBASE.Syria.HMed18
|
||||||
|
-- * AIRBASE.Syria.HMed19
|
||||||
|
-- * AIRBASE.Syria.HMed20
|
||||||
|
-- * AIRBASE.Syria.HMed21
|
||||||
|
-- * AIRBASE.Syria.HMed22
|
||||||
|
-- * AIRBASE.Syria.HMed23
|
||||||
|
-- * AIRBASE.Syria.HMed24
|
||||||
|
-- * AIRBASE.Syria.HMed25
|
||||||
|
-- * AIRBASE.Syria.HMed26
|
||||||
|
-- * AIRBASE.Syria.HMed27
|
||||||
|
-- * AIRBASE.Syria.HMed28
|
||||||
|
-- * AIRBASE.Syria.HMed29
|
||||||
|
-- * AIRBASE.Syria.HMed30
|
||||||
|
-- * AIRBASE.Syria.HOil01
|
||||||
|
-- * AIRBASE.Syria.HOil02
|
||||||
|
-- * AIRBASE.Syria.HOil03
|
||||||
|
-- * AIRBASE.Syria.HOil04
|
||||||
|
-- * AIRBASE.Syria.HOil05
|
||||||
|
-- * AIRBASE.Syria.HOil06
|
||||||
|
-- * AIRBASE.Syria.HS02
|
||||||
|
-- * AIRBASE.Syria.HS03
|
||||||
|
-- * AIRBASE.Syria.HS04
|
||||||
|
-- * AIRBASE.Syria.HS05
|
||||||
|
-- * AIRBASE.Syria.HS06
|
||||||
|
-- * AIRBASE.Syria.HS07
|
||||||
|
-- * AIRBASE.Syria.HS08
|
||||||
|
-- * AIRBASE.Syria.HS09
|
||||||
|
-- * AIRBASE.Syria.HS10
|
||||||
|
-- * AIRBASE.Syria.HS11
|
||||||
|
-- * AIRBASE.Syria.HS12
|
||||||
|
-- * AIRBASE.Syria.HS13
|
||||||
|
-- * AIRBASE.Syria.HS14
|
||||||
|
-- * AIRBASE.Syria.HS15
|
||||||
|
-- * AIRBASE.Syria.HS16
|
||||||
|
-- * AIRBASE.Syria.HS17
|
||||||
|
-- * AIRBASE.Syria.HS18
|
||||||
|
-- * AIRBASE.Syria.HS19
|
||||||
|
-- * AIRBASE.Syria.HS20
|
||||||
|
-- * AIRBASE.Syria.HS21
|
||||||
|
-- * AIRBASE.Syria.HS22
|
||||||
|
-- * AIRBASE.Syria.HS23
|
||||||
|
-- * AIRBASE.Syria.HS24
|
||||||
|
-- * AIRBASE.Syria.HS25
|
||||||
|
-- * AIRBASE.Syria.HS26
|
||||||
|
-- * AIRBASE.Syria.HS27
|
||||||
|
-- * AIRBASE.Syria.HS28
|
||||||
|
-- * AIRBASE.Syria.HS29
|
||||||
|
-- * AIRBASE.Syria.HS30
|
||||||
|
-- * AIRBASE.Syria.HS31
|
||||||
|
-- * AIRBASE.Syria.HS32
|
||||||
|
-- * AIRBASE.Syria.HS33
|
||||||
|
-- * AIRBASE.Syria.HS34
|
||||||
|
-- * AIRBASE.Syria.HS35
|
||||||
|
-- * AIRBASE.Syria.HS36
|
||||||
|
-- * AIRBASE.Syria.HS37
|
||||||
|
-- * AIRBASE.Syria.HS38
|
||||||
|
-- * AIRBASE.Syria.HS39
|
||||||
|
-- * AIRBASE.Syria.HS40
|
||||||
|
-- * AIRBASE.Syria.HS41
|
||||||
|
-- * AIRBASE.Syria.HS42
|
||||||
|
-- * AIRBASE.Syria.HStad01
|
||||||
|
-- * AIRBASE.Syria.HStad02
|
||||||
|
-- * AIRBASE.Syria.HStad03
|
||||||
|
-- * AIRBASE.Syria.HStad04
|
||||||
|
-- * AIRBASE.Syria.HStad05
|
||||||
|
-- * AIRBASE.Syria.HStad06
|
||||||
|
-- * AIRBASE.Syria.HT01
|
||||||
|
-- * AIRBASE.Syria.HT02
|
||||||
|
-- * AIRBASE.Syria.H_med_orig_01
|
||||||
|
-- * AIRBASE.Syria.H_med_orig_02
|
||||||
|
-- * AIRBASE.Syria.H_med_orig_03
|
||||||
|
-- * AIRBASE.Syria.H_med_orig_04
|
||||||
|
-- * AIRBASE.Syria.H_med_orig_05
|
||||||
|
-- * AIRBASE.Syria.H_med_orig_06
|
||||||
|
-- * AIRBASE.Syria.H_med_orig_07
|
||||||
|
-- * AIRBASE.Syria.H_med_orig_08
|
||||||
|
-- * AIRBASE.Syria.H_med_orig_09
|
||||||
|
-- * AIRBASE.Syria.Haifa
|
||||||
|
-- * AIRBASE.Syria.Hama
|
||||||
|
-- * AIRBASE.Syria.Hatay
|
||||||
|
-- * AIRBASE.Syria.Hatzerim
|
||||||
|
-- * AIRBASE.Syria.Hatzor
|
||||||
|
-- * AIRBASE.Syria.Herzliya
|
||||||
|
-- * AIRBASE.Syria.Incirlik
|
||||||
|
-- * AIRBASE.Syria.Jirah
|
||||||
|
-- * AIRBASE.Syria.Kahramanmaras
|
||||||
|
-- * AIRBASE.Syria.Kedem
|
||||||
|
-- * AIRBASE.Syria.Khalkhalah
|
||||||
|
-- * AIRBASE.Syria.Kharab_Ishk
|
||||||
|
-- * AIRBASE.Syria.King_Abdullah_II
|
||||||
|
-- * AIRBASE.Syria.King_Hussein_Air_College
|
||||||
|
-- * AIRBASE.Syria.Kingsfield
|
||||||
|
-- * AIRBASE.Syria.Kiryat_Shmona
|
||||||
|
-- * AIRBASE.Syria.Konya
|
||||||
|
-- * AIRBASE.Syria.Kuweires
|
||||||
|
-- * AIRBASE.Syria.Lakatamia
|
||||||
|
-- * AIRBASE.Syria.Larnaca
|
||||||
|
-- * AIRBASE.Syria.Marj_Ruhayyil
|
||||||
|
-- * AIRBASE.Syria.Marj_as_Sultan_North
|
||||||
|
-- * AIRBASE.Syria.Marj_as_Sultan_South
|
||||||
|
-- * AIRBASE.Syria.Marka
|
||||||
|
-- * AIRBASE.Syria.Megiddo
|
||||||
|
-- * AIRBASE.Syria.Mezzeh
|
||||||
|
-- * AIRBASE.Syria.Minakh
|
||||||
|
-- * AIRBASE.Syria.Muwaffaq_Salti
|
||||||
|
-- * AIRBASE.Syria.Naqoura
|
||||||
|
-- * AIRBASE.Syria.Nevatim
|
||||||
|
-- * AIRBASE.Syria.Nicosia
|
||||||
|
-- * AIRBASE.Syria.Palmachim
|
||||||
|
-- * AIRBASE.Syria.Palmyra
|
||||||
|
-- * AIRBASE.Syria.Paphos
|
||||||
|
-- * AIRBASE.Syria.Pinarbashi
|
||||||
|
-- * AIRBASE.Syria.Prince_Hassan
|
||||||
|
-- * AIRBASE.Syria.Qabr_as_Sitt
|
||||||
|
-- * AIRBASE.Syria.Ramat_David
|
||||||
|
-- * AIRBASE.Syria.Rayak
|
||||||
|
-- * AIRBASE.Syria.Rene_Mouawad
|
||||||
|
-- * AIRBASE.Syria.Rosh_Pina
|
||||||
|
-- * AIRBASE.Syria.Ruwayshid
|
||||||
|
-- * AIRBASE.Syria.Sanliurfa
|
||||||
|
-- * AIRBASE.Syria.Sanliurfa_Heliport
|
||||||
|
-- * AIRBASE.Syria.Sayqal
|
||||||
|
-- * AIRBASE.Syria.Shayrat
|
||||||
|
-- * AIRBASE.Syria.T2
|
||||||
|
-- * AIRBASE.Syria.T3
|
||||||
|
-- * AIRBASE.Syria.Tabqa
|
||||||
|
-- * AIRBASE.Syria.Taftanaz
|
||||||
|
-- * AIRBASE.Syria.Tal_Siman
|
||||||
|
-- * AIRBASE.Syria.Tel_Nof
|
||||||
|
-- * AIRBASE.Syria.Teyman
|
||||||
|
-- * AIRBASE.Syria.Tha_lah
|
||||||
|
-- * AIRBASE.Syria.Tiyas
|
||||||
|
-- * AIRBASE.Syria.Wujah_Al_Hajar
|
||||||
|
-- * AIRBASE.Syria.Zarqa
|
||||||
|
|
||||||
--
|
--
|
||||||
-- @field Syria
|
-- @field Syria
|
||||||
AIRBASE.Syria = {
|
AIRBASE.Syria = {
|
||||||
["Abu_al_Duhur"] = "Abu al-Duhur",
|
["Abu_al_Duhur"] = "Abu al-Duhur",
|
||||||
["Adana_Sakirpasa"] = "Adana Sakirpasa",
|
["Adana_Sakirpasa"] = "Adana Sakirpasa",
|
||||||
|
["Adiyaman"] = "Adiyaman",
|
||||||
["Akrotiri"] = "Akrotiri",
|
["Akrotiri"] = "Akrotiri",
|
||||||
["Al_Qusayr"] = "Al Qusayr",
|
|
||||||
["Al_Dumayr"] = "Al-Dumayr",
|
["Al_Dumayr"] = "Al-Dumayr",
|
||||||
|
["Al_Qusayr"] = "Al Qusayr",
|
||||||
["Aleppo"] = "Aleppo",
|
["Aleppo"] = "Aleppo",
|
||||||
["An_Nasiriyah"] = "An Nasiriyah",
|
["An_Nasiriyah"] = "An Nasiriyah",
|
||||||
["At_Tanf"] = "At Tanf",
|
["At_Tanf"] = "At Tanf",
|
||||||
["Bassel_Al_Assad"] = "Bassel Al-Assad",
|
["Bassel_Al_Assad"] = "Bassel Al-Assad",
|
||||||
["Beirut_Rafic_Hariri"] = "Beirut-Rafic Hariri",
|
["Beirut_Rafic_Hariri"] = "Beirut-Rafic Hariri",
|
||||||
["Ben_Gurion"] = "Ben Gurion",
|
["Ben_Gurion"] = "Ben Gurion",
|
||||||
|
["Chukurova"] = "Chukurova",
|
||||||
["Damascus"] = "Damascus",
|
["Damascus"] = "Damascus",
|
||||||
["Deir_ez_Zor"] = "Deir ez-Zor",
|
["Deir_ez_Zor"] = "Deir ez-Zor",
|
||||||
|
["Diyarbakir"] = "Diyarbakir",
|
||||||
["Ercan"] = "Ercan",
|
["Ercan"] = "Ercan",
|
||||||
["Eyn_Shemer"] = "Eyn Shemer",
|
["Eyn_Shemer"] = "Eyn Shemer",
|
||||||
["Gaziantep"] = "Gaziantep",
|
["Gaziantep"] = "Gaziantep",
|
||||||
["Gazipasa"] = "Gazipasa",
|
["Gazipasa"] = "Gazipasa",
|
||||||
["Gecitkale"] = "Gecitkale",
|
["Gecitkale"] = "Gecitkale",
|
||||||
["H"] = "H",
|
["Gulechoba"] = "Gulechoba",
|
||||||
["H3"] = "H3",
|
["H3"] = "H3",
|
||||||
["H3_Northwest"] = "H3 Northwest",
|
["H3_Northwest"] = "H3 Northwest",
|
||||||
["H3_Southwest"] = "H3 Southwest",
|
["H3_Southwest"] = "H3 Southwest",
|
||||||
["H4"] = "H4",
|
["H4"] = "H4",
|
||||||
|
["H4_Emergency"] = "H4 Emergency",
|
||||||
|
["HC01"] = "HC01",
|
||||||
|
["HC02"] = "HC02",
|
||||||
|
["HC03"] = "HC03",
|
||||||
|
["HC04"] = "HC04",
|
||||||
|
["HC05"] = "HC05",
|
||||||
|
["HC06"] = "HC06",
|
||||||
|
["HI01"] = "HI01",
|
||||||
|
["HI02"] = "HI02",
|
||||||
|
["HI03"] = "HI03",
|
||||||
|
["HI05"] = "HI05",
|
||||||
|
["HI06"] = "HI06",
|
||||||
|
["HI07"] = "HI07",
|
||||||
|
["HI08"] = "HI08",
|
||||||
|
["HI09"] = "HI09",
|
||||||
|
["HI11"] = "HI11",
|
||||||
|
["HI12"] = "HI12",
|
||||||
|
["HI13"] = "HI13",
|
||||||
|
["HI14"] = "HI14",
|
||||||
|
["HI15"] = "HI15",
|
||||||
|
["HI16"] = "HI16",
|
||||||
|
["HI17"] = "HI17",
|
||||||
|
["HI18"] = "HI18",
|
||||||
|
["HI20"] = "HI20",
|
||||||
|
["HI21"] = "HI21",
|
||||||
|
["HI22"] = "HI22",
|
||||||
|
["HI23"] = "HI23",
|
||||||
|
["HI24"] = "HI24",
|
||||||
|
["HI25"] = "HI25",
|
||||||
|
["HI26"] = "HI26",
|
||||||
|
["HJ01"] = "HJ01",
|
||||||
|
["HJ02"] = "HJ02",
|
||||||
|
["HJ03"] = "HJ03",
|
||||||
|
["HJ04"] = "HJ04",
|
||||||
|
["HL01"] = "HL01",
|
||||||
|
["HL02"] = "HL02",
|
||||||
|
["HL03"] = "HL03",
|
||||||
|
["HL04"] = "HL04",
|
||||||
|
["HL05"] = "HL05",
|
||||||
|
["HL06"] = "HL06",
|
||||||
|
["HL07"] = "HL07",
|
||||||
|
["HL08"] = "HL08",
|
||||||
|
["HL09"] = "HL09",
|
||||||
|
["HL10"] = "HL10",
|
||||||
|
["HL11"] = "HL11",
|
||||||
|
["HL12"] = "HL12",
|
||||||
|
["HL13"] = "HL13",
|
||||||
|
["HMed00"] = "HMed00",
|
||||||
|
["HMed01"] = "HMed01",
|
||||||
|
["HMed02"] = "HMed02",
|
||||||
|
["HMed03"] = "HMed03",
|
||||||
|
["HMed04"] = "HMed04",
|
||||||
|
["HMed05"] = "HMed05",
|
||||||
|
["HMed06"] = "HMed06",
|
||||||
|
["HMed07"] = "HMed07",
|
||||||
|
["HMed08"] = "HMed08",
|
||||||
|
["HMed09"] = "HMed09",
|
||||||
|
["HMed10"] = "HMed10",
|
||||||
|
["HMed11"] = "HMed11",
|
||||||
|
["HMed12"] = "HMed12",
|
||||||
|
["HMed13"] = "HMed13",
|
||||||
|
["HMed14"] = "HMed14",
|
||||||
|
["HMed15"] = "HMed15",
|
||||||
|
["HMed16"] = "HMed16",
|
||||||
|
["HMed17"] = "HMed17",
|
||||||
|
["HMed18"] = "HMed18",
|
||||||
|
["HMed19"] = "HMed19",
|
||||||
|
["HMed20"] = "HMed20",
|
||||||
|
["HMed21"] = "HMed21",
|
||||||
|
["HMed22"] = "HMed22",
|
||||||
|
["HMed23"] = "HMed23",
|
||||||
|
["HMed24"] = "HMed24",
|
||||||
|
["HMed25"] = "HMed25",
|
||||||
|
["HMed26"] = "HMed26",
|
||||||
|
["HMed27"] = "HMed27",
|
||||||
|
["HMed28"] = "HMed28",
|
||||||
|
["HMed29"] = "HMed29",
|
||||||
|
["HMed30"] = "HMed30",
|
||||||
|
["HOil01"] = "HOil01",
|
||||||
|
["HOil02"] = "HOil02",
|
||||||
|
["HOil03"] = "HOil03",
|
||||||
|
["HOil04"] = "HOil04",
|
||||||
|
["HOil05"] = "HOil05",
|
||||||
|
["HOil06"] = "HOil06",
|
||||||
|
["HS02"] = "HS02",
|
||||||
|
["HS03"] = "HS03",
|
||||||
|
["HS04"] = "HS04",
|
||||||
|
["HS05"] = "HS05",
|
||||||
|
["HS06"] = "HS06",
|
||||||
|
["HS07"] = "HS07",
|
||||||
|
["HS08"] = "HS08",
|
||||||
|
["HS09"] = "HS09",
|
||||||
|
["HS10"] = "HS10",
|
||||||
|
["HS11"] = "HS11",
|
||||||
|
["HS12"] = "HS12",
|
||||||
|
["HS13"] = "HS13",
|
||||||
|
["HS14"] = "HS14",
|
||||||
|
["HS15"] = "HS15",
|
||||||
|
["HS16"] = "HS16",
|
||||||
|
["HS17"] = "HS17",
|
||||||
|
["HS18"] = "HS18",
|
||||||
|
["HS19"] = "HS19",
|
||||||
|
["HS20"] = "HS20",
|
||||||
|
["HS21"] = "HS21",
|
||||||
|
["HS22"] = "HS22",
|
||||||
|
["HS23"] = "HS23",
|
||||||
|
["HS24"] = "HS24",
|
||||||
|
["HS25"] = "HS25",
|
||||||
|
["HS26"] = "HS26",
|
||||||
|
["HS27"] = "HS27",
|
||||||
|
["HS28"] = "HS28",
|
||||||
|
["HS29"] = "HS29",
|
||||||
|
["HS30"] = "HS30",
|
||||||
|
["HS31"] = "HS31",
|
||||||
|
["HS32"] = "HS32",
|
||||||
|
["HS33"] = "HS33",
|
||||||
|
["HS34"] = "HS34",
|
||||||
|
["HS35"] = "HS35",
|
||||||
|
["HS36"] = "HS36",
|
||||||
|
["HS37"] = "HS37",
|
||||||
|
["HS38"] = "HS38",
|
||||||
|
["HS39"] = "HS39",
|
||||||
|
["HS40"] = "HS40",
|
||||||
|
["HS41"] = "HS41",
|
||||||
|
["HS42"] = "HS42",
|
||||||
|
["HStad01"] = "HStad01",
|
||||||
|
["HStad02"] = "HStad02",
|
||||||
|
["HStad03"] = "HStad03",
|
||||||
|
["HStad04"] = "HStad04",
|
||||||
|
["HStad05"] = "HStad05",
|
||||||
|
["HStad06"] = "HStad06",
|
||||||
|
["HT01"] = "HT01",
|
||||||
|
["HT02"] = "HT02",
|
||||||
|
["H_med_orig_01"] = "H_med_orig_01",
|
||||||
|
["H_med_orig_02"] = "H_med_orig_02",
|
||||||
|
["H_med_orig_03"] = "H_med_orig_03",
|
||||||
|
["H_med_orig_04"] = "H_med_orig_04",
|
||||||
|
["H_med_orig_05"] = "H_med_orig_05",
|
||||||
|
["H_med_orig_06"] = "H_med_orig_06",
|
||||||
|
["H_med_orig_07"] = "H_med_orig_07",
|
||||||
|
["H_med_orig_08"] = "H_med_orig_08",
|
||||||
|
["H_med_orig_09"] = "H_med_orig_09",
|
||||||
["Haifa"] = "Haifa",
|
["Haifa"] = "Haifa",
|
||||||
["Hama"] = "Hama",
|
["Hama"] = "Hama",
|
||||||
["Hatay"] = "Hatay",
|
["Hatay"] = "Hatay",
|
||||||
|
["Hatzerim"] = "Hatzerim",
|
||||||
["Hatzor"] = "Hatzor",
|
["Hatzor"] = "Hatzor",
|
||||||
["Herzliya"] = "Herzliya",
|
["Herzliya"] = "Herzliya",
|
||||||
["Incirlik"] = "Incirlik",
|
["Incirlik"] = "Incirlik",
|
||||||
["Jirah"] = "Jirah",
|
["Jirah"] = "Jirah",
|
||||||
|
["Kahramanmaras"] = "Kahramanmaras",
|
||||||
|
["Kedem"] = "Kedem",
|
||||||
["Khalkhalah"] = "Khalkhalah",
|
["Khalkhalah"] = "Khalkhalah",
|
||||||
["Kharab_Ishk"] = "Kharab Ishk",
|
["Kharab_Ishk"] = "Kharab Ishk",
|
||||||
["King_Abdullah_II"] = "King Abdullah II",
|
["King_Abdullah_II"] = "King Abdullah II",
|
||||||
["King_Hussein_Air_College"] = "King Hussein Air College",
|
["King_Hussein_Air_College"] = "King Hussein Air College",
|
||||||
["Kingsfield"] = "Kingsfield",
|
["Kingsfield"] = "Kingsfield",
|
||||||
["Kiryat_Shmona"] = "Kiryat Shmona",
|
["Kiryat_Shmona"] = "Kiryat Shmona",
|
||||||
|
["Konya"] = "Konya",
|
||||||
["Kuweires"] = "Kuweires",
|
["Kuweires"] = "Kuweires",
|
||||||
["Lakatamia"] = "Lakatamia",
|
["Lakatamia"] = "Lakatamia",
|
||||||
["Larnaca"] = "Larnaca",
|
["Larnaca"] = "Larnaca",
|
||||||
@@ -579,6 +885,7 @@ AIRBASE.Syria = {
|
|||||||
["Minakh"] = "Minakh",
|
["Minakh"] = "Minakh",
|
||||||
["Muwaffaq_Salti"] = "Muwaffaq Salti",
|
["Muwaffaq_Salti"] = "Muwaffaq Salti",
|
||||||
["Naqoura"] = "Naqoura",
|
["Naqoura"] = "Naqoura",
|
||||||
|
["Nevatim"] = "Nevatim",
|
||||||
["Nicosia"] = "Nicosia",
|
["Nicosia"] = "Nicosia",
|
||||||
["Palmachim"] = "Palmachim",
|
["Palmachim"] = "Palmachim",
|
||||||
["Palmyra"] = "Palmyra",
|
["Palmyra"] = "Palmyra",
|
||||||
@@ -592,15 +899,20 @@ AIRBASE.Syria = {
|
|||||||
["Rosh_Pina"] = "Rosh Pina",
|
["Rosh_Pina"] = "Rosh Pina",
|
||||||
["Ruwayshid"] = "Ruwayshid",
|
["Ruwayshid"] = "Ruwayshid",
|
||||||
["Sanliurfa"] = "Sanliurfa",
|
["Sanliurfa"] = "Sanliurfa",
|
||||||
|
["Sanliurfa_Heliport"] = "Sanliurfa Heliport",
|
||||||
["Sayqal"] = "Sayqal",
|
["Sayqal"] = "Sayqal",
|
||||||
["Shayrat"] = "Shayrat",
|
["Shayrat"] = "Shayrat",
|
||||||
|
["T2"] = "T2",
|
||||||
|
["T3"] = "T3",
|
||||||
["Tabqa"] = "Tabqa",
|
["Tabqa"] = "Tabqa",
|
||||||
["Taftanaz"] = "Taftanaz",
|
["Taftanaz"] = "Taftanaz",
|
||||||
["Tal_Siman"] = "Tal Siman",
|
["Tal_Siman"] = "Tal Siman",
|
||||||
["Tel_Nof"] = "Tel Nof",
|
["Tel_Nof"] = "Tel Nof",
|
||||||
|
["Teyman"] = "Teyman",
|
||||||
["Tha_lah"] = "Tha'lah",
|
["Tha_lah"] = "Tha'lah",
|
||||||
["Tiyas"] = "Tiyas",
|
["Tiyas"] = "Tiyas",
|
||||||
["Wujah_Al_Hajar"] = "Wujah Al Hajar",
|
["Wujah_Al_Hajar"] = "Wujah Al Hajar",
|
||||||
|
["Zarqa"] = "Zarqa",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Airbases of the Mariana Islands map
|
--- Airbases of the Mariana Islands map
|
||||||
@@ -1673,6 +1985,7 @@ elseif self.category==Airbase.Category.SHIP then
|
|||||||
self.category=Airbase.Category.HELIPAD
|
self.category=Airbase.Category.HELIPAD
|
||||||
_DATABASE:AddStatic(AirbaseName)
|
_DATABASE:AddStatic(AirbaseName)
|
||||||
end
|
end
|
||||||
|
if self:GetTypeName() == "Zell" then self.isZell = true end
|
||||||
else
|
else
|
||||||
self:E("ERROR: Unknown airbase category!")
|
self:E("ERROR: Unknown airbase category!")
|
||||||
end
|
end
|
||||||
@@ -2122,6 +2435,13 @@ function AIRBASE:IsShip()
|
|||||||
return self.isShip
|
return self.isShip
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Check if airbase is a ZELL booster.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @return #boolean If true, airbase is a ZELL booster.
|
||||||
|
function AIRBASE:IsZell()
|
||||||
|
return self.isZell
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Parking
|
-- Parking
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ Ops/OpsZone.lua
|
|||||||
Ops/ArmyGroup.lua
|
Ops/ArmyGroup.lua
|
||||||
Ops/OpsTransport.lua
|
Ops/OpsTransport.lua
|
||||||
Ops/Target.lua
|
Ops/Target.lua
|
||||||
|
Ops/TARS.lua
|
||||||
|
|
||||||
Sound/UserSound.lua
|
Sound/UserSound.lua
|
||||||
Sound/SoundOutput.lua
|
Sound/SoundOutput.lua
|
||||||
|
|||||||
Reference in New Issue
Block a user