diff --git a/Moose Development/Moose/AIBalancer.lua b/Moose Development/Moose/AIBalancer.lua index 6dadedd6b..d4494073e 100644 --- a/Moose Development/Moose/AIBalancer.lua +++ b/Moose Development/Moose/AIBalancer.lua @@ -13,6 +13,12 @@ -- -- * @{#AIBALANCER.New}: Creates a new AIBALANCER object. -- +-- 1.2) AIBALANCER return AI to Airbases: +-- -------------------------------------- +-- You can configure to have the AI to return to: +-- +-- * @{#AIBALANCER.ReturnToHomeAirbase}: Returns the AI to the home @{Airbase#AIRBASE}. +-- * @{#AIBALANCER.ReturnToNearestAirbases}: Returns the AI to the nearest friendly @{Airbase#AIRBASE}. -- -- === -- @module AIBalancer @@ -22,6 +28,10 @@ -- @type AIBALANCER -- @field Set#SET_CLIENT SetClient -- @field Spawn#SPAWN SpawnAI +-- @field #boolean ReturnToAirbase +-- @field Set#SET_AIRBASE ReturnAirbaseSet +-- @field DCSTypes#Distance ReturnTresholdRange +-- @field #boolean ReturnToHomeAirbase -- @extends Base#BASE AIBALANCER = { ClassName = "AIBALANCER", @@ -38,13 +48,55 @@ function AIBALANCER:New( SetClient, SpawnAI ) local self = BASE:Inherit( self, BASE:New() ) self.SetClient = SetClient - self.SpawnAI = SpawnAI + if type( SpawnAI ) == "table" then + if SpawnAI.ClassName and SpawnAI.ClassName == "SPAWN" then + self.SpawnAI = { SpawnAI } + else + local SpawnObjects = true + for SpawnObjectID, SpawnObject in pairs( SpawnAI ) do + if SpawnObject.ClassName and SpawnObject.ClassName == "SPAWN" then + self:E( SpawnObject.ClassName ) + else + self:E( "other object" ) + SpawnObjects = false + end + end + if SpawnObjects == true then + self.SpawnAI = SpawnAI + else + error( "No SPAWN object given in parameter SpawnAI, either as a single object or as a table of objects!" ) + end + end + end + + self.ReturnToAirbase = false + self.ReturnHomeAirbase = false self.AIMonitorSchedule = SCHEDULER:New( self, self._ClientAliveMonitorScheduler, {}, 1, 10, 0 ) return self end +--- Returns the AI to the nearest friendly @{Airbase#AIRBASE}. +-- @param #AIBALANCER self +-- @param DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Airbase#AIRBASE}. +-- @param Set#SET_AIRBASE ReturnAirbaseSet The SET of @{Set#SET_AIRBASE}s to evaluate where to return to. +function AIBALANCER:ReturnToNearestAirbases( ReturnTresholdRange, ReturnAirbaseSet ) + + self.ReturnToAirbase = true + self.ReturnTresholdRange = ReturnTresholdRange + self.ReturnAirbaseSet = ReturnAirbaseSet +end + +--- Returns the AI to the home @{Airbase#AIRBASE}. +-- @param #AIBALANCER self +-- @param DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Airbase#AIRBASE}. +function AIBALANCER:ReturnToHomeAirbase( ReturnTresholdRange ) + + self.ReturnToHomeAirbase = true + self.ReturnTresholdRange = ReturnTresholdRange +end + --- @param #AIBALANCER self function AIBALANCER:_ClientAliveMonitorScheduler() @@ -56,13 +108,70 @@ function AIBALANCER:_ClientAliveMonitorScheduler() if Client:IsAlive() then if ClientAIAliveState == true then Client:SetState( self, 'AIAlive', false ) + local AIGroup = Client:GetState( self, 'AIGroup' ) -- Group#GROUP - AIGroup:Destroy() + + if self.ReturnToAirbase == false and self.ReturnToHomeAirbase == false then + AIGroup:Destroy() + else + -- We test if there is no other CLIENT within the self.ReturnTresholdRange of the first unit of the AI group. + -- If there is a CLIENT, the AI stays engaged and will not return. + -- If there is no CLIENT within the self.ReturnTresholdRange, then the unit will return to the Airbase return method selected. + + local ClientInZone = { Value = false } + local RangeZone = ZONE_RADIUS:New( 'RangeZone', AIGroup:GetPointVec2(), self.ReturnTresholdRange ) + + self:E( RangeZone ) + + _DATABASE:ForEachUnit( + --- @param Unit#UNIT RangeTestUnit + function( RangeTestUnit, RangeZone, AIGroup, ClientInZone ) + self:E( { ClientInZone, RangeTestUnit.UnitName, RangeZone.ZoneName } ) + if RangeTestUnit:IsInZone( RangeZone ) == true then + self:E( "in zone" ) + if RangeTestUnit:GetCoalition() ~= AIGroup:GetCoalition() then + self:E( "in range" ) + ClientInZone.Value = true + end + end + end, + + --- @param Zone#ZONE_RADIUS RangeZone + -- @param Group#GROUP AIGroup + function( RangeZone, AIGroup, ClientInZone ) + local AIGroupTemplate = AIGroup:GetTemplate() + if ClientInZone.Value == false then + if self.ReturnToHomeAirbase == true then + local WayPointCount = #AIGroupTemplate.route.points + local SwitchWayPointCommand = AIGroup:CommandSwitchWayPoint( 1, WayPointCount, 1 ) + AIGroup:SetCommand( SwitchWayPointCommand ) + AIGroup:MessageToRed( "Returning to home base ...", 30 ) + else + -- Okay, we need to send this Group back to the nearest base of the Coalition of the AI. + --TODO: i need to rework the POINT_VEC2 thing. + local PointVec2 = POINT_VEC2:New( AIGroup:GetPointVec2().x, AIGroup:GetPointVec2().y ) + local ClosestAirbase = self.ReturnAirbaseSet:FindNearestAirbaseFromPointVec2( PointVec2 ) + self:T( ClosestAirbase.AirbaseName ) + AIGroup:MessageToRed( "Returning to " .. ClosestAirbase:GetName().. " ...", 30 ) + local RTBRoute = AIGroup:RouteReturnToAirbase( ClosestAirbase ) + AIGroupTemplate.route = RTBRoute + AIGroup:Respawn( AIGroupTemplate ) + end + end + end + , RangeZone, AIGroup, ClientInZone + ) + + end end else if not ClientAIAliveState or ClientAIAliveState == false then Client:SetState( self, 'AIAlive', true ) - Client:SetState( self, 'AIGroup', self.SpawnAI:Spawn() ) + + -- OK, spawn a new group from the SpawnAI objects provided. + local SpawnAICount = #self.SpawnAI + local SpawnAIIndex = math.random( 1, SpawnAICount ) + Client:SetState( self, 'AIGroup', self.SpawnAI[SpawnAIIndex]:Spawn() ) end end end diff --git a/Moose Development/Moose/Airbase.lua b/Moose Development/Moose/Airbase.lua index ec1e47e21..87ccf2ba9 100644 --- a/Moose Development/Moose/Airbase.lua +++ b/Moose Development/Moose/Airbase.lua @@ -1,15 +1,17 @@ ---- AIRBASE Class +--- This module contains the AIRBASE classes. -- --- @{AIRBASE} class --- ============== +-- === +-- +-- 1) @{Airbase#AIRBASE} class, extends @{Base#BASE} +-- ================================================= -- The @{AIRBASE} class is a wrapper class to handle the DCS Airbase objects: -- -- * Support all DCS Airbase APIs. -- * Enhance with Airbase specific APIs not in the DCS Airbase API set. -- -- --- AIRBASE reference methods --- ====================== +-- 1.1) AIRBASE reference methods +-- ------------------------------ -- For each DCS Airbase object alive within a running mission, a AIRBASE wrapper object (instance) will be created within the _@{DATABASE} object. -- This is done at the beginning of the mission (when the mission starts). -- @@ -27,8 +29,8 @@ -- -- IMPORTANT: ONE SHOULD NEVER SANATIZE these AIRBASE OBJECT REFERENCES! (make the AIRBASE object references nil). -- --- DCS AIRBASE APIs --- ============= +-- 1.2) DCS AIRBASE APIs +-- --------------------- -- The DCS Airbase APIs are used extensively within MOOSE. The AIRBASE class has for each DCS Airbase API a corresponding method. -- To be able to distinguish easily in your code the difference between a AIRBASE API call and a DCS Airbase API call, -- the first letter of the method is also capitalized. So, by example, the DCS Airbase method @{DCSAirbase#Airbase.getName}() @@ -274,6 +276,21 @@ function AIRBASE:GetPointVec2() return nil end +--- Returns the DCS Airbase category as defined within the DCS Airbase Descriptor. +-- @param Airbase#AIRBASE self +-- @return DCSAirbase#Airbase.Category The DCS Airbase Category +function AIRBASE:GetCategory() + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseCategory = self:GetDesc().category + return AirbaseCategory + end + + return nil +end + + --- Returns the DCS Airbase category name as defined within the DCS Airbase Descriptor. -- @param Airbase#AIRBASE self -- @return #string The DCS Airbase Category Name @@ -288,3 +305,4 @@ function AIRBASE:GetCategoryName() return nil end + diff --git a/Moose Development/Moose/Client.lua b/Moose Development/Moose/Client.lua index a9e582df1..919580b4a 100644 --- a/Moose Development/Moose/Client.lua +++ b/Moose Development/Moose/Client.lua @@ -236,7 +236,6 @@ end --- @param #CLIENT self function CLIENT:_AliveCheckScheduler( SchedulerName ) - self:E( SchedulerName ) self:F( { SchedulerName, self.ClientName, self.ClientAlive2, self.ClientBriefingShown, self.ClientCallBack } ) if self:IsAlive() then diff --git a/Moose Development/Moose/Database.lua b/Moose Development/Moose/Database.lua index c74cbdd64..9f5c8030b 100644 --- a/Moose Development/Moose/Database.lua +++ b/Moose Development/Moose/Database.lua @@ -1,7 +1,9 @@ ---- Manage the mission database. +--- This module contains the DATABASE class, managing the database of mission objects. -- --- @{#DATABASE} class --- ================== +-- ==== +-- +-- 1) @{Database#DATABASE} class, extends @{Base#BASE} +-- =================================================== -- Mission designers can use the DATABASE class to refer to: -- -- * UNITS @@ -16,8 +18,8 @@ -- Moose will automatically create one instance of the DATABASE class into the **global** object _DATABASE. -- Moose refers to _DATABASE within the framework extensively, but you can also refer to the _DATABASE object within your missions if required. -- --- DATABASE iterators: --- =================== +-- 1.1) DATABASE iterators +-- ----------------------- -- You can iterate the database with the available iterator methods. -- The iterator methods will walk the DATABASE set, and call for each element within the set a function that you provide. -- The following iterator methods are currently available within the DATABASE: @@ -32,17 +34,6 @@ -- @module Database -- @author FlightControl - - - - - - - - - - - --- DATABASE class -- @type DATABASE -- @extends Base#BASE @@ -61,6 +52,7 @@ DATABASE = { PLAYERSALIVE = {}, CLIENTS = {}, CLIENTSALIVE = {}, + AIRBASES = {}, NavPoints = {}, } @@ -105,6 +97,7 @@ function DATABASE:New() self:_RegisterClients() self:_RegisterStatics() self:_RegisterPlayers() + self:_RegisterAirbases() return self end @@ -166,6 +159,33 @@ function DATABASE:FindStatic( StaticName ) return StaticFound end +--- Adds a Airbase based on the Airbase Name in the DATABASE. +-- @param #DATABASE self +function DATABASE:AddAirbase( DCSAirbaseName ) + + if not self.AIRBASES[DCSAirbaseName] then + self.AIRBASES[DCSAirbaseName] = AIRBASE:Register( DCSAirbaseName ) + end +end + + +--- Deletes a Airbase from the DATABASE based on the Airbase Name. +-- @param #DATABASE self +function DATABASE:DeleteAirbase( DCSAirbaseName ) + + --self.AIRBASES[DCSAirbaseName] = nil +end + +--- Finds a AIRBASE based on the AirbaseName. +-- @param #DATABASE self +-- @param #string AirbaseName +-- @return Airbase#AIRBASE The found AIRBASE. +function DATABASE:FindAirbase( AirbaseName ) + + local AirbaseFound = self.AIRBASES[AirbaseName] + return AirbaseFound +end + --- Finds a CLIENT based on the ClientName. -- @param #DATABASE self @@ -371,6 +391,18 @@ function DATABASE:GetCountryFromClientTemplate( ClientName ) return self.Templates.ClientsByName[ClientName].CountryID end +--- Airbase + +function DATABASE:GetCoalitionFromAirbase( AirbaseName ) + return self.AIRBASES[AirbaseName]:GetCoalition() +end + +function DATABASE:GetCategoryFromAirbase( AirbaseName ) + return self.AIRBASES[AirbaseName]:GetCategory() +end + + + --- Private method that registers all alive players in the mission. -- @param #DATABASE self -- @return #DATABASE self @@ -439,6 +471,7 @@ function DATABASE:_RegisterClients() return self end +--- @param #DATABASE self function DATABASE:_RegisterStatics() local CoalitionsData = { GroupsRed = coalition.getStaticObjects( coalition.side.RED ), GroupsBlue = coalition.getStaticObjects( coalition.side.BLUE ) } @@ -459,6 +492,23 @@ function DATABASE:_RegisterStatics() return self end +--- @param #DATABASE self +function DATABASE:_RegisterAirbases() + + local CoalitionsData = { AirbasesRed = coalition.getAirbases( coalition.side.RED ), AirbasesBlue = coalition.getAirbases( coalition.side.BLUE ), AirbasesNeutral = coalition.getAirbases( coalition.side.NEUTRAL ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + for DCSAirbaseId, DCSAirbase in pairs( CoalitionData ) do + + local DCSAirbaseName = DCSAirbase:getName() + + self:E( { "Register Airbase:", DCSAirbaseName } ) + self:AddAirbase( DCSAirbaseName ) + end + end + + return self +end + --- Events @@ -526,7 +576,7 @@ end -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive player in the database. -- @return #DATABASE self -function DATABASE:ForEach( IteratorFunction, arg, Set ) +function DATABASE:ForEach( IteratorFunction, FinalizeFunction, arg, Set ) self:F2( arg ) local function CoRoutine() @@ -547,7 +597,7 @@ function DATABASE:ForEach( IteratorFunction, arg, Set ) local function Schedule() local status, res = coroutine.resume( co ) - self:T2( { status, res } ) + self:T3( { status, res } ) if status == false then error( res ) @@ -555,7 +605,9 @@ function DATABASE:ForEach( IteratorFunction, arg, Set ) if res == false then return true -- resume next time the loop end - + if FinalizeFunction then + FinalizeFunction( unpack( arg ) ) + end return false end @@ -569,10 +621,10 @@ end -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the database. The function needs to accept a UNIT parameter. -- @return #DATABASE self -function DATABASE:ForEachUnit( IteratorFunction, ... ) +function DATABASE:ForEachUnit( IteratorFunction, FinalizeFunction, ... ) self:F2( arg ) - self:ForEach( IteratorFunction, arg, self.UNITS ) + self:ForEach( IteratorFunction, FinalizeFunction, arg, self.UNITS ) return self end diff --git a/Moose Development/Moose/Group.lua b/Moose Development/Moose/Group.lua index 87cddd07e..a6711075d 100644 --- a/Moose Development/Moose/Group.lua +++ b/Moose Development/Moose/Group.lua @@ -65,6 +65,7 @@ -- * @{#GROUP.TaskRouteToVec2}: (AIR + GROUND) Make the Group move to a given point. -- * @{#GROUP.TaskRouteToVec3}: (AIR + GROUND) Make the Group move to a given point. -- * @{#GROUP.TaskRouteToZone}: (AIR + GROUND) Route the group to a given zone. +-- * @{#GROUP.TaskReturnToBase}: (AIR) Route the group to an airbase. -- -- ### 1.2.2) EnRoute task methods -- @@ -1050,6 +1051,24 @@ function GROUP:CommandSwitchWayPoint( FromWayPoint, ToWayPoint, Index ) return CommandSwitchWayPoint end +--- Perform stop route command +-- @param #GROUP self +-- @param #boolean StopRoute +-- @return DCSTask#Task +function GROUP:CommandStopRoute( StopRoute, Index ) + self:F2( { StopRoute, Index } ) + + local CommandStopRoute = { + id = 'StopRoute', + params = { + value = StopRoute, + }, + } + + self:T3( { CommandStopRoute } ) + return CommandStopRoute +end + -- TASKS FOR AIR GROUPS @@ -2216,6 +2235,125 @@ function GROUP:TaskRouteToZone( Zone, Randomize, Speed, Formation ) return nil end +--- (AIR) Return the Group to an @{Airbase#AIRBASE} +-- A speed can be given in km/h. +-- A given formation can be given. +-- @param #GROUP self +-- @param Airbase#AIRBASE ReturnAirbase The @{Airbase#AIRBASE} to return to. +-- @param #number Speed (optional) The speed. +-- @return #string The route +function GROUP:RouteReturnToAirbase( ReturnAirbase, Speed ) + self:F2( { ReturnAirbase, Speed } ) + +-- Example +-- [4] = +-- { +-- ["alt"] = 45, +-- ["type"] = "Land", +-- ["action"] = "Landing", +-- ["alt_type"] = "BARO", +-- ["formation_template"] = "", +-- ["properties"] = +-- { +-- ["vnav"] = 1, +-- ["scale"] = 0, +-- ["angle"] = 0, +-- ["vangle"] = 0, +-- ["steer"] = 2, +-- }, -- end of ["properties"] +-- ["ETA"] = 527.81058817743, +-- ["airdromeId"] = 12, +-- ["y"] = 243127.2973737, +-- ["x"] = -5406.2803440839, +-- ["name"] = "DictKey_WptName_53", +-- ["speed"] = 138.88888888889, +-- ["ETA_locked"] = false, +-- ["task"] = +-- { +-- ["id"] = "ComboTask", +-- ["params"] = +-- { +-- ["tasks"] = +-- { +-- }, -- end of ["tasks"] +-- }, -- end of ["params"] +-- }, -- end of ["task"] +-- ["speed_locked"] = true, +-- }, -- end of [4] + + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + + local GroupPoint = self:GetPointVec2() + local GroupVelocity = self:GetMaxVelocity() + + local PointFrom = {} + PointFrom.x = GroupPoint.x + PointFrom.y = GroupPoint.y + PointFrom.type = "Turning Point" + PointFrom.action = "Turning Point" + PointFrom.speed = GroupVelocity + + + local PointTo = {} + local AirbasePoint = ReturnAirbase:GetPointVec2() + + PointTo.x = AirbasePoint.x + PointTo.y = AirbasePoint.y + PointTo.type = "Land" + PointTo.action = "Landing" + PointTo.airdromeId = ReturnAirbase:GetID()-- Airdrome ID + self:T(PointTo.airdromeId) + --PointTo.alt = 0 + + local Points = { PointFrom, PointTo } + + self:T3( Points ) + + local Route = { points = Points, } + + return Route + end + + return nil +end + +--- @param Group#GROUP self +function GROUP:Respawn( Template ) + + local Vec3 = self:GetPointVec3() + --Template.x = Vec3.x + --Template.y = Vec3.z + Template.x = nil + Template.y = nil + + self:E( #Template.units ) + for UnitID, UnitData in pairs( self:GetUnits() ) do + local GroupUnit = UnitData -- Unit#UNIT + self:E( GroupUnit:GetName() ) + if GroupUnit:IsAlive() then + local GroupUnitVec3 = GroupUnit:GetPointVec3() + local GroupUnitHeading = GroupUnit:GetHeading() + Template.units[UnitID].alt = GroupUnitVec3.y + Template.units[UnitID].x = GroupUnitVec3.x + Template.units[UnitID].y = GroupUnitVec3.z + Template.units[UnitID].heading = GroupUnitHeading + self:E( { UnitID, Template.units[UnitID], Template.units[UnitID] } ) + end + end + + _DATABASE:Spawn( Template ) + +end + +function GROUP:GetTemplate() + + return _DATABASE.Templates.Groups[self:GetName()].Template + +end + -- Commands --- Do Script command diff --git a/Moose Development/Moose/Moose.lua b/Moose Development/Moose/Moose.lua index f6f3cafe8..eb707c211 100644 --- a/Moose Development/Moose/Moose.lua +++ b/Moose Development/Moose/Moose.lua @@ -10,6 +10,7 @@ Include.File( "Unit" ) Include.File( "Zone" ) Include.File( "Client" ) Include.File( "Static" ) +Include.File( "Airbase" ) Include.File( "Database" ) Include.File( "Set" ) Include.File( "Point" ) @@ -38,40 +39,6 @@ Include.File( "MissileTrainer" ) Include.File( "AIBalancer" ) Include.File( "AirbasePolice" ) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- The order of the declarations is important here. Don't touch it. --- Declare the event dispatcher based on the EVENT class diff --git a/Moose Development/Moose/Point.lua b/Moose Development/Moose/Point.lua index f45175397..e74c749e9 100644 --- a/Moose Development/Moose/Point.lua +++ b/Moose Development/Moose/Point.lua @@ -164,6 +164,7 @@ end --- The POINT_VEC2 class -- @type POINT_VEC2 +-- @field DCSTypes#Vec2 PointVec2 -- @extends Point#POINT_VEC3 POINT_VEC2 = { ClassName = "POINT_VEC2", @@ -184,8 +185,36 @@ function POINT_VEC2:New( x, y, LandHeightAdd ) local self = BASE:Inherit( self, POINT_VEC3:New( x, LandHeight, y ) ) self:F2( { x, y, LandHeightAdd } ) + + self.PointVec2 = { x = x, y = y } return self end +--- Calculate the distance from a reference @{Point#POINT_VEC2}. +-- @param #POINT_VEC2 self +-- @param #POINT_VEC2 PointVec2Reference The reference @{Point#POINT_VEC2}. +-- @return DCSTypes#Distance The distance from the reference @{Point#POINT_VEC2} in meters. +function POINT_VEC2:DistanceFromPointVec2( PointVec2Reference ) + self:F2( PointVec2Reference ) + + local Distance = ( ( PointVec2Reference.PointVec2.x - self.PointVec2.x ) ^ 2 + ( PointVec2Reference.PointVec2.y - self.PointVec2.y ) ^2 ) ^0.5 + + self:T2( Distance ) + return Distance +end + +--- Calculate the distance from a reference @{DCSTypes#Vec2}. +-- @param #POINT_VEC2 self +-- @param DCSTypes#Vec2 Vec2Reference The reference @{DCSTypes#Vec2}. +-- @return DCSTypes#Distance The distance from the reference @{DCSTypes#Vec2} in meters. +function POINT_VEC2:DistanceFromVec2( Vec2Reference ) + self:F2( Vec2Reference ) + + local Distance = ( ( Vec2Reference.x - self.PointVec2.x ) ^ 2 + ( Vec2Reference.y - self.PointVec2.y ) ^2 ) ^0.5 + + self:T2( Distance ) + return Distance +end + diff --git a/Moose Development/Moose/Set.lua b/Moose Development/Moose/Set.lua index 412d4af52..388de8741 100644 --- a/Moose Development/Moose/Set.lua +++ b/Moose Development/Moose/Set.lua @@ -3,7 +3,7 @@ -- === -- -- 1) @{Set#SET_BASE} class, extends @{Base#BASE} --- ================================================ +-- ============================================== -- The @{Set#SET_BASE} class defines the core functions that define a collection of objects. -- A SET provides iterators to iterate the SET, but will **temporarily** yield the ForEach interator loop at defined **"intervals"** to the mail simulator loop. -- In this way, large loops can be done while not blocking the simulator main processing loop. @@ -14,15 +14,15 @@ -- --------------------------------------- -- Some key core functions are @{Set#SET_BASE.Add} and @{Set#SET_BASE.Remove} to add or remove objects from the SET in your logic. -- --- 1.2) Define the SET iterator **"yield interval"** and the **"time interval"**. --- ------------------------------------------------------------------------------------- +-- 1.2) Define the SET iterator **"yield interval"** and the **"time interval"** +-- ----------------------------------------------------------------------------- -- Modify the iterator intervals with the @{Set#SET_BASE.SetInteratorIntervals} method. -- You can set the **"yield interval"**, and the **"time interval"**. (See above). -- -- === -- -- 2) @{Set#SET_GROUP} class, extends @{Set#SET_BASE} --- ==================================================== +-- ================================================== -- Mission designers can use the @{Set#SET_GROUP} class to build sets of groups belonging to certain: -- -- * Coalitions @@ -128,6 +128,8 @@ -- * @{#SET_UNIT.ForEachUnitCompletelyInZone}: Iterate and call an iterator function for each **alive** UNIT presence completely in a @{Zone}, providing the UNIT and optional parameters to the called function. -- * @{#SET_UNIT.ForEachUnitNotInZone}: Iterate and call an iterator function for each **alive** UNIT presence not in a @{Zone}, providing the UNIT and optional parameters to the called function. -- +-- === +-- -- 4) @{Set#SET_CLIENT} class, extends @{Set#SET_BASE} -- =================================================== -- Mission designers can use the @{Set#SET_CLIENT} class to build sets of units belonging to certain: @@ -178,9 +180,48 @@ -- -- ==== -- +-- 5) @{Set#SET_AIRBASE} class, extends @{Set#SET_BASE} +-- ==================================================== +-- Mission designers can use the @{Set#SET_AIRBASE} class to build sets of airbases optionally belonging to certain: +-- +-- * Coalitions +-- +-- 5.1) SET_AIRBASE construction +-- ----------------------------- +-- Create a new SET_AIRBASE object with the @{#SET_AIRBASE.New} method: +-- +-- * @{#SET_AIRBASE.New}: Creates a new SET_AIRBASE object. +-- +-- 5.2) Add or Remove AIRBASEs from SET_AIRBASE +-- -------------------------------------------- +-- AIRBASEs can be added and removed using the @{Set#SET_AIRBASE.AddAirbasesByName} and @{Set#SET_AIRBASE.RemoveAirbasesByName} respectively. +-- These methods take a single AIRBASE name or an array of AIRBASE names to be added or removed from SET_AIRBASE. +-- +-- 5.3) SET_AIRBASE filter criteria +-- -------------------------------- +-- You can set filter criteria to define the set of clients within the SET_AIRBASE. +-- Filter criteria are defined by: +-- +-- * @{#SET_AIRBASE.FilterCoalitions}: Builds the SET_AIRBASE with the airbases belonging to the coalition(s). +-- +-- Once the filter criteria have been set for the SET_AIRBASE, you can start filtering using: +-- +-- * @{#SET_AIRBASE.FilterStart}: Starts the filtering of the airbases within the SET_AIRBASE. +-- +-- 5.4) SET_AIRBASE iterators: +-- --------------------------- +-- Once the filters have been defined and the SET_AIRBASE has been built, you can iterate the SET_AIRBASE with the available iterator methods. +-- The iterator methods will walk the SET_AIRBASE set, and call for each airbase within the set a function that you provide. +-- The following iterator methods are currently available within the SET_AIRBASE: +-- +-- * @{#SET_AIRBASE.ForEachAirbase}: Calls a function for each airbase it finds within the SET_AIRBASE. +-- +-- ==== +-- -- @module Set -- @author FlightControl + --- SET_BASE class -- @type SET_BASE -- @extends Base#BASE @@ -279,6 +320,32 @@ function SET_BASE:_FilterStart() return self end +--- Iterate the SET_BASE while identifying the nearest object from a @{Point#POINT_VEC2}. +-- @param #SET_BASE self +-- @param Point#POINT_VEC2 PointVec2 A @{Point#POINT_VEC2} object from where to evaluate the closest object in the set. +-- @return Base#BASE The closest object. +function SET_BASE:FindNearestObjectFromPointVec2( PointVec2 ) + self:F2( PointVec2 ) + + local NearestObject = nil + local ClosestDistance = nil + + for ObjectID, ObjectData in pairs( self.Set ) do + if NearestObject == nil then + NearestObject = ObjectData + ClosestDistance = PointVec2:DistanceFromVec2( ObjectData:GetPointVec2() ) + else + local Distance = PointVec2:DistanceFromVec2( ObjectData:GetPointVec2() ) + if Distance < ClosestDistance then + NearestObject = ObjectData + ClosestDistance = Distance + end + end + end + + return NearestObject +end + ----- Private method that registers all alive players in the mission. @@ -420,7 +487,7 @@ function SET_BASE:ForEach( IteratorFunction, arg, Set, Function, FunctionArgumen end ------ Interate the SET_BASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. +----- Iterate the SET_BASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. ---- @param #SET_BASE self ---- @param #function IteratorFunction The function that will be called when there is an alive unit in the SET_BASE. The function needs to accept a UNIT parameter. ---- @return #SET_BASE self @@ -432,7 +499,7 @@ end -- return self --end -- ------ Interate the SET_BASE and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. +----- Iterate the SET_BASE and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. ---- @param #SET_BASE self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_BASE. The function needs to accept a UNIT parameter. ---- @return #SET_BASE self @@ -445,7 +512,7 @@ end --end -- -- ------ Interate the SET_BASE and call an interator function for each client, providing the Client to the function and optional parameters. +----- Iterate the SET_BASE and call an interator function for each client, providing the Client to the function and optional parameters. ---- @param #SET_BASE self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_BASE. The function needs to accept a CLIENT parameter. ---- @return #SET_BASE self @@ -767,7 +834,7 @@ function SET_GROUP:ForEachGroupNotInZone( ZoneObject, IteratorFunction, ... ) end ------ Interate the SET_GROUP and call an interator function for each **alive** player, providing the Group of the player and optional parameters. +----- Iterate the SET_GROUP and call an interator function for each **alive** player, providing the Group of the player and optional parameters. ---- @param #SET_GROUP self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_GROUP. The function needs to accept a GROUP parameter. ---- @return #SET_GROUP self @@ -780,7 +847,7 @@ end --end -- -- ------ Interate the SET_GROUP and call an interator function for each client, providing the Client to the function and optional parameters. +----- Iterate the SET_GROUP and call an interator function for each client, providing the Client to the function and optional parameters. ---- @param #SET_GROUP self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_GROUP. The function needs to accept a CLIENT parameter. ---- @return #SET_GROUP self @@ -1074,7 +1141,7 @@ function SET_UNIT:FindInDatabase( Event ) return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName] end ---- Interate the SET_UNIT and call an interator function for each **alive** UNIT, providing the UNIT and optional parameters. +--- Iterate the SET_UNIT and call an interator function for each **alive** UNIT, providing the UNIT and optional parameters. -- @param #SET_UNIT self -- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the SET_UNIT. The function needs to accept a UNIT parameter. -- @return #SET_UNIT self @@ -1132,7 +1199,7 @@ end ------ Interate the SET_UNIT and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. +----- Iterate the SET_UNIT and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. ---- @param #SET_UNIT self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_UNIT. The function needs to accept a UNIT parameter. ---- @return #SET_UNIT self @@ -1145,7 +1212,7 @@ end --end -- -- ------ Interate the SET_UNIT and call an interator function for each client, providing the Client to the function and optional parameters. +----- Iterate the SET_UNIT and call an interator function for each client, providing the Client to the function and optional parameters. ---- @param #SET_UNIT self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_UNIT. The function needs to accept a CLIENT parameter. ---- @return #SET_UNIT self @@ -1447,7 +1514,7 @@ function SET_CLIENT:FindInDatabase( Event ) return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName] end ---- Interate the SET_CLIENT and call an interator function for each **alive** CLIENT, providing the CLIENT and optional parameters. +--- Iterate the SET_CLIENT and call an interator function for each **alive** CLIENT, providing the CLIENT and optional parameters. -- @param #SET_CLIENT self -- @param #function IteratorFunction The function that will be called when there is an alive CLIENT in the SET_CLIENT. The function needs to accept a CLIENT parameter. -- @return #SET_CLIENT self @@ -1583,3 +1650,226 @@ function SET_CLIENT:IsIncludeObject( MClient ) return MClientInclude end +--- SET_AIRBASE + +--- SET_AIRBASE class +-- @type SET_AIRBASE +-- @extends Set#SET_BASE +SET_AIRBASE = { + ClassName = "SET_AIRBASE", + Airbases = {}, + Filter = { + Coalitions = nil, + }, + FilterMeta = { + Coalitions = { + red = coalition.side.RED, + blue = coalition.side.BLUE, + neutral = coalition.side.NEUTRAL, + }, + Categories = { + airdrome = Airbase.Category.AIRDROME, + helipad = Airbase.Category.HELIPAD, + ship = Airbase.Category.SHIP, + }, + }, +} + + +--- Creates a new SET_AIRBASE object, building a set of airbases belonging to a coalitions and categories. +-- @param #SET_AIRBASE self +-- @return #SET_AIRBASE self +-- @usage +-- -- Define a new SET_AIRBASE Object. The DatabaseSet will contain a reference to all Airbases. +-- DatabaseSet = SET_AIRBASE:New() +function SET_AIRBASE:New() + -- Inherits from BASE + local self = BASE:Inherit( self, SET_BASE:New( _DATABASE.AIRBASES ) ) + + return self +end + +--- Add AIRBASEs to SET_AIRBASE. +-- @param Set#SET_AIRBASE self +-- @param #string AddAirbaseNames A single name or an array of AIRBASE names. +-- @return self +function SET_AIRBASE:AddAirbasesByName( AddAirbaseNames ) + + local AddAirbaseNamesArray = ( type( AddAirbaseNames ) == "table" ) and AddAirbaseNames or { AddAirbaseNames } + + for AddAirbaseID, AddAirbaseName in pairs( AddAirbaseNamesArray ) do + self:Add( AddAirbaseName, AIRBASE:FindByName( AddAirbaseName ) ) + end + + return self +end + +--- Remove AIRBASEs from SET_AIRBASE. +-- @param Set#SET_AIRBASE self +-- @param Airbase#AIRBASE RemoveAirbaseNames A single name or an array of AIRBASE names. +-- @return self +function SET_AIRBASE:RemoveAirbasesByName( RemoveAirbaseNames ) + + local RemoveAirbaseNamesArray = ( type( RemoveAirbaseNames ) == "table" ) and RemoveAirbaseNames or { RemoveAirbaseNames } + + for RemoveAirbaseID, RemoveAirbaseName in pairs( RemoveAirbaseNamesArray ) do + self:Remove( RemoveAirbaseName.AirbaseName ) + end + + return self +end + + +--- Finds a Airbase based on the Airbase Name. +-- @param #SET_AIRBASE self +-- @param #string AirbaseName +-- @return Airbase#AIRBASE The found Airbase. +function SET_AIRBASE:FindAirbase( AirbaseName ) + + local AirbaseFound = self.Set[AirbaseName] + return AirbaseFound +end + + + +--- Builds a set of airbases of coalitions. +-- Possible current coalitions are red, blue and neutral. +-- @param #SET_AIRBASE self +-- @param #string Coalitions Can take the following values: "red", "blue", "neutral". +-- @return #SET_AIRBASE self +function SET_AIRBASE:FilterCoalitions( Coalitions ) + if not self.Filter.Coalitions then + self.Filter.Coalitions = {} + end + if type( Coalitions ) ~= "table" then + Coalitions = { Coalitions } + end + for CoalitionID, Coalition in pairs( Coalitions ) do + self.Filter.Coalitions[Coalition] = Coalition + end + return self +end + + +--- Builds a set of airbases out of categories. +-- Possible current categories are plane, helicopter, ground, ship. +-- @param #SET_AIRBASE self +-- @param #string Categories Can take the following values: "airdrome", "helipad", "ship". +-- @return #SET_AIRBASE self +function SET_AIRBASE:FilterCategories( Categories ) + if not self.Filter.Categories then + self.Filter.Categories = {} + end + if type( Categories ) ~= "table" then + Categories = { Categories } + end + for CategoryID, Category in pairs( Categories ) do + self.Filter.Categories[Category] = Category + end + return self +end + +--- Starts the filtering. +-- @param #SET_AIRBASE self +-- @return #SET_AIRBASE self +function SET_AIRBASE:FilterStart() + + if _DATABASE then + self:_FilterStart() + end + + return self +end + + +--- 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! +-- @param #SET_AIRBASE self +-- @param Event#EVENTDATA Event +-- @return #string The name of the AIRBASE +-- @return #table The AIRBASE +function SET_AIRBASE:AddInDatabase( Event ) + self:F3( { Event } ) + + return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName] +end + +--- Handles the Database to check on any event that Object exists in the Database. +-- This is required, because sometimes the _DATABASE event gets called later than the SET_BASE event or vise versa! +-- @param #SET_AIRBASE self +-- @param Event#EVENTDATA Event +-- @return #string The name of the AIRBASE +-- @return #table The AIRBASE +function SET_AIRBASE:FindInDatabase( Event ) + self:F3( { Event } ) + + return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName] +end + +--- Iterate the SET_AIRBASE and call an interator function for each AIRBASE, providing the AIRBASE and optional parameters. +-- @param #SET_AIRBASE self +-- @param #function IteratorFunction The function that will be called when there is an alive AIRBASE in the SET_AIRBASE. The function needs to accept a AIRBASE parameter. +-- @return #SET_AIRBASE self +function SET_AIRBASE:ForEachAirbase( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.Set ) + + return self +end + +--- Iterate the SET_AIRBASE while identifying the nearest @{Airbase#AIRBASE} from a @{Point#POINT_VEC2}. +-- @param #SET_AIRBASE self +-- @param Point#POINT_VEC2 PointVec2 A @{Point#POINT_VEC2} object from where to evaluate the closest @{Airbase#AIRBASE}. +-- @return Airbase#AIRBASE The closest @{Airbase#AIRBASE}. +function SET_AIRBASE:FindNearestAirbaseFromPointVec2( PointVec2 ) + self:F2( PointVec2 ) + + local NearestAirbase = self:FindNearestObjectFromPointVec2( PointVec2 ) + return NearestAirbase +end + + + +--- +-- @param #SET_AIRBASE self +-- @param Airbase#AIRBASE MAirbase +-- @return #SET_AIRBASE self +function SET_AIRBASE:IsIncludeObject( MAirbase ) + self:F2( MAirbase ) + + local MAirbaseInclude = true + + if MAirbase then + local MAirbaseName = MAirbase:GetName() + + if self.Filter.Coalitions then + local MAirbaseCoalition = false + for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do + local AirbaseCoalitionID = _DATABASE:GetCoalitionFromAirbase( MAirbaseName ) + self:T3( { "Coalition:", AirbaseCoalitionID, self.FilterMeta.Coalitions[CoalitionName], CoalitionName } ) + if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == AirbaseCoalitionID then + MAirbaseCoalition = true + end + end + self:T( { "Evaluated Coalition", MAirbaseCoalition } ) + MAirbaseInclude = MAirbaseInclude and MAirbaseCoalition + end + + if self.Filter.Categories then + local MAirbaseCategory = false + for CategoryID, CategoryName in pairs( self.Filter.Categories ) do + local AirbaseCategoryID = _DATABASE:GetCategoryFromAirbase( MAirbaseName ) + self:T3( { "Category:", AirbaseCategoryID, self.FilterMeta.Categories[CategoryName], CategoryName } ) + if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == AirbaseCategoryID then + MAirbaseCategory = true + end + end + self:T( { "Evaluated Category", MAirbaseCategory } ) + MAirbaseInclude = MAirbaseInclude and MAirbaseCategory + end + end + + self:T2( MAirbaseInclude ) + return MAirbaseInclude +end diff --git a/Moose Development/Moose/Unit.lua b/Moose Development/Moose/Unit.lua index fd176d5e1..744336e03 100644 --- a/Moose Development/Moose/Unit.lua +++ b/Moose Development/Moose/Unit.lua @@ -736,6 +736,29 @@ function UNIT:GetCategoryName() return nil end +--- Returns the DCS Unit heading. +-- @param Unit#UNIT self +-- @return #number The DCS Unit heading +function UNIT:GetHeading() + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + + local UnitPosition = DCSUnit:getPosition() + if UnitPosition then + local UnitHeading = math.atan2( UnitPosition.x.z, UnitPosition.x.x ) + if UnitHeading < 0 then + UnitHeading = UnitHeading + 2 * math.pi + end + self:T2( UnitHeading ) + return UnitHeading + end + end + + return nil +end + + --- Signal a flare at the position of the UNIT. -- @param #UNIT self function UNIT:Flare( FlareColor ) diff --git a/Moose Mission Setup/Moose Mission Update/l10n/DEFAULT/Moose.lua b/Moose Mission Setup/Moose Mission Update/l10n/DEFAULT/Moose.lua index 9c8bf3739..5475e0413 100644 --- a/Moose Mission Setup/Moose Mission Update/l10n/DEFAULT/Moose.lua +++ b/Moose Mission Setup/Moose Mission Update/l10n/DEFAULT/Moose.lua @@ -1,5 +1,5 @@ env.info( '*** MOOSE STATIC INCLUDE START *** ' ) -env.info( 'Moose Generation Timestamp: 20160615_0641' ) +env.info( 'Moose Generation Timestamp: 20160617_2325' ) local base = _G Include = {} @@ -3150,8 +3150,8 @@ end -- -- * @{Scheduler#SCHEDULER.New}: Setup a new scheduler and start it with the specified parameters. -- --- SCHEDULER timer stop and start --- ------------------------------ +-- 1.2) SCHEDULER timer stop and start +-- ----------------------------------- -- The SCHEDULER can be stopped and restarted with the following methods: -- -- * @{Scheduler#SCHEDULER.Start}: (Re-)Start the scheduler. @@ -4246,6 +4246,7 @@ end -- * @{#GROUP.TaskRouteToVec2}: (AIR + GROUND) Make the Group move to a given point. -- * @{#GROUP.TaskRouteToVec3}: (AIR + GROUND) Make the Group move to a given point. -- * @{#GROUP.TaskRouteToZone}: (AIR + GROUND) Route the group to a given zone. +-- * @{#GROUP.TaskReturnToBase}: (AIR) Route the group to an airbase. -- -- ### 1.2.2) EnRoute task methods -- @@ -5231,6 +5232,24 @@ function GROUP:CommandSwitchWayPoint( FromWayPoint, ToWayPoint, Index ) return CommandSwitchWayPoint end +--- Perform stop route command +-- @param #GROUP self +-- @param #boolean StopRoute +-- @return DCSTask#Task +function GROUP:CommandStopRoute( StopRoute, Index ) + self:F2( { StopRoute, Index } ) + + local CommandStopRoute = { + id = 'StopRoute', + params = { + value = StopRoute, + }, + } + + self:T3( { CommandStopRoute } ) + return CommandStopRoute +end + -- TASKS FOR AIR GROUPS @@ -6397,6 +6416,125 @@ function GROUP:TaskRouteToZone( Zone, Randomize, Speed, Formation ) return nil end +--- (AIR) Return the Group to an @{Airbase#AIRBASE} +-- A speed can be given in km/h. +-- A given formation can be given. +-- @param #GROUP self +-- @param Airbase#AIRBASE ReturnAirbase The @{Airbase#AIRBASE} to return to. +-- @param #number Speed (optional) The speed. +-- @return #string The route +function GROUP:RouteReturnToAirbase( ReturnAirbase, Speed ) + self:F2( { ReturnAirbase, Speed } ) + +-- Example +-- [4] = +-- { +-- ["alt"] = 45, +-- ["type"] = "Land", +-- ["action"] = "Landing", +-- ["alt_type"] = "BARO", +-- ["formation_template"] = "", +-- ["properties"] = +-- { +-- ["vnav"] = 1, +-- ["scale"] = 0, +-- ["angle"] = 0, +-- ["vangle"] = 0, +-- ["steer"] = 2, +-- }, -- end of ["properties"] +-- ["ETA"] = 527.81058817743, +-- ["airdromeId"] = 12, +-- ["y"] = 243127.2973737, +-- ["x"] = -5406.2803440839, +-- ["name"] = "DictKey_WptName_53", +-- ["speed"] = 138.88888888889, +-- ["ETA_locked"] = false, +-- ["task"] = +-- { +-- ["id"] = "ComboTask", +-- ["params"] = +-- { +-- ["tasks"] = +-- { +-- }, -- end of ["tasks"] +-- }, -- end of ["params"] +-- }, -- end of ["task"] +-- ["speed_locked"] = true, +-- }, -- end of [4] + + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + + local GroupPoint = self:GetPointVec2() + local GroupVelocity = self:GetMaxVelocity() + + local PointFrom = {} + PointFrom.x = GroupPoint.x + PointFrom.y = GroupPoint.y + PointFrom.type = "Turning Point" + PointFrom.action = "Turning Point" + PointFrom.speed = GroupVelocity + + + local PointTo = {} + local AirbasePoint = ReturnAirbase:GetPointVec2() + + PointTo.x = AirbasePoint.x + PointTo.y = AirbasePoint.y + PointTo.type = "Land" + PointTo.action = "Landing" + PointTo.airdromeId = ReturnAirbase:GetID()-- Airdrome ID + self:T(PointTo.airdromeId) + --PointTo.alt = 0 + + local Points = { PointFrom, PointTo } + + self:T3( Points ) + + local Route = { points = Points, } + + return Route + end + + return nil +end + +--- @param Group#GROUP self +function GROUP:Respawn( Template ) + + local Vec3 = self:GetPointVec3() + --Template.x = Vec3.x + --Template.y = Vec3.z + Template.x = nil + Template.y = nil + + self:E( #Template.units ) + for UnitID, UnitData in pairs( self:GetUnits() ) do + local GroupUnit = UnitData -- Unit#UNIT + self:E( GroupUnit:GetName() ) + if GroupUnit:IsAlive() then + local GroupUnitVec3 = GroupUnit:GetPointVec3() + local GroupUnitHeading = GroupUnit:GetHeading() + Template.units[UnitID].alt = GroupUnitVec3.y + Template.units[UnitID].x = GroupUnitVec3.x + Template.units[UnitID].y = GroupUnitVec3.z + Template.units[UnitID].heading = GroupUnitHeading + self:E( { UnitID, Template.units[UnitID], Template.units[UnitID] } ) + end + end + + _DATABASE:Spawn( Template ) + +end + +function GROUP:GetTemplate() + + return _DATABASE.Templates.Groups[self:GetName()].Template + +end + -- Commands --- Do Script command @@ -7658,6 +7796,29 @@ function UNIT:GetCategoryName() return nil end +--- Returns the DCS Unit heading. +-- @param Unit#UNIT self +-- @return #number The DCS Unit heading +function UNIT:GetHeading() + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + + local UnitPosition = DCSUnit:getPosition() + if UnitPosition then + local UnitHeading = math.atan2( UnitPosition.x.z, UnitPosition.x.x ) + if UnitHeading < 0 then + UnitHeading = UnitHeading + 2 * math.pi + end + self:T2( UnitHeading ) + return UnitHeading + end + end + + return nil +end + + --- Signal a flare at the position of the UNIT. -- @param #UNIT self function UNIT:Flare( FlareColor ) @@ -8514,7 +8675,6 @@ end --- @param #CLIENT self function CLIENT:_AliveCheckScheduler( SchedulerName ) - self:E( SchedulerName ) self:F( { SchedulerName, self.ClientName, self.ClientAlive2, self.ClientBriefingShown, self.ClientCallBack } ) if self:IsAlive() then @@ -8837,10 +8997,320 @@ function STATIC:GetDCSUnit() return nil end ---- Manage the mission database. +--- This module contains the AIRBASE classes. -- --- @{#DATABASE} class --- ================== +-- === +-- +-- 1) @{Airbase#AIRBASE} class, extends @{Base#BASE} +-- ================================================= +-- The @{AIRBASE} class is a wrapper class to handle the DCS Airbase objects: +-- +-- * Support all DCS Airbase APIs. +-- * Enhance with Airbase specific APIs not in the DCS Airbase API set. +-- +-- +-- 1.1) AIRBASE reference methods +-- ------------------------------ +-- For each DCS Airbase object alive within a running mission, a AIRBASE wrapper object (instance) will be created within the _@{DATABASE} object. +-- This is done at the beginning of the mission (when the mission starts). +-- +-- The AIRBASE class **does not contain a :New()** method, rather it provides **:Find()** methods to retrieve the object reference +-- using the DCS Airbase or the DCS AirbaseName. +-- +-- Another thing to know is that AIRBASE objects do not "contain" the DCS Airbase object. +-- The AIRBASE methods will reference the DCS Airbase object by name when it is needed during API execution. +-- If the DCS Airbase object does not exist or is nil, the AIRBASE methods will return nil and log an exception in the DCS.log file. +-- +-- The AIRBASE class provides the following functions to retrieve quickly the relevant AIRBASE instance: +-- +-- * @{#AIRBASE.Find}(): Find a AIRBASE instance from the _DATABASE object using a DCS Airbase object. +-- * @{#AIRBASE.FindByName}(): Find a AIRBASE instance from the _DATABASE object using a DCS Airbase name. +-- +-- IMPORTANT: ONE SHOULD NEVER SANATIZE these AIRBASE OBJECT REFERENCES! (make the AIRBASE object references nil). +-- +-- 1.2) DCS AIRBASE APIs +-- --------------------- +-- The DCS Airbase APIs are used extensively within MOOSE. The AIRBASE class has for each DCS Airbase API a corresponding method. +-- To be able to distinguish easily in your code the difference between a AIRBASE API call and a DCS Airbase API call, +-- the first letter of the method is also capitalized. So, by example, the DCS Airbase method @{DCSAirbase#Airbase.getName}() +-- is implemented in the AIRBASE class as @{#AIRBASE.GetName}(). +-- +-- More functions will be added +-- ---------------------------- +-- During the MOOSE development, more functions will be added. +-- +-- @module Airbase +-- @author FlightControl + + + + + +--- The AIRBASE class +-- @type AIRBASE +-- @extends Base#BASE +AIRBASE = { + ClassName="AIRBASE", + CategoryName = { + [Airbase.Category.AIRDROME] = "Airdrome", + [Airbase.Category.HELIPAD] = "Helipad", + [Airbase.Category.SHIP] = "Ship", + }, + } + +-- Registration. + +--- Create a new AIRBASE from DCSAirbase. +-- @param #AIRBASE self +-- @param DCSAirbase#Airbase DCSAirbase +-- @param Database#DATABASE Database +-- @return Airbase#AIRBASE +function AIRBASE:Register( AirbaseName ) + + local self = BASE:Inherit( self, BASE:New() ) + self:F2( AirbaseName ) + self.AirbaseName = AirbaseName + return self +end + +-- Reference methods. + +--- Finds a AIRBASE from the _DATABASE using a DCSAirbase object. +-- @param #AIRBASE self +-- @param DCSAirbase#Airbase DCSAirbase An existing DCS Airbase object reference. +-- @return Airbase#AIRBASE self +function AIRBASE:Find( DCSAirbase ) + + local AirbaseName = DCSAirbase:getName() + local AirbaseFound = _DATABASE:FindAirbase( AirbaseName ) + return AirbaseFound +end + +--- Find a AIRBASE in the _DATABASE using the name of an existing DCS Airbase. +-- @param #AIRBASE self +-- @param #string AirbaseName The Airbase Name. +-- @return Airbase#AIRBASE self +function AIRBASE:FindByName( AirbaseName ) + + local AirbaseFound = _DATABASE:FindAirbase( AirbaseName ) + return AirbaseFound +end + +function AIRBASE:GetDCSAirbase() + local DCSAirbase = Airbase.getByName( self.AirbaseName ) + + if DCSAirbase then + return DCSAirbase + end + + return nil +end + +--- Returns coalition of the Airbase. +-- @param Airbase#AIRBASE self +-- @return DCSCoalitionObject#coalition.side The side of the coalition. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetCoalition() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseCoalition = DCSAirbase:getCoalition() + self:T3( AirbaseCoalition ) + return AirbaseCoalition + end + + return nil +end + +--- Returns country of the Airbase. +-- @param Airbase#AIRBASE self +-- @return DCScountry#country.id The country identifier. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetCountry() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseCountry = DCSAirbase:getCountry() + self:T3( AirbaseCountry ) + return AirbaseCountry + end + + return nil +end + + +--- Returns DCS Airbase object name. +-- The function provides access to non-activated units too. +-- @param Airbase#AIRBASE self +-- @return #string The name of the DCS Airbase. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetName() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseName = self.AirbaseName + return AirbaseName + end + + return nil +end + + +--- Returns if the airbase is alive. +-- @param Airbase#AIRBASE self +-- @return #boolean true if Airbase is alive. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:IsAlive() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseIsAlive = DCSAirbase:isExist() + return AirbaseIsAlive + end + + return false +end + +--- Returns the unit's unique identifier. +-- @param Airbase#AIRBASE self +-- @return DCSAirbase#Airbase.ID Airbase ID +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetID() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseID = DCSAirbase:getID() + return AirbaseID + end + + return nil +end + +--- Returns the Airbase's callsign - the localized string. +-- @param Airbase#AIRBASE self +-- @return #string The Callsign of the Airbase. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetCallSign() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseCallSign = DCSAirbase:getCallsign() + return AirbaseCallSign + end + + return nil +end + + + +--- Returns unit descriptor. Descriptor type depends on unit category. +-- @param Airbase#AIRBASE self +-- @return DCSAirbase#Airbase.Desc The Airbase descriptor. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetDesc() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseDesc = DCSAirbase:getDesc() + return AirbaseDesc + end + + return nil +end + + +--- Returns the type name of the DCS Airbase. +-- @param Airbase#AIRBASE self +-- @return #string The type name of the DCS Airbase. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetTypeName() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseTypeName = DCSAirbase:getTypeName() + self:T3( AirbaseTypeName ) + return AirbaseTypeName + end + + return nil +end + + +--- Returns the @{DCSTypes#Vec2} vector indicating the point in 2D of the DCS Airbase within the mission. +-- @param Airbase#AIRBASE self +-- @return DCSTypes#Vec2 The 2D point vector of the DCS Airbase. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetPointVec2() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbasePointVec3 = DCSAirbase:getPosition().p + + local AirbasePointVec2 = {} + AirbasePointVec2.x = AirbasePointVec3.x + AirbasePointVec2.y = AirbasePointVec3.z + + self:T3( AirbasePointVec2 ) + return AirbasePointVec2 + end + + return nil +end + +--- Returns the DCS Airbase category as defined within the DCS Airbase Descriptor. +-- @param Airbase#AIRBASE self +-- @return DCSAirbase#Airbase.Category The DCS Airbase Category +function AIRBASE:GetCategory() + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseCategory = self:GetDesc().category + return AirbaseCategory + end + + return nil +end + + +--- Returns the DCS Airbase category name as defined within the DCS Airbase Descriptor. +-- @param Airbase#AIRBASE self +-- @return #string The DCS Airbase Category Name +function AIRBASE:GetCategoryName() + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseCategoryName = self.CategoryName[ self:GetDesc().category ] + return AirbaseCategoryName + end + + return nil +end + + +--- This module contains the DATABASE class, managing the database of mission objects. +-- +-- ==== +-- +-- 1) @{Database#DATABASE} class, extends @{Base#BASE} +-- =================================================== -- Mission designers can use the DATABASE class to refer to: -- -- * UNITS @@ -8855,8 +9325,8 @@ end -- Moose will automatically create one instance of the DATABASE class into the **global** object _DATABASE. -- Moose refers to _DATABASE within the framework extensively, but you can also refer to the _DATABASE object within your missions if required. -- --- DATABASE iterators: --- =================== +-- 1.1) DATABASE iterators +-- ----------------------- -- You can iterate the database with the available iterator methods. -- The iterator methods will walk the DATABASE set, and call for each element within the set a function that you provide. -- The following iterator methods are currently available within the DATABASE: @@ -8871,17 +9341,6 @@ end -- @module Database -- @author FlightControl - - - - - - - - - - - --- DATABASE class -- @type DATABASE -- @extends Base#BASE @@ -8900,6 +9359,7 @@ DATABASE = { PLAYERSALIVE = {}, CLIENTS = {}, CLIENTSALIVE = {}, + AIRBASES = {}, NavPoints = {}, } @@ -8944,6 +9404,7 @@ function DATABASE:New() self:_RegisterClients() self:_RegisterStatics() self:_RegisterPlayers() + self:_RegisterAirbases() return self end @@ -9005,6 +9466,33 @@ function DATABASE:FindStatic( StaticName ) return StaticFound end +--- Adds a Airbase based on the Airbase Name in the DATABASE. +-- @param #DATABASE self +function DATABASE:AddAirbase( DCSAirbaseName ) + + if not self.AIRBASES[DCSAirbaseName] then + self.AIRBASES[DCSAirbaseName] = AIRBASE:Register( DCSAirbaseName ) + end +end + + +--- Deletes a Airbase from the DATABASE based on the Airbase Name. +-- @param #DATABASE self +function DATABASE:DeleteAirbase( DCSAirbaseName ) + + --self.AIRBASES[DCSAirbaseName] = nil +end + +--- Finds a AIRBASE based on the AirbaseName. +-- @param #DATABASE self +-- @param #string AirbaseName +-- @return Airbase#AIRBASE The found AIRBASE. +function DATABASE:FindAirbase( AirbaseName ) + + local AirbaseFound = self.AIRBASES[AirbaseName] + return AirbaseFound +end + --- Finds a CLIENT based on the ClientName. -- @param #DATABASE self @@ -9210,6 +9698,18 @@ function DATABASE:GetCountryFromClientTemplate( ClientName ) return self.Templates.ClientsByName[ClientName].CountryID end +--- Airbase + +function DATABASE:GetCoalitionFromAirbase( AirbaseName ) + return self.AIRBASES[AirbaseName]:GetCoalition() +end + +function DATABASE:GetCategoryFromAirbase( AirbaseName ) + return self.AIRBASES[AirbaseName]:GetCategory() +end + + + --- Private method that registers all alive players in the mission. -- @param #DATABASE self -- @return #DATABASE self @@ -9278,6 +9778,7 @@ function DATABASE:_RegisterClients() return self end +--- @param #DATABASE self function DATABASE:_RegisterStatics() local CoalitionsData = { GroupsRed = coalition.getStaticObjects( coalition.side.RED ), GroupsBlue = coalition.getStaticObjects( coalition.side.BLUE ) } @@ -9298,6 +9799,23 @@ function DATABASE:_RegisterStatics() return self end +--- @param #DATABASE self +function DATABASE:_RegisterAirbases() + + local CoalitionsData = { AirbasesRed = coalition.getAirbases( coalition.side.RED ), AirbasesBlue = coalition.getAirbases( coalition.side.BLUE ), AirbasesNeutral = coalition.getAirbases( coalition.side.NEUTRAL ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + for DCSAirbaseId, DCSAirbase in pairs( CoalitionData ) do + + local DCSAirbaseName = DCSAirbase:getName() + + self:E( { "Register Airbase:", DCSAirbaseName } ) + self:AddAirbase( DCSAirbaseName ) + end + end + + return self +end + --- Events @@ -9365,7 +9883,7 @@ end -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive player in the database. -- @return #DATABASE self -function DATABASE:ForEach( IteratorFunction, arg, Set ) +function DATABASE:ForEach( IteratorFunction, FinalizeFunction, arg, Set ) self:F2( arg ) local function CoRoutine() @@ -9386,7 +9904,7 @@ function DATABASE:ForEach( IteratorFunction, arg, Set ) local function Schedule() local status, res = coroutine.resume( co ) - self:T2( { status, res } ) + self:T3( { status, res } ) if status == false then error( res ) @@ -9394,7 +9912,9 @@ function DATABASE:ForEach( IteratorFunction, arg, Set ) if res == false then return true -- resume next time the loop end - + if FinalizeFunction then + FinalizeFunction( unpack( arg ) ) + end return false end @@ -9408,10 +9928,10 @@ end -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the database. The function needs to accept a UNIT parameter. -- @return #DATABASE self -function DATABASE:ForEachUnit( IteratorFunction, ... ) +function DATABASE:ForEachUnit( IteratorFunction, FinalizeFunction, ... ) self:F2( arg ) - self:ForEach( IteratorFunction, arg, self.UNITS ) + self:ForEach( IteratorFunction, FinalizeFunction, arg, self.UNITS ) return self end @@ -9558,7 +10078,7 @@ end -- === -- -- 1) @{Set#SET_BASE} class, extends @{Base#BASE} --- ================================================ +-- ============================================== -- The @{Set#SET_BASE} class defines the core functions that define a collection of objects. -- A SET provides iterators to iterate the SET, but will **temporarily** yield the ForEach interator loop at defined **"intervals"** to the mail simulator loop. -- In this way, large loops can be done while not blocking the simulator main processing loop. @@ -9569,15 +10089,15 @@ end -- --------------------------------------- -- Some key core functions are @{Set#SET_BASE.Add} and @{Set#SET_BASE.Remove} to add or remove objects from the SET in your logic. -- --- 1.2) Define the SET iterator **"yield interval"** and the **"time interval"**. --- ------------------------------------------------------------------------------------- +-- 1.2) Define the SET iterator **"yield interval"** and the **"time interval"** +-- ----------------------------------------------------------------------------- -- Modify the iterator intervals with the @{Set#SET_BASE.SetInteratorIntervals} method. -- You can set the **"yield interval"**, and the **"time interval"**. (See above). -- -- === -- -- 2) @{Set#SET_GROUP} class, extends @{Set#SET_BASE} --- ==================================================== +-- ================================================== -- Mission designers can use the @{Set#SET_GROUP} class to build sets of groups belonging to certain: -- -- * Coalitions @@ -9683,6 +10203,8 @@ end -- * @{#SET_UNIT.ForEachUnitCompletelyInZone}: Iterate and call an iterator function for each **alive** UNIT presence completely in a @{Zone}, providing the UNIT and optional parameters to the called function. -- * @{#SET_UNIT.ForEachUnitNotInZone}: Iterate and call an iterator function for each **alive** UNIT presence not in a @{Zone}, providing the UNIT and optional parameters to the called function. -- +-- === +-- -- 4) @{Set#SET_CLIENT} class, extends @{Set#SET_BASE} -- =================================================== -- Mission designers can use the @{Set#SET_CLIENT} class to build sets of units belonging to certain: @@ -9733,9 +10255,48 @@ end -- -- ==== -- +-- 5) @{Set#SET_AIRBASE} class, extends @{Set#SET_BASE} +-- ==================================================== +-- Mission designers can use the @{Set#SET_AIRBASE} class to build sets of airbases optionally belonging to certain: +-- +-- * Coalitions +-- +-- 5.1) SET_AIRBASE construction +-- ----------------------------- +-- Create a new SET_AIRBASE object with the @{#SET_AIRBASE.New} method: +-- +-- * @{#SET_AIRBASE.New}: Creates a new SET_AIRBASE object. +-- +-- 5.2) Add or Remove AIRBASEs from SET_AIRBASE +-- -------------------------------------------- +-- AIRBASEs can be added and removed using the @{Set#SET_AIRBASE.AddAirbasesByName} and @{Set#SET_AIRBASE.RemoveAirbasesByName} respectively. +-- These methods take a single AIRBASE name or an array of AIRBASE names to be added or removed from SET_AIRBASE. +-- +-- 5.3) SET_AIRBASE filter criteria +-- -------------------------------- +-- You can set filter criteria to define the set of clients within the SET_AIRBASE. +-- Filter criteria are defined by: +-- +-- * @{#SET_AIRBASE.FilterCoalitions}: Builds the SET_AIRBASE with the airbases belonging to the coalition(s). +-- +-- Once the filter criteria have been set for the SET_AIRBASE, you can start filtering using: +-- +-- * @{#SET_AIRBASE.FilterStart}: Starts the filtering of the airbases within the SET_AIRBASE. +-- +-- 5.4) SET_AIRBASE iterators: +-- --------------------------- +-- Once the filters have been defined and the SET_AIRBASE has been built, you can iterate the SET_AIRBASE with the available iterator methods. +-- The iterator methods will walk the SET_AIRBASE set, and call for each airbase within the set a function that you provide. +-- The following iterator methods are currently available within the SET_AIRBASE: +-- +-- * @{#SET_AIRBASE.ForEachAirbase}: Calls a function for each airbase it finds within the SET_AIRBASE. +-- +-- ==== +-- -- @module Set -- @author FlightControl + --- SET_BASE class -- @type SET_BASE -- @extends Base#BASE @@ -9834,6 +10395,32 @@ function SET_BASE:_FilterStart() return self end +--- Iterate the SET_BASE while identifying the nearest object from a @{Point#POINT_VEC2}. +-- @param #SET_BASE self +-- @param Point#POINT_VEC2 PointVec2 A @{Point#POINT_VEC2} object from where to evaluate the closest object in the set. +-- @return Base#BASE The closest object. +function SET_BASE:FindNearestObjectFromPointVec2( PointVec2 ) + self:F2( PointVec2 ) + + local NearestObject = nil + local ClosestDistance = nil + + for ObjectID, ObjectData in pairs( self.Set ) do + if NearestObject == nil then + NearestObject = ObjectData + ClosestDistance = PointVec2:DistanceFromVec2( ObjectData:GetPointVec2() ) + else + local Distance = PointVec2:DistanceFromVec2( ObjectData:GetPointVec2() ) + if Distance < ClosestDistance then + NearestObject = ObjectData + ClosestDistance = Distance + end + end + end + + return NearestObject +end + ----- Private method that registers all alive players in the mission. @@ -9975,7 +10562,7 @@ function SET_BASE:ForEach( IteratorFunction, arg, Set, Function, FunctionArgumen end ------ Interate the SET_BASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. +----- Iterate the SET_BASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. ---- @param #SET_BASE self ---- @param #function IteratorFunction The function that will be called when there is an alive unit in the SET_BASE. The function needs to accept a UNIT parameter. ---- @return #SET_BASE self @@ -9987,7 +10574,7 @@ end -- return self --end -- ------ Interate the SET_BASE and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. +----- Iterate the SET_BASE and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. ---- @param #SET_BASE self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_BASE. The function needs to accept a UNIT parameter. ---- @return #SET_BASE self @@ -10000,7 +10587,7 @@ end --end -- -- ------ Interate the SET_BASE and call an interator function for each client, providing the Client to the function and optional parameters. +----- Iterate the SET_BASE and call an interator function for each client, providing the Client to the function and optional parameters. ---- @param #SET_BASE self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_BASE. The function needs to accept a CLIENT parameter. ---- @return #SET_BASE self @@ -10322,7 +10909,7 @@ function SET_GROUP:ForEachGroupNotInZone( ZoneObject, IteratorFunction, ... ) end ------ Interate the SET_GROUP and call an interator function for each **alive** player, providing the Group of the player and optional parameters. +----- Iterate the SET_GROUP and call an interator function for each **alive** player, providing the Group of the player and optional parameters. ---- @param #SET_GROUP self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_GROUP. The function needs to accept a GROUP parameter. ---- @return #SET_GROUP self @@ -10335,7 +10922,7 @@ end --end -- -- ------ Interate the SET_GROUP and call an interator function for each client, providing the Client to the function and optional parameters. +----- Iterate the SET_GROUP and call an interator function for each client, providing the Client to the function and optional parameters. ---- @param #SET_GROUP self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_GROUP. The function needs to accept a CLIENT parameter. ---- @return #SET_GROUP self @@ -10629,7 +11216,7 @@ function SET_UNIT:FindInDatabase( Event ) return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName] end ---- Interate the SET_UNIT and call an interator function for each **alive** UNIT, providing the UNIT and optional parameters. +--- Iterate the SET_UNIT and call an interator function for each **alive** UNIT, providing the UNIT and optional parameters. -- @param #SET_UNIT self -- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the SET_UNIT. The function needs to accept a UNIT parameter. -- @return #SET_UNIT self @@ -10687,7 +11274,7 @@ end ------ Interate the SET_UNIT and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. +----- Iterate the SET_UNIT and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. ---- @param #SET_UNIT self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_UNIT. The function needs to accept a UNIT parameter. ---- @return #SET_UNIT self @@ -10700,7 +11287,7 @@ end --end -- -- ------ Interate the SET_UNIT and call an interator function for each client, providing the Client to the function and optional parameters. +----- Iterate the SET_UNIT and call an interator function for each client, providing the Client to the function and optional parameters. ---- @param #SET_UNIT self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_UNIT. The function needs to accept a CLIENT parameter. ---- @return #SET_UNIT self @@ -11002,7 +11589,7 @@ function SET_CLIENT:FindInDatabase( Event ) return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName] end ---- Interate the SET_CLIENT and call an interator function for each **alive** CLIENT, providing the CLIENT and optional parameters. +--- Iterate the SET_CLIENT and call an interator function for each **alive** CLIENT, providing the CLIENT and optional parameters. -- @param #SET_CLIENT self -- @param #function IteratorFunction The function that will be called when there is an alive CLIENT in the SET_CLIENT. The function needs to accept a CLIENT parameter. -- @return #SET_CLIENT self @@ -11138,6 +11725,229 @@ function SET_CLIENT:IsIncludeObject( MClient ) return MClientInclude end +--- SET_AIRBASE + +--- SET_AIRBASE class +-- @type SET_AIRBASE +-- @extends Set#SET_BASE +SET_AIRBASE = { + ClassName = "SET_AIRBASE", + Airbases = {}, + Filter = { + Coalitions = nil, + }, + FilterMeta = { + Coalitions = { + red = coalition.side.RED, + blue = coalition.side.BLUE, + neutral = coalition.side.NEUTRAL, + }, + Categories = { + airdrome = Airbase.Category.AIRDROME, + helipad = Airbase.Category.HELIPAD, + ship = Airbase.Category.SHIP, + }, + }, +} + + +--- Creates a new SET_AIRBASE object, building a set of airbases belonging to a coalitions and categories. +-- @param #SET_AIRBASE self +-- @return #SET_AIRBASE self +-- @usage +-- -- Define a new SET_AIRBASE Object. The DatabaseSet will contain a reference to all Airbases. +-- DatabaseSet = SET_AIRBASE:New() +function SET_AIRBASE:New() + -- Inherits from BASE + local self = BASE:Inherit( self, SET_BASE:New( _DATABASE.AIRBASES ) ) + + return self +end + +--- Add AIRBASEs to SET_AIRBASE. +-- @param Set#SET_AIRBASE self +-- @param #string AddAirbaseNames A single name or an array of AIRBASE names. +-- @return self +function SET_AIRBASE:AddAirbasesByName( AddAirbaseNames ) + + local AddAirbaseNamesArray = ( type( AddAirbaseNames ) == "table" ) and AddAirbaseNames or { AddAirbaseNames } + + for AddAirbaseID, AddAirbaseName in pairs( AddAirbaseNamesArray ) do + self:Add( AddAirbaseName, AIRBASE:FindByName( AddAirbaseName ) ) + end + + return self +end + +--- Remove AIRBASEs from SET_AIRBASE. +-- @param Set#SET_AIRBASE self +-- @param Airbase#AIRBASE RemoveAirbaseNames A single name or an array of AIRBASE names. +-- @return self +function SET_AIRBASE:RemoveAirbasesByName( RemoveAirbaseNames ) + + local RemoveAirbaseNamesArray = ( type( RemoveAirbaseNames ) == "table" ) and RemoveAirbaseNames or { RemoveAirbaseNames } + + for RemoveAirbaseID, RemoveAirbaseName in pairs( RemoveAirbaseNamesArray ) do + self:Remove( RemoveAirbaseName.AirbaseName ) + end + + return self +end + + +--- Finds a Airbase based on the Airbase Name. +-- @param #SET_AIRBASE self +-- @param #string AirbaseName +-- @return Airbase#AIRBASE The found Airbase. +function SET_AIRBASE:FindAirbase( AirbaseName ) + + local AirbaseFound = self.Set[AirbaseName] + return AirbaseFound +end + + + +--- Builds a set of airbases of coalitions. +-- Possible current coalitions are red, blue and neutral. +-- @param #SET_AIRBASE self +-- @param #string Coalitions Can take the following values: "red", "blue", "neutral". +-- @return #SET_AIRBASE self +function SET_AIRBASE:FilterCoalitions( Coalitions ) + if not self.Filter.Coalitions then + self.Filter.Coalitions = {} + end + if type( Coalitions ) ~= "table" then + Coalitions = { Coalitions } + end + for CoalitionID, Coalition in pairs( Coalitions ) do + self.Filter.Coalitions[Coalition] = Coalition + end + return self +end + + +--- Builds a set of airbases out of categories. +-- Possible current categories are plane, helicopter, ground, ship. +-- @param #SET_AIRBASE self +-- @param #string Categories Can take the following values: "airdrome", "helipad", "ship". +-- @return #SET_AIRBASE self +function SET_AIRBASE:FilterCategories( Categories ) + if not self.Filter.Categories then + self.Filter.Categories = {} + end + if type( Categories ) ~= "table" then + Categories = { Categories } + end + for CategoryID, Category in pairs( Categories ) do + self.Filter.Categories[Category] = Category + end + return self +end + +--- Starts the filtering. +-- @param #SET_AIRBASE self +-- @return #SET_AIRBASE self +function SET_AIRBASE:FilterStart() + + if _DATABASE then + self:_FilterStart() + end + + return self +end + + +--- 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! +-- @param #SET_AIRBASE self +-- @param Event#EVENTDATA Event +-- @return #string The name of the AIRBASE +-- @return #table The AIRBASE +function SET_AIRBASE:AddInDatabase( Event ) + self:F3( { Event } ) + + return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName] +end + +--- Handles the Database to check on any event that Object exists in the Database. +-- This is required, because sometimes the _DATABASE event gets called later than the SET_BASE event or vise versa! +-- @param #SET_AIRBASE self +-- @param Event#EVENTDATA Event +-- @return #string The name of the AIRBASE +-- @return #table The AIRBASE +function SET_AIRBASE:FindInDatabase( Event ) + self:F3( { Event } ) + + return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName] +end + +--- Iterate the SET_AIRBASE and call an interator function for each AIRBASE, providing the AIRBASE and optional parameters. +-- @param #SET_AIRBASE self +-- @param #function IteratorFunction The function that will be called when there is an alive AIRBASE in the SET_AIRBASE. The function needs to accept a AIRBASE parameter. +-- @return #SET_AIRBASE self +function SET_AIRBASE:ForEachAirbase( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.Set ) + + return self +end + +--- Iterate the SET_AIRBASE while identifying the nearest @{Airbase#AIRBASE} from a @{Point#POINT_VEC2}. +-- @param #SET_AIRBASE self +-- @param Point#POINT_VEC2 PointVec2 A @{Point#POINT_VEC2} object from where to evaluate the closest @{Airbase#AIRBASE}. +-- @return Airbase#AIRBASE The closest @{Airbase#AIRBASE}. +function SET_AIRBASE:FindNearestAirbaseFromPointVec2( PointVec2 ) + self:F2( PointVec2 ) + + local NearestAirbase = self:FindNearestObjectFromPointVec2( PointVec2 ) + return NearestAirbase +end + + + +--- +-- @param #SET_AIRBASE self +-- @param Airbase#AIRBASE MAirbase +-- @return #SET_AIRBASE self +function SET_AIRBASE:IsIncludeObject( MAirbase ) + self:F2( MAirbase ) + + local MAirbaseInclude = true + + if MAirbase then + local MAirbaseName = MAirbase:GetName() + + if self.Filter.Coalitions then + local MAirbaseCoalition = false + for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do + local AirbaseCoalitionID = _DATABASE:GetCoalitionFromAirbase( MAirbaseName ) + self:T3( { "Coalition:", AirbaseCoalitionID, self.FilterMeta.Coalitions[CoalitionName], CoalitionName } ) + if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == AirbaseCoalitionID then + MAirbaseCoalition = true + end + end + self:T( { "Evaluated Coalition", MAirbaseCoalition } ) + MAirbaseInclude = MAirbaseInclude and MAirbaseCoalition + end + + if self.Filter.Categories then + local MAirbaseCategory = false + for CategoryID, CategoryName in pairs( self.Filter.Categories ) do + local AirbaseCategoryID = _DATABASE:GetCategoryFromAirbase( MAirbaseName ) + self:T3( { "Category:", AirbaseCategoryID, self.FilterMeta.Categories[CategoryName], CategoryName } ) + if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == AirbaseCategoryID then + MAirbaseCategory = true + end + end + self:T( { "Evaluated Category", MAirbaseCategory } ) + MAirbaseInclude = MAirbaseInclude and MAirbaseCategory + end + end + + self:T2( MAirbaseInclude ) + return MAirbaseInclude +end --- This module contains the POINT classes. -- -- 1) @{Point#POINT_VEC3} class, extends @{Base#BASE} @@ -11304,6 +12114,7 @@ end --- The POINT_VEC2 class -- @type POINT_VEC2 +-- @field DCSTypes#Vec2 PointVec2 -- @extends Point#POINT_VEC3 POINT_VEC2 = { ClassName = "POINT_VEC2", @@ -11324,10 +12135,38 @@ function POINT_VEC2:New( x, y, LandHeightAdd ) local self = BASE:Inherit( self, POINT_VEC3:New( x, LandHeight, y ) ) self:F2( { x, y, LandHeightAdd } ) + + self.PointVec2 = { x = x, y = y } return self end +--- Calculate the distance from a reference @{Point#POINT_VEC2}. +-- @param #POINT_VEC2 self +-- @param #POINT_VEC2 PointVec2Reference The reference @{Point#POINT_VEC2}. +-- @return DCSTypes#Distance The distance from the reference @{Point#POINT_VEC2} in meters. +function POINT_VEC2:DistanceFromPointVec2( PointVec2Reference ) + self:F2( PointVec2Reference ) + + local Distance = ( ( PointVec2Reference.PointVec2.x - self.PointVec2.x ) ^ 2 + ( PointVec2Reference.PointVec2.y - self.PointVec2.y ) ^2 ) ^0.5 + + self:T2( Distance ) + return Distance +end + +--- Calculate the distance from a reference @{DCSTypes#Vec2}. +-- @param #POINT_VEC2 self +-- @param DCSTypes#Vec2 Vec2Reference The reference @{DCSTypes#Vec2}. +-- @return DCSTypes#Distance The distance from the reference @{DCSTypes#Vec2} in meters. +function POINT_VEC2:DistanceFromVec2( Vec2Reference ) + self:F2( Vec2Reference ) + + local Distance = ( ( Vec2Reference.x - self.PointVec2.x ) ^ 2 + ( Vec2Reference.y - self.PointVec2.y ) ^2 ) ^0.5 + + self:T2( Distance ) + return Distance +end + --- The main include file for the MOOSE system. @@ -11341,6 +12180,7 @@ Include.File( "Unit" ) Include.File( "Zone" ) Include.File( "Client" ) Include.File( "Static" ) +Include.File( "Airbase" ) Include.File( "Database" ) Include.File( "Set" ) Include.File( "Point" ) @@ -11369,40 +12209,6 @@ Include.File( "MissileTrainer" ) Include.File( "AIBalancer" ) Include.File( "AirbasePolice" ) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- The order of the declarations is important here. Don't touch it. --- Declare the event dispatcher based on the EVENT class @@ -20147,6 +20953,12 @@ end -- -- * @{#AIBALANCER.New}: Creates a new AIBALANCER object. -- +-- 1.2) AIBALANCER return AI to Airbases: +-- -------------------------------------- +-- You can configure to have the AI to return to: +-- +-- * @{#AIBALANCER.ReturnToHomeAirbase}: Returns the AI to the home @{Airbase#AIRBASE}. +-- * @{#AIBALANCER.ReturnToNearestAirbases}: Returns the AI to the nearest friendly @{Airbase#AIRBASE}. -- -- === -- @module AIBalancer @@ -20156,6 +20968,10 @@ end -- @type AIBALANCER -- @field Set#SET_CLIENT SetClient -- @field Spawn#SPAWN SpawnAI +-- @field #boolean ReturnToAirbase +-- @field Set#SET_AIRBASE ReturnAirbaseSet +-- @field DCSTypes#Distance ReturnTresholdRange +-- @field #boolean ReturnToHomeAirbase -- @extends Base#BASE AIBALANCER = { ClassName = "AIBALANCER", @@ -20172,13 +20988,55 @@ function AIBALANCER:New( SetClient, SpawnAI ) local self = BASE:Inherit( self, BASE:New() ) self.SetClient = SetClient - self.SpawnAI = SpawnAI + if type( SpawnAI ) == "table" then + if SpawnAI.ClassName and SpawnAI.ClassName == "SPAWN" then + self.SpawnAI = { SpawnAI } + else + local SpawnObjects = true + for SpawnObjectID, SpawnObject in pairs( SpawnAI ) do + if SpawnObject.ClassName and SpawnObject.ClassName == "SPAWN" then + self:E( SpawnObject.ClassName ) + else + self:E( "other object" ) + SpawnObjects = false + end + end + if SpawnObjects == true then + self.SpawnAI = SpawnAI + else + error( "No SPAWN object given in parameter SpawnAI, either as a single object or as a table of objects!" ) + end + end + end + + self.ReturnToAirbase = false + self.ReturnHomeAirbase = false self.AIMonitorSchedule = SCHEDULER:New( self, self._ClientAliveMonitorScheduler, {}, 1, 10, 0 ) return self end +--- Returns the AI to the nearest friendly @{Airbase#AIRBASE}. +-- @param #AIBALANCER self +-- @param DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Airbase#AIRBASE}. +-- @param Set#SET_AIRBASE ReturnAirbaseSet The SET of @{Set#SET_AIRBASE}s to evaluate where to return to. +function AIBALANCER:ReturnToNearestAirbases( ReturnTresholdRange, ReturnAirbaseSet ) + + self.ReturnToAirbase = true + self.ReturnTresholdRange = ReturnTresholdRange + self.ReturnAirbaseSet = ReturnAirbaseSet +end + +--- Returns the AI to the home @{Airbase#AIRBASE}. +-- @param #AIBALANCER self +-- @param DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Airbase#AIRBASE}. +function AIBALANCER:ReturnToHomeAirbase( ReturnTresholdRange ) + + self.ReturnToHomeAirbase = true + self.ReturnTresholdRange = ReturnTresholdRange +end + --- @param #AIBALANCER self function AIBALANCER:_ClientAliveMonitorScheduler() @@ -20190,13 +21048,70 @@ function AIBALANCER:_ClientAliveMonitorScheduler() if Client:IsAlive() then if ClientAIAliveState == true then Client:SetState( self, 'AIAlive', false ) + local AIGroup = Client:GetState( self, 'AIGroup' ) -- Group#GROUP - AIGroup:Destroy() + + if self.ReturnToAirbase == false and self.ReturnToHomeAirbase == false then + AIGroup:Destroy() + else + -- We test if there is no other CLIENT within the self.ReturnTresholdRange of the first unit of the AI group. + -- If there is a CLIENT, the AI stays engaged and will not return. + -- If there is no CLIENT within the self.ReturnTresholdRange, then the unit will return to the Airbase return method selected. + + local ClientInZone = { Value = false } + local RangeZone = ZONE_RADIUS:New( 'RangeZone', AIGroup:GetPointVec2(), self.ReturnTresholdRange ) + + self:E( RangeZone ) + + _DATABASE:ForEachUnit( + --- @param Unit#UNIT RangeTestUnit + function( RangeTestUnit, RangeZone, AIGroup, ClientInZone ) + self:E( { ClientInZone, RangeTestUnit.UnitName, RangeZone.ZoneName } ) + if RangeTestUnit:IsInZone( RangeZone ) == true then + self:E( "in zone" ) + if RangeTestUnit:GetCoalition() ~= AIGroup:GetCoalition() then + self:E( "in range" ) + ClientInZone.Value = true + end + end + end, + + --- @param Zone#ZONE_RADIUS RangeZone + -- @param Group#GROUP AIGroup + function( RangeZone, AIGroup, ClientInZone ) + local AIGroupTemplate = AIGroup:GetTemplate() + if ClientInZone.Value == false then + if self.ReturnToHomeAirbase == true then + local WayPointCount = #AIGroupTemplate.route.points + local SwitchWayPointCommand = AIGroup:CommandSwitchWayPoint( 1, WayPointCount, 1 ) + AIGroup:SetCommand( SwitchWayPointCommand ) + AIGroup:MessageToRed( "Returning to home base ...", 30 ) + else + -- Okay, we need to send this Group back to the nearest base of the Coalition of the AI. + --TODO: i need to rework the POINT_VEC2 thing. + local PointVec2 = POINT_VEC2:New( AIGroup:GetPointVec2().x, AIGroup:GetPointVec2().y ) + local ClosestAirbase = self.ReturnAirbaseSet:FindNearestAirbaseFromPointVec2( PointVec2 ) + self:T( ClosestAirbase.AirbaseName ) + AIGroup:MessageToRed( "Returning to " .. ClosestAirbase:GetName().. " ...", 30 ) + local RTBRoute = AIGroup:RouteReturnToAirbase( ClosestAirbase ) + AIGroupTemplate.route = RTBRoute + AIGroup:Respawn( AIGroupTemplate ) + end + end + end + , RangeZone, AIGroup, ClientInZone + ) + + end end else if not ClientAIAliveState or ClientAIAliveState == false then Client:SetState( self, 'AIAlive', true ) - Client:SetState( self, 'AIGroup', self.SpawnAI:Spawn() ) + + -- OK, spawn a new group from the SpawnAI objects provided. + local SpawnAICount = #self.SpawnAI + local SpawnAIIndex = math.random( 1, SpawnAICount ) + Client:SetState( self, 'AIGroup', self.SpawnAI[SpawnAIIndex]:Spawn() ) end end end diff --git a/Moose Mission Setup/Moose.lua b/Moose Mission Setup/Moose.lua index 9c8bf3739..5475e0413 100644 --- a/Moose Mission Setup/Moose.lua +++ b/Moose Mission Setup/Moose.lua @@ -1,5 +1,5 @@ env.info( '*** MOOSE STATIC INCLUDE START *** ' ) -env.info( 'Moose Generation Timestamp: 20160615_0641' ) +env.info( 'Moose Generation Timestamp: 20160617_2325' ) local base = _G Include = {} @@ -3150,8 +3150,8 @@ end -- -- * @{Scheduler#SCHEDULER.New}: Setup a new scheduler and start it with the specified parameters. -- --- SCHEDULER timer stop and start --- ------------------------------ +-- 1.2) SCHEDULER timer stop and start +-- ----------------------------------- -- The SCHEDULER can be stopped and restarted with the following methods: -- -- * @{Scheduler#SCHEDULER.Start}: (Re-)Start the scheduler. @@ -4246,6 +4246,7 @@ end -- * @{#GROUP.TaskRouteToVec2}: (AIR + GROUND) Make the Group move to a given point. -- * @{#GROUP.TaskRouteToVec3}: (AIR + GROUND) Make the Group move to a given point. -- * @{#GROUP.TaskRouteToZone}: (AIR + GROUND) Route the group to a given zone. +-- * @{#GROUP.TaskReturnToBase}: (AIR) Route the group to an airbase. -- -- ### 1.2.2) EnRoute task methods -- @@ -5231,6 +5232,24 @@ function GROUP:CommandSwitchWayPoint( FromWayPoint, ToWayPoint, Index ) return CommandSwitchWayPoint end +--- Perform stop route command +-- @param #GROUP self +-- @param #boolean StopRoute +-- @return DCSTask#Task +function GROUP:CommandStopRoute( StopRoute, Index ) + self:F2( { StopRoute, Index } ) + + local CommandStopRoute = { + id = 'StopRoute', + params = { + value = StopRoute, + }, + } + + self:T3( { CommandStopRoute } ) + return CommandStopRoute +end + -- TASKS FOR AIR GROUPS @@ -6397,6 +6416,125 @@ function GROUP:TaskRouteToZone( Zone, Randomize, Speed, Formation ) return nil end +--- (AIR) Return the Group to an @{Airbase#AIRBASE} +-- A speed can be given in km/h. +-- A given formation can be given. +-- @param #GROUP self +-- @param Airbase#AIRBASE ReturnAirbase The @{Airbase#AIRBASE} to return to. +-- @param #number Speed (optional) The speed. +-- @return #string The route +function GROUP:RouteReturnToAirbase( ReturnAirbase, Speed ) + self:F2( { ReturnAirbase, Speed } ) + +-- Example +-- [4] = +-- { +-- ["alt"] = 45, +-- ["type"] = "Land", +-- ["action"] = "Landing", +-- ["alt_type"] = "BARO", +-- ["formation_template"] = "", +-- ["properties"] = +-- { +-- ["vnav"] = 1, +-- ["scale"] = 0, +-- ["angle"] = 0, +-- ["vangle"] = 0, +-- ["steer"] = 2, +-- }, -- end of ["properties"] +-- ["ETA"] = 527.81058817743, +-- ["airdromeId"] = 12, +-- ["y"] = 243127.2973737, +-- ["x"] = -5406.2803440839, +-- ["name"] = "DictKey_WptName_53", +-- ["speed"] = 138.88888888889, +-- ["ETA_locked"] = false, +-- ["task"] = +-- { +-- ["id"] = "ComboTask", +-- ["params"] = +-- { +-- ["tasks"] = +-- { +-- }, -- end of ["tasks"] +-- }, -- end of ["params"] +-- }, -- end of ["task"] +-- ["speed_locked"] = true, +-- }, -- end of [4] + + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + + local GroupPoint = self:GetPointVec2() + local GroupVelocity = self:GetMaxVelocity() + + local PointFrom = {} + PointFrom.x = GroupPoint.x + PointFrom.y = GroupPoint.y + PointFrom.type = "Turning Point" + PointFrom.action = "Turning Point" + PointFrom.speed = GroupVelocity + + + local PointTo = {} + local AirbasePoint = ReturnAirbase:GetPointVec2() + + PointTo.x = AirbasePoint.x + PointTo.y = AirbasePoint.y + PointTo.type = "Land" + PointTo.action = "Landing" + PointTo.airdromeId = ReturnAirbase:GetID()-- Airdrome ID + self:T(PointTo.airdromeId) + --PointTo.alt = 0 + + local Points = { PointFrom, PointTo } + + self:T3( Points ) + + local Route = { points = Points, } + + return Route + end + + return nil +end + +--- @param Group#GROUP self +function GROUP:Respawn( Template ) + + local Vec3 = self:GetPointVec3() + --Template.x = Vec3.x + --Template.y = Vec3.z + Template.x = nil + Template.y = nil + + self:E( #Template.units ) + for UnitID, UnitData in pairs( self:GetUnits() ) do + local GroupUnit = UnitData -- Unit#UNIT + self:E( GroupUnit:GetName() ) + if GroupUnit:IsAlive() then + local GroupUnitVec3 = GroupUnit:GetPointVec3() + local GroupUnitHeading = GroupUnit:GetHeading() + Template.units[UnitID].alt = GroupUnitVec3.y + Template.units[UnitID].x = GroupUnitVec3.x + Template.units[UnitID].y = GroupUnitVec3.z + Template.units[UnitID].heading = GroupUnitHeading + self:E( { UnitID, Template.units[UnitID], Template.units[UnitID] } ) + end + end + + _DATABASE:Spawn( Template ) + +end + +function GROUP:GetTemplate() + + return _DATABASE.Templates.Groups[self:GetName()].Template + +end + -- Commands --- Do Script command @@ -7658,6 +7796,29 @@ function UNIT:GetCategoryName() return nil end +--- Returns the DCS Unit heading. +-- @param Unit#UNIT self +-- @return #number The DCS Unit heading +function UNIT:GetHeading() + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + + local UnitPosition = DCSUnit:getPosition() + if UnitPosition then + local UnitHeading = math.atan2( UnitPosition.x.z, UnitPosition.x.x ) + if UnitHeading < 0 then + UnitHeading = UnitHeading + 2 * math.pi + end + self:T2( UnitHeading ) + return UnitHeading + end + end + + return nil +end + + --- Signal a flare at the position of the UNIT. -- @param #UNIT self function UNIT:Flare( FlareColor ) @@ -8514,7 +8675,6 @@ end --- @param #CLIENT self function CLIENT:_AliveCheckScheduler( SchedulerName ) - self:E( SchedulerName ) self:F( { SchedulerName, self.ClientName, self.ClientAlive2, self.ClientBriefingShown, self.ClientCallBack } ) if self:IsAlive() then @@ -8837,10 +8997,320 @@ function STATIC:GetDCSUnit() return nil end ---- Manage the mission database. +--- This module contains the AIRBASE classes. -- --- @{#DATABASE} class --- ================== +-- === +-- +-- 1) @{Airbase#AIRBASE} class, extends @{Base#BASE} +-- ================================================= +-- The @{AIRBASE} class is a wrapper class to handle the DCS Airbase objects: +-- +-- * Support all DCS Airbase APIs. +-- * Enhance with Airbase specific APIs not in the DCS Airbase API set. +-- +-- +-- 1.1) AIRBASE reference methods +-- ------------------------------ +-- For each DCS Airbase object alive within a running mission, a AIRBASE wrapper object (instance) will be created within the _@{DATABASE} object. +-- This is done at the beginning of the mission (when the mission starts). +-- +-- The AIRBASE class **does not contain a :New()** method, rather it provides **:Find()** methods to retrieve the object reference +-- using the DCS Airbase or the DCS AirbaseName. +-- +-- Another thing to know is that AIRBASE objects do not "contain" the DCS Airbase object. +-- The AIRBASE methods will reference the DCS Airbase object by name when it is needed during API execution. +-- If the DCS Airbase object does not exist or is nil, the AIRBASE methods will return nil and log an exception in the DCS.log file. +-- +-- The AIRBASE class provides the following functions to retrieve quickly the relevant AIRBASE instance: +-- +-- * @{#AIRBASE.Find}(): Find a AIRBASE instance from the _DATABASE object using a DCS Airbase object. +-- * @{#AIRBASE.FindByName}(): Find a AIRBASE instance from the _DATABASE object using a DCS Airbase name. +-- +-- IMPORTANT: ONE SHOULD NEVER SANATIZE these AIRBASE OBJECT REFERENCES! (make the AIRBASE object references nil). +-- +-- 1.2) DCS AIRBASE APIs +-- --------------------- +-- The DCS Airbase APIs are used extensively within MOOSE. The AIRBASE class has for each DCS Airbase API a corresponding method. +-- To be able to distinguish easily in your code the difference between a AIRBASE API call and a DCS Airbase API call, +-- the first letter of the method is also capitalized. So, by example, the DCS Airbase method @{DCSAirbase#Airbase.getName}() +-- is implemented in the AIRBASE class as @{#AIRBASE.GetName}(). +-- +-- More functions will be added +-- ---------------------------- +-- During the MOOSE development, more functions will be added. +-- +-- @module Airbase +-- @author FlightControl + + + + + +--- The AIRBASE class +-- @type AIRBASE +-- @extends Base#BASE +AIRBASE = { + ClassName="AIRBASE", + CategoryName = { + [Airbase.Category.AIRDROME] = "Airdrome", + [Airbase.Category.HELIPAD] = "Helipad", + [Airbase.Category.SHIP] = "Ship", + }, + } + +-- Registration. + +--- Create a new AIRBASE from DCSAirbase. +-- @param #AIRBASE self +-- @param DCSAirbase#Airbase DCSAirbase +-- @param Database#DATABASE Database +-- @return Airbase#AIRBASE +function AIRBASE:Register( AirbaseName ) + + local self = BASE:Inherit( self, BASE:New() ) + self:F2( AirbaseName ) + self.AirbaseName = AirbaseName + return self +end + +-- Reference methods. + +--- Finds a AIRBASE from the _DATABASE using a DCSAirbase object. +-- @param #AIRBASE self +-- @param DCSAirbase#Airbase DCSAirbase An existing DCS Airbase object reference. +-- @return Airbase#AIRBASE self +function AIRBASE:Find( DCSAirbase ) + + local AirbaseName = DCSAirbase:getName() + local AirbaseFound = _DATABASE:FindAirbase( AirbaseName ) + return AirbaseFound +end + +--- Find a AIRBASE in the _DATABASE using the name of an existing DCS Airbase. +-- @param #AIRBASE self +-- @param #string AirbaseName The Airbase Name. +-- @return Airbase#AIRBASE self +function AIRBASE:FindByName( AirbaseName ) + + local AirbaseFound = _DATABASE:FindAirbase( AirbaseName ) + return AirbaseFound +end + +function AIRBASE:GetDCSAirbase() + local DCSAirbase = Airbase.getByName( self.AirbaseName ) + + if DCSAirbase then + return DCSAirbase + end + + return nil +end + +--- Returns coalition of the Airbase. +-- @param Airbase#AIRBASE self +-- @return DCSCoalitionObject#coalition.side The side of the coalition. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetCoalition() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseCoalition = DCSAirbase:getCoalition() + self:T3( AirbaseCoalition ) + return AirbaseCoalition + end + + return nil +end + +--- Returns country of the Airbase. +-- @param Airbase#AIRBASE self +-- @return DCScountry#country.id The country identifier. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetCountry() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseCountry = DCSAirbase:getCountry() + self:T3( AirbaseCountry ) + return AirbaseCountry + end + + return nil +end + + +--- Returns DCS Airbase object name. +-- The function provides access to non-activated units too. +-- @param Airbase#AIRBASE self +-- @return #string The name of the DCS Airbase. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetName() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseName = self.AirbaseName + return AirbaseName + end + + return nil +end + + +--- Returns if the airbase is alive. +-- @param Airbase#AIRBASE self +-- @return #boolean true if Airbase is alive. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:IsAlive() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseIsAlive = DCSAirbase:isExist() + return AirbaseIsAlive + end + + return false +end + +--- Returns the unit's unique identifier. +-- @param Airbase#AIRBASE self +-- @return DCSAirbase#Airbase.ID Airbase ID +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetID() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseID = DCSAirbase:getID() + return AirbaseID + end + + return nil +end + +--- Returns the Airbase's callsign - the localized string. +-- @param Airbase#AIRBASE self +-- @return #string The Callsign of the Airbase. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetCallSign() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseCallSign = DCSAirbase:getCallsign() + return AirbaseCallSign + end + + return nil +end + + + +--- Returns unit descriptor. Descriptor type depends on unit category. +-- @param Airbase#AIRBASE self +-- @return DCSAirbase#Airbase.Desc The Airbase descriptor. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetDesc() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseDesc = DCSAirbase:getDesc() + return AirbaseDesc + end + + return nil +end + + +--- Returns the type name of the DCS Airbase. +-- @param Airbase#AIRBASE self +-- @return #string The type name of the DCS Airbase. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetTypeName() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseTypeName = DCSAirbase:getTypeName() + self:T3( AirbaseTypeName ) + return AirbaseTypeName + end + + return nil +end + + +--- Returns the @{DCSTypes#Vec2} vector indicating the point in 2D of the DCS Airbase within the mission. +-- @param Airbase#AIRBASE self +-- @return DCSTypes#Vec2 The 2D point vector of the DCS Airbase. +-- @return #nil The DCS Airbase is not existing or alive. +function AIRBASE:GetPointVec2() + self:F2( self.AirbaseName ) + + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbasePointVec3 = DCSAirbase:getPosition().p + + local AirbasePointVec2 = {} + AirbasePointVec2.x = AirbasePointVec3.x + AirbasePointVec2.y = AirbasePointVec3.z + + self:T3( AirbasePointVec2 ) + return AirbasePointVec2 + end + + return nil +end + +--- Returns the DCS Airbase category as defined within the DCS Airbase Descriptor. +-- @param Airbase#AIRBASE self +-- @return DCSAirbase#Airbase.Category The DCS Airbase Category +function AIRBASE:GetCategory() + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseCategory = self:GetDesc().category + return AirbaseCategory + end + + return nil +end + + +--- Returns the DCS Airbase category name as defined within the DCS Airbase Descriptor. +-- @param Airbase#AIRBASE self +-- @return #string The DCS Airbase Category Name +function AIRBASE:GetCategoryName() + local DCSAirbase = self:GetDCSAirbase() + + if DCSAirbase then + local AirbaseCategoryName = self.CategoryName[ self:GetDesc().category ] + return AirbaseCategoryName + end + + return nil +end + + +--- This module contains the DATABASE class, managing the database of mission objects. +-- +-- ==== +-- +-- 1) @{Database#DATABASE} class, extends @{Base#BASE} +-- =================================================== -- Mission designers can use the DATABASE class to refer to: -- -- * UNITS @@ -8855,8 +9325,8 @@ end -- Moose will automatically create one instance of the DATABASE class into the **global** object _DATABASE. -- Moose refers to _DATABASE within the framework extensively, but you can also refer to the _DATABASE object within your missions if required. -- --- DATABASE iterators: --- =================== +-- 1.1) DATABASE iterators +-- ----------------------- -- You can iterate the database with the available iterator methods. -- The iterator methods will walk the DATABASE set, and call for each element within the set a function that you provide. -- The following iterator methods are currently available within the DATABASE: @@ -8871,17 +9341,6 @@ end -- @module Database -- @author FlightControl - - - - - - - - - - - --- DATABASE class -- @type DATABASE -- @extends Base#BASE @@ -8900,6 +9359,7 @@ DATABASE = { PLAYERSALIVE = {}, CLIENTS = {}, CLIENTSALIVE = {}, + AIRBASES = {}, NavPoints = {}, } @@ -8944,6 +9404,7 @@ function DATABASE:New() self:_RegisterClients() self:_RegisterStatics() self:_RegisterPlayers() + self:_RegisterAirbases() return self end @@ -9005,6 +9466,33 @@ function DATABASE:FindStatic( StaticName ) return StaticFound end +--- Adds a Airbase based on the Airbase Name in the DATABASE. +-- @param #DATABASE self +function DATABASE:AddAirbase( DCSAirbaseName ) + + if not self.AIRBASES[DCSAirbaseName] then + self.AIRBASES[DCSAirbaseName] = AIRBASE:Register( DCSAirbaseName ) + end +end + + +--- Deletes a Airbase from the DATABASE based on the Airbase Name. +-- @param #DATABASE self +function DATABASE:DeleteAirbase( DCSAirbaseName ) + + --self.AIRBASES[DCSAirbaseName] = nil +end + +--- Finds a AIRBASE based on the AirbaseName. +-- @param #DATABASE self +-- @param #string AirbaseName +-- @return Airbase#AIRBASE The found AIRBASE. +function DATABASE:FindAirbase( AirbaseName ) + + local AirbaseFound = self.AIRBASES[AirbaseName] + return AirbaseFound +end + --- Finds a CLIENT based on the ClientName. -- @param #DATABASE self @@ -9210,6 +9698,18 @@ function DATABASE:GetCountryFromClientTemplate( ClientName ) return self.Templates.ClientsByName[ClientName].CountryID end +--- Airbase + +function DATABASE:GetCoalitionFromAirbase( AirbaseName ) + return self.AIRBASES[AirbaseName]:GetCoalition() +end + +function DATABASE:GetCategoryFromAirbase( AirbaseName ) + return self.AIRBASES[AirbaseName]:GetCategory() +end + + + --- Private method that registers all alive players in the mission. -- @param #DATABASE self -- @return #DATABASE self @@ -9278,6 +9778,7 @@ function DATABASE:_RegisterClients() return self end +--- @param #DATABASE self function DATABASE:_RegisterStatics() local CoalitionsData = { GroupsRed = coalition.getStaticObjects( coalition.side.RED ), GroupsBlue = coalition.getStaticObjects( coalition.side.BLUE ) } @@ -9298,6 +9799,23 @@ function DATABASE:_RegisterStatics() return self end +--- @param #DATABASE self +function DATABASE:_RegisterAirbases() + + local CoalitionsData = { AirbasesRed = coalition.getAirbases( coalition.side.RED ), AirbasesBlue = coalition.getAirbases( coalition.side.BLUE ), AirbasesNeutral = coalition.getAirbases( coalition.side.NEUTRAL ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + for DCSAirbaseId, DCSAirbase in pairs( CoalitionData ) do + + local DCSAirbaseName = DCSAirbase:getName() + + self:E( { "Register Airbase:", DCSAirbaseName } ) + self:AddAirbase( DCSAirbaseName ) + end + end + + return self +end + --- Events @@ -9365,7 +9883,7 @@ end -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive player in the database. -- @return #DATABASE self -function DATABASE:ForEach( IteratorFunction, arg, Set ) +function DATABASE:ForEach( IteratorFunction, FinalizeFunction, arg, Set ) self:F2( arg ) local function CoRoutine() @@ -9386,7 +9904,7 @@ function DATABASE:ForEach( IteratorFunction, arg, Set ) local function Schedule() local status, res = coroutine.resume( co ) - self:T2( { status, res } ) + self:T3( { status, res } ) if status == false then error( res ) @@ -9394,7 +9912,9 @@ function DATABASE:ForEach( IteratorFunction, arg, Set ) if res == false then return true -- resume next time the loop end - + if FinalizeFunction then + FinalizeFunction( unpack( arg ) ) + end return false end @@ -9408,10 +9928,10 @@ end -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the database. The function needs to accept a UNIT parameter. -- @return #DATABASE self -function DATABASE:ForEachUnit( IteratorFunction, ... ) +function DATABASE:ForEachUnit( IteratorFunction, FinalizeFunction, ... ) self:F2( arg ) - self:ForEach( IteratorFunction, arg, self.UNITS ) + self:ForEach( IteratorFunction, FinalizeFunction, arg, self.UNITS ) return self end @@ -9558,7 +10078,7 @@ end -- === -- -- 1) @{Set#SET_BASE} class, extends @{Base#BASE} --- ================================================ +-- ============================================== -- The @{Set#SET_BASE} class defines the core functions that define a collection of objects. -- A SET provides iterators to iterate the SET, but will **temporarily** yield the ForEach interator loop at defined **"intervals"** to the mail simulator loop. -- In this way, large loops can be done while not blocking the simulator main processing loop. @@ -9569,15 +10089,15 @@ end -- --------------------------------------- -- Some key core functions are @{Set#SET_BASE.Add} and @{Set#SET_BASE.Remove} to add or remove objects from the SET in your logic. -- --- 1.2) Define the SET iterator **"yield interval"** and the **"time interval"**. --- ------------------------------------------------------------------------------------- +-- 1.2) Define the SET iterator **"yield interval"** and the **"time interval"** +-- ----------------------------------------------------------------------------- -- Modify the iterator intervals with the @{Set#SET_BASE.SetInteratorIntervals} method. -- You can set the **"yield interval"**, and the **"time interval"**. (See above). -- -- === -- -- 2) @{Set#SET_GROUP} class, extends @{Set#SET_BASE} --- ==================================================== +-- ================================================== -- Mission designers can use the @{Set#SET_GROUP} class to build sets of groups belonging to certain: -- -- * Coalitions @@ -9683,6 +10203,8 @@ end -- * @{#SET_UNIT.ForEachUnitCompletelyInZone}: Iterate and call an iterator function for each **alive** UNIT presence completely in a @{Zone}, providing the UNIT and optional parameters to the called function. -- * @{#SET_UNIT.ForEachUnitNotInZone}: Iterate and call an iterator function for each **alive** UNIT presence not in a @{Zone}, providing the UNIT and optional parameters to the called function. -- +-- === +-- -- 4) @{Set#SET_CLIENT} class, extends @{Set#SET_BASE} -- =================================================== -- Mission designers can use the @{Set#SET_CLIENT} class to build sets of units belonging to certain: @@ -9733,9 +10255,48 @@ end -- -- ==== -- +-- 5) @{Set#SET_AIRBASE} class, extends @{Set#SET_BASE} +-- ==================================================== +-- Mission designers can use the @{Set#SET_AIRBASE} class to build sets of airbases optionally belonging to certain: +-- +-- * Coalitions +-- +-- 5.1) SET_AIRBASE construction +-- ----------------------------- +-- Create a new SET_AIRBASE object with the @{#SET_AIRBASE.New} method: +-- +-- * @{#SET_AIRBASE.New}: Creates a new SET_AIRBASE object. +-- +-- 5.2) Add or Remove AIRBASEs from SET_AIRBASE +-- -------------------------------------------- +-- AIRBASEs can be added and removed using the @{Set#SET_AIRBASE.AddAirbasesByName} and @{Set#SET_AIRBASE.RemoveAirbasesByName} respectively. +-- These methods take a single AIRBASE name or an array of AIRBASE names to be added or removed from SET_AIRBASE. +-- +-- 5.3) SET_AIRBASE filter criteria +-- -------------------------------- +-- You can set filter criteria to define the set of clients within the SET_AIRBASE. +-- Filter criteria are defined by: +-- +-- * @{#SET_AIRBASE.FilterCoalitions}: Builds the SET_AIRBASE with the airbases belonging to the coalition(s). +-- +-- Once the filter criteria have been set for the SET_AIRBASE, you can start filtering using: +-- +-- * @{#SET_AIRBASE.FilterStart}: Starts the filtering of the airbases within the SET_AIRBASE. +-- +-- 5.4) SET_AIRBASE iterators: +-- --------------------------- +-- Once the filters have been defined and the SET_AIRBASE has been built, you can iterate the SET_AIRBASE with the available iterator methods. +-- The iterator methods will walk the SET_AIRBASE set, and call for each airbase within the set a function that you provide. +-- The following iterator methods are currently available within the SET_AIRBASE: +-- +-- * @{#SET_AIRBASE.ForEachAirbase}: Calls a function for each airbase it finds within the SET_AIRBASE. +-- +-- ==== +-- -- @module Set -- @author FlightControl + --- SET_BASE class -- @type SET_BASE -- @extends Base#BASE @@ -9834,6 +10395,32 @@ function SET_BASE:_FilterStart() return self end +--- Iterate the SET_BASE while identifying the nearest object from a @{Point#POINT_VEC2}. +-- @param #SET_BASE self +-- @param Point#POINT_VEC2 PointVec2 A @{Point#POINT_VEC2} object from where to evaluate the closest object in the set. +-- @return Base#BASE The closest object. +function SET_BASE:FindNearestObjectFromPointVec2( PointVec2 ) + self:F2( PointVec2 ) + + local NearestObject = nil + local ClosestDistance = nil + + for ObjectID, ObjectData in pairs( self.Set ) do + if NearestObject == nil then + NearestObject = ObjectData + ClosestDistance = PointVec2:DistanceFromVec2( ObjectData:GetPointVec2() ) + else + local Distance = PointVec2:DistanceFromVec2( ObjectData:GetPointVec2() ) + if Distance < ClosestDistance then + NearestObject = ObjectData + ClosestDistance = Distance + end + end + end + + return NearestObject +end + ----- Private method that registers all alive players in the mission. @@ -9975,7 +10562,7 @@ function SET_BASE:ForEach( IteratorFunction, arg, Set, Function, FunctionArgumen end ------ Interate the SET_BASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. +----- Iterate the SET_BASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. ---- @param #SET_BASE self ---- @param #function IteratorFunction The function that will be called when there is an alive unit in the SET_BASE. The function needs to accept a UNIT parameter. ---- @return #SET_BASE self @@ -9987,7 +10574,7 @@ end -- return self --end -- ------ Interate the SET_BASE and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. +----- Iterate the SET_BASE and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. ---- @param #SET_BASE self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_BASE. The function needs to accept a UNIT parameter. ---- @return #SET_BASE self @@ -10000,7 +10587,7 @@ end --end -- -- ------ Interate the SET_BASE and call an interator function for each client, providing the Client to the function and optional parameters. +----- Iterate the SET_BASE and call an interator function for each client, providing the Client to the function and optional parameters. ---- @param #SET_BASE self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_BASE. The function needs to accept a CLIENT parameter. ---- @return #SET_BASE self @@ -10322,7 +10909,7 @@ function SET_GROUP:ForEachGroupNotInZone( ZoneObject, IteratorFunction, ... ) end ------ Interate the SET_GROUP and call an interator function for each **alive** player, providing the Group of the player and optional parameters. +----- Iterate the SET_GROUP and call an interator function for each **alive** player, providing the Group of the player and optional parameters. ---- @param #SET_GROUP self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_GROUP. The function needs to accept a GROUP parameter. ---- @return #SET_GROUP self @@ -10335,7 +10922,7 @@ end --end -- -- ------ Interate the SET_GROUP and call an interator function for each client, providing the Client to the function and optional parameters. +----- Iterate the SET_GROUP and call an interator function for each client, providing the Client to the function and optional parameters. ---- @param #SET_GROUP self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_GROUP. The function needs to accept a CLIENT parameter. ---- @return #SET_GROUP self @@ -10629,7 +11216,7 @@ function SET_UNIT:FindInDatabase( Event ) return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName] end ---- Interate the SET_UNIT and call an interator function for each **alive** UNIT, providing the UNIT and optional parameters. +--- Iterate the SET_UNIT and call an interator function for each **alive** UNIT, providing the UNIT and optional parameters. -- @param #SET_UNIT self -- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the SET_UNIT. The function needs to accept a UNIT parameter. -- @return #SET_UNIT self @@ -10687,7 +11274,7 @@ end ------ Interate the SET_UNIT and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. +----- Iterate the SET_UNIT and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. ---- @param #SET_UNIT self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_UNIT. The function needs to accept a UNIT parameter. ---- @return #SET_UNIT self @@ -10700,7 +11287,7 @@ end --end -- -- ------ Interate the SET_UNIT and call an interator function for each client, providing the Client to the function and optional parameters. +----- Iterate the SET_UNIT and call an interator function for each client, providing the Client to the function and optional parameters. ---- @param #SET_UNIT self ---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_UNIT. The function needs to accept a CLIENT parameter. ---- @return #SET_UNIT self @@ -11002,7 +11589,7 @@ function SET_CLIENT:FindInDatabase( Event ) return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName] end ---- Interate the SET_CLIENT and call an interator function for each **alive** CLIENT, providing the CLIENT and optional parameters. +--- Iterate the SET_CLIENT and call an interator function for each **alive** CLIENT, providing the CLIENT and optional parameters. -- @param #SET_CLIENT self -- @param #function IteratorFunction The function that will be called when there is an alive CLIENT in the SET_CLIENT. The function needs to accept a CLIENT parameter. -- @return #SET_CLIENT self @@ -11138,6 +11725,229 @@ function SET_CLIENT:IsIncludeObject( MClient ) return MClientInclude end +--- SET_AIRBASE + +--- SET_AIRBASE class +-- @type SET_AIRBASE +-- @extends Set#SET_BASE +SET_AIRBASE = { + ClassName = "SET_AIRBASE", + Airbases = {}, + Filter = { + Coalitions = nil, + }, + FilterMeta = { + Coalitions = { + red = coalition.side.RED, + blue = coalition.side.BLUE, + neutral = coalition.side.NEUTRAL, + }, + Categories = { + airdrome = Airbase.Category.AIRDROME, + helipad = Airbase.Category.HELIPAD, + ship = Airbase.Category.SHIP, + }, + }, +} + + +--- Creates a new SET_AIRBASE object, building a set of airbases belonging to a coalitions and categories. +-- @param #SET_AIRBASE self +-- @return #SET_AIRBASE self +-- @usage +-- -- Define a new SET_AIRBASE Object. The DatabaseSet will contain a reference to all Airbases. +-- DatabaseSet = SET_AIRBASE:New() +function SET_AIRBASE:New() + -- Inherits from BASE + local self = BASE:Inherit( self, SET_BASE:New( _DATABASE.AIRBASES ) ) + + return self +end + +--- Add AIRBASEs to SET_AIRBASE. +-- @param Set#SET_AIRBASE self +-- @param #string AddAirbaseNames A single name or an array of AIRBASE names. +-- @return self +function SET_AIRBASE:AddAirbasesByName( AddAirbaseNames ) + + local AddAirbaseNamesArray = ( type( AddAirbaseNames ) == "table" ) and AddAirbaseNames or { AddAirbaseNames } + + for AddAirbaseID, AddAirbaseName in pairs( AddAirbaseNamesArray ) do + self:Add( AddAirbaseName, AIRBASE:FindByName( AddAirbaseName ) ) + end + + return self +end + +--- Remove AIRBASEs from SET_AIRBASE. +-- @param Set#SET_AIRBASE self +-- @param Airbase#AIRBASE RemoveAirbaseNames A single name or an array of AIRBASE names. +-- @return self +function SET_AIRBASE:RemoveAirbasesByName( RemoveAirbaseNames ) + + local RemoveAirbaseNamesArray = ( type( RemoveAirbaseNames ) == "table" ) and RemoveAirbaseNames or { RemoveAirbaseNames } + + for RemoveAirbaseID, RemoveAirbaseName in pairs( RemoveAirbaseNamesArray ) do + self:Remove( RemoveAirbaseName.AirbaseName ) + end + + return self +end + + +--- Finds a Airbase based on the Airbase Name. +-- @param #SET_AIRBASE self +-- @param #string AirbaseName +-- @return Airbase#AIRBASE The found Airbase. +function SET_AIRBASE:FindAirbase( AirbaseName ) + + local AirbaseFound = self.Set[AirbaseName] + return AirbaseFound +end + + + +--- Builds a set of airbases of coalitions. +-- Possible current coalitions are red, blue and neutral. +-- @param #SET_AIRBASE self +-- @param #string Coalitions Can take the following values: "red", "blue", "neutral". +-- @return #SET_AIRBASE self +function SET_AIRBASE:FilterCoalitions( Coalitions ) + if not self.Filter.Coalitions then + self.Filter.Coalitions = {} + end + if type( Coalitions ) ~= "table" then + Coalitions = { Coalitions } + end + for CoalitionID, Coalition in pairs( Coalitions ) do + self.Filter.Coalitions[Coalition] = Coalition + end + return self +end + + +--- Builds a set of airbases out of categories. +-- Possible current categories are plane, helicopter, ground, ship. +-- @param #SET_AIRBASE self +-- @param #string Categories Can take the following values: "airdrome", "helipad", "ship". +-- @return #SET_AIRBASE self +function SET_AIRBASE:FilterCategories( Categories ) + if not self.Filter.Categories then + self.Filter.Categories = {} + end + if type( Categories ) ~= "table" then + Categories = { Categories } + end + for CategoryID, Category in pairs( Categories ) do + self.Filter.Categories[Category] = Category + end + return self +end + +--- Starts the filtering. +-- @param #SET_AIRBASE self +-- @return #SET_AIRBASE self +function SET_AIRBASE:FilterStart() + + if _DATABASE then + self:_FilterStart() + end + + return self +end + + +--- 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! +-- @param #SET_AIRBASE self +-- @param Event#EVENTDATA Event +-- @return #string The name of the AIRBASE +-- @return #table The AIRBASE +function SET_AIRBASE:AddInDatabase( Event ) + self:F3( { Event } ) + + return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName] +end + +--- Handles the Database to check on any event that Object exists in the Database. +-- This is required, because sometimes the _DATABASE event gets called later than the SET_BASE event or vise versa! +-- @param #SET_AIRBASE self +-- @param Event#EVENTDATA Event +-- @return #string The name of the AIRBASE +-- @return #table The AIRBASE +function SET_AIRBASE:FindInDatabase( Event ) + self:F3( { Event } ) + + return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName] +end + +--- Iterate the SET_AIRBASE and call an interator function for each AIRBASE, providing the AIRBASE and optional parameters. +-- @param #SET_AIRBASE self +-- @param #function IteratorFunction The function that will be called when there is an alive AIRBASE in the SET_AIRBASE. The function needs to accept a AIRBASE parameter. +-- @return #SET_AIRBASE self +function SET_AIRBASE:ForEachAirbase( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.Set ) + + return self +end + +--- Iterate the SET_AIRBASE while identifying the nearest @{Airbase#AIRBASE} from a @{Point#POINT_VEC2}. +-- @param #SET_AIRBASE self +-- @param Point#POINT_VEC2 PointVec2 A @{Point#POINT_VEC2} object from where to evaluate the closest @{Airbase#AIRBASE}. +-- @return Airbase#AIRBASE The closest @{Airbase#AIRBASE}. +function SET_AIRBASE:FindNearestAirbaseFromPointVec2( PointVec2 ) + self:F2( PointVec2 ) + + local NearestAirbase = self:FindNearestObjectFromPointVec2( PointVec2 ) + return NearestAirbase +end + + + +--- +-- @param #SET_AIRBASE self +-- @param Airbase#AIRBASE MAirbase +-- @return #SET_AIRBASE self +function SET_AIRBASE:IsIncludeObject( MAirbase ) + self:F2( MAirbase ) + + local MAirbaseInclude = true + + if MAirbase then + local MAirbaseName = MAirbase:GetName() + + if self.Filter.Coalitions then + local MAirbaseCoalition = false + for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do + local AirbaseCoalitionID = _DATABASE:GetCoalitionFromAirbase( MAirbaseName ) + self:T3( { "Coalition:", AirbaseCoalitionID, self.FilterMeta.Coalitions[CoalitionName], CoalitionName } ) + if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == AirbaseCoalitionID then + MAirbaseCoalition = true + end + end + self:T( { "Evaluated Coalition", MAirbaseCoalition } ) + MAirbaseInclude = MAirbaseInclude and MAirbaseCoalition + end + + if self.Filter.Categories then + local MAirbaseCategory = false + for CategoryID, CategoryName in pairs( self.Filter.Categories ) do + local AirbaseCategoryID = _DATABASE:GetCategoryFromAirbase( MAirbaseName ) + self:T3( { "Category:", AirbaseCategoryID, self.FilterMeta.Categories[CategoryName], CategoryName } ) + if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == AirbaseCategoryID then + MAirbaseCategory = true + end + end + self:T( { "Evaluated Category", MAirbaseCategory } ) + MAirbaseInclude = MAirbaseInclude and MAirbaseCategory + end + end + + self:T2( MAirbaseInclude ) + return MAirbaseInclude +end --- This module contains the POINT classes. -- -- 1) @{Point#POINT_VEC3} class, extends @{Base#BASE} @@ -11304,6 +12114,7 @@ end --- The POINT_VEC2 class -- @type POINT_VEC2 +-- @field DCSTypes#Vec2 PointVec2 -- @extends Point#POINT_VEC3 POINT_VEC2 = { ClassName = "POINT_VEC2", @@ -11324,10 +12135,38 @@ function POINT_VEC2:New( x, y, LandHeightAdd ) local self = BASE:Inherit( self, POINT_VEC3:New( x, LandHeight, y ) ) self:F2( { x, y, LandHeightAdd } ) + + self.PointVec2 = { x = x, y = y } return self end +--- Calculate the distance from a reference @{Point#POINT_VEC2}. +-- @param #POINT_VEC2 self +-- @param #POINT_VEC2 PointVec2Reference The reference @{Point#POINT_VEC2}. +-- @return DCSTypes#Distance The distance from the reference @{Point#POINT_VEC2} in meters. +function POINT_VEC2:DistanceFromPointVec2( PointVec2Reference ) + self:F2( PointVec2Reference ) + + local Distance = ( ( PointVec2Reference.PointVec2.x - self.PointVec2.x ) ^ 2 + ( PointVec2Reference.PointVec2.y - self.PointVec2.y ) ^2 ) ^0.5 + + self:T2( Distance ) + return Distance +end + +--- Calculate the distance from a reference @{DCSTypes#Vec2}. +-- @param #POINT_VEC2 self +-- @param DCSTypes#Vec2 Vec2Reference The reference @{DCSTypes#Vec2}. +-- @return DCSTypes#Distance The distance from the reference @{DCSTypes#Vec2} in meters. +function POINT_VEC2:DistanceFromVec2( Vec2Reference ) + self:F2( Vec2Reference ) + + local Distance = ( ( Vec2Reference.x - self.PointVec2.x ) ^ 2 + ( Vec2Reference.y - self.PointVec2.y ) ^2 ) ^0.5 + + self:T2( Distance ) + return Distance +end + --- The main include file for the MOOSE system. @@ -11341,6 +12180,7 @@ Include.File( "Unit" ) Include.File( "Zone" ) Include.File( "Client" ) Include.File( "Static" ) +Include.File( "Airbase" ) Include.File( "Database" ) Include.File( "Set" ) Include.File( "Point" ) @@ -11369,40 +12209,6 @@ Include.File( "MissileTrainer" ) Include.File( "AIBalancer" ) Include.File( "AirbasePolice" ) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- The order of the declarations is important here. Don't touch it. --- Declare the event dispatcher based on the EVENT class @@ -20147,6 +20953,12 @@ end -- -- * @{#AIBALANCER.New}: Creates a new AIBALANCER object. -- +-- 1.2) AIBALANCER return AI to Airbases: +-- -------------------------------------- +-- You can configure to have the AI to return to: +-- +-- * @{#AIBALANCER.ReturnToHomeAirbase}: Returns the AI to the home @{Airbase#AIRBASE}. +-- * @{#AIBALANCER.ReturnToNearestAirbases}: Returns the AI to the nearest friendly @{Airbase#AIRBASE}. -- -- === -- @module AIBalancer @@ -20156,6 +20968,10 @@ end -- @type AIBALANCER -- @field Set#SET_CLIENT SetClient -- @field Spawn#SPAWN SpawnAI +-- @field #boolean ReturnToAirbase +-- @field Set#SET_AIRBASE ReturnAirbaseSet +-- @field DCSTypes#Distance ReturnTresholdRange +-- @field #boolean ReturnToHomeAirbase -- @extends Base#BASE AIBALANCER = { ClassName = "AIBALANCER", @@ -20172,13 +20988,55 @@ function AIBALANCER:New( SetClient, SpawnAI ) local self = BASE:Inherit( self, BASE:New() ) self.SetClient = SetClient - self.SpawnAI = SpawnAI + if type( SpawnAI ) == "table" then + if SpawnAI.ClassName and SpawnAI.ClassName == "SPAWN" then + self.SpawnAI = { SpawnAI } + else + local SpawnObjects = true + for SpawnObjectID, SpawnObject in pairs( SpawnAI ) do + if SpawnObject.ClassName and SpawnObject.ClassName == "SPAWN" then + self:E( SpawnObject.ClassName ) + else + self:E( "other object" ) + SpawnObjects = false + end + end + if SpawnObjects == true then + self.SpawnAI = SpawnAI + else + error( "No SPAWN object given in parameter SpawnAI, either as a single object or as a table of objects!" ) + end + end + end + + self.ReturnToAirbase = false + self.ReturnHomeAirbase = false self.AIMonitorSchedule = SCHEDULER:New( self, self._ClientAliveMonitorScheduler, {}, 1, 10, 0 ) return self end +--- Returns the AI to the nearest friendly @{Airbase#AIRBASE}. +-- @param #AIBALANCER self +-- @param DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Airbase#AIRBASE}. +-- @param Set#SET_AIRBASE ReturnAirbaseSet The SET of @{Set#SET_AIRBASE}s to evaluate where to return to. +function AIBALANCER:ReturnToNearestAirbases( ReturnTresholdRange, ReturnAirbaseSet ) + + self.ReturnToAirbase = true + self.ReturnTresholdRange = ReturnTresholdRange + self.ReturnAirbaseSet = ReturnAirbaseSet +end + +--- Returns the AI to the home @{Airbase#AIRBASE}. +-- @param #AIBALANCER self +-- @param DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Airbase#AIRBASE}. +function AIBALANCER:ReturnToHomeAirbase( ReturnTresholdRange ) + + self.ReturnToHomeAirbase = true + self.ReturnTresholdRange = ReturnTresholdRange +end + --- @param #AIBALANCER self function AIBALANCER:_ClientAliveMonitorScheduler() @@ -20190,13 +21048,70 @@ function AIBALANCER:_ClientAliveMonitorScheduler() if Client:IsAlive() then if ClientAIAliveState == true then Client:SetState( self, 'AIAlive', false ) + local AIGroup = Client:GetState( self, 'AIGroup' ) -- Group#GROUP - AIGroup:Destroy() + + if self.ReturnToAirbase == false and self.ReturnToHomeAirbase == false then + AIGroup:Destroy() + else + -- We test if there is no other CLIENT within the self.ReturnTresholdRange of the first unit of the AI group. + -- If there is a CLIENT, the AI stays engaged and will not return. + -- If there is no CLIENT within the self.ReturnTresholdRange, then the unit will return to the Airbase return method selected. + + local ClientInZone = { Value = false } + local RangeZone = ZONE_RADIUS:New( 'RangeZone', AIGroup:GetPointVec2(), self.ReturnTresholdRange ) + + self:E( RangeZone ) + + _DATABASE:ForEachUnit( + --- @param Unit#UNIT RangeTestUnit + function( RangeTestUnit, RangeZone, AIGroup, ClientInZone ) + self:E( { ClientInZone, RangeTestUnit.UnitName, RangeZone.ZoneName } ) + if RangeTestUnit:IsInZone( RangeZone ) == true then + self:E( "in zone" ) + if RangeTestUnit:GetCoalition() ~= AIGroup:GetCoalition() then + self:E( "in range" ) + ClientInZone.Value = true + end + end + end, + + --- @param Zone#ZONE_RADIUS RangeZone + -- @param Group#GROUP AIGroup + function( RangeZone, AIGroup, ClientInZone ) + local AIGroupTemplate = AIGroup:GetTemplate() + if ClientInZone.Value == false then + if self.ReturnToHomeAirbase == true then + local WayPointCount = #AIGroupTemplate.route.points + local SwitchWayPointCommand = AIGroup:CommandSwitchWayPoint( 1, WayPointCount, 1 ) + AIGroup:SetCommand( SwitchWayPointCommand ) + AIGroup:MessageToRed( "Returning to home base ...", 30 ) + else + -- Okay, we need to send this Group back to the nearest base of the Coalition of the AI. + --TODO: i need to rework the POINT_VEC2 thing. + local PointVec2 = POINT_VEC2:New( AIGroup:GetPointVec2().x, AIGroup:GetPointVec2().y ) + local ClosestAirbase = self.ReturnAirbaseSet:FindNearestAirbaseFromPointVec2( PointVec2 ) + self:T( ClosestAirbase.AirbaseName ) + AIGroup:MessageToRed( "Returning to " .. ClosestAirbase:GetName().. " ...", 30 ) + local RTBRoute = AIGroup:RouteReturnToAirbase( ClosestAirbase ) + AIGroupTemplate.route = RTBRoute + AIGroup:Respawn( AIGroupTemplate ) + end + end + end + , RangeZone, AIGroup, ClientInZone + ) + + end end else if not ClientAIAliveState or ClientAIAliveState == false then Client:SetState( self, 'AIAlive', true ) - Client:SetState( self, 'AIGroup', self.SpawnAI:Spawn() ) + + -- OK, spawn a new group from the SpawnAI objects provided. + local SpawnAICount = #self.SpawnAI + local SpawnAIIndex = math.random( 1, SpawnAICount ) + Client:SetState( self, 'AIGroup', self.SpawnAI[SpawnAIIndex]:Spawn() ) end end end diff --git a/Moose Mission Setup/Moose_Create.bat b/Moose Mission Setup/Moose_Create.bat index 6265d188b..3a3b85b19 100644 --- a/Moose Mission Setup/Moose_Create.bat +++ b/Moose Mission Setup/Moose_Create.bat @@ -48,6 +48,7 @@ COPY /b Moose.lua + %1\Unit.lua Moose.lua COPY /b Moose.lua + %1\Zone.lua Moose.lua COPY /b Moose.lua + %1\Client.lua Moose.lua COPY /b Moose.lua + %1\Static.lua Moose.lua +COPY /b Moose.lua + %1\Airbase.lua Moose.lua COPY /b Moose.lua + %1\Database.lua Moose.lua COPY /b Moose.lua + %1\Set.lua Moose.lua COPY /b Moose.lua + %1\Point.lua Moose.lua diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER.lua b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER.lua index ef23d4354..77d24710c 100644 --- a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER.lua +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER.lua @@ -1,8 +1,14 @@ local US_PlanesClientSet = SET_CLIENT:New():FilterCountries( "USA" ):FilterCategories( "plane" ):FilterStart() -local US_PlanesSpawn = SPAWN:New( "AI US" ) -local RU_AIBalancer = AIBALANCER:New( US_PlanesClientSet, US_PlanesSpawn ) +local US_PlanesSpawn1 = SPAWN:New( "AI US 1" ) +local US_PlanesSpawn2 = SPAWN:New( "AI US 2" ) +local US_AIBalancer = AIBALANCER:New( US_PlanesClientSet, { US_PlanesSpawn1, US_PlanesSpawn2 } ) local RU_PlanesClientSet = SET_CLIENT:New():FilterCountries( "RUSSIA" ):FilterCategories( "plane" ):FilterStart() local RU_PlanesSpawn = SPAWN:New( "AI RU" ) local RU_AIBalancer = AIBALANCER:New( RU_PlanesClientSet, RU_PlanesSpawn ) + +local RU_AirbasesSet = SET_AIRBASE:New():FilterCoalitions("red"):FilterStart() +RU_AirbasesSet:Flush() +RU_AIBalancer:ReturnToNearestAirbases( 10000, RU_AirbasesSet ) +--RU_AIBalancer:ReturnToHomeAirbase( 10000 ) \ No newline at end of file diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER.miz b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER.miz index 23fb906eb..c6b4737b8 100644 Binary files a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER.miz and b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER.miz differ diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Config/View/Server.lua b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Config/View/Server.lua new file mode 100644 index 000000000..df77a168a --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Config/View/Server.lua @@ -0,0 +1,209 @@ +-- View scripts +-- Copyright (C) 2004, Eagle Dynamics. +DisableCombatViews = false -- F5 & Ctrl-F5 +ExternalObjectsLockDistance = 10000.0 +ShowTargetInfo = false +CameraTerrainRestriction = true +hAngleRearDefault = 180 +vAngleRearDefault = -8.0 +vAngleRearMin = -90 -- -8.0 +vAngleRearMax = 90.0 + +dbg_shell = "weapons.shells.PKT_7_62_T" -- 23mm shell +-- dbg_shell = "weapons.shells.2A64_152" -- 152mm shell +dbg_shell_v0 = -1 -- Muzzle speed m/s (-1 - speed from shall database) +dbg_shell_fire_rate = 60 +--reformatted per-unit data to be mod system friendly +--this file is no longer should be edited for adding new flyable aircraft , DCS automatically check core database (i.e. where you define your aircraft in aircraft table just define ViewSettings and SnapViews tables) + +function default_fighter_player(t) + local res = { + CameraViewAngleLimits = {20.000000,140.000000}, + CameraAngleRestriction = {false ,90.000000,0.500000}, + EyePoint = {0.05 ,0.000000 ,0.000000}, + limits_6DOF = {x = {-0.050000,0.4500000},y ={-0.300000,0.100000},z = {-0.220000,0.220000},roll = 90.000000}, + Allow360rotation = false, + CameraAngleLimits = {200,-80.000000,110.000000}, + ShoulderSize = 0.2, -- move body when azimuth value more then 90 degrees + } + if t then + for i,o in pairs(t) do + res[i] = o + end + end + return res +end + +function fulcrum() + return { + Cockpit = { + default_fighter_player({CockpitLocalPoint = {4.71,1.28,0.000000}}) + }, + Chase = { + LocalPoint = {1.220000,3.750000,0.000000}, + AnglesDefault = {180.000000,-8.000000}, + }, -- Chase + Arcade = { + LocalPoint = {-15.080000,6.350000,0.000000}, + AnglesDefault = {0.000000,-8.000000}, + }, -- Arcade + } +end + +ViewSettings = {} +ViewSettings["A-10A"] = { + Cockpit = { + [1] = default_fighter_player({CockpitLocalPoint = {4.300000,1.282000,0.000000}, + EyePoint = {0.000000,0.000000,0.000000}, + limits_6DOF = {x = {-0.050000,0.600000}, + y = {-0.300000,0.100000}, + z = {-0.250000,0.250000}, + roll = 90.000000}}), + }, -- Cockpit + Chase = { + LocalPoint = {0.600000,3.682000,0.000000}, + AnglesDefault = {180.000000,-8.000000}, + }, -- Chase + Arcade = { + LocalPoint = {-27.000000,12.000000,0.000000}, + AnglesDefault = {0.000000,-12.000000}, + }, -- Arcade +} +ViewSettings["A-10C"] = { + Cockpit = { + [1] = default_fighter_player({CockpitLocalPoint = {4.300000,1.282000,0.000000}, + EyePoint = {0.000000,0.000000,0.000000}, + limits_6DOF = {x = {-0.050000,0.600000}, + y = {-0.300000,0.100000}, + z = {-0.250000,0.250000}, + roll = 90.000000}}), + }, -- Cockpit + Chase = { + LocalPoint = {0.600000,3.682000,0.000000}, + AnglesDefault = {180.000000,-8.000000}, + }, -- Chase + Arcade = { + LocalPoint = {-27.000000,12.000000,0.000000}, + AnglesDefault = {0.000000,-12.000000}, + }, -- Arcade +} +ViewSettings["F-15C"] = { + Cockpit = { + [1] = default_fighter_player({CockpitLocalPoint = {6.210000,1.204000,0.000000}})-- player slot 1 + }, -- Cockpit + Chase = { + LocalPoint = {2.510000,3.604000,0.000000}, + AnglesDefault = {180.000000,-8.000000}, + }, -- Chase + Arcade = { + LocalPoint = {-13.790000,6.204000,0.000000}, + AnglesDefault = {0.000000,-8.000000}, + }, -- Arcade +} +ViewSettings["Ka-50"] = { + Cockpit = { + [1] = {-- player slot 1 + CockpitLocalPoint = {3.188000,0.390000,0.000000}, + CameraViewAngleLimits = {20.000000,120.000000}, + CameraAngleRestriction = {false,60.000000,0.400000}, + CameraAngleLimits = {140.000000,-65.000000,90.000000}, + EyePoint = {0.090000,0.000000,0.000000}, + limits_6DOF = {x = {-0.020000,0.350000},y ={-0.150000,0.165000},z = {-0.170000,0.170000},roll = 90.000000}, + }, + }, -- Cockpit + Chase = { + LocalPoint = {-0.512000,2.790000,0.000000}, + AnglesDefault = {180.000000,-8.000000}, + }, -- Chase + Arcade = { + LocalPoint = {-16.812000,5.390000,0.000000}, + AnglesDefault = {0.000000,-8.000000}, + }, -- Arcade +} +ViewSettings["MiG-29A"] = fulcrum() +ViewSettings["MiG-29G"] = fulcrum() +ViewSettings["MiG-29S"] = fulcrum() + +ViewSettings["P-51D"] = { + Cockpit = { + [1] = {-- player slot 1 + CockpitLocalPoint = {-1.500000,0.618000,0.000000}, + CameraViewAngleLimits = {20.000000,120.000000}, + CameraAngleRestriction = {false,90.000000,0.500000}, + CameraAngleLimits = {200,-80.000000,90.000000}, + EyePoint = {0.025000,0.100000,0.000000}, + ShoulderSize = 0.15, + Allow360rotation = false, + limits_6DOF = {x = {-0.050000,0.450000},y ={-0.200000,0.200000},z = {-0.220000,0.220000},roll = 90.000000}, + }, + }, -- Cockpit + Chase = { + LocalPoint = {0.200000,-0.652000,-0.650000}, + AnglesDefault = {0.000000,0.000000}, + }, -- Chase + Arcade = { + LocalPoint = {-21.500000,5.618000,0.000000}, + AnglesDefault = {0.000000,-8.000000}, + }, -- Arcade +} +ViewSettings["Su-25"] = { + Cockpit = { + [1] = default_fighter_player({CockpitLocalPoint = {3.352000,0.506000,0.000000}}),-- player slot 1 + }, -- Cockpit + Chase = { + LocalPoint = {-0.348000,2.906000,0.000000}, + AnglesDefault = {180.000000,-8.000000}, + }, -- Chase + Arcade = { + LocalPoint = {-16.648001,5.506000,0.000000}, + AnglesDefault = {0.000000,-8.000000}, + }, -- Arcade +} +ViewSettings["Su-25T"] = { + Cockpit = { + [1] = default_fighter_player({CockpitLocalPoint = {3.406000,0.466000,0.000000}}),-- player slot 1 + }, -- Cockpit + Chase = { + LocalPoint = {-0.294000,2.866000,0.000000}, + AnglesDefault = {180.000000,-8.000000}, + }, -- Chase + Arcade = { + LocalPoint = {-16.594000,5.466000,0.000000}, + AnglesDefault = {0.000000,-8.000000}, + }, -- Arcade +} +ViewSettings["Su-25TM"] = { + Cockpit = { + [1] = {-- player slot 1 + CockpitLocalPoint = {4.000000,1.000000,0.000000}, + CameraViewAngleLimits = {20.000000,140.000000}, + CameraAngleRestriction = {true,90.000000,0.400000}, + CameraAngleLimits = {160.000000,-70.000000,90.000000}, + EyePoint = {0.000000,0.000000,0.000000}, + limits_6DOF = {x = {-0.200000,0.200000},y ={-0.200000,0.200000},z = {-0.200000,0.200000},roll = 60.000000}, + }, + }, -- Cockpit + Chase = { + LocalPoint = {4.000000,2.000000,0.000000}, + AnglesDefault = {180.000000,-8.000000}, + }, -- Chase + Arcade = { + LocalPoint = {4.000000,2.000000,0.000000}, + AnglesDefault = {180.000000,-8.000000}, + }, -- Arcade +} +ViewSettings["Su-27"] = { + Cockpit = { + [1] = default_fighter_player({CockpitLocalPoint = {7.959000,1.419000,0.000000}})-- player slot 1 + }, -- Cockpit + Chase = { + LocalPoint = {4.259000,3.819000,0.000000}, + AnglesDefault = {180.000000,-8.000000}, + }, -- Chase + Arcade = { + LocalPoint = {-12.041000,6.419000,0.000000}, + AnglesDefault = {0.000000,-8.000000}, + }, -- Arcade +} + +ViewSettings["Su-33"] = ViewSettings["Su-27"] diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Config/View/SnapViewsDefault.lua b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Config/View/SnapViewsDefault.lua new file mode 100644 index 000000000..754522d55 --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Config/View/SnapViewsDefault.lua @@ -0,0 +1,1698 @@ +--reformatted per-unit data to be mod system friendly +--this file is no longer should be edited for adding new flyable aircraft , DCS automatically check core database for this data(i.e. where you define your aircraft in aircraft table just define ViewSettings and SnapViews tables) +-- result of ingame editing is saved to Saved Games//DCS/Config/View/SnapViews.lua +SnapViews = {} +SnapViews["A-10A"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 65.000000,--FOV + hAngle = 0.000000, + vAngle = -26.000000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 49.626770,--FOV + hAngle = 0.000000, + vAngle = -90.631294, + x_trans = 0.180499, + y_trans = -0.137064, + z_trans = -0.250000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 30.395041,--FOV + hAngle = 0.000000, + vAngle = -94.329208, + x_trans = 0.372718, + y_trans = -0.054055, + z_trans = 0.250000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 55.238567,--FOV + hAngle = 0.000000, + vAngle = -90.631294, + x_trans = 0.158523, + y_trans = -0.137064, + z_trans = 0.250000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 35.000000,--FOV + hAngle = 0.000000, + vAngle = -10.651850, + x_trans = 0.327622, + y_trans = -0.278207, + z_trans = -0.244799, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 34.340549,--FOV + hAngle = 0.000000, + vAngle = -9.500000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 35.000000,--FOV + hAngle = 0.000000, + vAngle = -10.651850, + x_trans = 0.327622, + y_trans = -0.278207, + z_trans = 0.244799, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 68.628296,--FOV + hAngle = 68.292320, + vAngle = -11.477349, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 68.628296,--FOV + hAngle = 0.000000, + vAngle = 30.227919, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 68.628296,--FOV + hAngle = -67.172974, + vAngle = -11.477349, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 70.000000,--FOV + hAngle = 20.000000, + vAngle = 8.000000, + x_trans = 0.360000, + y_trans = -0.041337, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 70.000000,--FOV + hAngle = -20.000000, + vAngle = 8.000000, + x_trans = 0.360000, + y_trans = -0.041337, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 75.000000,--FOV + hAngle = 0.000000, + vAngle = -23.000000, + x_trans = 0.360000, + y_trans = -0.041337, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["A-10C"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 65.000000,--FOV + hAngle = 0.000000, + vAngle = -26.000000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 49.626770,--FOV + hAngle = 0.000000, + vAngle = -90.631294, + x_trans = 0.180499, + y_trans = -0.137064, + z_trans = -0.250000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 30.395041,--FOV + hAngle = 0.000000, + vAngle = -94.329208, + x_trans = 0.372718, + y_trans = -0.054055, + z_trans = 0.250000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 55.238567,--FOV + hAngle = 0.000000, + vAngle = -90.631294, + x_trans = 0.158523, + y_trans = -0.137064, + z_trans = 0.250000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 35.000000,--FOV + hAngle = 0.000000, + vAngle = -10.651850, + x_trans = 0.327622, + y_trans = -0.278207, + z_trans = -0.244799, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 34.340549,--FOV + hAngle = 0.000000, + vAngle = -9.500000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 35.000000,--FOV + hAngle = 0.000000, + vAngle = -10.651850, + x_trans = 0.327622, + y_trans = -0.278207, + z_trans = 0.244799, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 68.628296,--FOV + hAngle = 68.292320, + vAngle = -11.477349, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 68.628296,--FOV + hAngle = 0.000000, + vAngle = 30.227919, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 68.628296,--FOV + hAngle = -67.172974, + vAngle = -11.477349, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 70.000000,--FOV + hAngle = 20.000000, + vAngle = 8.000000, + x_trans = 0.360000, + y_trans = -0.041337, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 70.000000,--FOV + hAngle = -20.000000, + vAngle = 8.000000, + x_trans = 0.360000, + y_trans = -0.041337, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 75.000000,--FOV + hAngle = 0.000000, + vAngle = -23.000000, + x_trans = 0.360000, + y_trans = -0.041337, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["F-15C"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 70.611748,--FOV + hAngle = -1.240272, + vAngle = -33.850250, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 32.704346,--FOV + hAngle = 25.696522, + vAngle = -34.778103, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 32.704346,--FOV + hAngle = 0.000000, + vAngle = -47.845268, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 36.106045,--FOV + hAngle = -28.878576, + vAngle = -36.780628, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 88.727844,--FOV + hAngle = 128.508865, + vAngle = 13.131046, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 41.928593,--FOV + hAngle = 0.000000, + vAngle = -4.630446, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 88.727844,--FOV + hAngle = -128.508865, + vAngle = 13.131046, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 88.727844,--FOV + hAngle = 81.648369, + vAngle = -9.500000, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 88.727844,--FOV + hAngle = 0.000000, + vAngle = 34.180634, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 88.727844,--FOV + hAngle = -80.997551, + vAngle = -9.500000, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 56.032040,--FOV + hAngle = 14.803060, + vAngle = 3.332499, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 56.032040,--FOV + hAngle = -14.414484, + vAngle = 3.332499, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 88.727844,--FOV + hAngle = 0.000000, + vAngle = -9.678451, + x_trans = 0.264295, + y_trans = -0.064373, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["Ka-50"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 67.452896,--FOV + hAngle = 0.000000, + vAngle = -40.067383, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 37.846794,--FOV + hAngle = 51.644135, + vAngle = -51.870411, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 36.178646,--FOV + hAngle = -1.912186, + vAngle = -34.446247, + x_trans = 0.000000, + y_trans = -0.025421, + z_trans = 0.073226, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 73.605141,--FOV + hAngle = -90.361992, + vAngle = -44.103138, + x_trans = 0.169696, + y_trans = -0.073508, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 91.348198,--FOV + hAngle = 109.752129, + vAngle = 1.484382, + x_trans = 0.190306, + y_trans = 0.044778, + z_trans = -0.150335, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 42.512844,--FOV + hAngle = 0.000000, + vAngle = -4.478010, + x_trans = 0.154018, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 91.348198,--FOV + hAngle = -108.852020, + vAngle = 0.085984, + x_trans = 0.190306, + y_trans = 0.044778, + z_trans = 0.139404, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 89.777542,--FOV + hAngle = 16.411518, + vAngle = -27.209915, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = -0.218292, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 88.727844,--FOV + hAngle = 0.000000, + vAngle = 34.042202, + x_trans = 0.142145, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 59.208893,--FOV + hAngle = -32.128311, + vAngle = -5.720805, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 56.032040,--FOV + hAngle = 14.803060, + vAngle = 3.332499, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 56.032040,--FOV + hAngle = -14.414484, + vAngle = 3.332499, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 89.777542,--FOV + hAngle = 0.000000, + vAngle = -15.592758, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["MiG-29A"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 76.124840,--FOV + hAngle = -2.623254, + vAngle = -26.566959, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 34.911949,--FOV + hAngle = 24.601770, + vAngle = -32.350807, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 26.184198,--FOV + hAngle = 12.026249, + vAngle = -40.075508, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 39.454399,--FOV + hAngle = -26.664328, + vAngle = -32.355324, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 81.240005,--FOV + hAngle = 131.503998, + vAngle = 10.804660, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 44.201855,--FOV + hAngle = 0.000000, + vAngle = -2.378299, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 81.240005,--FOV + hAngle = -131.503998, + vAngle = 10.804660, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 81.240005,--FOV + hAngle = 76.013145, + vAngle = 2.248441, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 81.240005,--FOV + hAngle = 0.000000, + vAngle = 36.304676, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 81.240005,--FOV + hAngle = -74.774559, + vAngle = 2.248441, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 68.250000,--FOV + hAngle = 13.070938, + vAngle = 7.522498, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 68.250000,--FOV + hAngle = -13.070938, + vAngle = 7.522498, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 81.240005,--FOV + hAngle = 0.000000, + vAngle = -9.500000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["MiG-29G"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 76.124840,--FOV + hAngle = -2.623254, + vAngle = -26.566959, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 34.911949,--FOV + hAngle = 24.601770, + vAngle = -32.350807, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 26.184198,--FOV + hAngle = 12.026249, + vAngle = -40.075508, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 39.454399,--FOV + hAngle = -26.664328, + vAngle = -32.355324, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 81.240005,--FOV + hAngle = 131.503998, + vAngle = 10.804660, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 44.201855,--FOV + hAngle = 0.000000, + vAngle = -2.378299, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 81.240005,--FOV + hAngle = -131.503998, + vAngle = 10.804660, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 81.240005,--FOV + hAngle = 76.013145, + vAngle = 2.248441, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 81.240005,--FOV + hAngle = 0.000000, + vAngle = 36.304676, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 81.240005,--FOV + hAngle = -74.774559, + vAngle = 2.248441, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 68.250000,--FOV + hAngle = 13.070938, + vAngle = 7.522498, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 68.250000,--FOV + hAngle = -13.070938, + vAngle = 7.522498, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 81.240005,--FOV + hAngle = 0.000000, + vAngle = -9.500000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["MiG-29K"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 65.000000,--FOV + hAngle = 0.000000, + vAngle = -26.000000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 30.000000,--FOV + hAngle = 20.000000, + vAngle = -43.000000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 30.000000,--FOV + hAngle = 0.000000, + vAngle = -43.000000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 30.000000,--FOV + hAngle = -20.000000, + vAngle = -43.000000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 30.000000,--FOV + hAngle = 20.000000, + vAngle = -23.000000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 30.000000,--FOV + hAngle = 0.000000, + vAngle = -23.000000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 30.000000,--FOV + hAngle = -20.000000, + vAngle = -23.000000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 30.000000,--FOV + hAngle = 20.000000, + vAngle = 2.000000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 30.000000,--FOV + hAngle = 0.000000, + vAngle = 2.000000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 30.000000,--FOV + hAngle = -20.000000, + vAngle = 2.000000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 68.250000,--FOV + hAngle = 13.070938, + vAngle = 7.522498, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 68.250000,--FOV + hAngle = -13.070938, + vAngle = 7.522498, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 60.000000,--FOV + hAngle = 0.000000, + vAngle = -9.500000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["MiG-29S"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 76.124840,--FOV + hAngle = -2.623254, + vAngle = -26.566959, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 34.911949,--FOV + hAngle = 24.601770, + vAngle = -32.350807, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 26.184198,--FOV + hAngle = 12.026249, + vAngle = -40.075508, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 39.454399,--FOV + hAngle = -26.664328, + vAngle = -32.355324, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 81.240005,--FOV + hAngle = 131.503998, + vAngle = 10.804660, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 44.201855,--FOV + hAngle = 0.000000, + vAngle = -2.378299, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 81.240005,--FOV + hAngle = -131.503998, + vAngle = 10.804660, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 81.240005,--FOV + hAngle = 76.013145, + vAngle = 2.248441, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 81.240005,--FOV + hAngle = 0.000000, + vAngle = 36.304676, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 81.240005,--FOV + hAngle = -74.774559, + vAngle = 2.248441, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 68.250000,--FOV + hAngle = 13.070938, + vAngle = 7.522498, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 68.250000,--FOV + hAngle = -13.070938, + vAngle = 7.522498, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 81.240005,--FOV + hAngle = 0.000000, + vAngle = -9.500000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["P-51D"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 80.000000,--FOV + hAngle = 0.000000, + vAngle = -45.000000, + x_trans = 0.120000, + y_trans = 0.059000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 80.000000,--FOV + hAngle = 45.000000, + vAngle = -45.000000, + x_trans = 0.120000, + y_trans = 0.059000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 80.000000,--FOV + hAngle = 0.000000, + vAngle = -75.000000, + x_trans = 0.120000, + y_trans = 0.059000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 80.000000,--FOV + hAngle = -45.000000, + vAngle = -45.000000, + x_trans = 0.120000, + y_trans = 0.059000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 91.040001,--FOV + hAngle = 157.332764, + vAngle = -28.359503, + x_trans = 0.063872, + y_trans = 0.082888, + z_trans = -0.116148, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 50.000000,--FOV + hAngle = 0.000000, + vAngle = -8.722581, + x_trans = 0.212078, + y_trans = 0.057813, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 80.000000,--FOV + hAngle = -143.000000, + vAngle = 0.000000, + x_trans = 0.350000, + y_trans = 0.059000, + z_trans = 0.100000, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 80.000000,--FOV + hAngle = 45.000000, + vAngle = -5.000000, + x_trans = 0.120000, + y_trans = 0.059000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 80.000000,--FOV + hAngle = 0.000000, + vAngle = 10.000000, + x_trans = 0.120000, + y_trans = 0.059000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 80.000000,--FOV + hAngle = -45.000000, + vAngle = -5.000000, + x_trans = 0.120000, + y_trans = 0.059000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 80.000000,--FOV + hAngle = 0.000000, + vAngle = 10.000000, + x_trans = 0.120000, + y_trans = 0.059000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 80.000000,--FOV + hAngle = -20.000000, + vAngle = 8.000000, + x_trans = 0.120000, + y_trans = 0.059000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 80.000000,--FOV + hAngle = 0.000000, + vAngle = -9.500000, + x_trans = 0.120000, + y_trans = 0.059000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["Su-25"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 68.767799,--FOV + hAngle = 1.929517, + vAngle = -30.846605, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 29.223452,--FOV + hAngle = 37.489525, + vAngle = -38.883888, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 40.635601,--FOV + hAngle = -0.438357, + vAngle = -33.138290, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 24.797405,--FOV + hAngle = -34.382549, + vAngle = -34.808853, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 69.302101,--FOV + hAngle = 89.405373, + vAngle = 1.213156, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 29.761202,--FOV + hAngle = 0.000000, + vAngle = -6.880077, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 69.302101,--FOV + hAngle = -89.691940, + vAngle = 4.554290, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 69.302101,--FOV + hAngle = 52.113377, + vAngle = -3.970644, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 72.856201,--FOV + hAngle = 0.000000, + vAngle = 30.866713, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 69.302101,--FOV + hAngle = -50.664936, + vAngle = -3.970644, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 47.680202,--FOV + hAngle = 43.054649, + vAngle = -7.799250, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 47.680202,--FOV + hAngle = -41.743240, + vAngle = -7.799250, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 69.302101,--FOV + hAngle = 0.000000, + vAngle = -15.137112, + x_trans = 0.050000, + y_trans = 0.010000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["Su-25T"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 80.663399,--FOV + hAngle = 0.000000, + vAngle = -30.619938, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 39.764698,--FOV + hAngle = 28.661316, + vAngle = -41.406044, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 38.090847,--FOV + hAngle = -24.622110, + vAngle = -45.153934, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 36.062012,--FOV + hAngle = -20.779360, + vAngle = -23.755520, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 80.663399,--FOV + hAngle = 99.816956, + vAngle = 8.032285, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 58.718098,--FOV + hAngle = 0.000000, + vAngle = -5.000803, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 80.663399,--FOV + hAngle = -99.999687, + vAngle = 8.032285, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 80.663399,--FOV + hAngle = 58.382488, + vAngle = -6.648195, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 94.037704,--FOV + hAngle = 0.000000, + vAngle = 41.421227, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 80.663399,--FOV + hAngle = -57.531212, + vAngle = -6.648195, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 60.203396,--FOV + hAngle = 55.124939, + vAngle = -8.400513, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 60.203396,--FOV + hAngle = -52.633553, + vAngle = -8.400513, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 90.000000,--FOV + hAngle = 0.000000, + vAngle = -18.382137, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["Su-25TM"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 80.663399,--FOV + hAngle = 0.000000, + vAngle = -30.619938, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 39.764698,--FOV + hAngle = 28.661316, + vAngle = -41.406044, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 38.090847,--FOV + hAngle = -24.622110, + vAngle = -45.153934, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 33.645596,--FOV + hAngle = -36.653450, + vAngle = -23.703861, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 80.663399,--FOV + hAngle = 99.816956, + vAngle = 8.032285, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 58.718098,--FOV + hAngle = 0.000000, + vAngle = -5.000803, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 80.663399,--FOV + hAngle = -99.999687, + vAngle = 8.032285, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 80.663399,--FOV + hAngle = 58.382488, + vAngle = -6.648195, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 94.037704,--FOV + hAngle = 0.000000, + vAngle = 41.421227, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 80.663399,--FOV + hAngle = -57.531212, + vAngle = -6.648195, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 60.203396,--FOV + hAngle = 55.124939, + vAngle = -8.400513, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 60.203396,--FOV + hAngle = -52.633553, + vAngle = -8.400513, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 90.000000,--FOV + hAngle = 0.000000, + vAngle = -18.382137, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["Su-27"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 71.824692,--FOV + hAngle = 0.000000, + vAngle = -32.458889, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 33.361835,--FOV + hAngle = 41.045925, + vAngle = -40.805656, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 30.427544,--FOV + hAngle = 0.000000, + vAngle = -41.808968, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 34.392349,--FOV + hAngle = -32.597401, + vAngle = -35.293747, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 87.468338,--FOV + hAngle = 129.012665, + vAngle = 14.547977, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 43.977936,--FOV + hAngle = 0.000000, + vAngle = -4.951577, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 87.468338,--FOV + hAngle = -129.012665, + vAngle = 14.491872, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 87.468338,--FOV + hAngle = 82.862923, + vAngle = -9.500000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 87.468338,--FOV + hAngle = 0.000000, + vAngle = 38.979362, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 87.468338,--FOV + hAngle = -82.461266, + vAngle = -12.843998, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 68.786629,--FOV + hAngle = 15.618313, + vAngle = 7.522498, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 69.165199,--FOV + hAngle = -15.683434, + vAngle = 8.549150, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 87.468338,--FOV + hAngle = 0.000000, + vAngle = -9.500000, + x_trans = 0.113927, + y_trans = -0.004946, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} +SnapViews["Su-33"] = { +[1] = {-- player slot 1 + [1] = { + viewAngle = 71.824692,--FOV + hAngle = 0.000000, + vAngle = -32.458889, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [2] = { + viewAngle = 33.361835,--FOV + hAngle = 41.045925, + vAngle = -40.805656, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [3] = { + viewAngle = 30.427544,--FOV + hAngle = 0.000000, + vAngle = -41.808968, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [4] = { + viewAngle = 34.392349,--FOV + hAngle = -32.597401, + vAngle = -35.293747, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [5] = { + viewAngle = 87.468338,--FOV + hAngle = 129.012665, + vAngle = 14.547977, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [6] = { + viewAngle = 43.977936,--FOV + hAngle = 0.000000, + vAngle = -4.951577, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [7] = { + viewAngle = 87.468338,--FOV + hAngle = -129.012665, + vAngle = 14.491872, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [8] = { + viewAngle = 87.468338,--FOV + hAngle = 82.862923, + vAngle = -9.500000, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [9] = { + viewAngle = 87.468338,--FOV + hAngle = 0.000000, + vAngle = 38.979362, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [10] = { + viewAngle = 87.468338,--FOV + hAngle = -82.461266, + vAngle = -12.843998, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [11] = {--look at left mirror + viewAngle = 68.786629,--FOV + hAngle = 15.618313, + vAngle = 7.522498, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [12] = {--look at right mirror + viewAngle = 69.165199,--FOV + hAngle = -15.683434, + vAngle = 8.549150, + x_trans = 0.000000, + y_trans = 0.000000, + z_trans = 0.000000, + rollAngle = 0.000000, + }, + [13] = {--default view + viewAngle = 87.468338,--FOV + hAngle = 0.000000, + vAngle = -9.500000, + x_trans = 0.113927, + y_trans = -0.004946, + z_trans = 0.000000, + rollAngle = 0.000000, + }, +}, +} \ No newline at end of file diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Config/View/View.lua b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Config/View/View.lua new file mode 100644 index 000000000..9baf3b7df --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Config/View/View.lua @@ -0,0 +1,128 @@ +-- View scripts +-- Copyright (C) 2004, Eagle Dynamics. + +CockpitMouse = true --false +CockpitMouseSpeedSlow = 1.0 +CockpitMouseSpeedNormal = 10.0 +CockpitMouseSpeedFast = 20.0 +CockpitKeyboardAccelerationSlow = 5.0 +CockpitKeyboardAccelerationNormal = 30.0 +CockpitKeyboardAccelerationFast = 80.0 +CockpitKeyboardZoomAcceleration = 300.0 +DisableSnapViewsSaving = false +UseDefaultSnapViews = true +CockpitPanStepHor = 45.0 +CockpitPanStepVert = 30.0 +CockpitNyMove = true + +CockpitHAngleAccelerateTimeMax = 0.15 +CockpitVAngleAccelerateTimeMax = 0.15 +CockpitZoomAccelerateTimeMax = 0.2 + +function NaturalHeadMoving(tang, roll, omz) + local r = roll + if r > 90.0 then + r = 180.0 - r + elseif roll < -90.0 then + r = -180.0 - r + end + local hAngle = -0.25 * r + local vAngle = math.min(math.max(0.0, 0.4 * tang + 45.0 * omz), 90.0) + return hAngle, vAngle +end + +ExternalMouse = true +ExternalMouseSpeedSlow = 1.0 +ExternalMouseSpeedNormal = 5.0 +ExternalMouseSpeedFast = 20.0 +ExternalViewAngleMin = 3.0 +ExternalViewAngleMax = 170.0 +ExternalViewAngleDefault = 60.0 +ExternalKeyboardZoomAcceleration = 30.0 +ExternalKeyboardZoomAccelerateTimeMax = 1.0 +ExplosionExpoTime = 4.0 +ExternalKeyboardAccelerationSlow = 1.0 +ExternalKeyboardAccelerationNormal = 10.0 +ExternalKeyboardAccelerationFast = 30.0 +ExternalHAngleAccelerateTimeMax = 3.0 +ExternalVAngleAccelerateTimeMax = 3.0 +ExternalDistAccelerateTimeMax = 3.0 +ExternalHAngleLocalAccelerateTimeMax = 3.0 +ExternalVAngleLocalAccelerateTimeMax = 3.0 +ExternalAngleNormalDiscreteStep = 15.0/ExternalKeyboardAccelerationNormal -- When 'S' is pressed only +ChaseCameraNyMove = true +FreeCameraAngleIncrement = 3.0 +FreeCameraDistanceIncrement = 200.0 +FreeCameraLeftRightIncrement = 2.0 +FreeCameraAltitudeIncrement = 2.0 +FreeCameraScalarSpeedAcceleration = 0.1 +xMinMap = -300000 +xMaxMap = 500000 +yMinMap = -400000 +yMaxMap = 200000 +dxMap = 150000 +dyMap = 100000 + +head_roll_shaking = true +head_roll_shaking_max = 30.0 +head_roll_shaking_compensation_gain = 0.3 + +-- CameraJiggle() and CameraFloat() functions make camera position +-- dependent on FPS so be careful in using the Shift-J command with tracks, please. +-- uncomment to use custom jiggle functions +--[[ +function CameraJiggle(t,rnd1,rnd2,rnd3) + local rotX, rotY, rotZ + rotX = 0.05 * rnd1 * math.sin(37.0 * (t - 0.0)) + rotY = 0.05 * rnd2 * math.sin(41.0 * (t - 1.0)) + rotZ = 0.05 * rnd3 * math.sin(53.0 * (t - 2.0)) + return rotX, rotY, rotZ +end + +function CameraFloat(t) + local dX, dY, dZ + dX = 0.61 * math.sin(0.7 * t) + 0.047 * math.sin(1.6 * t); + dY = 0.43 * math.sin(0.6 * t) + 0.067 * math.sin(1.7 * t); + dZ = 0.53 * math.sin(1.0 * t) + 0.083 * math.sin(1.9 * t); + return dX, dY, dZ +end +--]] +--Debug keys + +DEBUG_TEXT = 1 +DEBUG_GEOMETRY = 2 + +debug_keys = { + [DEBUG_TEXT] = 1, + [DEBUG_GEOMETRY] = 1 +} + +function onDebugCommand(command) + if command == 10000 then + if debug_keys[DEBUG_TEXT] ~= 0 or debug_keys[DEBUG_GEOMETRY] ~= 0 then + debug_keys[DEBUG_GEOMETRY] = 0 + debug_keys[DEBUG_TEXT] = 0 + else + debug_keys[DEBUG_GEOMETRY] = 1 + debug_keys[DEBUG_TEXT] = 1 + end + elseif command == 10001 then + if debug_keys[DEBUG_TEXT] ~= 0 then + debug_keys[DEBUG_TEXT] = 0 + else + debug_keys[DEBUG_TEXT] = 1 + end + elseif command == 10002 then + if debug_keys[DEBUG_GEOMETRY] ~= 0 then + debug_keys[DEBUG_GEOMETRY] = 0 + else + debug_keys[DEBUG_GEOMETRY] = 1 + end + end +end + +-- gain values for TrackIR , to unify responce on diffrent types of aircraft +TrackIR_gain_x = -0.6 +TrackIR_gain_y = 0.3 +TrackIR_gain_z = -0.25 +TrackIR_gain_roll = -90 \ No newline at end of file diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Scripts/World/GPS_GNSS.lua b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Scripts/World/GPS_GNSS.lua new file mode 100644 index 000000000..2cb4a8e8d --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Scripts/World/GPS_GNSS.lua @@ -0,0 +1,880 @@ +SAT_SYS_GLONASS = 0 +SAT_SYS_GPS = 1 + +almanac = {} +--GPS +almanac[0] = {} +almanac[0]["System"] = SAT_SYS_GPS +almanac[0]["Number"] = 1 +almanac[0]["Orbital"] = "F" +almanac[0]["Eccentricity"] = 6.294000e-003 +almanac[0]["Time_of_Applicability"] = 5.898240e+005 +almanac[0]["Orbital_Inclination"] = 9.885676e-001 +almanac[0]["Rate_of_Right_Ascen"] = -7.862702e-009 +almanac[0]["SQRT_A"] = 5.153700e+003 +almanac[0]["Right_Ascen_at_Week"] = 8.096750e-001 +almanac[0]["Argument_of_Perigee"] = -1.777773e+000 +almanac[0]["Mean_Anom"] = -5.315745e-001 +almanac[0]["week"] = 1390 + +almanac[1] = {} +almanac[1]["System"] = SAT_SYS_GPS +almanac[1]["Number"] = 2 +almanac[1]["Orbital"] = "C" +almanac[1]["Eccentricity"] = 8.794000e-003 +almanac[1]["Time_of_Applicability"] = 5.898240e+005 +almanac[1]["Orbital_Inclination"] = 9.487811e-001 +almanac[1]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[1]["SQRT_A"] = 5.153700e+003 +almanac[1]["Right_Ascen_at_Week"] = -1.329172e+000 +almanac[1]["Argument_of_Perigee"] = 2.138637e+000 +almanac[1]["Mean_Anom"] = 7.311702e-001 +almanac[1]["week"] = 1390 + +almanac[2] = {} +almanac[2]["System"] = SAT_SYS_GPS +almanac[2]["Number"] = 3 +almanac[2]["Orbital"] = "F" +almanac[2]["Eccentricity"] = 8.424000e-003 +almanac[2]["Time_of_Applicability"] = 5.898240e+005 +almanac[2]["Orbital_Inclination"] = 9.262804e-001 +almanac[2]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[2]["SQRT_A"] = 5.153600e+003 +almanac[2]["Right_Ascen_at_Week"] = -2.341514e+000 +almanac[2]["Argument_of_Perigee"] = 6.749357e-001 +almanac[2]["Mean_Anom"] = -2.296153e-001 +almanac[2]["week"] = 1389 + +almanac[3] = {} +almanac[3]["System"] = SAT_SYS_GPS +almanac[3]["Number"] = 4 +almanac[3]["Orbital"] = "D" +almanac[3]["Eccentricity"] = 7.413000e-003 +almanac[3]["Time_of_Applicability"] = 5.898240e+005 +almanac[3]["Orbital_Inclination"] = 9.482889e-001 +almanac[3]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[3]["SQRT_A"] = 5.153600e+003 +almanac[3]["Right_Ascen_at_Week"] = -1.309589e+000 +almanac[3]["Argument_of_Perigee"] = 1.623504e-001 +almanac[3]["Mean_Anom"] = -3.022943e+000 +almanac[3]["week"] = 1390 + +almanac[4] = {} +almanac[4]["System"] = SAT_SYS_GPS +almanac[4]["Number"] = 5 +almanac[4]["Orbital"] = "B" +almanac[4]["Eccentricity"] = 7.432000e-003 +almanac[4]["Time_of_Applicability"] = 5.898240e+005 +almanac[4]["Orbital_Inclination"] = 9.387437e-001 +almanac[4]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[4]["SQRT_A"] = 5.153700e+003 +almanac[4]["Right_Ascen_at_Week"] = 2.779487e+000 +almanac[4]["Argument_of_Perigee"] = 1.099033e+000 +almanac[4]["Mean_Anom"] = 2.970984e+000 +almanac[4]["week"] = 1390 + +almanac[5] = {} +almanac[5]["System"] = SAT_SYS_GPS +almanac[5]["Number"] = 6 +almanac[5]["Orbital"] = "C" +almanac[5]["Eccentricity"] = 6.020000e-003 +almanac[5]["Time_of_Applicability"] = 5.898240e+005 +almanac[5]["Orbital_Inclination"] = 9.337591e-001 +almanac[5]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[5]["SQRT_A"] = 5.153600e+003 +almanac[5]["Right_Ascen_at_Week"] = -2.407627e+000 +almanac[5]["Argument_of_Perigee"] = -1.788263e+000 +almanac[5]["Mean_Anom"] = -2.149877e+000 +almanac[5]["week"] = 1390 + +almanac[6] = {} +almanac[6]["System"] = SAT_SYS_GPS +almanac[6]["Number"] = 7 +almanac[6]["Orbital"] = "C" +almanac[6]["Eccentricity"] = 1.052400e-002 +almanac[6]["Time_of_Applicability"] = 5.898240e+005 +almanac[6]["Orbital_Inclination"] = 9.353229e-001 +almanac[6]["Rate_of_Right_Ascen"] = -8.080868e-009 +almanac[6]["SQRT_A"] = 5.153700e+003 +almanac[6]["Right_Ascen_at_Week"] = -2.433580e+000 +almanac[6]["Argument_of_Perigee"] = -1.767301e+000 +almanac[6]["Mean_Anom"] = -3.141503e+000 +almanac[6]["week"] = 1390 + +almanac[7] = {} +almanac[7]["System"] = SAT_SYS_GPS +almanac[7]["Number"] = 8 +almanac[7]["Orbital"] = "A" +almanac[7]["Eccentricity"] = 9.822000e-003 +almanac[7]["Time_of_Applicability"] = 5.898240e+005 +almanac[7]["Orbital_Inclination"] = 9.741390e-001 +almanac[7]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[7]["SQRT_A"] = 5.153600e+003 +almanac[7]["Right_Ascen_at_Week"] = 1.857849e+000 +almanac[7]["Argument_of_Perigee"] = 2.674034e+000 +almanac[7]["Mean_Anom"] = -2.009745e+000 +almanac[7]["week"] = 1390 + +almanac[8] = {} +almanac[8]["System"] = SAT_SYS_GPS +almanac[8]["Number"] = 9 +almanac[8]["Orbital"] = "A" +almanac[8]["Eccentricity"] = 1.839300e-002 +almanac[8]["Time_of_Applicability"] = 5.898240e+005 +almanac[8]["Orbital_Inclination"] = 9.617541e-001 +almanac[8]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[8]["SQRT_A"] = 5.153600e+003 +almanac[8]["Right_Ascen_at_Week"] = 1.777005e+000 +almanac[8]["Argument_of_Perigee"] = 1.274962e+000 +almanac[8]["Mean_Anom"] = -2.349578e+000 +almanac[8]["week"] = 1390 + +almanac[9] = {} +almanac[9]["System"] = SAT_SYS_GPS +almanac[9]["Number"] = 10 +almanac[9]["Orbital"] = "E" +almanac[9]["Eccentricity"] = 7.061000e-003 +almanac[9]["Time_of_Applicability"] = 5.898240e+005 +almanac[9]["Orbital_Inclination"] = 9.728876e-001 +almanac[9]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[9]["SQRT_A"] = 5.153600e+003 +almanac[9]["Right_Ascen_at_Week"] = -2.563014e-001 +almanac[9]["Argument_of_Perigee"] = 4.377980e-001 +almanac[9]["Mean_Anom"] = 1.210716e+000 +almanac[9]["week"] = 1390 + +almanac[10] = {} +almanac[10]["System"] = SAT_SYS_GPS +almanac[10]["Number"] = 11 +almanac[10]["Orbital"] = "D" +almanac[10]["Eccentricity"] = 5.744000e-003 +almanac[10]["Time_of_Applicability"] = 5.898240e+005 +almanac[10]["Orbital_Inclination"] = 8.959309e-001 +almanac[10]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[10]["SQRT_A"] = 5.153600e+003 +almanac[10]["Right_Ascen_at_Week"] = -1.478816e+000 +almanac[10]["Argument_of_Perigee"] = 3.750011e-001 +almanac[10]["Mean_Anom"] = -1.522048e+000 +almanac[10]["week"] = 1390 + +almanac[11] = {} +almanac[11]["System"] = SAT_SYS_GPS +almanac[11]["Number"] = 13 +almanac[11]["Orbital"] = "F" +almanac[11]["Eccentricity"] = 3.088000e-003 +almanac[11]["Time_of_Applicability"] = 5.898240e+005 +almanac[11]["Orbital_Inclination"] = 9.927564e-001 +almanac[11]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[11]["SQRT_A"] = 5.153700e+003 +almanac[11]["Right_Ascen_at_Week"] = 7.956600e-001 +almanac[11]["Argument_of_Perigee"] = 1.279395e+000 +almanac[11]["Mean_Anom"] = 1.004349e+000 +almanac[11]["week"] = 1390 + +almanac[12] = {} +almanac[12]["System"] = SAT_SYS_GPS +almanac[12]["Number"] = 14 +almanac[12]["Orbital"] = "F" +almanac[12]["Eccentricity"] = 2.591000e-003 +almanac[12]["Time_of_Applicability"] = 5.898240e+005 +almanac[12]["Orbital_Inclination"] = 9.868729e-001 +almanac[12]["Rate_of_Right_Ascen"] = -7.885391e-009 +almanac[12]["SQRT_A"] = 5.153600e+003 +almanac[12]["Right_Ascen_at_Week"] = 7.819592e-001 +almanac[12]["Argument_of_Perigee"] = -2.158621e+000 +almanac[12]["Mean_Anom"] = 5.412611e-001 +almanac[12]["week"] = 1390 + +almanac[13] = {} +almanac[13]["System"] = SAT_SYS_GPS +almanac[13]["Number"] = 15 +almanac[13]["Orbital"] = "D" +almanac[13]["Eccentricity"] = 9.828000e-003 +almanac[13]["Time_of_Applicability"] = 3.194880e+005 +almanac[13]["Orbital_Inclination"] = 9.554204e-001 +almanac[13]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[13]["SQRT_A"] = 5.153600e+003 +almanac[13]["Right_Ascen_at_Week"] = -1.123869e+000 +almanac[13]["Argument_of_Perigee"] = 2.690266e+000 +almanac[13]["Mean_Anom"] = 2.220476e+000 +almanac[13]["week"] = 1389 + +almanac[14] = {} +almanac[14]["System"] = SAT_SYS_GPS +almanac[14]["Number"] = 16 +almanac[14]["Orbital"] = "B" +almanac[14]["Eccentricity"] = 3.494000e-003 +almanac[14]["Time_of_Applicability"] = 5.898240e+005 +almanac[14]["Orbital_Inclination"] = 9.629340e-001 +almanac[14]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[14]["SQRT_A"] = 5.153700e+003 +almanac[14]["Right_Ascen_at_Week"] = 2.873124e+000 +almanac[14]["Argument_of_Perigee"] = -7.819243e-001 +almanac[14]["Mean_Anom"] = 2.623629e+000 +almanac[14]["week"] = 1390 + +almanac[15] = {} +almanac[15]["System"] = SAT_SYS_GPS +almanac[15]["Number"] = 17 +almanac[15]["Orbital"] = "C" +almanac[15]["Eccentricity"] = 2.141000e-003 +almanac[15]["Time_of_Applicability"] = 5.898240e+005 +almanac[15]["Orbital_Inclination"] = 9.601170e-001 +almanac[15]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[15]["SQRT_A"] = 5.153700e+003 +almanac[15]["Right_Ascen_at_Week"] = -2.371499e+000 +almanac[15]["Argument_of_Perigee"] = 3.087694e+000 +almanac[15]["Mean_Anom"] = 1.611217e+000 +almanac[15]["week"] = 1390 + +almanac[16] = {} +almanac[16]["System"] = SAT_SYS_GPS +almanac[16]["Number"] = 18 +almanac[16]["Orbital"] = "E" +almanac[16]["Eccentricity"] = 7.636000e-003 +almanac[16]["Time_of_Applicability"] = 5.898240e+005 +almanac[16]["Orbital_Inclination"] = 9.569597e-001 +almanac[16]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[16]["SQRT_A"] = 5.153700e+003 +almanac[16]["Right_Ascen_at_Week"] = -2.359858e-001 +almanac[16]["Argument_of_Perigee"] = -2.649216e+000 +almanac[16]["Mean_Anom"] = 2.675029e+000 +almanac[16]["week"] = 1390 + +almanac[17] = {} +almanac[17]["System"] = SAT_SYS_GPS +almanac[17]["Number"] = 19 +almanac[17]["Orbital"] = "C" +almanac[17]["Eccentricity"] = 3.602000e-003 +almanac[17]["Time_of_Applicability"] = 5.898240e+005 +almanac[17]["Orbital_Inclination"] = 9.580209e-001 +almanac[17]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[17]["SQRT_A"] = 5.153600e+003 +almanac[17]["Right_Ascen_at_Week"] = -2.312385e+000 +almanac[17]["Argument_of_Perigee"] = -1.161079e+000 +almanac[17]["Mean_Anom"] = 1.310619e+000 +almanac[17]["week"] = 1390 + +almanac[18] = {} +almanac[18]["System"] = SAT_SYS_GPS +almanac[18]["Number"] = 20 +almanac[18]["Orbital"] = "E" +almanac[18]["Eccentricity"] = 2.796000e-003 +almanac[18]["Time_of_Applicability"] = 5.898240e+005 +almanac[18]["Orbital_Inclination"] = 9.564693e-001 +almanac[18]["Rate_of_Right_Ascen"] = -7.908080e-009 +almanac[18]["SQRT_A"] = 5.153600e+003 +almanac[18]["Right_Ascen_at_Week"] = -2.889565e-001 +almanac[18]["Argument_of_Perigee"] = 1.379612e+000 +almanac[18]["Mean_Anom"] = 2.461750e+000 +almanac[18]["week"] = 1390 + +almanac[19] = {} +almanac[19]["System"] = SAT_SYS_GPS +almanac[19]["Number"] = 21 +almanac[19]["Orbital"] = "D" +almanac[19]["Eccentricity"] = 1.162900e-002 +almanac[19]["Time_of_Applicability"] = 5.898240e+005 +almanac[19]["Orbital_Inclination"] = 9.418592e-001 +almanac[19]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[19]["SQRT_A"] = 5.153600e+003 +almanac[19]["Right_Ascen_at_Week"] = -1.289972e+000 +almanac[19]["Argument_of_Perigee"] = -2.923686e+000 +almanac[19]["Mean_Anom"] = -2.349194e+000 +almanac[19]["week"] = 1390 + +almanac[20] = {} +almanac[20]["System"] = SAT_SYS_GPS +almanac[20]["Number"] = 22 +almanac[20]["Orbital"] = "E" +almanac[20]["Eccentricity"] = 4.893000e-003 +almanac[20]["Time_of_Applicability"] = 5.898240e+005 +almanac[20]["Orbital_Inclination"] = 9.545093e-001 +almanac[20]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[20]["SQRT_A"] = 5.153600e+003 +almanac[20]["Right_Ascen_at_Week"] = -2.280969e-001 +almanac[20]["Argument_of_Perigee"] = -1.674502e+000 +almanac[20]["Mean_Anom"] = 1.106852e+000 +almanac[20]["week"] = 1390 + +almanac[21] = {} +almanac[21]["System"] = SAT_SYS_GPS +almanac[21]["Number"] = 23 +almanac[21]["Orbital"] = "F" +almanac[21]["Eccentricity"] = 4.822000e-003 +almanac[21]["Time_of_Applicability"] = 5.898240e+005 +almanac[21]["Orbital_Inclination"] = 9.691247e-001 +almanac[21]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[21]["SQRT_A"] = 5.153700e+003 +almanac[21]["Right_Ascen_at_Week"] = 7.667399e-001 +almanac[21]["Argument_of_Perigee"] = 2.497634e+000 +almanac[21]["Mean_Anom"] = 3.184700e-001 +almanac[21]["week"] = 1390 + +almanac[22] = {} +almanac[22]["System"] = SAT_SYS_GPS +almanac[22]["Number"] = 24 +almanac[22]["Orbital"] = "D" +almanac[22]["Eccentricity"] = 9.277000e-003 +almanac[22]["Time_of_Applicability"] = 5.898240e+005 +almanac[22]["Orbital_Inclination"] = 9.585183e-001 +almanac[22]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[22]["SQRT_A"] = 5.153900e+003 +almanac[22]["Right_Ascen_at_Week"] = -1.274840e+000 +almanac[22]["Argument_of_Perigee"] = -8.815651e-001 +almanac[22]["Mean_Anom"] = -1.695551e+000 +almanac[22]["week"] = 1390 + +almanac[23] = {} +almanac[23]["System"] = SAT_SYS_GPS +almanac[23]["Number"] = 25 +almanac[23]["Orbital"] = "A" +almanac[23]["Eccentricity"] = 1.257400e-002 +almanac[23]["Time_of_Applicability"] = 5.898240e+005 +almanac[23]["Orbital_Inclination"] = 9.551027e-001 +almanac[23]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[23]["SQRT_A"] = 5.153600e+003 +almanac[23]["Right_Ascen_at_Week"] = 1.721853e+000 +almanac[23]["Argument_of_Perigee"] = -1.329870e+000 +almanac[23]["Mean_Anom"] = -1.769623e+000 +almanac[23]["week"] = 1390 + +almanac[24] = {} +almanac[24]["System"] = SAT_SYS_GPS +almanac[24]["Number"] = 26 +almanac[24]["Orbital"] = "F" +almanac[24]["Eccentricity"] = 1.745700e-002 +almanac[24]["Time_of_Applicability"] = 5.898240e+005 +almanac[24]["Orbital_Inclination"] = 9.908749e-001 +almanac[24]["Rate_of_Right_Ascen"] = -7.840012e-009 +almanac[24]["SQRT_A"] = 5.153700e+003 +almanac[24]["Right_Ascen_at_Week"] = 7.961836e-001 +almanac[24]["Argument_of_Perigee"] = 8.161502e-001 +almanac[24]["Mean_Anom"] = -5.841961e-001 +almanac[24]["week"] = 1390 + +almanac[25] = {} +almanac[25]["System"] = SAT_SYS_GPS +almanac[25]["Number"] = 27 +almanac[25]["Orbital"] = "A" +almanac[25]["Eccentricity"] = 1.991000e-002 +almanac[25]["Time_of_Applicability"] = 5.898240e+005 +almanac[25]["Orbital_Inclination"] = 9.596563e-001 +almanac[25]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[25]["SQRT_A"] = 5.153600e+003 +almanac[25]["Right_Ascen_at_Week"] = 1.754124e+000 +almanac[25]["Argument_of_Perigee"] = -1.900854e+000 +almanac[25]["Mean_Anom"] = 3.046487e+000 +almanac[25]["week"] = 1390 + +almanac[26] = {} +almanac[26]["System"] = SAT_SYS_GPS +almanac[26]["Number"] = 28 +almanac[26]["Orbital"] = "B" +almanac[26]["Eccentricity"] = 1.162800e-002 +almanac[26]["Time_of_Applicability"] = 5.898240e+005 +almanac[26]["Orbital_Inclination"] = 9.610106e-001 +almanac[26]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[26]["SQRT_A"] = 5.153600e+003 +almanac[26]["Right_Ascen_at_Week"] = 2.882583e+000 +almanac[26]["Argument_of_Perigee"] = -2.242868e+000 +almanac[26]["Mean_Anom"] = 1.860642e+000 +almanac[26]["week"] = 1390 + +almanac[27] = {} +almanac[27]["System"] = SAT_SYS_GPS +almanac[27]["Number"] = 29 +almanac[27]["Orbital"] = "F" +almanac[27]["Eccentricity"] = 9.462000e-003 +almanac[27]["Time_of_Applicability"] = 1.474560e+005 +almanac[27]["Orbital_Inclination"] = 9.874838e-001 +almanac[27]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[27]["SQRT_A"] = 5.153700e+003 +almanac[27]["Right_Ascen_at_Week"] = 7.647503e-001 +almanac[27]["Argument_of_Perigee"] = -8.614589e-001 +almanac[27]["Mean_Anom"] = -4.488983e-001 +almanac[27]["week"] = 1390 + +almanac[28] = {} +almanac[28]["System"] = SAT_SYS_GPS +almanac[28]["Number"] = 30 +almanac[28]["Orbital"] = "B" +almanac[28]["Eccentricity"] = 9.296000e-003 +almanac[28]["Time_of_Applicability"] = 5.898240e+005 +almanac[28]["Orbital_Inclination"] = 9.452992e-001 +almanac[28]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[28]["SQRT_A"] = 5.153600e+003 +almanac[28]["Right_Ascen_at_Week"] = 2.826698e+000 +almanac[28]["Argument_of_Perigee"] = 1.306413e+000 +almanac[28]["Mean_Anom"] = 2.148725e+000 +almanac[28]["week"] = 1390 + + + + + + +--GLONASS +--1 îðáèòàëüíàÿ ïëîñêîñòü, íîìåðà 1-8 +almanac[29] = {} +almanac[29]["System"] = SAT_SYS_GLONASS +almanac[29]["Number"] = 1 +almanac[29]["Orbital"] = 1 +almanac[29]["GLONASS_Data"] = {} +almanac[29]["GLONASS_Data"]["NKU_Number"] = 796 +almanac[29]["GLONASS_Data"]["Cosmos_Number"] = 2411 +almanac[29]["Eccentricity"] = 1.184000e-003 +almanac[29]["Time_of_Applicability"] = 0.000000e+000 +almanac[29]["Orbital_Inclination"] = 1.126443e+000 +almanac[29]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[29]["SQRT_A"] = 5.050500e+003 +almanac[29]["Right_Ascen_at_Week"] = 5.979807e+000 +almanac[29]["Argument_of_Perigee"] = 2.622634e+000 +almanac[29]["Mean_Anom"] = -5.519651e+000 +almanac[29]["week"] = 1390 +almanac[29]["Commit_date"] = "06.02.2005" +almanac[29]["Life_dates"] = {} + +almanac[30] = {} +almanac[30]["System"] = SAT_SYS_GLONASS +almanac[30]["Number"] = 2 +almanac[30]["Orbital"] = 1 +almanac[30]["GLONASS_Data"] = {} +almanac[30]["GLONASS_Data"]["NKU_Number"] = 794 +almanac[30]["GLONASS_Data"]["Cosmos_Number"] = 2401 +almanac[30]["Eccentricity"] = 4.486000e-003 +almanac[30]["Time_of_Applicability"] = 0.000000e+000 +almanac[30]["Orbital_Inclination"] = 1.128459e+000 +almanac[30]["Rate_of_Right_Ascen"] = -6.759654e-009 +almanac[30]["SQRT_A"] = 5.050500e+003 +almanac[30]["Right_Ascen_at_Week"] = 5.997871e+000 +almanac[30]["Argument_of_Perigee"] = 1.709531e+000 +almanac[30]["Mean_Anom"] = -5.367633e+000 +almanac[30]["week"] = 1390 +almanac[30]["Commit_date"] = "02.02.2004" +almanac[30]["Life_dates"] = {} + +almanac[31] = {} +almanac[31]["System"] = SAT_SYS_GLONASS +almanac[31]["Number"] = 3 +almanac[31]["Orbital"] = 1 +almanac[31]["GLONASS_Data"] = {} +almanac[31]["GLONASS_Data"]["NKU_Number"] = 789 +almanac[31]["GLONASS_Data"]["Cosmos_Number"] = 2381 +almanac[31]["Eccentricity"] = 2.459000e-003 +almanac[31]["Time_of_Applicability"] = 0.000000e+000 +almanac[31]["Orbital_Inclination"] = 1.122958e+000 +almanac[31]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[31]["SQRT_A"] = 5.050500e+003 +almanac[31]["Right_Ascen_at_Week"] = 5.960713e+000 +almanac[31]["Argument_of_Perigee"] = -2.683407e+000 +almanac[31]["Mean_Anom"] = -1.791788e+000 +almanac[31]["week"] = 1390 +almanac[31]["Commit_date"] = "04.01.2002" +almanac[31]["Life_dates"] = {} + +almanac[32] = {} +almanac[32]["System"] = SAT_SYS_GLONASS +almanac[32]["Number"] = 4 +almanac[32]["Orbital"] = 1 +almanac[32]["GLONASS_Data"] = {} +almanac[32]["GLONASS_Data"]["NKU_Number"] = 795 +almanac[29]["GLONASS_Data"]["Cosmos_Number"] = 2403 +almanac[32]["Eccentricity"] = 4.054000e-003 +almanac[32]["Time_of_Applicability"] = 0.000000e+000 +almanac[32]["Orbital_Inclination"] = 1.128543e+000 +almanac[32]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[32]["SQRT_A"] = 5.050500e+003 +almanac[32]["Right_Ascen_at_Week"] = 5.998081e+000 +almanac[32]["Argument_of_Perigee"] = 1.497160e+000 +almanac[32]["Mean_Anom"] = -4.293681e-001 +almanac[32]["week"] = 1390 +almanac[32]["Commit_date"] = "29.01.2004" +almanac[32]["Life_dates"] = {} + +almanac[33] = {} +almanac[33]["System"] = SAT_SYS_GLONASS +almanac[33]["Number"] = 5 +almanac[33]["Orbital"] = 1 +almanac[33]["GLONASS_Data"] = {} +almanac[33]["GLONASS_Data"]["NKU_Number"] = 711 +almanac[33]["GLONASS_Data"]["Cosmos_Number"] = 2382 +almanac[33]["Eccentricity"] = 7.040000e-004 +almanac[33]["Time_of_Applicability"] = 0.000000e+000 +almanac[33]["Orbital_Inclination"] = 1.122886e+000 +almanac[33]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[33]["SQRT_A"] = 5.050600e+003 +almanac[33]["Right_Ascen_at_Week"] = 5.960713e+000 +almanac[33]["Argument_of_Perigee"] = 2.740933e+000 +almanac[33]["Mean_Anom"] = -2.523604e+000 +almanac[33]["week"] = 1390 +almanac[33]["Commit_date"] = "13.02.2003" +almanac[33]["Life_dates"] = {} + +almanac[34] = {} +almanac[34]["System"] = SAT_SYS_GLONASS +almanac[34]["Number"] = 6 +almanac[34]["Orbital"] = 1 +almanac[34]["GLONASS_Data"] = {} +almanac[34]["GLONASS_Data"]["NKU_Number"] = 701 +almanac[34]["GLONASS_Data"]["Cosmos_Number"] = 2404 +almanac[34]["Eccentricity"] = 4.766000e-003 +almanac[34]["Time_of_Applicability"] = 0.000000e+000 +almanac[34]["Orbital_Inclination"] = 1.128276e+000 +almanac[34]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[34]["SQRT_A"] = 5.050500e+003 +almanac[34]["Right_Ascen_at_Week"] = 5.997906e+000 +almanac[34]["Argument_of_Perigee"] = 1.802417e+000 +almanac[34]["Mean_Anom"] = -2.426512e+000 +almanac[34]["week"] = 1390 +almanac[34]["Commit_date"] = "08.12.2004" +almanac[34]["Life_dates"] = {} + +almanac[35] = {} +almanac[35]["System"] = SAT_SYS_GLONASS +almanac[35]["Number"] = 7 +almanac[35]["Orbital"] = 1 +almanac[35]["GLONASS_Data"] = {} +almanac[35]["GLONASS_Data"]["NKU_Number"] = 712 +almanac[35]["GLONASS_Data"]["Cosmos_Number"] = 2413 +almanac[35]["Eccentricity"] = 7.570000e-004 +almanac[35]["Time_of_Applicability"] = 0.000000e+000 +almanac[35]["Orbital_Inclination"] = 1.126344e+000 +almanac[35]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[35]["SQRT_A"] = 5.050500e+003 +almanac[35]["Right_Ascen_at_Week"] = 5.979388e+000 +almanac[35]["Argument_of_Perigee"] = 2.566068e+000 +almanac[35]["Mean_Anom"] = -3.921228e+000 +almanac[35]["week"] = 1390 +almanac[35]["Commit_date"] = "07.10.2005" +almanac[35]["Life_dates"] = {} + +almanac[36] = {} +almanac[36]["System"] = SAT_SYS_GLONASS +almanac[36]["GLONASS_Data"] = {} +almanac[36]["Number"] = 8 +almanac[36]["Orbital"] = 1 +almanac[36]["GLONASS_Data"] = {} +almanac[36]["GLONASS_Data"]["NKU_Number"] = 797 +almanac[36]["GLONASS_Data"]["Cosmos_Number"] = 2412 +almanac[36]["Eccentricity"] = 4.060000e-004 +almanac[36]["Time_of_Applicability"] = 0.000000e+000 +almanac[36]["Orbital_Inclination"] = 1.126564e+000 +almanac[36]["Rate_of_Right_Ascen"] = -6.785834e-009 +almanac[36]["SQRT_A"] = 5.050600e+003 +almanac[36]["Right_Ascen_at_Week"] = 5.980069e+000 +almanac[36]["Argument_of_Perigee"] = 2.673633e+000 +almanac[36]["Mean_Anom"] = -4.812026e+000 +almanac[36]["week"] = 1390 +almanac[36]["Commit_date"] = "06.02.2005" +almanac[36]["Life_dates"] = {} + +--3 îðáèòàëüíàÿ ïëîñêîñòü, íîìåðà 17-24 +almanac[37] = {} +almanac[37]["System"] = SAT_SYS_GLONASS +almanac[37]["Number"] = 17 +almanac[37]["Orbital"] = 3 +almanac[37]["GLONASS_Data"] = {} +almanac[37]["GLONASS_Data"]["NKU_Number"] = 787 +almanac[37]["GLONASS_Data"]["Cosmos_Number"] = 2375 +almanac[37]["Eccentricity"] = 5.670000e-004 +almanac[37]["Time_of_Applicability"] = 0.000000e+000 +almanac[37]["Orbital_Inclination"] = 1.126524e+000 +almanac[37]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[37]["SQRT_A"] = 5.050500e+003 +almanac[37]["Right_Ascen_at_Week"] = 3.895554e+000 +almanac[37]["Argument_of_Perigee"] = 6.085085e-001 +almanac[37]["Mean_Anom"] = -2.977407e+000 +almanac[37]["week"] = 1390 +almanac[37]["Commit_date"] = "04.11.2000" +almanac[37]["Life_dates"] = {} + + +almanac[38] = {} +almanac[38]["System"] = SAT_SYS_GLONASS +almanac[38]["Number"] = 18 +almanac[38]["Orbital"] = 3 +almanac[38]["GLONASS_Data"] = {} +almanac[38]["GLONASS_Data"]["NKU_Number"] = 783 +almanac[38]["GLONASS_Data"]["Cosmos_Number"] = 2374 +almanac[38]["Eccentricity"] = 4.520000e-003 +almanac[38]["Time_of_Applicability"] = 0.000000e+000 +almanac[38]["Orbital_Inclination"] = 1.126239e+000 +almanac[38]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[38]["SQRT_A"] = 5.050600e+003 +almanac[38]["Right_Ascen_at_Week"] = 3.894071e+000 +almanac[38]["Argument_of_Perigee"] = -2.509589e+000 +almanac[38]["Mean_Anom"] = -1.020057e+000 +almanac[38]["week"] = 1390 +almanac[38]["Commit_date"] = "05.01.2001" +almanac[38]["Life_dates"] = {} + +almanac[39] = {} +almanac[39]["System"] = SAT_SYS_GLONASS +almanac[39]["Number"] = 19 +almanac[39]["Orbital"] = 3 +almanac[39]["GLONASS_Data"] = {} +almanac[39]["GLONASS_Data"]["NKU_Number"] = 798 +almanac[39]["GLONASS_Data"]["Cosmos_Number"] = 2417 +almanac[39]["Eccentricity"] = 2.023000e-003 +almanac[39]["Time_of_Applicability"] = 0.000000e+000 +almanac[39]["Orbital_Inclination"] = 1.132205e+000 +almanac[39]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[39]["SQRT_A"] = 5.050500e+003 +almanac[39]["Right_Ascen_at_Week"] = 3.884018e+000 +almanac[39]["Argument_of_Perigee"] = 2.718313e+000 +almanac[39]["Mean_Anom"] = -3.933620e-001 +almanac[39]["week"] = 1390 +almanac[39]["Commit_date"] = "22.01.2006" +almanac[39]["Life_dates"] = {} + +almanac[40] = {} +almanac[40]["System"] = SAT_SYS_GLONASS +almanac[40]["Number"] = 20 +almanac[40]["Orbital"] = 3 +almanac[40]["GLONASS_Data"] = {} +almanac[40]["GLONASS_Data"]["NKU_Number"] = 793 +almanac[40]["GLONASS_Data"]["Cosmos_Number"] = 2396 +almanac[40]["Eccentricity"] = 1.822000e-003 +almanac[40]["Time_of_Applicability"] = 0.000000e+000 +almanac[40]["Orbital_Inclination"] = 1.129789e+000 +almanac[40]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[40]["SQRT_A"] = 5.050500e+003 +almanac[40]["Right_Ascen_at_Week"] = 3.896863e+000 +almanac[40]["Argument_of_Perigee"] = 2.723776e+000 +almanac[40]["Mean_Anom"] = -1.193647e+000 +almanac[40]["week"] = 1390 +almanac[40]["Commit_date"] = "31.01.2003" +almanac[40]["Life_dates"] = {} + +almanac[41] = {} +almanac[41]["System"] = SAT_SYS_GLONASS +almanac[41]["Number"] = 21 +almanac[41]["Orbital"] = 3 +almanac[41]["GLONASS_Data"] = {} +almanac[41]["GLONASS_Data"]["NKU_Number"] = 792 +almanac[41]["GLONASS_Data"]["Cosmos_Number"] = 2395 +almanac[41]["Eccentricity"] = 5.290000e-004 +almanac[41]["Time_of_Applicability"] = 0.000000e+000 +almanac[41]["Orbital_Inclination"] = 1.129957e+000 +almanac[41]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[41]["SQRT_A"] = 5.050500e+003 +almanac[41]["Right_Ascen_at_Week"] = 3.897806e+000 +almanac[41]["Argument_of_Perigee"] = -9.519367e-001 +almanac[41]["Mean_Anom"] = -4.578920e+000 +almanac[41]["week"] = 1390 +almanac[41]["Commit_date"] = "31.01.2003" +almanac[41]["Life_dates"] = {} + +almanac[42] = {} +almanac[42]["System"] = SAT_SYS_GLONASS +almanac[42]["Number"] = 22 +almanac[42]["Orbital"] = 3 +almanac[42]["GLONASS_Data"] = {} +almanac[42]["GLONASS_Data"]["NKU_Number"] = 791 +almanac[42]["GLONASS_Data"]["Cosmos_Number"] = 2394 +almanac[42]["Eccentricity"] = 9.200000e-005 +almanac[42]["Time_of_Applicability"] = 0.000000e+000 +almanac[42]["Orbital_Inclination"] = 1.129742e+000 +almanac[42]["Rate_of_Right_Ascen"] = -6.740456e-009 +almanac[42]["SQRT_A"] = 5.050500e+003 +almanac[42]["Right_Ascen_at_Week"] = 3.897404e+000 +almanac[42]["Argument_of_Perigee"] = 2.518211e+000 +almanac[42]["Mean_Anom"] = -2.530167e+000 +almanac[42]["week"] = 1390 +almanac[42]["Commit_date"] = "21.01.2003" +almanac[42]["Life_dates"] = {} + +almanac[43] = {} +almanac[43]["System"] = SAT_SYS_GLONASS +almanac[43]["Number"] = 23 +almanac[43]["Orbital"] = 3 +almanac[43]["GLONASS_Data"] = {} +almanac[43]["GLONASS_Data"]["NKU_Number"] = 714 +almanac[43]["GLONASS_Data"]["Cosmos_Number"] = 2419 +almanac[43]["Eccentricity"] = 8.730000e-004 +almanac[43]["Time_of_Applicability"] = 0.000000e+000 +almanac[43]["Orbital_Inclination"] = 1.132105e+000 +almanac[43]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[43]["SQRT_A"] = 5.050500e+003 +almanac[43]["Right_Ascen_at_Week"] = 3.883808e+000 +almanac[43]["Argument_of_Perigee"] = -3.039139e-001 +almanac[43]["Mean_Anom"] = -5.228304e-001 +almanac[43]["week"] = 1390 +almanac[43]["Commit_date"] = "31.08.2006" +almanac[43]["Life_dates"] = {} + +almanac[44] = {} +almanac[44]["System"] = SAT_SYS_GLONASS +almanac[44]["Number"] = 24 +almanac[44]["Orbital"] = 3 +almanac[44]["GLONASS_Data"] = {} +almanac[44]["GLONASS_Data"]["NKU_Number"] = 713 +almanac[44]["GLONASS_Data"]["Cosmos_Number"] = 2418 +almanac[44]["Eccentricity"] = 2.044000e-003 +almanac[44]["Time_of_Applicability"] = 0.000000e+000 +almanac[44]["Orbital_Inclination"] = 1.132430e+000 +almanac[44]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[44]["SQRT_A"] = 5.050500e+003 +almanac[44]["Right_Ascen_at_Week"] = 3.883983e+000 +almanac[44]["Argument_of_Perigee"] = -3.722784e-001 +almanac[44]["Mean_Anom"] = -1.240457e+000 +almanac[44]["week"] = 1390 +almanac[44]["Commit_date"] = "31.08.2006" +almanac[44]["Life_dates"] = {} + +--2 îðáèòàëüíàÿ ïëîñêîñòü, íîìåðà 9-16 +almanac[45] = {} +almanac[45]["System"] = SAT_SYS_GLONASS +almanac[45]["Number"] = 9 +almanac[45]["Orbital"] = 2 +almanac[45]["GLONASS_Data"] = {} +almanac[45]["GLONASS_Data"]["NKU_Number"] = "N/A" +almanac[45]["GLONASS_Data"]["Cosmos_Number"] = "N/A" +almanac[45]["Eccentricity"] = 1.184000e-003 +almanac[45]["Time_of_Applicability"] = 0.000000e+000 +almanac[45]["Orbital_Inclination"] = 1.126443e+000 +almanac[45]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[45]["SQRT_A"] = 5.050500e+003 +almanac[45]["Right_Ascen_at_Week"] = 1.79067e+000 +almanac[45]["Argument_of_Perigee"] = 2.88430067 +almanac[45]["Mean_Anom"] = -5.519651e+000 +almanac[45]["week"] = 1390 +almanac[45]["Commit_date"] = "N/A" +almanac[45]["Life_dates"] = {} + +almanac[46] = {} +almanac[46]["System"] = SAT_SYS_GLONASS +almanac[46]["Number"] = 10 +almanac[46]["Orbital"] = 2 +almanac[46]["GLONASS_Data"] = {} +almanac[46]["GLONASS_Data"]["NKU_Number"] = "N/A" +almanac[46]["GLONASS_Data"]["Cosmos_Number"] = "N/A" +almanac[46]["Eccentricity"] = 1.184000e-003 +almanac[46]["Time_of_Applicability"] = 0.000000e+000 +almanac[46]["Orbital_Inclination"] = 1.126443e+000 +almanac[46]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[46]["SQRT_A"] = 5.050500e+003 +almanac[46]["Right_Ascen_at_Week"] = 1.79067e+000 +almanac[46]["Argument_of_Perigee"] = 3.66930067 +almanac[46]["Mean_Anom"] = -5.519651e+000 +almanac[46]["week"] = 1390 +almanac[46]["Commit_date"] = "N/A" +almanac[46]["Life_dates"] = {} + +almanac[47] = {} +almanac[47]["System"] = SAT_SYS_GLONASS +almanac[47]["Number"] = 11 +almanac[47]["Orbital"] = 2 +almanac[47]["GLONASS_Data"] = {} +almanac[47]["GLONASS_Data"]["NKU_Number"] = "N/A" +almanac[47]["GLONASS_Data"]["Cosmos_Number"] = "N/A" +almanac[47]["Eccentricity"] = 1.184000e-003 +almanac[47]["Time_of_Applicability"] = 0.000000e+000 +almanac[47]["Orbital_Inclination"] = 1.126443e+000 +almanac[47]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[47]["SQRT_A"] = 5.050500e+003 +almanac[47]["Right_Ascen_at_Week"] = 1.79067e+000 +almanac[47]["Argument_of_Perigee"] = 4.45430067 +almanac[47]["Mean_Anom"] = -5.519651e+000 +almanac[47]["week"] = 1390 +almanac[47]["Commit_date"] = "N/A" +almanac[47]["Life_dates"] = {} + +almanac[48] = {} +almanac[48]["System"] = SAT_SYS_GLONASS +almanac[48]["Number"] = 12 +almanac[48]["Orbital"] = 2 +almanac[48]["GLONASS_Data"] = {} +almanac[48]["GLONASS_Data"]["NKU_Number"] = "N/A" +almanac[48]["GLONASS_Data"]["Cosmos_Number"] = "N/A" +almanac[48]["Eccentricity"] = 1.184000e-003 +almanac[48]["Time_of_Applicability"] = 0.000000e+000 +almanac[48]["Orbital_Inclination"] = 1.126443e+000 +almanac[48]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[48]["SQRT_A"] = 5.050500e+003 +almanac[48]["Right_Ascen_at_Week"] = 1.79067e+000 +almanac[48]["Argument_of_Perigee"] = 5.23930067 +almanac[48]["Mean_Anom"] = -5.519651e+000 +almanac[48]["week"] = 1390 +almanac[48]["Commit_date"] = "N/A" +almanac[48]["Life_dates"] = {} + +almanac[49] = {} +almanac[49]["System"] = SAT_SYS_GLONASS +almanac[49]["Number"] = 13 +almanac[49]["Orbital"] = 2 +almanac[49]["GLONASS_Data"] = {} +almanac[49]["GLONASS_Data"]["NKU_Number"] = "N/A" +almanac[49]["GLONASS_Data"]["Cosmos_Number"] = "N/A" +almanac[49]["Eccentricity"] = 1.184000e-003 +almanac[49]["Time_of_Applicability"] = 0.000000e+000 +almanac[49]["Orbital_Inclination"] = 1.126443e+000 +almanac[49]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[49]["SQRT_A"] = 5.050500e+003 +almanac[49]["Right_Ascen_at_Week"] = 1.79067e+000 +almanac[49]["Argument_of_Perigee"] = 6.02430067 +almanac[49]["Mean_Anom"] = -5.519651e+000 +almanac[49]["week"] = 1390 +almanac[49]["Commit_date"] = "N/A" +almanac[49]["Life_dates"] = {} + +almanac[50] = {} +almanac[50]["System"] = SAT_SYS_GLONASS +almanac[50]["Number"] = 14 +almanac[50]["Orbital"] = 2 +almanac[50]["GLONASS_Data"] = {} +almanac[50]["GLONASS_Data"]["NKU_Number"] = "N/A" +almanac[50]["GLONASS_Data"]["Cosmos_Number"] = "N/A" +almanac[50]["Eccentricity"] = 1.184000e-003 +almanac[50]["Time_of_Applicability"] = 0.000000e+000 +almanac[50]["Orbital_Inclination"] = 1.126443e+000 +almanac[50]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[50]["SQRT_A"] = 5.050500e+003 +almanac[50]["Right_Ascen_at_Week"] = 1.79067e+000 +almanac[50]["Argument_of_Perigee"] = 0.52930067 +almanac[50]["Mean_Anom"] = -5.519651e+000 +almanac[50]["week"] = 1390 +almanac[50]["Commit_date"] = "N/A" +almanac[50]["Life_dates"] = {} + +almanac[51] = {} +almanac[51]["System"] = SAT_SYS_GLONASS +almanac[51]["Number"] = 15 +almanac[51]["Orbital"] = 2 +almanac[51]["GLONASS_Data"] = {} +almanac[51]["GLONASS_Data"]["NKU_Number"] = "N/A" +almanac[51]["GLONASS_Data"]["Cosmos_Number"] = "N/A" +almanac[51]["Eccentricity"] = 1.184000e-003 +almanac[51]["Time_of_Applicability"] = 0.000000e+000 +almanac[51]["Orbital_Inclination"] = 1.126443e+000 +almanac[51]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[51]["SQRT_A"] = 5.050500e+003 +almanac[51]["Right_Ascen_at_Week"] = 1.79067e+000 +almanac[51]["Argument_of_Perigee"] = 1.31430067 +almanac[51]["Mean_Anom"] = -5.519651e+000 +almanac[51]["week"] = 1390 +almanac[51]["Commit_date"] = "N/A" +almanac[51]["Life_dates"] = {} + +almanac[52] = {} +almanac[52]["System"] = SAT_SYS_GLONASS +almanac[52]["Number"] = 16 +almanac[52]["Orbital"] = 2 +almanac[52]["GLONASS_Data"] = {} +almanac[52]["GLONASS_Data"]["NKU_Number"] = "N/A" +almanac[52]["GLONASS_Data"]["Cosmos_Number"] = "N/A" +almanac[52]["Eccentricity"] = 1.184000e-003 +almanac[52]["Time_of_Applicability"] = 0.000000e+000 +almanac[52]["Orbital_Inclination"] = 1.126443e+000 +almanac[52]["Rate_of_Right_Ascen"] = 0.000000e+000 +almanac[52]["SQRT_A"] = 5.050500e+003 +almanac[52]["Right_Ascen_at_Week"] = 1.79067e+000 +almanac[52]["Argument_of_Perigee"] = 2.09930067 +almanac[52]["Mean_Anom"] = -5.519651e+000 +almanac[52]["week"] = 1390 +almanac[52]["Commit_date"] = "N/A" +almanac[52]["Life_dates"] = {} + +SA_mode = false +AS_mode = false diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Scripts/World/birds.lua b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Scripts/World/birds.lua new file mode 100644 index 000000000..8aee1f700 --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/Scripts/World/birds.lua @@ -0,0 +1,27 @@ +birds_avail = true --Birds availability. false - there is no birds +birds_maximum_hrad = 200 --Maximum altitude above ground al sea level bird could be met +birds_maximum_absolute_height = 8000 --Maximum absolute altitude bird could be met +birds_minimum_velocity = 40 --Minimum velocity bird could be met +birds_delta_time = 3.55 +birds_probability = {0.006333333*150, + 0.004166667*150, + 0.001966667*150, + 0.001090909*150, + 0.000741818*150, + 0.0006*150, + 0.000510545*150, + 0.000447273*150, + 0.000389455*150, + 0.000349091*150, + 0.000310909*150, + 0.000282545*150, + 0.000250909*150, + 0.000220364*150, + 0.000196364*150, + 0.000174545*150, + 0.000152727*150, + 0.000128727*150, + 0.000103636*150, + 7.63636E-05*150, + 0*150 +} diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/VHF_RADIO/SETTINGS.lua b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/VHF_RADIO/SETTINGS.lua new file mode 100644 index 000000000..92c6a42c4 --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/VHF_RADIO/SETTINGS.lua @@ -0,0 +1,14 @@ +settings= +{ + ["dials"]= + { + ["channel"]=-1, + }, + ["presets"]= + { + [1]=124000000, + [2]=124000000, + [3]=131000000, + [4]=139000000, + }, +} diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/l10n/DEFAULT/Moose.lua b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/l10n/DEFAULT/Moose.lua new file mode 100644 index 000000000..f4f99d16b --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/l10n/DEFAULT/Moose.lua @@ -0,0 +1,45 @@ +env.info( '*** MOOSE DYNAMIC INCLUDE START *** ' ) +env.info( 'Moose Generation Timestamp: 20160616_1305' ) + +local base = _G + +Include = {} + +Include.Path = function() + local str = debug.getinfo(2, "S").source + return str:match("(.*/)"):sub(1,-2):gsub("\\","/") +end + +Include.File = function( IncludeFile ) + if not Include.Files[ IncludeFile ] then + Include.Files[IncludeFile] = IncludeFile + env.info( "Include:" .. IncludeFile .. " from " .. Include.ProgramPath ) + local f = assert( base.loadfile( Include.ProgramPath .. IncludeFile .. ".lua" ) ) + if f == nil then + env.info( "Include:" .. IncludeFile .. " from " .. Include.MissionPath ) + local f = assert( base.loadfile( Include.MissionPath .. IncludeFile .. ".lua" ) ) + if f == nil then + error ("Could not load MOOSE file " .. IncludeFile .. ".lua" ) + else + env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.MissionPath ) + return f() + end + else + env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.ProgramPath ) + return f() + end + end +end + +Include.ProgramPath = "Scripts/Moose/" +Include.MissionPath = Include.Path() + +env.info( "Include.ProgramPath = " .. Include.ProgramPath) +env.info( "Include.MissionPath = " .. Include.MissionPath) + +Include.Files = {} + +Include.File( "Moose" ) + +BASE:TraceOnOff( true ) +env.info( '*** MOOSE INCLUDE END *** ' ) diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/l10n/DEFAULT/Moose_Test_AIBALANCER.lua b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/l10n/DEFAULT/Moose_Test_AIBALANCER.lua new file mode 100644 index 000000000..ca7e91a91 --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/l10n/DEFAULT/Moose_Test_AIBALANCER.lua @@ -0,0 +1,11 @@ + +local US_PlanesClientSet = SET_CLIENT:New():FilterCountries( "USA" ):FilterCategories( "plane" ):FilterStart() +local US_PlanesSpawn = SPAWN:New( "AI US" ) +local US_AIBalancer = AIBALANCER:New( US_PlanesClientSet, US_PlanesSpawn ) + +local RU_PlanesClientSet = SET_CLIENT:New():FilterCountries( "RUSSIA" ):FilterCategories( "plane" ):FilterStart() +local RU_PlanesSpawn = SPAWN:New( "AI RU" ) +local RU_AIBalancer = AIBALANCER:New( RU_PlanesClientSet, RU_PlanesSpawn ) + +local RU_AirbasesSet = SET_AIRBASE:New():FilterCoalitions("red"):FilterStart() +RU_AIBalancer:ReturnToAirbases( 2000, RU_AirbasesSet ) \ No newline at end of file diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/l10n/DEFAULT/dictionary b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/l10n/DEFAULT/dictionary new file mode 100644 index 000000000..8e11eb5fc --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/l10n/DEFAULT/dictionary @@ -0,0 +1,57 @@ +dictionary = +{ + ["DictKey_UnitName_43"] = "Client 5", + ["DictKey_GroupName_42"] = "Client Group 5", + ["DictKey_GroupName_30"] = "AI RU", + ["DictKey_UnitName_19"] = "Client 3", + ["DictKey_GroupName_24"] = "AI RU", + ["DictKey_GroupName_7"] = "Client Group 1", + ["DictKey_WptName_23"] = "", + ["DictKey_WptName_41"] = "", + ["DictKey_WptName_38"] = "", + ["DictKey_GroupName_33"] = "AI RU", + ["DictKey_GroupName_21"] = "Client Group 4", + ["DictKey_UnitName_31"] = "AI RU", + ["DictKey_WptName_48"] = "", + ["DictKey_GroupName_39"] = "Client Group 6", + ["DictKey_WptName_12"] = "", + ["DictKey_WptName_26"] = "", + ["DictKey_sortie_4"] = "", + ["DictKey_UnitName_25"] = "AI RU", + ["DictKey_WptName_49"] = "", + ["DictKey_WptName_32"] = "", + ["DictKey_WptName_50"] = "", + ["DictKey_ActionText_17"] = "BASE:TraceClass(\"SET_CLIENT\")\ +BASE:TraceClass(\"CLIENT\")\ +BASE:TraceClass(\"AIBALANCER\")\ +BASE:TraceLevel(3)", + ["DictKey_UnitName_28"] = "AI RU", + ["DictKey_WptName_52"] = "", + ["DictKey_GroupName_36"] = "AI RU", + ["DictKey_GroupName_18"] = "Client Group 3", + ["DictKey_WptName_47"] = "", + ["DictKey_UnitName_40"] = "Client 6", + ["DictKey_UnitName_11"] = "Client 2", + ["DictKey_WptName_29"] = "", + ["DictKey_UnitName_15"] = "AI US", + ["DictKey_WptName_9"] = "", + ["DictKey_GroupName_10"] = "Client Group 2", + ["DictKey_WptName_20"] = "", + ["DictKey_UnitName_37"] = "AI RU", + ["DictKey_UnitName_34"] = "AI RU", + ["DictKey_descriptionBlueTask_3"] = "", + ["DictKey_descriptionText_1"] = "", + ["DictKey_GroupName_45"] = "Client Group 7", + ["DictKey_WptName_35"] = "", + ["DictKey_UnitName_22"] = "Client 4", + ["DictKey_GroupName_14"] = "AI US", + ["DictKey_WptName_16"] = "", + ["DictKey_WptName_44"] = "", + ["DictKey_WptName_13"] = "", + ["DictKey_UnitName_46"] = "Client 7", + ["DictKey_WptName_51"] = "", + ["DictKey_WptName_53"] = "", + ["DictKey_descriptionRedTask_2"] = "", + ["DictKey_GroupName_27"] = "AI RU", + ["DictKey_UnitName_8"] = "Client 1", +} -- end of dictionary diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/l10n/DEFAULT/mapResource b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/l10n/DEFAULT/mapResource new file mode 100644 index 000000000..2ec60591c --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/l10n/DEFAULT/mapResource @@ -0,0 +1,5 @@ +mapResource = +{ + ["ResKey_Action_5"] = "Moose.lua", + ["ResKey_Action_6"] = "Moose_Test_AIBALANCER.lua", +} -- end of mapResource diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/mission b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/mission new file mode 100644 index 000000000..afdf1e489 --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/mission @@ -0,0 +1,1625 @@ +mission = +{ + ["trig"] = + { + ["actions"] = + { + [1] = "a_do_script_file(getValueResourceByKey(\"ResKey_Action_5\"));", + [2] = "a_do_script(getValueDictByKey(\"DictKey_ActionText_17\"));", + [3] = "a_do_script_file(getValueResourceByKey(\"ResKey_Action_6\"));", + }, -- end of ["actions"] + ["events"] = + { + }, -- end of ["events"] + ["custom"] = + { + }, -- end of ["custom"] + ["func"] = + { + }, -- end of ["func"] + ["flag"] = + { + [1] = true, + [2] = true, + [3] = true, + }, -- end of ["flag"] + ["conditions"] = + { + [1] = "return(true)", + [2] = "return(true)", + [3] = "return(true)", + }, -- end of ["conditions"] + ["customStartup"] = + { + }, -- end of ["customStartup"] + ["funcStartup"] = + { + [1] = "if mission.trig.conditions[1]() then mission.trig.actions[1]() end", + [2] = "if mission.trig.conditions[2]() then mission.trig.actions[2]() end", + [3] = "if mission.trig.conditions[3]() then mission.trig.actions[3]() end", + }, -- end of ["funcStartup"] + }, -- end of ["trig"] + ["result"] = + { + ["offline"] = + { + ["conditions"] = + { + }, -- end of ["conditions"] + ["actions"] = + { + }, -- end of ["actions"] + ["func"] = + { + }, -- end of ["func"] + }, -- end of ["offline"] + ["total"] = 0, + ["blue"] = + { + ["conditions"] = + { + }, -- end of ["conditions"] + ["actions"] = + { + }, -- end of ["actions"] + ["func"] = + { + }, -- end of ["func"] + }, -- end of ["blue"] + ["red"] = + { + ["conditions"] = + { + }, -- end of ["conditions"] + ["actions"] = + { + }, -- end of ["actions"] + ["func"] = + { + }, -- end of ["func"] + }, -- end of ["red"] + }, -- end of ["result"] + ["maxDictId"] = 53, + ["groundControl"] = + { + ["isPilotControlVehicles"] = false, + ["roles"] = + { + ["artillery_commander"] = + { + ["blue"] = 0, + ["red"] = 0, + }, -- end of ["artillery_commander"] + ["instructor"] = + { + ["blue"] = 0, + ["red"] = 0, + }, -- end of ["instructor"] + ["observer"] = + { + ["blue"] = 0, + ["red"] = 0, + }, -- end of ["observer"] + ["forward_observer"] = + { + ["blue"] = 0, + ["red"] = 0, + }, -- end of ["forward_observer"] + }, -- end of ["roles"] + }, -- end of ["groundControl"] + ["usedModules"] = + { + ["F-5E/E-3 by Belsimtek"] = true, + ["M-2000C by RAZBAM Sims"] = true, + ["SA342 AI by Polychop-Simulations"] = true, + ["Hawk T.1A by VEAO Simulations"] = true, + ["MiG-15bis AI by Eagle Dynamics"] = true, + ["C-101 Aviojet by AvioDev"] = true, + ["F-86F Sabre by Belsimtek"] = true, + ["F-15C"] = false, + ["M-2000C AI by RAZBAM Sims"] = true, + ["SA342 Gazelle by Polychop-Simulations"] = true, + ["Ka-50 Black Shark by Eagle Dynamics"] = true, + ["World War II AI Units by Eagle Dynamics"] = true, + ["MiG-21Bis by Leatherneck Simulations"] = false, + ["F-86F Sabre AI by Eagle Dynamics"] = true, + ["TF-51D Mustang by Eagle Dynamics"] = true, + ["Su-25T by Eagle Dynamics"] = true, + ["Mi-8MTV2 Hip by Belsimtek"] = true, + ["FW-190D9 Dora by Eagle Dynamics"] = true, + ["Su-27 Flanker by Eagle Dynamics"] = false, + ["L-39C"] = true, + ["UH-1H Huey by Belsimtek"] = true, + ["C-101 Aviojet"] = true, + ["./CoreMods/aircraft/MQ-9 Reaper"] = true, + ["Combined Arms by Eagle Dynamics"] = true, + ["Su-25A by Eagle Dynamics"] = false, + ["MiG-21Bis AI by Leatherneck Simulations"] = true, + ["L-39C/ZA by Eagle Dynamics"] = true, + ["Bf 109 K-4 by Eagle Dynamics"] = true, + ["Caucasus"] = true, + ["A-10A by Eagle Dynamics"] = false, + ["Hawk T.1A AI by VEAO Simulations"] = true, + ["P-51D Mustang by Eagle Dynamics"] = true, + ["MiG-15bis by Belsimtek"] = true, + ["A-10C Warthog by Eagle Dynamics"] = true, + ["Flaming Cliffs by Eagle Dynamics"] = true, + }, -- end of ["usedModules"] + ["triggers"] = + { + ["zones"] = + { + }, -- end of ["zones"] + }, -- end of ["triggers"] + ["weather"] = + { + ["atmosphere_type"] = 0, + ["wind"] = + { + ["at8000"] = + { + ["speed"] = 0, + ["dir"] = 0, + }, -- end of ["at8000"] + ["atGround"] = + { + ["speed"] = 0, + ["dir"] = 0, + }, -- end of ["atGround"] + ["at2000"] = + { + ["speed"] = 0, + ["dir"] = 0, + }, -- end of ["at2000"] + }, -- end of ["wind"] + ["enable_fog"] = false, + ["turbulence"] = + { + ["at8000"] = 0, + ["atGround"] = 0, + ["at2000"] = 0, + }, -- end of ["turbulence"] + ["season"] = + { + ["iseason"] = 1, + ["temperature"] = 20, + }, -- end of ["season"] + ["type_weather"] = 0, + ["qnh"] = 760, + ["cyclones"] = + { + }, -- end of ["cyclones"] + ["name"] = "Winter, clean sky", + ["fog"] = + { + ["thickness"] = 0, + ["visibility"] = 25, + ["density"] = 7, + }, -- end of ["fog"] + ["visibility"] = + { + ["distance"] = 80000, + }, -- end of ["visibility"] + ["clouds"] = + { + ["thickness"] = 200, + ["density"] = 0, + ["base"] = 300, + ["iprecptns"] = 0, + }, -- end of ["clouds"] + }, -- end of ["weather"] + ["theatre"] = "Caucasus", + ["needModules"] = + { + ["TF-51D Mustang by Eagle Dynamics"] = "TF-51D Mustang by Eagle Dynamics", + }, -- end of ["needModules"] + ["map"] = + { + ["centerY"] = 332658.57142857, + ["zoom"] = 500000, + ["centerX"] = -9701.4285714281, + }, -- end of ["map"] + ["coalitions"] = + { + ["blue"] = + { + [1] = 11, + [2] = 4, + [3] = 6, + [4] = 16, + [5] = 13, + [6] = 15, + [7] = 9, + [8] = 8, + [9] = 12, + [10] = 2, + [11] = 3, + [12] = 5, + [13] = 10, + [14] = 20, + [15] = 21, + [16] = 40, + [17] = 26, + [18] = 45, + [19] = 28, + }, -- end of ["blue"] + ["neutrals"] = + { + [1] = 7, + [2] = 17, + [3] = 22, + [4] = 23, + [5] = 25, + [6] = 29, + [7] = 30, + [8] = 31, + [9] = 32, + [10] = 33, + [11] = 35, + [12] = 36, + [13] = 39, + [14] = 41, + [15] = 42, + [16] = 44, + [17] = 46, + }, -- end of ["neutrals"] + ["red"] = + { + [1] = 0, + [2] = 1, + [3] = 18, + [4] = 19, + [5] = 37, + [6] = 24, + [7] = 27, + [8] = 43, + [9] = 47, + [10] = 34, + [11] = 38, + }, -- end of ["red"] + }, -- end of ["coalitions"] + ["descriptionText"] = "DictKey_descriptionText_1", + ["pictureFileNameR"] = + { + }, -- end of ["pictureFileNameR"] + ["descriptionBlueTask"] = "DictKey_descriptionBlueTask_3", + ["descriptionRedTask"] = "DictKey_descriptionRedTask_2", + ["pictureFileNameB"] = + { + }, -- end of ["pictureFileNameB"] + ["trigrules"] = + { + [1] = + { + ["rules"] = + { + }, -- end of ["rules"] + ["eventlist"] = "", + ["predicate"] = "triggerStart", + ["actions"] = + { + [1] = + { + ["file"] = "ResKey_Action_5", + ["predicate"] = "a_do_script_file", + ["ai_task"] = + { + [1] = "", + [2] = "", + }, -- end of ["ai_task"] + }, -- end of [1] + }, -- end of ["actions"] + ["comment"] = "Load Moose", + }, -- end of [1] + [2] = + { + ["rules"] = + { + }, -- end of ["rules"] + ["eventlist"] = "", + ["predicate"] = "triggerStart", + ["actions"] = + { + [1] = + { + ["KeyDict_text"] = "DictKey_ActionText_17", + ["text"] = "DictKey_ActionText_17", + ["predicate"] = "a_do_script", + ["ai_task"] = + { + [1] = "", + [2] = "", + }, -- end of ["ai_task"] + }, -- end of [1] + }, -- end of ["actions"] + ["comment"] = "Trace", + }, -- end of [2] + [3] = + { + ["rules"] = + { + }, -- end of ["rules"] + ["eventlist"] = "", + ["predicate"] = "triggerStart", + ["actions"] = + { + [1] = + { + ["file"] = "ResKey_Action_6", + ["predicate"] = "a_do_script_file", + ["ai_task"] = + { + [1] = "", + [2] = "", + }, -- end of ["ai_task"] + }, -- end of [1] + }, -- end of ["actions"] + ["comment"] = "Load Mission", + }, -- end of [3] + }, -- end of ["trigrules"] + ["coalition"] = + { + ["blue"] = + { + ["bullseye"] = + { + ["y"] = 617414, + ["x"] = -291014, + }, -- end of ["bullseye"] + ["nav_points"] = + { + }, -- end of ["nav_points"] + ["name"] = "blue", + ["country"] = + { + [1] = + { + ["id"] = 11, + ["name"] = "Belgium", + }, -- end of [1] + [2] = + { + ["id"] = 4, + ["name"] = "UK", + }, -- end of [2] + [3] = + { + ["id"] = 6, + ["name"] = "Germany", + }, -- end of [3] + [4] = + { + ["id"] = 16, + ["name"] = "Georgia", + }, -- end of [4] + [5] = + { + ["id"] = 13, + ["name"] = "Denmark", + }, -- end of [5] + [6] = + { + ["id"] = 15, + ["name"] = "Israel", + }, -- end of [6] + [7] = + { + ["id"] = 9, + ["name"] = "Spain", + }, -- end of [7] + [8] = + { + ["id"] = 8, + ["name"] = "Canada", + }, -- end of [8] + [9] = + { + ["id"] = 12, + ["name"] = "Norway", + }, -- end of [9] + [10] = + { + ["id"] = 2, + ["name"] = "USA", + ["plane"] = + { + ["group"] = + { + [1] = + { + ["modulation"] = 0, + ["tasks"] = + { + }, -- end of ["tasks"] + ["radioSet"] = false, + ["task"] = "Reconnaissance", + ["uncontrolled"] = false, + ["route"] = + { + ["points"] = + { + [1] = + { + ["alt"] = 88, + ["type"] = "TakeOffParking", + ["action"] = "From Parking Area", + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["properties"] = + { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + }, -- end of ["properties"] + ["ETA"] = 0, + ["airdromeId"] = 13, + ["y"] = 369029.71875, + ["x"] = 11250.362304688, + ["name"] = "DictKey_WptName_9", + ["speed"] = 138.88888888889, + ["ETA_locked"] = true, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [1] + }, -- end of ["points"] + }, -- end of ["route"] + ["groupId"] = 1, + ["hidden"] = false, + ["units"] = + { + [1] = + { + ["alt"] = 88, + ["alt_type"] = "BARO", + ["livery_id"] = "Bare Metal", + ["skill"] = "Client", + ["parking"] = "3", + ["speed"] = 138.88888888889, + ["type"] = "TF-51D", + ["Radio"] = + { + [1] = + { + ["channels"] = + { + [1] = 124, + [2] = 124, + [4] = 139, + [3] = 131, + }, -- end of ["channels"] + }, -- end of [1] + }, -- end of ["Radio"] + ["unitId"] = 1, + ["psi"] = 0, + ["y"] = 369029.71875, + ["x"] = 11250.362304688, + ["name"] = "DictKey_UnitName_8", + ["payload"] = + { + ["pylons"] = + { + }, -- end of ["pylons"] + ["fuel"] = 340.68, + ["flare"] = 0, + ["chaff"] = 0, + ["gun"] = 100, + }, -- end of ["payload"] + ["heading"] = 0, + ["callsign"] = + { + [1] = 1, + [2] = 1, + [3] = 1, + ["name"] = "Enfield11", + }, -- end of ["callsign"] + ["onboard_num"] = "010", + }, -- end of [1] + }, -- end of ["units"] + ["y"] = 369029.71875, + ["x"] = 11250.362304688, + ["name"] = "DictKey_GroupName_7", + ["communication"] = true, + ["start_time"] = 0, + ["frequency"] = 124, + }, -- end of [1] + [2] = + { + ["modulation"] = 0, + ["tasks"] = + { + }, -- end of ["tasks"] + ["radioSet"] = false, + ["task"] = "Reconnaissance", + ["uncontrolled"] = false, + ["route"] = + { + ["points"] = + { + [1] = + { + ["alt"] = 88, + ["type"] = "TakeOffParking", + ["action"] = "From Parking Area", + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["properties"] = + { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + }, -- end of ["properties"] + ["ETA"] = 0, + ["airdromeId"] = 13, + ["y"] = 369103.96875, + ["x"] = 11209.124023438, + ["name"] = "DictKey_WptName_12", + ["speed"] = 138.88888888889, + ["ETA_locked"] = true, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [1] + }, -- end of ["points"] + }, -- end of ["route"] + ["groupId"] = 2, + ["hidden"] = false, + ["units"] = + { + [1] = + { + ["alt"] = 88, + ["alt_type"] = "BARO", + ["livery_id"] = "Bare Metal", + ["skill"] = "Client", + ["parking"] = "4", + ["speed"] = 138.88888888889, + ["type"] = "TF-51D", + ["Radio"] = + { + [1] = + { + ["channels"] = + { + [1] = 124, + [2] = 124, + [4] = 139, + [3] = 131, + }, -- end of ["channels"] + }, -- end of [1] + }, -- end of ["Radio"] + ["unitId"] = 2, + ["psi"] = 0, + ["y"] = 369103.96875, + ["x"] = 11209.124023438, + ["name"] = "DictKey_UnitName_11", + ["payload"] = + { + ["pylons"] = + { + }, -- end of ["pylons"] + ["fuel"] = 340.68, + ["flare"] = 0, + ["chaff"] = 0, + ["gun"] = 100, + }, -- end of ["payload"] + ["heading"] = 0, + ["callsign"] = + { + [1] = 2, + [2] = 1, + [3] = 1, + ["name"] = "Springfield11", + }, -- end of ["callsign"] + ["onboard_num"] = "011", + }, -- end of [1] + }, -- end of ["units"] + ["y"] = 369103.96875, + ["x"] = 11209.124023438, + ["name"] = "DictKey_GroupName_10", + ["communication"] = true, + ["start_time"] = 0, + ["frequency"] = 124, + }, -- end of [2] + [3] = + { + ["lateActivation"] = true, + ["tasks"] = + { + }, -- end of ["tasks"] + ["radioSet"] = false, + ["task"] = "Reconnaissance", + ["uncontrolled"] = false, + ["route"] = + { + ["routeRelativeTOT"] = true, + ["points"] = + { + [1] = + { + ["alt"] = 88, + ["type"] = "TakeOffParkingHot", + ["action"] = "From Parking Area Hot", + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["properties"] = + { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + }, -- end of ["properties"] + ["ETA"] = 0, + ["airdromeId"] = 13, + ["y"] = 369131.84375, + ["x"] = 11297.9140625, + ["name"] = "DictKey_WptName_16", + ["speed"] = 138.88888888889, + ["ETA_locked"] = true, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [1] + }, -- end of ["points"] + }, -- end of ["route"] + ["groupId"] = 3, + ["hidden"] = false, + ["units"] = + { + [1] = + { + ["alt"] = 88, + ["alt_type"] = "BARO", + ["livery_id"] = "Bare Metal", + ["skill"] = "High", + ["parking"] = "5", + ["speed"] = 138.88888888889, + ["type"] = "TF-51D", + ["unitId"] = 3, + ["psi"] = 0, + ["y"] = 369131.84375, + ["x"] = 11297.9140625, + ["name"] = "DictKey_UnitName_15", + ["payload"] = + { + ["pylons"] = + { + }, -- end of ["pylons"] + ["fuel"] = 340.68, + ["flare"] = 0, + ["chaff"] = 0, + ["gun"] = 100, + }, -- end of ["payload"] + ["heading"] = 0, + ["callsign"] = + { + [1] = 3, + [2] = 1, + [3] = 1, + ["name"] = "Uzi11", + }, -- end of ["callsign"] + ["onboard_num"] = "012", + }, -- end of [1] + }, -- end of ["units"] + ["y"] = 369131.84375, + ["x"] = 11297.9140625, + ["name"] = "DictKey_GroupName_14", + ["communication"] = true, + ["start_time"] = 0, + ["modulation"] = 0, + ["frequency"] = 124, + }, -- end of [3] + }, -- end of ["group"] + }, -- end of ["plane"] + }, -- end of [10] + [11] = + { + ["id"] = 3, + ["name"] = "Turkey", + }, -- end of [11] + [12] = + { + ["id"] = 5, + ["name"] = "France", + }, -- end of [12] + [13] = + { + ["id"] = 10, + ["name"] = "The Netherlands", + }, -- end of [13] + [14] = + { + ["id"] = 20, + ["name"] = "Italy", + }, -- end of [14] + [15] = + { + ["id"] = 21, + ["name"] = "Australia", + }, -- end of [15] + [16] = + { + ["id"] = 40, + ["name"] = "Poland", + }, -- end of [16] + [17] = + { + ["id"] = 26, + ["name"] = "Czech Republic", + }, -- end of [17] + [18] = + { + ["id"] = 45, + ["name"] = "South Korea", + }, -- end of [18] + [19] = + { + ["id"] = 28, + ["name"] = "Croatia", + }, -- end of [19] + }, -- end of ["country"] + }, -- end of ["blue"] + ["red"] = + { + ["bullseye"] = + { + ["y"] = 371700, + ["x"] = 11557, + }, -- end of ["bullseye"] + ["nav_points"] = + { + }, -- end of ["nav_points"] + ["name"] = "red", + ["country"] = + { + [1] = + { + ["id"] = 0, + ["name"] = "Russia", + ["plane"] = + { + ["group"] = + { + [1] = + { + ["modulation"] = 0, + ["tasks"] = + { + }, -- end of ["tasks"] + ["radioSet"] = false, + ["task"] = "CAS", + ["uncontrolled"] = false, + ["route"] = + { + ["points"] = + { + [1] = + { + ["alt"] = 88, + ["type"] = "TakeOffParking", + ["action"] = "From Parking Area", + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["properties"] = + { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + }, -- end of ["properties"] + ["ETA"] = 0, + ["airdromeId"] = 15, + ["y"] = 293785.125, + ["x"] = -7523.8505859375, + ["name"] = "DictKey_WptName_20", + ["speed"] = 138.88888888889, + ["ETA_locked"] = true, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + [1] = + { + ["number"] = 1, + ["key"] = "CAS", + ["id"] = "EngageTargets", + ["enabled"] = true, + ["auto"] = true, + ["params"] = + { + ["targetTypes"] = + { + [1] = "Helicopters", + [2] = "Ground Units", + [3] = "Light armed ships", + }, -- end of ["targetTypes"] + ["priority"] = 0, + }, -- end of ["params"] + }, -- end of [1] + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [1] + }, -- end of ["points"] + }, -- end of ["route"] + ["groupId"] = 4, + ["hidden"] = false, + ["units"] = + { + [1] = + { + ["alt"] = 88, + ["alt_type"] = "BARO", + ["livery_id"] = "af standard 1", + ["skill"] = "Client", + ["parking"] = "2", + ["speed"] = 138.88888888889, + ["type"] = "Su-25T", + ["unitId"] = 4, + ["psi"] = 0, + ["y"] = 293785.125, + ["x"] = -7523.8505859375, + ["name"] = "DictKey_UnitName_19", + ["payload"] = + { + ["pylons"] = + { + }, -- end of ["pylons"] + ["fuel"] = "3790", + ["flare"] = 128, + ["chaff"] = 128, + ["gun"] = 100, + }, -- end of ["payload"] + ["heading"] = 0, + ["callsign"] = 101, + ["onboard_num"] = "013", + }, -- end of [1] + }, -- end of ["units"] + ["y"] = 293785.125, + ["x"] = -7523.8505859375, + ["name"] = "DictKey_GroupName_18", + ["communication"] = true, + ["start_time"] = 0, + ["frequency"] = 124, + }, -- end of [1] + [2] = + { + ["modulation"] = 0, + ["tasks"] = + { + }, -- end of ["tasks"] + ["radioSet"] = false, + ["task"] = "CAS", + ["uncontrolled"] = false, + ["route"] = + { + ["points"] = + { + [1] = + { + ["alt"] = 88, + ["type"] = "TakeOffParking", + ["action"] = "From Parking Area", + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["properties"] = + { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + }, -- end of ["properties"] + ["ETA"] = 0, + ["airdromeId"] = 15, + ["y"] = 294994.1875, + ["x"] = -6702.66796875, + ["name"] = "DictKey_WptName_23", + ["speed"] = 138.88888888889, + ["ETA_locked"] = true, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + [1] = + { + ["number"] = 1, + ["key"] = "CAS", + ["id"] = "EngageTargets", + ["enabled"] = true, + ["auto"] = true, + ["params"] = + { + ["targetTypes"] = + { + [1] = "Helicopters", + [2] = "Ground Units", + [3] = "Light armed ships", + }, -- end of ["targetTypes"] + ["priority"] = 0, + }, -- end of ["params"] + }, -- end of [1] + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [1] + }, -- end of ["points"] + }, -- end of ["route"] + ["groupId"] = 5, + ["hidden"] = false, + ["units"] = + { + [1] = + { + ["alt"] = 88, + ["alt_type"] = "BARO", + ["livery_id"] = "af standard 1", + ["skill"] = "Client", + ["parking"] = "75", + ["speed"] = 138.88888888889, + ["type"] = "Su-25T", + ["unitId"] = 5, + ["psi"] = 0, + ["y"] = 294994.1875, + ["x"] = -6702.66796875, + ["name"] = "DictKey_UnitName_22", + ["payload"] = + { + ["pylons"] = + { + }, -- end of ["pylons"] + ["fuel"] = "3790", + ["flare"] = 128, + ["chaff"] = 128, + ["gun"] = 100, + }, -- end of ["payload"] + ["heading"] = 0, + ["callsign"] = 101, + ["onboard_num"] = "013", + }, -- end of [1] + }, -- end of ["units"] + ["y"] = 294994.1875, + ["x"] = -6702.66796875, + ["name"] = "DictKey_GroupName_21", + ["communication"] = true, + ["start_time"] = 0, + ["frequency"] = 124, + }, -- end of [2] + [3] = + { + ["lateActivation"] = true, + ["tasks"] = + { + }, -- end of ["tasks"] + ["radioSet"] = false, + ["task"] = "CAS", + ["uncontrolled"] = false, + ["route"] = + { + ["routeRelativeTOT"] = true, + ["points"] = + { + [1] = + { + ["alt"] = 88, + ["type"] = "TakeOffParking", + ["action"] = "From Parking Area", + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["properties"] = + { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + }, -- end of ["properties"] + ["ETA"] = 0, + ["airdromeId"] = 15, + ["y"] = 294155.125, + ["x"] = -7498.103515625, + ["name"] = "DictKey_WptName_26", + ["speed"] = 138.88888888889, + ["ETA_locked"] = true, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + [1] = + { + ["number"] = 1, + ["key"] = "CAS", + ["id"] = "EngageTargets", + ["enabled"] = true, + ["auto"] = true, + ["params"] = + { + ["targetTypes"] = + { + [1] = "Helicopters", + [2] = "Ground Units", + [3] = "Light armed ships", + }, -- end of ["targetTypes"] + ["priority"] = 0, + }, -- end of ["params"] + }, -- end of [1] + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [1] + [2] = + { + ["alt"] = 313, + ["type"] = "Turning Point", + ["action"] = "Turning Point", + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["properties"] = + { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + }, -- end of ["properties"] + ["ETA"] = 274.67610245895, + ["y"] = 279801.42857143, + ["x"] = -42844.285714285, + ["name"] = "DictKey_WptName_48", + ["speed"] = 138.88888888889, + ["ETA_locked"] = false, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [2] + [3] = + { + ["alt"] = 144, + ["type"] = "Turning Point", + ["action"] = "Turning Point", + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["properties"] = + { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + }, -- end of ["properties"] + ["ETA"] = 653.69455551249, + ["y"] = 229515.71428572, + ["x"] = -27272.857142857, + ["name"] = "DictKey_WptName_49", + ["speed"] = 138.88888888889, + ["ETA_locked"] = false, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [3] + [4] = + { + ["alt"] = 45, + ["type"] = "Land", + ["action"] = "Landing", + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["properties"] = + { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + }, -- end of ["properties"] + ["ETA"] = 527.81058817743, + ["airdromeId"] = 12, + ["y"] = 243127.2973737, + ["x"] = -5406.2803440839, + ["name"] = "DictKey_WptName_53", + ["speed"] = 138.88888888889, + ["ETA_locked"] = false, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [4] + }, -- end of ["points"] + }, -- end of ["route"] + ["groupId"] = 6, + ["hidden"] = false, + ["units"] = + { + [1] = + { + ["alt"] = 88, + ["alt_type"] = "BARO", + ["livery_id"] = "af standard 1", + ["skill"] = "High", + ["parking"] = "91", + ["speed"] = 138.88888888889, + ["type"] = "Su-25T", + ["unitId"] = 6, + ["psi"] = 2.755848169059, + ["y"] = 294155.125, + ["x"] = -7498.103515625, + ["name"] = "DictKey_UnitName_25", + ["payload"] = + { + ["pylons"] = + { + }, -- end of ["pylons"] + ["fuel"] = "3790", + ["flare"] = 128, + ["chaff"] = 128, + ["gun"] = 100, + }, -- end of ["payload"] + ["heading"] = -2.755848169059, + ["callsign"] = 101, + ["onboard_num"] = "013", + }, -- end of [1] + }, -- end of ["units"] + ["y"] = 294155.125, + ["x"] = -7498.103515625, + ["name"] = "DictKey_GroupName_24", + ["communication"] = true, + ["start_time"] = 0, + ["modulation"] = 0, + ["frequency"] = 124, + }, -- end of [3] + [4] = + { + ["modulation"] = 0, + ["tasks"] = + { + }, -- end of ["tasks"] + ["radioSet"] = false, + ["task"] = "CAS", + ["uncontrolled"] = false, + ["route"] = + { + ["points"] = + { + [1] = + { + ["alt"] = 88, + ["type"] = "TakeOffParking", + ["action"] = "From Parking Area", + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["properties"] = + { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + }, -- end of ["properties"] + ["ETA"] = 0, + ["airdromeId"] = 15, + ["y"] = 295139.9375, + ["x"] = -6351.4077148438, + ["name"] = "DictKey_WptName_41", + ["speed"] = 138.88888888889, + ["ETA_locked"] = true, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + [1] = + { + ["number"] = 1, + ["key"] = "CAS", + ["id"] = "EngageTargets", + ["enabled"] = true, + ["auto"] = true, + ["params"] = + { + ["targetTypes"] = + { + [1] = "Helicopters", + [2] = "Ground Units", + [3] = "Light armed ships", + }, -- end of ["targetTypes"] + ["priority"] = 0, + }, -- end of ["params"] + }, -- end of [1] + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [1] + }, -- end of ["points"] + }, -- end of ["route"] + ["groupId"] = 11, + ["hidden"] = false, + ["units"] = + { + [1] = + { + ["alt"] = 88, + ["alt_type"] = "BARO", + ["livery_id"] = "af standard 1", + ["skill"] = "Client", + ["parking"] = "107", + ["speed"] = 138.88888888889, + ["type"] = "Su-25T", + ["unitId"] = 11, + ["psi"] = 0, + ["y"] = 295139.9375, + ["x"] = -6351.4077148438, + ["name"] = "DictKey_UnitName_40", + ["payload"] = + { + ["pylons"] = + { + }, -- end of ["pylons"] + ["fuel"] = "3790", + ["flare"] = 128, + ["chaff"] = 128, + ["gun"] = 100, + }, -- end of ["payload"] + ["heading"] = 0, + ["callsign"] = 101, + ["onboard_num"] = "013", + }, -- end of [1] + }, -- end of ["units"] + ["y"] = 295139.9375, + ["x"] = -6351.4077148438, + ["name"] = "DictKey_GroupName_39", + ["communication"] = true, + ["start_time"] = 0, + ["frequency"] = 124, + }, -- end of [4] + [5] = + { + ["modulation"] = 0, + ["tasks"] = + { + }, -- end of ["tasks"] + ["radioSet"] = false, + ["task"] = "CAS", + ["uncontrolled"] = false, + ["route"] = + { + ["points"] = + { + [1] = + { + ["alt"] = 88, + ["type"] = "TakeOffParking", + ["action"] = "From Parking Area", + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["properties"] = + { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + }, -- end of ["properties"] + ["ETA"] = 0, + ["airdromeId"] = 15, + ["y"] = 295287.09375, + ["x"] = -6172.1333007813, + ["name"] = "DictKey_WptName_44", + ["speed"] = 138.88888888889, + ["ETA_locked"] = true, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + [1] = + { + ["number"] = 1, + ["key"] = "CAS", + ["id"] = "EngageTargets", + ["enabled"] = true, + ["auto"] = true, + ["params"] = + { + ["targetTypes"] = + { + [1] = "Helicopters", + [2] = "Ground Units", + [3] = "Light armed ships", + }, -- end of ["targetTypes"] + ["priority"] = 0, + }, -- end of ["params"] + }, -- end of [1] + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [1] + }, -- end of ["points"] + }, -- end of ["route"] + ["groupId"] = 12, + ["hidden"] = false, + ["units"] = + { + [1] = + { + ["alt"] = 88, + ["alt_type"] = "BARO", + ["livery_id"] = "af standard 1", + ["skill"] = "Client", + ["parking"] = "62", + ["speed"] = 138.88888888889, + ["type"] = "Su-25T", + ["unitId"] = 12, + ["psi"] = 0, + ["y"] = 295287.09375, + ["x"] = -6172.1333007813, + ["name"] = "DictKey_UnitName_43", + ["payload"] = + { + ["pylons"] = + { + }, -- end of ["pylons"] + ["fuel"] = "3790", + ["flare"] = 128, + ["chaff"] = 128, + ["gun"] = 100, + }, -- end of ["payload"] + ["heading"] = 0, + ["callsign"] = 101, + ["onboard_num"] = "013", + }, -- end of [1] + }, -- end of ["units"] + ["y"] = 295287.09375, + ["x"] = -6172.1333007813, + ["name"] = "DictKey_GroupName_42", + ["communication"] = true, + ["start_time"] = 0, + ["frequency"] = 124, + }, -- end of [5] + [6] = + { + ["modulation"] = 0, + ["tasks"] = + { + }, -- end of ["tasks"] + ["radioSet"] = false, + ["task"] = "CAS", + ["uncontrolled"] = false, + ["route"] = + { + ["points"] = + { + [1] = + { + ["alt"] = 88, + ["type"] = "TakeOffParking", + ["action"] = "From Parking Area", + ["alt_type"] = "BARO", + ["formation_template"] = "", + ["properties"] = + { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + }, -- end of ["properties"] + ["ETA"] = 0, + ["airdromeId"] = 15, + ["y"] = 295051.375, + ["x"] = -6629.2661132813, + ["name"] = "DictKey_WptName_47", + ["speed"] = 138.88888888889, + ["ETA_locked"] = true, + ["task"] = + { + ["id"] = "ComboTask", + ["params"] = + { + ["tasks"] = + { + [1] = + { + ["number"] = 1, + ["key"] = "CAS", + ["id"] = "EngageTargets", + ["enabled"] = true, + ["auto"] = true, + ["params"] = + { + ["targetTypes"] = + { + [1] = "Helicopters", + [2] = "Ground Units", + [3] = "Light armed ships", + }, -- end of ["targetTypes"] + ["priority"] = 0, + }, -- end of ["params"] + }, -- end of [1] + }, -- end of ["tasks"] + }, -- end of ["params"] + }, -- end of ["task"] + ["speed_locked"] = true, + }, -- end of [1] + }, -- end of ["points"] + }, -- end of ["route"] + ["groupId"] = 13, + ["hidden"] = false, + ["units"] = + { + [1] = + { + ["alt"] = 88, + ["alt_type"] = "BARO", + ["livery_id"] = "af standard 1", + ["skill"] = "Client", + ["parking"] = "76", + ["speed"] = 138.88888888889, + ["type"] = "Su-25T", + ["unitId"] = 13, + ["psi"] = 0, + ["y"] = 295051.375, + ["x"] = -6629.2661132813, + ["name"] = "DictKey_UnitName_46", + ["payload"] = + { + ["pylons"] = + { + }, -- end of ["pylons"] + ["fuel"] = "3790", + ["flare"] = 128, + ["chaff"] = 128, + ["gun"] = 100, + }, -- end of ["payload"] + ["heading"] = 0, + ["callsign"] = 101, + ["onboard_num"] = "013", + }, -- end of [1] + }, -- end of ["units"] + ["y"] = 295051.375, + ["x"] = -6629.2661132813, + ["name"] = "DictKey_GroupName_45", + ["communication"] = true, + ["start_time"] = 0, + ["frequency"] = 124, + }, -- end of [6] + }, -- end of ["group"] + }, -- end of ["plane"] + }, -- end of [1] + [2] = + { + ["id"] = 1, + ["name"] = "Ukraine", + }, -- end of [2] + [3] = + { + ["id"] = 18, + ["name"] = "Abkhazia", + }, -- end of [3] + [4] = + { + ["id"] = 19, + ["name"] = "South Ossetia", + }, -- end of [4] + [5] = + { + ["id"] = 37, + ["name"] = "Kazakhstan", + }, -- end of [5] + [6] = + { + ["id"] = 24, + ["name"] = "Belarus", + }, -- end of [6] + [7] = + { + ["id"] = 27, + ["name"] = "China", + }, -- end of [7] + [8] = + { + ["id"] = 43, + ["name"] = "Serbia", + }, -- end of [8] + [9] = + { + ["id"] = 47, + ["name"] = "Syria", + }, -- end of [9] + [10] = + { + ["id"] = 34, + ["name"] = "Iran", + }, -- end of [10] + [11] = + { + ["id"] = 38, + ["name"] = "North Korea", + }, -- end of [11] + }, -- end of ["country"] + }, -- end of ["red"] + }, -- end of ["coalition"] + ["sortie"] = "DictKey_sortie_4", + ["version"] = 11, + ["goals"] = + { + }, -- end of ["goals"] + ["currentKey"] = 510, + ["start_time"] = 43200, + ["forcedOptions"] = + { + }, -- end of ["forcedOptions"] + ["failures"] = + { + }, -- end of ["failures"] +} -- end of mission diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/options b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/options new file mode 100644 index 000000000..e68f02ebd --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/options @@ -0,0 +1,212 @@ +options = +{ + ["difficulty"] = + { + ["fuel"] = false, + ["labels"] = false, + ["easyRadar"] = false, + ["easyCommunication"] = true, + ["miniHUD"] = false, + ["setGlobal"] = true, + ["birds"] = 0, + ["optionsView"] = "optview_all", + ["permitCrash"] = true, + ["immortal"] = false, + ["avionicsLanguage"] = "native", + ["cockpitVisualRM"] = true, + ["padlock"] = true, + ["reports"] = true, + ["hideStick"] = false, + ["radio"] = true, + ["map"] = true, + ["externalViews"] = true, + ["spectatorExternalViews"] = true, + ["cockpitLanguage"] = "english", + ["tips"] = true, + ["userSnapView"] = true, + ["units"] = "metric", + ["impostors"] = "medium", + ["iconsTheme"] = "nato", + ["easyFlight"] = false, + ["weapons"] = false, + ["cockpitStatusBarAllowed"] = false, + ["geffect"] = "realistic", + }, -- end of ["difficulty"] + ["playerName"] = "Killer", + ["graphics"] = + { + ["OculusRift"] = false, + ["color"] = "32", + ["preloadRadius"] = 73885, + ["heatBlr"] = 2, + ["scenes"] = "high", + ["water"] = 2, + ["visibRange"] = "High", + ["treesVisibility"] = 25000, + ["aspect"] = 1.7777777777778, + ["lights"] = 2, + ["HDR"] = 1, + ["MSAA"] = 6, + ["civTraffic"] = "high", + ["clutterMaxDistance"] = 1500, + ["terrainTextures"] = "max", + ["multiMonitorSetup"] = "1camera", + ["shadowTree"] = true, + ["fullScreen"] = false, + ["disableAero"] = false, + ["DOF"] = 0, + ["clouds"] = 1, + ["flatTerrainShadows"] = 1, + ["cockpitShadows"] = true, + ["height"] = 900, + ["width"] = 1600, + ["shadows"] = 5, + ["textures"] = 2, + ["sync"] = true, + ["LensEffects"] = 3, + ["anisotropy"] = 4, + ["TranspSSAA"] = false, + ["haze"] = 1, + ["effects"] = 3, + }, -- end of ["graphics"] + ["plugins"] = + { + ["CA"] = + { + ["kompass_options"] = 1, + ["ground_target_info"] = true, + ["ground_aim_helper"] = true, + ["ground_platform_shake"] = true, + ["ground_automatic"] = true, + }, -- end of ["CA"] + ["M-2000C"] = + { + ["TDC_"] = false, + ["CPLocalList"] = "default", + }, -- end of ["M-2000C"] + ["A-10C"] = + { + ["CPLocalList"] = "default", + }, -- end of ["A-10C"] + ["FC3"] = + { + ["CPLocalList_F-15C"] = "default", + ["CPLocalList_MiG-29S"] = "default", + ["CPLocalList_MiG-29A"] = "default", + ["CPLocalList_Su-25"] = "default", + ["CPLocalList_A-10A"] = "default", + ["CPLocalList_Su-27"] = "chinese", + ["CPLocalList_MiG-29G"] = "default", + ["CPLocalList_Su-33"] = "default", + }, -- end of ["FC3"] + ["Hawk"] = + { + ["CPLocalList"] = "high", + }, -- end of ["Hawk"] + ["P-51D"] = + { + ["assistance"] = 100, + ["CPLocalList"] = "default", + ["autoRudder"] = false, + }, -- end of ["P-51D"] + ["TF-51D"] = + { + ["assistance"] = 100, + ["CPLocalList"] = "default", + ["autoRudder"] = false, + }, -- end of ["TF-51D"] + ["MiG-21Bis"] = + { + ["Engine"] = false, + ["Shake"] = 100, + ["CustomCockpit"] = false, + ["Reticle"] = false, + ["Freeze"] = false, + }, -- end of ["MiG-21Bis"] + ["F-86F"] = + { + ["landSeatAdjustF86"] = true, + ["CPLocalList"] = "default", + ["NoseWheelSteeringSimpleBehaviourF86"] = true, + ["gunCamera"] = 0, + }, -- end of ["F-86F"] + ["Su-25T"] = + { + ["CPLocalList"] = "default", + }, -- end of ["Su-25T"] + ["Mi-8MTV2"] = + { + ["altMi8TrimmingMethod"] = false, + ["Mi8AutopilotAdjustment"] = false, + ["Mi8RudderTrimmer"] = false, + ["controlHelperMi8"] = false, + ["CPLocalList"] = "default", + ["weapTooltipsMi8"] = true, + ["Mi8FOV"] = 120, + }, -- end of ["Mi-8MTV2"] + ["MiG-15bis"] = + { + ["autoLeanToAimMiG15"] = true, + ["CPLocalList"] = "chinese", + ["gunCamera"] = 0, + ["aiHelper"] = false, + }, -- end of ["MiG-15bis"] + ["FW-190D9"] = + { + ["assistance"] = 100, + ["CPLocalList"] = "default", + ["autoRudder"] = false, + }, -- end of ["FW-190D9"] + ["UH-1H"] = + { + ["UHRudderTrimmer"] = false, + ["autoPilot"] = true, + ["altUHTrimmingMethod"] = false, + ["CPLocalList"] = "default", + ["weapTooltips"] = true, + ["UHTrackIRAiming"] = true, + }, -- end of ["UH-1H"] + ["Ka-50"] = + { + ["altTrimmingMethod"] = false, + ["Ka50RudderTrimmer"] = false, + ["CPLocalList"] = "english", + }, -- end of ["Ka-50"] + }, -- end of ["plugins"] + ["views"] = + { + ["cockpit"] = + { + ["mirrors"] = false, + ["reflections"] = false, + ["avionics"] = 3, + ["russianHud"] = false, + }, -- end of ["cockpit"] + }, -- end of ["views"] + ["sound"] = + { + ["hear_in_helmet"] = true, + ["headphones"] = -15, + ["cockpit"] = 0, + ["GBreathEffect"] = true, + ["gui"] = 0, + ["volume"] = 0, + ["radioSpeech"] = true, + ["music"] = -100, + ["subtitles"] = true, + ["world"] = 0, + }, -- end of ["sound"] + ["miscellaneous"] = + { + ["headmove"] = true, + ["f5_nearest_ac"] = true, + ["f11_free_camera"] = true, + ["F2_view_effects"] = 2, + ["f10_awacs"] = true, + ["Coordinate_Display"] = "Lat Long", + ["accidental_failures"] = false, + ["force_feedback_enabled"] = true, + ["synchronize_controls"] = false, + ["show_pilot_body"] = true, + }, -- end of ["miscellaneous"] +} -- end of options diff --git a/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/warehouses b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/warehouses new file mode 100644 index 000000000..86cce835c --- /dev/null +++ b/Moose Test Missions/Moose_Test_AIBALANCER/Moose_Test_AIBALANCER/warehouses @@ -0,0 +1,807 @@ +warehouses = +{ + ["airports"] = + { + [12] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "RED", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [12] + [13] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "BLUE", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [13] + [14] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [14] + [15] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "RED", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [15] + [16] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [16] + [17] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "RED", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [17] + [18] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [18] + [19] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [19] + [20] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [20] + [21] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [21] + [22] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [22] + [23] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [23] + [24] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [24] + [25] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [25] + [26] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [26] + [27] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [27] + [28] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [28] + [29] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [29] + [30] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [30] + [31] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [31] + [32] = + { + ["gasoline"] = + { + ["InitFuel"] = 100, + }, -- end of ["gasoline"] + ["unlimitedMunitions"] = true, + ["methanol_mixture"] = + { + ["InitFuel"] = 100, + }, -- end of ["methanol_mixture"] + ["OperatingLevel_Air"] = 10, + ["diesel"] = + { + ["InitFuel"] = 100, + }, -- end of ["diesel"] + ["speed"] = 16.666666, + ["size"] = 100, + ["periodicity"] = 30, + ["suppliers"] = + { + }, -- end of ["suppliers"] + ["coalition"] = "NEUTRAL", + ["jet_fuel"] = + { + ["InitFuel"] = 100, + }, -- end of ["jet_fuel"] + ["OperatingLevel_Eqp"] = 10, + ["unlimitedFuel"] = true, + ["aircrafts"] = + { + }, -- end of ["aircrafts"] + ["weapons"] = + { + }, -- end of ["weapons"] + ["OperatingLevel_Fuel"] = 10, + ["unlimitedAircrafts"] = true, + }, -- end of [32] + }, -- end of ["airports"] + ["warehouses"] = + { + }, -- end of ["warehouses"] +} -- end of warehouses diff --git a/Moose Test Missions/Moose_Test_AIRBASEPOLICE/Moose_Test_AIRBASEPOLICE.miz b/Moose Test Missions/Moose_Test_AIRBASEPOLICE/Moose_Test_AIRBASEPOLICE.miz index 1382a0fd7..19678b24d 100644 Binary files a/Moose Test Missions/Moose_Test_AIRBASEPOLICE/Moose_Test_AIRBASEPOLICE.miz and b/Moose Test Missions/Moose_Test_AIRBASEPOLICE/Moose_Test_AIRBASEPOLICE.miz differ diff --git a/Moose Test Missions/Moose_Test_BASE/Moose_Test_AIRBLANCER_with_Moose.miz b/Moose Test Missions/Moose_Test_BASE/Moose_Test_AIRBLANCER_with_Moose.miz index 10f317853..5f25cb009 100644 Binary files a/Moose Test Missions/Moose_Test_BASE/Moose_Test_AIRBLANCER_with_Moose.miz and b/Moose Test Missions/Moose_Test_BASE/Moose_Test_AIRBLANCER_with_Moose.miz differ diff --git a/Moose Test Missions/Moose_Test_BASE/Moose_Test_AIRBLANCER_without_Moose.miz b/Moose Test Missions/Moose_Test_BASE/Moose_Test_AIRBLANCER_without_Moose.miz index cebcf095f..ef4c8f84f 100644 Binary files a/Moose Test Missions/Moose_Test_BASE/Moose_Test_AIRBLANCER_without_Moose.miz and b/Moose Test Missions/Moose_Test_BASE/Moose_Test_AIRBLANCER_without_Moose.miz differ diff --git a/Moose Test Missions/Moose_Test_BASE/Moose_Test_BASE.miz b/Moose Test Missions/Moose_Test_BASE/Moose_Test_BASE.miz index e451bf44a..56685da9a 100644 Binary files a/Moose Test Missions/Moose_Test_BASE/Moose_Test_BASE.miz and b/Moose Test Missions/Moose_Test_BASE/Moose_Test_BASE.miz differ diff --git a/Moose Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.miz b/Moose Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.miz index cae2f660c..0c9eeeac1 100644 Binary files a/Moose Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.miz and b/Moose Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.miz differ diff --git a/Moose Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz b/Moose Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz index 3299ab03b..4518e700a 100644 Binary files a/Moose Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz and b/Moose Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz differ diff --git a/Moose Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz b/Moose Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz index 4a9406b05..45c9cb7c3 100644 Binary files a/Moose Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz and b/Moose Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz differ diff --git a/Moose Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz b/Moose Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz index 1d54e02a9..4eb575548 100644 Binary files a/Moose Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz and b/Moose Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz differ diff --git a/Moose Test Missions/Moose_Test_SEAD/MOOSE_Test_SEAD.miz b/Moose Test Missions/Moose_Test_SEAD/MOOSE_Test_SEAD.miz index 9c48dae59..7cca85770 100644 Binary files a/Moose Test Missions/Moose_Test_SEAD/MOOSE_Test_SEAD.miz and b/Moose Test Missions/Moose_Test_SEAD/MOOSE_Test_SEAD.miz differ diff --git a/Moose Test Missions/Moose_Test_SET_AIRBASE/Moose_Test_SET_AIRBASE.lua b/Moose Test Missions/Moose_Test_SET_AIRBASE/Moose_Test_SET_AIRBASE.lua new file mode 100644 index 000000000..f7ca6951a --- /dev/null +++ b/Moose Test Missions/Moose_Test_SET_AIRBASE/Moose_Test_SET_AIRBASE.lua @@ -0,0 +1,16 @@ + +local BlueAirbaseSet = SET_AIRBASE:New():FilterCoalitions("blue"):FilterStart() + +local RedAirbaseSet = SET_AIRBASE:New():FilterCoalitions("red"):FilterStart() + +local RedAirbaseHelipadSet = SET_AIRBASE:New():FilterCoalitions("red"):FilterCategories("helipad"):FilterStart() + +local BlueAirbaseShipSet = SET_AIRBASE:New():FilterCoalitions("blue"):FilterCategories("ship"):FilterStart() + +BlueAirbaseSet:Flush() + +RedAirbaseSet:Flush() + +RedAirbaseHelipadSet:Flush() + +BlueAirbaseShipSet:Flush() \ No newline at end of file diff --git a/Moose Test Missions/Moose_Test_SET_AIRBASE/Moose_Test_SET_AIRBASE.miz b/Moose Test Missions/Moose_Test_SET_AIRBASE/Moose_Test_SET_AIRBASE.miz new file mode 100644 index 000000000..95ddf77bd Binary files /dev/null and b/Moose Test Missions/Moose_Test_SET_AIRBASE/Moose_Test_SET_AIRBASE.miz differ diff --git a/Moose Test Missions/Moose_Test_SET_CLIENT/Moose_Test_SET_CLIENT.miz b/Moose Test Missions/Moose_Test_SET_CLIENT/Moose_Test_SET_CLIENT.miz index 4d1619242..320cb96e5 100644 Binary files a/Moose Test Missions/Moose_Test_SET_CLIENT/Moose_Test_SET_CLIENT.miz and b/Moose Test Missions/Moose_Test_SET_CLIENT/Moose_Test_SET_CLIENT.miz differ diff --git a/Moose Test Missions/Moose_Test_SET_GROUP/Moose_Test_SET_GROUP.miz b/Moose Test Missions/Moose_Test_SET_GROUP/Moose_Test_SET_GROUP.miz index 20ea2e55b..4c46f6233 100644 Binary files a/Moose Test Missions/Moose_Test_SET_GROUP/Moose_Test_SET_GROUP.miz and b/Moose Test Missions/Moose_Test_SET_GROUP/Moose_Test_SET_GROUP.miz differ diff --git a/Moose Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz b/Moose Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz index 496edc2c6..854038f54 100644 Binary files a/Moose Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz and b/Moose Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz differ diff --git a/Moose Test Missions/Moose_Test_SPAWN_Repeat/MOOSE_Test_SPAWN_Repeat.miz b/Moose Test Missions/Moose_Test_SPAWN_Repeat/MOOSE_Test_SPAWN_Repeat.miz index f8d3e4101..59ad54f22 100644 Binary files a/Moose Test Missions/Moose_Test_SPAWN_Repeat/MOOSE_Test_SPAWN_Repeat.miz and b/Moose Test Missions/Moose_Test_SPAWN_Repeat/MOOSE_Test_SPAWN_Repeat.miz differ diff --git a/Moose Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.miz b/Moose Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.miz index 4afd8f05c..b121a1ef2 100644 Binary files a/Moose Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.miz and b/Moose Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.miz differ diff --git a/Moose Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.miz b/Moose Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.miz index 15d1b1326..0c8d1b5d7 100644 Binary files a/Moose Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.miz and b/Moose Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.miz differ diff --git a/Moose Test Missions/Moose_Test_ZONE/Moose_Test_ZONE.miz b/Moose Test Missions/Moose_Test_ZONE/Moose_Test_ZONE.miz index bf4f2c02a..ba747b709 100644 Binary files a/Moose Test Missions/Moose_Test_ZONE/Moose_Test_ZONE.miz and b/Moose Test Missions/Moose_Test_ZONE/Moose_Test_ZONE.miz differ diff --git a/Moose Test Missions/Moose_Test_ZONE_POLYGON/Moose_Test_ZONE_POLYGON.miz b/Moose Test Missions/Moose_Test_ZONE_POLYGON/Moose_Test_ZONE_POLYGON.miz index c4ce960a8..f8d8d4826 100644 Binary files a/Moose Test Missions/Moose_Test_ZONE_POLYGON/Moose_Test_ZONE_POLYGON.miz and b/Moose Test Missions/Moose_Test_ZONE_POLYGON/Moose_Test_ZONE_POLYGON.miz differ diff --git a/Moose Test Missions/Moose_Test_ZONE_RADIUS/Moose_Test_ZONE_RADIUS.miz b/Moose Test Missions/Moose_Test_ZONE_RADIUS/Moose_Test_ZONE_RADIUS.miz index e36b81726..f25590a5a 100644 Binary files a/Moose Test Missions/Moose_Test_ZONE_RADIUS/Moose_Test_ZONE_RADIUS.miz and b/Moose Test Missions/Moose_Test_ZONE_RADIUS/Moose_Test_ZONE_RADIUS.miz differ diff --git a/Moose Test Missions/Moose_Test_ZONE_UNIT/Moose_Test_ZONE_UNIT.miz b/Moose Test Missions/Moose_Test_ZONE_UNIT/Moose_Test_ZONE_UNIT.miz index b124b31ae..e76d5d37c 100644 Binary files a/Moose Test Missions/Moose_Test_ZONE_UNIT/Moose_Test_ZONE_UNIT.miz and b/Moose Test Missions/Moose_Test_ZONE_UNIT/Moose_Test_ZONE_UNIT.miz differ diff --git a/Moose Training/Documentation/AIBalancer.html b/Moose Training/Documentation/AIBalancer.html index 80c324590..69a8934f5 100644 --- a/Moose Training/Documentation/AIBalancer.html +++ b/Moose Training/Documentation/AIBalancer.html @@ -90,6 +90,13 @@ There will be as many AI GROUPS spawned as there at CLIENTS in SETCLIENT no
  • AIBALANCER.New: Creates a new AIBALANCER object.
  • +

    1.2) AIBALANCER return AI to Airbases:

    +

    You can configure to have the AI to return to:

    + +
    @@ -114,6 +121,36 @@ There will be as many AI GROUPS spawned as there at CLIENTS in SETCLIENT no AIBALANCER:New(SetClient, SpawnAI)

    Creates a new AIBALANCER object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.

    + + + + AIBALANCER.ReturnAirbaseSet + + + + + + AIBALANCER.ReturnToAirbase + + + + + + AIBALANCER.ReturnToHomeAirbase + + + + + + AIBALANCER:ReturnToNearestAirbases(ReturnTresholdRange, ReturnAirbaseSet) + +

    Returns the AI to the nearest friendly Airbase#AIRBASE.

    + + + + AIBALANCER.ReturnTresholdRange + + @@ -203,6 +240,90 @@ A SPAWN object that will spawn the AI units required, balancing the SetClient.#AIBALANCER: self

    + + +
    +
    + + Set#SET_AIRBASE + +AIBALANCER.ReturnAirbaseSet + +
    +
    + + + +
    +
    +
    +
    + + #boolean + +AIBALANCER.ReturnToAirbase + +
    +
    + + + +
    +
    +
    +
    + + #boolean + +AIBALANCER.ReturnToHomeAirbase + +
    +
    + + + +
    +
    +
    +
    + + +AIBALANCER:ReturnToNearestAirbases(ReturnTresholdRange, ReturnAirbaseSet) + +
    +
    + +

    Returns the AI to the nearest friendly Airbase#AIRBASE.

    + +

    Parameters

    + +
    +
    +
    +
    + + DCSTypes#Distance + +AIBALANCER.ReturnTresholdRange + +
    +
    + + +
    diff --git a/Moose Training/Documentation/Airbase.html b/Moose Training/Documentation/Airbase.html index a7d65029b..f63188be6 100644 --- a/Moose Training/Documentation/Airbase.html +++ b/Moose Training/Documentation/Airbase.html @@ -73,22 +73,22 @@

    Module Airbase

    -

    AIRBASE Class

    +

    This module contains the AIRBASE classes.

    -

    AIRBASE class

    + + +
    + +

    1) Airbase#AIRBASE class, extends Base#BASE

    The AIRBASE class is a wrapper class to handle the DCS Airbase objects:

    • Support all DCS Airbase APIs.
    • -
    - - -
    • Enhance with Airbase specific APIs not in the DCS Airbase API set.
    -

    AIRBASE reference methods

    +

    1.1) AIRBASE reference methods

    For each DCS Airbase object alive within a running mission, a AIRBASE wrapper object (instance) will be created within the _DATABASE object. This is done at the beginning of the mission (when the mission starts).

    @@ -108,7 +108,7 @@ If the DCS Airbase object does not exist or is nil, the AIRBASE methods will ret

    IMPORTANT: ONE SHOULD NEVER SANATIZE these AIRBASE OBJECT REFERENCES! (make the AIRBASE object references nil).

    -

    DCS AIRBASE APIs

    +

    1.2) DCS AIRBASE APIs

    The DCS Airbase APIs are used extensively within MOOSE. The AIRBASE class has for each DCS Airbase API a corresponding method. To be able to distinguish easily in your code the difference between a AIRBASE API call and a DCS Airbase API call, the first letter of the method is also capitalized. So, by example, the DCS Airbase method DCSAirbase#Airbase.getName() @@ -157,6 +157,12 @@ is implemented in the AIRBASE class as AIRBASE.Get AIRBASE:GetCallSign()

    Returns the Airbase's callsign - the localized string.

    + + + + AIRBASE:GetCategory() + +

    Returns the DCS Airbase category as defined within the DCS Airbase Descriptor.

    @@ -362,6 +368,24 @@ The DCS Airbase is not existing or alive.

    + +AIRBASE:GetCategory() + +
    +
    + +

    Returns the DCS Airbase category as defined within the DCS Airbase Descriptor.

    + +

    Return value

    + +

    DCSAirbase#Airbase.Category: +The DCS Airbase Category

    + +
    +
    +
    +
    + AIRBASE:GetCategoryName() diff --git a/Moose Training/Documentation/Database.html b/Moose Training/Documentation/Database.html index 0c2570270..47be64322 100644 --- a/Moose Training/Documentation/Database.html +++ b/Moose Training/Documentation/Database.html @@ -73,11 +73,13 @@

    Module Database

    -

    Manage the mission database.

    +

    This module contains the DATABASE class, managing the database of mission objects.

    -

    #DATABASE class

    +
    + +

    1) Database#DATABASE class, extends Base#BASE

    Mission designers can use the DATABASE class to refer to:

    +
    +
    + + +POINT_VEC2:DistanceFromPointVec2(PointVec2Reference) + +
    +
    + +

    Calculate the distance from a reference Point#POINT_VEC2.

    + +

    Parameter

    + +

    Return value

    + +

    DCSTypes#Distance: +The distance from the reference Point#POINT_VEC2 in meters.

    + +
    +
    +
    +
    + + +POINT_VEC2:DistanceFromVec2(Vec2Reference) + +
    +
    + +

    Calculate the distance from a reference DCSTypes#Vec2.

    + +

    Parameter

    + +

    Return value

    + +

    DCSTypes#Distance: +The distance from the reference DCSTypes#Vec2 in meters.

    +
    @@ -374,6 +446,20 @@ The y coordinate of the Vec3 point, pointing to the Right.

    Point#POINT_VEC2:

    + +
    +
    +
    + + DCSTypes#Vec2 + +POINT_VEC2.PointVec2 + +
    +
    + + +
    diff --git a/Moose Training/Documentation/Scheduler.html b/Moose Training/Documentation/Scheduler.html index a9d35ff3c..dcedab1d2 100644 --- a/Moose Training/Documentation/Scheduler.html +++ b/Moose Training/Documentation/Scheduler.html @@ -87,7 +87,7 @@
  • Scheduler#SCHEDULER.New: Setup a new scheduler and start it with the specified parameters.
  • -

    SCHEDULER timer stop and start

    +

    1.2) SCHEDULER timer stop and start

    The SCHEDULER can be stopped and restarted with the following methods:

      diff --git a/Moose Training/Documentation/Set.html b/Moose Training/Documentation/Set.html index cd907008b..751a47a5e 100644 --- a/Moose Training/Documentation/Set.html +++ b/Moose Training/Documentation/Set.html @@ -89,7 +89,7 @@ The default "time interval" is after 0.001 seconds.

      1.1) Add or remove objects from the SET

      Some key core functions are Set#SET_BASE.Add and Set#SET_BASE.Remove to add or remove objects from the SET in your logic.

      -

      1.2) Define the SET iterator "yield interval" and the "time interval".

      +

      1.2) Define the SET iterator "yield interval" and the "time interval"

      Modify the iterator intervals with the Set#SET_BASE.SetInteratorIntervals method. You can set the "yield interval", and the "time interval". (See above).

      @@ -218,6 +218,8 @@ The following iterator methods are currently available within the SETUNIT:<
    • SET_UNIT.ForEachUnitNotInZone: Iterate and call an iterator function for each alive UNIT presence not in a Zone, providing the UNIT and optional parameters to the called function.
    +
    +

    4) Set#SET_CLIENT class, extends Set#SET_BASE

    Mission designers can use the Set#SET_CLIENT class to build sets of units belonging to certain:

    @@ -273,11 +275,60 @@ The following iterator methods are currently available within the SETCLIENT
  • SET_CLIENT.ForEachClient: Calls a function for each alive client it finds within the SET_CLIENT.
  • +
    + +

    5) Set#SET_AIRBASE class, extends Set#SET_BASE

    +

    Mission designers can use the Set#SET_AIRBASE class to build sets of airbases optionally belonging to certain:

    + +
      +
    • Coalitions
    • +
    + +

    5.1) SET_AIRBASE construction

    +

    Create a new SET_AIRBASE object with the SET_AIRBASE.New method:

    + + + +

    5.2) Add or Remove AIRBASEs from SET_AIRBASE

    +

    AIRBASEs can be added and removed using the Set#SET_AIRBASE.AddAirbasesByName and Set#SET_AIRBASE.RemoveAirbasesByName respectively. +These methods take a single AIRBASE name or an array of AIRBASE names to be added or removed from SET_AIRBASE.

    + +

    5.3) SET_AIRBASE filter criteria

    +

    You can set filter criteria to define the set of clients within the SET_AIRBASE. +Filter criteria are defined by:

    + + + +

    Once the filter criteria have been set for the SET_AIRBASE, you can start filtering using:

    + + + +

    5.4) SET_AIRBASE iterators:

    +

    Once the filters have been defined and the SETAIRBASE has been built, you can iterate the SETAIRBASE with the available iterator methods. +The iterator methods will walk the SETAIRBASE set, and call for each airbase within the set a function that you provide. +The following iterator methods are currently available within the SETAIRBASE:

    + + +

    Global(s)

    + + + +
    SET_AIRBASE + +
    SET_BASE @@ -303,6 +354,106 @@ The following iterator methods are currently available within the SETCLIENT
    +

    Type SET_AIRBASE

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SET_AIRBASE:AddAirbasesByName(AddAirbaseNames) +

    Add AIRBASEs to SET_AIRBASE.

    +
    SET_AIRBASE:AddInDatabase(Event) +

    Handles the Database to check on an event (birth) that the Object was added in the Database.

    +
    SET_AIRBASE.Airbases + +
    SET_AIRBASE.ClassName + +
    SET_AIRBASE.Filter + +
    SET_AIRBASE:FilterCategories(Categories) +

    Builds a set of airbases out of categories.

    +
    SET_AIRBASE:FilterCoalitions(Coalitions) +

    Builds a set of airbases of coalitions.

    +
    SET_AIRBASE.FilterMeta + +
    SET_AIRBASE:FilterStart() +

    Starts the filtering.

    +
    SET_AIRBASE:FindAirbase(AirbaseName) +

    Finds a Airbase based on the Airbase Name.

    +
    SET_AIRBASE:FindInDatabase(Event) +

    Handles the Database to check on any event that Object exists in the Database.

    +
    SET_AIRBASE:FindNearestAirbaseFromPointVec2(PointVec2) +

    Iterate the SET_AIRBASE while identifying the nearest Airbase#AIRBASE from a Point#POINT_VEC2.

    +
    SET_AIRBASE:ForEachAirbase(IteratorFunction, ...) +

    Iterate the SET_AIRBASE and call an interator function for each AIRBASE, providing the AIRBASE and optional parameters.

    +
    SET_AIRBASE:IsIncludeObject(MAirbase) + +
    SET_AIRBASE:New() +

    Creates a new SET_AIRBASE object, building a set of airbases belonging to a coalitions and categories.

    +
    SET_AIRBASE:RemoveAirbasesByName(RemoveAirbaseNames) +

    Remove AIRBASEs from SET_AIRBASE.

    +
    +

    Type SET_BASE

    @@ -315,6 +466,12 @@ The following iterator methods are currently available within the SETCLIENT + + + + @@ -486,7 +643,7 @@ The following iterator methods are currently available within the SETCLIENT @@ -722,7 +879,7 @@ The following iterator methods are currently available within the SETCLIENT @@ -767,6 +924,20 @@ The following iterator methods are currently available within the SETCLIENT
    + #SET_AIRBASE + +SET_AIRBASE + +
    +
    + + + +
    +
    +
    +
    + #SET_BASE SET_BASE @@ -822,6 +993,411 @@ The following iterator methods are currently available within the SETCLIENT

    Type Set

    +

    Type SET_AIRBASE

    + +

    SET_AIRBASE class

    + +

    Field(s)

    +
    +
    + + +SET_AIRBASE:AddAirbasesByName(AddAirbaseNames) + +
    +
    + +

    Add AIRBASEs to SET_AIRBASE.

    + +

    Parameter

    +
      +
    • + +

      #string AddAirbaseNames : +A single name or an array of AIRBASE names.

      + +
    • +
    +

    Return value

    + + +

    self

    + +
    +
    +
    +
    + + +SET_AIRBASE:AddInDatabase(Event) + +
    +
    + +

    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 SETBASE birth event!

    + +

    Parameter

    + +

    Return values

    +
      +
    1. + +

      #string: +The name of the AIRBASE

      + +
    2. +
    3. + +

      #table: +The AIRBASE

      + +
    4. +
    +
    +
    +
    +
    + + + +SET_AIRBASE.Airbases + +
    +
    + + + +
    +
    +
    +
    + + #string + +SET_AIRBASE.ClassName + +
    +
    + + + +
    +
    +
    +
    + + + +SET_AIRBASE.Filter + +
    +
    + + + +
    +
    +
    +
    + + +SET_AIRBASE:FilterCategories(Categories) + +
    +
    + +

    Builds a set of airbases out of categories.

    + + +

    Possible current categories are plane, helicopter, ground, ship.

    + +

    Parameter

    +
      +
    • + +

      #string Categories : +Can take the following values: "airdrome", "helipad", "ship".

      + +
    • +
    +

    Return value

    + +

    #SET_AIRBASE: +self

    + +
    +
    +
    +
    + + +SET_AIRBASE:FilterCoalitions(Coalitions) + +
    +
    + +

    Builds a set of airbases of coalitions.

    + + +

    Possible current coalitions are red, blue and neutral.

    + +

    Parameter

    +
      +
    • + +

      #string Coalitions : +Can take the following values: "red", "blue", "neutral".

      + +
    • +
    +

    Return value

    + +

    #SET_AIRBASE: +self

    + +
    +
    +
    +
    + + + +SET_AIRBASE.FilterMeta + +
    +
    + + + +
    +
    +
    +
    + + +SET_AIRBASE:FilterStart() + +
    +
    + +

    Starts the filtering.

    + +

    Return value

    + +

    #SET_AIRBASE: +self

    + +
    +
    +
    +
    + + +SET_AIRBASE:FindAirbase(AirbaseName) + +
    +
    + +

    Finds a Airbase based on the Airbase Name.

    + +

    Parameter

    +
      +
    • + +

      #string AirbaseName :

      + +
    • +
    +

    Return value

    + +

    Airbase#AIRBASE: +The found Airbase.

    + +
    +
    +
    +
    + + +SET_AIRBASE:FindInDatabase(Event) + +
    +
    + +

    Handles the Database to check on any event that Object exists in the Database.

    + + +

    This is required, because sometimes the DATABASE event gets called later than the SETBASE event or vise versa!

    + +

    Parameter

    + +

    Return values

    +
      +
    1. + +

      #string: +The name of the AIRBASE

      + +
    2. +
    3. + +

      #table: +The AIRBASE

      + +
    4. +
    +
    +
    +
    +
    + + +SET_AIRBASE:FindNearestAirbaseFromPointVec2(PointVec2) + +
    +
    + +

    Iterate the SET_AIRBASE while identifying the nearest Airbase#AIRBASE from a Point#POINT_VEC2.

    + +

    Parameter

    + +

    Return value

    + +

    Airbase#AIRBASE: +The closest Airbase#AIRBASE.

    + +
    +
    +
    +
    + + +SET_AIRBASE:ForEachAirbase(IteratorFunction, ...) + +
    +
    + +

    Iterate the SET_AIRBASE and call an interator function for each AIRBASE, providing the AIRBASE and optional parameters.

    + +

    Parameters

    +
      +
    • + +

      #function IteratorFunction : +The function that will be called when there is an alive AIRBASE in the SET_AIRBASE. The function needs to accept a AIRBASE parameter.

      + +
    • +
    • + +

      ... :

      + +
    • +
    +

    Return value

    + +

    #SET_AIRBASE: +self

    + +
    +
    +
    +
    + + +SET_AIRBASE:IsIncludeObject(MAirbase) + +
    +
    + + + +

    Parameter

    + +

    Return value

    + +

    #SET_AIRBASE: +self

    + +
    +
    +
    +
    + + +SET_AIRBASE:New() + +
    +
    + +

    Creates a new SET_AIRBASE object, building a set of airbases belonging to a coalitions and categories.

    + +

    Return value

    + +

    #SET_AIRBASE: +self

    + +

    Usage:

    +
    -- Define a new SET_AIRBASE Object. The DatabaseSet will contain a reference to all Airbases.
    +DatabaseSet = SET_AIRBASE:New()
    + +
    +
    +
    +
    + + +SET_AIRBASE:RemoveAirbasesByName(RemoveAirbaseNames) + +
    +
    + +

    Remove AIRBASEs from SET_AIRBASE.

    + +

    Parameter

    +
      +
    • + +

      Airbase#AIRBASE RemoveAirbaseNames : +A single name or an array of AIRBASE names.

      + +
    • +
    +

    Return value

    + + +

    self

    + +
    +
    +

    Type SET_BASE

    SET_BASE class

    @@ -870,6 +1446,33 @@ The added BASE Object.

    + + +
    +
    + + +SET_BASE:FindNearestObjectFromPointVec2(PointVec2) + +
    +
    + +

    Iterate the SET_BASE while identifying the nearest object from a Point#POINT_VEC2.

    + +

    Parameter

    + +

    Return value

    + +

    Base#BASE: +The closest object.

    +
    @@ -1548,7 +2151,7 @@ The CLIENT

    -

    Interate the SET_CLIENT and call an interator function for each alive CLIENT, providing the CLIENT and optional parameters.

    +

    Iterate the SET_CLIENT and call an interator function for each alive CLIENT, providing the CLIENT and optional parameters.

    Parameters

      @@ -2616,7 +3219,7 @@ The found Unit.

      -

      Interate the SET_UNIT and call an interator function for each alive UNIT, providing the UNIT and optional parameters.

      +

      Iterate the SET_UNIT and call an interator function for each alive UNIT, providing the UNIT and optional parameters.

      Parameters

        diff --git a/Moose Training/Documentation/Unit.html b/Moose Training/Documentation/Unit.html index ca9b6a88c..2348dc8a5 100644 --- a/Moose Training/Documentation/Unit.html +++ b/Moose Training/Documentation/Unit.html @@ -269,6 +269,12 @@ If you want to obtain the complete 3D position including ori
    + + + + @@ -974,6 +980,24 @@ The DCS Unit is not existing or alive.

    + +UNIT:GetHeading() + +
    +
    + +

    Returns the DCS Unit heading.

    + +

    Return value

    + +

    #number: +The DCS Unit heading

    + +
    +
    +
    +
    + UNIT:GetID() diff --git a/Moose Training/Documentation/index.html b/Moose Training/Documentation/index.html index aff0615da..6b4ed124c 100644 --- a/Moose Training/Documentation/index.html +++ b/Moose Training/Documentation/index.html @@ -82,14 +82,7 @@
    @@ -221,7 +214,7 @@ diff --git a/Moose Training/Presentations/DCS World - MOOSE - AI Balancer.pptx b/Moose Training/Presentations/DCS World - MOOSE - AI Balancer.pptx new file mode 100644 index 000000000..b86d82f87 Binary files /dev/null and b/Moose Training/Presentations/DCS World - MOOSE - AI Balancer.pptx differ diff --git a/Moose Training/Presentations/DCS World - MOOSE - Zones - Part 1 - Use zones with GROUP and UNIT - kopie.pptx b/Moose Training/Presentations/DCS World - MOOSE - Zones - Part 1 - Use zones with GROUP and UNIT.pptx similarity index 100% rename from Moose Training/Presentations/DCS World - MOOSE - Zones - Part 1 - Use zones with GROUP and UNIT - kopie.pptx rename to Moose Training/Presentations/DCS World - MOOSE - Zones - Part 1 - Use zones with GROUP and UNIT.pptx
    SET_BASE.ClassName +
    SET_BASE:FindNearestObjectFromPointVec2(PointVec2) +

    Iterate the SET_BASE while identifying the nearest object from a Point#POINT_VEC2.

    SET_CLIENT:ForEachClient(IteratorFunction, ...) -

    Interate the SET_CLIENT and call an interator function for each alive CLIENT, providing the CLIENT and optional parameters.

    +

    Iterate the SET_CLIENT and call an interator function for each alive CLIENT, providing the CLIENT and optional parameters.

    SET_UNIT:ForEachUnit(IteratorFunction, ...) -

    Interate the SET_UNIT and call an interator function for each alive UNIT, providing the UNIT and optional parameters.

    +

    Iterate the SET_UNIT and call an interator function for each alive UNIT, providing the UNIT and optional parameters.

    UNIT:GetGroup()

    Returns the unit's group if it exist and nil otherwise.

    +
    UNIT:GetHeading() +

    Returns the DCS Unit heading.

    Airbase -

    AIRBASE Class

    - -

    AIRBASE class

    -

    The AIRBASE class is a wrapper class to handle the DCS Airbase objects:

    - -
      -
    • Support all DCS Airbase APIs.
    • -
    +

    This module contains the AIRBASE classes.

    Database -

    Manage the mission database.

    +

    This module contains the DATABASE class, managing the database of mission objects.