|
|
|
|
-- Create module
|
|
|
|
|
local addon, L = XLoot:NewModule("Group")
|
|
|
|
|
-- Prepare global
|
|
|
|
|
XLootGroup = addon
|
|
|
|
|
-- Grab locals
|
|
|
|
|
local opt, anchor, alert_anchor, mouse_focus, Skinner
|
|
|
|
|
local rolls = {}
|
|
|
|
|
local RAID_CLASS_COLORS = CUSTOM_CLASS_COLORS or _G.RAID_CLASS_COLORS
|
|
|
|
|
local GetLootRollItemInfo, GetLootRollItemLink, GetLootRollTimeLeft, RollOnLoot, UnitGroupRolesAssigned, print, string_format
|
|
|
|
|
= GetLootRollItemInfo, GetLootRollItemLink, GetLootRollTimeLeft, RollOnLoot, UnitGroupRolesAssigned, print, string.format
|
|
|
|
|
local HistoryGetItem, HistoryGetPlayerInfo, HistoryGetNumItems
|
|
|
|
|
= C_LootHistory.GetItem, C_LootHistory.GetPlayerInfo, C_LootHistory.GetNumItems
|
|
|
|
|
local CanEquipItem, IsItemUpgrade, FancyPlayerName = XLoot.CanEquipItem, XLoot.IsItemUpgrade, XLoot.FancyPlayerName
|
|
|
|
|
local RollFramePrototype
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
-- Settings
|
|
|
|
|
|
|
|
|
|
local defaults = {
|
|
|
|
|
profile = {
|
|
|
|
|
role_icon = true,
|
|
|
|
|
win_icon = false,
|
|
|
|
|
show_decided = true,
|
|
|
|
|
show_undecided = false,
|
|
|
|
|
show_time_remaining = false,
|
|
|
|
|
text_ilvl = false,
|
|
|
|
|
|
|
|
|
|
equip_prefix = true,
|
|
|
|
|
prefix_equippable = "*",
|
|
|
|
|
prefix_upgrade = "+",
|
|
|
|
|
|
|
|
|
|
hook_alert = false,
|
|
|
|
|
alert_skin = true,
|
|
|
|
|
alert_alpha = 1,
|
|
|
|
|
alert_scale = 1,
|
|
|
|
|
alert_offset = 4,
|
|
|
|
|
alert_background = false,
|
|
|
|
|
alert_icon_frame = false,
|
|
|
|
|
|
|
|
|
|
hook_bonus = false,
|
|
|
|
|
bonus_skin = true,
|
|
|
|
|
|
|
|
|
|
roll_button_size = 28,
|
|
|
|
|
roll_width = 325,
|
|
|
|
|
|
|
|
|
|
font = STANDARD_TEXT_FONT,
|
|
|
|
|
font_flag = "OUTLINE",
|
|
|
|
|
|
|
|
|
|
roll_anchor = {
|
|
|
|
|
direction = 'up',
|
|
|
|
|
spacing = 2,
|
|
|
|
|
offset = 0,
|
|
|
|
|
visible = true,
|
|
|
|
|
draggable = true,
|
|
|
|
|
scale = 1.0,
|
|
|
|
|
x = UIParent:GetWidth() * .75,
|
|
|
|
|
y = UIParent:GetHeight() * .4
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
alert_anchor = {
|
|
|
|
|
visible = true,
|
|
|
|
|
direction = 'up',
|
|
|
|
|
draggable = true,
|
|
|
|
|
scale = 1.0,
|
|
|
|
|
x = AlertFrame:GetLeft(),
|
|
|
|
|
y = AlertFrame:GetTop()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
track_all = false,
|
|
|
|
|
track_player_roll = false,
|
|
|
|
|
track_by_threshold = true,
|
|
|
|
|
track_threshold = 3,
|
|
|
|
|
|
|
|
|
|
expire_won = 20,
|
|
|
|
|
expire_lost = 10,
|
|
|
|
|
shown_hook_warning = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
opt = defaults.profile
|
|
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
-- Module init
|
|
|
|
|
|
|
|
|
|
local eframe = CreateFrame("Frame")
|
|
|
|
|
function addon:OnInitialize()
|
|
|
|
|
self:InitializeModule(defaults, eframe)
|
|
|
|
|
opt = self.db.profile
|
|
|
|
|
XLootGroup.opt = opt
|
|
|
|
|
-- Extra slash command
|
|
|
|
|
XLoot:SetSlashCommand("xlg", self.SlashHandler)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function addon:OnEnable()
|
|
|
|
|
-- Register events
|
|
|
|
|
eframe:RegisterEvent('START_LOOT_ROLL')
|
|
|
|
|
eframe:RegisterEvent('LOOT_HISTORY_ROLL_CHANGED')
|
|
|
|
|
eframe:RegisterEvent('LOOT_HISTORY_ROLL_COMPLETE')
|
|
|
|
|
eframe:RegisterEvent('LOOT_ROLLS_COMPLETE')
|
|
|
|
|
eframe:RegisterEvent('MODIFIER_STATE_CHANGED')
|
|
|
|
|
|
|
|
|
|
-- Disable default frame
|
|
|
|
|
UIParent:UnregisterEvent("START_LOOT_ROLL")
|
|
|
|
|
UIParent:UnregisterEvent("CANCEL_LOOT_ROLL")
|
|
|
|
|
|
|
|
|
|
-- Set up skins
|
|
|
|
|
Skinner = {}
|
|
|
|
|
XLoot:MakeSkinner(Skinner, {
|
|
|
|
|
anchor = { r = .4, g = .4, b = .4, a = .6, gradient = false },
|
|
|
|
|
anchor_pretty = { r = .6, g = .6, b = .6, a = .8 },
|
|
|
|
|
row = { gradient = false },
|
|
|
|
|
item = { backdrop = false },
|
|
|
|
|
alert = { gradient = true },
|
|
|
|
|
alert_item = { gradient = true, backdrop = false },
|
|
|
|
|
bonus = { }
|
|
|
|
|
}, 'row')
|
|
|
|
|
|
|
|
|
|
-- Create Roll anchor
|
|
|
|
|
anchor = XLoot.Stack:CreateStaticStack(function() return RollFramePrototype:New() end, L.anchor, opt.roll_anchor)
|
|
|
|
|
anchor:SetFrameLevel(7)
|
|
|
|
|
anchor:Scale(opt.roll_anchor.scale)
|
|
|
|
|
addon.anchor = anchor
|
|
|
|
|
|
|
|
|
|
-- Create alert anchor
|
|
|
|
|
alert_anchor = XLoot.Stack:CreateAnchor(L.alert_anchor, opt.alert_anchor)
|
|
|
|
|
alert_anchor:SetFrameLevel(7)
|
|
|
|
|
addon.alert_anchor = alert_anchor
|
|
|
|
|
-- DISABLED-PATCH: LEGION PRE-PATCH
|
|
|
|
|
alert_anchor.Show = alert_anchor.Hide
|
|
|
|
|
alert_anchor:Hide()
|
|
|
|
|
|
|
|
|
|
-- Skin anchor
|
|
|
|
|
Skinner:Skin(anchor, XLoot.opt.skin_anchors and 'anchor_pretty' or 'anchor')
|
|
|
|
|
Skinner:Skin(alert_anchor, XLoot.opt.skin_anchors and 'anchor_pretty' or 'anchor')
|
|
|
|
|
|
|
|
|
|
-- Row fader
|
|
|
|
|
local fader = CreateFrame('Frame')
|
|
|
|
|
local timer = 0
|
|
|
|
|
fader:SetScript('OnUpdate', function(self, elapsed)
|
|
|
|
|
if timer < 1 then
|
|
|
|
|
timer = timer + elapsed
|
|
|
|
|
else
|
|
|
|
|
timer = 0
|
|
|
|
|
local time = GetTime()
|
|
|
|
|
-- Extend expiration for mouseovered frames
|
|
|
|
|
if mouse_focus and mouse_focus.aexpire and (mouse_focus.aexpire - time) < 5 then
|
|
|
|
|
mouse_focus.aexpire = time + 5
|
|
|
|
|
end
|
|
|
|
|
for i=#anchor.expiring,1,-1 do
|
|
|
|
|
local frame = anchor.expiring[i]
|
|
|
|
|
if frame.aexpire and time > frame.aexpire then
|
|
|
|
|
anchor:Pop(frame)
|
|
|
|
|
table.remove(anchor.expiring, i)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
if not next(anchor.expiring) then
|
|
|
|
|
self:Hide()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end)
|
|
|
|
|
anchor.expiring = {}
|
|
|
|
|
function anchor:Expire(frame, time)
|
|
|
|
|
fader:Show()
|
|
|
|
|
table.insert(self.expiring, frame)
|
|
|
|
|
frame.aexpire = GetTime() + time
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Find and show active rolls
|
|
|
|
|
if IsInGroup() and (GetLootMethod() == 'group' or GetLootMethod() == 'needbeforegreed') then
|
|
|
|
|
for i=1,300 do
|
|
|
|
|
local time = GetLootRollTimeLeft(i)
|
|
|
|
|
if time > 0 and time < 300000 then
|
|
|
|
|
self:START_LOOT_ROLL(i, time, true)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--[[ DISABLED-PATCH: LEGION PRE-PATCH
|
|
|
|
|
-- Hook alert actions
|
|
|
|
|
if opt.hook_alert then
|
|
|
|
|
hooksecurefunc('LootUpgradeFrame_SetUp', self.AlertFrameHook)
|
|
|
|
|
hooksecurefunc('LootWonAlertFrame_SetUp', self.AlertFrameHook)
|
|
|
|
|
hooksecurefunc('MoneyWonAlertFrame_SetUp', self.AlertFrameHook)
|
|
|
|
|
local SetLootWonAnchors = AlertFrame_SetLootWonAnchors
|
|
|
|
|
local SetLootUpgradeFrameAnchors = AlertFrame_SetLootUpgradeFrameAnchors
|
|
|
|
|
local SetMoneyWonAnchors = AlertFrame_SetMoneyWonAnchors
|
|
|
|
|
|
|
|
|
|
local function SetAnchorPassthrough(alertAnchor)
|
|
|
|
|
return alertAnchor
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
AlertFrame_SetLootWonAnchors = SetAnchorPassthrough
|
|
|
|
|
AlertFrame_SetLootUpgradeFrameAnchors = SetAnchorPassthrough
|
|
|
|
|
AlertFrame_SetMoneyWonAnchors = SetAnchorPassthrough
|
|
|
|
|
|
|
|
|
|
hooksecurefunc('AlertFrame_FixAnchors', self.FixAnchors)
|
|
|
|
|
end
|
|
|
|
|
-- hooksecurefunc('BonusRollFrame_StartBonusRoll', self.BonusRollFrame_StartBonusRoll)
|
|
|
|
|
-- hooksecurefunc('BonusRollFrame_FinishedFading', self.BonusRollFrame_Hide)
|
|
|
|
|
-- BonusRollFrame._SetPoint, BonusRollFrame.SetPoint = BonusRollFrame.SetPoint, addon.BonusRollFrame_SetPoint
|
|
|
|
|
if opt.hook_bonus then
|
|
|
|
|
hooksecurefunc(BonusRollFrame, 'SetPoint', self.BonusRollFrame_SetPoint)
|
|
|
|
|
hooksecurefunc(BonusRollFrame, 'Show', self.BonusRollFrame_Show)
|
|
|
|
|
hooksecurefunc(BonusRollFrame, 'Hide', self.BonusRollFrame_Hide)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if (opt.hook_alert or opt.hook_bonus) and not opt.shown_hook_warning then
|
|
|
|
|
local function gprint(text) print(('%s: %s'):format('|c2244dd22XLoot Group|r', text)) end
|
|
|
|
|
gprint("The 'Modify bonus rolls' or 'Modify loot alerts' options are currently enabled, but are now disabled by default.")
|
|
|
|
|
gprint("I cannot guarantee that you will not experience any issues with bonus rolls with these options enabled.")
|
|
|
|
|
gprint("If you do not accept that risk, please disable those options or XLoot Group entirely. You should only see this message once.")
|
|
|
|
|
opt.shown_hook_warning = true
|
|
|
|
|
end
|
|
|
|
|
]]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
-- Frame helpers
|
|
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
-- Event handlers
|
|
|
|
|
|
|
|
|
|
addon.bars = {}
|
|
|
|
|
local type_strings = {
|
|
|
|
|
need = NEED,
|
|
|
|
|
greed = GREED,
|
|
|
|
|
disenchant = ROLL_DISENCHANT,
|
|
|
|
|
pass = PASS
|
|
|
|
|
}
|
|
|
|
|
local rtypes = { [0] = 'pass', 'need', 'greed', 'disenchant' } -- Tekkub. Writing smaller addons than me since ever.
|
|
|
|
|
|
|
|
|
|
function addon:START_LOOT_ROLL(id, length, uid, ongoing)
|
|
|
|
|
local icon, name, count, quality, bop, need, greed, de, reason_need, reason_greed, reason_de, de_skill = GetLootRollItemInfo(id)
|
|
|
|
|
local link = GetLootRollItemLink(id)
|
|
|
|
|
local r, g, b = GetItemQualityColor(quality)
|
|
|
|
|
|
|
|
|
|
local start = length
|
|
|
|
|
if ongoing then
|
|
|
|
|
if quality == 2 then
|
|
|
|
|
length = 60000
|
|
|
|
|
else
|
|
|
|
|
length = 180000
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
length, start = length/1000, start/1000
|
|
|
|
|
|
|
|
|
|
local frame = anchor:Push()
|
|
|
|
|
rolls[id] = frame
|
|
|
|
|
|
|
|
|
|
frame.need:Show()
|
|
|
|
|
frame.greed:Show()
|
|
|
|
|
frame.disenchant:Show()
|
|
|
|
|
frame.pass:Show()
|
|
|
|
|
frame.text_status:Hide()
|
|
|
|
|
frame.text_status:SetText()
|
|
|
|
|
frame.text_time:SetShown(opt.show_time_remaining)
|
|
|
|
|
|
|
|
|
|
frame.need.texture_special:SetTexture()
|
|
|
|
|
frame.greed.texture_special:SetTexture()
|
|
|
|
|
|
|
|
|
|
if opt.equip_prefix then
|
|
|
|
|
local canequip, isupgrade = CanEquipItem(link), IsItemUpgrade(link)
|
|
|
|
|
if canequip or isupgrade then
|
|
|
|
|
name = string_format("|cFF%s%s|r%s", isupgrade and "44FF22" or "BBBBBB", is_upgrade and opt.prefix_upgrade or opt.prefix_equippable, name)
|
|
|
|
|
if isupgrade then
|
|
|
|
|
(need and frame.need or frame.greed).texture_special:SetTexture([[Interface\AddOns\Pawn\Textures\UpgradeArrow.tga]])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
frame.need:Toggle(need)
|
|
|
|
|
frame.greed:Toggle(greed)
|
|
|
|
|
frame.disenchant:Toggle(de)
|
|
|
|
|
|
|
|
|
|
frame.need:SetText()
|
|
|
|
|
frame.greed:SetText()
|
|
|
|
|
frame.pass:SetText()
|
|
|
|
|
frame.disenchant:SetText()
|
|
|
|
|
|
|
|
|
|
frame.need.reason = reason_need ~= 0 and reason_need or nil
|
|
|
|
|
frame.greed.reason = reason_greed ~= 0 and reason_greed or nil
|
|
|
|
|
frame.disenchant.reason = reason_de ~= 0 and reason_de or nil
|
|
|
|
|
frame.disenchant.skill = de_skill ~= 0 and de_skill or nil
|
|
|
|
|
|
|
|
|
|
local bar = frame.bar
|
|
|
|
|
bar.length = length
|
|
|
|
|
bar.expires = GetTime() + start
|
|
|
|
|
|
|
|
|
|
frame.link = link
|
|
|
|
|
frame.rollid = id
|
|
|
|
|
frame.rollended = nil
|
|
|
|
|
frame.quality = quality
|
|
|
|
|
frame.expires = bar.expires
|
|
|
|
|
frame.over = nil
|
|
|
|
|
frame.have_rolled = false
|
|
|
|
|
frame.lead_type = 'pass'
|
|
|
|
|
|
|
|
|
|
frame.text_bind:SetText(bop and '|cffff4422BoP' or '')
|
|
|
|
|
frame.text_loot:SetText(name)
|
|
|
|
|
local ilvl = GetDetailedItemLevelInfo(link)
|
|
|
|
|
frame.text_ilvl:SetText(ilvl > 1 and ilvl or nil)
|
|
|
|
|
|
|
|
|
|
frame.text_loot:SetVertexColor(r, g, b)
|
|
|
|
|
frame.overlay:SetBorderColor(r, g, b)
|
|
|
|
|
frame.icon_frame:SetBorderColor(r, g, b)
|
|
|
|
|
bar:SetStatusBarColor(r, g, b, .7)
|
|
|
|
|
frame.icon:SetTexture(icon)
|
|
|
|
|
|
|
|
|
|
bar:SetMinMaxValues(0, length)
|
|
|
|
|
bar:SetValue(start)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return frame
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local tidx = { [0] = 1, [3] = 2, [2] = 2, [1] = 3 }
|
|
|
|
|
function addon:LOOT_HISTORY_ROLL_COMPLETE()
|
|
|
|
|
-- Locate history item
|
|
|
|
|
local hid, frame, rollid, players, done, _ = 1
|
|
|
|
|
while true do
|
|
|
|
|
rollid, _, players, done = HistoryGetItem(hid)
|
|
|
|
|
if not rollid or (rolls[rollid] and rolls[rollid].over) then
|
|
|
|
|
return
|
|
|
|
|
elseif done and rolls[rollid] then
|
|
|
|
|
frame = rolls[rollid]
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
hid = hid+1
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Active frame found
|
|
|
|
|
frame.over = true
|
|
|
|
|
local top_type, top_roll, top_pid = 0, 0
|
|
|
|
|
for j=1, players do
|
|
|
|
|
local name, class, rtype, roll, is_winner, is_me = HistoryGetPlayerInfo(hid, j)
|
|
|
|
|
-- roll = roll and roll or true
|
|
|
|
|
if is_winner then
|
|
|
|
|
top_pid = j
|
|
|
|
|
break
|
|
|
|
|
elseif rtype ~= 0 and tidx[rtype] >= tidx[top_type] and (not roll or roll > top_roll) then
|
|
|
|
|
top_type = rtype
|
|
|
|
|
top_roll = roll
|
|
|
|
|
top_pid = j
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Winner or lead
|
|
|
|
|
if top_pid then
|
|
|
|
|
local name, class = HistoryGetPlayerInfo(hid, top_pid)
|
|
|
|
|
local player, r, g, b = FancyPlayerName(name, class, opt)
|
|
|
|
|
if opt.win_icon then
|
|
|
|
|
if rtype == 'need' then
|
|
|
|
|
player = [[|TInterface\Buttons\UI-GroupLoot-Dice-Up:16:16:-1:-1|t]]..player
|
|
|
|
|
elseif rtype == 'greed' then
|
|
|
|
|
player = [[|TInterface\Buttons\UI-GroupLoot-Coin-Up:16:16:-1:-2|t]]..player
|
|
|
|
|
elseif rtype == 'disenchant' then
|
|
|
|
|
player = [[|TInterface\Buttons\UI-GroupLoot-DE-Up:16:16:-1:-1|t]]..player
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
frame.text_status:SetText(player)
|
|
|
|
|
frame.text_status:SetTextColor(r, g, b)
|
|
|
|
|
frame.bar.expires = GetTime()
|
|
|
|
|
anchor:Expire(frame, is_me and opt.expire_won or opt.expire_lost)
|
|
|
|
|
else
|
|
|
|
|
-- No winner/lead
|
|
|
|
|
frame.text_status:SetText(string_format('%s: %s', PASS, ALL))
|
|
|
|
|
frame.text_status:SetTextColor(.7, .7, .7)
|
|
|
|
|
frame.bar.expires = GetTime()
|
|
|
|
|
anchor:Expire(frame, opt.expire_lost)
|
|
|
|
|
end
|
|
|
|
|
-- Refresh tooltip
|
|
|
|
|
if frame and mouse_focus == frame then
|
|
|
|
|
frame:OnEnter()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
addon.LOOT_ROLLS_COMPLETE = addon.LOOT_HISTORY_ROLL_COMPLETE
|
|
|
|
|
|
|
|
|
|
local rweights = { need = 3, greed = 2, disenchant = 2, pass = 1 }
|
|
|
|
|
function addon:LOOT_HISTORY_ROLL_CHANGED(hid, pid)
|
|
|
|
|
-- Acquire roll information and frame
|
|
|
|
|
local rollid, link, players, done = HistoryGetItem(hid)
|
|
|
|
|
local frame = rolls[rollid]
|
|
|
|
|
if not frame or frame.rollid ~= rollid or not frame:IsShown() then
|
|
|
|
|
return nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Acquire player information
|
|
|
|
|
local name, class, rtypeid, roll, winner, is_me = HistoryGetPlayerInfo(hid, pid)
|
|
|
|
|
local rtype = rtypes[rtypeid]
|
|
|
|
|
|
|
|
|
|
-- Transition or expire frame on player roll
|
|
|
|
|
if is_me then
|
|
|
|
|
if opt.track_all
|
|
|
|
|
or (opt.track_player_roll and rtype ~= 'pass')
|
|
|
|
|
or (opt.track_by_threshold and frame.quality >= opt.track_threshold) then
|
|
|
|
|
frame.need:Hide()
|
|
|
|
|
frame.greed:Hide()
|
|
|
|
|
frame.disenchant:Hide()
|
|
|
|
|
frame.pass:Hide()
|
|
|
|
|
frame.text_status:Show()
|
|
|
|
|
frame.have_rolled = true
|
|
|
|
|
else
|
|
|
|
|
anchor:Pop(frame)
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Update post-player-roll status text
|
|
|
|
|
if frame.have_rolled then
|
|
|
|
|
local rtype = rtype == 'disenchant' and 'greed' or rtype
|
|
|
|
|
-- Roll of leading type or higher
|
|
|
|
|
if rweights[rtype] >= rweights[frame.lead_type] then
|
|
|
|
|
frame.lead_type = rtype
|
|
|
|
|
local bracket, mtype = 0, nil
|
|
|
|
|
for i=1, players do
|
|
|
|
|
local _, _, ptype, _, _, is_me = HistoryGetPlayerInfo(hid, i)
|
|
|
|
|
local ptype = rtypes[ptype == 3 and 2 or ptype]
|
|
|
|
|
if ptype == rtype then
|
|
|
|
|
bracket = bracket + 1
|
|
|
|
|
end
|
|
|
|
|
if is_me then
|
|
|
|
|
mtype = ptype
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local r, g, b = .7, .7, .7
|
|
|
|
|
if mtype == rtype then
|
|
|
|
|
r, g, b = .2, 1, .1
|
|
|
|
|
elseif mtype and mtype ~= 0 then
|
|
|
|
|
r, g, b = 1, .2, .1
|
|
|
|
|
end
|
|
|
|
|
frame.text_status:SetText(string_format('%s: %s', type_strings[rtype], bracket))
|
|
|
|
|
frame.text_status:SetTextColor(r, g, b)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Update roll button counters
|
|
|
|
|
else
|
|
|
|
|
local bracket = 0
|
|
|
|
|
for i=1, players do
|
|
|
|
|
local _, _, thistype = HistoryGetPlayerInfo(hid, i)
|
|
|
|
|
if thistype == rtypeid then
|
|
|
|
|
bracket = bracket + 1
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
frame[rtype]:SetText(bracket)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Refresh tooltip
|
|
|
|
|
if frame and mouse_focus == frame then
|
|
|
|
|
frame:OnEnter()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function addon:MODIFIER_STATE_CHANGED()
|
|
|
|
|
if mouse_focus and MouseIsOver(mouse_focus) and mouse_focus.OnEnter then
|
|
|
|
|
mouse_focus:OnEnter()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local alert_frames = {}
|
|
|
|
|
function addon.AlertFrameHook(alert)
|
|
|
|
|
-- Reskin toast
|
|
|
|
|
local elements = alert_frames[alert]
|
|
|
|
|
if not elements then
|
|
|
|
|
elements = {}
|
|
|
|
|
if not (opt.alert_background and opt.alert_icon_frame) then
|
|
|
|
|
local name
|
|
|
|
|
if alert.ItemName then
|
|
|
|
|
name = alert.ItemName
|
|
|
|
|
alert.Label:ClearAllPoints()
|
|
|
|
|
alert.Label:SetPoint('TOPLEFT', alert.Icon, 'TOPRIGHT', 15, -5)
|
|
|
|
|
elseif alert.BaseQualityItemName then
|
|
|
|
|
name = alert.BaseQualityItemName
|
|
|
|
|
alert.TitleText:ClearAllPoints()
|
|
|
|
|
alert.TitleText:SetPoint('TOPLEFT', alert.Icon, 'TOPRIGHT', 15, -2)
|
|
|
|
|
elseif alert.Amount then
|
|
|
|
|
name = alert.Amount
|
|
|
|
|
alert.Label:ClearAllPoints()
|
|
|
|
|
alert.Label:SetPoint('TOPLEFT', alert.Icon, 'TOPRIGHT', 15, -2)
|
|
|
|
|
end
|
|
|
|
|
name:ClearAllPoints()
|
|
|
|
|
name:SetPoint('LEFT', alert.Icon, 'RIGHT', 10, -6)
|
|
|
|
|
end
|
|
|
|
|
if opt.alert_skin then
|
|
|
|
|
local overlay = CreateFrame('Frame', nil, alert, BackdropTemplateMixin and "BackdropTemplate")
|
|
|
|
|
overlay:SetPoint('TOPLEFT', 11, -11)
|
|
|
|
|
overlay:SetPoint('BOTTOMRIGHT', -11, 11)
|
|
|
|
|
overlay:SetFrameLevel(alert:GetFrameLevel())
|
|
|
|
|
elements.overlay = overlay
|
|
|
|
|
Skinner:Skin(overlay, 'alert')
|
|
|
|
|
if opt.alert_background then
|
|
|
|
|
local backdrop = CreateFrame('Frame', nil, alert, BackdropTemplateMixin and "BackdropTemplate")
|
|
|
|
|
backdrop:SetAllPoints(overlay)
|
|
|
|
|
backdrop:SetFrameLevel(alert:GetFrameLevel()-1)
|
|
|
|
|
overlay.gradient:SetParent(backdrop)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local icon_frame = CreateFrame('Frame', nil, alert, BackdropTemplateMixin and "BackdropTemplate")
|
|
|
|
|
icon_frame:SetPoint('CENTER', alert.Icon, 'CENTER', 0, 0)
|
|
|
|
|
icon_frame:SetWidth(alert.Icon:GetWidth() + 4)
|
|
|
|
|
icon_frame:SetHeight(alert.Icon:GetHeight() + 4)
|
|
|
|
|
elements.icon_frame = icon_frame
|
|
|
|
|
Skinner:Skin(icon_frame, 'alert_item')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
alert_frames[alert] = elements
|
|
|
|
|
end
|
|
|
|
|
alert.Background:SetShown(opt.alert_background)
|
|
|
|
|
alert.IconBorder:SetShown(opt.alert_icon_frame)
|
|
|
|
|
alert.BaseQualityBorder:SetShown(opt.alert_icon_frame)
|
|
|
|
|
alert.UpgradeQualityBorder:SetShown(opt.alert_icon_frame)
|
|
|
|
|
alert:SetAlpha(opt.alert_alpha)
|
|
|
|
|
alert:SetScale(opt.alert_scale)
|
|
|
|
|
|
|
|
|
|
-- Update toast
|
|
|
|
|
if opt.alert_skin then
|
|
|
|
|
local c
|
|
|
|
|
if alert.hyperlink then
|
|
|
|
|
local _, _, rarity = GetItemInfo(alert.hyperlink)
|
|
|
|
|
c = ITEM_QUALITY_COLORS[rarity]
|
|
|
|
|
else
|
|
|
|
|
c = {r = 1, g = .8, b = 0.1}
|
|
|
|
|
end
|
|
|
|
|
if type(c) == "table" then -- Sanity check due to 5.4.1 reported error
|
|
|
|
|
elements.overlay:SetGradientColor(c.r, c.g, c.b, .2)
|
|
|
|
|
elements.icon_frame:SetGradientColor(c.r, c.g, c.b, .2)
|
|
|
|
|
elements.overlay:SetBorderColor(c.r, c.g, c.b)
|
|
|
|
|
elements.icon_frame:SetBorderColor(c.r, c.g, c.b)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local AlertFrameTables = {
|
|
|
|
|
'LOOT_WON_ALERT_FRAMES',
|
|
|
|
|
'LOOT_UPGRADE_ALERT_FRAMES',
|
|
|
|
|
'MONEY_WON_ALERT_FRAMES'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function addon.FixAnchors(frames, anchor)
|
|
|
|
|
local anchor = alert_anchor
|
|
|
|
|
local up, first, x, y = opt.alert_anchor.direction == 'up', true, 44, -10
|
|
|
|
|
for ix=1, #AlertFrameTables do
|
|
|
|
|
local t = _G[AlertFrameTables[ix]]
|
|
|
|
|
for i=1, #t do
|
|
|
|
|
local frame = t[i]
|
|
|
|
|
if frame:IsShown() then
|
|
|
|
|
frame:ClearAllPoints()
|
|
|
|
|
if up then
|
|
|
|
|
frame:SetPoint("BOTTOM", anchor, "TOP", x, y)
|
|
|
|
|
else
|
|
|
|
|
frame:SetPoint("TOP", anchor, "BOTTOM", x, -y)
|
|
|
|
|
end
|
|
|
|
|
anchor = frame
|
|
|
|
|
if first then
|
|
|
|
|
first, x, y = false, 0, opt.alert_offset - 20
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- function addon.BonusRollFrame_StartBonusRoll()
|
|
|
|
|
-- if BonusRollFrame:IsShown() then
|
|
|
|
|
-- addon.BonusRollFrame_Show()
|
|
|
|
|
-- end
|
|
|
|
|
-- end
|
|
|
|
|
|
|
|
|
|
function addon.BonusRollFrame_SetPoint(self, _, frame)
|
|
|
|
|
if frame ~= anchor then
|
|
|
|
|
self:ClearAllPoints()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local bonus_elements
|
|
|
|
|
function addon.BonusRollFrame_Show()
|
|
|
|
|
local frame = BonusRollFrame
|
|
|
|
|
if not bonus_elements then
|
|
|
|
|
bonus_elements = {}
|
|
|
|
|
|
|
|
|
|
frame.active = true -- Prevent anchor from acquiring as child
|
|
|
|
|
frame.scale_mod = 0.9 -- Anchor's scale modifier
|
|
|
|
|
if opt.bonus_skin then
|
|
|
|
|
frame.Background:Hide()
|
|
|
|
|
local overlay = CreateFrame('Frame', nil, frame, BackdropTemplateMixin and "BackdropTemplate")
|
|
|
|
|
overlay:SetAllPoints()
|
|
|
|
|
overlay:SetFrameLevel(frame:GetFrameLevel()-1)
|
|
|
|
|
Skinner:Skin(overlay, 'bonus')
|
|
|
|
|
overlay:SetGradientColor(.5, .5, .5, .4)
|
|
|
|
|
overlay:SetBorderColor(1, .8, .1)
|
|
|
|
|
bonus_elements.overlay = overlay
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if anchor.children[1] ~= BonusRollFrame then
|
|
|
|
|
table.insert(anchor.children, 1, frame) -- Force in first position
|
|
|
|
|
end
|
|
|
|
|
anchor:Restack()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function addon.BonusRollFrame_Hide()
|
|
|
|
|
if anchor.children[1] == BonusRollFrame then
|
|
|
|
|
table.remove(anchor.children, 1)
|
|
|
|
|
anchor:Restack()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function addon.SlashHandler(msg)
|
|
|
|
|
if msg == 'reset' then
|
|
|
|
|
anchor:Position()
|
|
|
|
|
alert_anchor:Position()
|
|
|
|
|
elseif msg == 'opt' or msg == 'options' then
|
|
|
|
|
addon.ShowOptions()
|
|
|
|
|
else
|
|
|
|
|
addon.ToggleAnchors()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function addon:UpdateAnchors()
|
|
|
|
|
anchor:SetShown(opt.roll_anchor.visible)
|
|
|
|
|
alert_anchor:SetShown(opt.alert_anchor.visible)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function addon.ToggleAnchors()
|
|
|
|
|
local state = anchor:IsShown()
|
|
|
|
|
anchor:SetShown(not state)
|
|
|
|
|
alert_anchor:SetShown(not state)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
-- Frame creation
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
local sf = string.format
|
|
|
|
|
-- Add a specific roll type to the tooltip
|
|
|
|
|
local function RollLines(list, hid)
|
|
|
|
|
for _,pid in pairs(list) do
|
|
|
|
|
local name, class, rtype, roll, is_winner, is_me = HistoryGetPlayerInfo(hid, pid)
|
|
|
|
|
-- TODO- ACCOUNT FOR MISSING PLAYERS BETTER
|
|
|
|
|
if not name then return nil end
|
|
|
|
|
local text, r, g, b, color = FancyPlayerName(name, class, opt)
|
|
|
|
|
if roll ~= nil then
|
|
|
|
|
if is_winner then
|
|
|
|
|
color = '44ff22'
|
|
|
|
|
elseif is_me then
|
|
|
|
|
color = 'ff2244'
|
|
|
|
|
else
|
|
|
|
|
color = 'CCCCCC'
|
|
|
|
|
end
|
|
|
|
|
GameTooltip:AddLine(sf(' |cff%s%s|r %s', color, roll, text), r, g, b)
|
|
|
|
|
else
|
|
|
|
|
GameTooltip:AddLine(' '..text, r, g, b)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Add roll status or summary to tooltip
|
|
|
|
|
local tneed, tgreed, tpass, trolls, tnone, table_sort
|
|
|
|
|
= {}, {}, {}, {}, {}, table.sort
|
|
|
|
|
local function rsort(a, b)
|
|
|
|
|
a, b = trolls[a] or 0, trolls[b] or 0
|
|
|
|
|
return a > b and true or false
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function AddIneligibleReason(button, r, g, b)
|
|
|
|
|
GameTooltip:AddLine(string_format(_G["LOOT_ROLL_INELIGIBLE_REASON"..button.reason], button.skill), r or .6, g or .6, b or .6)
|
|
|
|
|
GameTooltip:Show()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function AddTooltipLines(self, show_all, show)
|
|
|
|
|
-- Locate history item
|
|
|
|
|
local rollid, hid = self.rollid, 1
|
|
|
|
|
local hrollid, link, players, done
|
|
|
|
|
while true do
|
|
|
|
|
hrollid, link, players, done = HistoryGetItem(hid)
|
|
|
|
|
if not hrollid then
|
|
|
|
|
return
|
|
|
|
|
elseif hrollid == rollid then
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
hid = hid+1
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Generate player lists
|
|
|
|
|
local tneed, tgreed, tpass, tnone, trolls
|
|
|
|
|
= wipe(tneed), wipe(tgreed), wipe(tpass), wipe(tnone), wipe(trolls)
|
|
|
|
|
for pid=1, players do
|
|
|
|
|
local _, _, rtype, roll = HistoryGetPlayerInfo(hid, pid)
|
|
|
|
|
local t
|
|
|
|
|
if rtype then
|
|
|
|
|
if rtype == 0 then
|
|
|
|
|
t = tpass
|
|
|
|
|
elseif rtype == 1 then
|
|
|
|
|
t = tneed
|
|
|
|
|
elseif rtype == 2 or rtype == 3 then
|
|
|
|
|
t = tgreed
|
|
|
|
|
end
|
|
|
|
|
trolls[pid] = roll
|
|
|
|
|
else
|
|
|
|
|
t = tnone
|
|
|
|
|
end
|
|
|
|
|
if t then
|
|
|
|
|
t[#t+1] = pid
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
table_sort(tneed, rsort)
|
|
|
|
|
table_sort(tgreed, rsort)
|
|
|
|
|
table_sort(tpass, rsort)
|
|
|
|
|
|
|
|
|
|
-- Generate tooltip
|
|
|
|
|
if show_all then
|
|
|
|
|
GameTooltip:AddLine('.', 0, 0, 0)
|
|
|
|
|
end
|
|
|
|
|
if #tneed ~= 0 and (show_all or show == 1) then
|
|
|
|
|
GameTooltip:AddLine(NEED, .2, 1, .1)
|
|
|
|
|
RollLines(tneed, hid)
|
|
|
|
|
end
|
|
|
|
|
if #tgreed ~= 0 and (show_all or (show == 2 or show == 3)) then
|
|
|
|
|
GameTooltip:AddLine(GREED, .1, .2, 1)
|
|
|
|
|
RollLines(tgreed, hid)
|
|
|
|
|
end
|
|
|
|
|
if #tpass ~= 0 and (show_all or show == 0) then
|
|
|
|
|
GameTooltip:AddLine(PASS, .7, .7, .7)
|
|
|
|
|
RollLines(tpass, hid)
|
|
|
|
|
end
|
|
|
|
|
if show_all and opt.show_undecided then
|
|
|
|
|
GameTooltip:AddLine(L.undecided, .7, .3, .2)
|
|
|
|
|
RollLines(tnone, hid)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Force tooltip to refresh
|
|
|
|
|
GameTooltip:Show()
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
-- Roll buttons
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
local RollButtonPrototype = XLoot.NewPrototype()
|
|
|
|
|
do
|
|
|
|
|
function RollButtonPrototype:OnClick()
|
|
|
|
|
RollOnLoot(self.parent.rollid, self.type)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function RollButtonPrototype:Toggle(status)
|
|
|
|
|
if status then
|
|
|
|
|
self:Enable()
|
|
|
|
|
self:SetAlpha(1)
|
|
|
|
|
else
|
|
|
|
|
self:Disable()
|
|
|
|
|
self:SetAlpha(.6)
|
|
|
|
|
end
|
|
|
|
|
SetDesaturation(self:GetNormalTexture(), not status)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function RollButtonPrototype:OnEnter()
|
|
|
|
|
mouse_focus = self
|
|
|
|
|
GameTooltip:SetOwner(self, 'ANCHOR_TOPLEFT')
|
|
|
|
|
AddTooltipLines(self.parent, false, self.type)
|
|
|
|
|
-- This isn't working for some stupid reason
|
|
|
|
|
if GameTooltip:NumLines() == 0 then
|
|
|
|
|
GameTooltip:SetText(self.label, unpack(self.label_colors))
|
|
|
|
|
GameTooltip:Show()
|
|
|
|
|
end
|
|
|
|
|
-- This is for those people who think they should be able
|
|
|
|
|
-- to roll on something, can't, and then come complain to me.
|
|
|
|
|
if self.reason then
|
|
|
|
|
AddIneligibleReason(self, 1, .2, 0)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function RollButtonPrototype:OnLeave()
|
|
|
|
|
mouse_focus = nil
|
|
|
|
|
GameTooltip:Hide()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function RollButtonPrototype:SetText(text)
|
|
|
|
|
if text and text > 0 then
|
|
|
|
|
self.text:SetText(text)
|
|
|
|
|
else
|
|
|
|
|
self.text:SetText()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local path = [[Interface\Buttons\UI-GroupLoot-%s-%s]]
|
|
|
|
|
function RollButtonPrototype:New(parent, roll, label, tex, anchor_to, x, y, label_colors)
|
|
|
|
|
local b = self:_New(CreateFrame('Button', nil, parent))
|
|
|
|
|
b:SetPoint('LEFT', anchor_to, 'RIGHT', x, y)
|
|
|
|
|
b:SetNormalTexture(path:format(tex, 'Up'))
|
|
|
|
|
if tex ~= 'Pass' then
|
|
|
|
|
b:SetHighlightTexture(path:format(tex, 'Highlight'))
|
|
|
|
|
b:SetPushedTexture(path:format(tex, 'Down'))
|
|
|
|
|
else
|
|
|
|
|
b:SetHighlightTexture(path:format(tex, 'Up'))
|
|
|
|
|
b:GetNormalTexture():SetVertexColor(0.8, 0.7, 0.7)
|
|
|
|
|
b:GetHighlightTexture():SetAlpha(0.5)
|
|
|
|
|
end
|
|
|
|
|
b.parent = parent
|
|
|
|
|
|
|
|
|
|
local texture_special = b:CreateTexture(nil, 'OVERLAY')
|
|
|
|
|
texture_special:SetAllPoints(b)
|
|
|
|
|
texture_special:SetAlpha(0.5)
|
|
|
|
|
b.texture_special = texture_special
|
|
|
|
|
|
|
|
|
|
local text = b:CreateFontString(nil, 'OVERLAY')
|
|
|
|
|
text:SetPoint("CENTER", -x + 1, tex == 'DE' and -y +2 or -y)
|
|
|
|
|
b.text = text
|
|
|
|
|
|
|
|
|
|
b:SetScript('OnEnter', self.OnEnter)
|
|
|
|
|
b:SetScript('OnLeave', self.OnLeave)
|
|
|
|
|
b:SetScript('OnClick', self.OnClick)
|
|
|
|
|
b:SetMotionScriptsWhileDisabled(true)
|
|
|
|
|
b:Enable()
|
|
|
|
|
b.type = roll
|
|
|
|
|
b.label = label
|
|
|
|
|
b.label_colors = label_colors
|
|
|
|
|
|
|
|
|
|
b:ApplyOptions()
|
|
|
|
|
|
|
|
|
|
return b
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function RollButtonPrototype:ApplyOptions()
|
|
|
|
|
self.text:SetFont(opt.font, 12, opt.font_flag)
|
|
|
|
|
self:SetWidth(opt.roll_button_size)
|
|
|
|
|
self:SetHeight(opt.roll_button_size)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
-- Roll frames
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
RollFramePrototype = XLoot.NewPrototype()
|
|
|
|
|
-- Events
|
|
|
|
|
function RollFramePrototype:OnEnter()
|
|
|
|
|
mouse_focus = self
|
|
|
|
|
GameTooltip:SetOwner(self.icon_frame, 'ANCHOR_TOPLEFT', 28, 0)
|
|
|
|
|
GameTooltip:SetHyperlink(self.link)
|
|
|
|
|
if opt.show_decided or opt.show_undecided then
|
|
|
|
|
AddTooltipLines(self, true)
|
|
|
|
|
if self.need.reason then
|
|
|
|
|
AddIneligibleReason(self.need, 1, .2, 0)
|
|
|
|
|
end
|
|
|
|
|
if self.greed.reason and self.greed.reason ~= self.need.reason then
|
|
|
|
|
AddIneligibleReason(self.greed, .8, .1, 0)
|
|
|
|
|
end
|
|
|
|
|
if self.disenchant.reason then
|
|
|
|
|
AddIneligibleReason(self.disenchant, .6, .05, 0)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
if IsShiftKeyDown() then
|
|
|
|
|
GameTooltip_ShowCompareItem()
|
|
|
|
|
end
|
|
|
|
|
if IsModifiedClick('DRESSUP') then
|
|
|
|
|
ShowInspectCursor()
|
|
|
|
|
else
|
|
|
|
|
ResetCursor()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function RollFramePrototype:OnLeave()
|
|
|
|
|
mouse_focus = nil
|
|
|
|
|
GameTooltip:Hide()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function RollFramePrototype:OnClick(button)
|
|
|
|
|
if IsControlKeyDown() then
|
|
|
|
|
DressUpItemLink(self.link)
|
|
|
|
|
elseif IsShiftKeyDown() then
|
|
|
|
|
ChatEdit_InsertLink(self.link)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Status bar update
|
|
|
|
|
local max = math.max
|
|
|
|
|
function RollFramePrototype:OnBarUpdate()
|
|
|
|
|
local parent = self.parent
|
|
|
|
|
if parent.over then
|
|
|
|
|
self.spark:Hide()
|
|
|
|
|
self:SetValue(0)
|
|
|
|
|
parent.text_time:SetText()
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
local time = GetTime()
|
|
|
|
|
-- TODO: Remove?
|
|
|
|
|
local status, result = pcall(GetLootRollTimeLeft, parent.rollid)
|
|
|
|
|
if not status or result == 0 then
|
|
|
|
|
local ended = parent.rollended
|
|
|
|
|
if ended then
|
|
|
|
|
if time - ended > 10 then
|
|
|
|
|
anchor:Pop(parent)
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
parent.rollended = time
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
-- /TODO
|
|
|
|
|
local remaining = self.expires - time
|
|
|
|
|
if remaining < -4 then
|
|
|
|
|
anchor:Pop(parent)
|
|
|
|
|
else
|
|
|
|
|
local now, length = max(remaining, -1), self.length
|
|
|
|
|
self.spark:SetPoint('CENTER', self, 'LEFT', (now / length) * self:GetWidth(), 0)
|
|
|
|
|
self:SetValue(now)
|
|
|
|
|
self.spark:Show()
|
|
|
|
|
if opt.show_time_remaining then
|
|
|
|
|
if remaining >= 0 then
|
|
|
|
|
parent.text_time:SetText(sf('%.0f', max(0, remaining)))
|
|
|
|
|
parent.text_time:Show()
|
|
|
|
|
else
|
|
|
|
|
parent.text_time:Hide()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function RollFramePrototype:Popped()
|
|
|
|
|
rolls[self.rollid] = nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Create roll frame
|
|
|
|
|
function RollFramePrototype:New()
|
|
|
|
|
-- Base frame
|
|
|
|
|
local frame = self:_New(CreateFrame('Button', nil, UIParent))
|
|
|
|
|
frame:SetFrameLevel(anchor:GetFrameLevel())
|
|
|
|
|
frame:SetHeight(24)
|
|
|
|
|
frame:RegisterForClicks('LeftButtonUp', 'RightButtonUp')
|
|
|
|
|
frame:SetScript('OnEnter', self.OnEnter)
|
|
|
|
|
frame:SetScript('OnLeave', self.OnLeave)
|
|
|
|
|
frame:SetScript('OnClick', self.OnClick)
|
|
|
|
|
|
|
|
|
|
-- Overlay (For skin border)
|
|
|
|
|
local overlay = CreateFrame('frame', nil, frame, BackdropTemplateMixin and "BackdropTemplate")
|
|
|
|
|
overlay:SetFrameLevel(frame:GetFrameLevel())
|
|
|
|
|
overlay:SetAllPoints()
|
|
|
|
|
frame.overlay = overlay
|
|
|
|
|
local skin = Skinner:Skin(overlay, 'row')
|
|
|
|
|
|
|
|
|
|
-- Item icon (For skin border)
|
|
|
|
|
local icon_frame = CreateFrame('Frame', nil, frame)
|
|
|
|
|
icon_frame:SetPoint('LEFT', 0, 0)
|
|
|
|
|
icon_frame:SetWidth(28)
|
|
|
|
|
icon_frame:SetHeight(28)
|
|
|
|
|
frame.icon_frame = icon_frame
|
|
|
|
|
Skinner:Skin(icon_frame, 'item')
|
|
|
|
|
|
|
|
|
|
-- Item texture
|
|
|
|
|
local icon = icon_frame:CreateTexture(nil, 'BACKGROUND')
|
|
|
|
|
icon:SetPoint('TOPLEFT', 3, -3)
|
|
|
|
|
icon:SetPoint('BOTTOMRIGHT', -3, 3)
|
|
|
|
|
icon:SetTexCoord(.07,.93,.07,.93)
|
|
|
|
|
frame.icon = icon
|
|
|
|
|
|
|
|
|
|
-- Timer bar
|
|
|
|
|
local bar = CreateFrame('StatusBar', nil, frame)
|
|
|
|
|
bar:SetFrameLevel(frame:GetFrameLevel())
|
|
|
|
|
local pad = skin.padding or 2
|
|
|
|
|
bar:SetPoint('TOPRIGHT', -pad - 3, -pad - 3)
|
|
|
|
|
bar:SetPoint('BOTTOMRIGHT', -pad - 3, pad + 3)
|
|
|
|
|
bar:SetPoint('LEFT', icon_frame, 'RIGHT', -pad, 0)
|
|
|
|
|
bar:SetStatusBarTexture(skin.bar_texture)
|
|
|
|
|
bar:SetScript('OnUpdate', self.OnBarUpdate)
|
|
|
|
|
bar.parent = frame
|
|
|
|
|
frame.bar = bar
|
|
|
|
|
-- Reference bar for quick re-skinning when XLoot skin changes
|
|
|
|
|
table.insert(addon.bars, bar)
|
|
|
|
|
|
|
|
|
|
local spark = bar:CreateTexture(nil, 'OVERLAY')
|
|
|
|
|
spark:SetWidth(14)
|
|
|
|
|
spark:SetHeight(38)
|
|
|
|
|
spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
|
|
|
|
|
spark:SetBlendMode('ADD')
|
|
|
|
|
bar.spark = spark
|
|
|
|
|
|
|
|
|
|
-- Bind text
|
|
|
|
|
local bind = icon_frame:CreateFontString(nil, 'OVERLAY')
|
|
|
|
|
bind:SetPoint('BOTTOM', 0, 1)
|
|
|
|
|
frame.text_bind = bind
|
|
|
|
|
|
|
|
|
|
-- Time text
|
|
|
|
|
local time = icon_frame:CreateFontString(nil, 'OVERLAY')
|
|
|
|
|
time:SetPoint('CENTER', 0, 2)
|
|
|
|
|
frame.text_time = time
|
|
|
|
|
|
|
|
|
|
-- Item level
|
|
|
|
|
local ilvl = icon_frame:CreateFontString(nil, 'OVERLAY')
|
|
|
|
|
ilvl:SetPoint('TOPLEFT', 3, -3)
|
|
|
|
|
frame.text_ilvl = ilvl
|
|
|
|
|
|
|
|
|
|
-- Roll buttons
|
|
|
|
|
local n = RollButtonPrototype:New(frame, 1, NEED, 'Dice', icon_frame, 3, -1, {.2, 1, .1})
|
|
|
|
|
local g = RollButtonPrototype:New(frame, 2, GREED, 'Coin', n, 0, -2, {.1, .2, 1})
|
|
|
|
|
local d = RollButtonPrototype:New(frame, 3, ROLL_DISENCHANT, 'DE', g, 0, 2, {.1, .2, 1})
|
|
|
|
|
local p = RollButtonPrototype:New(frame, 0, PASS, 'Pass', d, 0, 2, {.7, .7, .7})
|
|
|
|
|
frame.need, frame.greed, frame.disenchant, frame.pass = n, g, d, p
|
|
|
|
|
|
|
|
|
|
-- Roll status text
|
|
|
|
|
local status = frame:CreateFontString(nil, 'OVERLAY')
|
|
|
|
|
status:SetHeight(16)
|
|
|
|
|
status:SetJustifyH('LEFT')
|
|
|
|
|
status:SetPoint('LEFT', icon_frame, 'RIGHT', 1, 0)
|
|
|
|
|
status:SetPoint('RIGHT', p, 'RIGHT', 2, 0)
|
|
|
|
|
frame.text_status = status
|
|
|
|
|
|
|
|
|
|
-- Loot name/link
|
|
|
|
|
local loot = frame:CreateFontString(nil, 'OVERLAY')
|
|
|
|
|
loot:SetHeight(16)
|
|
|
|
|
loot:SetJustifyH('LEFT')
|
|
|
|
|
loot:SetPoint('LEFT', p, 'RIGHT', 3, -1)
|
|
|
|
|
loot:SetPoint('RIGHT', frame, 'RIGHT', -5, 0)
|
|
|
|
|
frame.text_loot = loot
|
|
|
|
|
|
|
|
|
|
frame:ApplyOptions()
|
|
|
|
|
|
|
|
|
|
return frame
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function RollFramePrototype:ApplyOptions()
|
|
|
|
|
self:SetWidth(opt.roll_width)
|
|
|
|
|
|
|
|
|
|
-- Status bar is reskinned with SkinUpdate
|
|
|
|
|
|
|
|
|
|
self.need:ApplyOptions()
|
|
|
|
|
self.greed:ApplyOptions()
|
|
|
|
|
self.disenchant:ApplyOptions()
|
|
|
|
|
self.pass:ApplyOptions()
|
|
|
|
|
|
|
|
|
|
self.text_ilvl:SetFont(opt.font, 8, 'OUTLINE')
|
|
|
|
|
self.text_bind:SetFont(opt.font, 8, 'THICKOUTLINE')
|
|
|
|
|
self.text_time:SetFont(opt.font, 12, 'OUTLINE')
|
|
|
|
|
self.text_status:SetFont(opt.font, 12, opt.font_flag)
|
|
|
|
|
self.text_loot:SetFont(opt.font, 12, opt.font_flag)
|
|
|
|
|
|
|
|
|
|
self.text_time:SetShown(opt.show_time_remaining)
|
|
|
|
|
self.text_ilvl:SetShown(opt.text_ilvl)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
-- AddOn setup and events
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
-- Update skins when XLoot skin changes
|
|
|
|
|
function addon:SkinUpdate()
|
|
|
|
|
local skin = Skinner:Reskin()
|
|
|
|
|
local padding = skin.padding or 2
|
|
|
|
|
local p, n = padding + 3, -padding - 3
|
|
|
|
|
for _,bar in pairs(addon.bars) do
|
|
|
|
|
bar:ClearAllPoints()
|
|
|
|
|
bar:SetPoint('TOPRIGHT', n, n)
|
|
|
|
|
bar:SetPoint('BOTTOMRIGHT', n, p)
|
|
|
|
|
bar:SetPoint('LEFT', bar.parent.icon_frame, 'RIGHT', -padding, 0)
|
|
|
|
|
bar:SetStatusBarTexture(skin.bar_texture)
|
|
|
|
|
local link = bar.parent.link
|
|
|
|
|
if link then
|
|
|
|
|
local r, g, b = GetItemQualityColor(select(3, GetItemInfo(link)))
|
|
|
|
|
bar.parent.overlay:SetBorderColor(r, g, b)
|
|
|
|
|
bar.parent.icon_frame:SetBorderColor(r, g, b)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Move anchors when scale changes
|
|
|
|
|
function addon:ApplyOptions()
|
|
|
|
|
opt = self.opt
|
|
|
|
|
|
|
|
|
|
anchor:UpdateSVData(opt.roll_anchor)
|
|
|
|
|
alert_anchor:UpdateSVData(opt.alert_anchor)
|
|
|
|
|
|
|
|
|
|
self:SkinUpdate()
|
|
|
|
|
|
|
|
|
|
anchor:Restack()
|
|
|
|
|
|
|
|
|
|
for _,frame in pairs(anchor.children) do
|
|
|
|
|
if frame.ApplyOptions then
|
|
|
|
|
frame:ApplyOptions()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|