From 7e8f2fbb4cde3a06a761c491fb5f75319c1c9a50 Mon Sep 17 00:00:00 2001 From: shagu Date: Sun, 31 Dec 2017 17:36:39 +0100 Subject: [PATCH] rangecheck: rewrite of the 40y range check * remove the bad notice in GUI * set default interval to "2" * prevent all frames of being updated at once * refresh one unit after the other * use textures insted of spellnames * change interval settings to dropdown * remove no longer required locales --- api/api.lua | 31 ++------- api/config.lua | 11 ++- env/locales_deDE.lua | 7 -- env/locales_enUS.lua | 7 -- env/locales_esES.lua | 7 -- env/locales_frFR.lua | 7 -- env/locales_koKR.lua | 7 -- env/locales_ruRU.lua | 7 -- env/locales_zhCN.lua | 7 -- modules/gui.lua | 12 +++- modules/rangecheck.lua | 149 ++++++++++++++++++++++++++++++++++++----- pfUI.toc | 2 +- 12 files changed, 157 insertions(+), 97 deletions(-) diff --git a/api/api.lua b/api/api.lua index 26e17a58..4945152b 100644 --- a/api/api.lua +++ b/api/api.lua @@ -17,7 +17,8 @@ function pfUI.api.strsplit(delimiter, subject) end -- [ UnitInRange ] --- Returns whether a party/raid member is nearby. It uses spells with a distance of around 40 yards. +-- Returns whether a party/raid member is nearby. +-- It takes care of the rangecheck module if existing. -- unit [string] A unit to query (string, unitID) -- return: [bool] "1" if in range otherwise "nil" local RangeCache = {} @@ -28,32 +29,10 @@ function pfUI.api.UnitInRange(unit) if CheckInteractDistance(unit, 4) then return 1 - else if not pfUI.rangecheck or not pfUI.rangecheck.slot then - return nil + else if pfUI.rangecheck then + return pfUI.rangecheck:UnitInSpellRange(unit) else - -- Extended Range Check - if not RangeCache[unit] or RangeCache[unit].time + pfUI.rangecheck.interval < GetTime() then - RangeCache[unit] = {} - RangeCache[unit].time = GetTime() - - if not UnitIsUnit("target", unit) then - pfScanActive = true - TargetUnit(unit) - end - - if IsActionInRange(pfUI.rangecheck.slot) == 1 then - RangeCache[unit].range = 1 - else - RangeCache[unit].range = nil - end - - if pfScanActive then - TargetLastTarget() - pfScanActive = false - end - end - - return RangeCache[unit].range + return nil end end end diff --git a/api/config.lua b/api/config.lua index bcd3d67f..16bd6538 100644 --- a/api/config.lua +++ b/api/config.lua @@ -87,8 +87,8 @@ function pfUI:LoadConfig() pfUI:UpdateConfig("unitframes", nil, "always2dportrait", "0") pfUI:UpdateConfig("unitframes", nil, "portraittexture", "1") pfUI:UpdateConfig("unitframes", nil, "layout", "default") - pfUI:UpdateConfig("unitframes", nil, "rangecheck", "0") - pfUI:UpdateConfig("unitframes", nil, "rangechecki", "1") + pfUI:UpdateConfig("unitframes", nil, "rangecheck", "1") + pfUI:UpdateConfig("unitframes", nil, "rangechecki", "2") pfUI:UpdateConfig("unitframes", nil, "combosize", "6") pfUI:UpdateConfig("unitframes", nil, "abbrevnum", "1") @@ -723,5 +723,12 @@ function pfUI:MigrateConfig() end end + -- migrating rangecheck interval (> 3.2.2) + if checkversion(3, 2, 2) then + if tonumber(pfUI_config.unitframes.rangechecki) <= 1 then + pfUI_config.unitframes.rangechecki = "2" + end + end + pfUI_config.version = pfUI.version.string end diff --git a/env/locales_deDE.lua b/env/locales_deDE.lua index 8b21f4a3..dce6fd9b 100644 --- a/env/locales_deDE.lua +++ b/env/locales_deDE.lua @@ -26,13 +26,6 @@ pfUI_locale["deDE"]["itemtypes"] = { ["INVTYPE_PROJECTILE"] = "Projektil", } -pfUI_locale["deDE"]["rangecheck"] = { - ["PALADIN"] = "Heiliges Licht", - ["PRIEST"] = "Blitzheilung", - ["DRUID"] = "Heilende Berührung", - ["SHAMAN"] = "Welle der Heilung", -} - pfUI_locale["deDE"]["hunterpaging"] = { ["MELEE"] = "Zurechtstutzen", ["RANGED"] = "Arkaner Schuss", diff --git a/env/locales_enUS.lua b/env/locales_enUS.lua index 8b0c2d85..8ef63eec 100644 --- a/env/locales_enUS.lua +++ b/env/locales_enUS.lua @@ -26,13 +26,6 @@ pfUI_locale["enUS"]["itemtypes"] = { ["INVTYPE_PROJECTILE"] = "Projectile", } -pfUI_locale["enUS"]["rangecheck"] = { - ["PALADIN"] = "Holy Light", - ["PRIEST"] = "Flash Heal", - ["DRUID"] = "Healing Touch", - ["SHAMAN"] = "Healing Wave", -} - pfUI_locale["enUS"]["hunterpaging"] = { ["MELEE"] = "Wing Clip", ["RANGED"] = "Arcane Shot", diff --git a/env/locales_esES.lua b/env/locales_esES.lua index c37b7fe6..84b9dbc2 100644 --- a/env/locales_esES.lua +++ b/env/locales_esES.lua @@ -26,13 +26,6 @@ pfUI_locale["esES"]["itemtypes"] = { ["INVTYPE_PROJECTILE"] = "Proyectil", } -pfUI_locale["esES"]["rangecheck"] = { - ["PALADIN"] = "Luz Sagrada", - ["PRIEST"] = "Destello curativo", - ["DRUID"] = "Toque curativo", - ["SHAMAN"] = "Ola de curación", -} - pfUI_locale["esES"]["hunterpaging"] = { ["MELEE"] = "Cortar alas", ["RANGED"] = "Disparo Arcano", diff --git a/env/locales_frFR.lua b/env/locales_frFR.lua index e66affae..0366f689 100644 --- a/env/locales_frFR.lua +++ b/env/locales_frFR.lua @@ -26,13 +26,6 @@ pfUI_locale["frFR"]["itemtypes"] = { ["INVTYPE_PROJECTILE"] = "Projectile", } -pfUI_locale["frFR"]["rangecheck"] = { - ["PALADIN"] = "Lumière sacrée", - ["PRIEST"] = "Soins rapides", - ["DRUID"] = "Toucher guérisseur", - ["SHAMAN"] = "Vague de soins", -} - pfUI_locale["frFR"]["hunterpaging"] = { ["MELEE"] = "Coupure d'ailes", ["RANGED"] = "Tir des arcanes", diff --git a/env/locales_koKR.lua b/env/locales_koKR.lua index 6ffe6a96..d85a3ef0 100644 --- a/env/locales_koKR.lua +++ b/env/locales_koKR.lua @@ -26,13 +26,6 @@ pfUI_locale["koKR"]["itemtypes"] = { ["INVTYPE_PROJECTILE"] = "투사체", } -pfUI_locale["koKR"]["rangecheck"] = { - ["PALADIN"] = "성스러운 빛", - ["PRIEST"] = "순간 치유", - ["DRUID"] = "치유의 손길", - ["SHAMAN"] = "치유의 물결", -} - pfUI_locale["koKR"]["hunterpaging"] = { ["MELEE"] = "날개 절단", ["RANGED"] = "신비한 사격", diff --git a/env/locales_ruRU.lua b/env/locales_ruRU.lua index 2fe5ff53..1ffdb4b4 100644 --- a/env/locales_ruRU.lua +++ b/env/locales_ruRU.lua @@ -26,13 +26,6 @@ pfUI_locale["ruRU"]["itemtypes"] = { ["INVTYPE_PROJECTILE"] = "Боеприпасы", } -pfUI_locale["ruRU"]["rangecheck"] = { - ["PALADIN"] = "Свет небес", - ["PRIEST"] = "Быстрое исцеление", - ["DRUID"] = "Целительное прикосновение", - ["SHAMAN"] = "Волна исцеления", -} - pfUI_locale["ruRU"]["hunterpaging"] = { ["MELEE"] = "Подрезать крылья", ["RANGED"] = "Чародейский выстрел", diff --git a/env/locales_zhCN.lua b/env/locales_zhCN.lua index 9bf5a3c7..dda3d14e 100644 --- a/env/locales_zhCN.lua +++ b/env/locales_zhCN.lua @@ -26,13 +26,6 @@ pfUI_locale["zhCN"]["itemtypes"] = { ["INVTYPE_PROJECTILE"] = "弹药", } -pfUI_locale["zhCN"]["rangecheck"] = { - ["PALADIN"] = "圣光术", - ["PRIEST"] = "快速治疗", - ["DRUID"] = "治疗之触", - ["SHAMAN"] = "治疗波", -} - pfUI_locale["zhCN"]["hunterpaging"] = { ["MELEE"] = "摔绊", ["RANGED"] = "奥术射击", diff --git a/modules/gui.lua b/modules/gui.lua index a8412aa3..21fb0a68 100644 --- a/modules/gui.lua +++ b/modules/gui.lua @@ -406,6 +406,14 @@ pfUI:RegisterModule("gui", function () "13:" .. T["Very Slow"], } + pfUI.gui.dropdowns.uf_rangecheckinterval = { + "1:" .. T["Very Fast"], + "2:" .. T["Fast"], + "4:" .. T["Medium"], + "8:" .. T["Slow"], + "16:" .. T["Very Slow"], + } + pfUI.gui.dropdowns.uf_powerbar_position = { "TOPLEFT:" .. T["Left"], "TOP:" .. T["Center"], @@ -704,8 +712,8 @@ pfUI:RegisterModule("gui", function () CreateConfig(this, T["Always Use 2D Portraits"], C.unitframes, "always2dportrait", "checkbox") CreateConfig(this, T["Enable 2D Portraits As Fallback"], C.unitframes, "portraittexture", "checkbox") CreateConfig(this, T["Unit Frame Layout"], C.unitframes, "layout", "dropdown", pfUI.gui.dropdowns.uf_layout) - CreateConfig(this, T["Aggressive 40y-Range Check (Will break stuff)"], C.unitframes, "rangecheck", "checkbox") - CreateConfig(this, T["40y-Range Check Interval"], C.unitframes, "rangechecki") + CreateConfig(this, T["Enable 40y-Range Check"], C.unitframes, "rangecheck", "checkbox") + CreateConfig(this, T["Range Check Interval"], C.unitframes, "rangechecki", "dropdown", pfUI.gui.dropdowns.uf_rangecheckinterval) CreateConfig(this, T["Combopoint Size"], C.unitframes, "combosize") CreateConfig(this, T["Abbreviate Numbers (4200 -> 4.2k)"], C.unitframes, "abbrevnum", "checkbox") CreateConfig(this, T["Show PvP Icon"], C.unitframes.player, "showPVP", "checkbox") diff --git a/modules/rangecheck.lua b/modules/rangecheck.lua index 5fe994fe..27c7a225 100644 --- a/modules/rangecheck.lua +++ b/modules/rangecheck.lua @@ -1,31 +1,146 @@ pfUI:RegisterModule("rangecheck", function () - local _,class = UnitClass("player") if C.unitframes.rangecheck == "0" then return end + -- table of 40y spells per class + local spells = { + ["PALADIN"] = { + "Interface\\Icons\\Spell_Holy_FlashHeal", + "Interface\\Icons\\Spell_Holy_HolyBolt", + }, + ["PRIEST"] = { + "Interface\\Icons\\Spell_Holy_FlashHeal", + "Interface\\Icons\\Spell_Holy_LesserHeal", + "Interface\\Icons\\Spell_Holy_Heal", + "Interface\\Icons\\Spell_Holy_GreaterHeal", + "Interface\\Icons\\Spell_Holy_Renew", + }, + ["DRUID"] = { + "Interface\\Icons\\Spell_Nature_HealingTouch", + "Interface\\Icons\\Spell_Nature_ResistNature", + "Interface\\Icons\\Spell_Nature_Rejuvenation", + }, + ["SHAMAN"] = { + "Interface\\Icons\\Spell_Nature_MagicImmunity", + "Interface\\Icons\\Spell_Nature_HealingWaveLesser", + "Interface\\Icons\\Spell_Nature_HealingWaveGreater", + }, + } + + local _, class = UnitClass("player") + if not spells[class] then return end + + -- units that should be scanned + local units = {} + table.insert(units, "pet") + for i=1,4 do table.insert(units, "party" .. i) end + for i=1,4 do table.insert(units, "partypet" .. i) end + for i=1,40 do table.insert(units, "raid" .. i) end + for i=1,40 do table.insert(units, "raidpet" .. i) end + local numunits = table.getn(units) + + -- cache for unit relations + local unitcache = {} + + -- actual unit-range table + local unitdata = { } + + -- the interval between each range check + local interval = tonumber(C.unitframes.rangechecki)/numunits + pfUI.rangecheck = CreateFrame("Frame", "pfRangecheck", UIParent) - pfUI.rangecheck.scanner = CreateFrame("GameTooltip", "pfRangecheckScanner", UIParent, "GameTooltipTemplate") - pfUI.rangecheck.scanner:SetOwner(pfUI.rangecheck, "ANCHOR_NONE") - - pfUI.rangecheck.slot = nil - pfUI.rangecheck.interval = C.unitframes.rangechecki - + pfUI.rangecheck.id = 1 pfUI.rangecheck:RegisterEvent("ACTIONBAR_SLOT_CHANGED") pfUI.rangecheck:RegisterEvent("PLAYER_ENTERING_WORLD") pfUI.rangecheck:SetScript("OnEvent", function() - pfUI.rangecheck.slot = nil + pfUI.rangecheck.slot = this:GetRangeSlot() + end) + pfUI.rangecheck:SetScript("OnUpdate", function() + if ( this.tick or 1) > GetTime() then + return + else + this.tick = GetTime() + interval + end + + -- skip invalid units + while not this:NeedRangeScan(units[this.id]) and this.id <= numunits do + this.id = this.id + 1 + end + + if this.id <= numunits and pfUI.rangecheck.slot then + local unit = units[this.id] + if not UnitIsUnit("target", unit) then + -- don't break looting + if pfUI.loot and pfUI.loot:IsShown() then return nil end + if LootFrame and LootFrame:IsShown() then return nil end + + -- don't break auto-attacks + if PlayerFrame.inCombat and UnitCanAttack("player", "target") then + return nil + end + + pfScanActive = true + TargetUnit(unit) + unitdata[unit] = IsActionInRange(pfUI.rangecheck.slot) + TargetLastTarget() + pfScanActive = false + else + unitdata[unit] = IsActionInRange(pfUI.rangecheck.slot) + end + + this.id = this.id + 1 + else + this.id = 1 + end + end) + + function pfUI.rangecheck:NeedRangeScan(unit) + if not UnitExists(unit) then return nil end + if not UnitIsVisible(unit) then return nil end + if CheckInteractDistance(unit, 4) then return nil end + return true + end + + function pfUI.rangecheck:GetRealUnit(unit) + if unitdata[unit] then return unit end + + if unitcache[unit] then + if UnitIsUnit(unitcache[unit], unit) then + return unitcache[unit] + end + end + + for id, realunit in pairs(units) do + if UnitIsUnit(realunit, unit) then + unitcache[unit] = realunit + return realunit + end + end + + return unit + end + + function pfUI.rangecheck:GetRangeSlot() for i=1,120 do - if pfUI.rangecheck.slot then return end - - pfUI.rangecheck.scanner:ClearLines() - pfUI.rangecheck.scanner:SetAction(i) - - if pfRangecheckScannerTextLeft1 and pfRangecheckScannerTextLeft1:GetText() then - if pfRangecheckScannerTextLeft1:GetText() == L["rangecheck"][class] then - pfUI.rangecheck.slot = i + local texture = GetActionTexture(i) + for _, check in pairs(spells[class]) do + if check == texture then + return i end end end - end) + + return nil + end + + function pfUI.rangecheck:UnitInSpellRange(unit) + local unit = pfUI.rangecheck:GetRealUnit(unit) + + if unitdata[unit] and unitdata[unit] == 1 then + return 1 + else + return nil + end + end end) diff --git a/pfUI.toc b/pfUI.toc index 3b8674a6..99430e46 100644 --- a/pfUI.toc +++ b/pfUI.toc @@ -2,7 +2,7 @@ ## Title: |cff33ffccpf|cffffffffUI ## Author: Shagu ## Notes: A complete user interface replacement. -## Version: 3.2.2 +## Version: 3.3.0 ## SavedVariables: pfUI_profiles, pfUI_gold ## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB