From b3714f6e822c8ac17980bb2489ac30f297c89cd6 Mon Sep 17 00:00:00 2001 From: jordonwow <29447509+jordonwow@users.noreply.github.com> Date: Tue, 14 May 2024 03:10:58 -0700 Subject: [PATCH] Initial commit --- .editorconfig | 13 +++ .github/workflows/build.yml | 29 ++++++ .luacheckrc | 37 +++++++ .pkgmeta | 1 + Core.lua | 191 ++++++++++++++++++++++++++++++++++++ Items.lua | 59 +++++++++++ README.md | 57 +++++++++++ TeleportCloak.toc | 13 +++ 8 files changed, 400 insertions(+) create mode 100644 .editorconfig create mode 100644 .github/workflows/build.yml create mode 100644 .luacheckrc create mode 100644 .pkgmeta create mode 100644 Core.lua create mode 100644 Items.lua create mode 100644 README.md create mode 100644 TeleportCloak.toc diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ca30253 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[.pkgmeta] +indent_size = 2 +indent_style = space diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..4b3003e --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,29 @@ +name: Build + +on: + push: + tags: + - '*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Run Luacheck + uses: nebularg/actions-luacheck@v1 + with: + args: '--no-color -q' + annotate: warning + + - name: Package and Release + uses: BigWigsMods/packager@master + env: + CF_API_KEY: ${{ secrets.CF_API_KEY }} + GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }} + WAGO_API_TOKEN: ${{ secrets.WAGO_API_TOKEN }} + WOWI_API_TOKEN: ${{ secrets.WOWI_API_TOKEN }} diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..d31c79c --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,37 @@ +std = "lua51" +max_line_length = false +exclude_files = { + ".luacheckrc", +} +ignore = { + "212/self", +} +read_globals = { + "C_AddOns", + "C_Item", + "CreateFrame", + "GetInventoryItemID", + "GetTime", + "InCombatLockdown", + "INVSLOT_BACK", + "INVSLOT_FEET", + "INVSLOT_FINGER1", + "INVSLOT_FINGER2", + "INVSLOT_NECK", + "INVSLOT_TABARD", + "INVSLOT_TRINKET1", + "INVSLOT_TRINKET2", + "INVTYPE_CLOAK", + "INVTYPE_FEET", + "INVTYPE_FINGER", + "INVTYPE_NECK", + "INVTYPE_TABARD", + "INVTYPE_TRINKET", + "tinsert", + "UIParent", + "wipe", +} +globals = { + "SlashCmdList", + "TeleportCloakDB", +} diff --git a/.pkgmeta b/.pkgmeta new file mode 100644 index 0000000..73e2485 --- /dev/null +++ b/.pkgmeta @@ -0,0 +1 @@ +package-as: TeleportCloak diff --git a/Core.lua b/Core.lua new file mode 100644 index 0000000..7d3f6d6 --- /dev/null +++ b/Core.lua @@ -0,0 +1,191 @@ +local Private = select(2, ...) +local TeleportCloak = CreateFrame("Button", "TeleportCloak", UIParent, "SecureActionButtonTemplate") +TeleportCloak:RegisterEvent("ADDON_LOADED") +TeleportCloak:SetMouseClickEnabled(true) +TeleportCloak:SetAttribute("pressAndHoldAction", true) +TeleportCloak:SetAttribute("typerelease", "item") + +local TeleportItems = Private.Items + +local EquipItemByName, GetInventoryItemID, GetItemCooldown, GetItemCount, GetItemInfo, + GetItemInfoInstant, GetTime, InCombatLockdown, pairs, print, tinsert, wipe = + C_Item.EquipItemByName, GetInventoryItemID, C_Item.GetItemCooldown, C_Item.GetItemCount, C_Item.GetItemInfo, + C_Item.GetItemInfoInstant, GetTime, InCombatLockdown, pairs, print, tinsert, wipe + +function TeleportCloak:Print(...) + print("|cff33ff99TeleportCloak:|r ", ...) +end + +local InventoryTypes = { + cloaks = INVTYPE_CLOAK, + feet = INVTYPE_FEET, + necks = INVTYPE_NECK, + rings = INVTYPE_FINGER, + tabards = INVTYPE_TABARD, + trinkets = INVTYPE_TRINKET, +} + +function TeleportCloak:Command(msg) + local cmd, arg = (msg or ""):lower():match("^(%S*)%s*(.-)$") + if cmd == "add" then + if arg == "" then + self:Print("Usage: |cff80ffc0/tc add |r") + else + if InventoryTypes[arg] then + for _, item in pairs(TeleportItems[InventoryTypes[arg]]) do + tinsert(self.items, item) + end + else + local itemId = GetItemInfoInstant(arg) + if (not itemId) then + self:Print("Item not found:", arg) + else + tinsert(self.items, itemId) + end + end + end + return + elseif cmd == "warnings" then + self.db.warnings = not self.db.warnings + else + print("|cff33ff99TeleportCloak", self.Version, "|r") + self:Print("Add |cff80ffc0/click TeleportCloak|r", + "to a macro, and TeleportCloak will use your equipped teleport item,", + "or attempt to equip one if none are equipped.") + self:Print("To limit to specific items, add", + "|cff80ffc0/tc add |r", + "for each item or type to the beginning of the macro.") + self:Print("|cff80ffc0|r can be an item ID or item name") + local types = "|cff80ffc0|r can be" + for inventoryType, _ in pairs(InventoryTypes) do + types = types.." |cff80ffc0"..inventoryType.."|r," + end + self:Print(types, "and will add all items of that type.") + + end + self:Print("Warnings are", + self.db.warnings and "|cff19ff19Enabled|r." or "|cffff2020Disabled|r.", + "To turn them", + self.db.warnings and "off," or "on,", + "type |cff80ffc0/tc warnings|r") +end + +function TeleportCloak:IsTeleportItem(item) + for _, items in pairs(TeleportItems) do + for _, teleportItem in pairs(items) do + if item == teleportItem then + return true + end + end + end + return false +end + +local InventorySlots = { + INVSLOT_NECK, + INVSLOT_FEET, + INVSLOT_FINGER1, + INVSLOT_FINGER2, + INVSLOT_TRINKET1, + INVSLOT_TRINKET2, + INVSLOT_BACK, + INVSLOT_TABARD, +} + +TeleportCloak:SetScript("OnEvent", function(self, event, ...) + if event == "ADDON_LOADED" then + local addon = ... + if addon == "TeleportCloak" then + self:UnregisterEvent("ADDON_LOADED") + self.items = {} + + -- Set version + self.Version = C_AddOns.GetAddOnMetadata("TeleportCloak", "Version") or "" + if self.Version:sub(1, 1) == "@" then + self.Version = "Development Version" + end + + -- Initialize saved variables + TeleportCloakDB = TeleportCloakDB or { warnings = true } + self.db = TeleportCloakDB + self.db.saved = self.db.saved or {} + + -- Register events + self:RegisterEvent("PLAYER_ENTERING_WORLD") + self:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") + self:RegisterEvent("ZONE_CHANGED_INDOORS") + self:RegisterEvent("ZONE_CHANGED_NEW_AREA") + self:RegisterEvent("ZONE_CHANGED") + + -- Register slash commands + _G["SLASH_TeleportCloak1"] = "/teleportcloak" + _G["SLASH_TeleportCloak2"] = "/tc" + SlashCmdList.TeleportCloak = function(msg) TeleportCloak:Command(msg) end + end + return + end + + if event == "PLAYER_ENTERING_WORLD" or event == "PLAYER_EQUIPMENT_CHANGED" then + -- Save equipped items + for _, slot in pairs(InventorySlots) do + local item = GetInventoryItemID("player", slot) + -- Save the item if it's not a teleport item + if item and (not self:IsTeleportItem(item)) then + self.db.saved[slot] = item + end + end + return + end + + -- Wait to restore until out of combat + if InCombatLockdown() then + -- A restore was requested while in combat + self:RegisterEvent("PLAYER_REGEN_ENABLED") + return + end + if event == "PLAYER_REGEN_ENABLED" then + self:UnregisterEvent("PLAYER_REGEN_ENABLED") + end + + -- Restore equipped items + for _, slot in pairs(InventorySlots) do + local item = GetInventoryItemID("player", slot) + if item and self:IsTeleportItem(item) then + if (not self.db.saved[slot]) then + if self.db.warnings then + TeleportCloak:Print(select(2, GetItemInfo(item)), "is equipped.") + end + else + EquipItemByName(self.db.saved[slot]) + end + end + end +end) + +TeleportCloak:SetScript("PreClick", function(self) + if InCombatLockdown() then return end + if (not self.items[1]) then + -- no items are set, default to cloaks + for _, item in pairs(TeleportItems[INVTYPE_CLOAK]) do + tinsert(self.items, item) + end + end + for _, item in pairs(self.items) do + local count = GetItemCount(item) + if count > 0 then + local startTime, duration = GetItemCooldown(item) + if (startTime == 0 or duration - (GetTime() - startTime) <= 30) then + self:SetAttribute("item", "item:"..item) + return + end + end + end + self:Print("All items are on cooldown.") +end) + +TeleportCloak:SetScript("PostClick", function(self) + wipe(self.items) + if (not InCombatLockdown()) then + self:SetAttribute("item", nil) + end +end) diff --git a/Items.lua b/Items.lua new file mode 100644 index 0000000..7d9baa5 --- /dev/null +++ b/Items.lua @@ -0,0 +1,59 @@ +local Private = select(2, ...) +Private.Items = { + [INVTYPE_CLOAK] = { + 63206, -- Wrap of Unity (Alliance) + 63207, -- Wrap of Unity (Horde) + 63352, -- Shroud of Cooperation (Alliance) + 63353, -- Shroud of Cooperation (Horde) + 65274, -- Cloak of Coordination (Horde) + 65360, -- Cloak of Coordination (Alliance) + }, + [INVTYPE_TRINKET] = { + 17690, -- Frostwolf Insignia Rank 1 + 17691, -- Stormpike Insignia Rank 1 + 17900, -- Stormpike Insignia Rank 2 + 17901, -- Stormpike Insignia Rank 3 + 17902, -- Stormpike Insignia Rank 4 + 17903, -- Stormpike Insignia Rank 5 + 17904, -- Stormpike Insignia Rank 6 + 17905, -- Frostwolf Insignia Rank 2 + 17906, -- Frostwolf Insignia Rank 3 + 17907, -- Frostwolf Insignia Rank 4 + 17908, -- Frostwolf Insignia Rank 5 + 17909, -- Frostwolf Insignia Rank 6 + 103678, -- Time-Lost Artifact + }, + [INVTYPE_FINGER] = { + 40585, -- Signet of the Kirin Tor + 40586, -- Band of the Kirin Tor + 44934, -- Loop of the Kirin Tor + 44935, -- Ring of the Kirin Tor + 45688, -- Inscribed Band of the Kirin Tor + 45689, -- Inscribed Loop of the Kirin Tor + 45690, -- Inscribed Ring of the Kirin Tor + 45691, -- Inscribed Signet of the Kirin Tor + 48954, -- Etched Band of the Kirin Tor + 48955, -- Etched Loop of the Kirin Tor + 48956, -- Etched Ring of the Kirin Tor + 48957, -- Etched Signet of the Kirin Tor + 51557, -- Runed Signet of the Kirin Tor + 51558, -- Runed Loop of the Kirin Tor + 51559, -- Runed Ring of the Kirin Tor + 51560, -- Runed Band of the Kirin Tor + 95050, -- Brassiest Knuckle (Horde) + 95051, -- Brassiest Knuckle (Alliance) + 139599, -- Empowered Ring of the Kirin Tor + }, + [INVTYPE_FEET] = { + 28585, -- Ruby Slippers + 50287, -- Boots of the Bay + }, + [INVTYPE_NECK] = { + 32757, -- Blessed Medallion of Karabor + }, + [INVTYPE_TABARD] = { + 46874, -- Argent Crusader's Tabard + 63378, -- Hellscream's Reach Tabard + 63379, -- Baradin's Wardens Tabard + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..1a0ac01 --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# TeleportCloak + +TeleportCloak saves your currently equipped item when you switch to a teleport item and automatically re-equips it after teleporting. + +[Open a ticket to report any issues](https://github.com/jordonwow/teleportcloak/issues) + +[Submit a pull request](https://github.com/jordonwow/teleportcloak/pulls) + +## Supported Items + +* [Cloak of Coordination](https://www.wowhead.com/item=65360) +* [Wrap of Unity](https://www.wowhead.com/item=63206) +* [Shroud of Cooperation](https://www.wowhead.com/item=63352) +* [Ring of the Kirin Tor](https://www.wowhead.com/item=44935) +* [Time-Lost Artifact](https://www.wowhead.com/item=103678) +* [Stormpike Insignia](https://www.wowhead.com/item=17691) +* [Frostwolf Insignia](https://www.wowhead.com/item=17690) +* [Boots of the Bay](https://www.wowhead.com/item=50287) +* [Ruby Slippers](https://www.wowhead.com/item=28585) +* [Blessed Medallion of Karabor](https://www.wowhead.com/item=32757) +* [Brassiest Knuckle](https://www.wowhead.com/item=95051) +* [Argent Crusader's Tabard](https://www.wowhead.com/item=46874) +* [Hellscream's Reach Tabard](https://www.wowhead.com/item=63378) +* [Baradin's Wardens Tabard](https://www.wowhead.com/item=63379) + +## Usage + +You can manually equip and use teleport items, or you can add `/click TeleportCloak` to a macro. Clicking the macro once equips a teleport cloak from your inventory, and clicking it again uses the item. + +After using a teleport item, TeleportCloak will attempt to re-equip your previously equipped item. If this restoration fails, a warning will be displayed. You can toggle warnings on or off by typing `/tc warnings`. + +## Macros + +### Specific Items + +If you wish to limit a TeleportCloak macro to a specific set of items, you can do so by adding `/tc add ` before `/click TeleportCloak` for each item. + +``` +/tc add Boots of the Bay +/tc add Ruby Slippers +/click TeleportCloak +``` + +### Specific Types + +You can also `/tc add ` to limit the macro to a specific type. Valid types are: `cloaks`, `feet`, `necks`, `rings`, `tabards`, `trinkets` + +``` +/tc add rings +/click TeleportCloak +``` + +Items added with `/tc add` will be reset after each click. + +## Contributors +* [@petewooley](https://github.com/peterwooley) +* Kanegasi diff --git a/TeleportCloak.toc b/TeleportCloak.toc new file mode 100644 index 0000000..35470a7 --- /dev/null +++ b/TeleportCloak.toc @@ -0,0 +1,13 @@ +## Interface: 11502, 100207, 40400, 110000 +## Title: TeleportCloak +## Notes: Saves your currently equipped item when you switch to a teleport item and automatically re-equips it after teleporting. +## Version: @project-version@ +## Author: Jordon +## SavedVariablesPerCharacter: TeleportCloakDB +## IconTexture: Interface\Icons\inv_guild_cloak_alliance_a +## X-Curse-Project-ID: 81148 +## X-Wago-ID: YK9EWlKL +## X-WoWI-ID: 26733 + +Items.lua +Core.lua