mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'develop' into FF/Ops
This commit is contained in:
commit
c8b36b8c99
8
.github/workflows/build-includes.yml
vendored
8
.github/workflows/build-includes.yml
vendored
@ -95,10 +95,6 @@ jobs:
|
|||||||
export COMMIT_TIME=$(git show -s --format=%cd ${{ github.sha }} --date=iso-strict)
|
export COMMIT_TIME=$(git show -s --format=%cd ${{ github.sha }} --date=iso-strict)
|
||||||
lua5.3 "./Moose Setup/Moose_Create.lua" D "$COMMIT_TIME-${{ github.sha }}" "./Moose Development/Moose" "./Moose Setup" "./build/result/Moose_Include_Dynamic"
|
lua5.3 "./Moose Setup/Moose_Create.lua" D "$COMMIT_TIME-${{ github.sha }}" "./Moose Development/Moose" "./Moose Setup" "./build/result/Moose_Include_Dynamic"
|
||||||
|
|
||||||
- name: Run LuaSrcDiet
|
|
||||||
run: |
|
|
||||||
luasrcdiet --basic --opt-emptylines ./build/result/Moose_Include_Static/Moose.lua -o ./build/result/Moose_Include_Static/Moose_.lua
|
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
# Run LuaCheck
|
# Run LuaCheck
|
||||||
#########################################################################
|
#########################################################################
|
||||||
@ -108,6 +104,10 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
luacheck --std=lua51c --config=.luacheckrc -gurasqq "Moose Development/Moose"
|
luacheck --std=lua51c --config=.luacheckrc -gurasqq "Moose Development/Moose"
|
||||||
|
|
||||||
|
- name: Run LuaSrcDiet
|
||||||
|
run: |
|
||||||
|
luasrcdiet --basic --opt-emptylines ./build/result/Moose_Include_Static/Moose.lua -o ./build/result/Moose_Include_Static/Moose_.lua
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
# Push to MOOSE_INCLUDE
|
# Push to MOOSE_INCLUDE
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
--
|
--
|
||||||
-- ## Missions:
|
-- ## Missions:
|
||||||
--
|
--
|
||||||
-- [AID-A2A - AI A2A Dispatching](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching)
|
-- [AID-A2A - AI A2A Dispatching](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/AI_A2A_Dispatcher)
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -310,7 +310,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
-- Use the method @{#AI_A2A_DISPATCHER.SetEngageRadius}() to set a specific Engage Radius.
|
-- Use the method @{#AI_A2A_DISPATCHER.SetEngageRadius}() to set a specific Engage Radius.
|
||||||
-- **The Engage Radius is defined for ALL squadrons which are operational.**
|
-- **The Engage Radius is defined for ALL squadrons which are operational.**
|
||||||
--
|
--
|
||||||
-- Demonstration Mission: [AID-019 - AI_A2A - Engage Range Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching/AID-A2A-019%20-%20Engage%20Range%20Test)
|
-- Demonstration Mission: [AID-019 - AI_A2A - Engage Range Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/AI_A2A_Dispatcher/AID-A2A-019%20-%20Engage%20Range%20Test)
|
||||||
--
|
--
|
||||||
-- In this example an Engage Radius is set to various values.
|
-- In this example an Engage Radius is set to various values.
|
||||||
--
|
--
|
||||||
@ -333,7 +333,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
-- Use the method @{#AI_A2A_DISPATCHER.SetGciRadius}() to set a specific controlled ground intercept radius.
|
-- Use the method @{#AI_A2A_DISPATCHER.SetGciRadius}() to set a specific controlled ground intercept radius.
|
||||||
-- **The Ground Controlled Intercept radius is defined for ALL squadrons which are operational.**
|
-- **The Ground Controlled Intercept radius is defined for ALL squadrons which are operational.**
|
||||||
--
|
--
|
||||||
-- Demonstration Mission: [AID-013 - AI_A2A - Intercept Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching/AID-A2A-013%20-%20Intercept%20Test)
|
-- Demonstration Mission: [AID-013 - AI_A2A - Intercept Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/AI_A2A_Dispatcher/AID-A2A-013%20-%20Intercept%20Test)
|
||||||
--
|
--
|
||||||
-- In these examples, the Gci Radius is set to various values:
|
-- In these examples, the Gci Radius is set to various values:
|
||||||
--
|
--
|
||||||
@ -366,7 +366,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
-- it makes it easier sometimes for the mission maker to envisage where the red and blue territories roughly are.
|
-- it makes it easier sometimes for the mission maker to envisage where the red and blue territories roughly are.
|
||||||
-- In a hot war the borders are effectively defined by the ground based radar coverage of a coalition.
|
-- In a hot war the borders are effectively defined by the ground based radar coverage of a coalition.
|
||||||
--
|
--
|
||||||
-- Demonstration Mission: [AID-009 - AI_A2A - Border Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching/AID-A2A-009%20-%20Border%20Test)
|
-- Demonstration Mission: [AID-009 - AI_A2A - Border Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/AI_A2A_Dispatcher/AID-A2A-009%20-%20Border%20Test)
|
||||||
--
|
--
|
||||||
-- In this example a border is set for the CCCP A2A dispatcher:
|
-- In this example a border is set for the CCCP A2A dispatcher:
|
||||||
--
|
--
|
||||||
@ -1233,7 +1233,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
--
|
--
|
||||||
-- **Use the method @{#AI_A2A_DISPATCHER.SetEngageRadius}() to modify the default Engage Radius for ALL squadrons.**
|
-- **Use the method @{#AI_A2A_DISPATCHER.SetEngageRadius}() to modify the default Engage Radius for ALL squadrons.**
|
||||||
--
|
--
|
||||||
-- Demonstration Mission: [AID-019 - AI_A2A - Engage Range Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching/AID-A2A-019%20-%20Engage%20Range%20Test)
|
-- Demonstration Mission: [AID-019 - AI_A2A - Engage Range Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/AI_A2A_Dispatcher/AID-A2A-019%20-%20Engage%20Range%20Test)
|
||||||
--
|
--
|
||||||
-- @param #AI_A2A_DISPATCHER self
|
-- @param #AI_A2A_DISPATCHER self
|
||||||
-- @param #number EngageRadius (Optional, Default = 100000) The radius to report friendlies near the target.
|
-- @param #number EngageRadius (Optional, Default = 100000) The radius to report friendlies near the target.
|
||||||
@ -1283,7 +1283,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
-- Use the method @{#AI_A2A_DISPATCHER.SetGciRadius}() to set a specific controlled ground intercept radius.
|
-- Use the method @{#AI_A2A_DISPATCHER.SetGciRadius}() to set a specific controlled ground intercept radius.
|
||||||
-- **The Ground Controlled Intercept radius is defined for ALL squadrons which are operational.**
|
-- **The Ground Controlled Intercept radius is defined for ALL squadrons which are operational.**
|
||||||
--
|
--
|
||||||
-- Demonstration Mission: [AID-013 - AI_A2A - Intercept Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching/AID-A2A-013%20-%20Intercept%20Test)
|
-- Demonstration Mission: [AID-013 - AI_A2A - Intercept Test](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/AI_A2A_Dispatcher/AID-A2A-013%20-%20Intercept%20Test)
|
||||||
--
|
--
|
||||||
-- @param #AI_A2A_DISPATCHER self
|
-- @param #AI_A2A_DISPATCHER self
|
||||||
-- @param #number GciRadius (Optional, Default = 200000) The radius to ground control intercept detected targets from the nearest airbase.
|
-- @param #number GciRadius (Optional, Default = 200000) The radius to ground control intercept detected targets from the nearest airbase.
|
||||||
@ -3257,7 +3257,8 @@ do -- AI_A2A_DISPATCHER
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2A_DISPATCHER self
|
--- AI_A2A_Fsm:onafterHome
|
||||||
|
-- @param #AI_A2A_DISPATCHER self
|
||||||
function AI_A2A_Fsm:onafterHome( Defender, From, Event, To, Action )
|
function AI_A2A_Fsm:onafterHome( Defender, From, Event, To, Action )
|
||||||
if Defender and Defender:IsAlive() then
|
if Defender and Defender:IsAlive() then
|
||||||
self:F( { "CAP Home", Defender:GetName() } )
|
self:F( { "CAP Home", Defender:GetName() } )
|
||||||
@ -3505,7 +3506,8 @@ do -- AI_A2A_DISPATCHER
|
|||||||
Dispatcher:ClearDefenderTaskTarget( DefenderGroup )
|
Dispatcher:ClearDefenderTaskTarget( DefenderGroup )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2A_DISPATCHER self
|
--- function Fsm:onafterLostControl
|
||||||
|
-- @param #AI_A2A_DISPATCHER self
|
||||||
function Fsm:onafterLostControl( Defender, From, Event, To )
|
function Fsm:onafterLostControl( Defender, From, Event, To )
|
||||||
self:F( { "GCI LostControl", Defender:GetName() } )
|
self:F( { "GCI LostControl", Defender:GetName() } )
|
||||||
self:GetParent( self ).onafterHome( self, Defender, From, Event, To )
|
self:GetParent( self ).onafterHome( self, Defender, From, Event, To )
|
||||||
@ -3518,7 +3520,8 @@ do -- AI_A2A_DISPATCHER
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2A_DISPATCHER self
|
--- function Fsm:onafterHome
|
||||||
|
-- @param #AI_A2A_DISPATCHER self
|
||||||
function Fsm:onafterHome( DefenderGroup, From, Event, To, Action )
|
function Fsm:onafterHome( DefenderGroup, From, Event, To, Action )
|
||||||
self:F( { "GCI Home", DefenderGroup:GetName() } )
|
self:F( { "GCI Home", DefenderGroup:GetName() } )
|
||||||
self:GetParent( self ).onafterHome( self, DefenderGroup, From, Event, To )
|
self:GetParent( self ).onafterHome( self, DefenderGroup, From, Event, To )
|
||||||
@ -3959,7 +3962,7 @@ do
|
|||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- # Demo Missions
|
||||||
--
|
--
|
||||||
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching)
|
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/AI_A2A_Dispatcher)
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
--
|
--
|
||||||
-- ## Missions:
|
-- ## Missions:
|
||||||
--
|
--
|
||||||
-- [AID-A2G - AI A2G Dispatching](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2G%20-%20AI%20A2G%20Dispatching)
|
-- [AID-A2G - AI A2G Dispatching](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/AI_A2G_Dispatcher)
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
--
|
--
|
||||||
-- ## Missions:
|
-- ## Missions:
|
||||||
--
|
--
|
||||||
-- [AID-AIR - AI AIR Dispatching](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching)
|
-- [AI_A2A_Dispatcher](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/AI_A2A_Dispatcher)
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AIB%20-%20AI%20Balancing)
|
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/AI_Balancer)
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -168,7 +168,8 @@ function AI_BALANCER:ReturnToHomeAirbase( ReturnThresholdRange )
|
|||||||
self.ReturnThresholdRange = ReturnThresholdRange
|
self.ReturnThresholdRange = ReturnThresholdRange
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_BALANCER self
|
--- AI_BALANCER:onenterSpawning
|
||||||
|
-- @param #AI_BALANCER self
|
||||||
-- @param Core.Set#SET_GROUP SetGroup
|
-- @param Core.Set#SET_GROUP SetGroup
|
||||||
-- @param #string ClientName
|
-- @param #string ClientName
|
||||||
-- @param Wrapper.Group#GROUP AIGroup
|
-- @param Wrapper.Group#GROUP AIGroup
|
||||||
@ -190,7 +191,8 @@ function AI_BALANCER:onenterSpawning( SetGroup, From, Event, To, ClientName )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_BALANCER self
|
--- AI_BALANCER:onenterDestroying
|
||||||
|
-- @param #AI_BALANCER self
|
||||||
-- @param Core.Set#SET_GROUP SetGroup
|
-- @param Core.Set#SET_GROUP SetGroup
|
||||||
-- @param Wrapper.Group#GROUP AIGroup
|
-- @param Wrapper.Group#GROUP AIGroup
|
||||||
function AI_BALANCER:onenterDestroying( SetGroup, From, Event, To, ClientName, AIGroup )
|
function AI_BALANCER:onenterDestroying( SetGroup, From, Event, To, ClientName, AIGroup )
|
||||||
@ -233,15 +235,16 @@ function AI_BALANCER:onenterReturning( SetGroup, From, Event, To, AIGroup )
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- AI_BALANCER:onenterMonitoring
|
||||||
--- @param #AI_BALANCER self
|
-- @param #AI_BALANCER self
|
||||||
function AI_BALANCER:onenterMonitoring( SetGroup )
|
function AI_BALANCER:onenterMonitoring( SetGroup )
|
||||||
|
|
||||||
self:T2( { self.SetClient:Count() } )
|
self:T2( { self.SetClient:Count() } )
|
||||||
--self.SetClient:Flush()
|
--self.SetClient:Flush()
|
||||||
|
|
||||||
self.SetClient:ForEachClient(
|
self.SetClient:ForEachClient(
|
||||||
--- @param Wrapper.Client#CLIENT Client
|
--- SetClient:ForEachClient
|
||||||
|
-- @param Wrapper.Client#CLIENT Client
|
||||||
function( Client )
|
function( Client )
|
||||||
self:T3(Client.ClientName)
|
self:T3(Client.ClientName)
|
||||||
|
|
||||||
@ -264,7 +267,8 @@ function AI_BALANCER:onenterMonitoring( SetGroup )
|
|||||||
self:T2( RangeZone )
|
self:T2( RangeZone )
|
||||||
|
|
||||||
_DATABASE:ForEachPlayerUnit(
|
_DATABASE:ForEachPlayerUnit(
|
||||||
--- @param Wrapper.Unit#UNIT RangeTestUnit
|
--- Nameless function
|
||||||
|
-- @param Wrapper.Unit#UNIT RangeTestUnit
|
||||||
function( RangeTestUnit, RangeZone, AIGroup, PlayerInRange )
|
function( RangeTestUnit, RangeZone, AIGroup, PlayerInRange )
|
||||||
self:T2( { PlayerInRange, RangeTestUnit.UnitName, RangeZone.ZoneName } )
|
self:T2( { PlayerInRange, RangeTestUnit.UnitName, RangeZone.ZoneName } )
|
||||||
if RangeTestUnit:IsInZone( RangeZone ) == true then
|
if RangeTestUnit:IsInZone( RangeZone ) == true then
|
||||||
@ -276,7 +280,8 @@ function AI_BALANCER:onenterMonitoring( SetGroup )
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--- @param Core.Zone#ZONE_RADIUS RangeZone
|
--- Nameless function
|
||||||
|
-- @param Core.Zone#ZONE_RADIUS RangeZone
|
||||||
-- @param Wrapper.Group#GROUP AIGroup
|
-- @param Wrapper.Group#GROUP AIGroup
|
||||||
function( RangeZone, AIGroup, PlayerInRange )
|
function( RangeZone, AIGroup, PlayerInRange )
|
||||||
if PlayerInRange.Value == false then
|
if PlayerInRange.Value == false then
|
||||||
@ -307,6 +312,3 @@ function AI_BALANCER:onenterMonitoring( SetGroup )
|
|||||||
|
|
||||||
self:__Monitor( 10 )
|
self:__Monitor( 10 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
--
|
--
|
||||||
-- Test missions can be located on the main GITHUB site.
|
-- Test missions can be located on the main GITHUB site.
|
||||||
--
|
--
|
||||||
-- [FlightControl-Master/MOOSE_MISSIONS/AID - AI Dispatching/AID-CGO - AI Cargo Dispatching/](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/AID%20-%20AI%20Dispatching/AID-CGO%20-%20AI%20Cargo%20Dispatching)
|
-- [FlightControl-Master/MOOSE_MISSIONS/AID - AI Dispatching/AID-CGO - AI Cargo Dispatching/](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/AI_Cargo_Dispatcher)
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -572,7 +572,7 @@
|
|||||||
-- A home zone can be specified to where the Carriers will move when there isn't any cargo left for pickup.
|
-- A home zone can be specified to where the Carriers will move when there isn't any cargo left for pickup.
|
||||||
-- Use @{#AI_CARGO_DISPATCHER.SetHomeZone}() to specify the home zone.
|
-- Use @{#AI_CARGO_DISPATCHER.SetHomeZone}() to specify the home zone.
|
||||||
--
|
--
|
||||||
-- If no home zone is specified, the carriers will wait near the deploy zone for a new pickup command.
|
-- If no home zone is specified, the carriers will wait near the deploy zone for a new pickup command.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -583,10 +583,12 @@ AI_CARGO_DISPATCHER = {
|
|||||||
PickupCargo = {}
|
PickupCargo = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
--- @field #list
|
--- List of AI_Cargo
|
||||||
|
-- @field #list
|
||||||
AI_CARGO_DISPATCHER.AI_Cargo = {}
|
AI_CARGO_DISPATCHER.AI_Cargo = {}
|
||||||
|
|
||||||
--- @field #list
|
--- List of PickupCargo
|
||||||
|
-- @field #list
|
||||||
AI_CARGO_DISPATCHER.PickupCargo = {}
|
AI_CARGO_DISPATCHER.PickupCargo = {}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -370,7 +370,7 @@ CARGOS = {}
|
|||||||
|
|
||||||
do -- CARGO
|
do -- CARGO
|
||||||
|
|
||||||
--- @type CARGO
|
-- @type CARGO
|
||||||
-- @extends Core.Fsm#FSM_PROCESS
|
-- @extends Core.Fsm#FSM_PROCESS
|
||||||
-- @field #string Type A string defining the type of the cargo. eg. Engineers, Equipment, Screwdrivers.
|
-- @field #string Type A string defining the type of the cargo. eg. Engineers, Equipment, Screwdrivers.
|
||||||
-- @field #string Name A string defining the name of the cargo. The name is the unique identifier of the cargo.
|
-- @field #string Name A string defining the name of the cargo. The name is the unique identifier of the cargo.
|
||||||
@ -433,7 +433,7 @@ do -- CARGO
|
|||||||
Reported = {},
|
Reported = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- @type CARGO.CargoObjects
|
-- @type CARGO.CargoObjects
|
||||||
-- @map < #string, Wrapper.Positionable#POSITIONABLE > The alive POSITIONABLE objects representing the the cargo.
|
-- @map < #string, Wrapper.Positionable#POSITIONABLE > The alive POSITIONABLE objects representing the the cargo.
|
||||||
|
|
||||||
--- CARGO Constructor. This class is an abstract class and should not be instantiated.
|
--- CARGO Constructor. This class is an abstract class and should not be instantiated.
|
||||||
@ -447,7 +447,7 @@ do -- CARGO
|
|||||||
function CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) --R2.1
|
function CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) --R2.1
|
||||||
|
|
||||||
local self = BASE:Inherit( self, FSM:New() ) -- #CARGO
|
local self = BASE:Inherit( self, FSM:New() ) -- #CARGO
|
||||||
self:F( { Type, Name, Weight, LoadRadius, NearRadius } )
|
self:T( { Type, Name, Weight, LoadRadius, NearRadius } )
|
||||||
|
|
||||||
self:SetStartState( "UnLoaded" )
|
self:SetStartState( "UnLoaded" )
|
||||||
self:AddTransition( { "UnLoaded", "Boarding" }, "Board", "Boarding" )
|
self:AddTransition( { "UnLoaded", "Boarding" }, "Board", "Boarding" )
|
||||||
@ -711,7 +711,7 @@ do -- CARGO
|
|||||||
-- @param #CARGO self
|
-- @param #CARGO self
|
||||||
-- @return #CARGO
|
-- @return #CARGO
|
||||||
function CARGO:Spawn( PointVec2 )
|
function CARGO:Spawn( PointVec2 )
|
||||||
self:F()
|
self:T()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -812,7 +812,7 @@ do -- CARGO
|
|||||||
-- @param Core.Point#COORDINATE Coordinate
|
-- @param Core.Point#COORDINATE Coordinate
|
||||||
-- @return #boolean true if the CargoGroup is within the loading radius.
|
-- @return #boolean true if the CargoGroup is within the loading radius.
|
||||||
function CARGO:IsInLoadRadius( Coordinate )
|
function CARGO:IsInLoadRadius( Coordinate )
|
||||||
self:F( { Coordinate, LoadRadius = self.LoadRadius } )
|
self:T( { Coordinate, LoadRadius = self.LoadRadius } )
|
||||||
|
|
||||||
local Distance = 0
|
local Distance = 0
|
||||||
if self:IsUnLoaded() then
|
if self:IsUnLoaded() then
|
||||||
@ -832,7 +832,7 @@ do -- CARGO
|
|||||||
-- @param Core.Point#COORDINATE Coordinate
|
-- @param Core.Point#COORDINATE Coordinate
|
||||||
-- @return #boolean true if the Cargo can report itself.
|
-- @return #boolean true if the Cargo can report itself.
|
||||||
function CARGO:IsInReportRadius( Coordinate )
|
function CARGO:IsInReportRadius( Coordinate )
|
||||||
self:F( { Coordinate } )
|
self:T( { Coordinate } )
|
||||||
|
|
||||||
local Distance = 0
|
local Distance = 0
|
||||||
if self:IsUnLoaded() then
|
if self:IsUnLoaded() then
|
||||||
@ -853,23 +853,23 @@ do -- CARGO
|
|||||||
-- @param #number NearRadius The radius when the cargo will board the Carrier (to avoid collision).
|
-- @param #number NearRadius The radius when the cargo will board the Carrier (to avoid collision).
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
function CARGO:IsNear( Coordinate, NearRadius )
|
function CARGO:IsNear( Coordinate, NearRadius )
|
||||||
--self:F( { PointVec2 = PointVec2, NearRadius = NearRadius } )
|
--self:T( { PointVec2 = PointVec2, NearRadius = NearRadius } )
|
||||||
|
|
||||||
if self.CargoObject:IsAlive() then
|
if self.CargoObject:IsAlive() then
|
||||||
--local Distance = PointVec2:Get2DDistance( self.CargoObject:GetPointVec2() )
|
--local Distance = PointVec2:Get2DDistance( self.CargoObject:GetPointVec2() )
|
||||||
--self:F( { CargoObjectName = self.CargoObject:GetName() } )
|
--self:T( { CargoObjectName = self.CargoObject:GetName() } )
|
||||||
--self:F( { CargoObjectVec2 = self.CargoObject:GetVec2() } )
|
--self:T( { CargoObjectVec2 = self.CargoObject:GetVec2() } )
|
||||||
--self:F( { PointVec2 = PointVec2:GetVec2() } )
|
--self:T( { PointVec2 = PointVec2:GetVec2() } )
|
||||||
local Distance = Coordinate:Get2DDistance( self.CargoObject:GetCoordinate() )
|
local Distance = Coordinate:Get2DDistance( self.CargoObject:GetCoordinate() )
|
||||||
--self:F( { Distance = Distance, NearRadius = NearRadius or "nil" } )
|
--self:T( { Distance = Distance, NearRadius = NearRadius or "nil" } )
|
||||||
|
|
||||||
if Distance <= NearRadius then
|
if Distance <= NearRadius then
|
||||||
--self:F( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = true } )
|
--self:T( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = true } )
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--self:F( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = false } )
|
--self:T( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = false } )
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -878,12 +878,12 @@ do -- CARGO
|
|||||||
-- @param Core.Zone#ZONE_BASE Zone
|
-- @param Core.Zone#ZONE_BASE Zone
|
||||||
-- @return #boolean **true** if cargo is in the Zone, **false** if cargo is not in the Zone.
|
-- @return #boolean **true** if cargo is in the Zone, **false** if cargo is not in the Zone.
|
||||||
function CARGO:IsInZone( Zone )
|
function CARGO:IsInZone( Zone )
|
||||||
--self:F( { Zone } )
|
--self:T( { Zone } )
|
||||||
|
|
||||||
if self:IsLoaded() then
|
if self:IsLoaded() then
|
||||||
return Zone:IsPointVec2InZone( self.CargoCarrier:GetPointVec2() )
|
return Zone:IsPointVec2InZone( self.CargoCarrier:GetPointVec2() )
|
||||||
else
|
else
|
||||||
--self:F( { Size = self.CargoObject:GetSize(), Units = self.CargoObject:GetUnits() } )
|
--self:T( { Size = self.CargoObject:GetSize(), Units = self.CargoObject:GetUnits() } )
|
||||||
if self.CargoObject:GetSize() ~= 0 then
|
if self.CargoObject:GetSize() ~= 0 then
|
||||||
return Zone:IsPointVec2InZone( self.CargoObject:GetPointVec2() )
|
return Zone:IsPointVec2InZone( self.CargoObject:GetPointVec2() )
|
||||||
else
|
else
|
||||||
@ -1034,7 +1034,7 @@ end -- CARGO
|
|||||||
|
|
||||||
do -- CARGO_REPRESENTABLE
|
do -- CARGO_REPRESENTABLE
|
||||||
|
|
||||||
--- @type CARGO_REPRESENTABLE
|
-- @type CARGO_REPRESENTABLE
|
||||||
-- @extends #CARGO
|
-- @extends #CARGO
|
||||||
-- @field test
|
-- @field test
|
||||||
|
|
||||||
@ -1056,7 +1056,7 @@ do -- CARGO_REPRESENTABLE
|
|||||||
|
|
||||||
-- Inherit CARGO.
|
-- Inherit CARGO.
|
||||||
local self = BASE:Inherit( self, CARGO:New( Type, Name, 0, LoadRadius, NearRadius ) ) -- #CARGO_REPRESENTABLE
|
local self = BASE:Inherit( self, CARGO:New( Type, Name, 0, LoadRadius, NearRadius ) ) -- #CARGO_REPRESENTABLE
|
||||||
self:F( { Type, Name, LoadRadius, NearRadius } )
|
self:T( { Type, Name, LoadRadius, NearRadius } )
|
||||||
|
|
||||||
-- Descriptors.
|
-- Descriptors.
|
||||||
local Desc=CargoObject:GetDesc()
|
local Desc=CargoObject:GetDesc()
|
||||||
@ -1086,7 +1086,7 @@ do -- CARGO_REPRESENTABLE
|
|||||||
function CARGO_REPRESENTABLE:Destroy()
|
function CARGO_REPRESENTABLE:Destroy()
|
||||||
|
|
||||||
-- Cargo objects are deleted from the _DATABASE and SET_CARGO objects.
|
-- Cargo objects are deleted from the _DATABASE and SET_CARGO objects.
|
||||||
self:F( { CargoName = self:GetName() } )
|
self:T( { CargoName = self:GetName() } )
|
||||||
--_EVENTDISPATCHER:CreateEventDeleteCargo( self )
|
--_EVENTDISPATCHER:CreateEventDeleteCargo( self )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -1123,12 +1123,12 @@ do -- CARGO_REPRESENTABLE
|
|||||||
CoordinateZone:Scan( { Object.Category.UNIT } )
|
CoordinateZone:Scan( { Object.Category.UNIT } )
|
||||||
for _, DCSUnit in pairs( CoordinateZone:GetScannedUnits() ) do
|
for _, DCSUnit in pairs( CoordinateZone:GetScannedUnits() ) do
|
||||||
local NearUnit = UNIT:Find( DCSUnit )
|
local NearUnit = UNIT:Find( DCSUnit )
|
||||||
self:F({NearUnit=NearUnit})
|
self:T({NearUnit=NearUnit})
|
||||||
local NearUnitCoalition = NearUnit:GetCoalition()
|
local NearUnitCoalition = NearUnit:GetCoalition()
|
||||||
local CargoCoalition = self:GetCoalition()
|
local CargoCoalition = self:GetCoalition()
|
||||||
if NearUnitCoalition == CargoCoalition then
|
if NearUnitCoalition == CargoCoalition then
|
||||||
local Attributes = NearUnit:GetDesc()
|
local Attributes = NearUnit:GetDesc()
|
||||||
self:F({Desc=Attributes})
|
self:T({Desc=Attributes})
|
||||||
if NearUnit:HasAttribute( "Trucks" ) then
|
if NearUnit:HasAttribute( "Trucks" ) then
|
||||||
MESSAGE:New( Message, 20, NearUnit:GetCallsign() .. " reporting - Cargo " .. self:GetName() ):ToGroup( TaskGroup )
|
MESSAGE:New( Message, 20, NearUnit:GetCallsign() .. " reporting - Cargo " .. self:GetName() ):ToGroup( TaskGroup )
|
||||||
break
|
break
|
||||||
@ -1142,7 +1142,7 @@ end -- CARGO_REPRESENTABLE
|
|||||||
|
|
||||||
do -- CARGO_REPORTABLE
|
do -- CARGO_REPORTABLE
|
||||||
|
|
||||||
--- @type CARGO_REPORTABLE
|
-- @type CARGO_REPORTABLE
|
||||||
-- @extends #CARGO
|
-- @extends #CARGO
|
||||||
CARGO_REPORTABLE = {
|
CARGO_REPORTABLE = {
|
||||||
ClassName = "CARGO_REPORTABLE"
|
ClassName = "CARGO_REPORTABLE"
|
||||||
@ -1158,7 +1158,7 @@ do -- CARGO_REPORTABLE
|
|||||||
-- @return #CARGO_REPORTABLE
|
-- @return #CARGO_REPORTABLE
|
||||||
function CARGO_REPORTABLE:New( Type, Name, Weight, LoadRadius, NearRadius )
|
function CARGO_REPORTABLE:New( Type, Name, Weight, LoadRadius, NearRadius )
|
||||||
local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_REPORTABLE
|
local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_REPORTABLE
|
||||||
self:F( { Type, Name, Weight, LoadRadius, NearRadius } )
|
self:T( { Type, Name, Weight, LoadRadius, NearRadius } )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -1178,7 +1178,7 @@ end
|
|||||||
|
|
||||||
do -- CARGO_PACKAGE
|
do -- CARGO_PACKAGE
|
||||||
|
|
||||||
--- @type CARGO_PACKAGE
|
-- @type CARGO_PACKAGE
|
||||||
-- @extends #CARGO_REPRESENTABLE
|
-- @extends #CARGO_REPRESENTABLE
|
||||||
CARGO_PACKAGE = {
|
CARGO_PACKAGE = {
|
||||||
ClassName = "CARGO_PACKAGE"
|
ClassName = "CARGO_PACKAGE"
|
||||||
@ -1195,7 +1195,7 @@ do -- CARGO_PACKAGE
|
|||||||
-- @return #CARGO_PACKAGE
|
-- @return #CARGO_PACKAGE
|
||||||
function CARGO_PACKAGE:New( CargoCarrier, Type, Name, Weight, LoadRadius, NearRadius )
|
function CARGO_PACKAGE:New( CargoCarrier, Type, Name, Weight, LoadRadius, NearRadius )
|
||||||
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoCarrier, Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_PACKAGE
|
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoCarrier, Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_PACKAGE
|
||||||
self:F( { Type, Name, Weight, LoadRadius, NearRadius } )
|
self:T( { Type, Name, Weight, LoadRadius, NearRadius } )
|
||||||
|
|
||||||
self:T( CargoCarrier )
|
self:T( CargoCarrier )
|
||||||
self.CargoCarrier = CargoCarrier
|
self.CargoCarrier = CargoCarrier
|
||||||
@ -1213,7 +1213,7 @@ end
|
|||||||
-- @param #number BoardDistance
|
-- @param #number BoardDistance
|
||||||
-- @param #number Angle
|
-- @param #number Angle
|
||||||
function CARGO_PACKAGE:onafterOnBoard( From, Event, To, CargoCarrier, Speed, BoardDistance, LoadDistance, Angle )
|
function CARGO_PACKAGE:onafterOnBoard( From, Event, To, CargoCarrier, Speed, BoardDistance, LoadDistance, Angle )
|
||||||
self:F()
|
self:T()
|
||||||
|
|
||||||
self.CargoInAir = self.CargoCarrier:InAir()
|
self.CargoInAir = self.CargoCarrier:InAir()
|
||||||
|
|
||||||
@ -1246,7 +1246,7 @@ end
|
|||||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
function CARGO_PACKAGE:IsNear( CargoCarrier )
|
function CARGO_PACKAGE:IsNear( CargoCarrier )
|
||||||
self:F()
|
self:T()
|
||||||
|
|
||||||
local CargoCarrierPoint = CargoCarrier:GetCoordinate()
|
local CargoCarrierPoint = CargoCarrier:GetCoordinate()
|
||||||
|
|
||||||
@ -1271,7 +1271,7 @@ end
|
|||||||
-- @param #number LoadDistance
|
-- @param #number LoadDistance
|
||||||
-- @param #number Angle
|
-- @param #number Angle
|
||||||
function CARGO_PACKAGE:onafterOnBoarded( From, Event, To, CargoCarrier, Speed, BoardDistance, LoadDistance, Angle )
|
function CARGO_PACKAGE:onafterOnBoarded( From, Event, To, CargoCarrier, Speed, BoardDistance, LoadDistance, Angle )
|
||||||
self:F()
|
self:T()
|
||||||
|
|
||||||
if self:IsNear( CargoCarrier ) then
|
if self:IsNear( CargoCarrier ) then
|
||||||
self:__Load( 1, CargoCarrier, Speed, LoadDistance, Angle )
|
self:__Load( 1, CargoCarrier, Speed, LoadDistance, Angle )
|
||||||
@ -1292,7 +1292,7 @@ end
|
|||||||
-- @param #number Radius
|
-- @param #number Radius
|
||||||
-- @param #number Angle
|
-- @param #number Angle
|
||||||
function CARGO_PACKAGE:onafterUnBoard( From, Event, To, CargoCarrier, Speed, UnLoadDistance, UnBoardDistance, Radius, Angle )
|
function CARGO_PACKAGE:onafterUnBoard( From, Event, To, CargoCarrier, Speed, UnLoadDistance, UnBoardDistance, Radius, Angle )
|
||||||
self:F()
|
self:T()
|
||||||
|
|
||||||
self.CargoInAir = self.CargoCarrier:InAir()
|
self.CargoInAir = self.CargoCarrier:InAir()
|
||||||
|
|
||||||
@ -1331,7 +1331,7 @@ end
|
|||||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||||
-- @param #number Speed
|
-- @param #number Speed
|
||||||
function CARGO_PACKAGE:onafterUnBoarded( From, Event, To, CargoCarrier, Speed )
|
function CARGO_PACKAGE:onafterUnBoarded( From, Event, To, CargoCarrier, Speed )
|
||||||
self:F()
|
self:T()
|
||||||
|
|
||||||
if self:IsNear( CargoCarrier ) then
|
if self:IsNear( CargoCarrier ) then
|
||||||
self:__UnLoad( 1, CargoCarrier, Speed )
|
self:__UnLoad( 1, CargoCarrier, Speed )
|
||||||
@ -1350,7 +1350,7 @@ end
|
|||||||
-- @param #number LoadDistance
|
-- @param #number LoadDistance
|
||||||
-- @param #number Angle
|
-- @param #number Angle
|
||||||
function CARGO_PACKAGE:onafterLoad( From, Event, To, CargoCarrier, Speed, LoadDistance, Angle )
|
function CARGO_PACKAGE:onafterLoad( From, Event, To, CargoCarrier, Speed, LoadDistance, Angle )
|
||||||
self:F()
|
self:T()
|
||||||
|
|
||||||
self.CargoCarrier = CargoCarrier
|
self.CargoCarrier = CargoCarrier
|
||||||
|
|
||||||
@ -1378,7 +1378,7 @@ end
|
|||||||
-- @param #number Distance
|
-- @param #number Distance
|
||||||
-- @param #number Angle
|
-- @param #number Angle
|
||||||
function CARGO_PACKAGE:onafterUnLoad( From, Event, To, CargoCarrier, Speed, Distance, Angle )
|
function CARGO_PACKAGE:onafterUnLoad( From, Event, To, CargoCarrier, Speed, Distance, Angle )
|
||||||
self:F()
|
self:T()
|
||||||
|
|
||||||
local StartPointVec2 = self.CargoCarrier:GetPointVec2()
|
local StartPointVec2 = self.CargoCarrier:GetPointVec2()
|
||||||
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||||
|
|||||||
@ -59,7 +59,7 @@ do -- CARGO_CRATE
|
|||||||
-- @return #CARGO_CRATE
|
-- @return #CARGO_CRATE
|
||||||
function CARGO_CRATE:New( CargoStatic, Type, Name, LoadRadius, NearRadius )
|
function CARGO_CRATE:New( CargoStatic, Type, Name, LoadRadius, NearRadius )
|
||||||
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, LoadRadius, NearRadius ) ) -- #CARGO_CRATE
|
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, LoadRadius, NearRadius ) ) -- #CARGO_CRATE
|
||||||
self:F( { Type, Name, NearRadius } )
|
self:T( { Type, Name, NearRadius } )
|
||||||
|
|
||||||
self.CargoObject = CargoStatic -- Wrapper.Static#STATIC
|
self.CargoObject = CargoStatic -- Wrapper.Static#STATIC
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ do -- CARGO_CRATE
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Core.Point#POINT_VEC2
|
-- @param Core.Point#POINT_VEC2
|
||||||
function CARGO_CRATE:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
function CARGO_CRATE:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
||||||
--self:F( { ToPointVec2, From, Event, To } )
|
--self:T( { ToPointVec2, From, Event, To } )
|
||||||
|
|
||||||
local Angle = 180
|
local Angle = 180
|
||||||
local Speed = 10
|
local Speed = 10
|
||||||
@ -153,7 +153,7 @@ do -- CARGO_CRATE
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||||
function CARGO_CRATE:onenterLoaded( From, Event, To, CargoCarrier )
|
function CARGO_CRATE:onenterLoaded( From, Event, To, CargoCarrier )
|
||||||
--self:F( { From, Event, To, CargoCarrier } )
|
--self:T( { From, Event, To, CargoCarrier } )
|
||||||
|
|
||||||
self.CargoCarrier = CargoCarrier
|
self.CargoCarrier = CargoCarrier
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ do -- CARGO_CRATE
|
|||||||
-- @param Core.Point#COORDINATE Coordinate
|
-- @param Core.Point#COORDINATE Coordinate
|
||||||
-- @return #boolean true if the Cargo Crate is within the report radius.
|
-- @return #boolean true if the Cargo Crate is within the report radius.
|
||||||
function CARGO_CRATE:IsInReportRadius( Coordinate )
|
function CARGO_CRATE:IsInReportRadius( Coordinate )
|
||||||
--self:F( { Coordinate, LoadRadius = self.LoadRadius } )
|
--self:T( { Coordinate, LoadRadius = self.LoadRadius } )
|
||||||
|
|
||||||
local Distance = 0
|
local Distance = 0
|
||||||
if self:IsUnLoaded() then
|
if self:IsUnLoaded() then
|
||||||
@ -210,7 +210,7 @@ do -- CARGO_CRATE
|
|||||||
-- @param Core.Point#Coordinate Coordinate
|
-- @param Core.Point#Coordinate Coordinate
|
||||||
-- @return #boolean true if the Cargo Crate is within the loading radius.
|
-- @return #boolean true if the Cargo Crate is within the loading radius.
|
||||||
function CARGO_CRATE:IsInLoadRadius( Coordinate )
|
function CARGO_CRATE:IsInLoadRadius( Coordinate )
|
||||||
--self:F( { Coordinate, LoadRadius = self.NearRadius } )
|
--self:T( { Coordinate, LoadRadius = self.NearRadius } )
|
||||||
|
|
||||||
local Distance = 0
|
local Distance = 0
|
||||||
if self:IsUnLoaded() then
|
if self:IsUnLoaded() then
|
||||||
@ -231,7 +231,7 @@ do -- CARGO_CRATE
|
|||||||
-- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup.
|
-- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup.
|
||||||
-- @return #nil There is no valid Cargo in the CargoGroup.
|
-- @return #nil There is no valid Cargo in the CargoGroup.
|
||||||
function CARGO_CRATE:GetCoordinate()
|
function CARGO_CRATE:GetCoordinate()
|
||||||
--self:F()
|
--self:T()
|
||||||
|
|
||||||
return self.CargoObject:GetCoordinate()
|
return self.CargoObject:GetCoordinate()
|
||||||
end
|
end
|
||||||
@ -261,7 +261,7 @@ do -- CARGO_CRATE
|
|||||||
-- @param #CARGO_CRATE self
|
-- @param #CARGO_CRATE self
|
||||||
-- @param Core.Point#COORDINATE Coordinate
|
-- @param Core.Point#COORDINATE Coordinate
|
||||||
function CARGO_CRATE:RouteTo( Coordinate )
|
function CARGO_CRATE:RouteTo( Coordinate )
|
||||||
self:F( {Coordinate = Coordinate } )
|
self:T( {Coordinate = Coordinate } )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -274,7 +274,7 @@ do -- CARGO_CRATE
|
|||||||
-- @return #boolean The Cargo is near to the Carrier.
|
-- @return #boolean The Cargo is near to the Carrier.
|
||||||
-- @return #nil The Cargo is not near to the Carrier.
|
-- @return #nil The Cargo is not near to the Carrier.
|
||||||
function CARGO_CRATE:IsNear( CargoCarrier, NearRadius )
|
function CARGO_CRATE:IsNear( CargoCarrier, NearRadius )
|
||||||
self:F( {NearRadius = NearRadius } )
|
self:T( {NearRadius = NearRadius } )
|
||||||
|
|
||||||
return self:IsNear( CargoCarrier:GetCoordinate(), NearRadius )
|
return self:IsNear( CargoCarrier:GetCoordinate(), NearRadius )
|
||||||
end
|
end
|
||||||
@ -283,7 +283,7 @@ do -- CARGO_CRATE
|
|||||||
-- @param #CARGO_CRATE self
|
-- @param #CARGO_CRATE self
|
||||||
function CARGO_CRATE:Respawn()
|
function CARGO_CRATE:Respawn()
|
||||||
|
|
||||||
self:F( { "Respawning crate " .. self:GetName() } )
|
self:T( { "Respawning crate " .. self:GetName() } )
|
||||||
|
|
||||||
|
|
||||||
-- Respawn the group...
|
-- Respawn the group...
|
||||||
@ -300,7 +300,7 @@ do -- CARGO_CRATE
|
|||||||
-- @param #CARGO_CRATE self
|
-- @param #CARGO_CRATE self
|
||||||
function CARGO_CRATE:onafterReset()
|
function CARGO_CRATE:onafterReset()
|
||||||
|
|
||||||
self:F( { "Reset crate " .. self:GetName() } )
|
self:T( { "Reset crate " .. self:GetName() } )
|
||||||
|
|
||||||
|
|
||||||
-- Respawn the group...
|
-- Respawn the group...
|
||||||
|
|||||||
@ -64,7 +64,7 @@ do -- CARGO_GROUP
|
|||||||
|
|
||||||
-- Inherit CAROG_REPORTABLE
|
-- Inherit CAROG_REPORTABLE
|
||||||
local self = BASE:Inherit( self, CARGO_REPORTABLE:New( Type, Name, 0, LoadRadius, NearRadius ) ) -- #CARGO_GROUP
|
local self = BASE:Inherit( self, CARGO_REPORTABLE:New( Type, Name, 0, LoadRadius, NearRadius ) ) -- #CARGO_GROUP
|
||||||
self:F( { Type, Name, LoadRadius } )
|
self:T( { Type, Name, LoadRadius } )
|
||||||
|
|
||||||
self.CargoSet = SET_CARGO:New()
|
self.CargoSet = SET_CARGO:New()
|
||||||
self.CargoGroup = CargoGroup
|
self.CargoGroup = CargoGroup
|
||||||
@ -146,7 +146,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param #CARGO_GROUP self
|
-- @param #CARGO_GROUP self
|
||||||
function CARGO_GROUP:Respawn()
|
function CARGO_GROUP:Respawn()
|
||||||
|
|
||||||
self:F( { "Respawning" } )
|
self:T( { "Respawning" } )
|
||||||
|
|
||||||
for CargoID, CargoData in pairs( self.CargoSet:GetSet() ) do
|
for CargoID, CargoData in pairs( self.CargoSet:GetSet() ) do
|
||||||
local Cargo = CargoData -- Cargo.Cargo#CARGO
|
local Cargo = CargoData -- Cargo.Cargo#CARGO
|
||||||
@ -227,7 +227,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param #CARGO_GROUP self
|
-- @param #CARGO_GROUP self
|
||||||
function CARGO_GROUP:Regroup()
|
function CARGO_GROUP:Regroup()
|
||||||
|
|
||||||
self:F("Regroup")
|
self:T("Regroup")
|
||||||
|
|
||||||
if self.Grouped == false then
|
if self.Grouped == false then
|
||||||
|
|
||||||
@ -241,7 +241,7 @@ do -- CARGO_GROUP
|
|||||||
for CargoUnitName, CargoUnit in pairs( self.CargoSet:GetSet() ) do
|
for CargoUnitName, CargoUnit in pairs( self.CargoSet:GetSet() ) do
|
||||||
local CargoUnit = CargoUnit -- Cargo.CargoUnit#CARGO_UNIT
|
local CargoUnit = CargoUnit -- Cargo.CargoUnit#CARGO_UNIT
|
||||||
|
|
||||||
self:F( { CargoUnit:GetName(), UnLoaded = CargoUnit:IsUnLoaded() } )
|
self:T( { CargoUnit:GetName(), UnLoaded = CargoUnit:IsUnLoaded() } )
|
||||||
|
|
||||||
if CargoUnit:IsUnLoaded() then
|
if CargoUnit:IsUnLoaded() then
|
||||||
|
|
||||||
@ -258,7 +258,7 @@ do -- CARGO_GROUP
|
|||||||
-- Then we register the new group in the database
|
-- Then we register the new group in the database
|
||||||
self.CargoGroup = GROUP:NewTemplate( GroupTemplate, GroupTemplate.CoalitionID, GroupTemplate.CategoryID, GroupTemplate.CountryID )
|
self.CargoGroup = GROUP:NewTemplate( GroupTemplate, GroupTemplate.CoalitionID, GroupTemplate.CategoryID, GroupTemplate.CountryID )
|
||||||
|
|
||||||
self:F( { "Regroup", GroupTemplate } )
|
self:T( { "Regroup", GroupTemplate } )
|
||||||
|
|
||||||
-- Now we spawn the new group based on the template created.
|
-- Now we spawn the new group based on the template created.
|
||||||
self.CargoObject = _DATABASE:Spawn( GroupTemplate )
|
self.CargoObject = _DATABASE:Spawn( GroupTemplate )
|
||||||
@ -271,7 +271,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
function CARGO_GROUP:OnEventCargoDead( EventData )
|
function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||||
|
|
||||||
self:E(EventData)
|
self:T(EventData)
|
||||||
|
|
||||||
local Destroyed = false
|
local Destroyed = false
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ do -- CARGO_GROUP
|
|||||||
|
|
||||||
if Destroyed then
|
if Destroyed then
|
||||||
self:Destroyed()
|
self:Destroyed()
|
||||||
self:E( { "Cargo group destroyed" } )
|
self:T( { "Cargo group destroyed" } )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -309,14 +309,14 @@ do -- CARGO_GROUP
|
|||||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||||
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
|
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
|
||||||
function CARGO_GROUP:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... )
|
function CARGO_GROUP:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||||
self:F( { CargoCarrier.UnitName, From, Event, To, NearRadius = NearRadius } )
|
self:T( { CargoCarrier.UnitName, From, Event, To, NearRadius = NearRadius } )
|
||||||
|
|
||||||
NearRadius = NearRadius or self.NearRadius
|
NearRadius = NearRadius or self.NearRadius
|
||||||
|
|
||||||
-- For each Cargo object within the CARGO_GROUPED, route each object to the CargoLoadPointVec2
|
-- For each Cargo object within the CARGO_GROUPED, route each object to the CargoLoadPointVec2
|
||||||
self.CargoSet:ForEach(
|
self.CargoSet:ForEach(
|
||||||
function( Cargo, ... )
|
function( Cargo, ... )
|
||||||
self:F( { "Board Unit", Cargo:GetName( ), Cargo:IsDestroyed(), Cargo.CargoObject:IsAlive() } )
|
self:T( { "Board Unit", Cargo:GetName( ), Cargo:IsDestroyed(), Cargo.CargoObject:IsAlive() } )
|
||||||
local CargoGroup = Cargo.CargoObject --Wrapper.Group#GROUP
|
local CargoGroup = Cargo.CargoObject --Wrapper.Group#GROUP
|
||||||
CargoGroup:OptionAlarmStateGreen()
|
CargoGroup:OptionAlarmStateGreen()
|
||||||
Cargo:__Board( 1, CargoCarrier, NearRadius, ... )
|
Cargo:__Board( 1, CargoCarrier, NearRadius, ... )
|
||||||
@ -334,7 +334,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||||
function CARGO_GROUP:onafterLoad( From, Event, To, CargoCarrier, ... )
|
function CARGO_GROUP:onafterLoad( From, Event, To, CargoCarrier, ... )
|
||||||
--self:F( { From, Event, To, CargoCarrier, ...} )
|
--self:T( { From, Event, To, CargoCarrier, ...} )
|
||||||
|
|
||||||
if From == "UnLoaded" then
|
if From == "UnLoaded" then
|
||||||
-- For each Cargo object within the CARGO_GROUP, load each cargo to the CargoCarrier.
|
-- For each Cargo object within the CARGO_GROUP, load each cargo to the CargoCarrier.
|
||||||
@ -359,7 +359,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||||
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
|
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
|
||||||
function CARGO_GROUP:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
function CARGO_GROUP:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||||
--self:F( { CargoCarrier.UnitName, From, Event, To } )
|
--self:T( { CargoCarrier.UnitName, From, Event, To } )
|
||||||
|
|
||||||
local Boarded = true
|
local Boarded = true
|
||||||
local Cancelled = false
|
local Cancelled = false
|
||||||
@ -393,7 +393,7 @@ do -- CARGO_GROUP
|
|||||||
if not Boarded then
|
if not Boarded then
|
||||||
self:__Boarding( -5, CargoCarrier, NearRadius, ... )
|
self:__Boarding( -5, CargoCarrier, NearRadius, ... )
|
||||||
else
|
else
|
||||||
self:F("Group Cargo is loaded")
|
self:T("Group Cargo is loaded")
|
||||||
self:__Load( 1, CargoCarrier, ... )
|
self:__Load( 1, CargoCarrier, ... )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -413,7 +413,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||||
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
|
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
|
||||||
function CARGO_GROUP:onafterUnBoard( From, Event, To, ToPointVec2, NearRadius, ... )
|
function CARGO_GROUP:onafterUnBoard( From, Event, To, ToPointVec2, NearRadius, ... )
|
||||||
self:F( {From, Event, To, ToPointVec2, NearRadius } )
|
self:T( {From, Event, To, ToPointVec2, NearRadius } )
|
||||||
|
|
||||||
NearRadius = NearRadius or 25
|
NearRadius = NearRadius or 25
|
||||||
|
|
||||||
@ -456,7 +456,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||||
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
|
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
|
||||||
function CARGO_GROUP:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
|
function CARGO_GROUP:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
|
||||||
--self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
--self:T( { From, Event, To, ToPointVec2, NearRadius } )
|
||||||
|
|
||||||
--local NearRadius = NearRadius or 25
|
--local NearRadius = NearRadius or 25
|
||||||
|
|
||||||
@ -493,7 +493,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||||
function CARGO_GROUP:onafterUnLoad( From, Event, To, ToPointVec2, ... )
|
function CARGO_GROUP:onafterUnLoad( From, Event, To, ToPointVec2, ... )
|
||||||
--self:F( { From, Event, To, ToPointVec2 } )
|
--self:T( { From, Event, To, ToPointVec2 } )
|
||||||
|
|
||||||
if From == "Loaded" then
|
if From == "Loaded" then
|
||||||
|
|
||||||
@ -611,7 +611,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param #CARGO_GROUP self
|
-- @param #CARGO_GROUP self
|
||||||
-- @param Core.Point#COORDINATE Coordinate
|
-- @param Core.Point#COORDINATE Coordinate
|
||||||
function CARGO_GROUP:RouteTo( Coordinate )
|
function CARGO_GROUP:RouteTo( Coordinate )
|
||||||
--self:F( {Coordinate = Coordinate } )
|
--self:T( {Coordinate = Coordinate } )
|
||||||
|
|
||||||
-- For each Cargo within the CargoSet, route each object to the Coordinate
|
-- For each Cargo within the CargoSet, route each object to the Coordinate
|
||||||
self.CargoSet:ForEach(
|
self.CargoSet:ForEach(
|
||||||
@ -629,13 +629,13 @@ do -- CARGO_GROUP
|
|||||||
-- @param #number NearRadius
|
-- @param #number NearRadius
|
||||||
-- @return #boolean The Cargo is near to the Carrier or #nil if the Cargo is not near to the Carrier.
|
-- @return #boolean The Cargo is near to the Carrier or #nil if the Cargo is not near to the Carrier.
|
||||||
function CARGO_GROUP:IsNear( CargoCarrier, NearRadius )
|
function CARGO_GROUP:IsNear( CargoCarrier, NearRadius )
|
||||||
self:F( {NearRadius = NearRadius } )
|
self:T( {NearRadius = NearRadius } )
|
||||||
|
|
||||||
for _, Cargo in pairs( self.CargoSet:GetSet() ) do
|
for _, Cargo in pairs( self.CargoSet:GetSet() ) do
|
||||||
local Cargo = Cargo -- Cargo.Cargo#CARGO
|
local Cargo = Cargo -- Cargo.Cargo#CARGO
|
||||||
if Cargo:IsAlive() then
|
if Cargo:IsAlive() then
|
||||||
if Cargo:IsNear( CargoCarrier:GetCoordinate(), NearRadius ) then
|
if Cargo:IsNear( CargoCarrier:GetCoordinate(), NearRadius ) then
|
||||||
self:F( "Near" )
|
self:T( "Near" )
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -649,7 +649,7 @@ do -- CARGO_GROUP
|
|||||||
-- @param Core.Point#COORDINATE Coordinate
|
-- @param Core.Point#COORDINATE Coordinate
|
||||||
-- @return #boolean true if the Cargo Group is within the load radius.
|
-- @return #boolean true if the Cargo Group is within the load radius.
|
||||||
function CARGO_GROUP:IsInLoadRadius( Coordinate )
|
function CARGO_GROUP:IsInLoadRadius( Coordinate )
|
||||||
--self:F( { Coordinate } )
|
--self:T( { Coordinate } )
|
||||||
|
|
||||||
local Cargo = self:GetFirstAlive() -- Cargo.Cargo#CARGO
|
local Cargo = self:GetFirstAlive() -- Cargo.Cargo#CARGO
|
||||||
|
|
||||||
@ -669,7 +669,7 @@ do -- CARGO_GROUP
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
self:F( { Distance = Distance, LoadRadius = self.LoadRadius } )
|
self:T( { Distance = Distance, LoadRadius = self.LoadRadius } )
|
||||||
if Distance <= self.LoadRadius then
|
if Distance <= self.LoadRadius then
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
@ -687,12 +687,12 @@ do -- CARGO_GROUP
|
|||||||
-- @param Core.Point#Coordinate Coordinate
|
-- @param Core.Point#Coordinate Coordinate
|
||||||
-- @return #boolean true if the Cargo Group is within the report radius.
|
-- @return #boolean true if the Cargo Group is within the report radius.
|
||||||
function CARGO_GROUP:IsInReportRadius( Coordinate )
|
function CARGO_GROUP:IsInReportRadius( Coordinate )
|
||||||
--self:F( { Coordinate } )
|
--self:T( { Coordinate } )
|
||||||
|
|
||||||
local Cargo = self:GetFirstAlive() -- Cargo.Cargo#CARGO
|
local Cargo = self:GetFirstAlive() -- Cargo.Cargo#CARGO
|
||||||
|
|
||||||
if Cargo then
|
if Cargo then
|
||||||
self:F( { Cargo } )
|
self:T( { Cargo } )
|
||||||
local Distance = 0
|
local Distance = 0
|
||||||
if Cargo:IsUnLoaded() then
|
if Cargo:IsUnLoaded() then
|
||||||
Distance = Coordinate:Get2DDistance( Cargo.CargoObject:GetCoordinate() )
|
Distance = Coordinate:Get2DDistance( Cargo.CargoObject:GetCoordinate() )
|
||||||
@ -738,7 +738,7 @@ do -- CARGO_GROUP
|
|||||||
-- @return #boolean **true** if the first element of the CargoGroup is in the Zone
|
-- @return #boolean **true** if the first element of the CargoGroup is in the Zone
|
||||||
-- @return #boolean **false** if there is no element of the CargoGroup in the Zone.
|
-- @return #boolean **false** if there is no element of the CargoGroup in the Zone.
|
||||||
function CARGO_GROUP:IsInZone( Zone )
|
function CARGO_GROUP:IsInZone( Zone )
|
||||||
--self:F( { Zone } )
|
--self:T( { Zone } )
|
||||||
|
|
||||||
local Cargo = self.CargoSet:GetFirst() -- Cargo.Cargo#CARGO
|
local Cargo = self.CargoSet:GetFirst() -- Cargo.Cargo#CARGO
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,7 @@ do -- CARGO_SLINGLOAD
|
|||||||
-- @return #CARGO_SLINGLOAD
|
-- @return #CARGO_SLINGLOAD
|
||||||
function CARGO_SLINGLOAD:New( CargoStatic, Type, Name, LoadRadius, NearRadius )
|
function CARGO_SLINGLOAD:New( CargoStatic, Type, Name, LoadRadius, NearRadius )
|
||||||
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, LoadRadius, NearRadius ) ) -- #CARGO_SLINGLOAD
|
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, LoadRadius, NearRadius ) ) -- #CARGO_SLINGLOAD
|
||||||
self:F( { Type, Name, NearRadius } )
|
self:T( { Type, Name, NearRadius } )
|
||||||
|
|
||||||
self.CargoObject = CargoStatic
|
self.CargoObject = CargoStatic
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ do -- CARGO_SLINGLOAD
|
|||||||
-- @param Core.Point#COORDINATE Coordinate
|
-- @param Core.Point#COORDINATE Coordinate
|
||||||
-- @return #boolean true if the Cargo Crate is within the report radius.
|
-- @return #boolean true if the Cargo Crate is within the report radius.
|
||||||
function CARGO_SLINGLOAD:IsInReportRadius( Coordinate )
|
function CARGO_SLINGLOAD:IsInReportRadius( Coordinate )
|
||||||
--self:F( { Coordinate, LoadRadius = self.LoadRadius } )
|
--self:T( { Coordinate, LoadRadius = self.LoadRadius } )
|
||||||
|
|
||||||
local Distance = 0
|
local Distance = 0
|
||||||
if self:IsUnLoaded() then
|
if self:IsUnLoaded() then
|
||||||
@ -149,7 +149,7 @@ do -- CARGO_SLINGLOAD
|
|||||||
-- @param Core.Point#COORDINATE Coordinate
|
-- @param Core.Point#COORDINATE Coordinate
|
||||||
-- @return #boolean true if the Cargo Slingload is within the loading radius.
|
-- @return #boolean true if the Cargo Slingload is within the loading radius.
|
||||||
function CARGO_SLINGLOAD:IsInLoadRadius( Coordinate )
|
function CARGO_SLINGLOAD:IsInLoadRadius( Coordinate )
|
||||||
--self:F( { Coordinate } )
|
--self:T( { Coordinate } )
|
||||||
|
|
||||||
local Distance = 0
|
local Distance = 0
|
||||||
if self:IsUnLoaded() then
|
if self:IsUnLoaded() then
|
||||||
@ -169,7 +169,7 @@ do -- CARGO_SLINGLOAD
|
|||||||
-- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup.
|
-- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup.
|
||||||
-- @return #nil There is no valid Cargo in the CargoGroup.
|
-- @return #nil There is no valid Cargo in the CargoGroup.
|
||||||
function CARGO_SLINGLOAD:GetCoordinate()
|
function CARGO_SLINGLOAD:GetCoordinate()
|
||||||
--self:F()
|
--self:T()
|
||||||
|
|
||||||
return self.CargoObject:GetCoordinate()
|
return self.CargoObject:GetCoordinate()
|
||||||
end
|
end
|
||||||
@ -199,7 +199,7 @@ do -- CARGO_SLINGLOAD
|
|||||||
-- @param #CARGO_SLINGLOAD self
|
-- @param #CARGO_SLINGLOAD self
|
||||||
-- @param Core.Point#COORDINATE Coordinate
|
-- @param Core.Point#COORDINATE Coordinate
|
||||||
function CARGO_SLINGLOAD:RouteTo( Coordinate )
|
function CARGO_SLINGLOAD:RouteTo( Coordinate )
|
||||||
--self:F( {Coordinate = Coordinate } )
|
--self:T( {Coordinate = Coordinate } )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -212,7 +212,7 @@ do -- CARGO_SLINGLOAD
|
|||||||
-- @return #boolean The Cargo is near to the Carrier.
|
-- @return #boolean The Cargo is near to the Carrier.
|
||||||
-- @return #nil The Cargo is not near to the Carrier.
|
-- @return #nil The Cargo is not near to the Carrier.
|
||||||
function CARGO_SLINGLOAD:IsNear( CargoCarrier, NearRadius )
|
function CARGO_SLINGLOAD:IsNear( CargoCarrier, NearRadius )
|
||||||
--self:F( {NearRadius = NearRadius } )
|
--self:T( {NearRadius = NearRadius } )
|
||||||
|
|
||||||
return self:IsNear( CargoCarrier:GetCoordinate(), NearRadius )
|
return self:IsNear( CargoCarrier:GetCoordinate(), NearRadius )
|
||||||
end
|
end
|
||||||
@ -222,7 +222,7 @@ do -- CARGO_SLINGLOAD
|
|||||||
-- @param #CARGO_SLINGLOAD self
|
-- @param #CARGO_SLINGLOAD self
|
||||||
function CARGO_SLINGLOAD:Respawn()
|
function CARGO_SLINGLOAD:Respawn()
|
||||||
|
|
||||||
--self:F( { "Respawning slingload " .. self:GetName() } )
|
--self:T( { "Respawning slingload " .. self:GetName() } )
|
||||||
|
|
||||||
|
|
||||||
-- Respawn the group...
|
-- Respawn the group...
|
||||||
@ -239,7 +239,7 @@ do -- CARGO_SLINGLOAD
|
|||||||
-- @param #CARGO_SLINGLOAD self
|
-- @param #CARGO_SLINGLOAD self
|
||||||
function CARGO_SLINGLOAD:onafterReset()
|
function CARGO_SLINGLOAD:onafterReset()
|
||||||
|
|
||||||
--self:F( { "Reset slingload " .. self:GetName() } )
|
--self:T( { "Reset slingload " .. self:GetName() } )
|
||||||
|
|
||||||
|
|
||||||
-- Respawn the group...
|
-- Respawn the group...
|
||||||
|
|||||||
@ -75,7 +75,7 @@ do -- CARGO_UNIT
|
|||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||||
-- @param #number NearRadius (optional) Defaut 25 m.
|
-- @param #number NearRadius (optional) Defaut 25 m.
|
||||||
function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
self:T( { From, Event, To, ToPointVec2, NearRadius } )
|
||||||
|
|
||||||
local Angle = 180
|
local Angle = 180
|
||||||
local Speed = 60
|
local Speed = 60
|
||||||
@ -114,7 +114,7 @@ do -- CARGO_UNIT
|
|||||||
else
|
else
|
||||||
self.CargoObject:ReSpawnAt( FromPointVec2, CargoDeployHeading )
|
self.CargoObject:ReSpawnAt( FromPointVec2, CargoDeployHeading )
|
||||||
end
|
end
|
||||||
self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } )
|
self:T( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } )
|
||||||
self.CargoCarrier = nil
|
self.CargoCarrier = nil
|
||||||
|
|
||||||
local Points = {}
|
local Points = {}
|
||||||
@ -148,7 +148,7 @@ do -- CARGO_UNIT
|
|||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||||
-- @param #number NearRadius (optional) Defaut 100 m.
|
-- @param #number NearRadius (optional) Defaut 100 m.
|
||||||
function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
self:T( { From, Event, To, ToPointVec2, NearRadius } )
|
||||||
|
|
||||||
local Angle = 180
|
local Angle = 180
|
||||||
local Speed = 10
|
local Speed = 10
|
||||||
@ -174,7 +174,7 @@ do -- CARGO_UNIT
|
|||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||||
-- @param #number NearRadius (optional) Defaut 100 m.
|
-- @param #number NearRadius (optional) Defaut 100 m.
|
||||||
function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
self:T( { From, Event, To, ToPointVec2, NearRadius } )
|
||||||
|
|
||||||
self.CargoInAir = self.CargoObject:InAir()
|
self.CargoInAir = self.CargoObject:InAir()
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ do -- CARGO_UNIT
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Core.Point#POINT_VEC2
|
-- @param Core.Point#POINT_VEC2
|
||||||
function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
||||||
self:F( { ToPointVec2, From, Event, To } )
|
self:T( { ToPointVec2, From, Event, To } )
|
||||||
|
|
||||||
local Angle = 180
|
local Angle = 180
|
||||||
local Speed = 10
|
local Speed = 10
|
||||||
@ -236,7 +236,7 @@ do -- CARGO_UNIT
|
|||||||
-- @param Wrapper.Group#GROUP CargoCarrier
|
-- @param Wrapper.Group#GROUP CargoCarrier
|
||||||
-- @param #number NearRadius
|
-- @param #number NearRadius
|
||||||
function CARGO_UNIT:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... )
|
function CARGO_UNIT:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||||
self:F( { From, Event, To, CargoCarrier, NearRadius = NearRadius } )
|
self:T( { From, Event, To, CargoCarrier, NearRadius = NearRadius } )
|
||||||
|
|
||||||
self.CargoInAir = self.CargoObject:InAir()
|
self.CargoInAir = self.CargoObject:InAir()
|
||||||
|
|
||||||
@ -244,7 +244,7 @@ do -- CARGO_UNIT
|
|||||||
local MaxSpeed = Desc.speedMaxOffRoad
|
local MaxSpeed = Desc.speedMaxOffRoad
|
||||||
local TypeName = Desc.typeName
|
local TypeName = Desc.typeName
|
||||||
|
|
||||||
--self:F({Unit=self.CargoObject:GetName()})
|
--self:T({Unit=self.CargoObject:GetName()})
|
||||||
|
|
||||||
-- A cargo unit can only be boarded if it is not dead
|
-- A cargo unit can only be boarded if it is not dead
|
||||||
|
|
||||||
@ -298,9 +298,9 @@ do -- CARGO_UNIT
|
|||||||
-- @param Wrapper.Client#CLIENT CargoCarrier
|
-- @param Wrapper.Client#CLIENT CargoCarrier
|
||||||
-- @param #number NearRadius Default 25 m.
|
-- @param #number NearRadius Default 25 m.
|
||||||
function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||||
self:F( { From, Event, To, CargoCarrier:GetName(), NearRadius = NearRadius } )
|
self:T( { From, Event, To, CargoCarrier:GetName(), NearRadius = NearRadius } )
|
||||||
|
|
||||||
self:F( { IsAlive=self.CargoObject:IsAlive() } )
|
self:T( { IsAlive=self.CargoObject:IsAlive() } )
|
||||||
|
|
||||||
if CargoCarrier and CargoCarrier:IsAlive() then -- and self.CargoObject and self.CargoObject:IsAlive() then
|
if CargoCarrier and CargoCarrier:IsAlive() then -- and self.CargoObject and self.CargoObject:IsAlive() then
|
||||||
if (CargoCarrier:IsAir() and not CargoCarrier:InAir()) or true then
|
if (CargoCarrier:IsAir() and not CargoCarrier:InAir()) or true then
|
||||||
@ -321,7 +321,7 @@ do -- CARGO_UNIT
|
|||||||
local Angle = 180
|
local Angle = 180
|
||||||
local Distance = 0
|
local Distance = 0
|
||||||
|
|
||||||
--self:F({Unit=self.CargoObject:GetName()})
|
--self:T({Unit=self.CargoObject:GetName()})
|
||||||
|
|
||||||
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
||||||
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||||
@ -348,7 +348,7 @@ do -- CARGO_UNIT
|
|||||||
self.CargoObject:SetCommand( self.CargoObject:CommandStopRoute( true ) )
|
self.CargoObject:SetCommand( self.CargoObject:CommandStopRoute( true ) )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:E("Something is wrong")
|
self:T("Something is wrong")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -361,11 +361,11 @@ do -- CARGO_UNIT
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||||
function CARGO_UNIT:onenterLoaded( From, Event, To, CargoCarrier )
|
function CARGO_UNIT:onenterLoaded( From, Event, To, CargoCarrier )
|
||||||
self:F( { From, Event, To, CargoCarrier } )
|
self:T( { From, Event, To, CargoCarrier } )
|
||||||
|
|
||||||
self.CargoCarrier = CargoCarrier
|
self.CargoCarrier = CargoCarrier
|
||||||
|
|
||||||
--self:F({Unit=self.CargoObject:GetName()})
|
--self:T({Unit=self.CargoObject:GetName()})
|
||||||
|
|
||||||
-- Only destroy the CargoObject if there is a CargoObject (packages don't have CargoObjects).
|
-- Only destroy the CargoObject if there is a CargoObject (packages don't have CargoObjects).
|
||||||
if self.CargoObject then
|
if self.CargoObject then
|
||||||
|
|||||||
@ -449,10 +449,10 @@ do -- Zones and Pathlines
|
|||||||
|
|
||||||
-- Loop over layers.
|
-- Loop over layers.
|
||||||
for layerID, layerData in pairs(env.mission.drawings.layers or {}) do
|
for layerID, layerData in pairs(env.mission.drawings.layers or {}) do
|
||||||
|
|
||||||
-- Loop over objects in layers.
|
-- Loop over objects in layers.
|
||||||
for objectID, objectData in pairs(layerData.objects or {}) do
|
for objectID, objectData in pairs(layerData.objects or {}) do
|
||||||
|
|
||||||
-- Check for polygon which has at least 4 points (we would need 3 but the origin seems to be there twice)
|
-- Check for polygon which has at least 4 points (we would need 3 but the origin seems to be there twice)
|
||||||
if objectData.polygonMode and (objectData.polygonMode=="free") and objectData.points and #objectData.points>=4 then
|
if objectData.polygonMode and (objectData.polygonMode=="free") and objectData.points and #objectData.points>=4 then
|
||||||
|
|
||||||
@ -488,10 +488,32 @@ do -- Zones and Pathlines
|
|||||||
|
|
||||||
-- Create new polygon zone.
|
-- Create new polygon zone.
|
||||||
local Zone=ZONE_POLYGON:NewFromPointsArray(ZoneName, points)
|
local Zone=ZONE_POLYGON:NewFromPointsArray(ZoneName, points)
|
||||||
|
|
||||||
|
--Zone.DrawID = objectID
|
||||||
|
|
||||||
-- Set color.
|
-- Set color.
|
||||||
Zone:SetColor({1, 0, 0}, 0.15)
|
Zone:SetColor({1, 0, 0}, 0.15)
|
||||||
|
Zone:SetFillColor({1, 0, 0}, 0.15)
|
||||||
|
|
||||||
|
if objectData.colorString then
|
||||||
|
-- eg colorString = 0xff0000ff
|
||||||
|
local color = string.gsub(objectData.colorString,"^0x","")
|
||||||
|
local r = tonumber(string.sub(color,1,2),16)/255
|
||||||
|
local g = tonumber(string.sub(color,3,4),16)/255
|
||||||
|
local b = tonumber(string.sub(color,5,6),16)/255
|
||||||
|
local a = tonumber(string.sub(color,7,8),16)/255
|
||||||
|
Zone:SetColor({r, g, b}, a)
|
||||||
|
end
|
||||||
|
if objectData.fillColorString then
|
||||||
|
-- eg fillColorString = 0xff00004b
|
||||||
|
local color = string.gsub(objectData.colorString,"^0x","")
|
||||||
|
local r = tonumber(string.sub(color,1,2),16)/255
|
||||||
|
local g = tonumber(string.sub(color,3,4),16)/255
|
||||||
|
local b = tonumber(string.sub(color,5,6),16)/255
|
||||||
|
local a = tonumber(string.sub(color,7,8),16)/255
|
||||||
|
Zone:SetFillColor({r, g, b}, a)
|
||||||
|
end
|
||||||
|
|
||||||
-- Store in DB.
|
-- Store in DB.
|
||||||
self.ZONENAMES[ZoneName] = ZoneName
|
self.ZONENAMES[ZoneName] = ZoneName
|
||||||
|
|
||||||
@ -532,7 +554,26 @@ do -- Zones and Pathlines
|
|||||||
|
|
||||||
-- Set color.
|
-- Set color.
|
||||||
Zone:SetColor({1, 0, 0}, 0.15)
|
Zone:SetColor({1, 0, 0}, 0.15)
|
||||||
|
|
||||||
|
if objectData.colorString then
|
||||||
|
-- eg colorString = 0xff0000ff
|
||||||
|
local color = string.gsub(objectData.colorString,"^0x","")
|
||||||
|
local r = tonumber(string.sub(color,1,2),16)/255
|
||||||
|
local g = tonumber(string.sub(color,3,4),16)/255
|
||||||
|
local b = tonumber(string.sub(color,5,6),16)/255
|
||||||
|
local a = tonumber(string.sub(color,7,8),16)/255
|
||||||
|
Zone:SetColor({r, g, b}, a)
|
||||||
|
end
|
||||||
|
if objectData.fillColorString then
|
||||||
|
-- eg fillColorString = 0xff00004b
|
||||||
|
local color = string.gsub(objectData.colorString,"^0x","")
|
||||||
|
local r = tonumber(string.sub(color,1,2),16)/255
|
||||||
|
local g = tonumber(string.sub(color,3,4),16)/255
|
||||||
|
local b = tonumber(string.sub(color,5,6),16)/255
|
||||||
|
local a = tonumber(string.sub(color,7,8),16)/255
|
||||||
|
Zone:SetFillColor({r, g, b}, a)
|
||||||
|
end
|
||||||
|
|
||||||
-- Store in DB.
|
-- Store in DB.
|
||||||
self.ZONENAMES[ZoneName] = ZoneName
|
self.ZONENAMES[ZoneName] = ZoneName
|
||||||
|
|
||||||
@ -756,7 +797,7 @@ end -- cargo
|
|||||||
|
|
||||||
--- Finds a CLIENT based on the ClientName.
|
--- Finds a CLIENT based on the ClientName.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string ClientName
|
-- @param #string ClientName - Note this is the UNIT name of the client!
|
||||||
-- @return Wrapper.Client#CLIENT The found CLIENT.
|
-- @return Wrapper.Client#CLIENT The found CLIENT.
|
||||||
function DATABASE:FindClient( ClientName )
|
function DATABASE:FindClient( ClientName )
|
||||||
|
|
||||||
|
|||||||
@ -98,7 +98,7 @@ function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen
|
|||||||
|
|
||||||
self.MessageType = nil
|
self.MessageType = nil
|
||||||
|
|
||||||
-- When no MessageCategory is given, we don't show it as a title...
|
-- When no MessageCategory is given, we don't show it as a title...
|
||||||
if MessageCategory and MessageCategory ~= "" then
|
if MessageCategory and MessageCategory ~= "" then
|
||||||
if MessageCategory:sub( -1 ) ~= "\n" then
|
if MessageCategory:sub( -1 ) ~= "\n" then
|
||||||
self.MessageCategory = MessageCategory .. ": "
|
self.MessageCategory = MessageCategory .. ": "
|
||||||
@ -498,7 +498,6 @@ function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,G
|
|||||||
_MESSAGESRS.Gender = Gender or "female"
|
_MESSAGESRS.Gender = Gender or "female"
|
||||||
|
|
||||||
_MESSAGESRS.MSRS:SetGoogle(PathToCredentials)
|
_MESSAGESRS.MSRS:SetGoogle(PathToCredentials)
|
||||||
_MESSAGESRS.google = PathToCredentials
|
|
||||||
|
|
||||||
_MESSAGESRS.MSRS:SetLabel(Label or "MESSAGE")
|
_MESSAGESRS.MSRS:SetLabel(Label or "MESSAGE")
|
||||||
_MESSAGESRS.label = Label or "MESSAGE"
|
_MESSAGESRS.label = Label or "MESSAGE"
|
||||||
@ -512,8 +511,6 @@ function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,G
|
|||||||
if Voice then _MESSAGESRS.MSRS:SetVoice(Voice) end
|
if Voice then _MESSAGESRS.MSRS:SetVoice(Voice) end
|
||||||
|
|
||||||
_MESSAGESRS.voice = Voice --or MSRS.Voices.Microsoft.Hedda
|
_MESSAGESRS.voice = Voice --or MSRS.Voices.Microsoft.Hedda
|
||||||
--if _MESSAGESRS.google and not Voice then _MESSAGESRS.Voice = MSRS.Voices.Google.Standard.en_GB_Standard_A end
|
|
||||||
--_MESSAGESRS.MSRS:SetVoice(Voice or _MESSAGESRS.voice)
|
|
||||||
|
|
||||||
_MESSAGESRS.SRSQ = MSRSQUEUE:New(Label or "MESSAGE")
|
_MESSAGESRS.SRSQ = MSRSQUEUE:New(Label or "MESSAGE")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -2456,15 +2456,18 @@ do -- COORDINATE
|
|||||||
-- Write command as string and execute that. Idea by Grimes https://forum.dcs.world/topic/324201-mark-to-all-function/#comment-5273793
|
-- Write command as string and execute that. Idea by Grimes https://forum.dcs.world/topic/324201-mark-to-all-function/#comment-5273793
|
||||||
local s=string.format("trigger.action.markupToAll(7, %d, %d,", Coalition, MarkID)
|
local s=string.format("trigger.action.markupToAll(7, %d, %d,", Coalition, MarkID)
|
||||||
for _,vec in pairs(vecs) do
|
for _,vec in pairs(vecs) do
|
||||||
s=s..string.format("%s,", UTILS._OneLineSerialize(vec))
|
--s=s..string.format("%s,", UTILS._OneLineSerialize(vec))
|
||||||
|
s=s..string.format("{x=%.1f, y=%.1f, z=%.1f},", vec.x, vec.y, vec.z)
|
||||||
end
|
end
|
||||||
s=s..string.format("%s, %s, %s, %s", UTILS._OneLineSerialize(Color), UTILS._OneLineSerialize(FillColor), tostring(LineType), tostring(ReadOnly))
|
s=s..string.format("{%.3f, %.3f, %.3f, %.3f},", Color[1], Color[2], Color[3], Color[4])
|
||||||
if Text and Text~="" then
|
s=s..string.format("{%.3f, %.3f, %.3f, %.3f},", FillColor[1], FillColor[2], FillColor[3], FillColor[4])
|
||||||
s=s..string.format(", \"%s\"", Text)
|
s=s..string.format("%d,", LineType or 1)
|
||||||
|
s=s..string.format("%s", tostring(ReadOnly))
|
||||||
|
if Text and type(Text)=="string" and string.len(Text)>0 then
|
||||||
|
s=s..string.format(", \"%s\"", tostring(Text))
|
||||||
end
|
end
|
||||||
s=s..")"
|
s=s..")"
|
||||||
|
|
||||||
|
|
||||||
-- Execute string command
|
-- Execute string command
|
||||||
local success=UTILS.DoString(s)
|
local success=UTILS.DoString(s)
|
||||||
|
|
||||||
|
|||||||
@ -146,7 +146,45 @@ do -- SET_BASE
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [Internal] Add a functional filter
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @param #function ConditionFunction If this function returns `true`, the object is added to the SET. The function needs to take a CONTROLLABLE object as first argument.
|
||||||
|
-- @param ... Condition function arguments, if any.
|
||||||
|
-- @return #boolean If true, at least one condition is true
|
||||||
|
function SET_BASE:FilterFunction(ConditionFunction, ...)
|
||||||
|
|
||||||
|
local condition={}
|
||||||
|
condition.func=ConditionFunction
|
||||||
|
condition.arg={}
|
||||||
|
|
||||||
|
if arg then
|
||||||
|
condition.arg=arg
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self.Filter.Functions then self.Filter.Functions = {} end
|
||||||
|
table.insert(self.Filter.Functions, condition)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [Internal] Check if the condition functions returns true.
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @param Wrapper.Controllable#CONTROLLABLE Object The object to filter for
|
||||||
|
-- @return #boolean If true, if **all** conditions are true
|
||||||
|
function SET_BASE:_EvalFilterFunctions(Object)
|
||||||
|
-- All conditions must be true.
|
||||||
|
for _,_condition in pairs(self.Filter.Functions or {}) do
|
||||||
|
local condition=_condition
|
||||||
|
-- Call function.
|
||||||
|
if condition.func(Object,unpack(condition.arg)) == false then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- No condition was true.
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
--- Clear the Objects in the Set.
|
--- Clear the Objects in the Set.
|
||||||
-- @param #SET_BASE self
|
-- @param #SET_BASE self
|
||||||
-- @param #boolean TriggerEvent If `true`, an event remove is triggered for each group that is removed from the set.
|
-- @param #boolean TriggerEvent If `true`, an event remove is triggered for each group that is removed from the set.
|
||||||
@ -967,6 +1005,7 @@ do
|
|||||||
-- * @{#SET_GROUP.FilterCategoryShip}: Builds the SET_GROUP from ships.
|
-- * @{#SET_GROUP.FilterCategoryShip}: Builds the SET_GROUP from ships.
|
||||||
-- * @{#SET_GROUP.FilterCategoryStructure}: Builds the SET_GROUP from structures.
|
-- * @{#SET_GROUP.FilterCategoryStructure}: Builds the SET_GROUP from structures.
|
||||||
-- * @{#SET_GROUP.FilterZones}: Builds the SET_GROUP with the groups within a @{Core.Zone#ZONE}.
|
-- * @{#SET_GROUP.FilterZones}: Builds the SET_GROUP with the groups within a @{Core.Zone#ZONE}.
|
||||||
|
-- * @{#SET_GROUP.FilterFunction}: Builds the SET_GROUP with a custom condition.
|
||||||
--
|
--
|
||||||
-- Once the filter criteria have been set for the SET_GROUP, you can start filtering using:
|
-- Once the filter criteria have been set for the SET_GROUP, you can start filtering using:
|
||||||
--
|
--
|
||||||
@ -1040,6 +1079,7 @@ do
|
|||||||
Countries = nil,
|
Countries = nil,
|
||||||
GroupPrefixes = nil,
|
GroupPrefixes = nil,
|
||||||
Zones = nil,
|
Zones = nil,
|
||||||
|
Functions = nil,
|
||||||
},
|
},
|
||||||
FilterMeta = {
|
FilterMeta = {
|
||||||
Coalitions = {
|
Coalitions = {
|
||||||
@ -1253,7 +1293,26 @@ do
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [User] Add a custom condition function.
|
||||||
|
-- @function [parent=#SET_GROUP] FilterFunction
|
||||||
|
-- @param #SET_GROUP self
|
||||||
|
-- @param #function ConditionFunction If this function returns `true`, the object is added to the SET. The function needs to take a GROUP object as first argument.
|
||||||
|
-- @param ... Condition function arguments if any.
|
||||||
|
-- @return #SET_GROUP self
|
||||||
|
-- @usage
|
||||||
|
-- -- Image you want to exclude a specific GROUP from a SET:
|
||||||
|
-- local groundset = SET_GROUP:New():FilterCoalitions("blue"):FilterCategoryGround():FilterFunction(
|
||||||
|
-- -- The function needs to take a GROUP object as first - and in this case, only - argument.
|
||||||
|
-- function(grp)
|
||||||
|
-- local isinclude = true
|
||||||
|
-- if grp:GetName() == "Exclude Me" then isinclude = false end
|
||||||
|
-- return isinclude
|
||||||
|
-- end
|
||||||
|
-- ):FilterOnce()
|
||||||
|
-- BASE:I(groundset:Flush())
|
||||||
|
|
||||||
|
|
||||||
--- Builds a set of groups of coalitions.
|
--- Builds a set of groups of coalitions.
|
||||||
-- Possible current coalitions are red, blue and neutral.
|
-- Possible current coalitions are red, blue and neutral.
|
||||||
-- @param #SET_GROUP self
|
-- @param #SET_GROUP self
|
||||||
@ -1927,7 +1986,7 @@ do
|
|||||||
MGroupInclude = MGroupInclude and MGroupActive
|
MGroupInclude = MGroupInclude and MGroupActive
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Coalitions then
|
if self.Filter.Coalitions and MGroupInclude then
|
||||||
local MGroupCoalition = false
|
local MGroupCoalition = false
|
||||||
for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do
|
for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do
|
||||||
self:T3( { "Coalition:", MGroup:GetCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } )
|
self:T3( { "Coalition:", MGroup:GetCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } )
|
||||||
@ -1938,7 +1997,7 @@ do
|
|||||||
MGroupInclude = MGroupInclude and MGroupCoalition
|
MGroupInclude = MGroupInclude and MGroupCoalition
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Categories then
|
if self.Filter.Categories and MGroupInclude then
|
||||||
local MGroupCategory = false
|
local MGroupCategory = false
|
||||||
for CategoryID, CategoryName in pairs( self.Filter.Categories ) do
|
for CategoryID, CategoryName in pairs( self.Filter.Categories ) do
|
||||||
self:T3( { "Category:", MGroup:GetCategory(), self.FilterMeta.Categories[CategoryName], CategoryName } )
|
self:T3( { "Category:", MGroup:GetCategory(), self.FilterMeta.Categories[CategoryName], CategoryName } )
|
||||||
@ -1949,7 +2008,7 @@ do
|
|||||||
MGroupInclude = MGroupInclude and MGroupCategory
|
MGroupInclude = MGroupInclude and MGroupCategory
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Countries then
|
if self.Filter.Countries and MGroupInclude then
|
||||||
local MGroupCountry = false
|
local MGroupCountry = false
|
||||||
for CountryID, CountryName in pairs( self.Filter.Countries ) do
|
for CountryID, CountryName in pairs( self.Filter.Countries ) do
|
||||||
self:T3( { "Country:", MGroup:GetCountry(), CountryName } )
|
self:T3( { "Country:", MGroup:GetCountry(), CountryName } )
|
||||||
@ -1960,7 +2019,7 @@ do
|
|||||||
MGroupInclude = MGroupInclude and MGroupCountry
|
MGroupInclude = MGroupInclude and MGroupCountry
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.GroupPrefixes 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
|
||||||
self:T3( { "Prefix:", string.find( MGroup:GetName(), GroupPrefix, 1 ), GroupPrefix } )
|
self:T3( { "Prefix:", string.find( MGroup:GetName(), GroupPrefix, 1 ), GroupPrefix } )
|
||||||
@ -1971,7 +2030,7 @@ do
|
|||||||
MGroupInclude = MGroupInclude and MGroupPrefix
|
MGroupInclude = MGroupInclude and MGroupPrefix
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Zones then
|
if self.Filter.Zones and MGroupInclude then
|
||||||
local MGroupZone = false
|
local MGroupZone = false
|
||||||
for ZoneName, Zone in pairs( self.Filter.Zones ) do
|
for ZoneName, Zone in pairs( self.Filter.Zones ) do
|
||||||
--self:T( "Zone:", ZoneName )
|
--self:T( "Zone:", ZoneName )
|
||||||
@ -1981,6 +2040,12 @@ do
|
|||||||
end
|
end
|
||||||
MGroupInclude = MGroupInclude and MGroupZone
|
MGroupInclude = MGroupInclude and MGroupZone
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.Filter.Functions and MGroupInclude then
|
||||||
|
local MGroupFunc = false
|
||||||
|
MGroupFunc = self:_EvalFilterFunctions(MGroup)
|
||||||
|
MGroupInclude = MGroupInclude and MGroupFunc
|
||||||
|
end
|
||||||
|
|
||||||
self:T2( MGroupInclude )
|
self:T2( MGroupInclude )
|
||||||
return MGroupInclude
|
return MGroupInclude
|
||||||
@ -2080,6 +2145,7 @@ do -- SET_UNIT
|
|||||||
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
|
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
|
||||||
-- * @{#SET_UNIT.FilterActive}: Builds the SET_UNIT with the units that are only active. Units that are inactive (late activation) won't be included in the set!
|
-- * @{#SET_UNIT.FilterActive}: Builds the SET_UNIT with the units that are only active. Units that are inactive (late activation) won't be included in the set!
|
||||||
-- * @{#SET_UNIT.FilterZones}: Builds the SET_UNIT with the units within a @{Core.Zone#ZONE}.
|
-- * @{#SET_UNIT.FilterZones}: Builds the SET_UNIT with the units within a @{Core.Zone#ZONE}.
|
||||||
|
-- * @{#SET_UNIT.FilterFunction}: Builds the SET_UNIT with a custom condition.
|
||||||
--
|
--
|
||||||
-- Once the filter criteria have been set for the SET_UNIT, you can start filtering using:
|
-- Once the filter criteria have been set for the SET_UNIT, you can start filtering using:
|
||||||
--
|
--
|
||||||
@ -2158,6 +2224,7 @@ do -- SET_UNIT
|
|||||||
Countries = nil,
|
Countries = nil,
|
||||||
UnitPrefixes = nil,
|
UnitPrefixes = nil,
|
||||||
Zones = nil,
|
Zones = nil,
|
||||||
|
Functions = nil,
|
||||||
},
|
},
|
||||||
FilterMeta = {
|
FilterMeta = {
|
||||||
Coalitions = {
|
Coalitions = {
|
||||||
@ -2529,6 +2596,25 @@ do -- SET_UNIT
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [User] Add a custom condition function.
|
||||||
|
-- @function [parent=#SET_UNIT] FilterFunction
|
||||||
|
-- @param #SET_UNIT self
|
||||||
|
-- @param #function ConditionFunction If this function returns `true`, the object is added to the SET. The function needs to take a UNIT object as first argument.
|
||||||
|
-- @param ... Condition function arguments if any.
|
||||||
|
-- @return #SET_UNIT self
|
||||||
|
-- @usage
|
||||||
|
-- -- Image you want to exclude a specific UNIT from a SET:
|
||||||
|
-- local groundset = SET_UNIT:New():FilterCoalitions("blue"):FilterCategories("ground"):FilterFunction(
|
||||||
|
-- -- The function needs to take a UNIT object as first - and in this case, only - argument.
|
||||||
|
-- function(unit)
|
||||||
|
-- local isinclude = true
|
||||||
|
-- if unit:GetName() == "Exclude Me" then isinclude = false end
|
||||||
|
-- return isinclude
|
||||||
|
-- end
|
||||||
|
-- ):FilterOnce()
|
||||||
|
-- BASE:I(groundset:Flush())
|
||||||
|
|
||||||
|
|
||||||
--- Handles the Database to check on an event (birth) that the Object was added in the Database.
|
--- Handles the Database to check on an event (birth) that the Object was added in the Database.
|
||||||
-- This is required, because sometimes the _DATABASE birth event gets called later than the SET_BASE birth event!
|
-- This is required, because sometimes the _DATABASE birth event gets called later than the SET_BASE birth event!
|
||||||
-- @param #SET_UNIT self
|
-- @param #SET_UNIT self
|
||||||
@ -3106,7 +3192,7 @@ do -- SET_UNIT
|
|||||||
MUnitInclude = MUnitInclude and MUnitActive
|
MUnitInclude = MUnitInclude and MUnitActive
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Coalitions then
|
if self.Filter.Coalitions and MUnitInclude then
|
||||||
local MUnitCoalition = false
|
local MUnitCoalition = false
|
||||||
for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do
|
for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do
|
||||||
self:F( { "Coalition:", MUnit:GetCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } )
|
self:F( { "Coalition:", MUnit:GetCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } )
|
||||||
@ -3117,7 +3203,7 @@ do -- SET_UNIT
|
|||||||
MUnitInclude = MUnitInclude and MUnitCoalition
|
MUnitInclude = MUnitInclude and MUnitCoalition
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Categories then
|
if self.Filter.Categories and MUnitInclude then
|
||||||
local MUnitCategory = false
|
local MUnitCategory = false
|
||||||
for CategoryID, CategoryName in pairs( self.Filter.Categories ) do
|
for CategoryID, CategoryName in pairs( self.Filter.Categories ) do
|
||||||
self:T3( { "Category:", MUnit:GetDesc().category, self.FilterMeta.Categories[CategoryName], CategoryName } )
|
self:T3( { "Category:", MUnit:GetDesc().category, self.FilterMeta.Categories[CategoryName], CategoryName } )
|
||||||
@ -3128,7 +3214,7 @@ do -- SET_UNIT
|
|||||||
MUnitInclude = MUnitInclude and MUnitCategory
|
MUnitInclude = MUnitInclude and MUnitCategory
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Types then
|
if self.Filter.Types and MUnitInclude then
|
||||||
local MUnitType = false
|
local MUnitType = false
|
||||||
for TypeID, TypeName in pairs( self.Filter.Types ) do
|
for TypeID, TypeName in pairs( self.Filter.Types ) do
|
||||||
self:T3( { "Type:", MUnit:GetTypeName(), TypeName } )
|
self:T3( { "Type:", MUnit:GetTypeName(), TypeName } )
|
||||||
@ -3139,7 +3225,7 @@ do -- SET_UNIT
|
|||||||
MUnitInclude = MUnitInclude and MUnitType
|
MUnitInclude = MUnitInclude and MUnitType
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Countries then
|
if self.Filter.Countries and MUnitInclude then
|
||||||
local MUnitCountry = false
|
local MUnitCountry = false
|
||||||
for CountryID, CountryName in pairs( self.Filter.Countries ) do
|
for CountryID, CountryName in pairs( self.Filter.Countries ) do
|
||||||
self:T3( { "Country:", MUnit:GetCountry(), CountryName } )
|
self:T3( { "Country:", MUnit:GetCountry(), CountryName } )
|
||||||
@ -3150,7 +3236,7 @@ do -- SET_UNIT
|
|||||||
MUnitInclude = MUnitInclude and MUnitCountry
|
MUnitInclude = MUnitInclude and MUnitCountry
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.UnitPrefixes 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
|
||||||
self:T3( { "Prefix:", string.find( MUnit:GetName(), UnitPrefix, 1 ), UnitPrefix } )
|
self:T3( { "Prefix:", string.find( MUnit:GetName(), UnitPrefix, 1 ), UnitPrefix } )
|
||||||
@ -3161,7 +3247,7 @@ do -- SET_UNIT
|
|||||||
MUnitInclude = MUnitInclude and MUnitPrefix
|
MUnitInclude = MUnitInclude and MUnitPrefix
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.RadarTypes then
|
if self.Filter.RadarTypes and MUnitInclude then
|
||||||
local MUnitRadar = false
|
local MUnitRadar = false
|
||||||
for RadarTypeID, RadarType in pairs( self.Filter.RadarTypes ) do
|
for RadarTypeID, RadarType in pairs( self.Filter.RadarTypes ) do
|
||||||
self:T3( { "Radar:", RadarType } )
|
self:T3( { "Radar:", RadarType } )
|
||||||
@ -3175,7 +3261,7 @@ do -- SET_UNIT
|
|||||||
MUnitInclude = MUnitInclude and MUnitRadar
|
MUnitInclude = MUnitInclude and MUnitRadar
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.SEAD then
|
if self.Filter.SEAD and MUnitInclude then
|
||||||
local MUnitSEAD = false
|
local MUnitSEAD = false
|
||||||
if MUnit:HasSEAD() == true then
|
if MUnit:HasSEAD() == true then
|
||||||
self:T3( "SEAD Found" )
|
self:T3( "SEAD Found" )
|
||||||
@ -3185,7 +3271,7 @@ do -- SET_UNIT
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Zones then
|
if self.Filter.Zones and MUnitInclude then
|
||||||
local MGroupZone = false
|
local MGroupZone = false
|
||||||
for ZoneName, Zone in pairs( self.Filter.Zones ) do
|
for ZoneName, Zone in pairs( self.Filter.Zones ) do
|
||||||
self:T3( "Zone:", ZoneName )
|
self:T3( "Zone:", ZoneName )
|
||||||
@ -3196,6 +3282,11 @@ do -- SET_UNIT
|
|||||||
MUnitInclude = MUnitInclude and MGroupZone
|
MUnitInclude = MUnitInclude and MGroupZone
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.Filter.Functions and MUnitInclude then
|
||||||
|
local MUnitFunc = self:_EvalFilterFunctions(MUnit)
|
||||||
|
MUnitInclude = MUnitInclude and MUnitFunc
|
||||||
|
end
|
||||||
|
|
||||||
self:T2( MUnitInclude )
|
self:T2( MUnitInclude )
|
||||||
return MUnitInclude
|
return MUnitInclude
|
||||||
end
|
end
|
||||||
@ -3277,6 +3368,7 @@ do -- SET_STATIC
|
|||||||
-- * @{#SET_STATIC.FilterPrefixes}: Builds the SET_STATIC with the units containing the same string(s) in their name. **Attention!** LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
|
-- * @{#SET_STATIC.FilterPrefixes}: Builds the SET_STATIC with the units containing the same string(s) in their name. **Attention!** LUA regular expression apply here, so special characters in names like minus, dot, hash (#) etc might lead to unexpected results.
|
||||||
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
|
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
|
||||||
-- * @{#SET_STATIC.FilterZones}: Builds the SET_STATIC with the units within a @{Core.Zone#ZONE}.
|
-- * @{#SET_STATIC.FilterZones}: Builds the SET_STATIC with the units within a @{Core.Zone#ZONE}.
|
||||||
|
-- * @{#SET_STATIC.FilterFunction}: Builds the SET_STATIC with a custom condition.
|
||||||
--
|
--
|
||||||
-- Once the filter criteria have been set for the SET_STATIC, you can start filtering using:
|
-- Once the filter criteria have been set for the SET_STATIC, you can start filtering using:
|
||||||
--
|
--
|
||||||
@ -3479,7 +3571,25 @@ do -- SET_STATIC
|
|||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [User] Add a custom condition function.
|
||||||
|
-- @function [parent=#SET_STATIC] FilterFunction
|
||||||
|
-- @param #SET_STATIC self
|
||||||
|
-- @param #function ConditionFunction If this function returns `true`, the object is added to the SET. The function needs to take a STATIC object as first argument.
|
||||||
|
-- @param ... Condition function arguments if any.
|
||||||
|
-- @return #SET_STATIC self
|
||||||
|
-- @usage
|
||||||
|
-- -- Image you want to exclude a specific CLIENT from a SET:
|
||||||
|
-- local groundset = SET_STATIC:New():FilterCoalitions("blue"):FilterActive(true):FilterFunction(
|
||||||
|
-- -- The function needs to take a STATIC object as first - and in this case, only - argument.
|
||||||
|
-- function(static)
|
||||||
|
-- local isinclude = true
|
||||||
|
-- if static:GetName() == "Exclude Me" then isinclude = false end
|
||||||
|
-- return isinclude
|
||||||
|
-- end
|
||||||
|
-- ):FilterOnce()
|
||||||
|
-- BASE:I(groundset:Flush())
|
||||||
|
|
||||||
--- Builds a set of units of defined countries.
|
--- Builds a set of units of defined countries.
|
||||||
-- Possible current countries are those known within DCS world.
|
-- Possible current countries are those known within DCS world.
|
||||||
-- @param #SET_STATIC self
|
-- @param #SET_STATIC self
|
||||||
@ -4036,6 +4146,7 @@ do -- SET_CLIENT
|
|||||||
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
|
-- Have a read through here to understand the application of regular expressions: [LUA regular expressions](https://riptutorial.com/lua/example/20315/lua-pattern-matching)
|
||||||
-- * @{#SET_CLIENT.FilterActive}: Builds the SET_CLIENT with the units that are only active. Units that are inactive (late activation) won't be included in the set!
|
-- * @{#SET_CLIENT.FilterActive}: Builds the SET_CLIENT with the units that are only active. Units that are inactive (late activation) won't be included in the set!
|
||||||
-- * @{#SET_CLIENT.FilterZones}: Builds the SET_CLIENT with the clients within a @{Core.Zone#ZONE}.
|
-- * @{#SET_CLIENT.FilterZones}: Builds the SET_CLIENT with the clients within a @{Core.Zone#ZONE}.
|
||||||
|
-- * @{#SET_CLIENT.FilterFunction}: Builds the SET_CLIENT with a custom condition.
|
||||||
--
|
--
|
||||||
-- Once the filter criteria have been set for the SET_CLIENT, you can start filtering using:
|
-- Once the filter criteria have been set for the SET_CLIENT, you can start filtering using:
|
||||||
--
|
--
|
||||||
@ -4538,6 +4649,25 @@ do -- SET_CLIENT
|
|||||||
return AliveSet.Set or {}
|
return AliveSet.Set or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [User] Add a custom condition function.
|
||||||
|
-- @function [parent=#SET_CLIENT] FilterFunction
|
||||||
|
-- @param #SET_CLIENT self
|
||||||
|
-- @param #function ConditionFunction If this function returns `true`, the object is added to the SET. The function needs to take a CLIENT object as first argument.
|
||||||
|
-- @param ... Condition function arguments if any.
|
||||||
|
-- @return #SET_CLIENT self
|
||||||
|
-- @usage
|
||||||
|
-- -- Image you want to exclude a specific CLIENT from a SET:
|
||||||
|
-- local groundset = SET_CLIENT:New():FilterCoalitions("blue"):FilterActive(true):FilterFunction(
|
||||||
|
-- -- The function needs to take a UNIT object as first - and in this case, only - argument.
|
||||||
|
-- function(client)
|
||||||
|
-- local isinclude = true
|
||||||
|
-- if client:GetPlayerName() == "Exclude Me" then isinclude = false end
|
||||||
|
-- return isinclude
|
||||||
|
-- end
|
||||||
|
-- ):FilterOnce()
|
||||||
|
-- BASE:I(groundset:Flush())
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @param #SET_CLIENT self
|
-- @param #SET_CLIENT self
|
||||||
-- @param Wrapper.Client#CLIENT MClient
|
-- @param Wrapper.Client#CLIENT MClient
|
||||||
@ -4559,7 +4689,7 @@ do -- SET_CLIENT
|
|||||||
MClientInclude = MClientInclude and MClientActive
|
MClientInclude = MClientInclude and MClientActive
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Coalitions then
|
if self.Filter.Coalitions and MClientInclude then
|
||||||
local MClientCoalition = false
|
local MClientCoalition = false
|
||||||
for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do
|
for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do
|
||||||
local ClientCoalitionID = _DATABASE:GetCoalitionFromClientTemplate( MClientName )
|
local ClientCoalitionID = _DATABASE:GetCoalitionFromClientTemplate( MClientName )
|
||||||
@ -4572,7 +4702,7 @@ do -- SET_CLIENT
|
|||||||
MClientInclude = MClientInclude and MClientCoalition
|
MClientInclude = MClientInclude and MClientCoalition
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Categories then
|
if self.Filter.Categories and MClientInclude then
|
||||||
local MClientCategory = false
|
local MClientCategory = false
|
||||||
for CategoryID, CategoryName in pairs( self.Filter.Categories ) do
|
for CategoryID, CategoryName in pairs( self.Filter.Categories ) do
|
||||||
local ClientCategoryID = _DATABASE:GetCategoryFromClientTemplate( MClientName )
|
local ClientCategoryID = _DATABASE:GetCategoryFromClientTemplate( MClientName )
|
||||||
@ -4585,7 +4715,7 @@ do -- SET_CLIENT
|
|||||||
MClientInclude = MClientInclude and MClientCategory
|
MClientInclude = MClientInclude and MClientCategory
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Types then
|
if self.Filter.Types and MClientInclude then
|
||||||
local MClientType = false
|
local MClientType = false
|
||||||
for TypeID, TypeName in pairs( self.Filter.Types ) do
|
for TypeID, TypeName in pairs( self.Filter.Types ) do
|
||||||
self:T3( { "Type:", MClient:GetTypeName(), TypeName } )
|
self:T3( { "Type:", MClient:GetTypeName(), TypeName } )
|
||||||
@ -4597,7 +4727,7 @@ do -- SET_CLIENT
|
|||||||
MClientInclude = MClientInclude and MClientType
|
MClientInclude = MClientInclude and MClientType
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Countries then
|
if self.Filter.Countries and MClientInclude then
|
||||||
local MClientCountry = false
|
local MClientCountry = false
|
||||||
for CountryID, CountryName in pairs( self.Filter.Countries ) do
|
for CountryID, CountryName in pairs( self.Filter.Countries ) do
|
||||||
local ClientCountryID = _DATABASE:GetCountryFromClientTemplate( MClientName )
|
local ClientCountryID = _DATABASE:GetCountryFromClientTemplate( MClientName )
|
||||||
@ -4610,7 +4740,7 @@ do -- SET_CLIENT
|
|||||||
MClientInclude = MClientInclude and MClientCountry
|
MClientInclude = MClientInclude and MClientCountry
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.ClientPrefixes 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
|
||||||
self:T3( { "Prefix:", string.find( MClient.UnitName, ClientPrefix, 1 ), ClientPrefix } )
|
self:T3( { "Prefix:", string.find( MClient.UnitName, ClientPrefix, 1 ), ClientPrefix } )
|
||||||
@ -4622,7 +4752,7 @@ do -- SET_CLIENT
|
|||||||
MClientInclude = MClientInclude and MClientPrefix
|
MClientInclude = MClientInclude and MClientPrefix
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Zones then
|
if self.Filter.Zones and MClientInclude then
|
||||||
local MClientZone = false
|
local MClientZone = false
|
||||||
for ZoneName, Zone in pairs( self.Filter.Zones ) do
|
for ZoneName, Zone in pairs( self.Filter.Zones ) do
|
||||||
self:T3( "Zone:", ZoneName )
|
self:T3( "Zone:", ZoneName )
|
||||||
@ -4634,7 +4764,7 @@ do -- SET_CLIENT
|
|||||||
MClientInclude = MClientInclude and MClientZone
|
MClientInclude = MClientInclude and MClientZone
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Playernames then
|
if self.Filter.Playernames and MClientInclude then
|
||||||
local MClientPlayername = false
|
local MClientPlayername = false
|
||||||
local playername = MClient:GetPlayerName() or "Unknown"
|
local playername = MClient:GetPlayerName() or "Unknown"
|
||||||
--self:T(playername)
|
--self:T(playername)
|
||||||
@ -4647,7 +4777,7 @@ do -- SET_CLIENT
|
|||||||
MClientInclude = MClientInclude and MClientPlayername
|
MClientInclude = MClientInclude and MClientPlayername
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Callsigns then
|
if self.Filter.Callsigns and MClientInclude then
|
||||||
local MClientCallsigns = false
|
local MClientCallsigns = false
|
||||||
local callsign = MClient:GetCallsign()
|
local callsign = MClient:GetCallsign()
|
||||||
--self:I(callsign)
|
--self:I(callsign)
|
||||||
@ -4660,6 +4790,11 @@ do -- SET_CLIENT
|
|||||||
MClientInclude = MClientInclude and MClientCallsigns
|
MClientInclude = MClientInclude and MClientCallsigns
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.Filter.Functions and MClientInclude then
|
||||||
|
local MClientFunc = self:_EvalFilterFunctions(MClient)
|
||||||
|
MClientInclude = MClientInclude and MClientFunc
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
self:T2( MClientInclude )
|
self:T2( MClientInclude )
|
||||||
return MClientInclude
|
return MClientInclude
|
||||||
@ -5253,7 +5388,7 @@ do -- SET_AIRBASE
|
|||||||
function SET_AIRBASE:GetRandomAirbase()
|
function SET_AIRBASE:GetRandomAirbase()
|
||||||
|
|
||||||
local RandomAirbase = self:GetRandom()
|
local RandomAirbase = self:GetRandom()
|
||||||
self:F( { RandomAirbase = RandomAirbase:GetName() } )
|
--self:F( { RandomAirbase = RandomAirbase:GetName() } )
|
||||||
|
|
||||||
return RandomAirbase
|
return RandomAirbase
|
||||||
end
|
end
|
||||||
@ -5419,7 +5554,7 @@ do -- SET_AIRBASE
|
|||||||
MAirbaseInclude = MAirbaseInclude and MAirbaseCoalition
|
MAirbaseInclude = MAirbaseInclude and MAirbaseCoalition
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.Filter.Categories then
|
if self.Filter.Categories and MAirbaseInclude then
|
||||||
local MAirbaseCategory = false
|
local MAirbaseCategory = false
|
||||||
for CategoryID, CategoryName in pairs( self.Filter.Categories ) do
|
for CategoryID, CategoryName in pairs( self.Filter.Categories ) do
|
||||||
local AirbaseCategoryID = _DATABASE:GetCategoryFromAirbase( MAirbaseName )
|
local AirbaseCategoryID = _DATABASE:GetCategoryFromAirbase( MAirbaseName )
|
||||||
@ -7765,7 +7900,7 @@ do -- SET_OPSGROUP
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Filter coalitions.
|
-- Filter coalitions.
|
||||||
if self.Filter.Coalitions then
|
if self.Filter.Coalitions and MGroupInclude then
|
||||||
|
|
||||||
local MGroupCoalition = false
|
local MGroupCoalition = false
|
||||||
|
|
||||||
@ -7779,7 +7914,7 @@ do -- SET_OPSGROUP
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Filter categories.
|
-- Filter categories.
|
||||||
if self.Filter.Categories then
|
if self.Filter.Categories and MGroupInclude then
|
||||||
|
|
||||||
local MGroupCategory = false
|
local MGroupCategory = false
|
||||||
|
|
||||||
@ -7793,7 +7928,7 @@ do -- SET_OPSGROUP
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Filter countries.
|
-- Filter countries.
|
||||||
if self.Filter.Countries then
|
if self.Filter.Countries and MGroupInclude then
|
||||||
local MGroupCountry = false
|
local MGroupCountry = false
|
||||||
for CountryID, CountryName in pairs( self.Filter.Countries ) do
|
for CountryID, CountryName in pairs( self.Filter.Countries ) do
|
||||||
if country.id[CountryName] == MGroup:GetCountry() then
|
if country.id[CountryName] == MGroup:GetCountry() then
|
||||||
@ -7804,12 +7939,12 @@ do -- SET_OPSGROUP
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Filter "prefixes".
|
-- Filter "prefixes".
|
||||||
if self.Filter.GroupPrefixes 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 string.find( MGroup:GetName(), GroupPrefix:gsub ("-", "%%-"), 1 ) then --Not sure why "-" is replaced by "%-" ?!
|
if string.find( MGroup:GetName(), GroupPrefix:gsub ("-", "%%-"), 1 ) then --Not sure why "-" is replaced by "%-" ?! - So we can still match group names with a dash in them
|
||||||
MGroupPrefix = true
|
MGroupPrefix = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -2020,7 +2020,7 @@ _ZONE_TRIANGLE = {
|
|||||||
Coords={},
|
Coords={},
|
||||||
CenterVec2={x=0, y=0},
|
CenterVec2={x=0, y=0},
|
||||||
SurfaceArea=0,
|
SurfaceArea=0,
|
||||||
DrawIDs={}
|
DrawID={}
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
-- @param #_ZONE_TRIANGLE self
|
-- @param #_ZONE_TRIANGLE self
|
||||||
@ -2100,15 +2100,35 @@ function _ZONE_TRIANGLE:Draw(Coalition, Color, Alpha, FillColor, FillAlpha, Line
|
|||||||
for i=1, #self.Coords do
|
for i=1, #self.Coords do
|
||||||
local c1 = self.Coords[i]
|
local c1 = self.Coords[i]
|
||||||
local c2 = self.Coords[i % #self.Coords + 1]
|
local c2 = self.Coords[i % #self.Coords + 1]
|
||||||
table.add(self.DrawIDs, c1:LineToAll(c2, Coalition, Color, Alpha, LineType, ReadOnly))
|
local id = c1:LineToAll(c2, Coalition, Color, Alpha, LineType, ReadOnly)
|
||||||
|
self.DrawID[#self.DrawID+1] = id
|
||||||
end
|
end
|
||||||
return self.DrawIDs
|
local newID = self.Coords[1]:MarkupToAllFreeForm({self.Coords[2],self.Coords[3]},Coalition,Color,Alpha,FillColor,FillAlpha,LineType,ReadOnly)
|
||||||
|
self.DrawID[#self.DrawID+1] = newID
|
||||||
|
return self.DrawID
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Draw the triangle
|
||||||
|
-- @param #_ZONE_TRIANGLE self
|
||||||
|
-- @return #table of draw IDs
|
||||||
|
function _ZONE_TRIANGLE:Fill(Coalition, FillColor, FillAlpha, ReadOnly)
|
||||||
|
Coalition=Coalition or -1
|
||||||
|
FillColor = FillColor
|
||||||
|
FillAlpha = FillAlpha
|
||||||
|
local newID = self.Coords[1]:MarkupToAllFreeForm({self.Coords[2],self.Coords[3]},Coalition,nil,nil,FillColor,FillAlpha,0,nil)
|
||||||
|
self.DrawID[#self.DrawID+1] = newID
|
||||||
|
return self.DrawID
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @type ZONE_POLYGON_BASE
|
-- @type ZONE_POLYGON_BASE
|
||||||
-- @field #ZONE_POLYGON_BASE.ListVec2 Polygon The polygon defined by an array of @{DCS#Vec2}.
|
-- @field #ZONE_POLYGON_BASE.ListVec2 Polygon The polygon defined by an array of @{DCS#Vec2}.
|
||||||
|
-- @field #number SurfaceArea
|
||||||
|
-- @field #table DrawID
|
||||||
|
-- @field #table FillTriangles
|
||||||
|
-- @field #table _Triangles
|
||||||
|
-- @field #table Borderlines
|
||||||
-- @extends #ZONE_BASE
|
-- @extends #ZONE_BASE
|
||||||
|
|
||||||
|
|
||||||
@ -2133,9 +2153,11 @@ end
|
|||||||
-- @field #ZONE_POLYGON_BASE
|
-- @field #ZONE_POLYGON_BASE
|
||||||
ZONE_POLYGON_BASE = {
|
ZONE_POLYGON_BASE = {
|
||||||
ClassName="ZONE_POLYGON_BASE",
|
ClassName="ZONE_POLYGON_BASE",
|
||||||
_Triangles={}, -- _ZONE_TRIANGLES
|
_Triangles={}, -- #table of #_ZONE_TRIANGLE
|
||||||
SurfaceArea=0,
|
SurfaceArea=0,
|
||||||
DrawID={} -- making a table out of the MarkID so its easier to draw an n-sided polygon, see ZONE_POLYGON_BASE:Draw()
|
DrawID={}, -- making a table out of the MarkID so its easier to draw an n-sided polygon, see ZONE_POLYGON_BASE:Draw()
|
||||||
|
FillTriangles = {},
|
||||||
|
Borderlines = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- A 2D points array.
|
--- A 2D points array.
|
||||||
@ -2172,7 +2194,7 @@ function ZONE_POLYGON_BASE:New( ZoneName, PointsArray )
|
|||||||
self._Triangles = self:_Triangulate()
|
self._Triangles = self:_Triangulate()
|
||||||
-- set the polygon's surface area
|
-- set the polygon's surface area
|
||||||
self.SurfaceArea = self:_CalculateSurfaceArea()
|
self.SurfaceArea = self:_CalculateSurfaceArea()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -2470,57 +2492,113 @@ end
|
|||||||
-- @param #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red. Default is same as `Color` value. -- doesn't seem to work
|
-- @param #table FillColor RGB color table {r, g, b}, e.g. {1,0,0} for red. Default is same as `Color` value. -- doesn't seem to work
|
||||||
-- @param #number FillAlpha Transparency [0,1]. Default 0.15. -- doesn't seem to work
|
-- @param #number FillAlpha Transparency [0,1]. Default 0.15. -- doesn't seem to work
|
||||||
-- @param #number LineType Line type: 0=No line, 1=Solid, 2=Dashed, 3=Dotted, 4=Dot dash, 5=Long dash, 6=Two dash. Default 1=Solid.
|
-- @param #number LineType Line type: 0=No line, 1=Solid, 2=Dashed, 3=Dotted, 4=Dot dash, 5=Long dash, 6=Two dash. Default 1=Solid.
|
||||||
-- @param #boolean ReadOnly (Optional) Mark is readonly and cannot be removed by users. Default false.
|
-- @param #boolean ReadOnly (Optional) Mark is readonly and cannot be removed by users. Default false.s
|
||||||
-- @return #ZONE_POLYGON_BASE self
|
-- @return #ZONE_POLYGON_BASE self
|
||||||
function ZONE_POLYGON_BASE:DrawZone(Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly, IncludeTriangles)
|
function ZONE_POLYGON_BASE:DrawZone(Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly, IncludeTriangles)
|
||||||
if self._.Polygon and #self._.Polygon >= 3 then
|
|
||||||
Coalition = Coalition or self:GetDrawCoalition()
|
|
||||||
|
|
||||||
-- Set draw coalition.
|
|
||||||
self:SetDrawCoalition(Coalition)
|
if self._.Polygon and #self._.Polygon >= 3 then
|
||||||
|
Coalition = Coalition or self:GetDrawCoalition()
|
||||||
Color = Color or self:GetColorRGB()
|
|
||||||
Alpha = Alpha or 1
|
-- Set draw coalition.
|
||||||
|
self:SetDrawCoalition(Coalition)
|
||||||
-- Set color.
|
|
||||||
self:SetColor(Color, Alpha)
|
Color = Color or self:GetColorRGB()
|
||||||
|
Alpha = Alpha or self:GetColorAlpha()
|
||||||
FillColor = FillColor or self:GetFillColorRGB()
|
|
||||||
if not FillColor then
|
FillColor = FillColor or self:GetFillColorRGB()
|
||||||
UTILS.DeepCopy(Color)
|
FillAlpha = FillAlpha or self:GetFillColorAlpha()
|
||||||
end
|
|
||||||
FillAlpha = FillAlpha or self:GetFillColorAlpha()
|
if FillColor then
|
||||||
if not FillAlpha then
|
self:ReFill(FillColor,FillAlpha)
|
||||||
FillAlpha = 0.15
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Set fill color -----------> has fill color worked in recent versions of DCS?
|
|
||||||
-- doing something like
|
|
||||||
--
|
|
||||||
-- trigger.action.markupToAll(7, -1, 501, p.Coords[1]:GetVec3(), p.Coords[2]:GetVec3(),p.Coords[3]:GetVec3(),p.Coords[4]:GetVec3(),{1,0,0, 1}, {1,0,0, 1}, 4, false, Text or "")
|
|
||||||
--
|
|
||||||
-- doesn't seem to fill in the shape for an n-sided polygon
|
|
||||||
self:SetFillColor(FillColor, FillAlpha)
|
|
||||||
|
|
||||||
IncludeTriangles = IncludeTriangles or false
|
|
||||||
|
|
||||||
-- just draw the triangles, we get the outline for free
|
|
||||||
if IncludeTriangles then
|
|
||||||
for _, triangle in pairs(self._Triangles) do
|
|
||||||
local draw_ids = triangle:Draw()
|
|
||||||
table.combine(self.DrawID, draw_ids)
|
|
||||||
end
|
|
||||||
-- draw outline only
|
|
||||||
else
|
|
||||||
local coords = self:GetVerticiesCoordinates()
|
|
||||||
for i = 1, #coords do
|
|
||||||
local c1 = coords[i]
|
|
||||||
local c2 = coords[i % #coords + 1]
|
|
||||||
table.add(self.DrawID, c1:LineToAll(c2, Coalition, Color, Alpha, LineType, ReadOnly))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return self
|
|
||||||
|
if Color then
|
||||||
|
self:ReDrawBorderline(Color,Alpha,LineType)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if false then
|
||||||
|
local coords = self:GetVerticiesCoordinates()
|
||||||
|
|
||||||
|
local coord=coords[1] --Core.Point#COORDINATE
|
||||||
|
|
||||||
|
table.remove(coords, 1)
|
||||||
|
|
||||||
|
coord:MarkupToAllFreeForm(coords, Coalition, Color, Alpha, FillColor, FillAlpha, LineType, ReadOnly, "Drew Polygon")
|
||||||
|
|
||||||
|
if true then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Change/Re-fill a Polygon Zone
|
||||||
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
|
-- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red.
|
||||||
|
-- @param #number Alpha Transparency [0,1]. Default 1.
|
||||||
|
-- @return #ZONE_POLYGON_BASE self
|
||||||
|
function ZONE_POLYGON_BASE:ReFill(Color,Alpha)
|
||||||
|
local color = Color or self:GetFillColorRGB() or {1,0,0}
|
||||||
|
local alpha = Alpha or self:GetFillColorAlpha() or 1
|
||||||
|
local coalition = self:GetDrawCoalition() or -1
|
||||||
|
-- undraw if already filled
|
||||||
|
if #self.FillTriangles > 0 then
|
||||||
|
for _, triangle in pairs(self._Triangles) do
|
||||||
|
triangle:UndrawZone()
|
||||||
|
end
|
||||||
|
-- remove mark IDs
|
||||||
|
for _,_value in pairs(self.FillTriangles) do
|
||||||
|
table.remove_by_value(self.DrawID, _value)
|
||||||
|
end
|
||||||
|
self.FillTriangles = nil
|
||||||
|
self.FillTriangles = {}
|
||||||
|
end
|
||||||
|
-- refill
|
||||||
|
for _, triangle in pairs(self._Triangles) do
|
||||||
|
local draw_ids = triangle:Fill(coalition,color,alpha,nil)
|
||||||
|
self.FillTriangles = draw_ids
|
||||||
|
table.combine(self.DrawID, draw_ids)
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Change/Re-draw the border of a Polygon Zone
|
||||||
|
-- @param #ZONE_POLYGON_BASE self
|
||||||
|
-- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red.
|
||||||
|
-- @param #number Alpha Transparency [0,1]. Default 1.
|
||||||
|
-- @param #number LineType Line type: 0=No line, 1=Solid, 2=Dashed, 3=Dotted, 4=Dot dash, 5=Long dash, 6=Two dash. Default 1=Solid.
|
||||||
|
-- @return #ZONE_POLYGON_BASE
|
||||||
|
function ZONE_POLYGON_BASE:ReDrawBorderline(Color, Alpha, LineType)
|
||||||
|
local color = Color or self:GetFillColorRGB() or {1,0,0}
|
||||||
|
local alpha = Alpha or self:GetFillColorAlpha() or 1
|
||||||
|
local coalition = self:GetDrawCoalition() or -1
|
||||||
|
local linetype = LineType or 1
|
||||||
|
-- undraw if already drawn
|
||||||
|
if #self.Borderlines > 0 then
|
||||||
|
for _, MarkID in pairs(self.Borderlines) do
|
||||||
|
trigger.action.removeMark(MarkID)
|
||||||
|
end
|
||||||
|
-- remove mark IDs
|
||||||
|
for _,_value in pairs(self.Borderlines) do
|
||||||
|
table.remove_by_value(self.DrawID, _value)
|
||||||
|
end
|
||||||
|
self.Borderlines = nil
|
||||||
|
self.Borderlines = {}
|
||||||
|
end
|
||||||
|
-- Redraw border
|
||||||
|
local coords = self:GetVerticiesCoordinates()
|
||||||
|
for i = 1, #coords do
|
||||||
|
local c1 = coords[i]
|
||||||
|
local c2 = coords[i % #coords + 1]
|
||||||
|
local newID = c1:LineToAll(c2, coalition, color, alpha, linetype, nil)
|
||||||
|
self.DrawID[#self.DrawID+1]=newID
|
||||||
|
self.Borderlines[#self.Borderlines+1] = newID
|
||||||
|
end
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get the surface area of this polygon
|
--- Get the surface area of this polygon
|
||||||
@ -2856,6 +2934,7 @@ function ZONE_POLYGON_BASE:Boundary(Coalition, Color, Radius, Alpha, Segments, C
|
|||||||
Alpha = Alpha or 1
|
Alpha = Alpha or 1
|
||||||
Segments = Segments or 10
|
Segments = Segments or 10
|
||||||
Closed = Closed or false
|
Closed = Closed or false
|
||||||
|
local Limit
|
||||||
local i = 1
|
local i = 1
|
||||||
local j = #self._.Polygon
|
local j = #self._.Polygon
|
||||||
if (Closed) then
|
if (Closed) then
|
||||||
@ -3054,18 +3133,18 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
|
|||||||
self.ScanData.Scenery = {}
|
self.ScanData.Scenery = {}
|
||||||
self.ScanData.SceneryTable = {}
|
self.ScanData.SceneryTable = {}
|
||||||
self.ScanData.Units = {}
|
self.ScanData.Units = {}
|
||||||
|
|
||||||
local vectors = self:GetBoundingSquare()
|
local vectors = self:GetBoundingSquare()
|
||||||
|
|
||||||
local minVec3 = {x=vectors.x1, y=0, z=vectors.y1}
|
local minVec3 = {x=vectors.x1, y=0, z=vectors.y1}
|
||||||
local maxVec3 = {x=vectors.x2, y=0, z=vectors.y2}
|
local maxVec3 = {x=vectors.x2, y=0, z=vectors.y2}
|
||||||
|
|
||||||
local minmarkcoord = COORDINATE:NewFromVec3(minVec3)
|
local minmarkcoord = COORDINATE:NewFromVec3(minVec3)
|
||||||
local maxmarkcoord = COORDINATE:NewFromVec3(maxVec3)
|
local maxmarkcoord = COORDINATE:NewFromVec3(maxVec3)
|
||||||
local ZoneRadius = minmarkcoord:Get2DDistance(maxmarkcoord)/2
|
local ZoneRadius = minmarkcoord:Get2DDistance(maxmarkcoord)/2
|
||||||
-- self:I("Scan Radius:" ..ZoneRadius)
|
-- self:I("Scan Radius:" ..ZoneRadius)
|
||||||
local CenterVec3 = self:GetCoordinate():GetVec3()
|
local CenterVec3 = self:GetCoordinate():GetVec3()
|
||||||
|
|
||||||
--[[ this a bit shaky in functionality it seems
|
--[[ this a bit shaky in functionality it seems
|
||||||
local VolumeBox = {
|
local VolumeBox = {
|
||||||
id = world.VolumeType.BOX,
|
id = world.VolumeType.BOX,
|
||||||
@ -3075,7 +3154,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
local SphereSearch = {
|
local SphereSearch = {
|
||||||
id = world.VolumeType.SPHERE,
|
id = world.VolumeType.SPHERE,
|
||||||
params = {
|
params = {
|
||||||
@ -3083,13 +3162,13 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
|
|||||||
radius = ZoneRadius,
|
radius = ZoneRadius,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
local function EvaluateZone( ZoneObject )
|
local function EvaluateZone( ZoneObject )
|
||||||
|
|
||||||
if ZoneObject then
|
if ZoneObject then
|
||||||
|
|
||||||
local ObjectCategory = Object.getCategory(ZoneObject)
|
local ObjectCategory = Object.getCategory(ZoneObject)
|
||||||
|
|
||||||
if ( ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive() ) or (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then
|
if ( ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive() ) or (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then
|
||||||
|
|
||||||
local CoalitionDCSUnit = ZoneObject:getCoalition()
|
local CoalitionDCSUnit = ZoneObject:getCoalition()
|
||||||
@ -3123,7 +3202,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
|
|||||||
self:F2( { Name = ZoneObject:getName(), Coalition = CoalitionDCSUnit } )
|
self:F2( { Name = ZoneObject:getName(), Coalition = CoalitionDCSUnit } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- trying with box search
|
-- trying with box search
|
||||||
if ObjectCategory == Object.Category.SCENERY and self:IsVec3InZone(ZoneObject:getPoint()) then
|
if ObjectCategory == Object.Category.SCENERY and self:IsVec3InZone(ZoneObject:getPoint()) then
|
||||||
local SceneryType = ZoneObject:getTypeName()
|
local SceneryType = ZoneObject:getTypeName()
|
||||||
@ -3142,7 +3221,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
|
|||||||
-- Search objects.
|
-- Search objects.
|
||||||
local inzoneunits = SET_UNIT:New():FilterZones({self}):FilterOnce()
|
local inzoneunits = SET_UNIT:New():FilterZones({self}):FilterOnce()
|
||||||
local inzonestatics = SET_STATIC:New():FilterZones({self}):FilterOnce()
|
local inzonestatics = SET_STATIC:New():FilterZones({self}):FilterOnce()
|
||||||
|
|
||||||
inzoneunits:ForEach(
|
inzoneunits:ForEach(
|
||||||
function(unit)
|
function(unit)
|
||||||
local Unit = unit --Wrapper.Unit#UNIT
|
local Unit = unit --Wrapper.Unit#UNIT
|
||||||
@ -3150,7 +3229,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
|
|||||||
EvaluateZone(DCS)
|
EvaluateZone(DCS)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
inzonestatics:ForEach(
|
inzonestatics:ForEach(
|
||||||
function(static)
|
function(static)
|
||||||
local Static = static --Wrapper.Static#STATIC
|
local Static = static --Wrapper.Static#STATIC
|
||||||
@ -3158,19 +3237,19 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
|
|||||||
EvaluateZone(DCS)
|
EvaluateZone(DCS)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
local searchscenery = false
|
local searchscenery = false
|
||||||
for _,_type in pairs(ObjectCategories) do
|
for _,_type in pairs(ObjectCategories) do
|
||||||
if _type == Object.Category.SCENERY then
|
if _type == Object.Category.SCENERY then
|
||||||
searchscenery = true
|
searchscenery = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if searchscenery then
|
if searchscenery then
|
||||||
-- Search objects.
|
-- Search objects.
|
||||||
world.searchObjects({Object.Category.SCENERY}, SphereSearch, EvaluateZone )
|
world.searchObjects({Object.Category.SCENERY}, SphereSearch, EvaluateZone )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Count the number of different coalitions inside the zone.
|
--- Count the number of different coalitions inside the zone.
|
||||||
@ -3386,7 +3465,7 @@ end
|
|||||||
end
|
end
|
||||||
|
|
||||||
do -- ZONE_ELASTIC
|
do -- ZONE_ELASTIC
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @type ZONE_ELASTIC
|
-- @type ZONE_ELASTIC
|
||||||
-- @field #table points Points in 2D.
|
-- @field #table points Points in 2D.
|
||||||
@ -3413,14 +3492,14 @@ do -- ZONE_ELASTIC
|
|||||||
function ZONE_ELASTIC:New(ZoneName, Points)
|
function ZONE_ELASTIC:New(ZoneName, Points)
|
||||||
|
|
||||||
local self=BASE:Inherit(self, ZONE_POLYGON_BASE:New(ZoneName, Points)) --#ZONE_ELASTIC
|
local self=BASE:Inherit(self, ZONE_POLYGON_BASE:New(ZoneName, Points)) --#ZONE_ELASTIC
|
||||||
|
|
||||||
-- Zone objects are added to the _DATABASE and SET_ZONE objects.
|
-- Zone objects are added to the _DATABASE and SET_ZONE objects.
|
||||||
_EVENTDISPATCHER:CreateEventNewZone( self )
|
_EVENTDISPATCHER:CreateEventNewZone( self )
|
||||||
|
|
||||||
if Points then
|
if Points then
|
||||||
self.points=Points
|
self.points=Points
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3429,10 +3508,10 @@ do -- ZONE_ELASTIC
|
|||||||
-- @param DCS#Vec2 Vec2 Point in 2D (with x and y coordinates).
|
-- @param DCS#Vec2 Vec2 Point in 2D (with x and y coordinates).
|
||||||
-- @return #ZONE_ELASTIC self
|
-- @return #ZONE_ELASTIC self
|
||||||
function ZONE_ELASTIC:AddVertex2D(Vec2)
|
function ZONE_ELASTIC:AddVertex2D(Vec2)
|
||||||
|
|
||||||
-- Add vec2 to points.
|
-- Add vec2 to points.
|
||||||
table.insert(self.points, Vec2)
|
table.insert(self.points, Vec2)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3442,10 +3521,10 @@ do -- ZONE_ELASTIC
|
|||||||
-- @param DCS#Vec3 Vec3 Point in 3D (with x, y and z coordinates). Only the x and z coordinates are used.
|
-- @param DCS#Vec3 Vec3 Point in 3D (with x, y and z coordinates). Only the x and z coordinates are used.
|
||||||
-- @return #ZONE_ELASTIC self
|
-- @return #ZONE_ELASTIC self
|
||||||
function ZONE_ELASTIC:AddVertex3D(Vec3)
|
function ZONE_ELASTIC:AddVertex3D(Vec3)
|
||||||
|
|
||||||
-- Add vec2 from vec3 to points.
|
-- Add vec2 from vec3 to points.
|
||||||
table.insert(self.points, {x=Vec3.x, y=Vec3.z})
|
table.insert(self.points, {x=Vec3.x, y=Vec3.z})
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3455,10 +3534,10 @@ do -- ZONE_ELASTIC
|
|||||||
-- @param Core.Set#SET_GROUP GroupSet Set of groups.
|
-- @param Core.Set#SET_GROUP GroupSet Set of groups.
|
||||||
-- @return #ZONE_ELASTIC self
|
-- @return #ZONE_ELASTIC self
|
||||||
function ZONE_ELASTIC:AddSetGroup(GroupSet)
|
function ZONE_ELASTIC:AddSetGroup(GroupSet)
|
||||||
|
|
||||||
-- Add set to table.
|
-- Add set to table.
|
||||||
table.insert(self.setGroups, GroupSet)
|
table.insert(self.setGroups, GroupSet)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3470,13 +3549,13 @@ do -- ZONE_ELASTIC
|
|||||||
-- @param #boolean Draw Draw the zone. Default `nil`.
|
-- @param #boolean Draw Draw the zone. Default `nil`.
|
||||||
-- @return #ZONE_ELASTIC self
|
-- @return #ZONE_ELASTIC self
|
||||||
function ZONE_ELASTIC:Update(Delay, Draw)
|
function ZONE_ELASTIC:Update(Delay, Draw)
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(string.format("Updating ZONE_ELASTIC %s", tostring(self.ZoneName)))
|
self:T(string.format("Updating ZONE_ELASTIC %s", tostring(self.ZoneName)))
|
||||||
|
|
||||||
-- Copy all points.
|
-- Copy all points.
|
||||||
local points=UTILS.DeepCopy(self.points or {})
|
local points=UTILS.DeepCopy(self.points or {})
|
||||||
|
|
||||||
if self.setGroups then
|
if self.setGroups then
|
||||||
for _,_setGroup in pairs(self.setGroups) do
|
for _,_setGroup in pairs(self.setGroups) do
|
||||||
local setGroup=_setGroup --Core.Set#SET_GROUP
|
local setGroup=_setGroup --Core.Set#SET_GROUP
|
||||||
@ -3491,7 +3570,7 @@ do -- ZONE_ELASTIC
|
|||||||
|
|
||||||
-- Update polygon verticies from points.
|
-- Update polygon verticies from points.
|
||||||
self._.Polygon=self:_ConvexHull(points)
|
self._.Polygon=self:_ConvexHull(points)
|
||||||
|
|
||||||
if Draw~=false then
|
if Draw~=false then
|
||||||
if self.DrawID or Draw==true then
|
if self.DrawID or Draw==true then
|
||||||
self:UndrawZone()
|
self:UndrawZone()
|
||||||
@ -3501,7 +3580,7 @@ do -- ZONE_ELASTIC
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Start the updating scheduler.
|
--- Start the updating scheduler.
|
||||||
-- @param #ZONE_ELASTIC self
|
-- @param #ZONE_ELASTIC self
|
||||||
-- @param #number Tstart Time in seconds before the updating starts.
|
-- @param #number Tstart Time in seconds before the updating starts.
|
||||||
@ -3510,9 +3589,9 @@ do -- ZONE_ELASTIC
|
|||||||
-- @param #boolean Draw Draw the zone. Default `nil`.
|
-- @param #boolean Draw Draw the zone. Default `nil`.
|
||||||
-- @return #ZONE_ELASTIC self
|
-- @return #ZONE_ELASTIC self
|
||||||
function ZONE_ELASTIC:StartUpdate(Tstart, dT, Tstop, Draw)
|
function ZONE_ELASTIC:StartUpdate(Tstart, dT, Tstop, Draw)
|
||||||
|
|
||||||
self.updateID=self:ScheduleRepeat(Tstart, dT, 0, Tstop, ZONE_ELASTIC.Update, self, 0, Draw)
|
self.updateID=self:ScheduleRepeat(Tstart, dT, 0, Tstop, ZONE_ELASTIC.Update, self, 0, Draw)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3521,46 +3600,46 @@ do -- ZONE_ELASTIC
|
|||||||
-- @param #number Delay Delay in seconds before the scheduler will be stopped. Default 0.
|
-- @param #number Delay Delay in seconds before the scheduler will be stopped. Default 0.
|
||||||
-- @return #ZONE_ELASTIC self
|
-- @return #ZONE_ELASTIC self
|
||||||
function ZONE_ELASTIC:StopUpdate(Delay)
|
function ZONE_ELASTIC:StopUpdate(Delay)
|
||||||
|
|
||||||
if Delay and Delay>0 then
|
if Delay and Delay>0 then
|
||||||
self:ScheduleOnce(Delay, ZONE_ELASTIC.StopUpdate, self)
|
self:ScheduleOnce(Delay, ZONE_ELASTIC.StopUpdate, self)
|
||||||
else
|
else
|
||||||
|
|
||||||
if self.updateID then
|
if self.updateID then
|
||||||
|
|
||||||
self:ScheduleStop(self.updateID)
|
self:ScheduleStop(self.updateID)
|
||||||
|
|
||||||
self.updateID=nil
|
self.updateID=nil
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Create a convec hull.
|
--- Create a convec hull.
|
||||||
-- @param #ZONE_ELASTIC self
|
-- @param #ZONE_ELASTIC self
|
||||||
-- @param #table pl Points
|
-- @param #table pl Points
|
||||||
-- @return #table Points
|
-- @return #table Points
|
||||||
function ZONE_ELASTIC:_ConvexHull(pl)
|
function ZONE_ELASTIC:_ConvexHull(pl)
|
||||||
|
|
||||||
if #pl == 0 then
|
if #pl == 0 then
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
|
|
||||||
table.sort(pl, function(left,right)
|
table.sort(pl, function(left,right)
|
||||||
return left.x < right.x
|
return left.x < right.x
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local h = {}
|
local h = {}
|
||||||
|
|
||||||
-- Function: ccw > 0 if three points make a counter-clockwise turn, clockwise if ccw < 0, and collinear if ccw = 0.
|
-- Function: ccw > 0 if three points make a counter-clockwise turn, clockwise if ccw < 0, and collinear if ccw = 0.
|
||||||
local function ccw(a,b,c)
|
local function ccw(a,b,c)
|
||||||
return (b.x - a.x) * (c.y - a.y) > (b.y - a.y) * (c.x - a.x)
|
return (b.x - a.x) * (c.y - a.y) > (b.y - a.y) * (c.x - a.x)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- lower hull
|
-- lower hull
|
||||||
for i,pt in pairs(pl) do
|
for i,pt in pairs(pl) do
|
||||||
while #h >= 2 and not ccw(h[#h-1], h[#h], pt) do
|
while #h >= 2 and not ccw(h[#h-1], h[#h], pt) do
|
||||||
@ -3568,7 +3647,7 @@ do -- ZONE_ELASTIC
|
|||||||
end
|
end
|
||||||
table.insert(h,pt)
|
table.insert(h,pt)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- upper hull
|
-- upper hull
|
||||||
local t = #h + 1
|
local t = #h + 1
|
||||||
for i=#pl, 1, -1 do
|
for i=#pl, 1, -1 do
|
||||||
@ -3578,12 +3657,12 @@ do -- ZONE_ELASTIC
|
|||||||
end
|
end
|
||||||
table.insert(h, pt)
|
table.insert(h, pt)
|
||||||
end
|
end
|
||||||
|
|
||||||
table.remove(h, #h)
|
table.remove(h, #h)
|
||||||
|
|
||||||
return h
|
return h
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -3610,13 +3689,17 @@ ZONE_OVAL = {
|
|||||||
|
|
||||||
--- Creates a new ZONE_OVAL from a center point, major axis, minor axis, and angle.
|
--- Creates a new ZONE_OVAL from a center point, major axis, minor axis, and angle.
|
||||||
--- ported from https://github.com/nielsvaes/CCMOOSE/blob/master/Moose%20Development/Moose/Shapes/Oval.lua
|
--- ported from https://github.com/nielsvaes/CCMOOSE/blob/master/Moose%20Development/Moose/Shapes/Oval.lua
|
||||||
|
-- @param #ZONE_OVAL self
|
||||||
|
-- @param #string name Name of the zone.
|
||||||
-- @param #table vec2 The center point of the oval
|
-- @param #table vec2 The center point of the oval
|
||||||
-- @param #number major_axis The major axis of the oval
|
-- @param #number major_axis The major axis of the oval
|
||||||
-- @param #number minor_axis The minor axis of the oval
|
-- @param #number minor_axis The minor axis of the oval
|
||||||
-- @param #number angle The angle of the oval
|
-- @param #number angle The angle of the oval
|
||||||
-- @return #ZONE_OVAL The new oval
|
-- @return #ZONE_OVAL The new oval
|
||||||
function ZONE_OVAL:New(name, vec2, major_axis, minor_axis, angle)
|
function ZONE_OVAL:New(name, vec2, major_axis, minor_axis, angle)
|
||||||
|
|
||||||
self = BASE:Inherit(self, ZONE_BASE:New())
|
self = BASE:Inherit(self, ZONE_BASE:New())
|
||||||
|
|
||||||
self.ZoneName = name
|
self.ZoneName = name
|
||||||
self.CenterVec2 = vec2
|
self.CenterVec2 = vec2
|
||||||
self.MajorAxis = major_axis
|
self.MajorAxis = major_axis
|
||||||
@ -3654,7 +3737,7 @@ function ZONE_OVAL:NewFromDrawing(DrawingName)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Gets the major axis of the oval.
|
--- Gets the major axis of the oval.
|
||||||
-- @param #ZONE_OVAL self
|
-- @param #ZONE_OVAL self
|
||||||
-- @return #number The major axis of the oval
|
-- @return #number The major axis of the oval
|
||||||
function ZONE_OVAL:GetMajorAxis()
|
function ZONE_OVAL:GetMajorAxis()
|
||||||
@ -3850,7 +3933,7 @@ do -- ZONE_AIRBASE
|
|||||||
|
|
||||||
self._.ZoneAirbase = Airbase
|
self._.ZoneAirbase = Airbase
|
||||||
self._.ZoneVec2Cache = self._.ZoneAirbase:GetVec2()
|
self._.ZoneVec2Cache = self._.ZoneAirbase:GetVec2()
|
||||||
|
|
||||||
if Airbase:IsShip() then
|
if Airbase:IsShip() then
|
||||||
self.isShip=true
|
self.isShip=true
|
||||||
self.isHelipad=false
|
self.isHelipad=false
|
||||||
@ -3858,11 +3941,11 @@ do -- ZONE_AIRBASE
|
|||||||
elseif Airbase:IsHelipad() then
|
elseif Airbase:IsHelipad() then
|
||||||
self.isShip=false
|
self.isShip=false
|
||||||
self.isHelipad=true
|
self.isHelipad=true
|
||||||
self.isAirdrome=false
|
self.isAirdrome=false
|
||||||
elseif Airbase:IsAirdrome() then
|
elseif Airbase:IsAirdrome() then
|
||||||
self.isShip=false
|
self.isShip=false
|
||||||
self.isHelipad=false
|
self.isHelipad=false
|
||||||
self.isAirdrome=true
|
self.isAirdrome=true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Zone objects are added to the _DATABASE and SET_ZONE objects.
|
-- Zone objects are added to the _DATABASE and SET_ZONE objects.
|
||||||
|
|||||||
@ -606,8 +606,10 @@ function AICSAR:SetPilotTTSVoice(Voice,Culture,Gender)
|
|||||||
self.SRSPilot:SetCulture(Culture or "en-US")
|
self.SRSPilot:SetCulture(Culture or "en-US")
|
||||||
self.SRSPilot:SetGender(Gender or "male")
|
self.SRSPilot:SetGender(Gender or "male")
|
||||||
self.SRSPilot:SetLabel("PILOT")
|
self.SRSPilot:SetLabel("PILOT")
|
||||||
if self.SRS.google then
|
if self.SRSGoogle then
|
||||||
self.SRSPilot:SetGoogle(self.SRS.google)
|
local poptions = self.SRS:GetProviderOptions(MSRS.Provider.GOOGLE) -- Sound.SRS#MSRS.ProviderOptions
|
||||||
|
self.SRSPilot:SetGoogle(poptions.credentials)
|
||||||
|
self.SRSPilot:SetGoogleAPIKey(poptions.key)
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -627,9 +629,11 @@ function AICSAR:SetOperatorTTSVoice(Voice,Culture,Gender)
|
|||||||
self.SRSOperator:SetVoice(Voice)
|
self.SRSOperator:SetVoice(Voice)
|
||||||
self.SRSOperator:SetCulture(Culture or "en-GB")
|
self.SRSOperator:SetCulture(Culture or "en-GB")
|
||||||
self.SRSOperator:SetGender(Gender or "female")
|
self.SRSOperator:SetGender(Gender or "female")
|
||||||
self.SRSPilot:SetLabel("RESCUE")
|
self.SRSOperator:SetLabel("RESCUE")
|
||||||
if self.SRS.google then
|
if self.SRSGoogle then
|
||||||
self.SRSOperator:SetGoogle(self.SRS.google)
|
local poptions = self.SRS:GetProviderOptions(MSRS.Provider.GOOGLE) -- Sound.SRS#MSRS.ProviderOptions
|
||||||
|
self.SRSOperator:SetGoogle(poptions.credentials)
|
||||||
|
self.SRSOperator:SetGoogleAPIKey(poptions.key)
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|||||||
@ -10,9 +10,7 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ## Missions:
|
-- ## Missions: None
|
||||||
--
|
|
||||||
-- [ABP - Airbase Police](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/ABP%20-%20Airbase%20Police)
|
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -699,7 +697,8 @@ end
|
|||||||
function ATC_GROUND_UNIVERSAL:_AirbaseMonitor()
|
function ATC_GROUND_UNIVERSAL:_AirbaseMonitor()
|
||||||
self:I("_AirbaseMonitor")
|
self:I("_AirbaseMonitor")
|
||||||
self.SetClient:ForEachClient(
|
self.SetClient:ForEachClient(
|
||||||
--- @param Wrapper.Client#CLIENT Client
|
--- Nameless function
|
||||||
|
-- @param Wrapper.Client#CLIENT Client
|
||||||
function( Client )
|
function( Client )
|
||||||
|
|
||||||
if Client:IsAlive() then
|
if Client:IsAlive() then
|
||||||
|
|||||||
@ -95,7 +95,7 @@ do -- DETECTION_BASE
|
|||||||
--
|
--
|
||||||
-- ## Radar Blur - use to make the radar less exact, e.g. for WWII scenarios
|
-- ## Radar Blur - use to make the radar less exact, e.g. for WWII scenarios
|
||||||
--
|
--
|
||||||
-- * @{DETECTION_BASE.SetRadarBlur}(): Set the radar blur to be used.
|
-- * @{#DETECTION_BASE.SetRadarBlur}(): Set the radar blur to be used.
|
||||||
--
|
--
|
||||||
-- ## **DETECTION_ derived classes** group the detected units into a **DetectedItems[]** list
|
-- ## **DETECTION_ derived classes** group the detected units into a **DetectedItems[]** list
|
||||||
--
|
--
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
-- @module Functional.Mantis
|
-- @module Functional.Mantis
|
||||||
-- @image Functional.Mantis.jpg
|
-- @image Functional.Mantis.jpg
|
||||||
--
|
--
|
||||||
-- Last Update: Nov 2023
|
-- Last Update: Dec 2023
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **MANTIS** class, extends Core.Base#BASE
|
--- **MANTIS** class, extends Core.Base#BASE
|
||||||
@ -94,7 +94,7 @@
|
|||||||
-- Known SAM types at the time of writing are:
|
-- Known SAM types at the time of writing are:
|
||||||
--
|
--
|
||||||
-- * Avenger
|
-- * Avenger
|
||||||
-- * Chaparrel
|
-- * Chaparral
|
||||||
-- * Hawk
|
-- * Hawk
|
||||||
-- * Linebacker
|
-- * Linebacker
|
||||||
-- * NASAMS
|
-- * NASAMS
|
||||||
@ -365,7 +365,7 @@ MANTIS.SamData = {
|
|||||||
["SA-15"] = { Range=11, Blindspot=0, Height=6, Type="Short", Radar="Tor 9A331" },
|
["SA-15"] = { Range=11, Blindspot=0, Height=6, Type="Short", Radar="Tor 9A331" },
|
||||||
["SA-13"] = { Range=5, Blindspot=0, Height=3, Type="Short", Radar="Strela" },
|
["SA-13"] = { Range=5, Blindspot=0, Height=3, Type="Short", Radar="Strela" },
|
||||||
["Avenger"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="Avenger" },
|
["Avenger"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="Avenger" },
|
||||||
["Chaparrel"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Chaparral" },
|
["Chaparral"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Chaparral" },
|
||||||
["Linebacker"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="Linebacker" },
|
["Linebacker"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="Linebacker" },
|
||||||
["Silkworm"] = { Range=90, Blindspot=1, Height=0.2, Type="Long", Radar="Silkworm" },
|
["Silkworm"] = { Range=90, Blindspot=1, Height=0.2, Type="Long", Radar="Silkworm" },
|
||||||
-- units from HDS Mod, multi launcher options is tricky
|
-- units from HDS Mod, multi launcher options is tricky
|
||||||
@ -631,7 +631,7 @@ do
|
|||||||
|
|
||||||
-- TODO Version
|
-- TODO Version
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
self.version="0.8.15"
|
self.version="0.8.16"
|
||||||
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
||||||
|
|
||||||
--- FSM Functions ---
|
--- FSM Functions ---
|
||||||
@ -1149,7 +1149,7 @@ do
|
|||||||
--self:T(self.lid.." Relocating HQ")
|
--self:T(self.lid.." Relocating HQ")
|
||||||
local text = self.lid.." Relocating HQ"
|
local text = self.lid.." Relocating HQ"
|
||||||
--local m= MESSAGE:New(text,10,"MANTIS"):ToAll()
|
--local m= MESSAGE:New(text,10,"MANTIS"):ToAll()
|
||||||
_hqgrp:RelocateGroundRandomInRadius(20,500,true,true)
|
_hqgrp:RelocateGroundRandomInRadius(20,500,true,true,nil,true)
|
||||||
end
|
end
|
||||||
--relocate EWR
|
--relocate EWR
|
||||||
-- TODO: maybe dependent on AlarmState? Observed: SA11 SR only relocates if no objects in reach
|
-- TODO: maybe dependent on AlarmState? Observed: SA11 SR only relocates if no objects in reach
|
||||||
@ -1163,7 +1163,7 @@ do
|
|||||||
local text = self.lid.." Relocating EWR ".._grp:GetName()
|
local text = self.lid.." Relocating EWR ".._grp:GetName()
|
||||||
local m= MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
local m= MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
||||||
if self.verbose then self:I(text) end
|
if self.verbose then self:I(text) end
|
||||||
_grp:RelocateGroundRandomInRadius(20,500,true,true)
|
_grp:RelocateGroundRandomInRadius(20,500,true,true,nil,true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -170,7 +170,7 @@
|
|||||||
--
|
--
|
||||||
-- * A specific departure and/or destination airport can be chosen.
|
-- * A specific departure and/or destination airport can be chosen.
|
||||||
-- * Valid coalitions can be set, e.g. only red, blue or neutral, all three "colours".
|
-- * Valid coalitions can be set, e.g. only red, blue or neutral, all three "colours".
|
||||||
-- * It is possible to start in air within a zone defined in the mission editor or within a zone above an airport of the map.
|
-- * It is possible to start in air within a zone or within a zone above an airport of the map.
|
||||||
--
|
--
|
||||||
-- ## Flight Plan
|
-- ## Flight Plan
|
||||||
--
|
--
|
||||||
@ -1179,13 +1179,13 @@ function RAT:SetTakeoffAir()
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set possible departure ports. This can be an airport or a zone defined in the mission editor.
|
--- Set possible departure ports. This can be an airport or a zone.
|
||||||
-- @param #RAT self
|
-- @param #RAT self
|
||||||
-- @param #string departurenames Name or table of names of departure airports or zones.
|
-- @param #string departurenames Name or table of names of departure airports or zones.
|
||||||
-- @return #RAT RAT self object.
|
-- @return #RAT RAT self object.
|
||||||
-- @usage RAT:SetDeparture("Sochi-Adler") will spawn RAT objects at Sochi-Adler airport.
|
-- @usage RAT:SetDeparture("Sochi-Adler") will spawn RAT objects at Sochi-Adler airport.
|
||||||
-- @usage RAT:SetDeparture({"Sochi-Adler", "Gudauta"}) will spawn RAT aircraft radomly at Sochi-Adler or Gudauta airport.
|
-- @usage RAT:SetDeparture({"Sochi-Adler", "Gudauta"}) will spawn RAT aircraft radomly at Sochi-Adler or Gudauta airport.
|
||||||
-- @usage RAT:SetDeparture({"Zone A", "Gudauta"}) will spawn RAT aircraft in air randomly within Zone A, which has to be defined in the mission editor, or within a zone around Gudauta airport. Note that this also requires RAT:takeoff("air") to be set.
|
-- @usage RAT:SetDeparture({"Zone A", "Gudauta"}) will spawn RAT aircraft in air randomly within Zone A, or within a zone around Gudauta airport. Note that this also requires RAT:takeoff("air") to be set.
|
||||||
function RAT:SetDeparture(departurenames)
|
function RAT:SetDeparture(departurenames)
|
||||||
self:F2(departurenames)
|
self:F2(departurenames)
|
||||||
|
|
||||||
@ -2537,7 +2537,7 @@ function RAT:_SetRoute(takeoff, landing, _departure, _destination, _waypoint)
|
|||||||
end
|
end
|
||||||
elseif self:_ZoneExists(_departure) then
|
elseif self:_ZoneExists(_departure) then
|
||||||
-- If it's not an airport, check whether it's a zone.
|
-- If it's not an airport, check whether it's a zone.
|
||||||
departure=ZONE:New(_departure)
|
departure=ZONE:FindByName(_departure)
|
||||||
else
|
else
|
||||||
local text=string.format("ERROR! Specified departure airport %s does not exist for %s.", _departure, self.alias)
|
local text=string.format("ERROR! Specified departure airport %s does not exist for %s.", _departure, self.alias)
|
||||||
self:E(RAT.id..text)
|
self:E(RAT.id..text)
|
||||||
@ -2635,7 +2635,7 @@ function RAT:_SetRoute(takeoff, landing, _departure, _destination, _waypoint)
|
|||||||
end
|
end
|
||||||
|
|
||||||
elseif self:_ZoneExists(_destination) then
|
elseif self:_ZoneExists(_destination) then
|
||||||
destination=ZONE:New(_destination)
|
destination=ZONE:FindByName(_destination)
|
||||||
else
|
else
|
||||||
local text=string.format("ERROR: Specified destination airport/zone %s does not exist for %s!", _destination, self.alias)
|
local text=string.format("ERROR: Specified destination airport/zone %s does not exist for %s!", _destination, self.alias)
|
||||||
self:E(RAT.id.."ERROR: "..text)
|
self:E(RAT.id.."ERROR: "..text)
|
||||||
@ -3142,7 +3142,7 @@ function RAT:_PickDeparture(takeoff)
|
|||||||
end
|
end
|
||||||
elseif self:_ZoneExists(name) then
|
elseif self:_ZoneExists(name) then
|
||||||
if takeoff==RAT.wp.air then
|
if takeoff==RAT.wp.air then
|
||||||
dep=ZONE:New(name)
|
dep=ZONE:FindByName(name)
|
||||||
else
|
else
|
||||||
self:E(RAT.id..string.format("ERROR! Takeoff is not in air. Cannot use %s as departure.", name))
|
self:E(RAT.id..string.format("ERROR! Takeoff is not in air. Cannot use %s as departure.", name))
|
||||||
end
|
end
|
||||||
@ -3254,7 +3254,7 @@ function RAT:_PickDestination(departure, q, minrange, maxrange, random, landing)
|
|||||||
end
|
end
|
||||||
elseif self:_ZoneExists(name) then
|
elseif self:_ZoneExists(name) then
|
||||||
if landing==RAT.wp.air then
|
if landing==RAT.wp.air then
|
||||||
dest=ZONE:New(name)
|
dest=ZONE:FindByName(name)
|
||||||
else
|
else
|
||||||
self:E(RAT.id..string.format("ERROR! Landing is not in air. Cannot use zone %s as destination!", name))
|
self:E(RAT.id..string.format("ERROR! Landing is not in air. Cannot use zone %s as destination!", name))
|
||||||
end
|
end
|
||||||
@ -4930,12 +4930,12 @@ function RAT:_AirportExists(name)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Test if a trigger zone defined in the mission editor exists.
|
--- Test if a zone exists.
|
||||||
-- @param #RAT self
|
-- @param #RAT self
|
||||||
-- @param #string name
|
-- @param #string name
|
||||||
-- @return #boolean True if zone exsits, false otherwise.
|
-- @return #boolean True if zone exsits, false otherwise.
|
||||||
function RAT:_ZoneExists(name)
|
function RAT:_ZoneExists(name)
|
||||||
local z=trigger.misc.getZone(name)
|
local z=ZONE:FindByName(name) --trigger.misc.getZone(name) as suggested by @Viking on MOOSE discord #rat
|
||||||
if z then
|
if z then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1737,7 +1737,9 @@ end
|
|||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
function RANGE:OnEventBirth( EventData )
|
function RANGE:OnEventBirth( EventData )
|
||||||
self:F( { eventbirth = EventData } )
|
self:F( { eventbirth = EventData } )
|
||||||
|
|
||||||
|
if not EventData.IniPlayerName then return end
|
||||||
|
|
||||||
local _unitName = EventData.IniUnitName
|
local _unitName = EventData.IniUnitName
|
||||||
local _unit, _playername = self:_GetPlayerUnitAndName( _unitName )
|
local _unit, _playername = self:_GetPlayerUnitAndName( _unitName )
|
||||||
|
|
||||||
|
|||||||
@ -17,9 +17,9 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Authors: **FlightControl**, **applevangelist**
|
-- ### Authors: **applevangelist**, **FlightControl**
|
||||||
--
|
--
|
||||||
-- Last Update: Oct 2023
|
-- Last Update: Dec 2023
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -144,7 +144,7 @@ function SEAD:New( SEADGroupPrefixes, Padding )
|
|||||||
self:AddTransition("*", "ManageEvasion", "*")
|
self:AddTransition("*", "ManageEvasion", "*")
|
||||||
self:AddTransition("*", "CalculateHitZone", "*")
|
self:AddTransition("*", "CalculateHitZone", "*")
|
||||||
|
|
||||||
self:I("*** SEAD - Started Version 0.4.5")
|
self:I("*** SEAD - Started Version 0.4.6")
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -401,7 +401,7 @@ function SEAD:onafterManageEvasion(From,Event,To,_targetskill,_targetgroup,SEADP
|
|||||||
grp:EnableEmission(false)
|
grp:EnableEmission(false)
|
||||||
end
|
end
|
||||||
grp:OptionAlarmStateGreen() -- needed else we cannot move around
|
grp:OptionAlarmStateGreen() -- needed else we cannot move around
|
||||||
grp:RelocateGroundRandomInRadius(20,300,false,false,"Diamond")
|
grp:RelocateGroundRandomInRadius(20,300,false,false,"Diamond",true)
|
||||||
if self.UseCallBack then
|
if self.UseCallBack then
|
||||||
local object = self.CallBack
|
local object = self.CallBack
|
||||||
object:SeadSuppressionStart(grp,name,attacker)
|
object:SeadSuppressionStart(grp,name,attacker)
|
||||||
|
|||||||
590
Moose Development/Moose/Functional/Tiresias.lua
Normal file
590
Moose Development/Moose/Functional/Tiresias.lua
Normal file
@ -0,0 +1,590 @@
|
|||||||
|
--- **Functional** - TIRESIAS - manages AI behaviour.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- The @{#TIRESIAS} class is working in the back to keep your large-scale ground units in check.
|
||||||
|
--
|
||||||
|
-- ## Features:
|
||||||
|
--
|
||||||
|
-- * Designed to keep CPU and Network usage lower on missions with a lot of ground units.
|
||||||
|
-- * Does not affect ships to keep the Navy guys happy.
|
||||||
|
-- * Does not affect OpsGroup type groups.
|
||||||
|
-- * Distinguishes between SAM groups, AAA groups and other ground groups.
|
||||||
|
-- * Exceptions can be defined to keep certain actions going.
|
||||||
|
-- * Works coalition-independent in the back
|
||||||
|
-- * Easy setup.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ## Missions:
|
||||||
|
--
|
||||||
|
-- ### [TIRESIAS](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master)
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author : **applevangelist **
|
||||||
|
--
|
||||||
|
-- @module Functional.Tiresias
|
||||||
|
-- @image Functional.Tiresias.jpg
|
||||||
|
--
|
||||||
|
-- Last Update: Dec 2023
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
--- **TIRESIAS** class, extends Core.Base#BASE
|
||||||
|
-- @type TIRESIAS
|
||||||
|
-- @field #string ClassName
|
||||||
|
-- @field #booelan debug
|
||||||
|
-- @field #string version
|
||||||
|
-- @field #number Interval
|
||||||
|
-- @field Core.Set#SET_GROUP GroundSet
|
||||||
|
-- @field #number Coalition
|
||||||
|
-- @field Core.Set#SET_GROUP VehicleSet
|
||||||
|
-- @field Core.Set#SET_GROUP AAASet
|
||||||
|
-- @field Core.Set#SET_GROUP SAMSet
|
||||||
|
-- @field Core.Set#SET_GROUP ExceptionSet
|
||||||
|
-- @field Core.Set#SET_OPSGROUP OpsGroupSet
|
||||||
|
-- @field #number AAARange
|
||||||
|
-- @field #number HeloSwitchRange
|
||||||
|
-- @field #number PlaneSwitchRange
|
||||||
|
-- @field Core.Set#SET_GROUP FlightSet
|
||||||
|
-- @field #boolean SwitchAAA
|
||||||
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @type TIRESIAS.Data
|
||||||
|
-- @field #string type
|
||||||
|
-- @field #number range
|
||||||
|
-- @field #boolean invisible
|
||||||
|
-- @field #boolean AIOff
|
||||||
|
-- @field #boolean exception
|
||||||
|
|
||||||
|
|
||||||
|
--- *Tiresias, Greek demi-god and shapeshifter, blinded by the Gods, works as oracle for you.* (Wiki)
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ## TIRESIAS Concept
|
||||||
|
--
|
||||||
|
-- * Designed to keep CPU and Network usage lower on missions with a lot of ground units.
|
||||||
|
-- * Does not affect ships to keep the Navy guys happy.
|
||||||
|
-- * Does not affect OpsGroup type groups.
|
||||||
|
-- * Distinguishes between SAM groups, AAA groups and other ground groups.
|
||||||
|
-- * Exceptions can be defined in SET_GROUP objects to keep certain actions going.
|
||||||
|
-- * Works coalition-independent in the back
|
||||||
|
-- * Easy setup.
|
||||||
|
--
|
||||||
|
-- ## Setup
|
||||||
|
--
|
||||||
|
-- Setup is a one-liner:
|
||||||
|
--
|
||||||
|
-- local blinder = TIRESIAS:New()
|
||||||
|
--
|
||||||
|
-- Optionally you can set up exceptions, e.g. for convoys driving around
|
||||||
|
--
|
||||||
|
-- local exceptionset = SET_GROUP:New():FilterCoalitions("red"):FilterPrefixes("Convoy"):FilterStart()
|
||||||
|
-- local blinder = TIRESIAS:New()
|
||||||
|
-- blinder:AddExceptionSet(exceptionset)
|
||||||
|
--
|
||||||
|
-- Options
|
||||||
|
--
|
||||||
|
-- -- Setup different radius for activation around helo and airplane groups (applies to AI and humans)
|
||||||
|
-- blinder:SetActivationRanges(10,25) -- defaults are 10, and 25
|
||||||
|
--
|
||||||
|
-- -- Setup engagement ranges for AAA (non-advanced SAM units like Flaks etc) and if you want them to be AIOff
|
||||||
|
-- blinder:SetAAARanges(60,true) -- defaults are 60, and true
|
||||||
|
--
|
||||||
|
-- @field #TIRESIAS
|
||||||
|
TIRESIAS = {
|
||||||
|
ClassName = "TIRESIAS",
|
||||||
|
debug = false,
|
||||||
|
version = "0.0.4",
|
||||||
|
Interval = 20,
|
||||||
|
GroundSet = nil,
|
||||||
|
VehicleSet = nil,
|
||||||
|
AAASet = nil,
|
||||||
|
SAMSet = nil,
|
||||||
|
ExceptionSet = nil,
|
||||||
|
AAARange = 60, -- 60%
|
||||||
|
HeloSwitchRange = 10, -- NM
|
||||||
|
PlaneSwitchRange = 25, -- NM
|
||||||
|
SwitchAAA = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- [USER] Create a new Tiresias object and start it up.
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @return #TIRESIAS self
|
||||||
|
function TIRESIAS:New()
|
||||||
|
|
||||||
|
-- Inherit everything from FSM class.
|
||||||
|
local self = BASE:Inherit(self, FSM:New()) -- #TIRESIAS
|
||||||
|
|
||||||
|
--- FSM Functions ---
|
||||||
|
|
||||||
|
-- Start State.
|
||||||
|
self:SetStartState("Stopped")
|
||||||
|
|
||||||
|
-- Add FSM transitions.
|
||||||
|
-- From State --> Event --> To State
|
||||||
|
self:AddTransition("Stopped", "Start", "Running") -- Start FSM.
|
||||||
|
self:AddTransition("*", "Status", "*") -- TIRESIAS status update.
|
||||||
|
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
|
||||||
|
|
||||||
|
self.ExceptionSet = SET_GROUP:New():Clear(false)
|
||||||
|
|
||||||
|
self:HandleEvent(EVENTS.PlayerEnterAircraft,self._EventHandler)
|
||||||
|
|
||||||
|
self.lid = string.format("TIRESIAS %s | ",self.version)
|
||||||
|
|
||||||
|
self:I(self.lid.."Managing ground groups!")
|
||||||
|
|
||||||
|
--- Triggers the FSM event "Stop". Stops TIRESIAS and all its event handlers.
|
||||||
|
-- @function [parent=#TIRESIAS] Stop
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
|
||||||
|
--- Triggers the FSM event "Stop" after a delay. Stops TIRESIAS and all its event handlers.
|
||||||
|
-- @function [parent=#TIRESIAS] __Stop
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @param #number delay Delay in seconds.
|
||||||
|
|
||||||
|
--- Triggers the FSM event "Start". Starts TIRESIAS and all its event handlers. Note - `:New()` already starts the instance.
|
||||||
|
-- @function [parent=#TIRESIAS] Start
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
|
||||||
|
--- Triggers the FSM event "Start" after a delay. Starts TIRESIAS and all its event handlers. Note - `:New()` already starts the instance.
|
||||||
|
-- @function [parent=#TIRESIAS] __Start
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @param #number delay Delay in seconds.
|
||||||
|
|
||||||
|
self:__Start(1)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
--
|
||||||
|
-- Helper Functions
|
||||||
|
--
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
---[USER] Set activation radius for Helos and Planes in Nautical Miles.
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @param #number HeloMiles Radius around a Helicopter in which AI ground units will be activated. Defaults to 10NM.
|
||||||
|
-- @param #number PlaneMiles Radius around an Airplane in which AI ground units will be activated. Defaults to 25NM.
|
||||||
|
-- @return #TIRESIAS self
|
||||||
|
function TIRESIAS:SetActivationRanges(HeloMiles,PlaneMiles)
|
||||||
|
self.HeloSwitchRange = HeloMiles or 10
|
||||||
|
self.PlaneSwitchRange = PlaneMiles or 25
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
---[USER] Set AAA Ranges - AAA equals non-SAM systems which qualify as AAA in DCS world.
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @param #number FiringRange The engagement range that AAA units will be set to. Can be 0 to 100 (percent). Defaults to 60.
|
||||||
|
-- @param #boolean SwitchAAA Decide if these system will have their AI switched off, too. Defaults to true.
|
||||||
|
-- @return #TIRESIAS self
|
||||||
|
function TIRESIAS:SetAAARanges(FiringRange,SwitchAAA)
|
||||||
|
self.AAARange = FiringRange or 60
|
||||||
|
self.SwitchAAA = (SwitchAAA == false) and false or true
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [USER] Add a SET_GROUP of GROUP objects as exceptions. Can be done multiple times.
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @param Core.Set#SET_GROUP Set to add to the exception list.
|
||||||
|
-- @return #TIRESIAS self
|
||||||
|
function TIRESIAS:AddExceptionSet(Set)
|
||||||
|
self:T(self.lid.."AddExceptionSet")
|
||||||
|
local exceptions = self.ExceptionSet
|
||||||
|
Set:ForEachGroupAlive(
|
||||||
|
function(grp)
|
||||||
|
if not grp.Tiresias then
|
||||||
|
grp.Tiresias = { -- #TIRESIAS.Data
|
||||||
|
type = "Exception",
|
||||||
|
exception = true,
|
||||||
|
}
|
||||||
|
exceptions:AddGroup(grp,true)
|
||||||
|
end
|
||||||
|
BASE:I("TIRESIAS: Added exception group: "..grp:GetName())
|
||||||
|
end
|
||||||
|
)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [INTERNAL] Filter Function
|
||||||
|
-- @param Wrapper.Group#GROUP Group
|
||||||
|
-- @return #boolean isin
|
||||||
|
function TIRESIAS._FilterNotAAA(Group)
|
||||||
|
local grp = Group -- Wrapper.Group#GROUP
|
||||||
|
local isaaa = grp:IsAAA()
|
||||||
|
if isaaa == true and grp:IsGround() and not grp:IsShip() then
|
||||||
|
return false -- remove from SET
|
||||||
|
else
|
||||||
|
return true -- keep in SET
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [INTERNAL] Filter Function
|
||||||
|
-- @param Wrapper.Group#GROUP Group
|
||||||
|
-- @return #boolean isin
|
||||||
|
function TIRESIAS._FilterNotSAM(Group)
|
||||||
|
local grp = Group -- Wrapper.Group#GROUP
|
||||||
|
local issam = grp:IsSAM()
|
||||||
|
if issam == true and grp:IsGround() and not grp:IsShip() then
|
||||||
|
return false -- remove from SET
|
||||||
|
else
|
||||||
|
return true -- keep in SET
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [INTERNAL] Filter Function
|
||||||
|
-- @param Wrapper.Group#GROUP Group
|
||||||
|
-- @return #boolean isin
|
||||||
|
function TIRESIAS._FilterAAA(Group)
|
||||||
|
local grp = Group -- Wrapper.Group#GROUP
|
||||||
|
local isaaa = grp:IsAAA()
|
||||||
|
if isaaa == true and grp:IsGround() and not grp:IsShip() then
|
||||||
|
return true -- remove from SET
|
||||||
|
else
|
||||||
|
return false -- keep in SET
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [INTERNAL] Filter Function
|
||||||
|
-- @param Wrapper.Group#GROUP Group
|
||||||
|
-- @return #boolean isin
|
||||||
|
function TIRESIAS._FilterSAM(Group)
|
||||||
|
local grp = Group -- Wrapper.Group#GROUP
|
||||||
|
local issam = grp:IsSAM()
|
||||||
|
if issam == true and grp:IsGround() and not grp:IsShip() then
|
||||||
|
return true -- remove from SET
|
||||||
|
else
|
||||||
|
return false -- keep in SET
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [INTERNAL] Init Groups
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @return #TIRESIAS self
|
||||||
|
function TIRESIAS:_InitGroups()
|
||||||
|
self:T(self.lid.."_InitGroups")
|
||||||
|
-- Set all groups invisible/motionless
|
||||||
|
local EngageRange = self.AAARange
|
||||||
|
local SwitchAAA = self.SwitchAAA
|
||||||
|
--- AAA
|
||||||
|
self.AAASet:ForEachGroupAlive(
|
||||||
|
function(grp)
|
||||||
|
if not grp.Tiresias then
|
||||||
|
grp:OptionEngageRange(EngageRange)
|
||||||
|
grp:SetCommandInvisible(true)
|
||||||
|
if SwitchAAA then
|
||||||
|
grp:SetAIOff()
|
||||||
|
grp:EnableEmission(false)
|
||||||
|
end
|
||||||
|
grp.Tiresias = { -- #TIRESIAS.Data
|
||||||
|
type = "AAA",
|
||||||
|
invisible = true,
|
||||||
|
range = EngageRange,
|
||||||
|
exception = false,
|
||||||
|
AIOff = SwitchAAA,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
if grp.Tiresias and (not grp.Tiresias.exception == true) then
|
||||||
|
if grp.Tiresias.invisible and grp.Tiresias.invisible == false then
|
||||||
|
grp:SetCommandInvisible(true)
|
||||||
|
grp.Tiresias.invisible = true
|
||||||
|
if SwitchAAA then
|
||||||
|
grp:SetAIOff()
|
||||||
|
grp:EnableEmission(false)
|
||||||
|
grp.Tiresias.AIOff = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--BASE:I(string.format("Init/Switch off AAA %s (Exception %s)",grp:GetName(),tostring(grp.Tiresias.exception)))
|
||||||
|
end
|
||||||
|
)
|
||||||
|
--- Vehicles
|
||||||
|
self.VehicleSet:ForEachGroupAlive(
|
||||||
|
function(grp)
|
||||||
|
if not grp.Tiresias then
|
||||||
|
grp:SetAIOff()
|
||||||
|
grp:SetCommandInvisible(true)
|
||||||
|
grp.Tiresias = { -- #TIRESIAS.Data
|
||||||
|
type = "Vehicle",
|
||||||
|
invisible = true,
|
||||||
|
AIOff = true,
|
||||||
|
exception = false,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
if grp.Tiresias and (not grp.Tiresias.exception == true) then
|
||||||
|
if grp.Tiresias and grp.Tiresias.invisible and grp.Tiresias.invisible == false then
|
||||||
|
grp:SetCommandInvisible(true)
|
||||||
|
grp:SetAIOff()
|
||||||
|
grp.Tiresias.invisible = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--BASE:I(string.format("Init/Switch off Vehicle %s (Exception %s)",grp:GetName(),tostring(grp.Tiresias.exception)))
|
||||||
|
end
|
||||||
|
)
|
||||||
|
--- SAM
|
||||||
|
self.SAMSet:ForEachGroupAlive(
|
||||||
|
function(grp)
|
||||||
|
if not grp.Tiresias then
|
||||||
|
grp:SetCommandInvisible(true)
|
||||||
|
grp.Tiresias = { -- #TIRESIAS.Data
|
||||||
|
type = "SAM",
|
||||||
|
invisible = true,
|
||||||
|
exception = false,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
if grp.Tiresias and (not grp.Tiresias.exception == true) then
|
||||||
|
if grp.Tiresias and grp.Tiresias.invisible and grp.Tiresias.invisible == false then
|
||||||
|
grp:SetCommandInvisible(true)
|
||||||
|
grp.Tiresias.invisible = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--BASE:I(string.format("Init/Switch off SAM %s (Exception %s)",grp:GetName(),tostring(grp.Tiresias.exception)))
|
||||||
|
end
|
||||||
|
)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [INTERNAL] Event handler function
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
|
-- @return #TIRESIAS self
|
||||||
|
function TIRESIAS:_EventHandler(EventData)
|
||||||
|
self:T(string.format("%s Event = %d",self.lid, EventData.id))
|
||||||
|
local event = EventData -- Core.Event#EVENTDATA
|
||||||
|
if event.id == EVENTS.PlayerEnterAircraft or event.id == EVENTS.PlayerEnterUnit then
|
||||||
|
--local _coalition = event.IniCoalition
|
||||||
|
--if _coalition ~= self.Coalition then
|
||||||
|
-- return --ignore!
|
||||||
|
--end
|
||||||
|
local unitname = event.IniUnitName or "none"
|
||||||
|
local _unit = event.IniUnit
|
||||||
|
local _group = event.IniGroup
|
||||||
|
if _group and _group:IsAlive() then
|
||||||
|
local radius = self.PlaneSwitchRange
|
||||||
|
if _group:IsHelicopter() then
|
||||||
|
radius = self.HeloSwitchRange
|
||||||
|
end
|
||||||
|
self:_SwitchOnGroups(_group,radius)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [INTERNAL] Switch Groups Behaviour
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @param Wrapper.Group#GROUP group
|
||||||
|
-- @param #number radius Radius in NM
|
||||||
|
-- @return #TIRESIAS self
|
||||||
|
function TIRESIAS:_SwitchOnGroups(group,radius)
|
||||||
|
self:T(self.lid.."_SwitchOnGroups "..group:GetName().." Radius "..radius.." NM")
|
||||||
|
local zone = ZONE_GROUP:New("Zone-"..group:GetName(),group,UTILS.NMToMeters(radius))
|
||||||
|
local ground = SET_GROUP:New():FilterCategoryGround():FilterZones({zone}):FilterOnce()
|
||||||
|
local count = ground:CountAlive()
|
||||||
|
if self.debug then
|
||||||
|
local text = string.format("There are %d groups around this plane or helo!",count)
|
||||||
|
self:I(text)
|
||||||
|
end
|
||||||
|
local SwitchAAA = self.SwitchAAA
|
||||||
|
if ground:CountAlive() > 0 then
|
||||||
|
ground:ForEachGroupAlive(
|
||||||
|
function(grp)
|
||||||
|
if grp.Tiresias and grp.Tiresias.type and (not grp.Tiresias.exception == true ) then
|
||||||
|
if grp.Tiresias.invisible == true then
|
||||||
|
grp:SetCommandInvisible(false)
|
||||||
|
grp.Tiresias.invisible = false
|
||||||
|
end
|
||||||
|
if grp.Tiresias.type == "Vehicle" and grp.Tiresias.AIOff and grp.Tiresias.AIOff == true then
|
||||||
|
grp:SetAIOn()
|
||||||
|
grp.Tiresias.AIOff = false
|
||||||
|
end
|
||||||
|
if SwitchAAA and grp.Tiresias.type == "AAA" and grp.Tiresias.AIOff and grp.Tiresias.AIOff == true then
|
||||||
|
grp:SetAIOn()
|
||||||
|
grp:EnableEmission(true)
|
||||||
|
grp.Tiresias.AIOff = false
|
||||||
|
end
|
||||||
|
--BASE:I(string.format("TIRESIAS - Switch on %s %s (Exception %s)",tostring(grp.Tiresias.type),grp:GetName(),tostring(grp.Tiresias.exception)))
|
||||||
|
else
|
||||||
|
BASE:E("TIRESIAS - This group has not been initialized or is an exception!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
--
|
||||||
|
-- FSM Functions
|
||||||
|
--
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- [INTERNAL] FSM Function
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #TIRESIAS self
|
||||||
|
function TIRESIAS:onafterStart(From, Event, To)
|
||||||
|
self:T({From, Event, To})
|
||||||
|
|
||||||
|
local VehicleSet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterNotAAA):FilterFunction(TIRESIAS._FilterNotSAM):FilterStart()
|
||||||
|
local AAASet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterAAA):FilterStart()
|
||||||
|
local SAMSet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterSAM):FilterStart()
|
||||||
|
local OpsGroupSet = SET_OPSGROUP:New():FilterActive(true):FilterStart()
|
||||||
|
self.FlightSet = SET_GROUP:New():FilterCategories({"plane","helicopter"}):FilterStart()
|
||||||
|
|
||||||
|
local EngageRange = self.AAARange
|
||||||
|
|
||||||
|
local ExceptionSet = self.ExceptionSet
|
||||||
|
if self.ExceptionSet then
|
||||||
|
function ExceptionSet:OnAfterAdded(From,Event,To,ObjectName,Object)
|
||||||
|
BASE:I("TIRESIAS: EXCEPTION Object Added: "..Object:GetName())
|
||||||
|
if Object and Object:IsAlive() then
|
||||||
|
Object.Tiresias = { -- #TIRESIAS.Data
|
||||||
|
type = "Exception",
|
||||||
|
exception = true,
|
||||||
|
}
|
||||||
|
Object:SetAIOn()
|
||||||
|
Object:SetCommandInvisible(false)
|
||||||
|
Object:EnableEmission(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local OGS = OpsGroupSet:GetAliveSet()
|
||||||
|
for _,_OG in pairs(OGS or {}) do
|
||||||
|
local OG = _OG -- Ops.OpsGroup#OPSGROUP
|
||||||
|
local grp = OG:GetGroup()
|
||||||
|
ExceptionSet:AddGroup(grp,true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function OpsGroupSet:OnAfterAdded(From,Event,To,ObjectName,Object)
|
||||||
|
local grp = Object:GetGroup()
|
||||||
|
ExceptionSet:AddGroup(grp,true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function VehicleSet:OnAfterAdded(From,Event,To,ObjectName,Object)
|
||||||
|
BASE:I("TIRESIAS: VEHCILE Object Added: "..Object:GetName())
|
||||||
|
if Object and Object:IsAlive() then
|
||||||
|
Object:SetAIOff()
|
||||||
|
Object:SetCommandInvisible(true)
|
||||||
|
Object.Tiresias = { -- #TIRESIAS.Data
|
||||||
|
type = "Vehicle",
|
||||||
|
invisible = true,
|
||||||
|
AIOff = true,
|
||||||
|
exception = false,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local SwitchAAA = self.SwitchAAA
|
||||||
|
|
||||||
|
function AAASet:OnAfterAdded(From,Event,To,ObjectName,Object)
|
||||||
|
if Object and Object:IsAlive() then
|
||||||
|
BASE:I("TIRESIAS: AAA Object Added: "..Object:GetName())
|
||||||
|
Object:OptionEngageRange(EngageRange)
|
||||||
|
Object:SetCommandInvisible(true)
|
||||||
|
if SwitchAAA then
|
||||||
|
Object:SetAIOff()
|
||||||
|
Object:EnableEmission(false)
|
||||||
|
end
|
||||||
|
Object.Tiresias = { -- #TIRESIAS.Data
|
||||||
|
type = "AAA",
|
||||||
|
invisible = true,
|
||||||
|
range = EngageRange,
|
||||||
|
exception = false,
|
||||||
|
AIOff = SwitchAAA,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SAMSet:OnAfterAdded(From,Event,To,ObjectName,Object)
|
||||||
|
if Object and Object:IsAlive() then
|
||||||
|
BASE:I("TIRESIAS: SAM Object Added: "..Object:GetName())
|
||||||
|
Object:SetCommandInvisible(true)
|
||||||
|
Object.Tiresias = { -- #TIRESIAS.Data
|
||||||
|
type = "SAM",
|
||||||
|
invisible = true,
|
||||||
|
exception = false,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.VehicleSet = VehicleSet
|
||||||
|
self.AAASet = AAASet
|
||||||
|
self.SAMSet = SAMSet
|
||||||
|
self.OpsGroupSet = OpsGroupSet
|
||||||
|
|
||||||
|
self:_InitGroups()
|
||||||
|
|
||||||
|
self:__Status(1)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [INTERNAL] FSM Function
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #TIRESIAS self
|
||||||
|
function TIRESIAS:onbeforeStatus(From, Event, To)
|
||||||
|
self:T({From, Event, To})
|
||||||
|
if self:GetState() == "Stopped" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [INTERNAL] FSM Function
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #TIRESIAS self
|
||||||
|
function TIRESIAS:onafterStatus(From, Event, To)
|
||||||
|
self:T({From, Event, To})
|
||||||
|
if self.debug then
|
||||||
|
local count = self.VehicleSet:CountAlive()
|
||||||
|
local AAAcount = self.AAASet:CountAlive()
|
||||||
|
local SAMcount = self.SAMSet:CountAlive()
|
||||||
|
local text = string.format("Overall: %d | Vehicles: %d | AAA: %d | SAM: %d",count+AAAcount+SAMcount,count,AAAcount,SAMcount)
|
||||||
|
self:I(text)
|
||||||
|
end
|
||||||
|
self:_InitGroups()
|
||||||
|
if self.FlightSet:CountAlive() > 0 then
|
||||||
|
local Set = self.FlightSet:GetAliveSet()
|
||||||
|
for _,_plane in pairs(Set) do
|
||||||
|
local plane = _plane -- Wrapper.Group#GROUP
|
||||||
|
local radius = self.PlaneSwitchRange
|
||||||
|
if plane:IsHelicopter() then
|
||||||
|
radius = self.HeloSwitchRange
|
||||||
|
end
|
||||||
|
self:_SwitchOnGroups(_plane,radius)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if self:GetState() ~= "Stopped" then
|
||||||
|
self:__Status(self.Interval)
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [INTERNAL] FSM Function
|
||||||
|
-- @param #TIRESIAS self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #TIRESIAS self
|
||||||
|
function TIRESIAS:onafterStop(From, Event, To)
|
||||||
|
self:T({From, Event, To})
|
||||||
|
self:UnHandleEvent(EVENTS.PlayerEnterAircraft)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
--
|
||||||
|
-- End
|
||||||
|
--
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
@ -83,6 +83,7 @@ __Moose.Include( 'Scripts/Moose/Functional/ZoneCaptureCoalition.lua' )
|
|||||||
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoal.lua' )
|
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoal.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoalCargo.lua' )
|
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoalCargo.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoalCoalition.lua' )
|
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoalCoalition.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/Tiresias.lua' )
|
||||||
|
|
||||||
__Moose.Include( 'Scripts/Moose/Ops/Airboss.lua' )
|
__Moose.Include( 'Scripts/Moose/Ops/Airboss.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/Ops/AirWing.lua' )
|
__Moose.Include( 'Scripts/Moose/Ops/AirWing.lua' )
|
||||||
|
|||||||
@ -890,7 +890,7 @@ _ATIS = {}
|
|||||||
|
|
||||||
--- ATIS class version.
|
--- ATIS class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
ATIS.version = "0.10.4"
|
ATIS.version = "1.0.0"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@ -1528,12 +1528,12 @@ end
|
|||||||
|
|
||||||
--- Use SRS Simple-Text-To-Speech for transmissions. No sound files necessary.
|
--- Use SRS Simple-Text-To-Speech for transmissions. No sound files necessary.
|
||||||
-- @param #ATIS self
|
-- @param #ATIS self
|
||||||
-- @param #string PathToSRS Path to SRS directory.
|
-- @param #string PathToSRS Path to SRS directory (only necessary if SRS exe backend is used).
|
||||||
-- @param #string Gender Gender: "male" or "female" (default).
|
-- @param #string Gender Gender: "male" or "female" (default).
|
||||||
-- @param #string Culture Culture, e.g. "en-GB" (default).
|
-- @param #string Culture Culture, e.g. "en-GB" (default).
|
||||||
-- @param #string Voice Specific voice. Overrides `Gender` and `Culture`.
|
-- @param #string Voice Specific voice. Overrides `Gender` and `Culture`.
|
||||||
-- @param #number Port SRS port. Default 5002.
|
-- @param #number Port SRS port. Default 5002.
|
||||||
-- @param #string GoogleKey Path to Google JSON-Key.
|
-- @param #string GoogleKey Path to Google JSON-Key (SRS exe backend) or Google API key (DCS-gRPC backend).
|
||||||
-- @return #ATIS self
|
-- @return #ATIS self
|
||||||
function ATIS:SetSRS(PathToSRS, Gender, Culture, Voice, Port, GoogleKey)
|
function ATIS:SetSRS(PathToSRS, Gender, Culture, Voice, Port, GoogleKey)
|
||||||
if PathToSRS or MSRS.path then
|
if PathToSRS or MSRS.path then
|
||||||
|
|||||||
@ -8212,7 +8212,7 @@ function AIRBOSS:OnEventBirth( EventData )
|
|||||||
self:E( EventData )
|
self:E( EventData )
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if EventData.IniUnit == nil then
|
if EventData.IniUnit == nil and (not EventData.IniObjectCategory == Object.Category.STATIC) then
|
||||||
self:E( self.lid .. "ERROR: EventData.IniUnit=nil in event BIRTH!" )
|
self:E( self.lid .. "ERROR: EventData.IniUnit=nil in event BIRTH!" )
|
||||||
self:E( EventData )
|
self:E( EventData )
|
||||||
return
|
return
|
||||||
@ -11197,7 +11197,7 @@ function AIRBOSS:_AttitudeMonitor( playerData )
|
|||||||
end
|
end
|
||||||
text = text .. string.format( "\nPitch=%.1f° | Roll=%.1f° | Yaw=%.1f°", pitch, roll, yaw )
|
text = text .. string.format( "\nPitch=%.1f° | Roll=%.1f° | Yaw=%.1f°", pitch, roll, yaw )
|
||||||
text = text .. string.format( "\nClimb Angle=%.1f° | Rate=%d ft/min", unit:GetClimbAngle(), velo.y * 196.85 )
|
text = text .. string.format( "\nClimb Angle=%.1f° | Rate=%d ft/min", unit:GetClimbAngle(), velo.y * 196.85 )
|
||||||
local dist = self:_GetOptLandingCoordinate():Get3DDistance( playerData.unit )
|
local dist = self:_GetOptLandingCoordinate():Get3DDistance( playerData.unit:GetVec3() )
|
||||||
-- Get player velocity in km/h.
|
-- Get player velocity in km/h.
|
||||||
local vplayer = playerData.unit:GetVelocityKMH()
|
local vplayer = playerData.unit:GetVelocityKMH()
|
||||||
-- Get carrier velocity in km/h.
|
-- Get carrier velocity in km/h.
|
||||||
@ -14957,7 +14957,7 @@ function AIRBOSS:SetSRSPilotVoice( Voice, Gender, Culture )
|
|||||||
self.PilotRadio.gender = Gender or "male"
|
self.PilotRadio.gender = Gender or "male"
|
||||||
self.PilotRadio.culture = Culture or "en-US"
|
self.PilotRadio.culture = Culture or "en-US"
|
||||||
|
|
||||||
if (not Voice) and self.SRS and self.SRS.google then
|
if (not Voice) and self.SRS and self.SRS:GetProvider() == MSRS.Provider.GOOGLE then
|
||||||
self.PilotRadio.voice = MSRS.Voices.Google.Standard.en_US_Standard_J
|
self.PilotRadio.voice = MSRS.Voices.Google.Standard.en_US_Standard_J
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1861,6 +1861,7 @@ function ARMYGROUP:_UpdateEngageTarget()
|
|||||||
else
|
else
|
||||||
|
|
||||||
-- Could not get position of target (not alive any more?) ==> Disengage.
|
-- Could not get position of target (not alive any more?) ==> Disengage.
|
||||||
|
self:T(self.lid.."Could not get position of target ==> Disengage!")
|
||||||
self:Disengage()
|
self:Disengage()
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -1868,6 +1869,7 @@ function ARMYGROUP:_UpdateEngageTarget()
|
|||||||
else
|
else
|
||||||
|
|
||||||
-- Target not alive any more ==> Disengage.
|
-- Target not alive any more ==> Disengage.
|
||||||
|
self:T(self.lid.."Target not ALIVE ==> Disengage!")
|
||||||
self:Disengage()
|
self:Disengage()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
-- @image OPS_CSAR.jpg
|
-- @image OPS_CSAR.jpg
|
||||||
|
|
||||||
-- Date: May 2023
|
-- Date: May 2023
|
||||||
-- Last: Update Oct 2024
|
-- Last: Update Dec 2024
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
|
||||||
|
|||||||
@ -1228,7 +1228,7 @@ CTLD.UnitTypeCapabilities = {
|
|||||||
|
|
||||||
--- CTLD class version.
|
--- CTLD class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CTLD.version="1.0.44"
|
CTLD.version="1.0.45"
|
||||||
|
|
||||||
--- Instantiate a new CTLD.
|
--- Instantiate a new CTLD.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
@ -1443,6 +1443,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
|||||||
-- @param #number delay Delay in seconds.
|
-- @param #number delay Delay in seconds.
|
||||||
|
|
||||||
--- Triggers the FSM event "Stop". Stops the CTLD and all its event handlers.
|
--- Triggers the FSM event "Stop". Stops the CTLD and all its event handlers.
|
||||||
|
-- @function [parent=#CTLD] Stop
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
|
|
||||||
--- Triggers the FSM event "Stop" after a delay. Stops the CTLD and all its event handlers.
|
--- Triggers the FSM event "Stop" after a delay. Stops the CTLD and all its event handlers.
|
||||||
@ -2454,11 +2455,13 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack)
|
|||||||
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,true,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],true,cargotype.PerCrateMass,nil,subcat)
|
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,true,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],true,cargotype.PerCrateMass,nil,subcat)
|
||||||
table.insert(droppedcargo,realcargo)
|
table.insert(droppedcargo,realcargo)
|
||||||
else
|
else
|
||||||
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,false,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],false,cargotype.PerCrateMass,nil,subcat)
|
realcargo = CTLD_CARGO:New(self.CargoCounter,cratename,templ,sorte,false,false,cratesneeded,self.Spawned_Crates[self.CrateCounter],false,cargotype.PerCrateMass,nil,subcat)
|
||||||
Cargo:RemoveStock()
|
|
||||||
end
|
end
|
||||||
table.insert(self.Spawned_Cargo, realcargo)
|
table.insert(self.Spawned_Cargo, realcargo)
|
||||||
end
|
end
|
||||||
|
if not (drop or pack) then
|
||||||
|
Cargo:RemoveStock()
|
||||||
|
end
|
||||||
local text = string.format("Crates for %s have been positioned near you!",cratename)
|
local text = string.format("Crates for %s have been positioned near you!",cratename)
|
||||||
if drop then
|
if drop then
|
||||||
text = string.format("Crates for %s have been dropped!",cratename)
|
text = string.format("Crates for %s have been dropped!",cratename)
|
||||||
@ -3824,7 +3827,7 @@ end
|
|||||||
-- @param #CTLD_CARGO.Enum Type Type of cargo. I.e. VEHICLE or FOB. VEHICLE will move to destination zones when dropped/build, FOB stays put.
|
-- @param #CTLD_CARGO.Enum Type Type of cargo. I.e. VEHICLE or FOB. VEHICLE will move to destination zones when dropped/build, FOB stays put.
|
||||||
-- @param #number NoCrates Number of crates needed to build this cargo.
|
-- @param #number NoCrates Number of crates needed to build this cargo.
|
||||||
-- @param #number PerCrateMass Mass in kg of each crate
|
-- @param #number PerCrateMass Mass in kg of each crate
|
||||||
-- @param #number Stock Number of groups in stock. Nil for unlimited.
|
-- @param #number Stock Number of buildable groups in stock. Nil for unlimited.
|
||||||
-- @param #string SubCategory Name of sub-category (optional).
|
-- @param #string SubCategory Name of sub-category (optional).
|
||||||
function CTLD:AddCratesCargo(Name,Templates,Type,NoCrates,PerCrateMass,Stock,SubCategory)
|
function CTLD:AddCratesCargo(Name,Templates,Type,NoCrates,PerCrateMass,Stock,SubCategory)
|
||||||
self:T(self.lid .. " AddCratesCargo")
|
self:T(self.lid .. " AddCratesCargo")
|
||||||
|
|||||||
@ -141,14 +141,14 @@
|
|||||||
-- -- **Note** If you need different tanker types, i.e. Boom and Drogue, set them up at different AirWings!
|
-- -- **Note** If you need different tanker types, i.e. Boom and Drogue, set them up at different AirWings!
|
||||||
-- -- Add a tanker point
|
-- -- Add a tanker point
|
||||||
-- mywing:AddPatrolPointTanker(AIRBASE.Caucasus.Kutaisi,ZONE:FindByName("Blue Zone Tanker"):GetCoordinate(),20000,280,270,50)
|
-- mywing:AddPatrolPointTanker(AIRBASE.Caucasus.Kutaisi,ZONE:FindByName("Blue Zone Tanker"):GetCoordinate(),20000,280,270,50)
|
||||||
-- -- Add an AWACS squad - Radio 251 AM, TACAN 51Y
|
-- -- Add a tanker squad - Radio 251 AM, TACAN 51Y
|
||||||
-- mywing:AddTankerSquadron("Blue Tanker","Tanker Ops Kutaisi",AIRBASE.Caucasus.Kutaisi,20,AI.Skill.EXCELLENT,602,nil,251,radio.modulation.AM,51)
|
-- mywing:AddTankerSquadron("Blue Tanker","Tanker Ops Kutaisi",AIRBASE.Caucasus.Kutaisi,20,AI.Skill.EXCELLENT,602,nil,251,radio.modulation.AM,51)
|
||||||
--
|
--
|
||||||
-- ### Add an AWACS (optional)
|
-- ### Add an AWACS (optional)
|
||||||
--
|
--
|
||||||
-- -- Add an AWACS point
|
-- -- Add an AWACS point
|
||||||
-- mywing:AddPatrolPointAwacs(AIRBASE.Caucasus.Kutaisi,ZONE:FindByName("Blue Zone AWACS"):GetCoordinate(),25000,300,270,50)
|
-- mywing:AddPatrolPointAwacs(AIRBASE.Caucasus.Kutaisi,ZONE:FindByName("Blue Zone AWACS"):GetCoordinate(),25000,300,270,50)
|
||||||
-- -- Add a tanker squad - Radio 251 AM, TACAN 51Y
|
-- -- Add an AWACS squad - Radio 251 AM, TACAN 51Y
|
||||||
-- mywing:AddAWACSSquadron("Blue AWACS","AWACS Ops Kutaisi",AIRBASE.Caucasus.Kutaisi,20,AI.Skill.AVERAGE,702,nil,271,radio.modulation.AM)
|
-- mywing:AddAWACSSquadron("Blue AWACS","AWACS Ops Kutaisi",AIRBASE.Caucasus.Kutaisi,20,AI.Skill.AVERAGE,702,nil,271,radio.modulation.AM)
|
||||||
--
|
--
|
||||||
-- # Fine-Tuning
|
-- # Fine-Tuning
|
||||||
|
|||||||
@ -4424,14 +4424,11 @@ end
|
|||||||
-- Misc Functions
|
-- Misc Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Add parking guard in front of a parking aircraft.
|
--- [INTERNAL] Add parking guard in front of a parking aircraft - delayed for MP.
|
||||||
-- @param #FLIGHTCONTROL self
|
-- @param #FLIGHTCONTROL self
|
||||||
-- @param Wrapper.Unit#UNIT unit The aircraft.
|
-- @param Wrapper.Unit#UNIT unit The aircraft.
|
||||||
function FLIGHTCONTROL:SpawnParkingGuard(unit)
|
function FLIGHTCONTROL:_SpawnParkingGuard(unit)
|
||||||
|
-- Position of the unit.
|
||||||
if unit and self.parkingGuard then
|
|
||||||
|
|
||||||
-- Position of the unit.
|
|
||||||
local coordinate=unit:GetCoordinate()
|
local coordinate=unit:GetCoordinate()
|
||||||
|
|
||||||
-- Parking spot.
|
-- Parking spot.
|
||||||
@ -4478,6 +4475,17 @@ function FLIGHTCONTROL:SpawnParkingGuard(unit)
|
|||||||
else
|
else
|
||||||
self:E(self.lid.."ERROR: Parking Guard already exists!")
|
self:E(self.lid.."ERROR: Parking Guard already exists!")
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add parking guard in front of a parking aircraft.
|
||||||
|
-- @param #FLIGHTCONTROL self
|
||||||
|
-- @param Wrapper.Unit#UNIT unit The aircraft.
|
||||||
|
function FLIGHTCONTROL:SpawnParkingGuard(unit)
|
||||||
|
|
||||||
|
if unit and self.parkingGuard then
|
||||||
|
|
||||||
|
-- Schedule delay so in MP we get the heading of the client's plane
|
||||||
|
self:ScheduleOnce(1,FLIGHTCONTROL._SpawnParkingGuard,self,unit)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -526,11 +526,11 @@ function TARGET:IsAlive()
|
|||||||
|
|
||||||
for _,_target in pairs(self.targets) do
|
for _,_target in pairs(self.targets) do
|
||||||
local target=_target --Ops.Target#TARGET.Object
|
local target=_target --Ops.Target#TARGET.Object
|
||||||
if target.Status==TARGET.ObjectStatus.ALIVE then
|
if target.Status~=TARGET.ObjectStatus.DEAD then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -160,52 +160,63 @@ do -- Sound File
|
|||||||
-- @param #string FileName The name of the sound file, e.g. "Hello World.ogg".
|
-- @param #string FileName The name of the sound file, e.g. "Hello World.ogg".
|
||||||
-- @param #string Path The path of the directory, where the sound file is located. Default is "l10n/DEFAULT/" within the miz file.
|
-- @param #string Path The path of the directory, where the sound file is located. Default is "l10n/DEFAULT/" within the miz file.
|
||||||
-- @param #number Duration Duration in seconds, how long it takes to play the sound file. Default is 3 seconds.
|
-- @param #number Duration Duration in seconds, how long it takes to play the sound file. Default is 3 seconds.
|
||||||
|
-- @param #bolean UseSrs Set if SRS should be used to play this file. Default is false.
|
||||||
-- @return #SOUNDFILE self
|
-- @return #SOUNDFILE self
|
||||||
function SOUNDFILE:New(FileName, Path, Duration)
|
function SOUNDFILE:New(FileName, Path, Duration, UseSrs)
|
||||||
|
|
||||||
-- Inherit BASE.
|
-- Inherit BASE.
|
||||||
local self=BASE:Inherit(self, BASE:New()) -- #SOUNDFILE
|
local self=BASE:Inherit(self, BASE:New()) -- #SOUNDFILE
|
||||||
|
|
||||||
|
-- Debug info:
|
||||||
|
self:F( {FileName, Path, Duration, UseSrs} )
|
||||||
|
|
||||||
-- Set file name.
|
-- Set file name.
|
||||||
self:SetFileName(FileName)
|
self:SetFileName(FileName)
|
||||||
|
|
||||||
|
-- Set if SRS should be used to play this file
|
||||||
|
self:SetPlayWithSRS(UseSrs or false)
|
||||||
|
|
||||||
-- Set path.
|
-- Set path.
|
||||||
self:SetPath(Path)
|
self:SetPath(Path)
|
||||||
|
|
||||||
-- Set duration.
|
-- Set duration.
|
||||||
self:SetDuration(Duration)
|
self:SetDuration(Duration)
|
||||||
|
|
||||||
-- Debug info:
|
|
||||||
self:T(string.format("New SOUNDFILE: file name=%s, path=%s", self.filename, self.path))
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set path, where the sound file is located.
|
--- Set path, where the sound file is located.
|
||||||
-- @param #SOUNDFILE self
|
-- @param #SOUNDFILE self
|
||||||
-- @param #string Path Path to the directory, where the sound file is located. In case this is nil, it defaults to the DCS mission temp directory.
|
-- @param #string Path Path to the directory, where the sound file is located. In case this is nil, it defaults to the DCS mission temp directory.
|
||||||
-- @return #SOUNDFILE self
|
-- @return #SOUNDFILE self
|
||||||
function SOUNDFILE:SetPath(Path)
|
function SOUNDFILE:SetPath(Path)
|
||||||
|
self:F( {Path} )
|
||||||
|
|
||||||
-- Init path.
|
-- Init path.
|
||||||
self.path=Path or "l10n/DEFAULT/"
|
if not Path then
|
||||||
|
if self.useSRS then -- use path to mission temp dir
|
||||||
if not Path and self.useSRS then -- use path to mission temp dir
|
self.path = lfs.tempdir() .. "Mission\\l10n\\DEFAULT"
|
||||||
self.path = os.getenv('TMP') .. "\\DCS\\Mission\\l10n\\DEFAULT"
|
else -- use internal path in miz file
|
||||||
end
|
self.path="l10n/DEFAULT/"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.path = Path
|
||||||
|
end
|
||||||
|
|
||||||
-- Remove (back)slashes.
|
-- Remove (back)slashes.
|
||||||
local nmax=1000 ; local n=1
|
local nmax=1000 ; local n=1
|
||||||
while (self.path:sub(-1)=="/" or self.path:sub(-1)==[[\]]) and n<=nmax do
|
while (self.path:sub(-1)=="/" or self.path:sub(-1)==[[\]]) and n<=nmax do
|
||||||
self.path=self.path:sub(1,#self.path-1)
|
self.path=self.path:sub(1,#self.path-1)
|
||||||
n=n+1
|
n=n+1
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Append slash.
|
-- Append slash.
|
||||||
self.path=self.path.."/"
|
self.path=self.path.."/"
|
||||||
|
|
||||||
|
self:T("self.path=".. self.path)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get path of the directory, where the sound file is located.
|
--- Get path of the directory, where the sound file is located.
|
||||||
-- @param #SOUNDFILE self
|
-- @param #SOUNDFILE self
|
||||||
@ -228,7 +239,7 @@ do -- Sound File
|
|||||||
--- Get the sound file name.
|
--- Get the sound file name.
|
||||||
-- @param #SOUNDFILE self
|
-- @param #SOUNDFILE self
|
||||||
-- @return #string Name of the soud file. This does *not* include its path.
|
-- @return #string Name of the soud file. This does *not* include its path.
|
||||||
function SOUNDFILE:GetFileName()
|
function SOUNDFILE:GetFileName()
|
||||||
return self.filename
|
return self.filename
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -264,14 +275,16 @@ do -- Sound File
|
|||||||
-- @param #boolean Switch If true or nil, use SRS. If false, use DCS transmission.
|
-- @param #boolean Switch If true or nil, use SRS. If false, use DCS transmission.
|
||||||
-- @return #SOUNDFILE self
|
-- @return #SOUNDFILE self
|
||||||
function SOUNDFILE:SetPlayWithSRS(Switch)
|
function SOUNDFILE:SetPlayWithSRS(Switch)
|
||||||
|
self:F( {Switch} )
|
||||||
if Switch==true or Switch==nil then
|
if Switch==true or Switch==nil then
|
||||||
self.useSRS=true
|
self.useSRS=true
|
||||||
else
|
else
|
||||||
self.useSRS=false
|
self.useSRS=false
|
||||||
end
|
end
|
||||||
|
self:T("self.useSRS=".. tostring(self.useSRS))
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- Text-To-Speech
|
do -- Text-To-Speech
|
||||||
|
|||||||
@ -523,6 +523,7 @@ ENUMS.ReportingName =
|
|||||||
Hawkeye = "E-2D",
|
Hawkeye = "E-2D",
|
||||||
Sentry = "E-3A",
|
Sentry = "E-3A",
|
||||||
Stratotanker = "KC-135",
|
Stratotanker = "KC-135",
|
||||||
|
Gasstation = "KC-135MPRS",
|
||||||
Extender = "KC-10",
|
Extender = "KC-10",
|
||||||
Orion = "P-3C",
|
Orion = "P-3C",
|
||||||
Viking = "S-3B",
|
Viking = "S-3B",
|
||||||
|
|||||||
@ -1064,9 +1064,9 @@ function UTILS.BeaufortScale(speed)
|
|||||||
return bn,bd
|
return bn,bd
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Split string at seperators. C.f. [split-string-in-lua](http://stackoverflow.com/questions/1426954/split-string-in-lua).
|
--- Split string at separators. C.f. [split-string-in-lua](http://stackoverflow.com/questions/1426954/split-string-in-lua).
|
||||||
-- @param #string str Sting to split.
|
-- @param #string str Sting to split.
|
||||||
-- @param #string sep Speparator for split.
|
-- @param #string sep Separator for split.
|
||||||
-- @return #table Split text.
|
-- @return #table Split text.
|
||||||
function UTILS.Split(str, sep)
|
function UTILS.Split(str, sep)
|
||||||
local result = {}
|
local result = {}
|
||||||
@ -2146,17 +2146,17 @@ function UTILS.IsLoadingDoorOpen( unit_name )
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
if string.find(type_name, "Bell-47") then -- bell aint got no doors so always ready to load injured soldiers
|
if type_name == "Bell-47" then -- bell aint got no doors so always ready to load injured soldiers
|
||||||
BASE:T(unit_name .. " door is open")
|
BASE:T(unit_name .. " door is open")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
if string.find(type_name, "UH-60L") and (unit:getDrawArgumentValue(401) == 1 or unit:getDrawArgumentValue(402) == 1) then
|
if type_name == "UH-60L" and (unit:getDrawArgumentValue(401) == 1 or unit:getDrawArgumentValue(402) == 1) then
|
||||||
BASE:T(unit_name .. " cargo door is open")
|
BASE:T(unit_name .. " cargo door is open")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
if string.find(type_name, "UH-60L" ) and (unit:getDrawArgumentValue(38) == 1 or unit:getDrawArgumentValue(400) == 1 ) then
|
if type_name == "UH-60L" and (unit:getDrawArgumentValue(38) > 0 or unit:getDrawArgumentValue(400) == 1 ) then
|
||||||
BASE:T(unit_name .. " front door(s) are open")
|
BASE:T(unit_name .. " front door(s) are open")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|||||||
@ -2937,7 +2937,7 @@ function CONTROLLABLE:CopyRoute( Begin, End, Randomize, Radius )
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Return the detected targets of the controllable.
|
--- Return the detected targets of the controllable.
|
||||||
-- The optional parametes specify the detection methods that can be applied.
|
-- The optional parameters specify the detection methods that can be applied.
|
||||||
-- If no detection method is given, the detection will use all the available methods by default.
|
-- If no detection method is given, the detection will use all the available methods by default.
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @param #boolean DetectVisual (optional)
|
-- @param #boolean DetectVisual (optional)
|
||||||
@ -3772,54 +3772,66 @@ function CONTROLLABLE:OptionProhibitAfterburner( Prohibit )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Defines the usage of Electronic Counter Measures by airborne forces. Disables the ability for AI to use their ECM.
|
--- [Air] Defines the usage of Electronic Counter Measures by airborne forces.
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @param #number ECMvalue Can be - 0=Never on, 1=if locked by radar, 2=if detected by radar, 3=always on, defaults to 1
|
||||||
-- @return #CONTROLLABLE self
|
-- @return #CONTROLLABLE self
|
||||||
function CONTROLLABLE:OptionECM_Never()
|
function CONTROLLABLE:OptionECM( ECMvalue )
|
||||||
self:F2( { self.ControllableName } )
|
self:F2( { self.ControllableName } )
|
||||||
|
|
||||||
if self:IsAir() then
|
local DCSControllable = self:GetDCSObject()
|
||||||
self:SetOption( AI.Option.Air.id.ECM_USING, 0 )
|
if DCSControllable then
|
||||||
|
local Controller = self:_GetController()
|
||||||
|
|
||||||
|
if self:IsAir() then
|
||||||
|
Controller:setOption( AI.Option.Air.id.ECM_USING, ECMvalue or 1 )
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Defines the usage of Electronic Counter Measures by airborne forces. If the AI is actively being locked by an enemy radar they will enable their ECM jammer.
|
--- [Air] Defines the usage of Electronic Counter Measures by airborne forces. Disables the ability for AI to use their ECM.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:OptionECM_Never()
|
||||||
|
self:F2( { self.ControllableName } )
|
||||||
|
|
||||||
|
self:OptionECM(0)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [Air] Defines the usage of Electronic Counter Measures by airborne forces. If the AI is actively being locked by an enemy radar they will enable their ECM jammer.
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @return #CONTROLLABLE self
|
-- @return #CONTROLLABLE self
|
||||||
function CONTROLLABLE:OptionECM_OnlyLockByRadar()
|
function CONTROLLABLE:OptionECM_OnlyLockByRadar()
|
||||||
self:F2( { self.ControllableName } )
|
self:F2( { self.ControllableName } )
|
||||||
|
|
||||||
if self:IsAir() then
|
self:OptionECM(1)
|
||||||
self:SetOption( AI.Option.Air.id.ECM_USING, 1 )
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Defines the usage of Electronic Counter Measures by airborne forces. If the AI is being detected by a radar they will enable their ECM.
|
--- [Air] Defines the usage of Electronic Counter Measures by airborne forces. If the AI is being detected by a radar they will enable their ECM.
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @return #CONTROLLABLE self
|
-- @return #CONTROLLABLE self
|
||||||
function CONTROLLABLE:OptionECM_DetectedLockByRadar()
|
function CONTROLLABLE:OptionECM_DetectedLockByRadar()
|
||||||
self:F2( { self.ControllableName } )
|
self:F2( { self.ControllableName } )
|
||||||
|
|
||||||
if self:IsAir() then
|
self:OptionECM(2)
|
||||||
self:SetOption( AI.Option.Air.id.ECM_USING, 2 )
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Defines the usage of Electronic Counter Measures by airborne forces. AI will leave their ECM on all the time.
|
--- [Air] Defines the usage of Electronic Counter Measures by airborne forces. AI will leave their ECM on all the time.
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @return #CONTROLLABLE self
|
-- @return #CONTROLLABLE self
|
||||||
function CONTROLLABLE:OptionECM_AlwaysOn()
|
function CONTROLLABLE:OptionECM_AlwaysOn()
|
||||||
self:F2( { self.ControllableName } )
|
self:F2( { self.ControllableName } )
|
||||||
|
|
||||||
if self:IsAir() then
|
self:OptionECM(3)
|
||||||
self:SetOption( AI.Option.Air.id.ECM_USING, 3 )
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -4013,14 +4025,22 @@ end
|
|||||||
-- @param #boolean onroad If true, route on road (less problems with AI way finding), default true
|
-- @param #boolean onroad If true, route on road (less problems with AI way finding), default true
|
||||||
-- @param #boolean shortcut If true and onroad is set, take a shorter route - if available - off road, default false
|
-- @param #boolean shortcut If true and onroad is set, take a shorter route - if available - off road, default false
|
||||||
-- @param #string formation Formation string as in the mission editor, e.g. "Vee", "Diamond", "Line abreast", etc. Defaults to "Off Road"
|
-- @param #string formation Formation string as in the mission editor, e.g. "Vee", "Diamond", "Line abreast", etc. Defaults to "Off Road"
|
||||||
|
-- @param #boolean onland (optional) If true, try up to 50 times to get a coordinate on land.SurfaceType.LAND. Note - this descriptor value is not reliably implemented on all maps.
|
||||||
-- @return #CONTROLLABLE self
|
-- @return #CONTROLLABLE self
|
||||||
function CONTROLLABLE:RelocateGroundRandomInRadius( speed, radius, onroad, shortcut, formation )
|
function CONTROLLABLE:RelocateGroundRandomInRadius( speed, radius, onroad, shortcut, formation, onland )
|
||||||
self:F2( { self.ControllableName } )
|
self:F2( { self.ControllableName } )
|
||||||
|
|
||||||
local _coord = self:GetCoordinate()
|
local _coord = self:GetCoordinate()
|
||||||
local _radius = radius or 500
|
local _radius = radius or 500
|
||||||
local _speed = speed or 20
|
local _speed = speed or 20
|
||||||
local _tocoord = _coord:GetRandomCoordinateInRadius( _radius, 100 )
|
local _tocoord = _coord:GetRandomCoordinateInRadius( _radius, 100 )
|
||||||
|
if onland then
|
||||||
|
for i=1,50 do
|
||||||
|
local island = _tocoord:GetSurfaceType() == land.SurfaceType.LAND and true or false
|
||||||
|
if island then break end
|
||||||
|
_tocoord = _coord:GetRandomCoordinateInRadius( _radius, 100 )
|
||||||
|
end
|
||||||
|
end
|
||||||
local _onroad = onroad or true
|
local _onroad = onroad or true
|
||||||
local _grptsk = {}
|
local _grptsk = {}
|
||||||
local _candoroad = false
|
local _candoroad = false
|
||||||
|
|||||||
@ -302,7 +302,7 @@ end
|
|||||||
|
|
||||||
--- Find the first(!) GROUP matching using patterns. Note that this is **a lot** slower than `:FindByName()`!
|
--- Find the first(!) GROUP matching using patterns. Note that this is **a lot** slower than `:FindByName()`!
|
||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @param #string Pattern The pattern to look for. Refer to [LUA patterns](http://www.easyuo.com/openeuo/wiki/index.php/Lua_Patterns_and_Captures_(Regular_Expressions)) for regular expressions in LUA.
|
-- @param #string Pattern The pattern to look for. Refer to [LUA patterns](http://www.easyuo.com/openeuo/wiki/index.php/Lua_Patterns_and_Captures_\(Regular_Expressions\)) for regular expressions in LUA.
|
||||||
-- @return #GROUP The GROUP.
|
-- @return #GROUP The GROUP.
|
||||||
-- @usage
|
-- @usage
|
||||||
-- -- Find a group with a partial group name
|
-- -- Find a group with a partial group name
|
||||||
@ -327,7 +327,7 @@ end
|
|||||||
|
|
||||||
--- Find all GROUP objects matching using patterns. Note that this is **a lot** slower than `:FindByName()`!
|
--- Find all GROUP objects matching using patterns. Note that this is **a lot** slower than `:FindByName()`!
|
||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @param #string Pattern The pattern to look for. Refer to [LUA patterns](http://www.easyuo.com/openeuo/wiki/index.php/Lua_Patterns_and_Captures_(Regular_Expressions)) for regular expressions in LUA.
|
-- @param #string Pattern The pattern to look for. Refer to [LUA patterns](http://www.easyuo.com/openeuo/wiki/index.php/Lua_Patterns_and_Captures_\(Regular_Expressions\)) for regular expressions in LUA.
|
||||||
-- @return #table Groups Table of matching #GROUP objects found
|
-- @return #table Groups Table of matching #GROUP objects found
|
||||||
-- @usage
|
-- @usage
|
||||||
-- -- Find all group with a partial group name
|
-- -- Find all group with a partial group name
|
||||||
@ -2765,7 +2765,7 @@ end
|
|||||||
|
|
||||||
--- Switch on/off invisible flag for the group.
|
--- Switch on/off invisible flag for the group.
|
||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @param #boolean switch If true, emission is enabled. If false, emission is disabled.
|
-- @param #boolean switch If true, Invisible is enabled. If false, Invisible is disabled.
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:SetCommandInvisible(switch)
|
function GROUP:SetCommandInvisible(switch)
|
||||||
self:F2( self.GroupName )
|
self:F2( self.GroupName )
|
||||||
@ -2779,7 +2779,7 @@ end
|
|||||||
|
|
||||||
--- Switch on/off immortal flag for the group.
|
--- Switch on/off immortal flag for the group.
|
||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @param #boolean switch If true, emission is enabled. If false, emission is disabled.
|
-- @param #boolean switch If true, Immortal is enabled. If false, Immortal is disabled.
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:SetCommandImmortal(switch)
|
function GROUP:SetCommandImmortal(switch)
|
||||||
self:F2( self.GroupName )
|
self:F2( self.GroupName )
|
||||||
@ -2985,3 +2985,36 @@ function GROUP:GetGroupSTN()
|
|||||||
return tSTN,text
|
return tSTN,text
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [GROUND] Determine if a GROUP is a SAM unit, i.e. has radar or optical tracker and is no mobile AAA.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @return #boolean IsSAM True if SAM, else false
|
||||||
|
function GROUP:IsSAM()
|
||||||
|
local issam = false
|
||||||
|
local units = self:GetUnits()
|
||||||
|
for _,_unit in pairs(units or {}) do
|
||||||
|
local unit = _unit -- Wrapper.Unit#UNIT
|
||||||
|
if unit:HasSEAD() and unit:IsGround() and (not unit:HasAttribute("Mobile AAA")) then
|
||||||
|
issam = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return issam
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [GROUND] Determine if a GROUP has a AAA unit, i.e. has no radar or optical tracker but the AAA = true or the "Mobile AAA" = true attribute.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @return #boolean IsSAM True if AAA, else false
|
||||||
|
function GROUP:IsAAA()
|
||||||
|
local issam = false
|
||||||
|
local units = self:GetUnits()
|
||||||
|
for _,_unit in pairs(units or {}) do
|
||||||
|
local unit = _unit -- Wrapper.Unit#UNIT
|
||||||
|
local desc = unit:GetDesc() or {}
|
||||||
|
local attr = desc.attributes or {}
|
||||||
|
if unit:HasSEAD() then return false end
|
||||||
|
if attr["AAA"] or attr["SAM related"] then
|
||||||
|
issam = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return issam
|
||||||
|
end
|
||||||
|
|||||||
@ -164,7 +164,7 @@ end
|
|||||||
|
|
||||||
--- Find the first(!) UNIT matching using patterns. Note that this is **a lot** slower than `:FindByName()`!
|
--- Find the first(!) UNIT matching using patterns. Note that this is **a lot** slower than `:FindByName()`!
|
||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @param #string Pattern The pattern to look for. Refer to [LUA patterns](http://www.easyuo.com/openeuo/wiki/index.php/Lua_Patterns_and_Captures_(Regular_Expressions)) for regular expressions in LUA.
|
-- @param #string Pattern The pattern to look for. Refer to [LUA patterns](http://www.easyuo.com/openeuo/wiki/index.php/Lua_Patterns_and_Captures_\(Regular_Expressions\)) for regular expressions in LUA.
|
||||||
-- @return #UNIT The UNIT.
|
-- @return #UNIT The UNIT.
|
||||||
-- @usage
|
-- @usage
|
||||||
-- -- Find a group with a partial group name
|
-- -- Find a group with a partial group name
|
||||||
@ -189,7 +189,7 @@ end
|
|||||||
|
|
||||||
--- Find all UNIT objects matching using patterns. Note that this is **a lot** slower than `:FindByName()`!
|
--- Find all UNIT objects matching using patterns. Note that this is **a lot** slower than `:FindByName()`!
|
||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @param #string Pattern The pattern to look for. Refer to [LUA patterns](http://www.easyuo.com/openeuo/wiki/index.php/Lua_Patterns_and_Captures_(Regular_Expressions)) for regular expressions in LUA.
|
-- @param #string Pattern The pattern to look for. Refer to [LUA patterns](http://www.easyuo.com/openeuo/wiki/index.php/Lua_Patterns_and_Captures_\(Regular_Expressions\)) for regular expressions in LUA.
|
||||||
-- @return #table Units Table of matching #UNIT objects found
|
-- @return #table Units Table of matching #UNIT objects found
|
||||||
-- @usage
|
-- @usage
|
||||||
-- -- Find all group with a partial group name
|
-- -- Find all group with a partial group name
|
||||||
|
|||||||
@ -83,6 +83,7 @@ Functional/Autolase.lua
|
|||||||
Functional/AICSAR.lua
|
Functional/AICSAR.lua
|
||||||
Functional/AmmoTruck.lua
|
Functional/AmmoTruck.lua
|
||||||
Functional/ZoneGoalCargo.lua
|
Functional/ZoneGoalCargo.lua
|
||||||
|
Functional/Tiresias.lua
|
||||||
|
|
||||||
Ops/Airboss.lua
|
Ops/Airboss.lua
|
||||||
Ops/RecoveryTanker.lua
|
Ops/RecoveryTanker.lua
|
||||||
|
|||||||
77
docs/beginner/ask-for-help.md
Normal file
77
docs/beginner/ask-for-help.md
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
parent: Beginner
|
||||||
|
nav_order: 06
|
||||||
|
---
|
||||||
|
# How to ask for help
|
||||||
|
{: .no_toc }
|
||||||
|
|
||||||
|
1. Table of contents
|
||||||
|
{:toc}
|
||||||
|
|
||||||
|
After you have tried to solve the problem on your own, you can also get help
|
||||||
|
from the community.
|
||||||
|
|
||||||
|
{: .highlight }
|
||||||
|
> But it is important to follow certain rules! Read them below.
|
||||||
|
|
||||||
|
## Communities
|
||||||
|
|
||||||
|
There are two ways to communicate with the community.
|
||||||
|
The fastest way is to use Discord:
|
||||||
|
|
||||||
|
- <https://discord.gg/gj68fm969S>{:target="_blank"}
|
||||||
|
|
||||||
|
But if you don't like Discord, you are able to post in the DCS forum.
|
||||||
|
Check out the MOOSE thread here:
|
||||||
|
|
||||||
|
- <https://forums.eagle.ru/showthread.php?t=138043>
|
||||||
|
|
||||||
|
## How to post requests
|
||||||
|
|
||||||
|
MOOSE is a community project and support is community based.
|
||||||
|
|
||||||
|
Please remember when posting a question:
|
||||||
|
|
||||||
|
- Before posting anything follow the [troubleshooting steps].
|
||||||
|
- **Read your logs**.
|
||||||
|
|
||||||
|
A post should contain the following:
|
||||||
|
|
||||||
|
1. A describtion what you expected to happen and what actually happened.
|
||||||
|
- Do not use vague words this stuff is hard to help with! Be specific.
|
||||||
|
|
||||||
|
2. Describe what happens instead.
|
||||||
|
- The less detail you offer, the less chance you can be helped.
|
||||||
|
- Don’t say it doesn’t work. Or is it broken. Say what it actually does.
|
||||||
|
|
||||||
|
3. Post your code in Discord as formatted code:
|
||||||
|
|
||||||
|
- Wrap a single line of code in backticks \` like this:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- Multiple lines of code should be posted like this:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- Post your log lines with the error or warning messages. Format them like this:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- Some complex problems need the mission (.miz file) also.
|
||||||
|
|
||||||
|
- But post your mission only when requested.
|
||||||
|
- Try to simplify your mission if it is complex!
|
||||||
|
|
||||||
|
There are people in the Discord and in the forum, who spend their free time to
|
||||||
|
help you. <br />
|
||||||
|
It is your responsibility to make their "work" as easy as possible.
|
||||||
|
|
||||||
|
Welcome to MOOSE and good luck!
|
||||||
|
|
||||||
|
## Next step
|
||||||
|
|
||||||
|
Last but not least some [tipps and tricks].
|
||||||
|
|
||||||
|
[troubleshooting steps]: problems.md
|
||||||
|
[tipps and tricks]: tipps-and-tricks.md
|
||||||
@ -9,5 +9,50 @@ nav_order: 04
|
|||||||
1. Table of contents
|
1. Table of contents
|
||||||
{:toc}
|
{:toc}
|
||||||
|
|
||||||
{: .warning }
|
The best way to get comfortable with a Moose class is to try the demo missions
|
||||||
> THIS DOCUMENT IS STILL WORK IN PROGRESS!
|
of the class you want to learn. The Moose team created a lot of demo missions
|
||||||
|
for most of the classes.
|
||||||
|
|
||||||
|
## Download demo missions
|
||||||
|
|
||||||
|
Go to the repository [MOOSE_MISSIONS]{:target="_blank"}, search the folder of
|
||||||
|
the class, download the mission (`.miz`) and run them.
|
||||||
|
|
||||||
|
## Read the mission script
|
||||||
|
|
||||||
|
In the same folder a `.lua` file with the same name is placed which is the
|
||||||
|
included mission script. You can watch these mission scripts easily online at
|
||||||
|
GitHub to understand what is happening in the mission.
|
||||||
|
|
||||||
|
## Read documentation
|
||||||
|
|
||||||
|
Next step is to read the [documentation]{:target="_blank"} of the class to
|
||||||
|
understand the code of the demo mission.
|
||||||
|
|
||||||
|
{: .note }
|
||||||
|
> The documentation is quite long and might be confusing for beginners.
|
||||||
|
> Start by looking at the description at the top of the documentation of a
|
||||||
|
> class. It often contains examples and explanations. <br /><br />
|
||||||
|
> Then search for the function names and look at the description of the
|
||||||
|
> functions and its parameters.
|
||||||
|
|
||||||
|
## Make small changes to the script
|
||||||
|
|
||||||
|
Download the `.lua` file, change the parameters to suit your needs in
|
||||||
|
[Notepad++]{:target="_blank"}, add it to the mission and rerun the mission.
|
||||||
|
Observe what happens and adapt the code.
|
||||||
|
|
||||||
|
If you want to use more functions combine them all up.
|
||||||
|
|
||||||
|
{: .note }
|
||||||
|
> But it is wise to do this in small steps. So it is easier to find errors.
|
||||||
|
|
||||||
|
## Next step
|
||||||
|
|
||||||
|
If the mission does not show the expected behaviour take a look at section
|
||||||
|
[problems].
|
||||||
|
|
||||||
|
[MOOSE_MISSIONS]: https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop
|
||||||
|
[documentation]: https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/index.html
|
||||||
|
[Notepad++]: https://notepad-plus-plus.org/downloads/
|
||||||
|
[problems]: problems.md
|
||||||
|
|||||||
@ -144,9 +144,16 @@ have create everything on your own.
|
|||||||
- Change the text a little bit, like `Hello Dude! ...` and save the file.
|
- Change the text a little bit, like `Hello Dude! ...` and save the file.
|
||||||
- Run the mission again.
|
- Run the mission again.
|
||||||
- The text will not be changed in the mission. Why?
|
- The text will not be changed in the mission. Why?
|
||||||
The mission editor copies the script into the mission file when you add it.
|
|
||||||
Ever change on the script file on your hard disk is not recognized by mission editor.
|
{: .important }
|
||||||
You have to add the file after each change again.
|
The mission editor copies the script into the mission file when you add it.
|
||||||
|
Every change on the script file on your hard disk is not recognized by mission
|
||||||
|
editor. **You have to add the file after each change again!**
|
||||||
|
|
||||||
|
There is also another method available to dynamically load mission scripts.
|
||||||
|
But this method has some brawbacks and will be explained in the advanced section.
|
||||||
|
|
||||||
|
Now we add the mission script again:
|
||||||
|
|
||||||
- On the left side of the `TRIGGERS` dialog click on `Load Mission Script`.
|
- On the left side of the `TRIGGERS` dialog click on `Load Mission Script`.
|
||||||
- On the right side under `ACTIONS` you need to add the script again:
|
- On the right side under `ACTIONS` you need to add the script again:
|
||||||
|
|||||||
46
docs/beginner/problems.md
Normal file
46
docs/beginner/problems.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
parent: Beginner
|
||||||
|
nav_order: 05
|
||||||
|
---
|
||||||
|
|
||||||
|
# Problems
|
||||||
|
{: .no_toc }
|
||||||
|
|
||||||
|
1. Table of contents
|
||||||
|
{:toc}
|
||||||
|
|
||||||
|
## Something went wrong
|
||||||
|
|
||||||
|
If the mission shows not the expected behaviour do the following steps:
|
||||||
|
|
||||||
|
1. Double check if you added the changed mission script to the mission again!
|
||||||
|
1. Check if the triggers are configured as requested in the last sections.
|
||||||
|
|
||||||
|
## Read the logs
|
||||||
|
|
||||||
|
The DCS log is a super important and useful log for the entire of DCS World.
|
||||||
|
All scripting and other errors are recorded here. It is the one stop shop for
|
||||||
|
things that occurred in your mission. It will tell you if there was a mistake.
|
||||||
|
|
||||||
|
1. Open the file `dcs.log` in the `Logs` subfolder in your DCS
|
||||||
|
[Saved Games folder].
|
||||||
|
|
||||||
|
1. Search for the following line: `*** MOOSE INCLUDE END ***`
|
||||||
|
- If it is included in the log, Moose was loaded.
|
||||||
|
- If the line is not in the log check the triggers again!
|
||||||
|
|
||||||
|
1. Search for lines with `SCRIPTING` and `WARNING` or `ERROR` and read them.
|
||||||
|
- This might help to find your error.
|
||||||
|
|
||||||
|
{: .note }
|
||||||
|
> You will find a lot of warning and error lines in the log which are not
|
||||||
|
> related to `SCRIPTING`. They are related to stuff from Eagle Dynamics or
|
||||||
|
> Third Parties and you have to ignore them. EA does the same. ;o)
|
||||||
|
|
||||||
|
## Next step
|
||||||
|
|
||||||
|
If you don't find the error and/or don't understand the messages in the log file
|
||||||
|
you can [ask for help].
|
||||||
|
|
||||||
|
[Saved Games folder]: tipps-and-tricks.md#find-the-saved-games-folder
|
||||||
|
[ask for help]: ask-for-help.md
|
||||||
@ -33,7 +33,9 @@ This folder can be found in your userprofile as subfolder of `Saved Games`.
|
|||||||
The easiest way to find it, is to open search and paste the text below into it
|
The easiest way to find it, is to open search and paste the text below into it
|
||||||
and press Enter:
|
and press Enter:
|
||||||
|
|
||||||
```%userprofile%\Saved Games```
|
```
|
||||||
|
%userprofile%\Saved Games
|
||||||
|
```
|
||||||
|
|
||||||
{: .note }
|
{: .note }
|
||||||
> The text will work even if your Windows is installed with another language,
|
> The text will work even if your Windows is installed with another language,
|
||||||
|
|||||||
BIN
docs/images/beginner/discord-fomat-logs.png
Normal file
BIN
docs/images/beginner/discord-fomat-logs.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
BIN
docs/images/beginner/discord-multi-line-code.png
Normal file
BIN
docs/images/beginner/discord-multi-line-code.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.3 KiB |
BIN
docs/images/beginner/discord-single-line-code.png
Normal file
BIN
docs/images/beginner/discord-single-line-code.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
@ -26,14 +26,30 @@ You only need to load **one** of those files at the beginning of your mission.
|
|||||||
|
|
||||||
This repository contains the generated documentation and pictures and other references.
|
This repository contains the generated documentation and pictures and other references.
|
||||||
The generated documentation is reflected in html and is published at:
|
The generated documentation is reflected in html and is published at:
|
||||||
- Stable `master` branch: <https://flightcontrol-master.github.io/MOOSE_DOCS/>
|
- `master` branch: <https://flightcontrol-master.github.io/MOOSE_DOCS/>
|
||||||
- `develop` branch: <https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/>
|
- `develop` branch: <https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/>
|
||||||
|
|
||||||
|
## [MOOSE_GUIDES](https://github.com/FlightControl-Master/MOOSE_GUIDES) - For external documentation and help
|
||||||
|
|
||||||
|
This repository will be removed in future.
|
||||||
|
|
||||||
|
## [MOOSE_PRESENTATIONS](https://github.com/FlightControl-Master/MOOSE_PRESENTATIONS)
|
||||||
|
|
||||||
|
A collection of presentations used in the videos on the youtube channel of FlightControl.
|
||||||
|
|
||||||
## [MOOSE_MISSIONS](https://github.com/FlightControl-Master/MOOSE_MISSIONS) - For users (provides demo missions)
|
## [MOOSE_MISSIONS](https://github.com/FlightControl-Master/MOOSE_MISSIONS) - For users (provides demo missions)
|
||||||
|
|
||||||
This repository contains all the demonstration missions in packed format (*.miz),
|
This repository contains all the demonstration missions in packed format (*.miz),
|
||||||
and can be used without any further setup in DCS WORLD.
|
and can be used without any further setup in DCS WORLD.
|
||||||
|
|
||||||
|
## [Moose_Community_Scripts](https://github.com/FlightControl-Master/Moose_Community_Scripts)
|
||||||
|
|
||||||
|
This repository is for Moose based helper scripts, snippets, functional demos.
|
||||||
|
|
||||||
|
## [MOOSE_SOUND](https://github.com/FlightControl-Master/MOOSE_SOUND)
|
||||||
|
|
||||||
|
Sound packs for different MOOSE framework classes.
|
||||||
|
|
||||||
## [MOOSE_MISSIONS_DYNAMIC](https://github.com/FlightControl-Master/MOOSE_MISSIONS_DYNAMIC) - Outdated
|
## [MOOSE_MISSIONS_DYNAMIC](https://github.com/FlightControl-Master/MOOSE_MISSIONS_DYNAMIC) - Outdated
|
||||||
|
|
||||||
This repository will be removed in future.
|
This repository will be removed in future.
|
||||||
@ -41,3 +57,11 @@ This repository will be removed in future.
|
|||||||
## [MOOSE_MISSIONS_UNPACKED](https://github.com/FlightControl-Master/MOOSE_MISSIONS_UNPACKED) - Outdated
|
## [MOOSE_MISSIONS_UNPACKED](https://github.com/FlightControl-Master/MOOSE_MISSIONS_UNPACKED) - Outdated
|
||||||
|
|
||||||
This repository will be removed in future.
|
This repository will be removed in future.
|
||||||
|
|
||||||
|
## [MOOSE_COMMUNITY_MISSIONS](https://github.com/FlightControl-Master/MOOSE_COMMUNITY_MISSIONS) - Outdated
|
||||||
|
|
||||||
|
A database of missions created by the community, using MOOSE.
|
||||||
|
|
||||||
|
## [MOOSE_TOOLS](https://github.com/FlightControl-Master/MOOSE_TOOLS) - Outdated
|
||||||
|
|
||||||
|
A collection of the required tools to develop and contribute in the MOOSE framework for DCS World.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user