diff --git a/Moose Development/Moose/Core/Beacon.lua b/Moose Development/Moose/Core/Beacon.lua index 37dba8c76..c5203a6b3 100644 --- a/Moose Development/Moose/Core/Beacon.lua +++ b/Moose Development/Moose/Core/Beacon.lua @@ -1,9 +1,9 @@ --- **Core** - TACAN and other beacons. --- +-- -- === --- +-- -- ## Features: --- +-- -- * Provide beacon functionality to assist pilots. -- -- === @@ -14,34 +14,34 @@ -- @image Core_Radio.JPG --- *In order for the light to shine so brightly, the darkness must be present.* -- Francis Bacon --- +-- -- After attaching a @{#BEACON} to your @{Wrapper.Positionable#POSITIONABLE}, you need to select the right function to activate the kind of beacon you want. -- There are two types of BEACONs available : the AA TACAN Beacon and the general purpose Radio Beacon. -- Note that in both case, you can set an optional parameter : the `BeaconDuration`. This can be very usefull to simulate the battery time if your BEACON is --- attach to a cargo crate, for exemple. --- +-- attach to a cargo crate, for exemple. +-- -- ## AA TACAN Beacon usage --- +-- -- This beacon only works with airborne @{Wrapper.Unit#UNIT} or a @{Wrapper.Group#GROUP}. Use @{#BEACON:AATACAN}() to set the beacon parameters and start the beacon. -- Use @#BEACON:StopAATACAN}() to stop it. --- +-- -- ## General Purpose Radio Beacon usage --- +-- -- This beacon will work with any @{Wrapper.Positionable#POSITIONABLE}, but **it won't follow the @{Wrapper.Positionable#POSITIONABLE}** ! This means that you should only use it with -- @{Wrapper.Positionable#POSITIONABLE} that don't move, or move very slowly. Use @{#BEACON:RadioBeacon}() to set the beacon parameters and start the beacon. -- Use @{#BEACON:StopRadioBeacon}() to stop it. --- +-- -- @type BEACON -- @field #string ClassName Name of the class "BEACON". -- @field Wrapper.Controllable#CONTROLLABLE Positionable The @{#CONTROLLABLE} that will receive radio capabilities. -- @extends Core.Base#BASE BEACON = { - ClassName = "BEACON", + ClassName = "BEACON", Positionable = nil, - name = nil, + name = nil, } ---- Beacon types supported by DCS. +--- Beacon types supported by DCS. -- @type BEACON.Type -- @field #number NULL -- @field #number VOR @@ -65,19 +65,19 @@ BEACON = { -- @field #number ICLS_GLIDESLOPE -- @field #number NAUTICAL_HOMER BEACON.Type={ - NULL = 0, + NULL = 0, VOR = 1, DME = 2, - VOR_DME = 3, + VOR_DME = 3, TACAN = 4, - VORTAC = 5, + VORTAC = 5, RSBN = 128, - BROADCAST_STATION = 1024, + BROADCAST_STATION = 1024, HOMER = 8, - AIRPORT_HOMER = 4104, - AIRPORT_HOMER_WITH_MARKER = 4136, + AIRPORT_HOMER = 4104, + AIRPORT_HOMER_WITH_MARKER = 4136, ILS_FAR_HOMER = 16408, - ILS_NEAR_HOMER = 16424, + ILS_NEAR_HOMER = 16424, ILS_LOCALIZER = 16640, ILS_GLIDESLOPE = 16896, PRMG_LOCALIZER = 33024, @@ -95,11 +95,11 @@ BEACON.Type={ -- @field #number TACAN TACtical Air Navigation system on ground. -- @field #number TACAN_TANKER_X TACtical Air Navigation system for tankers on X band. -- @field #number TACAN_TANKER_Y TACtical Air Navigation system for tankers on Y band. --- @field #number VOR Very High Frequency Omni-Directional Range +-- @field #number VOR Very High Frequency Omnidirectional Range -- @field #number ILS_LOCALIZER ILS localizer --- @field #number ILS_GLIDESLOPE ILS glideslope. +-- @field #number ILS_GLIDESLOPE ILS glide slope. -- @field #number PRGM_LOCALIZER PRGM localizer. --- @field #number PRGM_GLIDESLOPE PRGM glideslope. +-- @field #number PRGM_GLIDESLOPE PRGM glide slope. -- @field #number BROADCAST_STATION Broadcast station. -- @field #number VORTAC Radio-based navigational aid for aircraft pilots consisting of a co-located VHF omnidirectional range (VOR) beacon and a tactical air navigation system (TACAN) beacon. -- @field #number TACAN_AA_MODE_X TACtical Air Navigation for aircraft on X band. @@ -108,13 +108,13 @@ BEACON.Type={ -- @field #number ICLS_LOCALIZER Carrier landing system. -- @field #number ICLS_GLIDESLOPE Carrier landing system. BEACON.System={ - PAR_10 = 1, - RSBN_5 = 2, - TACAN = 3, + PAR_10 = 1, + RSBN_5 = 2, + TACAN = 3, TACAN_TANKER_X = 4, TACAN_TANKER_Y = 5, - VOR = 6, - ILS_LOCALIZER = 7, + VOR = 6, + ILS_LOCALIZER = 7, ILS_GLIDESLOPE = 8, PRMG_LOCALIZER = 9, PRMG_GLIDESLOPE = 10, @@ -131,28 +131,27 @@ BEACON.System={ -- If you want to create a BEACON, you probably should use @{Wrapper.Positionable#POSITIONABLE.GetBeacon}() instead. -- @param #BEACON self -- @param Wrapper.Positionable#POSITIONABLE Positionable The @{Positionable} that will receive radio capabilities. --- @return #BEACON Beacon object or #nil if the positionable is invalid. -function BEACON:New(Positionable) +-- @return #BEACON Beacon object or #nil if the POSITIONABLE is invalid. +function BEACON:New( Positionable ) -- Inherit BASE. - local self=BASE:Inherit(self, BASE:New()) --#BEACON - + local self = BASE:Inherit( self, BASE:New() ) -- #BEACON + -- Debug. - self:F(Positionable) - + self:F( Positionable ) + -- Set positionable. - if Positionable:GetPointVec2() then -- It's stupid, but the only way I found to make sure positionable is valid + if Positionable:GetPointVec2() then -- It's stupid, but the only way I found to make sure POSITIONABLE is valid self.Positionable = Positionable - self.name=Positionable:GetName() - self:I(string.format("New BEACON %s", tostring(self.name))) + self.name = Positionable:GetName() + self:I( string.format( "New BEACON %s", tostring( self.name ) ) ) return self end - - self:E({"The passed positionable is invalid, no BEACON created", Positionable}) + + self:E( { "The passed POSITIONABLE is invalid, no BEACON created", Positionable } ) return nil end - --- Activates a TACAN BEACON. -- @param #BEACON self -- @param #number Channel TACAN channel, i.e. the "10" part in "10Y". @@ -162,53 +161,55 @@ end -- @param #number Duration How long will the beacon last in seconds. Omit for forever. -- @return #BEACON self -- @usage +-- -- -- Let's create a TACAN Beacon for a tanker --- local myUnit = UNIT:FindByName("MyUnit") +-- local myUnit = UNIT:FindByName("MyUnit") -- local myBeacon = myUnit:GetBeacon() -- Creates the beacon --- +-- -- myBeacon:ActivateTACAN(20, "Y", "TEXACO", true) -- Activate the beacon -function BEACON:ActivateTACAN(Channel, Mode, Message, Bearing, Duration) - self:T({channel=Channel, mode=Mode, callsign=Message, bearing=Bearing, duration=Duration}) - +-- +function BEACON:ActivateTACAN( Channel, Mode, Message, Bearing, Duration ) + self:T( { channel = Channel, mode = Mode, callsign = Message, bearing = Bearing, duration = Duration } ) + -- Get frequency. - local Frequency=UTILS.TACANToFrequency(Channel, Mode) - + local Frequency = UTILS.TACANToFrequency( Channel, Mode ) + -- Check. - if not Frequency then - self:E({"The passed TACAN channel is invalid, the BEACON is not emitting"}) + if not Frequency then + self:E( { "The passed TACAN channel is invalid, the BEACON is not emitting" } ) return self end - + -- Beacon type. - local Type=BEACON.Type.TACAN - + local Type = BEACON.Type.TACAN + -- Beacon system. - local System=BEACON.System.TACAN - + local System = BEACON.System.TACAN + -- Check if unit is an aircraft and set system accordingly. - local AA=self.Positionable:IsAir() + local AA = self.Positionable:IsAir() if AA then - System=5 --NOTE: 5 is how you cat the correct tanker behaviour! --BEACON.System.TACAN_TANKER + System = 5 -- NOTE: 5 is how you cat the correct tanker behaviour! --BEACON.System.TACAN_TANKER -- Check if "Y" mode is selected for aircraft. - if Mode~="Y" then - self:E({"WARNING: The POSITIONABLE you want to attach the AA Tacan Beacon is an aircraft: Mode should Y !The BEACON is not emitting.", self.Positionable}) + if Mode ~= "Y" then + self:E( { "WARNING: The POSITIONABLE you want to attach the AA TACAN Beacon is an aircraft: Mode should Y! The BEACON is not emitting.", self.Positionable } ) end end - + -- Attached unit. - local UnitID=self.Positionable:GetID() - + local UnitID = self.Positionable:GetID() + -- Debug. - self:I({string.format("BEACON Activating TACAN %s: Channel=%d%s, Morse=%s, Bearing=%s, Duration=%s!", tostring(self.name), Channel, Mode, Message, tostring(Bearing), tostring(Duration))}) - + self:I( { string.format( "BEACON Activating TACAN %s: Channel=%d%s, Morse=%s, Bearing=%s, Duration=%s!", tostring( self.name ), Channel, Mode, Message, tostring( Bearing ), tostring( Duration ) ) } ) + -- Start beacon. - self.Positionable:CommandActivateBeacon(Type, System, Frequency, UnitID, Channel, Mode, AA, Message, Bearing) - - -- Stop sheduler. + self.Positionable:CommandActivateBeacon( Type, System, Frequency, UnitID, Channel, Mode, AA, Message, Bearing ) + + -- Stop scheduler. if Duration then - self.Positionable:DeactivateBeacon(Duration) + self.Positionable:DeactivateBeacon( Duration ) end - + return self end @@ -218,23 +219,23 @@ end -- @param #string Callsign The Message that is going to be coded in Morse and broadcasted by the beacon. -- @param #number Duration How long will the beacon last in seconds. Omit for forever. -- @return #BEACON self -function BEACON:ActivateICLS(Channel, Callsign, Duration) - self:F({Channel=Channel, Callsign=Callsign, Duration=Duration}) - +function BEACON:ActivateICLS( Channel, Callsign, Duration ) + self:F( { Channel = Channel, Callsign = Callsign, Duration = Duration } ) + -- Attached unit. - local UnitID=self.Positionable:GetID() - + local UnitID = self.Positionable:GetID() + -- Debug - self:T2({"ICLS BEACON started!"}) - + self:T2( { "ICLS BEACON started!" } ) + -- Start beacon. - self.Positionable:CommandActivateICLS(Channel, UnitID, Callsign) - - -- Stop sheduler + self.Positionable:CommandActivateICLS( Channel, UnitID, Callsign ) + + -- Stop scheduler if Duration then -- Schedule the stop of the BEACON if asked by the MD - self.Positionable:DeactivateBeacon(Duration) + self.Positionable:DeactivateBeacon( Duration ) end - + return self end @@ -246,27 +247,29 @@ end -- @param #number BeaconDuration How long will the beacon last in seconds. Omit for forever. -- @return #BEACON self -- @usage +-- -- -- Let's create a TACAN Beacon for a tanker --- local myUnit = UNIT:FindByName("MyUnit") +-- local myUnit = UNIT:FindByName("MyUnit") -- local myBeacon = myUnit:GetBeacon() -- Creates the beacon --- +-- -- myBeacon:AATACAN(20, "TEXACO", true) -- Activate the beacon -function BEACON:AATACAN(TACANChannel, Message, Bearing, BeaconDuration) - self:F({TACANChannel, Message, Bearing, BeaconDuration}) - +-- +function BEACON:AATACAN( TACANChannel, Message, Bearing, BeaconDuration ) + self:F( { TACANChannel, Message, Bearing, BeaconDuration } ) + local IsValid = true - + if not self.Positionable:IsAir() then - self:E({"The POSITIONABLE you want to attach the AA Tacan Beacon is not an aircraft ! The BEACON is not emitting", self.Positionable}) + self:E( { "The POSITIONABLE you want to attach the AA TACAN Beacon is not an aircraft! The BEACON is not emitting", self.Positionable } ) IsValid = false end - - local Frequency = self:_TACANToFrequency(TACANChannel, "Y") - if not Frequency then - self:E({"The passed TACAN channel is invalid, the BEACON is not emitting"}) + + local Frequency = self:_TACANToFrequency( TACANChannel, "Y" ) + if not Frequency then + self:E( { "The passed TACAN channel is invalid, the BEACON is not emitting" } ) IsValid = false end - + -- I'm using the beacon type 4 (BEACON_TYPE_TACAN). For System, I'm using 5 (TACAN_TANKER_MODE_Y) if the bearing shows its bearing -- or 14 (TACAN_AA_MODE_Y) if it does not local System @@ -275,27 +278,26 @@ function BEACON:AATACAN(TACANChannel, Message, Bearing, BeaconDuration) else System = 14 end - + if IsValid then -- Starts the BEACON - self:T2({"AA TACAN BEACON started !"}) - self.Positionable:SetCommand({ + self:T2( { "AA TACAN BEACON started !" } ) + self.Positionable:SetCommand( { id = "ActivateBeacon", params = { type = 4, system = System, callsign = Message, frequency = Frequency, - } - }) - + }, + } ) + if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD - SCHEDULER:New(nil, - function() + SCHEDULER:New( nil, function() self:StopAATACAN() - end, {}, BeaconDuration) + end, {}, BeaconDuration ) end end - + return self end @@ -305,21 +307,19 @@ end function BEACON:StopAATACAN() self:F() if not self.Positionable then - self:E({"Start the beacon first before stoping it !"}) + self:E( { "Start the beacon first before stopping it!" } ) else - self.Positionable:SetCommand({ - id = 'DeactivateBeacon', - params = { - } - }) + self.Positionable:SetCommand( { + id = 'DeactivateBeacon', + params = {}, + } ) end end - ---- Activates a general pupose Radio Beacon +--- Activates a general purpose Radio Beacon -- This uses the very generic singleton function "trigger.action.radioTransmission()" provided by DCS to broadcast a sound file on a specific frequency. -- Although any frequency could be used, only 2 DCS Modules can home on radio beacons at the time of writing : the Huey and the Mi-8. --- They can home in on these specific frequencies : +-- They can home in on these specific frequencies : -- * **Mi8** -- * R-828 -> 20-60MHz -- * ARKUD -> 100-150MHz (canal 1 : 114166, canal 2 : 114333, canal 3 : 114583, canal 4 : 121500, canal 5 : 123100, canal 6 : 124100) AM @@ -342,55 +342,54 @@ end -- -- -- Set the beacon and start it -- UnitBeacon:RadioBeacon("MySoundFileSOS.ogg", 40, radio.modulation.FM, 20, 5*60) -function BEACON:RadioBeacon(FileName, Frequency, Modulation, Power, BeaconDuration) - self:F({FileName, Frequency, Modulation, Power, BeaconDuration}) +function BEACON:RadioBeacon( FileName, Frequency, Modulation, Power, BeaconDuration ) + self:F( { FileName, Frequency, Modulation, Power, BeaconDuration } ) local IsValid = false - + -- Check the filename - if type(FileName) == "string" then - if FileName:find(".ogg") or FileName:find(".wav") then - if not FileName:find("l10n/DEFAULT/") then + if type( FileName ) == "string" then + if FileName:find( ".ogg" ) or FileName:find( ".wav" ) then + if not FileName:find( "l10n/DEFAULT/" ) then FileName = "l10n/DEFAULT/" .. FileName end IsValid = true end end if not IsValid then - self:E({"File name invalid. Maybe something wrong with the extension ? ", FileName}) + self:E( { "File name invalid. Maybe something wrong with the extension? ", FileName } ) end - + -- Check the Frequency - if type(Frequency) ~= "number" and IsValid then - self:E({"Frequency invalid. ", Frequency}) + if type( Frequency ) ~= "number" and IsValid then + self:E( { "Frequency invalid. ", Frequency } ) IsValid = false end Frequency = Frequency * 1000000 -- Conversion to Hz - + -- Check the modulation - if Modulation ~= radio.modulation.AM and Modulation ~= radio.modulation.FM and IsValid then --TODO Maybe make this future proof if ED decides to add an other modulation ? - self:E({"Modulation is invalid. Use DCS's enum radio.modulation.", Modulation}) + if Modulation ~= radio.modulation.AM and Modulation ~= radio.modulation.FM and IsValid then -- TODO: Maybe make this future proof if ED decides to add an other modulation ? + self:E( { "Modulation is invalid. Use DCS's enum radio.modulation.", Modulation } ) IsValid = false end - + -- Check the Power - if type(Power) ~= "number" and IsValid then - self:E({"Power is invalid. ", Power}) + if type( Power ) ~= "number" and IsValid then + self:E( { "Power is invalid. ", Power } ) IsValid = false end - Power = math.floor(math.abs(Power)) --TODO Find what is the maximum power allowed by DCS and limit power to that - + Power = math.floor( math.abs( Power ) ) -- TODO: Find what is the maximum power allowed by DCS and limit power to that + if IsValid then - self:T2({"Activating Beacon on ", Frequency, Modulation}) + self:T2( { "Activating Beacon on ", Frequency, Modulation } ) -- Note that this is looped. I have to give this transmission a unique name, I use the class ID - trigger.action.radioTransmission(FileName, self.Positionable:GetPositionVec3(), Modulation, true, Frequency, Power, tostring(self.ID)) - - if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD - SCHEDULER:New( nil, - function() - self:StopRadioBeacon() - end, {}, BeaconDuration) - end - end + trigger.action.radioTransmission( FileName, self.Positionable:GetPositionVec3(), Modulation, true, Frequency, Power, tostring( self.ID ) ) + + if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD + SCHEDULER:New( nil, function() + self:StopRadioBeacon() + end, {}, BeaconDuration ) + end + end end --- Stops the AA TACAN BEACON @@ -399,7 +398,7 @@ end function BEACON:StopRadioBeacon() self:F() -- The unique name of the transmission is the class ID - trigger.action.stopRadioTransmission(tostring(self.ID)) + trigger.action.stopRadioTransmission( tostring( self.ID ) ) return self end @@ -407,26 +406,26 @@ end -- @param #BEACON self -- @param #number TACANChannel -- @param #string TACANMode --- @return #number Frequecy +-- @return #number Frequency -- @return #nil if parameters are invalid -function BEACON:_TACANToFrequency(TACANChannel, TACANMode) - self:F3({TACANChannel, TACANMode}) +function BEACON:_TACANToFrequency( TACANChannel, TACANMode ) + self:F3( { TACANChannel, TACANMode } ) - if type(TACANChannel) ~= "number" then + if type( TACANChannel ) ~= "number" then if TACANMode ~= "X" and TACANMode ~= "Y" then return nil -- error in arguments end end - --- This code is largely based on ED's code, in DCS World\Scripts\World\Radio\BeaconTypes.lua, line 137. --- I have no idea what it does but it seems to work + + -- This code is largely based on ED's code, in DCS World\Scripts\World\Radio\BeaconTypes.lua, line 137. + -- I have no idea what it does but it seems to work local A = 1151 -- 'X', channel >= 64 - local B = 64 -- channel >= 64 - + local B = 64 -- channel >= 64 + if TACANChannel < 64 then B = 1 end - + if TACANMode == 'Y' then A = 1025 if TACANChannel < 64 then @@ -437,6 +436,6 @@ function BEACON:_TACANToFrequency(TACANChannel, TACANMode) A = 962 end end - + return (A + TACANChannel - B) * 1000000 -end \ No newline at end of file +end diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index 50031e81b..02a2d8b57 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -31,7 +31,6 @@ -- @module Core.Database -- @image Core_Database.JPG - --- @type DATABASE -- @field #string ClassName Name of the class. -- @field #table Templates Templates: Units, Groups, Statics, ClientsByName, ClientsByID. @@ -51,7 +50,7 @@ -- * PLAYERS -- * CARGOS -- --- On top, for internal MOOSE administration purposes, the DATBASE administers the Unit and Group TEMPLATES as defined within the Mission Editor. +-- On top, for internal MOOSE administration purposes, the DATABASE administers the Unit and Group TEMPLATES as defined within the Mission Editor. -- -- The singleton object **_DATABASE** is automatically created by MOOSE, that administers all objects within the mission. -- Moose refers to **_DATABASE** within the framework extensively, but you can also refer to the _DATABASE object within your missions if required. @@ -90,22 +89,19 @@ DATABASE = { FLIGHTCONTROLS = {}, } -local _DATABASECoalition = - { - [1] = "Red", - [2] = "Blue", - [3] = "Neutral", - } - -local _DATABASECategory = - { - ["plane"] = Unit.Category.AIRPLANE, - ["helicopter"] = Unit.Category.HELICOPTER, - ["vehicle"] = Unit.Category.GROUND_UNIT, - ["ship"] = Unit.Category.SHIP, - ["static"] = Unit.Category.STRUCTURE, - } +local _DATABASECoalition = { + [1] = "Red", + [2] = "Blue", + [3] = "Neutral", +} +local _DATABASECategory = { + ["plane"] = Unit.Category.AIRPLANE, + ["helicopter"] = Unit.Category.HELICOPTER, + ["vehicle"] = Unit.Category.GROUND_UNIT, + ["ship"] = Unit.Category.SHIP, + ["static"] = Unit.Category.STRUCTURE, +} --- Creates a new DATABASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names. -- @param #DATABASE self @@ -129,15 +125,15 @@ function DATABASE:New() self:HandleEvent( EVENTS.DeleteCargo ) self:HandleEvent( EVENTS.NewZone ) self:HandleEvent( EVENTS.DeleteZone ) - --self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) -- This is not working anymore!, handling this through the birth event. + -- self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) -- This is not working anymore!, handling this through the birth event. self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit ) self:_RegisterTemplates() self:_RegisterGroupsAndUnits() self:_RegisterClients() self:_RegisterStatics() - --self:_RegisterAirbases() - --self:_RegisterPlayers() + -- self:_RegisterAirbases() + -- self:_RegisterPlayers() self.UNITS_Position = 0 @@ -154,7 +150,6 @@ function DATABASE:FindUnit( UnitName ) return UnitFound end - --- Adds a Unit based on the Unit Name in the DATABASE. -- @param #DATABASE self -- @param #string DCSUnitName Unit name. @@ -162,23 +157,22 @@ end function DATABASE:AddUnit( DCSUnitName ) if not self.UNITS[DCSUnitName] then - + -- Debug info. self:T( { "Add UNIT:", DCSUnitName } ) - - --local UnitRegister = UNIT:Register( DCSUnitName ) - + + -- local UnitRegister = UNIT:Register( DCSUnitName ) + -- Register unit - self.UNITS[DCSUnitName]=UNIT:Register(DCSUnitName) + self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName ) -- This is not used anywhere in MOOSE as far as I can see so I remove it until there comes an error somewhere. - --table.insert(self.UNITS_Index, DCSUnitName ) + -- table.insert(self.UNITS_Index, DCSUnitName ) end return self.UNITS[DCSUnitName] end - --- Deletes a Unit from the DATABASE based on the Unit Name. -- @param #DATABASE self function DATABASE:DeleteUnit( DCSUnitName ) @@ -200,7 +194,6 @@ function DATABASE:AddStatic( DCSStaticName ) return nil end - --- Deletes a Static from the DATABASE based on the Static Name. -- @param #DATABASE self function DATABASE:DeleteStatic( DCSStaticName ) @@ -240,7 +233,6 @@ function DATABASE:AddAirbase( AirbaseName ) return self.AIRBASES[AirbaseName] end - --- Deletes a Airbase from the DATABASE based on the Airbase Name. -- @param #DATABASE self -- @param #string AirbaseName The name of the airbase @@ -259,7 +251,6 @@ function DATABASE:FindAirbase( AirbaseName ) return AirbaseFound end - do -- Zones --- Finds a @{Zone} based on the zone name. @@ -283,7 +274,6 @@ do -- Zones end end - --- Deletes a @{Zone} from the DATABASE based on the zone name. -- @param #DATABASE self -- @param #string ZoneName The name of the zone. @@ -292,83 +282,82 @@ do -- Zones self.ZONES[ZoneName] = nil end - --- Private method that registers new ZONE_BASE derived objects within the DATABASE Object. -- @param #DATABASE self -- @return #DATABASE self function DATABASE:_RegisterZones() - for ZoneID, ZoneData in pairs(env.mission.triggers.zones) do + for ZoneID, ZoneData in pairs( env.mission.triggers.zones ) do local ZoneName = ZoneData.name - + -- Color - local color=ZoneData.color or {1, 0, 0, 0.15} - + local color = ZoneData.color or { 1, 0, 0, 0.15 } + -- Create new Zone - local Zone=nil --Core.Zone#ZONE_BASE - - if ZoneData.type==0 then - + local Zone = nil -- Core.Zone#ZONE_BASE + + if ZoneData.type == 0 then + --- -- Circular zone --- - - self:I(string.format("Register ZONE: %s (Circular)", ZoneName)) - - Zone=ZONE:New(ZoneName) - + + self:I( string.format( "Register ZONE: %s (Circular)", ZoneName ) ) + + Zone = ZONE:New( ZoneName ) + else --- -- Quad-point zone --- - self:I(string.format("Register ZONE: %s (Polygon, Quad)", ZoneName)) - - Zone=ZONE_POLYGON_BASE:New(ZoneName, ZoneData.verticies) - - --for i,vec2 in pairs(ZoneData.verticies) do + self:I( string.format( "Register ZONE: %s (Polygon, Quad)", ZoneName ) ) + + Zone = ZONE_POLYGON_BASE:New( ZoneName, ZoneData.verticies ) + + -- for i,vec2 in pairs(ZoneData.verticies) do -- local coord=COORDINATE:NewFromVec2(vec2) -- coord:MarkToAll(string.format("%s Point %d", ZoneName, i)) - --end - + -- end + end - + if Zone then -- Store color of zone. - Zone.Color=color - + Zone.Color = color + -- Store in DB. self.ZONENAMES[ZoneName] = ZoneName - + -- Add zone. - self:AddZone(ZoneName, Zone) - + self:AddZone( ZoneName, Zone ) + end - + end -- Polygon zones defined by late activated groups. for ZoneGroupName, ZoneGroup in pairs( self.GROUPS ) do - if ZoneGroupName:match("#ZONE_POLYGON") then - - local ZoneName1 = ZoneGroupName:match("(.*)#ZONE_POLYGON") - local ZoneName2 = ZoneGroupName:match(".*#ZONE_POLYGON(.*)") - local ZoneName = ZoneName1 .. ( ZoneName2 or "" ) + if ZoneGroupName:match( "#ZONE_POLYGON" ) then + + local ZoneName1 = ZoneGroupName:match( "(.*)#ZONE_POLYGON" ) + local ZoneName2 = ZoneGroupName:match( ".*#ZONE_POLYGON(.*)" ) + local ZoneName = ZoneName1 .. (ZoneName2 or "") -- Debug output - self:I(string.format("Register ZONE: %s (Polygon)", ZoneName)) - + self:I( string.format( "Register ZONE: %s (Polygon)", ZoneName ) ) + -- Create a new polygon zone. local Zone_Polygon = ZONE_POLYGON:New( ZoneName, ZoneGroup ) - + -- Set color. - Zone_Polygon:SetColor({1, 0, 0}, 0.15) - + Zone_Polygon:SetColor( { 1, 0, 0 }, 0.15 ) + -- Store name in DB. self.ZONENAMES[ZoneName] = ZoneName - + -- Add zone to DB. self:AddZone( ZoneName, Zone_Polygon ) end @@ -376,7 +365,6 @@ do -- Zones end - end -- zone do -- Zone_Goal @@ -402,7 +390,6 @@ do -- Zone_Goal end end - --- Deletes a @{Zone} from the DATABASE based on the zone name. -- @param #DATABASE self -- @param #string ZoneName The name of the zone. @@ -424,7 +411,6 @@ do -- cargo end end - --- Deletes a Cargo from the DATABASE based on the Cargo Name. -- @param #DATABASE self -- @param #string CargoName The name of the airbase @@ -466,38 +452,38 @@ do -- cargo for CargoGroupName, CargoGroup in pairs( Groups ) do if self:IsCargo( CargoGroupName ) then - local CargoInfo = CargoGroupName:match("#CARGO(.*)") - local CargoParam = CargoInfo and CargoInfo:match( "%((.*)%)") - local CargoName1 = CargoGroupName:match("(.*)#CARGO%(.*%)") - local CargoName2 = CargoGroupName:match(".*#CARGO%(.*%)(.*)") - local CargoName = CargoName1 .. ( CargoName2 or "" ) - local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?") - local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?") or CargoName - local LoadRadius = CargoParam and tonumber( CargoParam:match( "RR=([%a%d]+),?") ) - local NearRadius = CargoParam and tonumber( CargoParam:match( "NR=([%a%d]+),?") ) + local CargoInfo = CargoGroupName:match( "#CARGO(.*)" ) + local CargoParam = CargoInfo and CargoInfo:match( "%((.*)%)" ) + local CargoName1 = CargoGroupName:match( "(.*)#CARGO%(.*%)" ) + local CargoName2 = CargoGroupName:match( ".*#CARGO%(.*%)(.*)" ) + local CargoName = CargoName1 .. (CargoName2 or "") + local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?" ) + local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?" ) or CargoName + local LoadRadius = CargoParam and tonumber( CargoParam:match( "RR=([%a%d]+),?" ) ) + local NearRadius = CargoParam and tonumber( CargoParam:match( "NR=([%a%d]+),?" ) ) - self:I({"Register CargoGroup:",Type=Type,Name=Name,LoadRadius=LoadRadius,NearRadius=NearRadius}) + self:I( { "Register CargoGroup:", Type = Type, Name = Name, LoadRadius = LoadRadius, NearRadius = NearRadius } ) CARGO_GROUP:New( CargoGroup, Type, Name, LoadRadius, NearRadius ) end end for CargoStaticName, CargoStatic in pairs( self.STATICS ) do if self:IsCargo( CargoStaticName ) then - local CargoInfo = CargoStaticName:match("#CARGO(.*)") - local CargoParam = CargoInfo and CargoInfo:match( "%((.*)%)") - local CargoName = CargoStaticName:match("(.*)#CARGO") - local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?") - local Category = CargoParam and CargoParam:match( "C=([%a%d ]+),?") - local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?") or CargoName - local LoadRadius = CargoParam and tonumber( CargoParam:match( "RR=([%a%d]+),?") ) - local NearRadius = CargoParam and tonumber( CargoParam:match( "NR=([%a%d]+),?") ) + local CargoInfo = CargoStaticName:match( "#CARGO(.*)" ) + local CargoParam = CargoInfo and CargoInfo:match( "%((.*)%)" ) + local CargoName = CargoStaticName:match( "(.*)#CARGO" ) + local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?" ) + local Category = CargoParam and CargoParam:match( "C=([%a%d ]+),?" ) + local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?" ) or CargoName + local LoadRadius = CargoParam and tonumber( CargoParam:match( "RR=([%a%d]+),?" ) ) + local NearRadius = CargoParam and tonumber( CargoParam:match( "NR=([%a%d]+),?" ) ) if Category == "SLING" then - self:I({"Register CargoSlingload:",Type=Type,Name=Name,LoadRadius=LoadRadius,NearRadius=NearRadius}) + self:I( { "Register CargoSlingload:", Type = Type, Name = Name, LoadRadius = LoadRadius, NearRadius = NearRadius } ) CARGO_SLINGLOAD:New( CargoStatic, Type, Name, LoadRadius, NearRadius ) else if Category == "CRATE" then - self:I({"Register CargoCrate:",Type=Type,Name=Name,LoadRadius=LoadRadius,NearRadius=NearRadius}) + self:I( { "Register CargoCrate:", Type = Type, Name = Name, LoadRadius = LoadRadius, NearRadius = NearRadius } ) CARGO_CRATE:New( CargoStatic, Type, Name, LoadRadius, NearRadius ) end end @@ -518,7 +504,6 @@ function DATABASE:FindClient( ClientName ) return ClientFound end - --- Adds a CLIENT based on the ClientName in the DATABASE. -- @param #DATABASE self -- @param #string ClientName Name of the Client unit. @@ -532,7 +517,6 @@ function DATABASE:AddClient( ClientName ) return self.CLIENTS[ClientName] end - --- Finds a GROUP based on the GroupName. -- @param #DATABASE self -- @param #string GroupName @@ -543,7 +527,6 @@ function DATABASE:FindGroup( GroupName ) return GroupFound end - --- Adds a GROUP based on the GroupName in the DATABASE. -- @param #DATABASE self function DATABASE:AddGroup( GroupName ) @@ -591,7 +574,6 @@ function DATABASE:GetPlayers() return self.PLAYERS end - --- Get the player table from the DATABASE, which contains all UNIT objects. -- The player table contains all UNIT objects of the player with the key the name of the player (PlayerName). -- @param #DATABASE self @@ -604,7 +586,6 @@ function DATABASE:GetPlayerUnits() return self.PLAYERUNITS end - --- Get the player table from the DATABASE which have joined in the mission historically. -- The player table contains all UNIT objects with the key the name of the player (PlayerName). -- @param #DATABASE self @@ -617,7 +598,6 @@ function DATABASE:GetPlayersJoined() return self.PLAYERSJOINED end - --- Instantiate new Groups within the DCSRTE. -- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined: -- SpawnCountryID, SpawnCategoryID @@ -640,7 +620,7 @@ function DATABASE:Spawn( SpawnTemplate ) SpawnTemplate.CountryID = nil SpawnTemplate.CategoryID = nil - self:_RegisterGroupTemplate( SpawnTemplate, SpawnCoalitionID, SpawnCategoryID, SpawnCountryID ) + self:_RegisterGroupTemplate( SpawnTemplate, SpawnCoalitionID, SpawnCategoryID, SpawnCountryID ) self:T3( SpawnTemplate ) coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate ) @@ -722,7 +702,7 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category for unit_num, UnitTemplate in pairs( GroupTemplate.units ) do - UnitTemplate.name = env.getValueDictByKey(UnitTemplate.name) + UnitTemplate.name = env.getValueDictByKey( UnitTemplate.name ) self.Templates.Units[UnitTemplate.name] = {} self.Templates.Units[UnitTemplate.name].UnitName = UnitTemplate.name @@ -742,17 +722,16 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category self.Templates.ClientsByID[UnitTemplate.unitId] = UnitTemplate end - UnitNames[#UnitNames+1] = self.Templates.Units[UnitTemplate.name].UnitName + UnitNames[#UnitNames + 1] = self.Templates.Units[UnitTemplate.name].UnitName end -- Debug info. - self:T( { Group = self.Templates.Groups[GroupTemplateName].GroupName, + self:T( { Group = self.Templates.Groups[GroupTemplateName].GroupName, Coalition = self.Templates.Groups[GroupTemplateName].CoalitionID, - Category = self.Templates.Groups[GroupTemplateName].CategoryID, - Country = self.Templates.Groups[GroupTemplateName].CountryID, - Units = UnitNames - } - ) + Category = self.Templates.Groups[GroupTemplateName].CategoryID, + Country = self.Templates.Groups[GroupTemplateName].CountryID, + Units = UnitNames, + } ) end --- Get group template. @@ -778,7 +757,7 @@ function DATABASE:_RegisterStaticTemplate( StaticTemplate, CoalitionID, Category local StaticTemplate = UTILS.DeepCopy( StaticTemplate ) - local StaticTemplateName = env.getValueDictByKey(StaticTemplate.name) + local StaticTemplateName = env.getValueDictByKey( StaticTemplate.name ) self.Templates.Statics[StaticTemplateName] = self.Templates.Statics[StaticTemplateName] or {} @@ -797,9 +776,8 @@ function DATABASE:_RegisterStaticTemplate( StaticTemplate, CoalitionID, Category self:T( { Static = self.Templates.Statics[StaticTemplateName].StaticName, Coalition = self.Templates.Statics[StaticTemplateName].CoalitionID, Category = self.Templates.Statics[StaticTemplateName].CategoryID, - Country = self.Templates.Statics[StaticTemplateName].CountryID - } - ) + Country = self.Templates.Statics[StaticTemplateName].CountryID, + } ) self:AddStatic( StaticTemplateName ) @@ -815,7 +793,7 @@ function DATABASE:GetStaticGroupTemplate( StaticName ) local StaticTemplate = self.Templates.Statics[StaticName].GroupTemplate return StaticTemplate, self.Templates.Statics[StaticName].CoalitionID, self.Templates.Statics[StaticName].CategoryID, self.Templates.Statics[StaticName].CountryID else - self:E("ERROR: Static group template does NOT exist for static "..tostring(StaticName)) + self:E( "ERROR: Static group template does NOT exist for static " .. tostring( StaticName ) ) return nil end end @@ -829,8 +807,8 @@ function DATABASE:GetStaticUnitTemplate( StaticName ) local UnitTemplate = self.Templates.Statics[StaticName].UnitTemplate return UnitTemplate, self.Templates.Statics[StaticName].CoalitionID, self.Templates.Statics[StaticName].CategoryID, self.Templates.Statics[StaticName].CountryID else - self:E("ERROR: Static unit template does NOT exist for static "..tostring(StaticName)) - return nil + self:E( "ERROR: Static unit template does NOT exist for static " .. tostring( StaticName ) ) + return nil end end @@ -842,7 +820,7 @@ function DATABASE:GetGroupNameFromUnitName( UnitName ) if self.Templates.Units[UnitName] then return self.Templates.Units[UnitName].GroupName else - self:E("ERROR: Unit template does not exist for unit "..tostring(UnitName)) + self:E( "ERROR: Unit template does not exist for unit " .. tostring( UnitName ) ) return nil end end @@ -855,8 +833,8 @@ function DATABASE:GetGroupTemplateFromUnitName( UnitName ) if self.Templates.Units[UnitName] then return self.Templates.Units[UnitName].GroupTemplate else - self:E("ERROR: Unit template does not exist for unit "..tostring(UnitName)) - return nil + self:E( "ERROR: Unit template does not exist for unit " .. tostring( UnitName ) ) + return nil end end @@ -902,8 +880,6 @@ function DATABASE:GetCategoryFromAirbase( AirbaseName ) return self.AIRBASES[AirbaseName]:GetCategory() end - - --- Private method that registers all alive players in the mission. -- @param #DATABASE self -- @return #DATABASE self @@ -927,25 +903,24 @@ function DATABASE:_RegisterPlayers() return self end - --- Private method that registers all Groups and Units within in the mission. -- @param #DATABASE self -- @return #DATABASE self function DATABASE:_RegisterGroupsAndUnits() - local CoalitionsData = { GroupsRed = coalition.getGroups( coalition.side.RED ), GroupsBlue = coalition.getGroups( coalition.side.BLUE ), GroupsNeutral = coalition.getGroups( coalition.side.NEUTRAL ) } - + local CoalitionsData = { GroupsRed = coalition.getGroups( coalition.side.RED ), GroupsBlue = coalition.getGroups( coalition.side.BLUE ), GroupsNeutral = coalition.getGroups( coalition.side.NEUTRAL ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do - + for DCSGroupId, DCSGroup in pairs( CoalitionData ) do if DCSGroup:isExist() then - + -- Group name. local DCSGroupName = DCSGroup:getName() -- Add group. - self:I(string.format("Register Group: %s", tostring(DCSGroupName))) + self:I( string.format( "Register Group: %s", tostring( DCSGroupName ) ) ) self:AddGroup( DCSGroupName ) -- Loop over units in group. @@ -953,14 +928,14 @@ function DATABASE:_RegisterGroupsAndUnits() -- Get unit name. local DCSUnitName = DCSUnit:getName() - + -- Add unit. - self:I(string.format("Register Unit: %s", tostring(DCSUnitName))) + self:I( string.format( "Register Unit: %s", tostring( DCSUnitName ) ) ) self:AddUnit( DCSUnitName ) - + end else - self:E({"Group does not exist: ", DCSGroup}) + self:E( { "Group does not exist: ", DCSGroup } ) end end @@ -975,7 +950,7 @@ end function DATABASE:_RegisterClients() for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do - self:I(string.format("Register Client: %s", tostring(ClientName))) + self:I( string.format( "Register Client: %s", tostring( ClientName ) ) ) self:AddClient( ClientName ) end @@ -985,7 +960,7 @@ end --- @param #DATABASE self function DATABASE:_RegisterStatics() - local CoalitionsData={GroupsRed=coalition.getStaticObjects(coalition.side.RED), GroupsBlue=coalition.getStaticObjects(coalition.side.BLUE), GroupsNeutral=coalition.getStaticObjects(coalition.side.NEUTRAL)} + local CoalitionsData = { GroupsRed = coalition.getStaticObjects( coalition.side.RED ), GroupsBlue = coalition.getStaticObjects( coalition.side.BLUE ), GroupsNeutral = coalition.getStaticObjects( coalition.side.NEUTRAL ) } for CoalitionId, CoalitionData in pairs( CoalitionsData ) do for DCSStaticId, DCSStatic in pairs( CoalitionData ) do @@ -993,10 +968,10 @@ function DATABASE:_RegisterStatics() if DCSStatic:isExist() then local DCSStaticName = DCSStatic:getName() - self:I(string.format("Register Static: %s", tostring(DCSStaticName))) + self:I( string.format( "Register Static: %s", tostring( DCSStaticName ) ) ) self:AddStatic( DCSStaticName ) else - self:E( { "Static does not exist: ", DCSStatic } ) + self:E( { "Static does not exist: ", DCSStatic } ) end end end @@ -1009,41 +984,40 @@ end -- @return #DATABASE self function DATABASE:_RegisterAirbases() - for DCSAirbaseId, DCSAirbase in pairs(world.getAirbases()) do - + for DCSAirbaseId, DCSAirbase in pairs( world.getAirbases() ) do + -- Get the airbase name. local DCSAirbaseName = DCSAirbase:getName() -- This gave the incorrect value to be inserted into the airdromeID for DCS 2.5.6. Is fixed now. - local airbaseID=DCSAirbase:getID() + local airbaseID = DCSAirbase:getID() -- Add and register airbase. - local airbase=self:AddAirbase( DCSAirbaseName ) - + local airbase = self:AddAirbase( DCSAirbaseName ) + -- Unique ID. - local airbaseUID=airbase:GetID(true) + local airbaseUID = airbase:GetID( true ) -- Debug output. - local text=string.format("Register %s: %s (ID=%d UID=%d), parking=%d [", AIRBASE.CategoryName[airbase.category], tostring(DCSAirbaseName), airbaseID, airbaseUID, airbase.NparkingTotal) - for _,terminalType in pairs(AIRBASE.TerminalType) do + local text = string.format( "Register %s: %s (ID=%d UID=%d), parking=%d [", AIRBASE.CategoryName[airbase.category], tostring( DCSAirbaseName ), airbaseID, airbaseUID, airbase.NparkingTotal ) + for _, terminalType in pairs( AIRBASE.TerminalType ) do if airbase.NparkingTerminal and airbase.NparkingTerminal[terminalType] then - text=text..string.format("%d=%d ", terminalType, airbase.NparkingTerminal[terminalType]) + text = text .. string.format( "%d=%d ", terminalType, airbase.NparkingTerminal[terminalType] ) end end - text=text.."]" - self:I(text) - + text = text .. "]" + self:I( text ) + -- Check for DCS bug IDs. - if airbaseID~=airbase:GetID() then - --self:E("WARNING: :getID does NOT match :GetID!") - end - + if airbaseID ~= airbase:GetID() then + -- self:E("WARNING: :getID does NOT match :GetID!") + end + end return self end - --- Events --- Handles the OnBirth event for the alive units set. @@ -1053,76 +1027,75 @@ function DATABASE:_EventOnBirth( Event ) self:F( { Event } ) if Event.IniDCSUnit then - + if Event.IniObjectCategory == 3 then - + self:AddStatic( Event.IniDCSUnitName ) - + else - + if Event.IniObjectCategory == 1 then - + self:AddUnit( Event.IniDCSUnitName ) self:AddGroup( Event.IniDCSGroupName ) - + -- Add airbase if it was spawned later in the mission. - local DCSAirbase = Airbase.getByName(Event.IniDCSUnitName) + local DCSAirbase = Airbase.getByName( Event.IniDCSUnitName ) if DCSAirbase then - self:I(string.format("Adding airbase %s", tostring(Event.IniDCSUnitName))) - self:AddAirbase(Event.IniDCSUnitName) + self:I( string.format( "Adding airbase %s", tostring( Event.IniDCSUnitName ) ) ) + self:AddAirbase( Event.IniDCSUnitName ) end - + end end - + if Event.IniObjectCategory == 1 then - + Event.IniUnit = self:FindUnit( Event.IniDCSUnitName ) Event.IniGroup = self:FindGroup( Event.IniDCSGroupName ) - + -- Client - local client=self.CLIENTS[Event.IniDCSUnitName] --Wrapper.Client#CLIENT - + local client = self.CLIENTS[Event.IniDCSUnitName] -- Wrapper.Client#CLIENT + if client then -- TODO: create event ClientAlive - end - + end + -- Get player name. local PlayerName = Event.IniUnit:GetPlayerName() - + if PlayerName then - + -- Debug info. - self:I(string.format("Player '%s' joint unit '%s' of group '%s'", tostring(PlayerName), tostring(Event.IniDCSUnitName), tostring(Event.IniDCSGroupName))) - + self:I( string.format( "Player '%s' joint unit '%s' of group '%s'", tostring( PlayerName ), tostring( Event.IniDCSUnitName ), tostring( Event.IniDCSGroupName ) ) ) + -- Add client in case it does not exist already. if not client then - client=self:AddClient(Event.IniDCSUnitName) + client = self:AddClient( Event.IniDCSUnitName ) end - + -- Add player. - client:AddPlayer(PlayerName) - + client:AddPlayer( PlayerName ) + -- Add player. if not self.PLAYERS[PlayerName] then self:AddPlayer( Event.IniUnitName, PlayerName ) end - + -- Player settings. local Settings = SETTINGS:Set( PlayerName ) - Settings:SetPlayerMenu(Event.IniUnit) - - -- Create an event. - self:CreateEventPlayerEnterAircraft(Event.IniUnit) - - end - - end - - end - -end + Settings:SetPlayerMenu( Event.IniUnit ) + -- Create an event. + self:CreateEventPlayerEnterAircraft( Event.IniUnit ) + + end + + end + + end + +end --- Handles the OnDead or OnCrash event for alive units set. -- @param #DATABASE self @@ -1130,55 +1103,54 @@ end function DATABASE:_EventOnDeadOrCrash( Event ) if Event.IniDCSUnit then - - local name=Event.IniDCSUnitName - + + local name = Event.IniDCSUnitName + if Event.IniObjectCategory == 3 then - + --- -- STATICS --- - + if self.STATICS[Event.IniDCSUnitName] then self:DeleteStatic( Event.IniDCSUnitName ) end - + else - + if Event.IniObjectCategory == 1 then - + --- -- UNITS --- - + -- Delete unit. if self.UNITS[Event.IniDCSUnitName] then - self:DeleteUnit(Event.IniDCSUnitName) + self:DeleteUnit( Event.IniDCSUnitName ) end - + -- Remove client players. - local client=self.CLIENTS[name] --Wrapper.Client#CLIENT - + local client = self.CLIENTS[name] -- Wrapper.Client#CLIENT + if client then client:RemovePlayers() end - + end end - + -- Add airbase if it was spawned later in the mission. - local airbase=self.AIRBASES[Event.IniDCSUnitName] --Wrapper.Airbase#AIRBASE + local airbase = self.AIRBASES[Event.IniDCSUnitName] -- Wrapper.Airbase#AIRBASE if airbase and (airbase:IsHelipad() or airbase:IsShip()) then - self:DeleteAirbase(Event.IniDCSUnitName) + self:DeleteAirbase( Event.IniDCSUnitName ) end - + end -- Account destroys. self:AccountDestroys( Event ) end - --- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied). -- @param #DATABASE self -- @param Core.Event#EVENTDATA Event @@ -1187,36 +1159,35 @@ function DATABASE:_EventOnPlayerEnterUnit( Event ) if Event.IniDCSUnit then if Event.IniObjectCategory == 1 then - + -- Add unit. self:AddUnit( Event.IniDCSUnitName ) - + -- Ini unit. Event.IniUnit = self:FindUnit( Event.IniDCSUnitName ) - + -- Add group. self:AddGroup( Event.IniDCSGroupName ) - + -- Get player unit. local PlayerName = Event.IniDCSUnit:getPlayerName() - + if PlayerName then - + if not self.PLAYERS[PlayerName] then self:AddPlayer( Event.IniDCSUnitName, PlayerName ) end - + local Settings = SETTINGS:Set( PlayerName ) Settings:SetPlayerMenu( Event.IniUnit ) - + else - self:E("ERROR: getPlayerName() returned nil for event PlayerEnterUnit") + self:E( "ERROR: getPlayerName() returned nil for event PlayerEnterUnit" ) end end end end - --- Handles the OnPlayerLeaveUnit event to clean the active players table. -- @param #DATABASE self -- @param Core.Event#EVENTDATA Event @@ -1224,30 +1195,30 @@ function DATABASE:_EventOnPlayerLeaveUnit( Event ) self:F2( { Event } ) if Event.IniUnit then - + if Event.IniObjectCategory == 1 then - + -- Try to get the player name. This can be buggy for multicrew aircraft! local PlayerName = Event.IniUnit:GetPlayerName() - - if PlayerName then --and self.PLAYERS[PlayerName] then - + + if PlayerName then -- and self.PLAYERS[PlayerName] then + -- Debug info. - self:I(string.format("Player '%s' left unit %s", tostring(PlayerName), tostring(Event.IniUnitName))) - + self:I( string.format( "Player '%s' left unit %s", tostring( PlayerName ), tostring( Event.IniUnitName ) ) ) + -- Remove player menu. local Settings = SETTINGS:Set( PlayerName ) - Settings:RemovePlayerMenu(Event.IniUnit) - + Settings:RemovePlayerMenu( Event.IniUnit ) + -- Delete player. - self:DeletePlayer(Event.IniUnit, PlayerName) - + self:DeletePlayer( Event.IniUnit, PlayerName ) + -- Client stuff. - local client=self.CLIENTS[Event.IniDCSUnitName] --Wrapper.Client#CLIENT + local client = self.CLIENTS[Event.IniDCSUnitName] -- Wrapper.Client#CLIENT if client then - client:RemovePlayer(PlayerName) + client:RemovePlayer( PlayerName ) end - + end end end @@ -1265,22 +1236,22 @@ function DATABASE:ForEach( IteratorFunction, FinalizeFunction, arg, Set ) local function CoRoutine() local Count = 0 for ObjectID, Object in pairs( Set ) do - self:T2( Object ) - IteratorFunction( Object, unpack( arg ) ) - Count = Count + 1 --- if Count % 100 == 0 then --- coroutine.yield( false ) --- end + self:T2( Object ) + IteratorFunction( Object, unpack( arg ) ) + Count = Count + 1 + -- if Count % 100 == 0 then + -- coroutine.yield( false ) + -- end end return true end --- local co = coroutine.create( CoRoutine ) + -- local co = coroutine.create( CoRoutine ) local co = CoRoutine local function Schedule() --- local status, res = coroutine.resume( co ) + -- local status, res = coroutine.resume( co ) local status, res = co() self:T3( { status, res } ) @@ -1296,18 +1267,17 @@ function DATABASE:ForEach( IteratorFunction, FinalizeFunction, arg, Set ) return false end - --local Scheduler = SCHEDULER:New( self, Schedule, {}, 0.001, 0.001, 0 ) + -- local Scheduler = SCHEDULER:New( self, Schedule, {}, 0.001, 0.001, 0 ) Schedule() return self end - --- Iterate the DATABASE and call an iterator function for each **alive** STATIC, providing the STATIC and optional parameters. -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a STATIC parameter. -- @return #DATABASE self -function DATABASE:ForEachStatic( IteratorFunction, FinalizeFunction, ... ) --R2.1 +function DATABASE:ForEachStatic( IteratorFunction, FinalizeFunction, ... ) -- R2.1 self:F2( arg ) self:ForEach( IteratorFunction, FinalizeFunction, arg, self.STATICS ) @@ -1315,7 +1285,6 @@ function DATABASE:ForEachStatic( IteratorFunction, FinalizeFunction, ... ) --R2 return self end - --- Iterate the DATABASE and call an iterator function for each **alive** UNIT, providing the UNIT and optional parameters. -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a UNIT parameter. @@ -1328,7 +1297,6 @@ function DATABASE:ForEachUnit( IteratorFunction, FinalizeFunction, ... ) return self end - --- Iterate the DATABASE and call an iterator function for each **alive** GROUP, providing the GROUP and optional parameters. -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a GROUP parameter. @@ -1341,7 +1309,6 @@ function DATABASE:ForEachGroup( IteratorFunction, FinalizeFunction, ... ) return self end - --- Iterate the DATABASE and call an iterator function for each **ALIVE** player, providing the player name and optional parameters. -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept the player name. @@ -1354,7 +1321,6 @@ function DATABASE:ForEachPlayer( IteratorFunction, FinalizeFunction, ... ) return self end - --- Iterate the DATABASE and call an iterator function for each player who has joined the mission, providing the Unit of the player and optional parameters. -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a UNIT parameter. @@ -1379,7 +1345,6 @@ function DATABASE:ForEachPlayerUnit( IteratorFunction, FinalizeFunction, ... ) return self end - --- Iterate the DATABASE and call an iterator function for each CLIENT, providing the CLIENT to the function and optional parameters. -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called object in the database. The function needs to accept a CLIENT parameter. @@ -1404,7 +1369,6 @@ function DATABASE:ForEachCargo( IteratorFunction, ... ) return self end - --- Handles the OnEventNewCargo event. -- @param #DATABASE self -- @param Core.Event#EVENTDATA EventData @@ -1416,7 +1380,6 @@ function DATABASE:OnEventNewCargo( EventData ) end end - --- Handles the OnEventDeleteCargo. -- @param #DATABASE self -- @param Core.Event#EVENTDATA EventData @@ -1428,7 +1391,6 @@ function DATABASE:OnEventDeleteCargo( EventData ) end end - --- Handles the OnEventNewZone event. -- @param #DATABASE self -- @param Core.Event#EVENTDATA EventData @@ -1440,7 +1402,6 @@ function DATABASE:OnEventNewZone( EventData ) end end - --- Handles the OnEventDeleteZone. -- @param #DATABASE self -- @param Core.Event#EVENTDATA EventData @@ -1452,8 +1413,6 @@ function DATABASE:OnEventDeleteZone( EventData ) end end - - --- Gets the player settings -- @param #DATABASE self -- @param #string PlayerName @@ -1463,7 +1422,6 @@ function DATABASE:GetPlayerSettings( PlayerName ) return self.PLAYERSETTINGS[PlayerName] end - --- Sets the player settings -- @param #DATABASE self -- @param #string PlayerName @@ -1477,21 +1435,21 @@ end --- Add a flight group to the data base. -- @param #DATABASE self -- @param Ops.FlightGroup#FLIGHTGROUP flightgroup -function DATABASE:AddFlightGroup(flightgroup) - self:I({NewFlightGroup=flightgroup.groupname}) - self.FLIGHTGROUPS[flightgroup.groupname]=flightgroup +function DATABASE:AddFlightGroup( flightgroup ) + self:I( { NewFlightGroup = flightgroup.groupname } ) + self.FLIGHTGROUPS[flightgroup.groupname] = flightgroup end --- Get a flight group from the data base. -- @param #DATABASE self -- @param #string groupname Group name of the flight group. Can also be passed as GROUP object. -- @return Ops.FlightGroup#FLIGHTGROUP Flight group object. -function DATABASE:GetFlightGroup(groupname) +function DATABASE:GetFlightGroup( groupname ) -- Get group and group name. - if type(groupname)=="string" then + if type( groupname ) == "string" then else - groupname=groupname:GetName() + groupname = groupname:GetName() end return self.FLIGHTGROUPS[groupname] @@ -1500,16 +1458,16 @@ end --- Add a flight control to the data base. -- @param #DATABASE self -- @param Ops.FlightControl#FLIGHTCONTROL flightcontrol -function DATABASE:AddFlightControl(flightcontrol) +function DATABASE:AddFlightControl( flightcontrol ) self:F2( { flightcontrol } ) - self.FLIGHTCONTROLS[flightcontrol.airbasename]=flightcontrol + self.FLIGHTCONTROLS[flightcontrol.airbasename] = flightcontrol end --- Get a flight control object from the data base. -- @param #DATABASE self -- @param #string airbasename Name of the associated airbase. -- @return Ops.FlightControl#FLIGHTCONTROL The FLIGHTCONTROL object.s -function DATABASE:GetFlightControl(airbasename) +function DATABASE:GetFlightControl( airbasename ) return self.FLIGHTCONTROLS[airbasename] end @@ -1519,32 +1477,32 @@ function DATABASE:_RegisterTemplates() self.Navpoints = {} self.UNITS = {} - --Build routines.db.units and self.Navpoints - for CoalitionName, coa_data in pairs(env.mission.coalition) do - self:T({CoalitionName=CoalitionName}) + -- Build routines.db.units and self.Navpoints + for CoalitionName, coa_data in pairs( env.mission.coalition ) do + self:T( { CoalitionName = CoalitionName } ) - if (CoalitionName == 'red' or CoalitionName == 'blue' or CoalitionName == 'neutrals') and type(coa_data) == 'table' then - --self.Units[coa_name] = {} + if (CoalitionName == 'red' or CoalitionName == 'blue' or CoalitionName == 'neutrals') and type( coa_data ) == 'table' then + -- self.Units[coa_name] = {} - local CoalitionSide = coalition.side[string.upper(CoalitionName)] - if CoalitionName=="red" then - CoalitionSide=coalition.side.RED - elseif CoalitionName=="blue" then - CoalitionSide=coalition.side.BLUE + local CoalitionSide = coalition.side[string.upper( CoalitionName )] + if CoalitionName == "red" then + CoalitionSide = coalition.side.RED + elseif CoalitionName == "blue" then + CoalitionSide = coalition.side.BLUE else - CoalitionSide=coalition.side.NEUTRAL + CoalitionSide = coalition.side.NEUTRAL end -- build nav points DB self.Navpoints[CoalitionName] = {} - if coa_data.nav_points then --navpoints - for nav_ind, nav_data in pairs(coa_data.nav_points) do + if coa_data.nav_points then -- navpoints + for nav_ind, nav_data in pairs( coa_data.nav_points ) do - if type(nav_data) == 'table' then - self.Navpoints[CoalitionName][nav_ind] = routines.utils.deepCopy(nav_data) + if type( nav_data ) == 'table' then + self.Navpoints[CoalitionName][nav_ind] = routines.utils.deepCopy( nav_data ) - self.Navpoints[CoalitionName][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory. - self.Navpoints[CoalitionName][nav_ind]['point'] = {} -- point is used by SSE, support it. + self.Navpoints[CoalitionName][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory. + self.Navpoints[CoalitionName][nav_ind]['point'] = {} -- point is used by SSE, support it. self.Navpoints[CoalitionName][nav_ind]['point']['x'] = nav_data.x self.Navpoints[CoalitionName][nav_ind]['point']['y'] = 0 self.Navpoints[CoalitionName][nav_ind]['point']['z'] = nav_data.y @@ -1553,138 +1511,138 @@ function DATABASE:_RegisterTemplates() end ------------------------------------------------- - if coa_data.country then --there is a country table - for cntry_id, cntry_data in pairs(coa_data.country) do + if coa_data.country then -- there is a country table + for cntry_id, cntry_data in pairs( coa_data.country ) do - local CountryName = string.upper(cntry_data.name) + local CountryName = string.upper( cntry_data.name ) local CountryID = cntry_data.id self.COUNTRY_ID[CountryName] = CountryID self.COUNTRY_NAME[CountryID] = CountryName - --self.Units[coa_name][countryName] = {} - --self.Units[coa_name][countryName]["countryId"] = cntry_data.id + -- self.Units[coa_name][countryName] = {} + -- self.Units[coa_name][countryName]["countryId"] = cntry_data.id - if type(cntry_data) == 'table' then --just making sure + if type( cntry_data ) == 'table' then -- just making sure - for obj_type_name, obj_type_data in pairs(cntry_data) do + for obj_type_name, obj_type_data in pairs( cntry_data ) do - if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then --should be an unncessary check + if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then -- should be an unncessary check local CategoryName = obj_type_name - if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then --there's a group! + if ((type( obj_type_data ) == 'table') and obj_type_data.group and (type( obj_type_data.group ) == 'table') and (#obj_type_data.group > 0)) then -- there's a group! - --self.Units[coa_name][countryName][category] = {} + -- self.Units[coa_name][countryName][category] = {} - for group_num, Template in pairs(obj_type_data.group) do + for group_num, Template in pairs( obj_type_data.group ) do + + if obj_type_name ~= "static" and Template and Template.units and type( Template.units ) == 'table' then -- making sure again- this is a valid group + + self:_RegisterGroupTemplate( Template, CoalitionSide, _DATABASECategory[string.lower( CategoryName )], CountryID ) - if obj_type_name ~= "static" and Template and Template.units and type(Template.units) == 'table' then --making sure again- this is a valid group - - self:_RegisterGroupTemplate(Template, CoalitionSide, _DATABASECategory[string.lower(CategoryName)], CountryID) - else - - self:_RegisterStaticTemplate(Template, CoalitionSide, _DATABASECategory[string.lower(CategoryName)], CountryID) - - end --if GroupTemplate and GroupTemplate.units then - end --for group_num, GroupTemplate in pairs(obj_type_data.group) do - end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then - end --if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then - end --for obj_type_name, obj_type_data in pairs(cntry_data) do - end --if type(cntry_data) == 'table' then - end --for cntry_id, cntry_data in pairs(coa_data.country) do - end --if coa_data.country then --there is a country table - end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then - end --for coa_name, coa_data in pairs(mission.coalition) do + + self:_RegisterStaticTemplate( Template, CoalitionSide, _DATABASECategory[string.lower( CategoryName )], CountryID ) + + end -- if GroupTemplate and GroupTemplate.units then + end -- for group_num, GroupTemplate in pairs(obj_type_data.group) do + end -- if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then + end -- if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then + end -- for obj_type_name, obj_type_data in pairs(cntry_data) do + end -- if type(cntry_data) == 'table' then + end -- for cntry_id, cntry_data in pairs(coa_data.country) do + end -- if coa_data.country then --there is a country table + end -- if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then + end -- for coa_name, coa_data in pairs(mission.coalition) do return self end - --- Account the Hits of the Players. - -- @param #DATABASE self - -- @param Core.Event#EVENTDATA Event - function DATABASE:AccountHits( Event ) - self:F( { Event } ) +--- Account the Hits of the Players. +-- @param #DATABASE self +-- @param Core.Event#EVENTDATA Event +function DATABASE:AccountHits( Event ) + self:F( { Event } ) - if Event.IniPlayerName ~= nil then -- It is a player that is hitting something - self:T( "Hitting Something" ) + if Event.IniPlayerName ~= nil then -- It is a player that is hitting something + self:T( "Hitting Something" ) - -- What is he hitting? - if Event.TgtCategory then + -- What is he hitting? + if Event.TgtCategory then + -- A target got hit + self.HITS[Event.TgtUnitName] = self.HITS[Event.TgtUnitName] or {} + local Hit = self.HITS[Event.TgtUnitName] + + Hit.Players = Hit.Players or {} + Hit.Players[Event.IniPlayerName] = true + end + end + + -- 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:T( "Hitting Scenery" ) + + -- What is he hitting? + if Event.TgtCategory then + + if Event.WeaponCoalition then -- A coalition object was hit, probably a static. -- A target got hit self.HITS[Event.TgtUnitName] = self.HITS[Event.TgtUnitName] or {} local Hit = self.HITS[Event.TgtUnitName] Hit.Players = Hit.Players or {} - Hit.Players[Event.IniPlayerName] = true - end - end - - -- 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:T( "Hitting Scenery" ) - - -- What is he hitting? - if Event.TgtCategory then - - if Event.WeaponCoalition then -- A coalition object was hit, probably a static. - -- A target got hit - self.HITS[Event.TgtUnitName] = self.HITS[Event.TgtUnitName] or {} - local Hit = self.HITS[Event.TgtUnitName] - - Hit.Players = Hit.Players or {} - Hit.Players[Event.WeaponPlayerName] = true - else -- A scenery object was hit. - end + Hit.Players[Event.WeaponPlayerName] = true + else -- A scenery object was hit. end end end +end - --- Account the destroys. - -- @param #DATABASE self - -- @param Core.Event#EVENTDATA Event - function DATABASE:AccountDestroys( Event ) - self:F( { Event } ) +--- Account the destroys. +-- @param #DATABASE self +-- @param Core.Event#EVENTDATA Event +function DATABASE:AccountDestroys( Event ) + self:F( { Event } ) - local TargetUnit = nil - local TargetGroup = nil - local TargetUnitName = "" - local TargetGroupName = "" - local TargetPlayerName = "" - local TargetCoalition = nil - local TargetCategory = nil - local TargetType = nil - local TargetUnitCoalition = nil - local TargetUnitCategory = nil - local TargetUnitType = nil + local TargetUnit = nil + local TargetGroup = nil + local TargetUnitName = "" + local TargetGroupName = "" + local TargetPlayerName = "" + local TargetCoalition = nil + local TargetCategory = nil + local TargetType = nil + local TargetUnitCoalition = nil + local TargetUnitCategory = nil + local TargetUnitType = nil - if Event.IniDCSUnit then + if Event.IniDCSUnit then - TargetUnit = Event.IniUnit - TargetUnitName = Event.IniDCSUnitName - TargetGroup = Event.IniDCSGroup - TargetGroupName = Event.IniDCSGroupName - TargetPlayerName = Event.IniPlayerName + TargetUnit = Event.IniUnit + TargetUnitName = Event.IniDCSUnitName + TargetGroup = Event.IniDCSGroup + TargetGroupName = Event.IniDCSGroupName + TargetPlayerName = Event.IniPlayerName - TargetCoalition = Event.IniCoalition - --TargetCategory = TargetUnit:getCategory() - --TargetCategory = TargetUnit:getDesc().category -- Workaround - TargetCategory = Event.IniCategory - TargetType = Event.IniTypeName + TargetCoalition = Event.IniCoalition + -- TargetCategory = TargetUnit:getCategory() + -- TargetCategory = TargetUnit:getDesc().category -- Workaround + TargetCategory = Event.IniCategory + TargetType = Event.IniTypeName - TargetUnitType = TargetType + TargetUnitType = TargetType - self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } ) - end - - local Destroyed = false - - -- What is the player destroying? - if self.HITS[Event.IniUnitName] then -- Was there a hit for this unit for this player before registered??? - self.DESTROYS[Event.IniUnitName] = self.DESTROYS[Event.IniUnitName] or {} - self.DESTROYS[Event.IniUnitName] = true - end + self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } ) end + + local Destroyed = false + + -- What is the player destroying? + if self.HITS[Event.IniUnitName] then -- Was there a hit for this unit for this player before registered??? + self.DESTROYS[Event.IniUnitName] = self.DESTROYS[Event.IniUnitName] or {} + self.DESTROYS[Event.IniUnitName] = true + end +end diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index 02dab0afc..ea8b7575a 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -14,7 +14,7 @@ -- ![Objects](..\Presentations\EVENT\Dia2.JPG) -- -- Within a running mission, various DCS events occur. Units are dynamically created, crash, die, shoot stuff, get hit etc. --- This module provides a mechanism to dispatch those events occuring within your running mission, to the different objects orchestrating your mission. +-- This module provides a mechanism to dispatch those events occurring within your running mission, to the different objects orchestrating your mission. -- -- ![Objects](..\Presentations\EVENT\Dia3.JPG) -- @@ -141,7 +141,6 @@ -- EventData.IniUnit:SmokeGreen() -- end -- --- -- Find below an overview which events populate which information categories: -- -- ![Objects](..\Presentations\EVENT\Dia14.JPG) @@ -172,7 +171,6 @@ -- @module Core.Event -- @image Core_Event.JPG - --- @type EVENT -- @field #EVENT.Events Events -- @extends Core.Base#BASE @@ -194,7 +192,6 @@ world.event.S_EVENT_DELETE_ZONE_GOAL = world.event.S_EVENT_MAX + 1005 world.event.S_EVENT_REMOVE_UNIT = world.event.S_EVENT_MAX + 1006 world.event.S_EVENT_PLAYER_ENTER_AIRCRAFT = world.event.S_EVENT_MAX + 1007 - --- The different types of events supported by MOOSE. -- Use this structure to subscribe to events using the @{Core.Base#BASE.HandleEvent}() method. -- @type EVENTS @@ -227,13 +224,13 @@ EVENTS = { MarkChange = world.event.S_EVENT_MARK_CHANGE, MarkRemoved = world.event.S_EVENT_MARK_REMOVED, -- Moose Events - NewCargo = world.event.S_EVENT_NEW_CARGO, - DeleteCargo = world.event.S_EVENT_DELETE_CARGO, - NewZone = world.event.S_EVENT_NEW_ZONE, - DeleteZone = world.event.S_EVENT_DELETE_ZONE, - NewZoneGoal = world.event.S_EVENT_NEW_ZONE_GOAL, - DeleteZoneGoal = world.event.S_EVENT_DELETE_ZONE_GOAL, - RemoveUnit = world.event.S_EVENT_REMOVE_UNIT, + NewCargo = world.event.S_EVENT_NEW_CARGO, + DeleteCargo = world.event.S_EVENT_DELETE_CARGO, + NewZone = world.event.S_EVENT_NEW_ZONE, + DeleteZone = world.event.S_EVENT_DELETE_ZONE, + NewZoneGoal = world.event.S_EVENT_NEW_ZONE_GOAL, + DeleteZoneGoal = world.event.S_EVENT_DELETE_ZONE_GOAL, + RemoveUnit = world.event.S_EVENT_REMOVE_UNIT, PlayerEnterAircraft = world.event.S_EVENT_PLAYER_ENTER_AIRCRAFT, -- Added with DCS 2.5.6 DetailedFailure = world.event.S_EVENT_DETAILED_FAILURE or -1, --We set this to -1 for backward compatibility to DCS 2.5.5 and earlier @@ -304,8 +301,6 @@ EVENTS = { -- @field Core.ZONE#ZONE Zone The zone object. -- @field #string ZoneName The name of the zone. - - local _EVENTMETA = { [world.event.S_EVENT_SHOT] = { Order = 1, @@ -562,7 +557,6 @@ local _EVENTMETA = { }, } - --- The Events structure -- @type EVENT.Events -- @field #number IniUnit @@ -576,12 +570,11 @@ function EVENT:New() local self = BASE:Inherit( self, BASE:New() ) -- Add world event handler. - self.EventHandler = world.addEventHandler(self) + self.EventHandler = world.addEventHandler( self ) return self end - --- Initializes the Events structure for the event. -- @param #EVENT self -- @param DCS#world.event EventID Event ID. @@ -595,7 +588,7 @@ function EVENT:Init( EventID, EventClass ) self.Events[EventID] = {} end - -- Each event has a subtable of EventClasses, ordered by EventPriority. + -- Each event has a sub-table of EventClasses, ordered by EventPriority. local EventPriority = EventClass:GetEventPriority() if not self.Events[EventID][EventPriority] then @@ -603,7 +596,7 @@ function EVENT:Init( EventID, EventClass ) end if not self.Events[EventID][EventPriority][EventClass] then - self.Events[EventID][EventPriority][EventClass] = {} + self.Events[EventID][EventPriority][EventClass] = {} end return self.Events[EventID][EventPriority][EventClass] @@ -614,7 +607,7 @@ end -- @param Core.Base#BASE EventClass The self instance of the class for which the event is. -- @param DCS#world.event EventID Event ID. -- @return #EVENT self -function EVENT:RemoveEvent( EventClass, EventID ) +function EVENT:RemoveEvent( EventClass, EventID ) -- Debug info. self:F2( { "Removing subscription for class: ", EventClass:GetClassNameAndID() } ) @@ -638,7 +631,7 @@ end -- @param Core.Base#BASE EventClass The self instance of the class for which the event is. -- @param DCS#world.event EventID Event ID. -- @return #EVENT.Events -function EVENT:Reset( EventObject ) --R2.1 +function EVENT:Reset( EventObject ) -- R2.1 self:F( { "Resetting subscriptions for class: ", EventObject:GetClassNameAndID() } ) @@ -657,12 +650,11 @@ function EVENT:Reset( EventObject ) --R2.1 end end - --- Clears all event subscriptions for a @{Core.Base#BASE} derived object. -- @param #EVENT self -- @param Core.Base#BASE EventClass The self class object for which the events are removed. -- @return #EVENT self -function EVENT:RemoveAll(EventClass) +function EVENT:RemoveAll( EventClass ) local EventClassName = EventClass:GetClassNameAndID() @@ -676,8 +668,6 @@ function EVENT:RemoveAll(EventClass) return self end - - --- Create an OnDead event handler for a group -- @param #EVENT self -- @param #table EventTemplate @@ -709,7 +699,6 @@ function EVENT:OnEventGeneric( EventFunction, EventClass, EventID ) return self end - --- Set a new listener for an `S_EVENT_X` event for a UNIT. -- @param #EVENT self -- @param #string UnitName The name of the UNIT. @@ -797,7 +786,6 @@ do -- OnDead end - do -- OnLand --- Create an OnLand event handler for a group @@ -864,7 +852,7 @@ do -- Event Creation id = EVENTS.NewCargo, time = timer.getTime(), cargo = Cargo, - } + } world.onEvent( Event ) end @@ -879,7 +867,7 @@ do -- Event Creation id = EVENTS.DeleteCargo, time = timer.getTime(), cargo = Cargo, - } + } world.onEvent( Event ) end @@ -894,7 +882,7 @@ do -- Event Creation id = EVENTS.NewZone, time = timer.getTime(), zone = Zone, - } + } world.onEvent( Event ) end @@ -909,7 +897,7 @@ do -- Event Creation id = EVENTS.DeleteZone, time = timer.getTime(), zone = Zone, - } + } world.onEvent( Event ) end @@ -924,12 +912,11 @@ do -- Event Creation id = EVENTS.NewZoneGoal, time = timer.getTime(), ZoneGoal = ZoneGoal, - } + } world.onEvent( Event ) end - --- Creation of a ZoneGoal Deletion Event. -- @param #EVENT self -- @param Core.ZoneGoal#ZONE_GOAL ZoneGoal The ZoneGoal created. @@ -940,12 +927,11 @@ do -- Event Creation id = EVENTS.DeleteZoneGoal, time = timer.getTime(), ZoneGoal = ZoneGoal, - } + } world.onEvent( Event ) end - --- Creation of a S_EVENT_PLAYER_ENTER_UNIT Event. -- @param #EVENT self -- @param Wrapper.Unit#UNIT PlayerUnit. @@ -955,8 +941,8 @@ do -- Event Creation local Event = { id = EVENTS.PlayerEnterUnit, time = timer.getTime(), - initiator = PlayerUnit:GetDCSObject() - } + initiator = PlayerUnit:GetDCSObject(), + } world.onEvent( Event ) end @@ -970,8 +956,8 @@ do -- Event Creation local Event = { id = EVENTS.PlayerEnterAircraft, time = timer.getTime(), - initiator = PlayerUnit:GetDCSObject() - } + initiator = PlayerUnit:GetDCSObject(), + } world.onEvent( Event ) end @@ -993,14 +979,13 @@ function EVENT:onEvent( Event ) return errmsg end - -- Get event meta data. local EventMeta = _EVENTMETA[Event.id] -- Check if this is a known event? if EventMeta then - if self and self.Events and self.Events[Event.id] and self.MissionEnd==false and (Event.initiator~=nil or (Event.initiator==nil and Event.id~=EVENTS.PlayerLeaveUnit)) then + if self and self.Events and self.Events[Event.id] and self.MissionEnd == false and (Event.initiator ~= nil or (Event.initiator == nil and Event.id ~= EVENTS.PlayerLeaveUnit)) then if Event.id and Event.id == EVENTS.MissionEnd then self.MissionEnd = true @@ -1024,9 +1009,9 @@ function EVENT:onEvent( Event ) if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then Event.IniDCSGroupName = Event.IniDCSGroup:getName() Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) - --if Event.IniGroup then - Event.IniGroupName = Event.IniDCSGroupName - --end + -- if Event.IniGroup then + Event.IniGroupName = Event.IniDCSGroupName + -- end end Event.IniPlayerName = Event.IniDCSUnit:getPlayerName() Event.IniCoalition = Event.IniDCSUnit:getCoalition() @@ -1036,23 +1021,23 @@ function EVENT:onEvent( Event ) if Event.IniObjectCategory == Object.Category.STATIC then - if Event.id==31 then + if Event.id == 31 then -- Event.initiator is a Static object representing the pilot. But getName() errors due to DCS bug. Event.IniDCSUnit = Event.initiator - local ID=Event.initiator.id_ - Event.IniDCSUnitName = string.format("Ejected Pilot ID %s", tostring(ID)) + local ID = Event.initiator.id_ + Event.IniDCSUnitName = string.format( "Ejected Pilot ID %s", tostring( ID ) ) Event.IniUnitName = Event.IniDCSUnitName Event.IniCoalition = 0 - Event.IniCategory = 0 + Event.IniCategory = 0 Event.IniTypeName = "Ejected Pilot" - elseif Event.id == 33 then -- ejection seat discarded + elseif Event.id == 33 then -- ejection seat discarded Event.IniDCSUnit = Event.initiator - local ID=Event.initiator.id_ - Event.IniDCSUnitName = string.format("Ejection Seat ID %s", tostring(ID)) + local ID = Event.initiator.id_ + Event.IniDCSUnitName = string.format( "Ejection Seat ID %s", tostring( ID ) ) Event.IniUnitName = Event.IniDCSUnitName Event.IniCoalition = 0 - Event.IniCategory = 0 + Event.IniCategory = 0 Event.IniTypeName = "Ejection Seat" else Event.IniDCSUnit = Event.initiator @@ -1088,7 +1073,7 @@ function EVENT:onEvent( Event ) Event.IniDCSUnit = Event.initiator Event.IniDCSUnitName = Event.IniDCSUnit:getName() Event.IniUnitName = Event.IniDCSUnitName - Event.IniUnit = AIRBASE:FindByName(Event.IniDCSUnitName) + Event.IniUnit = AIRBASE:FindByName( Event.IniDCSUnitName ) Event.IniCoalition = Event.IniDCSUnit:getCoalition() Event.IniCategory = Event.IniDCSUnit:getDesc().category Event.IniTypeName = Event.IniDCSUnit:getTypeName() @@ -1109,9 +1094,9 @@ function EVENT:onEvent( Event ) if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then Event.TgtDCSGroupName = Event.TgtDCSGroup:getName() Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName ) - --if Event.TgtGroup then - Event.TgtGroupName = Event.TgtDCSGroupName - --end + -- if Event.TgtGroup then + Event.TgtGroupName = Event.TgtDCSGroupName + -- end end Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName() Event.TgtCoalition = Event.TgtDCSUnit:getCoalition() @@ -1130,18 +1115,18 @@ function EVENT:onEvent( Event ) Event.TgtCategory = Event.TgtDCSUnit:getDesc().category Event.TgtTypeName = Event.TgtDCSUnit:getTypeName() else - Event.TgtDCSUnitName = string.format("No target object for Event ID %s", tostring(Event.id)) + Event.TgtDCSUnitName = string.format( "No target object for Event ID %s", tostring( Event.id ) ) Event.TgtUnitName = Event.TgtDCSUnitName Event.TgtUnit = nil Event.TgtCoalition = 0 Event.TgtCategory = 0 if Event.id == 6 then Event.TgtTypeName = "Ejected Pilot" - Event.TgtDCSUnitName = string.format("Ejected Pilot ID %s", tostring(Event.IniDCSUnitName)) + Event.TgtDCSUnitName = string.format( "Ejected Pilot ID %s", tostring( Event.IniDCSUnitName ) ) Event.TgtUnitName = Event.TgtDCSUnitName elseif Event.id == 33 then Event.TgtTypeName = "Ejection Seat" - Event.TgtDCSUnitName = string.format("Ejection Seat ID %s", tostring(Event.IniDCSUnitName)) + Event.TgtDCSUnitName = string.format( "Ejection Seat ID %s", tostring( Event.IniDCSUnitName ) ) Event.TgtUnitName = Event.TgtDCSUnitName else Event.TgtTypeName = "Static" @@ -1167,29 +1152,29 @@ function EVENT:onEvent( Event ) Event.WeaponCoalition = Event.WeaponUNIT and Event.Weapon:getCoalition() Event.WeaponCategory = Event.WeaponUNIT and Event.Weapon:getDesc().category Event.WeaponTypeName = Event.WeaponUNIT and Event.Weapon:getTypeName() - --Event.WeaponTgtDCSUnit = Event.Weapon:getTarget() + -- Event.WeaponTgtDCSUnit = Event.Weapon:getTarget() end -- Place should be given for takeoff and landing events as well as base captured. It should be a DCS airbase. if Event.place then - if Event.id==EVENTS.LandingAfterEjection then + if Event.id == EVENTS.LandingAfterEjection then -- Place is here the UNIT of which the pilot ejected. - --local name=Event.place:getName() -- This returns a DCS error "Airbase doesn't exit" :( + -- local name=Event.place:getName() -- This returns a DCS error "Airbase doesn't exit" :( -- However, this is not a big thing, as the aircraft the pilot ejected from is usually long crashed before the ejected pilot touches the ground. - --Event.Place=UNIT:Find(Event.place) + -- Event.Place=UNIT:Find(Event.place) else - Event.Place=AIRBASE:Find(Event.place) - Event.PlaceName=Event.Place:GetName() + Event.Place = AIRBASE:Find( Event.place ) + Event.PlaceName = Event.Place:GetName() end end -- Mark points. if Event.idx then - Event.MarkID=Event.idx - Event.MarkVec3=Event.pos - Event.MarkCoordinate=COORDINATE:NewFromVec3(Event.pos) - Event.MarkText=Event.text - Event.MarkCoalition=Event.coalition + Event.MarkID = Event.idx + Event.MarkVec3 = Event.pos + Event.MarkCoordinate = COORDINATE:NewFromVec3( Event.pos ) + Event.MarkText = Event.text + Event.MarkCoalition = Event.coalition Event.MarkGroupID = Event.groupID end @@ -1218,9 +1203,9 @@ function EVENT:onEvent( Event ) -- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called. for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do - --if Event.IniObjectCategory ~= Object.Category.STATIC then + -- if Event.IniObjectCategory ~= Object.Category.STATIC then -- self:E( { "Evaluating: ", EventClass:GetClassNameAndID() } ) - --end + -- end Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName ) @@ -1237,8 +1222,8 @@ function EVENT:onEvent( Event ) local UnitName = EventClass:GetName() - if ( EventMeta.Side == "I" and UnitName == Event.IniDCSUnitName ) or - ( EventMeta.Side == "T" and UnitName == Event.TgtDCSUnitName ) then + if (EventMeta.Side == "I" and UnitName == Event.IniDCSUnitName) or + (EventMeta.Side == "T" and UnitName == Event.TgtDCSUnitName) then -- First test if a EventFunction is Set, otherwise search for the default function if EventData.EventFunction then @@ -1247,15 +1232,14 @@ function EVENT:onEvent( Event ) self:F( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) end - local Result, Value = xpcall( - function() - return EventData.EventFunction( EventClass, Event ) - end, ErrorHandler ) + local Result, Value = xpcall( function() + return EventData.EventFunction( EventClass, Event ) + end, ErrorHandler ) else -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. - local EventFunction = EventClass[ EventMeta.Event ] + local EventFunction = EventClass[EventMeta.Event] if EventFunction and type( EventFunction ) == "function" then -- Now call the default event function. @@ -1263,10 +1247,9 @@ function EVENT:onEvent( Event ) self:F( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) end - local Result, Value = xpcall( - function() - return EventFunction( EventClass, Event ) - end, ErrorHandler ) + local Result, Value = xpcall( function() + return EventFunction( EventClass, Event ) + end, ErrorHandler ) end end end @@ -1290,8 +1273,8 @@ function EVENT:onEvent( Event ) -- We can get the name of the EventClass, which is now always a GROUP object. local GroupName = EventClass:GetName() - if ( EventMeta.Side == "I" and GroupName == Event.IniDCSGroupName ) or - ( EventMeta.Side == "T" and GroupName == Event.TgtDCSGroupName ) then + if (EventMeta.Side == "I" and GroupName == Event.IniDCSGroupName) or + (EventMeta.Side == "T" and GroupName == Event.TgtDCSGroupName) then -- First test if a EventFunction is Set, otherwise search for the default function if EventData.EventFunction then @@ -1300,15 +1283,14 @@ function EVENT:onEvent( Event ) self:F( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) end - local Result, Value = xpcall( - function() - return EventData.EventFunction( EventClass, Event, unpack( EventData.Params ) ) - end, ErrorHandler ) + local Result, Value = xpcall( function() + return EventData.EventFunction( EventClass, Event, unpack( EventData.Params ) ) + end, ErrorHandler ) else -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. - local EventFunction = EventClass[ EventMeta.Event ] + local EventFunction = EventClass[EventMeta.Event] if EventFunction and type( EventFunction ) == "function" then -- Now call the default event function. @@ -1316,16 +1298,15 @@ function EVENT:onEvent( Event ) self:F( { "Calling " .. EventMeta.Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } ) end - local Result, Value = xpcall( - function() - return EventFunction( EventClass, Event, unpack( EventData.Params ) ) - end, ErrorHandler ) + local Result, Value = xpcall( function() + return EventFunction( EventClass, Event, unpack( EventData.Params ) ) + end, ErrorHandler ) end end end else -- The EventClass is not alive anymore, we remove it from the EventHandlers... - --self:RemoveEvent( EventClass, Event.id ) + -- self:RemoveEvent( EventClass, Event.id ) end else @@ -1340,14 +1321,13 @@ function EVENT:onEvent( Event ) if Event.IniObjectCategory ~= 3 then self:F2( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } ) end - local Result, Value = xpcall( - function() - return EventData.EventFunction( EventClass, Event ) - end, ErrorHandler ) + local Result, Value = xpcall( function() + return EventData.EventFunction( EventClass, Event ) + end, ErrorHandler ) else -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. - local EventFunction = EventClass[ EventMeta.Event ] + local EventFunction = EventClass[EventMeta.Event] if EventFunction and type( EventFunction ) == "function" then -- Now call the default event function. @@ -1355,11 +1335,10 @@ function EVENT:onEvent( Event ) self:F2( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) end - local Result, Value = xpcall( - function() - local Result, Value = EventFunction( EventClass, Event ) - return Result, Value - end, ErrorHandler ) + local Result, Value = xpcall( function() + local Result, Value = EventFunction( EventClass, Event ) + return Result, Value + end, ErrorHandler ) end end @@ -1383,7 +1362,7 @@ function EVENT:onEvent( Event ) self:T( { EventMeta.Text, Event } ) end else - self:E(string.format("WARNING: Could not get EVENTMETA data for event ID=%d! Is this an unknown/new DCS event?", tostring(Event.id))) + self:E( string.format( "WARNING: Could not get EVENTMETA data for event ID=%d! Is this an unknown/new DCS event?", tostring( Event.id ) ) ) end Event = nil