From 76f2e259c78c273edd1c633eb96d2eadd922bd9d Mon Sep 17 00:00:00 2001 From: Benjamin Staneck Date: Tue, 11 Jul 2023 19:15:20 +0200 Subject: [PATCH] Apply formatting --- LibRangeCheck-3.0/LibRangeCheck-3.0.lua | 2023 ++++++++++++----------- 1 file changed, 1029 insertions(+), 994 deletions(-) diff --git a/LibRangeCheck-3.0/LibRangeCheck-3.0.lua b/LibRangeCheck-3.0/LibRangeCheck-3.0.lua index 71c245d..d6301f9 100644 --- a/LibRangeCheck-3.0/LibRangeCheck-3.0.lua +++ b/LibRangeCheck-3.0/LibRangeCheck-3.0.lua @@ -43,12 +43,13 @@ local MAJOR_VERSION = "LibRangeCheck-3.0" local MINOR_VERSION = 1 local lib, oldminor = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION) -if not lib then return end +if not lib then + return +end local isRetail = WOW_PROJECT_ID == WOW_PROJECT_MAINLINE local isWrath = WOW_PROJECT_ID == WOW_PROJECT_WRATH_CLASSIC --- GLOBALS: LibStub, CreateFrame, C_Map, FriendColor (??), HarmColor (??) local _G = _G local next = next local sort = sort @@ -86,37 +87,37 @@ local UnitIsVisible = UnitIsVisible -- << STATIC CONFIG -local UpdateDelay = .5 +local UpdateDelay = 0.5 local ItemRequestTimeout = 10.0 -- interact distance based checks. ranges are based on my own measurements (thanks for all the folks who helped me with this) local DefaultInteractList = { --- [1] = 28, -- Compare Achievements --- [2] = 9, -- Trade - [3] = 8, -- Duel - [4] = 28, -- Follow --- [5] = 7, -- unknown + -- [1] = 28, -- Compare Achievements + -- [2] = 9, -- Trade + [3] = 8, -- Duel + [4] = 28, -- Follow + -- [5] = 7, -- unknown } -- interact list overrides for races local InteractLists = { - Tauren = { + Tauren = { -- [2] = 7, - [3] = 6, - [4] = 25, - }, - Scourge = { + [3] = 6, + [4] = 25, + }, + Scourge = { -- [2] = 8, - [3] = 7, - [4] = 27, - }, + [3] = 7, + [4] = 27, + }, } local MeleeRange = 2 local FriendSpells, HarmSpells, ResSpells, PetSpells = {}, {}, {}, {} -for _, n in ipairs({ 'EVOKER', 'DEATHKNIGHT', 'DEMONHUNTER', 'DRUID', 'HUNTER', 'SHAMAN', 'MAGE', 'PALADIN', 'PRIEST', 'WARLOCK', 'WARRIOR', 'MONK', 'ROGUE' }) do - FriendSpells[n], HarmSpells[n], ResSpells[n], PetSpells[n] = {}, {}, {}, {} +for _, n in ipairs({ "EVOKER", "DEATHKNIGHT", "DEMONHUNTER", "DRUID", "HUNTER", "SHAMAN", "MAGE", "PALADIN", "PRIEST", "WARLOCK", "WARRIOR", "MONK", "ROGUE" }) do + FriendSpells[n], HarmSpells[n], ResSpells[n], PetSpells[n] = {}, {}, {}, {} end -- Evoker @@ -128,10 +129,10 @@ tinsert(FriendSpells.EVOKER, 360823) -- Naturalize (Preservation) (30 yards) tinsert(ResSpells.EVOKER, 361227) -- Return (40 yards) -- Death Knights -tinsert(HarmSpells.DEATHKNIGHT, 49576) -- Death Grip (30 yards) -tinsert(HarmSpells.DEATHKNIGHT, 47541) -- Death Coil (Unholy) (40 yards) +tinsert(HarmSpells.DEATHKNIGHT, 49576) -- Death Grip (30 yards) +tinsert(HarmSpells.DEATHKNIGHT, 47541) -- Death Coil (Unholy) (40 yards) -tinsert(ResSpells.DEATHKNIGHT, 61999) -- Raise Ally (40 yards) +tinsert(ResSpells.DEATHKNIGHT, 61999) -- Raise Ally (40 yards) -- Demon Hunters tinsert(HarmSpells.DEMONHUNTER, 185123) -- Throw Glaive (Havoc) (30 yards) @@ -139,375 +140,374 @@ tinsert(HarmSpells.DEMONHUNTER, 183752) -- Consume Magic (20 yards) tinsert(HarmSpells.DEMONHUNTER, 204021) -- Fiery Brand (Vengeance) (30 yards) -- Druids -tinsert(FriendSpells.DRUID, 8936) -- Regrowth (40 yards, level 3) -tinsert(FriendSpells.DRUID, 774) -- Rejuvenation (Restoration) (40 yards, level 10) -tinsert(FriendSpells.DRUID, 2782) -- Remove Corruption (Restoration) (40 yards, level 19) -tinsert(FriendSpells.DRUID, 88423) -- Natures Cure (Restoration) (40 yards, level 19) +tinsert(FriendSpells.DRUID, 8936) -- Regrowth (40 yards, level 3) +tinsert(FriendSpells.DRUID, 774) -- Rejuvenation (Restoration) (40 yards, level 10) +tinsert(FriendSpells.DRUID, 2782) -- Remove Corruption (Restoration) (40 yards, level 19) +tinsert(FriendSpells.DRUID, 88423) -- Natures Cure (Restoration) (40 yards, level 19) if not isRetail then - tinsert(FriendSpells.DRUID, 5185) -- Healing Touch (40 yards, level 1, rank 1) + tinsert(FriendSpells.DRUID, 5185) -- Healing Touch (40 yards, level 1, rank 1) end -tinsert(HarmSpells.DRUID, 5176) -- Wrath (40 yards) -tinsert(HarmSpells.DRUID, 339) -- Entangling Roots (35 yards) -tinsert(HarmSpells.DRUID, 6795) -- Growl (30 yards) -tinsert(HarmSpells.DRUID, 33786) -- Cyclone (20 yards) -tinsert(HarmSpells.DRUID, 22568) -- Ferocious Bite (Melee Range) -tinsert(HarmSpells.DRUID, 8921) -- Moonfire (40 yards, level 2) +tinsert(HarmSpells.DRUID, 5176) -- Wrath (40 yards) +tinsert(HarmSpells.DRUID, 339) -- Entangling Roots (35 yards) +tinsert(HarmSpells.DRUID, 6795) -- Growl (30 yards) +tinsert(HarmSpells.DRUID, 33786) -- Cyclone (20 yards) +tinsert(HarmSpells.DRUID, 22568) -- Ferocious Bite (Melee Range) +tinsert(HarmSpells.DRUID, 8921) -- Moonfire (40 yards, level 2) -tinsert(ResSpells.DRUID, 50769) -- Revive (40 yards, level 14) -tinsert(ResSpells.DRUID, 20484) -- Rebirth (40 yards, level 29) +tinsert(ResSpells.DRUID, 50769) -- Revive (40 yards, level 14) +tinsert(ResSpells.DRUID, 20484) -- Rebirth (40 yards, level 29) -- Hunters -tinsert(HarmSpells.HUNTER, 75) -- Auto Shot (40 yards) +tinsert(HarmSpells.HUNTER, 75) -- Auto Shot (40 yards) if not isRetail then - tinsert(HarmSpells.HUNTER, 2764) -- Throw (30 yards, level 1) + tinsert(HarmSpells.HUNTER, 2764) -- Throw (30 yards, level 1) end -tinsert(PetSpells.HUNTER, 136) -- Mend Pet (45 yards) +tinsert(PetSpells.HUNTER, 136) -- Mend Pet (45 yards) -- Mages -tinsert(FriendSpells.MAGE, 1459) -- Arcane Intellect (40 yards, level 8) -tinsert(FriendSpells.MAGE, 475) -- Remove Curse (40 yards, level 28) +tinsert(FriendSpells.MAGE, 1459) -- Arcane Intellect (40 yards, level 8) +tinsert(FriendSpells.MAGE, 475) -- Remove Curse (40 yards, level 28) if not isRetail then - tinsert(FriendSpells.MAGE, 130) -- Slow Fall (40 yards, level 12) + tinsert(FriendSpells.MAGE, 130) -- Slow Fall (40 yards, level 12) end -tinsert(HarmSpells.MAGE, 44614) -- Flurry (40 yards) -tinsert(HarmSpells.MAGE, 5019) -- Shoot (30 yards) -tinsert(HarmSpells.MAGE, 118) -- Polymorph (30 yards) -tinsert(HarmSpells.MAGE, 116) -- Frostbolt (40 yards) -tinsert(HarmSpells.MAGE, 133) -- Fireball (40 yards) -tinsert(HarmSpells.MAGE, 44425) -- Arcane Barrage (40 yards) +tinsert(HarmSpells.MAGE, 44614) -- Flurry (40 yards) +tinsert(HarmSpells.MAGE, 5019) -- Shoot (30 yards) +tinsert(HarmSpells.MAGE, 118) -- Polymorph (30 yards) +tinsert(HarmSpells.MAGE, 116) -- Frostbolt (40 yards) +tinsert(HarmSpells.MAGE, 133) -- Fireball (40 yards) +tinsert(HarmSpells.MAGE, 44425) -- Arcane Barrage (40 yards) -- Monks -tinsert(FriendSpells.MONK, 115450) -- Detox (40 yards) -tinsert(FriendSpells.MONK, 115546) -- Provoke (30 yards) -tinsert(FriendSpells.MONK, 116670) -- Vivify (40 yards) +tinsert(FriendSpells.MONK, 115450) -- Detox (40 yards) +tinsert(FriendSpells.MONK, 115546) -- Provoke (30 yards) +tinsert(FriendSpells.MONK, 116670) -- Vivify (40 yards) -tinsert(HarmSpells.MONK, 115546) -- Provoke (30 yards) -tinsert(HarmSpells.MONK, 115078) -- Paralysis (20 yards) -tinsert(HarmSpells.MONK, 100780) -- Tiger Palm (Melee Range) -tinsert(HarmSpells.MONK, 117952) -- Crackling Jade Lightning (40 yards) +tinsert(HarmSpells.MONK, 115546) -- Provoke (30 yards) +tinsert(HarmSpells.MONK, 115078) -- Paralysis (20 yards) +tinsert(HarmSpells.MONK, 100780) -- Tiger Palm (Melee Range) +tinsert(HarmSpells.MONK, 117952) -- Crackling Jade Lightning (40 yards) -tinsert(ResSpells.MONK, 115178) -- Resuscitate (40 yards, level 13) +tinsert(ResSpells.MONK, 115178) -- Resuscitate (40 yards, level 13) -- Paladins -tinsert(FriendSpells.PALADIN, 19750) -- Flash of Light (40 yards, level 4) -tinsert(FriendSpells.PALADIN, 85673) -- Word of Glory (40 yards, level 7) -tinsert(FriendSpells.PALADIN, 4987) -- Cleanse (Holy) (40 yards, level 12) -tinsert(FriendSpells.PALADIN, 213644) -- Cleanse Toxins (Protection, Retribution) (40 yards, level 12) +tinsert(FriendSpells.PALADIN, 19750) -- Flash of Light (40 yards, level 4) +tinsert(FriendSpells.PALADIN, 85673) -- Word of Glory (40 yards, level 7) +tinsert(FriendSpells.PALADIN, 4987) -- Cleanse (Holy) (40 yards, level 12) +tinsert(FriendSpells.PALADIN, 213644) -- Cleanse Toxins (Protection, Retribution) (40 yards, level 12) if not isRetail then - tinsert(FriendSpells.PALADIN, 635) -- Holy Light (40 yards, level 1, rank 1) + tinsert(FriendSpells.PALADIN, 635) -- Holy Light (40 yards, level 1, rank 1) end -tinsert(HarmSpells.PALADIN, 853) -- Hammer of Justice (10 yards) -tinsert(HarmSpells.PALADIN, 35395) -- Crusader Strike (Melee Range) -tinsert(HarmSpells.PALADIN, 62124) -- Hand of Reckoning (30 yards) +tinsert(HarmSpells.PALADIN, 853) -- Hammer of Justice (10 yards) +tinsert(HarmSpells.PALADIN, 35395) -- Crusader Strike (Melee Range) +tinsert(HarmSpells.PALADIN, 62124) -- Hand of Reckoning (30 yards) tinsert(HarmSpells.PALADIN, 183218) -- Hand of Hindrance (30 yards) -tinsert(HarmSpells.PALADIN, 20271) -- Judgement (30 yards) -tinsert(HarmSpells.PALADIN, 20473) -- Holy Shock (40 yards) +tinsert(HarmSpells.PALADIN, 20271) -- Judgement (30 yards) +tinsert(HarmSpells.PALADIN, 20473) -- Holy Shock (40 yards) -tinsert(ResSpells.PALADIN, 7328) -- Redemption (40 yards) +tinsert(ResSpells.PALADIN, 7328) -- Redemption (40 yards) -- Priests if isRetail then - tinsert(FriendSpells.PRIEST, 21562) -- Power Word: Fortitude (40 yards, level 6) [use first to fix Kyrian boon/fae soulshape] - tinsert(FriendSpells.PRIEST, 17) -- Power Word: Shield (40 yards, level 4) + tinsert(FriendSpells.PRIEST, 21562) -- Power Word: Fortitude (40 yards, level 6) [use first to fix Kyrian boon/fae soulshape] + tinsert(FriendSpells.PRIEST, 17) -- Power Word: Shield (40 yards, level 4) else -- PWS is group only in classic, use lesser heal as main spell check - tinsert(FriendSpells.PRIEST, 2050) -- Lesser Heal (40 yards, level 1, rank 1) + tinsert(FriendSpells.PRIEST, 2050) -- Lesser Heal (40 yards, level 1, rank 1) end -tinsert(FriendSpells.PRIEST, 527) -- Purify / Dispel Magic (40 yards retail, 30 yards tbc, level 18, rank 1) -tinsert(FriendSpells.PRIEST, 2061) -- Flash Heal (40 yards, level 3 retail, level 20 tbc) +tinsert(FriendSpells.PRIEST, 527) -- Purify / Dispel Magic (40 yards retail, 30 yards tbc, level 18, rank 1) +tinsert(FriendSpells.PRIEST, 2061) -- Flash Heal (40 yards, level 3 retail, level 20 tbc) -tinsert(HarmSpells.PRIEST, 589) -- Shadow Word: Pain (40 yards) -tinsert(HarmSpells.PRIEST, 585) -- Smite (40 yards) -tinsert(HarmSpells.PRIEST, 5019) -- Shoot (30 yards) +tinsert(HarmSpells.PRIEST, 589) -- Shadow Word: Pain (40 yards) +tinsert(HarmSpells.PRIEST, 585) -- Smite (40 yards) +tinsert(HarmSpells.PRIEST, 5019) -- Shoot (30 yards) if not isRetail then - tinsert(HarmSpells.PRIEST, 8092) -- Mindblast (30 yards, level 10) + tinsert(HarmSpells.PRIEST, 8092) -- Mindblast (30 yards, level 10) end -tinsert(ResSpells.PRIEST, 2006) -- Resurrection (40 yards, level 10) +tinsert(ResSpells.PRIEST, 2006) -- Resurrection (40 yards, level 10) -- Rogues if isRetail then - tinsert(FriendSpells.ROGUE, 36554) -- Shadowstep (Assassination, Subtlety) (25 yards, level 18) -- works on friendly in retail - tinsert(FriendSpells.ROGUE, 921) -- Pick Pocket (10 yards, level 24) -- this works for range, keep it in friendly as well for retail but on classic this is melee range and will return min 0 range 0 + tinsert(FriendSpells.ROGUE, 36554) -- Shadowstep (Assassination, Subtlety) (25 yards, level 18) -- works on friendly in retail + tinsert(FriendSpells.ROGUE, 921) -- Pick Pocket (10 yards, level 24) -- this works for range, keep it in friendly as well for retail but on classic this is melee range and will return min 0 range 0 end -tinsert(HarmSpells.ROGUE, 2764) -- Throw (30 yards) -tinsert(HarmSpells.ROGUE, 36554) -- Shadowstep (Assassination, Subtlety) (25 yards, level 18) -tinsert(HarmSpells.ROGUE, 185763) -- Pistol Shot (Outlaw) (20 yards) -tinsert(HarmSpells.ROGUE, 2094) -- Blind (15 yards) -tinsert(HarmSpells.ROGUE, 921) -- Pick Pocket (10 yards, level 24) +tinsert(HarmSpells.ROGUE, 2764) -- Throw (30 yards) +tinsert(HarmSpells.ROGUE, 36554) -- Shadowstep (Assassination, Subtlety) (25 yards, level 18) +tinsert(HarmSpells.ROGUE, 185763) -- Pistol Shot (Outlaw) (20 yards) +tinsert(HarmSpells.ROGUE, 2094) -- Blind (15 yards) +tinsert(HarmSpells.ROGUE, 921) -- Pick Pocket (10 yards, level 24) -- Shamans -tinsert(FriendSpells.SHAMAN, 546) -- Water Walking (30 yards) -tinsert(FriendSpells.SHAMAN, 8004) -- Healing Surge (Resto, Elemental) (40 yards) -tinsert(FriendSpells.SHAMAN, 188070) -- Healing Surge (Enhancement) (40 yards) +tinsert(FriendSpells.SHAMAN, 546) -- Water Walking (30 yards) +tinsert(FriendSpells.SHAMAN, 8004) -- Healing Surge (Resto, Elemental) (40 yards) +tinsert(FriendSpells.SHAMAN, 188070) -- Healing Surge (Enhancement) (40 yards) if not isRetail then - tinsert(FriendSpells.SHAMAN, 331) -- Healing Wave (40 yards, level 1, rank 1) - tinsert(FriendSpells.SHAMAN, 526) -- Cure Poison (40 yards, level 16) - tinsert(FriendSpells.SHAMAN, 2870) -- Cure Disease (40 yards, level 22) + tinsert(FriendSpells.SHAMAN, 331) -- Healing Wave (40 yards, level 1, rank 1) + tinsert(FriendSpells.SHAMAN, 526) -- Cure Poison (40 yards, level 16) + tinsert(FriendSpells.SHAMAN, 2870) -- Cure Disease (40 yards, level 22) end -tinsert(HarmSpells.SHAMAN, 370) -- Purge (30 yards) -tinsert(HarmSpells.SHAMAN, 188196) -- Lightning Bolt (40 yards) -tinsert(HarmSpells.SHAMAN, 73899) -- Primal Strike (Melee Range) +tinsert(HarmSpells.SHAMAN, 370) -- Purge (30 yards) +tinsert(HarmSpells.SHAMAN, 188196) -- Lightning Bolt (40 yards) +tinsert(HarmSpells.SHAMAN, 73899) -- Primal Strike (Melee Range) if not isRetail then - tinsert(HarmSpells.SHAMAN, 403) -- Lightning Bolt (30 yards, level 1, rank 1) - tinsert(HarmSpells.SHAMAN, 8042) -- Earth Shock (20 yards, level 4, rank 1) + tinsert(HarmSpells.SHAMAN, 403) -- Lightning Bolt (30 yards, level 1, rank 1) + tinsert(HarmSpells.SHAMAN, 8042) -- Earth Shock (20 yards, level 4, rank 1) end -tinsert(ResSpells.SHAMAN, 2008) -- Ancestral Spirit (40 yards, level 13) +tinsert(ResSpells.SHAMAN, 2008) -- Ancestral Spirit (40 yards, level 13) -- Warriors -tinsert(HarmSpells.WARRIOR, 355) -- Taunt (30 yards) -tinsert(HarmSpells.WARRIOR, 5246) -- Intimidating Shout (Arms, Fury) (8 yards) -tinsert(HarmSpells.WARRIOR, 100) -- Charge (Arms, Fury) (8-25 yards) +tinsert(HarmSpells.WARRIOR, 355) -- Taunt (30 yards) +tinsert(HarmSpells.WARRIOR, 5246) -- Intimidating Shout (Arms, Fury) (8 yards) +tinsert(HarmSpells.WARRIOR, 100) -- Charge (Arms, Fury) (8-25 yards) if not isRetail then - tinsert(HarmSpells.WARRIOR, 2764) -- Throw (30 yards, level 1, 5-30 range) + tinsert(HarmSpells.WARRIOR, 2764) -- Throw (30 yards, level 1, 5-30 range) end -- Warlocks -tinsert(FriendSpells.WARLOCK, 5697) -- Unending Breath (30 yards) -tinsert(FriendSpells.WARLOCK, 20707) -- Soulstone (40 yards) ~ this can be precasted so leave it in friendly as well as res +tinsert(FriendSpells.WARLOCK, 5697) -- Unending Breath (30 yards) +tinsert(FriendSpells.WARLOCK, 20707) -- Soulstone (40 yards) ~ this can be precasted so leave it in friendly as well as res if isRetail then - tinsert(FriendSpells.WARLOCK, 132) -- Detect Invisibility (30 yards, level 26) + tinsert(FriendSpells.WARLOCK, 132) -- Detect Invisibility (30 yards, level 26) end -tinsert(HarmSpells.WARLOCK, 5019) -- Shoot (30 yards) -tinsert(HarmSpells.WARLOCK, 234153) -- Drain Life (40 yards, level 9) -tinsert(HarmSpells.WARLOCK, 198590) -- Drain Soul (40 yards, level 15) -tinsert(HarmSpells.WARLOCK, 686) -- Shadow Bolt (Demonology, Affliction) (40 yards) -tinsert(HarmSpells.WARLOCK, 232670) -- Shadow Bolt (40 yards) -tinsert(HarmSpells.WARLOCK, 5782) -- Fear (30 yards) +tinsert(HarmSpells.WARLOCK, 5019) -- Shoot (30 yards) +tinsert(HarmSpells.WARLOCK, 234153) -- Drain Life (40 yards, level 9) +tinsert(HarmSpells.WARLOCK, 198590) -- Drain Soul (40 yards, level 15) +tinsert(HarmSpells.WARLOCK, 686) -- Shadow Bolt (Demonology, Affliction) (40 yards) +tinsert(HarmSpells.WARLOCK, 232670) -- Shadow Bolt (40 yards) +tinsert(HarmSpells.WARLOCK, 5782) -- Fear (30 yards) if not isRetail then - tinsert(HarmSpells.WARLOCK, 172) -- Corruption (30 yards, level 4, rank 1) - tinsert(HarmSpells.WARLOCK, 348) -- Immolate (30 yards, level 1, rank 1) - tinsert(HarmSpells.WARLOCK, 17877) -- Shadowburn (Destruction) (20 yards) - tinsert(HarmSpells.WARLOCK, 18223) -- Curse of Exhaustion (Affliction) (30/33/36/35/38/42 yards) + tinsert(HarmSpells.WARLOCK, 172) -- Corruption (30 yards, level 4, rank 1) + tinsert(HarmSpells.WARLOCK, 348) -- Immolate (30 yards, level 1, rank 1) + tinsert(HarmSpells.WARLOCK, 17877) -- Shadowburn (Destruction) (20 yards) + tinsert(HarmSpells.WARLOCK, 18223) -- Curse of Exhaustion (Affliction) (30/33/36/35/38/42 yards) end -tinsert(ResSpells.WARLOCK, 20707) -- Soulstone (40 yards) +tinsert(ResSpells.WARLOCK, 20707) -- Soulstone (40 yards) -tinsert(PetSpells.WARLOCK, 755) -- Health Funnel (45 yards) +tinsert(PetSpells.WARLOCK, 755) -- Health Funnel (45 yards) -- Items [Special thanks to Maldivia for the nice list] -local FriendItems = { - [2] = { - 37727, -- Ruby Acorn - }, - [3] = { - 42732, -- Everfrost Razor - }, - [5] = { - 8149, -- Voodoo Charm - 136605, -- Solendra's Compassion - 63427, -- Worgsaw - }, - [8] = { - 34368, -- Attuned Crystal Cores - 33278, -- Burning Torch - }, - [10] = { - 32321, -- Sparrowhawk Net - 17626, -- Frostwolf Muzzle - }, - [15] = { - 1251, -- Linen Bandage - 2581, -- Heavy Linen Bandage - 3530, -- Wool Bandage - 3531, -- Heavy Wool Bandage - 6450, -- Silk Bandage - 6451, -- Heavy Silk Bandage - 8544, -- Mageweave Bandage - 8545, -- Heavy Mageweave Bandage - 14529, -- Runecloth Bandage - 14530, -- Heavy Runecloth Bandage - 21990, -- Netherweave Bandage - 21991, -- Heavy Netherweave Bandage - 34721, -- Frostweave Bandage - 34722, -- Heavy Frostweave Bandage - --38643, -- Thick Frostweave Bandage (uncomment for Wotlk) - --38640, -- Dense Frostweave Bandage (uncomment for Wotlk) - }, - [20] = { - 21519, -- Mistletoe - }, - [25] = { - 31463, -- Zezzak's Shard - 13289, -- Egan's Blaster - }, - [30] = { - 1180, -- Scroll of Stamina - 1478, -- Scroll of Protection II - 3012, -- Scroll of Agility - 1712, -- Scroll of Spirit II - 2290, -- Scroll of Intellect II - 1711, -- Scroll of Stamina II - 34191, -- Handful of Snowflakes - }, - [35] = { - 18904, -- Zorbin's Ultra-Shrinker - }, - [40] = { - 34471, -- Vial of the Sunwell - }, - [45] = { - 32698, -- Wrangling Rope - }, - [60] = { - 32825, -- Soul Cannon - 37887, -- Seeds of Nature's Wrath - }, - [70] = { - 41265, -- Eyesore Blaster - }, - [80] = { - 35278, -- Reinforced Net - }, - [100] = { - 41058, -- Hyldnir Harpoon - }, - [150] = { - 46954, -- Flaming Spears - }, +local FriendItems = { + [2] = { + 37727, -- Ruby Acorn + }, + [3] = { + 42732, -- Everfrost Razor + }, + [5] = { + 8149, -- Voodoo Charm + 136605, -- Solendra's Compassion + 63427, -- Worgsaw + }, + [8] = { + 34368, -- Attuned Crystal Cores + 33278, -- Burning Torch + }, + [10] = { + 32321, -- Sparrowhawk Net + 17626, -- Frostwolf Muzzle + }, + [15] = { + 1251, -- Linen Bandage + 2581, -- Heavy Linen Bandage + 3530, -- Wool Bandage + 3531, -- Heavy Wool Bandage + 6450, -- Silk Bandage + 6451, -- Heavy Silk Bandage + 8544, -- Mageweave Bandage + 8545, -- Heavy Mageweave Bandage + 14529, -- Runecloth Bandage + 14530, -- Heavy Runecloth Bandage + 21990, -- Netherweave Bandage + 21991, -- Heavy Netherweave Bandage + 34721, -- Frostweave Bandage + 34722, -- Heavy Frostweave Bandage + --38643, -- Thick Frostweave Bandage (uncomment for Wotlk) + --38640, -- Dense Frostweave Bandage (uncomment for Wotlk) + }, + [20] = { + 21519, -- Mistletoe + }, + [25] = { + 31463, -- Zezzak's Shard + 13289, -- Egan's Blaster + }, + [30] = { + 1180, -- Scroll of Stamina + 1478, -- Scroll of Protection II + 3012, -- Scroll of Agility + 1712, -- Scroll of Spirit II + 2290, -- Scroll of Intellect II + 1711, -- Scroll of Stamina II + 34191, -- Handful of Snowflakes + }, + [35] = { + 18904, -- Zorbin's Ultra-Shrinker + }, + [40] = { + 34471, -- Vial of the Sunwell + }, + [45] = { + 32698, -- Wrangling Rope + }, + [60] = { + 32825, -- Soul Cannon + 37887, -- Seeds of Nature's Wrath + }, + [70] = { + 41265, -- Eyesore Blaster + }, + [80] = { + 35278, -- Reinforced Net + }, + [100] = { + 41058, -- Hyldnir Harpoon + }, + [150] = { + 46954, -- Flaming Spears + }, } if isRetail then - FriendItems[1] = { - 90175, -- Gin-Ji Knife Set -- doesn't seem to work for pets (always returns nil) - } - FriendItems[4] = { - 129055, -- Shoe Shine Kit - } - FriendItems[7] = { - 61323, -- Ruby Seeds - } - FriendItems[38] = { - 140786, -- Ley Spider Eggs - } - FriendItems[55] = { - 74637, -- Kiryn's Poison Vial - } - FriendItems[50] = { - 116139, -- Haunting Memento - } - FriendItems[90] = { - 133925, -- Fel Lash - } - FriendItems[200] = { - 75208, -- Rancher's Lariat - } + FriendItems[1] = { + 90175, -- Gin-Ji Knife Set -- doesn't seem to work for pets (always returns nil) + } + FriendItems[4] = { + 129055, -- Shoe Shine Kit + } + FriendItems[7] = { + 61323, -- Ruby Seeds + } + FriendItems[38] = { + 140786, -- Ley Spider Eggs + } + FriendItems[55] = { + 74637, -- Kiryn's Poison Vial + } + FriendItems[50] = { + 116139, -- Haunting Memento + } + FriendItems[90] = { + 133925, -- Fel Lash + } + FriendItems[200] = { + 75208, -- Rancher's Lariat + } end local HarmItems = { - [1] = { - }, - [2] = { - 37727, -- Ruby Acorn - }, - [3] = { - 42732, -- Everfrost Razor - }, - [5] = { - 8149, -- Voodoo Charm - 136605, -- Solendra's Compassion - 63427, -- Worgsaw - }, - [8] = { - 34368, -- Attuned Crystal Cores - 33278, -- Burning Torch - }, - [10] = { - 32321, -- Sparrowhawk Net - 17626, -- Frostwolf Muzzle - }, - [15] = { - 33069, -- Sturdy Rope - }, - [20] = { - 10645, -- Gnomish Death Ray - }, - [25] = { - 24268, -- Netherweave Net - 41509, -- Frostweave Net - 31463, -- Zezzak's Shard - 13289, -- Egan's Blaster - }, - [30] = { - 835, -- Large Rope Net - 7734, -- Six Demon Bag - 34191, -- Handful of Snowflakes - }, - [35] = { - 24269, -- Heavy Netherweave Net - 18904, -- Zorbin's Ultra-Shrinker - }, - [40] = { - 28767, -- The Decapitator - }, - [45] = { - --32698, -- Wrangling Rope - 23836, -- Goblin Rocket Launcher - }, - [60] = { - 32825, -- Soul Cannon - 37887, -- Seeds of Nature's Wrath - }, - [70] = { - 41265, -- Eyesore Blaster - }, - [80] = { - 35278, -- Reinforced Net - }, - [100] = { - 33119, -- Malister's Frost Wand - }, - [150] = { - 46954, -- Flaming Spears - }, + [1] = {}, + [2] = { + 37727, -- Ruby Acorn + }, + [3] = { + 42732, -- Everfrost Razor + }, + [5] = { + 8149, -- Voodoo Charm + 136605, -- Solendra's Compassion + 63427, -- Worgsaw + }, + [8] = { + 34368, -- Attuned Crystal Cores + 33278, -- Burning Torch + }, + [10] = { + 32321, -- Sparrowhawk Net + 17626, -- Frostwolf Muzzle + }, + [15] = { + 33069, -- Sturdy Rope + }, + [20] = { + 10645, -- Gnomish Death Ray + }, + [25] = { + 24268, -- Netherweave Net + 41509, -- Frostweave Net + 31463, -- Zezzak's Shard + 13289, -- Egan's Blaster + }, + [30] = { + 835, -- Large Rope Net + 7734, -- Six Demon Bag + 34191, -- Handful of Snowflakes + }, + [35] = { + 24269, -- Heavy Netherweave Net + 18904, -- Zorbin's Ultra-Shrinker + }, + [40] = { + 28767, -- The Decapitator + }, + [45] = { + --32698, -- Wrangling Rope + 23836, -- Goblin Rocket Launcher + }, + [60] = { + 32825, -- Soul Cannon + 37887, -- Seeds of Nature's Wrath + }, + [70] = { + 41265, -- Eyesore Blaster + }, + [80] = { + 35278, -- Reinforced Net + }, + [100] = { + 33119, -- Malister's Frost Wand + }, + [150] = { + 46954, -- Flaming Spears + }, } if isRetail then - HarmItems[4] = { - 129055, -- Shoe Shine Kit - } - HarmItems[7] = { - 61323, -- Ruby Seeds - } - HarmItems[38] = { - 140786, -- Ley Spider Eggs - } - HarmItems[50] = { - 116139, -- Haunting Memento - } - HarmItems[55] = { - 74637, -- Kiryn's Poison Vial - } - HarmItems[90] = { - 133925, -- Fel Lash - } - HarmItems[200] = { - 75208, -- Rancher's Lariat - } + HarmItems[4] = { + 129055, -- Shoe Shine Kit + } + HarmItems[7] = { + 61323, -- Ruby Seeds + } + HarmItems[38] = { + 140786, -- Ley Spider Eggs + } + HarmItems[50] = { + 116139, -- Haunting Memento + } + HarmItems[55] = { + 74637, -- Kiryn's Poison Vial + } + HarmItems[90] = { + 133925, -- Fel Lash + } + HarmItems[200] = { + 75208, -- Rancher's Lariat + } end -- This could've been done by checking player race as well and creating tables for those, but it's easier like this for _, v in pairs(FriendSpells) do - tinsert(v, 28880) -- Gift of the Naaru (40 yards) + tinsert(v, 28880) -- Gift of the Naaru (40 yards) end -- >> END OF STATIC CONFIG @@ -523,333 +523,338 @@ local harmItemRequests local lastUpdate = 0 -- minRangeCheck is a function to check if spells with minimum range are really out of range, or fail due to range < minRange. See :init() for its setup -local minRangeCheck = function(unit) return CheckInteractDistance(unit, 2) end +local minRangeCheck = function(unit) + return CheckInteractDistance(unit, 2) +end local checkers_Spell = setmetatable({}, { - __index = function(t, spellIdx) - local func = function(unit) - if IsSpellInRange(spellIdx, BOOKTYPE_SPELL, unit) == 1 then - return true - end - end - t[spellIdx] = func - return func + __index = function(t, spellIdx) + local func = function(unit) + if IsSpellInRange(spellIdx, BOOKTYPE_SPELL, unit) == 1 then + return true + end end + t[spellIdx] = func + return func + end, }) local checkers_SpellWithMin = setmetatable({}, { - __index = function(t, spellIdx) - local func = function(unit) - if IsSpellInRange(spellIdx, BOOKTYPE_SPELL, unit) == 1 then - return true - elseif minRangeCheck(unit) then - return true, true - end - end - t[spellIdx] = func - return func + __index = function(t, spellIdx) + local func = function(unit) + if IsSpellInRange(spellIdx, BOOKTYPE_SPELL, unit) == 1 then + return true + elseif minRangeCheck(unit) then + return true, true + end end + t[spellIdx] = func + return func + end, }) local checkers_Item = setmetatable({}, { - __index = function(t, item) - local func = function(unit) - return IsItemInRange(item, unit) - end - t[item] = func - return func + __index = function(t, item) + local func = function(unit) + return IsItemInRange(item, unit) end + t[item] = func + return func + end, }) local checkers_Interact = setmetatable({}, { - __index = function(t, index) - local func = function(unit) - if CheckInteractDistance(unit, index) then - return true - end - end - t[index] = func - return func + __index = function(t, index) + local func = function(unit) + if CheckInteractDistance(unit, index) then + return true + end end + t[index] = func + return func + end, }) -- helper functions local function copyTable(src, dst) - if type(dst) ~= "table" then dst = {} end - if type(src) == "table" then - for k, v in pairs(src) do - if type(v) == "table" then - v = copyTable(v, dst[k]) - end - dst[k] = v - end + if type(dst) ~= "table" then + dst = {} + end + if type(src) == "table" then + for k, v in pairs(src) do + if type(v) == "table" then + v = copyTable(v, dst[k]) + end + dst[k] = v end - return dst + end + return dst end local function initItemRequests(cacheAll) - friendItemRequests = copyTable(FriendItems) - harmItemRequests = copyTable(HarmItems) - cacheAllItems = cacheAll - foundNewItems = nil + friendItemRequests = copyTable(FriendItems) + harmItemRequests = copyTable(HarmItems) + cacheAllItems = cacheAll + foundNewItems = nil end local function getNumSpells() - local _, _, offset, numSpells = GetSpellTabInfo(GetNumSpellTabs()) - return offset + numSpells + local _, _, offset, numSpells = GetSpellTabInfo(GetNumSpellTabs()) + return offset + numSpells end -- return the spellIndex of the given spell by scanning the spellbook local function findSpellIdx(spellName) - if not spellName or spellName == "" then - return nil - end - for i = 1, getNumSpells() do - local spell = GetSpellBookItemName(i, BOOKTYPE_SPELL) - if spell == spellName then - return i - end - end + if not spellName or spellName == "" then return nil + end + for i = 1, getNumSpells() do + local spell = GetSpellBookItemName(i, BOOKTYPE_SPELL) + if spell == spellName then + return i + end + end + return nil end -- minRange should be nil if there's no minRange, not 0 local function addChecker(t, range, minRange, checker, info) - local rc = { ["range"] = range, ["minRange"] = minRange, ["checker"] = checker, ["info"] = info } - for i = 1, #t do - local v = t[i] - if rc.range == v.range then return end - if rc.range > v.range then - tinsert(t, i, rc) - return - end + local rc = { ["range"] = range, ["minRange"] = minRange, ["checker"] = checker, ["info"] = info } + for i = 1, #t do + local v = t[i] + if rc.range == v.range then + return end - tinsert(t, rc) + if rc.range > v.range then + tinsert(t, i, rc) + return + end + end + tinsert(t, rc) end local function createCheckerList(spellList, itemList, interactList) - local res = {} - if itemList then - for range, items in pairs(itemList) do - for i = 1, #items do - local item = items[i] - if GetItemInfo(item) then - addChecker(res, range, nil, checkers_Item[item], "item:" .. item) - break - end - end + local res = {} + if itemList then + for range, items in pairs(itemList) do + for i = 1, #items do + local item = items[i] + if GetItemInfo(item) then + addChecker(res, range, nil, checkers_Item[item], "item:" .. item) + break end + end end + end + + if spellList then + for i = 1, #spellList do + local sid = spellList[i] + local name, _, _, _, minRange, range = GetSpellInfo(sid) + local spellIdx = findSpellIdx(name) + if spellIdx and range then + minRange = math_floor(minRange + 0.5) + range = math_floor(range + 0.5) - if spellList then - for i = 1, #spellList do - local sid = spellList[i] - local name, _, _, _, minRange, range = GetSpellInfo(sid) - local spellIdx = findSpellIdx(name) - if spellIdx and range then - minRange = math_floor(minRange + 0.5) - range = math_floor(range + 0.5) - - -- print("### spell: " .. tostring(name) .. ", " .. tostring(minRange) .. " - " .. tostring(range)) - - if minRange == 0 then -- getRange() expects minRange to be nil in this case - minRange = nil - end - - if range == 0 then - range = MeleeRange - end - - if minRange then - addChecker(res, range, minRange, checkers_SpellWithMin[spellIdx], "spell:" .. sid .. ":" .. tostring(name)) - else - addChecker(res, range, minRange, checkers_Spell[spellIdx], "spell:" .. sid .. ":" .. tostring(name)) - end - end + -- print("### spell: " .. tostring(name) .. ", " .. tostring(minRange) .. " - " .. tostring(range)) + + if minRange == 0 then -- getRange() expects minRange to be nil in this case + minRange = nil end - end - if interactList and not next(res) then - for index, range in pairs(interactList) do - addChecker(res, range, nil, checkers_Interact[index], "interact:" .. index) + if range == 0 then + range = MeleeRange end + + if minRange then + addChecker(res, range, minRange, checkers_SpellWithMin[spellIdx], "spell:" .. sid .. ":" .. tostring(name)) + else + addChecker(res, range, minRange, checkers_Spell[spellIdx], "spell:" .. sid .. ":" .. tostring(name)) + end + end end + end - return res + if interactList and not next(res) then + for index, range in pairs(interactList) do + addChecker(res, range, nil, checkers_Interact[index], "interact:" .. index) + end + end + + return res end local rangeCache = {} local function resetRangeCache() - wipe(rangeCache) + wipe(rangeCache) end local function invalidateRangeCache(maxAge) - local currentTime = GetTime() - for k, v in pairs(rangeCache) do - -- if the entry is older than maxAge, clear this data from the cache - if v.updateTime + maxAge < currentTime then - rangeCache[k] = nil - end + local currentTime = GetTime() + for k, v in pairs(rangeCache) do + -- if the entry is older than maxAge, clear this data from the cache + if v.updateTime + maxAge < currentTime then + rangeCache[k] = nil end + end end -- returns minRange, maxRange or nil local function getRangeWithCheckerList(unit, checkerList) - local lo, hi = 1, #checkerList - while lo <= hi do - local mid = math_floor((lo + hi) / 2) - local rc = checkerList[mid] - if rc.checker(unit) then - lo = mid + 1 - else - hi = mid - 1 - end - end - if lo > #checkerList then - return 0, checkerList[#checkerList].range - elseif lo <= 1 then - return checkerList[1].range, nil + local lo, hi = 1, #checkerList + while lo <= hi do + local mid = math_floor((lo + hi) / 2) + local rc = checkerList[mid] + if rc.checker(unit) then + lo = mid + 1 else - return checkerList[lo].range, checkerList[lo - 1].range + hi = mid - 1 end + end + if lo > #checkerList then + return 0, checkerList[#checkerList].range + elseif lo <= 1 then + return checkerList[1].range, nil + else + return checkerList[lo].range, checkerList[lo - 1].range + end end local function getRange(unit, noItems) - local canAssist = UnitCanAssist("player", unit) - if UnitIsDeadOrGhost(unit) then - if canAssist then - return getRangeWithCheckerList(unit, lib.resRC) - else - return getRangeWithCheckerList(unit, lib.miscRC) - end + local canAssist = UnitCanAssist("player", unit) + if UnitIsDeadOrGhost(unit) then + if canAssist then + return getRangeWithCheckerList(unit, lib.resRC) + else + return getRangeWithCheckerList(unit, lib.miscRC) end + end - if UnitCanAttack("player", unit) then - return getRangeWithCheckerList(unit, noItems and lib.harmNoItemsRC or lib.harmRC) - elseif UnitIsUnit("pet", unit) then - local minRange, maxRange = getRangeWithCheckerList(unit, noItems and lib.friendNoItemsRC or lib.friendRC) - if minRange or maxRange then - return minRange, maxRange - else - return getRangeWithCheckerList(unit, lib.petRC) - end - elseif canAssist then - return getRangeWithCheckerList(unit, noItems and lib.friendNoItemsRC or lib.friendRC) + if UnitCanAttack("player", unit) then + return getRangeWithCheckerList(unit, noItems and lib.harmNoItemsRC or lib.harmRC) + elseif UnitIsUnit("pet", unit) then + local minRange, maxRange = getRangeWithCheckerList(unit, noItems and lib.friendNoItemsRC or lib.friendRC) + if minRange or maxRange then + return minRange, maxRange else - return getRangeWithCheckerList(unit, lib.miscRC) + return getRangeWithCheckerList(unit, lib.petRC) end + elseif canAssist then + return getRangeWithCheckerList(unit, noItems and lib.friendNoItemsRC or lib.friendRC) + else + return getRangeWithCheckerList(unit, lib.miscRC) + end end local function getCachedRange(unit, noItems, maxCacheAge) - -- maxCacheAge has a default of 0.1 and a maximum of 1 second - maxCacheAge = maxCacheAge or 0.1; - maxCacheAge = maxCacheAge > 1 and 1 or maxCacheAge; + -- maxCacheAge has a default of 0.1 and a maximum of 1 second + maxCacheAge = maxCacheAge or 0.1 + maxCacheAge = maxCacheAge > 1 and 1 or maxCacheAge - -- compose cache key out of unit guid and noItems - local guid = UnitGUID(unit) - local cacheKey = guid .. (noItems and "-1" or "-0") - local cacheItem = rangeCache[cacheKey] + -- compose cache key out of unit guid and noItems + local guid = UnitGUID(unit) + local cacheKey = guid .. (noItems and "-1" or "-0") + local cacheItem = rangeCache[cacheKey] - local currentTime = GetTime() + local currentTime = GetTime() - -- if then cache item is valid return it - if cacheItem and cacheItem.updateTime + maxCacheAge > currentTime then - return cacheItem.minRange, cacheItem.maxRange - end + -- if then cache item is valid return it + if cacheItem and cacheItem.updateTime + maxCacheAge > currentTime then + return cacheItem.minRange, cacheItem.maxRange + end - -- otherwise create a new or update the existing cache item - local result = cacheItem or {} - result.minRange, result.maxRange = getRange(unit, noItems) - result.updateTime = currentTime - rangeCache[cacheKey] = result - return result.minRange, result.maxRange + -- otherwise create a new or update the existing cache item + local result = cacheItem or {} + result.minRange, result.maxRange = getRange(unit, noItems) + result.updateTime = currentTime + rangeCache[cacheKey] = result + return result.minRange, result.maxRange end local function updateCheckers(origList, newList) - if #origList ~= #newList then - wipe(origList) - copyTable(newList, origList) - return true - end - for i = 1, #origList do - if origList[i].range ~= newList[i].range or origList[i].checker ~= newList[i].checker then - wipe(origList) - copyTable(newList, origList) - return true - end + if #origList ~= #newList then + wipe(origList) + copyTable(newList, origList) + return true + end + for i = 1, #origList do + if origList[i].range ~= newList[i].range or origList[i].checker ~= newList[i].checker then + wipe(origList) + copyTable(newList, origList) + return true end + end end local function rcIterator(checkerList) - local curr = #checkerList - return function() - local rc = checkerList[curr] - if not rc then - return nil - end - curr = curr - 1 - return rc.range, rc.checker + local curr = #checkerList + return function() + local rc = checkerList[curr] + if not rc then + return nil end + curr = curr - 1 + return rc.range, rc.checker + end end local function getMinChecker(checkerList, range) - local checker, checkerRange - for i = 1, #checkerList do - local rc = checkerList[i] - if rc.range < range then - return checker, checkerRange - end - checker, checkerRange = rc.checker, rc.range + local checker, checkerRange + for i = 1, #checkerList do + local rc = checkerList[i] + if rc.range < range then + return checker, checkerRange end - return checker, checkerRange + checker, checkerRange = rc.checker, rc.range + end + return checker, checkerRange end local function getMaxChecker(checkerList, range) - for i = 1, #checkerList do - local rc = checkerList[i] - if rc.range <= range then - return rc.checker, rc.range - end + for i = 1, #checkerList do + local rc = checkerList[i] + if rc.range <= range then + return rc.checker, rc.range end + end end local function getChecker(checkerList, range) - for i = 1, #checkerList do - local rc = checkerList[i] - if rc.range == range then - return rc.checker - end + for i = 1, #checkerList do + local rc = checkerList[i] + if rc.range == range then + return rc.checker end + end end -local function null() -end +local function null() end local function createSmartChecker(friendChecker, harmChecker, miscChecker) - miscChecker = miscChecker or null - friendChecker = friendChecker or miscChecker - harmChecker = harmChecker or miscChecker - return function(unit) - if not UnitExists(unit) then - return nil - end - if UnitIsDeadOrGhost(unit) then - return miscChecker(unit) - end - if UnitCanAttack("player", unit) then - return harmChecker(unit) - elseif UnitCanAssist("player", unit) then - return friendChecker(unit) - else - return miscChecker(unit) - end + miscChecker = miscChecker or null + friendChecker = friendChecker or miscChecker + harmChecker = harmChecker or miscChecker + return function(unit) + if not UnitExists(unit) then + return nil end + if UnitIsDeadOrGhost(unit) then + return miscChecker(unit) + end + if UnitCanAttack("player", unit) then + return harmChecker(unit) + elseif UnitCanAssist("player", unit) then + return friendChecker(unit) + else + return miscChecker(unit) + end + end end local minItemChecker = function(item) - if GetItemInfo(item) then - return function(unit) - return IsItemInRange(item, unit) - end + if GetItemInfo(item) then + return function(unit) + return IsItemInRange(item, unit) end + end end -- OK, here comes the actual lib @@ -877,8 +882,7 @@ lib.failedItemRequests = {} --- A checker function. This type of function is returned by the various Get*Checker() calls. -- @param unit the unit to check range to. -- @return **true** if the unit is within the range for this checker. -local function checker(unit) -end +local function checker(unit) end --@end-do-not-package@ --- The callback name that is fired when checkers are changed. @@ -890,182 +894,178 @@ lib.CHECKERS_CHANGED = "CHECKERS_CHANGED" lib.MeleeRange = MeleeRange function lib:findSpellIndex(spell) - if type(spell) == 'number' then - spell = GetSpellInfo(spell) - end - return findSpellIdx(spell) + if type(spell) == "number" then + spell = GetSpellInfo(spell) + end + return findSpellIdx(spell) end -- returns the range estimate as a string -- deprecated, use :getRange(unit) instead and build your own strings -- @param checkVisible if set to true, then a UnitIsVisible check is made, and **nil** is returned if the unit is not visible function lib:getRangeAsString(unit, checkVisible, showOutOfRange) - local minRange, maxRange = self:getRange(unit, checkVisible) - if not minRange then return nil end - if not maxRange then - return showOutOfRange and minRange .. " +" or nil - end - return minRange .. " - " .. maxRange + local minRange, maxRange = self:getRange(unit, checkVisible) + if not minRange then + return nil + end + if not maxRange then + return showOutOfRange and minRange .. " +" or nil + end + return minRange .. " - " .. maxRange end -- initialize RangeCheck if not yet initialized or if "forced" function lib:init(forced) - if self.initialized and (not forced) then - return - end - self.initialized = true - local _, playerClass = UnitClass("player") - local _, playerRace = UnitRace("player") - - minRangeCheck = nil - - -- first try to find a nice item we can use for minRangeCheck - local harmItems = HarmItems[15] - if harmItems then - for i = 1, #harmItems do - local minCheck = minItemChecker(harmItems[i]) - if minCheck then - minRangeCheck = minCheck - break - end - end - end - - if not minRangeCheck then -- fall back to interact distance checks - if playerClass == "HUNTER" or playerRace == "Tauren" then - -- for Hunters: use interact4 as it's safer - -- for Tauren: interact4 is actually closer than 25yd and interact3 is closer than 8yd, so we can't use that - minRangeCheck = checkers_Interact[4] - else - minRangeCheck = checkers_Interact[3] - end - end - - local interactList = InteractLists[playerRace] or DefaultInteractList - self.handSlotItem = GetInventoryItemLink("player", HandSlotId) - local changed = false - if updateCheckers(self.friendRC, createCheckerList(FriendSpells[playerClass], FriendItems, interactList)) then - changed = true - end - if updateCheckers(self.harmRC, createCheckerList(HarmSpells[playerClass], HarmItems, interactList)) then - changed = true - end - if updateCheckers(self.friendNoItemsRC, createCheckerList(FriendSpells[playerClass], nil, interactList)) then - changed = true - end - if updateCheckers(self.harmNoItemsRC, createCheckerList(HarmSpells[playerClass], nil, interactList)) then - changed = true - end - if updateCheckers(self.miscRC, createCheckerList(nil, nil, interactList)) then - changed = true - end - if updateCheckers(self.resRC, createCheckerList(ResSpells[playerClass], nil, interactList)) then - changed = true - end - if updateCheckers(self.petRC, createCheckerList(PetSpells[playerClass], nil, interactList)) then - changed = true - end - if changed and self.callbacks then - self.callbacks:Fire(self.CHECKERS_CHANGED) - end + if self.initialized and not forced then + return + end + self.initialized = true + local _, playerClass = UnitClass("player") + local _, playerRace = UnitRace("player") + + minRangeCheck = nil + + -- first try to find a nice item we can use for minRangeCheck + local harmItems = HarmItems[15] + if harmItems then + for i = 1, #harmItems do + local minCheck = minItemChecker(harmItems[i]) + if minCheck then + minRangeCheck = minCheck + break + end + end + end + + if not minRangeCheck then -- fall back to interact distance checks + if playerClass == "HUNTER" or playerRace == "Tauren" then + -- for Hunters: use interact4 as it's safer + -- for Tauren: interact4 is actually closer than 25yd and interact3 is closer than 8yd, so we can't use that + minRangeCheck = checkers_Interact[4] + else + minRangeCheck = checkers_Interact[3] + end + end + + local interactList = InteractLists[playerRace] or DefaultInteractList + self.handSlotItem = GetInventoryItemLink("player", HandSlotId) + local changed = false + if updateCheckers(self.friendRC, createCheckerList(FriendSpells[playerClass], FriendItems, interactList)) then + changed = true + end + if updateCheckers(self.harmRC, createCheckerList(HarmSpells[playerClass], HarmItems, interactList)) then + changed = true + end + if updateCheckers(self.friendNoItemsRC, createCheckerList(FriendSpells[playerClass], nil, interactList)) then + changed = true + end + if updateCheckers(self.harmNoItemsRC, createCheckerList(HarmSpells[playerClass], nil, interactList)) then + changed = true + end + if updateCheckers(self.miscRC, createCheckerList(nil, nil, interactList)) then + changed = true + end + if updateCheckers(self.resRC, createCheckerList(ResSpells[playerClass], nil, interactList)) then + changed = true + end + if updateCheckers(self.petRC, createCheckerList(PetSpells[playerClass], nil, interactList)) then + changed = true + end + if changed and self.callbacks then + self.callbacks:Fire(self.CHECKERS_CHANGED) + end end --- Return an iterator for checkers usable on friendly units as (**range**, **checker**) pairs. function lib:GetFriendCheckers() - return rcIterator(self.friendRC) + return rcIterator(self.friendRC) end --- Return an iterator for checkers usable on enemy units as (**range**, **checker**) pairs. function lib:GetHarmCheckers() - return rcIterator(self.harmRC) + return rcIterator(self.harmRC) end --- Return an iterator for checkers usable on miscellaneous units as (**range**, **checker**) pairs. These units are neither enemy nor friendly, such as people in sanctuaries or corpses. function lib:GetMiscCheckers() - return rcIterator(self.miscRC) + return rcIterator(self.miscRC) end --- Return a checker suitable for out-of-range checking on friendly units, that is, a checker whose range is equal or larger than the requested range. -- @param range the range to check for. -- @return **checker**, **range** pair or **nil** if no suitable checker is available. **range** is the actual range the returned **checker** checks for. function lib:GetFriendMinChecker(range) - return getMinChecker(self.friendRC, range) + return getMinChecker(self.friendRC, range) end --- Return a checker suitable for out-of-range checking on enemy units, that is, a checker whose range is equal or larger than the requested range. -- @param range the range to check for. -- @return **checker**, **range** pair or **nil** if no suitable checker is available. **range** is the actual range the returned **checker** checks for. function lib:GetHarmMinChecker(range) - return getMinChecker(self.harmRC, range) + return getMinChecker(self.harmRC, range) end --- Return a checker suitable for out-of-range checking on miscellaneous units, that is, a checker whose range is equal or larger than the requested range. -- @param range the range to check for. -- @return **checker**, **range** pair or **nil** if no suitable checker is available. **range** is the actual range the returned **checker** checks for. function lib:GetMiscMinChecker(range) - return getMinChecker(self.miscRC, range) + return getMinChecker(self.miscRC, range) end --- Return a checker suitable for in-range checking on friendly units, that is, a checker whose range is equal or smaller than the requested range. -- @param range the range to check for. -- @return **checker**, **range** pair or **nil** if no suitable checker is available. **range** is the actual range the returned **checker** checks for. function lib:GetFriendMaxChecker(range) - return getMaxChecker(self.friendRC, range) + return getMaxChecker(self.friendRC, range) end --- Return a checker suitable for in-range checking on enemy units, that is, a checker whose range is equal or smaller than the requested range. -- @param range the range to check for. -- @return **checker**, **range** pair or **nil** if no suitable checker is available. **range** is the actual range the returned **checker** checks for. function lib:GetHarmMaxChecker(range) - return getMaxChecker(self.harmRC, range) + return getMaxChecker(self.harmRC, range) end --- Return a checker suitable for in-range checking on miscellaneous units, that is, a checker whose range is equal or smaller than the requested range. -- @param range the range to check for. -- @return **checker**, **range** pair or **nil** if no suitable checker is available. **range** is the actual range the returned **checker** checks for. function lib:GetMiscMaxChecker(range) - return getMaxChecker(self.miscRC, range) + return getMaxChecker(self.miscRC, range) end --- Return a checker for the given range for friendly units. -- @param range the range to check for. -- @return **checker** function or **nil** if no suitable checker is available. function lib:GetFriendChecker(range) - return getChecker(self.friendRC, range) + return getChecker(self.friendRC, range) end --- Return a checker for the given range for enemy units. -- @param range the range to check for. -- @return **checker** function or **nil** if no suitable checker is available. function lib:GetHarmChecker(range) - return getChecker(self.harmRC, range) + return getChecker(self.harmRC, range) end --- Return a checker for the given range for miscellaneous units. -- @param range the range to check for. -- @return **checker** function or **nil** if no suitable checker is available. function lib:GetMiscChecker(range) - return getChecker(self.miscRC, range) + return getChecker(self.miscRC, range) end --- Return a checker suitable for out-of-range checking that checks the unit type and calls the appropriate checker (friend/harm/misc). -- @param range the range to check for. -- @return **checker** function. function lib:GetSmartMinChecker(range) - return createSmartChecker( - getMinChecker(self.friendRC, range), - getMinChecker(self.harmRC, range), - getMinChecker(self.miscRC, range)) + return createSmartChecker(getMinChecker(self.friendRC, range), getMinChecker(self.harmRC, range), getMinChecker(self.miscRC, range)) end --- Return a checker suitable for in-range checking that checks the unit type and calls the appropriate checker (friend/harm/misc). -- @param range the range to check for. -- @return **checker** function. function lib:GetSmartMaxChecker(range) - return createSmartChecker( - getMaxChecker(self.friendRC, range), - getMaxChecker(self.harmRC, range), - getMaxChecker(self.miscRC, range)) + return createSmartChecker(getMaxChecker(self.friendRC, range), getMaxChecker(self.harmRC, range), getMaxChecker(self.miscRC, range)) end --- Return a checker for the given range that checks the unit type and calls the appropriate checker (friend/harm/misc). @@ -1073,10 +1073,7 @@ end -- @param fallback optional fallback function that gets called as fallback(unit) if a checker is not available for the given type (friend/harm/misc) at the requested range. The default fallback function return nil. -- @return **checker** function. function lib:GetSmartChecker(range, fallback) - return createSmartChecker( - getChecker(self.friendRC, range) or fallback, - getChecker(self.harmRC, range) or fallback, - getChecker(self.miscRC, range) or fallback) + return createSmartChecker(getChecker(self.friendRC, range) or fallback, getChecker(self.harmRC, range) or fallback, getChecker(self.miscRC, range) or fallback) end --- Get a range estimate as **minRange**, **maxRange**. @@ -1091,15 +1088,15 @@ end -- local minRange, maxRange = rc:GetRange('target') -- local minRangeIfVisible, maxRangeIfVisible = rc:GetRange('target', true) function lib:GetRange(unit, checkVisible, noItems, maxCacheAge) - if not UnitExists(unit) then - return nil - end + if not UnitExists(unit) then + return nil + end - if checkVisible and not UnitIsVisible(unit) then - return nil - end + if checkVisible and not UnitIsVisible(unit) then + return nil + end - return getCachedRange(unit, noItems, maxCacheAge) + return getCachedRange(unit, noItems, maxCacheAge) end -- keep this for compatibility @@ -1108,422 +1105,457 @@ lib.getRange = lib.GetRange -- >> Public API function lib:OnEvent(event, ...) - if type(self[event]) == 'function' then - self[event](self, event, ...) - end + if type(self[event]) == "function" then + self[event](self, event, ...) + end end function lib:LEARNED_SPELL_IN_TAB() - self:scheduleInit() + self:scheduleInit() end function lib:CHARACTER_POINTS_CHANGED() - self:scheduleInit() + self:scheduleInit() end function lib:PLAYER_TALENT_UPDATE() - self:scheduleInit() + self:scheduleInit() end function lib:SPELLS_CHANGED() - self:scheduleInit() + self:scheduleInit() end function lib:UNIT_INVENTORY_CHANGED(event, unit) - if self.initialized and unit == "player" and self.handSlotItem ~= GetInventoryItemLink("player", HandSlotId) then - self:scheduleInit() - end + if self.initialized and unit == "player" and self.handSlotItem ~= GetInventoryItemLink("player", HandSlotId) then + self:scheduleInit() + end end function lib:UNIT_AURA(event, unit) - if self.initialized and unit == "player" then - self:scheduleAuraCheck() - end + if self.initialized and unit == "player" then + self:scheduleAuraCheck() + end end function lib:GET_ITEM_INFO_RECEIVED(event, item, success) - -- print("### GET_ITEM_INFO_RECEIVED: " .. tostring(item) .. ", " .. tostring(success)) - if item == pendingItemRequest then - pendingItemRequest = nil - if not success then - self.failedItemRequests[item] = true - end - lastUpdate = UpdateDelay + -- print("### GET_ITEM_INFO_RECEIVED: " .. tostring(item) .. ", " .. tostring(success)) + if item == pendingItemRequest then + pendingItemRequest = nil + if not success then + self.failedItemRequests[item] = true end + lastUpdate = UpdateDelay + end end function lib:processItemRequests(itemRequests) + while true do + local range, items = next(itemRequests) + if not range then + return + end while true do - local range, items = next(itemRequests) - if not range then return end - while true do - local i, item = next(items) - if not i then - itemRequests[range] = nil - break - elseif self.failedItemRequests[item] then - -- print("### processItemRequests: failed: " .. tostring(item)) - tremove(items, i) - elseif item == pendingItemRequest and GetTime() < itemRequestTimeoutAt then - return true; -- still waiting for server response - elseif GetItemInfo(item) then - -- print("### processItemRequests: found: " .. tostring(item)) - if itemRequestTimeoutAt then - -- print("### processItemRequests: new: " .. tostring(item)) - foundNewItems = true - itemRequestTimeoutAt = nil - pendingItemRequest = nil - end - if not cacheAllItems then - itemRequests[range] = nil - break - end - tremove(items, i) - elseif not itemRequestTimeoutAt then - -- print("### processItemRequests: waiting: " .. tostring(item)) - itemRequestTimeoutAt = GetTime() + ItemRequestTimeout - pendingItemRequest = item - if not self.frame:IsEventRegistered("GET_ITEM_INFO_RECEIVED") then - self.frame:RegisterEvent("GET_ITEM_INFO_RECEIVED") - end - return true - elseif GetTime() >= itemRequestTimeoutAt then - -- print("### processItemRequests: timeout: " .. tostring(item)) - if cacheAllItems then - print(MAJOR_VERSION .. ": timeout for item: " .. tostring(item)) - end - self.failedItemRequests[item] = true - itemRequestTimeoutAt = nil - pendingItemRequest = nil - tremove(items, i) - else - return true -- still waiting for server response - end + local i, item = next(items) + if not i then + itemRequests[range] = nil + break + elseif self.failedItemRequests[item] then + -- print("### processItemRequests: failed: " .. tostring(item)) + tremove(items, i) + elseif item == pendingItemRequest and GetTime() < itemRequestTimeoutAt then + return true -- still waiting for server response + elseif GetItemInfo(item) then + -- print("### processItemRequests: found: " .. tostring(item)) + if itemRequestTimeoutAt then + -- print("### processItemRequests: new: " .. tostring(item)) + foundNewItems = true + itemRequestTimeoutAt = nil + pendingItemRequest = nil end + if not cacheAllItems then + itemRequests[range] = nil + break + end + tremove(items, i) + elseif not itemRequestTimeoutAt then + -- print("### processItemRequests: waiting: " .. tostring(item)) + itemRequestTimeoutAt = GetTime() + ItemRequestTimeout + pendingItemRequest = item + if not self.frame:IsEventRegistered("GET_ITEM_INFO_RECEIVED") then + self.frame:RegisterEvent("GET_ITEM_INFO_RECEIVED") + end + return true + elseif GetTime() >= itemRequestTimeoutAt then + -- print("### processItemRequests: timeout: " .. tostring(item)) + if cacheAllItems then + print(MAJOR_VERSION .. ": timeout for item: " .. tostring(item)) + end + self.failedItemRequests[item] = true + itemRequestTimeoutAt = nil + pendingItemRequest = nil + tremove(items, i) + else + return true -- still waiting for server response + end end + end end function lib:initialOnUpdate() - self:init() - if friendItemRequests then - if self:processItemRequests(friendItemRequests) then return end - friendItemRequests = nil - end - if harmItemRequests then - if self:processItemRequests(harmItemRequests) then return end - harmItemRequests = nil - end - if foundNewItems then - self:init(true) - foundNewItems = nil - end - if cacheAllItems then - print(MAJOR_VERSION .. ": finished cache") - cacheAllItems = nil - end - self.frame:Hide() - self.frame:UnregisterEvent("GET_ITEM_INFO_RECEIVED") + self:init() + if friendItemRequests then + if self:processItemRequests(friendItemRequests) then + return + end + friendItemRequests = nil + end + if harmItemRequests then + if self:processItemRequests(harmItemRequests) then + return + end + harmItemRequests = nil + end + if foundNewItems then + self:init(true) + foundNewItems = nil + end + if cacheAllItems then + print(MAJOR_VERSION .. ": finished cache") + cacheAllItems = nil + end + self.frame:Hide() + self.frame:UnregisterEvent("GET_ITEM_INFO_RECEIVED") end function lib:scheduleInit() - self.initialized = nil - lastUpdate = 0 - self.frame:Show() + self.initialized = nil + lastUpdate = 0 + self.frame:Show() end function lib:scheduleAuraCheck() - lastUpdate = UpdateDelay - self.frame:Show() + lastUpdate = UpdateDelay + self.frame:Show() end --@do-not-package@ -- << DEBUG STUFF local function pairsByKeys(t, f) - local a = {} - for n in pairs(t) do tinsert(a, n) end - sort(a, f) - local i = 0 - local iter = function () - i = i + 1 - if a[i] == nil then - return nil - else - return a[i], t[a[i]] - end + local a = {} + for n in pairs(t) do + tinsert(a, n) + end + sort(a, f) + local i = 0 + local iter = function() + i = i + 1 + if a[i] == nil then + return nil + else + return a[i], t[a[i]] end - return iter + end + return iter end function lib:cacheAllItems() - if (not self.initialized) or harmItemRequests then - print(MAJOR_VERSION .. ": init hasn't finished yet") - return - end - print(MAJOR_VERSION .. ": starting item cache") - initItemRequests(true) - self.frame:Show() + if (not self.initialized) or harmItemRequests then + print(MAJOR_VERSION .. ": init hasn't finished yet") + return + end + print(MAJOR_VERSION .. ": starting item cache") + initItemRequests(true) + self.frame:Show() end function lib:startMeasurement(unit, resultTable) - if (not self.initialized) or harmItemRequests then - print(MAJOR_VERSION .. ": init hasn't finished yet") - return - end - if self.measurements then - print(MAJOR_VERSION .. ": measurements already running") - return - end - print(MAJOR_VERSION .. ": starting measurements") - local _, playerClass = UnitClass("player") - local spellList - local itemList - if UnitCanAttack("player", unit) then - spellList = HarmSpells[playerClass] - itemList = HarmItems - elseif UnitCanAssist("player", unit) then - spellList = FriendSpells[playerClass] - itemList = FriendItems - end - self.spellsToMeasure = {} - if spellList then - for i = 1, #spellList do - local sid = spellList[i] - local name = GetSpellInfo(sid) - local spellIdx = findSpellIdx(name) - if spellIdx then - self.spellsToMeasure[name] = spellIdx - end - end - end - self.itemsToMeasure = {} - if itemList then - for range, items in pairs(itemList) do - for i = 1, #items do - local item = items[i] - local name = GetItemInfo(item) - if name then - self.itemsToMeasure[name] = item - end - end + if (not self.initialized) or harmItemRequests then + print(MAJOR_VERSION .. ": init hasn't finished yet") + return + end + if self.measurements then + print(MAJOR_VERSION .. ": measurements already running") + return + end + print(MAJOR_VERSION .. ": starting measurements") + local _, playerClass = UnitClass("player") + local spellList + local itemList + if UnitCanAttack("player", unit) then + spellList = HarmSpells[playerClass] + itemList = HarmItems + elseif UnitCanAssist("player", unit) then + spellList = FriendSpells[playerClass] + itemList = FriendItems + end + self.spellsToMeasure = {} + if spellList then + for i = 1, #spellList do + local sid = spellList[i] + local name = GetSpellInfo(sid) + local spellIdx = findSpellIdx(name) + if spellIdx then + self.spellsToMeasure[name] = spellIdx + end + end + end + self.itemsToMeasure = {} + if itemList then + for range, items in pairs(itemList) do + for i = 1, #items do + local item = items[i] + local name = GetItemInfo(item) + if name then + self.itemsToMeasure[name] = item end - end - self.measurements = resultTable - self.measurementUnit = unit - self.measurementStart = GetTime() - self.lastMeasurements = {} + end + end + end + self.measurements = resultTable + self.measurementUnit = unit + self.measurementStart = GetTime() + self.lastMeasurements = {} + self:updateMeasurements() + self.frame:SetScript("OnUpdate", function(frame, elapsed) self:updateMeasurements() - self.frame:SetScript("OnUpdate", function(frame, elapsed) self:updateMeasurements() end) - self.frame:Show() + end) + self.frame:Show() end function lib:stopMeasurement() - print(MAJOR_VERSION .. ": stopping measurements") - self.frame:Hide() - self.frame:SetScript("OnUpdate", function(frame, elapsed) - lastUpdate = lastUpdate + elapsed - if lastUpdate < UpdateDelay then - return - end - lastUpdate = 0 - self:initialOnUpdate() - end) - self.measurements = nil + print(MAJOR_VERSION .. ": stopping measurements") + self.frame:Hide() + self.frame:SetScript("OnUpdate", function(frame, elapsed) + lastUpdate = lastUpdate + elapsed + if lastUpdate < UpdateDelay then + return + end + lastUpdate = 0 + self:initialOnUpdate() + end) + self.measurements = nil end function lib:checkItems(itemList, verbose, color) - if not itemList then return end - color = color or 'ffffffff' - for range, items in pairsByKeys(itemList) do - for i = 1, #items do - local item = items[i] - local name = GetItemInfo(item) - if not name then - print(MAJOR_VERSION .. ": |c" .. color .. tostring(item) .. "|r: " .. tostring(range) .. "yd: |cffeda500not in cache|r") - else - local res = IsItemInRange(item, "target") - if res == nil or verbose then - if res == nil then res = "|cffed0000nil|r" end - print(MAJOR_VERSION .. ": |c" .. color .. tostring(item) .. ": " .. tostring(name) .. "|r: " .. tostring(range) .. "yd: " .. tostring(res)) - end - end + if not itemList then + return + end + color = color or "ffffffff" + for range, items in pairsByKeys(itemList) do + for i = 1, #items do + local item = items[i] + local name = GetItemInfo(item) + if not name then + print(MAJOR_VERSION .. ": |c" .. color .. tostring(item) .. "|r: " .. tostring(range) .. "yd: |cffeda500not in cache|r") + else + local res = IsItemInRange(item, "target") + if res == nil or verbose then + if res == nil then + res = "|cffed0000nil|r" + end + print(MAJOR_VERSION .. ": |c" .. color .. tostring(item) .. ": " .. tostring(name) .. "|r: " .. tostring(range) .. "yd: " .. tostring(res)) end + end end + end end function lib:checkSpells(spellList, verbose, color) - if not spellList then return end - color = color or 'ffffffff' - for i = 1, #spellList do - local sid = spellList[i] - local name, _, _, _, minRange, range = GetSpellInfo(sid) - if (not name) or (name == "") or (not range) then - print(MAJOR_VERSION .. ": |c" .. color .. tostring(sid) .. "|r: " .. tostring(range) .. "yd: |cffeda500invalid spell id|r") - else - local spellIdx = self:findSpellIndex(sid) - if not spellIdx then - print(MAJOR_VERSION .. ": |c" .. color .. tostring(sid) .. ": " .. tostring(name) .. "|r: " .. tostring(minRange) .. "-" .. tostring(range) .. "yd: |cffeda500not in spellbook|r") - else - local res = IsSpellInRange(spellIdx, BOOKTYPE_SPELL, "target") - if res == nil or verbose then - if res == nil then res = "|cffed0000nil|r" end - print(MAJOR_VERSION .. ": |c" .. color .. tostring(sid) .. ": " .. tostring(name) .. "|r: " .. tostring(minRange) .. "-" .. tostring(range) .. "yd: " .. tostring(res)) - end - end + if not spellList then + return + end + color = color or "ffffffff" + for i = 1, #spellList do + local sid = spellList[i] + local name, _, _, _, minRange, range = GetSpellInfo(sid) + if (not name) or (name == "") or not range then + print(MAJOR_VERSION .. ": |c" .. color .. tostring(sid) .. "|r: " .. tostring(range) .. "yd: |cffeda500invalid spell id|r") + else + local spellIdx = self:findSpellIndex(sid) + if not spellIdx then + print( + MAJOR_VERSION + .. ": |c" + .. color + .. tostring(sid) + .. ": " + .. tostring(name) + .. "|r: " + .. tostring(minRange) + .. "-" + .. tostring(range) + .. "yd: |cffeda500not in spellbook|r" + ) + else + local res = IsSpellInRange(spellIdx, BOOKTYPE_SPELL, "target") + if res == nil or verbose then + if res == nil then + res = "|cffed0000nil|r" + end + print(MAJOR_VERSION .. ": |c" .. color .. tostring(sid) .. ": " .. tostring(name) .. "|r: " .. tostring(minRange) .. "-" .. tostring(range) .. "yd: " .. tostring(res)) end + end end + end end function lib:checkAllItems() - print(MAJOR_VERSION .. ": Checking FriendItems...") - self:checkItems(FriendItems, true, FriendColor) - print(MAJOR_VERSION .. ": Checking HarmItems...") - self:checkItems(HarmItems, true, HarmColor) + print(MAJOR_VERSION .. ": Checking FriendItems...") + self:checkItems(FriendItems, true, FriendColor) + print(MAJOR_VERSION .. ": Checking HarmItems...") + self:checkItems(HarmItems, true, HarmColor) end function lib:checkAllSpells() - local _, playerClass = UnitClass("player") - print(MAJOR_VERSION .. ": Checking FriendSpells: " .. playerClass) - self:checkSpells(FriendSpells[playerClass], true, FriendColor) - print(MAJOR_VERSION .. ": Checking HarmSpells..." .. playerClass) - self:checkSpells(HarmSpells[playerClass], true, HarmColor) + local _, playerClass = UnitClass("player") + print(MAJOR_VERSION .. ": Checking FriendSpells: " .. playerClass) + self:checkSpells(FriendSpells[playerClass], true, FriendColor) + print(MAJOR_VERSION .. ": Checking HarmSpells..." .. playerClass) + self:checkSpells(HarmSpells[playerClass], true, HarmColor) end local function dumpCheckerList(checkerList) - for _, rc in ipairs(checkerList) do - if rc.minRange then - print(rc.minRange .. "-" .. rc.range .. ": " .. rc.info) - else - print(rc.range .. ": " .. rc.info) - end + for _, rc in ipairs(checkerList) do + if rc.minRange then + print(rc.minRange .. "-" .. rc.range .. ": " .. rc.info) + else + print(rc.range .. ": " .. rc.info) end + end end function lib:checkAllCheckers() - if not UnitExists("target") then - print(MAJOR_VERSION .. ": Invalid unit, cannot check") - return - end - local _, playerClass = UnitClass("player") - if UnitCanAttack("player", "target") then - print(MAJOR_VERSION .. ": Harm checker list: " .. playerClass) - dumpCheckerList(self.harmRC) - print(MAJOR_VERSION .. ": Checking HarmCheckers: " .. playerClass) - self:checkItems(HarmItems) - self:checkSpells(HarmSpells[playerClass]) - elseif UnitCanAssist("player", "target") then - print(MAJOR_VERSION .. ": Friend checker list: " .. playerClass) - dumpCheckerList(self.friendRC) - print(MAJOR_VERSION .. ": Checking FriendCheckers: ") - self:checkItems(FriendItems) - self:checkSpells(FriendSpells[playerClass]) - else - print(MAJOR_VERSION .. ": Misc checker list: " .. playerClass) - dumpCheckerList(self.miscRC) - print(MAJOR_VERSION .. ": Misc unit, cannot check") - return - end - print(MAJOR_VERSION .. ": done.") + if not UnitExists("target") then + print(MAJOR_VERSION .. ": Invalid unit, cannot check") + return + end + local _, playerClass = UnitClass("player") + if UnitCanAttack("player", "target") then + print(MAJOR_VERSION .. ": Harm checker list: " .. playerClass) + dumpCheckerList(self.harmRC) + print(MAJOR_VERSION .. ": Checking HarmCheckers: " .. playerClass) + self:checkItems(HarmItems) + self:checkSpells(HarmSpells[playerClass]) + elseif UnitCanAssist("player", "target") then + print(MAJOR_VERSION .. ": Friend checker list: " .. playerClass) + dumpCheckerList(self.friendRC) + print(MAJOR_VERSION .. ": Checking FriendCheckers: ") + self:checkItems(FriendItems) + self:checkSpells(FriendSpells[playerClass]) + else + print(MAJOR_VERSION .. ": Misc checker list: " .. playerClass) + dumpCheckerList(self.miscRC) + print(MAJOR_VERSION .. ": Misc unit, cannot check") + return + end + print(MAJOR_VERSION .. ": done.") end local function logMeasurementChange(t, t0, key, last, curr) - local d = 0 - local scale = 1240 - if t0 then - local dx = scale * (t.x - t0.x) - local dy = scale * (t.y - t0.y) - d = _G.sqrt(dx * dx + dy * dy) - end - print(MAJOR_VERSION .. ": t=" .. ("%.4f"):format(t.stamp) .. ": d=" .. ("%.4f"):format(d) .. ": " .. tostring(key) .. ": " .. tostring(last) .. " -> " .. tostring(curr)) -end - -local GetPlayerMapPosition = GetPlayerMapPosition or function(unit) + local d = 0 + local scale = 1240 + if t0 then + local dx = scale * (t.x - t0.x) + local dy = scale * (t.y - t0.y) + d = _G.sqrt(dx * dx + dy * dy) + end + print(MAJOR_VERSION .. ": t=" .. ("%.4f"):format(t.stamp) .. ": d=" .. ("%.4f"):format(d) .. ": " .. tostring(key) .. ": " .. tostring(last) .. " -> " .. tostring(curr)) +end + +local GetPlayerMapPosition = GetPlayerMapPosition + or function(unit) local map = C_Map.GetBestMapForUnit(unit) local pos = C_Map.GetPlayerMapPosition(map, unit) return pos:GetXY() -end + end function lib:updateMeasurements() - local now = GetTime() - self.measurementStart - local x, y = GetPlayerMapPosition("player") - local t0 = self.measurements[0] - local t = self.measurements[now] - local unit = self.measurementUnit - for name, id in pairs(self.spellsToMeasure) do - local key = 'spell: ' .. name - local last = self.lastMeasurements[key] - local curr = (IsSpellInRange(id, BOOKTYPE_SPELL, unit) == 1) and true or false - if last == nil or last ~= curr then - if not t then - t = {} - t.x, t.y, t.stamp, t.states = x, y, now, {} - self.measurements[now] = t - end - logMeasurementChange(t, t0, key, last, curr) - t.states[key]= curr - self.lastMeasurements[key] = curr - end - end - for name, item in pairs(self.itemsToMeasure) do - local key = 'item: ' .. name; - local last = self.lastMeasurements[key] - local curr = IsItemInRange(item, unit) and true or false - if last == nil or last ~= curr then - if not t then - t = {} - t.x, t.y, t.stamp, t.states = x, y, now, {} - self.measurements[now] = t - end - logMeasurementChange(t, t0, key, last, curr) - t.states[key]= curr - self.lastMeasurements[key] = curr - end - end - for i, v in pairs(DefaultInteractList) do - local key = 'interact: ' .. i - local last = self.lastMeasurements[key] - local curr = CheckInteractDistance(unit, i) and true or false - if last == nil or last ~= curr then - if not t then - t = {} - t.x, t.y, t.stamp, t.states = x, y, now, {} - self.measurements[now] = t - end - logMeasurementChange(t, t0, key, last, curr) - t.states[key] = curr - self.lastMeasurements[key] = curr - end - end + local now = GetTime() - self.measurementStart + local x, y = GetPlayerMapPosition("player") + local t0 = self.measurements[0] + local t = self.measurements[now] + local unit = self.measurementUnit + for name, id in pairs(self.spellsToMeasure) do + local key = "spell: " .. name + local last = self.lastMeasurements[key] + local curr = (IsSpellInRange(id, BOOKTYPE_SPELL, unit) == 1) and true or false + if last == nil or last ~= curr then + if not t then + t = {} + t.x, t.y, t.stamp, t.states = x, y, now, {} + self.measurements[now] = t + end + logMeasurementChange(t, t0, key, last, curr) + t.states[key] = curr + self.lastMeasurements[key] = curr + end + end + for name, item in pairs(self.itemsToMeasure) do + local key = "item: " .. name + local last = self.lastMeasurements[key] + local curr = IsItemInRange(item, unit) and true or false + if last == nil or last ~= curr then + if not t then + t = {} + t.x, t.y, t.stamp, t.states = x, y, now, {} + self.measurements[now] = t + end + logMeasurementChange(t, t0, key, last, curr) + t.states[key] = curr + self.lastMeasurements[key] = curr + end + end + for i, v in pairs(DefaultInteractList) do + local key = "interact: " .. i + local last = self.lastMeasurements[key] + local curr = CheckInteractDistance(unit, i) and true or false + if last == nil or last ~= curr then + if not t then + t = {} + t.x, t.y, t.stamp, t.states = x, y, now, {} + self.measurements[now] = t + end + logMeasurementChange(t, t0, key, last, curr) + t.states[key] = curr + self.lastMeasurements[key] = curr + end + end end local debugprofilestop = debugprofilestop function lib:speedTest(numBatches, numIterationsPerBatch) - if not UnitExists("target") then - print(MAJOR_VERSION .. ": Invalid unit, cannot check") - return - end + if not UnitExists("target") then + print(MAJOR_VERSION .. ": Invalid unit, cannot check") + return + end - numBatches = numBatches or 10000 - numIterationsPerBatch = numIterationsPerBatch or 1 + numBatches = numBatches or 10000 + numIterationsPerBatch = numIterationsPerBatch or 1 - local min, max, total = 999999, 0, 0 - for b = 1, numBatches do - resetRangeCache() - local start = debugprofilestop() - for i = 1, numIterationsPerBatch do - self:getRange("target") - end - local duration = debugprofilestop() - start + local min, max, total = 999999, 0, 0 + for b = 1, numBatches do + resetRangeCache() + local start = debugprofilestop() + for i = 1, numIterationsPerBatch do + self:getRange("target") + end + local duration = debugprofilestop() - start - if duration < min then min = duration end - if duration > max then max = duration end - total = total + duration + if duration < min then + min = duration end + if duration > max then + max = duration + end + total = total + duration + end - local minRange, maxRange = self:getRange("target"); + local minRange, maxRange = self:getRange("target") - print(string.format("SpeedTest: numBatches = %d, numIterationsPerBatch = %d", numBatches, numIterationsPerBatch)) - print(string.format(" Range: min = %d, max = %d", minRange, maxRange)) - print(string.format(" Time per batch: min = %f, max = %f, total = %f, avg = %f", min, max, total, total/numBatches)) + print(string.format("SpeedTest: numBatches = %d, numIterationsPerBatch = %d", numBatches, numIterationsPerBatch)) + print(string.format(" Range: min = %d, max = %d", minRange, maxRange)) + print(string.format(" Time per batch: min = %f, max = %f, total = %f, avg = %f", min, max, total, total / numBatches)) end -- >> DEBUG STUFF @@ -1532,63 +1564,66 @@ end -- << load-time initialization function lib:activate() - if not self.frame then - local frame = CreateFrame("Frame") - self.frame = frame - - frame:RegisterEvent("LEARNED_SPELL_IN_TAB") - frame:RegisterEvent("CHARACTER_POINTS_CHANGED") - frame:RegisterEvent("SPELLS_CHANGED") + if not self.frame then + local frame = CreateFrame("Frame") + self.frame = frame - if isRetail or isWrath then - frame:RegisterEvent("PLAYER_TALENT_UPDATE") - end + frame:RegisterEvent("LEARNED_SPELL_IN_TAB") + frame:RegisterEvent("CHARACTER_POINTS_CHANGED") + frame:RegisterEvent("SPELLS_CHANGED") - local _, playerClass = UnitClass("player") - if playerClass == "MAGE" or playerClass == "SHAMAN" then - -- Mage and Shaman gladiator gloves modify spell ranges - frame:RegisterUnitEvent("UNIT_INVENTORY_CHANGED", "player") - end + if isRetail or isWrath then + frame:RegisterEvent("PLAYER_TALENT_UPDATE") end - if not self.cacheResetTimer then - self.cacheResetTimer = C_Timer.NewTicker(5, function() - invalidateRangeCache(5) - end) + local _, playerClass = UnitClass("player") + if playerClass == "MAGE" or playerClass == "SHAMAN" then + -- Mage and Shaman gladiator gloves modify spell ranges + frame:RegisterUnitEvent("UNIT_INVENTORY_CHANGED", "player") end + end - initItemRequests() - - self.frame:SetScript("OnEvent", function(_, ...) self:OnEvent(...) end) - self.frame:SetScript("OnUpdate", function(_, elapsed) - lastUpdate = lastUpdate + elapsed - if lastUpdate < UpdateDelay then - return - end - lastUpdate = 0 - self:initialOnUpdate() + if not self.cacheResetTimer then + self.cacheResetTimer = C_Timer.NewTicker(5, function() + invalidateRangeCache(5) end) + end - self:scheduleInit() + initItemRequests() + + self.frame:SetScript("OnEvent", function(_, ...) + self:OnEvent(...) + end) + self.frame:SetScript("OnUpdate", function(_, elapsed) + lastUpdate = lastUpdate + elapsed + if lastUpdate < UpdateDelay then + return + end + lastUpdate = 0 + self:initialOnUpdate() + end) + + self:scheduleInit() end --- BEGIN CallbackHandler stuff do - --- Register a callback to get called when checkers are updated - -- @class function - -- @name lib.RegisterCallback - -- @usage - -- rc.RegisterCallback(self, rc.CHECKERS_CHANGED, "myCallback") - -- -- or - -- rc.RegisterCallback(self, "CHECKERS_CHANGED", someCallbackFunction) - -- @see CallbackHandler-1.0 documentation for more details - lib.RegisterCallback = lib.RegisterCallback or function(...) - local CBH = LibStub("CallbackHandler-1.0") - lib.RegisterCallback = nil -- extra safety, we shouldn't get this far if CBH is not found, but better an error later than an infinite recursion now - lib.callbacks = CBH:New(lib) - -- ok, CBH hopefully injected or new shiny RegisterCallback - return lib.RegisterCallback(...) + --- Register a callback to get called when checkers are updated + -- @class function + -- @name lib.RegisterCallback + -- @usage + -- rc.RegisterCallback(self, rc.CHECKERS_CHANGED, "myCallback") + -- -- or + -- rc.RegisterCallback(self, "CHECKERS_CHANGED", someCallbackFunction) + -- @see CallbackHandler-1.0 documentation for more details + lib.RegisterCallback = lib.RegisterCallback + or function(...) + local CBH = LibStub("CallbackHandler-1.0") + lib.RegisterCallback = nil -- extra safety, we shouldn't get this far if CBH is not found, but better an error later than an infinite recursion now + lib.callbacks = CBH:New(lib) + -- ok, CBH hopefully injected or new shiny RegisterCallback + return lib.RegisterCallback(...) end end