local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB local M = E:GetModule("Misc"); --Cache global variables --Lua functions local find, match = string.find, string.match local pairs, unpack, ipairs, next, tonumber = pairs, unpack, ipairs, next, tonumber local tinsert = table.insert --WoW API / Variables local CursorOnUpdate = CursorOnUpdate local DressUpItemLink = DressUpItemLink local GetLootRollItemInfo = GetLootRollItemInfo local GetLootRollItemLink = GetLootRollItemLink local GetLootRollTimeLeft = GetLootRollTimeLeft local IsControlKeyDown = IsControlKeyDown local IsShiftKeyDown = IsShiftKeyDown local ResetCursor = ResetCursor local RollOnLoot = RollOnLoot local ShowInspectCursor = ShowInspectCursor local CUSTOM_CLASS_COLORS = CUSTOM_CLASS_COLORS local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS local RAID_CLASS_COLORS = RAID_CLASS_COLORS local pos = "TOP" local cancelled_rolls = {} local FRAME_WIDTH, FRAME_HEIGHT = 328, 28 M.RollBars = {} local locale = GetLocale() local rollpairs = locale == "deDE" and { ["(.*) würfelt nicht für: (.+|r)$"] = "pass", ["(.*) hat für (.+) 'Gier' ausgewählt"] = "greed", ["(.*) hat für (.+) 'Bedarf' ausgewählt"] = "need", } or locale == "frFR" and { ["(.*) a passé pour : (.+)"] = "pass", ["(.*) a choisi Cupidité pour : (.+)"] = "greed", ["(.*) a choisi Besoin pour : (.+)"] = "need", } or locale == "zhTW" and { ["(.*)放棄了:(.+)"] = "pass", ["(.*)選擇了貪婪:(.+)"] = "greed", ["(.*)選擇了需求:(.+)"] = "need", } or locale == "ruRU" and { ["(.*) отказывается от предмета (.+)%."] = "pass", ["Разыгрывается: (.+)%. (.*): \"Не откажусь\""] = "greed", ["Разыгрывается: (.+)%. (.*): \"Мне это нужно\""] = "need", } or locale == "koKR" and { ["(.*)님이 주사위 굴리기를 포기했습니다: (.+)"] = "pass", ["(.*)님이 차비를 선택했습니다: (.+)"] = "greed", ["(.*)님이 입찰을 선택했습니다: (.+)"] = "need", } or locale == "esES" and { ["^(.*) pasó de: (.+|r)$"] = "pass", ["(.*) eligió Codicia para: (.+)"] = "greed", ["(.*) eligió Necesidad para: (.+)"] = "need", } or locale == "esMX" and { ["^(.*) pasó de: (.+|r)$"] = "pass", ["(.*) eligió Codicia para: (.+)"] = "greed", ["(.*) eligió Necesidad para: (.+)"] = "need", } or { ["^(.*) passed on: (.+|r)$"] = "pass", ["(.*) has selected Greed for: (.+)"] = "greed", ["(.*) has selected Need for: (.+)"] = "need", } local function ClickRoll(frame) RollOnLoot(frame.parent.rollID, frame.rolltype) end local function HideTip() GameTooltip:Hide() end local function HideTip2() GameTooltip:Hide() ResetCursor() end local rolltypes = {"need", "greed", [0] = "pass"} local function SetTip(frame) GameTooltip:SetOwner(frame, "ANCHOR_RIGHT") GameTooltip:SetText(frame.tiptext) if frame:IsEnabled() == 0 then GameTooltip:AddLine("|cffff3333"..L["Can't Roll"]) end for name, tbl in pairs(frame.parent.rolls) do if tbl[1] == rolltypes[frame.rolltype] and tbl[2] then local classColor = CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[tbl[2]] or RAID_CLASS_COLORS[tbl[2]] GameTooltip:AddLine(name, classColor.r, classColor.g, classColor.b) end end GameTooltip:Show() end local function SetItemTip(frame) if not frame.link then return end GameTooltip:SetOwner(frame, "ANCHOR_TOPLEFT") GameTooltip:SetHyperlink(match(frame.link, "item[%-?%d:]+")) -- if IsShiftKeyDown() then -- GameTooltip_ShowCompareItem() -- end if IsControlKeyDown() then ShowInspectCursor() else ResetCursor() end end local function ItemOnUpdate(self) -- if IsShiftKeyDown() then -- GameTooltip_ShowCompareItem() -- end CursorOnUpdate(self) end local function LootClick(frame) if IsControlKeyDown() then DressUpItemLink(frame.link) elseif IsShiftKeyDown() then ChatEdit_InsertLink(frame.link) end end local function OnEvent(frame) local rollID = arg1 cancelled_rolls[rollID] = true if frame.rollID ~= rollID then return end frame.rollID = nil frame.time = nil frame:Hide() end local function StatusUpdate(frame) if not frame.parent.rollID then return end local t = GetLootRollTimeLeft(frame.parent.rollID) local perc = t / frame.parent.time E:Point(frame.spark, "CENTER", frame, "LEFT", perc * frame:GetWidth(), 0) frame:SetValue(t) if t > 1000000000 then frame:GetParent():Hide() end end local function CreateRollButton(parent, ntex, ptex, htex, rolltype, tiptext, point, relativeFrame, relativePoint, ofsx, ofsy) local f = CreateFrame("Button", nil, parent) E:Point(f, point, relativeFrame, relativePoint, ofsx, ofsy) E:Size(f, FRAME_HEIGHT - 4) f:SetNormalTexture(ntex) if ptex then f:SetPushedTexture(ptex) end f:SetHighlightTexture(htex) f.rolltype = rolltype f.parent = parent f.tiptext = tiptext f:SetScript("OnEnter", function() SetTip(f) end) f:SetScript("OnLeave", HideTip) f:SetScript("OnClick", function() ClickRoll(f) end) local txt = f:CreateFontString(nil, nil) E:FontTemplate(txt, nil, nil, "OUTLINE") E:Point(txt, "CENTER", 0, rolltype == 2 and 1 or rolltype == 0 and -1.2 or 0) return f, txt end function M:CreateRollFrame() local frame = CreateFrame("Frame", nil, E.UIParent) E:Size(frame, FRAME_WIDTH, FRAME_HEIGHT) E:SetTemplate(frame, "Default") frame:SetScript("OnEvent", function() OnEvent(frame) end) frame:RegisterEvent("CANCEL_LOOT_ROLL") frame:Hide() local button = CreateFrame("Button", nil, frame) E:Point(button, "RIGHT", frame, "LEFT", -(E.Spacing*3), 0) E:Size(button, FRAME_HEIGHT - (E.Border * 2)) E:CreateBackdrop(button, "Default") button:SetScript("OnEnter", function() SetItemTip(button) end) button:SetScript("OnLeave", HideTip2) button:SetScript("OnUpdate", function() ItemOnUpdate(button) end) button:SetScript("OnClick", function() LootClick(button) end) frame.button = button button.icon = button:CreateTexture(nil, "OVERLAY") button.icon:SetAllPoints() button.icon:SetTexCoord(unpack(E.TexCoords)) local tfade = frame:CreateTexture(nil, "BORDER") E:Point(tfade, "TOPLEFT", frame, "TOPLEFT", 4, 0) E:Point(tfade, "BOTTOMRIGHT", frame, "BOTTOMRIGHT", -4, 0) tfade:SetTexture("Interface\\ChatFrame\\ChatFrameBackground") tfade:SetBlendMode("ADD") tfade:SetGradientAlpha("VERTICAL", .1, .1, .1, 0, .1, .1, .1, 0) local status = CreateFrame("StatusBar", nil, frame) E:SetInside(status) status:SetScript("OnUpdate", function() StatusUpdate(status) end) status:SetFrameLevel(status:GetFrameLevel() - 1) status:SetStatusBarTexture(E.media.normTex) E:RegisterStatusBar(status) status:SetStatusBarColor(.8, .8, .8, .9) status.parent = frame frame.status = status status.bg = status:CreateTexture(nil, "BACKGROUND") status.bg:SetAlpha(0.1) status.bg:SetAllPoints() local spark = frame:CreateTexture(nil, "OVERLAY") E:Size(spark, 14, FRAME_HEIGHT) spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark") spark:SetBlendMode("ADD") status.spark = spark local need, needtext = CreateRollButton(frame, "Interface\\Buttons\\UI-GroupLoot-Dice-Up", "Interface\\Buttons\\UI-GroupLoot-Dice-Highlight", "Interface\\Buttons\\UI-GroupLoot-Dice-Down", 1, NEED, "LEFT", frame.button, "RIGHT", 5, -1) local greed, greedtext = CreateRollButton(frame, "Interface\\Buttons\\UI-GroupLoot-Coin-Up", "Interface\\Buttons\\UI-GroupLoot-Coin-Highlight", "Interface\\Buttons\\UI-GroupLoot-Coin-Down", 2, GREED, "LEFT", need, "RIGHT", 0, -1) local pass, passtext = CreateRollButton(frame, "Interface\\AddOns\\ElvUI\\media\\textures\\UI-GroupLoot-Pass-Up", nil, "Interface\\AddOns\\ElvUI\\media\\textures\\UI-GroupLoot-Pass-Down", 0, PASS, "LEFT", greed, "RIGHT", 0, 2) frame.needbutt, frame.greedbutt = need, greed frame.need, frame.greed, frame.pass = needtext, greedtext, passtext local bind = frame:CreateFontString() E:Point(bind, "LEFT", pass, "RIGHT", 3, 1) E:FontTemplate(bind, nil, nil, "OUTLINE") frame.fsbind = bind local loot = frame:CreateFontString(nil, "ARTWORK") E:FontTemplate(loot, nil, nil, "OUTLINE") E:Point(loot, "LEFT", bind, "RIGHT", 0, 0) E:Point(loot, "RIGHT", frame, "RIGHT", -5, 0) E:Size(loot, 200, 10) loot:SetJustifyH("LEFT") frame.fsloot = loot frame.rolls = {} return frame end local function GetFrame() for _, f in ipairs(M.RollBars) do if not f.rollID then return f end end local f = M:CreateRollFrame() if pos == "TOP" then E:Point(f, "TOP", next(M.RollBars) and M.RollBars[getn(M.RollBars)] or AlertFrameHolder, "BOTTOM", 0, -4) else E:Point(f, "BOTTOM", next(M.RollBars) and M.RollBars[getn(M.RollBars)] or AlertFrameHolder, "TOP", 0, 4) end tinsert(M.RollBars, f) return f end function M:START_LOOT_ROLL() if cancelled_rolls[rollID] then return end local f = GetFrame() f.rollID = arg1 f.time = arg2 for i in pairs(f.rolls) do f.rolls[i] = nil end f.need:SetText(0) f.greed:SetText(0) f.pass:SetText(0) local texture, name, _, quality, bindOnPickUp = GetLootRollItemInfo(arg1) f.button.icon:SetTexture(texture) f.button.link = GetLootRollItemLink(arg1) f.needbutt:Enable() f.greedbutt:Enable() SetDesaturation(f.needbutt:GetNormalTexture()) SetDesaturation(f.greedbutt:GetNormalTexture()) f.needbutt:SetAlpha(1) f.greedbutt:SetAlpha(1) f.fsbind:SetText(bindOnPickUp and "BoP" or "BoE") f.fsbind:SetVertexColor(bindOnPickUp and 1 or .3, bindOnPickUp and .3 or 1, bindOnPickUp and .1 or .3) local color = ITEM_QUALITY_COLORS[quality] f.fsloot:SetText(name) f.status:SetStatusBarColor(color.r, color.g, color.b, .7) f.status.bg:SetTexture(color.r, color.g, color.b) f.status:SetMinMaxValues(0, arg2) f.status:SetValue(arg2) E:Point(f, "CENTER", WorldFrame, "CENTER") f:Show() if E.db.general.autoRoll and UnitLevel("player") == MAX_PLAYER_LEVEL and quality == 2 and not bindOnPickUp then RollOnLoot(arg1, 2) end end function M:ParseRollChoice(msg) if not msg then return end for i, v in pairs(rollpairs) do local _, _, playername, itemname = find(msg, i) if locale == "ruRU" and (v == "greed" or v == "need") then local temp = playername playername = itemname itemname = temp end if playername and itemname and playername ~= "Everyone" then return playername, itemname, v end end end function M:CHAT_MSG_LOOT() local playername, itemname, rolltype = self:ParseRollChoice(arg1) if playername and itemname and rolltype then for _, f in ipairs(M.RollBars) do if f.rollID and f.button.link == itemname and not f.rolls[playername] then f.rolls[playername] = { rolltype } f[rolltype]:SetText(tonumber(f[rolltype]:GetText()) + 1) return end end --[[ local _, class = UnitClass(playername) for _, f in ipairs(M.RollBars) do if f.rollID and f.button.link == itemname and not f.rolls[playername] then f.rolls[playername] = { rolltype, class } f[rolltype]:SetText(tonumber(f[rolltype]:GetText()) + 1) return end end ]] end end function M:LoadLootRoll() if not E.private.general.lootRoll then return end self:RegisterEvent("START_LOOT_ROLL") self:RegisterEvent("CHAT_MSG_LOOT") UIParent:UnregisterEvent("START_LOOT_ROLL") UIParent:UnregisterEvent("CANCEL_LOOT_ROLL") end