diff Degaine.lua @ 63:3daeb57da1a9 tip

Automated merge with ssh://hg.wowace.com/wow/degaine/mainline
author contrebasse
date Wed, 01 Jun 2011 19:16:37 +0200
parents 16828b1f9f9d
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Degaine.lua	Wed Jun 01 19:16:37 2011 +0200
@@ -0,0 +1,390 @@
+local AddonName, T = ...
+-- Draw your weapons automagically
+
+
+---------------------------------------------------------------
+-- Known bugs
+---------------------------------------------------------------
+-- If you stand up by jumping or walking it won't draw your weapon
+--     (it's not possible to know if you were sitting or standing before)
+
+--@debug@
+local debug = false
+local debugAll = false
+--@end-debug@
+
+
+---------------------------------------------------------------
+-- Globals to local
+---------------------------------------------------------------
+-- These need to be globals :
+-- GLOBALS: Degaine_ToggleAuto, Degaine_isAuto, BINDING_HEADER_DEGAINE, BINDING_NAME_DEGAINE_TOGGLE
+
+-- It doesn't matter if they are globals, rarely unsed :
+-- GLOBALS: DEFAULT_CHAT_FRAME
+
+-- Lua functions
+local pairs = pairs;
+local type = type;
+local select = select
+local wipe = wipe
+
+-- Wow functions
+local GetTime = GetTime
+local InCombatLockdown = InCombatLockdown
+local UnitName = UnitName
+local IsMounted = IsMounted
+local UnitCastingInfo = UnitCastingInfo
+local GetUnitSpeed = GetUnitSpeed
+local UnitBuff = UnitBuff
+-- The hook has to be done before registering the local reference
+local t_lastDegaine = 0 -- Time of the last draw
+hooksecurefunc("ToggleSheath",function()
+	t_lastDegaine = GetTime()
+end);
+local ToggleSheath = ToggleSheath
+
+
+---------------------------------------------------------------
+-- Local vars
+---------------------------------------------------------------
+-- const
+local DegaineFrame = CreateFrame("Frame")
+local playername = UnitName("player")
+local delay = 2.5 -- seconds
+local delay_short = 0.5 -- seconds
+
+-- vars
+local t_left = -1
+local isGossipClosed = true
+local wasGossipOpened = false
+local t_lastGossipClosed = 0
+--local wasMounted = IsMounted() -- handle mounts with UNIT_AURA
+local isTradeSkill = false
+
+
+---------------------------------------------------------------
+-- Some stuff...
+---------------------------------------------------------------
+-- Print status
+local printState = function()
+	DEFAULT_CHAT_FRAME:AddMessage(Degaine_isAuto and T.L["PRINT_ENABLED"] or T.L["PRINT_DISABLED"])
+end
+
+
+---------------------------------------------------------------
+-- Launch drawing weapons
+---------------------------------------------------------------
+
+-- Wait a few seconds before drawing, to be able to see the curren animation (and avoid bugs)
+local Degaine_OnUpdate = function(self,t_elapsed)
+	t_left = t_left - t_elapsed;
+	if t_left<=0 then
+		ToggleSheath()
+		DegaineFrame:SetScript("OnUpdate", nil)
+	end
+end
+local start = function(arg_delay)
+
+	--@debug@
+	--DEFAULT_CHAT_FRAME:AddMessage("Go !")
+	--@end-debug@
+
+	if Degaine_isAuto and (GetTime()-t_lastDegaine)>1 and not InCombatLockdown() then
+		t_left = arg_delay or delay
+		DegaineFrame:SetScript("OnUpdate", Degaine_OnUpdate)
+	end
+end
+
+
+---------------------------------------------------------------
+-- Events config
+---------------------------------------------------------------
+-- Events to watch
+local events = { -- no args to watch
+	GOSSIP_SHOW = function()
+		-- isGossipClosed :
+		-- if the gossip is already opened, no need to draw weapon
+		-- UnitName("npc")==UnitName("target") :
+		-- hack gossips again because there's no emote with non npc
+		-- you have to target the npc to interact with it
+		-- things such as boards can't be targeted and start no emote
+		local returnvalue = isGossipClosed and UnitName("npc")==UnitName("target")
+		isGossipClosed = false
+		return returnvalue
+	end,
+	MERCHANT_SHOW = function()
+		-- hack for the cases where the merchant's frame is opened from a gossip frame :
+		--  the gossip is closed and the merchant opened but the weapon is not stealthed
+		if (GetTime() - t_lastGossipClosed) < 0.5 then
+			return not wasGossipOpened
+		else
+			return isGossipClosed
+		end
+	end,
+	QUEST_PROGRESS = true,
+	BANKFRAME_OPENED = true, --function() return GossipFrame:IsShown() end,
+	AUCTION_HOUSE_SHOW = true,
+}
+local events1player = { -- the first arg is "player"
+	UNIT_SPELLCAST_FAILED = true,
+	UNIT_SPELLCAST_INTERRUPTED = true,
+	UNIT_SPELLCAST_SUCCEEDED = true,
+	UNIT_SPELLCAST_START = true, -- to ckeck tradeskill
+}
+
+--[[
+-- Was used when moving prevented to play the emote when talking
+-- Was needed for CHAT_MSG_SAY and CHAT_MSG_YELL
+local function playerIsNotMoving()
+	return GetUnitSpeed("player") == 0
+end
+--]]
+local events2playername = { -- the 2nd arg is playername
+	CHAT_MSG_SAY = true,
+	CHAT_MSG_YELL = true,
+	CHAT_MSG_TEXT_EMOTE = true, -- the emote is not shown, but the weapon is stealthed
+}
+
+
+---------------------------------------------------------------
+-- Handle mounts with OnUpdate
+---------------------------------------------------------------
+-- works with GupPet but not with the default interface...
+-- I guess that's because a specific /cancelaura or alike is done
+-- hooksecurefunc("Dismount",start);
+
+-- With OnUpdate
+local handleMountsFrame = CreateFrame("frame")
+local handleMountsOnUpdate
+do
+	local IsMounted = IsMounted
+	local wasMounted = IsMounted()
+	local buffsIDs = {}
+	function handleMountsOnUpdate(self,t_elapsed)
+		if IsMounted() then
+			wasMounted = true
+		else
+			if wasMounted then
+				start(delay_short) -- no animation for unmounting
+				wasMounted = false
+			end
+		end
+
+		-- hack to watch auras too
+		-- Loop over all buffs
+		-- name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable,
+		--    shouldConsolidate, spellId = UnitBuff("unit", index or ["name", "rank"][, "filter"])
+		local i = 1
+		-- list player's buffs
+		local buffID = select(11,UnitBuff("player", i)); -- spell id
+		while buffID do
+			buffsIDs[buffID] = true
+			i = i + 1;
+			buffID = select(11,UnitBuff("player", i));
+		end
+		--[[
+		for i=1,40 do
+			buffID = select(11,UnitBuff("player", i));
+			if buffID then
+				buffsIDs[buffID] = true
+			end
+		end
+		--]]
+		--@debug@
+		--if debug then
+		--	DEFAULT_CHAT_FRAME:AddMessage(""..i-1.."Buff(s) found")
+		--end
+		--@end-debug@
+
+		-- loop over watched buffs to check if it is present or not
+		-- we have to loop over T.LoseAura (and not buffsIDs) to be able to check for buff disappearance
+		for id,state in pairs(T.LoseAura) do
+			if buffsIDs[id] then
+				if not T.LoseAura[id] then
+					-- buff gained
+					--@debug@
+					if debug then
+						DEFAULT_CHAT_FRAME:AddMessage("Buff gained: "..id)
+					end
+					--@end-debug@
+					T.LoseAura[id] = true
+				end
+			else
+				if T.LoseAura[id] then
+					-- buff lost
+					--@debug@
+					if debug then
+						DEFAULT_CHAT_FRAME:AddMessage("Buff lost: "..id)
+					end
+					--@end-debug@
+					T.LoseAura[id] = false
+
+					-- draw weapon
+					start()
+				end
+			end
+		end
+
+		-- empty temporary table
+		wipe(buffsIDs)
+	end
+end
+
+
+---------------------------------------------------------------
+-- Activation functions
+---------------------------------------------------------------
+local activate = function()
+	if (not Degaine_isAuto) or InCombatLockdown() then return end
+
+	--DegaineFrame:SetScript("OnUpdate", Degaine_OnUpdate);
+	--@debug@
+	if debugAll then
+		DegaineFrame:RegisterAllEvents()
+	else
+	--@end-debug@
+		for k,_ in pairs(events) do DegaineFrame:RegisterEvent(k) end
+		for k,_ in pairs(events1player) do DegaineFrame:RegisterEvent(k) end
+		for k,_ in pairs(events2playername) do DegaineFrame:RegisterEvent(k) end
+		--DegaineFrame:RegisterEvent("UNIT_AURA")
+		handleMountsFrame:SetScript("OnUpdate",handleMountsOnUpdate)
+	--@debug@
+	end
+	--@end-debug@
+end
+local desactivate = function()
+	DegaineFrame:SetScript("OnUpdate", nil)
+	t_left = -1
+	isTradeSkill = false
+	for k,_ in pairs(events) do DegaineFrame:UnregisterEvent(k) end
+	for k,_ in pairs(events1player) do DegaineFrame:UnregisterEvent(k) end
+	for k,_ in pairs(events2playername) do DegaineFrame:UnregisterEvent(k) end
+	--DegaineFrame:UnregisterEvent("UNIT_AURA")
+	handleMountsFrame:SetScript("OnUpdate",nil)
+end
+Degaine_ToggleAuto = function()
+	if Degaine_isAuto then
+		Degaine_isAuto = false
+		desactivate()
+	else
+		Degaine_isAuto = true
+		activate()
+	end
+	printState()
+end
+
+
+
+---------------------------------------------------------------
+-- Event/hooks functions
+---------------------------------------------------------------
+local Degaine_OnEvent = function(self,event, arg1, arg2, _, _, arg5, ...)
+	--@debug@
+	if debug then
+		DEFAULT_CHAT_FRAME:AddMessage(event)
+		if arg1 then DEFAULT_CHAT_FRAME:AddMessage("arg1 = "..arg1) end
+		if arg2 then DEFAULT_CHAT_FRAME:AddMessage("arg2 = "..arg2) end
+	end
+	--@end-debug@
+
+	--[[ IsMounted() renvoie toujours false ici, on doit passer par OnUpdate
+	if event=="UNIT_AURA" then
+		if arg1=="player" then
+			DEFAULT_CHAT_FRAME:AddMessage("player")
+			if IsMounted() then
+				DEFAULT_CHAT_FRAME:AddMessage("ismounted")
+				wasMounted = true
+			else
+				DEFAULT_CHAT_FRAME:AddMessage("notmounted")
+				if wasMounted then
+					DEFAULT_CHAT_FRAME:AddMessage("wasmounted : start")
+					wasMounted = false
+					start()
+				end
+			end
+		end
+	else
+	--]]
+	if events[event] then
+		if type(events[event])~="function" or events[event]() then
+			start()
+		end
+	elseif events1player[event] then
+		if arg1=="player" then
+			if event == "UNIT_SPELLCAST_START" then
+				--name, nameSubtext, text, texture, startTime, endTime, isTradeSkill, castID, notInterruptible = UnitCastingInfo("unit")
+				isTradeSkill = select(7,UnitCastingInfo("player"))
+				--DEFAULT_CHAT_FRAME:AddMessage(name)
+				--DEFAULT_CHAT_FRAME:AddMessage(isTradeSkill and "True" or "False")
+				--if isTradeSkill then
+
+				--end
+			--elseif arg5 and not T.SpellBlackList[arg5] then -- arg5 is SpellID
+			elseif (arg5 and T.SpellWhiteList[arg5]) or isTradeSkill then -- arg5 is SpellID
+				isTradeSkill = false -- for next time
+				start(type(T.SpellWhiteList[arg5])=="number" and T.SpellWhiteList[arg5] or delay_short)
+			end
+		end
+	elseif events2playername[event] then
+		if arg2==playername and (type(events2playername[event])~="function" or events2playername[event]()) then
+			start()
+		end
+	elseif event == "GOSSIP_CLOSED" then
+		wasGossipOpened = not isGossipClosed
+		isGossipClosed = true
+		t_lastGossipClosed = GetTime()
+
+	elseif event == "PLAYER_REGEN_ENABLED" then
+		for k,_ in pairs(events1player) do DegaineFrame:UnregisterEvent(k) end
+		--desactivate()
+	elseif event == "PLAYER_REGEN_DISABLED" then
+		for k,_ in pairs(events1player) do DegaineFrame:RegisterEvent(k) end
+		--activate()
+
+	elseif event == "ADDON_LOADED" and arg1==AddonName then
+		if Degaine_isAuto==nil then
+			Degaine_isAuto = true
+		end
+		if Degaine_isAuto then activate() else desactivate() end
+		printState()
+
+		-- Not needed anymore
+		DegaineFrame:UnregisterEvent("ADDON_LOADED")
+
+	elseif event == "PLAYER_LOGIN" then
+		-- BLacklis alomst all Companions and mounts
+		T.DoBlackListCrittersAndMount()
+	end
+end
+
+-- Hook when standing up
+-- (Didn't work, see http://forums.wowace.com/showthread.php?p=310547#post310547)
+hooksecurefunc("SitStandOrDescendStart",start);
+
+
+---------------------------------------------------------------
+-- Commands
+---------------------------------------------------------------
+-- Bindings
+BINDING_HEADER_DEGAINE = T.L["BINDING_HEADER"]
+BINDING_NAME_DEGAINE_TOGGLE = T.L["BINDING_NAME_DEGAINE_TOGGLE"]
+
+-- Slash command
+-- GLOBALS: SLASH_DEGAINE1
+SLASH_DEGAINE1 = "/degaine"
+SlashCmdList["DEGAINE"] = Degaine_ToggleAuto
+
+
+---------------------------------------------------------------
+-- Initialization
+---------------------------------------------------------------
+DegaineFrame:SetScript("OnEvent",Degaine_OnEvent)
+
+-- Global events
+DegaineFrame:RegisterEvent("GOSSIP_CLOSED")
+DegaineFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
+DegaineFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
+DegaineFrame:RegisterEvent("ADDON_LOADED")
+DegaineFrame:RegisterEvent("PLAYER_LOGIN")
+activate()