-------------------------------------------------------------------------- -- IsMounted.lua -------------------------------------------------------------------------- --[[ IsMounted author: AnduinLothar KarlKFI@cosmosui.org -Mini-Library that maintains a list of who's mounted. Note: Information gathered from this addon is only correct for friendly units or units that you can see the buffs of. Change Log: v1.61 -Fixed nil find string error v1.6 -Player mounted check now uses the PlayerBuff functions rather than UnitBuff. -Player Buff ID returned now coresponds to the buff index returned from GetPlayerBuff(i, "HELPFUL|PASSIVE") and can be used directly by CancelPlayerBuff. -Dismount now works correctly with debuffs. -Localed a few internal functions for quicker indexing v1.5 - Mounted status now accurate when called from PLAYER_AURAS_CHANGED and not cleared on UNIT_AURA (UNIT_AURA w/ arg1=="player" is always called after PLAYER_AURAS_CHANGED.) v1.4 - Changed tooltip scan to use IsShown to work with 1.9 v1.3 - Added French and German Localizations v1.2 - Added Function: Dismount() - Added Function: UnitMountSpeed(unit) - Added Function: UnitMountBuffID( string unit ) - Changed all refrences of 'buff slot' to 'id' Note: id is the id of the buff in terms of Tooltip/Texture index that starts at 1 while the Buff/Frame index starts at 0. So you might have to subtract 1 till blizz fixes it next patch, depending on your usage. v1.1 - Fixed but that would throw error when UNIT_AURA triggered for 'mouseover' unit. (I Didn't know it caught mouseover O.o) v1.0 - Initial Release ]]-- -------------------------------------------------- -- Globals -------------------------------------------------- IsMounted = {}; -- Predictibly consistant units IsMounted.UnitTable = { player = {}; target = {}; } for i=1, 4 do IsMounted.UnitTable["party"..i] = {} end for i=1, 40 do IsMounted.UnitTable["raid"..i] = {} end -------------------------------------------------- -- Internal Functions -------------------------------------------------- IsMounted.OnLoad = function() IsMountedFrame:RegisterEvent("PLAYER_AURAS_CHANGED"); IsMountedFrame:RegisterEvent("UNIT_AURA"); IsMountedFrame:RegisterEvent("PLAYER_TARGET_CHANGED"); IsMountedFrame:RegisterEvent("PARTY_MEMBERS_CHANGED"); IsMountedFrame:RegisterEvent("RAID_ROSTER_UPDATE"); IsMountedFrame:RegisterEvent("PLAYER_ENTERING_WORLD"); IsMountedTooltip:SetOwner(UIParent, "ANCHOR_NONE"); end -- Nils predictibly consistant stored values when the unit or its buffs change IsMounted.OnEvent = function(event) if (event == "PLAYER_ENTERING_WORLD") then IsMounted.UnitTable["player"].speed = nil; IsMounted.UnitTable["player"].id = nil; elseif (event == "PLAYER_AURAS_CHANGED") then --Sea.io.print("player IsMounted mount state nilled."); IsMounted.UnitTable["player"].speed = nil; IsMounted.UnitTable["player"].id = nil; elseif (event == "UNIT_AURA") then if (not IsMounted.UnitTable[arg1]) then --Triggered by 'mouseover' buff change --Sea.io.print("UNIT_AURA: ", arg1); elseif (arg1 ~= "player") then --Sea.io.print(arg1, " IsMounted mount state nilled."); IsMounted.UnitTable[arg1].speed = nil; IsMounted.UnitTable[arg1].id = nil; end elseif (event == "PLAYER_TARGET_CHANGED") then IsMounted.UnitTable["target"].speed = nil; IsMounted.UnitTable["target"].id = nil; elseif (event == "PARTY_MEMBERS_CHANGED") then for i=1, 4 do IsMounted.UnitTable["party"..i].speed = nil; IsMounted.UnitTable["party"..i].id = nil; end elseif (event == "RAID_ROSTER_UPDATE") then for i=1, 40 do IsMounted.UnitTable["raid"..i].speed = nil; IsMounted.UnitTable["raid"..i].id = nil; end end end -- Sets stored values of predictibly consistant units and returns the speed and id of the mount buff. local GetUpdatedUnitTable = function(unit) local speed, id = IsMounted.GetUpdatedMountBuffInfo(unit); if (IsMounted.UnitTable[unit]) then --Sea.io.print("Updating UnitTable for ".. unit..": ", speed, ", ", id); -- debug msg IsMounted.UnitTable[unit].speed = speed; IsMounted.UnitTable[unit].id = id; end return speed, id; end -- Gets speed and id of player mount buff according to GetPlayerBuff local GetPlayerMountBuffInfo = function() -- Check the tooltips of the player's active buffs for the key string. local text, buffIndex, untilCancelled, _, speed; for i = 0, 23 do buffIndex, untilCancelled = GetPlayerBuff(i, "HELPFUL|PASSIVE"); if ( buffIndex < 0 ) then break; elseif ( untilCancelled ) then IsMountedTooltip:SetPlayerBuff(buffIndex); if (IsMountedTooltipTextLeft2:IsShown()) then text = IsMountedTooltipTextLeft2:GetText(); if (text) then _, _, speed = string.find(text, ISMOUNTED_SPEED_INCREASED_BY); if (speed) then return tonumber(speed), buffIndex; end end end end end return false; end -- Gets speed and id of non-player mount buff according to UnitBuff local GetNonPlayerMountBuffInfo = function(unit) -- Check the tooltips of the unit's active buffs for the key string. local text, _, speed; for i = 1, 24 do if (not UnitBuff(unit, i)) then break; end IsMountedTooltip:SetUnitBuff(unit, i); if (IsMountedTooltipTextLeft2:IsShown()) then text = IsMountedTooltipTextLeft2:GetText(); if (text) then --Sea.io.print("Checking text: ".. text); -- debug msg _, _, speed = string.find(text, ISMOUNTED_SPEED_INCREASED_BY); if (speed) then return tonumber(speed), i; end end end end return false; end -------------------------------------------------- -- User Functions -------------------------------------------------- -- -- UnitIsMounted( string unit ) -- -- EX: if (UnitIsMounted("player")) then doSomething(); end -- -- Returns: -- (Boolean isMounted) -- isMounted - 1 if mounted, else nil -- function UnitIsMounted(unit) if (IsMounted.GetMountBuffInfo(unit)) then return 1; end end -- -- Dismount() -- -- EX: if (Dismount()) then print("I'm Dismounting"); end -- Macro EX: /dismount -- -- Returns: -- (Boolean wasMounted) -- wasMounted - 1 if was mounted, else nil -- function Dismount() local speed, id = IsMounted.GetMountBuffInfo("player"); if (speed) then CancelPlayerBuff(id); return 1; end end SlashCmdList["DISMOUNT"] = Dismount; SLASH_DISMOUNT1 = "/dismount"; --[[ SlashCmdList["LAG"] = function(msg) local n, _, t, spell = strfind(msg, "(%d-[%.%d]%d-) (.*)", 1); if (not n) then n, _, t = strfind(msg, "(%d-[%.%d]%d-)", 1); end local endTime = GetTime() + t; while (GetTime() < endTime) do end if (spell) then CastSpellByName(spell); end end SLASH_LAG1 = "/lag"; ]]-- -- -- UnitMountSpeed( string unit ) -- -- EX: local speed = UnitMountSpeed("target") -- -- Returns: -- (Number speed) -- speed - percent speed increase of the mount (60 or 100) if unit is mounted, -- false if mount is not found -- function UnitMountSpeed(unit) local speed, id = IsMounted.GetMountBuffInfo(unit); return speed; end -- -- UnitMountBuffID( string unit ) -- -- EX: local id = UnitMountBuffID("target") -- -- Returns: -- (Number id) -- id - the buff id id of the mount, nil if mount is not found or unit doesn't exist -- function UnitMountBuffID(unit) local speed, id = IsMounted.GetMountBuffInfo(unit); return id; end -- -- IsMounted.GetMountBuffInfo( string unit ) -- -- EX: local speed, id = IsMounted.GetMountBuffInfo("player") -- -- Returns: -- (Number speed, Number id) -- speed - percent speed increase of the mount (60 or 100) if unit is mounted, -- false if mount is not found -- id - the buff id id of the mount, nil if mount is not found or unit doesn't exist -- IsMounted.GetMountBuffInfo = function(unit) if (IsMounted.UnitTable[unit]) and (IsMounted.UnitTable[unit].speed ~= nil) then return IsMounted.UnitTable[unit].speed, IsMounted.UnitTable[unit].id; end return GetUpdatedUnitTable(unit); end -- -- IsMounted.GetUpdatedMountBuffInfo( string unit ) -- -- Gets Updated Mount Buff Info (duh!) -- -- Returns: -- (Number speed, Number id) -- speed - percent speed increase of the mount (60 or 100) if unit is mounted, -- false if mount is not found (so that we know it's been checked since last changed) -- id - the buff id id of the mount, nil if mount is not found or unit doesn't exist -- IsMounted.GetUpdatedMountBuffInfo = function(unit) if (UnitIsPlayer(unit)) then if ( (not IsMounted.UnitTable[unit]) or (unit == "target") ) and (UnitIsFriend("player", unit)) then -- This unit check will always check 46 stored tables for saved speed, but it should hopefully still be faster than setting and checking the tooltips of the unit's active buffs. for u, i in IsMounted.UnitTable do if (i.speed ~= nil) and (UnitIsUnit(unit, u)) then --Sea.io.print(unit, " is ", u); -- debug msg if (unit == "target") then --only store the info for the unit if it is predictibly consistant IsMounted.UnitTable.target.speed = i.speed; IsMounted.UnitTable.target.id = i.id; end return i.speed, i.id; end end end if (unit == "player") then return GetPlayerMountBuffInfo(); else return GetNonPlayerMountBuffInfo(unit); end end return false; end