view PVPScan.lua @ 0:ce416064d8a1

first commit
author tercio
date Sat, 17 May 2014 02:17:10 -0300
parents
children 726745261b87
line wrap: on
line source

PVPScan = LibStub ("AceAddon-3.0"):NewAddon ("PVPScan", "AceConsole-3.0", "AceEvent-3.0")

local LDB = LibStub ("LibDataBroker-1.1", true)
local LDBIcon = LDB and LibStub ("LibDBIcon-1.0", true)
local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0")

local _bit_band = bit.band

local REACTION_HOSTILE = 0x00000040
local OBJECT_TYPE_PLAYER = 0x00000400

PVPScan.SpotBars = {}
PVPScan.NeedClass = {}
PVPScan.NextSpotBar = 1
PVPScan.CurrentShownIndex = {}
PVPScan.CurrentShownHash = {}
PVPScan.CurrentShownTime = {}

local default_db = {
	profile = {
		SpotBarHeight = 20,
		SpotBarAmount = 5,
		SpotBarWidth = 150,
		Locked = false,
		SoundPlay = false,
		SoundFile = "",
		Minimap = {hide = false, radius = 160, minimapPos = 220},
	},
}

function PVPScan:OnEnable()
end

function PVPScan:OnDisable()
end

local OptionsTable = {
	name = "PVPScan",
	type = "group",
	args = {
		SpotBarHeight = {
			type = "range",
			name = "Bar Height", 
			desc = "Change the height of spot bars.",
			min = 10,
			max = 40,
			step = 1,
			get = function() return PVPScan.db.profile.SpotBarHeight end,
			set = function (self, val) PVPScan.db.profile.SpotBarHeight = val; PVPScan:RefreshSpotBars() end,
			order = 1,
		},
		SpotBarWidth = {
			type = "range",
			name = "Bar Width", 
			desc = "Change the width of spot bars.",
			min = 50,
			max = 250,
			step = 1,
			get = function() return PVPScan.db.profile.SpotBarWidth end,
			set = function (self, val) PVPScan.db.profile.SpotBarWidth = val; PVPScan:RefreshSpotBars() end,
			order = 2,
		},
		SpotBarAmount = {
			type = "range",
			name = "Bar Amount", 
			desc = "Change the amount of spot bars.",
			min = 1,
			max = 40,
			step = 1,
			get = function() return PVPScan.db.profile.SpotBarAmount end,
			set = function (self, val) PVPScan.db.profile.SpotBarAmount = val; PVPScan:RefreshSpotBars() end,
			order = 3,
		},
		Locked = {
			type = "toggle",
			name = "Lock Frame",
			desc = "Lock or unlock the SpotBars Frame.",
			order = 4,
			get = function() return PVPScan.db.profile.Locked end,
			set = function (self, val) PVPScan.db.profile.Locked = not PVPScan.db.profile.Locked end,
		},
		SoundPlay = {
			type = "toggle",
			name = "Play Sound",
			desc = "Play a sound when a enemy is found.",
			order = 5,
			get = function() return PVPScan.db.profile.SoundPlay end,
			set = function (self, val) PVPScan.db.profile.SoundPlay = not PVPScan.db.profile.SoundPlay end,
		},
		SoundFile = {
			type = "select",
			name = "Sound File",
			desc = "Choose the sound to play when a enemy is found.",
			values = function()
					local SoundTable = {}
					for name, _ in pairs (SharedMedia:HashTable ("sound")) do 
						SoundTable [name] = name
					end
					return SoundTable 
				end,
			get = function() return PVPScan.db.profile.SoundFile end,
			set = function (self, file) PVPScan.db.profile.SoundFile = file end,
			order = 6,
		},
		Minimap = {
			type = "toggle",
			name = "Hide Minimap Icon",
			desc = "Show or hide the minimap icon.",
			order = 7,
			get = function() return PVPScan.db.profile.Minimap.hide end,
			set = function (self, val) 
				PVPScan.db.profile.Minimap.hide = not PVPScan.db.profile.Minimap.hide
				LDBIcon:Refresh ("PVPScan", PVPScan.db.profile.Minimap)
				if (PVPScan.db.profile.Minimap.hide) then
					LDBIcon:Hide ("PVPScan")
				else
					LDBIcon:Show ("PVPScan")
				end
			end,
		},		
	},
}

function PVPScan:OnInitialize()

	--declarar primeiro o db usando a global que é declarada no toc.
  	self.db = LibStub ("AceDB-3.0"):New ("PVPScanDB", default_db, true)
	
	--declara agora as opções da tab raiz
	LibStub("AceConfig-3.0"):RegisterOptionsTable ("PVPScan", OptionsTable)
	PVPScan.OptionsFrame1 = LibStub ("AceConfigDialog-3.0"):AddToBlizOptions ("PVPScan", "PVPScan")
	--sub tab
	LibStub ("AceConfig-3.0"):RegisterOptionsTable ("PVPScan-Profiles", LibStub ("AceDBOptions-3.0"):GetOptionsTable (self.db))
	PVPScan.OptionsFrame2 = LibStub ("AceConfigDialog-3.0"):AddToBlizOptions ("PVPScan-Profiles", "Profiles", "PVPScan")
	
	if LDB then
		local databroker = LDB:NewDataObject ("PVPScan", {
			type = "launcher",
			icon = [[Interface\PvPRankBadges\PvPRank15]],
			--HotCornerIgnore = true,
			OnClick = function (self, button)
				InterfaceOptionsFrame_OpenToCategory ("PVPScan")
				InterfaceOptionsFrame_OpenToCategory ("PVPScan")
			end
		})
		
		if (databroker and not LDBIcon:IsRegistered ("PVPScan")) then
			LDBIcon:Register ("PVPScan", databroker, PVPScan.db.profile.Minimap)
		end	
	end
	
	PVPScan:RefreshSpotBars()
	
end

PVPScan:RegisterChatCommand ("pvpscan", function() 
	InterfaceOptionsFrame_OpenToCategory ("PVPScan")
	InterfaceOptionsFrame_OpenToCategory ("PVPScan")
end)

------------------------------------------------------------------------------------------------------------------------------------------------------------
--> parser stuff

	local event_frame = CreateFrame ("frame", "PVPScanCombatLobReader", UIParent)
	event_frame:RegisterEvent ("COMBAT_LOG_EVENT_UNFILTERED")

	function PVPScan:OnParserEvent (event, time, token, hidding, who_serial, who_name, who_flags, who_flags2, target_serial, target_name, target_flags, target_flags2, ...)

		if (PVPScan.NeedClass [who_name]) then
			local class = PVPScan:GuessClass (...)
			if (class) then
				PVPScan:UpdateBar (PVPScan.NeedClass [who_name], class, who_name)
				PVPScan.NeedClass [who_name] = nil
			end
			return
		end
		
		if (PVPScan.NeedClass [target_name]) then
			local class = PVPScan:GuessClass (...)
			if (class) then
				PVPScan:UpdateBar (PVPScan.NeedClass [target_name], class, target_name)
				PVPScan.NeedClass [target_name] = nil
			end
			return
		end

		if (not PVPScan.CurrentShownHash [target_name] and _bit_band (target_flags, OBJECT_TYPE_PLAYER) ~= 0) then --> is player
			if (_bit_band (target_flags, REACTION_HOSTILE ) ~= 0) then --> is hostile
				local class = PVPScan:GuessClass (...)
				PVPScan:EnemySpoted (target_name, target_serial, target_flags, class)
			end
		end
		
		if (not PVPScan.CurrentShownHash [who_name] and _bit_band (who_flags, OBJECT_TYPE_PLAYER) ~= 0) then --> is player
			if (_bit_band (who_flags, REACTION_HOSTILE ) ~= 0) then --> is hostile
				local class = PVPScan:GuessClass (...)
				PVPScan:EnemySpoted (who_name, who_serial, who_flags, class)
			end
		end
	end

	event_frame:SetScript ("OnEvent", PVPScan.OnParserEvent)
	
	function PVPScan:LeftCombatLockdown()
		if (PVPScan.schedule_frame_update) then
			PVPScan.schedule_frame_update = false
			PVPScan:RefreshSpotBars()
		end
	end
	function PVPScan:GotCombatLockdown()
	end
	
	PVPScan:RegisterEvent ("PLAYER_REGEN_DISABLED", "GotCombatLockdown")
	PVPScan:RegisterEvent ("PLAYER_REGEN_ENABLED", "LeftCombatLockdown")

	function PVPScan:EnemySpoted (name, serial, flags, class)

		--> check for overwrite
		local current_player_shown = PVPScan.CurrentShownIndex [PVPScan.NextSpotBar]
		if (current_player_shown) then
			PVPScan.NeedClass [current_player_shown] = nil
		end
	
		local SpotBar = PVPScan.SpotBars [PVPScan.NextSpotBar]

		if (class) then
			PVPScan:UpdateBar (PVPScan.NextSpotBar, class, name)
		else
			PVPScan:UpdateBar (PVPScan.NextSpotBar, nil, name)
			PVPScan.NeedClass [name] = PVPScan.NextSpotBar
		end
		
		PVPScan.CurrentShownIndex [PVPScan.NextSpotBar] = name
		PVPScan.CurrentShownHash [name] = PVPScan.NextSpotBar
		PVPScan.CurrentShownTime [name] = GetTime()
		
		if (not UnitAffectingCombat ("player") and not InCombatLockdown()) then
			SpotBar:SetAttribute("macrotext", "/cleartarget\n/targetexact " .. name)
		end
		
		SpotBar:Show()
		
		PVPScan.NextSpotBar = PVPScan.NextSpotBar + 1
		if (PVPScan.NextSpotBar > PVPScan.db.profile.SpotBarAmount) then
			PVPScan.NextSpotBar = 1
		end

	end
	

	
------------------------------------------------------------------------------------------------------------------------------------------------------------
--> frames

	function PVPScanOnFrameMouseDown (self)
		if (not self.IsMoving) then
			self:StartMoving()
			self.IsMoving = true
		end
	end

	function PVPScanOnFrameMouseUp (self)
		if (self.IsMoving) then
			self:StopMovingOrSizing()
			self.IsMoving = false
		end
	end

	function PVPScan:UpdateBar (index, class, name)
	
		local SpotBar = PVPScan.SpotBars [index]
		
		if (class) then
			local color = RAID_CLASS_COLORS [class]
			SpotBar.classtexture:SetVertexColor (color.r, color.g, color.b)

			local texcoord = CLASS_ICON_TCOORDS [class]
			SpotBar.classicon:SetTexture ([[Interface\Glues\CHARACTERCREATE\UI-CHARACTERCREATE-CLASSES]])
			SpotBar.classicon:SetTexCoord (unpack (texcoord))
		else
			SpotBar.classtexture:SetVertexColor (.7, .7, .7)
			SpotBar.classicon:SetTexture ([[Interface\InventoryItems\WoWUnknownItem01]])
			SpotBar.classicon:SetTexCoord (0, 1, 0, 1)
		end
		
		SpotBar.name:SetText (name)
		
	end
	
	function PVPScan:RefreshSpotBars()
	
		if (UnitAffectingCombat ("player") or InCombatLockdown()) then
			PVPScan.schedule_frame_update = true
			PVPScan:Print ("When the combat finishes, the frame will be updated.")
			return
		end
		
		local amount_bars = PVPScan.db.profile.SpotBarAmount
		PVPScanFrame:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight)

		--> we need extra bars?
		if (amount_bars > #PVPScan.SpotBars) then
			for i = #PVPScan.SpotBars+1, amount_bars do 
			
				local new_bar = CreateFrame ("Button", "PVPScanSpotBar" .. i, PVPScanFrame, "PVPScanSpotBarTemplate")
				
				local y = (i-1) * PVPScan.db.profile.SpotBarHeight * -1
				
				new_bar:SetPoint ("topleft", PVPScanFrame, "topleft", 0, y)
				new_bar:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight)
				
				tinsert (PVPScan.SpotBars, new_bar)
			end
		end
		
		if (#PVPScan.SpotBars > amount_bars) then
			for i = #PVPScan.SpotBars, amount_bars+1, -1 do
				PVPScan.SpotBars [i]:Hide()
				local name = PVPScan.CurrentShownIndex [i]
				if (name) then
					tremove (PVPScan.CurrentShownIndex, i)
					PVPScan.CurrentShownHash [name] = nil
					PVPScan.CurrentShownTime [name] = nil
					PVPScan.NeedClass [name] = nil
				end
			end
		end

		--> refresh existing
		for index, bar in ipairs (PVPScan.SpotBars) do
			local y = (index-1) * PVPScan.db.profile.SpotBarHeight * -1
			bar:SetPoint ("topleft", PVPScanFrame, "topleft", 0, y)
			bar:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight)
		end
		
	end





------------------------------------------------------------------------------------------------------------------------------------------------------------
--> misc

	function PVPScan:GuessClass (...)
		local arg1, arg2, arg3, arg4 = select (1, ...)
		
		if (type (arg1) == "number") then
			if (PVPScan.ClassSpellList [arg1]) then
				return PVPScan.ClassSpellList [arg1]
			end
		end
		
		if (type (arg3) == "number") then
			if (PVPScan.ClassSpellList [arg3]) then
				return PVPScan.ClassSpellList [arg3]
			end
		end
		
		if (type (arg2) == "number") then
			if (PVPScan.ClassSpellList [arg3]) then
				return PVPScan.ClassSpellList [arg3]
			end
		end

		if (type (arg4) == "number") then
			if (PVPScan.ClassSpellList [arg4]) then
				return PVPScan.ClassSpellList [arg4]
			end
		end
		
		return nil
	end