commit 5648cd858d9c882eafdd72626d1e5c3969bbb70b Author: Chris Kaczor Date: Wed Dec 28 20:05:30 2022 -0500 Initial commit diff --git a/.pkgmeta b/.pkgmeta new file mode 100644 index 0000000..6e22a2f --- /dev/null +++ b/.pkgmeta @@ -0,0 +1,42 @@ +package-as: TuskarrCatchAndRelease + +externals: + Libs/LibStub: + url: https://repos.wowace.com/wow/libstub/trunk + tag: latest + Libs/CallbackHandler-1.0: + url: https://repos.wowace.com/wow/ace3/trunk/CallbackHandler-1.0 + tag: latest + Libs/LibQTip-1.0: + url: https://repos.wowace.com/wow/libqtip-1-0 + tag: latest + Libs/LibDataBroker-1.1: + url: git://github.com/tekkub/libdatabroker-1-1.git + tag: latest + Libs/AceLocale-3.0: + url: https://repos.wowace.com/wow/ace3/trunk/AceLocale-3.0 + tag: latest + Libs/AceConsole-3.0: + url: https://repos.wowace.com/wow/ace3/trunk/AceConsole-3.0 + tag: latest + Libs/AceAddon-3.0: + url: https://repos.wowace.com/wow/ace3/trunk/AceAddon-3.0 + tag: latest + Libs/AceEvent-3.0: + url: https://repos.wowace.com/wow/ace3/trunk/AceEvent-3.0 + tag: latest + Libs/AceTimer-3.0: + url: https://repos.wowace.com/wow/ace3/trunk/AceTimer-3.0 + tag: latest + Libs/AceConfig-3.0: + url: https://repos.wowace.com/wow/ace3/trunk/AceConfig-3.0 + tag: latest + Libs/AceDB-3.0: + url: https://repos.wowace.com/wow/ace3/trunk/AceDB-3.0 + tag: latest + Libs/AceGUI-3.0: + url: https://repos.wowace.com/wow/ace3/trunk/AceGUI-3.0 + tag: latest + Libs/LibDBIcon-1.0: + url: https://repos.wowace.com/wow/libdbicon-1-0/trunk/LibDBIcon-1.0 + tag: latest \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..fb86f25 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "cSpell.words": [ + "Amanoa", + "Iskaara", + "Tuskarr" + ] +} \ No newline at end of file diff --git a/Data.lua b/Data.lua new file mode 100644 index 0000000..8d2538f --- /dev/null +++ b/Data.lua @@ -0,0 +1,36 @@ +local ADDON_NAME, private = ... + +local L = LibStub("AceLocale-3.0"):GetLocale(ADDON_NAME) + +private.QUESTS = { + [72826] = { + NAME = L["Catch and Release: Aileron Seamoth"], + FISH_ID = 194967, + FISH_COUNT = 20 + }, + [72825] = { + NAME = L["Catch and Release: Cerulean Spinefish"], + FISH_ID = 194968, + FISH_COUNT = 20 + }, + [72823] = { + NAME = L["Catch and Release: Islefin Dorado"], + FISH_ID = 194970, + FISH_COUNT = 20 + }, + [72828] = { + NAME = L["Catch and Release: Scalebelly Mackerel"], + FISH_ID = 194730, + FISH_COUNT = 20 + }, + [72824] = { + NAME = L["Catch and Release: Temporal Dragonhead"], + FISH_ID = 194969, + FISH_COUNT = 20 + }, + [72827] = { + NAME = L["Catch and Release: Thousandbite Piranha"], + FISH_ID = 194966, + FISH_COUNT = 20 + } +} diff --git a/Locale/deDE.lua b/Locale/deDE.lua new file mode 100644 index 0000000..857bf9c --- /dev/null +++ b/Locale/deDE.lua @@ -0,0 +1,8 @@ +local ADDON_NAME = ... + +local L = LibStub("AceLocale-3.0"):NewLocale(ADDON_NAME, "deDE") +if not L then + return +end + +-- @localization(locale="deDE", format="lua_additive_table")@ diff --git a/Locale/enUS.lua b/Locale/enUS.lua new file mode 100644 index 0000000..8dfc149 --- /dev/null +++ b/Locale/enUS.lua @@ -0,0 +1,31 @@ +local ADDON_NAME = ... + +local L = LibStub("AceLocale-3.0"):NewLocale(ADDON_NAME, "enUS", true, false) +if not L then + return +end + +L["Tuskarr Catch and Release"] = true +L["Catch and Release: Scalebelly Mackerel"] = true +L["Catch and Release: Thousandbite Piranha"] = true +L["Catch and Release: Aileron Seamoth"] = true +L["Catch and Release: Cerulean Spinefish"] = true +L["Catch and Release: Temporal Dragonhead"] = true +L["Catch and Release: Islefin Dorado"] = true +L["Disabled until level 10"] = true +L["Loading..."] = true +L["|cFF00FF00Complete|r"] = true +L["|cFFFF0000Not Complete|r"] = true +L["Loaded"] = true +L["Done"] = true +L["Show minimap icon"] = true +L["Shows or hides the minimap icon"] = true +L["|cFFFFFF00Click|r the main button to toggle whether the tooltip stays open"] = true +L["|cFFFFFF00Right Click|r the main button to cycle through which quest to track"] = true +L["Quest"] = true +L["Fish"] = true +L["Have"] = true +L["Status"] = true +L["Need"] = true +L["Gather:"] = true +L["Turn In:"] = true diff --git a/Locale/frFR.lua b/Locale/frFR.lua new file mode 100644 index 0000000..d834465 --- /dev/null +++ b/Locale/frFR.lua @@ -0,0 +1,8 @@ +local ADDON_NAME = ... + +local L = LibStub("AceLocale-3.0"):NewLocale(ADDON_NAME, "frFR") +if not L then + return +end + +-- @localization(locale="frFR", format="lua_additive_table")@ diff --git a/Locale/itIT.lua b/Locale/itIT.lua new file mode 100644 index 0000000..41d4bdb --- /dev/null +++ b/Locale/itIT.lua @@ -0,0 +1,8 @@ +local ADDON_NAME = ... + +local L = LibStub("AceLocale-3.0"):NewLocale(ADDON_NAME, "itIT") +if not L then + return +end + +-- @localization(locale="itIT", format="lua_additive_table")@ diff --git a/Locale/ruRU.lua b/Locale/ruRU.lua new file mode 100644 index 0000000..73cb818 --- /dev/null +++ b/Locale/ruRU.lua @@ -0,0 +1,8 @@ +local ADDON_NAME = ... + +local L = LibStub("AceLocale-3.0"):NewLocale(ADDON_NAME, "ruRU") +if not L then + return +end + +-- @localization(locale="ruRU", format="lua_additive_table")@ diff --git a/Locale/zhTW.lua b/Locale/zhTW.lua new file mode 100644 index 0000000..360d35c --- /dev/null +++ b/Locale/zhTW.lua @@ -0,0 +1,8 @@ +local ADDON_NAME = ... + +local L = LibStub("AceLocale-3.0"):NewLocale(ADDON_NAME, "zhTW") +if not L then + return +end + +-- @localization(locale="zhTW", format="lua_additive_table")@ diff --git a/README.md b/README.md new file mode 100644 index 0000000..a754ef5 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# TuskarrCatchAndRelease diff --git a/Sort.lua b/Sort.lua new file mode 100644 index 0000000..8014904 --- /dev/null +++ b/Sort.lua @@ -0,0 +1,50 @@ +local ADDON_NAME, private = ... + +private.SORT_FUNCTIONS = { + NAME_ASC = function(a, b) + return a["NAME"] < b["NAME"] + end, + FISH_ASC = function(a, b) + return a["FISH"] < b["FISH"] + end, + AMOUNT_ASC = function(a, b) + if (a["AMOUNT"] == b["AMOUNT"]) then + return a["NAME"] < b["NAME"] + else + return a["AMOUNT"] < b["AMOUNT"] + end + end, + STATUS_ASC = function(a, b) + if (a["STATUS"] == b["STATUS"]) then + return a["NAME"] < b["NAME"] + else + return a["STATUS"] < b["STATUS"] + end + end, + NEED_ASC = function(a, b) + return a["NEED"] < b["NEED"] + end, + NAME_DESC = function(a, b) + return a["NAME"] > b["NAME"] + end, + FISH_DESC = function(a, b) + return a["FISH"] > b["FISH"] + end, + AMOUNT_DESC = function(a, b) + if (a["AMOUNT"] == b["AMOUNT"]) then + return a["NAME"] < b["NAME"] + else + return a["AMOUNT"] > b["AMOUNT"] + end + end, + STATUS_DESC = function(a, b) + if (a["STATUS"] == b["STATUS"]) then + return a["NAME"] < b["NAME"] + else + return a["STATUS"] > b["STATUS"] + end + end, + NEED_DESC = function(a, b) + return a["NEED"] > b["NEED"] + end +} diff --git a/TuskarrCatchAndRelease.lua b/TuskarrCatchAndRelease.lua new file mode 100644 index 0000000..b51a202 --- /dev/null +++ b/TuskarrCatchAndRelease.lua @@ -0,0 +1,417 @@ +local ADDON_NAME, private = ... + +TuskarrCatchAndRelease = LibStub("AceAddon-3.0"):NewAddon(ADDON_NAME, "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0") +local L = LibStub("AceLocale-3.0"):GetLocale(ADDON_NAME) +local LibQTip = LibStub("LibQTip-1.0") +local LibDBIcon = LibStub("LibDBIcon-1.0") +local AceConfig = LibStub("AceConfig-3.0") + +local _ + +local defaults = { + global = { + sort_field = "NAME", + sort_dir = "ASC", + minimap_icon = { + hide = false + } + } +} + +local options = { + name = L["Tuskarr Catch and Release"], + type = "group", + args = { + minimap_icon = { + order = 1, + type = "toggle", + name = L["Show minimap icon"], + desc = L["Shows or hides the minimap icon"], + get = function() + return not private.db.global.minimap_icon.hide + end, + set = function(info, value) + private.db.global.minimap_icon.hide = not value + TuskarrCatchAndRelease:UpdateMinimapConfig() + end + } + } +} + +local LDB = LibStub("LibDataBroker-1.1"):NewDataObject(ADDON_NAME, { + type = "data source", + icon = "Interface\\Icons\\Inv_fishing_netlinen01", + label = L["Tuskarr Catch and Release"], + text = L["Tuskarr Catch and Release"], + OnClick = function(clickedframe, button) + if not private.loaded then + return + end + + if button == "LeftButton" then + if (private.pinned) then + private.tooltip:SetAutoHideDelay(0.25, self) + + private.pinned = false + else + private.tooltip:SetAutoHideDelay() + + private.pinned = true + end + elseif button == "RightButton" then + private.need_index = private.need_index + 1 + + TuskarrCatchAndRelease:UpdateText() + end + end +}) + +function TuskarrCatchAndRelease:OnInitialize() + private.pinned = false + private.need_index = 1 + private.loaded = false + private.item_name_table = {} + + -- Create the database with defaults + private.db = LibStub("AceDB-3.0"):New("TuskarrCatchAndReleaseDB", defaults) + + -- Register options + AceConfig:RegisterOptionsTable(ADDON_NAME, options, {"/tcr"}) + + -- Add to the options frame + private.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions(ADDON_NAME, L["Tuskarr Catch and Release"]) + + -- Register a chat command + self:RegisterChatCommand("tcr", "ChatCommand") + + -- Register the minimap icon + LibDBIcon:Register(ADDON_NAME, LDB, private.db.global.minimap_icon) +end + +function TuskarrCatchAndRelease:OnEnable() + -- Disable if the player is less than 10 + if (UnitLevel("player") < 10) then + LDB.text = L["Disabled until level 10"] + + -- Register to get player level events + self:RegisterEvent("PLAYER_LEVEL_UP") + + return + end + + -- Do the real enable + TuskarrCatchAndRelease:OnEnableCore() +end + +function TuskarrCatchAndRelease:PLAYER_LEVEL_UP(event, newLevel) + if (tonumber(newLevel) >= 10) then + -- Do the real enable + TuskarrCatchAndRelease:OnEnableCore() + + -- Done with player level events + self:UnregisterEvent("PLAYER_LEVEL_UP") + end +end + +function TuskarrCatchAndRelease:OnEnableCore() + -- Show loading text + TuskarrCatchAndRelease:Print(L["Loading..."]) + LDB.text = L["Loading..."] + + -- Load item info from cache + TuskarrCatchAndRelease:LoadCache() +end + +function TuskarrCatchAndRelease:LoadCache() + local item_count = 0 + local item_loaded_count = 0 + local item_table = {} + + private.item_name_table = {} + + -- Loop over each quest in the data + for _, quest_info in pairs(private.QUESTS) do + + -- Get the item ID of the fish + local fish_id = quest_info["FISH_ID"] + + -- Add the fish to the list of items + item_table[fish_id] = Item:CreateFromItemID(fish_id) + item_count = item_count + 1 + end + + -- Loop over all items we need to cache + for _, item in pairs(item_table) do + + -- Wait for the item to load + item:ContinueOnItemLoad(function() + + -- Save the name + private.item_name_table[item:GetItemID()] = item:GetItemName() + item_loaded_count = item_loaded_count + 1 + + -- If everything is cached we're good to go + if (item_count == item_loaded_count) then + TuskarrCatchAndRelease:OnLoaded(self) + end + end) + end +end + +function TuskarrCatchAndRelease:OnLoaded(self) + -- Show loaded text + TuskarrCatchAndRelease:Print(L["Loaded"]) + LDB.text = L["Loaded"] + + self:RegisterEvent("QUEST_LOG_UPDATE") + self:RegisterEvent("BAG_UPDATE") + + TuskarrCatchAndRelease:UpdateData() + TuskarrCatchAndRelease:UpdateText() + + private.loaded = true +end + +local function SetSort(cell, sort) + if private.db.global.sort_field == sort then + if (private.db.global.sort_dir == "ASC") then + private.db.global.sort_dir = "DESC" + else + private.db.global.sort_dir = "ASC" + end + else + private.db.global.sort_field = sort + private.db.global.sort_dir = "ASC" + end + + if not private.loaded then + return + end + + TuskarrCatchAndRelease:UpdateData() + TuskarrCatchAndRelease:UpdateTooltip() +end + +function TuskarrCatchAndRelease:UpdateData() + + -- Create a table to store all needs + private.need_table = {} + private.need_count = 0 + + -- Create a table to hold the information to display for each quest + private.quest_table = {} + private.quest_count = 0 + + -- Loop over each quest in the data + for quest_id, quest_info in pairs(private.QUESTS) do + + -- Check if the quest is completed + local is_completed = C_QuestLog.IsQuestFlaggedCompleted(quest_id) + + -- Get the ID of the fish required for this quest + local fish_id = quest_info["FISH_ID"] + + -- Get the name of the fish for display + local fish_name = private.item_name_table[fish_id] + + -- Get how many of the fish we have in our bags + local fish_count = GetItemCount(fish_id, true, false) + + -- Get the number of items required + local required_count = quest_info["FISH_COUNT"] + + -- Color the fish count based on whether there is enough in the bags or not + local fish_count_display = + (fish_count >= required_count) and "|cFF00FF00" .. fish_count .. "|r" or "|cFFFFFF00" .. fish_count .. "|r" + + -- Initialize need and status strings + local need_count = 0 + local quest_status = "" + local can_craft = 0 + + -- Figure out how many of the fish we need to get to what we need + need_count = (fish_count < required_count) and required_count - fish_count or 0 + + if (is_completed) then + -- Quest has already been completed today + quest_status = L["|cFF00FF00Complete|r"] + else + -- Quest still needs to be done + quest_status = L["|cFFFF0000Not Complete|r"] + + private.need_table[quest_id] = need_count + private.need_count = private.need_count + 1 + end + + -- Insert everything we figured out into the quest table + table.insert(private.quest_table, { + NAME = quest_info["NAME"], + NAME_DISPLAY = "|cffeda55f" .. quest_info["NAME"] .. "|r", + FISH = fish_name, + FISH_DISPLAY = fish_name, + AMOUNT = fish_count, + AMOUNT_DISPLAY = fish_count_display, + STATUS = quest_status, + NEED = need_count + }) + + private.quest_count = private.quest_count + 1 + end + + -- Sort the quest table using the sort field and direction from the settings + table.sort(private.quest_table, + private.SORT_FUNCTIONS[private.db.global.sort_field .. "_" .. private.db.global.sort_dir]) +end + +function TuskarrCatchAndRelease:UpdateTooltip() + if LibQTip:IsAcquired(ADDON_NAME) then + private.tooltip:Clear() + else + private.tooltip = LibQTip:Acquire(ADDON_NAME, 5) + + private.tooltip:SetBackdropColor(0, 0, 0, 1) + + private.tooltip:SmartAnchorTo(private.LDB_ANCHOR) + private.tooltip:SetAutoHideDelay(0.25, private.LDB_ANCHOR) + end + + -- Add the header line and set the cell text and scripts + local line = private.tooltip:AddHeader() + + private.tooltip:SetCell(line, 1, L["Quest"]) + private.tooltip:SetCellScript(line, 1, "OnMouseUp", SetSort, "NAME") + + private.tooltip:SetCell(line, 2, L["Fish"]) + private.tooltip:SetCellScript(line, 2, "OnMouseUp", SetSort, "FISH") + + private.tooltip:SetCell(line, 3, L["Have"]) + private.tooltip:SetCellScript(line, 3, "OnMouseUp", SetSort, "AMOUNT") + + private.tooltip:SetCell(line, 4, L["Status"]) + private.tooltip:SetCellScript(line, 4, "OnMouseUp", SetSort, "STATUS") + + private.tooltip:SetCell(line, 5, L["Need"]) + private.tooltip:SetCellScript(line, 5, "OnMouseUp", SetSort, "NEED") + + private.tooltip:AddSeparator() + + -- Loop over all quests in the sorted table + for _, quest in pairs(private.quest_table) do + + -- Add the line with info about the current quest + line = private.tooltip:AddLine(quest["NAME_DISPLAY"], quest["FISH_DISPLAY"], quest["AMOUNT_DISPLAY"], + quest["STATUS"], quest["NEED"]) + end + + -- Add the normal usage hints + private.tooltip:AddLine(" ") + + line = private.tooltip:AddLine() + private.tooltip:SetCell(line, 1, L["|cFFFFFF00Click|r the main button to toggle whether the tooltip stays open"], + "LEFT", private.tooltip:GetColumnCount()) + + line = private.tooltip:AddLine() + private.tooltip:SetCell(line, 1, L["|cFFFFFF00Right Click|r the main button to cycle through which quest to track"], + "LEFT", private.tooltip:GetColumnCount()) +end + +function TuskarrCatchAndRelease:UpdateText() + local need_index = 1 + + if (private.need_index > private.need_count) then + private.need_index = 1 + end + + if (private.need_count == 0) then + LDB.text = L["Done"] + return + end + + -- Loop over the need table + for quest_id, need_count in pairs(private.need_table) do + if need_index == private.need_index then + local fish_id = private.QUESTS[quest_id]["FISH_ID"] + + if need_count == 0 then + LDB.text = L["Turn In:"] .. " " .. private.item_name_table[fish_id] + else + LDB.text = L["Gather:"] .. " " .. need_count .. " " .. private.item_name_table[fish_id] + end + + return + end + + need_index = need_index + 1 + end +end + +function LDB.OnEnter(self) + if not private.loaded then + return + end + + private.LDB_ANCHOR = self + TuskarrCatchAndRelease:UpdateTooltip() + + private.tooltip:Show() +end + +function TuskarrCatchAndRelease:QUEST_LOG_UPDATE() + if not private.loaded then + return + end + + TuskarrCatchAndRelease:UpdateData() + TuskarrCatchAndRelease:UpdateText() + + if not private.LDB_ANCHOR then + return + end + + TuskarrCatchAndRelease:UpdateTooltip() +end + +function TuskarrCatchAndRelease:BAG_UPDATE() + if not private.loaded then + return + end + + TuskarrCatchAndRelease:UpdateData() + TuskarrCatchAndRelease:UpdateText() + + if not private.LDB_ANCHOR then + return + end + + TuskarrCatchAndRelease:UpdateTooltip() +end + +function TuskarrCatchAndRelease:UpdateMinimapConfig() + if private.db.global.minimap_icon.hide then + LibDBIcon:Hide(ADDON_NAME) + else + LibDBIcon:Show(ADDON_NAME) + end +end + +function TuskarrCatchAndRelease:ChatCommand(input) + + local command, arg1 = self:GetArgs(input, 2) + + if (command == nil) then + command = "" + end + + command = command:lower() + + if command == L["config"]:lower() then + InterfaceOptionsFrame_OpenToCategory(private.optionsFrame) + elseif command == L["minimap"]:lower() then + private.db.global.minimap_icon.hide = not private.db.global.minimap_icon.hide + TuskarrCatchAndRelease:UpdateMinimapConfig() + else + TuskarrCatchAndRelease:Print(L["Available commands:"]) + TuskarrCatchAndRelease:Print("|cFF00C0FF" .. L["config"] .. "|r - " .. L["Show configuration"]) + TuskarrCatchAndRelease:Print("|cFF00C0FF" .. L["minimap"] .. "|r - " .. L["Toggles the minimap icon"]) + end +end diff --git a/TuskarrCatchAndRelease.toc b/TuskarrCatchAndRelease.toc new file mode 100644 index 0000000..b2b75a4 --- /dev/null +++ b/TuskarrCatchAndRelease.toc @@ -0,0 +1,31 @@ +## Interface: 100000 +## Title: Tuskarr Catch and Release +## Version: 10.0.0 +## Notes: Helps with the weekly Iskaara Tuskarr fishing quests ("Catch and Release") by keeping track of what quests have been completed and what fish are required. +## Author: Amanoa +## SavedVariables: TuskarrCatchAndReleaseDB +## OptionalDeps: Ace3, AceEvent-3.0, LibQTip-1.0, LibStub, AceTimer-3.0, AceConsole-3.0 + +#@no-lib-strip@ +Libs\LibStub\LibStub.lua +Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml +Libs\AceAddon-3.0\AceAddon-3.0.xml +Libs\AceConsole-3.0\AceConsole-3.0.xml +Libs\AceEvent-3.0\AceEvent-3.0.xml +Libs\AceLocale-3.0\AceLocale-3.0.xml +Libs\AceTimer-3.0\AceTimer-3.0.xml +Libs\AceDB-3.0\AceDB-3.0.xml +Libs\AceGUI-3.0\AceGUI-3.0.xml +Libs\AceConfig-3.0\AceConfig-3.0.xml +Libs\LibQTip-1.0\lib.xml +Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua +Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua +#@end-no-lib-strip@ + +Locale\enUS.lua +Locale\frFR.lua +Locale\deDE.lua + +Data.lua +Sort.lua +TuskarrCatchAndRelease.lua