local SLE, T, E, L, V, P, G = unpack(select(2, ...)) local LT = SLE:NewModule('Loot','AceHook-3.0', 'AceEvent-3.0') local M = E:GetModule('Misc') --GLOBALS: hooksecurefunc, ChatFrame_AddMessageEventFilter, ChatFrame_RemoveMessageEventFilter, UIParent local _G = _G local ConfirmLootSlot = ConfirmLootSlot LT.PlayerLevel = 0 LT.MaxPlayerLevel = 0 LT.LootItems = 0 --To determine how many items are in our loot cache LT.LootEvents = { "CONFIRM_DISENCHANT_ROLL", --Group "CONFIRM_LOOT_ROLL", --Group "LOOT_BIND_CONFIRM", --Solo } LT.Loot = {} LT.LootTemp = {} LT.Numbers = {} local check = false local t = 0 local QUEUED_STATUS_UNKNOWN = QUEUED_STATUS_UNKNOWN local LOOT_ROLL_TYPE_GREED = LOOT_ROLL_TYPE_GREED local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown local SendChatMessage = SendChatMessage local RollOnLoot, ConfirmLootRoll, CloseLoot = RollOnLoot, ConfirmLootRoll, CloseLoot LT.IconChannels = { "CHAT_MSG_BN_CONVERSATION","CHAT_MSG_BN_WHISPER","CHAT_MSG_BN_WHISPER_INFORM", "CHAT_MSG_CHANNEL","CHAT_MSG_EMOTE","CHAT_MSG_GUILD","CHAT_MSG_INSTANCE_CHAT", "CHAT_MSG_INSTANCE_CHAT_LEADER","CHAT_MSG_LOOT","CHAT_MSG_OFFICER","CHAT_MSG_PARTY", "CHAT_MSG_PARTY_LEADER","CHAT_MSG_RAID","CHAT_MSG_RAID_LEADER","CHAT_MSG_RAID_WARNING", "CHAT_MSG_SAY","CHAT_MSG_SYSTEM","CHAT_MSG_WHISPER","CHAT_MSG_WHISPER_INFORM","CHAT_MSG_YELL", } local function Check() for x = 1, T.GetNumGroupMembers() do local name, rank, _, _, _, _, _, _, _, _, isML = T.GetRaidRosterInfo(x) if name == E.myname then if isML then return true elseif rank == 1 then return true elseif rank == 2 then return true end end end return false end function LT:ModifierCheck() local heldModifier = LT.db.announcer.override local shiftDown = IsShiftKeyDown(); local ctrlDown = IsControlKeyDown(); local altDown = IsAltKeyDown(); if heldModifier == '3' and shiftDown then return true elseif heldModifier == '5' and ctrlDown then return true elseif heldModifier == '4' and altDown then return true elseif heldModifier == '2' then return true end return false end local function Merge() -- local checking for i = 1, #(LT.Loot) do local checking = 1 while LT.Loot[i] ~= LT.Loot[checking] do checking = checking + 1 end if i ~= checking then LT.Numbers[i] = LT.Numbers[i] + LT.Numbers[checking] T.tremove(LT.Numbers, checking) T.tremove(LT.Loot, checking) LT.LootItems = LT.LootItems - 1 end end end function LT:PopulateTable(qualityPassed) for i = 1, T.GetNumLootItems() do if T.GetLootSlotType(i) == 1 then local _, item, quantity, quality = T.GetLootSlotInfo(i) local link, ilvl if quality >= qualityPassed then link = T.GetLootSlotLink(i) ilvl = T.select(4, T.GetItemInfo(link)) or QUEUED_STATUS_UNKNOWN LT.LootItems = LT.LootItems + 1 LT.Loot[LT.LootItems] = link LT.Loot[LT.LootItems] = LT.Loot[LT.LootItems].." (ilvl: "..ilvl..")" LT.Numbers[LT.LootItems] = quantity or 1 end end end Merge() end local function Channel() if LT.db.announcer.channel ~= "SAY" and T.IsPartyLFG() then return "INSTANCE_CHAT" end if LT.db.announcer.channel == "RAID" and not T.IsInRaid() then return "PARTY" end return LT.db.announcer.channel end function LT:AnnounceList() for i = 1, LT.LootItems do if LT.Numbers[i] == 1 then SendChatMessage(i..". "..LT.Loot[i], Channel()) elseif LT.Numbers[i] > 1 then SendChatMessage(i..". "..LT.Numbers[i].."x"..LT.Loot[i], Channel()) end if i == LT.LootItems then T.twipe(LT.Loot) T.twipe(LT.Numbers) LT.LootItems = 0 end end end function LT:Announce(event) if not T.IsInGroup() then return end -- not in group, exit. local m = 0 local quality = LT.db.announcer.quality == "EPIC" and 4 or LT.db.announcer.quality == "RARE" and 3 or LT.db.announcer.quality == "UNCOMMON" and 2 if (Check() and LT.db.announcer.auto) or (LT:ModifierCheck() and (T.IsInGroup() or T.IsInRaid())) then for i = 1, T.GetNumLootItems() do if T.GetLootSlotType(i) == 1 then for j = 1, t do if T.GetLootSlotLink(i) == LT.LootTemp[j] then check = true end end end end if check == false or LT:ModifierCheck() then LT:PopulateTable(quality) if LT.LootItems ~= 0 then SendChatMessage(L["Loot Dropped:"], Channel()) LT:AnnounceList() end end for i = 1, T.GetNumLootItems() do if T.GetLootSlotType(i) == 1 then LT.LootTemp[i] = T.GetLootSlotLink(i) end end t = T.GetNumLootItems() check = false end end function LT:HandleRoll(event, id) if not LT.db.autoroll.enable then return end if not (LT.db.autoroll.autogreed or LT.db.autoroll.autode) then return end local _, name, _, quality, _, _, _, disenchant = T.GetLootRollItemInfo(id) local link = T.GetLootRollItemLink(id) local itemID = T.tonumber(T.match(link, 'item:(%d+)')) if itemID == 43102 or itemID == 52078 then RollOnLoot(id, LOOT_ROLL_TYPE_GREED) end if T.IsXPUserDisabled() then LT.MaxPlayerLevel = LT.PlayerLevel end if (LT.db.autoroll.bylevel and LT.PlayerLevel < LT.db.autoroll.level) and LT.PlayerLevel ~= LT.MaxPlayerLevel then return end if LT.db.autoroll.bylevel then if T.IsEquippableItem(link) then local _, _, _, ilvl, _, _, _, _, slot = T.GetItemInfo(link) local itemLink = T.GetInventoryItemLink('player', slot) local matchItemLevel = itemLink and T.select(4, T.GetItemInfo(itemLink)) or 1 if quality ~= 7 and matchItemLevel < ilvl then return end end end if quality <= LT.db.autoroll.autoqlty then if LT.db.autoroll.autode and disenchant then RollOnLoot(id, 3) else RollOnLoot(id, 2) end end end function LT:HandleEvent(event, ...) if event == "LOOT_OPENED" then if LT.db.announcer.enable then LT:Announce(event) end end if not LT.db.autoroll.autoconfirm then return end if event == "CONFIRM_LOOT_ROLL" or event == "CONFIRM_DISENCHANT_ROLL" then local arg1, arg2 = ... ConfirmLootRoll(arg1, arg2) elseif event == "LOOT_OPENED" or event == "LOOT_BIND_CONFIRM" then local count = T.GetNumLootItems() if count == 0 then CloseLoot() return end for numslot = 1, count do ConfirmLootSlot(numslot) end end end local function LoadConfig(event, addon) if addon ~= "ElvUI_Config" then return end LT:Update() LT:UnregisterEvent("ADDON_LOADED") end function LT:Toggle() if LT.db.enable then self:RegisterEvent("LOOT_OPENED", "HandleEvent") self:RegisterEvent('PLAYER_ENTERING_WORLD', 'LootShow'); if not T.IsAddOnLoaded("ElvUI_Config") then self:RegisterEvent("ADDON_LOADED", LoadConfig) end else self:UnregisterEvent("LOOT_OPENED") self:UnregisterEvent('PLAYER_ENTERING_WORLD') self:UnregisterEvent("ADDON_LOADED") end end function LT:AutoToggle() for i = 1, 3 do if LT.db.autoroll.autoconfirm and LT.db.enable then self:RegisterEvent(LT.LootEvents[i], "HandleEvent") UIParent:UnregisterEvent(LT.LootEvents[i]) else UIParent:RegisterEvent(LT.LootEvents[i]) self:UnregisterEvent(LT.LootEvents[i]) end end end function LT:LootAlpha() _G["LootHistoryFrame"]:SetAlpha(LT.db.history.alpha or 1) end function LT:LootShow() local instance = T.IsInInstance() if (not instance and LT.db.history.autohide) then _G["LootHistoryFrame"]:Hide() end end function LT:Update() if T.IsAddOnLoaded("ElvUI_Config") then if LT.db.autoroll.enable then E.Options.args.general.args.general.args.autoRoll = { order = 6, name = L["Auto Greed/DE"], desc = L["This option have been disabled by Shadow & Light. To return it you need to disable S&L's option. Click here to see it's location."], type = "execute", func = function() SLE.ACD:SelectGroup("ElvUI", "sle", "modules", "loot") end, } else E.Options.args.general.args.general.args.autoRoll = { order = 6, name = L["Auto Greed/DE"], desc = L["Automatically select greed or disenchant (when available) on green quality items. This will only work if you are the max level."], type = 'toggle', disabled = function() return not E.private.general.lootRoll end } end end LT:Toggle() LT:AutoToggle() LT:LootAlpha() end function LT:PLAYER_LEVEL_UP(event, level) LT.PlayerLevel = level end function LT:AddLootIcons(event, message, ...) if LT.db.looticons.channels[event] then local function IconForLink(link) local texture = T.GetItemIcon(link) return (LT.db.looticons.position == "LEFT") and "\124T" .. texture .. ":" .. LT.db.looticons.size .. "\124t" .. link or link .. "\124T" .. texture .. ":" .. LT.db.looticons.size .. "\124t" end message = T.gsub(message, "(\124c%x+\124Hitem:.-\124h\124r)", IconForLink) end return false, message, ... end function LT:LootIconToggle() if LT.db.looticons.enable then for i = 1, #LT.IconChannels do ChatFrame_AddMessageEventFilter(LT.IconChannels[i], LT.AddLootIcons) end else for i = 1, #LT.IconChannels do ChatFrame_RemoveMessageEventFilter(LT.IconChannels[i], LT.AddLootIcons) end end end function LT:Initialize() if not SLE.initialized then return end LT.db = E.db.sle.loot self:RegisterEvent("PLAYER_LEVEL_UP") function LT:ForUpdateAll() LT.db = E.db.sle.loot LT:Update() LT:LootShow() LT:LootIconToggle() end LT.MaxPlayerLevel = T.GetMaxPlayerLevel() LT.PlayerLevel = T.UnitLevel('player') --Azil made this, blame him if something fucked up if E.db.general and LT.db.autoroll.enable then E.db.general.autoRoll = false end LT:Update() hooksecurefunc(M, 'START_LOOT_ROLL', function(self, event, id) LT:HandleRoll(event, id) end) -- hooksecurefunc("LootHistoryFrame_FullUpdate", ) LT:LootIconToggle() end SLE:RegisterModule(LT:GetName())