├── externals.txt
├── .pkgmeta
├── modules
├── Hunter.lua
├── Priest.lua
├── Shaman.lua
├── Warrior.lua
├── DeathKnight.lua
├── Druid.lua
├── Warlock.lua
├── PilgrimsBountyRep.lua
├── DarkmoonExp.lua
├── Minipet.lua
├── Talents.lua
├── BonusEvents.lua
├── GarrisonMissions.lua
├── WarlockHealthstone.lua
├── RogueWeapon.lua
├── Monk.lua
├── PaladinSeal.lua
├── WarlockSoulLink.lua
├── ArtifactPowerItems.lua
├── FishingHat.lua
├── GarrisonBodyguardMinifier.lua
├── Mage.lua
├── BuffItems.lua
├── GarrisonFreeFood.lua
├── Salvage.lua
├── GarrisonCache.lua
├── GarrisonMineItems.lua
├── ClassHallWorkOrders.lua
├── GarrisonBuildings.lua
├── Lures.lua
├── QuestStartingItems.lua
├── BattleStandard.lua
├── OpenableItems.lua
├── Capsules.lua
├── GarrisonWorkOrders.lua
├── LancePole.lua
├── Combine.lua
├── Repairs.lua
├── Paladin.lua
├── Tracking.lua
├── WarlockPets.lua
└── WellFed.lua
├── Bindings.xml
├── AceEvent-3.0
├── AceEvent-3.0.xml
└── AceEvent-3.0.lua
├── tekKonfig
├── tekKonfig.xml
├── tekKonfigHeading.lua
├── tekKonfigFadeIn.lua
├── tekKonfigGroup.lua
├── LibStub.lua
├── tekKonfigCheckbox.lua
├── tekKonfigButton.lua
├── tekKonfigSlider.lua
├── tekKonfigScroll.lua
└── tekKonfigDropdown.lua
├── services
└── holiday_active.lua
├── Locale.lua
├── KeyBlacklist.lua
├── Mousewheel.lua
├── templates
├── ItemSelfBuffer.lua
├── SelfBuffer.lua
├── RaidBuffingItems.lua
├── RaidBuffer.lua
├── SelfBufferAdvanced.lua
├── LastBuffedBuffer.lua
└── TempEnchant.lua
├── README.md
├── externals
├── timer.lua
├── tooltip_scanner.lua
└── ui-tab.lua
├── MacroGenerator.lua
├── Cork.toc
├── LibDataBroker-1.1
└── LibDataBroker-1.1.lua
├── Config.lua
├── CallbackHandler-1.0.lua
├── Cork.lua
└── changelog.txt
/externals.txt:
--------------------------------------------------------------------------------
1 | timer.lua
2 | tooltip_scanner.lua
3 | ui-tab.lua
4 |
--------------------------------------------------------------------------------
/.pkgmeta:
--------------------------------------------------------------------------------
1 | manual-changelog:
2 | filename: changelog.txt
3 | markup-type: markdown
4 |
--------------------------------------------------------------------------------
/modules/Hunter.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "HUNTER" then return end
4 |
--------------------------------------------------------------------------------
/modules/Priest.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "PRIEST" then return end
4 |
--------------------------------------------------------------------------------
/modules/Shaman.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "SHAMAN" then return end
4 |
--------------------------------------------------------------------------------
/modules/Warrior.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "WARRIOR" then return end
4 |
--------------------------------------------------------------------------------
/Bindings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -- Click the CorkFrame
4 |
5 |
6 |
--------------------------------------------------------------------------------
/AceEvent-3.0/AceEvent-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/modules/DeathKnight.lua:
--------------------------------------------------------------------------------
1 | local myname, Cork = ...
2 | if Cork.MYCLASS ~= "DEATHKNIGHT" then return end
3 |
4 | -- Path of Frost
5 | local spellname, _, icon = GetSpellInfo(3714)
6 | Cork:GenerateSelfBuffer(spellname, icon)
7 |
8 |
9 | -- Horn of Winter
10 | local spellname, _, icon = GetSpellInfo(57330)
11 | local str_earth = GetSpellInfo(58646) -- Strength of Earth
12 | Cork:GenerateSelfBuffer(spellname, icon, str_earth)
13 |
--------------------------------------------------------------------------------
/tekKonfig/tekKonfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/modules/Druid.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "DRUID" then return end
4 |
5 |
6 | -- Shapeshifts
7 | local dobj, ref = Cork:GenerateAdvancedSelfBuffer("Fursuit", {768, 5487, 24858})
8 | function dobj:CorkIt(frame)
9 | ref()
10 | local spell = Cork.dbpc["Fursuit-spell"]
11 | if self.player and Corkboard:NumLines() == 1 then
12 | return frame:SetManyAttributes("type1", "spell", "spell", spell, "unit", "player")
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/services/holiday_active.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 |
4 |
5 | function ns.IsHolidayActive(name)
6 | local _, _, day = CalendarGetDate()
7 | local title, hour, sequenceType
8 | local i = 1
9 | repeat
10 | title, hour, _, _, sequenceType = CalendarGetDayEvent(0, day, i)
11 | if title == name then
12 | if sequenceType == "START" then
13 | return GetGameTime() >= hour
14 | elseif sequenceType == "END" then
15 | return GetGameTime() < hour
16 | else
17 | return true
18 | end
19 | end
20 | i = i + 1
21 | until not title
22 | end
23 |
--------------------------------------------------------------------------------
/Locale.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 |
4 |
5 | ns.classnames = {
6 | ["WARLOCK"] = "Warlock",
7 | ["WARRIOR"] = "Warrior",
8 | ["HUNTER"] = "Hunter",
9 | ["MAGE"] = "Mage",
10 | ["PRIEST"] = "Priest",
11 | ["DRUID"] = "Druid",
12 | ["PALADIN"] = "Paladin",
13 | ["SHAMAN"] = "Shaman",
14 | ["ROGUE"] = "Rogue",
15 | ["DEATHKNIGHT"] = "Death Knight",
16 | ["MONK"] = "Monk",
17 | ["DEMONHUNTER"] = "Demon Hunter",
18 | }
19 |
20 | ns.colors = {}
21 | for token in pairs(ns.classnames) do
22 | local c = RAID_CLASS_COLORS[token]
23 | ns.colors[token] = string.format("%02x%02x%02x", c.r*255, c.g*255, c.b*255)
24 | end
25 |
--------------------------------------------------------------------------------
/KeyBlacklist.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 |
4 | local keys = {
5 | "configframe",
6 | "CanCorkStealthed",
7 | "CorkIt",
8 | "corktype",
9 | "icon",
10 | "iconline",
11 | "Init",
12 | "GROUP_ROSTER_UPDATE",
13 | "ignoreplayer",
14 | "itemid",
15 | "items",
16 | "lasttarget",
17 | "name",
18 | "nobg",
19 | "oldtest",
20 | "partyonly",
21 | "priority",
22 | "RaidLine",
23 | "Scan",
24 | "slot",
25 | "sortname",
26 | "spellname",
27 | "spells",
28 | "Test",
29 | "TestWithoutResting",
30 | "tiplink",
31 | "tiptext",
32 | "toyname",
33 | "type",
34 | "UNIT_AURA",
35 | "UNIT_INVENTORY_CHANGED",
36 | "UNIT_PET",
37 | }
38 |
39 | ns.keyblist = {}
40 | for i,key in pairs(keys) do ns.keyblist[key] = true end
41 |
--------------------------------------------------------------------------------
/modules/Warlock.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "WARLOCK" then return end
4 |
5 |
6 | -- Grimoire of Sacrifice
7 | local spellname, _, icon = GetSpellInfo(108503)
8 | Cork:GenerateSelfBuffer(spellname, icon)
9 |
10 |
11 | -- Soulstone
12 | local spellname, _, icon = GetSpellInfo(20707)
13 | local dataobj = Cork:GenerateLastBuffedBuffer(spellname, icon)
14 |
15 | local wasgrouped
16 | local oldGRU = dataobj.GROUP_ROSTER_UPDATE
17 | function dataobj:GROUP_ROSTER_UPDATE(...)
18 | local nowgrouped = IsInGroup()
19 | if wasgrouped and not nowgrouped then
20 | dataobj.onlyrebuffs = false
21 | dataobj.lasttarget = nil
22 | elseif not wasgrouped and nowgrouped then
23 | dataobj.onlyrebuffs = true
24 | dataobj.lasttarget = nil
25 | end
26 |
27 | wasgrouped = nowgrouped
28 |
29 | return oldGRU(self, ...)
30 | end
31 |
--------------------------------------------------------------------------------
/tekKonfig/tekKonfigHeading.lua:
--------------------------------------------------------------------------------
1 |
2 | local lib, oldminor = LibStub:NewLibrary("tekKonfig-Heading", 1)
3 | if not lib then return end
4 |
5 |
6 | -- Creates a heading and subheading
7 | -- parent is required, texts are optional
8 | function lib.new(parent, text, subtext)
9 | local title = parent:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
10 | title:SetPoint("TOPLEFT", 16, -16)
11 | title:SetText(text)
12 |
13 | local subtitle = parent:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
14 | subtitle:SetHeight(32)
15 | subtitle:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -8)
16 | subtitle:SetPoint("RIGHT", parent, -32, 0)
17 | --~ nonSpaceWrap="true" maxLines="3"
18 | subtitle:SetNonSpaceWrap(true)
19 | subtitle:SetJustifyH("LEFT")
20 | subtitle:SetJustifyV("TOP")
21 | subtitle:SetText(subtext)
22 |
23 | return title, subtitle
24 | end
25 |
--------------------------------------------------------------------------------
/tekKonfig/tekKonfigFadeIn.lua:
--------------------------------------------------------------------------------
1 |
2 | local lib, oldminor = LibStub:NewLibrary("tekKonfig-FadeIn", 1)
3 | if not lib then return end
4 |
5 |
6 | local starttimes, endtimes, OnUpdates = {}, {}, {}
7 | local function OnUpdate(frame)
8 | local time = GetTime()
9 | if time >= (starttimes[frame] + endtimes[frame]) then
10 | frame:SetScript("OnUpdate", OnUpdates[frame])
11 | frame:SetAlpha(1)
12 | else frame:SetAlpha((time - starttimes[frame])/endtimes[frame]) end
13 | end
14 |
15 | -- Fades in a frame, if time is not passed 0.5sec is used
16 | function lib.FadeIn(frame, time)
17 | time = time or 0.5
18 | assert(frame, "No frame passed")
19 | assert(time > 0, "Time must be positive")
20 |
21 | starttimes[frame], endtimes[frame], OnUpdates[frame] = GetTime(), time, frame:GetScript("OnUpdate")
22 | frame:SetAlpha(0)
23 | frame:SetScript("OnUpdate", OnUpdate)
24 | end
25 |
--------------------------------------------------------------------------------
/modules/PilgrimsBountyRep.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 | local ae = LibStub("AceEvent-3.0")
4 |
5 |
6 | local maxlevel = GetMaxPlayerLevel()
7 | local itemname = "Pilgrim's Bounty Rep Buff"
8 | local spellname, _, icon = GetSpellInfo(61849)
9 | local dataobj = ns:GenerateSelfBuffer(itemname, icon, spellname)
10 | ns.defaultspc[itemname.."-enabled"] = true
11 |
12 |
13 | local function BountyToday()
14 | return ns.IsHolidayActive("Pilgrim's Bounty")
15 | end
16 |
17 |
18 | function dataobj:Test()
19 | if UnitLevel("player") < maxlevel then return false end
20 | return BountyToday() and self:TestWithoutResting()
21 | end
22 |
23 |
24 | function dataobj:Init()
25 | if UnitLevel("player") == maxlevel then OpenCalendar() end
26 | end
27 |
28 |
29 | ae.RegisterEvent(dataobj, "CALENDAR_UPDATE_EVENT_LIST", "Scan")
30 | dataobj.tiplink = "spell:61849"
31 | dataobj.CorkIt = nil
32 |
--------------------------------------------------------------------------------
/modules/DarkmoonExp.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 | local ae = LibStub("AceEvent-3.0")
4 |
5 |
6 | local maxlevel = GetMaxPlayerLevel()
7 | local itemname = "Darkmoon EXP Buff"
8 | local spellname, _, icon = GetSpellInfo(46668)
9 | local hatspell = GetSpellInfo(136583)
10 | local dataobj = ns:GenerateSelfBuffer(itemname, icon, spellname, hatspell)
11 | ns.defaultspc[itemname.."-enabled"] = true
12 |
13 |
14 | local function DarkmoonToday()
15 | return ns.IsHolidayActive("Darkmoon Faire")
16 | end
17 |
18 |
19 | function dataobj:Test()
20 | if UnitLevel("player") == maxlevel then return false end
21 | return DarkmoonToday() and self:TestWithoutResting()
22 | end
23 |
24 |
25 | function dataobj:Init()
26 | if UnitLevel("player") < maxlevel then OpenCalendar() end
27 | end
28 |
29 |
30 | ae.RegisterEvent(dataobj, "CALENDAR_UPDATE_EVENT_LIST", "Scan")
31 | dataobj.tiplink = "spell:46668"
32 | dataobj.CorkIt = nil
33 |
--------------------------------------------------------------------------------
/modules/Minipet.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 |
4 | local IconLine = Cork.IconLine("Interface\\Icons\\INV_Box_PetCarrier_01", 'Minipet')
5 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
6 |
7 | Cork.defaultspc["Minipet-enabled"] = true
8 |
9 | local dataobj = ldb:NewDataObject("Cork Minipet", {
10 | type = "cork",
11 | priority = 8,
12 | tiptext = "Warn when you don't have a minipet summoned."
13 | })
14 |
15 | function dataobj:Scan()
16 | if Cork.dbpc["Minipet-enabled"] and not C_PetJournal.GetSummonedPetGUID() then
17 | dataobj.player = IconLine
18 | return
19 | end
20 |
21 | dataobj.player = nil
22 | end
23 |
24 | ae.RegisterEvent("Cork Minipet", "COMPANION_UPDATE", dataobj.Scan)
25 |
26 | function dataobj:CorkIt(frame)
27 | if self.player then
28 | local macro = math.random(4) == 1 and '/randompet' or '/randomfavoritepet'
29 | return frame:SetManyAttributes("type1", "macro", "macrotext1", macro)
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/Mousewheel.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 |
4 | -- Dynamic mousewheel binding module, originally created by Adirelle
5 |
6 | local function ClearBindings()
7 | if InCombatLockdown() then return end
8 | ClearOverrideBindings(CorkFrame)
9 | end
10 |
11 | function Cork:UpdateMouseBinding(event, unit)
12 | if InCombatLockdown() then return end
13 | if Cork.db.bindwheel and (event ~= "PLAYER_REGEN_DISABLED") and Corkboard:IsVisible() then
14 | SetOverrideBindingClick(CorkFrame, true, 'MOUSEWHEELUP', 'CorkFrame')
15 | SetOverrideBindingClick(CorkFrame, true, 'MOUSEWHEELDOWN', 'CorkFrame')
16 | else
17 | ClearOverrideBindings(CorkFrame)
18 | end
19 | end
20 |
21 |
22 | local frame = CreateFrame('Frame', nil, Corkboard)
23 | frame:SetScript('OnShow', Cork.UpdateMouseBinding)
24 | frame:SetScript('OnHide', ClearBindings)
25 |
26 | frame:SetScript("OnEvent", Cork.UpdateMouseBinding)
27 | frame:RegisterEvent('PLAYER_REGEN_ENABLED')
28 | frame:RegisterEvent('PLAYER_REGEN_DISABLED')
29 |
--------------------------------------------------------------------------------
/tekKonfig/tekKonfigGroup.lua:
--------------------------------------------------------------------------------
1 |
2 | local lib, oldminor = LibStub:NewLibrary("tekKonfig-Group", 2)
3 | if not lib then return end
4 |
5 | lib.bg = {
6 | bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
7 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
8 | tile = true,
9 | tileSize = 16,
10 | edgeSize = 16,
11 | insets = { left = 5, right = 5, top = 5, bottom = 5 }
12 | }
13 |
14 |
15 | -- Creates a background box to place behind widgets for visual grouping.
16 | -- All args optional, parent highly recommended
17 | function lib.new(parent, label, ...)
18 | local box = CreateFrame('Frame', nil, parent)
19 | box:SetBackdrop(lib.bg)
20 | box:SetBackdropBorderColor(0.4, 0.4, 0.4)
21 | box:SetBackdropColor(0.1, 0.1, 0.1)
22 | if select('#',...) > 0 then box:SetPoint(...) end
23 |
24 | if label then
25 | local fs = box:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
26 | fs:SetPoint("BOTTOMLEFT", box, "TOPLEFT", 16, 0)
27 | fs:SetText(label)
28 | end
29 |
30 | return box
31 | end
32 |
--------------------------------------------------------------------------------
/modules/Talents.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local SpellCastableOnUnit = Cork.SpellCastableOnUnit
4 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
5 |
6 | local IconLine = Cork.IconLine("Interface\\Icons\\Ability_Marksmanship", "Unspent talent points")
7 | Cork.defaultspc["Talents-enabled"] = true
8 |
9 | local dataobj = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject(
10 | "Cork Talents",
11 | {type = "cork", tiptext = "Warn when you have unspent talent points."}
12 | )
13 |
14 | function dataobj:Init()
15 | if Cork.dbpc["Talents-enabled"] then TalentMicroButtonAlert:Hide() end
16 | end
17 |
18 | local function talentlesshack()
19 | return GetNumUnspentTalents() > 0
20 | end
21 | local function Test()
22 | return Cork.dbpc["Talents-enabled"] and talentlesshack() and IconLine
23 | end
24 |
25 | function dataobj:Scan() dataobj.player = Test() end
26 |
27 | ae.RegisterEvent("Cork Talents", "CHARACTER_POINTS_CHANGED", dataobj.Scan)
28 | ae.RegisterEvent("Cork Talents", "PLAYER_TALENT_UPDATE", dataobj.Scan)
29 | ae.RegisterEvent("Cork Talents", "ACTIVE_TALENT_GROUP_CHANGED", dataobj.Scan)
30 |
31 |
32 | TalentMicroButtonAlert:SetScript("OnShow", function(self)
33 | if Cork.dbpc["Talents-enabled"] then self:Hide() end
34 | end)
35 |
--------------------------------------------------------------------------------
/modules/BonusEvents.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 |
4 |
5 | local WQ_QUEST_ID = 44175
6 | local WQ_BUFF, _, WQ_BUFF_ICON = GetSpellInfo(186404)
7 | local WQ_ICONLINE = ns.IconLine(WQ_BUFF_ICON, "Bonus event quest")
8 |
9 |
10 | -- You have to be 110 to get the weekly bonus events
11 | if UnitLevel("player") < 110 then return end
12 |
13 |
14 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
15 |
16 |
17 | local dataobj = ns:New("Bonus Events")
18 | dataobj.tiptext = "Notify you when there is a weekly Bonus Event quest to accept"
19 | dataobj.priority = 15
20 |
21 |
22 | function dataobj:Init()
23 | ns.defaultspc[self.name.."-enabled"] = true
24 | end
25 |
26 |
27 | local completed
28 | local function IsCompleted()
29 | completed = completed or GetQuestsCompleted()[WQ_QUEST_ID]
30 | return completed
31 | end
32 |
33 |
34 | local function Test()
35 | if not UnitAura("player", WQ_BUFF) then return end
36 | if GetQuestLogIndexByID(WQ_QUEST_ID) ~= 0 then return end
37 | if IsCompleted() then return end
38 | return WQ_ICONLINE
39 | end
40 |
41 |
42 | local lastid
43 | function dataobj:Scan()
44 | if not ns.dbpc[self.name.."-enabled"] then
45 | self.player = nil
46 | return
47 | end
48 |
49 | self.player = Test()
50 | end
51 |
52 |
53 | ae.RegisterEvent(dataobj, "QUEST_LOG_UPDATE", "Scan")
54 |
--------------------------------------------------------------------------------
/templates/ItemSelfBuffer.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 | local level = UnitLevel("player")
4 | local ae = LibStub("AceEvent-3.0")
5 |
6 |
7 | local function Init(self)
8 | local itemname = GetItemInfo(self.itemid)
9 | if itemname ~= nil then
10 | self.name = GetItemInfo(self.itemid)
11 | self.spellname = self.name
12 | self.spells = {self.name}
13 | self.iconline = ns.IconLine(GetItemIcon(self.itemid), self.name)
14 | end
15 | local itemID, name, texture, collected = C_ToyBox.GetToyInfo(self.itemid)
16 | self.toyname = name
17 | ns.defaultspc[self.name.."-enabled"] = collected or (GetItemCount(self.itemid) > 0)
18 | end
19 |
20 |
21 | local function CorkIt(self, frame)
22 | if self.player then
23 | local item = self.toyname or ("item:".. self.itemid)
24 | return frame:SetManyAttributes("type1", "item", "item1", item)
25 | end
26 | end
27 |
28 |
29 | function ns:GenerateItemSelfBuffer(itemid, buffid)
30 | local itemname = GetItemInfo(itemid) or ("Unknown item #".. itemid)
31 | local icon = GetItemIcon(itemid)
32 | local buff = buffid and GetSpellInfo(buffid) or itemname
33 |
34 | local dataobj = ns:GenerateSelfBuffer(itemname, icon, buff)
35 | dataobj.tiplink = "item:".. itemid
36 | dataobj.corktype = "item"
37 | dataobj.itemid = itemid
38 | dataobj.Init = Init
39 | dataobj.CorkIt = CorkIt
40 |
41 | return dataobj
42 | end
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Cork is a reminder addon, aimed primarily at buffs. Cork was inspired long ago
2 | by NeedyList, and has been Alpha quality for years. Wrath introduces new buff
3 | query APIs that let me finally make Cork as small as I'd prefer, so I'm finally pushing out a beta-quality version.
4 |
5 | Cork provides, at it's heart, one-click buff casting. Some non-buff reminders
6 | are included as well:
7 |
8 | * Reminders for self-only buffs, auras and shapeshifts
9 | * Reminders for raid-group buffs (ones that cast on multiple targets)
10 | * Reminders for warrior shouts only shown in combat
11 | * Priest Fear Ward (shows whenever fear ward is not on cooldown, must be manually enabled when needed)
12 | * Shaman Earth Shield (tracks the last group member cast on, so you must cast manually the first time)
13 | * Warlock demons
14 | * Warlock Soul Link
15 | * Low durability warnings when resting (in town)
16 | * Clam shucker
17 | * Minimap tracking
18 | * Keybinding (thanks cladhaire)
19 | * Macro-generating button
20 |
21 | ## One-click? How?
22 |
23 | Simple! Make a macro: `/click CorkFrame`. You might wish to add a
24 | `/cast [combat] Some Spell` at the start as well.
25 |
26 | You can also use the keybinding in the default k2eybind UI.
27 |
28 | Be warned, Cork will only cast out of combat. If you want to apply buffs in combat, you'll have to do it manually.
29 |
--------------------------------------------------------------------------------
/modules/GarrisonMissions.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 | local level = UnitLevel("player")
4 | local ae = LibStub("AceEvent-3.0")
5 |
6 |
7 | -- Items only available when you have a lvl3 garrison
8 | if level < 90 then return end
9 |
10 |
11 | local name = "Completed missions"
12 | local iconline = ns.IconLine("Interface\\ICONS\\achievement_raregarrisonquests_x", name)
13 |
14 |
15 | local dataobj = ns:New(name)
16 | dataobj.tiptext = "Notify you when you are in your garrison and have completed missions"
17 | dataobj.priority = 20
18 | ns.defaultspc[name.."-enabled"] = true
19 |
20 |
21 | local function Test(force)
22 | if not ns.InGarrison() then return end
23 |
24 | if force then return true end
25 |
26 | local items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_6_0)
27 | for i,item in ipairs(items) do
28 | if item.isComplete and not item.isBuilding then return true end
29 | end
30 | end
31 |
32 |
33 | function dataobj:Scan(event, ...)
34 | local force = event == "GARRISON_MISSION_FINISHED"
35 |
36 | if ns.dbpc[self.name.."-enabled"] and Test(force) then
37 | self.player = iconline
38 | else
39 | self.player = nil
40 | end
41 | end
42 |
43 |
44 | ae.RegisterEvent(dataobj, "ZONE_CHANGED", "Scan")
45 | ae.RegisterEvent(dataobj, "GARRISON_MISSION_NPC_CLOSED", "Scan")
46 | ae.RegisterEvent(dataobj, "GARRISON_MISSION_FINISHED", "Scan")
47 |
--------------------------------------------------------------------------------
/modules/WarlockHealthstone.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "WARLOCK" then return end
4 |
5 | local myname, Cork = ...
6 | local spellname = GetSpellInfo(6201)
7 | local IconLine = Cork.IconLine(GetItemIcon(5509), spellname)
8 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
9 |
10 | local ITEMS = {5509, 5510, 5511, 5512, 9421, 19004, 19005, 19006, 19007, 19008, 19009, 19010, 19011, 19012, 19013, 22103, 22104, 22105, 36889, 36890, 36891, 36892, 36893, 36894}
11 |
12 | local dataobj = ldb:NewDataObject("Cork Healthstone", {type = "cork", tiptext = "Warn when you do not have a healthstone in your bags."})
13 |
14 | function dataobj:Init()
15 | Cork.defaultspc["Healthstone-enabled"] = GetSpellInfo(spellname)
16 | end
17 |
18 | function dataobj:Scan()
19 | if not Cork.dbpc["Healthstone-enabled"] or (IsResting() and not Cork.db.debug) then
20 | dataobj.player = nil
21 | return
22 | end
23 |
24 | for _,id in pairs(ITEMS) do
25 | if (GetItemCount(id) or 0) > 0 then
26 | dataobj.player = nil
27 | return
28 | end
29 | end
30 | dataobj.player = IconLine
31 | end
32 |
33 | ae.RegisterEvent("Cork Healthstone", "BAG_UPDATE", dataobj.Scan)
34 | ae.RegisterEvent("Cork Healthstone", "PLAYER_UPDATE_RESTING", dataobj.Scan)
35 |
36 | function dataobj:CorkIt(frame)
37 | if dataobj.player then return frame:SetManyAttributes("type1", "spell", "spell", spellname) end
38 | end
39 |
--------------------------------------------------------------------------------
/modules/RogueWeapon.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "ROGUE" then return end
4 |
5 | local ae = LibStub("AceEvent-3.0")
6 |
7 |
8 | local mainhand = GetInventorySlotInfo("MainHandSlot")
9 | local onehandtypes = {
10 | INVTYPE_WEAPON = true,
11 | INVTYPE_WEAPONMAINHAND = true,
12 | INVTYPE_WEAPONOFFHAND = true,
13 | }
14 |
15 |
16 | local function UNIT_INVENTORY_CHANGED(self, event, unit)
17 | if unit == 'player' then self:Scan() end
18 | end
19 |
20 |
21 | local function Test(self, ...)
22 | local id = GetInventoryItemID('player', mainhand)
23 | if not id then return end
24 |
25 | local _, _, _, _, _, _, _, _, slot = GetItemInfo(id)
26 | if not slot or not onehandtypes[slot] then return end
27 |
28 | return self.oldtest(...)
29 | end
30 |
31 |
32 | -- Damage poisons
33 | local dataobj = Cork:GenerateAdvancedSelfBuffer("Lethal Poison", {2823,8679,200802})
34 | dataobj.oldtest = dataobj.Test
35 | dataobj.Test = Test
36 | dataobj.UNIT_INVENTORY_CHANGED = UNIT_INVENTORY_CHANGED
37 | dataobj.CanCorkStealthed = true
38 | ae.RegisterEvent(dataobj, "UNIT_INVENTORY_CHANGED")
39 |
40 |
41 | -- Utility poisons
42 | local dataobj = Cork:GenerateAdvancedSelfBuffer("Non-Lethal Poison", {3408,108211})
43 | dataobj.oldtest = dataobj.Test
44 | dataobj.Test = Test
45 | dataobj.UNIT_INVENTORY_CHANGED = UNIT_INVENTORY_CHANGED
46 | dataobj.CanCorkStealthed = true
47 | ae.RegisterEvent(dataobj, "UNIT_INVENTORY_CHANGED")
48 |
--------------------------------------------------------------------------------
/modules/Monk.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "MONK" then return end
4 |
5 | -- Enlightenment (EXP boost buff)
6 | local UnitAura = Cork.UnitAura or UnitAura
7 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
8 | local spellname, _, icon = GetSpellInfo(130283)
9 | local iconline = Cork.IconLine(icon, spellname)
10 | local dataobj = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject("Cork "..spellname, {
11 | type = "cork",
12 | tiplink = GetSpellLink(130283),
13 | })
14 |
15 | function dataobj:Init()
16 | local level = UnitLevel('player')
17 | Cork.defaultspc[spellname.."-enabled"] = level >= 20 and level < 90
18 | end
19 |
20 | local function Test(unit)
21 | if not Cork.dbpc[spellname.."-enabled"] then return end
22 | if UnitAura("player", spellname) then return end
23 |
24 | -- We only need to check the level 20 quest, they all return true if any one
25 | -- has been completed. It's like the fishing dailies, a random one each day.
26 | if IsQuestFlaggedCompleted(31840) then return end
27 |
28 | local level = UnitLevel('player')
29 | if level < 20 or level >= 90 then return end
30 |
31 | return iconline
32 | end
33 |
34 | function dataobj:Scan() self.player = Test() end
35 |
36 | ae.RegisterEvent(dataobj, "PLAYER_UPDATE_RESTING", "Scan")
37 | ae.RegisterEvent("Cork "..spellname, "UNIT_AURA", function(event, unit)
38 | if unit == "player" then dataobj.player = Test() end
39 | end)
40 |
--------------------------------------------------------------------------------
/modules/PaladinSeal.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "PALADIN" then return end
4 |
5 |
6 | local myname, Cork = ...
7 | local UnitAura = UnitAura
8 | local SpellCastableOnUnit = Cork.SpellCastableOnUnit
9 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
10 |
11 | local spellidlist = {20375, 31892, 53736, 20164, 20165, 21084, 53720, 31801, 20166}
12 |
13 | local iconline = Cork.IconLine(select(3, GetSpellInfo(spellidlist[1])), "No seal!")
14 | local buffnames = {}
15 | for _,id in pairs(spellidlist) do buffnames[id] = GetSpellInfo(id) end
16 |
17 | local defaults = Cork.defaultspc
18 | defaults["Seal-enabled"] = true
19 |
20 | local dataobj = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject("Cork Seal", {type = "cork"})
21 |
22 | local function Test()
23 | if Cork.dbpc["Seal-enabled"] then
24 | for _,buff in pairs(buffnames) do if UnitAura("player", buff) then return end end
25 | return iconline
26 | end
27 | end
28 |
29 | LibStub("AceEvent-3.0").RegisterEvent("Cork Seal", "UNIT_AURA", function(event, unit) if unit == "player" and InCombatLockdown() then dataobj.player = Test() end end)
30 | LibStub("AceEvent-3.0").RegisterEvent("Cork Seal", "PLAYER_REGEN_DISABLED", function() dataobj.player = Test() end)
31 | LibStub("AceEvent-3.0").RegisterEvent("Cork Seal", "PLAYER_REGEN_ENABLED", function() dataobj.player = nil end)
32 |
33 | function dataobj:Scan() self.player = InCombatLockdown() and Test() end
34 |
--------------------------------------------------------------------------------
/modules/WarlockSoulLink.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "WARLOCK" then return end
4 |
5 | local myname, Cork = ...
6 | local UnitAura = UnitAura
7 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
8 |
9 |
10 | local soul_link_enabled = select(5, GetTalentInfo(3,1,GetActiveSpecGroup()))
11 | if soul_link_enabled then
12 | local spellname, _, icon = GetSpellInfo(108415)
13 | local IconLine = Cork.IconLine(icon, spellname)
14 |
15 | local dataobj = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject("Cork "..spellname, {type = "cork", tiplink = GetSpellLink(spellname)})
16 |
17 | function dataobj:Init() Cork.defaultspc[spellname.."-enabled"] = GetSpellInfo(spellname) ~= nil end
18 |
19 | local function Test(unit)
20 | if Cork.dbpc[spellname.."-enabled"] and UnitExists("pet") and not UnitIsDead("pet") and not UnitAura("pet", spellname) and UnitName("pet") ~= UNKNOWN and not IsMounted() then
21 | return IconLine
22 | end
23 | end
24 |
25 | ae.RegisterEvent("Cork "..spellname, "UNIT_PET", function(event, unit) if unit == "player" then dataobj.pet = Test() end end)
26 | ae.RegisterEvent("Cork "..spellname, "UNIT_AURA", function(event, unit) if unit == "pet" then dataobj.pet = Test() end end)
27 |
28 | function dataobj:Scan() self.pet = Test() end
29 |
30 | function dataobj:CorkIt(frame)
31 | if self.pet then return frame:SetManyAttributes("type1", "spell", "spell", spellname) end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/tekKonfig/LibStub.lua:
--------------------------------------------------------------------------------
1 | -- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
2 | -- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
3 | local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
4 | local LibStub = _G[LIBSTUB_MAJOR]
5 |
6 | if not LibStub or LibStub.minor < LIBSTUB_MINOR then
7 | LibStub = LibStub or {libs = {}, minors = {} }
8 | _G[LIBSTUB_MAJOR] = LibStub
9 | LibStub.minor = LIBSTUB_MINOR
10 |
11 | function LibStub:NewLibrary(major, minor)
12 | assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
13 | minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
14 |
15 | local oldminor = self.minors[major]
16 | if oldminor and oldminor >= minor then return nil end
17 | self.minors[major], self.libs[major] = minor, self.libs[major] or {}
18 | return self.libs[major], oldminor
19 | end
20 |
21 | function LibStub:GetLibrary(major, silent)
22 | if not self.libs[major] and not silent then
23 | error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
24 | end
25 | return self.libs[major], self.minors[major]
26 | end
27 |
28 | function LibStub:IterateLibraries() return pairs(self.libs) end
29 | setmetatable(LibStub, { __call = LibStub.GetLibrary })
30 | end
31 |
--------------------------------------------------------------------------------
/modules/ArtifactPowerItems.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 |
4 |
5 | local EMPOWERING = GetSpellInfo(228647)
6 |
7 |
8 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
9 |
10 |
11 | local dataobj = ns:New("Artifact Power Items")
12 | dataobj.tiptext = "Notify you when there are items with artifact power in your bags"
13 | dataobj.corktype = "item"
14 | dataobj.priority = 12
15 |
16 |
17 | function dataobj:Init()
18 | ns.defaultspc[self.name.."-enabled"] = true
19 | end
20 |
21 |
22 |
23 | local function Test()
24 | for bag=0,4 do
25 | for slot=1,GetContainerNumSlots(bag) do
26 | local itemid = GetContainerItemID(bag, slot)
27 | if itemid and GetItemSpell(itemid) == EMPOWERING then return itemid end
28 | end
29 | end
30 | end
31 |
32 |
33 | local lastid
34 | function dataobj:Scan()
35 | if not ns.dbpc[self.name.."-enabled"] then
36 | self.player = nil
37 | return
38 | end
39 |
40 | lastid = Test()
41 | if lastid then
42 | local num = GetItemCount(lastid)
43 | local itemname, _, _, _, _, _, _, _, _, texture = GetItemInfo(lastid)
44 | if itemname ~= nil then
45 | self.player = ns.IconLine(texture, itemname.. " (".. num.. ")")
46 | else
47 | -- we probably haven't seen the item yet so it's not cached
48 | self.player = nil
49 | end
50 | else
51 | self.player = nil
52 | end
53 | end
54 |
55 | ae.RegisterEvent(dataobj, "BAG_UPDATE_DELAYED", "Scan")
56 |
57 |
58 | function dataobj:CorkIt(frame)
59 | if lastid then
60 | return frame:SetManyAttributes("type1", "item", "item1", "item:"..lastid)
61 | end
62 | end
63 |
--------------------------------------------------------------------------------
/modules/FishingHat.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local IconLine = Cork.IconLine
4 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
5 |
6 |
7 | local dataobj = ldb:NewDataObject("Cork Fishing hat", {
8 | type = "cork",
9 | corktype = "item",
10 | name = "Fishing hat",
11 | tiptext = "Remind you to equip your fishing hat when you have a fishing pole equipped.",
12 | priority = 7,
13 | })
14 | Cork.defaultspc["Fishing hat-enabled"] = true
15 |
16 |
17 | local hats = {
18 | 118393, -- 100 Tentacled Hat
19 | 118380, -- 100 Hightfish Cap
20 | 117405, -- 10 Nat's Drinking Hat
21 | 88710, -- 5 Nat's Hat
22 | 93732, -- 5 Darkmoon Fishing Cap
23 | 33820, -- 5 Weather-Beaten Fishing Hat
24 | 19972, -- 5 Lucky Fishing Hat
25 | }
26 | local function Test(id)
27 | if not Cork.dbpc[dataobj.name.."-enabled"] then return end
28 | if not IsEquippedItemType("Fishing Pole") then return end
29 |
30 | for _,id in ipairs(hats) do
31 | if GetItemCount(id) > 0 then
32 | return (not IsEquippedItem(id)) and id
33 | end
34 | end
35 | end
36 |
37 |
38 | function dataobj:Scan(event, unit)
39 | if unit ~= "player" then return end
40 |
41 | local id = Test()
42 | if id then
43 | self.player = IconLine(GetItemIcon(id), (GetItemInfo(id)))
44 | else
45 | self.player = nil
46 | end
47 | end
48 |
49 |
50 | function dataobj:CorkIt(frame)
51 | local id = Test()
52 | if id then
53 | return frame:SetManyAttributes("type1", "item", "item1", "item:"..id)
54 | end
55 | end
56 |
57 |
58 | ae.RegisterEvent(dataobj, "UNIT_INVENTORY_CHANGED", "Scan")
59 |
--------------------------------------------------------------------------------
/modules/GarrisonBodyguardMinifier.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local level = UnitLevel("player")
4 | local ae = LibStub("AceEvent-3.0")
5 |
6 |
7 | -- Garrison only available at 90
8 | if level < 90 then return end
9 |
10 |
11 | local dataobj = Cork:GenerateItemSelfBuffer(122298)
12 |
13 |
14 | local function CheckForBodyguard()
15 | local buildings = C_Garrison.GetBuildings(LE_GARRISON_TYPE_6_0)
16 |
17 | if not next(buildings) then
18 | C_Garrison.RequestLandingPageShipmentInfo()
19 | C_Timer.After(0.25, CheckForBodyguard)
20 | end
21 |
22 | for i,building in pairs(buildings) do
23 | if building.buildingID == 27 or building.buildingID == 28 then
24 | local bg = not not C_Garrison.GetFollowerInfoForBuilding(building.plotID)
25 | Cork.defaultspc[dataobj.name.."-enabled"] = bg
26 | return
27 | end
28 | end
29 | end
30 |
31 |
32 | local orig = dataobj.Init
33 | function dataobj:Init()
34 | orig(self)
35 | if Cork.defaultspc[self.name.."-enabled"] then CheckForBodyguard() end
36 | self.Init = nil
37 | end
38 |
39 |
40 | local zoneids = {}
41 | local function ParseSubzones(id, name, ...)
42 | zoneids[name] = true
43 | if select("#", ...) > 0 then return ParseSubzones(...) end
44 | end
45 | local function ParseZones(id, name, ...)
46 | zoneids[name] = true
47 | ParseSubzones(GetMapSubzones(id))
48 | if select("#", ...) > 0 then return ParseZones(...) end
49 | end
50 | ParseZones(GetMapZones(7))
51 |
52 |
53 | local orig2 = dataobj.TestWithoutResting
54 | function dataobj:Test()
55 | if not zoneids[GetRealZoneText()] then return end
56 | return orig2(self)
57 | end
58 |
59 |
60 | ae.RegisterEvent(dataobj, "ZONE_CHANGED", "Scan")
61 |
--------------------------------------------------------------------------------
/modules/Mage.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "MAGE" then return end
4 |
5 |
6 | -- Ice Barrier
7 | local spellname, _, icon = GetSpellInfo(11426)
8 | local dataobj = Cork:GenerateSelfBuffer(spellname, icon)
9 | dataobj.checkcooldown = true
10 |
11 |
12 | -- Water Elemental (frost pet)
13 | local UnitAura = Cork.UnitAura or UnitAura
14 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
15 | local spellname, _, icon = GetSpellInfo(31687)
16 | local iconline = Cork.IconLine(icon, spellname)
17 |
18 | local function Init(self)
19 | local name = GetSpellInfo(spellname)
20 | Cork.defaultspc[spellname.."-enabled"] = name ~= nil
21 | end
22 |
23 | local function TestWithoutResting()
24 | if Cork.dbpc[spellname.."-enabled"] and not UnitExists('pet') then
25 | return iconline
26 | end
27 | end
28 |
29 | local function Test()
30 | return not (IsResting() and not Cork.db.debug) and TestWithoutResting()
31 | end
32 |
33 | local function Scan(self, ...) self.player = Test() end
34 |
35 | local function CorkIt(self, frame)
36 | if self.player then
37 | return frame:SetManyAttributes("type1", "spell", "spell", spellname,
38 | "unit", "player")
39 | end
40 | end
41 |
42 | local function UNIT_PET(self, event, unit)
43 | if unit == "player" then self:Scan() end
44 | end
45 |
46 |
47 | local dataobj = ldb:NewDataObject("Cork "..spellname, {
48 | type = "cork",
49 | tiplink = GetSpellLink(spellname),
50 | Init = Init,
51 | Scan = Scan,
52 | CorkIt = CorkIt,
53 | UNIT_PET = UNIT_PET,
54 | })
55 |
56 | ae.RegisterEvent(dataobj, "UNIT_PET")
57 | ae.RegisterEvent(dataobj, "PLAYER_UPDATE_RESTING", "Scan")
58 |
--------------------------------------------------------------------------------
/externals/timer.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 |
4 | local _, _, _, build = GetBuildInfo()
5 | if build >= 60000 then
6 | local C_Timer = _G.C_Timer
7 |
8 | ns.StartRepeatingTimer = C_Timer.NewTicker
9 |
10 | function ns.StartTimer(endtime, callback)
11 | local duration = endtime - GetTime()
12 | C_Timer.After(duration, callback)
13 | end
14 |
15 | function ns.StopRepeatingTimer(timer)
16 | timer:Cancel()
17 | end
18 |
19 | else
20 | local funcs, nextup = {}
21 | local f = CreateFrame("Frame")
22 | f:Hide()
23 |
24 |
25 | local function SetNextTime()
26 | local besttime, bestv = math.huge
27 | for v in pairs(funcs) do
28 | if v.time < besttime then
29 | besttime, bestv = v.time, v
30 | end
31 | end
32 |
33 | if bestv then
34 | nextup = bestv
35 | f:Show()
36 | else
37 | f:Hide()
38 | end
39 | end
40 |
41 | function ns.StartTimer(endtime, func)
42 | local t = {time = endtime, func = func}
43 | funcs[t] = true
44 | SetNextTime()
45 | end
46 |
47 | function ns.StartRepeatingTimer(period, func)
48 | local t = {period = period, func = func, time = GetTime() + period}
49 | funcs[t] = true
50 | SetNextTime()
51 | return t
52 | end
53 |
54 | function ns.StopRepeatingTimer(timer)
55 | funcs[timer] = nil
56 | SetNextTime()
57 | end
58 |
59 |
60 | f:SetScript("OnHide", function() nextup = nil end)
61 | f:SetScript("OnUpdate", function(self)
62 | if not nextup then return f:Hide() end
63 | if GetTime() >= nextup.time then
64 | local endloop = nextup.func()
65 | if nextup.period and not endloop then
66 | nextup.time = GetTime() + nextup.period
67 | else funcs[nextup] = nil end
68 | SetNextTime()
69 | end
70 | end)
71 | end
72 |
--------------------------------------------------------------------------------
/modules/BuffItems.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local level = UnitLevel("player")
4 | local ae = LibStub("AceEvent-3.0")
5 |
6 |
7 | -- Items only available at 80
8 | if level < 80 then return end
9 |
10 |
11 | -- Only available to alchys
12 | local itemname = GetItemInfo(75525) or "Alchemist's Flask"
13 | local dataobj = Cork:GenerateSelfBuffer(itemname, GetItemIcon(75525),
14 | GetSpellInfo(79469), -- Flask of Steelskin
15 | GetSpellInfo(79470), -- Flask of the Draconic Mind
16 | GetSpellInfo(79471), -- Flask of the Winds
17 | GetSpellInfo(79472), -- Flask of Titanic Strength
18 | GetSpellInfo(94160), -- Flask of Flowing Water
19 | GetSpellInfo(92679), -- Flask of Battle (Guild Flask)
20 | GetSpellInfo(79638), -- Flask of Enhancement - Strength
21 | GetSpellInfo(79639), -- Flask of Enhancement - Agilty
22 | GetSpellInfo(79640), -- Flask of Enhancement - Intellect
23 | GetSpellInfo(105689), -- Flask of Spring Blossoms
24 | GetSpellInfo(105691), -- Flask of the Warm Sun
25 | GetSpellInfo(105693), -- Flask of Falling Leaves
26 | GetSpellInfo(105694), -- Flask of the Earth
27 | (GetSpellInfo(105696)) -- Flask of Winter's Bite
28 | )
29 | dataobj.tiplink = "item:75525"
30 |
31 | function dataobj:Init() Cork.defaultspc[itemname.."-enabled"] = GetItemCount(75525) > 0 end
32 |
33 | function dataobj:CorkIt(frame)
34 | if self.player then return frame:SetManyAttributes("type1", "item", "item1", "item:75525") end
35 | end
36 |
37 |
38 | if level < 91 then return end
39 |
40 | -- Excess Potion of Accelerated Learning
41 | local dataobj = Cork:GenerateItemSelfBuffer(120182, 178119)
42 | function dataobj:Init()
43 | Cork.defaultspc[self.name.."-enabled"] = level < 100 and GetItemCount(120182) > 0
44 | end
45 |
--------------------------------------------------------------------------------
/modules/GarrisonFreeFood.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 | local level = UnitLevel("player")
4 | local ae = LibStub("AceEvent-3.0")
5 |
6 |
7 | -- Items only available when you have a lvl3 garrison
8 | if level < 100 then return end
9 |
10 |
11 | local name = "Herb garden food"
12 | local iconline = ns.IconLine("Interface\\ICONS\\INV_Misc_Food_41", name)
13 | local foods = {}
14 | for i=118268,118277 do foods[i] = true end
15 |
16 |
17 | local dataobj = ns:New(name)
18 | dataobj.tiptext = "Notify you when you do not have free herb garden food in your bag"
19 | dataobj.corktype = "item"
20 | dataobj.priority = 15
21 | ns.defaultspc[name.."-enabled"] = true
22 |
23 |
24 | local function ScanPlots()
25 | local plots = C_Garrison.GetPlots(LE_FOLLOWER_TYPE_GARRISON_6_0)
26 | if not plots then return end
27 | for i,plot in ipairs(plots) do
28 | local id, _, _, _, rank = C_Garrison.GetOwnedBuildingInfoAbbrev(plot.id)
29 | if id == 137 and rank == 3 then return true end
30 | end
31 | return false
32 | end
33 |
34 |
35 | local hastree = false
36 | local function HasTree()
37 | if not hastree then hastree = ScanPlots() end
38 | return hastree
39 | end
40 |
41 |
42 | local function Test(self)
43 | if not ns.InGarrison() or not HasTree() then return end
44 |
45 | for id in pairs(foods) do
46 | if GetItemCount(id) > 0 then return end
47 | end
48 |
49 | return true
50 | end
51 |
52 |
53 | function dataobj:Scan()
54 | if ns.dbpc[self.name.."-enabled"] and Test() then
55 | self.player = iconline
56 | else
57 | self.player = nil
58 | end
59 | end
60 |
61 |
62 | ae.RegisterEvent(dataobj, "ZONE_CHANGED", "Scan")
63 | ae.RegisterEvent(dataobj, "BAG_UPDATE_DELAYED", "Scan")
64 | ae.RegisterEvent(dataobj, "GARRISON_UPDATE", "Scan")
65 |
--------------------------------------------------------------------------------
/modules/Salvage.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 |
4 |
5 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
6 |
7 | if UnitLevel("player") < 90 then return end
8 |
9 |
10 | local dataobj = ns:New("Salvage")
11 | dataobj.tiptext = "Notify you when you have openable salvage containers and are in your garrison"
12 | dataobj.corktype = "item"
13 | dataobj.priority = 10
14 |
15 |
16 | function dataobj:Init()
17 | ns.defaultspc[self.name.."-enabled"] = UnitLevel("player") >= 90
18 | end
19 |
20 |
21 | local openable_ids = {
22 | [118473] = true, -- Small Sack of Salvaged Goods
23 | [114116] = true, -- Bag of Salvaged Goods
24 | [114119] = true, -- Crate of Salvage
25 | [114120] = true, -- Big Crate of Salvage
26 | [139593] = true, -- Sack of Salvaged Goods
27 | [140590] = true, -- Large Crate of Salvage
28 | }
29 |
30 | local function Test()
31 | if not ns.InGarrison() then return end
32 | for id in pairs(openable_ids) do
33 | if GetItemCount(id) > 0 then return id end
34 | end
35 | end
36 |
37 |
38 | function dataobj:Scan()
39 | if not ns.dbpc[self.name.."-enabled"] then
40 | self.player = nil
41 | return
42 | end
43 |
44 | local id = Test()
45 | if id then
46 | local num = GetItemCount(id)
47 | local itemname, _, _, _, _, _, _, _, _, texture = GetItemInfo(id)
48 | if itemname then
49 | self.player = ns.IconLine(texture, itemname.. " (".. num.. ")")
50 | else
51 | self.player = nil
52 | end
53 | else
54 | self.player = nil
55 | end
56 | end
57 |
58 | ae.RegisterEvent(dataobj, "BAG_UPDATE_DELAYED", "Scan")
59 | ae.RegisterEvent(dataobj, "GARRISON_UPDATE", "Scan")
60 |
61 |
62 | function dataobj:CorkIt(frame)
63 | local id = Test()
64 | if id then
65 | return frame:SetManyAttributes("type1", "item", "item1", "item:"..id)
66 | end
67 | end
68 |
--------------------------------------------------------------------------------
/tekKonfig/tekKonfigCheckbox.lua:
--------------------------------------------------------------------------------
1 |
2 | local lib, oldminor = LibStub:NewLibrary("tekKonfig-Checkbox", 3)
3 | if not lib then return end
4 |
5 |
6 | local GameTooltip = GameTooltip
7 | local function HideTooltip() GameTooltip:Hide() end
8 | local function ShowTooltip(self)
9 | if self.tiptext then
10 | GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
11 | GameTooltip:SetText(self.tiptext, nil, nil, nil, nil, true)
12 | elseif self.tiplink then
13 | GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
14 | GameTooltip:SetHyperlink(self.tiplink)
15 | end
16 | end
17 | local function OnClick(self) PlaySound(self:GetChecked() and SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON or SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF) end
18 |
19 |
20 | -- Creates a checkbox.
21 | -- All args optional but parent is highly recommended
22 | function lib.new(parent, size, label, ...)
23 | local check = CreateFrame("CheckButton", nil, parent)
24 | check:SetWidth(size or 26)
25 | check:SetHeight(size or 26)
26 | if select(1, ...) then check:SetPoint(...) end
27 |
28 | check:SetHitRectInsets(0, -100, 0, 0)
29 |
30 | check:SetNormalTexture("Interface\\Buttons\\UI-CheckBox-Up")
31 | check:SetPushedTexture("Interface\\Buttons\\UI-CheckBox-Down")
32 | check:SetHighlightTexture("Interface\\Buttons\\UI-CheckBox-Highlight")
33 | check:SetDisabledCheckedTexture("Interface\\Buttons\\UI-CheckBox-Check-Disabled")
34 | check:SetCheckedTexture("Interface\\Buttons\\UI-CheckBox-Check")
35 |
36 | -- Tooltip bits
37 | check:SetScript("OnEnter", ShowTooltip)
38 | check:SetScript("OnLeave", HideTooltip)
39 |
40 | -- Sound
41 | check:SetScript("OnClick", OnClick)
42 | check:SetScript("PostClick", OnClick) -- So we don't have to hook OnClick to get the sound
43 |
44 | -- Label
45 | local fs = check:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
46 | fs:SetPoint("LEFT", check, "RIGHT", 0, 1)
47 | fs:SetText(label)
48 |
49 | return check, fs
50 | end
51 |
--------------------------------------------------------------------------------
/modules/GarrisonCache.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 | local level = UnitLevel("player")
4 | local ae = LibStub("AceEvent-3.0")
5 |
6 |
7 | -- Items only available when you have a garrison
8 | if level < 90 then return end
9 |
10 |
11 | function ns.InGarrison()
12 | return C_Garrison.IsOnGarrisonMap() or C_Garrison.IsOnShipyardMap()
13 | end
14 |
15 |
16 | local name = "Garrison cache"
17 |
18 |
19 | local dataobj = ns:New(name)
20 | dataobj.tiptext = "Notify you when you are in your garrison and the resource cache is unopened"
21 | dataobj.priority = 20
22 | ns.defaultspc[name.."-enabled"] = true
23 |
24 |
25 | local function SecondsSinceLastOpened()
26 | local lasttime = ns.dbpc[name.."-lastopen"] or 0
27 | return time() - lasttime
28 | end
29 |
30 |
31 | local function MaxSize()
32 | return IsQuestFlaggedCompleted(37485) and 1000 or 500
33 | end
34 |
35 |
36 | local function AmountPending()
37 | local size = SecondsSinceLastOpened() / 60 / 10
38 | return math.min(size, MaxSize())
39 | end
40 |
41 |
42 | local function Test()
43 | if not ns.InGarrison() then return end
44 | return AmountPending() >= (MaxSize() - (24*60/10))
45 | end
46 |
47 |
48 | function dataobj:Scan()
49 | if ns.dbpc[self.name.."-enabled"] and Test() then
50 | if not ns.dbpc[name.."-lastopen"] then
51 | self.player = ns.IconLine("Interface\\ICONS\\inv_garrison_resource", name)
52 | return
53 | end
54 |
55 | local size = AmountPending()
56 | local title = string.format("%s (%d)", name, size)
57 | self.player = ns.IconLine("Interface\\ICONS\\inv_garrison_resource", title)
58 | else
59 | self.player = nil
60 | end
61 | end
62 |
63 |
64 | ae.RegisterEvent(dataobj, "ZONE_CHANGED", "Scan")
65 | ae.RegisterEvent("Cork "..name, "SHOW_LOOT_TOAST", function(event, ...)
66 | local _, _, _, _, _, _, lootSource = ...
67 | if lootSource == 10 then
68 | ns.dbpc[name.."-lastopen"] = time()
69 | end
70 |
71 | dataobj:Scan()
72 | end)
73 |
--------------------------------------------------------------------------------
/tekKonfig/tekKonfigButton.lua:
--------------------------------------------------------------------------------
1 |
2 | local lib, oldminor = LibStub:NewLibrary("tekKonfig-Button", 5)
3 | if not lib then return end
4 | oldminor = oldminor or 0
5 |
6 |
7 | if oldminor < 5 then
8 | local GameTooltip = GameTooltip
9 | local function HideTooltip() GameTooltip:Hide() end
10 | local function ShowTooltip(self)
11 | if self.tiptext then
12 | GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
13 | GameTooltip:SetText(self.tiptext, nil, nil, nil, nil, true)
14 | end
15 | end
16 |
17 |
18 | -- Create a button.
19 | -- All args optional, parent recommended
20 | function lib.new(parent, ...)
21 | local butt = CreateFrame("Button", nil, parent)
22 | if select("#", ...) > 0 then butt:SetPoint(...) end
23 | butt:SetWidth(80) butt:SetHeight(22)
24 |
25 | -- Fonts --
26 | butt:SetDisabledFontObject(GameFontDisable)
27 | butt:SetHighlightFontObject(GameFontHighlight)
28 | butt:SetNormalFontObject(GameFontNormal)
29 |
30 | -- Textures --
31 | butt:SetNormalTexture("Interface\\Buttons\\UI-Panel-Button-Up")
32 | butt:SetPushedTexture("Interface\\Buttons\\UI-Panel-Button-Down")
33 | butt:SetHighlightTexture("Interface\\Buttons\\UI-Panel-Button-Highlight")
34 | butt:SetDisabledTexture("Interface\\Buttons\\UI-Panel-Button-Disabled")
35 | butt:GetNormalTexture():SetTexCoord(0, 0.625, 0, 0.6875)
36 | butt:GetPushedTexture():SetTexCoord(0, 0.625, 0, 0.6875)
37 | butt:GetHighlightTexture():SetTexCoord(0, 0.625, 0, 0.6875)
38 | butt:GetDisabledTexture():SetTexCoord(0, 0.625, 0, 0.6875)
39 | butt:GetHighlightTexture():SetBlendMode("ADD")
40 |
41 | -- Tooltip bits
42 | butt:SetScript("OnEnter", ShowTooltip)
43 | butt:SetScript("OnLeave", HideTooltip)
44 |
45 | return butt
46 | end
47 |
48 |
49 | function lib.new_small(parent, ...)
50 | local butt = lib.new(parent, ...)
51 | butt:SetHighlightFontObject(GameFontHighlightSmall)
52 | butt:SetNormalFontObject(GameFontNormalSmall)
53 | return butt
54 | end
55 | end
56 |
--------------------------------------------------------------------------------
/modules/GarrisonMineItems.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local level = UnitLevel("player")
4 | local ae = LibStub("AceEvent-3.0")
5 |
6 |
7 | -- Items only available when you have a garrison (lvl 90+)
8 | if level < 90 then return end
9 |
10 |
11 | local zone = "Frostwall Mine"
12 | if UnitFactionGroup("player") == "Alliance" then
13 | zone = "Lunarfall Excavation"
14 | end
15 |
16 |
17 | local function Init(self)
18 | Cork.defaultspc[self.spellname.."-enabled"] = true
19 | end
20 |
21 |
22 | local function TestWithoutResting(self)
23 | if Cork.dbpc[self.spellname.."-enabled"] and not self.HasBuff(self.spells) and GetItemCount(self.itemid) > 0 then
24 | return self.iconline
25 | end
26 | end
27 |
28 |
29 | local function Test(self)
30 | return not IsResting() and GetSubZoneText() == zone and self:TestWithoutResting()
31 | end
32 |
33 |
34 | local itemname = GetItemInfo(118897) or "Miner's Coffee"
35 | local buffname, _, icon = GetSpellInfo(176049)
36 | local dataobj = Cork:GenerateSelfBuffer(itemname, icon, buffname)
37 | dataobj.Init = Init
38 | dataobj.Test = Test
39 | dataobj.TestWithoutResting = TestWithoutResting
40 | dataobj.itemid = 118897
41 | dataobj.tiplink = "item:118897"
42 | ae.RegisterEvent(dataobj, "ZONE_CHANGED", "Scan")
43 | function dataobj:CorkIt(frame)
44 | if self.player then return frame:SetManyAttributes("type1", "item", "item1", "item:118897") end
45 | end
46 |
47 |
48 | local itemname = GetItemInfo(118903) or "Preserved Mining Pick"
49 | local buffname, _, icon = GetSpellInfo(176061)
50 | local dataobj = Cork:GenerateSelfBuffer(itemname, icon, buffname)
51 | dataobj.Init = Init
52 | dataobj.Test = Test
53 | dataobj.TestWithoutResting = TestWithoutResting
54 | dataobj.itemid = 118903
55 | dataobj.tiplink = "item:118903"
56 | ae.RegisterEvent(dataobj, "ZONE_CHANGED", "Scan")
57 | function dataobj:CorkIt(frame)
58 | if self.player then return frame:SetManyAttributes("type1", "item", "item1", "item:118903") end
59 | end
60 |
--------------------------------------------------------------------------------
/modules/ClassHallWorkOrders.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 | local level = UnitLevel("player")
4 | local ae = LibStub("AceEvent-3.0")
5 |
6 |
7 | -- Items only available when you have a class hall
8 | if level < 101 then return end
9 |
10 |
11 | local name = "Completed class hall work orders"
12 |
13 |
14 | local dataobj = ns:New(name)
15 | dataobj.tiptext = "Notify you when you are resting and have completed work orders"
16 | dataobj.priority = 20
17 | ns.defaultspc[name.."-enabled"] = true
18 |
19 |
20 | local shipment_ids = {}
21 | local function Test(shipment_id)
22 | shipment_ids[shipment_id] = true
23 |
24 | local name, icon, capacity, ready, total =
25 | C_Garrison.GetLandingPageShipmentInfoByContainerID(shipment_id)
26 |
27 | if name and ready > 0 then
28 | local txt = string.format("%s (%d/%d)", name, ready, total)
29 | return ns.IconLine(icon, txt)
30 | end
31 | end
32 |
33 |
34 | local function RequestRefresh()
35 | if not ns.dbpc[name.."-enabled"] or not IsResting() then return end
36 | C_Garrison.RequestLandingPageShipmentInfo()
37 | end
38 |
39 |
40 | function dataobj:Scan(...)
41 | for id in pairs(shipment_ids) do
42 | self["shipment"..id] = nil
43 | shipment_ids[id] = nil
44 | end
45 |
46 | if not ns.dbpc[self.name.."-enabled"] or not IsResting() then return end
47 |
48 | local shipments = C_Garrison.GetLooseShipments(LE_GARRISON_TYPE_7_0)
49 | for i,shipment_id in pairs(shipments) do
50 | self["shipment"..shipment_id] = Test(shipment_id)
51 | end
52 | end
53 |
54 |
55 | ae.RegisterEvent(dataobj, "GARRISON_LANDINGPAGE_SHIPMENTS", "Scan")
56 | ae.RegisterEvent(dataobj, "GARRISON_TALENT_UPDATE", "Scan")
57 | ae.RegisterEvent(dataobj, "GARRISON_TALENT_COMPLETE", "Scan")
58 | ae.RegisterEvent(dataobj, "GARRISON_SHIPMENT_RECEIVED", RequestRefresh)
59 | ae.RegisterEvent(dataobj, "SHIPMENT_UPDATE", RequestRefresh)
60 | ae.RegisterEvent(dataobj, "ZONE_CHANGED", RequestRefresh)
61 |
62 | C_Timer.NewTicker(60*5, RequestRefresh)
63 |
--------------------------------------------------------------------------------
/modules/GarrisonBuildings.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 | local level = UnitLevel("player")
4 | local ae = LibStub("AceEvent-3.0")
5 |
6 |
7 | -- Items only available when you have a garrison
8 | if level < 90 then return end
9 |
10 |
11 | local name = "Completed buildings"
12 |
13 |
14 | local dataobj = ns:New(name)
15 | dataobj.tiptext = "Notify you when you are in your garrison and have a completed building"
16 | dataobj.priority = 20
17 | ns.defaultspc[name.."-enabled"] = level >= 100
18 |
19 |
20 | local function Test(self, building)
21 | if not ns.InGarrison() then return end
22 |
23 | local items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_6_0)
24 | for i,item in ipairs(items) do
25 | if item.isComplete and item.isBuilding then return true end
26 | end
27 | end
28 |
29 |
30 | local textures = setmetatable({}, {
31 | __index = function(t,i)
32 | local buildings = C_Garrison.GetBuildings(LE_GARRISON_TYPE_6_0)
33 | for _,building in pairs(buildings) do
34 | local _, name, _, icon = C_Garrison.GetBuildingInfo(building.buildingID)
35 | if i == name then
36 | t[i] = icon
37 | return icon
38 | end
39 | end
40 | end
41 | })
42 |
43 |
44 | local set_indexes = {}
45 | function dataobj:Scan(event, ...)
46 | for i in pairs(set_indexes) do self["index"..i] = nil end
47 | wipe(set_indexes)
48 |
49 | if not ns.dbpc[self.name.."-enabled"] or not ns.InGarrison() then return end
50 |
51 | local items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_6_0)
52 | for i,item in ipairs(items) do
53 | if item.isComplete and item.isBuilding then
54 | set_indexes[i] = true
55 | self["index"..i] = ns.IconLine(textures[item.name], item.name)
56 | end
57 | end
58 | end
59 |
60 |
61 | ae.RegisterEvent(dataobj, "ZONE_CHANGED", "Scan")
62 | ae.RegisterEvent(dataobj, "GARRISON_MISSION_NPC_CLOSED", "Scan")
63 | ae.RegisterEvent(dataobj, "GARRISON_MISSION_FINISHED", "Scan")
64 | ae.RegisterEvent(dataobj, "GARRISON_MISSION_LIST_UPDATE", "Scan")
65 |
66 |
--------------------------------------------------------------------------------
/modules/Lures.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local IconLine = Cork.IconLine
4 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
5 |
6 |
7 | local dataobj = ldb:NewDataObject("Cork Lure", {
8 | type = "cork",
9 | corktype = "item",
10 | name = "Lure",
11 | tiptext = "Remind you to use a lure when you have a fishing pole equipped.",
12 | priority = 8,
13 | })
14 | Cork.defaultspc["Lure-enabled"] = true
15 |
16 |
17 | local lures = {
18 | 116825, -- 200 Savage Fishing Pole (10min duration, 20min CD)
19 | 116826, -- 200 Draenic Fishing Pole (10min duration, 20min CD)
20 | 118391, -- 200 Worm Supreme
21 | 117405, -- 150 Nat's Drinking Hat
22 | 88710, -- 150 Nat's Hat
23 | 68049, -- 150 Heat-Treated Spinning Lure
24 | 46006, -- 100 Glow Worm
25 | 34861, -- 100 Sharpened Fish Hook
26 | 6533, -- 100 Aquadynamic Fish Attractor
27 | 62673, -- 100 Feathered Lure
28 | 7307, -- 75 Flesh Eating Worm
29 | 6532, -- 75 Bright Baubles
30 | 33820, -- 75 Weather-Beaten Fishing Hat
31 | 6530, -- 50 Nightcrawlers
32 | 6811, -- 50 Aquadynamic Fish Lens
33 | 6529, -- 25 Shiny Bauble
34 | 67404, -- 15 Glass Fishing Bobber
35 | }
36 | local function Test(id)
37 | if not Cork.dbpc[dataobj.name.."-enabled"] then return end
38 | if not IsEquippedItemType("Fishing Pole") then return end
39 | if GetWeaponEnchantInfo() then return end
40 |
41 | for _,id in ipairs(lures) do
42 | if GetItemCount(id) > 0 then return id end
43 | end
44 | end
45 |
46 |
47 | function dataobj:Scan(event, unit)
48 | if unit ~= "player" then return end
49 |
50 | local id = Test()
51 | if id then
52 | self.player = IconLine(GetItemIcon(id), (GetItemInfo(id)))
53 | else
54 | self.player = nil
55 | end
56 | end
57 |
58 |
59 | function dataobj:CorkIt(frame)
60 | local id = Test()
61 | if id then
62 | return frame:SetManyAttributes("type1", "item", "item1", "item:"..id)
63 | end
64 | end
65 |
66 |
67 | ae.RegisterEvent(dataobj, "UNIT_INVENTORY_CHANGED", "Scan")
68 |
--------------------------------------------------------------------------------
/MacroGenerator.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 |
4 | local function GetMacroID()
5 | for i=(MAX_ACCOUNT_MACROS+1),(MAX_ACCOUNT_MACROS+MAX_CHARACTER_MACROS) do if GetMacroInfo(i) == "Cork" then return i end end
6 | end
7 |
8 | function Cork.GenerateMacro()
9 | if InCombatLockdown() then return end
10 |
11 | local id = GetMacroID()
12 | if id then PickupMacro(id)
13 | elseif select(2, GetNumMacros()) < MAX_CHARACTER_MACROS then
14 | local body, ic, ooc
15 | local icon = "INV_MISC_QUESTIONMARK"
16 | local c = Cork.MYCLASS
17 | if c == "DEATHKNIGHT" then ooc = 3714
18 | elseif c == "HUNTER" then -- ooc = 13165 -- dead spell
19 | elseif c == "SHAMAN" then -- ooc = 324 -- dead spell
20 | elseif c == "WARLOCK" then -- ooc = 6201
21 | elseif c == "WARRIOR" then -- ooc = 6673 -- dead spell
22 | elseif c == "MONK" then -- ooc = 115921 -- dead spell
23 | elseif c == "ROGUE" then ooc = 2823
24 | elseif c == "DRUID" then ic, ooc = 22812, nil -- 1126 -- dead spell
25 | elseif c == "MAGE" then ic, ooc = 30482, nil -- 1459 -- dead spell
26 | elseif c == "PALADIN" then -- ic, ooc = 20165, 19740 -- dead spells
27 | elseif c == "PRIEST" then -- ic, ooc = 588, 21562 -- dead spells
28 | end
29 | if ic and ooc then
30 | ic, ooc = GetSpellInfo(ic), GetSpellInfo(ooc)
31 | body = "#showtooltip [combat] "..ic.."; "..ooc.."\n/cast [combat] "..ic.."\n/stopmacro [combat]\n/click CorkFrame"
32 | elseif ooc then
33 | local ooc, _, texture = GetSpellInfo(ooc)
34 | texture = texture:upper():match("^INTERFACE\\ICONS\\(.+)")
35 | if texture then
36 | icon = texture
37 | body = "/click CorkFrame"
38 | else
39 | body = "#showtooltip "..ooc.."\n/click CorkFrame"
40 | end
41 | elseif ic then
42 | ic = GetSpellInfo(ic)
43 | body = "#showtooltip [combat] "..ic.."\n/cast [combat] "..ic.."\n/stopmacro [combat]\n/click CorkFrame"
44 | else
45 | body = "/click CorkFrame"
46 | end
47 | local id = CreateMacro("Cork", icon, body, true)
48 | PickupMacro(id)
49 | end
50 | end
51 |
--------------------------------------------------------------------------------
/modules/QuestStartingItems.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local IconLine = Cork.IconLine("Interface\\OptionsFrame\\UI-OptionsFrame-NewFeatureIcon", "Quest starter")
4 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
5 |
6 | local bags = {}
7 |
8 | Cork.defaultspc["Quest Starting Items-enabled"] = true
9 |
10 | local dataobj = ldb:NewDataObject("Cork Quest Starting Items", {
11 | type = "cork",
12 | corktype = "item",
13 | tiptext = "Warn when you have available quests from items in your bags.",
14 | })
15 |
16 | local function TestBag(bag)
17 | for slot=0,GetContainerNumSlots(bag) do
18 | local _, qid, active = GetContainerItemQuestInfo(bag, slot)
19 | if qid and not active then return true end
20 | end
21 | end
22 |
23 | function dataobj:Scan()
24 | if not Cork.dbpc["Quest Starting Items-enabled"] then
25 | dataobj.player = nil
26 | return
27 | end
28 |
29 | wipe(bags)
30 | for bag=0,4 do bags[bag] = TestBag(bag) end
31 | if next(bags) then dataobj.player = IconLine; return end
32 | dataobj.player = nil
33 | end
34 |
35 | ae.RegisterEvent("Cork Quest Starting Items", "QUEST_ACCEPTED", function() if next(bags) then dataobj:Scan() end end)
36 | ae.RegisterEvent("Cork Quest Starting Items", "UNIT_QUEST_LOG_CHANGED", function(event, unit) if unit == "player" and next(bags) then dataobj:Scan() end end)
37 | ae.RegisterEvent("Cork Quest Starting Items", "BAG_UPDATE", function(event, bag)
38 | if not Cork.dbpc["Quest Starting Items-enabled"] then return end
39 | bags[bag] = TestBag(bag)
40 | if next(bags) then dataobj.player = IconLine; return end
41 | dataobj.player = nil
42 | end)
43 |
44 | function dataobj:CorkIt(frame)
45 | if dataobj.player then
46 | for bag=0,4 do
47 | for slot=0,GetContainerNumSlots(bag) do
48 | local _, qid, active = GetContainerItemQuestInfo(bag, slot)
49 | if qid and not active then
50 | local id = GetContainerItemID(bag, slot)
51 | return frame:SetManyAttributes("type1", "item", "item1", "item:"..id)
52 | end
53 | end
54 | end
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/modules/BattleStandard.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local UnitAura = Cork.UnitAura or UnitAura
4 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
5 |
6 |
7 | local ally = UnitFactionGroup('player') == "Alliance"
8 | local ids = ally and {64399, 64398, 63359} or {64402, 64401, 64400}
9 | local buffname = GetSpellInfo(90633)
10 | local name = "Cork "..buffname
11 | local iconline = Cork.IconLine(GetItemIcon(ids[1]), buffname)
12 | local coolingdown
13 |
14 |
15 | local dataobj = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject(name, {
16 | type = "cork", tiplink = GetSpellLink(buffname),
17 | corktype = "item",
18 | tiplink = "item:"..ids[1],
19 | priority = 9,
20 | })
21 |
22 |
23 | local function FindItem()
24 | for _,id in ipairs(ids) do
25 | if GetItemCount(id) > 0 then return id end
26 | end
27 | end
28 |
29 |
30 | local function HasBuff()
31 | return UnitAura("player", buffname)
32 | end
33 |
34 |
35 | local function CooldownFinish()
36 | coolingdown = false
37 | dataobj:Scan()
38 | end
39 |
40 |
41 | function dataobj:Init()
42 | Cork.defaultspc[buffname.."-enabled"] = FindItem() ~= nil
43 | end
44 |
45 |
46 | local function Test(unit)
47 | if coolingdown or not Cork.dbpc[buffname.."-enabled"] or HasBuff() then return end
48 |
49 | local id = FindItem()
50 | if not id then return end
51 |
52 | local start, duration = GetItemCooldown(id)
53 | if start > 0 then
54 | coolingdown = true
55 | Cork.StartTimer(start + duration, CooldownFinish)
56 | elseif not (IsResting() and not Cork.db.debug) then
57 | return iconline
58 | end
59 | end
60 |
61 |
62 | function dataobj:Scan() self.custom = Test() end
63 |
64 |
65 | function dataobj:CorkIt(frame)
66 | local itemowned = FindItem()
67 | if self.custom and itemowned then
68 | return frame:SetManyAttributes("type1", "item", "item1", "item:"..itemowned)
69 | end
70 | end
71 |
72 |
73 | ae.RegisterEvent(dataobj, "PLAYER_UPDATE_RESTING", "Scan")
74 | ae.RegisterEvent(name, "UNIT_AURA", function(event, unit)
75 | if unit == "player" then dataobj.custom = Test() end
76 | end)
77 |
--------------------------------------------------------------------------------
/modules/OpenableItems.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 |
4 |
5 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
6 |
7 |
8 | local dataobj = ns:New("Openable items")
9 | dataobj.tiptext = "Notify you when there are openable containers in your bags"
10 | dataobj.corktype = "item"
11 | dataobj.priority = 8
12 |
13 |
14 | function dataobj:Init()
15 | ns.defaultspc[self.name.."-enabled"] = true
16 | end
17 |
18 |
19 | local OPEN_CLAM = "Use: Open the clam!"
20 | local openable_ids = {
21 | [120301] = true, -- Armor Enhancement Token
22 | [120302] = true, -- Weapon Enhancement Token
23 | }
24 | local function IsOpenable(bag, slot, id)
25 | if openable_ids[id] ~= nil then return openable_ids[id] end
26 |
27 | ns.scantip:SetBagItem(bag, slot)
28 | for i=1,5 do
29 | if ns.scantip.L[i] == RETRIEVING_ITEM_INFO then return false end
30 | if ns.scantip.L[i] == ITEM_OPENABLE or ns.scantip.L[i] == OPEN_CLAM then
31 | openable_ids[id] = true
32 | return true
33 | end
34 | end
35 | openable_ids[id] = false
36 | return false
37 | end
38 |
39 |
40 | local function Test()
41 | for bag=0,4 do
42 | for slot=1,GetContainerNumSlots(bag) do
43 | local itemid = GetContainerItemID(bag, slot)
44 | if itemid and IsOpenable(bag, slot, itemid) then return itemid end
45 | end
46 | end
47 | end
48 |
49 |
50 | local lastid
51 | function dataobj:Scan()
52 | if not ns.dbpc[self.name.."-enabled"] then
53 | self.player = nil
54 | return
55 | end
56 |
57 | lastid = Test()
58 | if lastid then
59 | local num = GetItemCount(lastid)
60 | local itemname, _, _, _, _, _, _, _, _, texture = GetItemInfo(lastid)
61 | if itemname ~= nil then
62 | self.player = ns.IconLine(texture, itemname.. " (".. num.. ")")
63 | else
64 | -- we probably haven't seen the item yet so it's not cached
65 | self.player = nil
66 | end
67 | else
68 | self.player = nil
69 | end
70 | end
71 |
72 | ae.RegisterEvent(dataobj, "BAG_UPDATE_DELAYED", "Scan")
73 |
74 |
75 | function dataobj:CorkIt(frame)
76 | if lastid then
77 | return frame:SetManyAttributes("type1", "item", "item1", "item:"..lastid)
78 | end
79 | end
80 |
--------------------------------------------------------------------------------
/Cork.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 70100
2 |
3 | ## Title: Cork
4 | ## Notes: Buff reminders and more
5 | ## Author: Tekkub Stoutwrithe
6 | ## X-Credits: Thiana (Warlock modules), Gnancy (Soullink module)
7 | ## X-Category: Buffs
8 | ## X-Icon: Interface\Icons\INV_Drink_11
9 |
10 | ## SavedVariables: CorkDB
11 | ## SavedVariablesPerCharacter: CorkDBPC
12 |
13 | ## OptionalDeps: tekErr
14 |
15 | externals\timer.lua
16 | externals\tooltip_scanner.lua
17 | externals\ui-tab.lua
18 |
19 | tekKonfig\tekKonfig.xml
20 | CallbackHandler-1.0.lua
21 | LibDataBroker-1.1\LibDataBroker-1.1.lua
22 | AceEvent-3.0\AceEvent-3.0.xml
23 |
24 | services\holiday_active.lua
25 |
26 | Locale.lua
27 | KeyBlacklist.lua
28 |
29 | Cork.lua
30 | Config.lua
31 | MacroGenerator.lua
32 | Mousewheel.lua
33 |
34 | templates\ItemSelfBuffer.lua
35 | templates\LastBuffedBuffer.lua
36 | templates\RaidBuffer.lua
37 | templates\RaidBuffingItems.lua
38 | templates\SelfBuffer.lua
39 | templates\SelfBufferAdvanced.lua
40 | templates\TempEnchant.lua
41 |
42 | modules\DeathKnight.lua
43 | modules\Druid.lua
44 | modules\Hunter.lua
45 | modules\Mage.lua
46 | modules\Monk.lua
47 | modules\Paladin.lua
48 | modules\Priest.lua
49 | modules\RogueWeapon.lua
50 | modules\Shaman.lua
51 | modules\Warlock.lua
52 | modules\WarlockHealthstone.lua
53 | modules\WarlockPets.lua
54 | modules\WarlockSoulLink.lua
55 | modules\Warrior.lua
56 |
57 | modules\ArtifactPowerItems.lua
58 | modules\BattleStandard.lua
59 | modules\BonusEvents.lua
60 | modules\BuffItems.lua
61 | modules\ClassHallWorkOrders.lua
62 | modules\Capsules.lua
63 | modules\Combine.lua
64 | modules\DarkmoonExp.lua
65 | modules\FishingHat.lua
66 | modules\GarrisonBodyguardMinifier.lua
67 | modules\GarrisonBuildings.lua
68 | modules\GarrisonCache.lua
69 | modules\GarrisonFreeFood.lua
70 | modules\GarrisonMineItems.lua
71 | modules\GarrisonMissions.lua
72 | modules\GarrisonWorkOrders.lua
73 | modules\LancePole.lua
74 | modules\Lures.lua
75 | modules\Minipet.lua
76 | modules\OpenableItems.lua
77 | modules\PilgrimsBountyRep.lua
78 | modules\QuestStartingItems.lua
79 | modules\Repairs.lua
80 | modules\Salvage.lua
81 | modules\Talents.lua
82 | modules\Tracking.lua
83 | modules\WellFed.lua
84 |
--------------------------------------------------------------------------------
/templates/SelfBuffer.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local UnitAura = Cork.UnitAura or UnitAura
4 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
5 |
6 |
7 | local function HasBuff(spells)
8 | for _,spell in pairs(spells) do
9 | if UnitAura("player", spell) then return true end
10 | end
11 | end
12 |
13 | local function CheckCooldown(self)
14 | if not self.checkcooldown then return true end
15 |
16 | local start, duration = GetSpellCooldown(self.spellname)
17 | if start == 0 or duration <= 1.5 then return true end
18 |
19 | Cork.StartTimer(start + duration, self.Scan)
20 | return false
21 | end
22 |
23 | local function Init(self)
24 | local name = GetSpellInfo(self.spellname)
25 | Cork.defaultspc[self.spellname.."-enabled"] = name ~= nil
26 | end
27 |
28 | local function TestWithoutResting(self)
29 | if Cork.dbpc[self.spellname.."-enabled"] and not HasBuff(self.spells) and CheckCooldown(self) then
30 | return self.iconline
31 | end
32 | end
33 |
34 | local function Test(self)
35 | return not (IsResting() and not Cork.db.debug) and self:TestWithoutResting()
36 | end
37 |
38 | local function CorkIt(self, frame)
39 | if self.player then
40 | return frame:SetManyAttributes("type1", "spell", "spell", self.spellname,
41 | "unit", "player")
42 | end
43 | end
44 |
45 | local function UNIT_AURA(self, event, unit)
46 | if unit == "player" then self:Scan() end
47 | end
48 |
49 |
50 | function Cork:GenerateSelfBuffer(spellname, icon, ...)
51 | local dataobj = ldb:NewDataObject("Cork "..spellname, {
52 | type = "cork",
53 | corktype = "buff",
54 | tiplink = GetSpellLink(spellname),
55 | iconline = self.IconLine(icon, spellname),
56 | spells = {spellname, ...},
57 | spellname = spellname,
58 | Init = Init,
59 | Test = Test,
60 | CorkIt = CorkIt,
61 | UNIT_AURA = UNIT_AURA,
62 | TestWithoutResting = TestWithoutResting,
63 | HasBuff = HasBuff,
64 | })
65 |
66 | function dataobj.Scan()
67 | dataobj.player = dataobj:Test()
68 | end
69 |
70 | ae.RegisterEvent(dataobj, "UNIT_AURA")
71 | ae.RegisterEvent(dataobj, "PLAYER_UPDATE_RESTING", "Scan")
72 |
73 | return dataobj
74 | end
75 |
--------------------------------------------------------------------------------
/modules/Capsules.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 |
4 |
5 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
6 |
7 |
8 | local dataobj = ns:New("Capsules")
9 | dataobj.tiptext = "Notify you when you have items that grant a boon when used"
10 | dataobj.corktype = "item"
11 | dataobj.priority = 9
12 |
13 |
14 | function dataobj:Init()
15 | ns.defaultspc[self.name.."-enabled"] = true
16 | end
17 |
18 |
19 | local OPENABLE_IDS = {
20 | [139020] = true, -- Valarjar Insignia
21 | [139021] = true, -- Dreamweaver Insignia
22 | [139023] = true, -- Court of Farondis Insignia
23 | [139024] = true, -- Highmountain Tribe Insignia
24 | [139025] = true, -- Wardens Insignia
25 | [139026] = true, -- Nightfallen Insignia
26 | [139390] = true, -- Artifact Research Notes
27 | [140260] = true, -- Arcane Remnant of Falanaar
28 | [141870] = true, -- Arcane Tablet of Falanaar
29 | [141987] = true, -- Greater Valarjar Insignia
30 | [141988] = true, -- Greater Dreamweaver Insignia
31 | [141989] = true, -- Greater Court of Farondis Insignia
32 | [141990] = true, -- Greater Highmountain Tribe Insignia
33 | [141991] = true, -- Greater Wardens Insignia
34 | [141992] = true, -- Greater Nightfallen Insignia
35 | }
36 |
37 |
38 | local function Test()
39 | for bag=0,4 do
40 | for slot=1,GetContainerNumSlots(bag) do
41 | local itemid = GetContainerItemID(bag, slot)
42 | if itemid and OPENABLE_IDS[itemid] then return itemid end
43 | end
44 | end
45 | end
46 |
47 |
48 | local lastid
49 | function dataobj:Scan()
50 | if not ns.dbpc[self.name.."-enabled"] then
51 | self.player = nil
52 | return
53 | end
54 |
55 | lastid = Test()
56 | if lastid then
57 | local num = GetItemCount(lastid)
58 | local itemname, _, _, _, _, _, _, _, _, texture = GetItemInfo(lastid)
59 | if itemname ~= nil then
60 | self.player = ns.IconLine(texture, itemname.. " (".. num.. ")")
61 | else
62 | -- we probably haven't seen the item yet so it's not cached
63 | self.player = nil
64 | end
65 | else
66 | self.player = nil
67 | end
68 | end
69 |
70 | ae.RegisterEvent(dataobj, "BAG_UPDATE_DELAYED", "Scan")
71 |
72 |
73 | function dataobj:CorkIt(frame)
74 | if lastid then
75 | return frame:SetManyAttributes("type1", "item", "item1", "item:"..lastid)
76 | end
77 | end
78 |
--------------------------------------------------------------------------------
/externals/tooltip_scanner.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 |
4 |
5 | local tip = CreateFrame("GameTooltip")
6 | tip:SetOwner(WorldFrame, "ANCHOR_NONE")
7 |
8 | ns.scantip = tip
9 |
10 |
11 | local lcache, rcache = {}, {}
12 | for i=1,30 do
13 | lcache[i], rcache[i] = tip:CreateFontString(), tip:CreateFontString()
14 | lcache[i]:SetFontObject(GameFontNormal)
15 | rcache[i]:SetFontObject(GameFontNormal)
16 | tip:AddFontStrings(lcache[i], rcache[i])
17 | end
18 |
19 |
20 | -- GetText cache tables, provide fast access to the tooltip's text
21 | tip.L = setmetatable({}, {
22 | __index = function(t, key)
23 | if tip:NumLines() >= key and lcache[key] then
24 | local v = lcache[key]:GetText()
25 | t[key] = v
26 | return v
27 | end
28 | return nil
29 | end,
30 | })
31 |
32 |
33 | tip.R = setmetatable({}, {
34 | __index = function(t, key)
35 | if tip:NumLines() >= key and rcache[key] then
36 | local v = rcache[key]:GetText()
37 | t[key] = v
38 | return v
39 | end
40 | return nil
41 | end,
42 | })
43 |
44 |
45 | -- Performes a "full" erase of the tooltip
46 | tip.Erase = function(self)
47 | self:ClearLines() -- Ensures tooltip's NumLines is reset
48 | for i in pairs(self.L) do self.L[i] = nil end -- Flush the metatable cache
49 | for i in pairs(self.R) do
50 | self.rcache[i]:SetText() -- Clear text from right side (ClearLines only hides them)
51 | self.R[i] = nil -- Flush the metatable cache
52 | end
53 | if not self:IsOwned(WorldFrame) then
54 | self:SetOwner(WorldFrame, "ANCHOR_NONE")
55 | end
56 | end
57 |
58 |
59 | -- Hooks the Set* methods to force a full erase beforehand
60 | local methods = {"SetMerchantCostItem", "SetBagItem", "SetAction",
61 | "SetAuctionItem", "SetAuctionSellItem", "SetBuybackItem", "SetCraftItem",
62 | "SetCraftSpell", "SetHyperlink", "SetInboxItem", "SetInventoryItem",
63 | "SetLootItem", "SetLootRollItem", "SetMerchantItem", "SetPetAction",
64 | "SetPlayerBuff", "SetQuestItem", "SetQuestLogItem", "SetQuestRewardSpell",
65 | "SetSendMailItem", "SetShapeshift", "SetSpell", "SetTalent",
66 | "SetTrackingSpell", "SetTradePlayerItem", "SetTradeSkillItem",
67 | "SetTradeTargetItem", "SetTrainerService", "SetUnit", "SetUnitBuff",
68 | "SetUnitDebuff"}
69 | for _,m in pairs(methods) do
70 | local orig = tip[m]
71 | tip[m] = function(self, ...)
72 | self:Erase()
73 | return orig(self, ...)
74 | end
75 | end
76 |
77 |
--------------------------------------------------------------------------------
/modules/GarrisonWorkOrders.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 | local level = UnitLevel("player")
4 | local ae = LibStub("AceEvent-3.0")
5 |
6 |
7 | -- Items only available when you have a garrison
8 | if level < 90 then return end
9 |
10 |
11 | local name = "Completed work orders"
12 |
13 |
14 | local dataobj = ns:New(name)
15 | dataobj.tiptext = "Notify you when you are in your garrison and have completed work orders"
16 | dataobj.priority = 20
17 | ns.defaultspc[name.."-enabled"] = true
18 |
19 |
20 | local blacklist = {
21 | [29] = true,
22 | [136] = true,
23 | [137] = true,
24 | }
25 | local function Test(self, building)
26 | if not ns.InGarrison() then return end
27 |
28 | local id = building.buildingID
29 | if id then
30 | local _, _, _, numready, total = C_Garrison.GetLandingPageShipmentInfo(id)
31 | numready = numready or 0
32 | total = total or 0
33 |
34 | if total > 0 and numready == total then return true end
35 | if not blacklist[id] and total > 0 and (total - numready) <= 9 then
36 | return true
37 | end
38 | end
39 | end
40 |
41 |
42 | local function RequestRefresh()
43 | if not ns.InGarrison() then return end
44 | C_Garrison.RequestLandingPageShipmentInfo()
45 | end
46 |
47 |
48 | function dataobj:Scan(...)
49 | if not ns.dbpc[self.name.."-enabled"] then
50 | self.player = nil
51 | return
52 | end
53 |
54 | local buildings = C_Garrison.GetBuildings(LE_GARRISON_TYPE_6_0)
55 | for i,building in pairs(buildings) do
56 | if Test(self, building) then
57 | local _, name, _, icon = C_Garrison.GetBuildingInfo(building.buildingID)
58 | local _, _, _, numready, total, started = C_Garrison.GetLandingPageShipmentInfo(building.buildingID)
59 |
60 | if numready == total then
61 | self["building"..building.buildingID] = ns.IconLine(icon, name)
62 | else
63 | local timeleft = (total - numready) * 4 - (time() - started) /60/60
64 | local title = string.format("%s (%dhr)", name, timeleft)
65 | self["building"..building.buildingID] = ns.IconLine(icon, title)
66 | end
67 | else
68 | self["building"..building.buildingID] = nil
69 | end
70 | end
71 | end
72 |
73 |
74 | ae.RegisterEvent(dataobj, "GARRISON_LANDINGPAGE_SHIPMENTS", "Scan")
75 | ae.RegisterEvent("Cork"..name, "ZONE_CHANGED", RequestRefresh)
76 | ae.RegisterEvent("Cork"..name, "BAG_UPDATE_DELAYED", RequestRefresh)
77 | ae.RegisterEvent("Cork"..name, "SHIPMENT_CRAFTER_INFO", RequestRefresh)
78 |
--------------------------------------------------------------------------------
/modules/LancePole.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local IconLine = Cork.IconLine
4 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
5 |
6 |
7 | local function Test(self, id)
8 | return self.items[id]
9 | end
10 |
11 |
12 | local incombat
13 | local lastitems = {}
14 | local function Scan(self, event)
15 | if event == "PLAYER_REGEN_DISABLED" then incombat = true
16 | elseif event == "PLAYER_REGEN_ENABLED" then incombat = false end
17 |
18 | local id = GetInventoryItemID("player", self.slot)
19 | if id and not self:Test(id) then
20 | lastitems[self] = GetInventoryItemLink("player", self.slot)
21 | end
22 |
23 | if not Cork.dbpc[self.name.."-enabled"] or not id or not self:Test(id) then
24 | self.player = nil
25 | return
26 | end
27 |
28 | self.player = IconLine(GetItemIcon(id), (GetItemInfo(id)))
29 | end
30 |
31 |
32 | local function CorkIt(self)
33 | local id = GetInventoryItemID("player", self.slot)
34 | if id and not self:Test(id) then return end
35 |
36 | local link = lastitems[self]
37 | if link then EquipItemByName(link); return true end
38 | end
39 |
40 |
41 | function Cork:GenerateEquippedWarning(name, slot, ...)
42 | local dataobj = ldb:NewDataObject("Cork "..name, {
43 | type = "cork",
44 | corktype = "item",
45 | name = name,
46 | slot = slot,
47 | Test = Test,
48 | Scan = Scan,
49 | CorkIt = CorkIt,
50 | items = {...},
51 | priority = 9,
52 | tiptext = "Warn when you have a ".. name:lower()..
53 | " equipped at a time you probably don't want it.",
54 | })
55 |
56 | for i=1,select("#", ...) do dataobj.items[select(i, ...)] = true end
57 |
58 | Cork.defaultspc[name.."-enabled"] = true
59 |
60 | ae.RegisterEvent(dataobj, "UNIT_INVENTORY_CHANGED", "Scan")
61 | ae.RegisterEvent(dataobj, "PLAYER_REGEN_DISABLED", "Scan")
62 | ae.RegisterEvent(dataobj, "PLAYER_REGEN_ENABLED", "Scan")
63 |
64 | return dataobj
65 | end
66 |
67 |
68 | local back = GetInventorySlotInfo("BackSlot")
69 | Cork:GenerateEquippedWarning("Teleport cloak", back,
70 | 63206, 63207, 65274, 65360, 83353, 83352)
71 |
72 |
73 | local mainhand = GetInventorySlotInfo("MainHandSlot")
74 | Cork:GenerateEquippedWarning("Lance", mainhand, 46069, 46106, 46070, 52716)
75 |
76 | local poles = Cork:GenerateEquippedWarning("Fishing pole", mainhand,
77 | 6256, 6365, 6366, 6367, 12225, 19022, 19970, -- Classic
78 | 25978, -- BC
79 | 44050, 45858, 45991, 45992, -- Wrath
80 | 46337, 52678, -- Cat
81 | 84660, 84661) -- PANDAS!
82 |
83 | function poles:Test(id)
84 | return Test(self, id) and not incombat
85 | end
86 |
--------------------------------------------------------------------------------
/AceEvent-3.0/AceEvent-3.0.lua:
--------------------------------------------------------------------------------
1 | --[[ $Id: AceEvent-3.0.lua 60131 2008-02-03 13:03:56Z nevcairiel $ ]]
2 | local MAJOR, MINOR = "AceEvent-3.0", 3
3 | local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
4 |
5 | if not AceEvent then return end
6 |
7 | local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
8 |
9 |
10 | AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
11 | AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
12 |
13 |
14 | -- APIs and registry for blizzard events, using CallbackHandler lib
15 | if not AceEvent.events then
16 | AceEvent.events = CallbackHandler:New(AceEvent,
17 | "RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
18 | end
19 |
20 | function AceEvent.events:OnUsed(target, eventname)
21 | AceEvent.frame:RegisterEvent(eventname)
22 | end
23 |
24 | function AceEvent.events:OnUnused(target, eventname)
25 | AceEvent.frame:UnregisterEvent(eventname)
26 | end
27 |
28 |
29 | -- APIs and registry for IPC messages, using CallbackHandler lib
30 | if not AceEvent.messages then
31 | AceEvent.messages = CallbackHandler:New(AceEvent,
32 | "RegisterMessage", "UnregisterMessage", "UnregisterAllMessages"
33 | )
34 | AceEvent.SendMessage = AceEvent.messages.Fire
35 | end
36 |
37 | --- embedding and embed handling
38 | local mixins = {
39 | "RegisterEvent", "UnregisterEvent",
40 | "RegisterMessage", "UnregisterMessage",
41 | "SendMessage",
42 | "UnregisterAllEvents", "UnregisterAllMessages",
43 | }
44 |
45 | -- AceEvent:Embed( target )
46 | -- target (object) - target object to embed AceEvent in
47 | --
48 | -- Embeds AceEvent into the target object making the functions from the mixins list available on target:..
49 | function AceEvent:Embed(target)
50 | for k, v in pairs(mixins) do
51 | target[v] = self[v]
52 | end
53 | self.embeds[target] = true
54 | return target
55 | end
56 |
57 | -- AceEvent:OnEmbedDisable( target )
58 | -- target (object) - target object that is being disabled
59 | --
60 | -- Unregister all events messages etc when the target disables.
61 | -- this method should be called by the target manually or by an addon framework
62 | function AceEvent:OnEmbedDisable(target)
63 | target:UnregisterAllEvents()
64 | target:UnregisterAllMessages()
65 | end
66 |
67 | -- Script to fire blizzard events into the event listeners
68 | local events = AceEvent.events
69 | AceEvent.frame:SetScript("OnEvent", function(this, event, ...)
70 | events:Fire(event, ...)
71 | end)
72 |
73 | --- Finally: upgrade our old embeds
74 | for target, v in pairs(AceEvent.embeds) do
75 | AceEvent:Embed(target)
76 | end
77 |
--------------------------------------------------------------------------------
/modules/Combine.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local IconLine = Cork.IconLine
4 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
5 |
6 | local ITEMS = {
7 | [33567] = 5,
8 | [34056] = 3,
9 | [52718] = 3,
10 | [52720] = 3,
11 | [52977] = 5,
12 | [74252] = 3,
13 | [89112] = 10,
14 | [90407] = 10,
15 | [115502] = 10,
16 | [115504] = 10,
17 |
18 | [110610] = 10,
19 | [108391] = 10,
20 | [109991] = 10,
21 | [109992] = 10,
22 |
23 | [111589] = 20,
24 | [111662] = 20,
25 | [118564] = 20,
26 | [111595] = 10,
27 | [118565] = 10,
28 | [111601] = 5,
29 | [118566] = 5,
30 | }
31 |
32 | -- Receipts can combine from the bank
33 | local receipts = {
34 | [118592] = 2,
35 | [119094] = 2,
36 | [119095] = 2,
37 | [119096] = 2,
38 | [119097] = 2,
39 | [119098] = 2,
40 | [119099] = 2,
41 | [119100] = 2,
42 | [119101] = 2,
43 | [119102] = 2,
44 | }
45 | for i,v in pairs(receipts) do ITEMS[i] = v end
46 |
47 | for i=37700,37705 do ITEMS[i] = 10 end -- crystallized elements
48 | for i=97619,97624 do ITEMS[i] = 10 end -- panda herbs
49 | for i=108318,108365 do ITEMS[i] = 10 end -- herbalism
50 | for i=109624,109629 do ITEMS[i] = 10 end -- draenor herbs
51 | for i=108294,108309 do ITEMS[i] = 10 end -- mining
52 | for i=111650,111659 do ITEMS[i] = 5 end -- small draenor fish
53 | for i=111663,111676 do ITEMS[i] = 5 end -- medium and large draenor fish
54 |
55 |
56 | Cork.defaultspc["Combine-enabled"] = true
57 |
58 | local dataobj = ldb:NewDataObject("Cork Combine", {
59 | type = "cork",
60 | corktype = "item",
61 | tiptext = "Warn when you have items in your bags that can be condensed like essences and crystalized elements.",
62 | })
63 |
64 | function dataobj:Scan()
65 | if not Cork.dbpc["Combine-enabled"] or InCombatLockdown() then
66 | dataobj.player = nil
67 | return
68 | end
69 |
70 | for id,threshold in pairs(ITEMS) do
71 | local bank = not not receipts[id]
72 | local count = GetItemCount(id, bank) or 0
73 | if count >= threshold then
74 | local itemName, _, _, _, _, _, _, _, _, itemTexture = GetItemInfo(id)
75 | if itemName then
76 | dataobj.player = IconLine(itemTexture, itemName.." ("..count..")")
77 | return
78 | end
79 | end
80 | end
81 | dataobj.player = nil
82 | end
83 |
84 | ae.RegisterEvent("Cork Combine", "BAG_UPDATE", dataobj.Scan)
85 |
86 | function dataobj:CorkIt(frame)
87 | if dataobj.player then
88 | for id,threshold in pairs(ITEMS) do
89 | local bank = not not receipts[id]
90 | if (GetItemCount(id, bank) or 0) >= threshold then
91 | return frame:SetManyAttributes("type1", "item", "item1", "item:"..id)
92 | end
93 | end
94 | end
95 | end
96 |
--------------------------------------------------------------------------------
/externals/ui-tab.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, ns = ...
3 |
4 |
5 | local function activatetab(self)
6 | self.left:ClearAllPoints()
7 | self.left:SetPoint("TOPLEFT")
8 | self.left:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-ActiveTab")
9 | self.middle:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-ActiveTab")
10 | self.right:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-ActiveTab")
11 | self:Disable()
12 | end
13 |
14 |
15 | local function deactivatetab(self)
16 | self.left:ClearAllPoints()
17 | self.left:SetPoint("BOTTOMLEFT", 0, 2)
18 | self.left:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-InActiveTab")
19 | self.middle:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-InActiveTab")
20 | self.right:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-InActiveTab")
21 | self:Enable()
22 | end
23 |
24 |
25 | local function SetTextHelper(self, ...)
26 | self:SetWidth(40 + self:GetFontString():GetStringWidth())
27 | return ...
28 | end
29 |
30 |
31 | local function NewSetText(self, ...)
32 | return SetTextHelper(self, self.OrigSetText(self, ...))
33 | end
34 |
35 |
36 | -- Creates a tab.
37 | -- All args optional but parent is highly recommended
38 | function ns.NewTab(parent, text, ...)
39 | local tab = CreateFrame("Button", nil, parent)
40 | tab:SetHeight(24)
41 | if select(1, ...) then tab:SetPoint(...) end
42 | tab:SetFrameLevel(tab:GetFrameLevel() + 4)
43 |
44 | tab.left = tab:CreateTexture(nil, "BORDER")
45 | tab.left:SetWidth(20) tab.left:SetHeight(24)
46 | tab.left:SetTexCoord(0, 0.15625, 0, 1)
47 |
48 | tab.right = tab:CreateTexture(nil, "BORDER")
49 | tab.right:SetWidth(20) tab.right:SetHeight(24)
50 | tab.right:SetPoint("TOP", tab.left)
51 | tab.right:SetPoint("RIGHT", tab)
52 | tab.right:SetTexCoord(0.84375, 1, 0, 1)
53 |
54 | tab.middle = tab:CreateTexture(nil, "BORDER")
55 | tab.middle:SetHeight(24)
56 | tab.middle:SetPoint("LEFT", tab.left, "RIGHT")
57 | tab.middle:SetPoint("RIGHT", tab.right, "Left")
58 | tab.middle:SetTexCoord(0.15625, 0.84375, 0, 1)
59 |
60 | tab:SetHighlightTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight", "ADD")
61 | local hilite = tab:GetHighlightTexture()
62 | hilite:ClearAllPoints()
63 | hilite:SetPoint("LEFT", 10, -4)
64 | hilite:SetPoint("RIGHT", -10, -4)
65 |
66 | tab:SetDisabledFontObject(GameFontHighlightSmall)
67 | tab:SetHighlightFontObject(GameFontHighlightSmall)
68 | tab:SetNormalFontObject(GameFontNormalSmall)
69 | tab.OrigSetText = tab.SetText
70 | tab.SetText = NewSetText
71 | if text then tab:SetText(text) end
72 |
73 | tab.Activate, tab.Deactivate = activatetab, deactivatetab
74 | tab:Activate()
75 |
76 | return tab
77 | end
78 |
79 |
--------------------------------------------------------------------------------
/tekKonfig/tekKonfigSlider.lua:
--------------------------------------------------------------------------------
1 |
2 | local lib, oldminor = LibStub:NewLibrary("tekKonfig-Slider", 3)
3 | if not lib then return end
4 | oldminor = oldminor or 0
5 |
6 |
7 | local GameTooltip = GameTooltip
8 | local function HideTooltip() GameTooltip:Hide() end
9 | local function ShowTooltip(self)
10 | if self.tiptext then
11 | GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
12 | GameTooltip:SetText(self.tiptext, nil, nil, nil, nil, true)
13 | end
14 | end
15 |
16 |
17 | local HorizontalSliderBG = {
18 | bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
19 | edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
20 | edgeSize = 8, tile = true, tileSize = 8,
21 | insets = {left = 3, right = 3, top = 6, bottom = 6}
22 | }
23 |
24 |
25 | if oldminor < 2 then
26 | -- Create a slider.
27 | -- All args optional, parent recommended
28 | -- If lowvalue and highvalue are strings it is assumed they are % values
29 | -- and the % is parsed and set as decimal values for min/max
30 | function lib.new(parent, label, lowvalue, highvalue, ...)
31 | local container = CreateFrame("Frame", nil, parent)
32 | container:SetWidth(144)
33 | container:SetHeight(17+12+10)
34 | if select(1, ...) then container:SetPoint(...) end
35 |
36 | local slider = CreateFrame("Slider", nil, container)
37 | slider:SetPoint("LEFT")
38 | slider:SetPoint("RIGHT")
39 | slider:SetHeight(17)
40 | slider:SetHitRectInsets(0, 0, -10, -10)
41 | slider:SetOrientation("HORIZONTAL")
42 | slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal") -- Dim: 32x32... can't find API to set this?
43 | slider:SetBackdrop(HorizontalSliderBG)
44 |
45 | local text = slider:CreateFontString(nil, "ARTWORK", "GameFontNormal")
46 | text:SetPoint("BOTTOM", slider, "TOP")
47 | text:SetText(label)
48 |
49 | local low = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
50 | low:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", -4, 3)
51 | low:SetText(lowvalue)
52 |
53 | local high = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
54 | high:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", 4, 3)
55 | high:SetText(highvalue)
56 |
57 | if type(lowvalue) == "string" then slider:SetMinMaxValues(tonumber((lowvalue:gsub("%%", "")))/100, tonumber((highvalue:gsub("%%", "")))/100)
58 | else slider:SetMinMaxValues(lowvalue, highvalue) end
59 |
60 | -- Tooltip bits
61 | slider:SetScript("OnEnter", ShowTooltip)
62 | slider:SetScript("OnLeave", HideTooltip)
63 |
64 | return slider, text, container, low, high
65 | end
66 | end
67 |
68 |
69 | -- Create a slider without labels.
70 | -- All args optional, parent recommended
71 | function lib.newbare(parent, ...)
72 | local slider = CreateFrame("Slider", nil, parent)
73 | slider:SetHeight(17)
74 | slider:SetWidth(144)
75 | if select(1, ...) then slider:SetPoint(...) end
76 | slider:SetOrientation("HORIZONTAL")
77 | slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal") -- Dim: 32x32... can't find API to set this?
78 | slider:SetBackdrop(HorizontalSliderBG)
79 |
80 | -- Tooltip bits
81 | slider:SetScript("OnEnter", ShowTooltip)
82 | slider:SetScript("OnLeave", HideTooltip)
83 |
84 | return slider
85 | end
86 |
--------------------------------------------------------------------------------
/modules/Repairs.lua:
--------------------------------------------------------------------------------
1 |
2 |
3 | local myname, Cork = ...
4 | local SpellCastableOnUnit, IconLine = Cork.SpellCastableOnUnit, Cork.IconLine
5 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
6 |
7 | local SLOTIDS, ICON = {}, "Interface\\Minimap\\Tracking\\Repair"
8 | for _,slot in pairs({"Head", "Shoulder", "Chest", "Waist", "Legs", "Feet", "Wrist", "Hands", "MainHand", "SecondaryHand"}) do SLOTIDS[slot] = GetInventorySlotInfo(slot .. "Slot") end
9 |
10 |
11 | local function RYGColorGradient(perc)
12 | local relperc = perc*2 % 1
13 | if perc <= 0 then return 1, 0, 0
14 | elseif perc < 0.5 then return 1, relperc, 0
15 | elseif perc == 0.5 then return 1, 1, 0
16 | elseif perc < 1.0 then return 1 - relperc, 1, 0
17 | else return 0, 1, 0 end
18 | end
19 |
20 |
21 | local defaults = Cork.defaultspc
22 | defaults["Repairs-enabled"] = true
23 | defaults["Repairs-threshold"] = .85
24 |
25 | local dataobj = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject("Cork Repairs", {type = "cork", tiptext = "Warn you if your equipment needs repaired and you are in a city or resting."})
26 |
27 | local function Test()
28 | if not Cork.dbpc["Repairs-enabled"] or InCombatLockdown() then return end
29 |
30 | local min = 1
31 | for slot,id in pairs(SLOTIDS) do
32 | local v1, v2 = GetInventoryItemDurability(id)
33 |
34 | if v1 and v2 and v2 ~= 0 then
35 | min = math.min(v1/v2, min)
36 | end
37 | end
38 |
39 | if min >= Cork.dbpc["Repairs-threshold"] or min >= 0.15 and not IsResting() then return end
40 |
41 | local r,g,b = RYGColorGradient(min)
42 | return IconLine(ICON, string.format("Your equipment is damaged |cff%02x%02x%02x(%d%%)", r*255, g*255, b*255, min*100))
43 | end
44 |
45 | function dataobj:Scan() dataobj.player = Test() end
46 |
47 | ae.RegisterEvent("Cork Repairs", "UPDATE_INVENTORY_DURABILITY", dataobj.Scan)
48 | ae.RegisterEvent("Cork Repairs", "PLAYER_UPDATE_RESTING", dataobj.Scan)
49 | ae.RegisterEvent("Cork Repairs", "PLAYER_REGEN_DISABLED", dataobj.Scan)
50 | ae.RegisterEvent("Cork Repairs", "PLAYER_REGEN_ENABLED", dataobj.Scan)
51 |
52 |
53 | ----------------------
54 | -- Config --
55 | ----------------------
56 |
57 | local frame = CreateFrame("Frame", nil, Cork.config)
58 | frame:SetWidth(1) frame:SetHeight(1)
59 | dataobj.configframe = frame
60 | frame:Hide()
61 |
62 | frame:SetScript("OnShow", function()
63 | local slider = LibStub("tekKonfig-Slider").newbare(frame, "RIGHT")
64 | slider.tiptext = "Durability threshold. If the lowest equipped item durability percent is below this, a reminder will be shown when you are resting."
65 | slider:SetMinMaxValues(0,1)
66 | slider:SetValueStep(0.05)
67 |
68 | local slidertext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
69 | slidertext:SetPoint("RIGHT", slider, "LEFT")
70 |
71 | slider:SetScript("OnValueChanged", function(self, newvalue)
72 | newvalue = math.floor(newvalue*20)/20
73 | Cork.dbpc["Repairs-threshold"] = newvalue
74 | slidertext:SetFormattedText("%d%%", newvalue*100)
75 | dataobj:Scan()
76 | end)
77 |
78 |
79 | local function Update(self) slider:SetValue(Cork.dbpc["Repairs-threshold"]) end
80 | frame:SetScript("OnShow", Update)
81 | Update(frame)
82 | end)
83 |
--------------------------------------------------------------------------------
/tekKonfig/tekKonfigScroll.lua:
--------------------------------------------------------------------------------
1 |
2 | local lib, oldminor = LibStub:NewLibrary("tekKonfig-Scroll", 2)
3 | if not lib then return end
4 |
5 | lib.bg = {
6 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
7 | tile = true,
8 | tileSize = 16,
9 | edgeSize = 12,
10 | insets = { left = 0, right = 0, top = 5, bottom = 5 }
11 | }
12 |
13 | -- Creates a scrollbar
14 | -- Parent is required, offset and step are optional
15 | function lib.new(parent, offset, step)
16 | local f = CreateFrame("Slider", nil, parent)
17 | f:SetWidth(16)
18 |
19 | f:SetPoint("TOPRIGHT", 0 - (offset or 0), -16 - (offset or 0))
20 | f:SetPoint("BOTTOMRIGHT", 0 - (offset or 0), 16 + (offset or 0))
21 |
22 | local up = CreateFrame("Button", nil, f)
23 | up:SetPoint("BOTTOM", f, "TOP")
24 | up:SetWidth(16) up:SetHeight(16)
25 | up:SetNormalTexture("Interface\\Buttons\\UI-ScrollBar-ScrollUpButton-Up")
26 | up:SetPushedTexture("Interface\\Buttons\\UI-ScrollBar-ScrollUpButton-Down")
27 | up:SetDisabledTexture("Interface\\Buttons\\UI-ScrollBar-ScrollUpButton-Disabled")
28 | up:SetHighlightTexture("Interface\\Buttons\\UI-ScrollBar-ScrollUpButton-Highlight")
29 |
30 | up:GetNormalTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
31 | up:GetPushedTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
32 | up:GetDisabledTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
33 | up:GetHighlightTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
34 | up:GetHighlightTexture():SetBlendMode("ADD")
35 |
36 | up:SetScript("OnClick", function(self)
37 | local parent = self:GetParent()
38 | parent:SetValue(parent:GetValue() - (step or parent:GetHeight()/2))
39 | PlaySound(SOUNDKIT.U_CHAT_SCROLL_BUTTON)
40 | end)
41 |
42 | local down = CreateFrame("Button", nil, f)
43 | down:SetPoint("TOP", f, "BOTTOM")
44 | down:SetWidth(16) down:SetHeight(16)
45 | down:SetNormalTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Up")
46 | down:SetPushedTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Down")
47 | down:SetDisabledTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Disabled")
48 | down:SetHighlightTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Highlight")
49 |
50 | down:GetNormalTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
51 | down:GetPushedTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
52 | down:GetDisabledTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
53 | down:GetHighlightTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
54 | down:GetHighlightTexture():SetBlendMode("ADD")
55 |
56 | down:SetScript("OnClick", function(self)
57 | local parent = self:GetParent()
58 | parent:SetValue(parent:GetValue() + (step or parent:GetHeight()/2))
59 | PlaySound(SOUNDKIT.U_CHAT_SCROLL_BUTTON)
60 | end)
61 |
62 | f:SetThumbTexture("Interface\\Buttons\\UI-ScrollBar-Knob")
63 | local thumb = f:GetThumbTexture()
64 | thumb:SetWidth(16) thumb:SetHeight(24)
65 | thumb:SetTexCoord(1/4, 3/4, 1/8, 7/8)
66 |
67 | f:SetScript("OnValueChanged", function(self, value)
68 | local min, max = self:GetMinMaxValues()
69 | if value == min then up:Disable() else up:Enable() end
70 | if value == max then down:Disable() else down:Enable() end
71 | end)
72 |
73 | local border = CreateFrame("Frame", nil, f)
74 | border:SetPoint("TOPLEFT", up, -5, 5)
75 | border:SetPoint("BOTTOMRIGHT", down, 5, -3)
76 | border:SetBackdrop(lib.bg)
77 | border:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b, 0.5)
78 |
79 | return f, up, down, border
80 | end
81 |
--------------------------------------------------------------------------------
/tekKonfig/tekKonfigDropdown.lua:
--------------------------------------------------------------------------------
1 |
2 | local lib, oldminor = LibStub:NewLibrary("tekKonfig-Dropdown", 3)
3 | if not lib then return end
4 | oldminor = oldminor or 0
5 |
6 |
7 | local GameTooltip = GameTooltip
8 | local function HideTooltip() GameTooltip:Hide() end
9 | local function ShowTooltip(self)
10 | if self.frame.tiptext then
11 | GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT")
12 | GameTooltip:SetText(self.frame.tiptext, nil, nil, nil, nil, true)
13 | end
14 | end
15 | local function ShowTooltip2(self) ShowTooltip(self.container) end
16 |
17 |
18 | local function OnClick(self)
19 | ToggleDropDownMenu(nil, nil, self:GetParent())
20 | PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON)
21 | end
22 |
23 | local function OnHide() CloseDropDownMenus() end
24 |
25 |
26 | -- Create a dropdown.
27 | -- All args optional, parent recommended
28 | function lib.new(parent, label, ...)
29 | local container = CreateFrame("Button", nil, parent)
30 | container:SetWidth(149+13) container:SetHeight(32+24)
31 | container:SetScript("OnEnter", ShowTooltip)
32 | container:SetScript("OnLeave", HideTooltip)
33 | if select("#", ...) > 0 then container:SetPoint(...) end
34 |
35 | local name = "tekKonfigDropdown"..GetTime() -- Sadly, some of these frames must be named
36 | local f = CreateFrame("Frame", name, parent)
37 | f:SetWidth(149) f:SetHeight(32)
38 | f:SetPoint("TOPLEFT", container, -13, -24)
39 | f:EnableMouse(true)
40 | f:SetScript("OnHide", OnHide)
41 | container.frame = f
42 |
43 | local ltex = f:CreateTexture(name.."Left", "ARTWORK")
44 | ltex:SetWidth(25) ltex:SetHeight(64)
45 | ltex:SetPoint("TOPLEFT", 0, 17)
46 | ltex:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame")
47 | ltex:SetTexCoord(0, 0.1953125, 0, 1)
48 |
49 | local rtex = f:CreateTexture(nil, "ARTWORK")
50 | rtex:SetWidth(25) rtex:SetHeight(64)
51 | rtex:SetPoint("RIGHT")
52 | rtex:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame")
53 | rtex:SetTexCoord(0.8046875, 1, 0, 1)
54 |
55 | local mtex = f:CreateTexture(nil, "ARTWORK")
56 | mtex:SetWidth(115) mtex:SetHeight(64)
57 | mtex:SetPoint("LEFT", ltex, "RIGHT")
58 | mtex:SetPoint("RIGHT", rtex, "LEFT")
59 | mtex:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame")
60 | mtex:SetTexCoord(0.1953125, 0.8046875, 0, 1)
61 |
62 | local text = f:CreateFontString(name.."Text", "ARTWORK", "GameFontHighlightSmall")
63 | text:SetWidth(0) text:SetHeight(10)
64 | text:SetPoint("RIGHT", rtex, -43, 2)
65 | text:SetJustifyH("RIGHT")
66 |
67 | local button = CreateFrame("Button", nil, f)
68 | button:SetWidth(24) button:SetHeight(24)
69 | button:SetPoint("TOPRIGHT", rtex, -16, -18)
70 | button:SetScript("OnClick", OnClick)
71 | button:SetScript("OnEnter", ShowTooltip2)
72 | button.container = container
73 |
74 | button:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up")
75 | button:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Down")
76 | button:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight")
77 | button:SetDisabledTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Disabled")
78 | button:GetHighlightTexture():SetBlendMode("ADD")
79 |
80 | local labeltext = f:CreateFontString(nil, "BACKGROUND", "GameFontNormal")--GameFontHighlight
81 | labeltext:SetPoint("BOTTOMLEFT", container, "TOPLEFT", 16-13, 3-24)
82 | labeltext:SetText(label)
83 |
84 | return f, text, container, labeltext
85 | end
86 |
87 |
--------------------------------------------------------------------------------
/LibDataBroker-1.1/LibDataBroker-1.1.lua:
--------------------------------------------------------------------------------
1 |
2 | assert(LibStub, "LibDataBroker-1.1 requires LibStub")
3 | assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
4 |
5 | local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
6 | if not lib then return end
7 | oldminor = oldminor or 0
8 |
9 |
10 | lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
11 | lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
12 | local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
13 |
14 | if oldminor < 2 then
15 | lib.domt = {
16 | __metatable = "access denied",
17 | __index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
18 | }
19 | end
20 |
21 | if oldminor < 3 then
22 | lib.domt.__newindex = function(self, key, value)
23 | if not attributestorage[self] then attributestorage[self] = {} end
24 | if attributestorage[self][key] == value then return end
25 | attributestorage[self][key] = value
26 | local name = namestorage[self]
27 | if not name then return end
28 | callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
29 | callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
30 | callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
31 | callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
32 | end
33 | end
34 |
35 | if oldminor < 2 then
36 | function lib:NewDataObject(name, dataobj)
37 | if self.proxystorage[name] then return end
38 |
39 | if dataobj then
40 | assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
41 | self.attributestorage[dataobj] = {}
42 | for i,v in pairs(dataobj) do
43 | self.attributestorage[dataobj][i] = v
44 | dataobj[i] = nil
45 | end
46 | end
47 | dataobj = setmetatable(dataobj or {}, self.domt)
48 | self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
49 | self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
50 | return dataobj
51 | end
52 | end
53 |
54 | if oldminor < 1 then
55 | function lib:DataObjectIterator()
56 | return pairs(self.proxystorage)
57 | end
58 |
59 | function lib:GetDataObjectByName(dataobjectname)
60 | return self.proxystorage[dataobjectname]
61 | end
62 |
63 | function lib:GetNameByDataObject(dataobject)
64 | return self.namestorage[dataobject]
65 | end
66 | end
67 |
68 | if oldminor < 4 then
69 | local next = pairs(attributestorage)
70 | function lib:pairs(dataobject_or_name)
71 | local t = type(dataobject_or_name)
72 | assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
73 |
74 | local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
75 | assert(attributestorage[dataobj], "Data object not found")
76 |
77 | return next, attributestorage[dataobj], nil
78 | end
79 |
80 | local ipairs_iter = ipairs(attributestorage)
81 | function lib:ipairs(dataobject_or_name)
82 | local t = type(dataobject_or_name)
83 | assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
84 |
85 | local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
86 | assert(attributestorage[dataobj], "Data object not found")
87 |
88 | return ipairs_iter, attributestorage[dataobj], 0
89 | end
90 | end
91 |
--------------------------------------------------------------------------------
/templates/RaidBuffingItems.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local UnitAura = Cork.UnitAura or UnitAura
4 | local IsSpellInRange = Cork.IsSpellInRange
5 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
6 |
7 |
8 | local partyunits, raidunits = {}, {}
9 | for i=1,4 do partyunits["party"..i] = i end
10 | for i=1,40 do raidunits["raid"..i] = i end
11 | local function ValidUnit(unit, nopets)
12 | if not (unit == "player" or partyunits[unit] or raidunits[unit]) or not UnitExists(unit) or (not UnitIsConnected(unit) or UnitIsDeadOrGhost(unit) or UnitInVehicle(unit))
13 | or raidunits[unit] and select(3, GetRaidRosterInfo(raidunits[unit])) > Cork.RaidThresh() then return end
14 |
15 | return true
16 | end
17 |
18 |
19 | function Cork:GenerateItemBuffer(class, itemid, spellid, classspellid)
20 | local multiclass = type(class) == "table"
21 | if Cork.MYCLASS == class or multiclass and class[Cork.MYCLASS] then return end
22 |
23 | Cork.hasgroupspell = true
24 |
25 | local spellname = GetSpellInfo(spellid)
26 | local classspellname = GetSpellInfo(classspellid)
27 | local itemname = GetItemInfo(itemid)
28 | local icon = GetItemIcon(itemid)
29 |
30 | local SpellCastableOnUnit, IconLine = self.SpellCastableOnUnit, self.IconLine
31 |
32 | local dataobj = ldb:NewDataObject("Cork "..spellname, {
33 | type = "cork",
34 | corktype = "buff",
35 | tiplink = "item:"..itemid,
36 | })
37 |
38 | Cork.defaultspc[spellname.."-enabled"] = true
39 |
40 | local hasclass
41 | local function TestUnit(unit)
42 | local _, _, _, _, _, c = GetRaidRosterInfo(unit)
43 | return class == c or multiclass and class[c]
44 | end
45 | local function ScanForClass()
46 | hasclass = false
47 | for i=1,GetNumGroupMembers() do if TestUnit(i) then hasclass = true; return end end
48 | end
49 |
50 | local function Test(unit)
51 | if hasclass or not Cork.dbpc[spellname.."-enabled"] or (IsResting() and not Cork.db.debug) or not ValidUnit(unit) or (GetItemCount(itemid) or 0) == 0 then return end
52 | if unit == "player" and GetNumGroupMembers() == 0 then return end
53 |
54 | if not (UnitAura(unit, classspellname) or UnitAura(unit, spellname)) then
55 | local _, token = UnitClass(unit)
56 | return IconLine(icon, UnitName(unit), token)
57 | end
58 | end
59 |
60 | function dataobj:Scan()
61 | ScanForClass()
62 | self.player = Test("player")
63 | for i=1,4 do self["party"..i] = Test("party"..i) end
64 | for i=1,40 do self["raid"..i] = Test("raid"..i) end
65 | end
66 |
67 | ae.RegisterEvent(dataobj, "GROUP_ROSTER_UPDATE", "Scan")
68 | ae.RegisterEvent(dataobj, "PLAYER_UPDATE_RESTING", "Scan")
69 | ae.RegisterEvent("Cork "..spellname, "UNIT_AURA", function(event, unit) dataobj[unit] = Test(unit) end)
70 |
71 |
72 | dataobj.RaidLine = IconLine(icon, spellname.." (%d)")
73 |
74 |
75 | local raidneeds = {}
76 | function dataobj:CorkIt(frame)
77 | if (GetItemCount(itemid) or 0) == 0 then return end
78 |
79 | -- Only use our item if everyone in need is in range, online and alive
80 | local cast = false
81 | for i=1,GetNumGroupMembers() do
82 | local unit = "raid"..i
83 | if select(3, GetRaidRosterInfo(i)) > Cork.RaidThresh() then
84 | local _, _, _, _, _, _, zone, online, dead = GetRaidRosterInfo(i)
85 | if not online or dead then return end
86 | if dataobj[unit] and (not zone or not ValidUnit(unit) or IsItemInRange(17202, unit) ~= 1) then return end
87 | if dataobj[unit] then cast = true end
88 | end
89 | end
90 | for i=1,GetNumSubgroupMembers() do
91 | local unit = "party"..i
92 | if dataobj[unit] and (not ValidUnit(unit) or IsItemInRange(17202, unit) ~= 1) then return end
93 | if dataobj[unit] then cast = true end
94 | end
95 | if cast then return frame:SetManyAttributes("type1", "item", "item1", "item:"..itemid) end
96 | end
97 | end
98 |
--------------------------------------------------------------------------------
/modules/Paladin.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "PALADIN" then return end
4 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
5 |
6 | -- Righteous Fury
7 | local spellname, _, icon = GetSpellInfo(25780)
8 | Cork:GenerateSelfBuffer(spellname, icon)
9 |
10 | -- Greater Blessings are any combination of 2 blessings across the whole raid.
11 | local spellnames = {(GetSpellInfo(203538)), (GetSpellInfo(203539))}
12 | local _, _, icon = GetSpellInfo(203538)
13 | local rolespells = {TANK=1, DAMAGER=2, HEALER=3}
14 | local dataobj = ldb:NewDataObject("Cork Greater Blessings", {
15 | type = "cork",
16 | corktype = "buff",
17 | tiplink = GetSpellLink(203538)
18 | })
19 |
20 | function dataobj:Init()
21 | Cork.defaultspc["Greater Blessings-enabled"] = GetSpellInfo(spellnames[1]) ~= nil
22 | end
23 |
24 | local raidunits, partyunits, otherunits = {}, {}, { ["player"] = true }
25 | for i=1,40 do raidunits["raid"..i] = i end
26 | for i=1,4 do partyunits["party"..i] = i end
27 | function dataobj:Test(unit)
28 | if not UnitExists(unit) or (unit ~= "player" and UnitIsUnit(unit, "player"))
29 | or (IsInRaid() and partyunits[unit])
30 | or (not raidunits[unit] and not partyunits[unit] and not otherunits[unit]) then return 0 end
31 | local count = 0
32 | for _, spellname in ipairs(spellnames) do
33 | if UnitAura(unit, spellname, nil, "PLAYER") then
34 | count = count + 1
35 | end
36 | end
37 | return count
38 | end
39 | function dataobj:Scan(enteringcombat)
40 | if not Cork.dbpc["Greater Blessings-enabled"] or (IsResting() and not Cork.db.debug) or (enteringcombat or InCombatLockdown()) then
41 | self.player = nil
42 | return
43 | end
44 | local count = self:Test("player")
45 | -- We can't scan the same unit twice or we'll get inaccurate results
46 | if IsInRaid() then
47 | for k, _ in pairs(raidunits) do
48 | count = count + self:Test(k)
49 | if count >= 2 then break end
50 | end
51 | elseif IsInGroup() then
52 | for k, _ in pairs(partyunits) do
53 | count = count + self:Test(k)
54 | if count >= 2 then break end
55 | end
56 | end
57 | if count < 2 then
58 | self.player = Cork.IconLine(icon, string.format("Greater Blessings (%d)", 2 - count))
59 | else
60 | self.player = nil
61 | end
62 | end
63 | function dataobj:CorkIt(frame)
64 | if self.player and Cork.SpellCastableOnUnit(spellnames[1], "player") then
65 | -- figure out which spell in the list we don't have
66 | -- prioritize the first spell based on our role
67 | local role = GetSpecializationRole(GetSpecialization())
68 | local rolespell = rolespells[role]
69 | if role and not UnitAura("player", spellnames[rolespell], nil, "PLAYER") then -- should this be player-only?
70 | return frame:SetManyAttributes("type1", "spell", "spell", spellnames[rolespell], "unit", "player")
71 | end
72 | -- otherwise just do the spells in order
73 | for _, spellname in ipairs(spellnames) do
74 | if not UnitAura("player", spellname, nil, "PLAYER") then -- should this be player-only?
75 | return frame:SetManyAttributes("type1", "spell", "spell", spellname, "unit", "player")
76 | end
77 | end
78 | end
79 | end
80 | local function isScanUnit(unit)
81 | return not not (raidunits[unit] or partyunits[unit] or otherunits[unit])
82 | end
83 | function dataobj:TestUnit(event, unit)
84 | if isScanUnit(unit) then self:Scan() end
85 | end
86 | ae.RegisterEvent(dataobj, "UNIT_AURA", "TestUnit")
87 | ae.RegisterEvent(dataobj, "GROUP_ROSTER_UPDATE", "TestUnit")
88 | ae.RegisterEvent(dataobj, "PLAYER_UPDATE_RESTING", function () dataobj:Scan() end)
89 | ae.RegisterEvent(dataobj, "PLAYER_REGEN_DISABLED", function () dataobj:Scan(true) end)
90 | ae.RegisterEvent(dataobj, "PLAYER_REGEN_ENABLED", function () dataobj:Scan() end)
91 |
92 | -- Beacon of Light
93 | local spellname, _, icon = GetSpellInfo(53563)
94 | local dataobj = Cork:GenerateLastBuffedBuffer(spellname, icon)
95 | dataobj.partyonly = true
96 | dataobj.ignoreplayer = true
97 |
--------------------------------------------------------------------------------
/modules/Tracking.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local SpellCastableOnUnit, IconLine = Cork.SpellCastableOnUnit, Cork.IconLine
4 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
5 |
6 | local NOTRACKING = "Interface\\Minimap\\Tracking\\None"
7 | local textures, spells = {}, {}
8 |
9 |
10 | local dataobj = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject("Cork Tracking", {type = "cork", tiptext = "Warn when you are not tracking anything on the minimap."})
11 |
12 | local function Test()
13 | if not Cork.dbpc["Tracking-enabled"] then return end
14 |
15 | for i=1,GetNumTrackingTypes() do
16 | local name, texture, active, category = GetTrackingInfo(i)
17 | if active and category == "spell" then return
18 | elseif active then return IconLine(textures[Cork.dbpc["Tracking-spell"]], Cork.dbpc["Tracking-spell"]) end
19 | end
20 | return IconLine(textures[Cork.dbpc["Tracking-spell"]], Cork.dbpc["Tracking-spell"])
21 | --~ local x = GetTrackingTexture()
22 | --~ if x == mybuff then return end
23 | end
24 |
25 | local function UpdateSpells()
26 | for i in pairs(spells) do spells[i] = nil end
27 | for i=1,GetNumTrackingTypes() do
28 | local name, texture, active, category = GetTrackingInfo(i)
29 | textures[name] = texture
30 | if category == "spell" then table.insert(spells, name) end
31 | end
32 | end
33 |
34 | function dataobj:Init()
35 | local name, texture, active, category = GetTrackingInfo(1)
36 | Cork.defaultspc["Tracking-enabled"] = category ~= "other"
37 | Cork.defaultspc["Tracking-spell"] = name
38 | UpdateSpells()
39 | end
40 | function dataobj:Scan() dataobj.player = Test() end
41 |
42 | ae.RegisterEvent("Cork Tracking", "MINIMAP_UPDATE_TRACKING", dataobj.Scan)
43 |
44 | function dataobj:CorkIt(frame)
45 | local spell = Cork.dbpc["Tracking-spell"]
46 | local id
47 | for i = 1, GetNumTrackingTypes() do
48 | if GetTrackingInfo(i) == spell then
49 | id = i
50 | break
51 | end
52 | end
53 | if id then
54 | if self.player then return frame:SetManyAttributes("type1", "macro", "macrotext1", "/run SetTracking("..id..", true)") end
55 | end
56 | end
57 |
58 |
59 | ----------------------
60 | -- Config --
61 | ----------------------
62 |
63 | local frame = CreateFrame("Frame", nil, Cork.config)
64 | frame:SetWidth(1) frame:SetHeight(1)
65 | dataobj.configframe = frame
66 | frame:Hide()
67 |
68 | frame:SetScript("OnShow", function()
69 | local EDGEGAP, ROWHEIGHT, ROWGAP, GAP = 16, 18, 2, 4
70 | local Update
71 |
72 | local function OnClick(self)
73 | Cork.dbpc["Tracking-spell"] = self.spell
74 | Update()
75 | dataobj:Scan()
76 | end
77 |
78 | local function OnEnter(self)
79 | GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
80 | GameTooltip:SetText(self.spell, nil, nil, nil, nil, true)
81 | end
82 | local function OnLeave() GameTooltip:Hide() end
83 |
84 |
85 | local buffbuttons = setmetatable({}, {__index = function(t, i)
86 | local butt = CreateFrame("CheckButton", nil, frame)
87 | butt:SetWidth(ROWHEIGHT) butt:SetHeight(ROWHEIGHT)
88 |
89 | local tex = butt:CreateTexture(nil, "BACKGROUND")
90 | tex:SetAllPoints()
91 | tex:SetTexCoord(4/48, 44/48, 4/48, 44/48)
92 | butt.icon = tex
93 |
94 | butt:SetPushedTexture("Interface\\Buttons\\UI-Quickslot-Depress")
95 | butt:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square")
96 | butt:SetCheckedTexture("Interface\\Buttons\\CheckButtonHilight")
97 |
98 | butt:SetScript("OnClick", OnClick)
99 | butt:SetScript("OnEnter", OnEnter)
100 | butt:SetScript("OnLeave", OnLeave)
101 |
102 | t[i] = butt
103 | return butt
104 | end})
105 |
106 | function Update(self)
107 | local lasticon
108 | for i,spell in ipairs(spells) do
109 | local butt = buffbuttons[i]
110 | butt.icon:SetTexture(textures[spell])
111 | butt:SetChecked(Cork.dbpc["Tracking-spell"] == spell)
112 | if lasticon then lasticon:SetPoint("RIGHT", butt, "LEFT", -ROWGAP, 0) end
113 | lasticon, butt.spell = butt, spell
114 | end
115 | if lasticon then lasticon:SetPoint("RIGHT", 0, 0) end
116 | end
117 |
118 | frame:SetScript("OnShow", Update)
119 | Update(frame)
120 | end)
121 |
--------------------------------------------------------------------------------
/modules/WarlockPets.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | if Cork.MYCLASS ~= "WARLOCK" then return end
4 |
5 |
6 | local myname, Cork = ...
7 | local IconLine = Cork.IconLine
8 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
9 |
10 |
11 | local soulburn = GetSpellInfo(74434)
12 |
13 | local knowssoulburn
14 | local spellidlist = {688, 697, 712, 691, 30146, 157757, 1122}
15 | local buffnames, icons, known = {}, {}, {}
16 | for _,id in pairs(spellidlist) do
17 | local spellname, _, icon = GetSpellInfo(id)
18 | buffnames[id], icons[spellname] = spellname, icon
19 | end
20 |
21 | Cork.defaultspc["Summon demon-spell"] = buffnames[spellidlist[1]]
22 |
23 | local dataobj = ldb:NewDataObject("Cork Summon demon", {type = "cork"})
24 |
25 | local function RefreshKnownSpells() -- Refresh in case the player has learned this since login
26 | for buff in pairs(icons) do if known[buff] == nil then known[buff] = GetSpellInfo(buff) end end
27 | end
28 |
29 | function dataobj:Init() RefreshKnownSpells() Cork.defaultspc["Summon demon-enabled"] = known[buffnames[spellidlist[1]]] ~= nil end
30 | function dataobj:Scan()
31 | if IsMounted() or not Cork.dbpc["Summon demon-enabled"] or UnitExists("pet") then dataobj.player = nil
32 | else dataobj.player = IconLine(icons[Cork.dbpc["Summon demon-spell"]], Cork.dbpc["Summon demon-spell"]) end
33 |
34 | end
35 |
36 | ae.RegisterEvent("Cork Summon demon", "UNIT_PET", function(event, unit) if unit == "player" then dataobj:Scan() end end)
37 | ae.RegisterEvent("Cork mount check", "COMPANION_UPDATE", function(event, type) if type == "MOUNT" then dataobj:Scan() end end)
38 | function dataobj:CorkIt(frame)
39 | if self.player then
40 | knowssoulburn = knowssoulburn or GetSpellInfo(soulburn)
41 | if knowssoulburn then
42 | return frame:SetManyAttributes("type1", "macro", "macrotext1", "/cast ".. soulburn.. "\n/cast ".. Cork.dbpc["Summon demon-spell"])
43 | else
44 | return frame:SetManyAttributes("type1", "spell", "spell", Cork.dbpc["Summon demon-spell"])
45 | end
46 | end
47 | end
48 |
49 |
50 | ----------------------
51 | -- Config --
52 | ----------------------
53 |
54 | local frame = CreateFrame("Frame", nil, Cork.config)
55 | frame:SetWidth(1) frame:SetHeight(1)
56 | dataobj.configframe = frame
57 | frame:Hide()
58 |
59 | frame:SetScript("OnShow", function()
60 | local EDGEGAP, ROWHEIGHT, ROWGAP, GAP = 16, 18, 2, 4
61 | local buffbuttons = {}
62 |
63 | local function OnClick(self)
64 | Cork.dbpc["Summon demon-spell"] = self.buff
65 | for buff,butt in pairs(buffbuttons) do butt:SetChecked(butt == self) end
66 | dataobj:Scan()
67 | end
68 |
69 | local function OnEnter(self)
70 | GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
71 | GameTooltip:SetHyperlink(GetSpellLink(self.buff))
72 | end
73 | local function OnLeave() GameTooltip:Hide() end
74 |
75 |
76 | local lasticon
77 | for _,id in ipairs(spellidlist) do
78 | local buff = buffnames[id]
79 |
80 | local butt = CreateFrame("CheckButton", nil, frame)
81 | butt:SetWidth(ROWHEIGHT) butt:SetHeight(ROWHEIGHT)
82 |
83 | local tex = butt:CreateTexture(nil, "BACKGROUND")
84 | tex:SetAllPoints()
85 | tex:SetTexture(icons[buff])
86 | tex:SetTexCoord(4/48, 44/48, 4/48, 44/48)
87 | butt.icon = tex
88 |
89 | butt:SetPushedTexture("Interface\\Buttons\\UI-Quickslot-Depress")
90 | butt:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square")
91 | butt:SetCheckedTexture("Interface\\Buttons\\CheckButtonHilight")
92 |
93 | if lasticon then lasticon:SetPoint("RIGHT", butt, "LEFT", -ROWGAP, 0) end
94 |
95 | butt.buff = buff
96 | butt:SetScript("OnClick", OnClick)
97 | butt:SetScript("OnEnter", OnEnter)
98 | butt:SetScript("OnLeave", OnLeave)
99 |
100 | buffbuttons[buff], lasticon = butt, butt
101 | end
102 | lasticon:SetPoint("RIGHT", 0, 0)
103 |
104 | local function Update(self)
105 | RefreshKnownSpells()
106 |
107 | for buff,butt in pairs(buffbuttons) do
108 | butt:SetChecked(Cork.dbpc["Summon demon-spell"] == buff)
109 | if known[buff] then
110 | butt:Enable()
111 | butt.icon:SetVertexColor(1.0, 1.0, 1.0)
112 | else
113 | butt:Disable()
114 | butt.icon:SetVertexColor(0.4, 0.4, 0.4)
115 | end
116 | end
117 | end
118 |
119 | frame:SetScript("OnShow", Update)
120 | Update(frame)
121 | end)
122 |
--------------------------------------------------------------------------------
/modules/WellFed.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local UnitAura = UnitAura
4 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
5 |
6 |
7 | local spellname, _, icon = GetSpellInfo(57139)
8 | local spellname2 = GetSpellInfo(44102)
9 |
10 | local iconline = Cork.IconLine(icon, spellname)
11 |
12 | local dataobj = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject("Cork "..spellname, {
13 | type = "cork",
14 | corktype = "buff",
15 | priority = 7,
16 | tiptext = "Warn when you are not well fed.",
17 | nobg = true,
18 | })
19 |
20 | Cork.defaultspc[spellname.."-enabled"] = UnitLevel("player") >= 10
21 |
22 | local function Test(unit)
23 | if not Cork.dbpc[spellname.."-enabled"] then return end
24 | if not IsInInstance() then return end
25 | if UnitAura("player", spellname) then return end
26 | if UnitAura("player", spellname2) then return end
27 | return iconline
28 | end
29 |
30 | LibStub("AceEvent-3.0").RegisterEvent("Cork "..spellname, "UNIT_AURA", function(event, unit) if unit == "player" then dataobj.custom = Test() end end)
31 | LibStub("AceEvent-3.0").RegisterEvent("Cork "..spellname, "PLAYER_UPDATE_RESTING", function() dataobj.custom = Test() end)
32 |
33 | function dataobj:Scan() self.custom = Test() end
34 |
35 | function dataobj:CorkIt(frame)
36 | local macro = Cork.dbpc[spellname.."-macro"]
37 | local id = Cork.dbpc[spellname.."-item"]
38 | if self.custom and id and GetItemCount(id) > 0 then
39 | return frame:SetManyAttributes("type1", "item", "item1", "item:"..id)
40 | end
41 | end
42 |
43 |
44 | ----------------------
45 | -- Config --
46 | ----------------------
47 |
48 | local frame = CreateFrame("Frame", nil, Cork.config)
49 | frame:SetWidth(1) frame:SetHeight(1)
50 | dataobj.configframe = frame
51 | frame:Hide()
52 |
53 | local FOOD_TYPE, FOOD_SUBTYPE = 0, 5
54 | local function IsFood(id)
55 | if not id then return end
56 |
57 | local _, _, _, _, _, _, _, _, _, _, _, type, subtype = GetItemInfo(id)
58 | return type == FOOD_TYPE and subtype == FOOD_SUBTYPE
59 | end
60 |
61 | frame:SetScript("OnShow", function()
62 | local EDGEGAP, ROWHEIGHT, ROWGAP, GAP = 16, 18, 2, 4
63 | local Update
64 | local FOOD = GetAuctionItemSubClasses(4)
65 |
66 | local function GetFoods()
67 | local t = {}
68 | local mylevel = UnitLevel('player')
69 |
70 | if Cork.dbpc[spellname.."-item"] then
71 | t[Cork.dbpc[spellname.."-item"]] = true
72 | end
73 |
74 | for bag=0,4 do
75 | for slot=1,GetContainerNumSlots(bag) do
76 | local id = GetContainerItemID(bag, slot)
77 | if IsFood(id) then t[id] = true end
78 | end
79 | end
80 |
81 | local sorted = {}
82 | for i in pairs(t) do table.insert(sorted, i) end
83 | table.sort(sorted)
84 | return sorted
85 | end
86 |
87 | local function OnClick(self)
88 | Cork.dbpc[spellname.."-item"] = self.itemid
89 | Update()
90 | dataobj:Scan()
91 | end
92 |
93 | local function OnEnter(self)
94 | GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
95 | GameTooltip:SetHyperlink("item:"..self.itemid)
96 | end
97 | local function OnLeave() GameTooltip:Hide() end
98 |
99 |
100 | local buffbuttons = setmetatable({}, {__index = function(t, i)
101 | local butt = CreateFrame("CheckButton", nil, frame)
102 | butt:SetWidth(ROWHEIGHT) butt:SetHeight(ROWHEIGHT)
103 |
104 | local tex = butt:CreateTexture(nil, "BACKGROUND")
105 | tex:SetAllPoints()
106 | tex:SetTexCoord(4/48, 44/48, 4/48, 44/48)
107 | butt.icon = tex
108 |
109 | butt:SetPushedTexture("Interface\\Buttons\\UI-Quickslot-Depress")
110 | butt:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square")
111 | butt:SetCheckedTexture("Interface\\Buttons\\CheckButtonHilight")
112 |
113 | butt:SetScript("OnClick", OnClick)
114 | butt:SetScript("OnEnter", OnEnter)
115 | butt:SetScript("OnLeave", OnLeave)
116 |
117 | t[i] = butt
118 | return butt
119 | end})
120 |
121 | function Update(self)
122 | for _,f in pairs(buffbuttons) do f:Hide(); f:ClearAllPoints() end
123 | local foods = GetFoods()
124 | local lasticon
125 | for i,id in ipairs(foods) do
126 | local butt = buffbuttons[id]
127 | butt.icon:SetTexture(GetItemIcon(id))
128 | butt:SetChecked(Cork.dbpc[spellname.."-item"] == id)
129 | butt:Show()
130 | if lasticon then lasticon:SetPoint("RIGHT", butt, "LEFT", -ROWGAP, 0) end
131 | lasticon, butt.itemid = butt, id
132 | end
133 | if lasticon then lasticon:SetPoint("RIGHT", 0, 0) end
134 | end
135 |
136 | frame:SetScript("OnShow", Update)
137 | Update(frame)
138 | end)
139 |
--------------------------------------------------------------------------------
/templates/RaidBuffer.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local UnitAura = Cork.UnitAura or UnitAura
4 | local IsSpellInRange = Cork.IsSpellInRange
5 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
6 |
7 |
8 | local blist = {npc = true, vehicle = true}
9 | for i=1,5 do blist["arena"..i], blist["arenapet"..i] = true, true end
10 |
11 | local MagicClasses = {["DRUID"] = true, ["MAGE"] = true, ["PALADIN"] = true, ["PRIEST"] = true, ["SHAMAN"] = true, ["WARLOCK"] = true}
12 |
13 | -- Create a raid buffing module. This module will try to make sure all group
14 | -- members have this buff
15 | --
16 | -- spellname - the name of our spell (give a localized one!)
17 | -- icon - the icon to show in the tip
18 | -- altspellname - name of other buff that fills this need, like Kings and Mark
19 | -- manausers_only - this buff is useless to folks without mana, ignore them
20 | -- extra_test - an extra check not covered in the generator. If this
21 | -- returns false and other conditions are not met, the need is
22 | -- displayed. Return true if the need is filled.
23 | function Cork:GenerateRaidBuffer(spellname, icon, altspellname, manausers_only, extra_test)
24 | local SpellCastableOnUnit, IconLine = self.SpellCastableOnUnit, self.IconLine
25 |
26 | local dataobj = ldb:NewDataObject("Cork "..spellname, {
27 | type = "cork",
28 | corktype = "buff",
29 | tiplink = GetSpellLink(spellname),
30 | })
31 |
32 | function dataobj:Init()
33 | Cork.defaultspc[spellname.."-enabled"] = GetSpellInfo(spellname) ~= nil
34 | end
35 |
36 | local function Test(unit)
37 | if not Cork.dbpc[spellname.."-enabled"] or (IsResting() and not Cork.db.debug) or not Cork:ValidUnit(unit) then return end
38 |
39 | if not UnitAura(unit, spellname) and (not altspellname or not UnitAura(unit, altspellname)) and (not extra_test or not extra_test(unit)) then
40 | local _, token = UnitClass(unit)
41 | if not manausers_only or MagicClasses[token] then return IconLine(icon, UnitName(unit), token) end
42 | end
43 | end
44 | Cork:RegisterRaidEvents(spellname, dataobj, Test)
45 | dataobj.Scan = Cork:GenerateRaidScan(Test)
46 |
47 | ae.RegisterEvent(dataobj, "PLAYER_UPDATE_RESTING", "Scan")
48 |
49 |
50 | dataobj.RaidLine = IconLine(icon, spellname.." (%d)")
51 |
52 |
53 | function dataobj:CorkIt(frame)
54 | local spell = altspellname and GetSpellInfo(altspellname) or spellname
55 | if self.player and SpellCastableOnUnit(spell, "player") then return frame:SetManyAttributes("type1", "spell", "spell", spell, "unit", "player") end
56 | for unit in ldb:pairs(self) do if SpellCastableOnUnit(spell, unit) then return frame:SetManyAttributes("type1", "spell", "spell", spell, "unit", unit) end end
57 | end
58 | end
59 |
60 | local raidunits, partyunits, otherunits = {}, {}, { ["player"] = true, ["target"] = true, ["focus"] = true }
61 | for i=1,40 do raidunits["raid"..i] = i end
62 | for i=1,4 do partyunits["party"..i] = i end
63 | function Cork:ValidUnit(unit)
64 | if blist[unit] or not UnitExists(unit) or (UnitIsPlayer(unit) and (not UnitIsConnected(unit) or UnitIsDeadOrGhost(unit) or UnitInVehicle(unit)))
65 | or (UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) -- No pets, ever
66 | or (unit ~= "player" and UnitIsUnit(unit, "player"))
67 | or (unit == "target" and (UnitIsUnit("target", "focus") or not UnitCanAssist("player", unit) or not UnitIsPlayer(unit) or UnitIsEnemy("player", unit)))
68 | or (unit == "focus" and not UnitCanAssist("player", unit))
69 | or (IsInRaid() and partyunits[unit])
70 | or raidunits[unit] and select(3, GetRaidRosterInfo(raidunits[unit])) > Cork.RaidThresh() then return end
71 |
72 | return true
73 | end
74 | local function isScanUnit(unit)
75 | return not not (raidunits[unit] or partyunits[unit] or otherunits[unit])
76 | end
77 |
78 |
79 | function Cork:RegisterRaidEvents(spellname, dataobj, Test)
80 | local function TestUnit(event, unit) if isScanUnit(unit) then dataobj[unit] = Test(unit) end end
81 | ae.RegisterEvent("Cork "..spellname, "UNIT_AURA", TestUnit)
82 | ae.RegisterEvent("Cork "..spellname, "UNIT_DYNAMIC_FLAGS", TestUnit)
83 | ae.RegisterEvent("Cork "..spellname, "UNIT_ENTERED_VEHICLE", TestUnit)
84 | ae.RegisterEvent("Cork "..spellname, "UNIT_EXITED_VEHICLE", TestUnit)
85 | ae.RegisterEvent("Cork "..spellname, "UNIT_FLAGS", TestUnit)
86 | ae.RegisterEvent("Cork "..spellname, "GROUP_ROSTER_UPDATE", function()
87 | for k, _ in pairs(partyunits) do dataobj[k] = Test(k) end
88 | for k, _ in pairs(raidunits) do dataobj[k] = Test(k) end
89 | end)
90 | local function TestTargetandFocus() dataobj.target, dataobj.focus = Test("target"), Test("focus") end
91 | ae.RegisterEvent("Cork "..spellname, "PLAYER_TARGET_CHANGED", TestTargetandFocus)
92 | ae.RegisterEvent("Cork "..spellname, "PLAYER_FOCUS_CHANGED", TestTargetandFocus)
93 | end
94 |
95 |
96 | function Cork:GenerateRaidScan(Test)
97 | return function(self)
98 | for k, _ in pairs(otherunits) do self[k] = Test(k) end
99 | for k, _ in pairs(partyunits) do self[k] = Test(k) end
100 | for k, _ in pairs(raidunits) do self[k] = Test(k) end
101 | end
102 | end
103 |
--------------------------------------------------------------------------------
/templates/SelfBufferAdvanced.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local UnitAura = Cork.UnitAura or UnitAura
4 | local SpellCastableOnUnit, IconLine = Cork.SpellCastableOnUnit, Cork.IconLine
5 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
6 |
7 |
8 | function Cork:GenerateAdvancedSelfBuffer(modulename, spellidlist, combatonly, usestance)
9 | local spellname, _, defaulticon = GetSpellInfo(spellidlist[1])
10 | local myname = UnitName("player")
11 | local buffnames, icons, known = {}, {}, {}
12 | for _,id in pairs(spellidlist) do
13 | local spellname, _, icon = GetSpellInfo(id)
14 | buffnames[id], icons[spellname] = spellname, icon
15 | end
16 |
17 | Cork.defaultspc[modulename.."-spell"] = buffnames[spellidlist[1]]
18 |
19 | local dataobj = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject("Cork "..modulename, {
20 | type = "cork",
21 | corktype = "buff",
22 | })
23 |
24 | local function RefreshKnownSpells() -- Refresh in case the player has learned this since login
25 | for buff in pairs(icons) do known[buff] = GetSpellInfo(buff) end
26 | end
27 |
28 | function dataobj:Init()
29 | known = {}
30 | RefreshKnownSpells()
31 | Cork.defaultspc[modulename.."-enabled"] = known[spellname] ~= nil
32 | end
33 |
34 | function dataobj:Test(enteringcombat)
35 | if Cork.dbpc[modulename.."-enabled"] and not (IsResting() and not Cork.db.debug) and (not combatonly or enteringcombat or InCombatLockdown()) then
36 | local spell = Cork.dbpc[modulename.."-spell"]
37 |
38 | if usestance then
39 | for i=1,GetNumShapeshiftForms() do
40 | local _, name, isActive = GetShapeshiftFormInfo(i)
41 | if name == spell and isActive then return end
42 | end
43 | else
44 | for _,buff in pairs(buffnames) do
45 | local name, _, _, _, _, _, _, isMine = UnitAura("player", buff)
46 | if name and isMine then return end
47 | end
48 | end
49 |
50 | local icon = icons[spell]
51 | return IconLine(icon, spell)
52 | end
53 | end
54 |
55 | function dataobj:Scan() self.player = self:Test() end
56 |
57 | function dataobj:CorkIt(frame)
58 | RefreshKnownSpells()
59 | local spell = Cork.dbpc[modulename.."-spell"]
60 | if self.player then return frame:SetManyAttributes("type1", "spell", "spell", spell, "unit", "player") end
61 | end
62 |
63 | if usestance then
64 | ae.RegisterEvent(dataobj, "UPDATE_SHAPESHIFT_FORM", "Scan")
65 | else
66 | ae.RegisterEvent("Cork "..modulename, "UNIT_AURA", function(event, unit)
67 | if unit == "player" then dataobj.player = dataobj:Test() end
68 | end)
69 | end
70 | ae.RegisterEvent(dataobj, "PLAYER_UPDATE_RESTING", "Scan")
71 | if combatonly then
72 | ae.RegisterEvent("Cork "..modulename, "PLAYER_REGEN_DISABLED", function() dataobj.player = dataobj:Test(true) end)
73 | ae.RegisterEvent("Cork "..modulename, "PLAYER_REGEN_ENABLED", function() dataobj.player = nil end)
74 | end
75 |
76 |
77 | ----------------------
78 | -- Config --
79 | ----------------------
80 |
81 | local frame = CreateFrame("Frame", nil, Cork.config)
82 | frame:SetWidth(1) frame:SetHeight(1)
83 | dataobj.configframe = frame
84 | frame:Hide()
85 |
86 | frame:SetScript("OnShow", function()
87 | local EDGEGAP, ROWHEIGHT, ROWGAP, GAP = 16, 18, 2, 4
88 | local buffbuttons = {}
89 |
90 | local function OnClick(self)
91 | Cork.dbpc[modulename.."-spell"] = self.buff
92 | for buff,butt in pairs(buffbuttons) do butt:SetChecked(butt == self) end
93 | dataobj:Scan()
94 | end
95 |
96 | local function OnEnter(self)
97 | GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
98 | GameTooltip:SetHyperlink(GetSpellLink(self.buffid))
99 | end
100 | local function OnLeave() GameTooltip:Hide() end
101 |
102 |
103 | local lasticon
104 | for _,id in ipairs(spellidlist) do
105 | local buff = buffnames[id]
106 |
107 | local butt = CreateFrame("CheckButton", nil, frame)
108 | butt:SetWidth(ROWHEIGHT) butt:SetHeight(ROWHEIGHT)
109 |
110 | local tex = butt:CreateTexture(nil, "BACKGROUND")
111 | tex:SetAllPoints()
112 | tex:SetTexture(icons[buff])
113 | tex:SetTexCoord(4/48, 44/48, 4/48, 44/48)
114 | butt.icon = tex
115 |
116 | butt:SetPushedTexture("Interface\\Buttons\\UI-Quickslot-Depress")
117 | butt:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square")
118 | butt:SetCheckedTexture("Interface\\Buttons\\CheckButtonHilight")
119 |
120 | if lasticon then lasticon:SetPoint("RIGHT", butt, "LEFT", -ROWGAP, 0) end
121 |
122 | butt.buff = buff
123 | butt.buffid = id
124 | butt:SetScript("OnClick", OnClick)
125 | butt:SetScript("OnEnter", OnEnter)
126 | butt:SetScript("OnLeave", OnLeave)
127 | butt:SetMotionScriptsWhileDisabled(true)
128 |
129 | buffbuttons[buff], lasticon = butt, butt
130 | end
131 | lasticon:SetPoint("RIGHT", 0, 0)
132 |
133 | local function Update(self)
134 | RefreshKnownSpells()
135 |
136 | for buff,butt in pairs(buffbuttons) do
137 | butt:SetChecked(Cork.dbpc[modulename.."-spell"] == buff)
138 | if known[buff] then
139 | butt:Enable()
140 | butt.icon:SetVertexColor(1.0, 1.0, 1.0)
141 | else
142 | butt:Disable()
143 | butt.icon:SetVertexColor(0.4, 0.4, 0.4)
144 | end
145 | end
146 | end
147 |
148 | frame:SetScript("OnShow", Update)
149 | Update(frame)
150 | end)
151 |
152 | return dataobj, RefreshKnownSpells
153 | end
154 |
--------------------------------------------------------------------------------
/templates/LastBuffedBuffer.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local UnitAura = Cork.UnitAura or UnitAura
4 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
5 | local blist = {npc = true, vehicle = true, focus = true, target = true}
6 | for i=1,5 do blist["arena"..i], blist["arenapet"..i] = true, true end
7 |
8 |
9 | function Cork:GenerateLastBuffedBuffer(spellname, icon)
10 | local SpellCastableOnUnit, IconLine = Cork.SpellCastableOnUnit, Cork.IconLine
11 |
12 |
13 | local dataobj = ldb:NewDataObject("Cork "..spellname, {
14 | type = "cork",
15 | corktype = "buff",
16 | tiplink = GetSpellLink(spellname),
17 | })
18 |
19 |
20 | local f = CreateFrame("Frame")
21 | f:Hide()
22 |
23 | local endtime, elapsed
24 | local function Test()
25 | if (IsResting() and not Cork.db.debug) then return end
26 | if not Cork.dbpc[spellname.."-enabled"]
27 | or (dataobj.onlyrebuffs and not dataobj.lasttarget)
28 | or (dataobj.partyonly and not IsInGroup()) then
29 |
30 | dataobj.lasttarget, dataobj.custom = nil
31 | f:Hide()
32 | return
33 | end
34 |
35 | local start, duration = GetSpellCooldown(spellname)
36 | if start == 0 then
37 | if dataobj.lasttarget then
38 | if not UnitAura(dataobj.lasttarget, spellname) then
39 | local _, class = UnitClass(dataobj.lasttarget)
40 | return IconLine(icon, dataobj.lasttarget, class)
41 | end
42 |
43 | return
44 | else
45 | return IconLine(icon, spellname)
46 | end
47 | end
48 | endtime = start + duration
49 | f:Show()
50 | end
51 |
52 |
53 | ae.RegisterEvent("Cork "..spellname, "PLAYER_UPDATE_RESTING", function()
54 | dataobj.custom = Test()
55 | end)
56 |
57 | function dataobj:GROUP_ROSTER_UPDATE()
58 | if dataobj.lasttarget and not (UnitInRaid(dataobj.lasttarget) or UnitInParty(dataobj.lasttarget)) then
59 | dataobj.lasttarget, dataobj.custom = nil
60 | end
61 | dataobj:Scan()
62 | end
63 | ae.RegisterEvent(dataobj, "GROUP_ROSTER_UPDATE")
64 |
65 | ae.RegisterEvent("Cork "..spellname, "UNIT_PET", function()
66 | if dataobj.lasttarget and not (UnitInParty(dataobj.lasttarget) or UnitInRaid(dataobj.lasttarget)) then
67 | dataobj.lasttarget, dataobj.custom = nil
68 | end
69 | end)
70 |
71 | ae.RegisterEvent("Cork "..spellname, "UNIT_SPELLCAST_SUCCEEDED", function(event, unit, spell)
72 | if unit == "player" and spell == spellname then dataobj.custom = Test() end
73 | end)
74 |
75 | ae.RegisterEvent("Cork "..spellname, "UNIT_AURA", function(event, unit)
76 | if not Cork.dbpc[spellname.."-enabled"] or blist[unit] then return end
77 |
78 | local name, _, _, _, _, _, _, caster = UnitAura(unit, spellname)
79 | local iscaster = name and caster and UnitIsUnit('player', caster)
80 | local playertargetted = UnitIsUnit('player', unit)
81 |
82 | if iscaster then
83 | if not (self.ignoreplayer and playertargetted) then
84 | dataobj.lasttarget, dataobj.custom = UnitName(unit), nil
85 | end
86 | elseif not name and UnitName(unit) == dataobj.lasttarget then
87 | dataobj.custom = Test()
88 | end
89 | end)
90 |
91 |
92 | local function TestUnit(unit)
93 | if not UnitExists(unit) or GetNumGroupMembers() == 0 then return end
94 | local name, _, _, _, _, _, _, caster = UnitAura(unit, spellname)
95 | if not name or not caster or not UnitIsUnit('player', caster) then return end
96 | dataobj.lasttarget = UnitName(unit)
97 | return true
98 | end
99 | local function FindCurrent()
100 | if TestUnit("player") then return true end
101 | for i=1,GetNumSubgroupMembers() do if TestUnit("party"..i) or TestUnit("partypet"..i) then return true end end
102 | for i=1,GetNumGroupMembers() do if TestUnit("raid"..i) or TestUnit("raidpet"..i) then return true end end
103 | end
104 |
105 | function dataobj:Init()
106 | FindCurrent()
107 | Cork.defaultspc[spellname.."-enabled"] = GetSpellInfo(spellname) ~= nil
108 | end
109 |
110 | function dataobj:Scan()
111 | dataobj.custom = Test()
112 | end
113 |
114 | function dataobj:CorkIt(frame)
115 | if self.custom then return
116 | frame:SetManyAttributes("type1", "spell", "spell", spellname, "unit", dataobj.lasttarget)
117 | end
118 | end
119 |
120 | f:SetScript("OnShow", function() elapsed = GetTime() end)
121 | f:SetScript("OnHide", function() dataobj.custom, endtime = Test() end)
122 | f:SetScript("OnUpdate", function(self, elap)
123 | elapsed = elapsed + elap
124 | if not endtime or elapsed >= endtime then self:Hide() end
125 | end)
126 |
127 |
128 | ----------------------
129 | -- Config --
130 | ----------------------
131 |
132 | local frame = CreateFrame("Frame", nil, Cork.config)
133 | frame:SetWidth(1) frame:SetHeight(1)
134 | dataobj.configframe = frame
135 | frame:Hide()
136 |
137 | frame:SetScript("OnShow", function()
138 | local butt = LibStub("tekKonfig-Button").new_small(frame, "RIGHT")
139 | butt:SetWidth(60) butt:SetHeight(18)
140 | butt:SetText("Clear")
141 | butt:SetScript("OnClick", function(self)
142 | self:Hide() lasttarget, dataobj.custom = nil
143 | end)
144 |
145 | local text = butt:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
146 | text:SetPoint("RIGHT", butt, "LEFT", -4, 0)
147 |
148 | local function Refresh()
149 | if dataobj.lasttarget then
150 | butt:Show()
151 | text:SetText(dataobj.lasttarget)
152 | else butt:Hide() end
153 | end
154 |
155 | local callbackname = "LibDataBroker_AttributeChanged_Cork "..spellname
156 | ldb.RegisterCallback("Cork "..spellname, callbackname, Refresh)
157 |
158 | frame:SetScript("OnShow", Refresh)
159 | Refresh()
160 | end)
161 |
162 | return dataobj
163 | end
164 |
--------------------------------------------------------------------------------
/templates/TempEnchant.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local UnitAura = Cork.UnitAura or UnitAura
4 | local ldb = LibStub:GetLibrary("LibDataBroker-1.1")
5 |
6 | local MAINHAND, OFFHAND = GetInventorySlotInfo("MainHandSlot"), GetInventorySlotInfo("SecondaryHandSlot")
7 | local offhands = {INVTYPE_WEAPON = true, INVTYPE_WEAPONOFFHAND = true}
8 | local _, _, _, _, _, _, _, _, _, _, _, MISC = GetAuctionItemSubClasses(1)
9 | local IconLine = Cork.IconLine
10 |
11 | -- Creates a module for applying temp enchants (poisons, etc) to weapons
12 | --
13 | -- weaponslot - The name of the slot this module is for, best use the globalstrings
14 | -- INVTYPE_WEAPONMAINHAND, INVTYPE_WEAPONOFFHAND or INVTYPE_THROWN
15 | -- spellids - List of spellIDs to use for name and icon lookups
16 | -- minlevel - Lowest level to activate this module for. Not used is itemmap isn't passed.
17 | -- itemmap - A table containing a table of itemIDs for each spellid.
18 | -- If not provided it is assumed the module is using spells instead.
19 | function Cork:GenerateTempEnchant(slotname, spellids, minlevel, itemmap)
20 | local isspells, weaponindex, weaponslot = not itemmap
21 | if slotname == INVTYPE_WEAPONMAINHAND then weaponindex, weaponslot = 1, MAINHAND
22 | elseif slotname == INVTYPE_WEAPONOFFHAND then weaponindex, weaponslot = 2, OFFHAND
23 | else return end
24 |
25 | local f, elapsed = CreateFrame("Frame"), 0
26 | local modulename = "Temp Enchant "..slotname
27 |
28 | local buffnames, icons, known = {}, {}
29 | for _,id in pairs(spellids) do
30 | local spellname, _, icon = GetSpellInfo(id)
31 | buffnames[id], icons[spellname] = spellname, icon
32 | end
33 |
34 | local function RefreshKnownSpells() -- Refresh in case the player has learned this since login
35 | if not isspells then return end
36 | for buff in pairs(icons) do if known[buff] == nil then known[buff] = GetSpellInfo(buff) end end
37 | end
38 |
39 | if not isspells then Cork.defaultspc[modulename.."-enabled"] = UnitLevel("player") >= minlevel end
40 | Cork.defaultspc[modulename.."-spell"] = buffnames[spellids[1]]
41 |
42 | local dataobj = ldb:NewDataObject("Cork "..modulename, {type = "cork"})
43 | local maindataobj = slotname == INVTYPE_WEAPONOFFHAND and ldb:GetDataObjectByName("Cork Temp Enchant "..INVTYPE_WEAPONMAINHAND)
44 |
45 | if isspells then
46 | function dataobj:Init()
47 | known = {}
48 | RefreshKnownSpells()
49 | Cork.defaultspc[modulename.."-enabled"] = not not next(known)
50 | end
51 | end
52 |
53 | function dataobj:Scan() if Cork.dbpc[modulename.."-enabled"] then f:Show() else f:Hide(); dataobj.custom = nil end end
54 |
55 | function dataobj:CorkIt(frame)
56 | if not self.custom then return end
57 | RefreshKnownSpells()
58 | if isspells then
59 | if maindataobj and maindataobj.custom then return end
60 | return frame:SetManyAttributes("type1", "spell", "spell", Cork.dbpc[modulename.."-spell"])
61 | else
62 | local id = itemmap[Cork.dbpc[modulename.."-spell"]]
63 | if id and (GetItemCount(id) or 0) > 0 then return frame:SetManyAttributes("type1", "macro", "macrotext1", "/use item:"..id.."\n/use "..weaponslot) end
64 | end
65 | end
66 |
67 | f:SetScript("OnUpdate", function(self, elap)
68 | elapsed = elapsed + elap
69 | if elapsed < 0.5 then return end
70 | elapsed = 0
71 |
72 | -- Return out if resting (with debug off) or if we have an active spell
73 | if (IsResting() and not Cork.db.debug) or select(weaponindex*3-2, GetWeaponEnchantInfo()) then dataobj.custom = nil return end
74 |
75 | -- Check that we have the right weapon type equipped
76 | local equippedID = GetInventoryItemID("player", weaponslot)
77 | if not equippedID or select(7, GetItemInfo(equippedID)) == MISC
78 | or (slotname == INVTYPE_WEAPONOFFHAND and not offhands[select(9, GetItemInfo(equippedID))])
79 | or (slotname == INVTYPE_THROWN and select(9, GetItemInfo(equippedID)) ~= "INVTYPE_THROWN") then
80 | dataobj.custom = nil
81 | return
82 | end
83 |
84 |
85 | local icon = icons[Cork.dbpc[modulename.."-spell"]]
86 | dataobj.custom = IconLine(icon, slotname)
87 | end)
88 |
89 | ----------------------
90 | -- Config --
91 | ----------------------
92 |
93 | local frame = CreateFrame("Frame", nil, Cork.config)
94 | frame:SetWidth(1) frame:SetHeight(1)
95 | dataobj.configframe = frame
96 | frame:Hide()
97 |
98 | frame:SetScript("OnShow", function()
99 | local EDGEGAP, ROWHEIGHT, ROWGAP, GAP = 16, 18, 2, 4
100 | local buffbuttons = {}
101 |
102 | local function OnClick(self)
103 | Cork.dbpc[modulename.."-spell"] = self.buff
104 | for buff,butt in pairs(buffbuttons) do butt:SetChecked(butt == self) end
105 | dataobj:Scan()
106 | end
107 |
108 | local function OnEnter(self)
109 | GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
110 | GameTooltip:SetText(self.buff)
111 | end
112 | local function OnLeave() GameTooltip:Hide() end
113 |
114 | local function MakeButt(buff)
115 | local butt = CreateFrame("CheckButton", nil, frame)
116 | butt:SetWidth(ROWHEIGHT) butt:SetHeight(ROWHEIGHT)
117 |
118 | local tex = butt:CreateTexture(nil, "BACKGROUND")
119 | tex:SetAllPoints()
120 | tex:SetTexture(icons[buff])
121 | tex:SetTexCoord(4/48, 44/48, 4/48, 44/48)
122 | butt.icon = tex
123 |
124 | butt:SetPushedTexture("Interface\\Buttons\\UI-Quickslot-Depress")
125 | butt:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square")
126 | butt:SetCheckedTexture("Interface\\Buttons\\CheckButtonHilight")
127 |
128 | butt.buff = buff
129 | butt:SetScript("OnClick", OnClick)
130 | butt:SetScript("OnEnter", OnEnter)
131 | butt:SetScript("OnLeave", OnLeave)
132 |
133 | return butt
134 | end
135 |
136 | local lasticon
137 | for _,id in ipairs(spellids) do
138 | local buff = buffnames[id]
139 | local butt = MakeButt(buff)
140 | if lasticon then lasticon:SetPoint("RIGHT", butt, "LEFT", -ROWGAP, 0) end
141 | buffbuttons[buff], lasticon = butt, butt
142 | end
143 | lasticon:SetPoint("RIGHT", 0, 0)
144 |
145 | local function Update(self)
146 | RefreshKnownSpells()
147 | for buff,butt in pairs(buffbuttons) do
148 | butt:SetChecked(Cork.dbpc[modulename.."-spell"] == buff)
149 | if not isspells or known[buff] then
150 | butt:Enable()
151 | butt.icon:SetVertexColor(1.0, 1.0, 1.0)
152 | else
153 | butt:Disable()
154 | butt.icon:SetVertexColor(0.4, 0.4, 0.4)
155 | end
156 | end
157 | end
158 |
159 | frame:SetScript("OnShow", Update)
160 | Update(frame)
161 | end)
162 | end
163 |
--------------------------------------------------------------------------------
/Config.lua:
--------------------------------------------------------------------------------
1 |
2 |
3 | local myname, Cork = ...
4 | local ns = Cork
5 |
6 | local GAP = 8
7 | local tekcheck = LibStub("tekKonfig-Checkbox")
8 |
9 |
10 | local frame = CreateFrame("Frame", nil, InterfaceOptionsFramePanelContainer)
11 | Cork.config = frame
12 | frame.name = "Cork"
13 | frame:Hide()
14 |
15 | frame:SetScript("OnShow", function()
16 | local EDGEGAP, ROWHEIGHT, ROWGAP, GAP = 16, 16, 2, 4
17 |
18 | local title, subtitle = LibStub("tekKonfig-Heading").new(frame, "Cork", "Most of these settings are saved on a per-talent spec basis. Settings will automatically switch when you swap specs.")
19 |
20 | local showanchor = tekcheck.new(frame, nil, "Show anchor", "TOPLEFT", subtitle, "BOTTOMLEFT", -2, -GAP)
21 | showanchor.tiptext = "Toggle the tooltip anchor. \n|cffffff9aThis setting is global."
22 | showanchor:SetScript("OnClick", function(self)
23 | Cork.db.showanchor = not Cork.db.showanchor
24 | if Cork.db.showanchor then Cork.anchor:Show() else Cork.anchor:Hide() end
25 | end)
26 |
27 |
28 | local resetanchor = LibStub("tekKonfig-Button").new_small(frame, "LEFT", showanchor, "RIGHT", 105, 0)
29 | resetanchor:SetWidth(60) resetanchor:SetHeight(18)
30 | resetanchor.tiptext = "Click to reset the anchor to it's default position. \n|cffffff9aPosition is a global setting."
31 | resetanchor:SetText("Reset")
32 | resetanchor:SetScript("OnClick", function()
33 | Cork.db.point, Cork.db.x, Cork.db.y = nil
34 | Cork.anchor:ClearAllPoints()
35 | Cork.anchor:SetPoint(Cork.db.point, Cork.db.x, Cork.db.y)
36 | Cork.Update()
37 | end)
38 |
39 |
40 | local showbg = tekcheck.new(frame, nil, "Show toolip in BG", "TOPLEFT", showanchor, "BOTTOMLEFT", 0, -GAP)
41 | showbg.tiptext = "Show the tooltip when in a battleground or outdoor PvP zone. When the tooltip is hidden the macro will still work."
42 | showbg:SetScript("OnClick", function(self)
43 | Cork.db.showbg = not Cork.db.showbg
44 | Cork.Update()
45 | end)
46 |
47 |
48 | local bindwheel = tekcheck.new(frame, nil, "Bind mousewheel", "TOPLEFT", showbg, "BOTTOMLEFT", 0, -GAP)
49 | bindwheel.tiptext = "Bind to mousewheel when out of combat and needs are present. \n|cffffff9aThis setting is global."
50 | bindwheel:SetScript("OnClick", function(self)
51 | Cork.db.bindwheel = not Cork.db.bindwheel
52 | Cork.UpdateMouseBinding()
53 | end)
54 |
55 |
56 | if tekDebug then
57 | local showunit = tekcheck.new(frame, nil, "Debug mode", "TOPLEFT", bindwheel, "BOTTOMLEFT", 0, -GAP)
58 | showunit.tiptext = "Ignores rest state and shows unitIDs (target, party1, raidpet5) in tooltip."
59 | showunit:SetChecked(Cork.db.debug)
60 | showunit:SetScript("OnClick", function(self)
61 | Cork.db.debug = not Cork.db.debug
62 | Cork.Update()
63 | end)
64 | end
65 |
66 | local group = LibStub("tekKonfig-Group").new(frame, nil, "TOP", subtitle, "BOTTOM", 0, -GAP-22)
67 | group:SetPoint("LEFT", frame, "CENTER", -40, 0)
68 | group:SetPoint("BOTTOMRIGHT", -EDGEGAP, EDGEGAP)
69 |
70 |
71 | local macrobutt = LibStub("tekKonfig-Button").new_small(frame, "BOTTOMRIGHT", group, "TOPRIGHT")
72 | macrobutt:SetWidth(60) macrobutt:SetHeight(18)
73 | macrobutt.tiptext = "Click to generate a macro, or pick it up if already generated."
74 | macrobutt:SetText("Macro")
75 | macrobutt:SetScript("OnClick", Cork.GenerateMacro)
76 |
77 |
78 | local corknames, rows, anchor = {}, {}
79 | local tekcheck = LibStub("tekKonfig-Checkbox")
80 | local NUMROWS = math.floor((group:GetHeight()-EDGEGAP+ROWGAP + 2) / (ROWHEIGHT+ROWGAP))
81 | for _,cork in pairs(Cork.corks) do table.insert(corknames, (cork.name:gsub("Cork ", ""))) end
82 | table.sort(corknames)
83 |
84 | local function OnClick(self)
85 | Cork.dbpc[self.name.."-enabled"] = not Cork.dbpc[self.name.."-enabled"]
86 | PlaySound(Cork.dbpc[self.name.."-enabled"] and SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON or SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF)
87 | self.cork:Scan()
88 | end
89 |
90 | for i=1,NUMROWS do
91 | local name = corknames[i]
92 | if name then
93 | local row = CreateFrame("Button", nil, group)
94 | table.insert(rows, row)
95 |
96 | if anchor then row:SetPoint("TOP", anchor , "BOTTOM", 0, -ROWGAP)
97 | else row:SetPoint("TOP", 0, -EDGEGAP/2) end
98 | row:SetPoint("LEFT", EDGEGAP/2, 0)
99 | row:SetPoint("RIGHT", -EDGEGAP/2, 0)
100 | row:SetHeight(ROWHEIGHT)
101 | anchor = row
102 |
103 |
104 | local check = tekcheck.new(row, ROWHEIGHT+4, nil, "LEFT")
105 | check:SetScript("OnClick", OnClick)
106 | row.check = check
107 |
108 |
109 | local title = row:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
110 | title:SetPoint("LEFT", check, "RIGHT", 4, 0)
111 | row.title = title
112 | end
113 | end
114 |
115 | local currenttab = 'buff'
116 | local function UpdateRows()
117 | for i,row in pairs(rows) do
118 | row:Hide()
119 | if row.configframe then row.configframe:Hide() end
120 | end
121 |
122 | local i = 1
123 | for j,cork in ipairs(Cork.sortedcorks) do
124 | if cork.corktype == currenttab then
125 | local row = rows[i]
126 | if not row then return end
127 | i = i + 1
128 |
129 | row.check.cork = cork
130 | row.check.name = cork.name
131 | row.check.tiptext = cork.tiptext
132 | row.check.tiplink = cork.tiplink
133 | row.check:SetChecked(Cork.dbpc[cork.name.."-enabled"])
134 |
135 | row.title:SetText(cork.name)
136 |
137 | local configframe = cork.configframe
138 | row.configframe = configframe
139 | if configframe then
140 | configframe:SetPoint("RIGHT", row)
141 | configframe:SetFrameLevel(row:GetFrameLevel() + 1)
142 | configframe:Show()
143 | end
144 |
145 | row:Show()
146 | end
147 | end
148 | end
149 |
150 |
151 | local tab1 = ns.NewTab(frame, "Buffs", "BOTTOMLEFT", group, "TOPLEFT", 0, -4)
152 | local tab2 = ns.NewTab(frame, "Items", "LEFT", tab1, "RIGHT", -15, 0)
153 | local tab3 = ns.NewTab(frame, "Other", "LEFT", tab2, "RIGHT", -15, 0)
154 | tab2:Deactivate()
155 | tab3:Deactivate()
156 |
157 | tab1:SetScript("OnClick", function(self)
158 | self:Activate()
159 | tab2:Deactivate()
160 | tab3:Deactivate()
161 | currenttab = 'buff'
162 | UpdateRows()
163 | end)
164 |
165 | tab2:SetScript("OnClick", function(self)
166 | self:Activate()
167 | tab1:Deactivate()
168 | tab3:Deactivate()
169 | currenttab = 'item'
170 | UpdateRows()
171 | end)
172 |
173 | tab3:SetScript("OnClick", function(self)
174 | self:Activate()
175 | tab1:Deactivate()
176 | tab2:Deactivate()
177 | currenttab = nil
178 | UpdateRows()
179 | end)
180 |
181 |
182 | frame.Update = function(self)
183 | if not self:IsVisible() then return end
184 | showanchor:SetChecked(Cork.db.showanchor)
185 | showbg:SetChecked(Cork.db.showbg)
186 | bindwheel:SetChecked(Cork.db.bindwheel)
187 | UpdateRows()
188 | end
189 |
190 | frame:SetScript("OnShow", frame.Update)
191 | frame:Update()
192 | end)
193 |
194 | InterfaceOptions_AddCategory(frame)
195 |
196 |
197 | ----------------------------
198 | -- LDB Launcher --
199 | ----------------------------
200 |
201 | local ldb = LibStub:GetLibrary("LibDataBroker-1.1")
202 | local dataobj = ldb:GetDataObjectByName("CorkLauncher") or ldb:NewDataObject("CorkLauncher", {type = "launcher", icon = "Interface\\Icons\\INV_Drink_11", tocname = "Cork"})
203 | dataobj.OnClick = function() InterfaceOptionsFrame_OpenToCategory(frame) end
204 |
205 |
206 | ----------------------------
207 | -- Key Binding --
208 | ----------------------------
209 |
210 | setglobal("BINDING_HEADER_CORK", "Cork")
211 | setglobal("BINDING_NAME_CLICK CorkFrame:LeftButton", "Click the Cork frame")
212 |
--------------------------------------------------------------------------------
/CallbackHandler-1.0.lua:
--------------------------------------------------------------------------------
1 | --[[ $Id: CallbackHandler-1.0.lua 60548 2008-02-07 11:04:06Z nevcairiel $ ]]
2 | local MAJOR, MINOR = "CallbackHandler-1.0", 3
3 | local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
4 |
5 | if not CallbackHandler then return end -- No upgrade needed
6 |
7 | local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
8 |
9 | local type = type
10 | local pcall = pcall
11 | local pairs = pairs
12 | local assert = assert
13 | local concat = table.concat
14 | local loadstring = loadstring
15 | local next = next
16 | local select = select
17 | local type = type
18 | local xpcall = xpcall
19 |
20 | local function errorhandler(err)
21 | return geterrorhandler()(err)
22 | end
23 |
24 | local function CreateDispatcher(argCount)
25 | local code = [[
26 | local next, xpcall, eh = ...
27 |
28 | local method, ARGS
29 | local function call() method(ARGS) end
30 |
31 | local function dispatch(handlers, ...)
32 | local index
33 | index, method = next(handlers)
34 | if not method then return end
35 | local OLD_ARGS = ARGS
36 | ARGS = ...
37 | repeat
38 | xpcall(call, eh)
39 | index, method = next(handlers, index)
40 | until not method
41 | ARGS = OLD_ARGS
42 | end
43 |
44 | return dispatch
45 | ]]
46 |
47 | local ARGS, OLD_ARGS = {}, {}
48 | for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
49 | code = code:gsub("OLD_ARGS", concat(OLD_ARGS, ", ")):gsub("ARGS", concat(ARGS, ", "))
50 | return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
51 | end
52 |
53 | local Dispatchers = setmetatable({}, {__index=function(self, argCount)
54 | local dispatcher = CreateDispatcher(argCount)
55 | rawset(self, argCount, dispatcher)
56 | return dispatcher
57 | end})
58 |
59 | --------------------------------------------------------------------------
60 | -- CallbackHandler:New
61 | --
62 | -- target - target object to embed public APIs in
63 | -- RegisterName - name of the callback registration API, default "RegisterCallback"
64 | -- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
65 | -- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
66 |
67 | function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
68 | -- TODO: Remove this after beta has gone out
69 | assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
70 |
71 | RegisterName = RegisterName or "RegisterCallback"
72 | UnregisterName = UnregisterName or "UnregisterCallback"
73 | if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
74 | UnregisterAllName = "UnregisterAllCallbacks"
75 | end
76 |
77 | -- we declare all objects and exported APIs inside this closure to quickly gain access
78 | -- to e.g. function names, the "target" parameter, etc
79 |
80 |
81 | -- Create the registry object
82 | local events = setmetatable({}, meta)
83 | local registry = { recurse=0, events=events }
84 |
85 | -- registry:Fire() - fires the given event/message into the registry
86 | function registry:Fire(eventname, ...)
87 | if not rawget(events, eventname) or not next(events[eventname]) then return end
88 | local oldrecurse = registry.recurse
89 | registry.recurse = oldrecurse + 1
90 |
91 | Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
92 |
93 | registry.recurse = oldrecurse
94 |
95 | if registry.insertQueue and oldrecurse==0 then
96 | -- Something in one of our callbacks wanted to register more callbacks; they got queued
97 | for eventname,callbacks in pairs(registry.insertQueue) do
98 | local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
99 | for self,func in pairs(callbacks) do
100 | events[eventname][self] = func
101 | -- fire OnUsed callback?
102 | if first and registry.OnUsed then
103 | registry.OnUsed(registry, target, eventname)
104 | first = nil
105 | end
106 | end
107 | end
108 | registry.insertQueue = nil
109 | end
110 | end
111 |
112 | -- Registration of a callback, handles:
113 | -- self["method"], leads to self["method"](self, ...)
114 | -- self with function ref, leads to functionref(...)
115 | -- "addonId" (instead of self) with function ref, leads to functionref(...)
116 | -- all with an optional arg, which, if present, gets passed as first argument (after self if present)
117 | target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
118 | if type(eventname) ~= "string" then
119 | error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
120 | end
121 |
122 | method = method or eventname
123 |
124 | local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
125 |
126 | if type(method) ~= "string" and type(method) ~= "function" then
127 | error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
128 | end
129 |
130 | local regfunc
131 |
132 | if type(method) == "string" then
133 | -- self["method"] calling style
134 | if type(self) ~= "table" then
135 | error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
136 | elseif self==target then
137 | error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
138 | elseif type(self[method]) ~= "function" then
139 | error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
140 | end
141 |
142 | if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
143 | local arg=select(1,...)
144 | regfunc = function(...) self[method](self,arg,...) end
145 | else
146 | regfunc = function(...) self[method](self,...) end
147 | end
148 | else
149 | -- function ref with self=object or self="addonId"
150 | if type(self)~="table" and type(self)~="string" then
151 | error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string expected.", 2)
152 | end
153 |
154 | if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
155 | local arg=select(1,...)
156 | regfunc = function(...) method(arg,...) end
157 | else
158 | regfunc = method
159 | end
160 | end
161 |
162 |
163 | if events[eventname][self] or registry.recurse<1 then
164 | -- if registry.recurse<1 then
165 | -- we're overwriting an existing entry, or not currently recursing. just set it.
166 | events[eventname][self] = regfunc
167 | -- fire OnUsed callback?
168 | if registry.OnUsed and first then
169 | registry.OnUsed(registry, target, eventname)
170 | end
171 | else
172 | -- we're currently processing a callback in this registry, so delay the registration of this new entry!
173 | -- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
174 | registry.insertQueue = registry.insertQueue or setmetatable({},meta)
175 | registry.insertQueue[eventname][self] = regfunc
176 | end
177 | end
178 |
179 | -- Unregister a callback
180 | target[UnregisterName] = function(self, eventname)
181 | if not self or self==target then
182 | error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
183 | end
184 | if type(eventname) ~= "string" then
185 | error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
186 | end
187 | if rawget(events, eventname) and events[eventname][self] then
188 | events[eventname][self] = nil
189 | -- Fire OnUnused callback?
190 | if registry.OnUnused and not next(events[eventname]) then
191 | registry.OnUnused(registry, target, eventname)
192 | end
193 | end
194 | if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
195 | registry.insertQueue[eventname][self] = nil
196 | end
197 | end
198 |
199 | -- OPTIONAL: Unregister all callbacks for given selfs/addonIds
200 | if UnregisterAllName then
201 | target[UnregisterAllName] = function(...)
202 | if select("#",...)<1 then
203 | error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
204 | end
205 | if select("#",...)==1 and ...==target then
206 | error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
207 | end
208 |
209 |
210 | for i=1,select("#",...) do
211 | local self = select(i,...)
212 | if registry.insertQueue then
213 | for eventname, callbacks in pairs(registry.insertQueue) do
214 | if callbacks[self] then
215 | callbacks[self] = nil
216 | end
217 | end
218 | end
219 | for eventname, callbacks in pairs(events) do
220 | if callbacks[self] then
221 | callbacks[self] = nil
222 | -- Fire OnUnused callback?
223 | if registry.OnUnused and not next(callbacks) then
224 | registry.OnUnused(registry, target, eventname)
225 | end
226 | end
227 | end
228 | end
229 | end
230 | end
231 |
232 | return registry
233 | end
234 |
235 |
236 | -- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
237 | -- try to upgrade old implicit embeds since the system is selfcontained and
238 | -- relies on closures to work.
239 |
240 |
--------------------------------------------------------------------------------
/Cork.lua:
--------------------------------------------------------------------------------
1 |
2 | local myname, Cork = ...
3 | local ldb, ae = LibStub:GetLibrary("LibDataBroker-1.1"), LibStub("AceEvent-3.0")
4 | local _
5 |
6 | _, Cork.MYCLASS = UnitClass("player")
7 |
8 | Cork.corks, Cork.db, Cork.dbpc, Cork.defaultspc = {}, {}, {}, {}
9 | Cork.sortedcorks = {}
10 |
11 | local defaults = {point = "TOP", x = 0, y = -100, showanchor = true, debug = false, bindwheel = false}
12 | local tooltip, anchor
13 |
14 | for i=1,MAX_BOSS_FRAMES do Cork.keyblist["boss"..i] = true end
15 |
16 |
17 | ------------------------------
18 | -- Initialization --
19 | ------------------------------
20 |
21 | ae.RegisterEvent("Cork", "ADDON_LOADED", function(event, addon)
22 | if addon:lower() ~= "cork" then return end
23 |
24 | CorkDB = setmetatable(CorkDB or {}, {__index = defaults})
25 | CorkDBPC = CorkDBPC or {{},{},{},{}}
26 | if not CorkDBPC[1] then CorkDBPC = {CorkDBPC, {}, {}, {}} end
27 | for _, i in ipairs({2,3,4}) do
28 | if not CorkDBPC[i] then CorkDBPC[i] = {} end
29 | end
30 | Cork.db = CorkDB
31 |
32 | anchor:SetPoint(Cork.db.point, Cork.db.x, Cork.db.y)
33 | if not Cork.db.showanchor then anchor:Hide() end
34 |
35 | ae.UnregisterEvent("Cork", "ADDON_LOADED")
36 | end)
37 |
38 |
39 | local meta = {__index = Cork.defaultspc}
40 | ae.RegisterEvent("Cork", "PLAYER_LOGIN", function()
41 | local lastspec = GetSpecialization()
42 | Cork.dbpc = setmetatable(CorkDBPC[lastspec], meta)
43 |
44 | for _,dataobj in pairs(Cork.sortedcorks) do if dataobj.Init then dataobj:Init() end end
45 | for _,dataobj in pairs(Cork.sortedcorks) do dataobj:Scan() end
46 |
47 | ae.RegisterEvent("Cork", "ZONE_CHANGED_NEW_AREA", Cork.Update)
48 | ae.RegisterEvent("Cork", "PLAYER_TALENT_UPDATE", function()
49 | if lastspec == GetSpecialization() then return end
50 |
51 | lastspec = GetSpecialization()
52 | for i,v in pairs(Cork.defaultspc) do if Cork.dbpc[i] == v then Cork.dbpc[i] = nil end end
53 | Cork.dbpc = setmetatable(CorkDBPC[lastspec], meta)
54 |
55 | if Cork.config.Update then Cork.config:Update() end
56 | for name,dataobj in pairs(Cork.corks) do if dataobj.Init then dataobj:Init() end end
57 | for name,dataobj in pairs(Cork.corks) do dataobj:Scan() end
58 | end)
59 |
60 | ae.UnregisterEvent("Cork", "PLAYER_LOGIN")
61 | end)
62 |
63 |
64 | ae.RegisterEvent("Cork", "PLAYER_LOGOUT", function()
65 | for i,v in pairs(defaults) do if Cork.db[i] == v then Cork.db[i] = nil end end
66 | for i,v in pairs(Cork.defaultspc) do if Cork.dbpc[i] == v then Cork.dbpc[i] = nil end end
67 | end)
68 |
69 | local onTaxi, petBattle
70 | ae.RegisterEvent("Cork Core", "PLAYER_CONTROL_LOST", function()
71 | onTaxi = true
72 | Cork.Update()
73 | end)
74 |
75 | ae.RegisterEvent("Cork Core", "PLAYER_CONTROL_GAINED", function()
76 | onTaxi = nil
77 | Cork.Update()
78 | end)
79 |
80 | ae.RegisterEvent("Cork Core", "UNIT_ENTERED_VEHICLE", function()
81 | onTaxi = UnitHasVehicleUI('player')
82 | Cork.Update()
83 | end)
84 | ae.RegisterEvent("Cork Core", "UNIT_EXITED_VEHICLE", function()
85 | onTaxi = nil
86 | Cork.Update()
87 | end)
88 |
89 | ae.RegisterEvent("Cork Core", "PET_BATTLE_OPENING_START", function()
90 | petBattle = true
91 | Cork.Update()
92 | end)
93 | ae.RegisterEvent("Cork Core", "PET_BATTLE_OVER", function()
94 | petBattle = nil
95 | Cork.Update()
96 | end)
97 |
98 | ------------------------------
99 | -- Tooltip anchor --
100 | ------------------------------
101 |
102 | anchor = CreateFrame("Button", nil, UIParent)
103 | anchor:SetHeight(24)
104 | Cork.anchor = anchor
105 |
106 | anchor:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 16, insets = {left = 5, right = 5, top = 5, bottom = 5}, tile = true, tileSize = 16})
107 | anchor:SetBackdropColor(0.09, 0.09, 0.19, 0.5)
108 | anchor:SetBackdropBorderColor(0.5, 0.5, 0.5, 1)
109 |
110 | local text = anchor:CreateFontString(nil, nil, "GameFontNormalSmall")
111 | text:SetPoint("CENTER")
112 | text:SetText("Cork")
113 | anchor:SetWidth(text:GetStringWidth() + 8)
114 |
115 |
116 | anchor:SetMovable(true)
117 | anchor:RegisterForDrag("LeftButton")
118 |
119 | anchor:SetScript("OnClick", function(self) InterfaceOptionsFrame_OpenToCategory(Cork.config) end)
120 |
121 |
122 | anchor:SetScript("OnDragStart", function(self)
123 | tooltip:Hide()
124 | self:StartMoving()
125 | end)
126 |
127 |
128 | anchor:SetScript("OnDragStop", function(self)
129 | self:StopMovingOrSizing()
130 | Cork.db.point, Cork.db.x, Cork.db.y = "BOTTOMLEFT", self:GetLeft(), self:GetBottom()
131 | Cork.Update()
132 | end)
133 |
134 |
135 | -----------------------
136 | -- Tooltip --
137 | -----------------------
138 |
139 | tooltip = CreateFrame("GameTooltip", "Corkboard", UIParent, "GameTooltipTemplate")
140 | tooltip:SetFrameStrata("MEDIUM")
141 | CorkboardTextLeft1:SetFontObject(GameTooltipText)
142 | CorkboardTextRight1:SetFontObject(GameTooltipText)
143 |
144 |
145 | local function GetTipAnchor(frame)
146 | local x,y = frame:GetCenter()
147 | if not x or not y then return "TOPLEFT", frame, "BOTTOMLEFT" end
148 | local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or ""
149 | local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM"
150 | return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf
151 | end
152 |
153 |
154 | local function CorkSorter(a, b)
155 | return a and b and a.sortname < b.sortname
156 | end
157 |
158 |
159 | local function SetSort(dataobj)
160 | local downcase = dataobj.name:lower()
161 | dataobj.sortname = string.format("%02d %s", (dataobj.priority or 5), downcase)
162 | end
163 |
164 |
165 | local activecorks, usedcorks = {}, {}
166 | local raidunits = {player = true}
167 | for i=1,4 do raidunits["party"..i] = true end
168 | for i=1,40 do raidunits["raid"..i] = true end
169 | function Cork.Update(event, name, attr, value, dataobj)
170 | if attr == "name" then
171 | Cork.corks[value] = dataobj
172 | end
173 |
174 | if attr == "priority" or attr == "name" then
175 | SetSort(dataobj)
176 | table.sort(Cork.sortedcorks, CorkSorter)
177 | end
178 |
179 | if Cork.keyblist[attr] then return end
180 |
181 | tooltip:Hide()
182 |
183 | table.wipe(activecorks)
184 | table.wipe(usedcorks)
185 |
186 | local inbg = GetZonePVPInfo() == "combat" or select(2, IsInInstance()) == "pvp"
187 |
188 | for i,dataobj in ipairs(Cork.sortedcorks) do
189 | if dataobj.nobg and inbg then usedcorks[dataobj] = true end
190 | end
191 |
192 | for i,dataobj in ipairs(Cork.sortedcorks) do
193 | if not usedcorks[dataobj] and dataobj.player then
194 | table.insert(activecorks, dataobj)
195 | usedcorks[dataobj] = true
196 | end
197 | end
198 |
199 | for i,dataobj in ipairs(Cork.sortedcorks) do
200 | if not usedcorks[dataobj] then
201 | table.insert(activecorks, dataobj)
202 | usedcorks[dataobj] = true
203 | end
204 | end
205 |
206 |
207 | tooltip:ClearLines()
208 | tooltip:SetOwner(anchor, "ANCHOR_NONE")
209 | tooltip:SetPoint(GetTipAnchor(anchor))
210 |
211 | if Cork.db.showbg or not inbg then
212 | local count = 0
213 | for i,dataobj in ipairs(activecorks) do
214 | if not (dataobj.nobg and inbg) then
215 | local inneed, numr, prefix = 0, GetNumGroupMembers(), IsInRaid() and "raid" or "party"
216 | for i=1,numr do if dataobj.RaidLine and dataobj[prefix..i] then inneed = inneed + 1 end end
217 | if dataobj.RaidLine and numr > 0 and dataobj["player"] then inneed = inneed + 1 end
218 | if inneed > 1 and count < 10 then -- Hard limit, show 10 lines at most
219 | if Cork.db.debug then tooltip:AddDoubleLine(string.format(dataobj.RaidLine, inneed), "raid") else tooltip:AddLine(string.format(dataobj.RaidLine, inneed)) end
220 | count = count + 1
221 | end
222 | for i,v in ldb:pairs(dataobj) do
223 | if v ~= false and not Cork.keyblist[i] and (inneed <= 1 or not raidunits[i]) and count < 10 then
224 | if Cork.db.debug then tooltip:AddDoubleLine(v, i) else tooltip:AddLine(v) end
225 | count = count + 1
226 | end
227 | end
228 | end
229 | end
230 | end
231 |
232 | if tooltip:NumLines() > 0 and not onTaxi and not petBattle then
233 | tooltip:Show()
234 | end
235 | end
236 |
237 |
238 | -------------------------
239 | -- LDB stuff --
240 | -------------------------
241 |
242 | local function NewDataobject(event, name, dataobj)
243 | if dataobj.type ~= "cork" then return end
244 | if not dataobj.name then dataobj.name = name:gsub("Cork ", "") end
245 | SetSort(dataobj)
246 | Cork.corks[name] = dataobj
247 | table.insert(Cork.sortedcorks, dataobj)
248 | table.sort(Cork.sortedcorks, CorkSorter)
249 | ldb.RegisterCallback("Corker", "LibDataBroker_AttributeChanged_"..name, Cork.Update)
250 | end
251 |
252 | ldb.RegisterCallback("Corker", "LibDataBroker_DataObjectCreated", NewDataobject)
253 |
254 |
255 | function Cork:New(name)
256 | return ldb:NewDataObject("Cork "..name, {type = "cork", name = name})
257 | end
258 |
259 |
260 | ----------------------------
261 | -- Secure frame --
262 | ----------------------------
263 |
264 | local secureframe = CreateFrame("Button", "CorkFrame", UIParent, "SecureActionButtonTemplate")
265 |
266 | secureframe.SetManyAttributes = function(self, ...)
267 | for i=1,select("#", ...),2 do
268 | local att,val = select(i, ...)
269 | if not att then return end
270 | self:SetAttribute(att,val)
271 | end
272 | return true
273 | end
274 |
275 |
276 | secureframe:SetScript("PreClick", function(self)
277 | if onTaxi or InCombatLockdown() then return end
278 | for i,dataobj in ipairs(activecorks) do
279 | if dataobj.CorkIt and (not IsStealthed() or dataobj.CanCorkStealthed) and dataobj:CorkIt(self) then return end
280 | end
281 | end)
282 |
283 |
284 | secureframe:SetScript("PostClick", function()
285 | if InCombatLockdown() then return end
286 | secureframe:SetManyAttributes("type1", ATTRIBUTE_NOOP, "bag1", nil, "slot1", nil, "item1", nil, "spell", nil, "unit", nil, "macrotext1", nil)
287 | end)
288 |
289 |
290 | --------------------------------
291 | -- Shared functions --
292 | --------------------------------
293 |
294 | function Cork.IsSpellInRange(spell, unit)
295 | return IsSpellInRange(spell, unit) == 1
296 | end
297 |
298 | function Cork.SpellCastableOnUnit(spell, unit)
299 | return UnitExists(unit) and UnitCanAssist("player", unit) and UnitIsVisible(unit) and UnitIsConnected(unit) and not UnitIsDeadOrGhost(unit) and Cork.IsSpellInRange(spell, unit)
300 | end
301 |
302 | function Cork.IconLine(icon, text, token)
303 | return "|T"..(icon or "")..":24:24:0:0:64:64:4:60:4:60|t ".. (token and ("|cff".. Cork.colors[token]) or "").. text
304 | end
305 |
306 | local last_thresh
307 | function Cork.RaidThresh()
308 | if not last_thresh then
309 | local name, type, difficulty, difficultyName, maxPlayers, playerDifficulty, isDynamicInstance = GetInstanceInfo()
310 | last_thresh = maxPlayers < 10 and 8 or maxPlayers / 5
311 | end
312 | return last_thresh
313 | end
314 |
315 | local function FlushThresh()
316 | last_thresh = nil
317 | for name,dataobj in pairs(Cork.corks) do dataobj:Scan() end
318 | end
319 | ae.RegisterEvent("Cork Core", "PLAYER_DIFFICULTY_CHANGED", FlushThresh)
320 | ae.RegisterEvent("Cork Core", "UPDATE_INSTANCE_INFO", FlushThresh)
321 | -- ae.RegisterEvent("Cork Core", "GUILD_PARTY_STATE_UPDATED", FlushThresh)
322 | -- ae.RegisterEvent("Cork Core", "PLAYER_GUILD_UPDATE", FlushThresh)
323 |
--------------------------------------------------------------------------------
/changelog.txt:
--------------------------------------------------------------------------------
1 | ### 7.1.0.62-Beta
2 |
3 | * Add module for artifact research and rep tokens
4 | * Drop artifact power items to a lower priority
5 |
6 |
7 | ### 7.0.0.61-Beta
8 |
9 | * Artifact Power Items support (thanks @Tarkumi)
10 | * Add class hall shipments module
11 | * So long MotW, you will be missed
12 | * Fix well fed config
13 |
14 |
15 | ### 7.0.0.60-Beta
16 |
17 | * Add new "permanent" warlock pets
18 | * Buhbye arcint
19 | * SPAAAAAAAAAAAAAAAAACE
20 | * Make LancePole re-equip last item on CorkIt
21 | * Add garrison building module... A little late to this, I know, whatever :P
22 | * Fix issues with bodyguard minifier on first login
23 | * Dead warlock spell
24 |
25 |
26 | ### 7.0.0.59-Beta
27 |
28 | All changes this version thanks to Kevin Ballard
29 |
30 | * Add Demon Hunter to the colors list
31 | * Fix the macro button
32 | * Get rid of Monk buffs/stances
33 | * Don't throw error if we can't fetch item info
34 | * Dead shaman buffs
35 | * Update rogue poisons
36 | * Fix Death Knights
37 |
38 |
39 | ### 7.0.0.58-Beta
40 |
41 | * Legion garrison fixes
42 | * Dead hunter buffs
43 | * Rewrite Paladin blessings check (thanks kballard)
44 | * Fix per-spec settings (thanks kballard)
45 | * Hide salvage from <90
46 | * New salvage boxes
47 | * Club some seals
48 | * Hide the default "unspent talent points" hint
49 | * Kings and Fort items are dead
50 | * Looks like all the priest buffs are gone now
51 | * Glyphs are dead, long live glyphs!
52 | * Feesh stacks changed
53 | * Add garrison EXP potion
54 | * Add module for bodyguard shrinker
55 | * I guess rogues have a new poison or some shit
56 | * What the fuck do I know, I hate rogues
57 | * Make missions alert when a mission completes
58 | * Add garrison cache module
59 | * Fix darkmoon start time
60 | * Fix for completed buildings
61 | * Add Inscription Receipts (follower bonus) to combine (thanks Daniel Pittman)
62 | * Add completed missions reminder
63 | * Add reminder to pick up garrison work orders
64 | * Add a reminder to grab free food from the tree
65 | * Fix mine items blocking if you don't have the item
66 | * SelfBufferAdvanced: spells can be unlearnt too (talents) (thanks Adirelle)
67 |
68 | ### 6.0.0.57-Beta
69 |
70 | * Add follower equipment tokens to openables
71 | * Add garrison mine buff items
72 | * Add fishing hat module
73 | * Add fishing lures module
74 | * Make self buffer check cooldown when needed
75 | * Add salvage items (thanks Daniel Pittman and Kevin Ballard)
76 | * Add missing "Nagrand Arrowbloom Petal" to combine (thanks Daniel Pittman)
77 | * Handle nil results from GetItemInfo for openables (thanks Kevin Ballard))
78 | * Add some Pandaria plant parts to the Combine module (thanks Adirelle)
79 | * Add Small Ethereal Shard to the combine module (thanks Adirelle)
80 |
81 | ### 6.0.0.56-Beta
82 |
83 | * Add WoD combinable items (thanks Daniel Pittman)
84 |
85 | ### 6.0.0.55-Beta
86 |
87 | * Account for actual start and end time of darkmoon
88 | * Fix clam opening
89 | * Fix warlock pet mount detection
90 |
91 | ### 6.0.0.54-Beta
92 |
93 | * 6.0 fixes (thanks @hughescr for Soul Link fix)
94 |
95 | ### 6.0.0.53-Beta
96 |
97 | * Fix tooltip scanning on initial login
98 | * Something on wod broke the empty tip
99 | * Simplify down the item scanner
100 | * Implement tooltip scanning based item opener (Thanks Daniel Pittman)
101 | * Better handling of maxlevel in darkmoon module
102 | * Don't warn about darkmoon if player has the hat buff
103 | * Config refresh on spec change, thanks @Adirelle
104 | * Add some tabs to the config panel
105 | * Update the configuration panel when switching spec.
106 | * Properly update checkboxes when showing the config panel.
107 | * Have the db values match the state of the checkboxes.
108 | * Allow poison application while stealthed
109 | * Avoid errors when item names are unknown (thanks Kevin Ballard)
110 | * Combine Sparkling Shards to make Serpent's Eye (thanks Craig R. Hughes)
111 | * Display party member buffs like raid member buffs (thanks Kevin Ballard)
112 | * Dark intent now overwrites Fort... bastards
113 | * Fix Priest Fort buffer (thanks Kevin Ballard)
114 | * Combine motes into spirits of harmony (thanks Craig R. Hughes)
115 | * Eggs are openable too!
116 | * Fix macro generation for Paladins (thanks Kevin Ballard)
117 | * Don't show mage gem when resting
118 |
119 | ### 5.2.0.52-Beta
120 |
121 | * Ice barrier!
122 | * Display corks in the same order they're fired (thanks @eridius)
123 | * Use consistant sorting, for @eridius
124 | * Use more refined sorting priorities
125 | * Sort the foods in the wellfed (by ID), again for @eridius
126 | * Filter out party units while in raids (thanks @eridius)
127 | * Don't show pets for raid buffs (thanks @eridius)
128 | * Kill the last bits of pet buffing, that's long dead
129 | * Fix inbg bug
130 | * Add a new lance
131 | * Helps to use the right thing to check for ingroupedness
132 |
133 | ### 5.1.0.51-Beta
134 |
135 | * Add Druid Symbiosis
136 | * Only warn about rogue poisons if a 1H weapon is equipped
137 | * Add Bag of Shiny Things to openables
138 | * Use SetTracking() to track things (Thanks eridius)
139 | * Fix the icon on the generated macro (Thanks eridius)
140 | * Stop using #showtooltip just for icon purposes (Thanks eridius)
141 | * Fix Soulstone (the spell works a bit differently now)
142 | * Restrict sybiosis and beacon of light to groups only
143 | * Make "last buffed" reminders work when the spell hasn't been cast yet
144 | * Add frost mage water elem module
145 | * Warn about tele cloaks
146 | * EXP buff reminders ignore resting state
147 | * Darkmoon EXP ignores resting
148 | * Drums are overwritten by almighty monk buff (Thanks ckaotik)
149 | * Forgot to exclude the new flask buffs
150 |
151 | ### 5.1.0.50-Beta
152 |
153 | * Hide tooltip during pet battles
154 | * Add darkmoon exp buff
155 | * Add minipet summoning module
156 | * Remove 8th anniversary buff item
157 | * Remove an old hunter aspect
158 |
159 | ### 5.0.1.49-Beta
160 |
161 | * Add anniversary exp buff item
162 | * Add new fortitude runescroll
163 |
164 | ### 5.0.1.48-Beta
165 |
166 | * Fix error with openable items
167 |
168 | ### 5.0.1.47-Beta
169 |
170 | * Added bloated skinning items to open
171 | * Fix a bug with the new wellfed config
172 | * Add monk exp booster buff
173 | * Don't prompt for guild battle standard when it's on CD
174 |
175 | ### 5.0.1.46-Beta
176 |
177 | * Add guild battle standard module
178 | * Add basic stance support for Monks (thanks jf647)
179 | * Add Legacy of the Emperor support for Monks
180 | * Add Legacy of the White Tiger
181 | * Rework mark logic for monks' buff
182 | * Update pally blessings for pandas
183 | * Fix error caused by monks
184 | * Fix alchy flask
185 | * Better config panel for well fed
186 | * New fishing boxes (thanks hughescr)
187 |
188 | ### 5.0.1.45-Beta
189 |
190 | * 5.0 updates, may not be complete (thanks hughescr and jf647)
191 |
192 | ### 4.3.0.44-Beta
193 |
194 | * "Well fed"
195 | * Add support for DK presences (thanks jf647)
196 | * Don't let alchy endless flask override normal flasks
197 | * D'oh, fort spellID changed
198 | * Safeguard against using a buff item if no unit is in need
199 | * Remove group threshold setting, buff items only cast if all needy units in range
200 | * Crazy attempt to make blessings report back the spell it would cast
201 | * If a single unit is in need, don't display the raid-need line
202 | * Pally blessings need to condense down in raid
203 | * Remove raid type config, now dynamically adjusts to instance size
204 | * Remove tooltip limit, hardcode at 10 lines
205 | * Rejigger config panel for 4.2
206 |
207 | ### 4.1.0.43-Beta
208 |
209 | * Don't do fancy shit for flask of enh... it doesn't work on initial login
210 | * Don't bitch at druids to cast mark on units that have both pally blessings
211 | * Ignore player for dark intent module
212 |
213 | ### 4.1.0.42-Beta
214 |
215 | * Add warlock dark intent module
216 | * Fix quest item cork not going away if item is dropped
217 | * Add alchemist Flask of Enhancement
218 | * New fort scroll at 85
219 | * Update that ancient readme
220 | * Pet happenis is no more
221 |
222 | ### 4.1.0.41-Beta
223 |
224 | * Add Beacon of Light
225 |
226 | ### 4.0.0.40-Beta
227 |
228 | * Don't bug about druid swift flight either
229 | * Bleepin bloop
230 | * Add Poison support for Rogue Thrown weapons (thanks winks)
231 | * Generalize rogue poisons into a template
232 | * Make shaman enchants work with new template too
233 | * All those poisons are gone now
234 | * Don't try to temp-chant lances and other "misc" weapons
235 |
236 | ### 4.0.0.39-Beta
237 |
238 | * And another openable box thing
239 | * Add new cat mats to combine module
240 | * Item cache failsafe kinda fixes #54 until Blizzy gives us an event that works
241 | * S M R T
242 | * Attempt to blacklist boss units, I think, i can't test this shit
243 | * What me break the crusader aura module? nevar!
244 | * Fix up pet happiness module for new UNIT_POWER events
245 | * I never had this error, but whatever, if it shuts the bitches up
246 | * Add archaeology module
247 |
248 | ### 4.0.0.38-Beta
249 |
250 | * Add quest starting items module
251 | * Change Inner Fire to an advanced self buffer for Inner Fire or Inner Will (thanks James FitzGibbon)
252 | * New clam!
253 | * No point in using pet names in the soul link module
254 | * Soul shards are lower priority than summon pet
255 | * Soulshards can bitch even when we're in town
256 | * Use soulburn when summoning warlock demons
257 |
258 | ### 4.0.0.37-Beta
259 |
260 | * Don't harass players to be well fed until, oh, lets say level 10
261 | * Don't bug warlocks to make a healthstone if they can't
262 | * Seems that poison was removed
263 |
264 | ### 4.0.0.36-Beta
265 |
266 | * Item cache is gone, use the spell name instead of the item name for buffing items
267 |
268 | ### 4.0.0.35-Beta
269 |
270 | * 4 loops r hard
271 |
272 | ### 4.0.0.34-Beta
273 |
274 | * That might be nil, fuh!
275 |
276 | ### 4.0.0.33-Beta
277 |
278 | * New and updated modules for 4.0
279 | * There are NINE glyphs
280 | * Enable disabled hovering on spell buttons in config
281 | * Don't harass people to get artisan or master riding
282 | * Ignore azeroth flying on live, for now
283 | * Tweak the pvp zone detection
284 | * Add in-town buff debuggery
285 | * Can't buff pets in 4.0 it seems
286 |
287 | ### 4.0.0.32-Beta
288 |
289 | * New unlearned spells module, only works in Cat
290 | * Pally buffs are a bit different in cat
291 | * Fix up macro generator for cat
292 | * Fix up raid buffer for cat
293 | * Talents API changed a bit in cat
294 | * Druid forms changed a tad in cat
295 | * Downranked spells module (wrath only)
296 |
297 | ### 3.3.0.31-Beta
298 |
299 | * Fall back to single-target spells when out of reagents
300 | * Mage mana gem module (thanks fryguy)
301 | * Make int module ignore resting
302 | * Don't bother solo players with buff items
303 |
304 | ### 3.3.0.30-Beta
305 |
306 | * Thanks Adirelle and PProvost for new good bits!
307 | * Fixed Abominable Might spell id.
308 | * Don't cork soulstone if player has buff
309 | * Always show repair warning if any equipped item is below 15% durability
310 | * Don't cork disconnected or non-visible characters
311 | * Don't buff raid items if player doesn't have item in bag
312 | * Added Rogue poisons
313 |
314 | ### 3.3.0.29-Beta
315 |
316 | * Make warrior battle shout module suck less
317 | * Add warlock healthstone module
318 | * Add fished crates
319 | * Add fishing pole and lance module
320 | * Disable when vehicle UI is active
321 | * Disable the macro as well, don't just hide the toolip
322 | * Add more useful tooltips to config
323 |
324 | ### 3.3.0.28-Beta
325 |
326 | * Fix shaman offhands that are offhand *only*
327 | * Force WellFed to the lowest priority when corking (so that we recover mana from our casts)
328 | * New clam
329 | * Vampiric Embrace is a buff now
330 | * Use new embed texture coords to crop off those goddamn borders on icons
331 | * Add soulstone module
332 | * Add glyph module
333 |
334 | ### 3.2.0.27-Beta
335 |
336 | * Add exclusions to self buffer... fix hunter trueshot (doesn't stack with unleashed rage or abom might)
337 | * Horn of Winter and Strength of Earth dun stack
338 |
339 | ### 3.2.0.26-Beta
340 |
341 | * Added "Combine" module, that combines small items into larger ones, e.g. 10 crystallized waters into eternal water. (Thanks Adirelle)
342 | * RaidBuff now ignores dead units and units in vehicle. (Thanks Adirelle)
343 | * Update "show in battleground" checkbox on config show. (Thanks Adirelle)
344 | * Embed update
345 |
346 | ### 3.2.0.25-Beta
347 |
348 | * Add new raid buffing items
349 | * Make macro editboxes also accept drag
350 | * Default blank macro would be a good thing.
351 |
352 | ### 3.2.0.24-Beta
353 |
354 | * UnitAura doesn't do isMine anymore
355 | * Rejigger druid bear list to avoid forgetting settings on low-level toons
356 |
357 | ### 3.1.0.23-Beta
358 |
359 | * Make "last buffed" templates hide when resting
360 | * And we have shaman weapon buffs!
361 | * Warlock temp enchant (spellstone) module
362 | * Fixed range check issues (Fucking eh, Blizzy, 0 IS NOT FALSE IN LUA)
363 | * Make druid shapeshift module only cast if no other needs are up
364 | * Hide tooltip when on a taxi (thanks PProvost)
365 | * Fixed Warlock pets (thanks PProvost)
366 | * Unspent talent points module (thanks Iain Broadfoot)
367 |
368 | ### 3.1.0.22-Beta
369 |
370 | * Fix tooltip not hiding when entering WG
371 |
372 | ### 3.1.0.21-Beta
373 |
374 | * Make buffer modules hide when in town (resting)
375 | * Ignore arena unitids
376 |
377 | ### 3.1.0.20-Beta
378 |
379 | * Fix macro blocking if well fed macro is nil (not blank)
380 | * Add more mini-config rows when possible
381 | * Add all-might/wis and all-kings buttons to pally blessing config
382 |
383 | ### 3.1.0.19-Beta
384 |
385 | * Add talent "profiles", per-char settings automatically Swap for the current talent set
386 | * Fix for UnitAura changes in 3.1
387 | * Adjust hunter viper slider min/max on value change to ensure low never goes above high
388 |
389 | ### 3.0.9.18-Beta
390 |
391 | * Fix secondary module config frames disappearing after first use
392 |
393 | ### 3.0.9.17-Beta
394 |
395 | * Add scrollbar to module config group
396 | * Add option to hide tooltip in battlegrounds
397 |
398 | ### 3.0.9.16-Beta
399 |
400 | * Clarify a tooltip just a smidge
401 | * Make sure all the modules are shown on the config pane
402 | * When in a raid, condese multi-target spells down into a single line
403 | * Add Well Fed module, cause I suck at keeping that buff up (I have year old buff food in my bag)
404 | * Add Vigilance to warrior modules
405 | * Add mage focus magic
406 |
407 | ### 3.0.9.15-Beta
408 |
409 | * Add amp/damp magic modules for mages, default them to disabled
410 | * Fix mage Int module for players without dalaran int
411 | * Merge fear ward and earth shield modules into an abstract template, add druid thorns to new system
412 |
413 | ### 3.0.9.14-Beta
414 |
415 | * Make crusader aura module only watch auras cast by the player
416 | * Move pally seals to normal buffs
417 | * Add raid mode setting for raid buffing classes
418 | * 10-man will only watch groups 1 and 2 for needed buffs
419 | * 25-man will watch groups 1-5
420 | * 40-man will watch all groups
421 | * Smarter mage int module (Will cast Dalaran Int and ignore non-mana classes)
422 | * Don't show target and focus if they're the same unit
423 | * Update after the anchor is reset to position the tip correctly
424 | * Add anchor reset button
425 |
426 | ### 3.0.3.13-Beta
427 |
428 | * Make crusader module properly update when aura module's config changes
429 |
430 | ### 3.0.3.12-Beta
431 |
432 | * Extend the config list checkbox hit rects
433 | * Make self-buff modules show spell name instead of unit name
434 | * Pally crusader aura module
435 | * Warlock soul link fixes
436 |
437 | ### 3.0.3.11-Beta
438 |
439 | * Fix anchor saving on drag stop
440 |
441 | ### 3.0.3.10-Beta
442 |
443 | * Vehicles are NEVER happy...
444 | * Remove locale-specific bits from pet happy module
445 |
446 | ### 3.0.3.9-Beta
447 |
448 | * Add a NR clam
449 | * "Feed Pet Effect" was renamed "Feed Pet"... bastards
450 | * Add aspect of the dragonhawk
451 |
452 | ### 3.0.3.8-Beta
453 |
454 | * Tweak tooltip strata a smidge
455 | * Hunter Viper module (thanks adirelle)
456 |
457 | ### 3.0.2.7-Beta
458 |
459 | * Don't track Earth Shield when solo
460 | * Greater wisdom and greater kings got swapped?
461 | * Allow bags to be opened when hunter pet module config is visible
462 |
463 | ### 3.0.2.6-Beta
464 |
465 | * Don't check if pally blessings are mine if target is out of range
466 | * Remove 2.4.3 compat
467 | * Remove Omen of Clarity, is now passive
468 |
469 | ### 3.0.2.5-Beta
470 |
471 | * Make raid buffer fall back to the single-target spell when checking range, since raid-wide spell range checking is currently broken
472 |
473 | ### 3.0.1.4-Beta
474 |
475 | * Update for wrath build 8962 config panel breakage
476 | * Embed update
477 | * Fix raid buffer not actually checking if people in the group need a buff
478 | * Fix hunter pet feeder nil error on first use
479 | * Prevent corking when stealthed
480 | * Add dynamic mousewheel binding (Thanks Adirelle)
481 |
482 | ### 3.0.1.3-Beta
483 |
484 | * Add priest fear ward module
485 | * Add shaman earth shield module, tracks the last group member you cast on
486 | * Make tooltip limit slider refresh the tooltip when changed
487 | * Add about panel
488 | * TOC metadata
489 | * Embed update
490 |
491 | ### 3.0.1.2-Beta
492 |
493 | * Add compatibility layer for live. Not super efficient, but it seems to get the jorb done
494 | * Fix raid buffer not checking focus and target on full scan
495 | * Delay spell checking till PLAYER_LOGIN
496 | * Prefer buffing the player first, players second, pets last
497 | * Pally seal was missing Seal of Wisdom
498 |
499 | * New Modules
500 | * Clam shucker
501 | * DK Horn of Winter
502 | * DK Path of Frost
503 | * Hunter pet happiness
504 | * Repairs
505 | * Tracking (Only spells, not "helpers")
506 | * Warlock demons
507 | * Warlock soul link
508 |
509 | * Config Enhancements
510 | * Added keybinding (thanks clad)
511 | * Add option to limit the tooltip lines (thanks clad)
512 | * Add group threshold config
513 | * Make cast on pets option char-wide instead of per-module
514 | * Add macro generator
515 | * Add pretty group box for modules
516 | * Add module toggles to base config page
517 | * Removed config panels for simple self buffs (only had "enable" toggle)
518 | * Removed config for raid buffs (all options in the base panel now)
519 | * Move advanced self buffer config into base config page
520 | * Strip off the borders from icons
521 | * Add solo/party/bg options to pally blessing module
522 |
523 | ### 3.0.1.1-Beta
524 |
525 | * Initial redesign for Wrath
526 |
--------------------------------------------------------------------------------