tercio@0: tercio@0: PVPScan = LibStub ("AceAddon-3.0"):NewAddon ("PVPScan", "AceConsole-3.0", "AceEvent-3.0") tercio@0: tercio@0: local LDB = LibStub ("LibDataBroker-1.1", true) tercio@0: local LDBIcon = LDB and LibStub ("LibDBIcon-1.0", true) tercio@0: local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0") tercio@0: tercio@0: local _bit_band = bit.band tercio@0: tercio@0: local REACTION_HOSTILE = 0x00000040 tercio@0: local OBJECT_TYPE_PLAYER = 0x00000400 tercio@0: tercio@0: PVPScan.SpotBars = {} tercio@0: PVPScan.NeedClass = {} tercio@0: PVPScan.NextSpotBar = 1 tercio@0: PVPScan.CurrentShownIndex = {} tercio@0: PVPScan.CurrentShownHash = {} tercio@0: PVPScan.CurrentShownTime = {} tercio@0: tercio@0: local default_db = { tercio@0: profile = { tercio@0: SpotBarHeight = 20, tercio@0: SpotBarAmount = 5, tercio@0: SpotBarWidth = 150, tercio@0: Locked = false, tercio@0: SoundPlay = false, tercio@0: SoundFile = "", tercio@0: Minimap = {hide = false, radius = 160, minimapPos = 220}, tercio@0: }, tercio@0: } tercio@0: tercio@0: function PVPScan:OnEnable() tercio@0: end tercio@0: tercio@0: function PVPScan:OnDisable() tercio@0: end tercio@0: tercio@0: local OptionsTable = { tercio@0: name = "PVPScan", tercio@0: type = "group", tercio@0: args = { tercio@0: SpotBarHeight = { tercio@0: type = "range", tercio@0: name = "Bar Height", tercio@0: desc = "Change the height of spot bars.", tercio@0: min = 10, tercio@0: max = 40, tercio@0: step = 1, tercio@0: get = function() return PVPScan.db.profile.SpotBarHeight end, tercio@0: set = function (self, val) PVPScan.db.profile.SpotBarHeight = val; PVPScan:RefreshSpotBars() end, tercio@0: order = 1, tercio@0: }, tercio@0: SpotBarWidth = { tercio@0: type = "range", tercio@0: name = "Bar Width", tercio@0: desc = "Change the width of spot bars.", tercio@0: min = 50, tercio@0: max = 250, tercio@0: step = 1, tercio@0: get = function() return PVPScan.db.profile.SpotBarWidth end, tercio@0: set = function (self, val) PVPScan.db.profile.SpotBarWidth = val; PVPScan:RefreshSpotBars() end, tercio@0: order = 2, tercio@0: }, tercio@0: SpotBarAmount = { tercio@0: type = "range", tercio@0: name = "Bar Amount", tercio@0: desc = "Change the amount of spot bars.", tercio@0: min = 1, tercio@0: max = 40, tercio@0: step = 1, tercio@0: get = function() return PVPScan.db.profile.SpotBarAmount end, tercio@0: set = function (self, val) PVPScan.db.profile.SpotBarAmount = val; PVPScan:RefreshSpotBars() end, tercio@0: order = 3, tercio@0: }, tercio@0: Locked = { tercio@0: type = "toggle", tercio@0: name = "Lock Frame", tercio@0: desc = "Lock or unlock the SpotBars Frame.", tercio@0: order = 4, tercio@0: get = function() return PVPScan.db.profile.Locked end, tercio@0: set = function (self, val) PVPScan.db.profile.Locked = not PVPScan.db.profile.Locked end, tercio@0: }, tercio@0: SoundPlay = { tercio@0: type = "toggle", tercio@0: name = "Play Sound", tercio@0: desc = "Play a sound when a enemy is found.", tercio@0: order = 5, tercio@0: get = function() return PVPScan.db.profile.SoundPlay end, tercio@0: set = function (self, val) PVPScan.db.profile.SoundPlay = not PVPScan.db.profile.SoundPlay end, tercio@0: }, tercio@0: SoundFile = { tercio@0: type = "select", tercio@0: name = "Sound File", tercio@0: desc = "Choose the sound to play when a enemy is found.", tercio@0: values = function() tercio@0: local SoundTable = {} tercio@0: for name, _ in pairs (SharedMedia:HashTable ("sound")) do tercio@0: SoundTable [name] = name tercio@0: end tercio@0: return SoundTable tercio@0: end, tercio@0: get = function() return PVPScan.db.profile.SoundFile end, tercio@0: set = function (self, file) PVPScan.db.profile.SoundFile = file end, tercio@0: order = 6, tercio@0: }, tercio@0: Minimap = { tercio@0: type = "toggle", tercio@0: name = "Hide Minimap Icon", tercio@0: desc = "Show or hide the minimap icon.", tercio@0: order = 7, tercio@0: get = function() return PVPScan.db.profile.Minimap.hide end, tercio@0: set = function (self, val) tercio@0: PVPScan.db.profile.Minimap.hide = not PVPScan.db.profile.Minimap.hide tercio@0: LDBIcon:Refresh ("PVPScan", PVPScan.db.profile.Minimap) tercio@0: if (PVPScan.db.profile.Minimap.hide) then tercio@0: LDBIcon:Hide ("PVPScan") tercio@0: else tercio@0: LDBIcon:Show ("PVPScan") tercio@0: end tercio@0: end, tercio@0: }, tercio@0: }, tercio@0: } tercio@0: tercio@0: function PVPScan:OnInitialize() tercio@0: tercio@0: --declarar primeiro o db usando a global que é declarada no toc. tercio@0: self.db = LibStub ("AceDB-3.0"):New ("PVPScanDB", default_db, true) tercio@0: tercio@0: --declara agora as opções da tab raiz tercio@0: LibStub("AceConfig-3.0"):RegisterOptionsTable ("PVPScan", OptionsTable) tercio@0: PVPScan.OptionsFrame1 = LibStub ("AceConfigDialog-3.0"):AddToBlizOptions ("PVPScan", "PVPScan") tercio@0: --sub tab tercio@0: LibStub ("AceConfig-3.0"):RegisterOptionsTable ("PVPScan-Profiles", LibStub ("AceDBOptions-3.0"):GetOptionsTable (self.db)) tercio@0: PVPScan.OptionsFrame2 = LibStub ("AceConfigDialog-3.0"):AddToBlizOptions ("PVPScan-Profiles", "Profiles", "PVPScan") tercio@0: tercio@0: if LDB then tercio@0: local databroker = LDB:NewDataObject ("PVPScan", { tercio@0: type = "launcher", tercio@0: icon = [[Interface\PvPRankBadges\PvPRank15]], tercio@0: --HotCornerIgnore = true, tercio@0: OnClick = function (self, button) tercio@0: InterfaceOptionsFrame_OpenToCategory ("PVPScan") tercio@0: InterfaceOptionsFrame_OpenToCategory ("PVPScan") tercio@0: end tercio@0: }) tercio@0: tercio@0: if (databroker and not LDBIcon:IsRegistered ("PVPScan")) then tercio@0: LDBIcon:Register ("PVPScan", databroker, PVPScan.db.profile.Minimap) tercio@0: end tercio@0: end tercio@0: tercio@0: PVPScan:RefreshSpotBars() tercio@0: tercio@0: end tercio@0: tercio@0: PVPScan:RegisterChatCommand ("pvpscan", function() tercio@0: InterfaceOptionsFrame_OpenToCategory ("PVPScan") tercio@0: InterfaceOptionsFrame_OpenToCategory ("PVPScan") tercio@0: end) tercio@0: tercio@0: ------------------------------------------------------------------------------------------------------------------------------------------------------------ tercio@0: --> parser stuff tercio@0: tercio@0: local event_frame = CreateFrame ("frame", "PVPScanCombatLobReader", UIParent) tercio@0: event_frame:RegisterEvent ("COMBAT_LOG_EVENT_UNFILTERED") tercio@0: tercio@0: function PVPScan:OnParserEvent (event, time, token, hidding, who_serial, who_name, who_flags, who_flags2, target_serial, target_name, target_flags, target_flags2, ...) tercio@0: tercio@0: if (PVPScan.NeedClass [who_name]) then tercio@0: local class = PVPScan:GuessClass (...) tercio@0: if (class) then tercio@0: PVPScan:UpdateBar (PVPScan.NeedClass [who_name], class, who_name) tercio@0: PVPScan.NeedClass [who_name] = nil tercio@0: end tercio@0: return tercio@0: end tercio@0: tercio@0: if (PVPScan.NeedClass [target_name]) then tercio@0: local class = PVPScan:GuessClass (...) tercio@0: if (class) then tercio@0: PVPScan:UpdateBar (PVPScan.NeedClass [target_name], class, target_name) tercio@0: PVPScan.NeedClass [target_name] = nil tercio@0: end tercio@0: return tercio@0: end tercio@0: tercio@0: if (not PVPScan.CurrentShownHash [target_name] and _bit_band (target_flags, OBJECT_TYPE_PLAYER) ~= 0) then --> is player tercio@0: if (_bit_band (target_flags, REACTION_HOSTILE ) ~= 0) then --> is hostile tercio@0: local class = PVPScan:GuessClass (...) tercio@0: PVPScan:EnemySpoted (target_name, target_serial, target_flags, class) tercio@0: end tercio@0: end tercio@0: tercio@0: if (not PVPScan.CurrentShownHash [who_name] and _bit_band (who_flags, OBJECT_TYPE_PLAYER) ~= 0) then --> is player tercio@0: if (_bit_band (who_flags, REACTION_HOSTILE ) ~= 0) then --> is hostile tercio@0: local class = PVPScan:GuessClass (...) tercio@0: PVPScan:EnemySpoted (who_name, who_serial, who_flags, class) tercio@0: end tercio@0: end tercio@0: end tercio@0: tercio@0: event_frame:SetScript ("OnEvent", PVPScan.OnParserEvent) tercio@0: tercio@0: function PVPScan:LeftCombatLockdown() tercio@0: if (PVPScan.schedule_frame_update) then tercio@0: PVPScan.schedule_frame_update = false tercio@0: PVPScan:RefreshSpotBars() tercio@0: end tercio@0: end tercio@0: function PVPScan:GotCombatLockdown() tercio@0: end tercio@0: tercio@0: PVPScan:RegisterEvent ("PLAYER_REGEN_DISABLED", "GotCombatLockdown") tercio@0: PVPScan:RegisterEvent ("PLAYER_REGEN_ENABLED", "LeftCombatLockdown") tercio@0: tercio@0: function PVPScan:EnemySpoted (name, serial, flags, class) tercio@0: tercio@0: --> check for overwrite tercio@0: local current_player_shown = PVPScan.CurrentShownIndex [PVPScan.NextSpotBar] tercio@0: if (current_player_shown) then tercio@0: PVPScan.NeedClass [current_player_shown] = nil tercio@0: end tercio@0: tercio@0: local SpotBar = PVPScan.SpotBars [PVPScan.NextSpotBar] tercio@0: tercio@0: if (class) then tercio@0: PVPScan:UpdateBar (PVPScan.NextSpotBar, class, name) tercio@0: else tercio@0: PVPScan:UpdateBar (PVPScan.NextSpotBar, nil, name) tercio@0: PVPScan.NeedClass [name] = PVPScan.NextSpotBar tercio@0: end tercio@0: tercio@0: PVPScan.CurrentShownIndex [PVPScan.NextSpotBar] = name tercio@0: PVPScan.CurrentShownHash [name] = PVPScan.NextSpotBar tercio@0: PVPScan.CurrentShownTime [name] = GetTime() tercio@0: tercio@0: if (not UnitAffectingCombat ("player") and not InCombatLockdown()) then tercio@0: SpotBar:SetAttribute("macrotext", "/cleartarget\n/targetexact " .. name) tercio@0: end tercio@0: tercio@0: SpotBar:Show() tercio@0: tercio@0: PVPScan.NextSpotBar = PVPScan.NextSpotBar + 1 tercio@0: if (PVPScan.NextSpotBar > PVPScan.db.profile.SpotBarAmount) then tercio@0: PVPScan.NextSpotBar = 1 tercio@0: end tercio@0: tercio@0: end tercio@0: tercio@0: tercio@0: tercio@0: ------------------------------------------------------------------------------------------------------------------------------------------------------------ tercio@0: --> frames tercio@0: tercio@0: function PVPScanOnFrameMouseDown (self) tercio@0: if (not self.IsMoving) then tercio@0: self:StartMoving() tercio@0: self.IsMoving = true tercio@0: end tercio@0: end tercio@0: tercio@0: function PVPScanOnFrameMouseUp (self) tercio@0: if (self.IsMoving) then tercio@0: self:StopMovingOrSizing() tercio@0: self.IsMoving = false tercio@0: end tercio@0: end tercio@0: tercio@0: function PVPScan:UpdateBar (index, class, name) tercio@0: tercio@0: local SpotBar = PVPScan.SpotBars [index] tercio@0: tercio@0: if (class) then tercio@0: local color = RAID_CLASS_COLORS [class] tercio@0: SpotBar.classtexture:SetVertexColor (color.r, color.g, color.b) tercio@0: tercio@0: local texcoord = CLASS_ICON_TCOORDS [class] tercio@0: SpotBar.classicon:SetTexture ([[Interface\Glues\CHARACTERCREATE\UI-CHARACTERCREATE-CLASSES]]) tercio@0: SpotBar.classicon:SetTexCoord (unpack (texcoord)) tercio@0: else tercio@0: SpotBar.classtexture:SetVertexColor (.7, .7, .7) tercio@0: SpotBar.classicon:SetTexture ([[Interface\InventoryItems\WoWUnknownItem01]]) tercio@0: SpotBar.classicon:SetTexCoord (0, 1, 0, 1) tercio@0: end tercio@0: tercio@0: SpotBar.name:SetText (name) tercio@0: tercio@0: end tercio@0: tercio@0: function PVPScan:RefreshSpotBars() tercio@0: tercio@0: if (UnitAffectingCombat ("player") or InCombatLockdown()) then tercio@0: PVPScan.schedule_frame_update = true tercio@0: PVPScan:Print ("When the combat finishes, the frame will be updated.") tercio@0: return tercio@0: end tercio@0: tercio@0: local amount_bars = PVPScan.db.profile.SpotBarAmount tercio@0: PVPScanFrame:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight) tercio@0: tercio@0: --> we need extra bars? tercio@0: if (amount_bars > #PVPScan.SpotBars) then tercio@0: for i = #PVPScan.SpotBars+1, amount_bars do tercio@0: tercio@0: local new_bar = CreateFrame ("Button", "PVPScanSpotBar" .. i, PVPScanFrame, "PVPScanSpotBarTemplate") tercio@0: tercio@0: local y = (i-1) * PVPScan.db.profile.SpotBarHeight * -1 tercio@0: tercio@0: new_bar:SetPoint ("topleft", PVPScanFrame, "topleft", 0, y) tercio@0: new_bar:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight) tercio@0: tercio@0: tinsert (PVPScan.SpotBars, new_bar) tercio@0: end tercio@0: end tercio@0: tercio@0: if (#PVPScan.SpotBars > amount_bars) then tercio@0: for i = #PVPScan.SpotBars, amount_bars+1, -1 do tercio@0: PVPScan.SpotBars [i]:Hide() tercio@0: local name = PVPScan.CurrentShownIndex [i] tercio@0: if (name) then tercio@0: tremove (PVPScan.CurrentShownIndex, i) tercio@0: PVPScan.CurrentShownHash [name] = nil tercio@0: PVPScan.CurrentShownTime [name] = nil tercio@0: PVPScan.NeedClass [name] = nil tercio@0: end tercio@0: end tercio@0: end tercio@0: tercio@0: --> refresh existing tercio@0: for index, bar in ipairs (PVPScan.SpotBars) do tercio@0: local y = (index-1) * PVPScan.db.profile.SpotBarHeight * -1 tercio@0: bar:SetPoint ("topleft", PVPScanFrame, "topleft", 0, y) tercio@0: bar:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight) tercio@0: end tercio@0: tercio@0: end tercio@0: tercio@0: tercio@0: tercio@0: tercio@0: tercio@0: ------------------------------------------------------------------------------------------------------------------------------------------------------------ tercio@0: --> misc tercio@0: tercio@0: function PVPScan:GuessClass (...) tercio@0: local arg1, arg2, arg3, arg4 = select (1, ...) tercio@0: tercio@0: if (type (arg1) == "number") then tercio@0: if (PVPScan.ClassSpellList [arg1]) then tercio@0: return PVPScan.ClassSpellList [arg1] tercio@0: end tercio@0: end tercio@0: tercio@0: if (type (arg3) == "number") then tercio@0: if (PVPScan.ClassSpellList [arg3]) then tercio@0: return PVPScan.ClassSpellList [arg3] tercio@0: end tercio@0: end tercio@0: tercio@0: if (type (arg2) == "number") then tercio@0: if (PVPScan.ClassSpellList [arg3]) then tercio@0: return PVPScan.ClassSpellList [arg3] tercio@0: end tercio@0: end tercio@0: tercio@0: if (type (arg4) == "number") then tercio@0: if (PVPScan.ClassSpellList [arg4]) then tercio@0: return PVPScan.ClassSpellList [arg4] tercio@0: end tercio@0: end tercio@0: tercio@0: return nil tercio@0: end tercio@0: