├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── .luacheckrc
├── .pkgmeta
├── Locales
├── Locales.xml
├── deDE.lua
├── enUS.lua
├── frFR.lua
├── koKR.lua
├── ptBR.lua
├── zhCN.lua
└── zhTW.lua
├── Media
└── Textures
│ └── icon.blp
├── OmniBar.lua
├── OmniBar.toc
├── OmniBar.xml
├── OmniBar_Cata.lua
├── OmniBar_Cata.toc
├── OmniBar_Mainline.lua
├── OmniBar_TBC.lua
├── OmniBar_TBC.toc
├── OmniBar_Vanilla.lua
├── OmniBar_Vanilla.toc
├── OmniBar_Wrath.lua
├── OmniBar_Wrath.toc
├── Options.lua
└── README.md
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | tags:
6 | - '*'
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v4
14 | with:
15 | fetch-depth: 0
16 |
17 | - name: Run Luacheck
18 | uses: nebularg/actions-luacheck@v1
19 | with:
20 | args: '--no-color -q'
21 | annotate: warning
22 |
23 | - name: Package and Release
24 | uses: BigWigsMods/packager@master
25 | env:
26 | CF_API_KEY: ${{ secrets.CF_API_KEY }}
27 | GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }}
28 | WAGO_API_TOKEN: ${{ secrets.WAGO_API_TOKEN }}
29 | WOWI_API_TOKEN: ${{ secrets.WOWI_API_TOKEN }}
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Libs
2 | .release
3 |
--------------------------------------------------------------------------------
/.luacheckrc:
--------------------------------------------------------------------------------
1 | std = "lua51"
2 | max_line_length = false
3 | exclude_files = {
4 | ".luacheckrc",
5 | "Libs/",
6 | }
7 | ignore = {
8 | "11./SLASH_.*",
9 | "211",
10 | "212",
11 | "213",
12 | "311",
13 | "423",
14 | "431",
15 | "432",
16 | "433",
17 | }
18 | read_globals = {
19 | "ARENA",
20 | "CLASS_ICON_TCOORDS",
21 | "CLASS_SORT_ORDER",
22 | "COMBATLOG_FILTER_STRING_UNKNOWN_UNITS",
23 | "COMBATLOG_OBJECT_AFFILIATION_MINE",
24 | "COMBATLOG_OBJECT_REACTION_HOSTILE",
25 | "COMBATLOG_OBJECT_TYPE_PLAYER",
26 | "C_AddOns",
27 | "C_PvP",
28 | "C_Spell",
29 | "C_Timer",
30 | "CanInspect",
31 | "ClearInspectPlayer",
32 | "CombatLogGetCurrentEventInfo",
33 | "CreateFrame",
34 | "DEFAULT_CHAT_FRAME",
35 | "DELETE",
36 | "FOCUS",
37 | "GENERAL",
38 | "GetAddOnMetadata",
39 | "GetArenaOpponentSpec",
40 | "GetBattlefieldScore",
41 | "GetClassInfo",
42 | "GetInspectSpecialization",
43 | "GetNumBattlefieldScores",
44 | "GetNumGroupMembers",
45 | "GetNumSpecializationsForClassID",
46 | "GetPlayerInfoByGUID",
47 | "GetRaidRosterInfo",
48 | "GetServerTime",
49 | "GetSpecialization",
50 | "GetSpecializationInfo",
51 | "GetSpecializationInfoByID",
52 | "GetSpecializationInfoForClassID",
53 | "GetSpellDescription",
54 | "GetSpellInfo",
55 | "GetSpellTexture",
56 | "GetTime",
57 | "GetUnitName",
58 | "GetZonePVPInfo",
59 | "InCombatLockdown",
60 | "InterfaceOptionsFrame_OpenToCategory",
61 | "IsInGroup",
62 | "IsInGuild",
63 | "IsInInstance",
64 | "IsInRaid",
65 | "LE_PARTY_CATEGORY_INSTANCE",
66 | "LOCALIZED_CLASS_NAMES_MALE",
67 | "LibStub",
68 | "MAX_CLASSES",
69 | "NO",
70 | "NotifyInspect",
71 | "OmniBarPetTooltipTextLeft2",
72 | "PARTY",
73 | "PLAYER",
74 | "SecondsToTime",
75 | "Settings",
76 | "Spell",
77 | "StaticPopup_Show",
78 | "TARGET",
79 | "UIParent",
80 | "UNITNAME_SUMMON_TITLE1",
81 | "UNITNAME_SUMMON_TITLE2",
82 | "UNITNAME_SUMMON_TITLE3",
83 | "UnitClass",
84 | "UnitExists",
85 | "UnitGUID",
86 | "UnitInParty",
87 | "UnitInRaid",
88 | "UnitIsPlayer",
89 | "UnitIsPossessed",
90 | "UnitIsUnit",
91 | "UnitReaction",
92 | "WOW_PROJECT_BURNING_CRUSADE_CLASSIC",
93 | "WOW_PROJECT_CLASSIC",
94 | "WOW_PROJECT_ID",
95 | "WOW_PROJECT_MAINLINE",
96 | "YES",
97 | "bit",
98 | "date",
99 | "format",
100 | "nop",
101 | "tinsert",
102 | "wipe",
103 | "tContains",
104 | }
105 | globals = {
106 | "OmniBar",
107 | "OmniBar_AddIcon",
108 | "OmniBar_AddIconsByClass",
109 | "OmniBar_Center",
110 | "OmniBar_CooldownFinish",
111 | "OmniBar_CreateIcon",
112 | "OmniBar_IsSpellEnabled",
113 | "OmniBar_IsUnitEnabled",
114 | "OmniBar_LoadPosition",
115 | "OmniBar_LoadSettings",
116 | "OmniBar_OnEvent",
117 | "OmniBar_Position",
118 | "OmniBar_Refresh",
119 | "OmniBar_ReplaySpellCasts",
120 | "OmniBar_ResetIcons",
121 | "OmniBar_ResetPosition",
122 | "OmniBar_SavePosition",
123 | "OmniBar_SetZone",
124 | "OmniBar_ShowAnchor",
125 | "OmniBar_SpecUpdated",
126 | "OmniBar_SpellCast",
127 | "OmniBar_StartCooldown",
128 | "OmniBar_Test",
129 | "OmniBar_UpdateAllBorders",
130 | "OmniBar_UpdateArenaSpecs",
131 | "OmniBar_UpdateBorder",
132 | "OmniBar_UpdateBorders",
133 | "OmniBar_UpdateIcons",
134 | "SlashCmdList",
135 | "StaticPopupDialogs",
136 | }
137 |
--------------------------------------------------------------------------------
/.pkgmeta:
--------------------------------------------------------------------------------
1 | package-as: OmniBar
2 |
3 | externals:
4 | Libs/LibStub: https://repos.curseforge.com/wow/libstub/trunk
5 | Libs/CallbackHandler-1.0: https://repos.curseforge.com/wow/callbackhandler/trunk/CallbackHandler-1.0
6 | Libs/AceAddon-3.0: https://repos.curseforge.com/wow/ace3/trunk/AceAddon-3.0
7 | Libs/AceComm-3.0: https://repos.curseforge.com/wow/ace3/trunk/AceComm-3.0
8 | Libs/AceDB-3.0: https://repos.curseforge.com/wow/ace3/trunk/AceDB-3.0
9 | Libs/AceDBOptions-3.0: https://repos.curseforge.com/wow/ace3/trunk/AceDBOptions-3.0
10 | Libs/AceEvent-3.0: https://repos.curseforge.com/wow/ace3/trunk/AceEvent-3.0
11 | Libs/AceGUI-3.0: https://repos.curseforge.com/wow/ace3/trunk/AceGUI-3.0
12 | Libs/AceConfig-3.0: https://repos.curseforge.com/wow/ace3/trunk/AceConfig-3.0
13 | Libs/AceLocale-3.0: https://repos.curseforge.com/wow/ace3/trunk/AceLocale-3.0
14 | Libs/AceSerializer-3.0: https://repos.curseforge.com/wow/ace3/trunk/AceSerializer-3.0
15 | Libs/LibDualSpec-1.0: https://repos.curseforge.com/wow/libdualspec-1-0
16 | Libs/LibDeflate: https://github.com/SafeteeWoW/LibDeflate
17 |
--------------------------------------------------------------------------------
/Locales/Locales.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Locales/deDE.lua:
--------------------------------------------------------------------------------
1 | -- OmniBar Locale
2 | -- https://www.curseforge.com/wow/addons/omnibar/localization
3 |
4 | local L = LibStub("AceLocale-3.0"):NewLocale("OmniBar", "frFR")
5 | if not L then return end
6 |
7 | L["Activate the icons for testing"] = "Aktiviert die Symbole für Tests"
8 | L["Alignment"] = "Ausrichtung"
9 | L["Allow Blizzard and other addons to display countdown text on the icons"] = "Ermöglicht es Blizzard oder anderen Addons, die Abklingzeit auf den Symbolen numerisch anzuzeigen"
10 | L["As Enemies Appear"] = "Je nach Gegner"
11 | L["Author"] = "Autor"
12 | L["Background"] = "Hintergrund"
13 | L["Bars"] = "Leisten"
14 | L["Bottom"] = "Unten"
15 | L["Bottom Left"] = "Unten links"
16 | L["Bottom Right"] = "Unten rechts"
17 | L["Center"] = "Mitte"
18 | L["Center Lock"] = "Mittig fixieren"
19 | L["Check Default Spells"] = "Standardzauber auswählen"
20 | L["Choose the order in which icons are sorted."] = "Wählen Sie die Reihenfolge, in der die Symbole sortiert werden."
21 | L["Columns"] = "Spalten"
22 | L["Countdown Count"] = "Abklingzeitzahl"
23 | L["Create a new bar"] = "Erstellt eine neue Leiste"
24 | L["Create Bar"] = "Leiste erstellen"
25 | L["Delete"] = "Löschen"
26 | L["Delete the bar"] = "Löscht die Leiste"
27 | L["Dialog"] = "Dialog"
28 | L["Display a glow animation around an icon when it is activated"] = "Zeigt eine Leuchtanimation um ein Symbol, wenn der dazugehörige Zauber aktiviert wurde"
29 | L["Draw a border around the icons"] = "Umrahmt die Symbole"
30 | L["Draw a border around your focus"] = "Umrahmt die Zauber deines Fokusziels"
31 | L["Draw a border around your target"] = "Umrahmt die Zauber deines Ziels"
32 | L["Frame Strata"] = "Fensterebene"
33 | L["Fullscreen"] = "Vollbild"
34 | L["Fullscreen Dialog"] = "Vollbilddialog"
35 | L["Glow Icons"] = "Leuchtende Symbole"
36 | L["Grow Rows Upward"] = "Nach oben erweitern"
37 | L["High"] = "Hoch"
38 | L["Highlight Focus"] = "Fokusziel hervorheben"
39 | L["Highlight Target"] = "Ziel hervorheben"
40 | L["Icon Limit"] = "Max. Symbolanzahl"
41 | L["Icons will always remain visible"] = "Symbole bleiben immer sichtbar"
42 | L["If another player is detected using the same ability, a duplicate icon will be created and tracked separately"] = "Falls ein anderer Spieler, der die gleiche Fähigkeit benutzt, entdeckt wird, wird ein zweites Symbol erstellt und getrennt verfolgt"
43 | L["Keep the bar centered horizontally"] = "Fixiert die Leiste horizontal mittig"
44 | L["Left"] = "Links"
45 | L["Lock"] = "Fixieren"
46 | L["Lock the bar to prevent dragging"] = "Fixiert die Leiste, um versehentliches Verschieben zu verhindern"
47 | L["Low"] = "Niedrig"
48 | L["Medium"] = "Mittel"
49 | L["Name"] = "Name"
50 | L["Only show unused icons for arena opponents or enemies you target while in combat"] = "Zeigt nur unbenutzte Zauber von Arenagegnern oder Gegnern, die du anvisiert, während du im Kampf bist, an"
51 | L["Padding"] = "Abstand"
52 | L["Point"] = "Punkt"
53 | L["Position"] = "Position"
54 | L["Relative Point"] = "Bezugspunkt"
55 | L["Relative To"] = "Bezogen auf (Bezugselement)"
56 | L["Reset"] = "Zurücksetzen"
57 | L["Reset the position of the bar"] = "Setzt die Position der Leiste zurück"
58 | L["Right"] = "Rechts"
59 | L["Set the alignment of the icons to the anchor"] = "Legt die Ausrichtung der Symbole zum Ankerpunkt fest"
60 | L["Set the maximum icons per row"] = "Legt die maximale Anzahl der Symbole pro Spalte fest"
61 | L["Set the maximum number of icons displayed on the bar"] = "Legt die maximale Anzahl der Symbole, die in dieser Leiste angezeigt werden, fest"
62 | L["Set the name of the bar"] = "Legt den Namen der Leiste fest"
63 | L["Set the name of the frame the bar will attach to"] = "Gib den Namen des UI-Elements ein, an dem die Leiste verankert wird"
64 | L["Set the point of the bar that will anchor"] = "Legt den Punkt der Leiste fest, der an dem unten angegebenen Punkt verankert wird"
65 | L["Set the point of the frame to attach the bar"] = "Legt den Punkt des UI-Elements fest, an dem die Leiste verankert wird"
66 | L["Set the size of the icons"] = "Legt die Größe der Symbole fest"
67 | L["Set the space between icons"] = "Legt den Platz zwischen den Symbolen fest"
68 | L["Set the strata of the bar"] = "Legt die Ebene der Leiste fest"
69 | L["Set the transparency of the swipe animation"] = "Legt die Transparenz des Bereichs der verstrichenen Zeit in der Animation fest"
70 | L["Set the transparency of unused icons"] = "Legt die Transparenz von Symbolen unbenutzter Zauber fest"
71 | L["Set the X offset of the bar"] = "Legt die Verschiebung der Leiste in X-Richtung fest"
72 | L["Set the Y offset of the bar"] = "Legt die Verschiebung der Leiste in Y-Richtung fest"
73 | L["Settings"] = "Einstellungen"
74 | L["Share settings across multiple characters"] = "Einstellungen mit mehreren Charaktere verwenden "
75 | L["Show Border"] = "Rahmen zeigen"
76 | L["Show in Arena"] = "In Arenen zeigen"
77 | L["Show in Ashran"] = "In Ashran zeigen"
78 | L["Show in Battlegrounds"] = "In Schlachtfeldern zeigen"
79 | L["Show in Rated Battlegrounds"] = "In gewerteten Schlachtfeldern zeigen"
80 | L["Show in World"] = "In der Welt zeigen"
81 | L["Show Names"] = "Namen zeigen"
82 | L["Show spell information when mousing over the icons (the bar must be unlocked)"] = "Zeigt Zauberinformationen, wenn du mit der Maus über die Symbole fährst (Die Leiste muss dazu entsperrt sein)"
83 | L["Show the icons in arena"] = "Zeigt die Symbole in Arenen"
84 | L["Show the icons in Ashran"] = "Zeigt die Symbole in Ashran"
85 | L["Show the icons in battlegrounds"] = "Zeigt die Symbole in Schlachtfeldern"
86 | L["Show the icons in rated battlegrounds"] = "Zeigt die Symbole in gewerteten Schlachtfeldern"
87 | L["Show the icons in the world"] = "Zeigt die Symbole in der Welt"
88 | L["Show the player name of the spell"] = "Zeigt den Namen des Spielers, der diesen Zauber benutzt hat"
89 | L["Show Tooltips"] = "Tooltips zeigen"
90 | L["Show Unused Icons"] = "Unbenutzte Zauber anzeigen"
91 | L["Size"] = "Größe"
92 | L["Sort Icons By:"] = "Symbole sortieren nach:"
93 | L["Spells"] = "Zauber"
94 | L["Swipe Transparency"] = "Transparenz der verstrichenen Zeit"
95 | L["Test"] = "Test"
96 | L["Time Added"] = "Hinzugefügte Zeit"
97 | L["Time Remaining"] = "Verbleibende Zeit"
98 | L["Toggle Lock"] = "Fixierung ein-/ausschalten"
99 | L["Toggle the grow direction of the icons"] = "Schaltet die Ausbreitungsrichtung der Symbole um"
100 | L["Tooltip"] = "Tooltip"
101 | L["Top"] = "Oben"
102 | L["Top Left"] = "Oben links"
103 | L["Top Right"] = "Oben rechts"
104 | L["Track Multiple Players"] = "Mehrere Spieler verfolgen"
105 | L["Uncheck All"] = "Alle abwählen"
106 | L["Unlock"] = "Entsperren"
107 | L["Unused Icon Transparency"] = "Transparenz unbenutzter Zauber"
108 | L["Version"] = "Version"
109 | L["Visibility"] = "Sichtbarkeit"
110 | L["X"] = "X"
111 | L["Y"] = "Y"
112 |
--------------------------------------------------------------------------------
/Locales/enUS.lua:
--------------------------------------------------------------------------------
1 | -- OmniBar Locale
2 | -- https://www.curseforge.com/wow/addons/omnibar/localization
3 |
4 | local L = LibStub("AceLocale-3.0"):NewLocale("OmniBar", "enUS", true)
5 |
6 | L["Activate the icons for testing"] = true
7 | L["Alignment"] = true
8 | L["Allow Blizzard and other addons to display countdown text on the icons"] = true
9 | L["As Enemies Appear"] = true
10 | L["Author"] = true
11 | L["Background"] = true
12 | L["Bars"] = true
13 | L["Bottom Left"] = true
14 | L["Bottom Right"] = true
15 | L["Bottom"] = true
16 | L["Center Lock"] = true
17 | L["Center"] = true
18 | L["Charges"] = true
19 | L["Check Default Spells"] = true
20 | L["Choose the order in which icons are sorted."] = true
21 | L["Class"] = true
22 | L["Columns"] = true
23 | L["Cooldown"] = true
24 | L["Countdown Count"] = true
25 | L["Create a new bar"] = true
26 | L["Create Bar"] = true
27 | L["Custom Spells"] = true
28 | L["Delete the bar"] = true
29 | L["Delete the cooldown"] = true
30 | L["Delete"] = true
31 | L["Dialog"] = true
32 | L["Display a glow animation around an icon when it is activated"] = true
33 | L["Draw a border around the icons"] = true
34 | L["Draw a border around your focus"] = true
35 | L["Draw a border around your target"] = true
36 | L["Duration"] = true
37 | L["Enable the cooldown for this specialization"] = true
38 | L["Enabled"] = true
39 | L["Frame Strata"] = true
40 | L["Fullscreen Dialog"] = true
41 | L["Fullscreen"] = true
42 | L["Glow Icons"] = true
43 | L["Grow Rows Upward"] = true
44 | L["High"] = true
45 | L["Highlight Focus"] = true
46 | L["Highlight Target"] = true
47 | L["Icon Limit"] = true
48 | L["Icons will always remain visible"] = true
49 | L["If another player is detected using the same ability, a duplicate icon will be created and tracked separately"] = true
50 | L["Keep the bar centered horizontally"] = true
51 | L["Left"] = true
52 | L["Lock the bar to prevent dragging"] = true
53 | L["Lock"] = true
54 | L["Low"] = true
55 | L["Medium"] = true
56 | L["Name"] = true
57 | L["Only show unused icons for arena opponents or enemies you target while in combat"] = true
58 | L["Padding"] = true
59 | L["Point"] = true
60 | L["Position"] = true
61 | L["Relative Point"] = true
62 | L["Relative To"] = true
63 | L["Reset the position of the bar"] = true
64 | L["Reset"] = true
65 | L["Right"] = true
66 | L["Set the alignment of the icons to the anchor"] = true
67 | L["Set the charges of the cooldown"] = true
68 | L["Set the class of the cooldown"] = true
69 | L["Set the duration of the cooldown"] = true
70 | L["Set the maximum icons per row"] = true
71 | L["Set the maximum number of icons displayed on the bar"] = true
72 | L["Set the name of the bar"] = true
73 | L["Set the name of the frame the bar will attach to"] = true
74 | L["Set the point of the bar that will anchor"] = true
75 | L["Set the point of the frame to attach the bar"] = true
76 | L["Set the size of the icons"] = true
77 | L["Set the space between icons"] = true
78 | L["Set the strata of the bar"] = true
79 | L["Set the transparency of the swipe animation"] = true
80 | L["Set the transparency of unused icons"] = true
81 | L["Set the X offset of the bar"] = true
82 | L["Set the Y offset of the bar"] = true
83 | L["Settings"] = true
84 | L["Share settings across multiple characters"] = true
85 | L["Show Border"] = true
86 | L["Show in Arena"] = true
87 | L["Show in Battlegrounds"] = true
88 | L["Show in Rated Battlegrounds"] = true
89 | L["Show in Scenarios"] = true
90 | L["Show in World"] = true
91 | L["Show Names"] = true
92 | L["Show spell information when mousing over the icons (the bar must be unlocked)"] = true
93 | L["Show the icons in arena"] = true
94 | L["Show the icons in battlegrounds"] = true
95 | L["Show the icons in rated battlegrounds"] = true
96 | L["Show the icons in scenarios"] = true
97 | L["Show the icons in the world"] = true
98 | L["Show the player name of the spell"] = true
99 | L["Show Tooltips"] = true
100 | L["Show Unused Icons"] = true
101 | L["Size"] = true
102 | L["Sort Icons By:"] = true
103 | L["Spell ID"] = true
104 | L["Spells"] = true
105 | L["Swipe Transparency"] = true
106 | L["Test"] = true
107 | L["Time Added"] = true
108 | L["Time Remaining"] = true
109 | L["Toggle Lock"] = true
110 | L["Toggle the grow direction of the icons"] = true
111 | L["Tooltip"] = true
112 | L["Top Left"] = true
113 | L["Top Right"] = true
114 | L["Top"] = true
115 | L["Track Multiple Players"] = true
116 | L["Uncheck All"] = true
117 | L["Unlock"] = true
118 | L["Unused Icon Transparency"] = true
119 | L["Version"] = true
120 | L["Visibility"] = true
121 | L["X"] = true
122 | L["Y"] = true
123 | L["Test All"] = true
124 | L.UPDATE_AVAILABLE = "There is an update available. Please download the latest release from https://www.curseforge.com/wow/addons/omnibar"
125 | L["Import"] = true
126 | L["Import an OmniBar profile"] = true
127 | L["Export"] = true
128 | L["Export this profile"] = true
129 | L["Import failed (%s)"] = true
130 | L["Imported (%s)"] = true
131 | L["Paste a code to import an OmniBar profile."] = true
132 | L["Invalid version"] = true
133 | L["Ready to import"] = true
134 | L["Copy this code to share this OmniBar profile."] = true
135 |
--------------------------------------------------------------------------------
/Locales/frFR.lua:
--------------------------------------------------------------------------------
1 | -- OmniBar Locale
2 | -- https://www.curseforge.com/wow/addons/omnibar/localization
3 |
4 | local L = LibStub("AceLocale-3.0"):NewLocale("OmniBar", "frFR")
5 | if not L then return end
6 |
7 | L["Activate the icons for testing"] = "Activer les icônes pour tester"
8 | L["Alignment"] = "Alignement"
9 | L["Allow Blizzard and other addons to display countdown text on the icons"] = "Autoriser les add-ons Blizzard et les autres à afficher le décompte sur les icônes"
10 | L["As Enemies Appear"] = "À l'apparition des ennemis"
11 | L["Author"] = "Auteur"
12 | L["Background"] = "Arrière-plan"
13 | L["Bars"] = "Barres"
14 | L["Bottom"] = "Bas"
15 | L["Bottom Left"] = "Bas gauche"
16 | L["Bottom Right"] = "Bas droite"
17 | L["Center"] = "Centre"
18 | L["Center Lock"] = "Verrouiller au milieu"
19 | L["Check Default Spells"] = "Vérifier les sorts par défaut"
20 | L["Choose the order in which icons are sorted."] = "Choisissez l'ordre dans lequel les icônes sont triées."
21 | L["Columns"] = "Colonnes"
22 | L["Countdown Count"] = "Compte à rebours"
23 | L["Create a new bar"] = "Créer une nouvelle barre"
24 | L["Create Bar"] = "Créer une barre"
25 | L["Delete"] = "Supprimer"
26 | L["Delete the bar"] = "Supprimer la barre"
27 | L["Dialog"] = "Dialogue"
28 | L["Display a glow animation around an icon when it is activated"] = "Afficher de la brillance autour des icônes activées"
29 | L["Draw a border around the icons"] = "Ajouter une bordure aux icônes"
30 | L["Draw a border around your focus"] = "Ajouter une bordure autour du focus"
31 | L["Draw a border around your target"] = "Ajouter une bordure autour de la cible"
32 | L["Frame Strata"] = "Couche d'image"
33 | L["Fullscreen"] = "Plein écran"
34 | L["Fullscreen Dialog"] = "Dialogue en plein écran"
35 | L["Glow Icons"] = "Faire briller les icônes"
36 | L["Grow Rows Upward"] = "Empiler les lignes"
37 | L["High"] = "Élevé"
38 | L["Highlight Focus"] = "Mettre en évidence le focus"
39 | L["Highlight Target"] = "Mettre en évidence la cible"
40 | L["Icon Limit"] = "Limite d'icônes"
41 | L["Icons will always remain visible"] = "Les icônes seront toujours visibles"
42 | L["If another player is detected using the same ability, a duplicate icon will be created and tracked separately"] = "Si un autre joueur utilisant la même compétence est détecté, une icône identique sera crée et suivie séparément"
43 | L["Keep the bar centered horizontally"] = "Garder la barre centrée horizontalement "
44 | L["Left"] = "Gauche"
45 | L["Lock"] = "Verrouiller"
46 | L["Lock the bar to prevent dragging"] = "Verrouiller la barre pour empêcher le glisser-déposer"
47 | L["Low"] = "Bas"
48 | L["Medium"] = "Moyen"
49 | L["Name"] = "Nom"
50 | L["Only show unused icons for arena opponents or enemies you target while in combat"] = "Afficher uniquement les icônes pour les adversaires d'arène ou ennemis que vous ciblez lors des combats"
51 | L["Padding"] = "Marge intérieure"
52 | L["Point"] = "Point"
53 | L["Position"] = "Position"
54 | L["Relative Point"] = "Point relatif"
55 | L["Relative To"] = "Relatif à"
56 | L["Reset"] = "Réinitialiser"
57 | L["Reset the position of the bar"] = "Réinitialiser la position de la barre"
58 | L["Right"] = "Droite"
59 | L["Set the alignment of the icons to the anchor"] = "Définir l'alignement des icônes sur l'ancre"
60 | L["Set the maximum icons per row"] = "Définir le nombre maximum d'icônes par ligne"
61 | L["Set the maximum number of icons displayed on the bar"] = "Définir le nombre maximum d'icônes sur la barre"
62 | L["Set the name of the bar"] = "Définir le nom de la barre"
63 | L["Set the name of the frame the bar will attach to"] = "Définir le nom de l'image à laquelle la barre se rattachera"
64 | L["Set the point of the bar that will anchor"] = "Définir le point de la barre qui se fixera"
65 | L["Set the point of the frame to attach the bar"] = "Définir le point de l'image auquel attacher la barre"
66 | L["Set the size of the icons"] = "Définir la taille des icônes"
67 | L["Set the space between icons"] = "Définir l'espace entre les icônes"
68 | L["Set the strata of the bar"] = "Définir la couche de la barre"
69 | L["Set the transparency of the swipe animation"] = "Définir la transparence de l'animation de balayage"
70 | L["Set the transparency of unused icons"] = "Définir la transparence des icônes non utilisées"
71 | L["Set the X offset of the bar"] = "Définir le décalage en X de la barre"
72 | L["Set the Y offset of the bar"] = "Définir le décalage en Y de la barre"
73 | L["Settings"] = "Paramètres"
74 | L["Share settings across multiple characters"] = "Appliquer les paramètres sur plusieurs personnages"
75 | L["Show Border"] = "Montrer bordure"
76 | L["Show in Arena"] = "Afficher dans Arène"
77 | L["Show in Ashran"] = "Afficher dans Ashran"
78 | L["Show in Battlegrounds"] = "Afficher dans Champs de bataille"
79 | L["Show in Rated Battlegrounds"] = "Afficher dans Champs de bataille côtés"
80 | L["Show in World"] = "Afficher dans Monde"
81 | L["Show Names"] = "Afficher noms"
82 | L["Show spell information when mousing over the icons (the bar must be unlocked)"] = "Afficher les informations de sort au survol de l'icône avec la souris (la barre doit être déverrouillée)"
83 | L["Show the icons in arena"] = "Afficher les icônes dans Arène"
84 | L["Show the icons in Ashran"] = "Afficher les icônes dans Ashran"
85 | L["Show the icons in battlegrounds"] = "Afficher les icônes dans champs de bataille"
86 | L["Show the icons in rated battlegrounds"] = "Afficher les icônes dans champs de bataille côtés"
87 | L["Show the icons in the world"] = "Afficher les icônes dans le monde"
88 | L["Show the player name of the spell"] = "Afficher le nom du joueur à l'origine du sort"
89 | L["Show Tooltips"] = "Afficher infobulles"
90 | L["Show Unused Icons"] = "Afficher icônes non utilisées"
91 | L["Size"] = "Taille"
92 | L["Sort Icons By:"] = "Trier les icônes par:"
93 | L["Spells"] = "Sorts"
94 | L["Swipe Transparency"] = "Transparence de balayage"
95 | L["Test"] = "Test"
96 | L["Time Added"] = "Temps ajouté"
97 | L["Time Remaining"] = "Temps restant"
98 | L["Toggle Lock"] = "Changer verrouillage"
99 | L["Toggle the grow direction of the icons"] = "Changer la direction de rangement des icônes"
100 | L["Tooltip"] = "Infobulle"
101 | L["Top"] = "Haut"
102 | L["Top Left"] = "Haut gauche"
103 | L["Top Right"] = "Haut droite"
104 | L["Track Multiple Players"] = "Suivre plusieurs joueurs"
105 | L["Uncheck All"] = "Tout décocher"
106 | L["Unlock"] = "Déverrouiller"
107 | L["Unused Icon Transparency"] = "Transparence des icônes non utilisées"
108 | L["Version"] = "Version"
109 | L["Visibility"] = "Visibilité"
110 | L["X"] = "X"
111 | L["Y"] = "Y"
112 |
--------------------------------------------------------------------------------
/Locales/koKR.lua:
--------------------------------------------------------------------------------
1 | -- OmniBar Locale
2 | -- https://www.curseforge.com/wow/addons/omnibar/localization
3 |
4 | local L = LibStub("AceLocale-3.0"):NewLocale("OmniBar", "koKR")
5 | if not L then return end
6 |
7 | L["Activate the icons for testing"] = "테스트를 위한 아이콘을 표시합니다."
8 | L["Alignment"] = "정렬"
9 | L["Allow Blizzard and other addons to display countdown text on the icons"] = "블리자드 및 기타 추가 애드온이 아이콘에 재사용 대기시간을 문자를 표시합니다."
10 | L["As Enemies Appear"] = "적이 나타날 때"
11 | L["Author"] = "제작자"
12 | L["Background"] = "배경"
13 | L["Bars"] = "바"
14 | L["Bottom"] = "하단"
15 | L["Bottom Left"] = "좌측 하단"
16 | L["Bottom Right"] = "우측 하단"
17 | L["Center"] = "중앙"
18 | L["Center Lock"] = "중앙 잠금"
19 | L["Check Default Spells"] = "기본 주문 체크"
20 | L["Choose the order in which icons are sorted."] = "아이콘이 정렬되는 순서를 선택하세요."
21 | L["Columns"] = "행"
22 | L["Countdown Count"] = "재사용 대기시간"
23 | L["Create a new bar"] = "새로운 바를 생성합니다."
24 | L["Create Bar"] = "바 생성"
25 | L["Delete"] = "삭제"
26 | L["Delete the bar"] = "바를 삭제합니다."
27 | L["Dialog"] = "Dialog"
28 | L["Display a glow animation around an icon when it is activated"] = "활성화될때 아이콘 주위에 빛나는 애니메이션을 표시합니다."
29 | L["Draw a border around the icons"] = "아이콘에 테두리를 표시합니다."
30 | L["Draw a border around your focus"] = "주시 대상에 테두리를 표시합니다."
31 | L["Draw a border around your target"] = "대상에 테두리를 표시합니다."
32 | L["Frame Strata"] = "창 우선 순위"
33 | L["Fullscreen"] = "Fullscreen"
34 | L["Fullscreen Dialog"] = "Fullscreen Dialog"
35 | L["Glow Icons"] = "빛나는 아이콘"
36 | L["Grow Rows Upward"] = "위쪽으로 행 확장"
37 | L["High"] = "High"
38 | L["Highlight Focus"] = "주시 대상 강조"
39 | L["Highlight Target"] = "대상 강조"
40 | L["Icon Limit"] = "아이콘 제한"
41 | L["Icons will always remain visible"] = "항상 아이콘을 표시합니다."
42 | L["If another player is detected using the same ability, a duplicate icon will be created and tracked separately"] = "똑같은 능력을 사용하는 다른 플레이어를 탐지되는 경우, 중복 아이콘이 생성되고 개별적으로 추적합니다."
43 | L["Keep the bar centered horizontally"] = "수평 중앙에 바를 유지시킵니다."
44 | L["Left"] = "좌측"
45 | L["Lock"] = "잠금"
46 | L["Lock the bar to prevent dragging"] = "드래그 방지를 위해 바를 잠급니다."
47 | L["Low"] = "Low"
48 | L["Medium"] = "Medium"
49 | L["Name"] = "이름"
50 | L["Only show unused icons for arena opponents or enemies you target while in combat"] = "전투중 당신이 목표로 삼은 투기장의 상대나 적대적 대상을 위한 사용하지 않는 아이콘을 표시합니다."
51 | L["Padding"] = "간격"
52 | L["Point"] = "포인트"
53 | L["Position"] = "위치"
54 | L["Relative Point"] = "상대적 포인트"
55 | L["Relative To"] = "상대적"
56 | L["Reset"] = "초기화"
57 | L["Reset the position of the bar"] = "바의 위치를 초기화합니다."
58 | L["Right"] = "우측"
59 | L["Set the alignment of the icons to the anchor"] = "지점에 아이콘 정렬을 설정합니다."
60 | L["Set the maximum icons per row"] = "행당 최대 아이콘을 설정합니다."
61 | L["Set the maximum number of icons displayed on the bar"] = "바에 표시할 아이콘의 최대 수를 설정합니다."
62 | L["Set the name of the bar"] = "바의 이름을 설정합니다."
63 | L["Set the name of the frame the bar will attach to"] = "고정 할 바의 프레임 이름을 설정합니다."
64 | L["Set the point of the bar that will anchor"] = "고정 할 바의 지점을 설정합니다."
65 | L["Set the point of the frame to attach the bar"] = "바를 연결할 프레임의 지점을 설정합니다."
66 | L["Set the size of the icons"] = "아이콘의 크기를 설정합니다."
67 | L["Set the space between icons"] = "아이콘 사이의 간격을 설정합니다."
68 | L["Set the strata of the bar"] = "바의 우선 순위를 설정합니다."
69 | L["Set the transparency of the swipe animation"] = "swipe 애니메이션의 투명도를 설정합니다."
70 | L["Set the transparency of unused icons"] = "사용하지 않는 아이콘의 투명도를 설정합니다."
71 | L["Set the X offset of the bar"] = "바의 X 간격을 설정합니다."
72 | L["Set the Y offset of the bar"] = "바의 Y 간격을 설정합니다."
73 | L["Settings"] = "설정"
74 | L["Share settings across multiple characters"] = "캐릭터의 설정을 공유합니다."
75 | L["Show Border"] = "테두리 표시"
76 | L["Show in Arena"] = "투기장에서 표시"
77 | L["Show in Ashran"] = "아스란에서 표시"
78 | L["Show in Battlegrounds"] = "전장에서 표시"
79 | L["Show in Rated Battlegrounds"] = "평점 전장에서 표시"
80 | L["Show in World"] = "일반에서 표시"
81 | L["Show Names"] = "이름 표시"
82 | L["Show spell information when mousing over the icons (the bar must be unlocked)"] = "(바 잠금 해제시) 아이콘에 마우스 오버시 주문의 정보를 표시합니다."
83 | L["Show the icons in arena"] = "투기장에서 아이콘을 표시합니다."
84 | L["Show the icons in Ashran"] = "아스란에서 아이콘을 표시합니다."
85 | L["Show the icons in battlegrounds"] = "전장에서 아이콘을 표시합니다."
86 | L["Show the icons in rated battlegrounds"] = "평점 전장에서 아이콘을 표시합니다."
87 | L["Show the icons in the world"] = "일반에서 아이콘을 표시합니다."
88 | L["Show the player name of the spell"] = "주문을 시전한 플레이어의 이름을 표시합니다."
89 | L["Show Tooltips"] = "툴팁 표시"
90 | L["Show Unused Icons"] = "사용하지 않는 아이콘 표시"
91 | L["Size"] = "크기"
92 | L["Sort Icons By:"] = "아이콘 정렬 기준:"
93 | L["Spells"] = "주문"
94 | L["Swipe Transparency"] = "Swipe 투명도"
95 | L["Test"] = "테스트"
96 | L["Time Added"] = "추가된 시간"
97 | L["Time Remaining"] = "남은 시간"
98 | L["Toggle Lock"] = "잠근 전환"
99 | L["Toggle the grow direction of the icons"] = "아이콘 확장 방향을 전환합니다."
100 | L["Tooltip"] = "Tooltip"
101 | L["Top"] = "상단"
102 | L["Top Left"] = "좌측 상단"
103 | L["Top Right"] = "우측 상단"
104 | L["Track Multiple Players"] = "다중 플레이어 추적"
105 | L["Uncheck All"] = "모두 체크 해제"
106 | L["Unlock"] = "이동"
107 | L["Unused Icon Transparency"] = "사용하지 않는 아이콘 투명도"
108 | L["Version"] = "버전"
109 | L["Visibility"] = "표시"
110 | L["X"] = "X"
111 | L["Y"] = "Y"
112 |
--------------------------------------------------------------------------------
/Locales/ptBR.lua:
--------------------------------------------------------------------------------
1 | -- OmniBar Locale
2 | -- https://www.curseforge.com/wow/addons/omnibar/localization
3 |
4 | local L = LibStub("AceLocale-3.0"):NewLocale("OmniBar", "ptBR")
5 | if not L then return end
6 |
7 | L["Activate the icons for testing"] = "Ativar ícones para teste"
8 | L["Alignment"] = "Alinhamento"
9 | L["Allow Blizzard and other addons to display countdown text on the icons"] = "Permitir a Blizzard e outros addons exibirem contadores nos ícones"
10 | L["As Enemies Appear"] = "Como Inimigos Aparecem"
11 | L["Author"] = "Autor"
12 | L["Background"] = "Plano de fundo"
13 | L["Bars"] = "Barras"
14 | L["Bottom"] = "Inferior"
15 | L["Bottom Left"] = "Inferior à Esquerda"
16 | L["Bottom Right"] = "Inferior à Direita"
17 | L["Center"] = "Centro"
18 | L["Center Lock"] = "Travar no Centro"
19 | L["Check Default Spells"] = "Marcar Magias Padrões"
20 | L["Choose the order in which icons are sorted."] = "Escolha a ordem em que os ícones serão ordenados."
21 | L["Columns"] = "Colunas"
22 | L["Countdown Count"] = "Contagem Regressiva"
23 | L["Create a new bar"] = "Criar nova barra"
24 | L["Create Bar"] = "Criar Barra"
25 | L["Delete"] = "Apagar"
26 | L["Delete the bar"] = "Apaga a barra"
27 | L["Dialog"] = "Diálogo"
28 | L["Display a glow animation around an icon when it is activated"] = "Exibir uma animação em volta do ícone quando for ativado"
29 | L["Draw a border around the icons"] = "Aplicar contorno nos ícones"
30 | L["Draw a border around your focus"] = "Aplicar contorno em seu foco"
31 | L["Draw a border around your target"] = "Aplicar contorno em seu alvo"
32 | L["Frame Strata"] = "Camada do Quadro"
33 | L["Fullscreen"] = "Tela Cheia"
34 | L["Fullscreen Dialog"] = "Diálogo da Tela Cheia"
35 | L["Glow Icons"] = "Claridade dos Ícones"
36 | L["Grow Rows Upward"] = "Crescer para Cima"
37 | L["High"] = "Alto"
38 | L["Highlight Focus"] = "Destacar Foco"
39 | L["Highlight Target"] = "Destacar Alvo"
40 | L["Icon Limit"] = "Limite de Ícone"
41 | L["Icons will always remain visible"] = "Ícones estarão sempre visíveis"
42 | L["If another player is detected using the same ability, a duplicate icon will be created and tracked separately"] = "Se outro jogador for detectado usando a mesma habilidade, um ícone duplicado será criado e rastreado separadamente"
43 | L["Keep the bar centered horizontally"] = "Manter a barra centralizada horizontalmente"
44 | L["Left"] = "Esquerda"
45 | L["Lock"] = "Travar"
46 | L["Lock the bar to prevent dragging"] = "Travar barra para prevenir arrastos acidentais"
47 | L["Low"] = "Baixo"
48 | L["Medium"] = "Médio"
49 | L["Name"] = "Nome"
50 | L["Only show unused icons for arena opponents or enemies you target while in combat"] = "Exibir apenas ícones não usados em oponentes de arena ou inimigos que você selecionar enquanto em combate"
51 | L["Padding"] = "Preenchimento"
52 | L["Point"] = "Ponto"
53 | L["Position"] = "Posição"
54 | L["Relative Point"] = "Ponto Relativo"
55 | L["Relative To"] = "Relativo à"
56 | L["Reset"] = "Resetar"
57 | L["Reset the position of the bar"] = "Resetar a posição da barra"
58 | L["Right"] = "Direita"
59 | L["Set the alignment of the icons to the anchor"] = "Ajustar o alinhamento dos ícones na âncora"
60 | L["Set the maximum icons per row"] = "Ajuste o máximo de ícones por linha"
61 | L["Set the maximum number of icons displayed on the bar"] = "Defina o máximo de ícones à serem exibidos na barra"
62 | L["Set the name of the bar"] = "Definir nome da barra"
63 | L["Set the name of the frame the bar will attach to"] = "Definir nome do quadro que será anexado à barra"
64 | L["Set the point of the bar that will anchor"] = "Definir o ponto da barra que ficará no meio do âncora"
65 | L["Set the point of the frame to attach the bar"] = "Definir o ponto do quadro que será anexo na barra."
66 | L["Set the size of the icons"] = "Definir o tamanho dos ícones"
67 | L["Set the space between icons"] = "Definir o espaço entre ícones"
68 | L["Set the strata of the bar"] = "Definir camadas da barra"
69 | L["Set the transparency of the swipe animation"] = "Definir transparência da animação"
70 | L["Set the transparency of unused icons"] = "Definir transparência de ícones não usados"
71 | L["Set the X offset of the bar"] = "Ajustar o deslocador X da barra"
72 | L["Set the Y offset of the bar"] = "Ajustar o "
73 | L["Settings"] = "Ajustes"
74 | L["Share settings across multiple characters"] = "Compartilhar configurações entre vários personagens"
75 | L["Show Border"] = "Exibir Borda"
76 | L["Show in Arena"] = "Exibir em Arena"
77 | L["Show in Ashran"] = "Exibir em Ashran"
78 | L["Show in Battlegrounds"] = "Exibir em Campos de Batalha"
79 | L["Show in Rated Battlegrounds"] = "Exibir em Campos de Batalhas Ranqueados"
80 | L["Show in World"] = "Exibir no Mundo"
81 | L["Show Names"] = "Exibir Nomes"
82 | L["Show spell information when mousing over the icons (the bar must be unlocked)"] = "Exibir informação da magia quando passar o mouse nos ícones (A barra deve estar travada)"
83 | L["Show the icons in arena"] = "Exibir ícones na arena"
84 | L["Show the icons in Ashran"] = "Exibir ícones em Ashran"
85 | L["Show the icons in battlegrounds"] = "Exibir ícones nos campos de batalha"
86 | L["Show the icons in rated battlegrounds"] = "Exibir ícones em campos de batalha ranqueados"
87 | L["Show the icons in the world"] = "Exibir ícones no mundo"
88 | L["Show the player name of the spell"] = "Exibir nome do jogador da magia"
89 | L["Show Tooltips"] = "Exibir Dicas"
90 | L["Show Unused Icons"] = "Exibir Ícones Não Usados"
91 | L["Size"] = "Tamanho"
92 | L["Sort Icons By:"] = "Ordenar ícones por:"
93 | L["Spells"] = "Magias"
94 | L["Swipe Transparency"] = "Deslize para Transparência"
95 | L["Test"] = "Teste"
96 | L["Time Added"] = "Tempo adicionado"
97 | L["Time Remaining"] = "Tempo restante"
98 | L["Toggle Lock"] = "Alternar Trava"
99 | L["Toggle the grow direction of the icons"] = "Alternar direção de aumento dos ícones"
100 | L["Tooltip"] = "Dica"
101 | L["Top"] = "Cima"
102 | L["Top Left"] = "Cima Esquerda"
103 | L["Top Right"] = "Cima Direita"
104 | L["Track Multiple Players"] = "Rastrear Vários Jogadores"
105 | L["Uncheck All"] = "Desmarcar Tudo"
106 | L["Unlock"] = "Destravar"
107 | L["Unused Icon Transparency"] = "Transparência de Ícones sem Uso"
108 | L["Version"] = "Versão"
109 | L["Visibility"] = "Visibilidade"
110 | L["X"] = "X"
111 | L["Y"] = "Y"
112 |
--------------------------------------------------------------------------------
/Locales/zhCN.lua:
--------------------------------------------------------------------------------
1 | -- OmniBar Locale
2 | -- https://www.curseforge.com/wow/addons/omnibar/localization
3 |
4 | local L = LibStub("AceLocale-3.0"):NewLocale("OmniBar", "zhCN")
5 | if not L then return end
6 |
7 | L["Activate the icons for testing"] = "激活测试图标"
8 | L["Alignment"] = "对齐"
9 | L["Allow Blizzard and other addons to display countdown text on the icons"] = "允许暴雪或者其他插件显示倒计时"
10 | L["As Enemies Appear"] = "仅敌对出现时"
11 | L["Author"] = "作者"
12 | L["Background"] = "背景"
13 | L["Bars"] = "监视条"
14 | L["Bottom"] = "下"
15 | L["Bottom Left"] = "左下"
16 | L["Bottom Right"] = "右下"
17 | L["Center"] = "居中"
18 | L["Center Lock"] = "居中锁定"
19 | L["Check Default Spells"] = "选中默认法术"
20 | L["Choose the order in which icons are sorted."] = "选择图标排序的顺序"
21 | L["Columns"] = "列数"
22 | L["Countdown Count"] = "冷却计时"
23 | L["Create a new bar"] = "创建一个新的监视条"
24 | L["Create Bar"] = "创建监视条"
25 | L["Delete"] = "删除"
26 | L["Delete the bar"] = "删除监视条"
27 | L["Dialog"] = "对话框"
28 | L["Display a glow animation around an icon when it is activated"] = "图标激活时显示闪光"
29 | L["Draw a border around the icons"] = "添加图标边框"
30 | L["Draw a border around your focus"] = "添加焦点的边框"
31 | L["Draw a border around your target"] = "添加目标的边框"
32 | L["Frame Strata"] = "框架层"
33 | L["Fullscreen"] = "全屏"
34 | L["Fullscreen Dialog"] = "全屏对话框"
35 | L["Glow Icons"] = "闪烁图标"
36 | L["Grow Rows Upward"] = "向上增长"
37 | L["High"] = "高"
38 | L["Highlight Focus"] = "高亮显示焦点"
39 | L["Highlight Target"] = "高亮显示目标"
40 | L["Icon Limit"] = "图标限制"
41 | L["Icons will always remain visible"] = "总是图标显示"
42 | L["If another player is detected using the same ability, a duplicate icon will be created and tracked separately"] = "如果检测到另一个玩家使用相同的能力,将创建一个重复的图标,并单独跟踪"
43 | L["Keep the bar centered horizontally"] = "保持监视条水平居中"
44 | L["Left"] = "左"
45 | L["Lock"] = "锁定"
46 | L["Lock the bar to prevent dragging"] = "锁定监视条防止拖拽移动"
47 | L["Low"] = "低"
48 | L["Medium"] = "中"
49 | L["Name"] = "名称"
50 | L["Only show unused icons for arena opponents or enemies you target while in combat"] = "仅当敌对目标存在时,才显示未使用技能图标"
51 | L["Padding"] = "间距"
52 | L["Point"] = "点"
53 | L["Position"] = "位置"
54 | L["Relative Point"] = "锚点"
55 | L["Relative To"] = "依附于"
56 | L["Reset"] = "重置"
57 | L["Reset the position of the bar"] = "重置监视条位置"
58 | L["Right"] = "右"
59 | L["Set the alignment of the icons to the anchor"] = "设置图标对齐方式"
60 | L["Set the maximum icons per row"] = "设置每行最多图标数量"
61 | L["Set the maximum number of icons displayed on the bar"] = "设置监视条上显示图标的最大数量"
62 | L["Set the name of the bar"] = "设置监视条名称"
63 | L["Set the name of the frame the bar will attach to"] = "设置监视条依附的框架名称"
64 | L["Set the point of the bar that will anchor"] = "设置监视条的锚点"
65 | L["Set the point of the frame to attach the bar"] = "设置依附到监视条的框架锚点"
66 | L["Set the size of the icons"] = "设置图标大小"
67 | L["Set the space between icons"] = "设置图标间的距离"
68 | L["Set the strata of the bar"] = "设置监视条分层"
69 | L["Set the transparency of the swipe animation"] = "设置CD中技能图标的刷新亮度"
70 | L["Set the transparency of unused icons"] = "设置未使用图标的透明度"
71 | L["Set the X offset of the bar"] = "设置监视条X轴"
72 | L["Set the Y offset of the bar"] = "设置监视条Y轴"
73 | L["Settings"] = "设置"
74 | L["Share settings across multiple characters"] = "多个角色共享设置"
75 | L["Show Border"] = "显示边框"
76 | L["Show in Arena"] = "竞技场"
77 | L["Show in Ashran"] = "阿什兰"
78 | L["Show in Battlegrounds"] = "战场"
79 | L["Show in Rated Battlegrounds"] = "评级战场"
80 | L["Show in World"] = "世界"
81 | L["Show Names"] = "显示姓名"
82 | L["Show spell information when mousing over the icons (the bar must be unlocked)"] = "显示技能详细信息(监视条必须处于解锁状态)"
83 | L["Show the icons in arena"] = "在竞技场中显示图标"
84 | L["Show the icons in Ashran"] = "在阿什兰中显示图标"
85 | L["Show the icons in battlegrounds"] = "在战场中显示图标"
86 | L["Show the icons in rated battlegrounds"] = "在评级战场中显示图标"
87 | L["Show the icons in the world"] = "在世界中显示图标"
88 | L["Show the player name of the spell"] = "显示施法者姓名"
89 | L["Show Tooltips"] = "显示详细提示信息"
90 | L["Show Unused Icons"] = "显示未使用的技能图标"
91 | L["Size"] = "大小"
92 | L["Sort Icons By:"] = "按此排序图标:"
93 | L["Spells"] = "监视法术"
94 | L["Swipe Transparency"] = "刷新亮度"
95 | L["Test"] = "测试"
96 | L["Time Added"] = "添加的时间"
97 | L["Time Remaining"] = "剩余时间"
98 | L["Toggle Lock"] = "切换锁定"
99 | L["Toggle the grow direction of the icons"] = "切换图标增长方向"
100 | L["Tooltip"] = "详细提示信息"
101 | L["Top"] = "上"
102 | L["Top Left"] = "左上"
103 | L["Top Right"] = "右上"
104 | L["Track Multiple Players"] = "监视多个同职业玩家"
105 | L["Uncheck All"] = "全部取消"
106 | L["Unlock"] = "解锁"
107 | L["Unused Icon Transparency"] = "未使用技能图标的透明度"
108 | L["Version"] = "版本"
109 | L["Visibility"] = "生效范围"
110 | L["X"] = "X轴"
111 | L["Y"] = "Y轴"
112 |
--------------------------------------------------------------------------------
/Locales/zhTW.lua:
--------------------------------------------------------------------------------
1 | -- OmniBar Locale
2 | -- https://www.curseforge.com/wow/addons/omnibar/localization
3 |
4 | local L = LibStub("AceLocale-3.0"):NewLocale("OmniBar", "zhTW")
5 | if not L then return end
6 |
7 | L["Activate the icons for testing"] = "啟用圖示以便測試"
8 | L["Alignment"] = "對齊"
9 | L["Allow Blizzard and other addons to display countdown text on the icons"] = "允許暴雪或其它插件在圖示上顯示冷卻計時文字"
10 | L["As Enemies Appear"] = "只有敵人出現時"
11 | L["Author"] = "作者"
12 | L["Background"] = "背景"
13 | L["Bars"] = "圖示列"
14 | L["Bottom"] = "下"
15 | L["Bottom Left"] = "左下"
16 | L["Bottom Right"] = "右下"
17 | L["Center"] = "中"
18 | L["Center Lock"] = "鎖定至水平中央"
19 | L["Check Default Spells"] = "選擇預設的法術"
20 | L["Choose the order in which icons are sorted."] = "選擇圖示排序的順序"
21 | L["Columns"] = "行數"
22 | L["Countdown Count"] = "冷卻計時"
23 | L["Create a new bar"] = "建立新的圖示列"
24 | L["Create Bar"] = "建立圖示列"
25 | L["Delete"] = "刪除"
26 | L["Delete the bar"] = "刪除圖示列"
27 | L["Dialog"] = "對話框"
28 | L["Display a glow animation around an icon when it is activated"] = "圖示啟用時在周圍顯示閃爍動畫"
29 | L["Draw a border around the icons"] = "在圖示周圍繪製邊框"
30 | L["Draw a border around your focus"] = "在你的專注目標周圍繪製邊框"
31 | L["Draw a border around your target"] = "在你的目標周圍繪製邊框"
32 | L["Frame Strata"] = "框架層級"
33 | L["Fullscreen"] = "全螢幕"
34 | L["Fullscreen Dialog"] = "全螢幕對話框"
35 | L["Glow Icons"] = "閃爍圖示"
36 | L["Grow Rows Upward"] = "往上方增加"
37 | L["High"] = "高"
38 | L["Highlight Focus"] = "明顯顯示專注目標"
39 | L["Highlight Target"] = "明顯顯示目標"
40 | L["Icon Limit"] = "圖示數量上限"
41 | L["Icons will always remain visible"] = "總是顯示圖示"
42 | L["If another player is detected using the same ability, a duplicate icon will be created and tracked separately"] = "如果偵測到另一位玩家也使用相同的技能,會建立重複的圖示並且分開監控"
43 | L["Keep the bar centered horizontally"] = "讓圖示列保持在水平中央"
44 | L["Left"] = "左"
45 | L["Lock"] = "鎖定"
46 | L["Lock the bar to prevent dragging"] = "鎖定圖示列,避免拖曳移動"
47 | L["Low"] = "低"
48 | L["Medium"] = "中"
49 | L["Name"] = "名稱"
50 | L["Only show unused icons for arena opponents or enemies you target while in combat"] = "只有競技場對手和戰鬥中的敵方目標,才顯示未使用的圖示"
51 | L["Padding"] = "間距"
52 | L["Point"] = "定位點"
53 | L["Position"] = "位置"
54 | L["Relative Point"] = "相對定位點"
55 | L["Relative To"] = "相對於"
56 | L["Reset"] = "重置"
57 | L["Reset the position of the bar"] = "重置圖示列的位置"
58 | L["Right"] = "右"
59 | L["Set the alignment of the icons to the anchor"] = "設定圖示對齊至定位點的位置"
60 | L["Set the maximum icons per row"] = "設定每一列最多顯示幾個圖示"
61 | L["Set the maximum number of icons displayed on the bar"] = "設定圖示列最多能夠顯示幾個圖示"
62 | L["Set the name of the bar"] = "設定圖示列的名稱"
63 | L["Set the name of the frame the bar will attach to"] = "設定圖示列依附對齊的框架名稱"
64 | L["Set the point of the bar that will anchor"] = "設定圖示列的的定位點"
65 | L["Set the point of the frame to attach the bar"] = "設定依附對齊圖示列的框架定位點"
66 | L["Set the size of the icons"] = "設定圖示的大小"
67 | L["Set the space between icons"] = "設定圖示之間的距離"
68 | L["Set the strata of the bar"] = "設定圖示列的框架層級"
69 | L["Set the transparency of the swipe animation"] = "設定轉圈動畫的透明度"
70 | L["Set the transparency of unused icons"] = "設定未使用圖示的透明度"
71 | L["Set the X offset of the bar"] = "設定圖示列的水平方向位移"
72 | L["Set the Y offset of the bar"] = "設定圖示列的垂直方向位移"
73 | L["Settings"] = "設定"
74 | L["Share settings across multiple characters"] = "多個角色共用相同的設定"
75 | L["Show Border"] = "顯示邊框"
76 | L["Show in Arena"] = "競技場"
77 | L["Show in Ashran"] = "艾斯蘭"
78 | L["Show in Battlegrounds"] = "戰場"
79 | L["Show in Rated Battlegrounds"] = "積分戰場"
80 | L["Show in World"] = "野外"
81 | L["Show Names"] = "顯示名字"
82 | L["Show spell information when mousing over the icons (the bar must be unlocked)"] = "滑鼠指向圖示時顯示法術資訊 (圖示列必須是解除鎖定狀態)"
83 | L["Show the icons in arena"] = "在競技場中顯示圖示"
84 | L["Show the icons in Ashran"] = "在艾斯蘭顯示圖示"
85 | L["Show the icons in battlegrounds"] = "在戰場中顯示圖示"
86 | L["Show the icons in rated battlegrounds"] = "在積分戰場中顯示圖示"
87 | L["Show the icons in the world"] = "在野外顯示圖示"
88 | L["Show the player name of the spell"] = "顯示施法者的名字"
89 | L["Show Tooltips"] = "顯示滑鼠提示"
90 | L["Show Unused Icons"] = "顯示未使用的圖示"
91 | L["Size"] = "大小"
92 | L["Sort Icons By:"] = "依此排序圖示:"
93 | L["Spells"] = "法術"
94 | L["Swipe Transparency"] = "倒數轉圈的透明度"
95 | L["Test"] = "測試"
96 | L["Time Added"] = "新增時間"
97 | L["Time Remaining"] = "剩餘時間"
98 | L["Toggle Lock"] = "切換鎖定"
99 | L["Toggle the grow direction of the icons"] = "切換圖示增加時的方向"
100 | L["Tooltip"] = "滑鼠提示"
101 | L["Top"] = "上"
102 | L["Top Left"] = "左上"
103 | L["Top Right"] = "右上"
104 | L["Track Multiple Players"] = "監控多位玩家"
105 | L["Uncheck All"] = "全部取消"
106 | L["Unlock"] = "解除鎖定"
107 | L["Unused Icon Transparency"] = "未使用圖示透明度"
108 | L["Version"] = "版本"
109 | L["Visibility"] = "顯示"
110 | L["X"] = "水平方向"
111 | L["Y"] = "垂直方向"
112 |
--------------------------------------------------------------------------------
/Media/Textures/icon.blp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jordonwow/omnibar/072fcb34da615704ea7dbfa88d3e7a5f7c4546e7/Media/Textures/icon.blp
--------------------------------------------------------------------------------
/OmniBar.lua:
--------------------------------------------------------------------------------
1 |
2 | -- OmniBar by Jordon
3 |
4 | local addonName, addon = ...
5 |
6 | local COMBATLOG_FILTER_STRING_UNKNOWN_UNITS = COMBATLOG_FILTER_STRING_UNKNOWN_UNITS
7 | local COMBATLOG_OBJECT_REACTION_HOSTILE = COMBATLOG_OBJECT_REACTION_HOSTILE
8 | local COMBATLOG_OBJECT_TYPE_PLAYER = COMBATLOG_OBJECT_TYPE_PLAYER
9 | local C_Timer_After = C_Timer.After
10 | local CanInspect = CanInspect
11 | local ClearInspectPlayer = ClearInspectPlayer
12 | local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo
13 | local CreateFrame = CreateFrame
14 | local DEFAULT_CHAT_FRAME = DEFAULT_CHAT_FRAME
15 | local GetArenaOpponentSpec = GetArenaOpponentSpec
16 | local GetBattlefieldScore = GetBattlefieldScore
17 | local GetClassInfo = GetClassInfo
18 | local GetInspectSpecialization = GetInspectSpecialization
19 | local GetNumBattlefieldScores = GetNumBattlefieldScores
20 | local GetNumGroupMembers = GetNumGroupMembers
21 | local GetNumSpecializationsForClassID = GetNumSpecializationsForClassID
22 | local GetPlayerInfoByGUID = GetPlayerInfoByGUID
23 | local GetRaidRosterInfo = GetRaidRosterInfo
24 | local GetServerTime = GetServerTime
25 | local GetSpecialization = GetSpecialization
26 | local GetSpecializationInfo = GetSpecializationInfo
27 | local GetSpecializationInfoByID = GetSpecializationInfoByID
28 | local GetSpecializationInfoForClassID = GetSpecializationInfoForClassID
29 | local GetSpellInfo = C_Spell and C_Spell.GetSpellInfo or GetSpellInfo
30 | local GetSpellTexture = C_Spell and C_Spell.GetSpellTexture or GetSpellTexture
31 | local GetTime = GetTime
32 | local GetUnitName = GetUnitName
33 | local GetZonePVPInfo = GetZonePVPInfo
34 | local InCombatLockdown = InCombatLockdown
35 | local InterfaceOptionsFrame_OpenToCategory = InterfaceOptionsFrame_OpenToCategory
36 | local IsInGroup = IsInGroup
37 | local IsInGuild = IsInGuild
38 | local IsInInstance = IsInInstance
39 | local IsInRaid = IsInRaid
40 | local IsRatedBattleground = C_PvP.IsRatedBattleground
41 | local LE_PARTY_CATEGORY_INSTANCE = LE_PARTY_CATEGORY_INSTANCE
42 | local LibStub = LibStub
43 | local MAX_CLASSES = MAX_CLASSES
44 | local NotifyInspect = NotifyInspect
45 | local SlashCmdList = SlashCmdList
46 | local UIParent = UIParent
47 | local UNITNAME_SUMMON_TITLE1 = UNITNAME_SUMMON_TITLE1
48 | local UNITNAME_SUMMON_TITLE2 = UNITNAME_SUMMON_TITLE2
49 | local UNITNAME_SUMMON_TITLE3 = UNITNAME_SUMMON_TITLE3
50 | local UnitClass = UnitClass
51 | local UnitExists = UnitExists
52 | local UnitGUID = UnitGUID
53 | local UnitInParty = UnitInParty
54 | local UnitInRaid = UnitInRaid
55 | local UnitIsPlayer = UnitIsPlayer
56 | local UnitIsPossessed = UnitIsPossessed
57 | local UnitIsUnit = UnitIsUnit
58 | local UnitReaction = UnitReaction
59 | local WOW_PROJECT_CLASSIC = WOW_PROJECT_CLASSIC
60 | local WOW_PROJECT_ID = WOW_PROJECT_ID
61 | local WOW_PROJECT_MAINLINE = WOW_PROJECT_MAINLINE
62 | local bit_band = bit.band
63 | local date = date
64 | local tinsert = tinsert
65 | local wipe = wipe
66 | local tContains = tContains
67 |
68 | local function GetSpellName(id)
69 | if C_Spell and C_Spell.GetSpellName then
70 | return C_Spell.GetSpellName(id)
71 | else
72 | return GetSpellInfo(id)
73 | end
74 | end
75 |
76 | OmniBar = LibStub("AceAddon-3.0"):NewAddon("OmniBar", "AceEvent-3.0", "AceComm-3.0", "AceSerializer-3.0")
77 | local L = LibStub("AceLocale-3.0"):GetLocale("OmniBar")
78 |
79 | -- Apply cooldown adjustments
80 | for k,v in pairs(addon.Cooldowns) do
81 | if v.duration and type(v.duration) == "number" then
82 | local adjust = v.adjust or 0
83 | if type(adjust) == "table" then
84 | adjust = adjust.default or 0 -- use default for now
85 | end
86 | addon.Cooldowns[k].duration = v.duration + adjust
87 | end
88 | end
89 |
90 | local CLASS_ORDER = {
91 | ["GENERAL"] = 0,
92 | ["DEMONHUNTER"] = 1,
93 | ["DEATHKNIGHT"] = 2,
94 | ["PALADIN"] = 3,
95 | ["WARRIOR"] = 4,
96 | ["DRUID"] = 5,
97 | ["PRIEST"] = 6,
98 | ["WARLOCK"] = 7,
99 | ["SHAMAN"] = 8,
100 | ["HUNTER"] = 9,
101 | ["MAGE"] = 10,
102 | ["ROGUE"] = 11,
103 | ["MONK"] = 12,
104 | ["EVOKER"] = 13,
105 | }
106 |
107 | local MAX_ARENA_SIZE = addon.MAX_ARENA_SIZE or 0
108 |
109 | local PLAYER_NAME = GetUnitName("player")
110 |
111 | local DEFAULTS = {
112 | adaptive = false,
113 | align = "CENTER",
114 | arena = true,
115 | battleground = true,
116 | border = true,
117 | center = false,
118 | columns = 8,
119 | cooldownCount = true,
120 | glow = true,
121 | growUpward = true,
122 | highlightFocus = false,
123 | highlightTarget = true,
124 | iconSorting = "TIME_ADDED",
125 | locked = false,
126 | maxIcons = 32,
127 | multiple = true,
128 | names = false,
129 | padding = 2,
130 | ratedBattleground = true,
131 | scenario = true,
132 | showUnused = false,
133 | size = 40,
134 | swipeAlpha = 0.65,
135 | tooltips = true,
136 | trackUnit = "ENEMY",
137 | unusedAlpha = 0.45,
138 | world = true,
139 | }
140 |
141 | local DB_VERSION = 4
142 |
143 | local MAX_DUPLICATE_ICONS = 5
144 |
145 | local BASE_ICON_SIZE = 36
146 |
147 | function OmniBar:Print(message)
148 | DEFAULT_CHAT_FRAME:AddMessage("|cff33ff99OmniBar|r: " .. message)
149 | end
150 |
151 | function OmniBar:OnInitialize()
152 | self.db = LibStub("AceDB-3.0"):New("OmniBarDB", {
153 | global = { version = DB_VERSION, cooldowns = {} },
154 | profile = { bars = {} }
155 | }, true)
156 | self.cooldowns = addon.Cooldowns
157 | self.bars = {}
158 | self.specs = {}
159 | self.spellCasts = {}
160 | self.db.RegisterCallback(self, "OnProfileChanged", "OnEnable")
161 | self.db.RegisterCallback(self, "OnProfileCopied", "OnEnable")
162 | self.db.RegisterCallback(self, "OnProfileReset", "OnEnable")
163 | self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
164 | self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
165 | self:RegisterEvent("GROUP_ROSTER_UPDATE", "GetSpecs")
166 | self:RegisterComm("OmniBarSpell", function(_, payload, _, sender)
167 | if (not UnitExists(sender)) or sender == PLAYER_NAME then return end
168 | local success, event, sourceGUID, sourceName, sourceFlags, spellID, serverTime = self:Deserialize(payload)
169 | if (not success) then return end
170 | self:AddSpellCast(event, sourceGUID, sourceName, sourceFlags, spellID, serverTime)
171 | end)
172 |
173 | -- Set version
174 | local version, major, minor = C_AddOns.GetAddOnMetadata(addonName, "Version") or "", 0, 0
175 | if version:sub(1, 1) == "@" then
176 | version = "Development"
177 | else
178 | major, minor = version:match("v(%d+)%.?(%d*)")
179 | end
180 | self.version = setmetatable({
181 | string = version,
182 | major = tonumber(major),
183 | minor = tonumber(minor) or 0,
184 | }, {
185 | __tostring = function()
186 | return version
187 | end
188 | })
189 |
190 | -- Check if update available
191 | if self.version.major > 0 then
192 | self:RegisterComm("OmniBarVersion", "ReceiveVersion")
193 | self:RegisterEvent("ZONE_CHANGED_NEW_AREA", "SendVersion")
194 | C_Timer_After(10, function()
195 | self:SendVersion()
196 | if IsInGuild() then self:SendVersion("GUILD") end
197 | self:SendVersion("YELL")
198 | end)
199 | end
200 |
201 | -- Remove invalid custom cooldowns
202 | for k,v in pairs(self.db.global.cooldowns) do
203 | if (not GetSpellInfo(k)) then
204 | self.db.global.cooldowns[k] = nil
205 | end
206 | end
207 |
208 | -- Populate cooldowns with spell names and icons
209 | for spellId,_ in pairs(self.cooldowns) do
210 | local name, icon
211 | if C_Spell and C_Spell.GetSpellInfo then
212 | local spellInfo = C_Spell.GetSpellInfo(spellId)
213 | name = spellInfo and spellInfo.name
214 | icon = spellInfo and spellInfo.iconID
215 | else
216 | name, _, icon = GetSpellInfo(spellId)
217 | end
218 | self.cooldowns[spellId].icon = self.cooldowns[spellId].icon or icon
219 | self.cooldowns[spellId].name = name
220 | end
221 |
222 | self:SetupOptions()
223 | end
224 |
225 | local function GetDefaultCommChannel()
226 | if IsInRaid() then
227 | return IsInRaid(LE_PARTY_CATEGORY_INSTANCE) and "INSTANCE_CHAT" or "RAID"
228 | elseif IsInGroup() then
229 | return IsInGroup(LE_PARTY_CATEGORY_INSTANCE) and "INSTANCE_CHAT" or "PARTY"
230 | elseif IsInGuild() then
231 | return "GUILD"
232 | else
233 | return "YELL"
234 | end
235 | end
236 |
237 | function OmniBar:ReceiveVersion(_, payload, _, sender)
238 | self.sender = sender
239 | if (not payload) or type(payload) ~= "string" then return end
240 | local major, minor = payload:match("v(%d+)%.?(%d*)")
241 | major = tonumber(major)
242 | minor = tonumber(minor) or 0
243 | if (not major) or (not minor) then return end
244 | if major < self.version.major then return end
245 | if major == self.version.major and minor <= self.version.minor then return end
246 | if (not self.outdatedSender) or self.outdatedSender == sender then
247 | self.outdatedSender = sender
248 | return
249 | end
250 | if self.nextWarn and self.nextWarn > GetTime() then return end
251 | self.nextWarn = GetTime() + 1800
252 | self:Print(L.UPDATE_AVAILABLE)
253 | self.outdatedSender = nil
254 | end
255 |
256 | function OmniBar:SendVersion(distribution)
257 | if (not self.version) or self.version.major == 0 then return end
258 | self:SendCommMessage("OmniBarVersion", self.version.string, distribution or GetDefaultCommChannel())
259 | end
260 |
261 | function OmniBar:OnEnable()
262 | wipe(self.specs)
263 |
264 | wipe(self.spellCasts)
265 |
266 | self.index = 1
267 |
268 | for i = #self.bars, 1, -1 do
269 | self:Delete(self.bars[i].key, true)
270 | table.remove(self.bars, i)
271 | end
272 |
273 | for key,_ in pairs(self.db.profile.bars) do
274 | self:Initialize(key)
275 | self.index = self.index + 1
276 | end
277 |
278 | -- Create a default bar if none exist
279 | if self.index == 1 then
280 | self:Initialize("OmniBar1", "OmniBar")
281 | self.index = 2
282 | end
283 |
284 | for key,_ in pairs(self.db.profile.bars) do
285 | self:AddBarToOptions(key)
286 | end
287 |
288 | self:Refresh(true)
289 | end
290 |
291 | function OmniBar:Decode(encoded)
292 | local LibDeflate = LibStub:GetLibrary("LibDeflate")
293 | local decoded = LibDeflate:DecodeForPrint(encoded)
294 | if (not decoded) then return self:ImportError("DecodeForPrint") end
295 | local decompressed = LibDeflate:DecompressZlib(decoded)
296 | if (not decompressed) then return self:ImportError("DecompressZlib") end
297 | local success, deserialized = self:Deserialize(decompressed)
298 | if (not success) then return self:ImportError("Deserialize") end
299 | return deserialized
300 | end
301 |
302 | function OmniBar:ExportProfile()
303 | local LibDeflate = LibStub:GetLibrary("LibDeflate")
304 | local data = {
305 | profile = self.db.profile,
306 | customSpells = self.db.global.cooldowns,
307 | version = 1
308 | }
309 | local serialized = self:Serialize(data)
310 | if (not serialized) then return end
311 | local compressed = LibDeflate:CompressZlib(serialized)
312 | if (not compressed) then return end
313 | return LibDeflate:EncodeForPrint(compressed)
314 | end
315 |
316 | function OmniBar:ImportError(message)
317 | if (not message) or self.import.editBox.editBox:GetNumLetters() == 0 then
318 | self.import.statustext:SetTextColor(1, 0.82, 0)
319 | self.import:SetStatusText(L["Paste a code to import an OmniBar profile."])
320 | else
321 | self.import.statustext:SetTextColor(1, 0, 0)
322 | self.import:SetStatusText(L["Import failed (%s)"]:format(message))
323 | end
324 | self.import.button:SetDisabled(true)
325 | end
326 |
327 | function OmniBar:ImportProfile(data)
328 | if (data.version ~= 1) then return self:ImportError(L["Invalid version"]) end
329 |
330 | local profile = L["Imported (%s)"]:format(date())
331 |
332 | self.db.profiles[profile] = data.profile
333 | self.db:SetProfile(profile)
334 |
335 | -- merge custom spells
336 | for k,v in pairs(data.customSpells) do
337 | self.db.global.cooldowns[k] = nil
338 | self.options.args.customSpells.args.spellId.set(nil, k, v)
339 | end
340 |
341 | self:OnEnable()
342 | LibStub("AceConfigRegistry-3.0"):NotifyChange("OmniBar")
343 | return true
344 | end
345 |
346 | function OmniBar:ShowExport()
347 | self.export.editBox:SetText(self:ExportProfile())
348 | self.export:Show()
349 | self.export.editBox:SetFocus()
350 | self.export.editBox:HighlightText()
351 | -- self.export.editBox:HighlightText(0, self.export.editBox.editBox:GetNumLetters())
352 |
353 | end
354 |
355 | function OmniBar:ShowImport()
356 | self.import.editBox:SetText("")
357 | self:ImportError()
358 | self.import:Show()
359 | self.import.button:SetDisabled(true)
360 | self.import.editBox:SetFocus()
361 | end
362 |
363 | function OmniBar:Delete(key, keepProfile)
364 | local bar = _G[key]
365 | if (not bar) then return end
366 | bar:UnregisterEvent("PLAYER_ENTERING_WORLD")
367 | bar:UnregisterEvent("ZONE_CHANGED_NEW_AREA")
368 | bar:UnregisterEvent("PLAYER_TARGET_CHANGED")
369 | bar:UnregisterEvent("PLAYER_REGEN_DISABLED")
370 | bar:UnregisterEvent("GROUP_ROSTER_UPDATE")
371 | bar:UnregisterEvent("UPDATE_BATTLEFIELD_SCORE")
372 | if WOW_PROJECT_ID ~= WOW_PROJECT_CLASSIC then
373 | bar:UnregisterEvent("PLAYER_FOCUS_CHANGED")
374 | bar:UnregisterEvent("ARENA_OPPONENT_UPDATE")
375 | end
376 | if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
377 | bar:UnregisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")
378 | bar:UnregisterEvent("UPDATE_BATTLEFIELD_STATUS")
379 | bar:UnregisterEvent("PVP_MATCH_ACTIVE")
380 | end
381 | bar:Hide()
382 | if (not keepProfile) then self.db.profile.bars[key] = nil end
383 | self.options.args.bars.args[key] = nil
384 | LibStub("AceConfigRegistry-3.0"):NotifyChange("OmniBar")
385 | end
386 |
387 | OmniBar.BackupCooldowns = {}
388 |
389 | function OmniBar:CopyCooldown(cooldown)
390 | local copy = {}
391 |
392 | for _,v in pairs({"class", "charges", "parent", "name", "icon"}) do
393 | if cooldown[v] then
394 | copy[v] = cooldown[v]
395 | end
396 | end
397 |
398 | if cooldown.duration then
399 | if type(cooldown.duration) == "table" then
400 | copy.duration = {}
401 | for k, v in pairs(cooldown.duration) do
402 | copy.duration[k] = v
403 | end
404 | else
405 | copy.duration = { default = cooldown.duration }
406 | end
407 | end
408 |
409 | if cooldown.specID then
410 | copy.specID = {}
411 | for i = 1, #cooldown.specID do
412 | table.insert(copy.specID, cooldown.specID[i])
413 | end
414 | end
415 |
416 | return copy
417 | end
418 |
419 | -- create a lookup table since CombatLogGetCurrentEventInfo() returns 0 for spellId
420 | local SPELL_ID_BY_NAME
421 | if WOW_PROJECT_ID == WOW_PROJECT_CLASSIC then
422 | SPELL_ID_BY_NAME = {}
423 | for id, value in pairs(addon.Cooldowns) do
424 | if (not value.parent) then SPELL_ID_BY_NAME[GetSpellName(id)] = id end
425 | end
426 | end
427 |
428 | function OmniBar:AddCustomSpells()
429 | -- Restore any overrides
430 | for k,v in pairs(self.BackupCooldowns) do
431 | addon.Cooldowns[k] = self:CopyCooldown(v)
432 | end
433 |
434 | -- Add custom spells
435 | for k,v in pairs(self.db.global.cooldowns) do
436 | local name, _, icon
437 | if C_Spell and C_Spell.GetSpellInfo then
438 | local spellInfo = C_Spell.GetSpellInfo(k)
439 | name = spellInfo and spellInfo.name
440 | icon = spellInfo and spellInfo.iconID
441 | else
442 | name, _, icon = GetSpellInfo(k)
443 | end
444 | if name then
445 | -- Backup if we are going to override
446 | if addon.Cooldowns[k] and (not addon.Cooldowns[k].custom) and (not self.BackupCooldowns[k]) then
447 | self.BackupCooldowns[k] = self:CopyCooldown(addon.Cooldowns[k])
448 | end
449 | addon.Cooldowns[k] = v
450 | addon.Cooldowns[k].icon = addon.Cooldowns[k].icon or icon
451 | addon.Cooldowns[k].name = name
452 | if SPELL_ID_BY_NAME then SPELL_ID_BY_NAME[name] = k end
453 | else
454 | self.db.global.cooldowns[k] = nil
455 | end
456 | end
457 | end
458 |
459 | local function OmniBar_IsAdaptive(self)
460 | if self.settings.adaptive then return true end
461 |
462 | -- force adaptive in arena since enemies are finite and known
463 | if self.zone == "arena" then return true end
464 |
465 | -- everything but all enemies are known, so force adaptive
466 | if self.settings.trackUnit ~= "ENEMY" then return true end
467 | end
468 |
469 | function OmniBar_SpellCast(self, event, name, spellID)
470 | if self.disabled then return end
471 |
472 | -- if GetZonePVPInfo() == "sanctuary" then return end
473 |
474 | OmniBar_AddIcon(self, self.spellCasts[name][spellID])
475 | end
476 |
477 | function OmniBar:Initialize(key, name)
478 | if (not self.db.profile.bars[key]) then
479 | self.db.profile.bars[key] = { name = name }
480 | for a,b in pairs(DEFAULTS) do
481 | self.db.profile.bars[key][a] = b
482 | end
483 | end
484 |
485 | self:AddCustomSpells()
486 |
487 | local f = _G[key] or CreateFrame("Frame", key, UIParent, "OmniBarTemplate")
488 | f:Show()
489 | f.settings = self.db.profile.bars[key]
490 | f.settings.align = f.settings.align or "CENTER"
491 | f.settings.maxIcons = f.settings.maxIcons or DEFAULTS.maxIcons
492 | f.key = key
493 | f.icons = {}
494 | f.active = {}
495 | f.detected = {}
496 | f.spellCasts = self.spellCasts
497 | f.specs = self.specs
498 | f.BASE_ICON_SIZE = BASE_ICON_SIZE
499 | f.numIcons = 0
500 | f:RegisterForDrag("LeftButton")
501 |
502 | f.anchor.text:SetText(f.settings.name)
503 |
504 | -- Upgrade units
505 | f.settings.units = nil
506 | if (not f.settings.trackUnit) then f.settings.trackUnit = "ENEMY" end
507 |
508 | -- Remove invalid spells
509 | if f.settings.spells then
510 | for k,_ in pairs(f.settings.spells) do
511 | if (not addon.Cooldowns[k]) or addon.Cooldowns[k].parent then f.settings.spells[k] = nil end
512 | end
513 | end
514 |
515 | f.adaptive = OmniBar_IsAdaptive(f)
516 |
517 | -- Upgrade custom spells
518 | for k,v in pairs(f.settings) do
519 | local spellID = tonumber(k:match("^spell(%d+)"))
520 | if spellID then
521 | if (not f.settings.spells) then
522 | f.settings.spells = {}
523 | if (not f.settings.noDefault) then
524 | for k,v in pairs(addon.Cooldowns) do
525 | if v.default then f.settings.spells[k] = true end
526 | end
527 | end
528 | end
529 | f.settings.spells[spellID] = v
530 | f.settings[k] = nil
531 | end
532 | end
533 | f.settings.noDefault = nil
534 |
535 | -- Load the settings
536 | OmniBar_LoadSettings(f)
537 |
538 | -- Create the icons
539 | for spellID,_ in pairs(addon.Cooldowns) do
540 | if OmniBar_IsSpellEnabled(f, spellID) then
541 | OmniBar_CreateIcon(f)
542 | end
543 | end
544 |
545 | -- Create the duplicate icons
546 | for i = 1, MAX_DUPLICATE_ICONS do
547 | OmniBar_CreateIcon(f)
548 | end
549 |
550 | OmniBar_ShowAnchor(f)
551 | OmniBar_ResetIcons(f)
552 | OmniBar_UpdateIcons(f)
553 | OmniBar_Center(f)
554 |
555 | f.OnEvent = OmniBar_OnEvent
556 |
557 | f:RegisterEvent("PLAYER_ENTERING_WORLD", "OnEvent")
558 | f:RegisterEvent("ZONE_CHANGED_NEW_AREA", "OnEvent")
559 | f:RegisterEvent("PLAYER_TARGET_CHANGED", "OnEvent")
560 | f:RegisterEvent("PLAYER_REGEN_DISABLED", "OnEvent")
561 | f:RegisterEvent("GROUP_ROSTER_UPDATE", "OnEvent")
562 |
563 | if WOW_PROJECT_ID ~= WOW_PROJECT_CLASSIC then
564 | f:RegisterEvent("PLAYER_FOCUS_CHANGED", "OnEvent")
565 | f:RegisterEvent("ARENA_OPPONENT_UPDATE", "OnEvent")
566 | end
567 |
568 | if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
569 | f:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS", "OnEvent")
570 | f:RegisterEvent("UPDATE_BATTLEFIELD_STATUS", "OnEvent")
571 | f:RegisterEvent("PVP_MATCH_ACTIVE", "OnEvent")
572 | end
573 |
574 | f:RegisterEvent("UPDATE_BATTLEFIELD_SCORE", "OnEvent")
575 |
576 | table.insert(self.bars, f)
577 | end
578 |
579 | function OmniBar:Create()
580 | while true do
581 | local key = "OmniBar"..self.index
582 | self.index = self.index + 1
583 | if (not self.db.profile.bars[key]) then
584 | self:Initialize(key, "OmniBar " .. (self.index - 1))
585 | self:AddBarToOptions(key, true)
586 | self:OnEnable()
587 | return
588 | end
589 | end
590 | end
591 |
592 | function OmniBar:Refresh(full)
593 | self:GetSpecs()
594 | for key,_ in pairs(self.db.profile.bars) do
595 | local f = _G[key]
596 | if f then
597 | f.container:SetScale(f.settings.size/BASE_ICON_SIZE)
598 | if full then
599 | f.adaptive = OmniBar_IsAdaptive(f)
600 | OmniBar_OnEvent(f, "PLAYER_ENTERING_WORLD")
601 | OmniBar_OnEvent(f, "PLAYER_TARGET_CHANGED")
602 | OmniBar_OnEvent(f, "PLAYER_FOCUS_CHANGED")
603 | OmniBar_OnEvent(f, "GROUP_ROSTER_UPDATE")
604 | else
605 | OmniBar_LoadPosition(f)
606 | OmniBar_UpdateIcons(f)
607 | OmniBar_Center(f)
608 | end
609 | end
610 | end
611 | end
612 |
613 | local Masque = LibStub and LibStub("Masque", true)
614 |
615 | -- create a lookup table to translate spec names into IDs
616 | local SPEC_ID_BY_NAME = {}
617 | if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
618 | for classID = 1, MAX_CLASSES do
619 | local _, classToken = GetClassInfo(classID)
620 | SPEC_ID_BY_NAME[classToken] = {}
621 | for i = 1, GetNumSpecializationsForClassID(classID) do
622 | local id, name = GetSpecializationInfoForClassID(classID, i)
623 | SPEC_ID_BY_NAME[classToken][name] = id
624 | end
625 | end
626 | end
627 |
628 | local function UnitIsHostile(unit)
629 | if (not unit) then return end
630 | if UnitIsUnit("player", unit) then return end
631 | local reaction = UnitReaction("player", unit)
632 | if (not reaction) then return end -- out of range
633 | return UnitIsPlayer(unit) and reaction < 4 and (not UnitIsPossessed(unit))
634 | end
635 |
636 | function OmniBar_ShowAnchor(self)
637 | if self.disabled or self.settings.locked or #self.active > 0 then
638 | self.anchor:Hide()
639 | else
640 | local width = self.anchor.text:GetWidth() + 29
641 | self.anchor:SetSize(width, 30)
642 | self.anchor:Show()
643 | end
644 | end
645 |
646 | function OmniBar_CreateIcon(self)
647 | if InCombatLockdown() then return end
648 | self.numIcons = self.numIcons + 1
649 | local name = self:GetName()
650 | local key = name.."Icon"..self.numIcons
651 | local f = _G[key] or CreateFrame("Button", key, _G[name.."Icons"], "OmniBarButtonTemplate")
652 | table.insert(self.icons, f)
653 | end
654 |
655 | local function SpellBelongsToSpec(spellID, specID)
656 | if (not specID) then return true end
657 | if (not addon.Cooldowns[spellID].specID) then return true end
658 | for i = 1, #addon.Cooldowns[spellID].specID do
659 | if addon.Cooldowns[spellID].specID[i] == specID then return true end
660 | end
661 | end
662 |
663 | function OmniBar_AddIconsByClass(self, class, sourceGUID, specID)
664 | for spellID, spell in pairs(addon.Cooldowns) do
665 | if OmniBar_IsSpellEnabled(self, spellID) and
666 | (spell.class == "GENERAL" or (spell.class == class and SpellBelongsToSpec(spellID, specID)))
667 | then
668 | OmniBar_AddIcon(self, { spellID = spellID, sourceGUID = sourceGUID, specID = specID })
669 | end
670 | end
671 | end
672 |
673 | local function IconIsUnit(iconGUID, guid)
674 | if (not guid) then return end
675 | if type(iconGUID) == "number" then
676 | -- arena target
677 | return UnitGUID("arena" .. iconGUID) == guid
678 | end
679 | return iconGUID == guid
680 | end
681 |
682 | local function OmniBar_StartAnimation(self, icon)
683 | if (not self.settings.glow) then return end
684 | icon.flashAnim:Play()
685 | icon.newitemglowAnim:Play()
686 | end
687 |
688 | local function OmniBar_StopAnimation(self, icon)
689 | if icon.flashAnim:IsPlaying() then icon.flashAnim:Stop() end
690 | if icon.newitemglowAnim:IsPlaying() then icon.newitemglowAnim:Stop() end
691 | end
692 |
693 | function OmniBar_UpdateBorder(self, icon)
694 | local border
695 | local guid = icon.sourceGUID
696 | local name = icon.sourceName
697 | if guid or name then
698 | if self.settings.highlightFocus and
699 | self.settings.trackUnit == "ENEMY" and
700 | (IconIsUnit(guid, UnitGUID("focus")) or name == GetUnitName("focus", true)) and
701 | UnitIsPlayer("focus")
702 | then
703 | icon.FocusTexture:SetAlpha(1)
704 | border = true
705 | else
706 | icon.FocusTexture:SetAlpha(0)
707 | end
708 | if self.settings.highlightTarget and
709 | self.settings.trackUnit == "ENEMY" and
710 | (IconIsUnit(guid, UnitGUID("target")) or name == GetUnitName("target", true)) and
711 | UnitIsPlayer("target")
712 | then
713 | icon.FocusTexture:SetAlpha(0)
714 | icon.TargetTexture:SetAlpha(1)
715 | border = true
716 | else
717 | icon.TargetTexture:SetAlpha(0)
718 | end
719 | else
720 | local _, class = UnitClass("focus")
721 | if self.settings.highlightFocus and
722 | self.settings.trackUnit == "ENEMY" and
723 | class and (class == icon.class or icon.class == "GENERAL") and
724 | UnitIsPlayer("focus")
725 | then
726 | icon.FocusTexture:SetAlpha(1)
727 | border = true
728 | else
729 | icon.FocusTexture:SetAlpha(0)
730 | end
731 | _, class = UnitClass("target")
732 | if self.settings.highlightTarget and
733 | self.settings.trackUnit == "ENEMY" and
734 | class and (class == icon.class or icon.class == "GENERAL") and
735 | UnitIsPlayer("target")
736 | then
737 | icon.FocusTexture:SetAlpha(0)
738 | icon.TargetTexture:SetAlpha(1)
739 | border = true
740 | else
741 | icon.TargetTexture:SetAlpha(0)
742 | end
743 | end
744 |
745 | -- Set dim
746 | icon:SetAlpha(self.settings.unusedAlpha and
747 | icon.cooldown:GetCooldownTimes() == 0 and
748 | (not border) and
749 | self.settings.unusedAlpha or 1)
750 | end
751 |
752 | function OmniBar_UpdateAllBorders(self)
753 | for i = 1, #self.active do
754 | OmniBar_UpdateBorder(self, self.active[i])
755 | end
756 | end
757 |
758 | function OmniBar_SetZone(self, refresh)
759 | local disabled = self.disabled
760 | local _, zone = IsInInstance()
761 | -- if zone == "none" then
762 | -- SetMapToCurrentZone()
763 | -- zone = GetCurrentMapAreaID()
764 | -- end
765 |
766 | self.zone = zone
767 | self.rated = IsRatedBattleground and IsRatedBattleground()
768 | self.disabled = (zone == "arena" and (not self.settings.arena)) or
769 | (self.rated and (not self.settings.ratedBattleground)) or
770 | (zone == "pvp" and (not self.settings.battleground) and (not self.rated)) or
771 | (zone == "scenario" and (not self.settings.scenario)) or
772 | (zone ~= "arena" and zone ~= "pvp" and zone ~= "scenario" and (not self.settings.world))
773 |
774 | self.adaptive = OmniBar_IsAdaptive(self)
775 |
776 | if refresh or disabled ~= self.disabled then
777 | OmniBar_LoadPosition(self)
778 | OmniBar_ResetIcons(self)
779 | OmniBar_UpdateIcons(self)
780 | OmniBar_ShowAnchor(self)
781 | if zone == "arena" and (not self.disabled) then
782 | wipe(self.detected)
783 | wipe(self.specs)
784 | wipe(self.spellCasts)
785 | OmniBar_OnEvent(self, "ARENA_OPPONENT_UPDATE")
786 | end
787 | end
788 |
789 | end
790 |
791 | local UNITNAME_SUMMON_TITLES = {
792 | UNITNAME_SUMMON_TITLE1,
793 | UNITNAME_SUMMON_TITLE2,
794 | UNITNAME_SUMMON_TITLE3,
795 | }
796 | local tooltip = CreateFrame("GameTooltip", "OmniBarPetTooltip", nil, "GameTooltipTemplate")
797 | local tooltipText = OmniBarPetTooltipTextLeft2
798 | local function UnitOwnerName(guid)
799 | if (not guid) then return end
800 | for i = 1, 3 do
801 | _G["UNITNAME_SUMMON_TITLE" .. i] = "OmniBar %s"
802 | end
803 | tooltip:SetOwner(UIParent, "ANCHOR_NONE")
804 | tooltip:SetHyperlink("unit:" .. guid)
805 | local name = tooltipText:GetText()
806 | for i = 1, 3 do
807 | _G["UNITNAME_SUMMON_TITLE" .. i] = UNITNAME_SUMMON_TITLES[i]
808 | end
809 | if (not name) then return end
810 | local owner = name:match("OmniBar (.+)")
811 | if owner then return owner end
812 | end
813 |
814 | local function IsSourceHostile(sourceFlags)
815 | local band = bit_band(sourceFlags, COMBATLOG_OBJECT_REACTION_HOSTILE)
816 | if UnitIsPossessed("player") and band == 0 then return true end
817 | return band == COMBATLOG_OBJECT_REACTION_HOSTILE
818 | end
819 |
820 | local function GetCooldownDuration(cooldown, specID)
821 | if (not cooldown.duration) then return end
822 | if type(cooldown.duration) == "table" then
823 | if specID and cooldown.duration[specID] then
824 | return cooldown.duration[specID]
825 | else
826 | return cooldown.duration.default
827 | end
828 | else
829 | return cooldown.duration
830 | end
831 | end
832 |
833 | function OmniBar:AddSpellCast(event, sourceGUID, sourceName, sourceFlags, spellID, serverTime, customDuration)
834 | local isLocal = (not serverTime)
835 | serverTime = serverTime or GetServerTime()
836 |
837 | -- activate shared cooldowns
838 | if (not customDuration) then
839 | for i = 1, #addon.Shared do
840 | local shared = addon.Shared[i]
841 | if (shared.triggers and tContains(shared.triggers, spellID)) or tContains(shared.spells, spellID) then
842 | for i = 1, #shared.spells do
843 | if spellID ~= shared.spells[i] then
844 | local amount = shared.amount
845 | -- use default until we add spec detection
846 | if type(amount) == "table" then amount = shared.amount.default end
847 | if addon.Cooldowns[shared.spells[i]] and (not addon.Cooldowns[shared.spells[i]].parent) then
848 | self:AddSpellCast(
849 | event,
850 | sourceGUID,
851 | sourceName,
852 | sourceFlags,
853 | shared.spells[i],
854 | nil, -- set to `serverTime` to disable sync
855 | amount
856 | )
857 | end
858 | end
859 | end
860 | end
861 | end
862 | end
863 |
864 | if (not addon.Resets[spellID]) and (not addon.Cooldowns[spellID]) then return end
865 |
866 | -- unset unknown sourceName
867 | sourceName = sourceName == COMBATLOG_FILTER_STRING_UNKNOWN_UNITS and nil or sourceName
868 |
869 | -- if it's a pet associate with owner
870 | local ownerName = UnitOwnerName(sourceGUID)
871 | local name = ownerName or sourceName
872 |
873 | if (not name) then return end
874 |
875 | if addon.Resets[spellID] and self.spellCasts[name] and event == "SPELL_CAST_SUCCESS" then
876 | for i = 1, #addon.Resets[spellID] do
877 | local reset = addon.Resets[spellID][i]
878 | if type(reset) == "table" and reset.amount then
879 | if self.spellCasts[name][reset.spellID] then
880 | self.spellCasts[name][reset.spellID].duration = self.spellCasts[name][reset.spellID].duration - reset.amount
881 | if self.spellCasts[name][reset.spellID].duration < 1 then
882 | self.spellCasts[name][reset.spellID] = nil
883 | end
884 | end
885 | else
886 | if type(reset) == "table" then reset = reset.spellID end
887 | self.spellCasts[name][reset] = nil
888 | end
889 | end
890 | self:SendMessage("OmniBar_ResetSpellCast", name, spellID)
891 | end
892 |
893 | if (not addon.Cooldowns[spellID]) then return end
894 |
895 | local now = GetTime()
896 |
897 | local charges = addon.Cooldowns[spellID].charges
898 | local duration = customDuration or GetCooldownDuration(addon.Cooldowns[spellID])
899 |
900 | -- make sure spellID is parent
901 | spellID = addon.Cooldowns[spellID].parent or spellID
902 |
903 | -- make sure we aren't adding a duplicate,
904 | -- and if it is a shared cooldown make sure we don't overwrite
905 | if self.spellCasts[name] and
906 | self.spellCasts[name][spellID] and
907 | (customDuration or self.spellCasts[name][spellID].serverTime == serverTime)
908 | then
909 | return
910 | end
911 |
912 | -- only track players and their pets
913 | if (not ownerName) and bit_band(sourceFlags, COMBATLOG_OBJECT_TYPE_PLAYER) == 0 then return end
914 |
915 | -- child doesn't have custom charges, use parent
916 | if (not charges) then
917 | charges = addon.Cooldowns[spellID].charges
918 | end
919 |
920 | -- child doesn't have a custom duration, use parent
921 | if (not duration) then
922 | duration = GetCooldownDuration(addon.Cooldowns[spellID])
923 | end
924 |
925 | -- combat log is clamped in classic, so make sure our raid members detect the cast
926 | -- if WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE and isLocal then
927 | -- self:AlertGroup(event, sourceGUID, sourceName, sourceFlags, spellID, serverTime)
928 | -- end
929 |
930 | self.spellCasts[name] = self.spellCasts[name] or {}
931 | self.spellCasts[name][spellID] = {
932 | charges = charges,
933 | duration = duration,
934 | event = event,
935 | expires = now + duration,
936 | ownerName = ownerName,
937 | serverTime = serverTime,
938 | sourceFlags = sourceFlags,
939 | sourceGUID = sourceGUID,
940 | sourceName = sourceName,
941 | spellID = spellID,
942 | spellName = GetSpellName(spellID),
943 | timestamp = now,
944 | }
945 |
946 | self:SendMessage("OmniBar_SpellCast", name, spellID)
947 | end
948 |
949 | function OmniBar:AlertGroup(...)
950 | if (not IsInGroup()) or GetNumGroupMembers() > 5 then return end
951 | local event, sourceGUID, sourceName, sourceFlags, spellID, serverTime = ...
952 | self:SendCommMessage("OmniBarSpell", self:Serialize(...), GetDefaultCommChannel(), nil, "ALERT")
953 | end
954 |
955 | -- Needed to track PvP trinkets and possibly other spells that do not show up in COMBAT_LOG_EVENT_UNFILTERED
956 | function OmniBar:UNIT_SPELLCAST_SUCCEEDED(event, unit, _, spellID)
957 | if (not addon.Cooldowns[spellID]) then return end
958 |
959 | local sourceFlags = 0
960 |
961 | if UnitReaction("player", unit) < 4 then
962 | sourceFlags = sourceFlags + COMBATLOG_OBJECT_REACTION_HOSTILE
963 | end
964 |
965 | if UnitIsPlayer(unit) then
966 | sourceFlags = sourceFlags + COMBATLOG_OBJECT_TYPE_PLAYER
967 | end
968 |
969 | self:AddSpellCast(event, UnitGUID(unit), GetUnitName(unit, true), sourceFlags, spellID)
970 | end
971 |
972 | function OmniBar:COMBAT_LOG_EVENT_UNFILTERED()
973 | local _, event, _, sourceGUID, sourceName, sourceFlags, _,_,_,_,_, spellID, spellName = CombatLogGetCurrentEventInfo()
974 | if (event == "SPELL_CAST_SUCCESS" or event == "SPELL_AURA_APPLIED") then
975 | if spellID == 0 and SPELL_ID_BY_NAME then spellID = SPELL_ID_BY_NAME[spellName] end
976 | self:AddSpellCast(event, sourceGUID, sourceName, sourceFlags, spellID)
977 | end
978 | end
979 |
980 | function OmniBar_Refresh(self)
981 | OmniBar_ResetIcons(self)
982 | OmniBar_ReplaySpellCasts(self)
983 | end
984 |
985 | function OmniBar_OnEvent(self, event, ...)
986 | if event == "PLAYER_ENTERING_WORLD" then
987 | OmniBar_SetZone(self, true)
988 | OmniBar_OnEvent(self, "ARENA_PREP_OPPONENT_SPECIALIZATIONS")
989 |
990 | elseif event == "ZONE_CHANGED_NEW_AREA" then
991 | OmniBar_SetZone(self, true)
992 |
993 | elseif event == "UPDATE_BATTLEFIELD_STATUS" then -- IsRatedBattleground() doesn't return valid response until this event
994 | if self.disabled or self.zone ~= "pvp" then return end
995 | if (not self.rated) and IsRatedBattleground() then OmniBar_SetZone(self) end
996 |
997 | elseif event == "UPDATE_BATTLEFIELD_SCORE" then
998 | for i = 1, GetNumBattlefieldScores() do
999 | local name, _,_,_,_,_,_,_, classToken, _,_,_,_,_,_, talentSpec = GetBattlefieldScore(i)
1000 | if name and SPEC_ID_BY_NAME[classToken] and SPEC_ID_BY_NAME[classToken][talentSpec] then
1001 | if (not self.specs[name]) then
1002 | self.specs[name] = SPEC_ID_BY_NAME[classToken][talentSpec]
1003 | self:SendMessage("OmniBar_SpecUpdated", name)
1004 | end
1005 | end
1006 | end
1007 |
1008 | elseif event == "ARENA_PREP_OPPONENT_SPECIALIZATIONS" then
1009 | if WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE then return end
1010 | if self.disabled or (not self.adaptive) or (not self.settings.showUnused) then return end
1011 | for i = 1, MAX_ARENA_SIZE do
1012 | if self.settings.trackUnit == "ENEMY" or self.settings.trackUnit == "arena" .. i then
1013 | local specID = GetArenaOpponentSpec(i)
1014 | if specID and specID > 0 and (not self.detected[i]) then
1015 | local _,_,_,_,_, class = GetSpecializationInfoByID(specID)
1016 | if class then
1017 | self.detected[i] = class
1018 | OmniBar_AddIconsByClass(self, class, i, specID)
1019 | end
1020 | end
1021 | end
1022 | end
1023 |
1024 | elseif event == "ARENA_OPPONENT_UPDATE" then
1025 | if self.disabled or (not self.settings.showUnused) then return end
1026 |
1027 | local unit, reason = ...
1028 |
1029 | if reason == "cleared" then
1030 | wipe(self.detected)
1031 | wipe(self.spellCasts)
1032 | OmniBar_Refresh(self)
1033 | end
1034 |
1035 | -- we get the info from ARENA_PREP_OPPONENT_SPECIALIZATIONS on retail
1036 | if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
1037 | OmniBar_OnEvent(self, "ARENA_PREP_OPPONENT_SPECIALIZATIONS")
1038 | return
1039 | end
1040 |
1041 | if (not unit) or (not UnitIsPlayer(unit)) then return end
1042 |
1043 | if unit == self.settings.trackUnit then
1044 | OmniBar_Refresh(self)
1045 | return
1046 | end
1047 |
1048 | if self.settings.trackUnit == "ENEMY" then
1049 | local _, class = UnitClass(unit)
1050 | if class then
1051 | local i = tonumber(unit:match("%d+$"))
1052 | if (not self.detected[i]) then
1053 | self.detected[i] = class
1054 | OmniBar_AddIconsByClass(self, class, i)
1055 | end
1056 | end
1057 | end
1058 |
1059 | elseif event == "GROUP_ROSTER_UPDATE" then
1060 | if self.disabled then return end
1061 | if self.settings.trackUnit == "GROUP" or self.settings.trackUnit:match("^party") then
1062 | OmniBar_Refresh(self)
1063 | end
1064 |
1065 | elseif event == "PVP_MATCH_ACTIVE" then
1066 | if self.zone == "arena" then
1067 | OmniBar_ResetIcons(self)
1068 | end
1069 |
1070 | elseif event == "PLAYER_TARGET_CHANGED" or event == "PLAYER_FOCUS_CHANGED" or event == "PLAYER_REGEN_DISABLED" then
1071 | if self.disabled then return end
1072 |
1073 | local unit = (event == "PLAYER_TARGET_CHANGED" and "target") or (event == "PLAYER_FOCUS_CHANGED" and "focus")
1074 | if unit and unit:upper() == self.settings.trackUnit then
1075 | OmniBar_Refresh(self)
1076 | end
1077 |
1078 | -- update icon borders
1079 | OmniBar_UpdateAllBorders(self)
1080 |
1081 | -- we don't need to add in arena
1082 | if self.zone == "arena" then return end
1083 |
1084 | -- only add to bars tracking all enemies
1085 | if self.settings.trackUnit ~= "ENEMY" then return end
1086 |
1087 | -- only add icons if show adaptive is checked
1088 | if (not self.settings.showUnused) or
1089 | (not self.adaptive) or
1090 | (not UnitIsHostile("target"))
1091 | then
1092 | return
1093 | end
1094 |
1095 | -- only add icons when we're in combat
1096 | -- if event == "PLAYER_TARGET_CHANGED" and (not InCombatLockdown()) then return end
1097 |
1098 | local guid = UnitGUID("target")
1099 | local _, class = UnitClass("target")
1100 | if class and UnitIsPlayer("target") then
1101 | if self.detected[guid] then return end
1102 | self.detected[guid] = class
1103 | OmniBar_AddIconsByClass(self, class, nil, self.specs[GetUnitName("target", true)])
1104 | end
1105 | end
1106 | end
1107 |
1108 | function OmniBar_LoadSettings(self)
1109 |
1110 | -- Set the scale
1111 | self.container:SetScale(self.settings.size/BASE_ICON_SIZE)
1112 |
1113 | OmniBar_LoadPosition(self)
1114 | OmniBar_ResetIcons(self)
1115 | OmniBar_UpdateIcons(self)
1116 | OmniBar_Center(self)
1117 | end
1118 |
1119 | function OmniBar_SavePosition(self, set)
1120 | local point, relativeTo, relativePoint, xOfs, yOfs = self:GetPoint()
1121 | local frameStrata = self:GetFrameStrata()
1122 | relativeTo = relativeTo and relativeTo:GetName() or "UIParent"
1123 | if set then
1124 | if set.point then point = set.point end
1125 | if set.relativeTo then relativeTo = set.relativeTo end
1126 | if set.relativePoint then relativePoint = set.relativePoint end
1127 | if set.xOfs then xOfs = set.xOfs end
1128 | if set.yOfs then yOfs = set.yOfs end
1129 | if set.frameStrata then frameStrata = set.frameStrata end
1130 | end
1131 |
1132 | if (not self.settings.position) then
1133 | self.settings.position = {}
1134 | end
1135 | self.settings.position.point = point
1136 | self.settings.position.relativeTo = relativeTo
1137 | self.settings.position.relativePoint = relativePoint
1138 | self.settings.position.xOfs = xOfs
1139 | self.settings.position.yOfs = yOfs
1140 | self.settings.position.frameStrata = frameStrata
1141 | end
1142 |
1143 | function OmniBar_ResetPosition(self)
1144 | self.settings.position.relativeTo = "UIParent"
1145 | self.settings.position.relativePoint = "CENTER"
1146 | self.settings.position.xOfs = 0
1147 | self.settings.position.yOfs = 0
1148 | OmniBar_LoadPosition(self)
1149 | end
1150 |
1151 | function OmniBar_LoadPosition(self)
1152 | self:ClearAllPoints()
1153 | if self.settings.position then
1154 | local point = self.settings.position.point or "CENTER"
1155 | self.anchor:ClearAllPoints()
1156 | self.anchor:SetPoint(point, self, point, 0, 0)
1157 | local relativeTo = self.settings.position.relativeTo or "UIParent"
1158 | if (not _G[relativeTo]) then
1159 | OmniBar_ResetPosition(self)
1160 | return
1161 | end
1162 | local relativePoint = self.settings.position.relativePoint or "CENTER"
1163 | local xOfs = self.settings.position.xOfs or 0
1164 | local yOfs = self.settings.position.yOfs or 0
1165 | self:SetPoint(point, relativeTo, relativePoint, xOfs, yOfs)
1166 | if (not self.settings.position.frameStrata) then self.settings.position.frameStrata = "MEDIUM" end
1167 | self:SetFrameStrata(self.settings.position.frameStrata)
1168 | else
1169 | self:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
1170 | OmniBar_SavePosition(self)
1171 | end
1172 | end
1173 |
1174 | function OmniBar_IsSpellEnabled(self, spellID)
1175 | if (not spellID) then return end
1176 |
1177 | if (not self.settings.spells) then return addon.Cooldowns[spellID].default end
1178 |
1179 | return self.settings.spells[spellID]
1180 | end
1181 |
1182 | function OmniBar:GetSpellTexture(spellID)
1183 | spellID = tonumber(spellID)
1184 | return (addon.Cooldowns[spellID] and addon.Cooldowns[spellID].icon) or GetSpellTexture(spellID)
1185 | end
1186 |
1187 | function OmniBar_SpecUpdated(self, event, name)
1188 | if self.disabled then return end
1189 | if self.settings.trackUnit == "GROUP" or UnitIsUnit(self.settings.trackUnit, name) then
1190 | OmniBar_Refresh(self)
1191 | end
1192 | end
1193 |
1194 | function OmniBar:GetSpecs()
1195 | if (not GetSpecializationInfo) then return end
1196 | if (not self.specs[PLAYER_NAME]) then
1197 | self.specs[PLAYER_NAME] = GetSpecializationInfo(GetSpecialization())
1198 | self:SendMessage("OmniBar_SpecUpdated", PLAYER_NAME)
1199 | end
1200 | if self.lastInspect and GetTime() - self.lastInspect < 3 then
1201 | return
1202 | end
1203 | for i = 1, GetNumGroupMembers() do
1204 | local name, _,_,_,_, class = GetRaidRosterInfo(i)
1205 | if name and (not self.specs[name]) and (not UnitIsUnit("player", name)) and CanInspect(name) then
1206 | self.inspectUnit = name
1207 | self.lastInspect = GetTime()
1208 | self:RegisterEvent("INSPECT_READY")
1209 | NotifyInspect(name)
1210 | return
1211 | end
1212 | end
1213 | end
1214 |
1215 | function OmniBar:INSPECT_READY(event, guid)
1216 | if (not self.inspectUnit) then return end
1217 | local unit = self.inspectUnit
1218 | self.inspectUnit = nil
1219 | self:UnregisterEvent("INSPECT_READY")
1220 | if (UnitGUID(unit) ~= guid) then
1221 | ClearInspectPlayer()
1222 | self:GetSpecs()
1223 | return
1224 | end
1225 | self.specs[unit] = GetInspectSpecialization(unit)
1226 | self:SendMessage("OmniBar_SpecUpdated", unit)
1227 | ClearInspectPlayer()
1228 | self:GetSpecs()
1229 | end
1230 |
1231 | function OmniBar_IsUnitEnabled(self, info)
1232 | if (not info.timestamp) then return true end
1233 | if info.test then return true end
1234 |
1235 | local guid = info.sourceGUID
1236 | if guid == nil then return end
1237 |
1238 | local name = info.ownerName or info.sourceName
1239 |
1240 | local isHostile = IsSourceHostile(info.sourceFlags)
1241 |
1242 | if self.settings.trackUnit == "ENEMY" and isHostile then
1243 | return true
1244 | end
1245 |
1246 | local isPlayer = UnitIsUnit("player", name)
1247 |
1248 | if self.settings.trackUnit == "PLAYER" and isPlayer then
1249 | return true
1250 | end
1251 |
1252 | if self.settings.trackUnit == "TARGET" and (UnitGUID("target") == guid or GetUnitName("target", true) == name) then
1253 | return true
1254 | end
1255 |
1256 | if self.settings.trackUnit == "FOCUS" and (UnitGUID("focus") == guid or GetUnitName("focus", true) == name) then
1257 | return true
1258 | end
1259 |
1260 | if self.settings.trackUnit == "GROUP" and (not isPlayer) and (UnitInParty(name) or UnitInRaid(name)) then
1261 | return true
1262 | end
1263 |
1264 | for i = 1, MAX_ARENA_SIZE do
1265 | local unit = "arena" .. i
1266 | if (i == guid or UnitGUID(unit) == guid) and self.settings.trackUnit == unit:lower() then
1267 | return true
1268 | end
1269 | end
1270 |
1271 | for i = 1, 4 do
1272 | local unit = "party" .. i
1273 | if (i == guid or UnitGUID(unit) == guid) and self.settings.trackUnit == unit:lower() then
1274 | return true
1275 | end
1276 | end
1277 | end
1278 |
1279 | function OmniBar_Center(self)
1280 | local parentWidth = UIParent:GetWidth()
1281 | local clamp = self.settings.center and (1 - parentWidth)/2 or 0
1282 | self:SetClampRectInsets(clamp, -clamp, 0, 0)
1283 | clamp = self.settings.center and (self.anchor:GetWidth() - parentWidth)/2 or 0
1284 | self.anchor:SetClampRectInsets(clamp, -clamp, 0, 0)
1285 | end
1286 |
1287 | function OmniBar_CooldownFinish(self, force)
1288 | local icon = self:GetParent()
1289 | if icon.cooldown and icon.cooldown:GetCooldownTimes() > 0 and (not force) then return end -- not complete
1290 | local charges = icon.charges
1291 | if charges then
1292 | charges = charges - 1
1293 | if charges > 0 then
1294 | -- remove a charge
1295 | icon.charges = charges
1296 | icon.Count:SetText(charges)
1297 | if self.omnicc then
1298 | self.omnicc:HookScript('OnHide', function()
1299 | OmniBar_StartCooldown(icon:GetParent():GetParent(), icon, GetTime())
1300 | end)
1301 | end
1302 | OmniBar_StartCooldown(icon:GetParent():GetParent(), icon, GetTime())
1303 | return
1304 | end
1305 | end
1306 |
1307 | local bar = icon:GetParent():GetParent()
1308 |
1309 | OmniBar_StopAnimation(self, icon)
1310 |
1311 | if (not bar.settings.showUnused) then
1312 | icon:Hide()
1313 | else
1314 | if icon.TargetTexture:GetAlpha() == 0 and
1315 | icon.FocusTexture:GetAlpha() == 0 and
1316 | bar.settings.unusedAlpha then
1317 | icon:SetAlpha(bar.settings.unusedAlpha)
1318 | end
1319 | end
1320 | bar:StopMovingOrSizing()
1321 | OmniBar_Position(bar)
1322 | end
1323 |
1324 | function OmniBar_ReplaySpellCasts(self)
1325 | if self.disabled then return end
1326 |
1327 | local now = GetTime()
1328 |
1329 | for name,_ in pairs(self.spellCasts) do
1330 | for k,v in pairs(self.spellCasts[name]) do
1331 | if now >= v.expires then
1332 | self.spellCasts[name][k] = nil
1333 | else
1334 | OmniBar_AddIcon(self, self.spellCasts[name][k])
1335 | end
1336 | end
1337 | end
1338 | end
1339 |
1340 | local function OmniBar_UnitClassAndSpec(self)
1341 | local unit = self.settings.trackUnit
1342 | if unit == "ENEMY" or unit == "GROUP" then return end
1343 | local _, class = UnitClass(unit)
1344 | local specID = self.specs[GetUnitName(unit, true)]
1345 | return class, specID
1346 | end
1347 |
1348 | function OmniBar_ResetIcons(self)
1349 | -- Hide all the icons
1350 | for i = 1, self.numIcons do
1351 | if self.icons[i].MasqueGroup then
1352 | --self.icons[i].MasqueGroup:Delete()
1353 | self.icons[i].MasqueGroup = nil
1354 | end
1355 | self.icons[i].TargetTexture:SetAlpha(0)
1356 | self.icons[i].FocusTexture:SetAlpha(0)
1357 | self.icons[i].flash:SetAlpha(0)
1358 | self.icons[i].NewItemTexture:SetAlpha(0)
1359 | self.icons[i].cooldown:SetCooldown(0, 0)
1360 | self.icons[i].cooldown:Hide()
1361 | self.icons[i]:Hide()
1362 | end
1363 | wipe(self.active)
1364 |
1365 | if self.disabled then return end
1366 |
1367 | if self.settings.showUnused then
1368 | if self.settings.trackUnit == "ENEMY" then
1369 | if (not self.adaptive) then
1370 | for spellID,_ in pairs(addon.Cooldowns) do
1371 | if OmniBar_IsSpellEnabled(self, spellID) then
1372 | OmniBar_AddIcon(self, { spellID = spellID })
1373 | end
1374 | end
1375 | end
1376 | elseif self.settings.trackUnit == "GROUP" then
1377 | for i = 1, GetNumGroupMembers() do
1378 | local name, _,_,_,_, class = GetRaidRosterInfo(i)
1379 | local guid = UnitGUID(name)
1380 | if class and (not UnitIsUnit("player", name)) then
1381 | OmniBar_AddIconsByClass(self, class, UnitGUID(name), self.specs[name])
1382 | end
1383 | end
1384 | else
1385 | local class, specID = OmniBar_UnitClassAndSpec(self)
1386 | if class and UnitIsPlayer(self.settings.trackUnit) then
1387 | OmniBar_AddIconsByClass(self, class, nil, specID)
1388 | end
1389 | end
1390 | end
1391 |
1392 | OmniBar_Position(self)
1393 | end
1394 |
1395 | function OmniBar_StartCooldown(self, icon, start)
1396 | icon.cooldown:SetCooldown(start, icon.duration)
1397 | icon.cooldown.finish = start + icon.duration
1398 | icon.cooldown:SetSwipeColor(0, 0, 0, self.settings.swipeAlpha or 0.65)
1399 | icon:SetAlpha(1)
1400 | end
1401 |
1402 | function OmniBar_AddIcon(self, info)
1403 | if (not OmniBar_IsUnitEnabled(self, info)) then return end
1404 | if (not OmniBar_IsSpellEnabled(self, info.spellID)) then return end
1405 |
1406 | local icon, duplicate
1407 |
1408 | -- Try to reuse a visible frame
1409 | for i = 1, #self.active do
1410 | if self.active[i].spellID == info.spellID then
1411 | duplicate = true
1412 | -- check if we can use this icon, but not when initializing arena opponents
1413 | if info.timestamp or self.zone ~= "arena" then
1414 | -- use icon if not bound to a sourceGUID
1415 | if (not self.active[i].sourceGUID) then
1416 | duplicate = nil
1417 | icon = self.active[i]
1418 | break
1419 | end
1420 |
1421 | -- if it's the same source, reuse the icon
1422 | if info.sourceGUID and IconIsUnit(self.active[i].sourceGUID, info.sourceGUID) then
1423 | duplicate = nil
1424 | icon = self.active[i]
1425 | break
1426 | end
1427 |
1428 | end
1429 | end
1430 | end
1431 |
1432 | -- We couldn't find a visible frame to reuse, try to find an unused
1433 | if (not icon) then
1434 | if #self.active >= self.settings.maxIcons then return end
1435 | if (not self.settings.multiple) and duplicate then return end
1436 | for i = 1, #self.icons do
1437 | if (not self.icons[i]:IsVisible()) then
1438 | icon = self.icons[i]
1439 | icon.specID = nil
1440 | break
1441 | end
1442 | end
1443 | end
1444 |
1445 | -- We couldn't find a frame to use
1446 | if (not icon) then return end
1447 |
1448 | icon.class = addon.Cooldowns[info.spellID].class
1449 | icon.sourceGUID = info.sourceGUID
1450 | icon.sourceName = info.ownerName or info.sourceName
1451 | icon.specID = info.specID and info.specID or self.specs[icon.sourceName]
1452 | icon.icon:SetTexture(addon.Cooldowns[info.spellID].icon)
1453 | icon.spellID = info.spellID
1454 | icon.timestamp = info.test and GetTime() or info.timestamp
1455 | icon.duration = info.test and math.random(5,30) or info.duration
1456 | icon.added = GetTime()
1457 | icon.expires = info.test and icon.timestamp + icon.duration or info.expires
1458 |
1459 | if icon.charges and info.charges and icon:IsVisible() then
1460 | local start, duration = icon.cooldown:GetCooldownTimes()
1461 | if icon.cooldown.finish and icon.cooldown.finish - GetTime() > 1 then
1462 | -- add a charge
1463 | local charges = icon.charges + 1
1464 | icon.charges = charges
1465 | icon.Count:SetText(charges)
1466 | OmniBar_StartAnimation(self, icon)
1467 | return icon
1468 | end
1469 | elseif info.charges then
1470 | icon.charges = 1
1471 | icon.Count:SetText("1")
1472 | else
1473 | icon.charges = nil
1474 | icon.Count:SetText(nil)
1475 | end
1476 |
1477 | if self.settings.names then
1478 | local name = info.test and "Name" or icon.sourceName
1479 | icon.Name:SetText(name)
1480 | end
1481 |
1482 | -- Masque
1483 | if Masque then
1484 | icon.MasqueGroup = Masque:Group("OmniBar", info.spellName)
1485 | icon.MasqueGroup:AddButton(icon, {
1486 | FloatingBG = false,
1487 | Icon = icon.icon,
1488 | Cooldown = icon.cooldown,
1489 | Flash = false,
1490 | Pushed = false,
1491 | Normal = icon:GetNormalTexture(),
1492 | Disabled = false,
1493 | Checked = false,
1494 | Border = _G[icon:GetName().."Border"],
1495 | AutoCastable = false,
1496 | Highlight = false,
1497 | Hotkey = false,
1498 | Count = false,
1499 | Name = false,
1500 | Duration = false,
1501 | AutoCast = false,
1502 | })
1503 | end
1504 |
1505 | icon:Show()
1506 |
1507 | if (icon.timestamp) then
1508 | OmniBar_StartCooldown(self, icon, icon.timestamp)
1509 | if (GetTime() == icon.timestamp) then OmniBar_StartAnimation(self, icon) end
1510 | end
1511 |
1512 | return icon
1513 | end
1514 |
1515 | function OmniBar_UpdateIcons(self)
1516 | for i = 1, self.numIcons do
1517 | -- Set show text
1518 | self.icons[i].cooldown:SetHideCountdownNumbers(not self.settings.cooldownCount and true or false)
1519 | self.icons[i].cooldown.noCooldownCount = (not self.settings.cooldownCount)
1520 |
1521 | -- Set swipe alpha
1522 | self.icons[i].cooldown:SetSwipeColor(0, 0, 0, self.settings.swipeAlpha or 0.65)
1523 |
1524 | -- Set border
1525 | if self.settings.border then
1526 | self.icons[i].icon:SetTexCoord(0, 0, 0, 1, 1, 0, 1, 1)
1527 | else
1528 | self.icons[i].icon:SetTexCoord(0.07, 0.9, 0.07, 0.9)
1529 | end
1530 |
1531 | -- Set dim
1532 | self.icons[i]:SetAlpha(self.settings.unusedAlpha and self.icons[i].cooldown:GetCooldownTimes() == 0 and
1533 | self.settings.unusedAlpha or 1)
1534 |
1535 | -- Masque
1536 | if self.icons[i].MasqueGroup then self.icons[i].MasqueGroup:ReSkin() end
1537 |
1538 | end
1539 | end
1540 |
1541 | function OmniBar_Test(self)
1542 | if (not self) then return end
1543 | self.disabled = nil
1544 | OmniBar_ResetIcons(self)
1545 | if self.settings.spells then
1546 | for k,v in pairs(self.settings.spells) do
1547 | OmniBar_AddIcon(self, { spellID = k, test = true })
1548 | end
1549 | else
1550 | for k,v in pairs(addon.Cooldowns) do
1551 | if v.default then
1552 | OmniBar_AddIcon(self, { spellID = k, test = true })
1553 | end
1554 | end
1555 | end
1556 | end
1557 |
1558 | local function SortIconsByRemainingTime(self)
1559 | table.sort(self.active, function(a, b)
1560 | return a.expires == b.expires and a.spellID < b.spellID or a.expires < b.expires
1561 | end)
1562 | end
1563 |
1564 | local function SortIconsByTimeAdded(self)
1565 | table.sort(self.active, function(a, b)
1566 | return a.added == b.added and a.spellID < b.spellID or a.added < b.added
1567 | end)
1568 | end
1569 |
1570 | function OmniBar_Position(self)
1571 | local numActive = #self.active
1572 | if numActive == 0 then
1573 | -- Show the anchor if needed
1574 | OmniBar_ShowAnchor(self)
1575 | return
1576 | end
1577 |
1578 | -- Keep cooldowns together by class
1579 | if self.settings.showUnused then
1580 | table.sort(self.active, function(a, b)
1581 | local x, y = a.ownerName or a.sourceName or "", b.ownerName or b.sourceName or ""
1582 | local aClass, bClass = a.class or 0, b.class or 0
1583 | if aClass == bClass then
1584 | -- if we are tracking a single unit we don't need to sort by name
1585 | if self.settings.trackUnit ~= "ENEMY" and self.settings.trackUnit ~= "GROUP" then
1586 | return a.spellID < b.spellID
1587 | end
1588 | if x < y then return true end
1589 | if x == y then return a.spellID < b.spellID end
1590 | end
1591 | return CLASS_ORDER[aClass] < CLASS_ORDER[bClass]
1592 | end)
1593 | else
1594 | -- if we aren't showing unused, sort active icons based on user preference: time remaining or time added
1595 | if self.settings.iconSorting == "TIME_REMAINING" then
1596 | SortIconsByRemainingTime(self)
1597 | else
1598 | SortIconsByTimeAdded(self)
1599 | end
1600 | end
1601 |
1602 | local count, rows = 0, 1
1603 | local grow = self.settings.growUpward and 1 or -1
1604 | local padding = self.settings.padding and self.settings.padding or 0
1605 | for i = 1, numActive do
1606 | if self.settings.locked then
1607 | self.active[i]:EnableMouse(false)
1608 | else
1609 | self.active[i]:EnableMouse(true)
1610 | end
1611 | self.active[i]:ClearAllPoints()
1612 | local columns = self.settings.columns and self.settings.columns > 0 and self.settings.columns < numActive and
1613 | self.settings.columns or numActive
1614 | if i > 1 then
1615 | count = count + 1
1616 | if count >= columns then
1617 | if self.settings.align == "CENTER" then
1618 | self.active[i]:SetPoint("CENTER", self.anchor, "CENTER", (-BASE_ICON_SIZE-padding)*(columns-1)/2, (BASE_ICON_SIZE+padding)*rows*grow)
1619 | else
1620 | self.active[i]:SetPoint(self.settings.align, self.anchor, self.settings.align, 0, (BASE_ICON_SIZE+padding)*rows*grow)
1621 | end
1622 |
1623 | count = 0
1624 | rows = rows + 1
1625 | else
1626 | if self.settings.align == "RIGHT" then
1627 | self.active[i]:SetPoint("TOPRIGHT", self.active[i-1], "TOPLEFT", -1 * padding, 0)
1628 | else
1629 | self.active[i]:SetPoint("TOPLEFT", self.active[i-1], "TOPRIGHT", padding, 0)
1630 | end
1631 | end
1632 |
1633 | else
1634 | if self.settings.align == "CENTER" then
1635 | self.active[i]:SetPoint("CENTER", self.anchor, "CENTER", (-BASE_ICON_SIZE-padding)*(columns-1)/2, 0)
1636 | else
1637 | self.active[i]:SetPoint(self.settings.align, self.anchor, self.settings.align, 0, 0)
1638 | end
1639 | end
1640 | end
1641 | OmniBar_ShowAnchor(self)
1642 | end
1643 |
1644 | function OmniBar:Test()
1645 | for key,_ in pairs(self.db.profile.bars) do
1646 | OmniBar_Test(_G[key])
1647 | end
1648 | end
1649 |
1650 | SLASH_OmniBar1 = "/ob"
1651 | SLASH_OmniBar2 = "/omnibar"
1652 | SlashCmdList.OmniBar = function()
1653 | if Settings and Settings.OpenToCategory then
1654 | Settings.OpenToCategory(addonName)
1655 | else
1656 | InterfaceOptionsFrame_OpenToCategory(addonName)
1657 | InterfaceOptionsFrame_OpenToCategory(addonName)
1658 | end
1659 | end
1660 |
--------------------------------------------------------------------------------
/OmniBar.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 110105, 110007, 110100
2 | ## Title: OmniBar
3 | ## Notes: Tracks enemy cooldowns
4 | ## Version: @project-version@
5 | ## Author: Jordon
6 | ## SavedVariables: OmniBarDB
7 | ## IconTexture: Interface\AddOns\OmniBar\Media\Textures\icon.blp
8 | ## X-Curse-Project-ID: 85814
9 | ## X-Wago-ID: BO678XK3
10 | ## X-WoWI-ID: 23235
11 |
12 | #@no-lib-strip@
13 | Libs\LibStub\LibStub.lua
14 | Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
15 | Libs\AceAddon-3.0\AceAddon-3.0.xml
16 | Libs\AceDB-3.0\AceDB-3.0.xml
17 | Libs\AceDBOptions-3.0\AceDBOptions-3.0.xml
18 | Libs\AceComm-3.0\AceComm-3.0.xml
19 | Libs\AceEvent-3.0\AceEvent-3.0.xml
20 | Libs\AceGUI-3.0\AceGUI-3.0.xml
21 | Libs\AceConfig-3.0\AceConfig-3.0.xml
22 | Libs\AceLocale-3.0\AceLocale-3.0.xml
23 | Libs\AceSerializer-3.0\AceSerializer-3.0.xml
24 | Libs\LibDualSpec-1.0\LibDualSpec-1.0.lua
25 | Libs\LibDeflate\LibDeflate.lua
26 | #@end-no-lib-strip@
27 |
28 | Locales\Locales.xml
29 | OmniBar.xml
30 | OmniBar_Mainline.lua
31 | OmniBar.lua
32 | Options.lua
33 |
--------------------------------------------------------------------------------
/OmniBar.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | local bar = self:GetParent()
41 | OmniBar_Center(bar)
42 | bar:StartMoving()
43 |
44 |
45 | local bar = self:GetParent()
46 | bar:StopMovingOrSizing()
47 | OmniBar_SavePosition(bar)
48 | LibStub("AceConfigRegistry-3.0"):NotifyChange("OmniBar")
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | LibStub("AceEvent-3.0"):Embed(self)
64 | self.SpellCast = OmniBar_SpellCast
65 | self:RegisterMessage("OmniBar_SpellCast", "SpellCast")
66 | self.Refresh = OmniBar_Refresh
67 | self:RegisterMessage("OmniBar_ResetSpellCast", "Refresh")
68 | self.SpecUpdated = OmniBar_SpecUpdated
69 | self:RegisterMessage("OmniBar_SpecUpdated", "SpecUpdated")
70 |
71 |
72 |
73 |
213 |
214 |
--------------------------------------------------------------------------------
/OmniBar_Cata.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 40402, 40401
2 | ## Title: OmniBar
3 | ## Notes: Tracks enemy cooldowns
4 | ## Version: @project-version@
5 | ## Author: Jordon
6 | ## SavedVariables: OmniBarDB
7 | ## IconTexture: Interface\AddOns\OmniBar\Media\Textures\icon.blp
8 | ## X-Curse-Project-ID: 85814
9 | ## X-Wago-ID: BO678XK3
10 | ## X-WoWI-ID: 23235
11 |
12 | #@no-lib-strip@
13 | Libs\LibStub\LibStub.lua
14 | Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
15 | Libs\AceAddon-3.0\AceAddon-3.0.xml
16 | Libs\AceDB-3.0\AceDB-3.0.xml
17 | Libs\AceDBOptions-3.0\AceDBOptions-3.0.xml
18 | Libs\AceComm-3.0\AceComm-3.0.xml
19 | Libs\AceEvent-3.0\AceEvent-3.0.xml
20 | Libs\AceGUI-3.0\AceGUI-3.0.xml
21 | Libs\AceConfig-3.0\AceConfig-3.0.xml
22 | Libs\AceLocale-3.0\AceLocale-3.0.xml
23 | Libs\AceSerializer-3.0\AceSerializer-3.0.xml
24 | Libs\LibDeflate\LibDeflate.lua
25 | #@end-no-lib-strip@
26 |
27 | Locales\Locales.xml
28 | OmniBar.xml
29 | OmniBar_Cata.lua
30 | OmniBar.lua
31 | Options.lua
32 |
--------------------------------------------------------------------------------
/OmniBar_Mainline.lua:
--------------------------------------------------------------------------------
1 | local addonName, addon = ...
2 |
3 | addon.MAX_ARENA_SIZE = 3
4 |
5 | addon.Shared = {}
6 |
7 | addon.Resets = {
8 | --[[ Grimoire: Felhunter
9 | - Spell Lock
10 | ]]
11 | [111897] = {119910},
12 | [133] = {{spellID = 190319, amount = 3}}
13 | }
14 |
15 | addon.Cooldowns = {
16 |
17 | -- Death Knight
18 |
19 | [47528] = {default = true, duration = 15, class = "DEATHKNIGHT"}, -- Mind Freeze
20 | [48265] = {duration = 45, class = "DEATHKNIGHT", charges = 2}, -- Death's Advance
21 | [444347] = {parent = 48265}, -- Death Charge
22 | [48707] = {duration = 40, class = "DEATHKNIGHT"}, -- Anti-Magic Shell
23 | [410358] = {parent = 48707, duration = 30}, -- Anti-Magic Shell (Spellwarden)
24 | [49576] = {duration = {default = 25, [250] = 15}, class = "DEATHKNIGHT", charges = 2}, -- Death Grip
25 | [51052] = {duration = 120, class = "DEATHKNIGHT"}, -- Anti-Magic Zone
26 | [61999] = {duration = 600, class = "DEATHKNIGHT"}, -- Raise Ally
27 | [77606] = {duration = 20, class = "DEATHKNIGHT"}, -- Dark Simulacrum
28 | [212552] = {duration = 60, class = "DEATHKNIGHT"}, -- Wraith Walk
29 | [47476] = {duration = 45, class = "DEATHKNIGHT"}, -- Strangulate
30 | [207167] = {duration = 60, class = "DEATHKNIGHT"}, -- Blinding Sleet
31 | [327574] = {duration = 120, class = "DEATHKNIGHT"}, -- Sacrificial Pact
32 | [221562] = {duration = 45, class = "DEATHKNIGHT"}, -- Asphyxiate
33 | [48792] = {duration = 120, class = "DEATHKNIGHT"}, -- Icebound Fortitude
34 | [383269] = {duration = 120, class = "DEATHKNIGHT"}, -- Abomination's Limb
35 | [48743] = {duration = 120, class = "DEATHKNIGHT"}, -- Death Pact
36 | [439843] = {duration = 30, class = "DEATHKNIGHT", specID = {250, 251}}, -- Reaper's Mark
37 | [43265] = {duration = 20, class = "DEATHKNIGHT", charges = 2}, -- Death and Decay
38 | [152280] = {parent = 43265, duration = 15, specID = {252}}, -- Defile
39 | [49039] = {duration = 120, class = "DEATHKNIGHT"}, -- Lichborne
40 |
41 | -- Blood
42 |
43 | [49028] = {duration = 120, class = "DEATHKNIGHT", specID = {250}}, -- Dancing Rune Weapon
44 | [55233] = {duration = 90, class = "DEATHKNIGHT", specID = {250}}, -- Vampiric Blood
45 | [108199] = {duration = 90, class = "DEATHKNIGHT", specID = {250}}, -- Gorefiend's Grasp
46 | [194679] = {duration = 25, class = "DEATHKNIGHT", specID = {250}, charges = 2}, -- Rune Tap
47 | [194844] = {duration = 60, class = "DEATHKNIGHT", specID = {250}}, -- Bonestorm
48 | [203173] = {duration = 30, class = "DEATHKNIGHT", specID = {250}}, -- Death Chain
49 | [274156] = {duration = 30, class = "DEATHKNIGHT", specID = {250}}, -- Consumption
50 | [206931] = {duration = 30, class = "DEATHKNIGHT", specID = {250}}, -- Blooddrinker
51 | [219809] = {duration = 60, class = "DEATHKNIGHT", specID = {250}}, -- Tombstone
52 | [221699] = {duration = 60, class = "DEATHKNIGHT", specID = {250}, charges = 2}, -- Blood Tap
53 |
54 | -- Frost
55 |
56 | [51271] = {duration = 60, class = "DEATHKNIGHT", specID = {251}}, -- Pillar of Frost
57 | [152279] = {duration = 120, class = "DEATHKNIGHT", specID = {251}}, -- Breath of Sindragosa
58 | [196770] = {duration = 20, class = "DEATHKNIGHT", specID = {251}}, -- Remorseless Winter
59 | [305392] = {duration = 45, class = "DEATHKNIGHT", specID = {251}}, -- Chill Streak
60 | [47568] = {duration = 120, class = "DEATHKNIGHT", specID = {251}}, -- Empower Rune Weapon
61 | [279302] = {duration = 90, class = "DEATHKNIGHT", specID = {251}}, -- Frostwyrm's Fury
62 |
63 | -- Unholy
64 |
65 | [42650] = {duration = 180, class = "DEATHKNIGHT", specID = {252}}, -- Army of the Dead
66 | [63560] = {duration = 45, class = "DEATHKNIGHT", specID = {252}}, -- Dark Transformation
67 | [47481] = {duration = 90, class = "DEATHKNIGHT", specID = {252}}, -- Gnaw (Ghoul)
68 | [47482] = {duration = 30, class = "DEATHKNIGHT", specID = {252}}, -- Leap (Ghoul)
69 | [49206] = {duration = 180, class = "DEATHKNIGHT", specID = {252}}, -- Summon Gargoyle
70 | [207349] = {parent = 49206}, -- Dark Arbiter
71 | [91802] = {duration = 30, class = "DEATHKNIGHT", specID = {252}}, -- Shambling Rush (Ghoul)
72 | [207289] = {duration = 90, class = "DEATHKNIGHT", specID = {252}}, -- Unholy Assault
73 | [275699] = {duration = 30, class = "DEATHKNIGHT", specID = {252}}, -- Apocalypse
74 | [390279] = {duration = 45, class = "DEATHKNIGHT", specID = {252}}, -- Vile Contagion
75 | [210128] = {duration = 12, class = "DEATHKNIGHT", specID = {252}, charges = 2}, -- Reanimation
76 | [455395] = {duration = 90, class = "DEATHKNIGHT", specID = {252}}, -- Raise Abomination
77 |
78 | -- Demon Hunter
79 |
80 | [179057] = {duration = 45, class = "DEMONHUNTER"}, -- Chaos Nova
81 | [183752] = {default = true, duration = 15, class = "DEMONHUNTER"}, -- Disrupt
82 | [188501] = {duration = 30, class = "DEMONHUNTER"}, -- Spectral Sight
83 | [191427] = {duration = 120, class = "DEMONHUNTER"}, -- Metamorphosis
84 | [187827] = {parent = 191427, duration = 120}, -- Metamorphosis (Vengeance)
85 | [196718] = {duration = 180, class = "DEMONHUNTER"}, -- Darkness
86 | [198793] = {duration = {default = 25, [577] = 20}, class = "DEMONHUNTER"}, -- Vengeful Retreat
87 | [205604] = {duration = 60, class = "DEMONHUNTER"}, -- Reverse Magic
88 | [206803] = {duration = 90, class = "DEMONHUNTER"}, -- Rain from Above
89 | [212800] = {duration = 60, class = "DEMONHUNTER"}, -- Blur
90 | [196555] = {duration = 180, class = "DEMONHUNTER"}, -- Netherwalk
91 | [217832] = {duration = 45, class = "DEMONHUNTER"}, -- Imprison
92 | [221527] = {parent = 217832}, -- Imprison (Detainment)
93 | [370965] = {duration = 90, class = "DEMONHUNTER"}, -- The Hunt
94 | [204596] = {duration = 30, class = "DEMONHUNTER"}, -- Sigil of Flame
95 | [452490] = {parent = 204596}, -- Sigil of Doom
96 | [207684] = {duration = 90, class = "DEMONHUNTER"}, -- Sigil of Misery
97 | [278326] = {duration = 10, class = "DEMONHUNTER"}, -- Consume Magic
98 |
99 | -- Havoc
100 |
101 | [258925] = {duration = 90, class = "DEMONHUNTER", specID = {577}}, -- Fel Barrage
102 | [211881] = {duration = 30, class = "DEMONHUNTER", specID = {577}}, -- Fel Eruption
103 | [390163] = {duration = 60, class = "DEMONHUNTER", specID = {577, 581}}, -- Elysian Decree
104 | [198013] = {duration = 40, class = "DEMONHUNTER", specID = {577}}, -- Eye Beam
105 | [452497] = {parent = 198013}, -- Abyssal Gaze
106 | [258860] = {duration = 40, class = "DEMONHUNTER", specID = {577}}, -- Essence Break
107 | [342817] = {duration = 21, class = "DEMONHUNTER", specID = {577}}, -- Glaive Tempest
108 |
109 | -- Vengeance
110 |
111 | [202137] = {duration = 60, class = "DEMONHUNTER", specID = {581}}, -- Sigil of Silence
112 | [202138] = {duration = 120, class = "DEMONHUNTER", specID = {581}}, -- Sigil of Chains
113 | [204021] = {duration = 48, class = "DEMONHUNTER", specID = {581}, charges = 2}, -- Fiery Brand
114 | [205629] = {duration = 9, class = "DEMONHUNTER", specID = {581}, charges = 2}, -- Demonic Trample
115 | [205630] = {duration = 60, class = "DEMONHUNTER", specID = {577, 581}}, -- Illidan's Grasp
116 | [263648] = {duration = 30, class = "DEMONHUNTER", specID = {581}}, -- Soul Barrier
117 | [207407] = {duration = 60, class = "DEMONHUNTER", specID = {581}}, -- Soul Carver
118 |
119 | -- Priest
120 |
121 | [586] = {duration = 20, class = "PRIEST"}, -- Fade
122 | [32375] = {duration = 60, class = "PRIEST"}, -- Mass Dispel
123 | [375901] = {duration = 45, class = "PRIEST"}, -- Mindgames
124 | [316262] = {duration = 90, class = "PRIEST"}, -- Thoughtsteal
125 | [32379] = {duration = 10, class = "PRIEST"}, -- Shadow Word: Death
126 | [10060] = {duration = 120, class = "PRIEST"}, -- Power Infusion
127 | [8122] = {duration = 30, class = "PRIEST"}, -- Psychic Scream
128 | [73325] = {duration = 60, class = "PRIEST"}, -- Leap of Faith
129 | [19236] = {duration = 70, class = "PRIEST"}, -- Desperate Prayer
130 | [108920] = {duration = 60, class = "PRIEST"}, -- Void Tendrils
131 | [108968] = {duration = 300, class = "PRIEST"}, -- Void Shift
132 | [373481] = {duration = 12, class = "PRIEST"}, -- Power Word: Life
133 | [15286] = {duration = 90, class = "PRIEST"}, -- Vampiric Embrace
134 | [120517] = {duration = 60, class = "PRIEST", specID = {256, 257}}, -- Halo
135 | [120644] = {parent = 120517, specID = {258}}, -- Halo
136 | [428924] = {duration = 45, class = "PRIEST", specID = {256, 257}, charges = 2}, -- Premonition
137 | [34433] = {duration = 180, class = "PRIEST"}, -- Shadowfiend
138 |
139 | -- Discipline
140 |
141 | [33206] = {duration = 180, class = "PRIEST", specID = {256}, charges = 2}, -- Pain Suppression
142 | [123040] = {duration = 30, class = "PRIEST", specID = {256}}, -- Mindbender (Discipline)
143 | [451235] = { duration = 60, class = "PRIEST", specID = { 256, 258 } }, -- Voidwrath
144 | [62618] = {duration = 180, class = "PRIEST", specID = {256}}, -- Power Word: Barrier
145 | [271466] = {parent = 34433}, -- Luminous Barrier
146 | [472433] = {duration = 90, class = "PRIEST", specID = {256}}, -- Evangelism
147 | [421453] = {duration = 240, class = "PRIEST", specID = {256}}, -- Ultimate Penitence
148 | [194509] = {duration = 15, class = "PRIEST", specID = {256}, charges = 2}, -- Power Word: Radiance
149 | [527] = {duration = 8, class = "PRIEST", specID = {256, 257}, charges = 2}, -- Purify
150 |
151 | -- Holy
152 |
153 | [47788] = {duration = 180, class = "PRIEST", specID = {257}}, -- Guardian Spirit
154 | [64843] = {duration = 120, class = "PRIEST", specID = {257}}, -- Divine Hymn
155 | [64901] = {duration = 180, class = "PRIEST", specID = {257}}, -- Symbol of Hope
156 | [197268] = {duration = 90, class = "PRIEST", specID = {257}}, -- Ray of Hope
157 | [200183] = {duration = 120, class = "PRIEST", specID = {257}}, -- Apotheosis
158 | [213610] = {duration = 45, class = "PRIEST", specID = {257}}, -- Holy Ward
159 | [215769] = {duration = 120, class = "PRIEST", specID = {257}}, -- Spirit of Redemption
160 | [88625] = {duration = 60, class = "PRIEST", specID = {257}}, -- Holy Word: Chastise
161 | [328530] = {duration = 60, class = "PRIEST", specID = {257}}, -- Divine Ascension
162 | [372835] = {duration = 120, class = "PRIEST", specID = {257}}, -- Lightwell
163 |
164 | -- Shadow
165 |
166 | [15487] = {duration = 45, class = "PRIEST", specID = {258}}, -- Silence
167 | [200174] = {duration = 60, class = "PRIEST", specID = {258}}, -- Mindbender (Shadow)
168 | [47585] = {duration = 90, class = "PRIEST", specID = {258}}, -- Dispersion
169 | [64044] = {duration = 45, class = "PRIEST", specID = {258}}, -- Psychic Horror
170 | [263165] = {duration = 30, class = "PRIEST", specID = {258}}, -- Void Torrent
171 | [211522] = {duration = 45, class = "PRIEST", specID = {258}}, -- Psyfiend
172 | [205385] = {duration = 20, class = "PRIEST", specID = {258}}, -- Shadow Crash
173 | [228260] = {duration = 120, class = "PRIEST", specID = {258}}, -- Void Form
174 | [391109] = {duration = 60, class = "PRIEST", specID = {258}}, -- Dark Ascension
175 | [213634] = {duration = 8, class = "PRIEST", specID = {258}}, -- Purify Disease
176 |
177 | -- Paladin
178 |
179 | [633] = {duration = 420, class = "PALADIN"}, -- Lay on Hands
180 | [471195] = {parent = 633}, -- Lay on Hands (30% Armor increase)
181 | [642] = {duration = 210, class = "PALADIN"}, -- Divine Shield
182 | [853] = {duration = 30, class = "PALADIN"}, -- Hammer of Justice
183 | [1022] = {duration = 240, class = "PALADIN"}, -- Blessing of Protection
184 | [204018] = {duration = {default = 240, [66] = 210}, class = "PALADIN"}, -- Blessing of Spellwarding
185 | [1044] = {duration = 25, class = "PALADIN"}, -- Blessing of Freedom
186 | [6940] = {duration = 60, class = "PALADIN"}, -- Blessing of Sacrifice
187 | [199448] = {parent = 6940, duration = 60}, -- Ultimate Sacrifice
188 | [20066] = {duration = 15, class = "PALADIN"}, -- Repentance
189 | [31884] = {duration = 120, class = "PALADIN"}, -- Avenging Wrath
190 | [115750] = {duration = 75, class = "PALADIN"}, -- Blinding Light
191 | [375576] = {duration = 60, class = "PALADIN"}, -- Divine Toll
192 | [96231] = {default = true, duration = 15, class = "PALADIN"}, -- Rebuke
193 | [190784] = {duration = 45, class = "PALADIN", charges = 2}, -- Divine Steed
194 | [410126] = {duration = 45, class = "PALADIN"}, -- Searing Glare
195 |
196 | -- Holy
197 |
198 | [498] = {duration = 42, class = "PALADIN", specID = {65}}, -- Divine Protection
199 | [31821] = {duration = 90, class = "PALADIN", specID = {65}}, -- Aura Mastery
200 | [200652] = {duration = 90, class = "PALADIN", specID = {65}}, -- Tyr's Deliverance
201 | [4987] = {duration = 8, class = "PALADIN", specID = {65}}, -- Cleanse
202 | [148039] = {duration = 30, class = "PALADIN", specID = {65}}, -- Barrier of Faith
203 | [414273] = {duration = 90, class = "PALADIN", specID = {65}}, -- Hand of Divinity
204 | [216331] = {duration = 60, class = "PALADIN", specID = {65}}, -- Avenging Crusader
205 | [114165] = {duration = 30, class = "PALADIN", specID = {65}}, -- Holy Prism
206 |
207 | -- Protection
208 |
209 | [31850] = {duration = 84, class = "PALADIN", specID = {66}}, -- Ardent Defender
210 | [31935] = {default = true, duration = 13, class = "PALADIN", specID = {66}}, -- Avenger's Shield
211 | [86659] = {duration = 300, class = "PALADIN", specID = {66}}, -- Guardian of Ancient Kings
212 | [228049] = {parent = 86659}, -- Guardian of the Forgotten Queen
213 | [387174] = {duration = 45, class = "PALADIN", specID = {66}}, -- Eye of Tyr
214 | [215652] = {duration = 45, class = "PALADIN", specID = {66}}, -- Shield of Virtue
215 | [213644] = {duration = 8, class = "PALADIN", specID = {66, 70}}, -- Cleanse Toxins
216 | [378974] = {duration = 120, class = "PALADIN", specID = {66}}, -- Bastion of Light
217 | [327193] = {duration = 90, class = "PALADIN", specID = {66}}, -- Moment of Glory
218 | [389539] = {duration = 120, class = "PALADIN", specID = {66}}, -- Sentinel
219 |
220 | -- Retribution
221 |
222 | [184662] = {duration = 63, class = "PALADIN", specID = {70}}, -- Shield of Vengeance
223 | [403876] = {duration = 63, class = "PALADIN", specID = {70}}, -- Divine Protection (Retribution)
224 | [255937] = {duration = 30, class = "PALADIN", specID = {70}}, -- Wake of Ashes
225 | [231895] = {duration = 120, class = "PALADIN", specID = {70}}, -- Crusade
226 | [198034] = {duration = 60, class = "PALADIN", specID = {70}}, -- Divine Hammer
227 | [210256] = {duration = 60, class = "PALADIN", specID = {70}}, -- Blessing of Sanctuary
228 | [343527] = {duration = 27, class = "PALADIN", specID = {70}}, -- Execution Sentence
229 | [343721] = {duration = 54, class = "PALADIN", specID = {70}}, -- Final Reckoning
230 |
231 | -- Druid
232 |
233 | [1850] = {duration = 120, class = "DRUID"}, -- Dash
234 | [252216] = {parent = 1850, duration = 45}, -- Tiger Dash
235 | [5211] = {duration = 60, class = "DRUID"}, -- Mighty Bash
236 | [20484] = {duration = 600, class = "DRUID"}, -- Rebirth
237 | [102359] = {duration = 30, class = "DRUID"}, -- Mass Entanglement
238 | [102401] = {duration = 15, class = "DRUID"}, -- Wild Charge
239 | [132469] = {duration = 30, class = "DRUID"}, -- Typhoon
240 | [391528] = {duration = 60, class = "DRUID"}, -- Convoke the Spirits
241 | [22812] = {duration = 60, class = "DRUID"}, -- Barkskin
242 | [29166] = {duration = 180, class = "DRUID"}, -- Innervate
243 | [108238] = {duration = 90, class = "DRUID"}, -- Renewal
244 | [22570] = {duration = 20, class = "DRUID"}, -- Maim
245 | [106839] = {default = true, duration = 15, class = "DRUID"}, -- Skull Bash
246 | [99] = {duration = 30, class = "DRUID"}, -- Incapacitating Roar
247 | [106898] = {duration = 60, class = "DRUID"}, -- Stampeding Roar
248 | [77761] = {parent = 106898, duration = 60}, -- Stampeding Roar
249 | [102793] = {duration = 60, class = "DRUID"}, -- Ursol's Vortex
250 | [124974] = {duration = 90, class = "DRUID"}, -- Nature's Vigil
251 |
252 | -- Balance
253 |
254 | [78675] = {default = true, duration = 60, class = "DRUID", specID = {102}}, -- Solar Beam
255 | [390414] = {duration = 120, class = "DRUID", specID = {102}}, -- Incarnation: Chosen of Elune (Orbital Strike)
256 | [102560] = {parent = 390414, duration = 90, charges = 2}, -- Incarnation: Chosen of Elune
257 | [383410] = {duration = 120, class = "DRUID", specID = {102}}, -- Celestial Alignment (Orbital Strike)
258 | [194223] = {parent = 383410, duration = 90, charges = 2}, -- Celestial Alignment
259 | [202425] = {duration = 45, class = "DRUID", specID = {102}}, -- Warrior of Elune
260 | [202770] = {duration = 45, class = "DRUID", specID = {102}}, -- Fury of Elune
261 | [205636] = {duration = 45, class = "DRUID", specID = {102}}, -- Force of Nature
262 | [209749] = {duration = 30, class = "DRUID", specID = {102}}, -- Faerie Swarm
263 | [2782] = {duration = 8, class = "DRUID", specID = {102, 103, 104}}, -- Remove Corruption
264 |
265 | -- Feral
266 |
267 | [5217] = {duration = 30, class = "DRUID", specID = {103}}, -- Tiger's Fury
268 | [61336] = {duration = {default = 180, [104] = 120}, class = "DRUID", specID = {103, 104}, charges = 2}, -- Survival Instincts
269 | [102543] = {duration = 120, class = "DRUID", specID = {103}}, -- Incarnation: Avatar of Ashamane
270 | [106951] = {parent = 102543}, -- Berserk
271 | [274837] = {duration = 45, class = "DRUID", specID = {103}}, -- Feral Frenzy
272 | [391888] = {duration = 25, class = "DRUID", specID = {103}}, -- Adaptive Swarm
273 |
274 | -- Guardian
275 |
276 | [22842] = {duration = 36, class = "DRUID", specID = {104}}, -- Frenzied Regeneration
277 | [102558] = {duration = 180, class = "DRUID", specID = {104}}, -- Incarnation: Guardian of Ursoc
278 | [200851] = {duration = 60, class = "DRUID", specID = {104}}, -- Rage of the Sleeper
279 | [202246] = {duration = 25, class = "DRUID", specID = {104}}, -- Overrun
280 | [80313] = {duration = 45, class = "DRUID", specID = {104}}, -- Pulverize
281 | [204066] = {duration = 60, class = "DRUID", specID = {104}}, -- Lunar Beam
282 | [201664] = {duration = 30, class = "DRUID", specID = {104}}, -- Demoralizing Roar
283 | [354654] = {duration = 60, class = "DRUID", specID = {104}}, -- Grove Protection
284 | [329042] = {duration = 120, class = "DRUID", specID = {104}}, -- Emerald Slumber
285 |
286 | -- Restoration
287 |
288 | [740] = {duration = 150, class = "DRUID", specID = {105}}, -- Tranquility
289 | [18562] = {duration = 15, class = "DRUID", specID = {105}, charges = 2}, -- Swiftmend
290 | [33891] = {duration = 180, class = "DRUID", specID = {105}}, -- Incarnation: Tree of Life
291 | [473909] = {duration = 90, class = "DRUID", specID = {105}}, -- Ancient of Lore
292 | [102342] = {duration = 90, class = "DRUID", specID = {105}}, -- Ironbark
293 | [102351] = {duration = 20, class = "DRUID", specID = {105}}, -- Cenarion Ward
294 | [197721] = {duration = 60, class = "DRUID", specID = {105}}, -- Flourish
295 | [203651] = {duration = 60, class = "DRUID", specID = {105}}, -- Overgrowth
296 | [392160] = {duration = 20, class = "DRUID", specID = {105}}, -- Invigorate
297 | [88423] = {duration = 8, class = "DRUID", specID = {105}}, -- Nature's Cure
298 | [102693] = {duration = 20, class = "DRUID", specID = {105}, charges = 3}, -- Grove Guardians
299 | [132158] = {duration = 60, class = "DRUID", specID = {105}, charges = 2}, -- Nature's Swiftness
300 |
301 | -- Warrior
302 |
303 | [100] = {duration = 18, class = "WARRIOR", charges = 2}, -- Charge
304 | [3411] = {duration = 38, class = "WARRIOR", charges = 2}, -- Intervene
305 | [6544] = {duration = 35, class = "WARRIOR"}, -- Heroic Leap
306 | [6552] = {default = true, duration = 14, class = "WARRIOR"}, -- Pummel
307 | [18499] = {duration = 60, class = "WARRIOR"}, -- Berserker Rage
308 | [384100] = {parent = 18499, duration = 60}, -- Berserker Shout
309 | [1219201] = {duration = 60, class = "WARRIOR"}, -- Berserker Roar
310 | [23920] = {duration = 24, class = "WARRIOR"}, -- Spell Reflection
311 | [46968] = {duration = 40, class = "WARRIOR"}, -- Shockwave
312 | [107570] = {duration = 28, class = "WARRIOR"}, -- Storm Bolt
313 | [107574] = {duration = 90, class = "WARRIOR"}, -- Avatar
314 | [236077] = {duration = 45, class = "WARRIOR"}, -- Disarm
315 | [376079] = {duration = 90, class = "WARRIOR"}, -- Spear of Bastion
316 | [5246] = {duration = 75, class = "WARRIOR"}, -- Intimidating Shout
317 | [316593] = {parent = 5246, duration = 75}, -- Intimidating Shout (Menace)
318 | [97462] = {duration = 180, class = "WARRIOR"}, -- Rallying Cry
319 | [386208] = {duration = 3, class = "WARRIOR"}, -- Defensive Stance
320 | [384318] = {duration = 45, class = "WARRIOR"}, -- Thunderous Roar
321 | [228920] = {duration = 60, class = "WARRIOR", charges = 2}, -- Ravager
322 | [436358] = {duration = 45, class = "WARRIOR", specID = {71,73}}, -- Demolish
323 | [206572] = {duration = 30, class = "WARRIOR"}, -- Dragon Charge
324 | [64382] = {duration = 180, class = "WARRIOR"}, -- Shattering Throw
325 | [384110] = {duration = 45, class = "WARRIOR"}, -- Wrecking Throw
326 |
327 | -- Arms
328 |
329 | [118038] = {duration = 85, class = "WARRIOR", specID = {71}}, -- Die by the Sword
330 | [167105] = {duration = 45, class = "WARRIOR", specID = {71}}, -- Colossus Smash
331 | [262161] = {parent = 167105}, -- Warbreaker
332 | [227847] = {duration = 60, class = "WARRIOR", specID = {71,72}}, -- Bladestorm
333 | [236273] = {duration = 60, class = "WARRIOR", specID = {71}}, -- Duel
334 | [260643] = {duration = 21, class = "WARRIOR", specID = {71}}, -- Skullsplitter
335 |
336 | -- Fury
337 |
338 | [184364] = {duration = 114, class = "WARRIOR", specID = {72}}, -- Enraged Regeneration
339 | [385059] = {duration = 45, class = "WARRIOR", specID = {72}}, -- Odyn's Fury
340 | [1719] = {duration = 90, class = "WARRIOR", specID = {72}}, -- Recklessness
341 | [315720] = {duration = 15, class = "WARRIOR", specID = {72}}, -- Onslaught
342 |
343 | -- Protection
344 |
345 | [871] = {duration = 120, class = "WARRIOR", specID = {73}, charges = 2}, -- Shield Wall
346 | [1160] = {duration = 30, class = "WARRIOR", specID = {73}}, -- Demoralizing Shout
347 | [12975] = {duration = 180, class = "WARRIOR", specID = {73}}, -- Last Stand
348 | [213871] = {duration = 15, class = "WARRIOR", specID = {73}}, -- Bodyguard
349 | [386071] = {duration = 90, class = "WARRIOR", specID = {73}}, -- Disrupting Shout
350 | [392966] = {duration = 90, class = "WARRIOR", specID = {73}}, -- Spell Block
351 | [385952] = {duration = 45, class = "WARRIOR", specID = {73}}, -- Shield Charge
352 |
353 | -- Warlock
354 |
355 | [6358] = {duration = 30, class = "WARLOCK"}, -- Seduction
356 | [115268] = {parent = 6358}, -- Mesmerize
357 | [6360] = {duration = 25, class = "WARLOCK"}, -- Whiplash
358 | [115770] = {parent = 6360}, -- Fellash
359 | [6789] = {duration = 45, class = "WARLOCK"}, -- Mortal Coil
360 | [20707] = {duration = 600, class = "WARLOCK"}, -- Soulstone
361 | [30283] = {duration = 60, class = "WARLOCK"}, -- Shadowfury
362 | [104773] = {duration = 180, class = "WARLOCK"}, -- Unending Resolve
363 | [108416] = {duration = 45, class = "WARLOCK"}, -- Dark Pact
364 | [119910] = {default = true, duration = 24, class = "WARLOCK"}, -- Spell Lock (Command Demon)
365 | [19647] = {parent = 119910}, -- Spell Lock (Felhunter)
366 | [119911] = {parent = 119910}, -- Optical Blast (Command Demon)
367 | [115781] = {parent = 119910}, -- Optical Blast (Observer)
368 | [132409] = {parent = 119910}, -- Spell Lock (Grimoire of Sacrifice)
369 | [171138] = {parent = 119910}, -- Shadow Lock (Doomguard)
370 | [171139] = {parent = 119910}, -- Shadow Lock (Grimoire of Sacrifice)
371 | [171140] = {parent = 119910}, -- Shadow Lock (Command Demon)
372 | [212295] = {duration = 45, class = "WARLOCK"}, -- Nether Ward
373 | [5484] = {duration = 40, class = "WARLOCK"}, -- Howl of Terror
374 | [384069] = {duration = 15, class = "WARLOCK"}, -- Shadowflame
375 | [353294] = {duration = 60, class = "WARLOCK"}, -- Shadow Rift
376 | [48020] = {duration = 30, class = "WARLOCK"}, -- Demonic Circle Teleport
377 | [333889] = {duration = 90, class = "WARLOCK"}, -- Fel Domination
378 | [328774] = {duration = 45, class = "WARLOCK"}, -- Amplify Curse
379 | [410598] = {duration = 60, class = "WARLOCK"}, -- Soul Rip
380 | [353753] = {duration = 30, class = "WARLOCK"}, -- Bonds of Fel
381 | [452930] = {duration = 60, class = "WARLOCK"}, -- Demonic Healthstone
382 | [442726] = {duration = 60, class = "WARLOCK", specID = {265, 267}}, -- Malevolence
383 | [212623] = {duration = 15, class = "WARLOCK"}, -- Singe Magic
384 | [89808] = {parent = 212623}, -- Singe Magic
385 | [119905] = {parent = 212623}, -- Singe Magic
386 |
387 | -- Affliction
388 |
389 | [48181] = {duration = 15, class = "WARLOCK", specID = {265}}, -- Haunt
390 | [386951] = {duration = 30, class = "WARLOCK", specID = {265}}, -- Soul Swap
391 | [205179] = {duration = 45, class = "WARLOCK", specID = {265}}, -- Phantom Singularity
392 | [205180] = {duration = 120, class = "WARLOCK", specID = {265}}, -- Summon Darkglare
393 | [386997] = {duration = 60, class = "WARLOCK", specID = {265}}, -- Soul Rot
394 | [108503] = {duration = 30, class = "WARLOCK", specID = {265, 267}}, -- Grimoire of Sacrifice
395 | [417537] = {duration = 45, class = "WARLOCK", specID = {265}}, -- Oblivion
396 |
397 | -- Demonology
398 |
399 | [89751] = {duration = 30, class = "WARLOCK", specID = {266}}, -- Felstorm
400 | [115831] = {parent = 89751}, -- Wrathstorm
401 | [89766] = {duration = 30, class = "WARLOCK", specID = {266}}, -- Axe Toss
402 | [265187] = {duration = 60, class = "WARLOCK", specID = {266}}, -- Summon Demonic Tyrant
403 | [212459] = {duration = 120, class = "WARLOCK", specID = {266}}, -- Call Fel Lord
404 | [267171] = {duration = 60, class = "WARLOCK", specID = {266}}, -- Demonic Strength
405 | [111898] = {duration = 120, class = "WARLOCK", specID = {266}}, -- Grimoire: Felguard
406 | [386833] = {duration = 45, class = "WARLOCK", specID = {266}}, -- Guillotine
407 | [264130] = {duration = 30, class = "WARLOCK", specID = {266}}, -- Power Siphon
408 | [264119] = {duration = 30, class = "WARLOCK", specID = {266}}, -- Summon Vilefiend
409 |
410 | -- Destruction
411 |
412 | [80240] = {duration = 30, class = "WARLOCK", specID = {267}}, -- Havoc
413 | [200546] = {parent = 80240, duration = 45}, -- Bane of Havoc
414 | [152108] = {duration = 30, class = "WARLOCK", specID = {267}}, -- Cataclysm
415 | [196447] = {duration = 20, class = "WARLOCK", specID = {267}}, -- Channel Demonfire
416 | [387976] = {duration = 45, class = "WARLOCK", specID = {267}, charges = 3}, -- Dimensional Rift
417 | [1122] = {duration = 120, class = "WARLOCK", specID = {267}}, -- Summon Infernal
418 | [6353] = {duration = 45, class = "WARLOCK", specID = {267}}, -- Soul Fire
419 |
420 | -- Shaman
421 |
422 | [20608] = {duration = 1800, class = "SHAMAN"}, -- Reincarnation
423 | [51485] = {duration = 24, class = "SHAMAN"}, -- Earthgrab Totem
424 | [51514] = {duration = 30, class = "SHAMAN"}, -- Hex
425 | [196932] = {parent = 51514}, -- Voodoo Totem
426 | [210873] = {parent = 51514}, -- Hex (Compy)
427 | [211004] = {parent = 51514}, -- Hex (Spider)
428 | [211010] = {parent = 51514}, -- Hex (Snake)
429 | [211015] = {parent = 51514}, -- Hex (Cockroach)
430 | [269352] = {parent = 51514}, -- Hex (Skeletal Hatchling)
431 | [277778] = {parent = 51514}, -- Hex (Zandalari Tendonripper)
432 | [277784] = {parent = 51514}, -- Hex (Wicker Mongrel)
433 | [309328] = {parent = 51514}, -- Hex (Living Honey)
434 | [57994] = {default = true, duration = 12, class = "SHAMAN"}, -- Wind Shear
435 | [108271] = {duration = 90, class = "SHAMAN"}, -- Astral Shift
436 | [192058] = {duration = 54, class = "SHAMAN"}, -- Capacitor
437 | [192077] = {duration = 84, class = "SHAMAN"}, -- Wind Rush Totem
438 | [204331] = {duration = 39, class = "SHAMAN"}, -- Counterstrike Totem
439 | [8143] = {duration = 54, class = "SHAMAN"}, -- Tremor Totem
440 | [51490] = {duration = 30, class = "SHAMAN"}, -- Thunderstorm
441 | [192063] = {duration = 20, class = "SHAMAN"}, -- Gust of Wind
442 | [198103] = {duration = 300, class = "SHAMAN"}, -- Earth Elemental
443 | [305483] = {duration = 45, class = "SHAMAN"}, -- Lightning Lasso
444 | [375982] = {duration = 30, class = "SHAMAN"}, -- Primordial Wave
445 | [428332] = {parent = 375982}, -- Primordial Wave (Restoration)
446 | [58875] = {duration = 60, class = "SHAMAN"}, -- Spirit Walk
447 | [79206] = {duration = 120, class = "SHAMAN"}, -- Spiritwalker's Grace
448 | [204336] = {duration = 24, class = "SHAMAN"}, -- Grounding Totem
449 | [356736] = {duration = 30, class = "SHAMAN"}, -- Unleash Shield
450 | [108270] = {duration = 174, class = "SHAMAN"}, -- Stone Bulwark Totem
451 | [383013] = {duration = 114, class = "SHAMAN"}, -- Poison Cleansing Totem
452 | [378773] = {duration = 12, class = "SHAMAN"}, -- Greater Purge
453 | [108285] = {duration = 180, class = "SHAMAN"}, -- Totemic Recall
454 | [355580] = {duration = 84, class = "SHAMAN"}, -- Static Field Totem
455 | [378081] = {duration = 60, class = "SHAMAN"}, -- Nature's Swiftness (Shaman)
456 | [443454] = {parent = 378081, duration = 30}, -- Ancestral Swiftness
457 | [444995] = {duration = 24, class = "SHAMAN", specID = {263, 264}}, -- Surging Totem
458 | [409293] = {duration = 120, class = "SHAMAN"}, -- Burrow
459 |
460 | -- Elemental
461 |
462 | [192222] = {duration = 24, class = "SHAMAN", specID = {262}}, -- Liquid Magma Totem
463 | [198067] = {duration = 150, class = "SHAMAN", specID = {262}}, -- Fire Elemental
464 | [192249] = {parent = 198067}, -- Storm Elemental
465 | [191634] = {duration = 60, class = "SHAMAN", specID = {262}, charges = 2}, -- Stormkeeper
466 | [117014] = {duration = 12, class = "SHAMAN", specID = {262, 263}}, -- Elemental Blast
467 | [51886] = {duration = 8, class = "SHAMAN", specID = {262, 263}}, -- Cleanse Spirit
468 | [114050] = {duration = 180, class = "SHAMAN", specID = {262}}, -- Ascendance (Elemental)
469 |
470 | -- Enhancement
471 |
472 | [196884] = {duration = 30, class = "SHAMAN", specID = {263}}, -- Feral Lunge
473 | [197214] = {duration = 40, class = "SHAMAN", specID = {263}}, -- Sundering
474 | [384352] = {duration = 60, class = "SHAMAN", specID = {263}}, -- Doom Winds
475 | [51533] = {duration = 90, class = "SHAMAN", specID = {263}}, -- Feral Spirits
476 | [204361] = {duration = 60, class = "SHAMAN", specID = {262,263}}, -- Bloodlust (Shamanism)
477 | [204362] = {parent = 204361}, -- Heroism (Shamanism)
478 | [114051] = {duration = 120, class = "SHAMAN", specID = {263}}, -- Ascendance (Enhancement)
479 |
480 | -- Restoration
481 |
482 | [5394] = {duration = 24, class = "SHAMAN", specID = {264}, charges = 2}, -- Healing Stream Totem
483 | [98008] = {duration = 174, class = "SHAMAN", specID = {264}}, -- Spirit Link Totem
484 | [108280] = {duration = 129, class = "SHAMAN", specID = {264}}, -- Healing Tide Totem
485 | [157153] = {duration = 39, class = "SHAMAN", specID = {264}, charges = 2}, -- Cloudburst Totem
486 | [198838] = {duration = 54, class = "SHAMAN", specID = {264}}, -- Earthen Wall Totem
487 | [207399] = {duration = 294, class = "SHAMAN", specID = {264}}, -- Ancestral Protection Totem
488 | [77130] = {duration = 8, class = "SHAMAN", specID = {264}}, -- Purify Spirit
489 | [114052] = {duration = 120, class = "SHAMAN", specID = {264}}, -- Ascendance (Restoration)
490 |
491 | -- Hunter
492 |
493 | [136] = {duration = 10, class = "HUNTER"}, -- Mend Pet
494 | [1543] = {duration = 20, class = "HUNTER"}, -- Flare
495 | [5384] = {duration = 30, class = "HUNTER"}, -- Feign Death
496 | [53480] = {duration = 60, class = "HUNTER"}, -- Roar of Sacrifice
497 | [109304] = {duration = 120, class = "HUNTER"}, -- Exhilaration
498 | [131894] = {duration = 60, class = "HUNTER"}, -- A Murder of Crows
499 | [186257] = {duration = 150, class = "HUNTER"}, -- Aspect of the Cheetah
500 | [186265] = {duration = 150, class = "HUNTER"}, -- Aspect of the Turtle
501 | [187650] = {duration = 25, class = "HUNTER"}, -- Freezing Trap
502 | [203340] = {parent = 187650}, -- Diamond Ice
503 | [356719] = {duration = 60, class = "HUNTER"}, -- Chimaeral Sting
504 | [209997] = {duration = 30, class = "HUNTER"}, -- Play Dead
505 | [781] = {duration = 20, class = "HUNTER"}, -- Disengage
506 | [19577] = {duration = 50, class = "HUNTER"}, -- Intimidation
507 | [474421] = {parent = 19577}, -- Intimidation (Marksman)
508 | [109248] = {duration = 45, class = "HUNTER"}, -- Binding Shot
509 | [34477] = {duration = 45, class = "HUNTER"}, -- Misdirection (Interlope)
510 | [199483] = {duration = 60, class = "HUNTER"}, -- Camouflage
511 | [213691] = {duration = 30, class = "HUNTER"}, -- Scatter Shot
512 | [53271] = {duration = 45, class = "HUNTER"}, -- Master's Call
513 | [187698] = {duration = 25, class = "HUNTER"}, -- Tar Trap
514 | [264735] = {duration = 90, class = "HUNTER", charges = 2}, -- Survival of the Fittest
515 | [19801] = {duration = 10, class = "HUNTER"}, -- Tranquilizing Shot
516 | [236776] = {duration = 35, class = "HUNTER"}, -- High Explosive Trap
517 | [462031] = {duration = 55, class = "HUNTER"}, -- Implosive Trap
518 | [186387] = {duration = 30, class = "HUNTER"}, -- Bursting Shot
519 | [212431] = {duration = 30, class = "HUNTER"}, -- Explosive Shot
520 |
521 | -- Beast Mastery
522 |
523 | [19574] = {duration = 90, class = "HUNTER", specID = {253}}, -- Bestial Wrath
524 | [147362] = {default = true, duration = 22, class = "HUNTER", specID = {253, 254}}, -- Counter Shot
525 | [359844] = {duration = 120, class = "HUNTER", specID = {253}}, -- Call of the Wild
526 | [356707] = {duration = 60, class = "HUNTER", specID = {253, 255}}, -- Wild Kingdom
527 | [321530] = {duration = 60, class = "HUNTER", specID = {253}}, -- Bloodshed
528 |
529 | -- Marksmanship
530 |
531 | [260243] = {duration = 45, class = "HUNTER", specID = {254}}, -- Volley
532 | [400456] = {duration = 45, class = "HUNTER", specID = {254}}, -- Salvo
533 | [257044] = {duration = 18, class = "HUNTER", specID = {254}}, -- Rapid Fire
534 | [288613] = {duration = 120, class = "HUNTER", specID = {254}}, -- Trueshot
535 |
536 | -- Survival
537 |
538 | [186289] = {duration = 60, class = "HUNTER", specID = {255}}, -- Aspect of the Eagle
539 | [187707] = {default = true, duration = 13, class = "HUNTER", specID = {255}}, -- Muzzle
540 | [190925] = {duration = 20, class = "HUNTER", specID = {255}}, -- Harpoon
541 | [203415] = {duration = 45, class = "HUNTER", specID = {255}}, -- Fury of the Eagle
542 | [212640] = {duration = 25, class = "HUNTER", specID = {255}}, -- Mending Bandage
543 | [360952] = {duration = 60, class = "HUNTER", specID = {255}}, -- Coordinated Assault
544 | [360966] = {duration = 60, class = "HUNTER", specID = {255}}, -- Spearhead
545 | [269751] = {duration = 30, class = "HUNTER", specID = {255}}, -- Flanking Strike
546 | [212638] = {duration = 25, class = "HUNTER", specID = {255}}, -- Tracker's Net
547 | [407028] = {duration = 45, class = "HUNTER", specID = {255}}, -- Sticky Tar Bomb
548 |
549 | -- Mage
550 |
551 | [66] = {duration = 300, class = "MAGE"}, -- Invisibility
552 | [110959] = {duration = 120, class = "MAGE"}, -- Greater Invisibility
553 | [1953] = {duration = 11, class = "MAGE"}, -- Blink
554 | [212653] = {duration = 21, class = "MAGE", charges = 2}, -- Shimmer
555 | [2139] = {default = true, duration = 20, class = "MAGE"}, -- Counterspell
556 | [11426] = {duration = 25, class = "MAGE"}, -- Ice Barrier
557 | [45438] = {duration = 180, class = "MAGE"}, -- Ice Block
558 | [414658] = {parent = 45438}, -- Ice Cold
559 | [55342] = {duration = 120, class = "MAGE"}, -- Mirror Image
560 | [80353] = {duration = 300, class = "MAGE"}, -- Time Warp
561 | [108839] = {duration = 20, class = "MAGE", charges = 3}, -- Ice Floes
562 | [113724] = {duration = 45, class = "MAGE"}, -- Ring of Frost
563 | [389713] = {duration = 45, class = "MAGE"}, -- Displacement
564 | [31661] = {duration = 45, class = "MAGE"}, -- Dragon's Breath
565 | [157981] = {duration = 25, class = "MAGE"}, -- Blast Wave
566 | [382440] = {duration = 60, class = "MAGE"}, -- Shifting Power
567 | [157997] = {duration = 25, class = "MAGE"}, -- Ice Nova
568 | [353082] = {duration = 45, class = "MAGE"}, -- Ring of Fire
569 | [352278] = {duration = 90, class = "MAGE"}, -- Ice Wall
570 | [122] = {duration = 30, class = "MAGE", charges = 2}, -- Frost Nova
571 | [342245] = {duration = 50, class = "MAGE"}, -- Alter Time
572 | [475] = {duration = 8, class = "MAGE"}, -- Remove Curse
573 | [157980] = {duration = 45, class = "MAGE"}, -- Supernova
574 | [449700] = {parent = 157980, duration = 40}, -- Gravity Lapse
575 | [414660] = {duration = 180, class = "MAGE"}, -- Mass Barrier
576 | [383121] = {duration = 60, class = "MAGE"}, -- Mass Polymorph
577 | [414664] = {duration = 60, class = "MAGE"}, -- Mass Invisibility
578 |
579 | -- Arcane
580 |
581 | [365350] = {duration = 90, class = "MAGE", specID = {62}}, -- Arcane Surge
582 | [12051] = {duration = 90, class = "MAGE", specID = {62}}, -- Evocation
583 | [153626] = {duration = 20, class = "MAGE", specID = {62}, charges = 2}, -- Arcane Orb
584 | [205025] = {duration = 45, class = "MAGE", specID = {62}}, -- Presence of Mind
585 | [198100] = {duration = 20, class = "MAGE", specID = {62}}, -- Spellsteal (Kleptomania)
586 | [353128] = {duration = 45, class = "MAGE", specID = {62}}, -- Arcanosphere
587 | [321507] = {duration = 45, class = "MAGE", specID = {62}}, -- Touch of the Magi
588 |
589 | -- Fire
590 |
591 | [108853] = {duration = 14, class = "MAGE", specID = {63}, charges = 3}, -- Fire Blast
592 | [190319] = {duration = 120, class = "MAGE", specID = {63}}, -- Combustion
593 | [194466] = {duration = 25, class = "MAGE", specID = {63}, charges = 2}, -- Phoenix's Flames
594 | [203286] = {duration = 15, class = "MAGE", specID = {63}}, -- Greater Pyroblast
595 | [153561] = {duration = 35, class = "MAGE", specID = {63}}, -- Meteor
596 |
597 | -- Frost
598 |
599 | [12472] = {duration = 120, class = "MAGE", specID = {64}}, -- Icy Veins
600 | [198144] = {parent = 12472, duration = 60}, -- Ice Form
601 | [84714] = {duration = 60, class = "MAGE", specID = {64}}, -- Frozen Orb
602 | [153595] = {duration = 30, class = "MAGE", specID = {64}}, -- Comet Storm
603 | [205021] = {duration = 60, class = "MAGE", specID = {64}}, -- Ray of Frost
604 | [389794] = {duration = 45, class = "MAGE", specID = {64}}, -- Snowdrift
605 | [390612] = {duration = 15, class = "MAGE", specID = {64}}, -- Frost Bomb
606 | [235219] = {duration = 300, class = "MAGE", specID = {64}}, -- Cold Snap
607 |
608 | -- Rogue
609 |
610 | [1725] = {duration = 30, class = "ROGUE"}, -- Distract
611 | [1766] = {default = true, duration = 15, class = "ROGUE"}, -- Kick
612 | [1856] = {duration = 120, class = "ROGUE", charges = 2}, -- Vanish
613 | [2983] = {duration = 60, class = "ROGUE"}, -- Sprint
614 | [31224] = {duration = 120, class = "ROGUE"}, -- Cloak of Shadows
615 | [57934] = {duration = 30, class = "ROGUE"}, -- Tricks of the Trade
616 | [152150] = {duration = 30, class = "ROGUE"}, -- Death from Above
617 | [408] = {duration = 30, class = "ROGUE"}, -- Kidney Shot
618 | [5277] = {duration = 120, class = "ROGUE"}, -- Evasion
619 | [36554] = {duration = 30, class = "ROGUE", charges = 2}, -- Shadowstep
620 | [5938] = {duration = 30, class = "ROGUE", charges = 2}, -- Shiv
621 | [207777] = {duration = 45, class = "ROGUE"}, -- Dismantle
622 | [381623] = {duration = 60, class = "ROGUE", specID = {63}, charges = 3}, -- Thistle Tea
623 | [1776] = {duration = 25, class = "ROGUE"}, -- Gouge
624 | [2094] = {duration = {default = 120, [260] = 81}, class = "ROGUE"}, -- Blind
625 | [212182] = {duration = 180, class = "ROGUE", specID = {259, 260}}, -- Smoke Bomb
626 | [359053] = {duration = 120, class = "ROGUE", specID = {261}}, -- Smoke Bomb (Subtlety)
627 | [382245] = {duration = 45, class = "ROGUE"}, -- Cold Blood
628 | [185311] = {duration = 30, class = "ROGUE"}, -- Crimson Vial
629 |
630 | -- Assassination
631 |
632 | [703] = {duration = 6, class = "ROGUE", specID = {259}}, -- Garrote
633 | [360194] = {duration = 120, class = "ROGUE", specID = {259}}, -- Deathmark
634 | [385627] = {duration = 60, class = "ROGUE", specID = {259}}, -- Kingsbane
635 |
636 | -- Outlaw
637 |
638 | [13750] = {duration = 180, class = "ROGUE", specID = {260}}, -- Adrenaline Rush
639 | [51690] = {duration = 90, class = "ROGUE", specID = {260}}, -- Killing Spree
640 | [195457] = {duration = 30, class = "ROGUE", specID = {260}, charges = 2}, -- Grappling Hook
641 | [315341] = {duration = 45, class = "ROGUE", specID = {260}}, -- Between the Eyes
642 | [196937] = {duration = 90, class = "ROGUE", specID = {260}}, -- Ghostly Strike
643 | [271877] = {duration = 45, class = "ROGUE", specID = {260}}, -- Blade Rush
644 |
645 | -- Subtlety
646 |
647 | [121471] = {duration = 90, class = "ROGUE", specID = {261}}, -- Shadow Blades
648 | [185313] = {duration = 50, class = "ROGUE", charges = 2}, -- Shadow Dance
649 | [384631] = {duration = 90, class = "ROGUE", specID = {261}}, -- Flagellation
650 | [280719] = {duration = 45, class = "ROGUE", specID = {261}}, -- Secret Technique
651 | [426591] = {duration = 45, class = "ROGUE", specID = {261}}, -- Goremaw's Bite
652 | [212283] = {duration = 25, class = "ROGUE", specID = {261}}, -- Symbols of Death
653 |
654 | -- Monk
655 |
656 | [109132] = {duration = 15, class = "MONK", charges = 3}, -- Roll
657 | [115008] = {parent = 109132, charges = 2, duration = 20}, -- Chi Torpedo
658 | [115078] = {duration = 30, class = "MONK"}, -- Paralysis
659 | [116841] = {duration = 30, class = "MONK"}, -- Tiger's Lust
660 | [116844] = {duration = 40, class = "MONK"}, -- Ring of Peace
661 | [119381] = {duration = 50, class = "MONK"}, -- Leg Sweep
662 | [119996] = {duration = 45, class = "MONK"}, -- Transcendence: Transfer
663 | [122783] = {duration = 90, class = "MONK"}, -- Diffuse Magic
664 | [115203] = {duration = 90, class = "MONK"}, -- Fortifying Brew
665 | [116705] = {default = true, duration = 15, class = "MONK"}, -- Spear Hand Strike
666 | [322109] = {duration = 180, class = "MONK"}, -- Touch of Death
667 | [324312] = {duration = 60, class = "MONK"}, -- Clash
668 | [443028] = {duration = 90, class = "MONK", specID = {269, 270}}, -- Celestial Conduit
669 | [233759] = {duration = 45, class = "MONK"}, -- Grapple Weapon
670 |
671 | -- Brewmaster
672 |
673 | [115399] = {duration = 120, class = "MONK", specID = {268}}, -- Black Ox Brew
674 | [132578] = {duration = 180, class = "MONK", specID = {268}}, -- Invoke Niuzao, the Black Ox
675 | [202162] = {duration = 45, class = "MONK", specID = {268}}, -- Avert Harm
676 | [115181] = {duration = 15, class = "MONK", specID = {268}}, -- Breath of Fire
677 | [387184] = {duration = 120, class = "MONK", specID = {268}}, -- Weapons of Order
678 | [202335] = {duration = 45, class = "MONK", specID = {268}}, -- Double Barrel
679 | [325153] = {duration = 60, class = "MONK", specID = {268}}, -- Exploding Keg
680 | [115176] = {duration = 150, class = "MONK", specID = {268}}, -- Zen Meditation
681 | [354540] = {duration = 90, class = "MONK", specID = {268}}, -- Nimble Brew
682 | [218164] = {duration = 8, class = "MONK", specID = {268, 269}}, -- Detox
683 | [122278] = {duration = 120, class = "MONK", specID = {268}}, -- Dampen Harm
684 |
685 | -- Windwalker
686 |
687 | [101545] = {duration = 30, class = "MONK", specID = {269}}, -- Flying Serpent Kick
688 | [1217413] = {duration = 30, class = "MONK", specID = {269}}, -- Slicing Winds
689 | [113656] = {duration = 24, class = "MONK", specID = {269}}, -- Fists of Fury
690 | [122470] = {duration = 90, class = "MONK", specID = {269}}, -- Touch of Karma
691 | [123904] = {duration = 90, class = "MONK", specID = {269}}, -- Invoke Xuen, the White Tiger
692 | [137639] = {duration = 90, class = "MONK", specID = {269}, charges = 2}, -- Storm, Earth, and Fire
693 | [152175] = {duration = 24, class = "MONK", specID = {269}}, -- Whirling Dragon Punch
694 | [392983] = {duration = 30, class = "MONK", specID = {269}}, -- Strike of the Windlord
695 |
696 | -- Mistweaver
697 |
698 | [115310] = {duration = 150, class = "MONK", specID = {270}}, -- Revival
699 | [388615] = {parent = 115310, duration = 150}, -- Restoral
700 | [116680] = {duration = 30, class = "MONK", specID = {270}}, -- Thunder Focus Tea
701 | [116849] = {duration = 75, class = "MONK", specID = {270}}, -- Life Cocoon
702 | [198898] = {duration = 30, class = "MONK", specID = {270}}, -- Song of Chi-Ji
703 | [205234] = {duration = 15, class = "MONK", specID = {270}, charges = 3}, -- Healing Sphere
704 | [388193] = {duration = 30, class = "MONK", specID = {269, 270}}, -- Jadefire Stomp
705 | [322118] = {duration = 120, class = "MONK", specID = {270}}, -- Invoke Yu'Lon, the Jade Serpent
706 | [325197] = {duration = 60, class = "MONK", specID = {270}}, -- Invoke Chi-Ji, the Red Crane
707 | [115450] = {duration = 8, class = "MONK", specID = {270}}, -- Detox
708 |
709 | -- Evoker
710 |
711 | [363916] = {duration = 90, class = "EVOKER", charges = 2}, -- Obsidian Scales
712 | [358385] = {duration = 60, class = "EVOKER"}, -- Landslide
713 | [360995] = {duration = 16, class = "EVOKER"}, -- Verdant Embrace
714 | [357214] = {duration = 60, class = "EVOKER"}, -- Wing Buffet
715 | [368970] = {duration = 180, class = "EVOKER"}, -- Tail Swipe
716 | [351338] = {default = true, duration = {default = 20, [1468] = 40}, class = "EVOKER"}, -- Quell
717 | [374251] = {duration = 60, class = "EVOKER"}, -- Cauterizing Flame
718 | [370553] = {duration = 120, class = "EVOKER"}, -- Tip the Scales
719 | [368432] = {duration = 9, class = "EVOKER"}, -- Unravel
720 | [372048] = {duration = 120, class = "EVOKER"}, -- Oppressing Roar
721 | [370665] = {duration = 60, class = "EVOKER"}, -- Rescue
722 | [374348] = {duration = 90, class = "EVOKER"}, -- Renewing Blaze
723 | [374968] = {duration = 120, class = "EVOKER"}, -- Time Spiral
724 | [374227] = {duration = 120, class = "EVOKER"}, -- Zephyr
725 | [358267] = {duration = 25, class = "EVOKER", charges = 2}, -- Hover
726 | [357208] = {duration = 30, class = "EVOKER"}, -- Fire Breath
727 | [357210] = {duration = {default = 120, [1467] = 60}, class = "EVOKER"}, -- Deep Breath
728 | [433874] = {parent = 357210, duration = 60}, -- Deep Breath (Maneuverability)
729 | [383005] = {duration = 45, class = "EVOKER"}, -- Chrono Loop
730 | [378441] = {duration = 45, class = "EVOKER"}, -- Time Stop
731 | [370388] = {duration = 90, class = "EVOKER"}, -- Swoop Up
732 | [406732] = {duration = 180, class = "EVOKER"}, -- Spatial Paradox
733 | [443328] = {duration = 27, class = "EVOKER", specID = {1467, 1468}, charges = 2}, -- Engulf
734 | [378464] = {duration = 90, class = "EVOKER"}, -- Nullifying Shroud
735 |
736 | -- Devastation
737 |
738 | [375087] = {duration = 120, class = "EVOKER", specID = {1467}}, -- Dragonrage
739 | [370452] = {duration = 20, class = "EVOKER", specID = {1467}}, -- Shattering Star
740 | [368847] = {duration = 20, class = "EVOKER", specID = {1467}}, -- Firestorm
741 | [359073] = {duration = 30, class = "EVOKER", specID = {1467}}, -- Eternity Surge
742 | [365585] = {duration = 8, class = "EVOKER", specID = {1467}}, -- Expunge
743 |
744 | -- Preservation
745 |
746 | [355936] = {duration = 30, class = "EVOKER", specID = {1468}}, -- Dream Breath
747 | [363534] = {duration = 180, class = "EVOKER", specID = {1468}, charges = 2}, -- Rewind
748 | [367226] = {duration = 30, class = "EVOKER", specID = {1468}}, -- Spiritbloom
749 | [357170] = {duration = 60, class = "EVOKER", specID = {1468}}, -- Time Dilation
750 | [370960] = {duration = 180, class = "EVOKER", specID = {1468}}, -- Emerald Communion
751 | [359816] = {duration = 120, class = "EVOKER", specID = {1468}}, -- Dream Flight
752 | [370537] = {duration = 90, class = "EVOKER", specID = {1468}}, -- Stasis
753 | [360823] = {duration = 8, class = "EVOKER", specID = {1468}}, -- Naturalize
754 |
755 | -- Augmentation
756 |
757 | [395152] = {duration = 30, class = "EVOKER", specID = {1473}}, -- Ebon Might
758 | [408092] = {duration = 40, class = "EVOKER", specID = {1473}}, -- Upheaval
759 | [403631] = {duration = 120, class = "EVOKER", specID = {1473}}, -- Breath of Eons
760 | [442204] = {parent = 403631}, -- Breath of Eons (Maneuverability)
761 | [408233] = {duration = 60, class = "EVOKER", specID = {1473}}, -- Bestow Weyrnstone
762 | [360827] = {duration = 30, class = "EVOKER", specID = {1473}}, -- Blistering Scales
763 | [409311] = {duration = 12, class = "EVOKER", specID = {1473}, charges = 2}, -- Prescience
764 | [404977] = {duration = 180, class = "EVOKER", specID = {1473}}, -- Time Skip
765 | }
766 |
--------------------------------------------------------------------------------
/OmniBar_TBC.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 20504
2 | ## Title: OmniBar
3 | ## Notes: Tracks enemy cooldowns
4 | ## Version: @project-version@
5 | ## Author: Jordon
6 | ## SavedVariables: OmniBarDB
7 | ## IconTexture: Interface\AddOns\OmniBar\Media\Textures\icon.blp
8 | ## X-Curse-Project-ID: 85814
9 | ## X-Wago-ID: BO678XK3
10 | ## X-WoWI-ID: 23235
11 |
12 | #@no-lib-strip@
13 | Libs\LibStub\LibStub.lua
14 | Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
15 | Libs\AceAddon-3.0\AceAddon-3.0.xml
16 | Libs\AceDB-3.0\AceDB-3.0.xml
17 | Libs\AceDBOptions-3.0\AceDBOptions-3.0.xml
18 | Libs\AceComm-3.0\AceComm-3.0.xml
19 | Libs\AceEvent-3.0\AceEvent-3.0.xml
20 | Libs\AceGUI-3.0\AceGUI-3.0.xml
21 | Libs\AceConfig-3.0\AceConfig-3.0.xml
22 | Libs\AceLocale-3.0\AceLocale-3.0.xml
23 | Libs\AceSerializer-3.0\AceSerializer-3.0.xml
24 | Libs\LibDeflate\LibDeflate.lua
25 | #@end-no-lib-strip@
26 |
27 | Locales\Locales.xml
28 | OmniBar.xml
29 | OmniBar_TBC.lua
30 | OmniBar.lua
31 | Options.lua
32 |
--------------------------------------------------------------------------------
/OmniBar_Vanilla.lua:
--------------------------------------------------------------------------------
1 | local addonName, addon = ...
2 |
3 | addon.Shared = {}
4 |
5 | addon.Resets = {
6 | --[[ Cold Snap
7 | - Ice Barrier
8 | - Frost Ward
9 | - Frost Nova
10 | - Ice Block
11 | ]]
12 | [12472] = { 11426, 6143, 122, 11958 },
13 |
14 | --[[ Preparation
15 | - Blade Flurry
16 | - Kidney Shot
17 | - Blind
18 | - Sprint
19 | - Evasion
20 | - Gouge
21 | - Ghostly Strike
22 | - Premeditation
23 | ]]
24 | [14185] = { 13877, 408, 2094, 2983, 5277, 1776, 14278, 14183 },
25 | }
26 |
27 | addon.Cooldowns = {
28 |
29 | -- Interrupts
30 |
31 | [16979] = { default = true, duration = 15, class = "DRUID" }, -- Feral Charge (Druid)
32 | [2139] = { default = true, duration = 30, class = "MAGE" }, -- Counterspell (Mage)
33 | [1766] = { default = true, duration = 10, class = "ROGUE" }, -- Kick (Rogue)
34 | [1767] = { parent = 1766 },
35 | [1768] = { parent = 1766 },
36 | [1769] = { parent = 1766 },
37 | [6552] = { default = true, duration = 10, class = "WARRIOR" }, -- Pummel (Warrior)
38 | [6554] = { parent = 6552 },
39 | [72] = { default = true, duration = 12, class = "WARRIOR" }, -- Shield Bash (Warrior)
40 | [1671] = { parent = 72 },
41 | [1672] = { parent = 72 },
42 | [8042] = { default = true, duration = 5, class = "SHAMAN" }, -- Earth Shock (Shaman)
43 | [8044] = { parent = 8042 },
44 | [8045] = { parent = 8042 },
45 | [8046] = { parent = 8042 },
46 | [10412] = { parent = 8042 },
47 | [10413] = { parent = 8042 },
48 | [10414] = { parent = 8042 },
49 | -- Flame Shock (shares CD)
50 | [8050] = { parent = 8042 },
51 | [8052] = { parent = 8042 },
52 | [8053] = { parent = 8042 },
53 | [10447] = { parent = 8042 },
54 | [10448] = { parent = 8042 },
55 | [29228] = { parent = 8042 },
56 | -- Frost Shock (shares CD)
57 | [8056] = { parent = 8042 },
58 | [8058] = { parent = 8042 },
59 | [10472] = { parent = 8042 },
60 | [10473] = { parent = 8042 },
61 |
62 | -- Priest
63 |
64 | [15487] = { duration = 45, class = "PRIEST" }, -- Silence
65 | [8122] = { class = "PRIEST", duration = 26 }, -- Psychic Scream
66 | [8124] = { parent = 8122 },
67 | [10888] = { parent = 8122 },
68 | [10890] = { parent = 8122 },
69 | [10060] = { class = "PRIEST", duration = 180 }, -- Power Infusion
70 |
71 | -- Warlock
72 |
73 | [19244] = { class = "WARLOCK", duration = 30 }, -- Spell Lock
74 | [19647] = { parent = 19244 },
75 | [5484] = { class = "WARLOCK", duration = 40 }, -- Howl of Terror
76 | [17928] = { parent = 5484 },
77 | [6789] = { class = "WARLOCK", duration = 102 }, -- Death Coil
78 | [17925] = { parent = 6789 },
79 | [17926] = { parent = 6789 },
80 | [6229] = { class = "WARLOCK", duration = 30 }, -- Shadow Ward
81 | [11739] = { parent = 6229 },
82 | [11740] = { parent = 6229 },
83 | [28610] = { parent = 6229 },
84 | [18288] = { class ="WARLOCK", duration = 180 }, -- Amplify Curse
85 |
86 | -- Shaman
87 |
88 | [8177] = { class = "SHAMAN", duration = 13 }, -- Grounding Totem
89 | [16188] = { class = "SHAMAN", duration = 180 }, -- Nature's Swiftness
90 |
91 | -- Paladin
92 |
93 | [1022] = { class = "PALADIN", duration = 180 },-- Blessing of Protection
94 | [5599] = { parent = 1022 },
95 | [10278] = { parent = 1022 },
96 | [498] = { class = "PALADIN", duration = 300 }, -- Divine Shield
97 | [5573] = { parent = 498 },
98 | [642] = { parent = 498 },
99 | [1020] = { parent = 498 },
100 | [853] = { class = "PALADIN", duration = 45 }, -- Hammer of Justice
101 | [5588] = { parent = 853 },
102 | [5589] = { parent = 853 },
103 | [10308] = { parent = 853 },
104 | [1044] = { class = "PALADIN", duration = 20 }, -- Blessing of Freedom
105 | [20066] = { class = "PALADIN", duration = 60 }, -- Repentance
106 |
107 | -- Hunter
108 |
109 | [3045] = { class = "HUNTER", duration = 180 }, -- Rapid Fire
110 | [19263] = { class = "HUNTER", duration = 300 }, -- Deterrence
111 | [19574] = { class = "HUNTER", duration = 120 }, -- Bestial Wrath
112 | [1499] = { class = "HUNTER", duration = 15 }, -- Freezing Trap
113 | [14310] = { parent = 1499 },
114 | [14311] = { parent = 1499 },
115 | [19386] = { class = "HUNTER", duration = 120 }, -- Wyvern Sting
116 | [24132] = { parent = 19386 },
117 | [24133] = { parent = 19386 },
118 | [19503] = { class = "HUNTER", duration = 30 }, -- Scatter Shot
119 | [25999] = { class = "HUNTER", duration = 25 }, -- Boar Charge
120 |
121 | -- Druid
122 |
123 | [22812] = { class = "DRUID", duration = 60 }, -- Barkskin
124 | [16689] = { class = "DRUID", duration = 60 }, -- Nature's Grasp
125 | [16810] = { parent = 16689 },
126 | [16811] = { parent = 16689 },
127 | [16812] = { parent = 16689 },
128 | [16813] = { parent = 16689 },
129 | [17329] = { parent = 16689 },
130 |
131 | [29166] = { class = "DRUID", duration = 360 }, -- Innervate
132 | [5211] = { class = "DRUID", duration = 60 }, -- Bash
133 | [6798] = { parent = 5211 },
134 | [8983] = { parent = 5211 },
135 | [1850] = { class = "DRUID", duration = 300 }, -- Dash
136 | [9821] = { parent = 1850 },
137 |
138 | -- Mage
139 |
140 | [11426] = { class = "MAGE", duration = 30 }, -- Ice Barrier
141 | [13031] = { parent = 11426 },
142 | [13032] = { parent = 11426 },
143 | [13033] = { parent = 11426 },
144 | [543] = { class = "MAGE", duration = 30 }, -- Fire Ward
145 | [8457] = { parent = 543 },
146 | [8458] = { parent = 543 },
147 | [10223] = { parent = 543 },
148 | [10225] = { parent = 543 },
149 | [6143] = { class = "MAGE", duration = 30 }, -- Frost Ward
150 | [8461] = { parent = 6143 },
151 | [8462] = { parent = 6143 },
152 | [10177] = { parent = 6143 },
153 | [28609] = { parent = 6143 },
154 | [122] = { class = "MAGE", duration = 21 }, -- Frost Nova
155 | [865] = { parent = 122 },
156 | [6131] = { parent = 122 },
157 | [10230] = { parent = 122 },
158 | [12042] = { class = "MAGE", duration = 180 }, -- Arcane Power
159 | [11958] = { class = "MAGE", duration = 300 }, -- Ice Block
160 | [12051] = { class = "MAGE", duration = 420 }, -- Evocation
161 | [12472] = { class = "MAGE", duration = 600 }, -- Cold Snap
162 |
163 | -- Rogue
164 |
165 | [13750] = { class = "ROGUE", duration = 300 }, -- Adrenaline Rush
166 | [13877] = { class = "ROGUE", duration = 120 }, -- Blade Flurry
167 | [408] = { class = "ROGUE", duration = 20 }, -- Kidney Shot
168 | [8643] = { parent = 408 },
169 | [2094] = { class = "ROGUE", duration = 180 }, -- Blind
170 | [2983] = { class = "ROGUE", duration = 180 }, -- Sprint
171 | [8696] = { parent = 2983 },
172 | [11305] = { parent = 2983 },
173 | [5277] = { class = "ROGUE", duration = 180 }, -- Evasion
174 | [1776] = { class = "ROGUE", duration = 9 }, -- Gouge
175 | [1777] = { parent = 1776 },
176 | [8629] = { parent = 1776 },
177 | [11285] = { parent = 1776 },
178 | [11286] = { parent = 1776 },
179 | [14278] = { class = "ROGUE", duration = 20 }, -- Ghostly Strike
180 | [14183] = { class = "ROGUE", duration = 120 }, -- Premeditation
181 | [14185] = { class = "ROGUE", duration = 600 }, -- Preparation
182 |
183 | -- Warrior
184 |
185 | [20230] = { class = "WARRIOR", duration = 1800 }, -- Retaliation
186 | [1719] = { class = "WARRIOR", duration = 1800 }, -- Recklessness
187 | [871] = { class = "WARRIOR", duration = 1800 }, -- Shield Wall
188 | [12328] = { class = "WARRIOR", duration = 180 }, -- Death Wish
189 | [18499] = { class = "WARRIOR", duration = 30 }, -- Berserker Rage
190 | [12809] = { class = "WARRIOR", duration = 45 }, -- Concussion Blow
191 | [100] = { class = "WARRIOR", duration = 15 }, -- Charge
192 | [6178] = { parent = 100 },
193 | [11578] = { parent = 100 },
194 | [20252] = { class = "WARRIOR", duration = 25 }, -- Intercept
195 | [20616] = { parent = 20252 },
196 | [20617] = { parent = 20252 },
197 |
198 | }
199 |
--------------------------------------------------------------------------------
/OmniBar_Vanilla.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 11506, 11507
2 | ## Title: OmniBar
3 | ## Notes: Tracks enemy cooldowns
4 | ## Version: @project-version@
5 | ## Author: Jordon
6 | ## SavedVariables: OmniBarDB
7 | ## IconTexture: Interface\AddOns\OmniBar\Media\Textures\icon.blp
8 | ## X-Curse-Project-ID: 85814
9 | ## X-Wago-ID: BO678XK3
10 | ## X-WoWI-ID: 23235
11 |
12 | #@no-lib-strip@
13 | Libs\LibStub\LibStub.lua
14 | Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
15 | Libs\AceAddon-3.0\AceAddon-3.0.xml
16 | Libs\AceDB-3.0\AceDB-3.0.xml
17 | Libs\AceDBOptions-3.0\AceDBOptions-3.0.xml
18 | Libs\AceComm-3.0\AceComm-3.0.xml
19 | Libs\AceEvent-3.0\AceEvent-3.0.xml
20 | Libs\AceGUI-3.0\AceGUI-3.0.xml
21 | Libs\AceConfig-3.0\AceConfig-3.0.xml
22 | Libs\AceLocale-3.0\AceLocale-3.0.xml
23 | Libs\AceSerializer-3.0\AceSerializer-3.0.xml
24 | Libs\LibDeflate\LibDeflate.lua
25 | #@end-no-lib-strip@
26 |
27 | Locales\Locales.xml
28 | OmniBar.xml
29 | OmniBar_Vanilla.lua
30 | OmniBar.lua
31 | Options.lua
32 |
--------------------------------------------------------------------------------
/OmniBar_Wrath.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 30404
2 | ## Title: OmniBar
3 | ## Notes: Tracks enemy cooldowns
4 | ## Version: @project-version@
5 | ## Author: Jordon
6 | ## SavedVariables: OmniBarDB
7 | ## IconTexture: Interface\AddOns\OmniBar\Media\Textures\icon.blp
8 | ## X-Curse-Project-ID: 85814
9 | ## X-Wago-ID: BO678XK3
10 | ## X-WoWI-ID: 23235
11 |
12 | #@no-lib-strip@
13 | Libs\LibStub\LibStub.lua
14 | Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
15 | Libs\AceAddon-3.0\AceAddon-3.0.xml
16 | Libs\AceDB-3.0\AceDB-3.0.xml
17 | Libs\AceDBOptions-3.0\AceDBOptions-3.0.xml
18 | Libs\AceComm-3.0\AceComm-3.0.xml
19 | Libs\AceEvent-3.0\AceEvent-3.0.xml
20 | Libs\AceGUI-3.0\AceGUI-3.0.xml
21 | Libs\AceConfig-3.0\AceConfig-3.0.xml
22 | Libs\AceLocale-3.0\AceLocale-3.0.xml
23 | Libs\AceSerializer-3.0\AceSerializer-3.0.xml
24 | Libs\LibDeflate\LibDeflate.lua
25 | #@end-no-lib-strip@
26 |
27 | Locales\Locales.xml
28 | OmniBar.xml
29 | OmniBar_Wrath.lua
30 | OmniBar.lua
31 | Options.lua
32 |
--------------------------------------------------------------------------------
/Options.lua:
--------------------------------------------------------------------------------
1 |
2 | -- OmniBar by Jordon
3 |
4 | local addonName, addon = ...
5 |
6 | local C_Spell = C_Spell
7 | local CLASS_ICON_TCOORDS = CLASS_ICON_TCOORDS
8 | local CLASS_SORT_ORDER = CLASS_SORT_ORDER
9 | local CreateFrame = CreateFrame
10 | local DELETE = DELETE
11 | local GENERAL = GENERAL
12 | local GetAddOnMetadata = GetAddOnMetadata
13 | local GetSpecializationInfoByID = GetSpecializationInfoByID
14 | local GetSpellDescription = C_Spell and C_Spell.GetSpellDescription or GetSpellDescription
15 | local GetSpellInfo = C_Spell and C_Spell.GetSpellInfo or GetSpellInfo
16 | local GetSpellTexture = C_Spell and C_Spell.GetSpellTexture or GetSpellTexture
17 | local LOCALIZED_CLASS_NAMES_MALE = LOCALIZED_CLASS_NAMES_MALE
18 | local LibStub = LibStub
19 | local MAX_CLASSES = MAX_CLASSES
20 | local NO = NO
21 | local OmniBar_CreateIcon = OmniBar_CreateIcon
22 | local OmniBar_IsSpellEnabled = OmniBar_IsSpellEnabled
23 | local OmniBar_LoadPosition = OmniBar_LoadPosition
24 | local OmniBar_OnEvent = OmniBar_OnEvent
25 | local OmniBar_Position = OmniBar_Position
26 | local OmniBar_SavePosition = OmniBar_SavePosition
27 | local SecondsToTime = SecondsToTime
28 | local Spell = Spell
29 | local StaticPopupDialogs = StaticPopupDialogs
30 | local StaticPopup_Show = StaticPopup_Show
31 | local UIParent = UIParent
32 | local WOW_PROJECT_CLASSIC = WOW_PROJECT_CLASSIC
33 | local WOW_PROJECT_ID = WOW_PROJECT_ID
34 | local WOW_PROJECT_MAINLINE = WOW_PROJECT_MAINLINE
35 | local YES = YES
36 | local format = format
37 | local nop = nop
38 |
39 | local function GetSpellName(id)
40 | if C_Spell and C_Spell.GetSpellName then
41 | return C_Spell.GetSpellName(id)
42 | else
43 | return GetSpellInfo(id)
44 | end
45 | end
46 |
47 | local OmniBar = LibStub("AceAddon-3.0"):GetAddon("OmniBar")
48 | local L = LibStub("AceLocale-3.0"):GetLocale("OmniBar")
49 |
50 | local MAX_ARENA_SIZE = addon.MAX_ARENA_SIZE or 0
51 |
52 | local LOCALIZED_CLASS_NAMES_MALE_WITH_GENERAL = {}
53 | for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do
54 | LOCALIZED_CLASS_NAMES_MALE_WITH_GENERAL[k] = v
55 | end
56 | LOCALIZED_CLASS_NAMES_MALE_WITH_GENERAL["GENERAL"] = GENERAL
57 |
58 | local CLASS_SORT_ORDER_WITH_GENERAL = {}
59 | for k,v in pairs(CLASS_SORT_ORDER) do
60 | CLASS_SORT_ORDER_WITH_GENERAL[k] = v
61 | end
62 | CLASS_SORT_ORDER_WITH_GENERAL[0] = "GENERAL"
63 |
64 | local points = {
65 | TOPLEFT = L["Top Left"],
66 | TOP = L["Top"],
67 | TOPRIGHT = L["Top Right"],
68 | LEFT = L["Left"],
69 | CENTER = L["Center"],
70 | RIGHT = L["Right"],
71 | BOTTOMLEFT = L["Bottom Left"],
72 | BOTTOM = L["Bottom"],
73 | BOTTOMRIGHT = L["Bottom Right"],
74 | }
75 |
76 | local tooltip = CreateFrame("GameTooltip", "OmniBarTooltip", UIParent, "GameTooltipTemplate")
77 | local function GetSpellTooltipText(spellID)
78 | tooltip:SetOwner(UIParent, "ANCHOR_NONE")
79 | tooltip:SetSpellByID(spellID)
80 | local lines = tooltip:NumLines()
81 | if lines < 1 then return end
82 | local line = _G["OmniBarTooltipTextLeft"..lines]:GetText()
83 | if not line then return end
84 | tooltip:Hide()
85 | return line
86 | end
87 |
88 | local function IsSpellEnabled(info)
89 | local spellID = tonumber(info[#info])
90 | local key = info[2]
91 | return OmniBar_IsSpellEnabled(_G[key], spellID)
92 | end
93 |
94 | StaticPopupDialogs["OMNIBAR_DELETE"] = {
95 | text = DELETE.." \"%s\"",
96 | button1 = YES,
97 | button2 = NO,
98 | OnAccept = function(self, data)
99 | OmniBar:Delete(data)
100 | OmniBar:OnEnable()
101 | end,
102 | timeout = 0,
103 | whileDead = true,
104 | }
105 |
106 |
107 | function OmniBar:ToggleLock(button)
108 | self.db.profile.bars[button.arg].locked = not self.db.profile.bars[button.arg].locked
109 | OmniBar_Position(_G[button.arg])
110 | self.options.args.bars.args[button.arg].args.lock.name = self.db.profile.bars[button.arg].locked and L["Unlock"] or L["Lock"]
111 | end
112 |
113 | local function GetBars(key)
114 | local bars = {}
115 | for k in pairs(OmniBar.db.profile.bars) do if k ~= key then bars[k] = OmniBar.db.profile.bars[k].name end end
116 | return bars
117 | end
118 |
119 | local descriptions = CreateFrame("Frame");
120 | descriptions:SetScript("OnEvent", function(self, event, spellID, success)
121 | if success then
122 | self[spellID] = GetSpellDescription(spellID);
123 | end
124 | end);
125 | descriptions:RegisterEvent("SPELL_DATA_LOAD_RESULT");
126 |
127 | local function GetSpells()
128 | local spells = {
129 | uncheck = {
130 | name = L["Uncheck All"],
131 | type = "execute",
132 | func = function(info)
133 | local key = info[#info-2]
134 | local bar = _G[key]
135 | bar.settings.spells = {}
136 | OmniBar:Refresh(true)
137 | end,
138 | order = 1,
139 | },
140 | check = {
141 | name = L["Check Default Spells"],
142 | type = "execute",
143 | func = function(info)
144 | local key = info[#info-2]
145 | local bar = _G[key]
146 | bar.settings.spells = nil
147 | OmniBar:Refresh(true)
148 | end,
149 | order = 2,
150 | },
151 | checkAll = {
152 | name = "Check All Spells",
153 | type = "execute",
154 | func = function(info)
155 | local key = info[#info-2]
156 | local bar = _G[key]
157 |
158 | bar.settings.spells = {}
159 | for k,v in pairs(addon.Cooldowns) do
160 | if (not v.parent) then
161 | bar.settings.spells[k] = true
162 | end
163 | end
164 |
165 | OmniBar:Refresh(true)
166 | end,
167 | order = 3,
168 | },
169 | }
170 | for i = 0, MAX_CLASSES do
171 |
172 | spells[CLASS_SORT_ORDER_WITH_GENERAL[i]] = {
173 | name = LOCALIZED_CLASS_NAMES_MALE_WITH_GENERAL[CLASS_SORT_ORDER_WITH_GENERAL[i]],
174 | type = "group",
175 | args = {},
176 | hidden = function(info)
177 | local bar = info[#info-2]
178 | local class = info[#info]
179 | return next(info.options.args.bars.args[bar].args.spells.args[class].args) == nil
180 | end,
181 | icon = "Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Classes",
182 | iconCoords = CLASS_ICON_TCOORDS[CLASS_SORT_ORDER_WITH_GENERAL[i]]
183 | }
184 |
185 | if i == 0 then
186 | spells[CLASS_SORT_ORDER_WITH_GENERAL[i]]["icon"] = "Interface\\Icons\\Trade_Engineering"
187 | spells[CLASS_SORT_ORDER_WITH_GENERAL[i]]["iconCoords"] = nil
188 | spells[CLASS_SORT_ORDER_WITH_GENERAL[i]]["order"] = 0
189 | end
190 |
191 | for spellID, spell in pairs(addon.Cooldowns) do
192 | if spell.class and spell.class == CLASS_SORT_ORDER_WITH_GENERAL[i] then
193 | local spellName = GetSpellName(spellID)
194 | if spellName then
195 | local spellTexture = OmniBar:GetSpellTexture(spellID) or ""
196 | if string.len(spellName) > 25 then
197 | spellName = string.sub(spellName, 0, 22) .. "..."
198 | end
199 |
200 | if not descriptions[spellID] then
201 | C_Spell.RequestLoadSpellData(spellID);
202 | end
203 |
204 | spells[CLASS_SORT_ORDER_WITH_GENERAL[i]].args[tostring(spellID)] = {
205 | type = "toggle",
206 | get = IsSpellEnabled,
207 | width = "full",
208 | hidden = nop,
209 | arg = spellID,
210 | desc = function()
211 | local duration = type(spell.duration) == "number" and spell.duration or spell.duration.default
212 | local spellDesc = descriptions[spellID] or ""
213 | local extra = "\n\n|cffffd700 "..L["Spell ID"].."|r "..spellID..
214 | "\n\n|cffffd700 "..L["Cooldown"].."|r "..SecondsToTime(duration)
215 | return spellDesc..extra
216 | end,
217 | name = function()
218 | return format("|T%s:20|t %s", spellTexture, spellName)
219 | end,
220 | }
221 | end
222 | end
223 | end
224 | end
225 | return spells
226 | end
227 |
228 | function OmniBar:AddBarToOptions(key, refresh)
229 | local trackUnits = {
230 | ENEMY = "All Enemies",
231 | GROUP = "Group Members",
232 | PLAYER = PLAYER,
233 | TARGET = TARGET,
234 | FOCUS = FOCUS,
235 | party1 = PARTY .. " 1",
236 | party2 = PARTY .. " 2",
237 | party3 = PARTY .. " 3",
238 | party4 = PARTY .. " 4",
239 | }
240 |
241 | local trackUnitsOrder = {
242 | "ENEMY",
243 | "PLAYER",
244 | "TARGET",
245 | "FOCUS",
246 | "GROUP",
247 | "party1",
248 | "party2",
249 | "party3",
250 | "party4",
251 | }
252 |
253 | for i = 1, MAX_ARENA_SIZE do
254 | local unit = "arena" .. i
255 | trackUnits[unit] = ARENA .. " " .. i
256 | tinsert(trackUnitsOrder, unit)
257 | end
258 |
259 | self.options.args.bars.args[key] = {
260 | name = self.db.profile.bars[key].name,
261 | type = "group",
262 | order = self.index + 1,
263 | childGroups = "tab",
264 | get = function(info)
265 | local option = info[#info]
266 | return self.db.profile.bars[key][option]
267 | end,
268 | set = function(info, state)
269 | local option = info[#info]
270 | self.db.profile.bars[key][option] = state
271 | self:Refresh()
272 | end,
273 | args = {
274 | settings = {
275 | name = L["Settings"],
276 | type = "group",
277 | order = 10,
278 | args = {
279 | name = {
280 | name = L["Name"],
281 | desc = L["Set the name of the bar"],
282 | type = "input",
283 | width = "double",
284 | set = function(info, state)
285 | local option = info[#info]
286 | self.db.profile.bars[key][option] = state
287 | self.options.args.bars.args[key].name = state
288 | local f = _G[key.."AnchorText"]
289 | f:SetText(state)
290 | local width = f:GetWidth() + 28
291 | _G[key.."Anchor"]:SetSize(width, 30)
292 | self:Refresh()
293 | end,
294 | order = 1,
295 | },
296 | trackUnit = {
297 | name = "Track",
298 | type = "select",
299 | values = trackUnits,
300 | sorting = trackUnitsOrder,
301 | set = function(info, state)
302 | local option = info[#info]
303 | self.db.profile.bars[key][option] = state
304 | self:Refresh(true)
305 | end,
306 | order = 2,
307 | },
308 | lb1 = {
309 | name = "",
310 | type = "description",
311 | order = 3,
312 | },
313 | center = {
314 | name = L["Center Lock"],
315 | desc = L["Keep the bar centered horizontally"],
316 | width = "normal",
317 | type = "toggle",
318 | order = 4,
319 | },
320 | showUnused = {
321 | name = L["Show Unused Icons"],
322 | desc = L["Icons will always remain visible"],
323 | width = "normal",
324 | type = "toggle",
325 | order = 5,
326 | set = function(info, state)
327 | local option = info[#info]
328 | self.db.profile.bars[key][option] = state
329 | self:Refresh(true)
330 | end,
331 | },
332 | adaptive = {
333 | name = L["As Enemies Appear"],
334 | desc = L["Only show unused icons for arena opponents or enemies you target while in combat"],
335 | disabled = function()
336 | return (not self.db.profile.bars[key].showUnused) or self.db.profile.bars[key].trackUnit ~= "ENEMY"
337 | end,
338 | width = "normal",
339 | type = "toggle",
340 | order = 6,
341 | set = function(info, state)
342 | local option = info[#info]
343 | self.db.profile.bars[key][option] = state
344 | self:Refresh(true)
345 | end,
346 | },
347 | growUpward = {
348 | name = L["Grow Rows Upward"],
349 | desc = L["Toggle the grow direction of the icons"],
350 | width = "normal",
351 | type = "toggle",
352 | order = 7,
353 | set = function(info, state)
354 | local option = info[#info]
355 | self.db.profile.bars[key][option] = state
356 | OmniBar_Position(_G[key])
357 | end,
358 | },
359 | cooldownCount = {
360 | name = L["Countdown Count"],
361 | desc = L["Allow Blizzard and other addons to display countdown text on the icons"],
362 | width = "normal",
363 | type = "toggle",
364 | set = function(info, state)
365 | local option = info[#info]
366 | self.db.profile.bars[key][option] = state
367 | self:Refresh(true)
368 | end,
369 | order = 8,
370 | },
371 | border = {
372 | name = L["Show Border"],
373 | desc = L["Draw a border around the icons"],
374 | width = "normal",
375 | type = "toggle",
376 | order = 9,
377 | },
378 | highlightTarget = {
379 | name = L["Highlight Target"],
380 | desc = L["Draw a border around your target"],
381 | width = "normal",
382 | type = "toggle",
383 | order = 10,
384 | disabled = function()
385 | return self.db.profile.bars[key].trackUnit ~= "ENEMY"
386 | end,
387 | set = function(info, state)
388 | local option = info[#info]
389 | self.db.profile.bars[key][option] = state
390 | self:Refresh(true)
391 | end,
392 | },
393 | names = {
394 | name = L["Show Names"],
395 | desc = L["Show the player name of the spell"],
396 | width = "normal",
397 | type = "toggle",
398 | order = 11,
399 | },
400 | multiple = {
401 | name = L["Track Multiple Players"],
402 | desc = L["If another player is detected using the same ability, a duplicate icon will be created and tracked separately"],
403 | width = "normal",
404 | disabled = function()
405 | return self.db.profile.bars[key].trackUnit ~= "ENEMY"
406 | end,
407 | type = "toggle",
408 | order = 16,
409 | },
410 | glow = {
411 | name = L["Glow Icons"],
412 | desc = L["Display a glow animation around an icon when it is activated"],
413 | width = "normal",
414 | type = "toggle",
415 | order = 17,
416 | },
417 | tooltips = {
418 | name = L["Show Tooltips"],
419 | desc = L["Show spell information when mousing over the icons (the bar must be unlocked)"],
420 | width = "normal",
421 | type = "toggle",
422 | order = 18,
423 | },
424 | lb2 = {
425 | name = "",
426 | type = "description",
427 | order = 19,
428 | },
429 | iconSorting = {
430 | name = L["Sort Icons By:"],
431 | desc = L["Choose the order in which icons are sorted."],
432 | type = "select",
433 | values = {
434 | TIME_REMAINING = L["Time Remaining"],
435 | TIME_ADDED = L["Time Added"],
436 | },
437 | set = function(info, state)
438 | local option = info[#info]
439 | self.db.profile.bars[key][option] = state
440 | OmniBar_Position(_G[key])
441 | end,
442 | disabled = function() return self.db.profile.bars[key].showUnused end,
443 | order = 20,
444 | },
445 | align = {
446 | name = L["Alignment"],
447 | desc = L["Set the alignment of the icons to the anchor"],
448 | type = "select",
449 | values = {
450 | CENTER = L["Center"],
451 | LEFT = L["Left"],
452 | RIGHT = L["Right"],
453 | },
454 | set = function(info, state)
455 | local option = info[#info]
456 | self.db.profile.bars[key][option] = state
457 | self:Refresh(true)
458 | end,
459 | order = 21,
460 | },
461 | lb5 = {
462 | name = "",
463 | type = "description",
464 | order = 22,
465 | },
466 | size = {
467 | name = L["Size"],
468 | desc = L["Set the size of the icons"],
469 | type = "range",
470 | min = 1,
471 | max = 100,
472 | step = 1,
473 | order = 100,
474 | width = "double",
475 | },
476 | sizeDesc = {
477 | name = L["Set the size of the icons"] .. "\n",
478 | type = "description",
479 | order = 101,
480 | },
481 | columns = {
482 | name = L["Columns"],
483 | desc = L["Set the maximum icons per row"],
484 | type = "range",
485 | min = 1,
486 | max = 100,
487 | step = 1,
488 | order = 102,
489 | width = "double",
490 | set = function(info, state)
491 | local option = info[#info]
492 | self.db.profile.bars[key][option] = state
493 | OmniBar_Position(_G[key])
494 | end,
495 | },
496 | columnsDesc = {
497 | name = L["Set the maximum icons per row"] .. "\n",
498 | type = "description",
499 | order = 103,
500 | },
501 | maxIcons = {
502 | name = L["Icon Limit"],
503 | desc = L["Set the maximum number of icons displayed on the bar"],
504 | type = "range",
505 | min = 1,
506 | max = 500,
507 | step = 1,
508 | order = 104,
509 | width = "double",
510 | set = function(info, state)
511 | local option = info[#info]
512 | self.db.profile.bars[key][option] = state
513 | self:Refresh(true)
514 | end,
515 | },
516 | maxIconsDesc = {
517 | name = L["Set the maximum number of icons displayed on the bar"] .. "\n",
518 | type = "description",
519 | order = 105,
520 | },
521 | padding = {
522 | name = L["Padding"],
523 | desc = L["Set the space between icons"],
524 | type = "range",
525 | min = 0,
526 | max = 100,
527 | step = 1,
528 | order = 106,
529 | width = "double",
530 | set = function(info, state)
531 | local option = info[#info]
532 | self.db.profile.bars[key][option] = state
533 | OmniBar_Position(_G[key])
534 | end,
535 | },
536 | paddingDesc = {
537 | name = L["Set the space between icons"] .. "\n",
538 | type = "description",
539 | order = 107,
540 | },
541 | unusedAlpha = {
542 | name = L["Unused Icon Transparency"],
543 | desc = L["Set the transparency of unused icons"],
544 | isPercent = true,
545 | type = "range",
546 | min = 0,
547 | max = 1,
548 | step = 0.01,
549 | order = 108,
550 | width = "double",
551 | },
552 | unusedAlphaDesc = {
553 | name = L["Set the transparency of unused icons"] .. "\n",
554 | type = "description",
555 | order = 109,
556 | },
557 | swipeAlpha = {
558 | name = L["Swipe Transparency"],
559 | desc = L["Set the transparency of the swipe animation"],
560 | isPercent = true,
561 | type = "range",
562 | min = 0,
563 | max = 1,
564 | step = 0.01,
565 | order = 110,
566 | width = "double",
567 | },
568 | swipeAlphaDesc = {
569 | name = L["Set the transparency of the swipe animation"] .. "\n",
570 | type = "description",
571 | order = 111,
572 | },
573 |
574 | },
575 | },
576 | position = {
577 | name = L["Position"],
578 | type = "group",
579 | order = 11,
580 | get = function(info)
581 | local option = info[#info]
582 | return self.db.profile.bars[key].position[option]
583 | end,
584 | set = function(info, state)
585 | local option = info[#info]
586 | local set = {}
587 | set[option] = state
588 | OmniBar_SavePosition(_G[key], set)
589 | OmniBar_LoadPosition(_G[key])
590 | OmniBar_Position(_G[key])
591 | end,
592 | args = {
593 | reset = {
594 | name = L["Reset"],
595 | desc = L["Reset the position of the bar"],
596 | type = "execute",
597 | func = function()
598 | OmniBar_SavePosition(_G[key], {
599 | point = "CENTER",
600 | relativeTo = "UIParent",
601 | relativePoint = "CENTER",
602 | xOfs = 0,
603 | yOfs = 0,
604 | frameStrata = "MEDIUM",
605 | })
606 | OmniBar_LoadPosition(_G[key])
607 | end,
608 | order = 1,
609 | },
610 | lb3 = {
611 | name = "",
612 | type = "description",
613 | order = 2,
614 | },
615 | point = {
616 | name = L["Point"],
617 | desc = L["Set the point of the bar that will anchor"],
618 | type = "select",
619 | values = points,
620 | order = 3,
621 | },
622 | lb4 = {
623 | name = "",
624 | type = "description",
625 | order = 4,
626 | },
627 | relativeTo = {
628 | type = "input",
629 | width = "double",
630 | name = L["Relative To"],
631 | desc = L["Set the name of the frame the bar will attach to"],
632 | order = 5,
633 | },
634 | relativePoint = {
635 | name = L["Relative Point"],
636 | desc = L["Set the point of the frame to attach the bar"],
637 | type = "select",
638 | values = points,
639 | order = 7,
640 | },
641 | lb6 = {
642 | name = "",
643 | type = "description",
644 | order = 8,
645 | },
646 | xOfs = {
647 | type = "range",
648 | name = L["X"],
649 | desc = L["Set the X offset of the bar"],
650 | min = -2560,
651 | max = 2560,
652 | bigStep = 4,
653 | order = 9,
654 | },
655 | yOfs = {
656 | type = "range",
657 | name = L["Y"],
658 | desc = L["Set the Y offset of the bar"],
659 | min = -1600,
660 | max = 1600,
661 | bigStep = 5,
662 | order = 10,
663 | },
664 | lb7 = {
665 | name = "",
666 | type = "description",
667 | order = 11,
668 | },
669 | frameStrata = {
670 | name = L["Frame Strata"],
671 | desc = L["Set the strata of the bar"],
672 | type = "select",
673 | values = {
674 | BACKGROUND = L["Background"],
675 | LOW = L["Low"],
676 | MEDIUM = L["Medium"],
677 | HIGH = L["High"],
678 | DIALOG = L["Dialog"],
679 | FULLSCREEN = L["Fullscreen"],
680 | FULLSCREEN_DIALOG = L["Fullscreen Dialog"],
681 | TOOLTIP = L["Tooltip"],
682 | },
683 | order = 12,
684 | },
685 | },
686 | },
687 | visibility = {
688 | name = L["Visibility"],
689 | type = "group",
690 | set = function(info, state)
691 | local option = info[#info]
692 | self.db.profile.bars[key][option] = state
693 | OmniBar_OnEvent(_G[key], "PLAYER_ENTERING_WORLD")
694 | end,
695 | order = 12,
696 | args = {
697 | battleground = {
698 | name = L["Show in Battlegrounds"],
699 | desc = L["Show the icons in battlegrounds"],
700 | width = "double",
701 | type = "toggle",
702 | order = 13,
703 | },
704 | world = {
705 | name = L["Show in World"],
706 | desc = L["Show the icons in the world"],
707 | width = "double",
708 | type = "toggle",
709 | order = 15,
710 | },
711 | },
712 | },
713 | spells = {
714 | name = L["Spells"],
715 | type = "group",
716 | order = 13,
717 | arg = key,
718 | args = GetSpells(),
719 | set = function(info, state)
720 | local spellID = tonumber(info[#info])
721 |
722 | -- set default spells explicitly
723 | if (not self.db.profile.bars[key].spells) then
724 | self.db.profile.bars[key].spells = {}
725 | for k,v in pairs(addon.Cooldowns) do
726 | if v.default then
727 | self.db.profile.bars[key].spells[k] = true
728 | end
729 | end
730 | end
731 |
732 | self.db.profile.bars[key].spells[spellID] = state
733 | OmniBar_CreateIcon(_G[key])
734 | self:Refresh(true)
735 | end,
736 | },
737 | lock = {
738 | type = "execute",
739 | name = self.db.profile.bars[key].locked and L["Unlock"] or L["Lock"],
740 | desc = L["Lock the bar to prevent dragging"],
741 | arg = key,
742 | func = "ToggleLock",
743 | handler = OmniBar,
744 | width = 0.75,
745 | order = 1,
746 | },
747 | test = {
748 | type = "execute",
749 | name = L["Test"],
750 | desc = L["Activate the icons for testing"],
751 | order = 2,
752 | width = 0.75,
753 | func = function(info)
754 | local key = info[#info-1]
755 | local bar = _G[key]
756 | OmniBar_Test(bar)
757 | end,
758 | },
759 | delete = {
760 | type = "execute",
761 | name = L["Delete"],
762 | width = 0.75,
763 | desc = L["Delete the bar"],
764 | func = function()
765 | local popup = StaticPopup_Show("OMNIBAR_DELETE", self.db.profile.bars[key].name)
766 | if popup then popup.data = key end
767 | end,
768 | arg = key,
769 | order = 3,
770 | },
771 | },
772 | }
773 |
774 | self.options.args.bars.args[key].args.spells.args.copy = {
775 | name = "Copy From: ",
776 | desc = "Copies spells from the selected OmniBar",
777 | type = "select",
778 | width = "normal",
779 | values = GetBars(key),
780 | set = function(info, state)
781 | local key = info[#info-2]
782 | local dst = _G[key]
783 | local src = _G[state]
784 |
785 | if (not src.settings.spells) then
786 | dst.settings.spells = nil
787 | return
788 | end
789 |
790 | dst.settings.spells = {}
791 | for k,v in pairs(src.settings.spells) do
792 | dst.settings.spells[k] = v
793 | end
794 |
795 | OmniBar:Refresh(true)
796 | end,
797 | order = 3,
798 | }
799 |
800 | if WOW_PROJECT_ID ~= WOW_PROJECT_CLASSIC then
801 | self.options.args.bars.args[key].args.settings.args.highlightFocus = {
802 | name = L["Highlight Focus"],
803 | desc = L["Draw a border around your focus"],
804 | width = "normal",
805 | type = "toggle",
806 | order = 10,
807 | disabled = function()
808 | return self.db.profile.bars[key].trackUnit ~= "ENEMY"
809 | end,
810 | set = function(info, state)
811 | local option = info[#info]
812 | self.db.profile.bars[key][option] = state
813 | self:Refresh(true)
814 | end,
815 | }
816 |
817 | self.options.args.bars.args[key].args.visibility.args.arena = {
818 | name = L["Show in Arena"],
819 | desc = L["Show the icons in arena"],
820 | width = "double",
821 | type = "toggle",
822 | order = 11,
823 | }
824 | end
825 |
826 | if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
827 | self.options.args.bars.args[key].args.visibility.args.ratedBattleground = {
828 | name = L["Show in Rated Battlegrounds"],
829 | desc = L["Show the icons in rated battlegrounds"],
830 | width = "double",
831 | type = "toggle",
832 | order = 12,
833 | }
834 |
835 | self.options.args.bars.args[key].args.visibility.args.scenario = {
836 | name = L["Show in Scenarios"],
837 | desc = L["Show the icons in scenarios"],
838 | width = "double",
839 | type = "toggle",
840 | order = 14,
841 | }
842 | end
843 |
844 | if refresh then LibStub("AceConfigRegistry-3.0"):NotifyChange("OmniBar") end
845 | end
846 |
847 | local specIDs = {
848 | 62, 63, 64, 65, 66, 70, 71, 72, 73, 102, 103, 104, 105,
849 | 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,
850 | 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 577,
851 | 581, 1467, 1468
852 | }
853 |
854 | local customSpellInfo = {
855 | spellId = {
856 | order = 1,
857 | type = "description",
858 | name = function(info)
859 | local spellId = info[#info-1]
860 | return "|cffffd700 ".."Spell ID".."|r ".. spellId .."\n"
861 | end,
862 | },
863 | delete = {
864 | type = "execute",
865 | name = L["Delete"],
866 | desc = L["Delete the cooldown"],
867 | func = function(info)
868 | local spellId = info[#info-1]
869 | spellId = tonumber(spellId)
870 | OmniBar.db.global.cooldowns[spellId] = nil
871 | addon.Cooldowns[spellId] = nil
872 | OmniBar:AddCustomSpells()
873 | info.options.args.customSpells.args[info[#info-1]] = nil
874 | OmniBar:OnEnable() -- to refresh the bar spells tab
875 | LibStub("AceConfigRegistry-3.0"):NotifyChange("OmniBar")
876 | end,
877 | order = 2,
878 | },
879 | lb = {
880 | name = "",
881 | type = "header",
882 | order = 3,
883 | },
884 | duration = {
885 | name = L["Duration"],
886 | width = "double",
887 | desc = L["Set the duration of the cooldown"],
888 | type = "range",
889 | min = 1,
890 | softMax = WOW_PROJECT_ID == WOW_PROJECT_CLASSIC and 1200 or 600,
891 | step = 1,
892 | order = 4,
893 | set = function(info, state)
894 | local spellId = info[#info-1]
895 | spellId = tonumber(spellId)
896 | OmniBar.db.global.cooldowns[spellId].duration.default = state
897 | OmniBar:AddCustomSpells()
898 | end,
899 | get = function(info)
900 | local spellId = info[#info-1]
901 | spellId = tonumber(spellId)
902 | return OmniBar.db.global.cooldowns[spellId].duration.default
903 | end,
904 |
905 | },
906 | charges = {
907 | order = 6,
908 | type = "range",
909 | min = 1,
910 | max = 10,
911 | step = 1,
912 | name = L["Charges"],
913 | desc = L["Set the charges of the cooldown"],
914 | set = function(info, state)
915 | local option = info[#info]
916 | local spellId = info[#info-1]
917 | spellId = tonumber(spellId)
918 | if state == 1 then state = nil end
919 | OmniBar.db.global.cooldowns[spellId][option] = state
920 | OmniBar:AddCustomSpells()
921 | end,
922 | get = function(info)
923 | local option = info[#info]
924 | local spellId = info[#info-1]
925 | spellId = tonumber(spellId)
926 | local value = OmniBar.db.global.cooldowns[spellId][option]
927 | if not value then return 1 end
928 | return OmniBar.db.global.cooldowns[spellId][option]
929 | end,
930 | },
931 | class = {
932 | name = L["Class"],
933 | desc = L["Set the class of the cooldown"],
934 | type = "select",
935 | values = LOCALIZED_CLASS_NAMES_MALE_WITH_GENERAL,
936 | order = 5,
937 | set = function(info, state)
938 | local option = info[#info]
939 | local spellId = info[#info-1]
940 | spellId = tonumber(spellId)
941 | OmniBar.db.global.cooldowns[spellId].specID = nil
942 | OmniBar.db.global.cooldowns[spellId].duration = { default = OmniBar.db.global.cooldowns[spellId].duration.default }
943 | OmniBar.db.global.cooldowns[spellId][option] = state
944 | OmniBar:OnEnable() -- to refresh the bar spells tab
945 | OmniBar:AddCustomSpells()
946 | end,
947 | },
948 | icon = {
949 | name = "Icon",
950 | desc = "Set the icon of the cooldown",
951 | type = "input",
952 | get = function(info)
953 | local spellId = info[#info-1]
954 | return tostring(OmniBar:GetSpellTexture(spellId))
955 | end,
956 | set = function(info, state)
957 | local option = info[#info]
958 | local spellId = info[#info-1]
959 | OmniBar.db.global.cooldowns[tonumber(spellId)][option] = tonumber(state)
960 | OmniBar:OnEnable() -- to refresh the bar spells tab
961 | OmniBar:AddCustomSpells()
962 | end,
963 | },
964 | }
965 |
966 | local customSpells = {
967 | spellId = {
968 | name = L["Spell ID"],
969 | type = "input",
970 | set = function(info, state, data)
971 | local spellId = tonumber(state)
972 | local name = GetSpellName(spellId)
973 | if OmniBar.db.global.cooldowns[spellId] then return end
974 | if spellId and name then
975 | OmniBar.db.global.cooldowns[spellId] = data or addon.Cooldowns[spellId] or { custom = true, duration = { default = 30 } , class = "GENERAL" }
976 |
977 | local duration
978 | -- If it's a child convert it
979 | if OmniBar.db.global.cooldowns[spellId].parent then
980 | -- If the child has a custom duration, save it so we can restore it after we copy from parent
981 | if OmniBar.db.global.cooldowns[spellId].duration then
982 | duration = OmniBar.db.global.cooldowns[spellId].duration
983 | end
984 |
985 | OmniBar.db.global.cooldowns[spellId] = OmniBar:CopyCooldown(addon.Cooldowns[OmniBar.db.global.cooldowns[spellId].parent])
986 |
987 | -- Restore child's duration
988 | if duration then
989 | OmniBar.db.global.cooldowns[spellId].duration = duration
990 | end
991 | end
992 |
993 | -- convert duration to array
994 | if type(OmniBar.db.global.cooldowns[spellId].duration) == "number" then
995 | OmniBar.db.global.cooldowns[spellId].duration = { default = OmniBar.db.global.cooldowns[spellId].duration }
996 | end
997 | OmniBar:AddCustomSpells()
998 |
999 | OmniBar.options.args.customSpells.args[tostring(spellId)] = {
1000 | name = name,
1001 | type = "group",
1002 | childGroups = "tab",
1003 | args = customSpellInfo,
1004 | icon = OmniBar:GetSpellTexture(spellId),
1005 | }
1006 | OmniBar:OnEnable() -- to refresh the bar spells tab
1007 | LibStub("AceConfigRegistry-3.0"):NotifyChange("OmniBar")
1008 | end
1009 | end,
1010 | },
1011 | }
1012 |
1013 | if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
1014 | for i = 1, #specIDs do
1015 | local specID = specIDs[i]
1016 | local _, name, _, icon = GetSpecializationInfoByID(specID)
1017 | customSpellInfo["spec"..specID] = {
1018 | name = format("|T%s:20|t %s", icon, name),
1019 | hidden = function(info)
1020 | local spellId = info[#info-1]
1021 | spellId = tonumber(spellId)
1022 | local specID = info[#info]:gsub("spec", "")
1023 | specID = tonumber(specID)
1024 | if not specID then return end
1025 | if OmniBar.db.global.cooldowns[spellId].class ~= select(6, GetSpecializationInfoByID(specID)) then return true end
1026 | end,
1027 | desc = "",
1028 | type = "group",
1029 | args = {
1030 | enabled = {
1031 | name = L["Enabled"],
1032 | desc = L["Enable the cooldown for this specialization"],
1033 | type = "toggle",
1034 | order = 1,
1035 | get = function(info)
1036 | local option = info[#info]
1037 | local spellId = info[#info-2]
1038 | spellId = tonumber(spellId)
1039 | local specID = info[#info-1]:gsub("spec", "")
1040 | specID = tonumber(specID)
1041 | if not OmniBar.db.global.cooldowns[spellId].specID then return true end
1042 | for i = 1, #OmniBar.db.global.cooldowns[spellId].specID do
1043 | if OmniBar.db.global.cooldowns[spellId].specID[i] == specID then return true end
1044 | end
1045 | return false
1046 | end,
1047 | set = function(info, state)
1048 | local option = info[#info]
1049 | local spellId = info[#info-2]
1050 | spellId = tonumber(spellId)
1051 | local specID = info[#info-1]:gsub("spec", "")
1052 | specID = tonumber(specID)
1053 |
1054 | -- check all specs first
1055 | if not OmniBar.db.global.cooldowns[spellId].specID then
1056 | OmniBar.db.global.cooldowns[spellId].specID = {}
1057 | for i = 1, #specIDs do
1058 | if OmniBar.db.global.cooldowns[spellId].class == select(6, GetSpecializationInfoByID(specIDs[i])) then
1059 | table.insert(OmniBar.db.global.cooldowns[spellId].specID, specIDs[i])
1060 | end
1061 | end
1062 | end
1063 |
1064 | -- then remove if we unchecked
1065 | for i = #OmniBar.db.global.cooldowns[spellId].specID, 1, -1 do
1066 | if not state and OmniBar.db.global.cooldowns[spellId].specID[i] == specID then
1067 | table.remove(OmniBar.db.global.cooldowns[spellId].specID, i)
1068 | break
1069 | end
1070 | end
1071 |
1072 | -- add if we checked it
1073 | if state then
1074 | table.insert(OmniBar.db.global.cooldowns[spellId].specID, specID)
1075 | end
1076 |
1077 | OmniBar:AddCustomSpells()
1078 | end,
1079 |
1080 | },
1081 | duration = {
1082 | name = L["Duration"],
1083 | desc = L["Set the duration of the cooldown"],
1084 | type = "range",
1085 | min = 1,
1086 | softMax = 600,
1087 | step = 1,
1088 | order = 2,
1089 | set = function(info, state)
1090 | local option = info[#info]
1091 | local spellId = info[#info-2]
1092 | spellId = tonumber(spellId)
1093 | local specID = info[#info-1]:gsub("spec", "")
1094 | specID = tonumber(specID)
1095 | if state == OmniBar.db.global.cooldowns[spellId].duration.default then
1096 | state = nil
1097 | end
1098 | OmniBar.db.global.cooldowns[spellId].duration[specID] = state
1099 | OmniBar:AddCustomSpells()
1100 | end,
1101 | get = function(info)
1102 | local option = info[#info]
1103 | local spellId = info[#info-2]
1104 | spellId = tonumber(spellId)
1105 | local specID = info[#info-1]:gsub("spec", "")
1106 | specID = tonumber(specID)
1107 | return OmniBar.db.global.cooldowns[spellId].duration[specID] or OmniBar.db.global.cooldowns[spellId].duration.default
1108 | end,
1109 | },
1110 | },
1111 | }
1112 | end
1113 | end
1114 |
1115 | function OmniBar:SetupOptions()
1116 |
1117 | for spellId, spell in pairs(OmniBar.db.global.cooldowns) do
1118 | customSpells[tostring(spellId)] = {
1119 | name = GetSpellName(spellId),
1120 | type = "group",
1121 | childGroups = "tab",
1122 | args = customSpellInfo,
1123 | icon = function() return OmniBar:GetSpellTexture(spellId) end,
1124 | }
1125 | end
1126 |
1127 | self.options = {
1128 | name = "OmniBar",
1129 | descStyle = "inline",
1130 | type = "group",
1131 | plugins = {
1132 | profiles = { profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db) }
1133 | },
1134 | childGroups = "tab",
1135 | args = {
1136 | vers = {
1137 | order = 1,
1138 | type = "description",
1139 | name = "|cffffd700"..L["Version"].."|r "..self.version.string.."\n",
1140 | cmdHidden = true
1141 | },
1142 | desc = {
1143 | order = 2,
1144 | type = "description",
1145 | name = "|cffffd700 "..L["Author"].."|r Jordon\n",
1146 | cmdHidden = true
1147 | },
1148 | bars = {
1149 | name = L["Bars"],
1150 | type = "group",
1151 | order = 10,
1152 | childGroups = "tab",
1153 | args = {
1154 | add = {
1155 | type = "execute",
1156 | name = L["Create Bar"],
1157 | desc = L["Create a new bar"],
1158 | order = 1,
1159 | func = "Create",
1160 | handler = OmniBar,
1161 | width = 0.7,
1162 | },
1163 | test = {
1164 | type = "execute",
1165 | name = L["Test All"],
1166 | desc = L["Activate the icons for testing"],
1167 | order = 2,
1168 | func = "Test",
1169 | handler = OmniBar,
1170 | width = 0.7,
1171 | },
1172 | import = {
1173 | type = "execute",
1174 | name = L["Import"],
1175 | desc = L["Import an OmniBar profile"],
1176 | order = 3,
1177 | func = "ShowImport",
1178 | handler = OmniBar,
1179 | width = 0.7,
1180 | },
1181 | export = {
1182 | type = "execute",
1183 | name = L["Export"],
1184 | desc = L["Export this profile"],
1185 | order = 4,
1186 | func = "ShowExport",
1187 | handler = OmniBar,
1188 | width = 0.7,
1189 | },
1190 | },
1191 | },
1192 | customSpells = {
1193 | name = L["Custom Spells"],
1194 | type = "group",
1195 | order = 20,
1196 | args = customSpells,
1197 | set = function(info, state)
1198 | local option = info[#info]
1199 | local spellId = info[#info-1]
1200 | spellId = tonumber(spellId)
1201 | OmniBar.db.global.cooldowns[spellId][option] = state
1202 | self:AddCustomSpells()
1203 | end,
1204 | get = function(info)
1205 | local option = info[#info]
1206 | local spellId = info[#info-1]
1207 | spellId = tonumber(spellId)
1208 | if not spellId then return end
1209 | return OmniBar.db.global.cooldowns[spellId][option]
1210 | end,
1211 | },
1212 | },
1213 | }
1214 |
1215 | if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
1216 | local LibDualSpec = LibStub('LibDualSpec-1.0')
1217 | LibDualSpec:EnhanceDatabase(self.db, "OmniBarDB")
1218 | LibDualSpec:EnhanceOptions(self.options.plugins.profiles.profiles, self.db)
1219 | end
1220 |
1221 | LibStub("AceConfig-3.0"):RegisterOptionsTable("OmniBar", self.options)
1222 | LibStub("AceConfigDialog-3.0"):AddToBlizOptions("OmniBar", "OmniBar")
1223 | end
1224 |
1225 | local AceGUI = LibStub("AceGUI-3.0")
1226 |
1227 | -- Export
1228 | local export = AceGUI:Create("Frame")
1229 | export:SetWidth(550)
1230 | export:EnableResize(false)
1231 | export:SetStatusText("")
1232 | export:SetLayout("Flow")
1233 | export:SetTitle(L["Export"])
1234 | export:SetStatusText(L["Copy this code to share this OmniBar profile."])
1235 | export:Hide()
1236 | local exportEditBox = AceGUI:Create("MultiLineEditBox")
1237 | exportEditBox:SetLabel("")
1238 | exportEditBox:SetNumLines(29)
1239 | exportEditBox:SetText("")
1240 | exportEditBox:SetFullWidth(true)
1241 | exportEditBox:SetWidth(500)
1242 | exportEditBox.button:Hide()
1243 | exportEditBox.frame:SetClipsChildren(true)
1244 | export:AddChild(exportEditBox)
1245 | export.editBox = exportEditBox
1246 | OmniBar.export = export
1247 |
1248 | -- Import
1249 | local import = AceGUI:Create("Frame")
1250 | import:SetWidth(550)
1251 | import:EnableResize(false)
1252 | import:SetStatusText("")
1253 | import:SetLayout("Flow")
1254 | import:SetTitle(L["Import"])
1255 | import:Hide()
1256 | local importEditBox = AceGUI:Create("MultiLineEditBox")
1257 | importEditBox:SetLabel("")
1258 | importEditBox:SetNumLines(25)
1259 | importEditBox:SetText("")
1260 | importEditBox:SetFullWidth(true)
1261 | importEditBox:SetWidth(500)
1262 | importEditBox.button:Hide()
1263 | importEditBox.frame:SetClipsChildren(true)
1264 | import:AddChild(importEditBox)
1265 | import.editBox = importEditBox
1266 | local importButton = AceGUI:Create("Button")
1267 | importButton:SetWidth(100)
1268 | importButton:SetText(L["Import"])
1269 | importButton:SetCallback("OnClick", function()
1270 | local data = import.data
1271 | if (not data) then return end
1272 | if OmniBar:ImportProfile(data) then import:Hide() end
1273 | end)
1274 | import:AddChild(importButton)
1275 | import.button = importButton
1276 | importEditBox:SetCallback("OnTextChanged", function(widget)
1277 | local data = OmniBar:Decode(widget:GetText())
1278 | if (not data) then return end
1279 | import.statustext:SetTextColor(0,1,0)
1280 | import:SetStatusText(L["Ready to import"])
1281 | importButton:SetDisabled(false)
1282 | import.data = data
1283 | end)
1284 | OmniBar.import = import
1285 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OmniBar
2 | OmniBar is an _extremely lightweight_ addon that tracks enemy cooldowns.
3 |
4 | 
5 |
6 | [Open a ticket to report any issues](https://github.com/jordonwow/omnibar/issues)
7 |
8 | [Submit a pull request](https://github.com/jordonwow/omnibar/pulls)
9 |
10 | ## Features
11 | OmniBar is easily customizable, and has a rich feature set.
12 |
13 | ### Customizable Cooldowns
14 | Open the options panel to easily select which cooldowns you wish to track:
15 |
16 | ### Multiple Bars
17 | Create as many bars are you want!
18 |
19 | ### Automatically Hide Icons
20 | When a cooldown is used, its icon will be added to the bar. After it's complete, it will be hidden automatically. This allows more cooldowns to be tracked, while avoiding awkward gaps between bars.
21 |
22 | ### Show Unused Icons
23 | Check this option if you prefer the icons to always remain visible. The **Unused Icon Transparency** slider will adjust the transparency of the unused icons. Check **As Enemies Appear** to only show unused icons for arena opponents or enemies you target while in combat.
24 |
25 | ### Track Multiple Players
26 | If another player is detected using the same ability, a duplicate icon will be created and tracked separately.
27 |
28 | ### Profiles
29 | Create custom profiles with dual specialization support.
30 |
31 | ### Cooldown Count
32 | Allow Blizzard and other addons to display countdown text on the icons.
33 |
34 | ### Glow Icons
35 | A glow animation will be displayed around an icon when it is activated.
36 |
37 | ### Visual Tweaks
38 | You can configure various visual tweaks such as size, border, glow, transparency, columns, and padding. OmniBar also includes Masque support.
39 |
40 | ### Visibility
41 | Choose to display OmniBar in arenas, battlegrounds, and world combat.
42 |
43 | ## Configuration
44 | To open the options panel, type `/ob`
45 |
46 | 
47 |
--------------------------------------------------------------------------------