FasterLoot - initial commit

need some config now.
This commit is contained in:
Sattva
2023-12-25 20:16:25 +03:00
parent c91564616d
commit 2179a0658e
+485 -44
View File
@@ -1682,55 +1682,496 @@
if LeaPlusLC["FasterLooting"] == "On" then
-- Time delay
local tDelay = 0
--------------------------------------------------------------------------------
-- Code taken, and modified by Sattva.
-- Source code is from SpeedyAutoLoot addon.
-- Increase speed of looting singnificantly. Makes the feel of it better.
-- The main approach is to not load the looting window, when is not needed.
-- It was initially made for my WeakAura https://wago.io/uGLs2fARD
--------------------------------------------------------------------------------
local AutoLoot = CreateFrame("Frame")
-- local aura_env = aura_env or {}
local SetCVar = SetCVar
local BACKPACK_CONTAINER, LOOT_SLOT_ITEM, NUM_BAG_SLOTS = BACKPACK_CONTAINER, LOOT_SLOT_ITEM, NUM_BAG_SLOTS
local GetContainerNumFreeSlots = GetContainerNumFreeSlots
local GetCursorPosition = GetCursorPosition
local GetItemCount = GetItemCount
local GetItemInfo = GetItemInfo
local GetLootSlotInfo = GetLootSlotInfo
local GetLootSlotLink = GetLootSlotLink
local GetNumLootItems = GetNumLootItems
local IsModifiedClick = IsModifiedClick
local LootSlot = LootSlot
local band = bit.band
local select = select
local tContains = tContains
_G.ElvLootFrame = ElvLootFrame
_G.ElvLootFrameHolder = ElvLootFrameHolder
local slotType = slotType
local invFullSoundPlayed = false
--===== Check for if 3.3.5 or 2.4.3 game client. =====--
local isTBC = select(4, GetBuildInfo()) == 20400 -- true if TBC 2.4.3
local isWOTLK = select(4, GetBuildInfo()) == 30300 -- true if WOTLK 3.3.5
--===== WA Custom Options - Sound database =====--
local soundFiles = {
[1] = "Sound/Interface/Pickup/putDownRocks_Ore01.wav",
[2] = "sound/character/gnome/gnomemaleerrormessages/gnomemale_err_inventoryfull01.wav",
[3] = "sound/character/dwarf/dwarfmaleerrormessages/dwarfmale_err_inventoryfull02.wav",
-- Add more sound file paths if needed
}
-----------------------------------------------------------------
-- Function checks for if player has free bag slots,
-- If not then checks if looted item can fit in existing stacks.
-----------------------------------------------------------------
function AutoLoot:ProcessLoot(item, q)
local total, free, bagFamily = 0
local itemFamily = GetItemFamily(item)
for i = BACKPACK_CONTAINER, NUM_BAG_SLOTS do
free, bagFamily = GetContainerNumFreeSlots(i)
if (not bagFamily or bagFamily == 0) or (itemFamily and band(itemFamily, bagFamily) > 0) then
total = total + free
-- Fast loot function
local function FastLoot()
if GetTime() - tDelay >= 0.3 then
tDelay = GetTime()
if GetCVarBool("autoLootDefault") ~= IsModifiedClick("AUTOLOOTTOGGLE") then
if TSMDestroyBtn and TSMDestroyBtn:IsShown() and TSMDestroyBtn:GetButtonState() == "DISABLED" then tDelay = GetTime() return end
local lootMethod = GetLootMethod()
if lootMethod == "master" then
-- Master loot is enabled so fast loot if item should be auto looted
local lootThreshold = GetLootThreshold()
for i = GetNumLootItems(), 1, -1 do
local lootIcon, lootName, lootQuantity, lootQuality = GetLootSlotInfo(i)
if lootQuality and lootThreshold and lootQuality < lootThreshold then
LootSlot(i)
end
end
else
-- Master loot is disabled so fast loot regardless
local grouped = IsInGroup()
for i = GetNumLootItems(), 1, -1 do
local lootIcon, lootName, lootQuantity, lootQuality, locked = GetLootSlotInfo(i)
--local slotType = GetLootSlotType(i)
if lootName and not locked then
if not grouped then
LootSlot(i)
else
--if lootMethod == "freeforall" then
-- if slotType == LOOT_SLOT_ITEM then
-- LootSlot(i)
-- end
--else
LootSlot(i)
--end
end
end
end
end
tDelay = GetTime()
end
end
if total > 0 then
return true
end
local have = (GetItemCount(item) or 0)
if have > 0 then
local itemStackCount = (select(8,GetItemInfo(item)) or 0)
if itemStackCount > 1 then
while have > itemStackCount do
have = have - itemStackCount
end
local remain = itemStackCount - have
if remain >= q then
return true
end
end
end
return false
end
--------------------------------------------------------------------------------
-- Function checks and helps to handle (show, hide) ElvUI looting frame.
-- It also helps to handle default looting frame.
--------------------------------------------------------------------------------
function AutoLoot:ShowLootFrame(show)
-- print("ShowLootFrame: Show: " .. tostring(show))
if IsAddOnLoaded("ElvUI") then
-- print("ShowLootFrame: ElvUI loaded")
if show then
-- print("ShowLootFrame: Show ElvLootFrame")
ElvLootFrame:SetParent(ElvLootFrameHolder)
ElvLootFrame:SetFrameStrata("HIGH")
self:LootUnderMouse(ElvLootFrame, ElvLootFrameHolder, 20)
self.isHidden = false
else
-- print("ShowLootFrame: Hide ElvLootFrame")
ElvLootFrame:SetParent(self)
self.isHidden = true
end
elseif LootFrame:IsEventRegistered("LOOT_SLOT_CLEARED") then
-- print("ShowLootFrame: Default UI loot frame")
LootFrame.page = 1;
if show then
if isWOTLK then
LootFrame_Show(LootFrame)
elseif isTBC then
ShowUIPanel(LootFrame)
end
self.isHidden = false
else
-- HideUIPanel(LootFrame)
self.isHidden = true
end
else
-- print("ShowLootFrame: No valid loot frames")
self.isHidden = true
end
-- print("ShowLootFrame: Done")
end
----------------------------------------------------------------------------------------------------
-- Function to automate looting items, before looting it checks for if item is being master looted.
----------------------------------------------------------------------------------------------------
function AutoLoot:LootItems(numItems)
local lootThreshold = (self.isClassic and select(2,GetLootMethod()) == 0) and GetLootThreshold() or 10
for i = numItems, 1, -1 do
local itemLink = GetLootSlotLink(i)
local _, _, lootQuantity, rarity, locked = GetLootSlotInfo(i)
-- print("itemLink: ", itemLink, "quantity: ", lootQuantity, "quality: ", rarity, "locked: ", locked)
if locked or (rarity and rarity >= lootThreshold) then
-- print("item is locked")
self.isItemLocked = true
else
--===== FIX ME =====--
--===== not sure why there is slotType ~= LOOT_SLOT_ITEM, its not defined =====--
if slotType ~= LOOT_SLOT_ITEM or self:ProcessLoot(itemLink, lootQuantity) then
-- print("It's working!")
numItems = numItems - 1
LootSlot(i)
end
end
end
if numItems > 0 then
self:ShowLootFrame(true)
end
end
--------------------------------------------------------------------------------
-- Function to filter error messages
--------------------------------------------------------------------------------
-- if aura_env.config["error_filter"] then
local AutoLootErrScript = UIErrorsFrame:GetScript('OnEvent')
-- Error message events
UIErrorsFrame:SetScript('OnEvent', function (self, event, AutoLootError, ...)
-- Handle error messages
if event == "UI_ERROR_MESSAGE" then
-- if aura_env.config["error_filter"] then
if AutoLootError == ERR_LOOT_GONE or
AutoLootError == ERR_LOOT_DIDNT_KILL or
AutoLootError == ERR_NO_LOOT then
return -- hide the error message
end
-- else
-- return -- hide the error message
-- end
end
return AutoLootErrScript(self, event, AutoLootError, ...)
end)
-- end
-------------------------------------------------------------------------------------
-- Function to handle all events related to looting.
-- Such as opening/closing loot windows and checking for inventory space.
--------------------------------------------------------------------------------
function AutoLoot:OnEvent(e, ...)
--===== Loot functions are called here =====--
if (e == "LOOT_READY" or e == "LOOT_OPENED") and not self.isLooting then
local numItems = GetNumLootItems()
--===== if nothing to loot, stop script =====--
if numItems == 0 then
return
end
self.isLooting = true
self.isHidden = true
--===== Checks for if modifier is held and stops looting if given errors are fired, to avoid looping when it's not needed =====--
if not IsModifiedClick("AUTOLOOTTOGGLE") and not tContains(({ERR_INV_FULL, ERR_ITEM_MAX_COUNT, ERR_LOOT_ROLL_PENDING}), select(1, ...)) then
self:LootItems(numItems)
-- print("loot")
else
self:ShowLootFrame(true)
-- print("show")
end
elseif e == "LOOT_CLOSED" then
self.isLooting = false
self.isHidden = false
self.isItemLocked = false
self:ShowLootFrame(false)
invFullSoundPlayed = false
--===== If inventory is full or you have too many of items, show loot frame and play sound. =====--
elseif tContains(({ERR_INV_FULL, ERR_ITEM_MAX_COUNT}), select(1, ...)) then
if not invFullSoundPlayed and self.isLooting then
AutoLoot:OnInvFull()
invFullSoundPlayed = true
end
--===== If item being rolled for (Group Loot), show loot frame. =====--
elseif tContains(({ERR_LOOT_ROLL_PENDING}), select(1, ...)) then
if self.isLooting then
self:ShowLootFrame(true)
-- print("pickup")
end
elseif e == "LOOT_BIND_CONFIRM" then
if self.isLooting and self.isHidden then
AutoLoot:OnBindConfirm()
end
elseif e == "OPEN_MASTER_LOOT_LIST" then
if self.isLooting and self.isHidden then
self:ShowLootFrame(true);
-- print("master loot")
end
-- elseif e == "PLAYER_LOGIN" or e == "ADDON_LOADED" and aura_env.config["autoLootGlobalEnabled"] then
elseif e == "PLAYER_LOGIN" or e == "ADDON_LOADED" then
if isTBC then
SetCVar("autoLootCorpse",1)
elseif isWOTLK then
SetCVar("autoLootDefault",1)
end
--===== Disable Auto Loot button in Interface menu and add tooltip to it. =====--
-- if aura_env.config["autoLootGlobalEnabled"] then
InterfaceOptionsControlsPanelAutoLootCorpse:Disable()
local autoLootText = InterfaceOptionsControlsPanelAutoLootCorpseText
autoLootText:SetText("Auto Loot option is controlled by Leatrix Plus.")
autoLootText:SetAlpha(0.6)
-- print("Auto Loot Set")
-- else
-- InterfaceOptionsControlsPanelAutoLootCorpse:Enable()
-- end
end
end
--------------------------------------------------------------------------------
-- Inventory Full Function
--------------------------------------------------------------------------------
function AutoLoot:OnInvFull()
-- local soundIndex = aura_env.config["full_inventory_sound"]
local soundIndex = 1
if soundIndex == 1 then
local soundPath = soundFiles[soundIndex]
PlaySoundFile(soundPath, "Sound")
-- elseif (soundIndex == 2 or soundIndex == 3) and (not aura_env.lastPlayTime or (GetTime() - aura_env.lastPlayTime) >= 1.5) then
-- aura_env.lastPlayTime = GetTime()
-- local soundPath = soundFiles[soundIndex]
-- PlaySoundFile(soundPath, "Sound")
end
self:ShowLootFrame(true)
-- print("inv full")
end
--------------------------------------------------------------------------------
-- Bind confirm Function
--------------------------------------------------------------------------------
function AutoLoot:OnBindConfirm(slot)
if self.isLooting then
self:ShowLootFrame(true);
-- print("bind confirm")
end
end
--------------------------------------------------------------------------------
-- Function to make sure the Looting Window is positioned well, when shown.
--------------------------------------------------------------------------------
function AutoLoot:LootUnderMouse(frame, parent, yoffset)
if ( GetCVar("lootUnderMouse") == "1" ) then
local x, y = GetCursorPosition()
x = x / frame:GetEffectiveScale()
y = y / frame:GetEffectiveScale()
frame:ClearAllPoints()
frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x - 40, y + (yoffset or 20))
frame:GetCenter()
frame:Raise()
-- print("Loot under mouse enabled. Positioning frame under cursor.")
else
frame:ClearAllPoints()
frame:SetPoint("TOPLEFT", parent, "TOPLEFT")
-- print("Loot under mouse disabled. Positioning frame at top-left of parent.")
end
end
-- Event frame
local faster = CreateFrame("Frame")
faster:RegisterEvent("LOOT_OPENED")
faster:SetScript("OnEvent", FastLoot)
--------------------------------------------------------------------------------
-- Function to setup events.
--------------------------------------------------------------------------------
function AutoLoot:OnLoad()
-- if (aura_env.config["errorFaster"] or aura_env.config["error_tiny"]) then
--===== Function to make error frame fade out animation faster. =====--
-- if aura_env.config["errorFaster"] then
UIErrorsFrame:SetTimeVisible(1)
-- end
--===== Function to make error frame contain only 1 line =====--
--===== It also checks if frame is not already 1 line, to make sure error frame doesnt get hidden fully. =====--
local errorFrameHeight = 20
-- if aura_env.config["error_tiny"] then
if UIErrorsFrame:GetHeight() ~= errorFrameHeight then
UIErrorsFrame:SetHeight(errorFrameHeight)
end
-- end
-- end
self:SetToplevel(true)
self:Hide()
--===== Function sets the OnEvent script for the AutoLoot frame to call the self:OnEvent(...) function. =====--
--===== Whenever an event is detected by the addon. =====--
self:SetScript("OnEvent", function(_,...)
self:OnEvent(...)
end)
for _,e in next, ({ "ADDON_LOADED", "PLAYER_LOGIN", "LOOT_READY", "LOOT_OPENED", "LOOT_CLOSED", "UI_ERROR_MESSAGE", "CVAR_UPDATE", "LOOT_BIND_CONFIRM", "OPEN_MASTER_LOOT_LIST"}) do
self:RegisterEvent(e)
end
-- I did not change this for 2.4.3 and 3.3.5, it's working, so i let it be "Classic" :D
self.isClassic = (WOW_PROJECT_ID == WOW_PROJECT_CLASSIC)
if self.isClassic then
-- print("classic")
self:RegisterEvent("LOOT_BIND_CONFIRM")
self:RegisterEvent("OPEN_MASTER_LOOT_LIST")
end
LootFrame:UnregisterEvent('LOOT_OPENED')
end
AutoLoot:OnLoad()
end