From d8e765a9b1975b2448223dd79a78bd417e10be85 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Tue, 18 Apr 2023 10:27:20 +0200 Subject: [PATCH 1/6] Fixes for `getPlayerName()` errors if DCS object is not a UNIT --- .../Moose/Functional/PseudoATC.lua | 146 ++++-------------- Moose Development/Moose/Ops/Airboss.lua | 2 + 2 files changed, 30 insertions(+), 118 deletions(-) diff --git a/Moose Development/Moose/Functional/PseudoATC.lua b/Moose Development/Moose/Functional/PseudoATC.lua index 5ee714705..16c530cf3 100644 --- a/Moose Development/Moose/Functional/PseudoATC.lua +++ b/Moose Development/Moose/Functional/PseudoATC.lua @@ -26,9 +26,9 @@ -- -- === -- --- ### Author: **[funkyfranky](https://forums.eagle.ru/member.php?u=115026)** +-- ### Author: **funkyfranky** -- --- ### Contributions: [FlightControl](https://forums.eagle.ru/member.php?u=89536) +-- ### Contributions: FlightControl, Applevangelist -- -- ==== -- @module Functional.PseudoATC @@ -44,7 +44,7 @@ -- @field #number mrefresh Interval in seconds after which the F10 menu is refreshed. E.g. by the closest airports. Default is 120 sec. -- @field #number talt Interval in seconds between reporting altitude until touchdown. Default 3 sec. -- @field #boolean chatty Display some messages on events like take-off and touchdown. --- @field #boolean eventsmoose If true, events are handled by MOOSE. If false, events are handled directly by DCS eventhandler. +-- @field #boolean eventsmoose [Deprecated] If true, events are handled by MOOSE. If false, events are handled directly by DCS eventhandler. -- @field #boolean reportplayername If true, use playername not callsign on callouts -- @extends Core.Base#BASE @@ -100,13 +100,14 @@ PSEUDOATC.id="PseudoATC | " --- PSEUDOATC version. -- @field #number version -PSEUDOATC.version="0.9.5" +PSEUDOATC.version="0.10.5" ----------------------------------------------------------------------------------------------------------------------------------------- -- TODO list -- DONE: Add takeoff event. -- DONE: Add user functions. +-- DONE: Refactor to use Moose event handling only ----------------------------------------------------------------------------------------------------------------------------------------- @@ -131,23 +132,14 @@ function PSEUDOATC:Start() self:F() -- Debug info - self:E(PSEUDOATC.id.."Starting PseudoATC") + self:I(PSEUDOATC.id.."Starting PseudoATC") -- Handle events. - if self.eventsmoose then - self:T(PSEUDOATC.id.."Events are handled by MOOSE.") - self:HandleEvent(EVENTS.Birth, self._OnBirth) - self:HandleEvent(EVENTS.Land, self._PlayerLanded) - self:HandleEvent(EVENTS.Takeoff, self._PlayerTakeOff) - self:HandleEvent(EVENTS.PlayerLeaveUnit, self._PlayerLeft) - self:HandleEvent(EVENTS.Crash, self._PlayerLeft) - --self:HandleEvent(EVENTS.Ejection, self._PlayerLeft) - --self:HandleEvent(EVENTS.PilotDead, self._PlayerLeft) - else - self:T(PSEUDOATC.id.."Events are handled by DCS.") - -- Events are handled directly by DCS. - world.addEventHandler(self) - end + self:HandleEvent(EVENTS.Birth, self._OnBirth) + self:HandleEvent(EVENTS.Land, self._PlayerLanded) + self:HandleEvent(EVENTS.Takeoff, self._PlayerTakeOff) + self:HandleEvent(EVENTS.PlayerLeaveUnit, self._PlayerLeft) + self:HandleEvent(EVENTS.Crash, self._PlayerLeft) end @@ -199,7 +191,7 @@ function PSEUDOATC:SetMenuRefresh(interval) self.mrefresh=interval or 120 end ---- Enable/disable event handling by MOOSE or DCS. +--- [Deprecated] Enable/disable event handling by MOOSE or DCS. -- @param #PSEUDOATC self -- @param #boolean switch If true, events are handled by MOOSE (default). If false, events are handled directly by DCS. function PSEUDOATC:SetEventsMoose(switch) @@ -216,84 +208,6 @@ end ----------------------------------------------------------------------------------------------------------------------------------------- -- Event Handling ---- Event handler for suppressed groups. ---@param #PSEUDOATC self ---@param #table Event Event data table. Holds event.id, event.initiator and event.target etc. -function PSEUDOATC:onEvent(Event) - if Event == nil or Event.initiator == nil or Unit.getByName(Event.initiator:getName()) == nil then - return true - end - - local DCSiniunit = Event.initiator - local DCSplace = Event.place - local DCSsubplace = Event.subplace - - local EventData={} - local _playerunit=nil - local _playername=nil - - if Event.initiator then - EventData.IniUnitName = Event.initiator:getName() - EventData.IniDCSGroup = Event.initiator:getGroup() - EventData.IniGroupName = Event.initiator:getGroup():getName() - -- Get player unit and name. This returns nil,nil if the event was not fired by a player unit. And these are the only events we are interested in. - _playerunit, _playername = self:_GetPlayerUnitAndName(EventData.IniUnitName) - end - - if Event.place then - EventData.Place=Event.place - EventData.PlaceName=Event.place:getName() - end - if Event.subplace then - EventData.SubPlace=Event.subplace - EventData.SubPlaceName=Event.subplace:getName() - end - - -- Event info. - self:T3(PSEUDOATC.id..string.format("EVENT: Event in onEvent with ID = %s", tostring(Event.id))) - self:T3(PSEUDOATC.id..string.format("EVENT: Ini unit = %s" , tostring(EventData.IniUnitName))) - self:T3(PSEUDOATC.id..string.format("EVENT: Ini group = %s" , tostring(EventData.IniGroupName))) - self:T3(PSEUDOATC.id..string.format("EVENT: Ini player = %s" , tostring(_playername))) - self:T3(PSEUDOATC.id..string.format("EVENT: Place = %s" , tostring(EventData.PlaceName))) - self:T3(PSEUDOATC.id..string.format("EVENT: SubPlace = %s" , tostring(EventData.SubPlaceName))) - - -- Event birth. - if Event.id == world.event.S_EVENT_BIRTH and _playername then - self:_OnBirth(EventData) - end - - -- Event takeoff. - if Event.id == world.event.S_EVENT_TAKEOFF and _playername and EventData.Place then - self:_PlayerTakeOff(EventData) - end - - -- Event land. - if Event.id == world.event.S_EVENT_LAND and _playername and EventData.Place then - self:_PlayerLanded(EventData) - end - - -- Event player left unit - if Event.id == world.event.S_EVENT_PLAYER_LEAVE_UNIT and _playername then - self:_PlayerLeft(EventData) - end - - -- Event crash ==> player left unit - if Event.id == world.event.S_EVENT_CRASH and _playername then - self:_PlayerLeft(EventData) - end - ---[[ - -- Event eject ==> player left unit - if Event.id == world.event.S_EVENT_EJECTION and _playername then - self:_PlayerLeft(EventData) - end - - -- Event pilot dead ==> player left unit - if Event.id == world.event.S_EVENT_PILOT_DEAD and _playername then - self:_PlayerLeft(EventData) - end -]] -end --- Function called my MOOSE event handler when a player enters a unit. -- @param #PSEUDOATC self @@ -303,7 +217,9 @@ function PSEUDOATC:_OnBirth(EventData) -- Get unit and player. local _unitName=EventData.IniUnitName - local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) + --local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) + local _unit = EventData.IniUnit + local _playername = EventData.IniPlayerName -- Check if a player entered. if _unit and _playername then @@ -320,7 +236,10 @@ function PSEUDOATC:_PlayerLeft(EventData) -- Get unit and player. local _unitName=EventData.IniUnitName - local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) + --local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) + + local _unit = EventData.IniUnit + local _playername = EventData.IniPlayerName -- Check if a player left. if _unit and _playername then @@ -335,18 +254,16 @@ function PSEUDOATC:_PlayerLanded(EventData) self:F({EventData=EventData}) -- Get unit, player and place. - local _unitName=EventData.IniUnitName - local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) + local _unitName=EventData.IniUnitName + local _unit = EventData.IniUnit + local _playername = EventData.IniPlayerName + --local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) local _base=nil local _baseName=nil if EventData.place then _base=EventData.place _baseName=EventData.place:getName() end --- if EventData.subplace then --- local _subPlace=EventData.subplace --- local _subPlaceName=EventData.subplace:getName() --- end -- Call landed function. if _unit and _playername and _base then @@ -361,8 +278,10 @@ function PSEUDOATC:_PlayerTakeOff(EventData) self:F({EventData=EventData}) -- Get unit, player and place. - local _unitName=EventData.IniUnitName - local _unit,_playername=self:_GetPlayerUnitAndName(_unitName) + local _unitName=EventData.IniUnitName + local _unit = EventData.IniUnit + local _playername = EventData.IniPlayerName + --local _unit,_playername=self:_GetPlayerUnitAndName(_unitName) local _base=nil local _baseName=nil if EventData.place then @@ -450,9 +369,6 @@ function PSEUDOATC:PlayerLanded(unit, place) local group=unit:GetGroup() local GID=group:GetID() local UID=unit:GetDCSObject():getID() - --local PlayerName=self.group[GID].player[UID].playername - --local UnitName=self.group[GID].player[UID].unitname - --local GroupName=self.group[GID].player[UID].groupname local PlayerName = unit:GetPlayerName() or "Ghost" local UnitName = unit:GetName() or "Ghostplane" local GroupName = group:GetName() or "Ghostgroup" @@ -483,12 +399,6 @@ function PSEUDOATC:PlayerTakeOff(unit, place) -- Gather some information. local group=unit:GetGroup() - --local GID=group:GetID() - --local UID=unit:GetDCSObject():getID() - --local PlayerName=self.group[GID].player[UID].playername - --local CallSign=self.group[GID].player[UID].callsign - --local UnitName=self.group[GID].player[UID].unitname - --local GroupName=self.group[GID].player[UID].groupname local PlayerName = unit:GetPlayerName() or "Ghost" local UnitName = unit:GetName() or "Ghostplane" local GroupName = group:GetName() or "Ghostgroup" @@ -926,7 +836,7 @@ function PSEUDOATC:AltitudeTimeStart(GID, UID) self:T(PSEUDOATC.id..string.format("Starting altitude report timer for player ID %d.", UID)) -- Start timer. Altitude is reported every ~3 seconds. - self.group[GID].player[UID].altimer, self.group[GID].player[UID].altimerid=SCHEDULER:New(nil, self.ReportHeight, {self, GID, UID, 0.1, true}, 1, 3) + self.group[GID].player[UID].altimer, self.group[GID].player[UID].altimerid=SCHEDULER:New(nil, self.ReportHeight, {self, GID, UID, 1, true}, 1, 3) end --- Stop/destroy DCS scheduler function for reporting altitude. diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index 21b5caa61..04e4b2b11 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -8115,6 +8115,8 @@ function AIRBOSS:OnEventBirth( EventData ) return end + if EventData.IniObjectCategory ~= Object.Category.UNIT then return end + local _unitName = EventData.IniUnitName local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) From f65783ed6c3ae82a2b011d81952a0266b0654b6d Mon Sep 17 00:00:00 2001 From: Thomas <72444570+Applevangelist@users.noreply.github.com> Date: Tue, 18 Apr 2023 12:28:17 +0200 Subject: [PATCH 2/6] SET - added continous zone filtering (#1934) SET - added continous zone filtering for SET_GROUP, SET_UNIT and SET_CLIENT. Adresses request #1933 --- Moose Development/Moose/Core/Set.lua | 170 ++++++++++++++++++++++++++- 1 file changed, 169 insertions(+), 1 deletion(-) diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index 4731ab3d5..fa64aae62 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -904,6 +904,8 @@ end do -- SET_GROUP --- @type SET_GROUP #SET_GROUP + -- @field Core.Timer#TIMER ZoneTimer + -- @field #number ZoneTimerInterval -- @extends Core.Set#SET_BASE --- Mission designers can use the @{Core.Set#SET_GROUP} class to build sets of groups belonging to certain: @@ -1343,6 +1345,25 @@ do -- SET_GROUP end return self end + + --- [Internal] Private function for use of continous zone filter + -- @param #SET_GROUP self + -- @return #SET_GROUP self + function SET_GROUP:_ContinousZoneFilter() + + local Database = _DATABASE.GROUPS + + for ObjectName, Object in pairs( Database ) do + if self:IsIncludeObject( Object ) and self:IsNotInSet(Object) then + self:Add( ObjectName, Object ) + elseif (not self:IsIncludeObject( Object )) and self:IsInSet(Object) then + self:Remove(ObjectName) + end + end + + return self + + end --- Builds a set of groups that are only active. -- Only the groups that are active will be included within the set. @@ -1381,10 +1402,46 @@ do -- SET_GROUP self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.RemoveUnit, self._EventOnDeadOrCrash ) + if self.Filter.Zones then + self.ZoneTimer = TIMER:New(self._ContinousZoneFilter,self) + local timing = self.ZoneTimerInterval or 30 + self.ZoneTimer:Start(timing,timing) + end end return self end + + --- Set filter timer interval for FilterZones if using active filtering with FilterStart(). + -- @param #SET_GROUP self + -- @param #number Seconds Seconds between check intervals, defaults to 30. **Caution** - do not be too agressive with timing! Groups are usually not moving fast enough + -- to warrant a check of below 10 seconds. + -- @return #SET_GROUP self + function SET_GROUP:FilterZoneTimer(Seconds) + self.ZoneTimerInterval = Seconds or 30 + return self + end + + --- Stops the filtering. + -- @param #SET_GROUP self + -- @return #SET_GROUP self + function SET_GROUP:FilterStop() + + if _DATABASE then + + self:UnHandleEvent(EVENTS.Birth) + self:UnHandleEvent(EVENTS.Dead) + self:UnHandleEvent(EVENTS.Crash) + self:UnHandleEvent(EVENTS.RemoveUnit) + + if self.Filter.Zones and self.ZoneTimer and self.ZoneTimer:IsRunning() then + self.ZoneTimer:Stop() + end + end + + return self + end + --- Handles the OnDead or OnCrash event for alive groups set. -- Note: The GROUP object in the SET_GROUP collection will only be removed if the last unit is destroyed of the GROUP. @@ -1888,7 +1945,7 @@ do -- SET_GROUP if self.Filter.Zones then local MGroupZone = false for ZoneName, Zone in pairs( self.Filter.Zones ) do - self:T3( "Zone:", ZoneName ) + self:I( "Zone:", ZoneName ) if MGroup:IsInZone(Zone) then MGroupZone = true end @@ -1956,6 +2013,8 @@ end do -- SET_UNIT --- @type SET_UNIT + -- @field Core.Timer#TIMER ZoneTimer + -- @field #number ZoneTimerInterval -- @extends Core.Set#SET_BASE --- Mission designers can use the SET_UNIT class to build sets of units belonging to certain: @@ -2347,7 +2406,56 @@ do -- SET_UNIT return CountU end + + --- [Internal] Private function for use of continous zone filter + -- @param #SET_UNIT self + -- @return #SET_UNIT self + function SET_UNIT:_ContinousZoneFilter() + + local Database = _DATABASE.UNITS + + for ObjectName, Object in pairs( Database ) do + if self:IsIncludeObject( Object ) and self:IsNotInSet(Object) then + self:Add( ObjectName, Object ) + elseif (not self:IsIncludeObject( Object )) and self:IsInSet(Object) then + self:Remove(ObjectName) + end + end + + return self + + end + + --- Set filter timer interval for FilterZones if using active filtering with FilterStart(). + -- @param #SET_UNIT self + -- @param #number Seconds Seconds between check intervals, defaults to 30. **Caution** - do not be too agressive with timing! Groups are usually not moving fast enough + -- to warrant a check of below 10 seconds. + -- @return #SET_UNIT self + function SET_UNIT:FilterZoneTimer(Seconds) + self.ZoneTimerInterval = Seconds or 30 + return self + end + + --- Stops the filtering. + -- @param #SET_UNIT self + -- @return #SET_UNIT self + function SET_UNIT:FilterStop() + if _DATABASE then + + self:UnHandleEvent(EVENTS.Birth) + self:UnHandleEvent(EVENTS.Dead) + self:UnHandleEvent(EVENTS.Crash) + self:UnHandleEvent(EVENTS.RemoveUnit) + + if self.Filter.Zones and self.ZoneTimer and self.ZoneTimer:IsRunning() then + self.ZoneTimer:Stop() + end + end + + return self + end + --- Starts the filtering. -- @param #SET_UNIT self -- @return #SET_UNIT self @@ -2359,6 +2467,11 @@ do -- SET_UNIT self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.RemoveUnit, self._EventOnDeadOrCrash ) + if self.Filter.Zones then + self.ZoneTimer = TIMER:New(self._ContinousZoneFilter,self) + local timing = self.ZoneTimerInterval or 30 + self.ZoneTimer:Start(timing,timing) + end end return self @@ -3834,6 +3947,8 @@ end do -- SET_CLIENT --- @type SET_CLIENT + -- @field Core.Timer#TIMER ZoneTimer + -- @field #number ZoneTimerInterval -- @extends Core.Set#SET_BASE --- Mission designers can use the @{Core.Set#SET_CLIENT} class to build sets of units belonging to certain: @@ -4141,6 +4256,54 @@ do -- SET_CLIENT return self end + --- [Internal] Private function for use of continous zone filter + -- @param #SET_CLIENT self + -- @return #SET_CLIENT self + function SET_CLIENT:_ContinousZoneFilter() + + local Database = _DATABASE.CLIENTS + + for ObjectName, Object in pairs( Database ) do + if self:IsIncludeObject( Object ) and self:IsNotInSet(Object) then + self:Add( ObjectName, Object ) + elseif (not self:IsIncludeObject( Object )) and self:IsInSet(Object) then + self:Remove(ObjectName) + end + end + + return self + + end + + --- Set filter timer interval for FilterZones if using active filtering with FilterStart(). + -- @param #SET_CLIENT self + -- @param #number Seconds Seconds between check intervals, defaults to 30. **Caution** - do not be too agressive with timing! Groups are usually not moving fast enough + -- to warrant a check of below 10 seconds. + -- @return #SET_CLIENT self + function SET_CLIENT:FilterZoneTimer(Seconds) + self.ZoneTimerInterval = Seconds or 30 + return self + end + + --- Stops the filtering. + -- @param #SET_CLIENT self + -- @return #SET_CLIENT self + function SET_CLIENT:FilterStop() + + if _DATABASE then + + self:UnHandleEvent(EVENTS.Birth) + self:UnHandleEvent(EVENTS.Dead) + self:UnHandleEvent(EVENTS.Crash) + + if self.Filter.Zones and self.ZoneTimer and self.ZoneTimer:IsRunning() then + self.ZoneTimer:Stop() + end + end + + return self + end + --- Starts the filtering. -- @param #SET_CLIENT self -- @return #SET_CLIENT self @@ -4151,6 +4314,11 @@ do -- SET_CLIENT self:HandleEvent( EVENTS.Birth, self._EventOnBirth ) self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash ) + if self.Filter.Zones then + self.ZoneTimer = TIMER:New(self._ContinousZoneFilter,self) + local timing = self.ZoneTimerInterval or 30 + self.ZoneTimer:Start(timing,timing) + end end return self From 6886107934ec2be8890fe25f0b09b685f84ec335 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Thu, 20 Apr 2023 08:05:11 +0200 Subject: [PATCH 3/6] #SET * Active Zone Filtering --- Moose Development/Moose/Core/Set.lua | 168 +++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index 4731ab3d5..a3a367a6f 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -904,6 +904,8 @@ end do -- SET_GROUP --- @type SET_GROUP #SET_GROUP + -- @field Core.Timer#TIMER ZoneTimer + -- @field #number ZoneTimerInterval -- @extends Core.Set#SET_BASE --- Mission designers can use the @{Core.Set#SET_GROUP} class to build sets of groups belonging to certain: @@ -1343,6 +1345,25 @@ do -- SET_GROUP end return self end + + --- [Internal] Private function for use of continous zone filter + -- @param #SET_GROUP self + -- @return #SET_GROUP self + function SET_GROUP:_ContinousZoneFilter() + + local Database = _DATABASE.GROUPS + + for ObjectName, Object in pairs( Database ) do + if self:IsIncludeObject( Object ) and self:IsNotInSet(Object) then + self:Add( ObjectName, Object ) + elseif (not self:IsIncludeObject( Object )) and self:IsInSet(Object) then + self:Remove(ObjectName) + end + end + + return self + + end --- Builds a set of groups that are only active. -- Only the groups that are active will be included within the set. @@ -1381,10 +1402,46 @@ do -- SET_GROUP self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.RemoveUnit, self._EventOnDeadOrCrash ) + if self.Filter.Zones then + self.ZoneTimer = TIMER:New(self._ContinousZoneFilter,self) + local timing = self.ZoneTimerInterval or 30 + self.ZoneTimer:Start(timing,timing) + end end return self end + + --- Set filter timer interval for FilterZones if using active filtering with FilterStart(). + -- @param #SET_GROUP self + -- @param #number Seconds Seconds between check intervals, defaults to 30. **Caution** - do not be too agressive with timing! Groups are usually not moving fast enough + -- to warrant a check of below 10 seconds. + -- @return #SET_GROUP self + function SET_GROUP:FilterZoneTimer(Seconds) + self.ZoneTimerInterval = Seconds or 30 + return self + end + + --- Stops the filtering. + -- @param #SET_GROUP self + -- @return #SET_GROUP self + function SET_GROUP:FilterStop() + + if _DATABASE then + + self:UnHandleEvent(EVENTS.Birth) + self:UnHandleEvent(EVENTS.Dead) + self:UnHandleEvent(EVENTS.Crash) + self:UnHandleEvent(EVENTS.RemoveUnit) + + if self.Filter.Zones and self.ZoneTimer and self.ZoneTimer:IsRunning() then + self.ZoneTimer:Stop() + end + end + + return self + end + --- Handles the OnDead or OnCrash event for alive groups set. -- Note: The GROUP object in the SET_GROUP collection will only be removed if the last unit is destroyed of the GROUP. @@ -1956,6 +2013,8 @@ end do -- SET_UNIT --- @type SET_UNIT + -- @field Core.Timer#TIMER ZoneTimer + -- @field #number ZoneTimerInterval -- @extends Core.Set#SET_BASE --- Mission designers can use the SET_UNIT class to build sets of units belonging to certain: @@ -2347,7 +2406,56 @@ do -- SET_UNIT return CountU end + + --- [Internal] Private function for use of continous zone filter + -- @param #SET_UNIT self + -- @return #SET_UNIT self + function SET_UNIT:_ContinousZoneFilter() + + local Database = _DATABASE.UNITS + + for ObjectName, Object in pairs( Database ) do + if self:IsIncludeObject( Object ) and self:IsNotInSet(Object) then + self:Add( ObjectName, Object ) + elseif (not self:IsIncludeObject( Object )) and self:IsInSet(Object) then + self:Remove(ObjectName) + end + end + + return self + + end + + --- Set filter timer interval for FilterZones if using active filtering with FilterStart(). + -- @param #SET_UNIT self + -- @param #number Seconds Seconds between check intervals, defaults to 30. **Caution** - do not be too agressive with timing! Groups are usually not moving fast enough + -- to warrant a check of below 10 seconds. + -- @return #SET_UNIT self + function SET_UNIT:FilterZoneTimer(Seconds) + self.ZoneTimerInterval = Seconds or 30 + return self + end + + --- Stops the filtering. + -- @param #SET_UNIT self + -- @return #SET_UNIT self + function SET_UNIT:FilterStop() + if _DATABASE then + + self:UnHandleEvent(EVENTS.Birth) + self:UnHandleEvent(EVENTS.Dead) + self:UnHandleEvent(EVENTS.Crash) + self:UnHandleEvent(EVENTS.RemoveUnit) + + if self.Filter.Zones and self.ZoneTimer and self.ZoneTimer:IsRunning() then + self.ZoneTimer:Stop() + end + end + + return self + end + --- Starts the filtering. -- @param #SET_UNIT self -- @return #SET_UNIT self @@ -2359,6 +2467,11 @@ do -- SET_UNIT self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.RemoveUnit, self._EventOnDeadOrCrash ) + if self.Filter.Zones then + self.ZoneTimer = TIMER:New(self._ContinousZoneFilter,self) + local timing = self.ZoneTimerInterval or 30 + self.ZoneTimer:Start(timing,timing) + end end return self @@ -3834,6 +3947,8 @@ end do -- SET_CLIENT --- @type SET_CLIENT + -- @field Core.Timer#TIMER ZoneTimer + -- @field #number ZoneTimerInterval -- @extends Core.Set#SET_BASE --- Mission designers can use the @{Core.Set#SET_CLIENT} class to build sets of units belonging to certain: @@ -4141,6 +4256,54 @@ do -- SET_CLIENT return self end + --- [Internal] Private function for use of continous zone filter + -- @param #SET_CLIENT self + -- @return #SET_CLIENT self + function SET_CLIENT:_ContinousZoneFilter() + + local Database = _DATABASE.CLIENTS + + for ObjectName, Object in pairs( Database ) do + if self:IsIncludeObject( Object ) and self:IsNotInSet(Object) then + self:Add( ObjectName, Object ) + elseif (not self:IsIncludeObject( Object )) and self:IsInSet(Object) then + self:Remove(ObjectName) + end + end + + return self + + end + + --- Set filter timer interval for FilterZones if using active filtering with FilterStart(). + -- @param #SET_CLIENT self + -- @param #number Seconds Seconds between check intervals, defaults to 30. **Caution** - do not be too agressive with timing! Groups are usually not moving fast enough + -- to warrant a check of below 10 seconds. + -- @return #SET_CLIENT self + function SET_CLIENT:FilterZoneTimer(Seconds) + self.ZoneTimerInterval = Seconds or 30 + return self + end + + --- Stops the filtering. + -- @param #SET_CLIENT self + -- @return #SET_CLIENT self + function SET_CLIENT:FilterStop() + + if _DATABASE then + + self:UnHandleEvent(EVENTS.Birth) + self:UnHandleEvent(EVENTS.Dead) + self:UnHandleEvent(EVENTS.Crash) + + if self.Filter.Zones and self.ZoneTimer and self.ZoneTimer:IsRunning() then + self.ZoneTimer:Stop() + end + end + + return self + end + --- Starts the filtering. -- @param #SET_CLIENT self -- @return #SET_CLIENT self @@ -4151,6 +4314,11 @@ do -- SET_CLIENT self:HandleEvent( EVENTS.Birth, self._EventOnBirth ) self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash ) + if self.Filter.Zones then + self.ZoneTimer = TIMER:New(self._ContinousZoneFilter,self) + local timing = self.ZoneTimerInterval or 30 + self.ZoneTimer:Start(timing,timing) + end end return self From f4080d93e8a3b226db5b92f60cd5fb8230ac1ab1 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Thu, 20 Apr 2023 08:06:57 +0200 Subject: [PATCH 4/6] #SET - Minus one log entry --- Moose Development/Moose/Core/Set.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index fa64aae62..a48e917f6 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -1945,7 +1945,7 @@ do -- SET_GROUP if self.Filter.Zones then local MGroupZone = false for ZoneName, Zone in pairs( self.Filter.Zones ) do - self:I( "Zone:", ZoneName ) + --self:I( "Zone:", ZoneName ) if MGroup:IsInZone(Zone) then MGroupZone = true end From 549c9b9ce5173f878bf52be469aa21dfa9e72cfa Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Thu, 20 Apr 2023 08:22:31 +0200 Subject: [PATCH 5/6] #CTLD * Docu changes --- Moose Development/Moose/Ops/CTLD.lua | 589 +++++++++++++-------------- 1 file changed, 294 insertions(+), 295 deletions(-) diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index 394a22138..1dca93f05 100644 --- a/Moose Development/Moose/Ops/CTLD.lua +++ b/Moose Development/Moose/Ops/CTLD.lua @@ -24,6 +24,299 @@ -- Last Update Apr 2023 +do + +------------------------------------------------------ +--- **CTLD_CARGO** class, extends Core.Base#BASE +-- @type CTLD_CARGO +-- @field #string ClassName Class name. +-- @field #number ID ID of this cargo. +-- @field #string Name Name for menu. +-- @field #table Templates Table of #POSITIONABLE objects. +-- @field #string CargoType Enumerator of Type. +-- @field #boolean HasBeenMoved Flag for moving. +-- @field #boolean LoadDirectly Flag for direct loading. +-- @field #number CratesNeeded Crates needed to build. +-- @field Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission. +-- @field #boolean HasBeenDropped True if dropped from heli. +-- @field #number PerCrateMass Mass in kg. +-- @field #number Stock Number of builds available, -1 for unlimited. +-- @field #string Subcategory Sub-category name. +-- @extends Core.Base#BASE + +--- +-- @field #CTLD_CARGO CTLD_CARGO +CTLD_CARGO = { + ClassName = "CTLD_CARGO", + ID = 0, + Name = "none", + Templates = {}, + CargoType = "none", + HasBeenMoved = false, + LoadDirectly = false, + CratesNeeded = 0, + Positionable = nil, + HasBeenDropped = false, + PerCrateMass = 0, + Stock = nil, + Mark = nil, + } + + --- Define cargo types. + -- @type CTLD_CARGO.Enum + -- @field #string VEHICLE + -- @field #string TROOPS + -- @field #string FOB + -- @field #string CRATE + -- @field #string REPAIR + -- @field #string ENGINEERS + -- @field #string STATIC + CTLD_CARGO.Enum = { + VEHICLE = "Vehicle", -- #string vehicles + TROOPS = "Troops", -- #string troops + FOB = "FOB", -- #string FOB + CRATE = "Crate", -- #string crate + REPAIR = "Repair", -- #string repair + ENGINEERS = "Engineers", -- #string engineers + STATIC = "Static", -- #string statics + } + + --- Function to create new CTLD_CARGO object. + -- @param #CTLD_CARGO self + -- @param #number ID ID of this #CTLD_CARGO + -- @param #string Name Name for menu. + -- @param #table Templates Table of #POSITIONABLE objects. + -- @param #CTLD_CARGO.Enum Sorte Enumerator of Type. + -- @param #boolean HasBeenMoved Flag for moving. + -- @param #boolean LoadDirectly Flag for direct loading. + -- @param #number CratesNeeded Crates needed to build. + -- @param Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission. + -- @param #boolean Dropped Cargo/Troops have been unloaded from a chopper. + -- @param #number PerCrateMass Mass in kg + -- @param #number Stock Number of builds available, nil for unlimited + -- @param #string Subcategory Name of subcategory, handy if using > 10 types to load. + -- @return #CTLD_CARGO self + function CTLD_CARGO:New(ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped, PerCrateMass, Stock, Subcategory) + -- Inherit everything from BASE class. + local self=BASE:Inherit(self, BASE:New()) -- #CTLD_CARGO + self:T({ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped}) + self.ID = ID or math.random(100000,1000000) + self.Name = Name or "none" -- #string + self.Templates = Templates or {} -- #table + self.CargoType = Sorte or "type" -- #CTLD_CARGO.Enum + self.HasBeenMoved = HasBeenMoved or false -- #boolean + self.LoadDirectly = LoadDirectly or false -- #boolean + self.CratesNeeded = CratesNeeded or 0 -- #number + self.Positionable = Positionable or nil -- Wrapper.Positionable#POSITIONABLE + self.HasBeenDropped = Dropped or false --#boolean + self.PerCrateMass = PerCrateMass or 0 -- #number + self.Stock = Stock or nil --#number + self.Mark = nil + self.Subcategory = Subcategory or "Other" + return self + end + + --- Query ID. + -- @param #CTLD_CARGO self + -- @return #number ID + function CTLD_CARGO:GetID() + return self.ID + end + + --- Query Subcategory + -- @param #CTLD_CARGO self + -- @return #string SubCategory + function CTLD_CARGO:GetSubCat() + return self.Subcategory + end + + --- Query Mass. + -- @param #CTLD_CARGO self + -- @return #number Mass in kg + function CTLD_CARGO:GetMass() + return self.PerCrateMass + end + + --- Query Name. + -- @param #CTLD_CARGO self + -- @return #string Name + function CTLD_CARGO:GetName() + return self.Name + end + + --- Query Templates. + -- @param #CTLD_CARGO self + -- @return #table Templates + function CTLD_CARGO:GetTemplates() + return self.Templates + end + + --- Query has moved. + -- @param #CTLD_CARGO self + -- @return #boolean Has moved + function CTLD_CARGO:HasMoved() + return self.HasBeenMoved + end + + --- Query was dropped. + -- @param #CTLD_CARGO self + -- @return #boolean Has been dropped. + function CTLD_CARGO:WasDropped() + return self.HasBeenDropped + end + + --- Query directly loadable. + -- @param #CTLD_CARGO self + -- @return #boolean loadable + function CTLD_CARGO:CanLoadDirectly() + return self.LoadDirectly + end + + --- Query number of crates or troopsize. + -- @param #CTLD_CARGO self + -- @return #number Crates or size of troops. + function CTLD_CARGO:GetCratesNeeded() + return self.CratesNeeded + end + + --- Query type. + -- @param #CTLD_CARGO self + -- @return #CTLD_CARGO.Enum Type + function CTLD_CARGO:GetType() + return self.CargoType + end + + --- Query type. + -- @param #CTLD_CARGO self + -- @return Wrapper.Positionable#POSITIONABLE Positionable + function CTLD_CARGO:GetPositionable() + return self.Positionable + end + + --- Set HasMoved. + -- @param #CTLD_CARGO self + -- @param #boolean moved + function CTLD_CARGO:SetHasMoved(moved) + self.HasBeenMoved = moved or false + end + + --- Query if cargo has been loaded. + -- @param #CTLD_CARGO self + -- @param #boolean loaded + function CTLD_CARGO:Isloaded() + if self.HasBeenMoved and not self.WasDropped() then + return true + else + return false + end + end + + --- Set WasDropped. + -- @param #CTLD_CARGO self + -- @param #boolean dropped + function CTLD_CARGO:SetWasDropped(dropped) + self.HasBeenDropped = dropped or false + end + + --- Get Stock. + -- @param #CTLD_CARGO self + -- @return #number Stock + function CTLD_CARGO:GetStock() + if self.Stock then + return self.Stock + else + return -1 + end + end + + --- Add Stock. + -- @param #CTLD_CARGO self + -- @param #number Number to add, none if nil. + -- @return #CTLD_CARGO self + function CTLD_CARGO:AddStock(Number) + if self.Stock then -- Stock nil? + local number = Number or 1 + self.Stock = self.Stock + number + end + return self + end + + --- Remove Stock. + -- @param #CTLD_CARGO self + -- @param #number Number to reduce, none if nil. + -- @return #CTLD_CARGO self + function CTLD_CARGO:RemoveStock(Number) + if self.Stock then -- Stock nil? + local number = Number or 1 + self.Stock = self.Stock - number + if self.Stock < 0 then self.Stock = 0 end + end + return self + end + + --- Set Stock. + -- @param #CTLD_CARGO self + -- @param #number Number to set, nil means unlimited. + -- @return #CTLD_CARGO self + function CTLD_CARGO:SetStock(Number) + self.Stock = Number + return self + end + + --- Query crate type for REPAIR + -- @param #CTLD_CARGO self + -- @param #boolean + function CTLD_CARGO:IsRepair() + if self.CargoType == "Repair" then + return true + else + return false + end + end + + --- Query crate type for STATIC + -- @param #CTLD_CARGO self + -- @return #boolean + function CTLD_CARGO:IsStatic() + if self.CargoType == "Static" then + return true + else + return false + end + end + + --- Add mark + -- @param #CTLD_CARGO self + -- @return #CTLD_CARGO self + function CTLD_CARGO:AddMark(Mark) + self.Mark = Mark + return self + end + + --- Get mark + -- @param #CTLD_CARGO self + -- @return #string Mark + function CTLD_CARGO:GetMark(Mark) + return self.Mark + end + + --- Wipe mark + -- @param #CTLD_CARGO self + -- @return #CTLD_CARGO self + function CTLD_CARGO:WipeMark() + self.Mark = nil + return self + end + + --- Get overall mass of a cargo object, i.e. crates needed x mass per crate + -- @param #CTLD_CARGO self + -- @return #number mass + function CTLD_CARGO:GetNetMass() + return self.CratesNeeded * self.PerCrateMass + end + +end + do ------------------------------------------------------ @@ -40,7 +333,7 @@ do -- @extends Core.Base#BASE --- --- @field #CTLD_ENGINEERING +-- @field #CTLD_ENGINEERING CTLD_ENGINEERING CTLD_ENGINEERING = { ClassName = "CTLD_ENGINEERING", lid = "", @@ -287,300 +580,6 @@ CTLD_ENGINEERING = { end - -do - ------------------------------------------------------- ---- **CTLD_CARGO** class, extends Core.Base#BASE --- @type CTLD_CARGO --- @field #string ClassName Class name. --- @field #number ID ID of this cargo. --- @field #string Name Name for menu. --- @field #table Templates Table of #POSITIONABLE objects. --- @field #string CargoType Enumerator of Type. --- @field #boolean HasBeenMoved Flag for moving. --- @field #boolean LoadDirectly Flag for direct loading. --- @field #number CratesNeeded Crates needed to build. --- @field Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission. --- @field #boolean HasBeenDropped True if dropped from heli. --- @field #number PerCrateMass Mass in kg. --- @field #number Stock Number of builds available, -1 for unlimited. --- @field #string Subcategory Sub-category name. --- @extends Core.Base#BASE - ---- --- @field #CTLD_CARGO CTLD_CARGO -CTLD_CARGO = { - ClassName = "CTLD_CARGO", - ID = 0, - Name = "none", - Templates = {}, - CargoType = "none", - HasBeenMoved = false, - LoadDirectly = false, - CratesNeeded = 0, - Positionable = nil, - HasBeenDropped = false, - PerCrateMass = 0, - Stock = nil, - Mark = nil, - } - - --- Define cargo types. - -- @type CTLD_CARGO.Enum - -- @field #string VEHICLE - -- @field #string TROOPS - -- @field #string FOB - -- @field #string CRATE - -- @field #string REPAIR - -- @field #string ENGINEERS - -- @field #string STATIC - CTLD_CARGO.Enum = { - VEHICLE = "Vehicle", -- #string vehicles - TROOPS = "Troops", -- #string troops - FOB = "FOB", -- #string FOB - CRATE = "Crate", -- #string crate - REPAIR = "Repair", -- #string repair - ENGINEERS = "Engineers", -- #string engineers - STATIC = "Static", -- #string statics - } - - --- Function to create new CTLD_CARGO object. - -- @param #CTLD_CARGO self - -- @param #number ID ID of this #CTLD_CARGO - -- @param #string Name Name for menu. - -- @param #table Templates Table of #POSITIONABLE objects. - -- @param #CTLD_CARGO.Enum Sorte Enumerator of Type. - -- @param #boolean HasBeenMoved Flag for moving. - -- @param #boolean LoadDirectly Flag for direct loading. - -- @param #number CratesNeeded Crates needed to build. - -- @param Wrapper.Positionable#POSITIONABLE Positionable Representation of cargo in the mission. - -- @param #boolean Dropped Cargo/Troops have been unloaded from a chopper. - -- @param #number PerCrateMass Mass in kg - -- @param #number Stock Number of builds available, nil for unlimited - -- @param #string Subcategory Name of subcategory, handy if using > 10 types to load. - -- @return #CTLD_CARGO self - function CTLD_CARGO:New(ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped, PerCrateMass, Stock, Subcategory) - -- Inherit everything from BASE class. - local self=BASE:Inherit(self, BASE:New()) -- #CTLD - self:T({ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped}) - self.ID = ID or math.random(100000,1000000) - self.Name = Name or "none" -- #string - self.Templates = Templates or {} -- #table - self.CargoType = Sorte or "type" -- #CTLD_CARGO.Enum - self.HasBeenMoved = HasBeenMoved or false -- #boolean - self.LoadDirectly = LoadDirectly or false -- #boolean - self.CratesNeeded = CratesNeeded or 0 -- #number - self.Positionable = Positionable or nil -- Wrapper.Positionable#POSITIONABLE - self.HasBeenDropped = Dropped or false --#boolean - self.PerCrateMass = PerCrateMass or 0 -- #number - self.Stock = Stock or nil --#number - self.Mark = nil - self.Subcategory = Subcategory or "Other" - return self - end - - --- Query ID. - -- @param #CTLD_CARGO self - -- @return #number ID - function CTLD_CARGO:GetID() - return self.ID - end - - --- Query Subcategory - -- @param #CTLD_CARGO self - -- @return #string SubCategory - function CTLD_CARGO:GetSubCat() - return self.Subcategory - end - - --- Query Mass. - -- @param #CTLD_CARGO self - -- @return #number Mass in kg - function CTLD_CARGO:GetMass() - return self.PerCrateMass - end - - --- Query Name. - -- @param #CTLD_CARGO self - -- @return #string Name - function CTLD_CARGO:GetName() - return self.Name - end - - --- Query Templates. - -- @param #CTLD_CARGO self - -- @return #table Templates - function CTLD_CARGO:GetTemplates() - return self.Templates - end - - --- Query has moved. - -- @param #CTLD_CARGO self - -- @return #boolean Has moved - function CTLD_CARGO:HasMoved() - return self.HasBeenMoved - end - - --- Query was dropped. - -- @param #CTLD_CARGO self - -- @return #boolean Has been dropped. - function CTLD_CARGO:WasDropped() - return self.HasBeenDropped - end - - --- Query directly loadable. - -- @param #CTLD_CARGO self - -- @return #boolean loadable - function CTLD_CARGO:CanLoadDirectly() - return self.LoadDirectly - end - - --- Query number of crates or troopsize. - -- @param #CTLD_CARGO self - -- @return #number Crates or size of troops. - function CTLD_CARGO:GetCratesNeeded() - return self.CratesNeeded - end - - --- Query type. - -- @param #CTLD_CARGO self - -- @return #CTLD_CARGO.Enum Type - function CTLD_CARGO:GetType() - return self.CargoType - end - - --- Query type. - -- @param #CTLD_CARGO self - -- @return Wrapper.Positionable#POSITIONABLE Positionable - function CTLD_CARGO:GetPositionable() - return self.Positionable - end - - --- Set HasMoved. - -- @param #CTLD_CARGO self - -- @param #boolean moved - function CTLD_CARGO:SetHasMoved(moved) - self.HasBeenMoved = moved or false - end - - --- Query if cargo has been loaded. - -- @param #CTLD_CARGO self - -- @param #boolean loaded - function CTLD_CARGO:Isloaded() - if self.HasBeenMoved and not self.WasDropped() then - return true - else - return false - end - end - - --- Set WasDropped. - -- @param #CTLD_CARGO self - -- @param #boolean dropped - function CTLD_CARGO:SetWasDropped(dropped) - self.HasBeenDropped = dropped or false - end - - --- Get Stock. - -- @param #CTLD_CARGO self - -- @return #number Stock - function CTLD_CARGO:GetStock() - if self.Stock then - return self.Stock - else - return -1 - end - end - - --- Add Stock. - -- @param #CTLD_CARGO self - -- @param #number Number to add, none if nil. - -- @return #CTLD_CARGO self - function CTLD_CARGO:AddStock(Number) - if self.Stock then -- Stock nil? - local number = Number or 1 - self.Stock = self.Stock + number - end - return self - end - - --- Remove Stock. - -- @param #CTLD_CARGO self - -- @param #number Number to reduce, none if nil. - -- @return #CTLD_CARGO self - function CTLD_CARGO:RemoveStock(Number) - if self.Stock then -- Stock nil? - local number = Number or 1 - self.Stock = self.Stock - number - if self.Stock < 0 then self.Stock = 0 end - end - return self - end - - --- Set Stock. - -- @param #CTLD_CARGO self - -- @param #number Number to set, nil means unlimited. - -- @return #CTLD_CARGO self - function CTLD_CARGO:SetStock(Number) - self.Stock = Number - return self - end - - --- Query crate type for REPAIR - -- @param #CTLD_CARGO self - -- @param #boolean - function CTLD_CARGO:IsRepair() - if self.CargoType == "Repair" then - return true - else - return false - end - end - - --- Query crate type for STATIC - -- @param #CTLD_CARGO self - -- @return #boolean - function CTLD_CARGO:IsStatic() - if self.CargoType == "Static" then - return true - else - return false - end - end - - --- Add mark - -- @param #CTLD_CARGO self - -- @return #CTLD_CARGO self - function CTLD_CARGO:AddMark(Mark) - self.Mark = Mark - return self - end - - --- Get mark - -- @param #CTLD_CARGO self - -- @return #string Mark - function CTLD_CARGO:GetMark(Mark) - return self.Mark - end - - --- Wipe mark - -- @param #CTLD_CARGO self - -- @return #CTLD_CARGO self - function CTLD_CARGO:WipeMark() - self.Mark = nil - return self - end - - --- Get overall mass of a cargo object, i.e. crates needed x mass per crate - -- @param #CTLD_CARGO self - -- @return #number mass - function CTLD_CARGO:GetNetMass() - return self.CratesNeeded * self.PerCrateMass - end - -end - do ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -- TODO CTLD From c7d990850a24b8bad32590a198fa4e61e01387f1 Mon Sep 17 00:00:00 2001 From: Thomas <72444570+Applevangelist@users.noreply.github.com> Date: Mon, 24 Apr 2023 11:16:45 +0200 Subject: [PATCH 6/6] AIRBASE - add Normandy AFBs (#1937) (#1938) Add Normandy AFBs --- Moose Development/Moose/Wrapper/Airbase.lua | 83 +++++++++++++++++++-- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/Moose Development/Moose/Wrapper/Airbase.lua b/Moose Development/Moose/Wrapper/Airbase.lua index 5e4a2d0e3..07c2acf7e 100644 --- a/Moose Development/Moose/Wrapper/Airbase.lua +++ b/Moose Development/Moose/Wrapper/Airbase.lua @@ -198,8 +198,47 @@ AIRBASE.Nevada = { -- * AIRBASE.Normandy.Needs_Oar_Point -- * AIRBASE.Normandy.Funtington -- * AIRBASE.Normandy.Tangmere --- * AIRBASE.Normandy.Ford_AF --- +-- * AIRBASE.Normandy.Ford +-- * AIRBASE.Normandy.Argentan +-- * AIRBASE.Normandy.Goulet +-- * AIRBASE.Normandy.Barville +-- * AIRBASE.Normandy.Essay +-- * AIRBASE.Normandy.Hauterive +-- * AIRBASE.Normandy.Lymington +-- * AIRBASE.Normandy.Vrigny +-- * AIRBASE.Normandy.Odiham +-- * AIRBASE.Normandy.Conches +-- * AIRBASE.Normandy.West_Malling +-- * AIRBASE.Normandy.Villacoublay +-- * AIRBASE.Normandy.Kenley +-- * AIRBASE.Normandy.Beauvais_Tille +-- * AIRBASE.Normandy.Cormeilles_en_Vexin +-- * AIRBASE.Normandy.Creil +-- * AIRBASE.Normandy.Guyancourt +-- * AIRBASE.Normandy.Lonrai +-- * AIRBASE.Normandy.Dinan_Trelivan +-- * AIRBASE.Normandy.Heathrow +-- * AIRBASE.Normandy.Fecamp_Benouville +-- * AIRBASE.Normandy.Farnborough +-- * AIRBASE.Normandy.Friston +-- * AIRBASE.Normandy.Deanland +-- * AIRBASE.Normandy.Triqueville +-- * AIRBASE.Normandy.Poix +-- * AIRBASE.Normandy.Orly +-- * AIRBASE.Normandy.Stoney_Cross +-- * AIRBASE.Normandy.Amiens_Glisy +-- * AIRBASE.Normandy.Ronai +-- * AIRBASE.Normandy.Rouen_Boos +-- * AIRBASE.Normandy.Deauville +-- * AIRBASE.Normandy.Saint_Aubin +-- * AIRBASE.Normandy.Flers +-- * AIRBASE.Normandy.Avranches_Le_Val_Saint_Pere +-- * AIRBASE.Normandy.Gravesend +-- * AIRBASE.Normandy.Beaumont_le_Roger +-- * AIRBASE.Normandy.Broglie +-- * AIRBASE.Normandy.Bernay_Saint_Martin +-- * AIRBASE.Normandy.Saint_Andre_de_lEure +-- -- @field Normandy AIRBASE.Normandy = { ["Saint_Pierre_du_Mont"] = "Saint Pierre du Mont", @@ -232,14 +271,46 @@ AIRBASE.Normandy = { ["Needs_Oar_Point"] = "Needs Oar Point", ["Funtington"] = "Funtington", ["Tangmere"] = "Tangmere", - ["Ford_AF"] = "Ford_AF", - ["Goulet"] = "Goulet", + ["Ford"] = "Ford", ["Argentan"] = "Argentan", - ["Vrigny"] = "Vrigny", + ["Goulet"] = "Goulet", + ["Barville"] = "Barville", ["Essay"] = "Essay", ["Hauterive"] = "Hauterive", - ["Barville"] = "Barville", + ["Lymington"] = "Lymington", + ["Vrigny"] = "Vrigny", + ["Odiham"] = "Odiham", ["Conches"] = "Conches", + ["West_Malling"] = "West Malling", + ["Villacoublay"] = "Villacoublay", + ["Kenley"] = "Kenley", + ["Beauvais_Tille"] = "Beauvais-Tille", + ["Cormeilles_en_Vexin"] = "Cormeilles-en-Vexin", + ["Creil"] = "Creil", + ["Guyancourt"] = "Guyancourt", + ["Lonrai"] = "Lonrai", + ["Dinan_Trelivan"] = "Dinan-Trelivan", + ["Heathrow"] = "Heathrow", + ["Fecamp_Benouville"] = "Fecamp-Benouville", + ["Farnborough"] = "Farnborough", + ["Friston"] = "Friston", + ["Deanland "] = "Deanland ", + ["Triqueville"] = "Triqueville", + ["Poix"] = "Poix", + ["Orly"] = "Orly", + ["Stoney_Cross"] = "Stoney Cross", + ["Amiens_Glisy"] = "Amiens-Glisy", + ["Ronai"] = "Ronai", + ["Rouen_Boos"] = "Rouen-Boos", + ["Deauville"] = "Deauville", + ["Saint_Aubin"] = "Saint-Aubin", + ["Flers"] = "Flers", + ["Avranches_Le_Val_Saint_Pere"] = "Avranches Le Val-Saint-Pere", + ["Gravesend"] = "Gravesend", + ["Beaumont_le_Roger"] = "Beaumont-le-Roger", + ["Broglie"] = "Broglie", + ["Bernay_Saint_Martin"] = "Bernay Saint Martin", + ["Saint_Andre_de_lEure"] = "Saint-Andre-de-lEure", } --- Airbases of the Persion Gulf Map: