diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index 7cdec63ac..87847f95a 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -1475,7 +1475,7 @@ function EVENT:onEvent( Event ) -- SCENERY --- Event.TgtDCSUnit = Event.target - Event.TgtDCSUnitName = Event.TgtDCSUnit.getName and Event.TgtDCSUnit.getName() or nil + Event.TgtDCSUnitName = Event.TgtDCSUnit.getName and Event.TgtDCSUnit:getName() or nil if Event.TgtDCSUnitName~=nil then Event.TgtUnitName = Event.TgtDCSUnitName Event.TgtUnit = SCENERY:Register( Event.TgtDCSUnitName, Event.target ) diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index 4e3e34317..7457eba34 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -3,8 +3,6 @@ -- ## Features: -- -- * Provides a COORDINATE class, which allows to manage points in 3D space and perform various operations on it. --- * Provides a POINT\_VEC2 class, which is derived from COORDINATE, and allows to manage points in 3D space, but from a Lat/Lon and Altitude perspective. --- * Provides a POINT\_VEC3 class, which is derived from COORDINATE, and allows to manage points in 3D space, but from a X, Z and Y vector perspective. -- -- === -- @@ -3892,171 +3890,3 @@ do -- COORDINATE end end - -do - - --- The POINT_VEC3 class - -- @type POINT_VEC3 - -- @field #number x The x coordinate in 3D space. - -- @field #number y The y coordinate in 3D space. - -- @field #number z The z COORDINATE in 3D space. - -- @field Utilities.Utils#SMOKECOLOR SmokeColor - -- @field Utilities.Utils#FLARECOLOR FlareColor - -- @field #POINT_VEC3.RoutePointAltType RoutePointAltType - -- @field #POINT_VEC3.RoutePointType RoutePointType - -- @field #POINT_VEC3.RoutePointAction RoutePointAction - -- @extends #COORDINATE - - - --- Defines a 3D point in the simulator and with its methods, you can use or manipulate the point in 3D space. - -- - -- **DEPRECATED - PLEASE USE COORDINATE!** - -- - -- **Important Note:** Most of the functions in this section were taken from MIST, and reworked to OO concepts. - -- In order to keep the credibility of the the author, - -- I want to emphasize that the formulas embedded in the MIST framework were created by Grimes or previous authors, - -- who you can find on the Eagle Dynamics Forums. - -- - -- - -- ## POINT_VEC3 constructor - -- - -- A new POINT_VEC3 object can be created with: - -- - -- * @{#POINT_VEC3.New}(): a 3D point. - -- * @{#POINT_VEC3.NewFromVec3}(): a 3D point created from a @{DCS#Vec3}. - -- - -- - -- ## Manupulate the X, Y, Z coordinates of the POINT_VEC3 - -- - -- A POINT_VEC3 class works in 3D space. It contains internally an X, Y, Z coordinate. - -- Methods exist to manupulate these coordinates. - -- - -- The current X, Y, Z axis can be retrieved with the methods @{#POINT_VEC3.GetX}(), @{#POINT_VEC3.GetY}(), @{#POINT_VEC3.GetZ}() respectively. - -- The methods @{#POINT_VEC3.SetX}(), @{#POINT_VEC3.SetY}(), @{#POINT_VEC3.SetZ}() change the respective axis with a new value. - -- The current axis values can be changed by using the methods @{#POINT_VEC3.AddX}(), @{#POINT_VEC3.AddY}(), @{#POINT_VEC3.AddZ}() - -- to add or substract a value from the current respective axis value. - -- Note that the Set and Add methods return the current POINT_VEC3 object, so these manipulation methods can be chained... For example: - -- - -- local Vec3 = PointVec3:AddX( 100 ):AddZ( 150 ):GetVec3() - -- - -- - -- ## 3D calculation methods - -- - -- Various calculation methods exist to use or manipulate 3D space. Find below a short description of each method: - -- - -- - -- ## Point Randomization - -- - -- Various methods exist to calculate random locations around a given 3D point. - -- - -- * @{#POINT_VEC3.GetRandomPointVec3InRadius}(): Provides a random 3D point around the current 3D point, in the given inner to outer band. - -- - -- - -- @field #POINT_VEC3 - POINT_VEC3 = { - ClassName = "POINT_VEC3", - Metric = true, - RoutePointAltType = { - BARO = "BARO", - }, - RoutePointType = { - TakeOffParking = "TakeOffParking", - TurningPoint = "Turning Point", - }, - RoutePointAction = { - FromParkingArea = "From Parking Area", - TurningPoint = "Turning Point", - }, - } - - --- RoutePoint AltTypes - -- @type POINT_VEC3.RoutePointAltType - -- @field BARO "BARO" - - --- RoutePoint Types - -- @type POINT_VEC3.RoutePointType - -- @field TakeOffParking "TakeOffParking" - -- @field TurningPoint "Turning Point" - - --- RoutePoint Actions - -- @type POINT_VEC3.RoutePointAction - -- @field FromParkingArea "From Parking Area" - -- @field TurningPoint "Turning Point" - - -- Constructor. - - --- Create a new POINT_VEC3 object. - -- @param #POINT_VEC3 self - -- @param DCS#Distance x The x coordinate of the Vec3 point, pointing to the North. - -- @param DCS#Distance y The y coordinate of the Vec3 point, pointing Upwards. - -- @param DCS#Distance z The z coordinate of the Vec3 point, pointing to the Right. - -- @return Core.Point#POINT_VEC3 - function POINT_VEC3:New( x, y, z ) - - local self = BASE:Inherit( self, COORDINATE:New( x, y, z ) ) -- Core.Point#POINT_VEC3 - self:F2( self ) - - return self - end - -end - -do - - --- @type POINT_VEC2 - -- @field DCS#Distance x The x coordinate in meters. - -- @field DCS#Distance y the y coordinate in meters. - -- @extends Core.Point#COORDINATE - - --- Defines a 2D point in the simulator. The height coordinate (if needed) will be the land height + an optional added height specified. - -- - -- **DEPRECATED - PLEASE USE COORDINATE!** - -- - -- ## POINT_VEC2 constructor - -- - -- A new POINT_VEC2 instance can be created with: - -- - -- * @{Core.Point#POINT_VEC2.New}(): a 2D point, taking an additional height parameter. - -- * @{Core.Point#POINT_VEC2.NewFromVec2}(): a 2D point created from a @{DCS#Vec2}. - -- - -- ## Manupulate the X, Altitude, Y coordinates of the 2D point - -- - -- A POINT_VEC2 class works in 2D space, with an altitude setting. It contains internally an X, Altitude, Y coordinate. - -- Methods exist to manupulate these coordinates. - -- - -- The current X, Altitude, Y axis can be retrieved with the methods @{#POINT_VEC2.GetX}(), @{#POINT_VEC2.GetAlt}(), @{#POINT_VEC2.GetY}() respectively. - -- The methods @{#POINT_VEC2.SetX}(), @{#POINT_VEC2.SetAlt}(), @{#POINT_VEC2.SetY}() change the respective axis with a new value. - -- The current Lat(itude), Alt(itude), Lon(gitude) values can also be retrieved with the methods @{#POINT_VEC2.GetLat}(), @{#POINT_VEC2.GetAlt}(), @{#POINT_VEC2.GetLon}() respectively. - -- The current axis values can be changed by using the methods @{#POINT_VEC2.AddX}(), @{#POINT_VEC2.AddAlt}(), @{#POINT_VEC2.AddY}() - -- to add or substract a value from the current respective axis value. - -- Note that the Set and Add methods return the current POINT_VEC2 object, so these manipulation methods can be chained... For example: - -- - -- local Vec2 = PointVec2:AddX( 100 ):AddY( 2000 ):GetVec2() - -- - -- @field #POINT_VEC2 - POINT_VEC2 = { - ClassName = "POINT_VEC2", - } - - - - --- POINT_VEC2 constructor. - -- @param #POINT_VEC2 self - -- @param DCS#Distance x The x coordinate of the Vec3 point, pointing to the North. - -- @param DCS#Distance y The y coordinate of the Vec3 point, pointing to the Right. - -- @param DCS#Distance LandHeightAdd (optional) The default height if required to be evaluated will be the land height of the x, y coordinate. You can specify an extra height to be added to the land height. - -- @return Core.Point#POINT_VEC2 - function POINT_VEC2:New( x, y, LandHeightAdd ) - - local LandHeight = land.getHeight( { ["x"] = x, ["y"] = y } ) - - LandHeightAdd = LandHeightAdd or 0 - LandHeight = LandHeight + LandHeightAdd - - local self = BASE:Inherit( self, COORDINATE:New( x, LandHeight, y ) ) -- Core.Point#POINT_VEC2 - self:F2( self ) - - return self - end - -end diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index f9134d6a5..191d62287 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -945,7 +945,8 @@ do -- SET_BASE function SET_BASE:IsInSet(Object) --self:F3(Object) local outcome = false - local name = Object:GetName() + if Object == nil then return false end + local name = (Object ~= nil and Object.GetName) and Object:GetName() or "none" --self:I("SET_BASE: Objectname = "..name) self:ForEach( function(object) diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index e434ea296..efccdd288 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -1179,7 +1179,7 @@ function ZONE_RADIUS:Scan( ObjectCategories, UnitCategories ) self.ScanData.SceneryTable = {} self.ScanData.Units = {} - local ZoneCoord = self:GetCoordinate() + local ZoneCoord = self:GetCoordinate():SetAlt() local ZoneRadius = self:GetRadius() --self:F({ZoneCoord = ZoneCoord, ZoneRadius = ZoneRadius, ZoneCoordLL = ZoneCoord:ToStringLLDMS()}) diff --git a/Moose Development/Moose/Functional/Formation.lua b/Moose Development/Moose/Functional/Formation.lua new file mode 100644 index 000000000..5eac066db --- /dev/null +++ b/Moose Development/Moose/Functional/Formation.lua @@ -0,0 +1,999 @@ +--- **Functional** - Build large airborne formations of aircraft. +-- +-- **Features:** +-- +-- * Build in-air formations consisting of more than 40 aircraft as one group. +-- * Build different formation types. +-- * Assign a group leader that will guide the large formation path. +-- +-- === +-- +-- ## Additional Material: +-- +-- * **Demo Missions:** [GitHub](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/FORMATION) +-- * **Guides:** None +-- +-- === +-- +-- ### Author: **FlightControl** +-- ### Contributions: **Applevangelist** (refactor) +-- +-- === +-- +-- @module Functional.FORMATION +-- @image AI_Large_Formations.JPG + +--- FORMATION class +-- @type FORMATION +-- @extends Core.Fsm#FSM_SET +-- @field Wrapper.Unit#UNIT FollowUnit +-- @field Core.Set#SET_GROUP FollowGroupSet +-- @field #string FollowName +-- @field Core.Scheduler#SCHEDULER FollowScheduler The instance of the SCHEDULER class. +-- @field #number FollowDistance The current follow distance. +-- @field DCS#AI.Option.Air.val.ROE OptionROE Which ROE is set to the FollowGroup. +-- @field DCS#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the FollowGroup. +-- @field #number dtFollow Time step between position updates. + + +--- Build (large) formations, make AI follow a @{Wrapper.Client#CLIENT} (player) leader or a @{Wrapper.Unit#UNIT} (AI) leader. +-- +-- FORMATION makes AI @{Wrapper.Group#GROUP}s fly in formation of various compositions. +-- The FORMATION class models formations in a different manner than the internal DCS formation logic!!! +-- The purpose of the class is to: +-- +-- * Make formation building a process that can be managed while in flight, rather than a task. +-- * Human players can guide formations, consisting of larget planes. +-- * Build large formations (like a large bomber field). +-- * Form formations that DCS does not support off-the-shelve. +-- +-- A few remarks: +-- +-- * Depending on the type of plane, the change in direction by the leader may result in the formation getting disentangled while in flight and needs to be rebuild. +-- * Formations are vulnerable to collissions, but is depending on the type of plane, the distance between the planes and the speed and angle executed by the leader. +-- * Formations may take a while to build up. +-- +-- As a result, the FORMATION is not perfect, but is very useful to: +-- +-- * Model large formations when flying straight line. You can build close formations when doing this. +-- * Make humans guide a large formation, when the planes are wide from each other. +-- +-- ## FORMATION construction +-- +-- Create a new SPAWN object with the @{#FORMATION.New} method: +-- +-- * @{#FORMATION.New}(): Creates a new FORMATION object from a @{Wrapper.Group#GROUP} for a @{Wrapper.Client#CLIENT} or a @{Wrapper.Unit#UNIT}, with an optional briefing text. +-- +-- ## Formation methods +-- +-- The following methods can be used to set or change the formation: +-- +-- * @{#FORMATION.FormationLine}(): Form a line formation (core formation function). +-- * @{#FORMATION.FormationTrail}(): Form a trail formation. +-- * @{#FORMATION.FormationLeftLine}(): Form a left line formation. +-- * @{#FORMATION.FormationRightLine}(): Form a right line formation. +-- * @{#FORMATION.FormationRightWing}(): Form a right wing formation. +-- * @{#FORMATION.FormationLeftWing}(): Form a left wing formation. +-- * @{#FORMATION.FormationCenterWing}(): Form a center wing formation. +-- * @{#FORMATION.FormationCenterVic}(): Form a Vic formation (same as CenterWing). +-- * @{#FORMATION.FormationCenterBoxed}(): Form a center boxed formation. +-- +-- ## Randomization +-- +-- Use the method @{FORMATION#FORMATION.SetFlightRandomization}() to simulate the formation flying errors that pilots make while in formation. Is a range set in meters. +-- +-- @usage +-- local FollowGroupSet = SET_GROUP:New():FilterCategories("plane"):FilterCoalitions("blue"):FilterPrefixes("Follow"):FilterStart() +-- local LeaderUnit = UNIT:FindByName( "Leader" ) +-- local LargeFormation = FORMATION:New( LeaderUnit, FollowGroupSet, "Center Wing Formation", "Briefing" ) +-- LargeFormation:FormationCenterWing( 500, 50, 0, 250, 250 ) +-- LargeFormation:__Start( 1 ) +-- +-- @field #FORMATION +FORMATION = { + ClassName = "FORMATION", + FollowName = nil, -- The Follow Name + FollowUnit = nil, + FollowGroupSet = nil, + FollowScheduler = nil, + OptionROE = AI.Option.Air.val.ROE.OPEN_FIRE, + OptionReactionOnThreat = AI.Option.Air.val.REACTION_ON_THREAT.ALLOW_ABORT_MISSION, + dtFollow = 0.5, +} + +--- @type FORMATION.Formation +-- @field #number None +-- @field #number Line +-- @field #number Trail +-- @field #number Stack +-- @field #number LeftLine +-- @field #number RightLine +-- @field #number LeftWing +-- @field #number RightWing +-- @field #number Vic +-- @field #number Box +FORMATION.Formation = { + None = 1, + Line = 2, + Trail = 3, + Stack = 4, + LeftLine = 5, + RightLine = 6, + LeftWing = 7, + RightWing = 8, + Vic = 9, + Box = 10, +} + +--- FORMATION class constructor for an AI group +-- @param #FORMATION self +-- @param Wrapper.Unit#UNIT FollowUnit The UNIT leading the FolllowGroupSet. +-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. +-- @param #string FollowName Name of the escort. +-- @return #FORMATION self +function FORMATION:New( FollowUnit, FollowGroupSet, FollowName ) + local self = BASE:Inherit( self, FSM_SET:New( FollowGroupSet ) ) + self:F( { FollowUnit, FollowGroupSet, FollowName } ) + + self.FollowUnit = FollowUnit -- Wrapper.Unit#UNIT + self.FollowGroupSet = FollowGroupSet -- Core.Set#SET_GROUP + + self:SetFlightRandomization( 2 ) + + self:SetStartState( "None" ) + + self:AddTransition( "*", "Stop", "Stopped" ) + + self:AddTransition( {"None", "Stopped"}, "Start", "Following" ) + + self:AddTransition( "*", "FormationLine", "*" ) + + --- Start Trigger for FORMATION + -- @function [parent=#FORMATION] Start + -- @param #FORMATION self + + --- Start Asynchronous Trigger for FORMATION + -- @function [parent=#FORMATION] __Start + -- @param #FORMATION self + -- @param #number Delay + + --- Stop Trigger for FORMATION + -- @function [parent=#FORMATION] Stop + -- @param #FORMATION self + + --- Stop Asynchronous Trigger for FORMATION + -- @function [parent=#FORMATION] __Stop + -- @param #FORMATION self + -- @param #number Delay + + --- FormationLine Handler OnAfter for FORMATION + -- @function [parent=#FORMATION] OnAfterFormationLine + -- @param #FORMATION self + -- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationLine Trigger for FORMATION + -- @function [parent=#FORMATION] FormationLine + -- @param #FORMATION self + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationLine Asynchronous Trigger for FORMATION + -- @function [parent=#FORMATION] __FormationLine + -- @param #FORMATION self + -- @param #number Delay + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + self:AddTransition( "*", "FormationTrail", "*" ) + + --- FormationTrail Handler OnAfter for FORMATION + -- @function [parent=#FORMATION] OnAfterFormationTrail + -- @param #FORMATION self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + + --- FormationTrail Trigger for FORMATION + -- @function [parent=#FORMATION] FormationTrail + -- @param #FORMATION self + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + + --- FormationTrail Asynchronous Trigger for FORMATION + -- @function [parent=#FORMATION] __FormationTrail + -- @param #FORMATION self + -- @param #number Delay + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + + self:AddTransition( "*", "FormationStack", "*" ) + + --- FormationStack Handler OnAfter for FORMATION + -- @function [parent=#FORMATION] OnAfterFormationStack + -- @param #FORMATION self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + + --- FormationStack Trigger for FORMATION + -- @function [parent=#FORMATION] FormationStack + -- @param #FORMATION self + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + + --- FormationStack Asynchronous Trigger for FORMATION + -- @function [parent=#FORMATION] __FormationStack + -- @param #FORMATION self + -- @param #number Delay + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + + self:AddTransition( "*", "FormationLeftLine", "*" ) + + --- FormationLeftLine Handler OnAfter for FORMATION + -- @function [parent=#FORMATION] OnAfterFormationLeftLine + -- @param #FORMATION self + -- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationLeftLine Trigger for FORMATION + -- @function [parent=#FORMATION] FormationLeftLine + -- @param #FORMATION self + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationLeftLine Asynchronous Trigger for FORMATION + -- @function [parent=#FORMATION] __FormationLeftLine + -- @param #FORMATION self + -- @param #number Delay + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + self:AddTransition( "*", "FormationRightLine", "*" ) + + --- FormationRightLine Handler OnAfter for FORMATION + -- @function [parent=#FORMATION] OnAfterFormationRightLine + -- @param #FORMATION self + -- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationRightLine Trigger for FORMATION + -- @function [parent=#FORMATION] FormationRightLine + -- @param #FORMATION self + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationRightLine Asynchronous Trigger for FORMATION + -- @function [parent=#FORMATION] __FormationRightLine + -- @param #FORMATION self + -- @param #number Delay + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + self:AddTransition( "*", "FormationLeftWing", "*" ) + + --- FormationLeftWing Handler OnAfter for FORMATION + -- @function [parent=#FORMATION] OnAfterFormationLeftWing + -- @param #FORMATION self + -- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationLeftWing Trigger for FORMATION + -- @function [parent=#FORMATION] FormationLeftWing + -- @param #FORMATION self + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationLeftWing Asynchronous Trigger for FORMATION + -- @function [parent=#FORMATION] __FormationLeftWing + -- @param #FORMATION self + -- @param #number Delay + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + self:AddTransition( "*", "FormationRightWing", "*" ) + + --- FormationRightWing Handler OnAfter for FORMATION + -- @function [parent=#FORMATION] OnAfterFormationRightWing + -- @param #FORMATION self + -- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationRightWing Trigger for FORMATION + -- @function [parent=#FORMATION] FormationRightWing + -- @param #FORMATION self + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationRightWing Asynchronous Trigger for FORMATION + -- @function [parent=#FORMATION] __FormationRightWing + -- @param #FORMATION self + -- @param #number Delay + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + self:AddTransition( "*", "FormationCenterWing", "*" ) + + --- FormationCenterWing Handler OnAfter for FORMATION + -- @function [parent=#FORMATION] OnAfterFormationCenterWing + -- @param #FORMATION self + -- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationCenterWing Trigger for FORMATION + -- @function [parent=#FORMATION] FormationCenterWing + -- @param #FORMATION self + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationCenterWing Asynchronous Trigger for FORMATION + -- @function [parent=#FORMATION] __FormationCenterWing + -- @param #FORMATION self + -- @param #number Delay + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + self:AddTransition( "*", "FormationVic", "*" ) + + --- FormationVic Handler OnAfter for FORMATION + -- @function [parent=#FORMATION] OnAfterFormationVic + -- @param #FORMATION self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationVic Trigger for FORMATION + -- @function [parent=#FORMATION] FormationVic + -- @param #FORMATION self + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + --- FormationVic Asynchronous Trigger for FORMATION + -- @function [parent=#FORMATION] __FormationVic + -- @param #FORMATION self + -- @param #number Delay + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + + self:AddTransition( "*", "FormationBox", "*" ) + + --- FormationBox Handler OnAfter for FORMATION + -- @function [parent=#FORMATION] OnAfterFormationBox + -- @param #FORMATION self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + -- @param #number ZLevels The amount of levels on the Z-axis. + + --- FormationBox Trigger for FORMATION + -- @function [parent=#FORMATION] FormationBox + -- @param #FORMATION self + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + -- @param #number ZLevels The amount of levels on the Z-axis. + + --- FormationBox Asynchronous Trigger for FORMATION + -- @function [parent=#FORMATION] __FormationBox + -- @param #FORMATION self + -- @param #number Delay + -- @param #number XStart The start position on the X-axis in meters for the first group. + -- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. + -- @param #number YStart The start position on the Y-axis in meters for the first group. + -- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. + -- @param #number ZStart The start position on the Z-axis in meters for the first group. + -- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. + -- @param #number ZLevels The amount of levels on the Z-axis. + + self:AddTransition( "*", "Follow", "Following" ) + + self:FormationLeftLine( 500, 0, 250, 250 ) + + self.FollowName = FollowName + + self.CT1 = 0 + self.GT1 = 0 + + return self +end + + +--- Set time interval between updates of the formation. +-- @param #FORMATION self +-- @param #number dt Time step in seconds between formation updates. Default is every 0.5 seconds. +-- @return #FORMATION +function FORMATION:SetFollowTimeInterval(dt) + self.dtFollow=dt or 0.5 + return self +end + +--- This function is for test, it will put on the frequency of the FollowScheduler a red smoke at the direction vector calculated for the escort to fly to. +-- This allows to visualize where the escort is flying to. +-- @param #FORMATION self +-- @param #boolean SmokeDirection If true, then the direction vector will be smoked. +-- @return #FORMATION +function FORMATION:TestSmokeDirectionVector( SmokeDirection ) + self.SmokeDirectionVector = ( SmokeDirection == true ) and true or false + return self +end + +--- FormationLine Handler OnAfter for FORMATION +-- @param #FORMATION self +-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. +-- @param #string From +-- @param #string Event +-- @param #string To +-- @param #number XStart The start position on the X-axis in meters for the first group. +-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. +-- @param #number YStart The start position on the Y-axis in meters for the first group. +-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. +-- @param #number ZStart The start position on the Z-axis in meters for the first group. +-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. +-- @return #FORMATION +function FORMATION:onafterFormationLine( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace, Formation ) + self:F( { FollowGroupSet, From , Event ,To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace, Formation } ) + + XStart = XStart or self.XStart + XSpace = XSpace or self.XSpace + YStart = YStart or self.YStart + YSpace = YSpace or self.YSpace + ZStart = ZStart or self.ZStart + ZSpace = ZSpace or self.ZSpace + + local FollowSet = FollowGroupSet:GetSet() + + local i = 1 --FF i=0 caused first unit to have no XSpace! Probably needs further adjustments. This is just a quick work around. + + for FollowID, FollowGroup in pairs( FollowSet ) do + + local PointVec3 = COORDINATE:New() + PointVec3:SetX( XStart + i * XSpace ) + PointVec3:SetY( YStart + i * YSpace ) + PointVec3:SetZ( ZStart + i * ZSpace ) + + local Vec3 = PointVec3:GetVec3() + FollowGroup:SetState( self, "FormationVec3", Vec3 ) + i = i + 1 + + FollowGroup:SetState( FollowGroup, "Formation", Formation ) + end + + return self + +end + +--- FormationTrail Handler OnAfter for FORMATION +-- @param #FORMATION self +-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. +-- @param #string From +-- @param #string Event +-- @param #string To +-- @param #number XStart The start position on the X-axis in meters for the first group. +-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. +-- @param #number YStart The start position on the Y-axis in meters for the first group. +-- @return #FORMATION +function FORMATION:onafterFormationTrail( FollowGroupSet, From , Event , To, XStart, XSpace, YStart ) + + self:onafterFormationLine(FollowGroupSet,From,Event,To,XStart,XSpace,YStart,0,0,0, self.Formation.Trail ) + + return self +end + + +--- FormationStack Handler OnAfter for FORMATION +-- @param #FORMATION self +-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. +-- @param #string From +-- @param #string Event +-- @param #string To +-- @param #number XStart The start position on the X-axis in meters for the first group. +-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. +-- @param #number YStart The start position on the Y-axis in meters for the first group. +-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. +-- @return #FORMATION +function FORMATION:onafterFormationStack( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace ) + + self:onafterFormationLine(FollowGroupSet,From,Event,To,XStart,XSpace,YStart,YSpace,0,0, self.Formation.Stack ) + + return self +end + +--- FormationLeftLine Handler OnAfter for FORMATION +-- @param #FORMATION self +-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. +-- @param #string From +-- @param #string Event +-- @param #string To +-- @param #number XStart The start position on the X-axis in meters for the first group. +-- @param #number YStart The start position on the Y-axis in meters for the first group. +-- @param #number ZStart The start position on the Z-axis in meters for the first group. +-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. +-- @return #FORMATION +function FORMATION:onafterFormationLeftLine( FollowGroupSet, From , Event , To, XStart, YStart, ZStart, ZSpace ) + + self:onafterFormationLine(FollowGroupSet,From,Event,To,XStart,0,YStart,0,-ZStart,-ZSpace, self.Formation.LeftLine ) + + return self +end + +--- FormationRightLine Handler OnAfter for FORMATION +-- @param #FORMATION self +-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. +-- @param #string From +-- @param #string Event +-- @param #string To +-- @param #number XStart The start position on the X-axis in meters for the first group. +-- @param #number YStart The start position on the Y-axis in meters for the first group. +-- @param #number ZStart The start position on the Z-axis in meters for the first group. +-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. +-- @return #FORMATION +function FORMATION:onafterFormationRightLine( FollowGroupSet, From , Event , To, XStart, YStart, ZStart, ZSpace ) + + self:onafterFormationLine(FollowGroupSet,From,Event,To,XStart,0,YStart,0,ZStart,ZSpace,self.Formation.RightLine) + + return self +end + +--- FormationLeftWing Handler OnAfter for FORMATION +-- @param #FORMATION self +-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. +-- @param #string From +-- @param #string Event +-- @param #string To +-- @param #number XStart The start position on the X-axis in meters for the first group. +-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. +-- @param #number YStart The start position on the Y-axis in meters for the first group. +-- @param #number ZStart The start position on the Z-axis in meters for the first group. +-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. +function FORMATION:onafterFormationLeftWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, ZStart, ZSpace ) + + self:onafterFormationLine(FollowGroupSet,From,Event,To,XStart,XSpace,YStart,0,-ZStart,-ZSpace,self.Formation.LeftWing) + + return self +end + +--- FormationRightWing Handler OnAfter for FORMATION +-- @function [parent=#FORMATION] OnAfterFormationRightWing +-- @param #FORMATION self +-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. +-- @param #string From +-- @param #string Event +-- @param #string To +-- @param #number XStart The start position on the X-axis in meters for the first group. +-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. +-- @param #number YStart The start position on the Y-axis in meters for the first group. +-- @param #number ZStart The start position on the Z-axis in meters for the first group. +-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. +function FORMATION:onafterFormationRightWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, ZStart, ZSpace ) + + self:onafterFormationLine(FollowGroupSet,From,Event,To,XStart,XSpace,YStart,0,ZStart,ZSpace,self.Formation.RightWing) + + return self +end + +--- FormationCenterWing Handler OnAfter for FORMATION +-- @param #FORMATION self +-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit. +-- @param #string From +-- @param #string Event +-- @param #string To +-- @param #number XStart The start position on the X-axis in meters for the first group. +-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. +-- @param #number YStart The start position on the Y-axis in meters for the first group. +-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. +-- @param #number ZStart The start position on the Z-axis in meters for the first group. +-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. +function FORMATION:onafterFormationCenterWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) + + local FollowSet = FollowGroupSet:GetSet() + + local i = 0 + + for FollowID, FollowGroup in pairs( FollowSet ) do + + local PointVec3 = COORDINATE:New() + + local Side = ( i % 2 == 0 ) and 1 or -1 + local Row = i / 2 + 1 + + PointVec3:SetX( XStart + Row * XSpace ) + PointVec3:SetY( YStart ) + PointVec3:SetZ( Side * ( ZStart + i * ZSpace ) ) + + local Vec3 = PointVec3:GetVec3() + FollowGroup:SetState( self, "FormationVec3", Vec3 ) + i = i + 1 + FollowGroup:SetState( FollowGroup, "Formation", self.Formation.Vic ) + end + + return self +end + +--- FormationVic Handle for FORMATION +-- @param #FORMATION self +-- @param #string From +-- @param #string Event +-- @param #string To +-- @param #number XStart The start position on the X-axis in meters for the first group. +-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. +-- @param #number YStart The start position on the Y-axis in meters for the first group. +-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. +-- @param #number ZStart The start position on the Z-axis in meters for the first group. +-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. +-- @return #FORMATION +function FORMATION:onafterFormationVic( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) + + self:onafterFormationCenterWing(FollowGroupSet,From,Event,To,XStart,XSpace,YStart,YSpace,ZStart,ZSpace) + + return self +end + +--- FormationBox Handler OnAfter for FORMATION +-- @param #FORMATION self +-- @param #string From +-- @param #string Event +-- @param #string To +-- @param #number XStart The start position on the X-axis in meters for the first group. +-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group. +-- @param #number YStart The start position on the Y-axis in meters for the first group. +-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group. +-- @param #number ZStart The start position on the Z-axis in meters for the first group. +-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group. +-- @param #number ZLevels The amount of levels on the Z-axis. +-- @return #FORMATION +function FORMATION:onafterFormationBox( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace, ZLevels ) + + local FollowSet = FollowGroupSet:GetSet() + + local i = 0 + + for FollowID, FollowGroup in pairs( FollowSet ) do + + local PointVec3 = COORDINATE:New() + + local ZIndex = i % ZLevels + local XIndex = math.floor( i / ZLevels ) + local YIndex = math.floor( i / ZLevels ) + + PointVec3:SetX( XStart + XIndex * XSpace ) + PointVec3:SetY( YStart + YIndex * YSpace ) + PointVec3:SetZ( -ZStart - (ZSpace * ZLevels / 2 ) + ZSpace * ZIndex ) + + local Vec3 = PointVec3:GetVec3() + FollowGroup:SetState( self, "FormationVec3", Vec3 ) + i = i + 1 + FollowGroup:SetState( FollowGroup, "Formation", self.Formation.Box ) + end + + return self +end + +--- Use the method @{FORMATION#FORMATION.SetFlightRandomization}() to make the air units in your formation randomize their flight a bit while in formation. +-- @param #FORMATION self +-- @param #number FlightRandomization The formation flying errors that pilots can make while in formation. Is a range set in meters. +-- @return #FORMATION +function FORMATION:SetFlightRandomization( FlightRandomization ) + self.FlightRandomization = FlightRandomization + return self +end + +--- Stop function. Formation will not be updated any more. +-- @param #FORMATION self +-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups. +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To The to state. +function FORMATION:onafterStop(FollowGroupSet, From, Event, To) + self:E("Stopping formation.") +end + +--- Follow event fuction. Check if coming from state "stopped". If so the transition is rejected. +-- @param #FORMATION self +-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups. +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To The to state. +function FORMATION:onbeforeFollow( FollowGroupSet, From, Event, To ) + if From=="Stopped" then + return false -- Deny transition. + end + return true +end + +--- Enter following state. +-- @param #FORMATION self +-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups. +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To The to state. +function FORMATION:onenterFollowing( FollowGroupSet ) + + if self.FollowUnit:IsAlive() then + + local ClientUnit = self.FollowUnit + + local CT1, CT2, CV1, CV2 + CT1 = ClientUnit:GetState( self, "CT1" ) + + local CuVec3=ClientUnit:GetVec3() + + if CT1 == nil or CT1 == 0 then + ClientUnit:SetState( self, "CV1", CuVec3) + ClientUnit:SetState( self, "CT1", timer.getTime() ) + else + CT1 = ClientUnit:GetState( self, "CT1" ) + CT2 = timer.getTime() + CV1 = ClientUnit:GetState( self, "CV1" ) + CV2 = CuVec3 + + ClientUnit:SetState( self, "CT1", CT2 ) + ClientUnit:SetState( self, "CV1", CV2 ) + end + + --FollowGroupSet:ForEachGroupAlive( bla, self, ClientUnit, CT1, CV1, CT2, CV2) + + for _,_group in pairs(FollowGroupSet:GetSet()) do + local group=_group --Wrapper.Group#GROUP + if group and group:IsAlive() then + self:FollowMe(group, ClientUnit, CT1, CV1, CT2, CV2) + end + end + + self:__Follow( -self.dtFollow ) + end + +end + +--- Follow me. +-- @param #FORMATION self +-- @param Wrapper.Group#GROUP FollowGroup Follow group. +-- @param Wrapper.Unit#UNIT ClientUnit Client Unit. +-- @param DCS#Time CT1 Time +-- @param DCS#Vec3 CV1 Vec3 +-- @param DCS#Time CT2 Time +-- @param DCS#Vec3 CV2 Vec3 +function FORMATION:FollowMe(FollowGroup, ClientUnit, CT1, CV1, CT2, CV2) + + if not self:Is("Stopped") then + + self:T({Mode=FollowGroup:GetState( FollowGroup, "Mode" )}) + + FollowGroup:OptionROTEvadeFire() + FollowGroup:OptionROEReturnFire() + + local GroupUnit = FollowGroup:GetUnit( 1 ) + + local GuVec3=GroupUnit:GetVec3() + + local FollowFormation = FollowGroup:GetState( self, "FormationVec3" ) + + if FollowFormation then + local FollowDistance = FollowFormation.x + + local GT1 = GroupUnit:GetState( self, "GT1" ) + + if CT1 == nil or CT1 == 0 or GT1 == nil or GT1 == 0 then + GroupUnit:SetState( self, "GV1", GuVec3) + GroupUnit:SetState( self, "GT1", timer.getTime() ) + else + local CD = ( ( CV2.x - CV1.x )^2 + ( CV2.y - CV1.y )^2 + ( CV2.z - CV1.z )^2 ) ^ 0.5 + local CT = CT2 - CT1 + + local CS = ( 3600 / CT ) * ( CD / 1000 ) / 3.6 + + local CDv = { x = CV2.x - CV1.x, y = CV2.y - CV1.y, z = CV2.z - CV1.z } + local Ca = math.atan2( CDv.x, CDv.z ) + + local GT1 = GroupUnit:GetState( self, "GT1" ) + local GT2 = timer.getTime() + + local GV1 = GroupUnit:GetState( self, "GV1" ) + local GV2 = GuVec3 + + GV2.x=GV2.x+math.random( -self.FlightRandomization / 2, self.FlightRandomization / 2 ) + GV2.y=GV2.y+math.random( -self.FlightRandomization / 2, self.FlightRandomization / 2 ) + GV2.z=GV2.z+math.random( -self.FlightRandomization / 2, self.FlightRandomization / 2 ) + + GroupUnit:SetState( self, "GT1", GT2 ) + GroupUnit:SetState( self, "GV1", GV2 ) + + local GD = ( ( GV2.x - GV1.x )^2 + ( GV2.y - GV1.y )^2 + ( GV2.z - GV1.z )^2 ) ^ 0.5 + local GT = GT2 - GT1 + + -- Calculate the distance + local GDv = { x = GV2.x - CV1.x, y = GV2.y - CV1.y, z = GV2.z - CV1.z } + local Alpha_T = math.atan2( GDv.x, GDv.z ) - math.atan2( CDv.x, CDv.z ) + local Alpha_R = ( Alpha_T < 0 ) and Alpha_T + 2 * math.pi or Alpha_T + local Position = math.cos( Alpha_R ) + local GD = ( ( GDv.x )^2 + ( GDv.z )^2 ) ^ 0.5 + local Distance = GD * Position + - CS * 0.5 + + -- Calculate the group direction vector + local GV = { x = GV2.x - CV2.x, y = GV2.y - CV2.y, z = GV2.z - CV2.z } + + -- Calculate GH2, GH2 with the same height as CV2. + local GH2 = { x = GV2.x, y = CV2.y + FollowFormation.y, z = GV2.z } + + -- Calculate the angle of GV to the orthonormal plane + local alpha = math.atan2( GV.x, GV.z ) + + local GVx = FollowFormation.z * math.cos( Ca ) + FollowFormation.x * math.sin( Ca ) + local GVz = FollowFormation.x * math.cos( Ca ) - FollowFormation.z * math.sin( Ca ) + + -- Now we calculate the intersecting vector between the circle around CV2 with radius FollowDistance and GH2. + -- From the GeoGebra model: CVI = (x(CV2) + FollowDistance cos(alpha), y(GH2) + FollowDistance sin(alpha), z(CV2)) + local Inclination = ( Distance + FollowFormation.x ) / 10 + if Inclination < -30 then + Inclination = - 30 + end + + local CVI = { + x = CV2.x + CS * 10 * math.sin(Ca), + y = GH2.y + Inclination, -- + FollowFormation.y, + z = CV2.z + CS * 10 * math.cos(Ca), + } + + -- Calculate the direction vector DV of the escort group. We use CVI as the base and CV2 as the direction. + local DV = { x = CV2.x - CVI.x, y = CV2.y - CVI.y, z = CV2.z - CVI.z } + + -- We now calculate the unary direction vector DVu, so that we can multiply DVu with the speed, which is expressed in meters / s. + -- We need to calculate this vector to predict the point the escort group needs to fly to according its speed. + -- The distance of the destination point should be far enough not to have the aircraft starting to swipe left to right... + local DVu = { x = DV.x / FollowDistance, y = DV.y, z = DV.z / FollowDistance } + + -- Now we can calculate the group destination vector GDV. + local GDV = { x = CVI.x, y = CVI.y, z = CVI.z } + + local ADDx = FollowFormation.x * math.cos(alpha) - FollowFormation.z * math.sin(alpha) + local ADDz = FollowFormation.z * math.cos(alpha) + FollowFormation.x * math.sin(alpha) + + local GDV_Formation = { + x = GDV.x - GVx, + y = GDV.y, + z = GDV.z - GVz + } + + -- Debug smoke. + if self.SmokeDirectionVector == true then + trigger.action.smoke( GDV, trigger.smokeColor.Green ) + trigger.action.smoke( GDV_Formation, trigger.smokeColor.White ) + end + + local Time = 120 + + local Speed = - ( Distance + FollowFormation.x ) / Time + + if Distance > -10000 then + Speed = - ( Distance + FollowFormation.x ) / 60 + end + + if Distance > -2500 then + Speed = - ( Distance + FollowFormation.x ) / 20 + end + + local GS = Speed + CS + + --self:F( { Distance = Distance, Speed = Speed, CS = CS, GS = GS } ) + + -- Now route the escort to the desired point with the desired speed. + FollowGroup:RouteToVec3( GDV_Formation, GS ) -- DCS models speed in Mps (Miles per second) + + end + end + end +end diff --git a/Moose Development/Moose/Functional/Scoring.lua b/Moose Development/Moose/Functional/Scoring.lua index d9427d279..6ddd370c4 100644 --- a/Moose Development/Moose/Functional/Scoring.lua +++ b/Moose Development/Moose/Functional/Scoring.lua @@ -90,7 +90,8 @@ -- @image Scoring.JPG --- @type SCORING --- @field Players A collection of the current players that have joined the game. +-- @field #table Players A collection of the current players that have joined the game. +-- @field Core.Set#SET_SCENERY ScoringScenery -- @extends Core.Base#BASE --- SCORING class @@ -229,7 +230,8 @@ SCORING = { ClassID = 0, Players = {}, AutoSave = true, - version = "1.18.4" + version = "1.18.4", + ScoringScenery = nil, -- Core.Set#SET_SCENERY } local _SCORINGCoalition = { @@ -325,6 +327,8 @@ function SCORING:New( GameName, SavePath, AutoSave ) self:OpenCSV( GameName ) end + self:I("SCORING "..tostring(GameName).." started! v"..self.version) + return self end @@ -377,7 +381,7 @@ function SCORING:AddUnitScore( ScoreUnit, Score ) return self end ---- Removes a @{Wrapper.Unit} for additional scoring when the @{Wrapper.Unit} is destroyed. +--- Removes a @{Wrapper.Unit} for scoring when the @{Wrapper.Unit} is destroyed. -- @param #SCORING self -- @param Wrapper.Unit#UNIT ScoreUnit The @{Wrapper.Unit} for which the Score needs to be given. -- @return #SCORING @@ -394,10 +398,26 @@ end -- Note that if there was already a @{Wrapper.Static} declared within the scoring with the same name, -- then the old @{Wrapper.Static} will be replaced with the new @{Wrapper.Static}. -- @param #SCORING self --- @param Wrapper.Static#UNIT ScoreStatic The @{Wrapper.Static} for which the Score needs to be given. +-- @param Wrapper.Static#STATIC ScoreStatic The @{Wrapper.Static} for which the Score needs to be given. -- @param #number Score The Score value. -- @return #SCORING function SCORING:AddStaticScore( ScoreStatic, Score ) + return self:AddScoreStatic( ScoreStatic, Score ) +end + +--- Add a @{Wrapper.Static} for additional scoring when the @{Wrapper.Static} is destroyed. +-- Note that if there was already a @{Wrapper.Static} declared within the scoring with the same name, +-- then the old @{Wrapper.Static} will be replaced with the new @{Wrapper.Static}. +-- @param #SCORING self +-- @param Wrapper.Static#STATIC ScoreStatic The @{Wrapper.Static} for which the Score needs to be given. +-- @param #number Score The Score value. +-- @return #SCORING +function SCORING:AddScoreStatic( ScoreStatic, Score ) + + if ScoreStatic == nil then + BASE:E("SCORING.AddStaticScore: Parameter ScoreStatic is nil!") + return self + end local StaticName = ScoreStatic:GetName() @@ -406,7 +426,61 @@ function SCORING:AddStaticScore( ScoreStatic, Score ) return self end ---- Removes a @{Wrapper.Static} for additional scoring when the @{Wrapper.Static} is destroyed. +--- Add a @{Wrapper.Scenery} for additional scoring when the @{Wrapper.Scenery} is destroyed. +-- @param #SCORING self +-- @param Wrapper.Scenery#SCENERY ScoreScenery The @{Wrapper.Scenery} for which the Score needs to be given. +-- @param #number Score The Score value. +-- @return #SCORING +function SCORING:AddScoreScenery( ScoreScenery, Score ) + + if ScoreScenery == nil then + self:E("SCORING.ScoreScenery: Parameter ScoreScenery is nil!") + return self + end + + if not self.ScoringScenery then + self.ScoringScenery = SET_SCENERY:New() -- Core.Set#SET_SCENERY + end + + local StaticName = ScoreScenery:GetName() + self:T("Scenery name = ".. StaticName) + + self.ScoringScenery:AddScenery(ScoreScenery) + + return self +end + +--- Removes a @{Wrapper.Scenery} for scoring when the @{Wrapper.Scenery} is destroyed. +-- @param #SCORING self +-- @param Wrapper.Scenery#SCENERY ScoreStatic The @{Wrapper.Scenery} for which the Score needs to be given. +-- @return #SCORING +function SCORING:RemoveSceneryScore( ScoreScenery ) + + local StaticName = ScoreScenery:GetName() + + self.ScoringObjects[StaticName] = nil + + return self +end + +--- Specify a special additional score for a @{Core.Set#SET_SCENERY}. +-- @param #SCORING self +-- @param Core.Set#SET_SCENERY Set The @{Core.Set#SET_SCENERY} for which each @{Wrapper.Scenery} in the SET a Score is given. +-- @param #number Score The Score value. +-- @return #SCORING +function SCORING:AddScoreSetScenery(Set, Score) + local set = Set.Set + + for _,_static in pairs (set) do + if _static ~= nil then + self:AddScoreScenery(_static,Score) + end + end + + return self +end + +--- Removes a @{Wrapper.Static} for scoring when the @{Wrapper.Static} is destroyed. -- @param #SCORING self -- @param Wrapper.Static#UNIT ScoreStatic The @{Wrapper.Static} for which the Score needs to be given. -- @return #SCORING @@ -461,6 +535,31 @@ function SCORING:AddScoreSetGroup(Set, Score) return self end +--- Specify a special additional score for a @{Core.Set#SET_STATIC}. +-- @param #SCORING self +-- @param Core.Set#SET_STATIC Set The @{Core.Set#SET_STATIC} for which each @{Wrapper.Static} in the SET a Score is given. +-- @param #number Score The Score value. +-- @return #SCORING +function SCORING:AddScoreSetStatic(Set, Score) + local set = Set:GetSetObjects() + + for _,_static in pairs (set) do + if _static and _static:IsAlive() then + self:AddStaticScore(_static,Score) + end + end + + local function AddScore(static) + self:AddStaticScore(static,Score) + end + + function Set:OnAfterAdded(From,Event,To,ObjectName,Object) + AddScore(Object) + end + + return self +end + --- Add a @{Core.Zone} to define additional scoring when any object is destroyed in that zone. -- Note that if a @{Core.Zone} with the same name is already within the scoring added, the @{Core.Zone} (type) and Score will be replaced! -- This allows for a dynamic destruction zone evolution within your mission. @@ -480,7 +579,24 @@ function SCORING:AddZoneScore( ScoreZone, Score ) return self end ---- Remove a @{Core.Zone} for additional scoring. +--- Add a @{Core.Set#SET_ZONE} to define additional scoring when any object is destroyed in that zone. +-- Note that if a @{Core.Zone} with the same name is already within the scoring added, the @{Core.Zone} (type) and Score will be replaced! +-- This allows for a dynamic destruction zone evolution within your mission. +-- @param #SCORING self +-- @param Core.Set#SET_ZONE ScoreZoneSet The @{Core.Set#SET_ZONE} which defines the destruction score perimeters. +-- Note that a zone can be a polygon or a moving zone. +-- @param #number Score The Score value. +-- @return #SCORING +function SCORING:AddZoneScoreSet( ScoreZoneSet, Score ) + + for _,_zone in pairs(ScoreZoneSet.Set or {}) do + self:AddZoneScore(_zone,Score) + end + + return self +end + +--- Remove a @{Core.Zone} for scoring. -- The scoring will search if any @{Core.Zone} is added with the given name, and will remove that zone from the scoring. -- This allows for a dynamic destruction zone evolution within your mission. -- @param #SCORING self @@ -958,7 +1074,7 @@ end -- @param #SCORING self -- @param Core.Event#EVENTDATA Event function SCORING:_EventOnHit( Event ) - self:F( { Event } ) + --self:F( { Event } ) local InitUnit = nil local InitUNIT = nil @@ -988,6 +1104,7 @@ function SCORING:_EventOnHit( Event ) local TargetUnitCategory = nil local TargetUnitType = nil local TargetIsScenery = false + local TargetSceneryObject = nil if Event.IniDCSUnit then @@ -1009,7 +1126,7 @@ function SCORING:_EventOnHit( Event ) InitUnitCategory = _SCORINGCategory[InitCategory] InitUnitType = InitType - self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType, InitUnitCoalition, InitUnitCategory, InitUnitType } ) + --self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType, InitUnitCoalition, InitUnitCategory, InitUnitType } ) end if Event.TgtDCSUnit then @@ -1027,18 +1144,23 @@ function SCORING:_EventOnHit( Event ) -- TargetCategory = TargetUnit:getDesc().category TargetCategory = Event.TgtCategory TargetType = Event.TgtTypeName + -- Scenery hit - if (not TargetCategory) and TargetUNIT ~= nil and TargetUnit:IsInstanceOf("SCENERY") then + if TargetUNIT ~= nil and TargetUNIT:IsInstanceOf("SCENERY") then TargetCategory = Unit.Category.STRUCTURE TargetIsScenery = true + TargetType = "Scenery" + TargetSceneryObject = TargetUNIT + self:T("***** Target is Scenery and TargetUNIT is SCENERY object!") + UTILS.PrintTableToLog(TargetSceneryObject) end TargetUnitCoalition = _SCORINGCoalition[TargetCoalition] TargetUnitCategory = _SCORINGCategory[TargetCategory] TargetUnitType = TargetType - self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } ) + --self:T( { TargetUnitName=TargetUnitName, TargetGroupName=TargetGroupName, TargetPlayerName=TargetPlayerName, TargetCoalition=TargetCoalition, TargetCategory=TargetCategory, TargetType=TargetType, TargetUnitCoalition=TargetUnitCoalition, TargetUnitCategory=TargetUnitCategory, TargetUnitType=TargetUnitType } ) end if InitPlayerName ~= nil then -- It is a player that is hitting something @@ -1051,7 +1173,7 @@ function SCORING:_EventOnHit( Event ) self:T( "Hitting Something" ) -- What is he hitting? - if TargetCategory then + if (TargetCategory ~=nil) and (TargetIsScenery == false) then -- A target got hit, score it. -- Player contains the score data from self.Players[InitPlayerName] @@ -1071,7 +1193,7 @@ function SCORING:_EventOnHit( Event ) PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0 PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT -- After an instant kill we can't compute the threat level anymore. To fix this we compute at OnEventBirth - if PlayerHit.UNIT.ThreatType == nil then + if PlayerHit.UNIT and PlayerHit.UNIT.ThreatType == nil then PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel() -- if this fails for some reason, set a good default value if PlayerHit.ThreatType == nil or PlayerHit.ThreatType == "" then @@ -1157,21 +1279,21 @@ function SCORING:_EventOnHit( Event ) -- It is a weapon initiated by a player, that is hitting something -- This seems to occur only with scenery and static objects. - if Event.WeaponPlayerName ~= nil then - self:_AddPlayerFromUnit( Event.WeaponUNIT ) - if self.Players[Event.WeaponPlayerName] then -- This should normally not happen, but i'll test it anyway. - if TargetPlayerName ~= nil then -- It is a player hitting another player ... - self:_AddPlayerFromUnit( TargetUNIT ) - end + if Event.WeaponPlayerName ~= nil or TargetIsScenery == true then + + local playername = Event.WeaponPlayerName or Event.IniPlayerName or "Ghost" + + --self:_AddPlayerFromUnit( Event.WeaponUNIT ) + if self.Players[playername] then -- This should normally not happen, but i'll test it anyway. - self:T( "Hitting Scenery" ) + self:T( "Hitting Scenery or Static" ) -- What is he hitting? - if TargetCategory then + if Event.TgtObjectCategory then -- A scenery or static got hit, score it. -- Player contains the score data from self.Players[WeaponPlayerName] - local Player = self.Players[Event.WeaponPlayerName] + local Player = self.Players[playername] -- Ensure there is a hit table per TargetCategory and TargetUnitName. Player.Hit[TargetCategory] = Player.Hit[TargetCategory] or {} @@ -1179,15 +1301,17 @@ function SCORING:_EventOnHit( Event ) -- PlayerHit contains the score counters and data per unit that was hit. local PlayerHit = Player.Hit[TargetCategory][TargetUnitName] - + + -- Init player scores PlayerHit.Score = PlayerHit.Score or 0 PlayerHit.Penalty = PlayerHit.Penalty or 0 PlayerHit.ScoreHit = PlayerHit.ScoreHit or 0 PlayerHit.PenaltyHit = PlayerHit.PenaltyHit or 0 PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0 PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT + -- After an instant kill we can't compute the threat level anymore. To fix this we compute at OnEventBirth - if PlayerHit.UNIT.ThreatType == nil then + if PlayerHit.UNIT and PlayerHit.UNIT.ThreatType == nil then PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel() -- if this fails for some reason, set a good default value if PlayerHit.ThreatType == nil then @@ -1195,8 +1319,8 @@ function SCORING:_EventOnHit( Event ) PlayerHit.ThreatType = "Unknown" end else - PlayerHit.ThreatLevel = PlayerHit.UNIT.ThreatLevel - PlayerHit.ThreatType = PlayerHit.UNIT.ThreatType + PlayerHit.ThreatLevel = PlayerHit.UNIT and PlayerHit.UNIT.ThreatLevel or 1 + PlayerHit.ThreatType = PlayerHit.UNIT and PlayerHit.UNIT.ThreatType or "Unknown" end -- Only grant hit scores if there was more than one second between the last hit. @@ -1204,50 +1328,68 @@ function SCORING:_EventOnHit( Event ) PlayerHit.TimeStamp = timer.getTime() local Score = 0 - - if InitCoalition then -- A coalition object was hit, probably a static. - if InitCoalition == TargetCoalition then - -- TODO: Penalty according scale - local Penalty = 10 - Player.Penalty = Player.Penalty + Penalty --* self.ScaleDestroyPenalty - PlayerHit.Penalty = PlayerHit.Penalty + Penalty --* self.ScaleDestroyPenalty - PlayerHit.PenaltyHit = PlayerHit.PenaltyHit + 1 * self.ScaleDestroyPenalty - - MESSAGE - :NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit friendly target " .. - TargetUnitCategory .. " ( " .. TargetType .. " ) " .. - "Penalty: -" .. Penalty .. " = " .. Player.Score - Player.Penalty, - MESSAGE.Type.Update - ) - :ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() ) - :ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() ) - self:ScoreCSV( Event.WeaponPlayerName, TargetPlayerName, "HIT_PENALTY", 1, -10, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) - else + + local TgtName = Event.TgtDCSUnit and Event.TgtDCSUnit.getName and Event.TgtDCSUnit:getName() or "Unknown" + + --if InitCoalition then -- A coalition object was hit, probably a static. + if TargetIsScenery == true and self.ScoringScenery:IsInSet(TargetSceneryObject) then Player.Score = Player.Score + self.ScoreIncrementOnHit PlayerHit.Score = PlayerHit.Score + self.ScoreIncrementOnHit PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1 - MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit enemy target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. + MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. playername .. "' hit scenery target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. "Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty, MESSAGE.Type.Update ) :ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() ) :ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() ) - self:ScoreCSV( Event.WeaponPlayerName, TargetPlayerName, "HIT_SCORE", 1, 1, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) - end - else -- A scenery object was hit. - MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit scenery object.", - MESSAGE.Type.Update ) - :ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() ) - :ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() ) + self:ScoreCSV( playername, TargetPlayerName, "HIT_SCORE", 1, 1, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + elseif TargetIsScenery == false and Event.TgtObjectCategory == Object.Category.STATIC and self.ScoringObjects[TgtName] then + Player.Score = Player.Score + self.ScoreIncrementOnHit + PlayerHit.Score = PlayerHit.Score + self.ScoreIncrementOnHit + PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1 + MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. playername .. "' hit static target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. + "Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty, + MESSAGE.Type.Update ) + :ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() ) + :ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() ) - self:ScoreCSV( Event.WeaponPlayerName, "", "HIT_SCORE", 1, 0, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, "", "Scenery", TargetUnitType ) - end + self:ScoreCSV( playername, TargetPlayerName, "HIT_SCORE", 1, 1, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + + else + self:E("Hit unregistered scenery or static object - NO target! ("..TgtName..")") + end + --end end end end + + -- Check if there are Zones where the destruction happened. + for ZoneName, ScoreZoneData in pairs( self.ScoringZones ) do + self:F( { ScoringZone = ScoreZoneData } ) + local hit=Event.TgtUnit + local ScoreZone = ScoreZoneData.ScoreZone -- Core.Zone#ZONE_BASE + local Score = ScoreZoneData.Score + if TargetUNIT and ScoreZone:IsVec2InZone( TargetUNIT:GetVec2() ) then + -- A scenery or static got hit, score it. + -- Player contains the score data from self.Players[WeaponPlayerName] + local PlayerName = Event.IniPlayerName or "Ghost" + local Player = self.Players[PlayerName] + + Player.Score = Player.Score + Score + Player.Score = Player.Score + self.ScoreIncrementOnHit + MESSAGE:NewType( self.DisplayMessagePrefix .. "hit in zone '" .. ScoreZone:GetName() .. "'." .. + "Player '" .. PlayerName .. "' receives an extra " .. Score .. " points! " .. "Total: " .. Player.Score - Player.Penalty, + MESSAGE.Type.Information ) + :ToAllIf( self:IfMessagesZone() and self:IfMessagesToAll() ) + :ToCoalitionIf( InitCoalition, self:IfMessagesZone() and self:IfMessagesToCoalition() ) + + self:ScoreCSV( PlayerName, "", "HIT_SCORE", 1, Score, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, "", "Zone", TargetUnitType ) + end + end end -end - + + end + --- Track DEAD or CRASH events for the scoring. -- @param #SCORING self -- @param Core.Event#EVENTDATA Event @@ -1305,7 +1447,7 @@ function SCORING:_EventOnDeadOrCrash( Event ) local Destroyed = false -- What is the player destroying? - if Player and Player.Hit and Player.Hit[TargetCategory] and Player.Hit[TargetCategory][TargetUnitName] and Player.Hit[TargetCategory][TargetUnitName].TimeStamp ~= 0 and (TargetUnit.BirthTime == nil or Player.Hit[TargetCategory][TargetUnitName].TimeStamp > TargetUnit.BirthTime) then -- Was there a hit for this unit for this player before registered??? + if Player and Player.Hit and Player.Hit[TargetCategory] and Player.Hit[TargetCategory][TargetUnitName] and Player.Hit[TargetCategory][TargetUnitName].TimeStamp ~= 0 and TargetUnit and (TargetUnit.BirthTime == nil or Player.Hit[TargetCategory][TargetUnitName].TimeStamp > TargetUnit.BirthTime) then -- Was there a hit for this unit for this player before registered??? local TargetThreatLevel = Player.Hit[TargetCategory][TargetUnitName].ThreatLevel local TargetThreatType = Player.Hit[TargetCategory][TargetUnitName].ThreatType diff --git a/Moose Development/Moose/Functional/Warehouse.lua b/Moose Development/Moose/Functional/Warehouse.lua index d5dbaec92..7e01df6bd 100644 --- a/Moose Development/Moose/Functional/Warehouse.lua +++ b/Moose Development/Moose/Functional/Warehouse.lua @@ -1132,7 +1132,7 @@ -- specify an "Assignment". This can be later used to identify the request and take the right actions. -- -- Once the request is processed, the @{#WAREHOUSE.OnAfterSelfRequest} function is called. This is where we hook in and postprocess the spawned assets. --- In particular, we use the @{AI.AI_Formation#AI_FORMATION} class to make some nice escorts for our carrier. +-- In particular, we use the @{Functional.Formation#FORMATION} class to make some nice escorts for our carrier. -- -- When the resue helo is spawned, we can check that this is the correct asset and make the helo go into formation with the carrier. -- Once the helo runs out of fuel, it will automatically return to the ship and land. For the warehouse, this means that the "cargo", i.e. the helicopter @@ -1175,7 +1175,7 @@ -- -- -- Define AI Formation object. -- -- Note that this has to be a global variable or the garbage collector will remove it for some reason! --- CarrierFormationLeft = AI_FORMATION:New(Mother, groupset, "Left Formation with Carrier", "Escort Carrier.") +-- CarrierFormationLeft = FORMATION:New(Mother, groupset, "Left Formation with Carrier") -- -- -- Formation parameters. -- CarrierFormationLeft:FormationLeftWing(200 ,50, 0, 0, 500, 50) @@ -1190,7 +1190,7 @@ -- -- -- Define AI Formation object. -- -- Note that this has to be a global variable or the garbage collector will remove it for some reason! --- CarrierFormationRight = AI_FORMATION:New(Mother, groupset, "Right Formation with Carrier", "Escort Carrier.") +-- CarrierFormationRight = FORMATION:New(Mother, groupset, "Right Formation with Carrier") -- -- -- Formation parameters. -- CarrierFormationRight:FormationRightWing(200 ,50, 0, 0, 500, 50) @@ -1208,7 +1208,7 @@ -- group:StartUncontrolled() -- -- -- Define AI Formation object. --- CarrierFormationHelo = AI_FORMATION:New(Mother, groupset, "Helo Formation with Carrier", "Fly Formation.") +-- CarrierFormationHelo = FORMATION:New(Mother, groupset, "Helo Formation with Carrier") -- -- -- Formation parameters. -- CarrierFormationHelo:FormationCenterWing(-150, 50, 20, 50, 100, 50) diff --git a/Moose Development/Moose/Modules.lua b/Moose Development/Moose/Modules.lua index 4a1bf82be..02f21633a 100644 --- a/Moose Development/Moose/Modules.lua +++ b/Moose Development/Moose/Modules.lua @@ -85,6 +85,7 @@ __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/ZoneGoalCargo.lua' __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Tiresias.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Stratego.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/ClientWatch.lua') +__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Formation.lua') __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/Airboss.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/RecoveryTanker.lua' ) diff --git a/Moose Development/Moose/Navigation/Beacons.lua b/Moose Development/Moose/Navigation/Beacons.lua index 00b5cb852..84ecf218d 100644 --- a/Moose Development/Moose/Navigation/Beacons.lua +++ b/Moose Development/Moose/Navigation/Beacons.lua @@ -18,7 +18,7 @@ -- -- === -- @module Navigation.Beacons --- @image NAVIGATION_Beacons.png +-- @image MOOSE.JPG ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -43,6 +43,7 @@ -- -- **Note** that try to avoid hard coding stuff in Moose since DCS is updated frequently and things change. Therefore, the main source of information is either a file `beacons.lua` that can be -- found in the installation directory of DCS for each map or a table that the user needs to provide. +-- **Note** your `MissionScripting` environment needs to be desanitized to read this data. `Package` als needs to be available. -- -- # Basic Setup -- diff --git a/Moose Development/Moose/Navigation/Point.lua b/Moose Development/Moose/Navigation/Point.lua index 963e8cd05..e02fb9945 100644 --- a/Moose Development/Moose/Navigation/Point.lua +++ b/Moose Development/Moose/Navigation/Point.lua @@ -17,7 +17,7 @@ -- -- === -- @module Navigation.Point --- @image NAVIGATION_Point.png +-- @image MOOSE.JPG ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Navigation/Radios.lua b/Moose Development/Moose/Navigation/Radios.lua index 531309fc2..4fe1dad72 100644 --- a/Moose Development/Moose/Navigation/Radios.lua +++ b/Moose Development/Moose/Navigation/Radios.lua @@ -18,7 +18,7 @@ -- -- === -- @module Navigation.Radios --- @image NAVIGATION_Radios.png +-- @image MOOSE.JPG ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -43,6 +43,7 @@ -- -- **Note** that try to avoid hard coding stuff in Moose since DCS is updated frequently and things change. Therefore, the main source of information is either a file `radio.lua` that can be -- found in the installation directory of DCS for each map or a table that the user needs to provide. +-- **Note** your `MissionScripting` environment needs to be desanitized to read this data. -- -- # Basic Setup -- diff --git a/Moose Development/Moose/Navigation/Towns.lua b/Moose Development/Moose/Navigation/Towns.lua index 5f8ef2619..3825854f9 100644 --- a/Moose Development/Moose/Navigation/Towns.lua +++ b/Moose Development/Moose/Navigation/Towns.lua @@ -18,7 +18,7 @@ -- -- === -- @module Navigation.Towns --- @image NAVIGATION_Towns.png +-- @image MOOSE.JPG ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -43,6 +43,7 @@ -- -- **Note** that try to avoid hard coding stuff in Moose since DCS is updated frequently and things change. Therefore, the main source of information is either a file `towns.lua` that can be -- found in the installation directory of DCS for each map or a table that the user needs to provide. +-- **Note** your `MissionScripting` environment needs to be desanitized to read this data. -- -- # Basic Setup -- diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index 5e83f1427..bc42633a6 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -45,7 +45,7 @@ -- **Supported Aircraft:** -- -- * [F/A-18C Hornet Lot 20](https://forums.eagle.ru/forumdisplay.php?f=557) (Player & AI) --- * [F-14A/B Tomcat](https://forums.eagle.ru/forumdisplay.php?f=395) (Player & AI) +-- * [F-14A/B/A Early Tomcat](https://forums.eagle.ru/forumdisplay.php?f=395) (Player & AI) -- * [A-4E Skyhawk Community Mod](https://forums.eagle.ru/showthread.php?t=224989) (Player & AI) -- * [AV-8B N/A Harrier](https://forums.eagle.ru/forumdisplay.php?f=555) (Player & AI) -- * [T-45C Goshawk](https://forum.dcs.world/topic/203816-vnao-t-45-goshawk/) (VNAO mod) (Player & AI) @@ -63,7 +63,7 @@ -- no other fixed wing aircraft (human or AI controlled) are supposed to land on these ships. Currently only Case I is supported. Case II/III take slightly different steps from the CVN carrier. -- However, if no offset is used for the holding radial this provides a very close representation of the V/STOL Case III, allowing for an approach to over the deck and a vertical landing. -- --- Heatblur's mighty F-14B Tomcat has been added (March 13th 2019) as well. Same goes for the A version. +-- Heatblur's mighty F-14A/B/A Early Tomcat has been added as well. -- -- The [DCS Supercarriers](https://www.digitalcombatsimulator.com/de/shop/modules/supercarrier/) are also supported. -- @@ -1276,6 +1276,7 @@ AIRBOSS = { -- @field #string A4EC A-4E Community mod. -- @field #string HORNET F/A-18C Lot 20 Hornet by Eagle Dynamics. -- @field #string F14A F-14A by Heatblur. +-- @field #string F14A_Early F-14A-135-GR-Early by Heatblur. -- @field #string F14B F-14B by Heatblur. -- @field #string F14A_AI F-14A Tomcat (AI). -- @field #string FA18C F/A-18C Hornet (AI). @@ -1294,6 +1295,7 @@ AIRBOSS.AircraftCarrier={ HORNET="FA-18C_hornet", A4EC="A-4E-C", F14A="F-14A-135-GR", + F14A_Early="F-14A-135-GR-Early", F14B="F-14B", F14A_AI="F-14A", FA18C="F/A-18C", @@ -5473,7 +5475,7 @@ function AIRBOSS:_GetAircraftAoA( playerData ) local goshawk = playerData.actype == AIRBOSS.AircraftCarrier.T45C local skyhawk = playerData.actype == AIRBOSS.AircraftCarrier.A4EC local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B - local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B + local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B or playerData.actype == AIRBOSS.AircraftCarrier.F14A_Early local corsair = playerData.actype == AIRBOSS.AircraftCarrier.CORSAIR or playerData.actype == AIRBOSS.AircraftCarrier.CORSAIR_CW -- Table with AoA values. @@ -5552,7 +5554,7 @@ function AIRBOSS:_AoAUnit2Deg( playerData, aoaunits ) local degrees = aoaunits -- Check aircraft type of player. - if playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then + if playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B or playerData.actype == AIRBOSS.AircraftCarrier.F14A_Early then ------------- -- F-14A/B -- @@ -5595,7 +5597,7 @@ function AIRBOSS:_AoADeg2Units( playerData, degrees ) local aoaunits = degrees -- Check aircraft type of player. - if playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then + if playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B or playerData.actype == AIRBOSS.AircraftCarrier.F14A_Early then ------------- -- F-14A/B -- @@ -11593,7 +11595,7 @@ function AIRBOSS:_AttitudeMonitor( playerData ) local unitClient = Unit.getByName(unit:GetName()) -- VNAO Edit - Added local hornet = playerData.actype == AIRBOSS.AircraftCarrier.HORNET -- VNAO Edit - Added - local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B -- VNAO Edit - Added + local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B or playerData.actype == AIRBOSS.AircraftCarrier.F14A_Early -- VNAO Edit - Added if hornet then -- VNAO Edit - Added local nozzlePosL = 0 -- VNAO Edit - Added @@ -11826,7 +11828,7 @@ function AIRBOSS:_NozzleArgumentLeft( unit ) -- VNAO Edit - Added else -- VNAO Edit - Added nozzlePosL = 0 -- VNAO Edit - Added end -- VNAO Edit - Added - elseif typeName == "F-14A-135-GR" or typeName == "F-14B" then -- VNAO Edit - Added + elseif typeName == "F-14A-135-GR" or typeName == "F-14B" or typeName == "F-14A-135-GR-Early" then -- VNAO Edit - Added nozzlePosL = unitClient:getDrawArgumentValue(434) -- VNAO Edit - Added end -- VNAO Edit - Added @@ -11851,7 +11853,7 @@ function AIRBOSS:_NozzleArgumentRight( unit ) -- VNAO Edit - Added else -- VNAO Edit - Added nozzlePosR = 0 -- VNAO Edit - Added end -- VNAO Edit - Added - elseif typeName == "F-14A-135-GR" or typeName == "F-14B" then -- VNAO Edit - Added + elseif typeName == "F-14A-135-GR" or typeName == "F-14B" or typeName == "F-14A-135-GR-Early" then -- VNAO Edit - Added nozzlePosR = unitClient:getDrawArgumentValue(433) -- VNAO Edit - Added end -- VNAO Edit - Added return nozzlePosR -- VNAO Edit - Added @@ -15066,7 +15068,7 @@ function AIRBOSS:_GetACNickname( actype ) nickname = "Hawkeye" elseif actype == AIRBOSS.AircraftCarrier.C2A then nickname = "Greyhound" - elseif actype == AIRBOSS.AircraftCarrier.F14A_AI or actype == AIRBOSS.AircraftCarrier.F14A or actype == AIRBOSS.AircraftCarrier.F14B then + elseif actype == AIRBOSS.AircraftCarrier.F14A_AI or actype == AIRBOSS.AircraftCarrier.F14A or actype == AIRBOSS.AircraftCarrier.F14B or actype == AIRBOSS.AircraftCarrier.F14A_Early then nickname = "Tomcat" elseif actype == AIRBOSS.AircraftCarrier.FA18C or actype == AIRBOSS.AircraftCarrier.HORNET then nickname = "Hornet" diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index cdad223f1..a3ac50a46 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -2037,7 +2037,7 @@ function AUFTRAG:NewRESCUEHELO(Carrier) -- Mission options: mission.missionTask=ENUMS.MissionTask.NOTHING - mission.missionFraction=0.5 + mission.missionFraction=0.9 mission.optionROE=ENUMS.ROE.WeaponHold mission.optionROT=ENUMS.ROT.NoReaction diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index c3a0e1680..1daa27e00 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -4308,7 +4308,27 @@ function OPSGROUP:_UpdateTask(Task, Mission) Mission=Mission or self:GetMissionByTaskID(self.taskcurrent) if Task.dcstask.id==AUFTRAG.SpecialTask.FORMATION then - + + if Mission.type == AUFTRAG.Type.RESCUEHELO then + self:T("**********") + self:T("** RESCUEHELO USED") + self:T("**********") + local param=Task.dcstask.params + local followUnit=UNIT:FindByName(param.unitname) + local helogroupname = self:GetGroup():GetName() + Task.formation = RESCUEHELO:New(followUnit,helogroupname) + Task.formation:SetRespawnOnOff(false) + Task.formation.respawninair=false + Task.formation:SetTakeoffCold() + Task.formation:SetHomeBase(followUnit) + Task.formation.helo = self:GetGroup() + -- Start formation FSM. + Task.formation:Start() + if self:IsFlightgroup() then + self:SetDespawnAfterLanding() + end + else + -- Set of group(s) to follow Mother. local followSet=SET_GROUP:New():AddGroup(self.group) @@ -4317,7 +4337,7 @@ function OPSGROUP:_UpdateTask(Task, Mission) local followUnit=UNIT:FindByName(param.unitname) -- Define AI Formation object. - Task.formation=AI_FORMATION:New(followUnit, followSet, AUFTRAG.SpecialTask.FORMATION, "Follow X at given parameters.") + Task.formation=FORMATION:New(followUnit, followSet, AUFTRAG.SpecialTask.FORMATION) -- Formation parameters. Task.formation:FormationCenterWing(-param.offsetX, 50, math.abs(param.altitude), 50, param.offsetZ, 50) @@ -4326,11 +4346,13 @@ function OPSGROUP:_UpdateTask(Task, Mission) Task.formation:SetFollowTimeInterval(param.dtFollow) -- Formation mode. - Task.formation:SetFlightModeFormation(self.group) + --Task.formation:SetFlightModeFormation(self.group) -- Start formation FSM. Task.formation:Start() - + + end + elseif Task.dcstask.id==AUFTRAG.SpecialTask.PATROLZONE then --- @@ -8026,11 +8048,16 @@ function OPSGROUP:onafterDead(From, Event, To) -- Get asset. local asset=self.legion:GetAssetByName(self.groupname) + if asset then + -- Get request. local request=self.legion:GetRequestByID(asset.rid) -- Trigger asset dead event. self.legion:AssetDead(asset, request) + + end + end -- Stop in 5 sec to give possible respawn attempts a chance. @@ -12723,7 +12750,7 @@ end -- @return #OPSGROUP self function OPSGROUP:SetDefaultCallsign(CallsignName, CallsignNumber) - self:T(self.lid..string.format("Setting Default callsing %s-%s", tostring(CallsignName), tostring(CallsignNumber))) + self:T(self.lid..string.format("Setting Default callsign %s-%s", tostring(CallsignName), tostring(CallsignNumber))) self.callsignDefault={} --#OPSGROUP.Callsign self.callsignDefault.NumberSquad=CallsignName @@ -13482,8 +13509,8 @@ function OPSGROUP:GetAmmoUnit(unit, display) if ammotable then local weapons=#ammotable - --self:I(ammotable) - --UTILS.PrintTableToLog(ammotable) + --self:I(ammotable) + --UTILS.PrintTableToLog(ammotable) -- Loop over all weapons. for w=1,weapons do @@ -13491,9 +13518,9 @@ function OPSGROUP:GetAmmoUnit(unit, display) -- Number of current weapon. local Nammo=ammotable[w]["count"] - -- Range in meters. Seems only to exist for missiles (not shells). - local rmin=ammotable[w]["desc"]["rangeMin"] or 0 - local rmax=ammotable[w]["desc"]["rangeMaxAltMin"] or 0 + -- Range in meters. Seems only to exist for missiles (not shells). + local rmin=ammotable[w]["desc"]["rangeMin"] or 0 + local rmax=ammotable[w]["desc"]["rangeMaxAltMin"] or 0 -- Type name of current weapon. local Tammo=ammotable[w]["desc"]["typeName"] @@ -13515,7 +13542,7 @@ function OPSGROUP:GetAmmoUnit(unit, display) -- Add up all shells. nshells=nshells+Nammo - + -- Add small and large caliber shells for guns and cannons if ammotable[w]["desc"]["warhead"] and ammotable[w]["desc"]["warhead"]["caliber"] then local caliber=ammotable[w]["desc"]["warhead"]["caliber"] diff --git a/Moose Development/Moose/Ops/RescueHelo.lua b/Moose Development/Moose/Ops/RescueHelo.lua index 70a1e95f4..62b54cfa8 100644 --- a/Moose Development/Moose/Ops/RescueHelo.lua +++ b/Moose Development/Moose/Ops/RescueHelo.lua @@ -20,7 +20,6 @@ -- === -- -- ### Author: **funkyfranky** --- ### Contributions: Flightcontrol (@{AI.AI_Formation} class being used here) -- -- @module Ops.RescueHelo -- @image Ops_RescueHelo.png @@ -37,7 +36,7 @@ -- @field #number takeoff Takeoff type. -- @field Wrapper.Airbase#AIRBASE airbase The airbase object acting as home base of the helo. -- @field Core.Set#SET_GROUP followset Follow group set. --- @field AI.AI_Formation#AI_FORMATION formation AI_FORMATION object. +-- @field Functional.Formation#FORMATION formation FORMATION object. -- @field #number lowfuel Low fuel threshold of helo in percent. -- @field #number altitude Altitude of helo in meters. -- @field #number offsetX Offset in meters to carrier in longitudinal direction. @@ -235,7 +234,7 @@ _RESCUEHELOID=0 --- Class version. -- @field #string version -RESCUEHELO.version="1.1.0" +RESCUEHELO.version="1.2.0" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -248,6 +247,7 @@ RESCUEHELO.version="1.1.0" -- DONE: Possibility to add already present/spawned aircraft, e.g. for warehouse. -- DONE: Add rescue event when aircraft crashes. -- DONE: Make offset input parameter. +-- DONE: Make useable for AUFTRAG ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Constructor @@ -337,6 +337,9 @@ function RESCUEHELO:New(carrierunit, helogroupname) self:AddTransition("*", "Status", "*") self:AddTransition("*", "Stop", "Stopped") + + self:I(self.lid.."Started.") + --- Triggers the FSM event "Start" that starts the rescue helo. Initializes parameters and starts event handlers. -- @function [parent=#RESCUEHELO] Start @@ -871,15 +874,25 @@ function RESCUEHELO:onafterStart(From, Event, To) -- Delay before formation is started. local delay=120 - - -- Spawn helo. We need to introduce an alias in case this class is used twice. This would confuse the spawn routine. - local Spawn=SPAWN:NewWithAlias(self.helogroupname, self.alias) - -- Set modex for spawn. - Spawn:InitModex(self.modex) - + local UsesAliveGroup=false + local Spawn = GROUP:FindByName(self.helogroupname) + if Spawn and Spawn:IsAlive() then + self.helo=Spawn + UsesAliveGroup = true + delay = 1 + else + + -- Spawn helo. We need to introduce an alias in case this class is used twice. This would confuse the spawn routine. + local Spawn=SPAWN:NewWithAlias(self.helogroupname, self.alias) + + -- Set modex for spawn. + Spawn:InitModex(self.modex) + + end + -- Spawn in air or at airbase. - if self.takeoff==SPAWN.Takeoff.Air then + if UsesAliveGroup==false and self.takeoff==SPAWN.Takeoff.Air then -- Carrier heading local hdg=self.carrier:GetHeading() @@ -899,7 +912,7 @@ function RESCUEHELO:onafterStart(From, Event, To) -- Start formation in 1 seconds delay=1 - else + elseif UsesAliveGroup==false and self.uncontrolledac then -- Check if an uncontrolled helo group was requested. if self.uncontrolledac then @@ -919,9 +932,9 @@ function RESCUEHELO:onafterStart(From, Event, To) -- No group of that name! self:E(string.format("ERROR: No uncontrolled (alive) rescue helo group with name %s could be found!", self.helogroupname)) return - end + end - else + elseif UsesAliveGroup==false then -- Spawn at airbase. self.helo=Spawn:SpawnAtAirbase(self.airbase, self.takeoff, nil, AIRBASE.TerminalType.HelicopterUsable) @@ -947,17 +960,13 @@ function RESCUEHELO:onafterStart(From, Event, To) self.HeloFuel0=self.helo:GetFuel() -- Define AI Formation object. - self.formation=AI_FORMATION:New(self.carrier, self.followset, "Helo Formation with Carrier", "Follow Carrier at given parameters.") - + self.formation=FORMATION:New(self.carrier, self.followset, "Helo Formation with Carrier") -- Formation parameters. self.formation:FormationCenterWing(-self.offsetX, 50, math.abs(self.altitude), 50, self.offsetZ, 50) -- Set follow time interval. self.formation:SetFollowTimeInterval(self.dtFollow) - -- Formation mode. - self.formation:SetFlightModeFormation(self.helo) - -- Start formation FSM. self.formation:__Start(delay) diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index d0b281a39..e79be74b8 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -5236,3 +5236,116 @@ function UTILS.ValidateAndRepositionStatic(Country, Category, Type, Position, Sh return nil end + +--- +-- This function can be used to scan all airdromes of a map and write the Moose enums to a file. +function UTILS.CreateAirbaseEnum() + + -- Save file function + local function _savefile( filename, data ) + local file=lfs.writedir() .. filename + local f = io.open(file , "wb") + if f then + f:write( data ) + f:close() + env.info(string.format("Saving to file %s", tostring(file) )) + else + env.info(string.format("ERROR: Could not save results to file %s", tostring(file) )) + end + end + + -- Get all airbases + local airbases=world.getAirbases() + + -- Get map name + local mapname=env.mission.theatre + + -- Put airbases in a table + local myab={} + for i,_airbase in pairs(airbases) do + local airbase=_airbase --DCS#Airbase + + + local cat=airbase:getDesc().category + + if cat==Airbase.Category.AIRDROME then + + -- Get airbase name + local name=airbase:getName() + + -- Key is the name with illigal characters replaced + local key=name + + -- Germany map specifics + if name=="Airracing Lubeck" then + key="Airracing_Luebeck" + elseif name=="Bad Durkheim" then + key="Bad_Duerkheim" + elseif name=="Buchel" then + key="Buechel" + elseif name=="Buckeburg" then + key="Bueckeburg" + elseif name=="Dusseldorf" then + key="Duesseldorf" + elseif name=="Gutersloh" then + key="Guetersloh" + elseif name=="Kothen" then + key="Koethen" + elseif name=="Larz" then + key="Laerz" + elseif name=="Lubeck" then + key="Luebeck" + elseif name=="Luneburg" then + key="Lueneburg" + elseif name=="Norvenich" then + key="Noervenich" + elseif name=="Ober-Morlen" then + key="Ober_Moerlen" + elseif name=="Peenemunde" then + key="Peenemuende" + elseif name=="Pottschutthohe" then + key="Pottschutthoehe" + elseif name=="Schonefeld" then + key="Schoenefeld" + elseif name=="Weser Wumme" then + key="Weser_Wuemme" + elseif name=="Zollschen" then + key="Zoellschen" + elseif name=="Zweibrucken" then + key="Zweibruecken" + end + + -- Replace blanks, hyphens by underscores + key=key:gsub(" ", "_") + key=key:gsub("-", "_") + key=key:gsub("'", "_") + key=UTILS.ReplaceIllegalCharacters(key, "_") + + local entry={} + entry.key=key + entry.name=name + table.insert(myab, entry) + + end + + end + + -- Sort by name + table.sort(myab, function(a,b) return a.name < b.name end) + + local text=string.format("\n--- Airbases of the %s map", mapname) + text=text.."\n--" + for _,ab in pairs(myab) do + text=text..string.format("\n-- * `AIRBASE.%s.%s` %s", mapname, ab.key, ab.name) + end + text=text.."\n--" + text=text..string.format("\n-- @field %s", mapname) + text=text..string.format("\nAIRBASE.%s = {", mapname) + for _,ab in pairs(myab) do + text=text..string.format('\n\t["%s"] = "%s",', ab.key, ab.name) + end + text=text.."\n}" + + _savefile(string.format("%s-enums.txt", env.mission.theatre), text) + --env.info(text) +end diff --git a/Moose Development/Moose/Wrapper/Airbase.lua b/Moose Development/Moose/Wrapper/Airbase.lua index 502b37dfc..8a8bf812d 100644 --- a/Moose Development/Moose/Wrapper/Airbase.lua +++ b/Moose Development/Moose/Wrapper/Airbase.lua @@ -82,31 +82,29 @@ AIRBASE = { taxiways = {}, } ---- Enumeration to identify the airbases in the Caucasus region. +--- Airbases of the Caucasus map -- --- Airbases of the Caucasus map: --- --- * AIRBASE.Caucasus.Anapa_Vityazevo --- * AIRBASE.Caucasus.Batumi --- * AIRBASE.Caucasus.Beslan --- * AIRBASE.Caucasus.Gelendzhik --- * AIRBASE.Caucasus.Gudauta --- * AIRBASE.Caucasus.Kobuleti --- * AIRBASE.Caucasus.Krasnodar_Center --- * AIRBASE.Caucasus.Krasnodar_Pashkovsky --- * AIRBASE.Caucasus.Krymsk --- * AIRBASE.Caucasus.Kutaisi --- * AIRBASE.Caucasus.Maykop_Khanskaya --- * AIRBASE.Caucasus.Mineralnye_Vody --- * AIRBASE.Caucasus.Mozdok --- * AIRBASE.Caucasus.Nalchik --- * AIRBASE.Caucasus.Novorossiysk --- * AIRBASE.Caucasus.Senaki_Kolkhi --- * AIRBASE.Caucasus.Sochi_Adler --- * AIRBASE.Caucasus.Soganlug --- * AIRBASE.Caucasus.Sukhumi_Babushara --- * AIRBASE.Caucasus.Tbilisi_Lochini --- * AIRBASE.Caucasus.Vaziani +-- * `AIRBASE.Caucasus.Anapa_Vityazevo` Anapa-Vityazevo +-- * `AIRBASE.Caucasus.Batumi` Batumi +-- * `AIRBASE.Caucasus.Beslan` Beslan +-- * `AIRBASE.Caucasus.Gelendzhik` Gelendzhik +-- * `AIRBASE.Caucasus.Gudauta` Gudauta +-- * `AIRBASE.Caucasus.Kobuleti` Kobuleti +-- * `AIRBASE.Caucasus.Krasnodar_Center` Krasnodar-Center +-- * `AIRBASE.Caucasus.Krasnodar_Pashkovsky` Krasnodar-Pashkovsky +-- * `AIRBASE.Caucasus.Krymsk` Krymsk +-- * `AIRBASE.Caucasus.Kutaisi` Kutaisi +-- * `AIRBASE.Caucasus.Maykop_Khanskaya` Maykop-Khanskaya +-- * `AIRBASE.Caucasus.Mineralnye_Vody` Mineralnye Vody +-- * `AIRBASE.Caucasus.Mozdok` Mozdok +-- * `AIRBASE.Caucasus.Nalchik` Nalchik +-- * `AIRBASE.Caucasus.Novorossiysk` Novorossiysk +-- * `AIRBASE.Caucasus.Senaki_Kolkhi` Senaki-Kolkhi +-- * `AIRBASE.Caucasus.Sochi_Adler` Sochi-Adler +-- * `AIRBASE.Caucasus.Soganlug` Soganlug +-- * `AIRBASE.Caucasus.Sukhumi_Babushara` Sukhumi-Babushara +-- * `AIRBASE.Caucasus.Tbilisi_Lochini` Tbilisi-Lochini +-- * `AIRBASE.Caucasus.Vaziani` Vaziani -- -- @field Caucasus AIRBASE.Caucasus = { @@ -133,25 +131,25 @@ AIRBASE.Caucasus = { ["Vaziani"] = "Vaziani", } ---- Airbases of the Nevada map: +--- Airbases of the Nevada map -- --- * AIRBASE.Nevada.Beatty --- * AIRBASE.Nevada.Boulder_City --- * AIRBASE.Nevada.Creech --- * AIRBASE.Nevada.Echo_Bay --- * AIRBASE.Nevada.Groom_Lake --- * AIRBASE.Nevada.Henderson_Executive --- * AIRBASE.Nevada.Jean --- * AIRBASE.Nevada.Laughlin --- * AIRBASE.Nevada.Lincoln_County --- * AIRBASE.Nevada.McCarran_International --- * AIRBASE.Nevada.Mesquite --- * AIRBASE.Nevada.Mina --- * AIRBASE.Nevada.Nellis --- * AIRBASE.Nevada.North_Las_Vegas --- * AIRBASE.Nevada.Pahute_Mesa --- * AIRBASE.Nevada.Tonopah --- * AIRBASE.Nevada.Tonopah_Test_Range +-- * `AIRBASE.Nevada.Beatty` Beatty +-- * `AIRBASE.Nevada.Boulder_City` Boulder City +-- * `AIRBASE.Nevada.Creech` Creech +-- * `AIRBASE.Nevada.Echo_Bay` Echo Bay +-- * `AIRBASE.Nevada.Groom_Lake` Groom Lake +-- * `AIRBASE.Nevada.Henderson_Executive` Henderson Executive +-- * `AIRBASE.Nevada.Jean` Jean +-- * `AIRBASE.Nevada.Laughlin` Laughlin +-- * `AIRBASE.Nevada.Lincoln_County` Lincoln County +-- * `AIRBASE.Nevada.McCarran_International` McCarran International +-- * `AIRBASE.Nevada.Mesquite` Mesquite +-- * `AIRBASE.Nevada.Mina` Mina +-- * `AIRBASE.Nevada.Nellis` Nellis +-- * `AIRBASE.Nevada.North_Las_Vegas` North Las Vegas +-- * `AIRBASE.Nevada.Pahute_Mesa` Pahute Mesa +-- * `AIRBASE.Nevada.Tonopah` Tonopah +-- * `AIRBASE.Nevada.Tonopah_Test_Range` Tonopah Test Range -- -- @field Nevada AIRBASE.Nevada = { @@ -174,94 +172,103 @@ AIRBASE.Nevada = { ["Tonopah_Test_Range"] = "Tonopah Test Range", } ---- Airbases of the Normandy map: +--- Airbases of the Normandy map -- --- * AIRBASE.Normandy.Abbeville_Drucat --- * AIRBASE.Normandy.Amiens_Glisy --- * AIRBASE.Normandy.Argentan --- * AIRBASE.Normandy.Avranches_Le_Val_Saint_Pere --- * AIRBASE.Normandy.Azeville --- * AIRBASE.Normandy.Barville --- * AIRBASE.Normandy.Bazenville --- * AIRBASE.Normandy.Beaumont_le_Roger --- * AIRBASE.Normandy.Beauvais_Tille --- * AIRBASE.Normandy.Beny_sur_Mer --- * AIRBASE.Normandy.Bernay_Saint_Martin --- * AIRBASE.Normandy.Beuzeville --- * AIRBASE.Normandy.Biggin_Hill --- * AIRBASE.Normandy.Biniville --- * AIRBASE.Normandy.Broglie --- * AIRBASE.Normandy.Brucheville --- * AIRBASE.Normandy.Cardonville --- * AIRBASE.Normandy.Carpiquet --- * AIRBASE.Normandy.Chailey --- * AIRBASE.Normandy.Chippelle --- * AIRBASE.Normandy.Conches --- * AIRBASE.Normandy.Cormeilles_en_Vexin --- * AIRBASE.Normandy.Creil --- * AIRBASE.Normandy.Cretteville --- * AIRBASE.Normandy.Cricqueville_en_Bessin --- * AIRBASE.Normandy.Deanland --- * AIRBASE.Normandy.Deauville --- * AIRBASE.Normandy.Detling --- * AIRBASE.Normandy.Deux_Jumeaux --- * AIRBASE.Normandy.Dinan_Trelivan --- * AIRBASE.Normandy.Dunkirk_Mardyck --- * AIRBASE.Normandy.Essay --- * AIRBASE.Normandy.Evreux --- * AIRBASE.Normandy.Farnborough --- * AIRBASE.Normandy.Fecamp_Benouville --- * AIRBASE.Normandy.Flers --- * AIRBASE.Normandy.Ford --- * AIRBASE.Normandy.Friston --- * AIRBASE.Normandy.Funtington --- * AIRBASE.Normandy.Goulet --- * AIRBASE.Normandy.Gravesend --- * AIRBASE.Normandy.Guyancourt --- * AIRBASE.Normandy.Hauterive --- * AIRBASE.Normandy.Heathrow --- * AIRBASE.Normandy.High_Halden --- * AIRBASE.Normandy.Kenley --- * AIRBASE.Normandy.Lantheuil --- * AIRBASE.Normandy.Le_Molay --- * AIRBASE.Normandy.Lessay --- * AIRBASE.Normandy.Lignerolles --- * AIRBASE.Normandy.Longues_sur_Mer --- * AIRBASE.Normandy.Lonrai --- * AIRBASE.Normandy.Lymington --- * AIRBASE.Normandy.Lympne --- * AIRBASE.Normandy.Manston --- * AIRBASE.Normandy.Maupertus --- * AIRBASE.Normandy.Meautis --- * AIRBASE.Normandy.Merville_Calonne --- * AIRBASE.Normandy.Needs_Oar_Point --- * AIRBASE.Normandy.Odiham --- * AIRBASE.Normandy.Orly --- * AIRBASE.Normandy.Picauville --- * AIRBASE.Normandy.Poix --- * AIRBASE.Normandy.Ronai --- * AIRBASE.Normandy.Rouen_Boos --- * AIRBASE.Normandy.Rucqueville --- * AIRBASE.Normandy.Saint_Andre_de_lEure --- * AIRBASE.Normandy.Saint_Aubin --- * AIRBASE.Normandy.Saint_Omer_Wizernes --- * AIRBASE.Normandy.Saint_Pierre_du_Mont --- * AIRBASE.Normandy.Sainte_Croix_sur_Mer --- * AIRBASE.Normandy.Sainte_Laurent_sur_Mer --- * AIRBASE.Normandy.Sommervieu --- * AIRBASE.Normandy.Stoney_Cross --- * AIRBASE.Normandy.Tangmere --- * AIRBASE.Normandy.Triqueville --- * AIRBASE.Normandy.Villacoublay --- * AIRBASE.Normandy.Vrigny --- * AIRBASE.Normandy.West_Malling --- * AIRBASE.Normandy.Eastchurch --- * AIRBASE.Normandy.Headcorn --- * AIRBASE.Normandy.Hawkinge +-- * `AIRBASE.Normandy.Abbeville_Drucat` Abbeville Drucat +-- * `AIRBASE.Normandy.Alderney` Alderney +-- * `AIRBASE.Normandy.Amiens_Glisy` Amiens-Glisy +-- * `AIRBASE.Normandy.Argentan` Argentan +-- * `AIRBASE.Normandy.Avranches_Le_Val_Saint_Pere` Avranches Le Val-Saint-Pere +-- * `AIRBASE.Normandy.Azeville` Azeville +-- * `AIRBASE.Normandy.Barville` Barville +-- * `AIRBASE.Normandy.Bazenville` Bazenville +-- * `AIRBASE.Normandy.Beaumont_le_Roger` Beaumont-le-Roger +-- * `AIRBASE.Normandy.Beauvais_Tille` Beauvais-Tille +-- * `AIRBASE.Normandy.Bembridg` Bembridg +-- * `AIRBASE.Normandy.Beny_sur_Mer` Beny-sur-Mer +-- * `AIRBASE.Normandy.Bernay_Saint_Martin` Bernay Saint Martin +-- * `AIRBASE.Normandy.Beuzeville` Beuzeville +-- * `AIRBASE.Normandy.Biggin_Hill` Biggin Hill +-- * `AIRBASE.Normandy.Biniville` Biniville +-- * `AIRBASE.Normandy.Broglie` Broglie +-- * `AIRBASE.Normandy.Brucheville` Brucheville +-- * `AIRBASE.Normandy.Cardonville` Cardonville +-- * `AIRBASE.Normandy.Carpiquet` Carpiquet +-- * `AIRBASE.Normandy.Chailey` Chailey +-- * `AIRBASE.Normandy.Chippelle` Chippelle +-- * `AIRBASE.Normandy.Conches` Conches +-- * `AIRBASE.Normandy.Cormeilles_en_Vexin` Cormeilles-en-Vexin +-- * `AIRBASE.Normandy.Creil` Creil +-- * `AIRBASE.Normandy.Cretteville` Cretteville +-- * `AIRBASE.Normandy.Cricqueville_en_Bessin` Cricqueville-en-Bessin +-- * `AIRBASE.Normandy.Deanland` Deanland +-- * `AIRBASE.Normandy.Deauville` Deauville +-- * `AIRBASE.Normandy.Detling` Detling +-- * `AIRBASE.Normandy.Deux_Jumeaux` Deux Jumeaux +-- * `AIRBASE.Normandy.Dinan_Trelivan` Dinan-Trelivan +-- * `AIRBASE.Normandy.Dunkirk_Mardyck` Dunkirk-Mardyck +-- * `AIRBASE.Normandy.Eastchurch` Eastchurch +-- * `AIRBASE.Normandy.Essay` Essay +-- * `AIRBASE.Normandy.Evreux` Evreux +-- * `AIRBASE.Normandy.Farnborough` Farnborough +-- * `AIRBASE.Normandy.Fecamp_Benouville` Fecamp-Benouville +-- * `AIRBASE.Normandy.Flers` Flers +-- * `AIRBASE.Normandy.Ford` Ford +-- * `AIRBASE.Normandy.Friston` Friston +-- * `AIRBASE.Normandy.Funtington` Funtington +-- * `AIRBASE.Normandy.Goulet` Goulet +-- * `AIRBASE.Normandy.Gravesend` Gravesend +-- * `AIRBASE.Normandy.Guernsey` Guernsey +-- * `AIRBASE.Normandy.Guyancourt` Guyancourt +-- * `AIRBASE.Normandy.Hauterive` Hauterive +-- * `AIRBASE.Normandy.Hawkinge` Hawkinge +-- * `AIRBASE.Normandy.Headcorn` Headcorn +-- * `AIRBASE.Normandy.Heathrow` Heathrow +-- * `AIRBASE.Normandy.High_Halden` High Halden +-- * `AIRBASE.Normandy.Holmsley_South` Holmsley South +-- * `AIRBASE.Normandy.Jersey` Jersey +-- * `AIRBASE.Normandy.Kenley` Kenley +-- * `AIRBASE.Normandy.Lantheuil` Lantheuil +-- * `AIRBASE.Normandy.Lashenden` Lashenden +-- * `AIRBASE.Normandy.Le_Molay` Le Molay +-- * `AIRBASE.Normandy.Lessay` Lessay +-- * `AIRBASE.Normandy.Lignerolles` Lignerolles +-- * `AIRBASE.Normandy.Longues_sur_Mer` Longues-sur-Mer +-- * `AIRBASE.Normandy.Lonrai` Lonrai +-- * `AIRBASE.Normandy.Lymington` Lymington +-- * `AIRBASE.Normandy.Lympne` Lympne +-- * `AIRBASE.Normandy.Manston` Manston +-- * `AIRBASE.Normandy.Maupertus` Maupertus +-- * `AIRBASE.Normandy.Meautis` Meautis +-- * `AIRBASE.Normandy.Merville_Calonne` Merville Calonne +-- * `AIRBASE.Normandy.Needs_Oar_Point` Needs Oar Point +-- * `AIRBASE.Normandy.Northolt` Northolt +-- * `AIRBASE.Normandy.Odiham` Odiham +-- * `AIRBASE.Normandy.Orly` Orly +-- * `AIRBASE.Normandy.Picauville` Picauville +-- * `AIRBASE.Normandy.Poix` Poix +-- * `AIRBASE.Normandy.Ronai` Ronai +-- * `AIRBASE.Normandy.Rouen_Boos` Rouen-Boos +-- * `AIRBASE.Normandy.Rucqueville` Rucqueville +-- * `AIRBASE.Normandy.Saint_Pierre_du_Mont` Saint Pierre du Mont +-- * `AIRBASE.Normandy.Saint_Andre_de_lEure` Saint-Andre-de-lEure +-- * `AIRBASE.Normandy.Saint_Aubin` Saint-Aubin +-- * `AIRBASE.Normandy.Saint_Omer_Wizernes` Saint-Omer Wizernes +-- * `AIRBASE.Normandy.Saint_Pol_Bryas` Saint-Pol-Bryas +-- * `AIRBASE.Normandy.Sainte_Croix_sur_Mer` Sainte-Croix-sur-Mer +-- * `AIRBASE.Normandy.Sainte_Laurent_sur_Mer` Sainte-Laurent-sur-Mer +-- * `AIRBASE.Normandy.Sommervieu` Sommervieu +-- * `AIRBASE.Normandy.Stoney_Cross` Stoney Cross +-- * `AIRBASE.Normandy.Tangmere` Tangmere +-- * `AIRBASE.Normandy.Triqueville` Triqueville +-- * `AIRBASE.Normandy.Villacoublay` Villacoublay +-- * `AIRBASE.Normandy.Vrigny` Vrigny +-- * `AIRBASE.Normandy.West_Malling` West Malling -- -- @field Normandy AIRBASE.Normandy = { ["Abbeville_Drucat"] = "Abbeville Drucat", + ["Alderney"] = "Alderney", ["Amiens_Glisy"] = "Amiens-Glisy", ["Argentan"] = "Argentan", ["Avranches_Le_Val_Saint_Pere"] = "Avranches Le Val-Saint-Pere", @@ -270,6 +277,7 @@ AIRBASE.Normandy = { ["Bazenville"] = "Bazenville", ["Beaumont_le_Roger"] = "Beaumont-le-Roger", ["Beauvais_Tille"] = "Beauvais-Tille", + ["Bembridg"] = "Bembridg", ["Beny_sur_Mer"] = "Beny-sur-Mer", ["Bernay_Saint_Martin"] = "Bernay Saint Martin", ["Beuzeville"] = "Beuzeville", @@ -292,6 +300,7 @@ AIRBASE.Normandy = { ["Deux_Jumeaux"] = "Deux Jumeaux", ["Dinan_Trelivan"] = "Dinan-Trelivan", ["Dunkirk_Mardyck"] = "Dunkirk-Mardyck", + ["Eastchurch"] = "Eastchurch", ["Essay"] = "Essay", ["Evreux"] = "Evreux", ["Farnborough"] = "Farnborough", @@ -302,12 +311,18 @@ AIRBASE.Normandy = { ["Funtington"] = "Funtington", ["Goulet"] = "Goulet", ["Gravesend"] = "Gravesend", + ["Guernsey"] = "Guernsey", ["Guyancourt"] = "Guyancourt", ["Hauterive"] = "Hauterive", + ["Hawkinge"] = "Hawkinge", + ["Headcorn"] = "Headcorn", ["Heathrow"] = "Heathrow", ["High_Halden"] = "High Halden", + ["Holmsley_South"] = "Holmsley South", + ["Jersey"] = "Jersey", ["Kenley"] = "Kenley", ["Lantheuil"] = "Lantheuil", + ["Lashenden"] = "Lashenden", ["Le_Molay"] = "Le Molay", ["Lessay"] = "Lessay", ["Lignerolles"] = "Lignerolles", @@ -320,6 +335,7 @@ AIRBASE.Normandy = { ["Meautis"] = "Meautis", ["Merville_Calonne"] = "Merville Calonne", ["Needs_Oar_Point"] = "Needs Oar Point", + ["Northolt"] = "Northolt", ["Odiham"] = "Odiham", ["Orly"] = "Orly", ["Picauville"] = "Picauville", @@ -327,10 +343,11 @@ AIRBASE.Normandy = { ["Ronai"] = "Ronai", ["Rouen_Boos"] = "Rouen-Boos", ["Rucqueville"] = "Rucqueville", + ["Saint_Pierre_du_Mont"] = "Saint Pierre du Mont", ["Saint_Andre_de_lEure"] = "Saint-Andre-de-lEure", ["Saint_Aubin"] = "Saint-Aubin", ["Saint_Omer_Wizernes"] = "Saint-Omer Wizernes", - ["Saint_Pierre_du_Mont"] = "Saint Pierre du Mont", + ["Saint_Pol_Bryas"] = "Saint-Pol-Bryas", ["Sainte_Croix_sur_Mer"] = "Sainte-Croix-sur-Mer", ["Sainte_Laurent_sur_Mer"] = "Sainte-Laurent-sur-Mer", ["Sommervieu"] = "Sommervieu", @@ -340,53 +357,50 @@ AIRBASE.Normandy = { ["Villacoublay"] = "Villacoublay", ["Vrigny"] = "Vrigny", ["West_Malling"] = "West Malling", - ["Eastchurch"] = "Eastchurch", - ["Headcorn"] = "Headcorn", - ["Hawkinge"] = "Hawkinge", } ---- Airbases of the Persion Gulf Map: +--- Airbases of the Persian Gulf map -- --- * AIRBASE.PersianGulf.Abu_Dhabi_Intl --- * AIRBASE.PersianGulf.Abu_Musa_Island --- * AIRBASE.PersianGulf.Al_Ain_Intl --- * AIRBASE.PersianGulf.Al_Bateen --- * AIRBASE.PersianGulf.Al_Dhafra_AFB --- * AIRBASE.PersianGulf.Al_Maktoum_Intl --- * AIRBASE.PersianGulf.Al_Minhad_AFB --- * AIRBASE.PersianGulf.Bandar_Abbas_Intl --- * AIRBASE.PersianGulf.Bandar_Lengeh --- * AIRBASE.PersianGulf.Bandar_e_Jask --- * AIRBASE.PersianGulf.Dubai_Intl --- * AIRBASE.PersianGulf.Fujairah_Intl --- * AIRBASE.PersianGulf.Havadarya --- * AIRBASE.PersianGulf.Jiroft --- * AIRBASE.PersianGulf.Kerman --- * AIRBASE.PersianGulf.Khasab --- * AIRBASE.PersianGulf.Kish_Intl --- * AIRBASE.PersianGulf.Lar --- * AIRBASE.PersianGulf.Lavan_Island --- * AIRBASE.PersianGulf.Liwa_AFB --- * AIRBASE.PersianGulf.Qeshm_Island --- * AIRBASE.PersianGulf.Quasoura_airport --- * AIRBASE.PersianGulf.Ras_Al_Khaimah_Intl --- * AIRBASE.PersianGulf.Sas_Al_Nakheel --- * AIRBASE.PersianGulf.Sharjah_Intl --- * AIRBASE.PersianGulf.Shiraz_Intl --- * AIRBASE.PersianGulf.Sir_Abu_Nuayr --- * AIRBASE.PersianGulf.Sirri_Island --- * AIRBASE.PersianGulf.Tunb_Island_AFB --- * AIRBASE.PersianGulf.Tunb_Kochak +-- * `AIRBASE.PersianGulf.Abu_Dhabi_Intl` Abu Dhabi Intl +-- * `AIRBASE.PersianGulf.Abu_Musa_Island` Abu Musa Island +-- * `AIRBASE.PersianGulf.Al_Ain_Intl` Al Ain Intl +-- * `AIRBASE.PersianGulf.Al_Dhafra_AFB` Al Dhafra AFB +-- * `AIRBASE.PersianGulf.Al_Maktoum_Intl` Al Maktoum Intl +-- * `AIRBASE.PersianGulf.Al_Minhad_AFB` Al Minhad AFB +-- * `AIRBASE.PersianGulf.Al_Bateen` Al-Bateen +-- * `AIRBASE.PersianGulf.Bandar_Abbas_Intl` Bandar Abbas Intl +-- * `AIRBASE.PersianGulf.Bandar_Lengeh` Bandar Lengeh +-- * `AIRBASE.PersianGulf.Bandar_e_Jask` Bandar-e-Jask +-- * `AIRBASE.PersianGulf.Dubai_Intl` Dubai Intl +-- * `AIRBASE.PersianGulf.Fujairah_Intl` Fujairah Intl +-- * `AIRBASE.PersianGulf.Havadarya` Havadarya +-- * `AIRBASE.PersianGulf.Jiroft` Jiroft +-- * `AIRBASE.PersianGulf.Kerman` Kerman +-- * `AIRBASE.PersianGulf.Khasab` Khasab +-- * `AIRBASE.PersianGulf.Kish_Intl` Kish Intl +-- * `AIRBASE.PersianGulf.Lar` Lar +-- * `AIRBASE.PersianGulf.Lavan_Island` Lavan Island +-- * `AIRBASE.PersianGulf.Liwa_AFB` Liwa AFB +-- * `AIRBASE.PersianGulf.Qeshm_Island` Qeshm Island +-- * `AIRBASE.PersianGulf.Quasoura_airport` Quasoura_airport +-- * `AIRBASE.PersianGulf.Ras_Al_Khaimah_Intl` Ras Al Khaimah Intl +-- * `AIRBASE.PersianGulf.Sas_Al_Nakheel` Sas Al Nakheel +-- * `AIRBASE.PersianGulf.Sharjah_Intl` Sharjah Intl +-- * `AIRBASE.PersianGulf.Shiraz_Intl` Shiraz Intl +-- * `AIRBASE.PersianGulf.Sir_Abu_Nuayr` Sir Abu Nuayr +-- * `AIRBASE.PersianGulf.Sirri_Island` Sirri Island +-- * `AIRBASE.PersianGulf.Tunb_Island_AFB` Tunb Island AFB +-- * `AIRBASE.PersianGulf.Tunb_Kochak` Tunb Kochak -- -- @field PersianGulf AIRBASE.PersianGulf = { ["Abu_Dhabi_Intl"] = "Abu Dhabi Intl", ["Abu_Musa_Island"] = "Abu Musa Island", ["Al_Ain_Intl"] = "Al Ain Intl", - ["Al_Bateen"] = "Al-Bateen", ["Al_Dhafra_AFB"] = "Al Dhafra AFB", ["Al_Maktoum_Intl"] = "Al Maktoum Intl", ["Al_Minhad_AFB"] = "Al Minhad AFB", + ["Al_Bateen"] = "Al-Bateen", ["Bandar_Abbas_Intl"] = "Bandar Abbas Intl", ["Bandar_Lengeh"] = "Bandar Lengeh", ["Bandar_e_Jask"] = "Bandar-e-Jask", @@ -412,20 +426,20 @@ AIRBASE.PersianGulf = { ["Tunb_Kochak"] = "Tunb Kochak", } ---- Airbases of The Channel Map: +--- Airbases of the The Channel map -- --- * AIRBASE.TheChannel.Abbeville_Drucat --- * AIRBASE.TheChannel.Biggin_Hill --- * AIRBASE.TheChannel.Detling --- * AIRBASE.TheChannel.Dunkirk_Mardyck --- * AIRBASE.TheChannel.Eastchurch --- * AIRBASE.TheChannel.Hawkinge --- * AIRBASE.TheChannel.Headcorn --- * AIRBASE.TheChannel.High_Halden --- * AIRBASE.TheChannel.Lympne --- * AIRBASE.TheChannel.Manston --- * AIRBASE.TheChannel.Merville_Calonne --- * AIRBASE.TheChannel.Saint_Omer_Longuenesse +-- * `AIRBASE.TheChannel.Abbeville_Drucat` Abbeville Drucat +-- * `AIRBASE.TheChannel.Biggin_Hill` Biggin Hill +-- * `AIRBASE.TheChannel.Detling` Detling +-- * `AIRBASE.TheChannel.Dunkirk_Mardyck` Dunkirk Mardyck +-- * `AIRBASE.TheChannel.Eastchurch` Eastchurch +-- * `AIRBASE.TheChannel.Hawkinge` Hawkinge +-- * `AIRBASE.TheChannel.Headcorn` Headcorn +-- * `AIRBASE.TheChannel.High_Halden` High Halden +-- * `AIRBASE.TheChannel.Lympne` Lympne +-- * `AIRBASE.TheChannel.Manston` Manston +-- * `AIRBASE.TheChannel.Merville_Calonne` Merville Calonne +-- * `AIRBASE.TheChannel.Saint_Omer_Longuenesse` Saint Omer Longuenesse -- -- @field TheChannel AIRBASE.TheChannel = { @@ -443,91 +457,92 @@ AIRBASE.TheChannel = { ["Saint_Omer_Longuenesse"] = "Saint Omer Longuenesse", } ---- Airbases of the Syria map: +--- Airbases of the Syria map -- --- * AIRBASE.Syria.Abu_al_Duhur --- * AIRBASE.Syria.Adana_Sakirpasa --- * AIRBASE.Syria.Akrotiri --- * AIRBASE.Syria.Al_Dumayr --- * AIRBASE.Syria.Al_Qusayr --- * AIRBASE.Syria.Aleppo --- * AIRBASE.Syria.An_Nasiriyah --- * AIRBASE.Syria.At_Tanf --- * AIRBASE.Syria.Bassel_Al_Assad --- * AIRBASE.Syria.Beirut_Rafic_Hariri --- * AIRBASE.Syria.Damascus --- * AIRBASE.Syria.Deir_ez_Zor --- * AIRBASE.Syria.Ercan --- * AIRBASE.Syria.Eyn_Shemer --- * AIRBASE.Syria.Gaziantep --- * AIRBASE.Syria.Gazipasa --- * AIRBASE.Syria.Gecitkale --- * AIRBASE.Syria.H --- * AIRBASE.Syria.H3 --- * AIRBASE.Syria.H3_Northwest --- * AIRBASE.Syria.H3_Southwest --- * AIRBASE.Syria.H4 --- * AIRBASE.Syria.Haifa --- * AIRBASE.Syria.Hama --- * AIRBASE.Syria.Hatay --- * AIRBASE.Syria.Herzliya --- * AIRBASE.Syria.Incirlik --- * AIRBASE.Syria.Jirah --- * AIRBASE.Syria.Khalkhalah --- * AIRBASE.Syria.Kharab_Ishk --- * AIRBASE.Syria.King_Abdullah_II --- * AIRBASE.Syria.King_Hussein_Air_College --- * AIRBASE.Syria.Kingsfield --- * AIRBASE.Syria.Kiryat_Shmona --- * AIRBASE.Syria.Kuweires --- * AIRBASE.Syria.Lakatamia --- * AIRBASE.Syria.Larnaca --- * AIRBASE.Syria.Marj_Ruhayyil --- * AIRBASE.Syria.Marj_as_Sultan_North --- * AIRBASE.Syria.Marj_as_Sultan_South --- * AIRBASE.Syria.Megiddo --- * AIRBASE.Syria.Mezzeh --- * AIRBASE.Syria.Minakh --- * AIRBASE.Syria.Muwaffaq_Salti --- * AIRBASE.Syria.Naqoura --- * AIRBASE.Syria.Nicosia --- * AIRBASE.Syria.Palmyra --- * AIRBASE.Syria.Paphos --- * AIRBASE.Syria.Pinarbashi --- * AIRBASE.Syria.Prince_Hassan --- * AIRBASE.Syria.Qabr_as_Sitt --- * AIRBASE.Syria.Ramat_David --- * AIRBASE.Syria.Rayak --- * AIRBASE.Syria.Rene_Mouawad --- * AIRBASE.Syria.Rosh_Pina --- * AIRBASE.Syria.Ruwayshid --- * AIRBASE.Syria.Sanliurfa --- * AIRBASE.Syria.Sayqal --- * AIRBASE.Syria.Shayrat --- * AIRBASE.Syria.Tabqa --- * AIRBASE.Syria.Taftanaz --- * AIRBASE.Syria.Tal_Siman --- * AIRBASE.Syria.Tha_lah --- * AIRBASE.Syria.Tiyas --- * AIRBASE.Syria.Wujah_Al_Hajar --- * AIRBASE.Syria.Ben_Gurion --- * AIRBASE.Syria.Hatzor --- * AIRBASE.Syria.Palmachim --- * AIRBASE.Syria.Tel_Nof --- * AIRBASE.Syria.Marka +-- * `AIRBASE.Syria.Abu_al_Duhur` Abu al-Duhur +-- * `AIRBASE.Syria.Adana_Sakirpasa` Adana Sakirpasa +-- * `AIRBASE.Syria.Akrotiri` Akrotiri +-- * `AIRBASE.Syria.Al_Qusayr` Al Qusayr +-- * `AIRBASE.Syria.Al_Dumayr` Al-Dumayr +-- * `AIRBASE.Syria.Aleppo` Aleppo +-- * `AIRBASE.Syria.An_Nasiriyah` An Nasiriyah +-- * `AIRBASE.Syria.At_Tanf` At Tanf +-- * `AIRBASE.Syria.Bassel_Al_Assad` Bassel Al-Assad +-- * `AIRBASE.Syria.Beirut_Rafic_Hariri` Beirut-Rafic Hariri +-- * `AIRBASE.Syria.Ben_Gurion` Ben Gurion +-- * `AIRBASE.Syria.Damascus` Damascus +-- * `AIRBASE.Syria.Deir_ez_Zor` Deir ez-Zor +-- * `AIRBASE.Syria.Ercan` Ercan +-- * `AIRBASE.Syria.Eyn_Shemer` Eyn Shemer +-- * `AIRBASE.Syria.Gaziantep` Gaziantep +-- * `AIRBASE.Syria.Gazipasa` Gazipasa +-- * `AIRBASE.Syria.Gecitkale` Gecitkale +-- * `AIRBASE.Syria.H` H +-- * `AIRBASE.Syria.H3` H3 +-- * `AIRBASE.Syria.H3_Northwest` H3 Northwest +-- * `AIRBASE.Syria.H3_Southwest` H3 Southwest +-- * `AIRBASE.Syria.H4` H4 +-- * `AIRBASE.Syria.Haifa` Haifa +-- * `AIRBASE.Syria.Hama` Hama +-- * `AIRBASE.Syria.Hatay` Hatay +-- * `AIRBASE.Syria.Hatzor` Hatzor +-- * `AIRBASE.Syria.Herzliya` Herzliya +-- * `AIRBASE.Syria.Incirlik` Incirlik +-- * `AIRBASE.Syria.Jirah` Jirah +-- * `AIRBASE.Syria.Khalkhalah` Khalkhalah +-- * `AIRBASE.Syria.Kharab_Ishk` Kharab Ishk +-- * `AIRBASE.Syria.King_Abdullah_II` King Abdullah II +-- * `AIRBASE.Syria.King_Hussein_Air_College` King Hussein Air College +-- * `AIRBASE.Syria.Kingsfield` Kingsfield +-- * `AIRBASE.Syria.Kiryat_Shmona` Kiryat Shmona +-- * `AIRBASE.Syria.Kuweires` Kuweires +-- * `AIRBASE.Syria.Lakatamia` Lakatamia +-- * `AIRBASE.Syria.Larnaca` Larnaca +-- * `AIRBASE.Syria.Marj_Ruhayyil` Marj Ruhayyil +-- * `AIRBASE.Syria.Marj_as_Sultan_North` Marj as Sultan North +-- * `AIRBASE.Syria.Marj_as_Sultan_South` Marj as Sultan South +-- * `AIRBASE.Syria.Marka` Marka +-- * `AIRBASE.Syria.Megiddo` Megiddo +-- * `AIRBASE.Syria.Mezzeh` Mezzeh +-- * `AIRBASE.Syria.Minakh` Minakh +-- * `AIRBASE.Syria.Muwaffaq_Salti` Muwaffaq Salti +-- * `AIRBASE.Syria.Naqoura` Naqoura +-- * `AIRBASE.Syria.Nicosia` Nicosia +-- * `AIRBASE.Syria.Palmachim` Palmachim +-- * `AIRBASE.Syria.Palmyra` Palmyra +-- * `AIRBASE.Syria.Paphos` Paphos +-- * `AIRBASE.Syria.Pinarbashi` Pinarbashi +-- * `AIRBASE.Syria.Prince_Hassan` Prince Hassan +-- * `AIRBASE.Syria.Qabr_as_Sitt` Qabr as Sitt +-- * `AIRBASE.Syria.Ramat_David` Ramat David +-- * `AIRBASE.Syria.Rayak` Rayak +-- * `AIRBASE.Syria.Rene_Mouawad` Rene Mouawad +-- * `AIRBASE.Syria.Rosh_Pina` Rosh Pina +-- * `AIRBASE.Syria.Ruwayshid` Ruwayshid +-- * `AIRBASE.Syria.Sanliurfa` Sanliurfa +-- * `AIRBASE.Syria.Sayqal` Sayqal +-- * `AIRBASE.Syria.Shayrat` Shayrat +-- * `AIRBASE.Syria.Tabqa` Tabqa +-- * `AIRBASE.Syria.Taftanaz` Taftanaz +-- * `AIRBASE.Syria.Tal_Siman` Tal Siman +-- * `AIRBASE.Syria.Tel_Nof` Tel Nof +-- * `AIRBASE.Syria.Tha_lah` Tha'lah +-- * `AIRBASE.Syria.Tiyas` Tiyas +-- * `AIRBASE.Syria.Wujah_Al_Hajar` Wujah Al Hajar -- ---@field Syria -AIRBASE.Syria={ +-- @field Syria +AIRBASE.Syria = { ["Abu_al_Duhur"] = "Abu al-Duhur", ["Adana_Sakirpasa"] = "Adana Sakirpasa", ["Akrotiri"] = "Akrotiri", - ["Al_Dumayr"] = "Al-Dumayr", ["Al_Qusayr"] = "Al Qusayr", + ["Al_Dumayr"] = "Al-Dumayr", ["Aleppo"] = "Aleppo", ["An_Nasiriyah"] = "An Nasiriyah", ["At_Tanf"] = "At Tanf", ["Bassel_Al_Assad"] = "Bassel Al-Assad", ["Beirut_Rafic_Hariri"] = "Beirut-Rafic Hariri", + ["Ben_Gurion"] = "Ben Gurion", ["Damascus"] = "Damascus", ["Deir_ez_Zor"] = "Deir ez-Zor", ["Ercan"] = "Ercan", @@ -543,6 +558,7 @@ AIRBASE.Syria={ ["Haifa"] = "Haifa", ["Hama"] = "Hama", ["Hatay"] = "Hatay", + ["Hatzor"] = "Hatzor", ["Herzliya"] = "Herzliya", ["Incirlik"] = "Incirlik", ["Jirah"] = "Jirah", @@ -555,16 +571,17 @@ AIRBASE.Syria={ ["Kuweires"] = "Kuweires", ["Lakatamia"] = "Lakatamia", ["Larnaca"] = "Larnaca", - ["Marka"] = "Marka", ["Marj_Ruhayyil"] = "Marj Ruhayyil", ["Marj_as_Sultan_North"] = "Marj as Sultan North", ["Marj_as_Sultan_South"] = "Marj as Sultan South", + ["Marka"] = "Marka", ["Megiddo"] = "Megiddo", ["Mezzeh"] = "Mezzeh", ["Minakh"] = "Minakh", ["Muwaffaq_Salti"] = "Muwaffaq Salti", ["Naqoura"] = "Naqoura", ["Nicosia"] = "Nicosia", + ["Palmachim"] = "Palmachim", ["Palmyra"] = "Palmyra", ["Paphos"] = "Paphos", ["Pinarbashi"] = "Pinarbashi", @@ -581,30 +598,27 @@ AIRBASE.Syria={ ["Tabqa"] = "Tabqa", ["Taftanaz"] = "Taftanaz", ["Tal_Siman"] = "Tal Siman", + ["Tel_Nof"] = "Tel Nof", ["Tha_lah"] = "Tha'lah", ["Tiyas"] = "Tiyas", ["Wujah_Al_Hajar"] = "Wujah Al Hajar", - ["Ben_Gurion"] = "Ben Gurion", - ["Hatzor"] = "Hatzor", - ["Palmachim"] = "Palmachim", - ["Tel_Nof"] = "Tel Nof", } ---- Airbases of the Mariana Islands map: +--- Airbases of the Mariana Islands map -- --- * AIRBASE.MarianaIslands.Andersen_AFB --- * AIRBASE.MarianaIslands.Antonio_B_Won_Pat_Intl --- * AIRBASE.MarianaIslands.North_West_Field --- * AIRBASE.MarianaIslands.Olf_Orote --- * AIRBASE.MarianaIslands.Pagan_Airstrip --- * AIRBASE.MarianaIslands.Rota_Intl --- * AIRBASE.MarianaIslands.Saipan_Intl --- * AIRBASE.MarianaIslands.Tinian_Intl +-- * `AIRBASE.MarianaIslands.Andersen_AFB` Andersen AFB +-- * `AIRBASE.MarianaIslands.Antonio_B._Won_Pat_Intl` Antonio B. Won Pat Intl +-- * `AIRBASE.MarianaIslands.North_West_Field` North West Field +-- * `AIRBASE.MarianaIslands.Olf_Orote` Olf Orote +-- * `AIRBASE.MarianaIslands.Pagan_Airstrip` Pagan Airstrip +-- * `AIRBASE.MarianaIslands.Rota_Intl` Rota Intl +-- * `AIRBASE.MarianaIslands.Saipan_Intl` Saipan Intl +-- * `AIRBASE.MarianaIslands.Tinian_Intl` Tinian Intl -- -- @field MarianaIslands AIRBASE.MarianaIslands = { ["Andersen_AFB"] = "Andersen AFB", - ["Antonio_B_Won_Pat_Intl"] = "Antonio B. Won Pat Intl", + ["Antonio_B._Won_Pat_Intl"] = "Antonio B. Won Pat Intl", ["North_West_Field"] = "North West Field", ["Olf_Orote"] = "Olf Orote", ["Pagan_Airstrip"] = "Pagan Airstrip", @@ -613,22 +627,22 @@ AIRBASE.MarianaIslands = { ["Tinian_Intl"] = "Tinian Intl", } ---- Airbase of the Marianas WWII map +--- Airbases of the MarianaIslandsWWII map -- --- * AIRBASE.MarianaIslandsWWII.Agana --- * AIRBASE.MarianaIslandsWWII.Airfield_3 --- * AIRBASE.MarianaIslandsWWII.Charon_Kanoa --- * AIRBASE.MarianaIslandsWWII.Gurguan_Point --- * AIRBASE.MarianaIslandsWWII.Isley --- * AIRBASE.MarianaIslandsWWII.Kagman --- * AIRBASE.MarianaIslandsWWII.Marpi --- * AIRBASE.MarianaIslandsWWII.Orote --- * AIRBASE.MarianaIslandsWWII.Pagan --- * AIRBASE.MarianaIslandsWWII.Rota --- * AIRBASE.MarianaIslandsWWII.Ushi --- @field AIRBASE.MarianaIslandsWWII -AIRBASE.MarianaIslandsWWII = -{ +-- * `AIRBASE.MarianaIslandsWWII.Agana` Agana +-- * `AIRBASE.MarianaIslandsWWII.Airfield_3` Airfield 3 +-- * `AIRBASE.MarianaIslandsWWII.Charon_Kanoa` Charon Kanoa +-- * `AIRBASE.MarianaIslandsWWII.Gurguan_Point` Gurguan Point +-- * `AIRBASE.MarianaIslandsWWII.Isley` Isley +-- * `AIRBASE.MarianaIslandsWWII.Kagman` Kagman +-- * `AIRBASE.MarianaIslandsWWII.Marpi` Marpi +-- * `AIRBASE.MarianaIslandsWWII.Orote` Orote +-- * `AIRBASE.MarianaIslandsWWII.Pagan` Pagan +-- * `AIRBASE.MarianaIslandsWWII.Rota` Rota +-- * `AIRBASE.MarianaIslandsWWII.Ushi` Ushi +-- +-- @field MarianaIslandsWWII +AIRBASE.MarianaIslandsWWII = { ["Agana"] = "Agana", ["Airfield_3"] = "Airfield 3", ["Charon_Kanoa"] = "Charon Kanoa", @@ -642,38 +656,38 @@ AIRBASE.MarianaIslandsWWII = ["Ushi"] = "Ushi", } ---- Airbases of the South Atlantic map: +--- Airbases of the South Atlantic (Falklands) map -- --- * AIRBASE.SouthAtlantic.Almirante_Schroeders --- * AIRBASE.SouthAtlantic.Comandante_Luis_Piedrabuena --- * AIRBASE.SouthAtlantic.Cullen --- * AIRBASE.SouthAtlantic.El_Calafate --- * AIRBASE.SouthAtlantic.Franco_Bianco --- * AIRBASE.SouthAtlantic.Gobernador_Gregores --- * AIRBASE.SouthAtlantic.Goose_Green --- * AIRBASE.SouthAtlantic.Gull_Point --- * AIRBASE.SouthAtlantic.Hipico_Flying_Club --- * AIRBASE.SouthAtlantic.Mount_Pleasant --- * AIRBASE.SouthAtlantic.O_Higgins --- * AIRBASE.SouthAtlantic.Pampa_Guanaco --- * AIRBASE.SouthAtlantic.Port_Stanley --- * AIRBASE.SouthAtlantic.Porvenir --- * AIRBASE.SouthAtlantic.Puerto_Natales --- * AIRBASE.SouthAtlantic.Puerto_Santa_Cruz --- * AIRBASE.SouthAtlantic.Puerto_Williams --- * AIRBASE.SouthAtlantic.Punta_Arenas --- * AIRBASE.SouthAtlantic.Rio_Chico --- * AIRBASE.SouthAtlantic.Rio_Gallegos --- * AIRBASE.SouthAtlantic.Rio_Grande --- * AIRBASE.SouthAtlantic.Rio_Turbio --- * AIRBASE.SouthAtlantic.San_Carlos_FOB --- * AIRBASE.SouthAtlantic.San_Julian --- * AIRBASE.SouthAtlantic.Tolhuin --- * AIRBASE.SouthAtlantic.Ushuaia --- * AIRBASE.SouthAtlantic.Ushuaia_Helo_Port +-- * `AIRBASE.SouthAtlantic.Almirante_Schroeders` Almirante Schroeders +-- * `AIRBASE.SouthAtlantic.Comandante_Luis_Piedrabuena` Comandante Luis Piedrabuena +-- * `AIRBASE.SouthAtlantic.Cullen` Cullen +-- * `AIRBASE.SouthAtlantic.El_Calafate` El Calafate +-- * `AIRBASE.SouthAtlantic.Franco_Bianco` Franco Bianco +-- * `AIRBASE.SouthAtlantic.Gobernador_Gregores` Gobernador Gregores +-- * `AIRBASE.SouthAtlantic.Goose_Green` Goose Green +-- * `AIRBASE.SouthAtlantic.Gull_Point` Gull Point +-- * `AIRBASE.SouthAtlantic.Hipico_Flying_Club` Hipico Flying Club +-- * `AIRBASE.SouthAtlantic.Mount_Pleasant` Mount Pleasant +-- * `AIRBASE.SouthAtlantic.O_Higgins` O'Higgins +-- * `AIRBASE.SouthAtlantic.Pampa_Guanaco` Pampa Guanaco +-- * `AIRBASE.SouthAtlantic.Port_Stanley` Port Stanley +-- * `AIRBASE.SouthAtlantic.Porvenir` Porvenir +-- * `AIRBASE.SouthAtlantic.Puerto_Natales` Puerto Natales +-- * `AIRBASE.SouthAtlantic.Puerto_Santa_Cruz` Puerto Santa Cruz +-- * `AIRBASE.SouthAtlantic.Puerto_Williams` Puerto Williams +-- * `AIRBASE.SouthAtlantic.Punta_Arenas` Punta Arenas +-- * `AIRBASE.SouthAtlantic.Rio_Chico` Rio Chico +-- * `AIRBASE.SouthAtlantic.Rio_Gallegos` Rio Gallegos +-- * `AIRBASE.SouthAtlantic.Rio_Grande` Rio Grande +-- * `AIRBASE.SouthAtlantic.Rio_Turbio` Rio Turbio +-- * `AIRBASE.SouthAtlantic.San_Carlos_FOB` San Carlos FOB +-- * `AIRBASE.SouthAtlantic.San_Julian` San Julian +-- * `AIRBASE.SouthAtlantic.Tolhuin` Tolhuin +-- * `AIRBASE.SouthAtlantic.Ushuaia` Ushuaia +-- * `AIRBASE.SouthAtlantic.Ushuaia_Helo_Port` Ushuaia Helo Port -- ---@field SouthAtlantic -AIRBASE.SouthAtlantic={ +-- @field SouthAtlantic +AIRBASE.SouthAtlantic = { ["Almirante_Schroeders"] = "Almirante Schroeders", ["Comandante_Luis_Piedrabuena"] = "Comandante Luis Piedrabuena", ["Cullen"] = "Cullen", @@ -703,58 +717,64 @@ AIRBASE.SouthAtlantic={ ["Ushuaia_Helo_Port"] = "Ushuaia Helo Port", } ---- Airbases of the Sinai map: +--- Airbases of the Sinai map -- --- * AIRBASE.SinaiMap.Abu_Rudeis --- * AIRBASE.SinaiMap.Abu_Suwayr --- * AIRBASE.SinaiMap.Al_Bahr_al_Ahmar --- * AIRBASE.SinaiMap.Al_Ismailiyah --- * AIRBASE.SinaiMap.Al_Khatatbah --- * AIRBASE.SinaiMap.Al_Mansurah --- * AIRBASE.SinaiMap.Al_Rahmaniyah_Air_Base --- * AIRBASE.SinaiMap.As_Salihiyah --- * AIRBASE.SinaiMap.AzZaqaziq --- * AIRBASE.SinaiMap.Baluza --- * AIRBASE.SinaiMap.Ben_Gurion --- * AIRBASE.SinaiMap.Beni_Suef --- * AIRBASE.SinaiMap.Bilbeis_Air_Base --- * AIRBASE.SinaiMap.Bir_Hasanah --- * AIRBASE.SinaiMap.Birma_Air_Base --- * AIRBASE.SinaiMap.Borg_El_Arab_International_Airport --- * AIRBASE.SinaiMap.Cairo_International_Airport --- * AIRBASE.SinaiMap.Cairo_West --- * AIRBASE.SinaiMap.Damascus_Intl --- * AIRBASE.SinaiMap.Difarsuwar_Airfield --- * AIRBASE.SinaiMap.El_Arish --- * AIRBASE.SinaiMap.El_Gora --- * AIRBASE.SinaiMap.El_Minya --- * AIRBASE.SinaiMap.Fayed --- * AIRBASE.SinaiMap.Gebel_El_Basur_Air_Base --- * AIRBASE.SinaiMap.Hatzerim --- * AIRBASE.SinaiMap.Hatzor --- * AIRBASE.SinaiMap.Hurghada_International_Airport --- * AIRBASE.SinaiMap.Inshas_Airbase --- * AIRBASE.SinaiMap.Jiyanklis_Air_Base --- * AIRBASE.SinaiMap.Kedem --- * AIRBASE.SinaiMap.Kibrit_Air_Base --- * AIRBASE.SinaiMap.Kom_Awshim --- * AIRBASE.SinaiMap.Melez --- * AIRBASE.SinaiMap.Mezzeh_Air_Base --- * AIRBASE.SinaiMap.Nevatim --- * AIRBASE.SinaiMap.Ovda --- * AIRBASE.SinaiMap.Palmachim --- * AIRBASE.SinaiMap.Quwaysina --- * AIRBASE.SinaiMap.Rafic_Hariri_Intl --- * AIRBASE.SinaiMap.Ramat_David --- * AIRBASE.SinaiMap.Ramon_Airbase --- * AIRBASE.SinaiMap.Ramon_International_Airport --- * AIRBASE.SinaiMap.Sde_Dov --- * AIRBASE.SinaiMap.Sharm_El_Sheikh_International_Airport --- * AIRBASE.SinaiMap.St_Catherine --- * AIRBASE.SinaiMap.Tabuk --- * AIRBASE.SinaiMap.Tel_Nof --- * AIRBASE.SinaiMap.Wadi_Abu_Rish --- * AIRBASE.SinaiMap.Wadi_al_Jandali +-- * `AIRBASE.SinaiMap.Abu_Rudeis` Abu Rudeis +-- * `AIRBASE.SinaiMap.Abu_Suwayr` Abu Suwayr +-- * `AIRBASE.SinaiMap.Al_Bahr_al_Ahmar` Al Bahr al Ahmar +-- * `AIRBASE.SinaiMap.Al_Ismailiyah` Al Ismailiyah +-- * `AIRBASE.SinaiMap.Al_Khatatbah` Al Khatatbah +-- * `AIRBASE.SinaiMap.Al_Mansurah` Al Mansurah +-- * `AIRBASE.SinaiMap.Al_Rahmaniyah_Air_Base` Al Rahmaniyah Air Base +-- * `AIRBASE.SinaiMap.As_Salihiyah` As Salihiyah +-- * `AIRBASE.SinaiMap.AzZaqaziq` AzZaqaziq +-- * `AIRBASE.SinaiMap.Baluza` Baluza +-- * `AIRBASE.SinaiMap.Ben_Gurion` Ben-Gurion +-- * `AIRBASE.SinaiMap.Beni_Suef` Beni Suef +-- * `AIRBASE.SinaiMap.Bilbeis_Air_Base` Bilbeis Air Base +-- * `AIRBASE.SinaiMap.Bir_Hasanah` Bir Hasanah +-- * `AIRBASE.SinaiMap.Birma_Air_Base` Birma Air Base +-- * `AIRBASE.SinaiMap.Borg_El_Arab_International_Airport` Borg El Arab International Airport +-- * `AIRBASE.SinaiMap.Cairo_International_Airport` Cairo International Airport +-- * `AIRBASE.SinaiMap.Cairo_West` Cairo West +-- * `AIRBASE.SinaiMap.Damascus_Intl` Damascus Intl +-- * `AIRBASE.SinaiMap.Difarsuwar_Airfield` Difarsuwar Airfield +-- * `AIRBASE.SinaiMap.Ein_Shamer` Ein Shamer +-- * `AIRBASE.SinaiMap.El_Arish` El Arish +-- * `AIRBASE.SinaiMap.El_Gora` El Gora +-- * `AIRBASE.SinaiMap.El_Minya` El Minya +-- * `AIRBASE.SinaiMap.Fayed` Fayed +-- * `AIRBASE.SinaiMap.Gebel_El_Basur_Air_Base` Gebel El Basur Air Base +-- * `AIRBASE.SinaiMap.Hatzerim` Hatzerim +-- * `AIRBASE.SinaiMap.Hatzor` Hatzor +-- * `AIRBASE.SinaiMap.Hurghada_International_Airport` Hurghada International Airport +-- * `AIRBASE.SinaiMap.Inshas_Airbase` Inshas Airbase +-- * `AIRBASE.SinaiMap.Jiyanklis_Air_Base` Jiyanklis Air Base +-- * `AIRBASE.SinaiMap.Kedem` Kedem +-- * `AIRBASE.SinaiMap.Khalkhalah_Air_Base` Khalkhalah Air Base +-- * `AIRBASE.SinaiMap.Kibrit_Air_Base` Kibrit Air Base +-- * `AIRBASE.SinaiMap.King_Feisal_Air_Base` King Feisal Air Base +-- * `AIRBASE.SinaiMap.Kom_Awshim` Kom Awshim +-- * `AIRBASE.SinaiMap.Megiddo` Megiddo +-- * `AIRBASE.SinaiMap.Melez` Melez +-- * `AIRBASE.SinaiMap.Mezzeh_Air_Base` Mezzeh Air Base +-- * `AIRBASE.SinaiMap.Nevatim` Nevatim +-- * `AIRBASE.SinaiMap.Ovda` Ovda +-- * `AIRBASE.SinaiMap.Palmachim` Palmachim +-- * `AIRBASE.SinaiMap.Quwaysina` Quwaysina +-- * `AIRBASE.SinaiMap.Rafic_Hariri_Intl` Rafic Hariri Intl +-- * `AIRBASE.SinaiMap.Ramat_David` Ramat David +-- * `AIRBASE.SinaiMap.Ramon_Airbase` Ramon Airbase +-- * `AIRBASE.SinaiMap.Ramon_International_Airport` Ramon International Airport +-- * `AIRBASE.SinaiMap.Sde_Dov` Sde Dov +-- * `AIRBASE.SinaiMap.Sharm_El_Sheikh_International_Airport` Sharm El Sheikh International Airport +-- * `AIRBASE.SinaiMap.St_Catherine` St Catherine +-- * `AIRBASE.SinaiMap.Taba_International_Airport` Taba International Airport +-- * `AIRBASE.SinaiMap.Tabuk` Tabuk +-- * `AIRBASE.SinaiMap.TabukHeliBase` TabukHeliBase +-- * `AIRBASE.SinaiMap.Tel_Nof` Tel Nof +-- * `AIRBASE.SinaiMap.Wadi_Abu_Rish` Wadi Abu Rish +-- * `AIRBASE.SinaiMap.Wadi_al_Jandali` Wadi al Jandali -- -- @field Sinai AIRBASE.Sinai = { @@ -778,6 +798,7 @@ AIRBASE.Sinai = { ["Cairo_West"] = "Cairo West", ["Damascus_Intl"] = "Damascus Intl", ["Difarsuwar_Airfield"] = "Difarsuwar Airfield", + ["Ein_Shamer"] = "Ein Shamer", ["El_Arish"] = "El Arish", ["El_Gora"] = "El Gora", ["El_Minya"] = "El Minya", @@ -789,8 +810,11 @@ AIRBASE.Sinai = { ["Inshas_Airbase"] = "Inshas Airbase", ["Jiyanklis_Air_Base"] = "Jiyanklis Air Base", ["Kedem"] = "Kedem", + ["Khalkhalah_Air_Base"] = "Khalkhalah Air Base", ["Kibrit_Air_Base"] = "Kibrit Air Base", + ["King_Feisal_Air_Base"] = "King Feisal Air Base", ["Kom_Awshim"] = "Kom Awshim", + ["Megiddo"] = "Megiddo", ["Melez"] = "Melez", ["Mezzeh_Air_Base"] = "Mezzeh Air Base", ["Nevatim"] = "Nevatim", @@ -804,106 +828,123 @@ AIRBASE.Sinai = { ["Sde_Dov"] = "Sde Dov", ["Sharm_El_Sheikh_International_Airport"] = "Sharm El Sheikh International Airport", ["St_Catherine"] = "St Catherine", + ["Taba_International_Airport"] = "Taba International Airport", ["Tabuk"] = "Tabuk", + ["TabukHeliBase"] = "TabukHeliBase", ["Tel_Nof"] = "Tel Nof", ["Wadi_Abu_Rish"] = "Wadi Abu Rish", ["Wadi_al_Jandali"] = "Wadi al Jandali", } --- Airbases of the Kola map --- --- * AIRBASE.Kola.Banak --- * AIRBASE.Kola.Bodo --- * AIRBASE.Kola.Ivalo --- * AIRBASE.Kola.Jokkmokk --- * AIRBASE.Kola.Kalixfors --- * AIRBASE.Kola.Kallax --- * AIRBASE.Kola.Kemi_Tornio --- * AIRBASE.Kola.Kirkenes --- * AIRBASE.Kola.Kiruna --- * AIRBASE.Kola.Kuusamo --- * AIRBASE.Kola.Monchegorsk --- * AIRBASE.Kola.Murmansk_International --- * AIRBASE.Kola.Olenya --- * AIRBASE.Kola.Rovaniemi --- * AIRBASE.Kola.Severomorsk_1 --- * AIRBASE.Kola.Severomorsk_3 --- * AIRBASE.Kola.Vidsel --- * AIRBASE.Kola.Vuojarvi --- * AIRBASE.Kola.Andoya --- * AIRBASE.Kola.Alakurtti --- * AIRBASE.Kola.Kittila --- * AIRBASE.Kola.Bardufoss --- * AIRBASE.Kola.Alta --- * AIRBASE.Kola.Sodankyla --- * AIRBASE.Kola.Enontekio --- * AIRBASE.Kola.Evenes --- * AIRBASE.Kola.Hosio -- --- @field Kola +-- * `AIRBASE.Kola.Afrikanda` Afrikanda +-- * `AIRBASE.Kola.Alakurtti` Alakurtti +-- * `AIRBASE.Kola.Alta` Alta +-- * `AIRBASE.Kola.Andoya` Andoya +-- * `AIRBASE.Kola.Arvidsjaur` Arvidsjaur +-- * `AIRBASE.Kola.Banak` Banak +-- * `AIRBASE.Kola.Bardufoss` Bardufoss +-- * `AIRBASE.Kola.Boden_Heli_Base` Boden Heli Base +-- * `AIRBASE.Kola.Bodo` Bodo +-- * `AIRBASE.Kola.Enontekio` Enontekio +-- * `AIRBASE.Kola.Evenes` Evenes +-- * `AIRBASE.Kola.Hemavan` Hemavan +-- * `AIRBASE.Kola.Hosio` Hosio +-- * `AIRBASE.Kola.Ivalo` Ivalo +-- * `AIRBASE.Kola.Jokkmokk` Jokkmokk +-- * `AIRBASE.Kola.Kalevala` Kalevala +-- * `AIRBASE.Kola.Kalixfors` Kalixfors +-- * `AIRBASE.Kola.Kallax` Kallax +-- * `AIRBASE.Kola.Kemi_Tornio` Kemi Tornio +-- * `AIRBASE.Kola.Kilpyavr` Kilpyavr +-- * `AIRBASE.Kola.Kirkenes` Kirkenes +-- * `AIRBASE.Kola.Kiruna` Kiruna +-- * `AIRBASE.Kola.Kittila` Kittila +-- * `AIRBASE.Kola.Koshka_Yavr` Koshka Yavr +-- * `AIRBASE.Kola.Kuusamo` Kuusamo +-- * `AIRBASE.Kola.Luostari_Pechenga` Luostari Pechenga +-- * `AIRBASE.Kola.Monchegorsk` Monchegorsk +-- * `AIRBASE.Kola.Murmansk_International` Murmansk International +-- * `AIRBASE.Kola.Olenya` Olenya +-- * `AIRBASE.Kola.Poduzhemye` Poduzhemye +-- * `AIRBASE.Kola.Rovaniemi` Rovaniemi +-- * `AIRBASE.Kola.Severomorsk_1` Severomorsk-1 +-- * `AIRBASE.Kola.Severomorsk_3` Severomorsk-3 +-- * `AIRBASE.Kola.Sodankyla` Sodankyla +-- * `AIRBASE.Kola.Vidsel` Vidsel +-- * `AIRBASE.Kola.Vuojarvi` Vuojarvi +-- AIRBASE.Kola = { + ["Afrikanda"] = "Afrikanda", + ["Alakurtti"] = "Alakurtti", + ["Alta"] = "Alta", + ["Andoya"] = "Andoya", + ["Arvidsjaur"] = "Arvidsjaur", ["Banak"] = "Banak", + ["Bardufoss"] = "Bardufoss", + ["Boden_Heli_Base"] = "Boden Heli Base", ["Bodo"] = "Bodo", + ["Enontekio"] = "Enontekio", + ["Evenes"] = "Evenes", + ["Hemavan"] = "Hemavan", + ["Hosio"] = "Hosio", ["Ivalo"] = "Ivalo", ["Jokkmokk"] = "Jokkmokk", + ["Kalevala"] = "Kalevala", ["Kalixfors"] = "Kalixfors", ["Kallax"] = "Kallax", ["Kemi_Tornio"] = "Kemi Tornio", + ["Kilpyavr"] = "Kilpyavr", ["Kirkenes"] = "Kirkenes", ["Kiruna"] = "Kiruna", + ["Kittila"] = "Kittila", + ["Koshka_Yavr"] = "Koshka Yavr", ["Kuusamo"] = "Kuusamo", + ["Luostari_Pechenga"] = "Luostari Pechenga", ["Monchegorsk"] = "Monchegorsk", ["Murmansk_International"] = "Murmansk International", ["Olenya"] = "Olenya", + ["Poduzhemye"] = "Poduzhemye", ["Rovaniemi"] = "Rovaniemi", ["Severomorsk_1"] = "Severomorsk-1", ["Severomorsk_3"] = "Severomorsk-3", + ["Sodankyla"] = "Sodankyla", ["Vidsel"] = "Vidsel", ["Vuojarvi"] = "Vuojarvi", - ["Andoya"] = "Andoya", - ["Alakurtti"] = "Alakurtti", - ["Kittila"] = "Kittila", - ["Bardufoss"] = "Bardufoss", - ["Alta"] = "Alta", - ["Sodankyla"] = "Sodankyla", - ["Enontekio"] = "Enontekio", - ["Evenes"] = "Evenes", - ["Hosio"] = "Hosio", - ["Kilpyavr"] = "Kilpyavr", - ["Afrikanda"] = "Afrikanda", - ["Kalevala"] = "Kalevala", - ["Koshka_Yavr"] = "Koshka Yavr", - ["Poduzhemye"] = "Poduzhemye", - ["Luostari_Pechenga"] = "Luostari Pechenga", } --- Airbases of the Afghanistan map --- --- * AIRBASE.Afghanistan.Bost --- * AIRBASE.Afghanistan.Bagram --- * AIRBASE.Afghanistan.Bamyan --- * AIRBASE.Afghanistan.Camp_Bastion --- * AIRBASE.Afghanistan.Camp_Bastion_Heliport --- * AIRBASE.Afghanistan.Chaghcharan --- * AIRBASE.Afghanistan.Dwyer --- * AIRBASE.Afghanistan.Farah --- * AIRBASE.Afghanistan.Herat --- * AIRBASE.Afghanistan.Gardez --- * AIRBASE.Afghanistan.Ghazni_Heliport --- * AIRBASE.Afghanistan.Jalalabad --- * AIRBASE.Afghanistan.Kabul --- * AIRBASE.Afghanistan.Kandahar --- * AIRBASE.Afghanistan.Kandahar_Heliport --- * AIRBASE.Afghanistan.Khost --- * AIRBASE.Afghanistan.Khost_Heliport --- * AIRBASE.Afghanistan.Maymana_Zahiraddin_Faryabi --- * AIRBASE.Afghanistan.Nimroz --- * AIRBASE.Afghanistan.Qala_i_Naw --- * AIRBASE.Afghanistan.Shindand --- * AIRBASE.Afghanistan.Shindand_Heliport --- * AIRBASE.Afghanistan.Tarinkot --- * AIRBASE.Afghanistan.Urgoon_Heliport --- +-- +-- * `AIRBASE.Afghanistan.Bagram` Bagram +-- * `AIRBASE.Afghanistan.Bamyan` Bamyan +-- * `AIRBASE.Afghanistan.Bost` Bost +-- * `AIRBASE.Afghanistan.Camp_Bastion` Camp Bastion +-- * `AIRBASE.Afghanistan.Camp_Bastion_Heliport` Camp Bastion Heliport +-- * `AIRBASE.Afghanistan.Chaghcharan` Chaghcharan +-- * `AIRBASE.Afghanistan.Dwyer` Dwyer +-- * `AIRBASE.Afghanistan.FOB_Camp_Dubs` FOB Camp Dubs +-- * `AIRBASE.Afghanistan.FOB_Clark` FOB Clark +-- * `AIRBASE.Afghanistan.FOB_Salerno` FOB Salerno +-- * `AIRBASE.Afghanistan.FOB_Thunder` FOB Thunder +-- * `AIRBASE.Afghanistan.Farah` Farah +-- * `AIRBASE.Afghanistan.Gardez` Gardez +-- * `AIRBASE.Afghanistan.Ghazni_Heliport` Ghazni Heliport +-- * `AIRBASE.Afghanistan.Herat` Herat +-- * `AIRBASE.Afghanistan.Jalalabad` Jalalabad +-- * `AIRBASE.Afghanistan.Kabul` Kabul +-- * `AIRBASE.Afghanistan.Kandahar` Kandahar +-- * `AIRBASE.Afghanistan.Kandahar_Heliport` Kandahar Heliport +-- * `AIRBASE.Afghanistan.Khost` Khost +-- * `AIRBASE.Afghanistan.Maymana_Zahiraddin_Faryabi` Maymana Zahiraddin Faryabi +-- * `AIRBASE.Afghanistan.Nimroz` Nimroz +-- * `AIRBASE.Afghanistan.Qala_i_Naw` Qala i Naw +-- * `AIRBASE.Afghanistan.Sharana` Sharana +-- * `AIRBASE.Afghanistan.Shindand` Shindand +-- * `AIRBASE.Afghanistan.Shindand_Heliport` Shindand Heliport +-- * `AIRBASE.Afghanistan.Tarinkot` Tarinkot +-- * `AIRBASE.Afghanistan.Urgoon_Heliport` Urgoon Heliport +-- -- @field Afghanistan AIRBASE.Afghanistan = { ["Bagram"] = "Bagram", @@ -913,6 +954,10 @@ AIRBASE.Afghanistan = { ["Camp_Bastion_Heliport"] = "Camp Bastion Heliport", ["Chaghcharan"] = "Chaghcharan", ["Dwyer"] = "Dwyer", + ["FOB_Camp_Dubs"] = "FOB Camp Dubs", + ["FOB_Clark"] = "FOB Clark", + ["FOB_Salerno"] = "FOB Salerno", + ["FOB_Thunder"] = "FOB Thunder", ["Farah"] = "Farah", ["Gardez"] = "Gardez", ["Ghazni_Heliport"] = "Ghazni Heliport", @@ -922,7 +967,6 @@ AIRBASE.Afghanistan = { ["Kandahar"] = "Kandahar", ["Kandahar_Heliport"] = "Kandahar Heliport", ["Khost"] = "Khost", - ["Khost_Heliport"] = "Khost Heliport", ["Maymana_Zahiraddin_Faryabi"] = "Maymana Zahiraddin Faryabi", ["Nimroz"] = "Nimroz", ["Qala_i_Naw"] = "Qala i Naw", @@ -935,26 +979,25 @@ AIRBASE.Afghanistan = { --- Airbases of the Iraq map -- --- * AIRBASE.Iraq.Al_Asad_Airbase --- * AIRBASE.Iraq.Al_Kut_Airbase --- * AIRBASE.Iraq.Al_Sahra_Airport --- * AIRBASE.Iraq.Al_Salam_Airbase --- * AIRBASE.Iraq.Al_Taji_Airport --- * AIRBASE.Iraq.Al_Taquddum_Airport --- * AIRBASE.Iraq.Baghdad_International_Airport --- * AIRBASE.Iraq.Balad_Airbase --- * AIRBASE.Iraq.Bashur_Airport --- * AIRBASE.Iraq.Erbil_International_Airport --- * AIRBASE.Iraq.Sulaimaniyah_International_Airport --- * AIRBASE.Iraq.H2_Airbase --- * AIRBASE.Iraq.H3_Main_Airbase --- * AIRBASE.Iraq.H3_Northwest_Airbase --- * AIRBASE.Iraq.H3_Southwest_Airbase --- * AIRBASE.Iraq.K1_Base --- * AIRBASE.Iraq.Kirkuk_International_Airport --- * AIRBASE.Iraq.Mosul_International_Airport --- * AIRBASE.Iraq.Qayyarah_Airfield_West --- * AIRBASE.Iraq.Sulaimaniyah_International_Airport +-- * `AIRBASE.Iraq.Al_Asad_Airbase` Al-Asad Airbase +-- * `AIRBASE.Iraq.Al_Kut_Airport` Al-Kut Airport +-- * `AIRBASE.Iraq.Al_Sahra_Airport` Al-Sahra Airport +-- * `AIRBASE.Iraq.Al_Salam_Airbase` Al-Salam Airbase +-- * `AIRBASE.Iraq.Al_Taji_Airport` Al-Taji Airport +-- * `AIRBASE.Iraq.Al_Taquddum_Airport` Al-Taquddum Airport +-- * `AIRBASE.Iraq.Baghdad_International_Airport` Baghdad International Airport +-- * `AIRBASE.Iraq.Balad_Airbase` Balad Airbase +-- * `AIRBASE.Iraq.Bashur_Airport` Bashur Airport +-- * `AIRBASE.Iraq.Erbil_International_Airport` Erbil International Airport +-- * `AIRBASE.Iraq.H_2_Airbase` H-2 Airbase +-- * `AIRBASE.Iraq.H_3_Main_Airbase` H-3 Main Airbase +-- * `AIRBASE.Iraq.H_3_Northwest_Airbase` H-3 Northwest Airbase +-- * `AIRBASE.Iraq.H_3_Southwest_Airbase` H-3 Southwest Airbase +-- * `AIRBASE.Iraq.K1_Base` K1 Base +-- * `AIRBASE.Iraq.Kirkuk_International_Airport` Kirkuk International Airport +-- * `AIRBASE.Iraq.Mosul_International_Airport` Mosul International Airport +-- * `AIRBASE.Iraq.Qayyarah_Airfield_West` Qayyarah Airfield West +-- * `AIRBASE.Iraq.Sulaimaniyah_International_Airport` Sulaimaniyah International Airport -- -- @field Iraq AIRBASE.Iraq = { @@ -968,10 +1011,10 @@ AIRBASE.Iraq = { ["Balad_Airbase"] = "Balad Airbase", ["Bashur_Airport"] = "Bashur Airport", ["Erbil_International_Airport"] = "Erbil International Airport", - ["H2_Airbase"] = "H-2 Airbase", - ["H3_Main_Airbase"] = "H-3 Main Airbase", - ["H3_Northwest_Airbase"] = "H-3 Northwest Airbase", - ["H3_Southwest_Airbase"] = "H-3 Southwest Airbase", + ["H_2_Airbase"] = "H-2 Airbase", + ["H_3_Main_Airbase"] = "H-3 Main Airbase", + ["H_3_Northwest_Airbase"] = "H-3 Northwest Airbase", + ["H_3_Southwest_Airbase"] = "H-3 Southwest Airbase", ["K1_Base"] = "K1 Base", ["Kirkuk_International_Airport"] = "Kirkuk International Airport", ["Mosul_International_Airport"] = "Mosul International Airport", @@ -980,212 +1023,239 @@ AIRBASE.Iraq = { } ---- Airbases of the Germany Cold War map --- * AIRBASE.GermanyCW.Airracing_Frankfurt --- * AIRBASE.GermanyCW.Airracing_Frankfurt --- * AIRBASE.GermanyCW.Airracing_Koblenz --- * AIRBASE.GermanyCW.Airracing_Luebeck --- * AIRBASE.GermanyCW.Allstedt --- * AIRBASE.GermanyCW.Altes_Lager --- * AIRBASE.GermanyCW.Bad_Duerkheim --- * AIRBASE.GermanyCW.Barth --- * AIRBASE.GermanyCW.Bienenfarm --- * AIRBASE.GermanyCW.Bindersleben --- * AIRBASE.GermanyCW.Bitburg --- * AIRBASE.GermanyCW.Braunschweig --- * AIRBASE.GermanyCW.Bremen --- * AIRBASE.GermanyCW.Briest --- * AIRBASE.GermanyCW.Buechel --- * AIRBASE.GermanyCW.Bueckeburg --- * AIRBASE.GermanyCW.Celle --- * AIRBASE.GermanyCW.Cochstedt --- * AIRBASE.GermanyCW.Damgarten --- * AIRBASE.GermanyCW.Dedelow --- * AIRBASE.GermanyCW.Dessau --- * AIRBASE.GermanyCW.Fassberg --- * AIRBASE.GermanyCW.Finow --- * AIRBASE.GermanyCW.Frankfurt --- * AIRBASE.GermanyCW.Fritzlar --- * AIRBASE.GermanyCW.Fulda --- * AIRBASE.GermanyCW.Gardelegen --- * AIRBASE.GermanyCW.Garz --- * AIRBASE.GermanyCW.Gatow --- * AIRBASE.GermanyCW.Gelnhausen --- * AIRBASE.GermanyCW.Giebelstadt --- * AIRBASE.GermanyCW.Glindbruchkippe --- * AIRBASE.GermanyCW.Gross_Mohrdorf --- * AIRBASE.GermanyCW.Grosse_Wiese --- * AIRBASE.GermanyCW.Guetersloh --- * AIRBASE.GermanyCW.H_FRG_01 --- * AIRBASE.GermanyCW.H_FRG_02 --- * AIRBASE.GermanyCW.H_FRG_03 --- * AIRBASE.GermanyCW.H_FRG_04 --- * AIRBASE.GermanyCW.H_FRG_05 --- * AIRBASE.GermanyCW.H_FRG_06 --- * AIRBASE.GermanyCW.H_FRG_07 --- * AIRBASE.GermanyCW.H_FRG_08 --- * AIRBASE.GermanyCW.H_FRG_09 --- * AIRBASE.GermanyCW.H_FRG_10 --- * AIRBASE.GermanyCW.H_FRG_11 --- * AIRBASE.GermanyCW.H_FRG_12 --- * AIRBASE.GermanyCW.H_FRG_13 --- * AIRBASE.GermanyCW.H_FRG_14 --- * AIRBASE.GermanyCW.H_FRG_15 --- * AIRBASE.GermanyCW.H_FRG_16 --- * AIRBASE.GermanyCW.H_FRG_17 --- * AIRBASE.GermanyCW.H_FRG_18 --- * AIRBASE.GermanyCW.H_FRG_19 --- * AIRBASE.GermanyCW.H_FRG_20 --- * AIRBASE.GermanyCW.H_FRG_21 --- * AIRBASE.GermanyCW.H_FRG_23 --- * AIRBASE.GermanyCW.H_FRG_25 --- * AIRBASE.GermanyCW.H_FRG_27 --- * AIRBASE.GermanyCW.H_FRG_30 --- * AIRBASE.GermanyCW.H_FRG_31 --- * AIRBASE.GermanyCW.H_FRG_32 --- * AIRBASE.GermanyCW.H_FRG_34 --- * AIRBASE.GermanyCW.H_FRG_38 --- * AIRBASE.GermanyCW.H_FRG_39 --- * AIRBASE.GermanyCW.H_FRG_40 --- * AIRBASE.GermanyCW.H_FRG_41 --- * AIRBASE.GermanyCW.H_FRG_42 --- * AIRBASE.GermanyCW.H_FRG_43 --- * AIRBASE.GermanyCW.H_FRG_44 --- * AIRBASE.GermanyCW.H_FRG_45 --- * AIRBASE.GermanyCW.H_FRG_46 --- * AIRBASE.GermanyCW.H_FRG_47 --- * AIRBASE.GermanyCW.H_FRG_48 --- * AIRBASE.GermanyCW.H_FRG_49 --- * AIRBASE.GermanyCW.H_FRG_50 --- * AIRBASE.GermanyCW.H_FRG_51 --- * AIRBASE.GermanyCW.H_GDR_01 --- * AIRBASE.GermanyCW.H_GDR_02 --- * AIRBASE.GermanyCW.H_GDR_03 --- * AIRBASE.GermanyCW.H_GDR_04 --- * AIRBASE.GermanyCW.H_GDR_05 --- * AIRBASE.GermanyCW.H_GDR_06 --- * AIRBASE.GermanyCW.H_GDR_07 --- * AIRBASE.GermanyCW.H_GDR_08 --- * AIRBASE.GermanyCW.H_GDR_09 --- * AIRBASE.GermanyCW.H_GDR_10 --- * AIRBASE.GermanyCW.H_GDR_11 --- * AIRBASE.GermanyCW.H_GDR_12 --- * AIRBASE.GermanyCW.H_GDR_13 --- * AIRBASE.GermanyCW.H_GDR_14 --- * AIRBASE.GermanyCW.H_GDR_15 --- * AIRBASE.GermanyCW.H_GDR_16 --- * AIRBASE.GermanyCW.H_GDR_17 --- * AIRBASE.GermanyCW.H_GDR_18 --- * AIRBASE.GermanyCW.H_GDR_19 --- * AIRBASE.GermanyCW.H_GDR_21 --- * AIRBASE.GermanyCW.H_GDR_22 --- * AIRBASE.GermanyCW.H_GDR_24 --- * AIRBASE.GermanyCW.H_GDR_25 --- * AIRBASE.GermanyCW.H_GDR_26 --- * AIRBASE.GermanyCW.H_GDR_30 --- * AIRBASE.GermanyCW.H_GDR_31 --- * AIRBASE.GermanyCW.H_GDR_32 --- * AIRBASE.GermanyCW.H_GDR_33 --- * AIRBASE.GermanyCW.H_GDR_34 --- * AIRBASE.GermanyCW.H_Med_FRG_01 --- * AIRBASE.GermanyCW.H_Med_FRG_02 --- * AIRBASE.GermanyCW.H_Med_FRG_04 --- * AIRBASE.GermanyCW.H_Med_FRG_06 --- * AIRBASE.GermanyCW.H_Med_FRG_11 --- * AIRBASE.GermanyCW.H_Med_FRG_12 --- * AIRBASE.GermanyCW.H_Med_FRG_13 --- * AIRBASE.GermanyCW.H_Med_FRG_14 --- * AIRBASE.GermanyCW.H_Med_FRG_15 --- * AIRBASE.GermanyCW.H_Med_FRG_16 --- * AIRBASE.GermanyCW.H_Med_FRG_17 --- * AIRBASE.GermanyCW.H_Med_FRG_21 --- * AIRBASE.GermanyCW.H_Med_FRG_24 --- * AIRBASE.GermanyCW.H_Med_FRG_26 --- * AIRBASE.GermanyCW.H_Med_FRG_27 --- * AIRBASE.GermanyCW.H_Med_FRG_29 --- * AIRBASE.GermanyCW.H_Med_GDR_01 --- * AIRBASE.GermanyCW.H_Med_GDR_02 --- * AIRBASE.GermanyCW.H_Med_GDR_03 --- * AIRBASE.GermanyCW.H_Med_GDR_08 --- * AIRBASE.GermanyCW.H_Med_GDR_09 --- * AIRBASE.GermanyCW.H_Med_GDR_10 --- * AIRBASE.GermanyCW.H_Med_GDR_11 --- * AIRBASE.GermanyCW.H_Med_GDR_12 --- * AIRBASE.GermanyCW.H_Med_GDR_13 --- * AIRBASE.GermanyCW.H_Med_GDR_14 --- * AIRBASE.GermanyCW.H_Med_GDR_16 --- * AIRBASE.GermanyCW.H_Radar_FRG_02 --- * AIRBASE.GermanyCW.H_Radar_GDR_01 --- * AIRBASE.GermanyCW.H_Radar_GDR_02 --- * AIRBASE.GermanyCW.H_Radar_GDR_03 --- * AIRBASE.GermanyCW.H_Radar_GDR_04 --- * AIRBASE.GermanyCW.H_Radar_GDR_05 --- * AIRBASE.GermanyCW.H_Radar_GDR_06 --- * AIRBASE.GermanyCW.H_Radar_GDR_07 --- * AIRBASE.GermanyCW.H_Radar_GDR_08 --- * AIRBASE.GermanyCW.H_Radar_GDR_09 --- * AIRBASE.GermanyCW.Hahn --- * AIRBASE.GermanyCW.Haina --- * AIRBASE.GermanyCW.Hamburg --- * AIRBASE.GermanyCW.Hamburg_Finkenwerder --- * AIRBASE.GermanyCW.Hannover --- * AIRBASE.GermanyCW.Hasselfelde --- * AIRBASE.GermanyCW.Herrenteich --- * AIRBASE.GermanyCW.Hildesheim --- * AIRBASE.GermanyCW.Hockenheim --- * AIRBASE.GermanyCW.Holzdorf --- * AIRBASE.GermanyCW.Kammermark --- * AIRBASE.GermanyCW.Koethen --- * AIRBASE.GermanyCW.Laage --- * AIRBASE.GermanyCW.Langenselbold --- * AIRBASE.GermanyCW.Laerz --- * AIRBASE.GermanyCW.Leipzig_Halle --- * AIRBASE.GermanyCW.Leipzig_Mockau --- * AIRBASE.GermanyCW.Luebeck --- * AIRBASE.GermanyCW.Lueneburg --- * AIRBASE.GermanyCW.Mahlwinkel --- * AIRBASE.GermanyCW.Mendig --- * AIRBASE.GermanyCW.Merseburg --- * AIRBASE.GermanyCW.Neubrandenburg --- * AIRBASE.GermanyCW.Neuruppin --- * AIRBASE.GermanyCW.Northeim --- * AIRBASE.GermanyCW.Ober_Moerlen --- * AIRBASE.GermanyCW.Obermehler_Schlotheim --- * AIRBASE.GermanyCW.Parchim --- * AIRBASE.GermanyCW.Peenemuende --- * AIRBASE.GermanyCW.Pferdsfeld --- * AIRBASE.GermanyCW.Pinnow --- * AIRBASE.GermanyCW.Pottschutthoehe --- * AIRBASE.GermanyCW.Ramstein --- * AIRBASE.GermanyCW.Rinteln --- * AIRBASE.GermanyCW.Schoenefeld --- * AIRBASE.GermanyCW.Schweinfurt --- * AIRBASE.GermanyCW.Sembach --- * AIRBASE.GermanyCW.Spangdahlem --- * AIRBASE.GermanyCW.Sperenberg --- * AIRBASE.GermanyCW.Stendal --- * AIRBASE.GermanyCW.Tegel --- * AIRBASE.GermanyCW.Tempelhof --- * AIRBASE.GermanyCW.Templin --- * AIRBASE.GermanyCW.Tutow --- * AIRBASE.GermanyCW.Uelzen --- * AIRBASE.GermanyCW.Uetersen --- * AIRBASE.GermanyCW.Ummern --- * AIRBASE.GermanyCW.Verden_Scharnhorst --- * AIRBASE.GermanyCW.Walldorf --- * AIRBASE.GermanyCW.Waren_Vielist --- * AIRBASE.GermanyCW.Werneuchen --- * AIRBASE.GermanyCW.Weser_Wuemme --- * AIRBASE.GermanyCW.Wiesbaden --- * AIRBASE.GermanyCW.Wismar --- * AIRBASE.GermanyCW.Wittstock --- * AIRBASE.GermanyCW.Worms --- * AIRBASE.GermanyCW.Wunstorf --- * AIRBASE.GermanyCW.Zerbst --- * AIRBASE.GermanyCW.Zweibruecken +--- Airbases of the GermanyCW map +-- +-- * `AIRBASE.GermanyCW.Adelsheim` Adelsheim +-- * `AIRBASE.GermanyCW.Airracing_Frankfurt` Airracing Frankfurt +-- * `AIRBASE.GermanyCW.Airracing_Koblenz` Airracing Koblenz +-- * `AIRBASE.GermanyCW.Airracing_Luebeck` Airracing Lubeck +-- * `AIRBASE.GermanyCW.Allstedt` Allstedt +-- * `AIRBASE.GermanyCW.Altes_Lager` Altes Lager +-- * `AIRBASE.GermanyCW.Bad_Duerkheim` Bad Durkheim +-- * `AIRBASE.GermanyCW.Barth` Barth +-- * `AIRBASE.GermanyCW.Bienenfarm` Bienenfarm +-- * `AIRBASE.GermanyCW.Bindersleben` Bindersleben +-- * `AIRBASE.GermanyCW.Bitburg` Bitburg +-- * `AIRBASE.GermanyCW.Bornholm` Bornholm +-- * `AIRBASE.GermanyCW.Brand` Brand +-- * `AIRBASE.GermanyCW.Brandis` Brandis +-- * `AIRBASE.GermanyCW.Braunschweig` Braunschweig +-- * `AIRBASE.GermanyCW.Bremen` Bremen +-- * `AIRBASE.GermanyCW.Briest` Briest +-- * `AIRBASE.GermanyCW.Buechel` Buchel +-- * `AIRBASE.GermanyCW.Bueckeburg` Buckeburg +-- * `AIRBASE.GermanyCW.Celle` Celle +-- * `AIRBASE.GermanyCW.Chojna` Chojna +-- * `AIRBASE.GermanyCW.Cochstedt` Cochstedt +-- * `AIRBASE.GermanyCW.Cologne` Cologne +-- * `AIRBASE.GermanyCW.Damgarten` Damgarten +-- * `AIRBASE.GermanyCW.Dedelow` Dedelow +-- * `AIRBASE.GermanyCW.Dessau` Dessau +-- * `AIRBASE.GermanyCW.Duesseldorf` Dusseldorf +-- * `AIRBASE.GermanyCW.Falkenberg` Falkenberg +-- * `AIRBASE.GermanyCW.Fassberg` Fassberg +-- * `AIRBASE.GermanyCW.Finow` Finow +-- * `AIRBASE.GermanyCW.Frankfurt` Frankfurt +-- * `AIRBASE.GermanyCW.Fritzlar` Fritzlar +-- * `AIRBASE.GermanyCW.Fulda` Fulda +-- * `AIRBASE.GermanyCW.Gardelegen` Gardelegen +-- * `AIRBASE.GermanyCW.Garz` Garz +-- * `AIRBASE.GermanyCW.Gatow` Gatow +-- * `AIRBASE.GermanyCW.Gelnhausen` Gelnhausen +-- * `AIRBASE.GermanyCW.Giebelstadt` Giebelstadt +-- * `AIRBASE.GermanyCW.Glindbruchkippe` Glindbruchkippe +-- * `AIRBASE.GermanyCW.Gross_Mohrdorf` Gross Mohrdorf +-- * `AIRBASE.GermanyCW.Grosse_Wiese` Grosse Wiese +-- * `AIRBASE.GermanyCW.Guetersloh` Gutersloh +-- * `AIRBASE.GermanyCW.H_FRG_01` H FRG 01 +-- * `AIRBASE.GermanyCW.H_FRG_02` H FRG 02 +-- * `AIRBASE.GermanyCW.H_FRG_03` H FRG 03 +-- * `AIRBASE.GermanyCW.H_FRG_04` H FRG 04 +-- * `AIRBASE.GermanyCW.H_FRG_05` H FRG 05 +-- * `AIRBASE.GermanyCW.H_FRG_06` H FRG 06 +-- * `AIRBASE.GermanyCW.H_FRG_07` H FRG 07 +-- * `AIRBASE.GermanyCW.H_FRG_08` H FRG 08 +-- * `AIRBASE.GermanyCW.H_FRG_09` H FRG 09 +-- * `AIRBASE.GermanyCW.H_FRG_10` H FRG 10 +-- * `AIRBASE.GermanyCW.H_FRG_11` H FRG 11 +-- * `AIRBASE.GermanyCW.H_FRG_12` H FRG 12 +-- * `AIRBASE.GermanyCW.H_FRG_13` H FRG 13 +-- * `AIRBASE.GermanyCW.H_FRG_14` H FRG 14 +-- * `AIRBASE.GermanyCW.H_FRG_15` H FRG 15 +-- * `AIRBASE.GermanyCW.H_FRG_16` H FRG 16 +-- * `AIRBASE.GermanyCW.H_FRG_17` H FRG 17 +-- * `AIRBASE.GermanyCW.H_FRG_18` H FRG 18 +-- * `AIRBASE.GermanyCW.H_FRG_19` H FRG 19 +-- * `AIRBASE.GermanyCW.H_FRG_20` H FRG 20 +-- * `AIRBASE.GermanyCW.H_FRG_21` H FRG 21 +-- * `AIRBASE.GermanyCW.H_FRG_23` H FRG 23 +-- * `AIRBASE.GermanyCW.H_FRG_25` H FRG 25 +-- * `AIRBASE.GermanyCW.H_FRG_27` H FRG 27 +-- * `AIRBASE.GermanyCW.H_FRG_30` H FRG 30 +-- * `AIRBASE.GermanyCW.H_FRG_31` H FRG 31 +-- * `AIRBASE.GermanyCW.H_FRG_32` H FRG 32 +-- * `AIRBASE.GermanyCW.H_FRG_34` H FRG 34 +-- * `AIRBASE.GermanyCW.H_FRG_38` H FRG 38 +-- * `AIRBASE.GermanyCW.H_FRG_39` H FRG 39 +-- * `AIRBASE.GermanyCW.H_FRG_40` H FRG 40 +-- * `AIRBASE.GermanyCW.H_FRG_41` H FRG 41 +-- * `AIRBASE.GermanyCW.H_FRG_42` H FRG 42 +-- * `AIRBASE.GermanyCW.H_FRG_43` H FRG 43 +-- * `AIRBASE.GermanyCW.H_FRG_44` H FRG 44 +-- * `AIRBASE.GermanyCW.H_FRG_45` H FRG 45 +-- * `AIRBASE.GermanyCW.H_FRG_46` H FRG 46 +-- * `AIRBASE.GermanyCW.H_FRG_47` H FRG 47 +-- * `AIRBASE.GermanyCW.H_FRG_48` H FRG 48 +-- * `AIRBASE.GermanyCW.H_FRG_49` H FRG 49 +-- * `AIRBASE.GermanyCW.H_FRG_50` H FRG 50 +-- * `AIRBASE.GermanyCW.H_FRG_51` H FRG 51 +-- * `AIRBASE.GermanyCW.H_GDR_01` H GDR 01 +-- * `AIRBASE.GermanyCW.H_GDR_02` H GDR 02 +-- * `AIRBASE.GermanyCW.H_GDR_03` H GDR 03 +-- * `AIRBASE.GermanyCW.H_GDR_04` H GDR 04 +-- * `AIRBASE.GermanyCW.H_GDR_05` H GDR 05 +-- * `AIRBASE.GermanyCW.H_GDR_06` H GDR 06 +-- * `AIRBASE.GermanyCW.H_GDR_07` H GDR 07 +-- * `AIRBASE.GermanyCW.H_GDR_08` H GDR 08 +-- * `AIRBASE.GermanyCW.H_GDR_09` H GDR 09 +-- * `AIRBASE.GermanyCW.H_GDR_10` H GDR 10 +-- * `AIRBASE.GermanyCW.H_GDR_11` H GDR 11 +-- * `AIRBASE.GermanyCW.H_GDR_12` H GDR 12 +-- * `AIRBASE.GermanyCW.H_GDR_13` H GDR 13 +-- * `AIRBASE.GermanyCW.H_GDR_14` H GDR 14 +-- * `AIRBASE.GermanyCW.H_GDR_15` H GDR 15 +-- * `AIRBASE.GermanyCW.H_GDR_16` H GDR 16 +-- * `AIRBASE.GermanyCW.H_GDR_17` H GDR 17 +-- * `AIRBASE.GermanyCW.H_GDR_18` H GDR 18 +-- * `AIRBASE.GermanyCW.H_GDR_19` H GDR 19 +-- * `AIRBASE.GermanyCW.H_GDR_21` H GDR 21 +-- * `AIRBASE.GermanyCW.H_GDR_22` H GDR 22 +-- * `AIRBASE.GermanyCW.H_GDR_24` H GDR 24 +-- * `AIRBASE.GermanyCW.H_GDR_25` H GDR 25 +-- * `AIRBASE.GermanyCW.H_GDR_26` H GDR 26 +-- * `AIRBASE.GermanyCW.H_GDR_30` H GDR 30 +-- * `AIRBASE.GermanyCW.H_GDR_31` H GDR 31 +-- * `AIRBASE.GermanyCW.H_GDR_32` H GDR 32 +-- * `AIRBASE.GermanyCW.H_GDR_33` H GDR 33 +-- * `AIRBASE.GermanyCW.H_GDR_34` H GDR 34 +-- * `AIRBASE.GermanyCW.H_Med_FRG_01` H Med FRG 01 +-- * `AIRBASE.GermanyCW.H_Med_FRG_02` H Med FRG 02 +-- * `AIRBASE.GermanyCW.H_Med_FRG_04` H Med FRG 04 +-- * `AIRBASE.GermanyCW.H_Med_FRG_06` H Med FRG 06 +-- * `AIRBASE.GermanyCW.H_Med_FRG_11` H Med FRG 11 +-- * `AIRBASE.GermanyCW.H_Med_FRG_12` H Med FRG 12 +-- * `AIRBASE.GermanyCW.H_Med_FRG_13` H Med FRG 13 +-- * `AIRBASE.GermanyCW.H_Med_FRG_14` H Med FRG 14 +-- * `AIRBASE.GermanyCW.H_Med_FRG_15` H Med FRG 15 +-- * `AIRBASE.GermanyCW.H_Med_FRG_16` H Med FRG 16 +-- * `AIRBASE.GermanyCW.H_Med_FRG_17` H Med FRG 17 +-- * `AIRBASE.GermanyCW.H_Med_FRG_21` H Med FRG 21 +-- * `AIRBASE.GermanyCW.H_Med_FRG_24` H Med FRG 24 +-- * `AIRBASE.GermanyCW.H_Med_FRG_26` H Med FRG 26 +-- * `AIRBASE.GermanyCW.H_Med_FRG_27` H Med FRG 27 +-- * `AIRBASE.GermanyCW.H_Med_FRG_29` H Med FRG 29 +-- * `AIRBASE.GermanyCW.H_Med_GDR_01` H Med GDR 01 +-- * `AIRBASE.GermanyCW.H_Med_GDR_02` H Med GDR 02 +-- * `AIRBASE.GermanyCW.H_Med_GDR_03` H Med GDR 03 +-- * `AIRBASE.GermanyCW.H_Med_GDR_08` H Med GDR 08 +-- * `AIRBASE.GermanyCW.H_Med_GDR_09` H Med GDR 09 +-- * `AIRBASE.GermanyCW.H_Med_GDR_10` H Med GDR 10 +-- * `AIRBASE.GermanyCW.H_Med_GDR_11` H Med GDR 11 +-- * `AIRBASE.GermanyCW.H_Med_GDR_12` H Med GDR 12 +-- * `AIRBASE.GermanyCW.H_Med_GDR_13` H Med GDR 13 +-- * `AIRBASE.GermanyCW.H_Med_GDR_14` H Med GDR 14 +-- * `AIRBASE.GermanyCW.H_Med_GDR_16` H Med GDR 16 +-- * `AIRBASE.GermanyCW.H_Radar_FRG_02` H Radar FRG 02 +-- * `AIRBASE.GermanyCW.H_Radar_GDR_01` H Radar GDR 01 +-- * `AIRBASE.GermanyCW.H_Radar_GDR_02` H Radar GDR 02 +-- * `AIRBASE.GermanyCW.H_Radar_GDR_03` H Radar GDR 03 +-- * `AIRBASE.GermanyCW.H_Radar_GDR_04` H Radar GDR 04 +-- * `AIRBASE.GermanyCW.H_Radar_GDR_05` H Radar GDR 05 +-- * `AIRBASE.GermanyCW.H_Radar_GDR_06` H Radar GDR 06 +-- * `AIRBASE.GermanyCW.H_Radar_GDR_07` H Radar GDR 07 +-- * `AIRBASE.GermanyCW.H_Radar_GDR_08` H Radar GDR 08 +-- * `AIRBASE.GermanyCW.H_Radar_GDR_09` H Radar GDR 09 +-- * `AIRBASE.GermanyCW.Hahn` Hahn +-- * `AIRBASE.GermanyCW.Haina` Haina +-- * `AIRBASE.GermanyCW.Hamburg` Hamburg +-- * `AIRBASE.GermanyCW.Hamburg_Finkenwerder` Hamburg Finkenwerder +-- * `AIRBASE.GermanyCW.Hannover` Hannover +-- * `AIRBASE.GermanyCW.Hasselfelde` Hasselfelde +-- * `AIRBASE.GermanyCW.Heidelberg` Heidelberg +-- * `AIRBASE.GermanyCW.Herrenteich` Herrenteich +-- * `AIRBASE.GermanyCW.Hildesheim` Hildesheim +-- * `AIRBASE.GermanyCW.Hockenheim` Hockenheim +-- * `AIRBASE.GermanyCW.Holzdorf` Holzdorf +-- * `AIRBASE.GermanyCW.Kammermark` Kammermark +-- * `AIRBASE.GermanyCW.Kastrup` Kastrup +-- * `AIRBASE.GermanyCW.Kiel` Kiel +-- * `AIRBASE.GermanyCW.Koethen` Kothen +-- * `AIRBASE.GermanyCW.Laage` Laage +-- * `AIRBASE.GermanyCW.Landstuhl` Landstuhl +-- * `AIRBASE.GermanyCW.Langenselbold` Langenselbold +-- * `AIRBASE.GermanyCW.Laerz` Larz +-- * `AIRBASE.GermanyCW.Leipzig_Mockau` Leipzig Mockau +-- * `AIRBASE.GermanyCW.Luebeck` Lubeck +-- * `AIRBASE.GermanyCW.Lueneburg` Luneburg +-- * `AIRBASE.GermanyCW.Mahlwinkel` Mahlwinkel +-- * `AIRBASE.GermanyCW.Mainz_Finthen` Mainz Finthen +-- * `AIRBASE.GermanyCW.Marxwalde` Marxwalde +-- * `AIRBASE.GermanyCW.Mendig` Mendig +-- * `AIRBASE.GermanyCW.Merseburg` Merseburg +-- * `AIRBASE.GermanyCW.Neubrandenburg` Neubrandenburg +-- * `AIRBASE.GermanyCW.Neuruppin` Neuruppin +-- * `AIRBASE.GermanyCW.Nordholz` Nordholz +-- * `AIRBASE.GermanyCW.Northeim` Northeim +-- * `AIRBASE.GermanyCW.Noervenich` Norvenich +-- * `AIRBASE.GermanyCW.Ober_Moerlen` Ober-Morlen +-- * `AIRBASE.GermanyCW.Obermehler_Schlotheim` Obermehler Schlotheim +-- * `AIRBASE.GermanyCW.Oranienburg` Oranienburg +-- * `AIRBASE.GermanyCW.Parchim` Parchim +-- * `AIRBASE.GermanyCW.Peenemuende` Peenemunde +-- * `AIRBASE.GermanyCW.Perwenitz` Perwenitz +-- * `AIRBASE.GermanyCW.Pferdsfeld` Pferdsfeld +-- * `AIRBASE.GermanyCW.Pinnow` Pinnow +-- * `AIRBASE.GermanyCW.Pottschutthoehe` Pottschutthohe +-- * `AIRBASE.GermanyCW.Ramstein` Ramstein +-- * `AIRBASE.GermanyCW.Revinge` Revinge +-- * `AIRBASE.GermanyCW.Rinteln` Rinteln +-- * `AIRBASE.GermanyCW.Schkeuditz` Schkeuditz +-- * `AIRBASE.GermanyCW.Schoenefeld` Schonefeld +-- * `AIRBASE.GermanyCW.Schweinfurt` Schweinfurt +-- * `AIRBASE.GermanyCW.Sembach` Sembach +-- * `AIRBASE.GermanyCW.Sittensen` Sittensen +-- * `AIRBASE.GermanyCW.Spangdahlem` Spangdahlem +-- * `AIRBASE.GermanyCW.Sperenberg` Sperenberg +-- * `AIRBASE.GermanyCW.Sprendlingen` Sprendlingen +-- * `AIRBASE.GermanyCW.Stendal` Stendal +-- * `AIRBASE.GermanyCW.Sturup` Sturup +-- * `AIRBASE.GermanyCW.Szczecin_Goleniow` Szczecin-Goleniow +-- * `AIRBASE.GermanyCW.Tagra` Tagra +-- * `AIRBASE.GermanyCW.Tegel` Tegel +-- * `AIRBASE.GermanyCW.Tempelhof` Tempelhof +-- * `AIRBASE.GermanyCW.Templin` Templin +-- * `AIRBASE.GermanyCW.Thurland` Thurland +-- * `AIRBASE.GermanyCW.Tutow` Tutow +-- * `AIRBASE.GermanyCW.Uelzen` Uelzen +-- * `AIRBASE.GermanyCW.Uetersen` Uetersen +-- * `AIRBASE.GermanyCW.Ummern` Ummern +-- * `AIRBASE.GermanyCW.Verden_Scharnhorst` Verden-Scharnhorst +-- * `AIRBASE.GermanyCW.Walldorf` Walldorf +-- * `AIRBASE.GermanyCW.Waren_Vielist` Waren Vielist +-- * `AIRBASE.GermanyCW.Werneuchen` Werneuchen +-- * `AIRBASE.GermanyCW.Weser_Wuemme` Weser Wumme +-- * `AIRBASE.GermanyCW.Wiesbaden` Wiesbaden +-- * `AIRBASE.GermanyCW.Wismar` Wismar +-- * `AIRBASE.GermanyCW.Wittstock` Wittstock +-- * `AIRBASE.GermanyCW.Worms` Worms +-- * `AIRBASE.GermanyCW.Wunstorf` Wunstorf +-- * `AIRBASE.GermanyCW.Zerbst` Zerbst +-- * `AIRBASE.GermanyCW.Zoellschen` Zollschen +-- * `AIRBASE.GermanyCW.Zweibruecken` Zweibrucken -- -- @field GermanyCW AIRBASE.GermanyCW = { + ["Adelsheim"] = "Adelsheim", ["Airracing_Frankfurt"] = "Airracing Frankfurt", ["Airracing_Koblenz"] = "Airracing Koblenz", ["Airracing_Luebeck"] = "Airracing Lubeck", @@ -1196,16 +1266,23 @@ AIRBASE.GermanyCW = { ["Bienenfarm"] = "Bienenfarm", ["Bindersleben"] = "Bindersleben", ["Bitburg"] = "Bitburg", + ["Bornholm"] = "Bornholm", + ["Brand"] = "Brand", + ["Brandis"] = "Brandis", ["Braunschweig"] = "Braunschweig", ["Bremen"] = "Bremen", ["Briest"] = "Briest", ["Buechel"] = "Buchel", ["Bueckeburg"] = "Buckeburg", ["Celle"] = "Celle", + ["Chojna"] = "Chojna", ["Cochstedt"] = "Cochstedt", + ["Cologne"] = "Cologne", ["Damgarten"] = "Damgarten", ["Dedelow"] = "Dedelow", ["Dessau"] = "Dessau", + ["Duesseldorf"] = "Dusseldorf", + ["Falkenberg"] = "Falkenberg", ["Fassberg"] = "Fassberg", ["Finow"] = "Finow", ["Frankfurt"] = "Frankfurt", @@ -1216,7 +1293,7 @@ AIRBASE.GermanyCW = { ["Gatow"] = "Gatow", ["Gelnhausen"] = "Gelnhausen", ["Giebelstadt"] = "Giebelstadt", - ["Glindbruchkippe"] = "Glindbruchkippe ", + ["Glindbruchkippe"] = "Glindbruchkippe", ["Gross_Mohrdorf"] = "Gross Mohrdorf", ["Grosse_Wiese"] = "Grosse Wiese", ["Guetersloh"] = "Gutersloh", @@ -1334,43 +1411,60 @@ AIRBASE.GermanyCW = { ["Hamburg_Finkenwerder"] = "Hamburg Finkenwerder", ["Hannover"] = "Hannover", ["Hasselfelde"] = "Hasselfelde", + ["Heidelberg"] = "Heidelberg", ["Herrenteich"] = "Herrenteich", ["Hildesheim"] = "Hildesheim", ["Hockenheim"] = "Hockenheim", ["Holzdorf"] = "Holzdorf", ["Kammermark"] = "Kammermark", + ["Kastrup"] = "Kastrup", + ["Kiel"] = "Kiel", ["Koethen"] = "Kothen", ["Laage"] = "Laage", + ["Landstuhl"] = "Landstuhl", ["Langenselbold"] = "Langenselbold", ["Laerz"] = "Larz", - ["Leipzig_Halle"] = "Leipzig Halle", ["Leipzig_Mockau"] = "Leipzig Mockau", ["Luebeck"] = "Lubeck", ["Lueneburg"] = "Luneburg", ["Mahlwinkel"] = "Mahlwinkel", + ["Mainz_Finthen"] = "Mainz Finthen", + ["Marxwalde"] = "Marxwalde", ["Mendig"] = "Mendig", ["Merseburg"] = "Merseburg", ["Neubrandenburg"] = "Neubrandenburg", ["Neuruppin"] = "Neuruppin", + ["Nordholz"] = "Nordholz", ["Northeim"] = "Northeim", + ["Noervenich"] = "Norvenich", ["Ober_Moerlen"] = "Ober-Morlen", ["Obermehler_Schlotheim"] = "Obermehler Schlotheim", + ["Oranienburg"] = "Oranienburg", ["Parchim"] = "Parchim", ["Peenemuende"] = "Peenemunde", + ["Perwenitz"] = "Perwenitz", ["Pferdsfeld"] = "Pferdsfeld", ["Pinnow"] = "Pinnow", ["Pottschutthoehe"] = "Pottschutthohe", ["Ramstein"] = "Ramstein", + ["Revinge"] = "Revinge", ["Rinteln"] = "Rinteln", + ["Schkeuditz"] = "Schkeuditz", ["Schoenefeld"] = "Schonefeld", ["Schweinfurt"] = "Schweinfurt", ["Sembach"] = "Sembach", + ["Sittensen"] = "Sittensen", ["Spangdahlem"] = "Spangdahlem", ["Sperenberg"] = "Sperenberg", + ["Sprendlingen"] = "Sprendlingen", ["Stendal"] = "Stendal", + ["Sturup"] = "Sturup", + ["Szczecin_Goleniow"] = "Szczecin-Goleniow", + ["Tagra"] = "Tagra", ["Tegel"] = "Tegel", ["Tempelhof"] = "Tempelhof", ["Templin"] = "Templin", + ["Thurland"] = "Thurland", ["Tutow"] = "Tutow", ["Uelzen"] = "Uelzen", ["Uetersen"] = "Uetersen", @@ -1386,6 +1480,7 @@ AIRBASE.GermanyCW = { ["Worms"] = "Worms", ["Wunstorf"] = "Wunstorf", ["Zerbst"] = "Zerbst", + ["Zoellschen"] = "Zollschen", ["Zweibruecken"] = "Zweibrucken", } diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 9a5409bdf..e9e629a0b 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -409,7 +409,7 @@ function CONTROLLABLE:SetTask( DCSTask, WaitTime ) local Controller = self:_GetController() -- self:I( "Before SetTask" ) Controller:setTask( DCSTask ) - -- AI_FORMATION class (used by RESCUEHELO) calls SetTask twice per second! hence spamming the DCS log file ==> setting this to trace. + -- FORMATION class (used by RESCUEHELO) calls SetTask twice per second! hence spamming the DCS log file ==> setting this to trace. self:T( { ControllableName = self:GetName(), DCSTask = DCSTask } ) else BASE:E( { DCSControllableName .. " is not alive anymore.", DCSTask = DCSTask } ) diff --git a/Moose Development/Moose/Wrapper/Scenery.lua b/Moose Development/Moose/Wrapper/Scenery.lua index 9c6b02516..d7e367e92 100644 --- a/Moose Development/Moose/Wrapper/Scenery.lua +++ b/Moose Development/Moose/Wrapper/Scenery.lua @@ -18,7 +18,13 @@ -- @field #string SceneryName Name of the scenery object. -- @field DCS#Object SceneryObject DCS scenery object. -- @field #number Life0 Initial life points. --- @field #table Properties +-- @field #table Properties. +-- @field #number ID. +-- @field Core.Zone#ZONE_POLYGON SceneryZone. +-- @field Core.Point#COORDINATE Coordinate. +-- @field DCS#Vec2 Vec2. +-- @field DCS#Vec3 Vec3. +-- @field Core.Vector#VECTOR Vector. -- @extends Wrapper.Positionable#POSITIONABLE @@ -35,27 +41,79 @@ SCENERY = { ClassName = "SCENERY", } +_SCENERY = {} + --- Register scenery object as POSITIONABLE. --@param #SCENERY self --@param #string SceneryName Scenery name. --@param DCS#Object SceneryObject DCS scenery object. +--@param Core.Zone#ZONE_POLYGON SceneryZone (optional) The zone object. --@return #SCENERY Scenery object. -function SCENERY:Register( SceneryName, SceneryObject ) - +function SCENERY:Register( SceneryName, SceneryObject, SceneryZone ) + + local ID = (SceneryObject and SceneryObject.getID) and SceneryObject:getID() or SceneryName + + if _SCENERY[ID] and _SCENERY[ID].SceneryObject == nil then + + _SCENERY[ID].SceneryObject=SceneryObject + SCENERY._UpdateFromDCSObject(_SCENERY[ID]) + + end + + if _SCENERY[ID] then return _SCENERY[ID] end + local self = BASE:Inherit( self, POSITIONABLE:New( SceneryName ) ) self.SceneryName = tostring(SceneryName) - + self.ID = ID self.SceneryObject = SceneryObject + self.SceneryZone = SceneryZone + + if SceneryZone then + self.Vec3 = SceneryZone:GetVec3() + self.Vec2 = SceneryZone:GetVec2() + self.Vector = (self.Vec3 and VECTOR) and VECTOR:NewFromVec(self.Vec3) or nil + end + + if SceneryObject then + local vec3 = SceneryObject:getPoint() + self.Vec3 = { x = vec3.x, y = vec3.y, z = vec3.z } + self.Vec2 = { x = vec3.x, y = vec3.z } + self.Vector = (self.Vec3 and VECTOR) and VECTOR:NewFromVec(self.Vec3) or nil + end if self.SceneryObject and self.SceneryObject.getLife then -- fix some objects do not have all functions - self.Life0 = self.SceneryObject:getLife() or 0 + self.Life0 = self.SceneryObject:getLife() or 1 else - self.Life0 = 0 + self.Life0 = 1 end self.Properties = {} + _SCENERY[self.ID] = self + + return self +end + + +--- [INTERNAL] Update data +-- @param Wrapper.Scenery#SCENERY Scenery The object to update. +function SCENERY._UpdateFromDCSObject(Scenery) + env.info("APPLE _UpdateFromDCSObject "..tostring(Scenery.SceneryName)) + local self=Scenery + if self.Vec2 == nil and self.SceneryObject ~= nil then + self.Vec3 = self.SceneryObject:getPoint() + if self.Vec3 then + self.Vec2 = {x=self.Vec3.x,y=self.Vec3.z} + self.Vector = VECTOR:NewFromVec(self.Vec3) + end + end + if not self.Life0 or self.Life0 == 1 then + if self.SceneryObject and self.SceneryObject.getLife() then + self.Life = self.SceneryObject:getLife() or 1 + self.Life0 = self.Life + end + end return self end @@ -99,6 +157,39 @@ function SCENERY:GetName() return self.SceneryName end +--- Obtain object coordinate. +--@param #SCENERY self +--@return Core.Point#COORDINATE Coordinate +function SCENERY:GetCoordinate() + if self.Coordinate then + return self.Coordinate + elseif self.Vec3 then + self.Coordinate = COORDINATE:NewFromVec3(self.Vec3):SetAlt() + end + return self.Coordinate +end + +--- Obtain object coordinate. +--@param #SCENERY self +--@return DCS#Vec3 Vec3 +function SCENERY:GetVec3() + return self.Vec3 +end + +--- Obtain object coordinate. +--@param #SCENERY self +--@return DCS#Vec2 Vec2 +function SCENERY:GetVec2() + return self.Vec2 +end + +--- Obtain object coordinate. +--@param #SCENERY self +--@return Core.Vector#VECTOR Vector +function SCENERY:GetVector() + return self.Vector +end + --- Obtain DCS Object from the SCENERY Object. --@param #SCENERY self --@return DCS#Object DCS scenery object. @@ -106,6 +197,13 @@ function SCENERY:GetDCSObject() return self.SceneryObject end +--- Obtain object ID. +--@param #SCENERY self +--@return #string Name +function SCENERY:GetID() + return self.ID +end + --- Get current life points from the SCENERY Object. Note - Some scenery objects always have 0 life points. -- **CAVEAT**: Some objects change their life value or "hitpoints" **after** the first hit. Hence we will adjust the life0 value to 120% -- of the last life value if life exceeds life0 (initial life) at any point. Thus will will get a smooth percentage decrease, if you use this e.g. as success @@ -113,12 +211,14 @@ end --@param #SCENERY self --@return #number life function SCENERY:GetLife() - local life = 0 + local life = 1 if self.SceneryObject and self.SceneryObject.getLife then life = self.SceneryObject:getLife() if life > self.Life0 then self.Life0 = math.floor(life * 1.2) end + elseif self.Life then + life = self.Life end return life end @@ -176,12 +276,19 @@ end --- Find a SCENERY object from its name or id. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first -- to find the correct object. --@param #SCENERY self ---@param #string Name The name/id of the scenery object as taken from the ME. Ex. '595785449' ---@param Core.Point#COORDINATE Coordinate Where to find the scenery object ---@param #number Radius (optional) Search radius around coordinate, defaults to 100 ---@return #SCENERY Scenery Object or `nil` if it cannot be found -function SCENERY:FindByName(Name, Coordinate, Radius, Role) - +--@param #string Name The name/id of the scenery object as taken from the ME. Ex. '595785449'. +--@param Core.Point#COORDINATE Coordinate Where to find the scenery object. +--@param #number Radius (optional) Search radius around coordinate, defaults to 100. +--@param #string Role (optional) The role if set on the zone object. +--@param Core.Zone#ZONE_POLYGON Zone (optional) The Zone where the scenery is located. +--@return #SCENERY Scenery Object or `nil` if it cannot be found. +function SCENERY:FindByName(Name, Coordinate, Radius, Role, Zone) + + --BASE:I("Coordinate x = "..Coordinate.x .. " y = "..Coordinate.y.." z = "..Coordinate.z) + + local findme = self:_FindByName(Name) + if findme then return findme end + local radius = Radius or 100 local name = Name or "unknown" local scenery = nil @@ -193,12 +300,13 @@ function SCENERY:FindByName(Name, Coordinate, Radius, Role) local function SceneryScan(scoordinate, sradius, sname) if scoordinate ~= nil then local Vec2 = scoordinate:GetVec2() - local scanzone = ZONE_RADIUS:New("Zone-"..sname,Vec2,sradius,true) + local scanzone = ZONE_RADIUS:New("Zone-"..sname,Vec2,sradius) scanzone:Scan({Object.Category.SCENERY}) local scanned = scanzone:GetScannedSceneryObjects() local rscenery = nil -- Wrapper.Scenery#SCENERY for _,_scenery in pairs(scanned) do local scenery = _scenery -- Wrapper.Scenery#SCENERY + --BASE:I({tostring(scenery.SceneryName),tostring(sname)}) if tostring(scenery.SceneryName) == tostring(sname) then rscenery = scenery if Role then rscenery:SetProperty("ROLE",Role) end @@ -211,13 +319,36 @@ function SCENERY:FindByName(Name, Coordinate, Radius, Role) end if Coordinate then - --BASE:I("Coordinate Scenery Scan") scenery = SceneryScan(Coordinate, radius, name) end - + + if not scenery then scenery = SCENERY:Register(Name,nil,Zone) end + return scenery end +--- Find a SCENERY object that was previously registered(!) by it's ID. +-- @param #SCENERY self +-- @param #number ID +-- @return Wrapper.Scenery#SCENERY Scenery or nil if it could not be found +function SCENERY:FindByID(ID) + return _SCENERY[ID] +end + +--- Find a SCENERY object that was previously registered(!) by it's name. +-- @param #SCENERY self +-- @param #string Name +-- @return Wrapper.Scenery#SCENERY Scenery or nil if it could not be found +function SCENERY:_FindByName(Name) + for _id,_object in pairs(_SCENERY) do + if _object and _object.GetName and _object:GetName() then + local name = _object:GetName() + if Name == name then return _object end + end + end + return nil +end + --- Find a SCENERY object from its name or id. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first -- to find the correct object. --@param #SCENERY self @@ -231,8 +362,8 @@ function SCENERY:FindByNameInZone(Name, Zone, Radius) if type(Zone) == "string" then Zone = ZONE:FindByName(Zone) end - local coordinate = Zone:GetCoordinate() - return self:FindByName(Name,coordinate,Radius,Zone:GetProperty("ROLE")) + local coordinate = Zone:GetCoordinate():SetAlt() + return self:FindByName(Name,coordinate,Radius,Zone:GetProperty("ROLE"),Zone) end --- Find a SCENERY object from its zone name. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first @@ -241,14 +372,18 @@ end --@param #string ZoneName The name of the scenery zone as created with a right-click on the map in the mission editor and select "assigned to...". Can be handed over as ZONE object. --@return #SCENERY First found Scenery Object or `nil` if it cannot be found function SCENERY:FindByZoneName( ZoneName ) + --BASE:I(ZoneName) + local zone = ZoneName -- Core.Zone#ZONE_BASE + if type(ZoneName) == "string" then zone = ZONE:FindByName(ZoneName) -- Core.Zone#ZONE_POLYGON end + local _id = zone:GetProperty('OBJECT ID') - --local properties = zone:GetAllProperties() or {} - --BASE:I(string.format("Object ID is: %s",_id or "none")) - --BASE:T("Object ID ".._id) + + --BASE:I("Object ID ".._id) + if not _id then -- this zone has no object ID BASE:E("**** Zone without object ID: "..ZoneName.." | Type: "..tostring(zone.ClassName)) @@ -257,23 +392,27 @@ function SCENERY:FindByZoneName( ZoneName ) local scanned = zone:GetScannedSceneryObjects() for _,_scenery in (scanned) do local scenery = _scenery -- Wrapper.Scenery#SCENERY - if scenery:IsAlive() then + --if scenery:IsAlive() then local role = zone:GetProperty("ROLE") if role then scenery:SetProperty("ROLE",role) end return scenery - end + --end end return nil else - return self:FindByName(_id, zone:GetCoordinate(),nil,zone:GetProperty("ROLE")) + local coordinate = zone:GetCoordinate() + coordinate:SetAlt() + return self:FindByName(_id, coordinate,nil,zone:GetProperty("ROLE"),zone) end else - return self:FindByName(_id, zone:GetCoordinate(),nil,zone:GetProperty("ROLE")) + local coordinate = zone:GetCoordinate() + coordinate:SetAlt() + return self:FindByName(_id, coordinate,nil,zone:GetProperty("ROLE"),zone) end end --- Scan and find all SCENERY objects from a zone by zone-name. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first --- to find the correct object. +-- to find the correct object. Might return nil! --@param #SCENERY self --@param #string ZoneName The name of the zone, can be handed as ZONE_RADIUS or ZONE_POLYGON object --@return #table of SCENERY Objects, or `nil` if nothing found @@ -295,7 +434,7 @@ function SCENERY:FindAllByZoneName( ZoneName ) return nil end else - local obj = self:FindByName(_id, zone:GetCoordinate(),nil,zone:GetProperty("ROLE")) + local obj = self:FindByName(_id, zone:GetCoordinate():SetAlt(),nil,zone:GetProperty("ROLE"), zone) if obj then return {obj} else diff --git a/Moose Setup/Moose.files b/Moose Setup/Moose.files index d1263e908..f7c8be377 100644 --- a/Moose Setup/Moose.files +++ b/Moose Setup/Moose.files @@ -75,6 +75,7 @@ Functional/ZoneGoalCargo.lua Functional/Tiresias.lua Functional/Stratego.lua Functional/ClientWatch.lua +Functional/Formation.lua Ops/Airboss.lua Ops/RecoveryTanker.lua