libtipscan: add new tooltip scanning library

This commit is contained in:
Road-block
2018-07-18 14:23:03 +03:00
committed by shagu
parent 1cebe52e29
commit 44ffb10024
14 changed files with 260 additions and 110 deletions
View File
View File
+2 -4
View File
@@ -289,13 +289,11 @@ hooksecurefunc("CastSpellByName", function(spellName, target)
end
end, true)
local scanner = CreateFrame("GameTooltip", "pfSpellScanner", nil, "GameTooltipTemplate")
scanner:SetOwner(WorldFrame, "ANCHOR_NONE")
local scanner = libtipscan:GetScanner("libcast")
hooksecurefunc("UseAction", function(slot, target, button)
if GetActionText(slot) or not IsCurrentAction(slot) then return end
scanner:ClearLines()
scanner:SetAction(slot)
local spellName = pfSpellScannerTextLeft1:GetText()
local spellName = scanner:Line(1)
CastCustom(spellName)
end, true)
+7 -13
View File
@@ -12,12 +12,12 @@ setfenv(1, pfUI:GetEnvironment())
-- start, duration, timeleft
local libdebuff = CreateFrame("Frame", "pfdebuffsScanner", UIParent)
local scanner = libtipscan:GetScanner("libdebuff")
function libdebuff:GetDebuffName(unit, index)
libdebuff.scanner:SetOwner(UIParent, "ANCHOR_NONE")
libdebuff.scanner:SetUnitDebuff(unit, index)
local text = getglobal("pfDebuffNameScanTextLeft1")
return ( text ) and text:GetText() or ""
scanner:SetUnitDebuff(unit, index)
local text = scanner:Line(1)
return ( text ) and text or ""
end
function libdebuff:GetDebuffInfo(unit, effect)
@@ -140,8 +140,6 @@ function libdebuff:AddEffect(unit, unitlevel, effect, duration)
end
end
libdebuff.scanner = CreateFrame('GameTooltip', "pfDebuffNameScan", UIParent, "GameTooltipTemplate")
-- scan for debuff application
libdebuff:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE")
libdebuff:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE")
@@ -217,25 +215,21 @@ end)
-- Gather Data by User Actions
hooksecurefunc("CastSpell", function(id, bookType)
local effect = GetSpellName(id, bookType)
local _, rank = GetSpellInfo(id, bookType)
local _, rank = libspell.GetSpellInfo(id, bookType)
local duration = libdebuff:GetDuration(effect, rank)
libdebuff:AddPending(UnitName("target"), UnitLevel("target"), effect, duration)
end, true)
hooksecurefunc("CastSpellByName", function(effect, target)
local _, rank = GetSpellInfo(effect)
local _, rank = libspell.GetSpellInfo(effect)
local duration = libdebuff:GetDuration(effect, rank)
libdebuff:AddPending(UnitName("target"), UnitLevel("target"), effect, duration)
end, true)
local scanner = CreateFrame("GameTooltip", "pfDebuffSpellScanner", nil, "GameTooltipTemplate")
scanner:SetOwner(WorldFrame, "ANCHOR_NONE")
hooksecurefunc("UseAction", function(slot, target, button)
if GetActionText(slot) or not IsCurrentAction(slot) then return end
scanner:ClearLines()
scanner:SetAction(slot)
local effect = pfDebuffSpellScannerTextLeft1:IsVisible() and pfDebuffSpellScannerTextLeft1:GetText()
local rank = pfDebuffSpellScannerTextRight1:IsVisible() and pfDebuffSpellScannerTextRight1:GetText()
local effect, rank = scanner:Line(1)
local duration = libdebuff:GetDuration(effect, rank)
libdebuff:AddPending(UnitName("target"), UnitLevel("target"), effect, duration)
end, true)
+25 -32
View File
@@ -1,8 +1,8 @@
-- load pfUI environment
setfenv(1, pfUI:GetEnvironment())
local pfSpellScan = CreateFrame("GameTooltip", "pfSpellScan", UIParent, "GameTooltipTemplate")
pfSpellScan:SetOwner(WorldFrame, "ANCHOR_NONE")
local scanner = libtipscan:GetScanner("libspell")
local libspell = {}
-- [ GetSpellMaxRank ]
-- Returns the maximum rank of a players spell.
@@ -10,7 +10,7 @@ pfSpellScan:SetOwner(WorldFrame, "ANCHOR_NONE")
-- return: [string],[number] maximum rank in characters and the number
-- e.g "Rank 1" and "1"
local spellmaxrank = {}
function pfUI.api.GetSpellMaxRank(name)
function libspell.GetSpellMaxRank(name)
if spellmaxrank[name] then return unpack(spellmaxrank[name]) end
local rank = { 0, nil}
@@ -40,9 +40,9 @@ end
-- 'rank' [string] rank to query (optional)
-- return: [number],[string] spell index and spellbook id
local spellindex = {}
function pfUI.api.GetSpellIndex(name, rank)
function libspell.GetSpellIndex(name, rank)
if spellindex[name..(rank or "")] then return unpack(spellindex[name..(rank or "")]) end
if not rank then rank = GetSpellMaxRank(name) end
if not rank then rank = libspell.GetSpellMaxRank(name) end
for i = 1, GetNumSpellTabs() do
local _, _, offset, num = GetSpellTabInfo(i)
@@ -75,7 +75,7 @@ end
-- [number] Minimum range from the target required to cast the spell
-- [number] Maximum range from the target at which you can cast the spell
local spellinfo = {}
function pfUI.api.GetSpellInfo(index, bookType)
function libspell.GetSpellInfo(index, bookType)
if spellinfo[index] then return unpack(spellinfo[index]) end
local name, rank, id
@@ -87,11 +87,11 @@ function pfUI.api.GetSpellInfo(index, bookType)
if type(index) == "string" then
local _, _, sname, srank = string.find(index, '(.+)%((.+)%)')
name = sname or index
rank = srank or GetSpellMaxRank(name)
id, bookType = GetSpellIndex(name, rank)
rank = srank or libspell.GetSpellMaxRank(name)
id, bookType = libspell.GetSpellIndex(name, rank)
else
name, rank = GetSpellName(index, bookType)
id, bookType = GetSpellIndex(name, rank)
id, bookType = libspell.GetSpellIndex(name, rank)
end
if name and id then
@@ -99,29 +99,19 @@ function pfUI.api.GetSpellInfo(index, bookType)
end
if id then
pfSpellScan:ClearLines()
pfSpellScan:SetSpell(id, bookType)
for i=1, 4 do
for _, text in pairs({_G["pfSpellScanTextLeft"..i], _G["pfSpellScanTextRight"..i]}) do
if text and text:IsVisible() and text:GetText() then
local _, _, sec = string.find(text:GetText(), gsub(SPELL_CAST_TIME_SEC, "%%.3g", "%(.+%)"))
local _, _, min = string.find(text:GetText(), gsub(SPELL_CAST_TIME_MIN, "%%.3g", "%(.+%)"))
local _, _, range = string.find(text:GetText(), gsub(SPELL_RANGE, "%%s", "%(.+%)"))
castingTime = (tonumber(sec) or tonumber(min) or 0) * 1000
if range then
local _, _, min, max = string.find(range, "(.+)-(.+)")
if min and max then
minRange = tonumber(min)
maxRange = tonumber(max)
else
minRange = 0
maxRange = tonumber(range)
end
end
end
scanner:SetSpell(id, bookType)
local _,sec = scanner:Find(gsub(SPELL_CAST_TIME_SEC, "%%.3g", "%(.+%)"))
local _,min = scanner:Find(gsub(SPELL_CAST_TIME_MIN, "%%.3g", "%(.+%)"))
local _,range = scanner:Find(gsub(SPELL_RANGE, "%%s", "%(.+%)"))
castingTime = (tonumber(sec) or tonumber(min) or 0) * 1000
if range then
local _, _, min, max = string.find(range, "(.+)-(.+)")
if min and max then
minRange = tonumber(min)
maxRange = tonumber(max)
else
minRange = 0
maxRange = tonumber(range)
end
end
end
@@ -129,3 +119,6 @@ function pfUI.api.GetSpellInfo(index, bookType)
spellinfo[index] = { name, rank, icon, castingTime, minRange, maxRange }
return name, rank, icon, castingTime, minRange, maxRange
end
-- add libspell to pfUI API
pfUI.api.libspell = libspell
+194
View File
@@ -0,0 +1,194 @@
-- load pfUI environment
setfenv(1, pfUI:GetEnvironment())
--[[ libtipscan ]]--
-- A pfUI library that provides tooltip scanner.
--
-- libtipscan:GetScanner(name)
-- returns or resets a scanner for use with tooltip methods
--
-- libtipscan:List()
-- prints a list of all active scanners
--
-- The scanner tooltip returned by :GetScanner has all the Set____ GameTooltip methods with a built-in full clear
-- In addition the scanner has the following custom methods
-- <scanner>:Clear()
-- empties the scanner tooltip
-- <scanner>:Text()
-- return a table with all the left, right texts in {[line] = {left, right}} format
-- <scanner>:Find(text, [exact])
-- returns true (linenumber) and [the text found or the captures made if text is a pattern]
-- exact is optional flag making it look only for exact matches
-- <scanner>:Color(r,g,b)
-- returns true (linenumber) if the r,g,b color tuple is found as text color on the scanner
-- accepts color table as argument as well (eg. <scanner>:Color(RED_FONT_COLOR) )
-- <scanner>:Line(line_number)
-- returns left, right text from that tooltip line
-- <scanner>:List()
-- prints a list of all available scanner methods
local libtipscan = {}
local baseName = "pfUIScan"
local methods = {
"SetBagItem", "SetAction", "SetAuctionItem", "SetAuctionSellItem", "SetBuybackItem",
"SetCraftItem", "SetCraftSpell", "SetHyperlink", "SetInboxItem", "SetInventoryItem",
"SetLootItem", "SetLootRollItem", "SetMerchantItem", "SetPetAction", "SetPlayerBuff",
"SetQuestItem", "SetQuestLogItem", "SetQuestRewardSpell", "SetSendMailItem", "SetShapeshift",
"SetSpell", "SetTalent", "SetTrackingSpell", "SetTradePlayerItem", "SetTradeSkillItem", "SetTradeTargetItem",
"SetTrainerService", "SetUnit", "SetUnitBuff", "SetUnitDebuff",
}
local extra_methods = {
"Clear", "Find", "Line", "Text", "List",
}
local clearText = function(...)
for i=1,arg.n do
local region = arg[i]
if region:IsObjectType("FontString") and region.SetText then
region:SetTextColor(0,0,0)
region:SetText()
end
end
end
local clearTooltip = function(obj)
clearText(obj:GetRegions())
obj:ClearLines()
return obj
end
local getText = function(obj)
local name = obj:GetName()
local text = {}
for i=1, obj:NumLines() do
local left, right = _G[string.format("%sTextLeft%d",name,i)]:GetText(), _G[string.format("%sTextRight%d",name,i)]:GetText()
left = left and left ~= "" and left or nil
right = right and right ~= "" and right or nil
if left or right then
text[i] = {left, right}
end
end
return text
end
local stripPos = function(...)
if arg[1] then
table.remove(arg,1)
table.remove(arg,1)
end
return unpack(arg)
end
local findText = function(obj, text, exact)
local name = obj:GetName()
for i=1, obj:NumLines() do
local left, right = _G[string.format("%sTextLeft%d",name,i)]:GetText(), _G[string.format("%sTextRight%d",name,i)]:GetText()
if exact then
if (left and left == text) or (right and right == text) then
return i, text
end
else
if left and (string.find(left, text)) then
return i, stripPos(string.find(left,text))
end
if right and (string.find(right, text)) then
return i, stripPos(string.find(right,text))
end
end
end
end
local lineText = function(obj, line)
local name = obj:GetName()
if line <= obj:NumLines() then
local left, right = _G[string.format("%sTextLeft%d",name,line)]:GetText(), _G[string.format("%sTextRight%d",name,line)]:GetText()
if left or right then
return left, right
end
end
end
local findColor = function(obj, r,g,b)
local name = obj:GetName()
if type(r) == "table" then
r,g,b = r.r or r[1], r.g or r[2], r.b or r[3]
end
for i=1, obj:NumLines() do
local tr, tg, tb
local left, right = _G[string.format("%sTextLeft%d",name,i)], _G[string.format("%sTextRight%d",name,i)]
if left then
tr, tg, tb = left:GetTextColor()
tr, tg, tb = round(tr,1), round(tg,1), round(tb,1)
end
if tr and (tr == r and tg == g and tb == b) then
return i
end
if right then
tr, tg, tb = right:GetTextColor()
tr, tg, tb = round(tr,1), round(tg,1), round(tb,1)
end
if tr and (tr == r and tg == g and tb == b) then
return i
end
end
end
libtipscan._registry = setmetatable({},{__index = function(t,k)
local v = CreateFrame("GameTooltip", string.format("%s%s",baseName,k), nil, "GameTooltipTemplate")
v:SetOwner(v,"ANCHOR_NONE")
v:SetScript("OnHide", function ()
this:SetOwner(this,"ANCHOR_NONE")
end)
function v:Clear()
clearTooltip(self)
end
function v:Text()
return getText(self)
end
function v:Find(text, exact)
return findText(self, text, exact)
end
function v:Color(r,g,b)
return findColor(self,r,g,b)
end
function v:Line(line)
return lineText(self, line)
end
for _,method in ipairs(methods) do
local method = method
local old = v[method]
v[method] = function(v, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
if v:IsShown() then
v:Hide()
end
v:Clear()
return old(v, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
end
end
function v:List()
table.sort(methods)
for _,method in ipairs(methods) do
print(method)
end
for _,method in ipairs(extra_methods) do
print(method)
end
end
rawset(t,k,v)
return v
end})
function libtipscan:GetScanner(type)
local scanner = self._registry[type]
scanner:Clear()
return scanner
end
function libtipscan:List()
for name, scanner in pairs(self._registry) do
print(name)
end
end
-- add libtipscan to pfUI API
pfUI.api.libtipscan = libtipscan
+8 -16
View File
@@ -72,8 +72,7 @@ pfUI:RegisterModule("actionbar", function ()
-- reagent counter
local reagentslots = { }
local reagentscan = CreateFrame("GameTooltip", "pfReagentScanner", UIParent, "GameTooltipTemplate")
reagentscan:SetOwner(UIParent, "ANCHOR_NONE")
local scanner = libtipscan:GetScanner("actionbar")
hooksecurefunc("ActionButton_OnEvent", function()
if event == "BAG_UPDATE" and arg1 < 5 then
@@ -81,25 +80,18 @@ pfUI:RegisterModule("actionbar", function ()
end
end)
local reagent_capture = SPELL_REAGENTS.."(.+)"
local oldIsConsumableAction = IsConsumableAction
_G.IsConsumableAction = function(slot)
if oldIsConsumableAction(slot) then return true end
if this and this.GetParent and ActionButton_GetPagedID(this) == slot then
reagentslots[slot] = nil
reagentscan:SetAction(slot)
if (reagentscan:NumLines() ~=0) then
for i=1,reagentscan:NumLines() do
local line = getglobal("pfReagentScannerTextLeft" .. i)
if line then
line = line:GetText()
local _, start = strfind(line,SPELL_REAGENTS,1)
if start then
reagentslots[slot] = strsub(line,start+1)
this:RegisterEvent("BAG_UPDATE")
return true
end
end
end
scanner:SetAction(slot)
local _, reagents = scanner:Find(reagent_capture)
if reagents then
reagentslots[slot] = reagents
this:RegisterEvent("BAG_UPDATE")
return true
end
this:UnregisterEvent("BAG_UPDATE")
+4 -5
View File
@@ -1,18 +1,17 @@
pfUI:RegisterModule("feigndeath", function ()
local cache = { }
local healthscan = CreateFrame("GameTooltip", "pfHpScanner", UIParent, "GameTooltipTemplate")
healthscan:SetOwner(healthscan,"ANCHOR_NONE")
local healthbar = healthscan:GetChildren()
local scanner = libtipscan:GetScanner("feigndeath")
local healthbar = scanner:GetChildren()
local cache_update = CreateFrame("Frame")
cache_update:RegisterEvent("UNIT_HEALTH")
cache_update:RegisterEvent("PLAYER_TARGET_CHANGED")
cache_update:SetScript("OnEvent", function()
if event == "PLAYER_TARGET_CHANGED" and UnitIsDead("target") then
healthscan:SetUnit("target")
scanner:SetUnit("target")
cache[UnitName("target")] = healthbar:GetValue()
elseif event == "UNIT_HEALTH" and UnitIsDead(arg1) and UnitName(arg1) then
healthscan:SetUnit(arg1)
scanner:SetUnit(arg1)
cache[UnitName(arg1)] = healthbar:GetValue()
elseif event == "UNIT_HEALTH" and UnitName(arg1) then
cache[UnitName(arg1)] = nil
+6 -7
View File
@@ -3,8 +3,7 @@ pfUI:RegisterModule("hunterbar", function ()
if class ~= "HUNTER" or C.bars.hunterbar == "0" then return end
pfUI.hunterbar = CreateFrame("Frame", "pfHunterBar", UIParent)
pfUI.hunterbar.scanner = CreateFrame("GameTooltip", "pfHunterBarScanner", UIParent, "GameTooltipTemplate")
pfUI.hunterbar.scanner:SetOwner(pfUI.hunterbar, "ANCHOR_NONE")
local scanner = libtipscan:GetScanner("hunterbar")
pfUI.hunterbar.melee = nil
pfUI.hunterbar.ranged = nil
@@ -19,13 +18,13 @@ pfUI:RegisterModule("hunterbar", function ()
for i=1,120 do
if pfUI.hunterbar.melee and pfUI.hunterbar.ranged then return end
pfUI.hunterbar.scanner:ClearLines()
pfUI.hunterbar.scanner:SetAction(i)
scanner:SetAction(i)
if pfHunterBarScannerTextLeft1 and pfHunterBarScannerTextLeft1:GetText() then
if pfHunterBarScannerTextLeft1:GetText() == L["hunterpaging"]["MELEE"] then
local left = scanner:Line(1)
if left then
if left == L["hunterpaging"]["MELEE"] then
pfUI.hunterbar.melee = i
elseif pfHunterBarScannerTextLeft1:GetText() == L["hunterpaging"]["RANGED"] then
elseif left == L["hunterpaging"]["RANGED"] then
pfUI.hunterbar.ranged = i
end
end
-9
View File
@@ -586,15 +586,6 @@ pfUI:RegisterModule("nameplates", function ()
end
end
-- debuff detection
local pfNameplateDebuffNameScan = CreateFrame('GameTooltip', "pfNameplateDebuffNameScan", UIParent, "GameTooltipTemplate")
local function GetDebuffName(unit, index)
pfNameplateDebuffNameScan:SetOwner(UIParent, "ANCHOR_NONE")
pfNameplateDebuffNameScan:SetUnitDebuff(unit, index)
local text = getglobal("pfNameplateDebuffNameScanTextLeft1")
return ( text ) and text:GetText() or ""
end
pfUI.nameplates:RegisterEvent("PLAYER_TARGET_CHANGED")
pfUI.nameplates:RegisterEvent("UNIT_AURA")
pfUI.nameplates:SetScript("OnEvent", function()
+12 -23
View File
@@ -318,7 +318,8 @@ pfUI:RegisterModule("panel", function()
widget.slotnames = { "Head", "Shoulder", "Chest", "Wrist",
"Hands", "Waist", "Legs", "Feet", "MainHand", "SecondaryHand", "Ranged", }
widget.totalRep = 0
widget.scantip = CreateFrame('GameTooltip', "pfRepairToolTip", this, "GameTooltipTemplate")
widget.scantip = libtipscan:GetScanner("panel")
widget.duracapture = string.gsub(DURABILITY_TEMPLATE, "%%[^%s]+", "(.+)")
widget.Click = function() ToggleCharacter("PaperDollFrame") end
widget.Tooltip = function()
if widget.totalRep > 0 then
@@ -339,28 +340,17 @@ pfUI:RegisterModule("panel", function()
wipe(widget.itemLines)
for i,slotName in pairs(widget.slotnames) do
local id, _ = GetInventorySlotInfo(slotName.. "Slot")
pfRepairToolTip:Hide()
pfRepairToolTip:SetOwner(this, "ANCHOR_LEFT")
local hasItem, _, repCost = pfRepairToolTip:SetInventoryItem("player", id)
if (not hasItem) then
pfRepairToolTip:ClearLines()
else
local hasItem, _, repCost = widget.scantip:SetInventoryItem("player", id)
if (hasItem) then
widget.totalRep = widget.totalRep + repCost
for i=1, 32, 1 do
local tmpText = _G["pfRepairToolTipTextLeft"..i]
if (tmpText ~= nil) and (tmpText:GetText()) then
local searchstr = string.gsub(DURABILITY_TEMPLATE, "%%[^%s]+", "(.+)")
local _, _, lval, rval = string.find(tmpText:GetText(), searchstr, 1)
if (lval and rval) then
repPercent = math.floor(lval / rval * 100)
if repPercent < 100 then
local link = GetInventoryItemLink("player",id)
local r,g,b,hex = GetColorGradient(repPercent/100, 1,0,0, 1,1,0, 0,1,0) -- red to green through yellow
local cPercent = string.format("%s%s%%|r",hex,repPercent)
widget.itemLines[table.getn(widget.itemLines)+1]={link, cPercent}
end
break
end
local line, lval, rval = widget.scantip:Find(widget.duracapture)
if (lval and rval) then
repPercent = math.floor(lval / rval * 100)
if repPercent < 100 then
local link = GetInventoryItemLink("player",id)
local r,g,b,hex = GetColorGradient(repPercent/100, 1,0,0, 1,1,0, 0,1,0) -- red to green through yellow
local cPercent = string.format("%s%s%%|r",hex,repPercent)
widget.itemLines[table.getn(widget.itemLines)+1]={link, cPercent}
end
end
end
@@ -368,7 +358,6 @@ pfUI:RegisterModule("panel", function()
lowestPercent = repPercent
end
end
pfRepairToolTip:Hide()
pfUI.panel:OutputPanel("durability", lowestPercent .. "% " .. ARMOR, widget.Tooltip, widget.Click)
end)
+2 -1
View File
@@ -34,12 +34,13 @@ env\profiles.lua
# api
api\api.lua
api\spell.lua
api\config.lua
api\ui-widgets.lua
api\unitframes.lua
# libs
libs\libtipscan.lua
libs\libspell.lua
libs\libcast.lua
libs\libdebuff.lua
libs\librange.lua