diff --git a/FreshShit/AutoLoot/AutoLootDisplay/Event.lua b/FreshShit/AutoLoot/AutoLootDisplay/Event.lua new file mode 100644 index 0000000..e35b380 --- /dev/null +++ b/FreshShit/AutoLoot/AutoLootDisplay/Event.lua @@ -0,0 +1,7 @@ +-- CHAT_MSG_LOOT +function(allstates, e, msg) + if msg:match("You receive loot") then + DrawIcon(msg, allstates) + return true + end +end diff --git a/FreshShit/AutoLoot/AutoLootDisplay/Init.lua b/FreshShit/AutoLoot/AutoLootDisplay/Init.lua new file mode 100644 index 0000000..956c559 --- /dev/null +++ b/FreshShit/AutoLoot/AutoLootDisplay/Init.lua @@ -0,0 +1,48 @@ +local iconDisplayDuration = 3 + +---@alias CItemInfo {name: string, icon: number, quantity: number, color: string} + +---@param msg string +---@return CItemInfo, string | nil +GetItemInfo = function(msg) + local itemInfo = {name = "", icon = 134400, quantity = 0, color = ""} + local name = msg:match("h%[(.+)%]") + if not name then return itemInfo, "No item name found" end + local quantity = msg:match("x(%d+)") or 1 + itemInfo.name = name + itemInfo.quantity = quantity + + if WeakAurasSaved.Cyka.ItemCache[name] then + itemInfo.icon = WeakAurasSaved.Cyka.ItemCache[name].icon + end + local color = msg:match("cff(%w%w%w%w%w%w)") or "ffffff" + itemInfo.color = color + + return itemInfo, nil +end + +---@param msg string +---@param allstates allstates +DrawIcon = function(msg, allstates) + local info, err = GetItemInfo(msg) + if err then + print(err) + return + end + + local formattedName = "\124cff" .. info.color .. "[" .. info.name .. "]\124r x" .. info.quantity + allstates[#aura_env.allstates + 1] = { + show = true, + changed = true, + index = GetTime(), + resort = true, + + icon = info.icon, + name = formattedName, + + progressType = "timed", + expirationTime = GetTime() + iconDisplayDuration, + duration = iconDisplayDuration, + autoHide = true, + } +end \ No newline at end of file diff --git a/FreshShit/AutoLoot/Event.lua b/FreshShit/AutoLoot/Event.lua new file mode 100644 index 0000000..5cb25a8 --- /dev/null +++ b/FreshShit/AutoLoot/Event.lua @@ -0,0 +1,6 @@ +-- LOOT_READY +function(e) + C_Timer.After(0.1, function() + WeakAuras.ScanEvents("DO_AUTOLOOT") + end) +end diff --git a/FreshShit/AutoLoot/Event2.lua b/FreshShit/AutoLoot/Event2.lua new file mode 100644 index 0000000..e4ffcb4 --- /dev/null +++ b/FreshShit/AutoLoot/Event2.lua @@ -0,0 +1,6 @@ +-- DO_AUTOLOOT +function(e) + local lootInfo = GetLootInfo() + aura_env.FilterService.Run(lootInfo) + CloseLoot() +end diff --git a/FreshShit/AutoLoot/Init.lua b/FreshShit/AutoLoot/Init.lua new file mode 100644 index 0000000..c4958d9 --- /dev/null +++ b/FreshShit/AutoLoot/Init.lua @@ -0,0 +1,852 @@ +local debug = false +if not WeakAurasSaved then WeakAurasSaved = {} end +if not WeakAurasSaved.Cyka then WeakAurasSaved.Cyka = {} end +if not WeakAurasSaved.Cyka.ItemCache then WeakAurasSaved.Cyka.ItemCache = {} end + +---@param slot number +---@return string, string|nil +local function getItemLink(slot) + if slot == nil then return "", string.format("Slot can not be nil") end + local link = GetLootSlotLink(slot) + if link == nil then return "", string.format("GetLootSlotLink returned nil for slot %d", slot) end + return link, nil +end +---@param slot number +---@return string, string|nil +local function getItemName(slot) + if slot == nil then return "", string.format("Slot can not be null") end + local name = select(2, GetLootSlotInfo(slot)) + if name == nil then return "", string.format("GetLootSlotInfo returned nil for slot %d", slot) end + return name, nil +end +---@param slot number +---@return string, string|nil +local function getItemType(slot) + if slot == nil then return "", string.format("Slot can not be nil") end + local itemLink, err = getItemLink(slot) + if err then return "", err end + local itemType = select(6, GetItemInfo(itemLink)) + if itemType == nil then return "", string.format("GetItemInfo returned nil for slot %d", slot) end + return itemType, nil +end +---@param slot number +---@return string, string|nil +local function getItemSubtype(slot) + if slot == nil then return "", string.format("Slot can not be nil") end + local itemLink, err = getItemLink(slot) + if err then return "", err end + local itemSubtype = select(7, GetItemInfo(itemLink)) + if itemSubtype == nil then return "", string.format("GetItemInfo returned nil for slot %d", slot) end + return itemSubtype, nil +end +---@param slot number +---@return number, string|nil +local function getItemLevel(slot) + if slot == nil then return 0, string.format("Slot can not be nil") end + local itemLink, err = getItemLink(slot) + if err then return 0, err end + local itemLevel = select(4, GetItemInfo(itemLink)) + if itemLevel == nil then return 0, string.format("GetItemInfo returned nil for slot %d", slot) end + return itemLevel, nil +end + +---The vendor price in copper, or 0 for items that cannot be sold +---@param slot number +---@return number, string|nil +local function getItemValue(slot) + if slot == nil then return 0, string.format("Slot can not be nil") end + local itemLink, err = getItemLink(slot) + if err then return 0, err end + local value = select(11, GetItemInfo(itemLink)) + if value == nil then return 0, string.format("GetItemInfo returned nil for slot %d", slot) end + return value, nil +end +---@param slot number +---@return number, string|nil +local function getItemSubclassId(slot) + if slot == nil then return 0, string.format("Slot can not be nil") end + local itemLink, err = getItemLink(slot) + if err then return 0, err end + local subclassId = select(13, GetItemInfo(itemLink)) + if subclassId == nil then return 0, string.format("GetItemInfo returned nil for slot %d", slot) end + return subclassId, nil +end +---@param slot number +---@return number, string|nil +local function getItemQuantity(slot) + if slot == nil then return 0, string.format("Slot can not be nil") end + local quantity = select(3, GetLootSlotInfo(slot)) + if quantity == nil then return 0, string.format("GetLootSlotInfo returned nil for slot %d", slot) end + return quantity, nil +end +---@param slot number +---@return Enum.ItemQuality, string|nil +local function getItemQuality(slot) + if slot == nil then return 0, string.format("Slot can not be nil") end + local itemLink, err = getItemLink(slot) + if err then return 0, err end + local quality = select(3, GetItemInfo(itemLink)) + if quality == nil then return 0, string.format("GetItemInfo returned nil for slot %d", slot) end + return quality, nil +end +---@param slot number +---@return string, string|nil +local function getItemEquipLocation(slot) + if slot == nil then return "", string.format("Slot can not be nil") end + local itemLink, err = getItemLink(slot) + if err then return "", err end + local equipLoc = select(9, GetItemInfo(itemLink)) + if equipLoc == nil then return "", string.format("GetItemInfo returned nil for slot %d", slot) end + return equipLoc, nil +end +---@param slot number +---@return number, string|nil +local function getItemIcon(slot) + if slot == nil then return 134400, string.format("Slot can not be nil") end + local itemLink, err = getItemLink(slot) + if err then return 134400, err end + local icon = select(10, GetItemInfo(itemLink)) + if icon == nil then return 134400, string.format("GetItemInfo returned nil for slot %d", slot) end + return icon, nil +end +---@param slot number +---@return number, string|nil +local function getBindType(slot) + if slot == nil then return 0, string.format("Slot can not be nil") end + local itemLink, err = getItemLink(slot) + if err then return 0, err end + local bindType = select(14, GetItemInfo(itemLink)) + if bindType == nil then return 0, string.format("GetItemInfo returned nil for slot %d", slot) end + return bindType, nil +end + +---@class Filter +---@field requires table | nil +---@field filter fun(slot: number, provided: table): boolean +Filter = { + ---@param requires table | nil + ---@param filter fun(slot: number, provided: table): boolean + ---@return Filter + new = function(requires, filter) + local self = setmetatable({}, { + __index = Filter + }) + self.requires = requires + self.filter = filter + return self + end, + + ---@param self Filter + ---@param slot number + ---@return boolean, string|nil + Run = function(self, slot) + ---@type table + local provided = {} + if self.requires then + for k, v in pairs(self.requires) do + local res, err = v(slot) + if err ~= nil then + if debug then print(err) end + return false, err + end + provided[k] = res + end + end + local res, err = self.filter(slot, provided) + if err ~= nil then + if debug then print(err) end + end + return res, nil + end +} + +local goldFilter = Filter.new({ ["name"] = getItemName }, + function(slot, provided) + ---@cast provided { name: string } + if string.find(provided.name, "Gold") or + string.find(provided.name, "Silver") or + string.find(provided.name, "Copper") then + if debug then print(string.format("Gold filter pass for %s", provided.name)) end + return true + end + if debug then print(string.format("Gold filter fail for %s", provided.name)) end + return false + end) +local orderResourcesFilter = Filter.new({ ["name"] = getItemName }, + function(slot, provided) + ---@cast provided { name: string } + if string.find(provided.name, "Order Resources") then + if debug then print(string.format("Order resource filter pass for %s", provided.name)) end + return true + end + if debug then print(string.format("Order resource filter fail for %s", provided.name)) end + return false + end) +local mountFilter = Filter.new({ ["type"] = getItemType }, + function(slot, provided) + ---@cast provided { type: string } + if provided.type == "Mount" then + if debug then print(string.format("Mount filter pass for type %s", provided.type)) end + return true + end + if debug then print(string.format("Mount filter fail for type %s", provided.type)) end + return false + end) +local ilvlFilter = Filter.new({ ["ilvl"] = getItemLevel }, + function(slot, provided) + ---@cast provided { ilvl: number } + if provided.ilvl and provided.ilvl > 800 then + if debug then print(string.format("ilvl filter pass for ilvl %d", provided.ilvl)) end + return true + end + if debug then print(string.format("ilvl filter fail for ilvl %d", provided.ilvl)) end + return false + end) +local professionFilter = Filter.new({ + ["type"] = getItemType, + ["subtype"] = getItemSubtype + }, + function(slot, provided) + ---@cast provided { type: string, subtype: string } + + local enabled = { + ["Herb"] = true, + ["Leather"] = true, + ["Cloth"] = true, + ["Ore"] = false, + ["Cooking"] = true, + ["Inscription"] = true, + ["Enchanting"] = true, + } + + -- Maybe implement an expansion based filter + if provided.type == "Tradeskill" then + if enabled[provided.subtype] then + if debug then print(string.format("Profession filter pass for type %s", provided.type)) end + return true + end + end + if debug then print(string.format("Profession filter fail for type %s", provided.type)) end + return false + end) +local valueFilter = Filter.new({ + ["value"] = getItemValue, + ["quantity"] = getItemQuality + }, + function(slot, provided) + ---@cast provided { value: number, quantity: number } + + local valueThreshold = 35 * 100 * 100 + local applyValueTostack = false + + local value = provided.value + if applyValueTostack then value = value * provided.quantity end + + if value > valueThreshold then + if debug then print(string.format("Value filter pass for value %d", value)) end + return true + end + if debug then print(string.format("Value filter fail for value %d", value)) end + return false + end) +local greyValueFilter = Filter.new({ + ["quality"] = getItemQuality, + ["value"] = getItemValue, + ["quantity"] = getItemQuantity + }, + function(slot, provided) + ---@cast provided { quality: number, value: number, quantity: number } + + local valueThreshold = 4 * 100 * 100 + local applyValueTostack = false + + if provided.quality == 0 then + local value = provided.value + if applyValueTostack then value = value * provided.quantity end + + if value > valueThreshold then + if debug then + print(string.format("Grey value filter pass for value %d of %s quality items", value, + provided.quality)) + end + return true + end + end + if debug then + print(string.format("Grey value filter fail for value %d of %s quality items", provided.value, + provided.quality)) + end + return false + end) +local questItemFilter = Filter.new({ + ["type"] = getItemType, + ["subtype"] = getItemSubtype + }, + function(slot, provided) + ---@cast provided { type: string, subtype: string } + if provided.type == "Quest" and provided.subtype == "Quest" then + if debug then + print(string.format("Quest item filter pass for type %s and subtype", provided.type, + provided.subtype)) + end + return true + end + if debug then + print(string.format("Quest item filter fail for type %s and subtype", provided.type, + provided.subtype)) + end + return false + end) +local classGearFilter = Filter.new({ + ["ilvl"] = getItemLevel, + ["quality"] = getItemQuality, + ["type"] = getItemType, + ["subtype"] = getItemSubtype, + ["equiploc"] = getItemEquipLocation + }, + function(slot, provided) + ---@cast provided { ilvl: number, quality: number, type: string, subtype: string, equiploc: string } + + local ilvlThreshold = 800 + local qualityThreshold = 2 + + local isEquippable = aura_env.skills[select(3, UnitClass("player"))][provided.subtype] == 1 + + if isEquippable and provided.ilvl > ilvlThreshold and provided.quality > qualityThreshold then + if debug then + print(string.format("Class gear filter pass for ilvl %d and quality %d", provided.ilvl, + provided.quality)) + end + return true + end + if debug then + print(string.format("Class gear filter fail for ilvl %d and quality %d", provided.ilvl, + provided.quality)) + end + return false + end) +local arguniteFilter = Filter.new({ ["name"] = getItemName }, + function(slot, provided) + ---@cast provided { name: string } + if provided.name == "Veiled Argunite" then + if debug then + print(string.format("Argunite filter pass for %s", provided.name)) + end + return true + end + if debug then print(string.format("Argunite filter fail for %s", provided.name)) end + return false + end) +local ancientManaFilter = Filter.new({ ["name"] = getItemName }, + function(slot, provided) + ---@cast provided { name: string } + if string.find(provided.name, "Ancient Mana") then + if debug then print(string.format("Ancient Mana filter pass for %s", provided.name)) end + return true + end + if debug then print(string.format("Ancient Mana filter fail for %s", provided.name)) end + return false + end) +local reicpeFilter = Filter.new({ ["name"] = getItemName }, + function(slot, provided) + ---@cast provided { name: string } + if string.find(provided.name, "Recipe") or string.find(provided.name, "Technique") then + if debug then print(string.format("Recipe filter pass for %s", provided.name)) end + return true + end + if debug then print(string.format("Recipe filter fail for %s", provided.name)) end + return false + end) +local bloodOfSargerasFilter = Filter.new({ ["name"] = getItemName }, + function(slot, provided) + ---@cast provided { name: string } + if provided.name == "Blood of Sargeras" then + if debug then print(string.format("Blood of Sargeras filter pass for %s", provided.name)) end + return true + end + if debug then print(string.format("Blood of Sargeras filter fail for %s", provided.name)) end + return false + end) +local bloodhunerQuarryFilter = Filter.new({ ["name"] = getItemName }, + function(slot, provided) + ---@cast provided { name: string } + if provided.name == "Bloodhunter's Quarry" then + if debug then print(string.format("Bloodhunter's Quarry filter pass for %s", provided.name)) end + return true + end + if debug then print(string.format("Bloodhunter's Quarry filter fail for %s", provided.name)) end + return false + end) +local arguniteClusterFilter = Filter.new({ ["name"] = getItemName }, + function(slot, provided) + ---@cast provided { name: string } + if provided.name == "Argunite Cluster" then + if debug then print(string.format("Argunite Cluster filter pass for %s", provided.name)) end + return true + end + if debug then print(string.format("Argunite Cluster filter fail for %s", provided.name)) end + return false + end) +local boeFilter = Filter.new({ + ["ilvl"] = getItemLevel, + ["type"] = getItemType, + ["quality"] = getItemQuality, + ["equiploc"] = getItemEquipLocation, + ["bindtype"] = getBindType + }, + function(slot, provided) + ---@cast provided { ilvl: number, type: string, quality: number, equiploc: string, bindtype: number } + + local ilvlThreshold = 800 + local qualityThreshold = 1 + + local itemType = provided.type + local itemEquipLoc = provided.equiploc + if (itemType == "Armor" + or itemType == "Weapon" + or itemEquipLoc == "INVTYPE_FINGER" + or itemEquipLoc == "INVTYPE_TRINKET" + or itemEquipLoc == "INVTYPE_CLOAK" + or itemEquipLoc == "INVTYPE_NECK") then + local itemLevel = provided.ilvl + local itemQuality = provided.quality + local bindType = provided.bindtype + + if itemLevel > ilvlThreshold and itemQuality > qualityThreshold and bindType == 1 then + if debug then print(string.format("BoE filter pass for ilvl %d and quality %d", itemLevel, itemQuality)) end + return true + end + end + if debug then print(string.format("BoE filter fail for ilvl %d and quality %d", provided.ilvl, provided.quality)) end + return false + end) +local artifactPowerFilter = Filter.new({ + ["type"] = getItemType, + ["subtype"] = getItemSubtype, + ["subclassid"] = getItemSubclassId, + ["value"] = getItemValue +}, function(slot, provided) + ---@cast provided { type: string, subtype: string, subclassid: number, value: number } + if provided.value == 0 and provided.type == "Consumable" and provided.subtype == "Other" and provided.subclassid == 8 then + if debug then + print(string.format("Artifact power filter pass for type %s and subtype %s and subclassid %d with value %d", + provided.type, provided.subtype, provided.subclassid, provided.value)) + end + return true + end + if debug then + DevTools_Dump(provided) + print(string.format("Artifact power filter fail for type %s and subtype %s and subclassid %d with value %d", + provided.type, provided.subtype, provided.subclassid, provided.value)) + end + return false +end) + +-- local azeriteFilter = { +-- enabled = true, +-- ilvlThreshold = 800, +-- qualityThreshold = 2, +-- filter = function(self, slot) +-- if self.enabled the +-- local itemType = getItemType(slot) +-- local itemSubtype = getItemSubtype(slot) +-- local itemQuality = getItemQuality(slot) +-- if itemType and itemSubtype and itemQuality and itemType == "Consumable" and itemSubtype == "Other" and itemQuality > 1 the +-- return true +-- en +-- tostring(itemType) .. " " .. tostring(itemSubtype) .. " " .. tostring(itemQuality)) +-- end +-- end +-- } + + +---@type table +local filters = { + ancientManaFilter, + arguniteFilter, + artifactPowerFilter, + bloodhunerQuarryFilter, + bloodOfSargerasFilter, + boeFilter, + classGearFilter, + goldFilter, + greyValueFilter, + ilvlFilter, + mountFilter, + orderResourcesFilter, + professionFilter, + questItemFilter, + -- reicpeFilter, + valueFilter, + arguniteClusterFilter, +} + +---@class FilterService +aura_env.FilterService = { + ---@param lootInfo table + Run = function(lootInfo) + ---@type table + local slotsToLoot = {} + for slot, item in pairs(lootInfo) do + if debug then + local itemname = getItemName(slot) + print(string.format("Checking slot %d for %s", slot, itemname)) + end + for _, filter in pairs(filters) do + local res, err = filter:Run(slot) + if err then + if debug then print(err) end + end + if res then + slotsToLoot[#slotsToLoot + 1] = slot + break + end + end + end + + aura_env.FilterService.doLoot(slotsToLoot) + end, + + ---@param slots table + ---@return nil + doLoot = function(slots) + for i = #slots, 1, -1 do + aura_env.FilterService.lootslot(slots[i]) + end + end, + + ---@param slot number + ---@return nil + lootslot = function(slot) + LootSlot(slot) + + local itemIcon = getItemIcon(slot) or 134400 + local itemName = getItemName(slot) or "Unknown" + itemName = itemName:gsub("\n", ", ") + local itemQuality = getItemQuality(slot) or 0 + + if string.find(itemName, "Gold") == nil + and string.find(itemName, "Silver") == nil + and string.find(itemName, "Copper") == nil then + if not WeakAurasSaved.Cyka.ItemCache[itemName] then + WeakAurasSaved.Cyka.ItemCache[itemName] = { + icon = itemIcon, + quality = itemQuality, + } + end + end + end +} + +aura_env.skills = { + --Warrior + [1] = { + --Armor Skills + ["Cloth"] = 0, + ["Leather"] = 0, + ["Mail"] = 0, + ["Plate"] = 1, + ["Shields"] = 1, + --Weapon Skills + ["One-Handed Axes"] = 1, + ["Two-Handed Axes"] = 1, + ["Bows"] = 1, + ["Guns"] = 1, + ["One-Handed Maces"] = 1, + ["Two-Handed Maces"] = 1, + ["Polearms"] = 1, + ["One-Handed Swords"] = 1, + ["Two-Handed Swords"] = 1, + ["Warglaives"] = 1, + ["Staves"] = 1, + ["Fist Weapons"] = 1, + ["Daggers"] = 1, + ["Crossbows"] = 1, + ["Wands"] = 0, + }, + --Paladin + [2] = { + --Armor Skills + ["Cloth"] = 0, + ["Leather"] = 0, + ["Mail"] = 0, + ["Plate"] = 1, + ["Shields"] = 1, + --Weapon Skills + ["One-Handed Axes"] = 1, + ["Two-Handed Axes"] = 1, + ["Bows"] = 0, + ["Guns"] = 0, + ["One-Handed Maces"] = 1, + ["Two-Handed Maces"] = 1, + ["Polearms"] = 1, + ["One-Handed Swords"] = 1, + ["Two-Handed Swords"] = 1, + ["Warglaives"] = 0, + ["Staves"] = 0, + ["Fist Weapons"] = 0, + ["Daggers"] = 0, + ["Crossbows"] = 0, + ["Wands"] = 0, + }, + --Hunter + [3] = { + --Armor Skills + ["Cloth"] = 0, + ["Leather"] = 0, + ["Mail"] = 1, + ["Plate"] = 0, + ["Shields"] = 0, + --Weapon Skills + ["One-Handed Axes"] = 1, + ["Two-Handed Axes"] = 1, + ["Bows"] = 1, + ["Guns"] = 1, + ["One-Handed Maces"] = 0, + ["Two-Handed Maces"] = 0, + ["Polearms"] = 1, + ["One-Handed Swords"] = 1, + ["Two-Handed Swords"] = 1, + ["Warglaives"] = 0, + ["Staves"] = 1, + ["Fist Weapons"] = 1, + ["Daggers"] = 1, + ["Crossbows"] = 1, + ["Wands"] = 0, + }, + --Rogue + [4] = { + --Armor Skills + ["Cloth"] = 0, + ["Leather"] = 1, + ["Mail"] = 0, + ["Plate"] = 0, + ["Shields"] = 0, + --Weapon Skills + ["One-Handed Axes"] = 1, + ["Two-Handed Axes"] = 0, + ["Bows"] = 0, + ["Guns"] = 0, + ["One-Handed Maces"] = 1, + ["Two-Handed Maces"] = 0, + ["Polearms"] = 0, + ["One-Handed Swords"] = 1, + ["Two-Handed Swords"] = 0, + ["Warglaives"] = 0, + ["Staves"] = 0, + ["Fist Weapons"] = 1, + ["Daggers"] = 1, + ["Crossbows"] = 0, + ["Wands"] = 0, + }, + --Priest + [5] = { + --Armor Skills + ["Cloth"] = 1, + ["Leather"] = 0, + ["Mail"] = 0, + ["Plate"] = 0, + ["Shields"] = 0, + --Weapon Skills + ["One-Handed Axes"] = 0, + ["Two-Handed Axes"] = 0, + ["Bows"] = 0, + ["Guns"] = 0, + ["One-Handed Maces"] = 1, + ["Two-Handed Maces"] = 0, + ["Polearms"] = 0, + ["One-Handed Swords"] = 0, + ["Two-Handed Swords"] = 0, + ["Warglaives"] = 0, + ["Staves"] = 1, + ["Fist Weapons"] = 0, + ["Daggers"] = 1, + ["Crossbows"] = 0, + ["Wands"] = 1, + }, + --Death Knight + [6] = { + --Armor Skills + ["Cloth"] = 0, + ["Leather"] = 0, + ["Mail"] = 0, + ["Plate"] = 1, + ["Shields"] = 0, + --Weapon Skills + ["One-Handed Axes"] = 1, + ["Two-Handed Axes"] = 1, + ["Bows"] = 0, + ["Guns"] = 0, + ["One-Handed Maces"] = 1, + ["Two-Handed Maces"] = 1, + ["Polearms"] = 1, + ["One-Handed Swords"] = 1, + ["Two-Handed Swords"] = 1, + ["Warglaives"] = 0, + ["Staves"] = 0, + ["Fist Weapons"] = 0, + ["Daggers"] = 0, + ["Crossbows"] = 0, + ["Wands"] = 0, + }, + --Shaman + [7] = { + --Armor Skills + ["Cloth"] = 0, + ["Leather"] = 0, + ["Mail"] = 1, + ["Plate"] = 0, + ["Shields"] = 1, + --Weapon Skills + ["One-Handed Axes"] = 1, + ["Two-Handed Axes"] = 0, + ["Bows"] = 0, + ["Guns"] = 0, + ["One-Handed Maces"] = 1, + ["Two-Handed Maces"] = 0, + ["Polearms"] = 0, + ["One-Handed Swords"] = 0, + ["Two-Handed Swords"] = 0, + ["Warglaives"] = 0, + ["Staves"] = 1, + ["Fist Weapons"] = 1, + ["Daggers"] = 1, + ["Crossbows"] = 0, + ["Wands"] = 0, + }, + --Mage + [8] = { + --Armor Skills + ["Cloth"] = 1, + ["Leather"] = 0, + ["Mail"] = 0, + ["Plate"] = 0, + ["Shields"] = 0, + --Weapon Skills + ["One-Handed Axes"] = 0, + ["Two-Handed Axes"] = 0, + ["Bows"] = 0, + ["Guns"] = 0, + ["One-Handed Maces"] = 0, + ["Two-Handed Maces"] = 0, + ["Polearms"] = 0, + ["One-Handed Swords"] = 1, + ["Two-Handed Swords"] = 0, + ["Warglaives"] = 0, + ["Staves"] = 1, + ["Fist Weapons"] = 0, + ["Daggers"] = 1, + ["Crossbows"] = 0, + ["Wands"] = 1, + }, + --Warlock + [9] = { + --Armor Skills + ["Cloth"] = 1, + ["Leather"] = 0, + ["Mail"] = 0, + ["Plate"] = 0, + ["Shields"] = 0, + --Weapon Skills + ["One-Handed Axes"] = 0, + ["Two-Handed Axes"] = 0, + ["Bows"] = 0, + ["Guns"] = 0, + ["One-Handed Maces"] = 0, + ["Two-Handed Maces"] = 0, + ["Polearms"] = 0, + ["One-Handed Swords"] = 1, + ["Two-Handed Swords"] = 0, + ["Warglaives"] = 0, + ["Staves"] = 1, + ["Fist Weapons"] = 0, + ["Daggers"] = 1, + ["Crossbows"] = 0, + ["Wands"] = 1, + }, + --Monk + [10] = { + --Armor Skills + ["Cloth"] = 0, + ["Leather"] = 1, + ["Mail"] = 0, + ["Plate"] = 1, + ["Shields"] = 1, + --Weapon Skills + ["One-Handed Axes"] = 1, + ["Two-Handed Axes"] = 0, + ["Bows"] = 0, + ["Guns"] = 0, + ["One-Handed Maces"] = 1, + ["Two-Handed Maces"] = 0, + ["Polearms"] = 1, + ["One-Handed Swords"] = 1, + ["Two-Handed Swords"] = 0, + ["Warglaives"] = 0, + ["Staves"] = 1, + ["Fist Weapons"] = 1, + ["Daggers"] = 0, + ["Crossbows"] = 0, + ["Wands"] = 0, + }, + --Druid + [11] = { + --Armor Skills + ["Cloth"] = 0, + ["Leather"] = 1, + ["Mail"] = 0, + ["Plate"] = 0, + ["Shields"] = 0, + --Weapon Skills + ["One-Handed Axes"] = 0, + ["Two-Handed Axes"] = 0, + ["Bows"] = 0, + ["Guns"] = 0, + ["One-Handed Maces"] = 1, + ["Two-Handed Maces"] = 0, + ["Polearms"] = 1, + ["One-Handed Swords"] = 0, + ["Two-Handed Swords"] = 0, + ["Warglaives"] = 0, + ["Staves"] = 1, + ["Fist Weapons"] = 1, + ["Daggers"] = 1, + ["Crossbows"] = 0, + ["Wands"] = 0, + }, + --Demon Hunter + [12] = { + --Armor Skills + ["Cloth"] = 0, + ["Leather"] = 1, + ["Mail"] = 0, + ["Plate"] = 0, + ["Shields"] = 0, + --Weapon Skills + ["One-Handed Axes"] = 1, + ["Two-Handed Axes"] = 0, + ["Bows"] = 0, + ["Guns"] = 0, + ["One-Handed Maces"] = 0, + ["Two-Handed Maces"] = 0, + ["Polearms"] = 0, + ["One-Handed Swords"] = 1, + ["Two-Handed Swords"] = 0, + ["Warglaives"] = 1, + ["Staves"] = 0, + ["Fist Weapons"] = 1, + ["Daggers"] = 0, + ["Crossbows"] = 0, + ["Wands"] = 0, + }, +} +aura_env.qualityColors = { + "\124cff9d9d9d", -- Poor + "\124cffffffff", -- Common + "\124cff1eff00", -- Uncommon + "\124cff0070dd", -- Rare + "\124cffa335ee", -- Epic + "\124cffff8000", -- Legendary + "\124cffe6cc80", -- Artifact + "\124cff00ccff", -- Heirloom +} diff --git a/FreshShit/AutoVendor/Event.lua b/FreshShit/AutoVendor/Event.lua new file mode 100644 index 0000000..35fc738 --- /dev/null +++ b/FreshShit/AutoVendor/Event.lua @@ -0,0 +1,15 @@ +-- MERCHANT_SHOW +function(allstates, e) + if (GetMerchantNumItems() > 0) then + aura_env.allstates = allstates + + if CanMerchantRepair() == true then RepairAllItems() end + + for container = 0, 4 do + for slot = 1, GetContainerNumSlots(container) do + aura_env.FilterService.Run(container, slot) + end + end + return true + end +end diff --git a/FreshShit/AutoVendor/Export b/FreshShit/AutoVendor/Export new file mode 100644 index 0000000..f39c7ad --- /dev/null +++ b/FreshShit/AutoVendor/Export @@ -0,0 +1 @@ +dif1EaqickXIOkEKcuvxIaLyukYPuOxjjQAwkQBPcSlQKHjvvhJGSmcKNPaAAQqDnQuPTPaLVrLIghbL6CsvPwhbL07iqPMNcuL7rQ6GQsyHQq6HuPQjQkrxubzJkaFuvsJusKojPYkvvVubQmtvPUjbk2jvj)ufIHsLkokbvlLkL8uQQPQIUQuvITsGQVsLsDwQuWBLQsAUeuCxjrL9kXFPk1GrhwOfRG6XQ0KLkxw0MLuFwvmAjHttYQPsHETuvmBb3Mk2Ts)MOHljDCvqwUuEoPmDkxNqBNa(UkOgVcKZlvz9eOKEVKOCFjrSF4IqLZIFSCwSIVwXxqUCxxcjOIVtXVR43vol(d6i11APv86a384(l(9osDTwAfVC3b2FXpEnLa5zt98KnbJSllEDGq9x81QgVzXR(l(Q1Y2gdcE20uYT41al(AzO2DKQ1k(NhXDEp0aol(XG6zl(VhAaNf)ks1tfwzah7U9pWbR)b23csqdCGUPB23cQuFWXdwXpiJDLZIVAFAsXQLZIVJyWuLZIvSIVfd5ALZIVJyWuLZIvSIFNQUwDfdwVYzX3rmyQYzXkwXVfVz5S47igmv5SyfR4xhVMsULZIVJyWuLZIvSIFvbQAXqUw5S47igmv5SyfR43KHSCw8DedMQCwSIv8f1sVVHOMwz4IVfd5AcQCw8DedMQCwSIvSIFCvorllhT43YhLCp7vnl(D92OJ6(0KIvl(5GQg3USRC0IV1uppzRCw81QqE4JSfFTkKh(i7lUMsGSyfFvxXxy5fIMuWZTt2k(Dkn3O4EnLazXpgcf)v05SPEEYMwXlHk(QvzERzXMLDfVeQ4FyvNvrzah7U9pWbRFHCt38yHT7ESqhFCP(GJhSIv8VLZIxcvol(woitObixZxjynlEjO(l(XRPeipBQNNSjyKDzXRdeQ)IF8Ak5Qvol(AwSzLZIFN0BNutl(KLHlwXxTkRCw87KEFf1mPt5Of)ROMjDk(b5nga7YHfFa1dwhdAj(b5ngavx5(sLw1qS3lfBrtjxq9GdeF8dYBmawlUxtjxWN00zPZB12NPRCTOAZ2mOwqAJ4dccc2stSTGAziV2KBod(AAUxUwuTztNLo62A50vUwuTzBguliTXr8ZTd)G8gdG1I71uYf8jnDw6iCX4AkR30vUwuTzBguliTr8bbbbBPj2wqTmKxBsqZGVMM7LRfvB20zPJUTwoDLRfvB2Mb1csBCe)C7WpiVXayT4EnLCbFstNLoEfDYPRCTOAZ2mOwqAJ4dccc2stSTGAziV2KqZGVMMolD0T1YPN00zPZB12NPRCTOAZ2mOwqAJJJ4NBh(b5ngaRf3RPKl4tA6S05Sx1C6kxlQ2SndQfK2i(GGGGT0eBlOwgYRnnyZGVMMolD0T1YPN00zPZB12NPRCTOAZ2mOwqAJJJ4NBh(b5ngaRf3RPKl4tA6S0XxCyRx1C6kxlQ2SndQfK2i(GGGGT0eBlOwgYRn5MZGVMMolD0T1YPN00zPZB12NPRCTOAZ2mOwqAJJJ4NBh(b5ngaRf3RPKl4tA6S05DkqgMUY1IQnBZGAbPnIpiiiylnX2cQLH8Athpd(AA6S0r3wlNEstNLoVvBFMUY1IQnBZGAbPnooIFUD4hK3yaSwCVMsUGpPPZshbpgeZPRCTOAZ2mOwqAJ4dccc2stSTGAziV2Kqcnd(AA6S0r3wlNEstNLoVvBFMUY1IQnBZGAbPnooIFUD4hK3yaSwCVMsUGpPPZshHlgdkR30vUwuTzBguliTr8bbbbBPj2wqTmKxBAGZGVMMolD0T1YPN00zPZB12NPRCTOAZ2mOwqAJJJ4NBh(b5ngaRf3RPKl4tA6S0zOdjQQ(wEJMsUtx5Ar1MTzqTG0gXheeeSLMyBb1YqETP(Eg8100zPJUTwo9KMolDER2(mDLRfvB2Mb1csBCCe)C7WpiVXayT4EnLCbFstNLo6UYD6kxlQ2SndQfK2i(GGGGT0eBlOwgYRnju)ZGVMMolD0T1YPN00zPZB12NPRCTOAZ2mOwqAJJJ4NBh(b5ngaRf3RPKl4tAhvTDN9QMtx5Ar1MTzqTG0gXheeeSLMyBb1YqETjHoEg8100zPJUTwo9KMolDER2(mDLRfvB2Mb1csBCCe)C7WhF8XpiVXa4tl2BaQGLnq9Gvg(GGGG5ghoKDG6bTMyoJpiiiyTkyzdupyT4EnLCN0Yq9m4vUwuTzBguliTr8bbbbbbbbv1GtAzO2vUXHdz3iOvrU4dcccccccccccgfBrVZvaxD5WIpVLptEETf7bwRcw2eSbVY1IQnBG6b9a6Yf4vUwuTzd0LlqpZGAbPbQh0dOlxGAbPnIpiiiiiiiiiiiyqEJbqLLocxmguwpq9GpPPZshHlgdkR30vUwuTzBguliTr8bbbbbbbbbbbbv1GtklDeUymOSEGXTduzPJWfJbL1duVEW(hbTkYfFqqqqqqqqqqqqqqqWOyl6DUc4Qlhw85T8zYZRTypWAvWYgy1OMMNr8bbbbbbbbbbbbbbbbBPj2wqRjM4dcccccccccccMBh(GGGGGGGG52HpiiiyUD4xj4hK3ya8jJTbOcw2a1dwz4dcccMBC4q2bQh0AI5m(GGGGQGaHZkAPwfYqhOEqHT72)m(GGGGAziCuzcQhSog0Yz8bbbbRvblBG6bRf3RPK7KwgQNbVY1IQnBZGAbPnIpiiiiiiiOQgCsld1UYnoCi7gbTkYfFqqqqqqqqqqqWOyl6DUc4Qlhw85T8zYZRzSbwRcw2eSbVY1IQnBG6b9a6Yf4vUwuTzd0LlqpZGAbPbQh0dOlxGAbPnIpiiiiiiiiiiiyqEJbqLLoVtbYaOEWN00zPZ7uGmmDLRfvB2Mb1csBeFqqqqqqqqqqqWG8gdGklDoQA7o7vnb1d(K2rvB3zVQ50vUwuTzBguliTr8bbbbbbbbbbbbdYBmaQS05Sx1eup4tA6S05Sx1C6kxlQ2SndQfK2i(GGGGGGGGGGGGb5ngavw6m0HevvFlVG6bFstNLodDirv13YB0uYD6kxlQ2SndQfK2i(GGGGGGGGGGGGQAWjLLoN9QMGXTduzPZqhsuv9T8cg3o8bbbbbbbbbbbbNuw6C2RAcQxpONx0CKnp4dccccccccccckBGklDo7vnb1Rh0JBNXQY1d(GGGGGGGGGGGGYgOYsNHoKOQ6B5fuVEqp68sWpDdUZqEpaDE96qULh8bbbbbbbbbbbbLnqLLodDirv13YlOE9GE05LGF6gCNH8(0T051GBOtp4dccccccccccckBGklDg6qIQQVLxq96b9OZlb)0n4od5T7FFKxm48GpiiiiiiiiiiiOSbQS0zOdjQQ(wEb1Rh0JoVe8t3G7mK3EnK7hCEgXheeeeeeeeeeemUDGklDENcKbW42bQS05OQT7Sx1emUDGklDENcKbWbpqTmu7sfeiCwrl1Qqg6aJBh4KYsNJQ2UZEvtq96bfcu2a1YqTlTmeoQmhhbTkYfFqqqqqqqqqqqqqqqWQn1AtpPPZshVIo50vUwuTzBguliTXr8bbbbbbbbbbbbbbbbR2uRn9KMolDENcKHPRCTOAZ2mOwqAJJ4dcccccccccccccccgfBrVZvaxD5WIpVLptEEnJnWAvWYgy1OMMNr8bbbbbbbbbbbbbbbbBPj2wqRjM4dcccccccccccMBh(GGGGGGGG52HpiiiyUD4xj4JFqEJbWAX9Ak5c2j9Zqy6kxlQ2SndQfK2i(GGGGb5ngavw6O7kxq9GpPPZshDx5oDLRfvB2Mb1csBeFqqqWG8gdGklD8k6KG6bFstNLoEfDYPRCTOAZ2mOwqAJ4dcccgK3yauzPJWfJRPSEG6bFstNLocxmUMY6nDLRfvB2Mb1csBeFqqqWG8gdGklDeUymOSEG6bFstNLocxmguwVPRCTOAZ2mOwqAJ4JpiiiyuSf9oxbC1Ldl(8w(m55LT4Hv7dO6kxWAzd0dOlxGklD8k6KGUCb6b8WkRcWdjgdkRhOhqxUavw6iCXyqz9gXheeemiVXa4gDs3wzv4Ezq2a1d6PV6b0LlWOyl6DUc46qIXGY65Ezq206RklDeUymOSEGvEqHQCGUCbQS0XROtc6YfONkNWiKGoU5bFqqqWG8gdGB0jDBLvHWfJRPSEG6b3Ot62kRc3ldYgOlxGEahKhqxUavw6iCX4AkRh(4dcccgfBrVZvaxD5WIpVLptEEHMM6zv7d4gDspGUCbUrN0TvwfcxmUMY6nIpiiiyuSf9oxbCfdbnlAPwFDWpk2IENRaUIHGMfTudSYdkuLdupyLHpiiiiiiiOwfYddQh0AI5m(GGGGGGGG3kI7t2bQh0AI5m(GGGGGGGGQTlheOEWxt7u5KtJZ4dccccccc2snzZa1dAnXCgF8bbbbbbbbvx5cQhuzPJURCNXheeeeeeeCJojOEWn6KUTYQq4IX1uwVz8bbbbbbbbJosX1a1dQS0r4IX1uwVz8XheeeeeeeSAt(0snTZEvtq9GEmLt25zgFqqqqqqqWCqvvTOPK7PYjb1d(AANkNCAeSYdQUY9LkTQHyVxk2IMsUZ4dccccccc2j2IMsUG6bvx5(sLw1qS3lfBrtj3z8bbbbbbbbJIMSsvDjOEqRjMZ4dcccwj4JpiiiyFrlDVCTOAZMolDMUY1IQnBZGAbPnIFUD4Jp(rXw07CfWvTkyzZpBcOUjOEWkdFqqqWAvWYMgOEWkdFqqqqqqqWNwS3aublBZ4dccccccc(KX2aublBZ4dcccwjZ4dcccQfKM2P8TuAG6bRSkzgFqqqWM4cQhSwCVMsUtAzOEg8kxlQ2SndQfK2i(GGGGGGGGrXw07CfWvxoS4ZB5ZKNbOcw2u7dOYshq1cELRfvB2a1d6b0LlWRCTOAZgOlxGEMb1csdupOhqxUa1csd0LlqpUC5YZi(GGGGGGGGQAWPvAGpPPZsN3QTptx5Ar1MTzqTG0ghbTkYfFqqqqqqqqqqqWOyl6DUc4Qlhw85T8zYJFqAGPtvRNNr8bbbbbbbbbbbbBPj2w8bbbbbbbbZTdFqqqqqqqWAzdSpZG1QGLnq1cwnQAAtAzO2vTkyztBeStIpiiiiiiiiiiiOQgCQwfSSjSwRcw2MUY1IQnBZGAbPnocAvKl(GGGGGGGGGGGGGGGGDs)meMUY1IQnBZGAbPnIpiiiiiiiiiiiiiiiylnX2IpiiiiiiiiiiiyUD4dcccccccMBh(GGGG52HFLGp(rXw07CfWvxoS4ZB5dOEWAX9Ak5ojh2noIpiiiOQgCQlhw8ze0Qix8bbbbbbbbR2uRn9AANkNCACeFqqqqqqqWxMcCkLbnVFPOt1j5WUXr8bbbbbbbbR2uRnnIpiiiyUD4NBh(4hfBrVZvaxhsmguwp3ldYMgOEWkdFqqqqpcJqc64BDDF313D9DNNzWdoa0DKYg(GGGGEegHe0X36666666ApZGhCaO7LooYfFqqqqpcJqc64BDTqzDD)97zg8Gda7l7v64ix8bbbb9imcjOJV1193VB2FxNNzWdoa0TITeFqqqqpcJqc64BDDCGd0DZ0Zm4bhaouv1fFqqqqpcJqc64BDDDTWU)(73Zm4bha(oFYTl26HpiiiOhHribD8TUohS7vy3VNzWdoa8fntvhVg(GGGGEegHe0X366(7)ERR9mdEWbGvAQAbP0b)kPyfR4RwlBBmi4zttj3IxdS4Bn1Zt2kNfFRx1S4Ff1mPtX)kQzshVTEvZIVMfTuSAx0YI)vuZKoExHQll(MYj7k(3kYBFk(Pa5Af)ROMjDk(hCaOGzi3Y9v6l860B)k9iUn(1I71uYDkgcAw0sTzWCeFqqqWOyl6DUc4kgcAw0snq9GXqqZIwQHp(GGGGQAq3hxbt2UvexZTYQrvBAeuVEqRjMGwf5c6wz1OQ9IqqNLoAtJG52Hp(GGGG1Yg4vUwuTzdupy)ZGhd2jXheeeeeeeSw2a1csdupOqZGVMM7LRfvB28s0XpinTPRCTOAZ2iyNeFqqqqqqqqqqqWOyl6DUc4QwfSS5Nnbu3uyTjUtx5Ar1MTzqTG0gXheeeeeeem3o8bbbbZTdFqqqWwAITf0AIj(52HFXpfixtR4lygYTCFL(cVo92VspIBx81QqE4JSfFTkKh(i7lUMsGSyf)UulAITOLLJw8TCqMqUJuTwX3T09ALEw8dYyx5S4R2NMuSA5S47igmv5SyfR4BXqUw5S47igmv5SyfR43PQRvxXG1RCw8DedMQCwSIv8BYqwol(oIbtvolwXk(1XRPKB5S47igmv5SyfR4xvGQwmKRvol(oIbtvolwXk(T4nlNfFhXGPkNfRyfFlgY1eu5S47igmv5SyfRyfFlhKj0aKRv8hAqvBPM2HJ9k(ROZzt98KnTIxcv8B5JsUN9QMfF1vUf)oLMBuCVMsGS4hdHIVLdYeQ4lyzl(QUIVWYlenPGNBNSP7k3I)vkdDYdVN5GSH24WHSRmCXxTkZBnl2SSR4Lqf)Rug6KhEldx8TCqMqUxUwuTo5Af)J0xo919YHkwXk(cu8sOJfKqfRuaa \ No newline at end of file diff --git a/FreshShit/AutoVendor/Init.lua b/FreshShit/AutoVendor/Init.lua new file mode 100644 index 0000000..13ad485 --- /dev/null +++ b/FreshShit/AutoVendor/Init.lua @@ -0,0 +1,264 @@ +local debug = false +local iconDisplayDuration = 3 + +---@param container number +---@param slot number +---@return string, string|nil +local function getItemLink(container, slot) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local link = select(7, GetContainerItemInfo(container, slot)) + if link == nil then return "", string.format("GetContainerItemInfo returned nil for link (arg 7)") end + return link +end +---@param container number +---@param slot number +---@return string, string|nil +local function getItemQuantity(container, slot) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local quantity = select(2, GetContainerItemInfo(container, slot)) + if quantity == nil then + return "", + string.format("GetContainerItemInfo returned nil for quantity (arg 2)") + end + return quantity +end +---@param container number +---@param slot number +---@return string, string|nil +local function getItemName(container, slot) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local name = select(1, GetItemInfo(getItemLink(container, slot))) + if name == nil then return "", string.format("GetItemInfo returned nil for name (arg 1)") end + return name +end +---@param container number +---@param slot number +---@return string, string|nil +local function getItemType(container, slot) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local type = select(6, GetItemInfo(getItemLink(container, slot))) + if type == nil then return "", string.format("GetItemInfo returned nil for type (arg 6)") end + return type +end +---@param container number +---@param slot number +---@return string, string|nil +local function getItemSubtype(container, slot) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local subtype = select(7, GetItemInfo(getItemLink(container, slot))) + if subtype == nil then return "", string.format("GetItemInfo returned nil for subtype (arg 7)") end + return subtype +end +---@param container number +---@param slot number +---@return string, string|nil +local function getItemLevel(container, slot) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local level = select(4, GetItemInfo(getItemLink(container, slot))) + if level == nil then return "", string.format("GetItemInfo returned nil for level (arg 4)") end + return level +end +---@param container number +---@param slot number +---@return string, string|nil +local function getItemValue(container, slot) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local value = select(11, GetItemInfo(getItemLink(container, slot))) + if value == nil then return "", string.format("GetItemInfo returned nil for value (arg 11)") end + return value +end +---@param container number +---@param slot number +---@return string, string|nil +local function getItemQuality(container, slot) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local quality = select(3, GetItemInfo(getItemLink(container, slot))) + if quality == nil then return "", string.format("GetItemInfo returned nil for quality (arg 3)") end + return quality +end +---@param container number +---@param slot number +---@return string, string|nil +local function getItemEquipLocation(container, slot) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local equipLoc = select(9, GetItemInfo(getItemLink(container, slot))) + if equipLoc == nil then return "", string.format("GetItemInfo returned nil for equipLoc (arg 9)") end + return equipLoc +end +---@param container number +---@param slot number +---@return string, string|nil +local function getItemIcon(container, slot) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local icon = select(10, GetItemInfo(getItemLink(container, slot))) + if icon == nil then return "", string.format("GetItemInfo returned nil for icon (arg 10)") end + return icon +end +---@param container number +---@param slot number +---@return string, string|nil +local function getBindType(container, slot) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local bindType = select(14, GetItemInfo(getItemLink(container, slot))) + if bindType == nil then return "", string.format("GetItemInfo returned nil for bindType (arg 14)") end + return bindType +end + +---@class Filter +---@field requires table | nil +---@field filter fun(container: number, slot: number, provided: table): boolean +Filter = { + ---@param requires table | nil + ---@param filter fun(container: number, slot: number, provided: table): boolean + ---@return Filter + new = function(requires, filter) + local self = setmetatable({}, { + __index = Filter + }) + self.requires = requires + self.filter = filter + return self + end, + + ---@param self Filter + ---@param container number + ---@param slot number + ---@return boolean, string|nil + Run = function(self, container, slot) + ---@type table + local provided = {} + if self.requires then + for k, v in pairs(self.requires) do + local res, err = v(container, slot) + if err then + if debug then print(err) end + return false, err + end + provided[k] = res + end + end + local res, err = self.filter(container, slot, provided) + if err then + if debug then print(err) end + end + return res, nil + end +} + +local grayFilter = Filter.new({ + ["quality"] = getItemQuality + }, + function(container, slot, provided) + if provided.quality == 0 then + return true + end + return false + end) +local gearFilter = Filter.new({ + ["ilvl"] = getItemLevel, + ["bindType"] = getBindType, + ["type"] = getItemType, + ["equipLoc"] = getItemEquipLocation + }, + function(container, slot, provided) + local ilvlThreshold = 850 + local sellBoe = false + + if provided.type == "Armor" + or provided.type == "Weapon" + or provided.equipLoc == "INVTYPE_FINGER" + or provided.equipLoc == "INVTYPE_TRINKET" + or provided.equipLoc == "INVTYPE_CLOAK" + or provided.equipLoc == "INVTYPE_NECK" then + if provided.ilvl < ilvlThreshold and (provided.bindType == 1 or sellBoe) then + return true + end + end + return false + end) + +---@param container number +---@param slot number +---@return nil, string|nil +local function doSell(container, slot) + local itemIcon, err = getItemIcon(container, slot) + if err then return nil, string.format("Error getting item icon: %s", err) end + local itemName, err = getItemName(container, slot) + if err then return nil, string.format("Error getting item name: %s", err) end + local itemQuantity, err = getItemQuantity(container, slot) + if err then return nil, string.format("Error getting item quantity: %s", err) end + local itemQuality, err = getItemQuality(container, slot) + if err then return nil, string.format("Error getting item quality: %s", err) end + + local nameWithColor = string.format("%s[%s]\124r", aura_env.qualityColors[itemQuality + 1], itemName) + local nameWithQuantity = string.format("%s x%s", nameWithColor, itemQuantity) + + aura_env.allstates[#aura_env.allstates + 1] = { + show = true, + changed = true, + index = GetTime(), + resort = true, + + icon = itemIcon, + name = nameWithQuantity, + amount = itemQuantity, + + progressType = "timed", + expirationTime = GetTime() + iconDisplayDuration, + duration = iconDisplayDuration, + autoHide = true, + } + + UseContainerItem(container, slot) + return nil, nil +end + +---@type table +local filters = { + grayFilter, + gearFilter +} + +---@class FilterService +aura_env.FilterService = { + ---@param container number + ---@param slot number + ---@return nil, nil + Run = function(container, slot) + local itemLink, err = getItemLink(container, slot) + if err then return nil, string.format("Err: slot empty (%d-%d) - %s", container, slot, err) end + for k, filter in pairs(filters) do + local res, err = filter:Run(container, slot) + if err then + if debug then print(err) end + else + if res then + doSell(container, slot) + return + end + end + end + end, +} + +aura_env.qualityColors = { + "\124cff9d9d9d", -- Poor + "\124cffffffff", -- Common + "\124cff1eff00", -- Uncommon + "\124cff0070dd", -- Rare + "\124cffa335ee", -- Epic + "\124cffff8000", -- Legendary + "\124cffe6cc80", -- Artifact + "\124cff00ccff", -- Heirloom +} diff --git a/FreshShit/GlobalTickers/event.lua b/FreshShit/GlobalTickers/event.lua new file mode 100644 index 0000000..fe8c01c --- /dev/null +++ b/FreshShit/GlobalTickers/event.lua @@ -0,0 +1,14 @@ +-- PLAYER_ENTERING_WORLD GUILD_ROSTER_UPDATE +function(e) + for interval, ticker in pairs(Tickers) do + if ticker == 0 then + if Debug then print("Creating ticker") end + local tickerEvent = string.format("TICKER_%d", interval) + Tickers[interval] = C_Timer.NewTicker(interval / 1000, function() + WeakAuras.ScanEvents(tickerEvent) + end) + else + if Debug then print("Ticker already exists") end + end + end +end \ No newline at end of file diff --git a/FreshShit/GlobalTickers/init.lua b/FreshShit/GlobalTickers/init.lua new file mode 100644 index 0000000..286391f --- /dev/null +++ b/FreshShit/GlobalTickers/init.lua @@ -0,0 +1,7 @@ +Debug = false +Tickers = { + [100] = 0, + [200] = 0, + [500] = 0, + [1000] = 0, +} diff --git a/FreshShit/RaiderlosSA/WeakAuras.lua b/FreshShit/RaiderlosSA/WeakAuras.lua new file mode 120000 index 0000000..90d2a4b --- /dev/null +++ b/FreshShit/RaiderlosSA/WeakAuras.lua @@ -0,0 +1 @@ +C:/Users/Administrator/Seafile/Backup-WoW/Ruski/WTF/Account/phatphuckdave/SavedVariables/WeakAuras.lua \ No newline at end of file diff --git a/FreshShit/RaiderlosSA/WeakAurasIridian.lua b/FreshShit/RaiderlosSA/WeakAurasIridian.lua new file mode 120000 index 0000000..a65bec3 --- /dev/null +++ b/FreshShit/RaiderlosSA/WeakAurasIridian.lua @@ -0,0 +1 @@ +C:/Users/Administrator/Seafile/Backup-WoW/Ruski/WTF/Account/Iridian/SavedVariables/WeakAuras.lua \ No newline at end of file diff --git a/FreshShit/RaiderlosSA/event.lua b/FreshShit/RaiderlosSA/event.lua new file mode 100644 index 0000000..74714e1 --- /dev/null +++ b/FreshShit/RaiderlosSA/event.lua @@ -0,0 +1,12 @@ +--- COMBAT_LOG_EVENT_UNFILTERED +---@param e string +---@param ... any +function(e, ...) + local spellName, err = CLEUParser.GetSpellName(...) + if err then return end + local spellId, err = CLEUParser.GetSpellId(...) + if err then return end + local subevent, err = CLEUParser.GetSubevent(...) + if err then return end + aura_env.LogSpell(spellName, spellId, subevent, ...) +end diff --git a/FreshShit/RaiderlosSA/filterLogBySpell.sh b/FreshShit/RaiderlosSA/filterLogBySpell.sh new file mode 100644 index 0000000..e728016 --- /dev/null +++ b/FreshShit/RaiderlosSA/filterLogBySpell.sh @@ -0,0 +1 @@ +IFS=$'\n'; for spell in $(cat spells.txt | grep -P "^\w+"); do filename=$(echo $spell | sed 's/ /_/g'); grep $spell WeakAurasIridian.lua > out/$filename.txt; done \ No newline at end of file diff --git a/FreshShit/RaiderlosSA/init.lua b/FreshShit/RaiderlosSA/init.lua new file mode 100644 index 0000000..0f519e0 --- /dev/null +++ b/FreshShit/RaiderlosSA/init.lua @@ -0,0 +1,1325 @@ +CLEUEventInfo = { + ["GENERIC"] = { + ["timestamp"] = 1, + ["subevent"] = 2, + ["hideCaster"] = 3, + ["sourceGUID"] = 4, + ["sourceName"] = 5, + ["sourceFlags"] = 6, + ["sourceRaidFlags"] = 7, + ["destGUID"] = 8, + ["destName"] = 9, + ["destFlags"] = 10, + ["destRaidFlags"] = 11, + }, + ["GENERIC_SPELL"] = { + ["spellId"] = 12, + ["spellName"] = 13, + ["spellSchool"] = 14, + }, + ["GENERIC_DAMAGE"] = { + ["amount"] = 15, + ["overkill"] = 16, + ["school"] = 17, + ["resisted"] = 18, + ["blocked"] = 19, + ["absorbed"] = 20, + ["critical"] = 21, + ["glancing"] = 22, + ["crushing"] = 23, + ["isOffHand"] = 24, + }, + ["GENERIC_MISSED"] = { + ["missType"] = 15, + ["isOffHand"] = 16, + ["amountMissed"] = 17, + ["critical"] = 18, + }, + ["GENERIC_HEAL"] = { + ["amount"] = 15, + ["overhealing"] = 16, + ["absorbed"] = 17, + ["critical"] = 18, + }, + ["GENERIC_HEAL_ABSORBED"] = { + ["extraGUID"] = 15, + ["extraName"] = 16, + ["extraFlags"] = 17, + ["extraRaidFlags"] = 18, + ["extraSpellID"] = 19, + ["extraSpellName"] = 20, + ["extraSchool"] = 21, + ["absorbedAmount"] = 22, + ["totalAmount"] = 23, + }, + ["GENERIC_ENERGIZE"] = { + ["amount"] = 15, + ["overEnergize"] = 16, + ["powerType"] = 17, + }, + ["GENERIC_DRAIN"] = { + ["amount"] = 15, + ["powerType"] = 16, + ["extraAmount"] = 17, + }, + ["GENERIC_LEECH"] = { + ["amount"] = 15, + ["powerType"] = 16, + ["extraAmount"] = 17, + }, + ["GENERIC_INTERRUPT"] = { + ["extraSpellId"] = 15, + ["extraSpellName"] = 16, + ["extraSchool"] = 17, + }, + ["GENERIC_DISPEL"] = { + ["extraSpellId"] = 15, + ["extraSpellName"] = 16, + ["extraSchool"] = 17, + ["auraType"] = 18, + }, + ["GENERIC_DISPEL_FAILED"] = { + ["extraSpellId"] = 15, + ["extraSpellName"] = 16, + ["extraSchool"] = 17, + }, + ["GENERIC_STOLEN"] = { + ["extraSpellId"] = 15, + ["extraSpellName"] = 16, + ["extraSchool"] = 17, + ["auraType"] = 18, + }, + ["GENERIC_EXTRA_ATTACKS"] = { + ["amount"] = 15, + }, + ["GENERIC_AURA_APPLIED"] = { + ["auraType"] = 15, + ["amount"] = 16, + }, + ["GENERIC_AURA_REMOVED"] = { + ["auraType"] = 15, + ["amount"] = 16, + }, + ["GENERIC_AURA_APPLIED_DOSE"] = { + ["auraType"] = 15, + ["amount"] = 16, + }, + ["GENERIC_AURA_REMOVED_DOSE"] = { + ["auraType"] = 15, + ["amount"] = 16, + }, + ["GENERIC_AURA_REFRESH"] = { + ["auraType"] = 15, + }, + ["GENERIC_AURA_BROKEN"] = { + ["auraType"] = 15, + }, + ["GENERIC_AURA_BROKEN_SPELL"] = { + ["extraSpellId"] = 15, + ["extraSpellName"] = 16, + ["extraSchool"] = 17, + ["auraType"] = 18, + }, + ["GENERIC_CAST_START"] = { + }, + ["GENERIC_CAST_SUCCESS"] = { + }, + ["GENERIC_CAST_FAILED"] = { + }, +} + +CLEUEventInfo["SWING_DAMAGE"] = CLEUEventInfo["GENERIC_DAMAGE"] +CLEUEventInfo["SWING_MISSED"] = CLEUEventInfo["GENERIC_MISSED"] +CLEUEventInfo["SWING_HEAL"] = CLEUEventInfo["GENERIC_HEAL"] +CLEUEventInfo["SWING_HEAL_ABSORBED"] = CLEUEventInfo["GENERIC_HEAL_ABSORBED"] +CLEUEventInfo["SWING_ENERGIZE"] = CLEUEventInfo["GENERIC_ENERGIZE"] +CLEUEventInfo["SWING_DRAIN"] = CLEUEventInfo["GENERIC_DRAIN"] +CLEUEventInfo["SWING_LEECH"] = CLEUEventInfo["GENERIC_LEECH"] +CLEUEventInfo["SWING_INTERRUPT"] = CLEUEventInfo["GENERIC_INTERRUPT"] +CLEUEventInfo["SWING_DISPEL"] = CLEUEventInfo["GENERIC_DISPEL"] +CLEUEventInfo["SWING_DISPEL_FAILED"] = CLEUEventInfo["GENERIC_DISPEL_FAILED"] +CLEUEventInfo["SWING_STOLEN"] = CLEUEventInfo["GENERIC_STOLEN"] +CLEUEventInfo["SWING_EXTRA_ATTACKS"] = CLEUEventInfo["GENERIC_EXTRA_ATTACKS"] +CLEUEventInfo["SWING_AURA_APPLIED"] = CLEUEventInfo["GENERIC_AURA_APPLIED"] +CLEUEventInfo["SWING_AURA_REMOVED"] = CLEUEventInfo["GENERIC_AURA_REMOVED"] +CLEUEventInfo["SWING_AURA_APPLIED_DOSE"] = CLEUEventInfo["GENERIC_AURA_APPLIED_DOSE"] +CLEUEventInfo["SWING_AURA_REMOVED_DOSE"] = CLEUEventInfo["GENERIC_AURA_REMOVED_DOSE"] +CLEUEventInfo["SWING_AURA_REFRESH"] = CLEUEventInfo["GENERIC_AURA_REFRESH"] +CLEUEventInfo["SWING_AURA_BROKEN"] = CLEUEventInfo["GENERIC_AURA_BROKEN"] +CLEUEventInfo["SWING_AURA_BROKEN_SPELL"] = CLEUEventInfo["GENERIC_AURA_BROKEN_SPELL"] +CLEUEventInfo["SWING_CAST_START"] = CLEUEventInfo["GENERIC_CAST_START"] +CLEUEventInfo["SWING_CAST_SUCCESS"] = CLEUEventInfo["GENERIC_CAST_SUCCESS"] +CLEUEventInfo["SWING_CAST_FAILED"] = CLEUEventInfo["GENERIC_CAST_FAILED"] + +CLEUEventInfo["RANGE_DAMAGE"] = CLEUEventInfo["GENERIC_DAMAGE"] +CLEUEventInfo["RANGE_MISSED"] = CLEUEventInfo["GENERIC_MISSED"] +CLEUEventInfo["RANGE_HEAL"] = CLEUEventInfo["GENERIC_HEAL"] +CLEUEventInfo["RANGE_HEAL_ABSORBED"] = CLEUEventInfo["GENERIC_HEAL_ABSORBED"] +CLEUEventInfo["RANGE_ENERGIZE"] = CLEUEventInfo["GENERIC_ENERGIZE"] +CLEUEventInfo["RANGE_DRAIN"] = CLEUEventInfo["GENERIC_DRAIN"] +CLEUEventInfo["RANGE_LEECH"] = CLEUEventInfo["GENERIC_LEECH"] +CLEUEventInfo["RANGE_INTERRUPT"] = CLEUEventInfo["GENERIC_INTERRUPT"] +CLEUEventInfo["RANGE_DISPEL"] = CLEUEventInfo["GENERIC_DISPEL"] +CLEUEventInfo["RANGE_DISPEL_FAILED"] = CLEUEventInfo["GENERIC_DISPEL_FAILED"] +CLEUEventInfo["RANGE_STOLEN"] = CLEUEventInfo["GENERIC_STOLEN"] +CLEUEventInfo["RANGE_EXTRA_ATTACKS"] = CLEUEventInfo["GENERIC_EXTRA_ATTACKS"] +CLEUEventInfo["RANGE_AURA_APPLIED"] = CLEUEventInfo["GENERIC_AURA_APPLIED"] +CLEUEventInfo["RANGE_AURA_REMOVED"] = CLEUEventInfo["GENERIC_AURA_REMOVED"] +CLEUEventInfo["RANGE_AURA_APPLIED_DOSE"] = CLEUEventInfo["GENERIC_AURA_APPLIED_DOSE"] +CLEUEventInfo["RANGE_AURA_REMOVED_DOSE"] = CLEUEventInfo["GENERIC_AURA_REMOVED_DOSE"] +CLEUEventInfo["RANGE_AURA_REFRESH"] = CLEUEventInfo["GENERIC_AURA_REFRESH"] +CLEUEventInfo["RANGE_AURA_BROKEN"] = CLEUEventInfo["GENERIC_AURA_BROKEN"] +CLEUEventInfo["RANGE_AURA_BROKEN_SPELL"] = CLEUEventInfo["GENERIC_AURA_BROKEN_SPELL"] +CLEUEventInfo["RANGE_CAST_START"] = CLEUEventInfo["GENERIC_CAST_START"] +CLEUEventInfo["RANGE_CAST_SUCCESS"] = CLEUEventInfo["GENERIC_CAST_SUCCESS"] +CLEUEventInfo["RANGE_CAST_FAILED"] = CLEUEventInfo["GENERIC_CAST_FAILED"] + +CLEUEventInfo["SPELL_DAMAGE"] = CLEUEventInfo["GENERIC_DAMAGE"] +CLEUEventInfo["SPELL_MISSED"] = CLEUEventInfo["GENERIC_MISSED"] +CLEUEventInfo["SPELL_HEAL"] = CLEUEventInfo["GENERIC_HEAL"] +CLEUEventInfo["SPELL_HEAL_ABSORBED"] = CLEUEventInfo["GENERIC_HEAL_ABSORBED"] +CLEUEventInfo["SPELL_ENERGIZE"] = CLEUEventInfo["GENERIC_ENERGIZE"] +CLEUEventInfo["SPELL_DRAIN"] = CLEUEventInfo["GENERIC_DRAIN"] +CLEUEventInfo["SPELL_LEECH"] = CLEUEventInfo["GENERIC_LEECH"] +CLEUEventInfo["SPELL_INTERRUPT"] = CLEUEventInfo["GENERIC_INTERRUPT"] +CLEUEventInfo["SPELL_DISPEL"] = CLEUEventInfo["GENERIC_DISPEL"] +CLEUEventInfo["SPELL_DISPEL_FAILED"] = CLEUEventInfo["GENERIC_DISPEL_FAILED"] +CLEUEventInfo["SPELL_STOLEN"] = CLEUEventInfo["GENERIC_STOLEN"] +CLEUEventInfo["SPELL_EXTRA_ATTACKS"] = CLEUEventInfo["GENERIC_EXTRA_ATTACKS"] +CLEUEventInfo["SPELL_AURA_APPLIED"] = CLEUEventInfo["GENERIC_AURA_APPLIED"] +CLEUEventInfo["SPELL_AURA_REMOVED"] = CLEUEventInfo["GENERIC_AURA_REMOVED"] +CLEUEventInfo["SPELL_AURA_APPLIED_DOSE"] = CLEUEventInfo["GENERIC_AURA_APPLIED_DOSE"] +CLEUEventInfo["SPELL_AURA_REMOVED_DOSE"] = CLEUEventInfo["GENERIC_AURA_REMOVED_DOSE"] +CLEUEventInfo["SPELL_AURA_REFRESH"] = CLEUEventInfo["GENERIC_AURA_REFRESH"] +CLEUEventInfo["SPELL_AURA_BROKEN"] = CLEUEventInfo["GENERIC_AURA_BROKEN"] +CLEUEventInfo["SPELL_AURA_BROKEN_SPELL"] = CLEUEventInfo["GENERIC_AURA_BROKEN_SPELL"] +CLEUEventInfo["SPELL_CAST_START"] = CLEUEventInfo["GENERIC_CAST_START"] +CLEUEventInfo["SPELL_CAST_SUCCESS"] = CLEUEventInfo["GENERIC_CAST_SUCCESS"] +CLEUEventInfo["SPELL_CAST_FAILED"] = CLEUEventInfo["GENERIC_CAST_FAILED"] + +CLEUEventInfo["SPELL_PERIODIC_DAMAGE"] = CLEUEventInfo["GENERIC_DAMAGE"] +CLEUEventInfo["SPELL_PERIODIC_MISSED"] = CLEUEventInfo["GENERIC_MISSED"] +CLEUEventInfo["SPELL_PERIODIC_HEAL"] = CLEUEventInfo["GENERIC_HEAL"] +CLEUEventInfo["SPELL_PERIODIC_HEAL_ABSORBED"] = CLEUEventInfo["GENERIC_HEAL_ABSORBED"] +CLEUEventInfo["SPELL_PERIODIC_ENERGIZE"] = CLEUEventInfo["GENERIC_ENERGIZE"] +CLEUEventInfo["SPELL_PERIODIC_DRAIN"] = CLEUEventInfo["GENERIC_DRAIN"] +CLEUEventInfo["SPELL_PERIODIC_LEECH"] = CLEUEventInfo["GENERIC_LEECH"] +CLEUEventInfo["SPELL_PERIODIC_INTERRUPT"] = CLEUEventInfo["GENERIC_INTERRUPT"] +CLEUEventInfo["SPELL_PERIODIC_DISPEL"] = CLEUEventInfo["GENERIC_DISPEL"] +CLEUEventInfo["SPELL_PERIODIC_DISPEL_FAILED"] = CLEUEventInfo["GENERIC_DISPEL_FAILED"] +CLEUEventInfo["SPELL_PERIODIC_STOLEN"] = CLEUEventInfo["GENERIC_STOLEN"] +CLEUEventInfo["SPELL_PERIODIC_EXTRA_ATTACKS"] = CLEUEventInfo["GENERIC_EXTRA_ATTACKS"] +CLEUEventInfo["SPELL_PERIODIC_AURA_APPLIED"] = CLEUEventInfo["GENERIC_AURA_APPLIED"] +CLEUEventInfo["SPELL_PERIODIC_AURA_REMOVED"] = CLEUEventInfo["GENERIC_AURA_REMOVED"] +CLEUEventInfo["SPELL_PERIODIC_AURA_APPLIED_DOSE"] = CLEUEventInfo["GENERIC_AURA_APPLIED_DOSE"] +CLEUEventInfo["SPELL_PERIODIC_AURA_REMOVED_DOSE"] = CLEUEventInfo["GENERIC_AURA_REMOVED_DOSE"] +CLEUEventInfo["SPELL_PERIODIC_AURA_REFRESH"] = CLEUEventInfo["GENERIC_AURA_REFRESH"] +CLEUEventInfo["SPELL_PERIODIC_AURA_BROKEN"] = CLEUEventInfo["GENERIC_AURA_BROKEN"] +CLEUEventInfo["SPELL_PERIODIC_AURA_BROKEN_SPELL"] = CLEUEventInfo["GENERIC_AURA_BROKEN_SPELL"] +CLEUEventInfo["SPELL_PERIODIC_CAST_START"] = CLEUEventInfo["GENERIC_CAST_START"] +CLEUEventInfo["SPELL_PERIODIC_CAST_SUCCESS"] = CLEUEventInfo["GENERIC_CAST_SUCCESS"] +CLEUEventInfo["SPELL_PERIODIC_CAST_FAILED"] = CLEUEventInfo["GENERIC_CAST_FAILED"] + +---@class CLEUParser +CLEUParser = { + ---@param ... any + ---@return number, nil|string + GetTimestamp = function(...) + local val = select(CLEUEventInfo["GENERIC"]["timestamp"], ...) + if val == nil then return 0, "Timestamp is nil or missing" end + if type(val) ~= "number" then return 0, "Timestamp is not a number" end + return val, nil + end, + ---@param ... any + ---@return string, nil|string + GetSubevent = function(...) + local val = select(CLEUEventInfo["GENERIC"]["subevent"], ...) + if val == nil then return "", "Subevent is nil or missing" end + if type(val) ~= "string" then return "", "Subevent is not a string" end + return val, nil + end, + ---@param ... any + ---@return boolean, nil|string + GetHideCaster = function(...) + local val = select(CLEUEventInfo["GENERIC"]["hideCaster"], ...) + if val == nil then return false, "HideCaster is nil or missing" end + if type(val) ~= "boolean" then return false, "HideCaster is not a boolean" end + return val, nil + end, + ---@param ... any + ---@return string, nil|string + GetSourceGUID = function(...) + local val = select(CLEUEventInfo["GENERIC"]["sourceGUID"], ...) + if val == nil then return "", "SourceGUID is nil or missing" end + if type(val) ~= "string" then return "", "SourceGUID is not a string" end + return val, nil + end, + ---@param ... any + ---@return string, nil|string + GetSourceName = function(...) + local val = select(CLEUEventInfo["GENERIC"]["sourceName"], ...) + if val == nil then return "", "SourceName is nil or missing" end + if type(val) ~= "string" then return "", "SourceName is not a string" end + return val, nil + end, + ---@param ... any + ---@return number, nil|string + GetSourceFlags = function(...) + local val = select(CLEUEventInfo["GENERIC"]["sourceFlags"], ...) + if val == nil then return 0, "SourceFlags is nil or missing" end + if type(val) ~= "number" then return 0, "SourceFlags is not a number" end + return val, nil + end, + ---@param ... any + ---@return number, nil|string + GetSourceRaidFlags = function(...) + local val = select(CLEUEventInfo["GENERIC"]["sourceRaidFlags"], ...) + if val == nil then return 0, "SourceRaidFlags is nil or missing" end + if type(val) ~= "number" then return 0, "SourceRaidFlags is not a number" end + return val, nil + end, + ---@param ... any + ---@return string, nil|string + GetDestGUID = function(...) + local val = select(CLEUEventInfo["GENERIC"]["destGUID"], ...) + if val == nil then return "", "DestGUID is nil or missing" end + if type(val) ~= "string" then return "", "DestGUID is not a string" end + return val, nil + end, + ---@param ... any + ---@return string, nil|string + GetDestName = function(...) + local val = select(CLEUEventInfo["GENERIC"]["destName"], ...) + if val == nil then return "", "DestName is nil or missing" end + if type(val) ~= "string" then return "", "DestName is not a string" end + return val, nil + end, + ---@param ... any + ---@return number, nil|string + GetDestFlags = function(...) + local val = select(CLEUEventInfo["GENERIC"]["destFlags"], ...) + if val == nil then return 0, "DestFlags is nil or missing" end + if type(val) ~= "number" then return 0, "DestFlags is not a number" end + return val, nil + end, + ---@param ... any + ---@return number, nil|string + GetDestRaidFlags = function(...) + local val = select(CLEUEventInfo["GENERIC"]["destRaidFlags"], ...) + if val == nil then return 0, "DestRaidFlags is nil or missing" end + if type(val) ~= "number" then return 0, "DestRaidFlags is not a number" end + return val, nil + end, + + + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + ---@param ... any + ---@return number, nil|string + GetSpellId = function(...) + local val = select(CLEUEventInfo["GENERIC_SPELL"]["spellId"], ...) + if val == nil then return 0, "SpellId is nil or missing" end + if type(val) ~= "number" then return 0, "SpellId is not a number" end + return val, nil + end, + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + ---@param ... any + ---@return string, nil|string + GetSpellName = function(...) + local val = select(CLEUEventInfo["GENERIC_SPELL"]["spellName"], ...) + if val == nil then return "", "SpellName is nil or missing" end + if type(val) ~= "string" then return "", "SpellName is not a string" end + return val, nil + end, + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + ---@param ... any + ---@return number, nil|string + GetSpellSchool = function(...) + local val = select(CLEUEventInfo["GENERIC_SPELL"]["spellSchool"], ...) + if val == nil then return 0, "SpellSchool is nil or missing" end + if type(val) ~= "number" then return 0, "SpellSchool is not a number" end + return val, nil + end, + + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_DAMAGE| + --- |_HEAL| + --- |_ENERGIZE| + --- |_DRAIN| + --- |_LEECH| + --- |_EXTRA_ATTACKS| + --- |_AURA_APPLIED| + --- |_AURA_REMOVED| + --- |_AURA_APPLIED_DOSE| + --- |_AURA_REMOVED_DOSE| + ---@param ... any + ---@return number, nil|string + GetAmount = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["amount"], ...) + if val == nil then return 0, "Amount is nil or missing" end + if type(val) ~= "number" then return 0, "Amount is not a number" end + return val, nil + end, + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_DAMAGE| + ---@param ... any + ---@return number, nil|string + GetOverkill = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["overkill"], ...) + if val == nil then return 0, "Overkill is nil or missing" end + if type(val) ~= "number" then return 0, "Overkill is not a number" end + return val, nil + end, + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_DAMAGE| + ---@param ... any + ---@return number, nil|string + GetSchool = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["school"], ...) + if val == nil then return 0, "School is nil or missing" end + if type(val) ~= "number" then return 0, "School is not a number" end + return val, nil + end, + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_DAMAGE| + --- + --- Apparently this is allowed to be nil? + ---@param ... any + ---@return boolean, nil|string + GetResisted = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return false, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["resisted"], ...) + if val == nil then return false, "Resisted is nil or missing" end + if type(val) ~= "boolean" then return false, "Resisted is not a boolean" end + return val, nil + end, + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_DAMAGE| + --- + --- Apparently this is allowed to be nil? + ---@param ... any + ---@return boolean, nil|string + GetBlocked = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return false, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["blocked"], ...) + if val == nil then return false, "Blocked is nil or missing" end + if type(val) ~= "boolean" then return false, "Blocked is not a boolean" end + return val, nil + end, + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_DAMAGE| + --- |_HEAL| + --- + --- Apparently this is allowed to be nil? + ---@param ... any + ---@return boolean, nil|string + GetAbsorbed = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return false, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["absorbed"], ...) + if val == nil then return false, "Absorbed is nil or missing" end + if type(val) ~= "boolean" then return false, "Absorbed is not a boolean" end + return val, nil + end, + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_DAMAGE| + --- |_MISSED| + --- |_HEAL| + ---@param ... any + ---@return boolean, nil|string + GetCritical = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return false, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["critical"], ...) + if val == nil then return false, "Critical is nil or missing" end + if type(val) ~= "boolean" then return false, "Critical is not a boolean" end + return val, nil + end, + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_DAMAGE| + ---@param ... any + ---@return boolean, nil|string + GetGlancing = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return false, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["glancing"], ...) + if val == nil then return false, "Glancing is nil or missing" end + if type(val) ~= "boolean" then return false, "Glancing is not a boolean" end + return val, nil + end, + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_DAMAGE| + ---@param ... any + ---@return boolean, nil|string + GetCrushing = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return false, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["crushing"], ...) + if val == nil then return false, "Crushing is nil or missing" end + if type(val) ~= "boolean" then return false, "Crushing is not a boolean" end + return val, nil + end, + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_DAMAGE| + --- |_MISSED| + ---@param ... any + ---@return boolean, nil|string + GetIsOffHand = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return false, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["isOffHand"], ...) + if val == nil then return false, "IsOffHand is nil or missing" end + if type(val) ~= "boolean" then return false, "IsOffHand is not a boolean" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_MISSED| + --- + --- return type is unconfirmed! + ---@param ... any + ---@return string, nil|string + GetMissType = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return "", string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["missType"], ...) + if val == nil then return "", "MissType is nil or missing" end + if type(val) ~= "string" then return "", "MissType is not a string" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_MISSED| + ---@param ... any + ---@return number, nil|string + --- + --- return type is unconfirmed! + GetAmountMissed = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["amountMissed"], ...) + if val == nil then return 0, "AmountMissed is nil or missing" end + if type(val) ~= "number" then return 0, "AmountMissed is not a number" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_HEAL| + --- + --- return type is unconfirmed! + ---@param ... any + ---@return number, nil|string + GetOverhealing = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["overhealing"], ...) + if val == nil then return 0, "Overhealing is nil or missing" end + if type(val) ~= "number" then return 0, "Overhealing is not a number" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_HEAL_ABSORBED| + ---@param ... any + ---@return string, nil|string + GetExtraGUID = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return "", string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["extraGUID"], ...) + if val == nil then return "", "ExtraGUID is nil or missing" end + if type(val) ~= "string" then return "", "ExtraGUID is not a string" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_HEAL_ABSORBED| + ---@param ... any + ---@return string, nil|string + GetExtraName = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return "", string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["extraName"], ...) + if val == nil then return "", "ExtraName is nil or missing" end + if type(val) ~= "string" then return "", "ExtraName is not a string" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_HEAL_ABSORBED| + ---@param ... any + ---@return number, nil|string + GetExtraFlags = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["extraFlags"], ...) + if val == nil then return 0, "ExtraFlags is nil or missing" end + if type(val) ~= "number" then return 0, "ExtraFlags is not a number" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_HEAL_ABSORBED| + ---@param ... any + ---@return number, nil|string + GetExtraRaidFlags = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["extraRaidFlags"], ...) + if val == nil then return 0, "ExtraRaidFlags is nil or missing" end + if type(val) ~= "number" then return 0, "ExtraRaidFlags is not a number" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_HEAL_ABSORBED| + --- + --- WARNING! Different from "GetExtraSpellId" (capital ID!)
+ --- This is the doing of Blizzard, not me.
+ ---@see CLEUParser.GetExtraSpellId + ---@param ... any + ---@return number, nil|string + GetExtraSpellID = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["extraSpellID"], ...) + if val == nil then return 0, "ExtraSpellID is nil or missing" end + if type(val) ~= "number" then return 0, "ExtraSpellID is not a number" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_HEAL_ABSORBED| + --- |_INTERRUPT| + --- |_DISPEL| + --- |_DISPEL_FAILED| + --- |_STOLEN| + --- |_AURA_BROKEN_SPELL| + ---@param ... any + ---@return string, nil|string + GetExtraSpellName = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return "", string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["extraSpellName"], ...) + if val == nil then return "", "extraSpellName is nil or missing" end + if type(val) ~= "string" then return "", "extraSpellName is not a string" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_HEAL_ABSORBED| + --- |_INTERRUPT| + --- |_DISPEL| + --- |_DISPEL_FAILED| + --- |_STOLEN| + --- |_AURA_BROKEN_SPELL| + ---@param ... any + ---@return number, nil|string + GetExtraSchool = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["extraSchool"], ...) + if val == nil then return 0, "ExtraSchool is nil or missing" end + if type(val) ~= "number" then return 0, "ExtraSchool is not a number" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_HEAL_ABSORBED| + ---@param ... any + ---@return number, nil|string + GetAbsorbedAmount = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["absorbedAmount"], ...) + if val == nil then return 0, "AbsorbedAmount is nil or missing" end + if type(val) ~= "number" then return 0, "AbsorbedAmount is not a number" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_ENERGIZE| + ---@param ... any + ---@return number, nil|string + GetOverEnergize = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["overEnergize"], ...) + if val == nil then return 0, "OverEnergize is nil or missing" end + if type(val) ~= "number" then return 0, "OverEnergize is not a number" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_ENERGIZE| + --- |_DRAIN| + --- |_LEECH| + --- + --- return type is unconfirmed! + ---@param ... any + ---@return number, nil|string + GetPowerType = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["powerType"], ...) + if val == nil then return 0, "PowerType is nil or missing" end + if type(val) ~= "number" then return 0, "PowerType is not a number" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_DRAIN| + --- |_LEECH| + ---@param ... any + ---@return number, nil|string + GetExtraAmount = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["extraAmount"], ...) + if val == nil then return 0, "ExtraAmount is nil or missing" end + if type(val) ~= "number" then return 0, "ExtraAmount is not a number" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_INTERRUPT| + --- |_DISPEL| + --- |_DISPEL_FAILED| + --- |_STOLEN| + --- |_AURA_BROKEN_SPELL| + --- + --- WARNING! Different from "GetExtraSpellID" (capital ID!)
+ --- This is the doing of Blizzard, not me.
+ ---@see CLEUParser.GetExtraSpellID + ---@param ... any + ---@return number, nil|string + GetExtraSpellId = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["extraSpellId"], ...) + if val == nil then return 0, "ExtraSpellId is nil or missing" end + if type(val) ~= "number" then return 0, "ExtraSpellId is not a number" end + return val, nil + end, + + --- Specific to subevents prefixed by: + --- |Prefix| + --- |-----| + --- |RANGE| + --- |SWING| + --- |SPELL| + --- |SPELL_PERIODIC| + --- |SPELL_BUILDING| + --- + --- And suffixed by: + --- |Suffix| + --- |------| + --- |_DISPEL| + --- |_STOLEN| + --- |_AURA_APPLIED| + --- |_AURA_REMOVED| + --- |_AURA_APPLIED_DOSE| + --- |_AURA_REMOVED_DOSE| + --- |_AURA_REFRESH| + --- |_AURA_BROKEN| + --- |_AURA_BROKEN_SPELL| + ---@param ... any + ---@return number, nil|string + GetExtraAuraType = function(...) + local subevent, err = CLEUParser.GetSubevent(...) + if err then return 0, string.format("Failed getting subevent due to: %s", err) end + local val = select(CLEUEventInfo[subevent]["auraType"], ...) + if val == nil then return 0, "AuraType is nil or missing" end + if type(val) ~= "number" then return 0, "AuraType is not a number" end + return val, nil + end, +} + +local function varargToString(...) + local output = {} + for i = 1, select("#", ...) do + table.insert(output, tostring(select(i, ...))) + end + return table.concat(output, ", ") +end + +-- C:\Users\Administrator\Seafile\Backup-WoW\Ruski\WTF\Account\phatphuckdave\SavedVariables\WeakAuras.lua +-- /dump WeakAurasSaved.Cyka.CLEUExample +if not WeakAurasSaved then WeakAurasSaved = {} end +if not WeakAurasSaved.Cyka then WeakAurasSaved.Cyka = {} end +if not WeakAurasSaved.Cyka.CLEUExample then WeakAurasSaved.Cyka.CLEUExample = {} end +---@param spellName string +---@param spellId number +---@param subevent string +---@param ... any +aura_env.LogSpell = function(spellName, spellId, subevent, ...) + local slug = string.format("%d-%s", spellId, subevent) + if not WeakAurasSaved.Cyka.CLEUExample[slug] then + WeakAurasSaved.Cyka.CLEUExample[slug] = varargToString(spellName, spellId, subevent, ...) + end +end + +local SoundFileRoot = "Interface\\Sounds\\spellAlert\\" + +---@class SpellAlert +---@field id number +---@field soundFile string +SpellAlert = { + ---@param id number + ---@param name string + ---@return SpellAlert + new = function(id, name) + local self = setmetatable({}, { + __index = SpellAlert + }) + self.id = id + name = string.gsub(name, " ", "_") + name = string.lower(name) + self.soundFile = string.format("%s%s.ogg", SoundFileRoot, name) + return self + end +} +-- [230094] = "Nullification, 230094, SPELL_CAST_SUCCESS, 1709744064.211, SPELL_CAST_SUCCESS, false, Creature-0-67-1651-0-115765-000039BF96, Abstract Nullifier, 68168, 0, Player-67-00341022, Lanarhodess, 1298, 0, 230094, Nullification, 1", +-- [230083] = "Nullification, 230083, SPELL_AURA_REMOVED, 1709744064.303, SPELL_AURA_REMOVED, false, Creature-0-67-1651-0-115765-000039BF96, Abstract Nullifier, 68168, 0, Player-67-003521C2, Bonkleta, 1297, 0, 230083, Nullification, 1, DEBUFF", +-- [227267] = "Summon Volatile Energy, 227267, SPELL_SUMMON, 1709744153.649, SPELL_SUMMON, false, Creature-0-67-1651-0-114247-000039BF70, The Curator, 68168, 0, Creature-0-67-1651-0-114249-00003A1923, Volatile Energy, 2632, 0, 227267, Summon Volatile Energy, 64", +local alerts = { + -- Garothi + SpellAlert.new(244410, "Decimation"), + SpellAlert.new(246220, "Fel Bombardment"), + SpellAlert.new(244969, "Eradication"), + SpellAlert.new(244106, "Carnage"), + -- Felhounds + SpellAlert.new(244086, "Molten Touch"), + SpellAlert.new(244768, "Desolate Gaze"), + SpellAlert.new(244057, "Enflame Corruption"), + SpellAlert.new(244131, "Consuming Sphere"), + SpellAlert.new(244056, "Siphon Corruption"), + -- Antoran High Command + SpellAlert.new(245161, "Entropic Mine"), + SpellAlert.new(245546, "Summon Reinforcements"), + -- Portal Keeper Hasabel + SpellAlert.new(244016, "Reality Tear"), + SpellAlert.new(243983, "Collapsing World"), + SpellAlert.new(244000, "Felstorm Barrage"), + -- Imonar + SpellAlert.new(247552, "Sleep Canister"), + SpellAlert.new(247367, "Shock Lance"), + SpellAlert.new(248068, "Empowered Pulse Grenade"), + SpellAlert.new(247376, "Pulse Grenade"), + SpellAlert.new(247716, "Charged Blasts"), + SpellAlert.new(247687, "Sever"), + SpellAlert.new(248070, "Empowered Shrapnel Blast"), + SpellAlert.new(250255, "Empowered Shock Lance"), + -- Kin'garoth + SpellAlert.new(254919, "Forging Strike"), + SpellAlert.new(254926, "Reverberating Strike"), + SpellAlert.new(246840, "Ruiner"), + SpellAlert.new(246779, "Diabolic Bomb"), + SpellAlert.new(246706, "Demolish"), + SpellAlert.new(246664, "Annihilation"), + -- Varimathras + SpellAlert.new(243960, "Shadow Strike"), + SpellAlert.new(243961, "Misery"), + SpellAlert.new(244042, "Marked Prey"), + SpellAlert.new(244093, "Necrotic Embrace"), + SpellAlert.new(248732, "Echoes of Doom"), + SpellAlert.new(243999, "Dark Fissure"), + -- Coven + SpellAlert.new(253189, "Shivan Pact"), + SpellAlert.new(244899, "Fiery Strike"), + SpellAlert.new(245627, "Whirling Saber"), + SpellAlert.new(245281, "Shadow Blades"), + SpellAlert.new(245586, "Chilled Blood"), + -- Aggramar + SpellAlert.new(254452, "Ravenous Blaze"), + SpellAlert.new(244693, "Wake of Flame"), + SpellAlert.new(244291, "Foe Braker"), + SpellAlert.new(244033, "Flame Rend"), + SpellAlert.new(247079, "Empowered Flame Rend"), + SpellAlert.new(245983, "Flare"), + SpellAlert.new(246037, "Empowered Flare"), + -- Argus + SpellAlert.new(256457, "Cone of Death"), + SpellAlert.new(248396, "Soulblight"), + SpellAlert.new(257296, "Tortured Rage"), + SpellAlert.new(251570, "Soulbomb"), + + -- Mythic+ + -- Black Rook Hold + SpellAlert.new(225573, "Dark Mending"), + SpellAlert.new(200105, "Sacrifice Soul"), + SpellAlert.new(225732, "Strike Down"), + SpellAlert.new(194996, "Soul Echoes"), + SpellAlert.new(195254, "Swirling Scythe"), + SpellAlert.new(194956, "Reap Soul"), + SpellAlert.new(200248, "Arcane Blitz"), + SpellAlert.new(200345, "Arrow Barrage"), + SpellAlert.new(200291, "Knife Dance"), + SpellAlert.new(200261, "Bonebreaking Strike"), + SpellAlert.new(197418, "Vengeful Shear"), + SpellAlert.new(201139, "Brutal Assault"), + SpellAlert.new(198245, "Brutal Haymaker"), + SpellAlert.new(198079, "Hateful Gaze"), + -- Cathedral of Eternal Night + SpellAlert.new(241937, "Shadow Wall"), + SpellAlert.new(238543, "Demonic Mending"), + SpellAlert.new(242792, "Vile Roots"), + SpellAlert.new(236627, "Floral Fulmination"), + SpellAlert.new(239217, "Blinding Glare"), + SpellAlert.new(237726, "Scornful Gaze"), + SpellAlert.new(190620, "Felblaze Orb"), + SpellAlert.new(239268, "Venom Storm"), + SpellAlert.new(234107, "Chaotic Energy"), + SpellAlert.new(236543, "Felsoul Cleave"), + SpellAlert.new(238315, "Shadow Sweep"), + SpellAlert.new(243168, "Demonic Upheaval"), + -- Court of Stars + SpellAlert.new(210261, "Sound Alarm"), + SpellAlert.new(215204, "Hinder"), + SpellAlert.new(209027, "Quelling Strike"), + SpellAlert.new(209516, "Mana Fang"), + SpellAlert.new(209485, "Drain Magic"), + SpellAlert.new(209404, "Seal Magic"), + SpellAlert.new(209495, "Charged Smash"), + SpellAlert.new(225100, "Charging Station"), + SpellAlert.new(219488, "Streetsweeper"), + SpellAlert.new(212784, "Eye Storm"), + SpellAlert.new(211464, "Fel Detonation"), + SpellAlert.new(207980, "Disintegration Beam"), + SpellAlert.new(207979, "Shockwave"), + SpellAlert.new(209628, "Piercing Gale"), + SpellAlert.new(209676, "Slicing Maelstrom"), + -- Darkheart Thicket + SpellAlert.new(200631, "Unnerving Screech"), + SpellAlert.new(200580, "Maddening Roar"), + SpellAlert.new(191326, "Breath of Corruption"), + SpellAlert.new(201400, "Dread Inferno"), + SpellAlert.new(200238, "Feed on the Weak"), + -- Eye of Azshara + SpellAlert.new(195172, "Mighty Slam"), + SpellAlert.new(195129, "Thundering Stomp"), + SpellAlert.new(195046, "Rejuvenating Waters"), + SpellAlert.new(162135, "Bellowing Roar"), + SpellAlert.new(197105, "Polymorh Fish"), + SpellAlert.new(193597, "Static Nova"), + SpellAlert.new(193611, "Focused Lightning"), + SpellAlert.new(196129, "Spray Sand"), + SpellAlert.new(196144, "Sandstorm"), + SpellAlert.new(196296, "Roiling Storm"), + SpellAlert.new(196290, "Chaotic Tempest"), + SpellAlert.new(191848, "Rampage"), + -- Halls of Valor + SpellAlert.new(198605, "Thunderstrike"), + SpellAlert.new(198888, "Lightning Breath"), + SpellAlert.new(191284, "Horn of Valor"), + SpellAlert.new(198934, "Rune of Healing"), + SpellAlert.new(215433, "Holy Radiance"), + SpellAlert.new(199210, "Penetrating Shot"), + SpellAlert.new(191976, "Arcing Bolt"), + SpellAlert.new(192305, "Eye of the Storm"), + SpellAlert.new(192307, "Sanctify"), + SpellAlert.new(192048, "Expel Light"), + SpellAlert.new(192018, "Shield of Light"), + SpellAlert.new(196512, "Claw Frenzy"), + SpellAlert.new(199652, "Sever"), + SpellAlert.new(199726, "Unruly Yell"), + SpellAlert.new(199674, "Wicked Dagger"), + SpellAlert.new(193826, "Ragnarok"), + SpellAlert.new(198263, "Radiant Tempest"), + SpellAlert.new(198072, "Spear of Light"), + SpellAlert.new(197961, "Runic Band"), + SpellAlert.new(198750, "Surge"), + -- Maw of Souls + SpellAlert.new(193364, "Screams of the Dead"), + SpellAlert.new(194442, "Six Pound Barrel"), + SpellAlert.new(194615, "Sea Legs"), + SpellAlert.new(192019, "Lantern of Darkness"), + SpellAlert.new(194099, "Bile Breath"), + SpellAlert.new(198405, "Bone Chilling Scream"), + SpellAlert.new(194325, "Fragment"), + SpellAlert.new(194216, "Cosmic Scythe"), + SpellAlert.new(195293, "Debilitating Shout"), + SpellAlert.new(185539, "Rapid Rupture"), + SpellAlert.new(198495, "Torrent"), + SpellAlert.new(202098, "Brackwater Barrage"), + -- Neltharion's Lair + SpellAlert.new(202181, "Stone Gaze"), + SpellAlert.new(226296, "Piercing Shards"), + SpellAlert.new(188169, "Razor Shards"), + SpellAlert.new(198496, "Sunder"), + SpellAlert.new(199176, "Spiked Tongue"), + SpellAlert.new(193585, "Bound"), + SpellAlert.new(200700, "Landslide"), + SpellAlert.new(200732, "Molten Crash"), + -- The Arcway + SpellAlert.new(211771, "Prophecies of Doom"), + SpellAlert.new(211037, "Celerity Zone"), + SpellAlert.new(195791, "Quarantine"), + SpellAlert.new(226285, "Demonic Ascension"), + SpellAlert.new(197810, "Wicked Slam"), + SpellAlert.new(211217, "Arcane Slicer"), + SpellAlert.new(211115, "Phase Breach"), + SpellAlert.new(196392, "Overcharge Mana"), + SpellAlert.new(200040, "Nether Venom"), + SpellAlert.new(200227, "Tangled Web"), + SpellAlert.new(220871, "Unstable Mana"), + -- Vault of the Wardens + SpellAlert.new(193069, "Nightmares"), + SpellAlert.new(197799, "Unleash Fury"), + SpellAlert.new(191735, "Deafening Screech"), + SpellAlert.new(190836, "Hatred"), + SpellAlert.new(202913, "Fel Mortar"), + SpellAlert.new(200898, "Teleport"), + SpellAlert.new(199917, "Shadow Crash"), + SpellAlert.new(202658, "Drain"), + SpellAlert.new(194945, "Lingering Gaze"), + SpellAlert.new(196249, "Meteor"), + SpellAlert.new(192631, "Lava Wreath"), + SpellAlert.new(197513, "Detonating Moonglaive"), + SpellAlert.new(189469, "Turn Kick"), + -- Upper Karazhan + SpellAlert.new(230083, "Nullification"), + SpellAlert.new(227267, "Summon Volatile Energy"), + SpellAlert.new(227254, "Evocation"), + SpellAlert.new(229662, "Fel Breath"), + SpellAlert.new(36247, "Fel Fireball"), + SpellAlert.new(227628, "Piercing Missiles"), + SpellAlert.new(227615, "Inferno Bolt"), + SpellAlert.new(227592, "Frostbite"), + SpellAlert.new(228269, "Flame Wreath"), + SpellAlert.new(227779, "Ceaseless Winter"), + SpellAlert.new(229706, "Leech Life"), + SpellAlert.new(229714, "Consume Magic"), + SpellAlert.new(229159, "Chaotic Shadows"), + SpellAlert.new(229083, "Burning Blast"), + SpellAlert.new(229151, "Disintegrate"), + -- Lower Karazhan + SpellAlert.new(228221, "Severe Dusting"), + SpellAlert.new(228225, "Sultry Heat"), + SpellAlert.new(232153, "Kara Kazham"), + SpellAlert.new(227987, "Dinner Bell"), + SpellAlert.new(228025, "Heat Wave"), + SpellAlert.new(227568, "Burning Leg Sweep"), + SpellAlert.new(227776, "Magic Magnificent"), + SpellAlert.new(227966, "Flashlight"), + SpellAlert.new(228279, "Shadow Rejuvenation"), + SpellAlert.new(228278, "Demoralizing Shout"), + SpellAlert.new(228277, "Shackles of Servitude"), + SpellAlert.new(226316, "Shadow Bolt Volley"), + SpellAlert.new(227508, "Mass Repentance"), + SpellAlert.new(227793, "Sacred Ground"), + SpellAlert.new(227463, "Whirling Edge"), + SpellAlert.new(227646, "Iron Whirlwind"), + SpellAlert.new(227672, "Will Breaker"), + SpellAlert.new(227404, "Intangible Presence"), + SpellAlert.new(227493, "Mortal Strike"), + SpellAlert.new(228852, "Shared Suffering"), + SpellAlert.new(228837, "Bellowing Roar"), +} + +aura_env.EventMap = { + ["SPELL_CAST_SUCCESS"] = { + alerts[230094], -- Nullification + } +} diff --git a/FreshShit/RaiderlosSA/scratch.lua b/FreshShit/RaiderlosSA/scratch.lua new file mode 100644 index 0000000..ad72493 --- /dev/null +++ b/FreshShit/RaiderlosSA/scratch.lua @@ -0,0 +1,9 @@ +local function varargToString(...) + local output = {} + for i = 1, select("#", ...) do + table.insert(output, tostring(select(i, ...))) + end + print(table.concat(output, ", ")) +end + +test("Hello", "world", "again", 2323, true) diff --git a/FreshShit/RaiderlosSA/spells.txt b/FreshShit/RaiderlosSA/spells.txt new file mode 100644 index 0000000..792a248 --- /dev/null +++ b/FreshShit/RaiderlosSA/spells.txt @@ -0,0 +1,548 @@ +##################################################################################### +### DEBUG ### +##################################################################################### + +##774!3 +Rejuvenation +##33763!3 +Lifebloom +##5185!3 +Healing Touch + +##################################################################################### +### Antorus ### +##################################################################################### + +########################################## +## Garothi ## +########################################## + +#244410!3 +Decimation +#246220!3 +Fel Bombardment +#244969!3 +Eradication +#244106!3 +Carnage + +########################################## +## Felhounds ## +########################################## + +#244086!3 +Molten Touch +#244768!3 +Desolate Gaze +#244057!3 +Enflame Corruption +#244131!3 +Consuming Sphere +#244056!3 +Siphon Corruption + +########################################## +## High Command ## +########################################## + +#245161!3 +Entropic Mine +#245546!3 +Summon Reinforcements + +########################################## +## Portal Keeper ## +########################################## + +#244016!3 +Reality Tear +#243983!3 +Collapsing World +#244000!3 +Felstorm Barrage + +########################################## +## Imonar ## +########################################## + +#247552!3 +Sleep Canister +#247367!3 +Shock Lance +#248068!3 +Empowered Pulse Grenade +#247376!3 +Pulse Grenade +#247716!3 +Charged Blasts +#247687!3 +Sever +#248070!3 +Empowered Shrapnel Blast +#250255!3 +Empowered Shock Lance + +########################################## +## Kin'garoth ## +########################################## + +#254919!3 +Forging Strike +#254926!3 +Reverberating Strike +#246840!3 +Ruiner +#246779!3 +Diabolic Bomb +#246706!3 +Demolish +#246664!3 +Annihilation + +########################################## +## Varimathras ## +########################################## + +#243960!3 +Shadow Strike +#243961!3 +Misery +#244042!3 +Marked Prey +#244093!3 +Necrotic Embrace +#248732!3 +Echoes of Doom +#243999!3 +Dark Fissure + +########################################## +## Coven ## +########################################## + +#253189!3 +Shivan Pact +#244899!1 +Fiery Strike +#245627!1 +Whirling Saber +#245281!3 +Shadow Blades +#245586!2 +Chilled Blood + +########################################## +## Aggramar ## +########################################## + +#254452!3 +Ravenous Blaze +#244693!3 +Wake of Flame +#244291!1 +Foe Braker +#244033!1 +Flame Rend +#247079!1 +Empowered Flame Rend +#245983!3 +Flare +#246037!3 +Empowered Flare + +########################################## +## Argus ## +########################################## + +#256457!3 +Cone of Death +#248396!3 +Soulblight +#257296!3 +Tortured Rage +#251570!3 +Soulbomb + +###################################################################################### +### DUNGEONS ### +###################################################################################### + +########################################## +## Black Rook Hold ## +########################################## + +#225573!3 +Dark Mending +#200105!3 +Sacrifice Soul +#225732!3 +Strike Down +#194996!3 +Soul Echoes +#195254!3 +Swirling Scythe +#194956!3 +Reap Soul +#200248!3 +Arcane Blitz +#200345!3 +Arrow Barrage +#200291!3 +Knife Dance +#200261!3 +Bonebreaking Strike +#197418!3 +Vengeful Shear +#201139!3 +Brutal Assault +#198245!3 +Brutal Haymaker +#198079!3 +Hateful Gaze + +########################################## +## Cathedral of Eternal Night ## +########################################## + +#241937!3 +Shadow Wall +#238543!3 +Demonic Mending +#242792!3 +Vile Roots +#236627!3 +Floral Fulmination +#239217!3 +Blinding Glare +#237726!3 +Scornful Gaze +#190620!3 +Felblaze Orb +#239268!3 +Venom Storm +#234107!3 +Chaotic Energy +#236543!3 +Felsoul Cleave +#238315!3 +Shadow Sweep +#243168!3 +Demonic Upheaval + +########################################## +## Court of Stars ## +########################################## + +#210261!3 +Sound Alarm +#215204!3 +Hinder +#209027!3 +Quelling Strike +#209516!3 +Mana Fang +#209485!3 +Drain Magic +#209404!3 +Seal Magic +#209495!3 +Charged Smash +#225100!3 +Charging Station +#219488!3 +Streetsweeper +#212784!3 +Eye Storm +#211464!3 +Fel Detonation +#207980!3 +Disintegration Beam +#207979!3 +Shockwave +#209628!3 +Piercing Gale +#209676!3 +Slicing Maelstrom + +########################################## +## Darkheart Thicket ## +########################################## + +#200631!3 +Unnerving Screech +#200580!3 +Maddening Roar +#191326!3 +Breath of Corruption +#201400!3 +Dread Inferno +#200238!3 +Feed on the Weak + +########################################## +## Eye of Azshara ## +########################################## + +#195172!3 +Mighty Slam +#195129!3 +Thundering Stomp +#195046!3 +Rejuvenating Waters +#162135!3 +Bellowing Roar +#197105!3 +Polymorh Fish +#193597!3 +Static Nova +#193611!3 +Focused Lightning +#196129!3 +Spray Sand +#196144!3 +Sandstorm +#196296!3 +Roiling Storm +#196290!3 +Chaotic Tempest +#191848!3 +Rampage + +########################################## +## Halls of Valor ## +########################################## + +#198605!3 +Thunderstrike +#198888!3 +Lightning Breath +#191284!3 +Horn of Valor +#198934!3 +Rune of Healing +#215433!3 +Holy Radiance +#199210!3 +Penetrating Shot +#191976!3 +Arcing Bolt +#192305!3 +Eye of the Storm +#192307!3 +Sanctify +#192048!3 +Expel Light +#192018!3 +Shield of Light +#196512!3 +Claw Frenzy +#199652!3 +Sever +#199726!3 +Unruly Yell +#199674!3 +Wicked Dagger +#193826!3 +Ragnarok +#198263!3 +Radiant Tempest +#198072!3 +Spear of Light +#197961!3 +Runic Band +#198750!3 +Surge + +########################################## +## Maw of Souls ## +########################################## + +#193364!3 +Screams of the Dead +#194442!3 +Six Pound Barrel +#194615!3 +Sea Legs +#192019!3 +Lantern of Darkness +#194099!3 +Bile Breath +#198405!3 +Bone Chilling Scream +#194325!3 +Fragment +#194216!3 +Cosmic Scythe +#195293!3 +Debilitating Shout +#185539!3 +Rapid Rupture +#198495!3 +Torrent +#202098!3 +Brackwater Barrage + +########################################## +## Neltharion's Lair ## +########################################## + +#202181!3 +Stone Gaze +#226296!3 +Piercing Shards +#188169!3 +Razor Shards +#198496!3 +Sunder +#199176!3 +Spiked Tongue +#193585!3 +Bound +#200700!3 +Landslide +#200732!3 +Molten Crash + +########################################## +## The Arcway ## +########################################## + +#211771!3 +Prophecies of Doom +#211037!3 +Celerity Zone +#195791!3 +Quarantine +#226285!3 +Demonic Ascension +#197810!3 +Wicked Slam +#211217!3 +Arcane Slicer +#211115!3 +Phase Breach +#196392!3 +Overcharge Mana +#200040!3 +Nether Venom +#200227!3 +Tangled Web +#220871!3 +Unstable Mana + +########################################## +## Vault of the Wardens ## +########################################## + +#193069!3 +Nightmares +#197799!3 +Unleash Fury +#191735!3 +Deafening Screech +#190836!3 +Hatred +#202913!3 +Fel Mortar +#200898!3 +Teleport +#199917!3 +Shadow Crash +#202658!3 +Drain +#194945!3 +Lingering Gaze +#196249!3 +Meteor +#192631!3 +Lava Wreath +#197513!3 +Detonating Moonglaive +#189469!3 +Turn Kick + +########################################## +## Seat of the Triumvirate ## +########################################## + +########################################## +## Upper Karazhan ## +########################################## + +#230083!3 +Nullification +#227267!3 +Summon Volatile Energy +#227254!3 +Evocation +#229662!3 +Fel Breath +#36247!3 +Fel Fireball +#227628!3 +Piercing Missiles +#227615!3 +Inferno Bolt +#227592!3 +Frostbite +#228269!3 +Flame Wreath +#227779!3 +Ceaseless Winter +#229706!3 +Leech Life +#229714!3 +Consume Magic +#229159!3 +Chaotic Shadows +#229083!3 +Burning Blast +#229151!3 +Disintegrate + +########################################## +## Lower Karazhan ## +########################################## + +#228221!3 +Severe Dusting +#228225!3 +Sultry Heat +#232153!3 +Kara Kazham +#227987!3 +Dinner Bell +#228025!3 +Heat Wave +#227568!3 +Burning Leg Sweep +#227776!3 +Magic Magnificent +#227966!3 +Flashlight +#228279!3 +Shadow Rejuvenation +#228278!3 +Demoralizing Shout +#228277!3 +Shackles of Servitude +#226316!3 +Shadow Bolt Volley +#227508!3 +Mass Repentance +#227793!3 +Sacred Ground +#227463!3 +Whirling Edge +#227646!3 +Iron Whirlwind +#227672!3 +Will Breaker +#227404!3 +Intangible Presence +#227493!3 +Mortal Strike +#228852!3 +Shared Suffering +#228837!3 +#Bellowing Roar \ No newline at end of file