mirror of
https://codeberg.org/Duvelcorp/MetaHunt.git
synced 2026-09-22 07:36:58 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c0c2c275eb | |||
| ab34946775 | |||
| d41703949d | |||
| 27d37564ce | |||
| 4aed1174dd | |||
| 233899b2a0 | |||
| 89fd8e079c | |||
| 1a28d95b87 |
@@ -9,4 +9,3 @@
|
||||
tools/
|
||||
LOC*.md
|
||||
LOCALIZATION*.md
|
||||
CHANGELOG.md
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to MetaHunt will be documented in this file.
|
||||
|
||||
## [1.2.0] - 2026-03-10
|
||||
|
||||
### Added
|
||||
- Added keybinding text overlay on zButtons: parent and child buttons now display their bound key for the 5 bindable sets (Aspect, Track, Trap, Ammo, Pet).
|
||||
- Added "Expand on Hover" option for zButton children: when enabled, hovering over the parent button automatically expands children (instead of requiring right-click).
|
||||
- Added "Auto-Hide Timer" option for zButton children: a configurable 0–10 second timer that automatically collapses expanded children after the mouse leaves the button group. Timer resets while hovering any button in the group.
|
||||
|
||||
### Fixed
|
||||
- Fixed SavedVariables data loss on login caused by initialization race condition overwriting persisted data.
|
||||
- Fixed SavedVariables bloat by adding a migration that strips redundant default-valued keys on first load.
|
||||
- Fixed six performance issues including throttling high-frequency event handlers, caching repeated `getglobal` lookups, and reducing unnecessary table allocations in hot paths.
|
||||
- Cleaned up ICU module global variable leaks by properly scoping locals.
|
||||
- Standardized all remaining `SetScript` handler patterns to use the WoW 1.12 `this`-based convention consistently.
|
||||
|
||||
|
||||
## [1.1.0] - 2026-03-09
|
||||
|
||||
### Added
|
||||
- Added new `ICU` module with dedicated options panel.
|
||||
- Added ICU custom popup anchor mode with draggable anchor and direction toggle.
|
||||
- Added ICU popup hide delay options (`INSTANT`, 1..10 seconds).
|
||||
- Added new `Auto Quest` module for :
|
||||
- `Salt of the Scorpok` (`Bloodmage Drazial`)
|
||||
- `Arrows Are For Sissies` (`Artilleryman Sheldonore`)
|
||||
- Added a Food Feed learning feature to Feed-O-Matic.
|
||||
- Added Chronometer `Entrapment` effect tracking support.
|
||||
|
||||
### Changed
|
||||
- Loads of Frame/Handlers/Processes adjustments to optimize addon's CPU time and Memory usage.
|
||||
- Updated Chronometer Improved Wing Clip effect color to `MAROON` for clearer effect-bar distinction.
|
||||
- Reworked Stable Master processing to minimize swap-time overhead:
|
||||
- No auto-scan on `PET_STABLE_SHOW`.
|
||||
- Deferred stable scan moved to `PET_STABLE_CLOSED`.
|
||||
- Optional heavy workloads are skipped while stable UI is open.
|
||||
- Changed Hunter Book page order, and default opening page to `Beast Lore`.
|
||||
- Optimized `Pet History` result build/sort path using cached precomputed sort keys.
|
||||
- Modules Auto-Buy, Auto-Quest, ICU, Feed-O-Matic are by default disabled on first use on a character.
|
||||
|
||||
### Fixed
|
||||
- Fixed issues with zBouttons,Autostrp and Chronometer bar anchor not retaining their configured spawn position after the disabling/renabling of the Addon.
|
||||
- Fixed issues with options checkbox-state not always retaining their state on startup.
|
||||
- Fixed multiple issues in Feeed-O-Matic with some foods that were accepted by lvl 60 pets in Vanilla and are not anymore on Turtle.
|
||||
- Fixed Chronometer spell/event disable toggles in options so disabled entries now reliably block bar creation.
|
||||
- Fixed Chronometer `Feed Pet` bar missing trigger by adding `UNIT_AURA` fallback detection.
|
||||
- Fixed stable swap stutter/freezes by removing heavy processing from repeated `UNIT_PET` bursts during stable interactions.
|
||||
|
||||
|
||||
## [1.0.6] - 2026-03-05
|
||||
|
||||
### Fixed
|
||||
- Added missing abilities to all pet families.
|
||||
- Rescraped from Twow DB the previously in correct `Roar of Fortitude` pet-ability.
|
||||
- Fixed an issue with Tooltip on pet action bar abilities, that were falsely displayed as not learned yet for rankless abilities.
|
||||
- Restored visible Stable Master auto-scan feedback (`Stable scan complete: X slot(s).`) when opening the stable window.
|
||||
- Fixed stable scan icon persistence for active pets that were never stabled by capturing current-pet icon data during stable scans.
|
||||
- Hardened stable-scan bootstrap to initialize on both `PET_STABLE_SHOW` and `PET_STABLE_UPDATE` event paths.
|
||||
- Fixed issues with taming pet metadata that were not properly recorded since the last update.
|
||||
- Fixed issues with pet runaway interception that was broken since the last update.
|
||||
- Updated version-update notification text to include clearer upgrade guidance and plain GitHub URL text for updates.
|
||||
- Fixed an issue with `zTrack` buttons spells being incorrect after having respec the talents using brainwashing device.
|
||||
|
||||
|
||||
## [1.0.5] - 2026-03-01
|
||||
|
||||
### Fixed
|
||||
- Multiple changes to the addon to reduce its memory and CPU time footprint to the strict minimum possible.
|
||||
- Restored FeedOMatic pet hunger notifications so hungry/very hungry warnings are emitted reliably again when enabled.
|
||||
- Fixed Chronometer `Wing Clip` tracking by adding a safe fallback timer path for the missing trigger case.
|
||||
- Fixed Chronometer `Quick Shots` bar icon by mapping the event to the correct icon texture.
|
||||
- Fixed module enabled/disabled persistence to be truly per-character (`MTH_CharSavedVariables.moduleStates`) instead of account-shared.
|
||||
- Fixed AutoBuy persistence fallback by removing undeclared `MTH_AutoBuy_Saved` paths and using module stores/transient runtime fallback only.
|
||||
- Consolidated FeedOMatic legacy persistence to a single module-backed store (`modules.feedomatic.legacy`) with globals bound to that source.
|
||||
- Switched Chronometer profile persistence to per-character module storage with one-time migration from existing account profile data.
|
||||
- Switched Tooltips module options persistence to per-character module storage with one-time migration from existing account settings.
|
||||
|
||||
## [1.0.4] - 2026-02-27
|
||||
|
||||
### Added
|
||||
- Added new zButton bar `zRanged` that tracks all ranged weapons in bags and allows to quickly swap them.
|
||||
- Added structured localization architecture with dedicated locale packs under `locales/` and loader wiring through `init/localization.xml`.
|
||||
- Added a dedicated `Messages` options panel with per-message toggles.
|
||||
- Added Smart Ammo option `Enable Weapon-Swap Auto Ammo` to instantly equip best bullets/arrows when switching ranged weapon type.
|
||||
- Added two new Hunter Book pages in the main tab bar: `Projectiles` and `Ammo Bags`
|
||||
|
||||
### Changed
|
||||
- Reworked core localization runtime to support explicit locale fallback rules (`enUS`, `deDE`, `esES`, `ptBR`, `ruRU`, `zhCN`; no `frFR` target).
|
||||
- Updated Hunter Book NPC finder and map vendor markers to use localized NPC names by NPC ID.
|
||||
- Updated Hunter Book, item search/sort, AutoBuy item labels, and drop map markers to use localized item names by item ID.
|
||||
|
||||
|
||||
### Fixed
|
||||
- Fixed version metadata consistency so all first-party module descriptors report the same release version as the main addon.
|
||||
- Fixed SmartAmmo junk-shot detection by including `Baited Shot` and `Tranquilizing Shot` in `MTH_AMMO_JUNKSHOT_SET`.
|
||||
- Fixed zButtons options side effect where opening Mounts/Companions/Toys options could implicitly enable those buttons.
|
||||
- Normalized zButtons checkbox defaults (`enabled`, `tooltip`, `hideonclick`, `parent.hide`, `parent.circle`, `showammoname`) so toggle states are always explicit and never nil.
|
||||
- Fixed Beast Lore ability dropdown to exclude trainer-only abilities and list beast-learned abilities only.
|
||||
- Removed junk `TBD` ability value from Wind Serpent dataset entry (`Venomflayer Serpent`) so it no longer appears in Beast Lore filters.
|
||||
- Fixed zhunter child-button visibility restore so collapsed bars no longer hard-hide children (`ztrack` / `ztrap` expansion regression).
|
||||
- Fixed pet tame metadata fallback so existing pets are not assigned current zone/time unless a real tame attempt is pending.
|
||||
- Fixed Smart Ammo options copy mismatch by clarifying junk-shot swap behavior and restoring ammo target as previous equipped ammo.
|
||||
- Fixed Smart Ammo default state so junk-shot swaps are enabled when no saved value exists.
|
||||
- Fixed Beast Training startup prompt behavior so low-level hunters no longer receive training-scan warnings before level threshold.
|
||||
- Restored hidden `/mth err` slash command behavior for debug-frame access.
|
||||
- Fixed `zammo` children refresh on bag/inventory updates so newly acquired ammo types appear without `/reload`.
|
||||
- Preserved `zammo` out-of-stock behavior so previously shown ammo entries still remain visible with zero/out state.
|
||||
- Fixed intermittent `ztrack`/`ztrap` right-click expand/collapse issue after fresh login by preventing duplicate child-frame recreation during startup.
|
||||
- Fixed `zpet` spell resolution after trainer updates by using robust spellbook lookup and immediate refresh on `LEARNED_SPELL_IN_TAB`.
|
||||
|
||||
|
||||
## [1.0.3] - 2026-02-24
|
||||
|
||||
### Added
|
||||
- Initial published release.
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
## Interface: 11200
|
||||
## Version: 1.0.4
|
||||
## Version: 1.2.0
|
||||
## Title: MetaHunt - |cff00ff00Hunter
|
||||
## Author: Metasploit and his Copilot ;)
|
||||
## Notes: Unified addon suite for huntards making old addons compatible with TurtleWoW, and adding an arsenal of never seen Hunter's utilities.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# MetaHunt
|
||||
|
||||
MetaHunt is a Turtle WoW Hunter toolkit.
|
||||
It combines never-seen pet-centric and beast tracking features, and revives old broken hunter add-ons.
|
||||
It provides usefull tools for all hunters, wheter they are still leveling, lone-wolf, or HL raider.
|
||||
It is a modern modular addon that combines never-seen features, and improves/fixes a few old hunter add-ons.
|
||||
It provides a bunch useful tools for all huntards, wheter they are still levelling, lone-wolf, or HL raider.
|
||||
|
||||
## Twow Data
|
||||
|
||||
Metahunt ships with larges up-to-date datastores for all Turtle WOW data a hunter needs :
|
||||
MetaHunt ships with large up-to-date datastores for all Turtle WOW data a hunter needs :
|
||||
|
||||
- All beasts, their location, and the abilities they can learn you
|
||||
- All Pet families, their abilities and their diet
|
||||
@@ -37,7 +37,7 @@ Old zHunterMod addon on steroids. Fully compatible with Twow, and enhanced with
|
||||
- zPet : Intelligent collapsible pet Bar regrouping all pet spells and providing an intelligent button that always show you the right spell to use depending on the situation
|
||||
- zTrack: All your trackings in one collapsible bar
|
||||
- zAspect: All your trackings in one collapsible bar
|
||||
- zRanged : All the rnaged weampons currently in your bags to swap them fast
|
||||
- zRanged : All the ranged weampons currently in your bags to swap them fast
|
||||
- But also zMounts, zToys and zCompanions.
|
||||
|
||||
## Feed-O-Matic
|
||||
@@ -48,16 +48,31 @@ Now compatible with Turtle, feed your pet with one key bind, it will always pick
|
||||
|
||||
The good old Chronometer addon, purged of non-necessary things and reconfigured for a pure hunter use.
|
||||
|
||||
## Autobuy
|
||||
## ICU (I see you)
|
||||
|
||||
Old addon used to display Targets' enhanced information when you click on your minimap tracking things. MetaHunt offers many more customization options for it.
|
||||
|
||||
|
||||
## Auto-Buy
|
||||
|
||||
Define your own simple rules for auto buy ammo and pet food when you open a vendor.
|
||||
|
||||
## The book of Hunters
|
||||
## Auto-Quest
|
||||
|
||||
The book of Hunters is the main GUI of Metahunt, it allows to display the data constantly collected about you and your pet, and browse the addon's data to find anything a Hunter needs.
|
||||
Just spam SHIFT-click on the NPC to validate quests Scorpok and Thorium arrows. Additionally you can have an enhanced tooltip that display your actual Scorpok-related items when you mouseover the mobs involved.
|
||||
|
||||
- Browse the Metahunt datastores of NPCs (Beast, vendors, masters) and open the map to locate them like in pfQuest
|
||||
|
||||
## The Great Book of Huntards
|
||||
|
||||
The Book is the main GUI of MetaHunt, it allows to display the data constantly collected about you and your pet, and browse the addon's data to find anything a Hunter needs.
|
||||
|
||||
- Browse the MetaHunt datastores of NPCs (Beast, vendors, masters) and open the map to locate them like in pfQuest
|
||||
- Track all info about the pet abilities that you know and don't know yet
|
||||
- Track all info about your stabled pets
|
||||
- Keep an history of all your pets after you abandon them or if they run away.
|
||||
|
||||
|
||||
## What it will never do.
|
||||
|
||||
The goal of MetaHunt is to offer hunter's features that are not covered by existing Twow addons, and in others https://github.com/SabineWren/Quiver .
|
||||
There's no point to reinvent the wheel, except is the wheel is broken. Nothing will work better than Quiver for auto-shot, castbar and tranqshot mgt. MetaHunt is build to work alongside of Quiver and is complementary to it, and it will remain like this unless Quiver turns to be not upgraded anymore.
|
||||
|
||||
+3
-3
@@ -98,7 +98,7 @@ local function AntiDaze_CancelRelevantAspect(isSelfDazed)
|
||||
|
||||
AntiDazeTooltip:SetOwner(UIParent, "ANCHOR_NONE")
|
||||
AntiDazeTooltip:SetPlayerBuff(i, "HELPFUL")
|
||||
local text = AntiDazeTooltipTextLeft1 and AntiDazeTooltipTextLeft1:GetText()
|
||||
local text = MTH_AntiDazeProbeTextLeft1 and MTH_AntiDazeProbeTextLeft1:GetText()
|
||||
if text == packName or (isSelfDazed and text == cheetahName) then
|
||||
CancelPlayerBuff(i)
|
||||
return 1
|
||||
@@ -112,8 +112,8 @@ local function AntiDaze_HandleSlash()
|
||||
AntiDaze_SetEnabled(not AntiDaze_IsEnabled())
|
||||
end
|
||||
|
||||
AntiDazeTooltip = CreateFrame("GameTooltip", "AntiDazeTooltip", nil, "GameTooltipTemplate")
|
||||
AntiDazeFrame = CreateFrame("Frame", "AntiDazeFrame")
|
||||
AntiDazeTooltip = CreateFrame("GameTooltip", "MTH_AntiDazeProbe", nil, "GameTooltipTemplate")
|
||||
AntiDazeFrame = CreateFrame("Frame", "MTH_AntiDazeEvent")
|
||||
if AntiDazeFrame then
|
||||
AntiDazeFrame:RegisterEvent("VARIABLES_LOADED")
|
||||
AntiDazeFrame:SetScript("OnEvent", function()
|
||||
|
||||
+153
-1
@@ -6,6 +6,29 @@ local function AutoStrip_Print(msg)
|
||||
end
|
||||
end
|
||||
|
||||
local AutoStrip_TraceEnabled = false
|
||||
|
||||
local function AutoStrip_Trace(msg)
|
||||
if not AutoStrip_TraceEnabled then
|
||||
return
|
||||
end
|
||||
AutoStrip_Print("[ASTRACE] " .. tostring(msg))
|
||||
end
|
||||
|
||||
function AutoStrip_CommandTrace(mode)
|
||||
local action = string.lower(tostring(mode or "status"))
|
||||
if action == "on" or action == "1" or action == "true" then
|
||||
AutoStrip_TraceEnabled = true
|
||||
AutoStrip_Trace("trace enabled")
|
||||
return
|
||||
elseif action == "off" or action == "0" or action == "false" then
|
||||
AutoStrip_Trace("trace disabled")
|
||||
AutoStrip_TraceEnabled = false
|
||||
return
|
||||
end
|
||||
AutoStrip_Print("[ASTRACE] status=" .. tostring(AutoStrip_TraceEnabled and true or false))
|
||||
end
|
||||
|
||||
function AutoStrip_GetSaved()
|
||||
if type(MTH_CharSavedVariables) ~= "table" then
|
||||
MTH_CharSavedVariables = {}
|
||||
@@ -20,6 +43,90 @@ local AUTO_STRIP_ORDER = {16, 17, 18, 5, 7, 1, 3, 10, 8, 6, 9}
|
||||
AutoStrip_On = nil
|
||||
AutoStrip_WasInCombat = nil
|
||||
AutoStrip_Frame = nil
|
||||
local AutoStrip_RestoreFrame = nil
|
||||
|
||||
local function AutoStrip_DescribePoint(frame)
|
||||
if not (frame and frame.GetPoint) then
|
||||
return "<no-frame>"
|
||||
end
|
||||
local point, relTo, relPoint, x, y = frame:GetPoint()
|
||||
local relName = "nil"
|
||||
if type(relTo) == "table" and relTo.GetName then
|
||||
relName = tostring(relTo:GetName() or "<anon>")
|
||||
elseif relTo then
|
||||
relName = tostring(relTo)
|
||||
end
|
||||
return tostring(point or "nil")
|
||||
.. "->" .. relName
|
||||
.. ":" .. tostring(relPoint or "nil")
|
||||
.. " @(" .. tostring(x) .. "," .. tostring(y) .. ")"
|
||||
end
|
||||
|
||||
function AutoStrip_SaveDisplayPosition(reason)
|
||||
if not (AutoStripDisplay and AutoStripDisplay.GetPoint) then
|
||||
return
|
||||
end
|
||||
local saved = AutoStrip_GetSaved()
|
||||
local point, _, relPoint, x, y = AutoStripDisplay:GetPoint()
|
||||
x = tonumber(x)
|
||||
y = tonumber(y)
|
||||
if not (point and relPoint and x and y) then
|
||||
return
|
||||
end
|
||||
saved["point"] = tostring(point)
|
||||
saved["relativePoint"] = tostring(relPoint)
|
||||
saved["x"] = math.floor(x + 0.5)
|
||||
saved["y"] = math.floor(y + 0.5)
|
||||
AutoStrip_Trace("persist-display-position reason=" .. tostring(reason or "")
|
||||
.. " point=" .. tostring(saved["point"])
|
||||
.. " rel=" .. tostring(saved["relativePoint"])
|
||||
.. " x=" .. tostring(saved["x"])
|
||||
.. " y=" .. tostring(saved["y"]))
|
||||
end
|
||||
|
||||
local function AutoStrip_RestoreDisplayPosition(reason)
|
||||
if not (AutoStripDisplay and AutoStripDisplay.ClearAllPoints and AutoStripDisplay.SetPoint) then
|
||||
return false
|
||||
end
|
||||
local saved = AutoStrip_GetSaved()
|
||||
local point = tostring(saved["point"] or "")
|
||||
local relPoint = tostring(saved["relativePoint"] or "")
|
||||
local x = tonumber(saved["x"])
|
||||
local y = tonumber(saved["y"])
|
||||
if point == "" or not x or not y then
|
||||
AutoStrip_Trace("restore-display-position skipped reason=" .. tostring(reason or "")
|
||||
.. " savedPoint=" .. tostring(saved["point"])
|
||||
.. " savedX=" .. tostring(saved["x"])
|
||||
.. " savedY=" .. tostring(saved["y"]))
|
||||
return false
|
||||
end
|
||||
if relPoint == "" then
|
||||
relPoint = point
|
||||
end
|
||||
AutoStripDisplay:ClearAllPoints()
|
||||
AutoStripDisplay:SetPoint(point, UIParent, relPoint, x, y)
|
||||
AutoStrip_Trace("restore-display-position reason=" .. tostring(reason or "")
|
||||
.. " frame=" .. AutoStrip_DescribePoint(AutoStripDisplay))
|
||||
return true
|
||||
end
|
||||
|
||||
local function AutoStrip_QueueDeferredRestore(reason)
|
||||
if not AutoStrip_RestoreFrame then
|
||||
AutoStrip_RestoreFrame = CreateFrame("Frame", "MTH_AutoStripRestore")
|
||||
if not AutoStrip_RestoreFrame then
|
||||
return
|
||||
end
|
||||
end
|
||||
AutoStrip_RestoreFrame._elapsed = 0
|
||||
AutoStrip_RestoreFrame:SetScript("OnUpdate", function()
|
||||
this._elapsed = (this._elapsed or 0) + (arg1 or 0)
|
||||
if this._elapsed < 0.2 then
|
||||
return
|
||||
end
|
||||
this:SetScript("OnUpdate", nil)
|
||||
AutoStrip_RestoreDisplayPosition("deferred:" .. tostring(reason or ""))
|
||||
end)
|
||||
end
|
||||
|
||||
function AutoStrip_SetDisplayIcon()
|
||||
local icon = getglobal("AutoStripDisplayIcon") or getglobal("AutoStripDisplayIconTexture")
|
||||
@@ -35,6 +142,11 @@ end
|
||||
|
||||
function AutoStrip_SetAutoStripToggle(enabled, silent)
|
||||
local saved = AutoStrip_GetSaved()
|
||||
AutoStrip_Trace("SetAutoStripToggle enabled=" .. tostring(enabled and true or false)
|
||||
.. " silent=" .. tostring(silent and true or false)
|
||||
.. " savedBefore=" .. tostring(saved["autostrip"] and 1 or 0)
|
||||
.. " runtimeBefore=" .. tostring(AutoStrip_On and 1 or 0)
|
||||
.. " castShownBefore=" .. tostring((AutoStripDisplayAutoCast and AutoStripDisplayAutoCast:IsVisible()) and 1 or 0))
|
||||
if enabled then
|
||||
saved["autostrip"] = 1
|
||||
AutoStrip_On = 1
|
||||
@@ -54,10 +166,17 @@ function AutoStrip_SetAutoStripToggle(enabled, silent)
|
||||
AutoStrip_Print("Auto-Strip disabled.")
|
||||
end
|
||||
end
|
||||
AutoStrip_Trace("SetAutoStripToggle savedAfter=" .. tostring(saved["autostrip"] and 1 or 0)
|
||||
.. " runtimeAfter=" .. tostring(AutoStrip_On and 1 or 0)
|
||||
.. " castShownAfter=" .. tostring((AutoStripDisplayAutoCast and AutoStripDisplayAutoCast:IsVisible()) and 1 or 0))
|
||||
end
|
||||
|
||||
function AutoStrip_SetDisplayToggle(enabled, silent)
|
||||
local saved = AutoStrip_GetSaved()
|
||||
AutoStrip_Trace("SetDisplayToggle enabled=" .. tostring(enabled and true or false)
|
||||
.. " silent=" .. tostring(silent and true or false)
|
||||
.. " savedDisplayBefore=" .. tostring(saved["display"] and 1 or 0)
|
||||
.. " frameShownBefore=" .. tostring((AutoStripDisplay and AutoStripDisplay:IsVisible()) and 1 or 0))
|
||||
if enabled then
|
||||
saved["display"] = 1
|
||||
if AutoStripDisplay then
|
||||
@@ -79,9 +198,15 @@ function AutoStrip_SetDisplayToggle(enabled, silent)
|
||||
AutoStrip_Print("AutoStrip button is now hidden.")
|
||||
end
|
||||
end
|
||||
AutoStrip_Trace("SetDisplayToggle savedDisplayAfter=" .. tostring(saved["display"] and 1 or 0)
|
||||
.. " frameShownAfter=" .. tostring((AutoStripDisplay and AutoStripDisplay:IsVisible()) and 1 or 0)
|
||||
.. " castShownAfter=" .. tostring((AutoStripDisplayAutoCast and AutoStripDisplayAutoCast:IsVisible()) and 1 or 0))
|
||||
end
|
||||
|
||||
function AutoStrip_UnequipAll(weaponsOnly)
|
||||
AutoStrip_Trace("UnequipAll called weaponsOnly=" .. tostring(weaponsOnly and 1 or 0)
|
||||
.. " runtimeBefore=" .. tostring(AutoStrip_On and 1 or 0)
|
||||
.. " wasInCombat=" .. tostring(AutoStrip_WasInCombat and 1 or 0))
|
||||
AutoStrip_On = nil
|
||||
if AutoStripDisplayAutoCast then
|
||||
AutoStripDisplayAutoCast:Hide()
|
||||
@@ -102,6 +227,7 @@ function AutoStrip_UnequipAll(weaponsOnly)
|
||||
|
||||
if not hasEmptySlot then
|
||||
AutoStrip_Print("You need at least one empty bag slot to auto-strip.")
|
||||
AutoStrip_Trace("UnequipAll aborted no-empty-slot")
|
||||
return
|
||||
end
|
||||
|
||||
@@ -121,19 +247,36 @@ function AutoStrip_UnequipAll(weaponsOnly)
|
||||
end
|
||||
end
|
||||
end
|
||||
AutoStrip_Trace("UnequipAll completed runtimeAfter=" .. tostring(AutoStrip_On and 1 or 0)
|
||||
.. " castShownAfter=" .. tostring((AutoStripDisplayAutoCast and AutoStripDisplayAutoCast:IsVisible()) and 1 or 0))
|
||||
end
|
||||
|
||||
local function AutoStrip_OnEvent()
|
||||
AutoStrip_Trace("OnEvent evt=" .. tostring(event or "")
|
||||
.. " runtime=" .. tostring(AutoStrip_On and 1 or 0)
|
||||
.. " wasInCombat=" .. tostring(AutoStrip_WasInCombat and 1 or 0)
|
||||
.. " playerInCombat=" .. tostring((type(UnitAffectingCombat) == "function" and UnitAffectingCombat("player")) and 1 or 0))
|
||||
if event == "VARIABLES_LOADED" then
|
||||
local saved = AutoStrip_GetSaved()
|
||||
AutoStrip_Trace("VARIABLES_LOADED saved.autostrip=" .. tostring(saved["autostrip"] and 1 or 0)
|
||||
.. " saved.display=" .. tostring(saved["display"] and 1 or 0))
|
||||
AutoStrip_WasInCombat = UnitAffectingCombat("player") and 1 or nil
|
||||
AutoStrip_RestoreDisplayPosition("VARIABLES_LOADED")
|
||||
AutoStrip_SetDisplayToggle(saved["display"] and true or false, 1)
|
||||
AutoStrip_SetAutoStripToggle(saved["autostrip"] and true or false, 1)
|
||||
AutoStrip_QueueDeferredRestore("VARIABLES_LOADED")
|
||||
return
|
||||
end
|
||||
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
AutoStrip_WasInCombat = UnitAffectingCombat("player") and 1 or nil
|
||||
AutoStrip_RestoreDisplayPosition("PLAYER_ENTERING_WORLD")
|
||||
AutoStrip_QueueDeferredRestore("PLAYER_ENTERING_WORLD")
|
||||
return
|
||||
end
|
||||
|
||||
if event == "PLAYER_LOGOUT" then
|
||||
AutoStrip_SaveDisplayPosition("PLAYER_LOGOUT")
|
||||
return
|
||||
end
|
||||
|
||||
@@ -144,6 +287,7 @@ local function AutoStrip_OnEvent()
|
||||
|
||||
if event == "PLAYER_REGEN_ENABLED" then
|
||||
if AutoStrip_On and AutoStrip_WasInCombat then
|
||||
AutoStrip_Trace("PLAYER_REGEN_ENABLED triggering auto strip")
|
||||
AutoStrip_UnequipAll()
|
||||
end
|
||||
AutoStrip_WasInCombat = nil
|
||||
@@ -152,6 +296,8 @@ end
|
||||
|
||||
local function AutoStrip_HandleSlash(msg)
|
||||
local saved = AutoStrip_GetSaved()
|
||||
AutoStrip_Trace("Slash msg='" .. tostring(msg or "") .. "' saved.autostrip=" .. tostring(saved["autostrip"] and 1 or 0)
|
||||
.. " runtime=" .. tostring(AutoStrip_On and 1 or 0))
|
||||
if msg == "display" then
|
||||
AutoStrip_SetDisplayToggle(not (saved["display"] and true or false))
|
||||
elseif msg == "toggle" then
|
||||
@@ -170,12 +316,13 @@ local function AutoStrip_HandleSlash(msg)
|
||||
end
|
||||
end
|
||||
|
||||
AutoStrip_Frame = CreateFrame("Frame", "AutoStripFrame")
|
||||
AutoStrip_Frame = CreateFrame("Frame", "MTH_AutoStripEvent")
|
||||
if AutoStrip_Frame then
|
||||
AutoStrip_Frame:RegisterEvent("VARIABLES_LOADED")
|
||||
AutoStrip_Frame:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
AutoStrip_Frame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
AutoStrip_Frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
AutoStrip_Frame:RegisterEvent("PLAYER_LOGOUT")
|
||||
AutoStrip_Frame:SetScript("OnEvent", AutoStrip_OnEvent)
|
||||
end
|
||||
|
||||
@@ -187,3 +334,8 @@ SLASH_AUTOSTRIP1 = "/autostrip"
|
||||
SlashCmdList["AUTOSTRIP"] = AutoStrip_HandleSlash
|
||||
SLASH_ZSTRIP1 = "/zstrip"
|
||||
SlashCmdList["ZSTRIP"] = AutoStrip_HandleSlash
|
||||
SLASH_AUTOSTRIPTRACE1 = "/autostriptrace"
|
||||
SLASH_AUTOSTRIPTRACE2 = "/astrace"
|
||||
SlashCmdList["AUTOSTRIPTRACE"] = function(msg)
|
||||
AutoStrip_CommandTrace(msg)
|
||||
end
|
||||
|
||||
@@ -68,6 +68,9 @@
|
||||
if ( this.isMoving ) then
|
||||
this:StopMovingOrSizing()
|
||||
this.isMoving = false
|
||||
if AutoStrip_SaveDisplayPosition then
|
||||
AutoStrip_SaveDisplayPosition("mouse-up-stop")
|
||||
end
|
||||
end
|
||||
</OnMouseUp>
|
||||
<OnDragStart>
|
||||
@@ -79,6 +82,9 @@
|
||||
<OnDragStop>
|
||||
this:StopMovingOrSizing()
|
||||
this.isMoving = false
|
||||
if AutoStrip_SaveDisplayPosition then
|
||||
AutoStrip_SaveDisplayPosition("drag-stop")
|
||||
end
|
||||
</OnDragStop>
|
||||
</Scripts>
|
||||
<NormalTexture name="$parentNormalTexture" file="Interface\Buttons\UI-Quickslot2">
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
MTH_CONST = MTH_CONST or {}
|
||||
MTH_CONST.version = MTH_CONST.version or "1.0.4"
|
||||
MTH_CONST.version = MTH_CONST.version or "1.2.0"
|
||||
|
||||
MTH_CONST.WEAPON_TYPES = {
|
||||
BOWS = "Bows",
|
||||
|
||||
+144
-13
@@ -460,6 +460,7 @@ local function MTH_FEED_CoreTrackerOnEvent()
|
||||
end
|
||||
elseif evt == "BAG_UPDATE" then
|
||||
MTH_FEED_IndexBagFoods()
|
||||
MTH_FEED_InvalidateDietMapCache()
|
||||
elseif evt == "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS" then
|
||||
if MTH_FEED_ActiveCoreAttemptId and MTH_FEED_HasPetFeedBuff() then
|
||||
MTH_FEED_Trace("Core tracker buff event confirms acceptance")
|
||||
@@ -468,7 +469,32 @@ local function MTH_FEED_CoreTrackerOnEvent()
|
||||
end
|
||||
end
|
||||
|
||||
local MTH_FEED_CoreTrackerUpdateElapsed = 0
|
||||
local MTH_FEED_LastStaleCleanupAt = 0
|
||||
|
||||
local function MTH_FEED_CoreTrackerOnUpdate()
|
||||
MTH_FEED_CoreTrackerUpdateElapsed = MTH_FEED_CoreTrackerUpdateElapsed + (arg1 or 0)
|
||||
if MTH_FEED_CoreTrackerUpdateElapsed < 0.10 then
|
||||
return
|
||||
end
|
||||
MTH_FEED_CoreTrackerUpdateElapsed = 0
|
||||
|
||||
-- Periodic stale attempt cleanup (every ~30 seconds)
|
||||
local now = GetTime() or 0
|
||||
if (now - MTH_FEED_LastStaleCleanupAt) >= 30 then
|
||||
MTH_FEED_LastStaleCleanupAt = now
|
||||
if MTH_FEED_Runtime and type(MTH_FEED_Runtime.attempts) == "table" then
|
||||
for id, row in pairs(MTH_FEED_Runtime.attempts) do
|
||||
if type(row) == "table" then
|
||||
local age = now - (tonumber(row.startedAt) or now)
|
||||
if age > 10 then
|
||||
MTH_FEED_Runtime.attempts[id] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local attemptId = MTH_FEED_ActiveCoreAttemptId
|
||||
if attemptId == nil then
|
||||
return
|
||||
@@ -499,7 +525,7 @@ local function MTH_FEED_EnsureTrackerFrame()
|
||||
if MTH_FEED_TrackerFrame then
|
||||
return MTH_FEED_TrackerFrame
|
||||
end
|
||||
local frame = CreateFrame("Frame", "MTH_FeedTrackingFrame")
|
||||
local frame = CreateFrame("Frame", "MTH_FeedTracking")
|
||||
if not frame then
|
||||
return nil
|
||||
end
|
||||
@@ -526,6 +552,7 @@ local function MTH_FEED_CoreDropItemOnUnitHook(unit)
|
||||
end
|
||||
|
||||
if target == "pet" and CursorHasItem and CursorHasItem() then
|
||||
MTH_FEED_EnsureTrackerFrame()
|
||||
local itemId, itemName, itemLink, itemIcon = MTH_FEED_GetCursorItemSnapshot()
|
||||
local pet = MTH_FEED_GetCurrentPetContext()
|
||||
if not itemId then
|
||||
@@ -608,7 +635,6 @@ function MTH_FEED_DebugStatus()
|
||||
end
|
||||
|
||||
function MTH_FEED_ReinstallCoreTracking()
|
||||
MTH_FEED_EnsureTrackerFrame()
|
||||
local ok = MTH_FEED_InstallCoreHooks()
|
||||
return ok and true or false
|
||||
end
|
||||
@@ -617,7 +643,7 @@ local function MTH_FEED_EnsureBootstrapFrame()
|
||||
if MTH_FEED_BootstrapFrame ~= nil then
|
||||
return MTH_FEED_BootstrapFrame
|
||||
end
|
||||
local frame = CreateFrame("Frame", "MTH_FeedTrackingBootstrapFrame")
|
||||
local frame = CreateFrame("Frame", "MTH_FeedTrackingBoot")
|
||||
if not frame then
|
||||
return nil
|
||||
end
|
||||
@@ -626,6 +652,8 @@ local function MTH_FEED_EnsureBootstrapFrame()
|
||||
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
frame:SetScript("OnEvent", function()
|
||||
MTH_FEED_ReinstallCoreTracking()
|
||||
this:UnregisterAllEvents()
|
||||
this:SetScript("OnEvent", nil)
|
||||
end)
|
||||
MTH_FEED_BootstrapFrame = frame
|
||||
return frame
|
||||
@@ -822,7 +850,16 @@ local function MTH_FEED_NormalizeReason(reason, rawMessage)
|
||||
return "unknown"
|
||||
end
|
||||
|
||||
local MTH_FEED_DietMapCache = nil
|
||||
|
||||
local function MTH_FEED_InvalidateDietMapCache()
|
||||
MTH_FEED_DietMapCache = nil
|
||||
end
|
||||
|
||||
local function MTH_FEED_GetDietByItemIdMap()
|
||||
if MTH_FEED_DietMapCache then
|
||||
return MTH_FEED_DietMapCache
|
||||
end
|
||||
local map = {}
|
||||
if type(FOM_Foods) ~= "table" then
|
||||
return map
|
||||
@@ -837,6 +874,7 @@ local function MTH_FEED_GetDietByItemIdMap()
|
||||
end
|
||||
end
|
||||
end
|
||||
MTH_FEED_DietMapCache = map
|
||||
return map
|
||||
end
|
||||
|
||||
@@ -940,9 +978,6 @@ function MTH_FEED_BeginAttempt(payload)
|
||||
itemIcon = infoTexture
|
||||
end
|
||||
end
|
||||
if (not itemIcon or itemIcon == "") then
|
||||
itemIcon = MTH_FEED_FindItemIconInBags(itemId, payload and payload.itemName)
|
||||
end
|
||||
|
||||
MTH_FEED_Runtime.attempts[attemptId] = {
|
||||
id = attemptId,
|
||||
@@ -1113,7 +1148,7 @@ function MTH_FEED_IsFoodCompatible(petLevel, foodLevel)
|
||||
return true
|
||||
end
|
||||
|
||||
function MTH_FEED_IsExceptionReject(itemId)
|
||||
function MTH_FEED_IsExceptionReject(itemId, petLevel)
|
||||
local key = tonumber(itemId)
|
||||
if not key then
|
||||
return false
|
||||
@@ -1123,6 +1158,11 @@ function MTH_FEED_IsExceptionReject(itemId)
|
||||
if type(row) ~= "table" then
|
||||
return false
|
||||
end
|
||||
local numericPet = tonumber(petLevel)
|
||||
local blockedAtOrAbove = tonumber(row.blockAtOrAbovePetLevel)
|
||||
if blockedAtOrAbove and numericPet and numericPet >= blockedAtOrAbove then
|
||||
return true
|
||||
end
|
||||
if row.anomalyReject ~= true then
|
||||
return false
|
||||
end
|
||||
@@ -1137,6 +1177,17 @@ function MTH_FEED_IsExceptionReject(itemId)
|
||||
if not reasons then
|
||||
return false
|
||||
end
|
||||
local lowLevelCount = tonumber(reasons.lowLevel) or 0
|
||||
if lowLevelCount >= 1 then
|
||||
local maxPetLevel = tonumber(row.maxPetLevel)
|
||||
if numericPet and maxPetLevel then
|
||||
if numericPet > maxPetLevel then
|
||||
return true
|
||||
end
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
local wrongFoodCount = tonumber(reasons.wrongFood) or 0
|
||||
if wrongFoodCount < 2 then
|
||||
return false
|
||||
@@ -1144,6 +1195,49 @@ function MTH_FEED_IsExceptionReject(itemId)
|
||||
return true
|
||||
end
|
||||
|
||||
function MTH_FEED_BlockItemForPetLevel(itemId, petLevel, reason)
|
||||
local key = tonumber(itemId)
|
||||
local numericPet = tonumber(petLevel)
|
||||
if not key or not numericPet then
|
||||
return false
|
||||
end
|
||||
if numericPet < 1 then
|
||||
numericPet = 1
|
||||
end
|
||||
local store = MTH_FEED_EnsureStore()
|
||||
if type(store.exceptions.byItemId[key]) ~= "table" then
|
||||
store.exceptions.byItemId[key] = {
|
||||
anomalyReject = true,
|
||||
reasons = { noBuff = 0, wrongFood = 0, lowLevel = 0, unknown = 0 },
|
||||
lastObservedAt = 0,
|
||||
}
|
||||
end
|
||||
local row = store.exceptions.byItemId[key]
|
||||
if type(row.reasons) ~= "table" then
|
||||
row.reasons = { noBuff = 0, wrongFood = 0, lowLevel = 0, unknown = 0 }
|
||||
end
|
||||
row.anomalyReject = true
|
||||
row.lastObservedAt = MTH_FEED_Now()
|
||||
if tonumber(row.blockAtOrAbovePetLevel) == nil or numericPet < tonumber(row.blockAtOrAbovePetLevel) then
|
||||
row.blockAtOrAbovePetLevel = numericPet
|
||||
end
|
||||
local normalizedReason = MTH_FEED_NormalizeReason(reason, nil)
|
||||
if normalizedReason == "no-buff" then
|
||||
row.reasons.noBuff = (tonumber(row.reasons.noBuff) or 0) + 1
|
||||
elseif normalizedReason == "low-level" then
|
||||
row.reasons.lowLevel = (tonumber(row.reasons.lowLevel) or 0) + 1
|
||||
elseif normalizedReason == "wrong-food" then
|
||||
row.reasons.wrongFood = (tonumber(row.reasons.wrongFood) or 0) + 1
|
||||
else
|
||||
row.reasons.unknown = (tonumber(row.reasons.unknown) or 0) + 1
|
||||
end
|
||||
MTH_FEED_TouchStore(store)
|
||||
MTH_FEED_Trace("BlockItemForPetLevel itemId=" .. tostring(key)
|
||||
.. " blockAtOrAbove=" .. tostring(row.blockAtOrAbovePetLevel)
|
||||
.. " reason=" .. tostring(normalizedReason))
|
||||
return true
|
||||
end
|
||||
|
||||
function MTH_FEED_GetPetFeedStats(petId)
|
||||
local key = tostring(petId or "")
|
||||
if key == "" then
|
||||
@@ -1153,7 +1247,7 @@ function MTH_FEED_GetPetFeedStats(petId)
|
||||
return store.byPetId[key]
|
||||
end
|
||||
|
||||
local function MTH_FEED_UpsertException(store, itemId, reason)
|
||||
local function MTH_FEED_UpsertException(store, itemId, reason, petLevel)
|
||||
if not itemId then
|
||||
return
|
||||
end
|
||||
@@ -1175,6 +1269,16 @@ local function MTH_FEED_UpsertException(store, itemId, reason)
|
||||
row.reasons.wrongFood = (tonumber(row.reasons.wrongFood) or 0) + 1
|
||||
elseif reason == "low-level" then
|
||||
row.reasons.lowLevel = (tonumber(row.reasons.lowLevel) or 0) + 1
|
||||
local numericPetLevel = tonumber(petLevel)
|
||||
if numericPetLevel and numericPetLevel > 1 then
|
||||
local derivedMaxPetLevel = numericPetLevel - 1
|
||||
if derivedMaxPetLevel < 1 then
|
||||
derivedMaxPetLevel = 1
|
||||
end
|
||||
if tonumber(row.maxPetLevel) == nil or derivedMaxPetLevel < tonumber(row.maxPetLevel) then
|
||||
row.maxPetLevel = derivedMaxPetLevel
|
||||
end
|
||||
end
|
||||
else
|
||||
row.reasons.unknown = (tonumber(row.reasons.unknown) or 0) + 1
|
||||
end
|
||||
@@ -1182,6 +1286,36 @@ local function MTH_FEED_UpsertException(store, itemId, reason)
|
||||
row.lastObservedAt = MTH_FEED_Now()
|
||||
end
|
||||
|
||||
local function MTH_FEED_ClearStaleExceptionOnAccept(store, itemId)
|
||||
if not itemId or type(store) ~= "table" or type(store.exceptions) ~= "table" or type(store.exceptions.byItemId) ~= "table" then
|
||||
return
|
||||
end
|
||||
local key = tonumber(itemId) or itemId
|
||||
local row = store.exceptions.byItemId[key]
|
||||
if type(row) ~= "table" then
|
||||
return
|
||||
end
|
||||
if type(row.reasons) ~= "table" then
|
||||
store.exceptions.byItemId[key] = nil
|
||||
return
|
||||
end
|
||||
row.reasons.noBuff = 0
|
||||
row.lastObservedAt = MTH_FEED_Now()
|
||||
|
||||
local noBuff = tonumber(row.reasons.noBuff) or 0
|
||||
local lowLevel = tonumber(row.reasons.lowLevel) or 0
|
||||
local wrongFood = tonumber(row.reasons.wrongFood) or 0
|
||||
local unknown = tonumber(row.reasons.unknown) or 0
|
||||
if noBuff <= 0
|
||||
and lowLevel <= 0
|
||||
and wrongFood <= 0
|
||||
and unknown <= 0
|
||||
and tonumber(row.blockAtOrAbovePetLevel) == nil
|
||||
and tonumber(row.maxPetLevel) == nil then
|
||||
store.exceptions.byItemId[key] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function MTH_FEED_FinalizeAttempt(attemptId, payload)
|
||||
local row = MTH_FEED_Runtime.attempts[attemptId]
|
||||
if type(row) ~= "table" then
|
||||
@@ -1241,6 +1375,7 @@ function MTH_FEED_FinalizeAttempt(attemptId, payload)
|
||||
if itemRow then
|
||||
itemRow.accepted = itemRow.accepted + 1
|
||||
end
|
||||
MTH_FEED_ClearStaleExceptionOnAccept(store, row.itemId)
|
||||
local petKey = tostring((petRow and petRow.petId) or row.petId or "")
|
||||
if petKey ~= "" then
|
||||
MTH_FEED_Runtime.sessionFeedsByPetId[petKey] = (tonumber(MTH_FEED_Runtime.sessionFeedsByPetId[petKey]) or 0) + 1
|
||||
@@ -1257,7 +1392,7 @@ function MTH_FEED_FinalizeAttempt(attemptId, payload)
|
||||
if itemRow then
|
||||
itemRow.rejected = itemRow.rejected + 1
|
||||
end
|
||||
MTH_FEED_UpsertException(store, row.itemId, reason)
|
||||
MTH_FEED_UpsertException(store, row.itemId, reason, row.petLevel)
|
||||
end
|
||||
|
||||
if itemRow then
|
||||
@@ -1280,9 +1415,6 @@ function MTH_FEED_FinalizeAttempt(attemptId, payload)
|
||||
persistedIcon = directTexture
|
||||
end
|
||||
end
|
||||
if (not persistedIcon or persistedIcon == "") then
|
||||
persistedIcon = MTH_FEED_FindItemIconInBags(row.itemId, row.itemName)
|
||||
end
|
||||
if persistedIcon and persistedIcon ~= "" then
|
||||
itemRow.itemIcon = persistedIcon
|
||||
end
|
||||
@@ -1542,6 +1674,5 @@ function MTH_FEED_DebugDumpCurrentPet(limit)
|
||||
return true
|
||||
end
|
||||
|
||||
MTH_FEED_EnsureTrackerFrame()
|
||||
MTH_FEED_InstallCoreHooks()
|
||||
MTH_FEED_EnsureBootstrapFrame()
|
||||
|
||||
+143
-80
@@ -1,5 +1,5 @@
|
||||
MTH = MTH or {
|
||||
version = "1.0.4",
|
||||
version = "1.2.0",
|
||||
name = "MetaHunt",
|
||||
modules = {},
|
||||
config = {},
|
||||
@@ -16,6 +16,14 @@ local MTH_MESSAGE_DEFAULTS = {
|
||||
spellbookScan = false,
|
||||
petRanAway = true,
|
||||
mapMarkers = true,
|
||||
stableScan = true,
|
||||
}
|
||||
|
||||
local MTH_MODULE_DEFAULT_STATES = {
|
||||
autoquest = false,
|
||||
autobuy = false,
|
||||
feedomatic = false,
|
||||
icu = false,
|
||||
}
|
||||
|
||||
local function MTH_ClassGateTrace(_step, _detail)
|
||||
@@ -36,7 +44,7 @@ local function MTH_ClassGateEnsureAnnounceFrame(self)
|
||||
if not self or self._classGateAnnounceFrame then
|
||||
return
|
||||
end
|
||||
local frame = CreateFrame("Frame", "MTH_ClassGateAnnounceFrame")
|
||||
local frame = CreateFrame("Frame", "MTH_ClassGateAnnounce")
|
||||
if not frame then
|
||||
return
|
||||
end
|
||||
@@ -47,12 +55,12 @@ local function MTH_ClassGateEnsureAnnounceFrame(self)
|
||||
end
|
||||
end)
|
||||
frame._mthElapsed = 0
|
||||
frame:SetScript("OnUpdate", function(self, elapsed)
|
||||
self._mthElapsed = (self._mthElapsed or 0) + (elapsed or arg1 or 0)
|
||||
if self._mthElapsed < 0.5 then
|
||||
frame:SetScript("OnUpdate", function()
|
||||
this._mthElapsed = (this._mthElapsed or 0) + (arg1 or 0)
|
||||
if this._mthElapsed < 0.5 then
|
||||
return
|
||||
end
|
||||
self._mthElapsed = 0
|
||||
this._mthElapsed = 0
|
||||
if MTH and MTH._classGateAnnouncedChat then
|
||||
MTH_ClassGateClearAnnounceFrame(MTH)
|
||||
return
|
||||
@@ -184,21 +192,19 @@ end
|
||||
MTH:ApplyClassGate("startup")
|
||||
|
||||
if not MTH._classGateLifecycleFrame then
|
||||
local classGateFrame = CreateFrame("Frame", "MTH_ClassGateLifecycleFrame")
|
||||
local classGateFrame = CreateFrame("Frame", "MTH_ClassGateLifecycle")
|
||||
if classGateFrame then
|
||||
classGateFrame:RegisterEvent("PLAYER_LOGIN")
|
||||
classGateFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
classGateFrame:SetScript("OnEvent", function(self, eventName)
|
||||
self = self or this
|
||||
eventName = eventName or event
|
||||
if MTH and eventName == "PLAYER_LOGIN" then
|
||||
classGateFrame:SetScript("OnEvent", function()
|
||||
if MTH and event == "PLAYER_LOGIN" then
|
||||
MTH._classGateAnnouncedChat = nil
|
||||
MTH._classGateAnnounced = nil
|
||||
MTH._classGateAnnouncePending = nil
|
||||
end
|
||||
if MTH and MTH.ApplyClassGate and MTH:ApplyClassGate(eventName) and MTH._classGateAnnouncedChat then
|
||||
self:UnregisterAllEvents()
|
||||
self:SetScript("OnEvent", nil)
|
||||
if MTH and MTH.ApplyClassGate and MTH:ApplyClassGate(event) and MTH._classGateAnnouncedChat then
|
||||
this:UnregisterAllEvents()
|
||||
this:SetScript("OnEvent", nil)
|
||||
end
|
||||
end)
|
||||
MTH._classGateLifecycleFrame = classGateFrame
|
||||
@@ -424,9 +430,53 @@ local function MTH_GetPersistedModuleEnabled(name, defaultEnabled)
|
||||
local resolvedName = MTH_NormalizeModuleName(name)
|
||||
local candidates = MTH_ModuleNameCandidates(name)
|
||||
|
||||
if type(MTH_CharSavedVariables) ~= "table" then
|
||||
MTH_CharSavedVariables = {}
|
||||
end
|
||||
if type(MTH_CharSavedVariables.moduleStates) ~= "table" then
|
||||
MTH_CharSavedVariables.moduleStates = {}
|
||||
end
|
||||
if type(MTH_CharSavedVariables.modules) ~= "table" then
|
||||
MTH_CharSavedVariables.modules = {}
|
||||
end
|
||||
if type(MTH_CharSavedVariables.modules[resolvedName]) ~= "table" then
|
||||
MTH_CharSavedVariables.modules[resolvedName] = {}
|
||||
end
|
||||
|
||||
if type(MTH_SavedVariables) ~= "table" then
|
||||
MTH_ModuleStateDebug("read " .. tostring(name) .. " no-savedvars fallback-default=" .. tostring(defaultEnabled and true or false))
|
||||
return defaultEnabled and true or false
|
||||
MTH_SavedVariables = {}
|
||||
end
|
||||
if type(MTH_SavedVariables.moduleStates) ~= "table" then
|
||||
MTH_SavedVariables.moduleStates = {}
|
||||
end
|
||||
if type(MTH_SavedVariables.modules) ~= "table" then
|
||||
MTH_SavedVariables.modules = {}
|
||||
end
|
||||
|
||||
local hardDefault = MTH_MODULE_DEFAULT_STATES[resolvedName]
|
||||
if hardDefault ~= nil then
|
||||
local hasCharState = MTH_CharSavedVariables.moduleStates[resolvedName] ~= nil
|
||||
or MTH_CharSavedVariables.modules[resolvedName].enabled ~= nil
|
||||
if not hasCharState then
|
||||
local resolved = hardDefault and true or false
|
||||
MTH_CharSavedVariables.moduleStates[resolvedName] = resolved
|
||||
MTH_CharSavedVariables.modules[resolvedName].enabled = resolved
|
||||
MTH_ModuleStateDebug("read " .. tostring(name) .. " seeded char default=" .. tostring(resolved))
|
||||
return resolved
|
||||
end
|
||||
end
|
||||
|
||||
if type(MTH_CharSavedVariables.moduleStates) == "table"
|
||||
then
|
||||
for i = 1, table.getn(candidates) do
|
||||
local key = candidates[i]
|
||||
if MTH_CharSavedVariables.moduleStates[key] ~= nil then
|
||||
local resolved = MTH_CharSavedVariables.moduleStates[key] and true or false
|
||||
MTH_ModuleStateDebug("read " .. tostring(name) .. " from char.moduleStates." .. tostring(key) .. "=" .. tostring(resolved))
|
||||
MTH_CharSavedVariables.moduleStates[resolvedName] = resolved
|
||||
return resolved
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if type(MTH_SavedVariables.moduleStates) == "table" then
|
||||
@@ -435,25 +485,11 @@ local function MTH_GetPersistedModuleEnabled(name, defaultEnabled)
|
||||
if MTH_SavedVariables.moduleStates[key] ~= nil then
|
||||
local resolved = MTH_SavedVariables.moduleStates[key] and true or false
|
||||
MTH_ModuleStateDebug("read " .. tostring(name) .. " from moduleStates." .. tostring(key) .. "=" .. tostring(resolved))
|
||||
MTH_SavedVariables.moduleStates[resolvedName] = resolved
|
||||
return resolved
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if type(MTH_CharSavedVariables) == "table"
|
||||
and type(MTH_CharSavedVariables.moduleStates) == "table"
|
||||
then
|
||||
for i = 1, table.getn(candidates) do
|
||||
local key = candidates[i]
|
||||
if MTH_CharSavedVariables.moduleStates[key] ~= nil then
|
||||
local resolved = MTH_CharSavedVariables.moduleStates[key] and true or false
|
||||
MTH_ModuleStateDebug("read " .. tostring(name) .. " from char.moduleStates." .. tostring(key) .. "=" .. tostring(resolved))
|
||||
if type(MTH_SavedVariables.moduleStates) ~= "table" then
|
||||
MTH_SavedVariables.moduleStates = {}
|
||||
end
|
||||
MTH_SavedVariables.moduleStates[resolvedName] = resolved
|
||||
MTH_CharSavedVariables.moduleStates[resolvedName] = resolved
|
||||
if type(MTH_CharSavedVariables.modules[resolvedName]) ~= "table" then
|
||||
MTH_CharSavedVariables.modules[resolvedName] = {}
|
||||
end
|
||||
MTH_CharSavedVariables.modules[resolvedName].enabled = resolved
|
||||
return resolved
|
||||
end
|
||||
end
|
||||
@@ -465,9 +501,11 @@ local function MTH_GetPersistedModuleEnabled(name, defaultEnabled)
|
||||
if type(MTH_SavedVariables.modules[key]) == "table" and MTH_SavedVariables.modules[key].enabled ~= nil then
|
||||
local resolved = MTH_SavedVariables.modules[key].enabled and true or false
|
||||
MTH_ModuleStateDebug("read " .. tostring(name) .. " from modules." .. tostring(key) .. ".enabled=" .. tostring(resolved))
|
||||
if type(MTH_SavedVariables.modules[resolvedName]) ~= "table" then
|
||||
MTH_SavedVariables.modules[resolvedName] = MTH_SavedVariables.modules[key]
|
||||
MTH_CharSavedVariables.moduleStates[resolvedName] = resolved
|
||||
if type(MTH_CharSavedVariables.modules[resolvedName]) ~= "table" then
|
||||
MTH_CharSavedVariables.modules[resolvedName] = {}
|
||||
end
|
||||
MTH_CharSavedVariables.modules[resolvedName].enabled = resolved
|
||||
return resolved
|
||||
end
|
||||
end
|
||||
@@ -478,16 +516,11 @@ local function MTH_GetPersistedModuleEnabled(name, defaultEnabled)
|
||||
if type(MTH_SavedVariables[key]) == "table" and MTH_SavedVariables[key].enabled ~= nil then
|
||||
local resolved = MTH_SavedVariables[key].enabled and true or false
|
||||
MTH_ModuleStateDebug("read " .. tostring(name) .. " from legacy-top-level." .. tostring(key) .. ".enabled=" .. tostring(resolved))
|
||||
if type(MTH_SavedVariables.modules) ~= "table" then
|
||||
MTH_SavedVariables.modules = {}
|
||||
MTH_CharSavedVariables.moduleStates[resolvedName] = resolved
|
||||
if type(MTH_CharSavedVariables.modules[resolvedName]) ~= "table" then
|
||||
MTH_CharSavedVariables.modules[resolvedName] = {}
|
||||
end
|
||||
if type(MTH_SavedVariables.modules[resolvedName]) ~= "table" then
|
||||
MTH_SavedVariables.modules[resolvedName] = MTH_SavedVariables[key]
|
||||
end
|
||||
if type(MTH_SavedVariables.moduleStates) ~= "table" then
|
||||
MTH_SavedVariables.moduleStates = {}
|
||||
end
|
||||
MTH_SavedVariables.moduleStates[resolvedName] = resolved
|
||||
MTH_CharSavedVariables.modules[resolvedName].enabled = resolved
|
||||
return resolved
|
||||
end
|
||||
end
|
||||
@@ -506,27 +539,22 @@ local function MTH_SetPersistedModuleEnabled(name, enabled)
|
||||
if type(MTH_SavedVariables) ~= "table" then
|
||||
MTH_SavedVariables = {}
|
||||
end
|
||||
if type(MTH_SavedVariables.moduleStates) ~= "table" then
|
||||
MTH_SavedVariables.moduleStates = {}
|
||||
end
|
||||
if type(MTH_SavedVariables.modules) ~= "table" then
|
||||
MTH_SavedVariables.modules = {}
|
||||
end
|
||||
if type(MTH_SavedVariables.modules[name]) ~= "table" then
|
||||
MTH_SavedVariables.modules[name] = {}
|
||||
end
|
||||
if type(MTH_CharSavedVariables) ~= "table" then
|
||||
MTH_CharSavedVariables = {}
|
||||
end
|
||||
if type(MTH_CharSavedVariables.moduleStates) ~= "table" then
|
||||
MTH_CharSavedVariables.moduleStates = {}
|
||||
end
|
||||
if type(MTH_CharSavedVariables.modules) ~= "table" then
|
||||
MTH_CharSavedVariables.modules = {}
|
||||
end
|
||||
if type(MTH_CharSavedVariables.modules[name]) ~= "table" then
|
||||
MTH_CharSavedVariables.modules[name] = {}
|
||||
end
|
||||
|
||||
enabled = enabled and true or false
|
||||
MTH_SavedVariables.moduleStates[name] = enabled
|
||||
MTH_SavedVariables.modules[name].enabled = enabled
|
||||
MTH_SavedVariables[name] = MTH_SavedVariables.modules[name]
|
||||
MTH_CharSavedVariables.moduleStates[name] = enabled
|
||||
MTH_CharSavedVariables.modules[name].enabled = enabled
|
||||
MTH_ModuleStateDebug("write " .. tostring(name) .. " enabled=" .. tostring(enabled))
|
||||
end
|
||||
|
||||
@@ -535,10 +563,10 @@ function MTH:InitEventRouter()
|
||||
return self._eventRouter.frame
|
||||
end
|
||||
|
||||
local frame = CreateFrame("Frame", "MTH_EventRouterFrame")
|
||||
frame:SetScript("OnEvent", function(self, evt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
local frame = CreateFrame("Frame", "MTH_EventRouter")
|
||||
frame:SetScript("OnEvent", function()
|
||||
if MTH and MTH.DispatchEvent then
|
||||
MTH:DispatchEvent(evt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
MTH:DispatchEvent(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -598,7 +626,7 @@ function MTH:_SetModuleEventSubscriptions(name, enabled)
|
||||
end
|
||||
end
|
||||
|
||||
function MTH:DispatchEvent(evt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||
function MTH:DispatchEvent(evt, ea1, ea2, ea3, ea4, ea5, ea6, ea7, ea8, ea9)
|
||||
for name, module in pairs(self.modules) do
|
||||
if module.enabled and module.onEvent then
|
||||
local allow = true
|
||||
@@ -607,11 +635,10 @@ function MTH:DispatchEvent(evt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
|
||||
end
|
||||
if allow then
|
||||
local ok, err = pcall(function()
|
||||
module:onEvent(evt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||
module:onEvent(evt, ea1, ea2, ea3, ea4, ea5, ea6, ea7, ea8, ea9)
|
||||
end)
|
||||
if not ok then
|
||||
self:Print("Module '" .. name .. "' event error on '" .. tostring(evt) .. "': " .. tostring(err))
|
||||
MTH:Print("[MTH] Module event error (" .. name .. ", " .. tostring(evt) .. "): " .. tostring(err), "error")
|
||||
MTH:Print("Module '" .. name .. "' event error on '" .. tostring(evt) .. "': " .. tostring(err), "error")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1265,24 +1292,22 @@ function MTH:EnsureModuleStateBootstrap()
|
||||
return self._moduleStateBootstrapFrame
|
||||
end
|
||||
|
||||
local frame = CreateFrame("Frame", "MTH_ModuleStateBootstrapFrame")
|
||||
local frame = CreateFrame("Frame", "MTH_ModuleBootstrap")
|
||||
if not frame then
|
||||
return nil
|
||||
end
|
||||
|
||||
frame:RegisterEvent("VARIABLES_LOADED")
|
||||
frame:SetScript("OnEvent", function(self, eventName)
|
||||
self = self or this
|
||||
eventName = eventName or event
|
||||
if eventName ~= "VARIABLES_LOADED" then
|
||||
frame:SetScript("OnEvent", function()
|
||||
if event ~= "VARIABLES_LOADED" then
|
||||
return
|
||||
end
|
||||
if MTH and MTH.ApplyPersistedModuleStates then
|
||||
MTH:ApplyPersistedModuleStates("VARIABLES_LOADED")
|
||||
end
|
||||
if not self then return end
|
||||
self:UnregisterAllEvents()
|
||||
self:SetScript("OnEvent", nil)
|
||||
if not this then return end
|
||||
this:UnregisterAllEvents()
|
||||
this:SetScript("OnEvent", nil)
|
||||
end)
|
||||
|
||||
self._moduleStateBootstrapFrame = frame
|
||||
@@ -1460,6 +1485,46 @@ function MTH:AnnounceLoadComplete()
|
||||
"Addon synced. Your threat meter just sent a stress signal.",
|
||||
"Loaded cleanly. Reputation with healers currently in freefall.",
|
||||
"Mission start: hit things from far away and deny everything in chat.",
|
||||
"Welcome back. Your pet missed you. Just kidding, it ran away.",
|
||||
"MetaHunt loaded. You're still a Huntard, but now you're an organized one.",
|
||||
"Aspects, traps, tracking... Don't worry, I'll handle the hard parts.",
|
||||
"Oh good, another hunter who needs an addon to remember their own spells.",
|
||||
"MetaHunt ready. Feign Death is not a personality trait.",
|
||||
"Loaded successfully. No, I can't fix your DPS.",
|
||||
"Welcome. Your pet's loyalty is higher than your raid attendance.",
|
||||
"MetaHunt online. Please don't Multishot the sheep.",
|
||||
"Greetings, hunter. I see you've chosen the 'easy' class and still need help.",
|
||||
"All systems go. Try not to pull the entire dungeon this time.",
|
||||
"MetaHunt activated. Reminder: Melee range is not your home.",
|
||||
"Welcome back. Your ammo count is almost as low as your situational awareness.",
|
||||
"Loaded. I'll manage your buttons since you clearly have too many.",
|
||||
"MetaHunt ready. Aspect of the Cheetah in dungeons is a choice, not a strategy.",
|
||||
"Oh look, a hunter that uses addons. There might be hope for you yet.",
|
||||
"Welcome. No, you cannot tame that. Or that. Stop asking.",
|
||||
"MetaHunt standing by. Unlike you during your last Feign Death.",
|
||||
"Initialized. Fun fact: your pet has more utility than you do.",
|
||||
"All buttons configured. Now if only I could configure your aim.",
|
||||
"MetaHunt loaded. Growl is off, right? ...RIGHT?",
|
||||
"MetaHunt loaded. Your Freezing Trap will still break early. That's on you.",
|
||||
"Welcome. Aspect of the Pack is ready. Your group is not.",
|
||||
"Initializing... unlike your pet, I actually come when called.",
|
||||
"MetaHunt online. Remember: Hunter loot is everything. Everything.",
|
||||
"Loaded. Concussive Shot the flag carrier, not the rogue vanishing.",
|
||||
"Welcome back. Eyes of the Beast is not a valid boss strategy.",
|
||||
"Ready. Your Aimed Shot takes longer to cast than this addon took to load.",
|
||||
"MetaHunt armed. Scatter Shot into Freezing Trap — you'll get it right someday.",
|
||||
"Online. Don't worry, I track your cooldowns since you clearly don't.",
|
||||
"Welcome. Wing Clip and run. It's what you do best.",
|
||||
"Loaded. Distracting Shot is for the boss, not for your ego.",
|
||||
"MetaHunt ready. Your quiver is full but your skill bar is empty.",
|
||||
"Initialized. Serpent Sting on every target doesn't make you a DoT class.",
|
||||
"Welcome, hunter. Viper Sting the healer. No, the OTHER healer.",
|
||||
"Ready to hunt. Mend Pet is not optional, it's a lifestyle.",
|
||||
"MetaHunt loaded. Tranquilizing Shot the enrage, not the warrior.",
|
||||
"Online. Rapid Fire is a cooldown, not your approach to pulling.",
|
||||
"Welcome. You have 28 arrows left. Should've checked before the raid.",
|
||||
"Loaded. Bestial Wrath does not make YOU immune. Learned that yet?",
|
||||
"MetaHunt standing by. Dead zone? What dead zone? Oh... that dead zone.",
|
||||
}
|
||||
|
||||
local welcomeIndex = 1
|
||||
@@ -1490,24 +1555,22 @@ function MTH:EnsureLoadCompleteAnnouncement()
|
||||
return self._loadCompleteFrame
|
||||
end
|
||||
|
||||
local frame = CreateFrame("Frame", "MTH_LoadCompleteAnnounceFrame")
|
||||
local frame = CreateFrame("Frame", "MTH_LoadAnnounce")
|
||||
if not frame then
|
||||
return nil
|
||||
end
|
||||
|
||||
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
frame:SetScript("OnEvent", function(self, eventName)
|
||||
self = self or this
|
||||
eventName = eventName or event
|
||||
if eventName ~= "PLAYER_ENTERING_WORLD" then
|
||||
frame:SetScript("OnEvent", function()
|
||||
if event ~= "PLAYER_ENTERING_WORLD" then
|
||||
return
|
||||
end
|
||||
if MTH and MTH.AnnounceLoadComplete then
|
||||
MTH:AnnounceLoadComplete()
|
||||
end
|
||||
if not self then return end
|
||||
self:UnregisterAllEvents()
|
||||
self:SetScript("OnEvent", nil)
|
||||
if not this then return end
|
||||
this:UnregisterAllEvents()
|
||||
this:SetScript("OnEvent", nil)
|
||||
end)
|
||||
|
||||
self._loadCompleteFrame = frame
|
||||
|
||||
@@ -20,6 +20,7 @@ end
|
||||
local MTH_PT_ApplyScan
|
||||
local MTH_PT_AbilityHasPositiveRanks
|
||||
local MTH_PT_PromoteUnrankedKnownAliases
|
||||
local MTH_PT_BootstrapFrame = nil
|
||||
|
||||
local MTH_PT_VERBOSE_SCAN_LOGS = false
|
||||
|
||||
@@ -801,7 +802,7 @@ function MTH_PT_InitService()
|
||||
if MTH_PetTrainingFrame then
|
||||
return
|
||||
end
|
||||
MTH_PetTrainingFrame = CreateFrame("Frame", "MTHPetTrainingScanFrame")
|
||||
MTH_PetTrainingFrame = CreateFrame("Frame", "MTH_PetTrainingScan")
|
||||
MTH_PetTrainingFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_PetTrainingFrame:RegisterEvent("LEARNED_SPELL_IN_TAB")
|
||||
MTH_PetTrainingFrame:RegisterEvent("PET_TRAINING_SHOW")
|
||||
@@ -812,9 +813,8 @@ function MTH_PT_InitService()
|
||||
MTH_PetTrainingFrame:RegisterEvent("CRAFT_SHOW")
|
||||
MTH_PetTrainingFrame:RegisterEvent("CRAFT_UPDATE")
|
||||
MTH_PetTrainingFrame:SetScript("OnEvent", MTH_PT_OnEvent)
|
||||
MTH_PetTrainingFrame:SetScript("OnUpdate", function(_, elapsed)
|
||||
elapsed = elapsed or arg1
|
||||
MTH_PT_PetBookPollElapsed = (MTH_PT_PetBookPollElapsed or 0) + (elapsed or 0)
|
||||
MTH_PetTrainingFrame:SetScript("OnUpdate", function()
|
||||
MTH_PT_PetBookPollElapsed = (MTH_PT_PetBookPollElapsed or 0) + (arg1 or 0)
|
||||
if MTH_PT_PetBookPollElapsed < 0.20 then
|
||||
return
|
||||
end
|
||||
@@ -846,6 +846,35 @@ function MTH_PT_InitService()
|
||||
end)
|
||||
end
|
||||
|
||||
function MTH_PT_InitBootstrap()
|
||||
if MTH and MTH.ApplyClassGate and MTH:ApplyClassGate("trainscan-bootstrap") then
|
||||
return
|
||||
end
|
||||
if MTH_PetTrainingFrame or MTH_PT_BootstrapFrame then
|
||||
return
|
||||
end
|
||||
|
||||
local frame = CreateFrame("Frame")
|
||||
if not frame then
|
||||
return
|
||||
end
|
||||
frame:RegisterEvent("PET_TRAINING_SHOW")
|
||||
frame:RegisterEvent("CRAFT_SHOW")
|
||||
frame:SetScript("OnEvent", function()
|
||||
if event ~= "PET_TRAINING_SHOW" and event ~= "CRAFT_SHOW" then
|
||||
return
|
||||
end
|
||||
MTH_PT_InitService()
|
||||
if type(MTH_PT_OnEvent) == "function" then
|
||||
MTH_PT_OnEvent(MTH_PetTrainingFrame, event)
|
||||
end
|
||||
this:UnregisterAllEvents()
|
||||
this:SetScript("OnEvent", nil)
|
||||
MTH_PT_BootstrapFrame = nil
|
||||
end)
|
||||
MTH_PT_BootstrapFrame = frame
|
||||
end
|
||||
|
||||
function MTH_PT_ShutdownService(_reason)
|
||||
if not MTH_PetTrainingFrame then
|
||||
return
|
||||
@@ -929,3 +958,4 @@ end
|
||||
|
||||
MTH_TR_InitService = MTH_PT_InitService
|
||||
MTH_TR_ShutdownService = MTH_PT_ShutdownService
|
||||
MTH_TR_InitBootstrap = MTH_PT_InitBootstrap
|
||||
|
||||
@@ -7,6 +7,25 @@ local MTH_PS_LastScanAt = 0
|
||||
local MTH_PS_VERBOSE_LOGS = false
|
||||
local MTH_PS_ForceScanUntil = 0
|
||||
local MTH_PS_ForceScanBudget = 0
|
||||
local MTH_PS_EventThrottle = {}
|
||||
local MTH_PS_LastNoPetScanAt = 0
|
||||
|
||||
local function MTH_PS_IsPlayerDeadOrGhost()
|
||||
if type(UnitIsDeadOrGhost) == "function" then
|
||||
return UnitIsDeadOrGhost("player") and true or false
|
||||
end
|
||||
if type(UnitIsDead) == "function" then
|
||||
return UnitIsDead("player") and true or false
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function MTH_PS_HasLivePet()
|
||||
if type(UnitExists) ~= "function" then
|
||||
return false
|
||||
end
|
||||
return UnitExists("pet") and true or false
|
||||
end
|
||||
|
||||
local function MTH_PS_ClearForceWindow()
|
||||
MTH_PS_ForceScanUntil = 0
|
||||
@@ -26,9 +45,25 @@ end
|
||||
local function MTH_PS_IsFollowupEventTrigger(trigger)
|
||||
local t = tostring(trigger or "")
|
||||
return t == "event:UNIT_PET"
|
||||
or t == "UNIT_PET"
|
||||
or t == "event:PET_BAR_UPDATE"
|
||||
or t == "PET_BAR_UPDATE"
|
||||
or t == "event:SPELLS_CHANGED"
|
||||
or t == "SPELLS_CHANGED"
|
||||
or t == "event:LEARNED_SPELL_IN_TAB"
|
||||
or t == "LEARNED_SPELL_IN_TAB"
|
||||
end
|
||||
|
||||
local function MTH_PS_ShouldHandleEvent(evt, minIntervalSeconds)
|
||||
local now = tonumber(GetTime and GetTime() or time()) or 0
|
||||
local key = tostring(evt or "")
|
||||
local minInterval = tonumber(minIntervalSeconds) or 0
|
||||
local last = tonumber(MTH_PS_EventThrottle[key] or 0) or 0
|
||||
if minInterval > 0 and (now - last) < minInterval then
|
||||
return false
|
||||
end
|
||||
MTH_PS_EventThrottle[key] = now
|
||||
return true
|
||||
end
|
||||
|
||||
local function MTH_PS_IsPriorityTrigger(trigger)
|
||||
@@ -190,6 +225,41 @@ function MTH_PSP_RequestScan(trigger, minIntervalSeconds)
|
||||
local minInterval = tonumber(minIntervalSeconds) or 1
|
||||
local bypassThrottle = false
|
||||
local bypassReason = ""
|
||||
local deadOrGhost = MTH_PS_IsPlayerDeadOrGhost()
|
||||
local hasLivePet = MTH_PS_HasLivePet()
|
||||
|
||||
if deadOrGhost then
|
||||
if triggerText == "PET_BAR_UPDATE" or triggerText == "event:PET_BAR_UPDATE"
|
||||
or triggerText == "SPELLS_CHANGED" or triggerText == "event:SPELLS_CHANGED"
|
||||
or triggerText == "LEARNED_SPELL_IN_TAB" or triggerText == "event:LEARNED_SPELL_IN_TAB"
|
||||
then
|
||||
MTH_PS_TraceTrigger(triggerText, false, "dead-skip")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if not hasLivePet then
|
||||
if MTH_PS_IsFollowupEventTrigger(triggerText) then
|
||||
MTH_PS_TraceTrigger(triggerText, false, "no-pet-followup")
|
||||
return false
|
||||
end
|
||||
if triggerText ~= "manual"
|
||||
and triggerText ~= "PLAYER_ENTERING_WORLD"
|
||||
and triggerText ~= "event:PLAYER_ENTERING_WORLD"
|
||||
and triggerText ~= "UNIT_PET"
|
||||
and triggerText ~= "event:UNIT_PET"
|
||||
then
|
||||
MTH_PS_TraceTrigger(triggerText, false, "no-pet")
|
||||
return false
|
||||
end
|
||||
if (now - (tonumber(MTH_PS_LastNoPetScanAt) or 0)) < 5 then
|
||||
MTH_PS_TraceTrigger(triggerText, false, "no-pet-throttled")
|
||||
return false
|
||||
end
|
||||
MTH_PS_LastNoPetScanAt = now
|
||||
else
|
||||
MTH_PS_LastNoPetScanAt = 0
|
||||
end
|
||||
|
||||
if MTH_PS_IsPriorityTrigger(triggerText) then
|
||||
bypassThrottle = true
|
||||
@@ -237,7 +307,19 @@ local function MTH_PS_OnEvent(_, evt, eventArg1)
|
||||
end
|
||||
|
||||
if evt == "PLAYER_ENTERING_WORLD" or evt == "UNIT_PET" or evt == "PET_BAR_UPDATE" or evt == "SPELLS_CHANGED" or evt == "LEARNED_SPELL_IN_TAB" then
|
||||
MTH_PSP_RequestScan("event:" .. tostring(evt), 1)
|
||||
local minInterval = 1
|
||||
if evt == "PET_BAR_UPDATE" then
|
||||
minInterval = 4
|
||||
elseif evt == "SPELLS_CHANGED" then
|
||||
minInterval = 4
|
||||
elseif evt == "LEARNED_SPELL_IN_TAB" then
|
||||
minInterval = 1.5
|
||||
elseif evt == "UNIT_PET" then
|
||||
minInterval = 1
|
||||
end
|
||||
if MTH_PS_ShouldHandleEvent(evt, minInterval) then
|
||||
MTH_PSP_RequestScan(evt, minInterval)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -249,7 +331,7 @@ function MTH_PS_InitService()
|
||||
return
|
||||
end
|
||||
|
||||
MTH_PS_Frame = CreateFrame("Frame", "MTHPetSpellScanFrame")
|
||||
MTH_PS_Frame = CreateFrame("Frame", "MTH_PetSpellbookEvent")
|
||||
MTH_PS_Frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_PS_Frame:RegisterEvent("UNIT_PET")
|
||||
MTH_PS_Frame:RegisterEvent("PET_BAR_UPDATE")
|
||||
@@ -266,6 +348,7 @@ function MTH_PS_ShutdownService(_reason)
|
||||
MTH_PS_Frame:SetScript("OnEvent", nil)
|
||||
MTH_PS_Frame = nil
|
||||
MTH_PS_LastScanAt = 0
|
||||
MTH_PS_LastNoPetScanAt = 0
|
||||
MTH_PS_ClearForceWindow()
|
||||
end
|
||||
|
||||
|
||||
+1443
-146
File diff suppressed because it is too large
Load Diff
+134
-18
@@ -12,7 +12,7 @@ local function MTH_PT_GetGlobal(name)
|
||||
return nil
|
||||
end
|
||||
|
||||
local MTH_ItemLinkCacheTooltip = nil
|
||||
local MTH_ItemLinkCache = nil
|
||||
|
||||
local function MTH_GetQualityHexColor(quality)
|
||||
local q = tonumber(quality)
|
||||
@@ -34,14 +34,14 @@ function MTH_PrimeItemCache(itemId)
|
||||
if not id or id <= 0 then return false end
|
||||
if type(GetItemInfo) == "function" and GetItemInfo(id) then return true end
|
||||
|
||||
if not MTH_ItemLinkCacheTooltip then
|
||||
MTH_ItemLinkCacheTooltip = CreateFrame("GameTooltip", "MTH_ItemLinkCacheTooltip", UIParent, "GameTooltipTemplate")
|
||||
if not MTH_ItemLinkCacheTooltip then return false end
|
||||
MTH_ItemLinkCacheTooltip:SetOwner(UIParent, "ANCHOR_NONE")
|
||||
if not MTH_ItemLinkCache then
|
||||
MTH_ItemLinkCache = CreateFrame("GameTooltip", "MTH_ItemLinkCache", UIParent, "GameTooltipTemplate")
|
||||
if not MTH_ItemLinkCache then return false end
|
||||
MTH_ItemLinkCache:SetOwner(UIParent, "ANCHOR_NONE")
|
||||
end
|
||||
|
||||
MTH_ItemLinkCacheTooltip:ClearLines()
|
||||
MTH_ItemLinkCacheTooltip:SetHyperlink("item:" .. tostring(id) .. ":0:0:0")
|
||||
MTH_ItemLinkCache:ClearLines()
|
||||
MTH_ItemLinkCache:SetHyperlink("item:" .. tostring(id) .. ":0:0:0")
|
||||
return type(GetItemInfo) == "function" and (GetItemInfo(id) ~= nil) or false
|
||||
end
|
||||
|
||||
@@ -129,6 +129,49 @@ local function MTH_CommandOptions()
|
||||
end
|
||||
end
|
||||
|
||||
local function MTH_FormatAgeSeconds(seconds)
|
||||
local value = tonumber(seconds) or 0
|
||||
if value < 0 then value = 0 end
|
||||
if value < 60 then
|
||||
return tostring(math.floor(value)) .. "s"
|
||||
end
|
||||
if value < 3600 then
|
||||
return tostring(math.floor(value / 60)) .. "m"
|
||||
end
|
||||
if value < 86400 then
|
||||
return tostring(math.floor(value / 3600)) .. "h"
|
||||
end
|
||||
return tostring(math.floor(value / 86400)) .. "d"
|
||||
end
|
||||
|
||||
local function MTH_CommandPeers()
|
||||
if not (MTH and MTH.VersionCheck and type(MTH.VersionCheck.GetTrackedPeers) == "function") then
|
||||
MTH:Print("Peer tracker is not available yet")
|
||||
return
|
||||
end
|
||||
|
||||
local peers = MTH.VersionCheck:GetTrackedPeers()
|
||||
local count = table.getn(peers)
|
||||
if count <= 0 then
|
||||
MTH:Print("No MetaHunt broadcasters seen yet on LFT")
|
||||
return
|
||||
end
|
||||
|
||||
MTH:Print("MetaHunt broadcasters seen on LFT: " .. tostring(count))
|
||||
local now = (type(time) == "function" and time()) or (type(GetTime) == "function" and math.floor(GetTime())) or 0
|
||||
local maxRows = math.min(count, 20)
|
||||
for i = 1, maxRows do
|
||||
local peer = peers[i]
|
||||
if type(peer) == "table" then
|
||||
local age = MTH_FormatAgeSeconds((now or 0) - (tonumber(peer.lastSeenAt) or 0))
|
||||
MTH:Print("- " .. tostring(peer.name or "?") .. " v" .. tostring(peer.versionText or "?") .. " (seen " .. tostring(age) .. " ago)")
|
||||
end
|
||||
end
|
||||
if count > maxRows then
|
||||
MTH:Print("... and " .. tostring(count - maxRows) .. " more")
|
||||
end
|
||||
end
|
||||
|
||||
local function MTH_CommandPetSpellScanFallback()
|
||||
local getSpellName = (type(getglobal) == "function" and getglobal("GetSpellName")) or (_G and _G["GetSpellName"])
|
||||
local getSpellTexture = (type(getglobal) == "function" and getglobal("GetSpellTexture")) or (_G and _G["GetSpellTexture"])
|
||||
@@ -197,6 +240,34 @@ local function MTH_CommandPetSpellScanFallback()
|
||||
end
|
||||
end
|
||||
|
||||
local function MTH_CommandFoodData(limitText)
|
||||
if type(FOM_PrintCollectedFoodData) ~= "function" then
|
||||
MTH:Print("Food data command is not available yet")
|
||||
return
|
||||
end
|
||||
local trimmed = string.gsub(tostring(limitText or ""), "^%s+", "")
|
||||
trimmed = string.gsub(trimmed, "%s+$", "")
|
||||
if string.lower(trimmed) == "purge" then
|
||||
if type(FOM_PruneCollectedFoodData) ~= "function" then
|
||||
MTH:Print("Food data purge is not available yet")
|
||||
return
|
||||
end
|
||||
local removed = tonumber(FOM_PruneCollectedFoodData()) or 0
|
||||
MTH:Print("Food data purge removed rows: " .. tostring(removed))
|
||||
return
|
||||
end
|
||||
if trimmed == "" then
|
||||
FOM_PrintCollectedFoodData(nil)
|
||||
return
|
||||
end
|
||||
local limit = tonumber(trimmed)
|
||||
if not limit then
|
||||
MTH:Print("Usage: /mth food [limit|purge]")
|
||||
return
|
||||
end
|
||||
FOM_PrintCollectedFoodData(limit)
|
||||
end
|
||||
|
||||
if type(MTH_PS_ScanNow) ~= "function" then
|
||||
function MTH_PS_ScanNow(trigger)
|
||||
local ok, count = MTH_CommandPetSpellScanFallback()
|
||||
@@ -230,6 +301,46 @@ if type(MTH_CommandPetSpellScan) ~= "function" then
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------
|
||||
-- /mth diag — Runtime Diagnostics
|
||||
------------------------------------------------------
|
||||
function MTH_CommandDiag()
|
||||
MTH:Print("======= MetaHunt Diagnostics =======", "debug")
|
||||
|
||||
-- 1. Lua version
|
||||
local luaVer = _VERSION or "unknown"
|
||||
MTH:Print("[DIAG] _VERSION = " .. tostring(luaVer), "debug")
|
||||
MTH:Print("[DIAG] string.match = " .. tostring(type(string.match) == "function"), "debug")
|
||||
MTH:Print("[DIAG] string.gfind = " .. tostring(type(string.gfind) == "function"), "debug")
|
||||
|
||||
-- 2. Active modules
|
||||
local moduleCount = 0
|
||||
local enabledModules = {}
|
||||
if MTH.modules then
|
||||
for name, mod in pairs(MTH.modules) do
|
||||
moduleCount = moduleCount + 1
|
||||
if mod.enabled then
|
||||
table.insert(enabledModules, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
MTH:Print("[DIAG] Registered modules: " .. tostring(moduleCount), "debug")
|
||||
MTH:Print("[DIAG] Enabled: " .. table.concat(enabledModules, ", "), "debug")
|
||||
|
||||
-- 3. Event router state
|
||||
local routerFrame = (MTH._eventRouter and MTH._eventRouter.frame) or nil
|
||||
local routerEvents = (MTH._eventRouter and MTH._eventRouter.eventRefs) or {}
|
||||
local eventCount = 0
|
||||
for _ in pairs(routerEvents) do eventCount = eventCount + 1 end
|
||||
MTH:Print("[DIAG] EventRouter frame: " .. tostring(routerFrame ~= nil) .. ", events: " .. tostring(eventCount), "debug")
|
||||
|
||||
-- 4. Debug frame initialized?
|
||||
local dfInit = (MTH_DebugFrame and MTH_DebugFrame.initialized) and true or false
|
||||
MTH:Print("[DIAG] DebugFrame initialized: " .. tostring(dfInit), "debug")
|
||||
|
||||
MTH:Print("======= End Diagnostics =======", "debug")
|
||||
end
|
||||
|
||||
function SlashCmdList.MTH(msg, editbox)
|
||||
if MTH and MTH.ApplyClassGate and MTH:ApplyClassGate("slash") then
|
||||
return
|
||||
@@ -239,33 +350,38 @@ function SlashCmdList.MTH(msg, editbox)
|
||||
msg = string.gsub(tostring(msg), "^%s+", "")
|
||||
msg = string.gsub(msg, "%s+$", "")
|
||||
local lowerMsg = string.lower(msg)
|
||||
local _, _, lowerCmd, lowerArg = string.find(lowerMsg, "^(%S+)%s*(.-)%s*$")
|
||||
if msg == "" then
|
||||
MTH:Print("Available: /mth options, /mth book")
|
||||
MTH:Print("Available: /mth options, /mth book, /mth diag, /mth err")
|
||||
elseif lowerMsg == "options" then
|
||||
MTH_CommandOptions()
|
||||
elseif lowerMsg == "book" or lowerMsg == "hunterbook" then
|
||||
MTH_CommandBook()
|
||||
elseif lowerMsg == "err" then
|
||||
if MTH_DebugFrame and type(MTH_DebugFrame.Toggle) == "function" then
|
||||
elseif lowerMsg == "peers" or lowerMsg == "who" then
|
||||
MTH_CommandPeers()
|
||||
elseif lowerMsg == "diag" then
|
||||
MTH_CommandDiag()
|
||||
elseif lowerMsg == "err" or lowerMsg == "errors" or lowerMsg == "debug" then
|
||||
if MTH_DebugFrame and MTH_DebugFrame.Toggle then
|
||||
MTH_DebugFrame:Toggle()
|
||||
else
|
||||
MTH:Print("Debug frame is not available yet")
|
||||
MTH:Print("Debug frame is not available.")
|
||||
end
|
||||
else
|
||||
MTH:Print("Unknown command: " .. tostring(msg))
|
||||
MTH:Print("Available: /mth options, /mth book")
|
||||
MTH:Print("Available: /mth options, /mth book, /mth diag, /mth err")
|
||||
end
|
||||
end
|
||||
|
||||
-- Initialize on load
|
||||
MTH:InitSavedVariables()
|
||||
if type(MTH_ST_InitService) == "function" then
|
||||
MTH_ST_InitService()
|
||||
if type(MTH_ST_InitBootstrap) == "function" then
|
||||
MTH_ST_InitBootstrap()
|
||||
end
|
||||
if type(MTH_TR_InitService) == "function" then
|
||||
MTH_TR_InitService()
|
||||
elseif type(MTH_PT_InitService) == "function" then
|
||||
MTH_PT_InitService()
|
||||
if type(MTH_TR_InitBootstrap) == "function" then
|
||||
MTH_TR_InitBootstrap()
|
||||
elseif type(MTH_PT_InitBootstrap) == "function" then
|
||||
MTH_PT_InitBootstrap()
|
||||
end
|
||||
if type(MTH_PS_InitService) == "function" then
|
||||
MTH_PS_InitService()
|
||||
|
||||
+6
-6
@@ -29,7 +29,7 @@ function MTH_DebugFrame:Initialize()
|
||||
self.initialized = true
|
||||
|
||||
-- Create main frame
|
||||
self.frame = CreateFrame("Frame", "MTH_DebugFrameWindow", UIParent)
|
||||
self.frame = CreateFrame("Frame", "MTH_DebugWindow", UIParent)
|
||||
self.frame:SetWidth(800)
|
||||
self.frame:SetHeight(400)
|
||||
self.frame:SetPoint("CENTER", UIParent, "CENTER")
|
||||
@@ -51,13 +51,13 @@ function MTH_DebugFrame:Initialize()
|
||||
if UISpecialFrames then
|
||||
local already = false
|
||||
for i = 1, table.getn(UISpecialFrames) do
|
||||
if UISpecialFrames[i] == "MTH_DebugFrameWindow" then
|
||||
if UISpecialFrames[i] == "MTH_DebugWindow" then
|
||||
already = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not already then
|
||||
table.insert(UISpecialFrames, "MTH_DebugFrameWindow")
|
||||
table.insert(UISpecialFrames, "MTH_DebugWindow")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -91,7 +91,7 @@ function MTH_DebugFrame:Initialize()
|
||||
copyButton:SetScript("OnClick", function() MTH_DebugFrame:SelectAllText() end)
|
||||
|
||||
-- Scroll frame + text content with proper vertical scrollbar
|
||||
self.scrollFrame = CreateFrame("ScrollFrame", "MTH_DebugScrollFrame", self.frame, "UIPanelScrollFrameTemplate")
|
||||
self.scrollFrame = CreateFrame("ScrollFrame", "MTH_DebugScroll", self.frame, "UIPanelScrollFrameTemplate")
|
||||
self.scrollFrame:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 15, -50)
|
||||
self.scrollFrame:SetPoint("BOTTOMRIGHT", self.frame, "BOTTOMRIGHT", -35, 45)
|
||||
|
||||
@@ -366,8 +366,8 @@ MTH_DebugFrame.UninstallHooks = MTH_DF_UninstallHooks
|
||||
-- Event listener for addon load
|
||||
local eventFrame = CreateFrame("Frame")
|
||||
eventFrame:RegisterEvent("ADDON_LOADED")
|
||||
eventFrame:SetScript("OnEvent", function(self, event, addonName)
|
||||
if event == "ADDON_LOADED" and addonName == "MetaHunt" then
|
||||
eventFrame:SetScript("OnEvent", function()
|
||||
if event == "ADDON_LOADED" and arg1 == "MetaHunt" then
|
||||
if MTH and MTH.GetConfig then
|
||||
MTH_DF_SetGlobalCaptureEnabled(MTH:GetConfig("debug", "globalErrorCapture", false))
|
||||
end
|
||||
|
||||
@@ -7,8 +7,8 @@ MTH_HUNTERBOOK_TABS.families = {
|
||||
{ x = 10, width = 106, align = "LEFT" },
|
||||
{ x = 122, width = 52, align = "LEFT" },
|
||||
{ x = 176, width = 52, align = "LEFT" },
|
||||
{ x = 232, width = 292, align = "LEFT" },
|
||||
{ x = 460, width = 184, align = "LEFT" },
|
||||
{ x = 232, width = 364, align = "LEFT" },
|
||||
{ x = 532, width = 112, align = "LEFT" },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -27,6 +27,11 @@ local function MTH_BOOKTAB_FamiliesTrim(value)
|
||||
return text
|
||||
end
|
||||
|
||||
local function MTH_BOOKTAB_ShouldDisplayAllDiet(familyName)
|
||||
local token = MTH_BOOKTAB_FamiliesSafeLower(MTH_BOOKTAB_FamiliesTrim(familyName))
|
||||
return token == "bears" or token == "boars"
|
||||
end
|
||||
|
||||
local function MTH_BOOKTAB_FindAbilityBundle(abilityName)
|
||||
if not (MTH_DS_PetSpells and type(MTH_DS_PetSpells.byAbility) == "table") then
|
||||
return nil
|
||||
@@ -95,25 +100,49 @@ function MTH_BOOKTAB_BuildFamiliesRows()
|
||||
if token ~= "" and not seen[token] then
|
||||
seen[token] = true
|
||||
local spellRows = (type(bundle) == "table" and type(bundle.spells) == "table") and bundle.spells or {}
|
||||
local firstAnySpell = nil
|
||||
local firstBeastSpell = nil
|
||||
local rankMin = nil
|
||||
local rankMax = nil
|
||||
local rankMap = {}
|
||||
local beastRankMin = nil
|
||||
local beastRankMax = nil
|
||||
local beastRankMap = {}
|
||||
local anyRankMin = nil
|
||||
local anyRankMax = nil
|
||||
local anyRankMap = {}
|
||||
for s = 1, table.getn(spellRows) do
|
||||
local spell = spellRows[s]
|
||||
if type(spell) == "table" and MTH_BOOKTAB_FamiliesSafeLower(spell.learnMethod or "beast") ~= "trainer" then
|
||||
if not firstBeastSpell then
|
||||
firstBeastSpell = spell
|
||||
if type(spell) == "table" then
|
||||
if not firstAnySpell then
|
||||
firstAnySpell = spell
|
||||
end
|
||||
local rank = tonumber(spell.rankNumber)
|
||||
if rank and rank > 0 then
|
||||
rankMap[rank] = true
|
||||
if not rankMin or rank < rankMin then rankMin = rank end
|
||||
if not rankMax or rank > rankMax then rankMax = rank end
|
||||
anyRankMap[rank] = true
|
||||
if not anyRankMin or rank < anyRankMin then anyRankMin = rank end
|
||||
if not anyRankMax or rank > anyRankMax then anyRankMax = rank end
|
||||
end
|
||||
if MTH_BOOKTAB_FamiliesSafeLower(spell.learnMethod or "beast") ~= "trainer" then
|
||||
if not firstBeastSpell then
|
||||
firstBeastSpell = spell
|
||||
end
|
||||
if rank and rank > 0 then
|
||||
beastRankMap[rank] = true
|
||||
if not beastRankMin or rank < beastRankMin then beastRankMin = rank end
|
||||
if not beastRankMax or rank > beastRankMax then beastRankMax = rank end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local displaySpell = firstBeastSpell or firstAnySpell
|
||||
local rankMap = beastRankMap
|
||||
local rankMin = beastRankMin
|
||||
local rankMax = beastRankMax
|
||||
if not firstBeastSpell then
|
||||
rankMap = anyRankMap
|
||||
rankMin = anyRankMin
|
||||
rankMax = anyRankMax
|
||||
end
|
||||
|
||||
local rankCount = 0
|
||||
for _ in pairs(rankMap) do
|
||||
rankCount = rankCount + 1
|
||||
@@ -123,8 +152,8 @@ function MTH_BOOKTAB_BuildFamiliesRows()
|
||||
name = canonicalMap[token] or canonical,
|
||||
token = token,
|
||||
isUnique = (abilityCounts[token] or 0) == 1,
|
||||
icon = firstBeastSpell and firstBeastSpell.icon or nil,
|
||||
description = firstBeastSpell and firstBeastSpell.description or "",
|
||||
icon = displaySpell and displaySpell.icon or nil,
|
||||
description = displaySpell and displaySpell.description or "",
|
||||
rankMin = rankMin,
|
||||
rankMax = rankMax,
|
||||
rankCount = rankCount,
|
||||
@@ -141,17 +170,23 @@ function MTH_BOOKTAB_BuildFamiliesRows()
|
||||
return MTH_BOOKTAB_FamiliesSafeLower(a.name) < MTH_BOOKTAB_FamiliesSafeLower(b.name)
|
||||
end)
|
||||
|
||||
local dietItems = {}
|
||||
if type(familyRow.food) == "table" then
|
||||
for i = 1, table.getn(familyRow.food) do
|
||||
local food = MTH_BOOKTAB_FamiliesTrim(familyRow.food[i])
|
||||
if food ~= "" then
|
||||
table.insert(dietItems, string.upper(string.sub(food, 1, 1)) .. string.sub(food, 2))
|
||||
local dietText = ""
|
||||
if MTH_BOOKTAB_ShouldDisplayAllDiet(familyName) then
|
||||
dietText = "ALL"
|
||||
else
|
||||
local dietItems = {}
|
||||
if type(familyRow.food) == "table" then
|
||||
for i = 1, table.getn(familyRow.food) do
|
||||
local food = MTH_BOOKTAB_FamiliesTrim(familyRow.food[i])
|
||||
if food ~= "" then
|
||||
table.insert(dietItems, string.upper(string.sub(food, 1, 1)) .. string.sub(food, 2))
|
||||
end
|
||||
end
|
||||
table.sort(dietItems, function(a, b)
|
||||
return MTH_BOOKTAB_FamiliesSafeLower(a) < MTH_BOOKTAB_FamiliesSafeLower(b)
|
||||
end)
|
||||
end
|
||||
table.sort(dietItems, function(a, b)
|
||||
return MTH_BOOKTAB_FamiliesSafeLower(a) < MTH_BOOKTAB_FamiliesSafeLower(b)
|
||||
end)
|
||||
dietText = table.concat(dietItems, ", ")
|
||||
end
|
||||
|
||||
table.insert(results, {
|
||||
@@ -159,7 +194,7 @@ function MTH_BOOKTAB_BuildFamiliesRows()
|
||||
named = tonumber(familyRow.named) or 0,
|
||||
coords = tonumber(familyRow.coords) or 0,
|
||||
abilities = abilities,
|
||||
dietText = table.concat(dietItems, ", "),
|
||||
dietText = dietText,
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -238,7 +273,7 @@ function MTH_BOOKTAB_EnsureFamiliesUI()
|
||||
ui.headerAbilities:SetText("Abilities")
|
||||
|
||||
ui.headerDiet = ui.frame:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
|
||||
ui.headerDiet:SetPoint("TOPLEFT", ui.frame, "TOPLEFT", 460, -2)
|
||||
ui.headerDiet:SetPoint("TOPLEFT", ui.frame, "TOPLEFT", 532, -2)
|
||||
ui.headerDiet:SetTextColor(1.00, 0.82, 0.00)
|
||||
ui.headerDiet:SetText("Diet")
|
||||
|
||||
@@ -270,8 +305,8 @@ function MTH_BOOKTAB_EnsureFamiliesUI()
|
||||
row.coords:SetJustifyH("LEFT")
|
||||
|
||||
row.diet = row:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
|
||||
row.diet:SetPoint("LEFT", row, "LEFT", 460, 0)
|
||||
row.diet:SetWidth(184)
|
||||
row.diet:SetPoint("LEFT", row, "LEFT", 532, 0)
|
||||
row.diet:SetWidth(112)
|
||||
row.diet:SetJustifyH("LEFT")
|
||||
|
||||
row.abilityButtons = {}
|
||||
@@ -363,6 +398,7 @@ function MTH_BOOKTAB_RenderFamiliesList()
|
||||
rowFrame.diet:SetText(tostring(row.dietText or "-"))
|
||||
|
||||
local offsetX = 232
|
||||
local abilityMaxRight = 526
|
||||
for b = 1, table.getn(rowFrame.abilityButtons) do
|
||||
local button = rowFrame.abilityButtons[b]
|
||||
local ability = row.abilities and row.abilities[b] or nil
|
||||
@@ -375,17 +411,23 @@ function MTH_BOOKTAB_RenderFamiliesList()
|
||||
button.text:SetText(nameText)
|
||||
local textW = button.text:GetStringWidth() or 40
|
||||
if textW < 24 then textW = 24 end
|
||||
button:SetWidth(14 + textW)
|
||||
button:ClearAllPoints()
|
||||
button:SetPoint("LEFT", rowFrame, "LEFT", offsetX, 0)
|
||||
local iconPath = ability.icon and MTH_BOOK_ResolveIconPath and MTH_BOOK_ResolveIconPath(ability.icon) or nil
|
||||
if iconPath then
|
||||
button.icon:SetTexture(iconPath)
|
||||
local buttonWidth = 14 + textW
|
||||
if (offsetX + buttonWidth) > abilityMaxRight then
|
||||
button.entry = nil
|
||||
button:Hide()
|
||||
else
|
||||
button.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
|
||||
button:SetWidth(buttonWidth)
|
||||
button:ClearAllPoints()
|
||||
button:SetPoint("LEFT", rowFrame, "LEFT", offsetX, 0)
|
||||
local iconPath = ability.icon and MTH_BOOK_ResolveIconPath and MTH_BOOK_ResolveIconPath(ability.icon) or nil
|
||||
if iconPath then
|
||||
button.icon:SetTexture(iconPath)
|
||||
else
|
||||
button.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
|
||||
end
|
||||
button:Show()
|
||||
offsetX = offsetX + button:GetWidth() + 6
|
||||
end
|
||||
button:Show()
|
||||
offsetX = offsetX + button:GetWidth() + 6
|
||||
else
|
||||
button.entry = nil
|
||||
button:Hide()
|
||||
|
||||
@@ -140,7 +140,7 @@ function MTH_BOOK_GetResistanceShortName(nameText)
|
||||
if string.find(lowerName, "arcane", 1, true) then return "AR" end
|
||||
if string.find(lowerName, "nature", 1, true) then return "NR" end
|
||||
if string.find(lowerName, "fire", 1, true) then return "FR" end
|
||||
if string.find(lowerName, "frost", 1, true) then return "FR" end
|
||||
if string.find(lowerName, "frost", 1, true) then return "FrR" end
|
||||
if string.find(lowerName, "shadow", 1, true) then return "SR" end
|
||||
return tostring(nameText or "-")
|
||||
end
|
||||
|
||||
+100
-38
@@ -55,7 +55,7 @@ local function MTH_BOOK_FamiliesTrace(message)
|
||||
end
|
||||
|
||||
local MTH_BOOK_STATE = {
|
||||
mode = "stable",
|
||||
mode = "pets",
|
||||
search = "",
|
||||
quick = "all",
|
||||
minLevel = nil,
|
||||
@@ -1002,9 +1002,9 @@ end
|
||||
local function MTH_BOOK_ParseProjectileDPSFromText(text)
|
||||
if type(text) ~= "string" or text == "" then return nil end
|
||||
local lowered = string.lower(text)
|
||||
local raw = string.match(lowered, "adds%s+([%d]+[%.,]?[%d]*)%s+damage%s+per%s+seconds?")
|
||||
local _, _, raw = string.find(lowered, "adds%s+([%d]+[%.,]?[%d]*)%s+damage%s+per%s+seconds?")
|
||||
if not raw then
|
||||
raw = string.match(lowered, "([%d]+[%.,]?[%d]*)%s+damage%s+per%s+seconds?")
|
||||
_, _, raw = string.find(lowered, "([%d]+[%.,]?[%d]*)%s+damage%s+per%s+seconds?")
|
||||
end
|
||||
if not raw then return nil end
|
||||
local normalized = string.gsub(raw, ",", ".")
|
||||
@@ -1537,13 +1537,75 @@ local function MTH_BOOK_BuildResults()
|
||||
if MTH_BOOK_STATE.mode == "pethistory" then
|
||||
local store = MTH_BOOK_GetPetDatastore()
|
||||
if type(store) ~= "table" or type(store.historyById) ~= "table" then return results end
|
||||
|
||||
local cached = {}
|
||||
for petId, row in pairs(store.historyById) do
|
||||
if type(row) == "table" then
|
||||
table.insert(results, petId)
|
||||
local idText = tostring(petId)
|
||||
table.insert(cached, {
|
||||
id = petId,
|
||||
idText = idText,
|
||||
name = MTH_BOOK_SafeLower(row.name),
|
||||
family = MTH_BOOK_SafeLower(row.family),
|
||||
level = tonumber(row.level) or 0,
|
||||
abandonedAt = tonumber(row.abandonedAt) or 0,
|
||||
reason = MTH_BOOK_SafeLower(tostring(row.abandonReason or "")),
|
||||
})
|
||||
end
|
||||
end
|
||||
table.sort(results, MTH_BOOK_PetHistorySort)
|
||||
MTH_BOOK_ApplyActiveSort(results)
|
||||
|
||||
local function defaultHistoryCompare(a, b)
|
||||
if a.abandonedAt ~= b.abandonedAt then
|
||||
return a.abandonedAt > b.abandonedAt
|
||||
end
|
||||
if a.name ~= b.name then
|
||||
return a.name < b.name
|
||||
end
|
||||
return a.idText < b.idText
|
||||
end
|
||||
|
||||
local state = MTH_BOOK_GetSortState()
|
||||
if state and state.col then
|
||||
table.sort(cached, function(a, b)
|
||||
local ka = nil
|
||||
local kb = nil
|
||||
if state.col == 1 then
|
||||
ka = a.idText
|
||||
kb = b.idText
|
||||
elseif state.col == 2 then
|
||||
ka = a.name
|
||||
kb = b.name
|
||||
elseif state.col == 3 then
|
||||
ka = a.family
|
||||
kb = b.family
|
||||
elseif state.col == 4 then
|
||||
ka = a.level
|
||||
kb = b.level
|
||||
elseif state.col == 5 then
|
||||
ka = a.abandonedAt
|
||||
kb = b.abandonedAt
|
||||
elseif state.col == 6 then
|
||||
ka = a.reason
|
||||
kb = b.reason
|
||||
end
|
||||
|
||||
if ka ~= kb then
|
||||
if ka == nil then return not state.asc end
|
||||
if kb == nil then return state.asc end
|
||||
if state.asc then
|
||||
return ka < kb
|
||||
end
|
||||
return ka > kb
|
||||
end
|
||||
return defaultHistoryCompare(a, b)
|
||||
end)
|
||||
else
|
||||
table.sort(cached, defaultHistoryCompare)
|
||||
end
|
||||
|
||||
for i = 1, table.getn(cached) do
|
||||
table.insert(results, cached[i].id)
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
@@ -4379,23 +4441,14 @@ local function MTH_BOOK_LayoutSectionTabs()
|
||||
local sectionPetHistory = getglobal("MTH_BOOK_SectionPetHistory")
|
||||
if not (tabBar and sectionPets and sectionFamilies and sectionPetAbilities and sectionItems and sectionNPCs and sectionProjectiles and sectionAmmoBags) then return end
|
||||
|
||||
if sectionStable then
|
||||
sectionStable:ClearAllPoints()
|
||||
sectionStable:SetPoint("TOPLEFT", tabBar, "TOPLEFT", 0, 0)
|
||||
end
|
||||
sectionPets:ClearAllPoints()
|
||||
sectionPets:SetPoint("TOPLEFT", tabBar, "TOPLEFT", 0, 0)
|
||||
|
||||
sectionPetAbilities:ClearAllPoints()
|
||||
if sectionStable then
|
||||
sectionPetAbilities:SetPoint("LEFT", sectionStable, "RIGHT", 2, 0)
|
||||
else
|
||||
sectionPetAbilities:SetPoint("TOPLEFT", tabBar, "TOPLEFT", 0, 0)
|
||||
end
|
||||
|
||||
sectionPets:ClearAllPoints()
|
||||
sectionPets:SetPoint("LEFT", sectionPetAbilities, "RIGHT", 2, 0)
|
||||
sectionPetAbilities:SetPoint("LEFT", sectionPets, "RIGHT", 2, 0)
|
||||
|
||||
sectionFamilies:ClearAllPoints()
|
||||
sectionFamilies:SetPoint("LEFT", sectionPets, "RIGHT", 2, 0)
|
||||
sectionFamilies:SetPoint("LEFT", sectionPetAbilities, "RIGHT", 2, 0)
|
||||
|
||||
sectionNPCs:ClearAllPoints()
|
||||
sectionNPCs:SetPoint("LEFT", sectionFamilies, "RIGHT", 2, 0)
|
||||
@@ -4409,9 +4462,18 @@ local function MTH_BOOK_LayoutSectionTabs()
|
||||
sectionAmmoBags:ClearAllPoints()
|
||||
sectionAmmoBags:SetPoint("LEFT", sectionProjectiles, "RIGHT", 2, 0)
|
||||
|
||||
if sectionStable then
|
||||
sectionStable:ClearAllPoints()
|
||||
sectionStable:SetPoint("LEFT", sectionAmmoBags, "RIGHT", 2, 0)
|
||||
end
|
||||
|
||||
if sectionPetHistory then
|
||||
sectionPetHistory:ClearAllPoints()
|
||||
sectionPetHistory:SetPoint("LEFT", sectionAmmoBags, "RIGHT", 2, 0)
|
||||
if sectionStable then
|
||||
sectionPetHistory:SetPoint("LEFT", sectionStable, "RIGHT", 2, 0)
|
||||
else
|
||||
sectionPetHistory:SetPoint("LEFT", sectionAmmoBags, "RIGHT", 2, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5004,19 +5066,19 @@ local function MTH_BOOK_WireUI(frame)
|
||||
listSlider:SetScript("OnMouseDown", function()
|
||||
MTH_BOOK_STATE.sliderDragging = true
|
||||
MTH_BOOK_SetSliderFromCursor(this)
|
||||
this:SetScript("OnUpdate", function()
|
||||
if IsMouseButtonDown and not IsMouseButtonDown("LeftButton") then
|
||||
MTH_BOOK_STATE.sliderDragging = false
|
||||
this:SetScript("OnUpdate", nil)
|
||||
else
|
||||
MTH_BOOK_SetSliderFromCursor(this)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
listSlider:SetScript("OnMouseUp", function()
|
||||
MTH_BOOK_SetSliderFromCursor(this)
|
||||
MTH_BOOK_STATE.sliderDragging = false
|
||||
end)
|
||||
listSlider:SetScript("OnUpdate", function()
|
||||
if MTH_BOOK_STATE.sliderDragging then
|
||||
if IsMouseButtonDown and not IsMouseButtonDown("LeftButton") then
|
||||
MTH_BOOK_STATE.sliderDragging = false
|
||||
else
|
||||
MTH_BOOK_SetSliderFromCursor(this)
|
||||
end
|
||||
end
|
||||
this:SetScript("OnUpdate", nil)
|
||||
end)
|
||||
listSlider:SetScript("OnValueChanged", function()
|
||||
local value = this:GetValue()
|
||||
@@ -5119,19 +5181,19 @@ local function MTH_BOOK_WireUI(frame)
|
||||
sliderBackdrop:SetScript("OnMouseDown", function()
|
||||
MTH_BOOK_STATE.sliderDragging = true
|
||||
MTH_BOOK_SetSliderFromCursor(listSlider)
|
||||
listSlider:SetScript("OnUpdate", function()
|
||||
if IsMouseButtonDown and not IsMouseButtonDown("LeftButton") then
|
||||
MTH_BOOK_STATE.sliderDragging = false
|
||||
this:SetScript("OnUpdate", nil)
|
||||
else
|
||||
MTH_BOOK_SetSliderFromCursor(listSlider)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
sliderBackdrop:SetScript("OnMouseUp", function()
|
||||
MTH_BOOK_SetSliderFromCursor(listSlider)
|
||||
MTH_BOOK_STATE.sliderDragging = false
|
||||
end)
|
||||
sliderBackdrop:SetScript("OnUpdate", function()
|
||||
if MTH_BOOK_STATE.sliderDragging then
|
||||
if IsMouseButtonDown and not IsMouseButtonDown("LeftButton") then
|
||||
MTH_BOOK_STATE.sliderDragging = false
|
||||
else
|
||||
MTH_BOOK_SetSliderFromCursor(listSlider)
|
||||
end
|
||||
end
|
||||
listSlider:SetScript("OnUpdate", nil)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,7 +9,6 @@ local MTH_LOCALE_ALIASES = {
|
||||
enGB = "enUS",
|
||||
esMX = "esES",
|
||||
zhTW = "zhCN",
|
||||
frFR = "enUS",
|
||||
}
|
||||
|
||||
local MTH_SUPPORTED_LOCALES = {
|
||||
@@ -198,6 +197,9 @@ local MTH_SPELL_ID_BY_TOKEN = {
|
||||
["Counterattack"] = 19306,
|
||||
["Clever Traps"] = 19239,
|
||||
["Deterrence"] = 19263,
|
||||
["Entrapment"] = 19184,
|
||||
["Entrapment (Rank 2)"] = 19387,
|
||||
["Entrapment (Rank 3)"] = 19388,
|
||||
["Explosive Trap"] = 13813,
|
||||
["Explosive Trap Effect"] = 13812,
|
||||
["Feed Pet"] = 6991,
|
||||
|
||||
+94
-42
@@ -2,7 +2,7 @@ MTH_Map = {
|
||||
enabled = true,
|
||||
showWorld = true,
|
||||
showMinimap = true,
|
||||
activeSource = "beasts",
|
||||
activeSource = "focus",
|
||||
providers = {},
|
||||
nodesByZone = {},
|
||||
worldPins = {},
|
||||
@@ -21,6 +21,10 @@ MTH_Map = {
|
||||
lastWorldReason = "n/a",
|
||||
lastMiniReason = "n/a",
|
||||
nodeRevision = 0,
|
||||
minimapForceRefreshInterval = 1.0,
|
||||
verboseMiniReasons = false,
|
||||
minimapTickActive = 0.20,
|
||||
minimapTickIdle = 0.75,
|
||||
}
|
||||
|
||||
local MTH_MAP_MINIMAP_ZOOM = {
|
||||
@@ -468,7 +472,18 @@ local function MTH_Map_ClearPendingZoneOpen()
|
||||
MTH_Map.pendingZoneOpenNextAttemptAt = 0
|
||||
end
|
||||
|
||||
function MTH_Map:EnsureInitialized()
|
||||
if self.controller then
|
||||
return true
|
||||
end
|
||||
self:Init()
|
||||
return self.controller ~= nil
|
||||
end
|
||||
|
||||
function MTH_Map:SetSource(key)
|
||||
if not self:EnsureInitialized() then
|
||||
return false
|
||||
end
|
||||
if not self.providers[key] then
|
||||
return false
|
||||
end
|
||||
@@ -672,6 +687,9 @@ function MTH_Map:SetEnabled(enabled)
|
||||
if not self.enabled then
|
||||
self:HideAllPins()
|
||||
else
|
||||
if not self:EnsureInitialized() then
|
||||
return
|
||||
end
|
||||
self:UpdateWorldMap()
|
||||
self:UpdateMinimap()
|
||||
end
|
||||
@@ -682,6 +700,9 @@ function MTH_Map:SetWorldEnabled(enabled)
|
||||
if not self.showWorld then
|
||||
self:HideWorldPins()
|
||||
else
|
||||
if not self:EnsureInitialized() then
|
||||
return
|
||||
end
|
||||
self:UpdateWorldMap()
|
||||
end
|
||||
end
|
||||
@@ -691,6 +712,9 @@ function MTH_Map:SetMinimapEnabled(enabled)
|
||||
if not self.showMinimap then
|
||||
self:HideMinimapPins()
|
||||
else
|
||||
if not self:EnsureInitialized() then
|
||||
return
|
||||
end
|
||||
self:UpdateMinimap()
|
||||
end
|
||||
end
|
||||
@@ -952,22 +976,21 @@ function MTH_Map:UpdateMinimap()
|
||||
end
|
||||
|
||||
local mapId = self:GetCurrentMapID()
|
||||
if not mapId or not self.nodesByZone[mapId] then
|
||||
local nodes = mapId and self.nodesByZone[mapId] or nil
|
||||
if not mapId or not nodes then
|
||||
self.lastMiniReason = "no-mapid-or-nodes"
|
||||
self._lastMiniState = nil
|
||||
self:HideMinimapPins()
|
||||
return
|
||||
end
|
||||
|
||||
local minimapSizes = MTH_DS_MinimapSizes or (pfDB and pfDB["minimap"])
|
||||
local mapSize = minimapSizes and minimapSizes[mapId]
|
||||
if not mapSize then
|
||||
self.lastMiniReason = "missing-minimap-size"
|
||||
if table.getn(nodes) <= 0 then
|
||||
self.lastMiniReason = "no-nodes-in-zone"
|
||||
self._lastMiniState = nil
|
||||
self:HideMinimapPins()
|
||||
return
|
||||
end
|
||||
|
||||
local now = GetTime() or 0
|
||||
local xPlayer, yPlayer = GetPlayerMapPosition("player")
|
||||
if not xPlayer or not yPlayer or (xPlayer == 0 and yPlayer == 0) then
|
||||
self.lastMiniReason = "player-position-unavailable"
|
||||
@@ -980,10 +1003,33 @@ function MTH_Map:UpdateMinimap()
|
||||
yPlayer = yPlayer * 100
|
||||
|
||||
local zoom = Minimap:GetZoom()
|
||||
local miniState = self._lastMiniState
|
||||
if miniState
|
||||
and miniState.mapId == mapId
|
||||
and miniState.zoom == zoom
|
||||
and miniState.nodeRevision == (self.nodeRevision or 0)
|
||||
then
|
||||
local dx = math.abs((xPlayer or 0) - (miniState.xPlayer or 0))
|
||||
local dy = math.abs((yPlayer or 0) - (miniState.yPlayer or 0))
|
||||
if dx < 0.05 and dy < 0.05 and now < (miniState.nextForceAt or 0) then
|
||||
self.lastMiniReason = self.verboseMiniReasons and "throttled-small-move" or "throttle"
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local minimapSizes = MTH_DS_MinimapSizes or (pfDB and pfDB["minimap"])
|
||||
local mapSize = minimapSizes and minimapSizes[mapId]
|
||||
if not mapSize then
|
||||
self.lastMiniReason = self.verboseMiniReasons and "missing-minimap-size" or "missing-size"
|
||||
self._lastMiniState = nil
|
||||
self:HideMinimapPins()
|
||||
return
|
||||
end
|
||||
|
||||
local indoor = MTH_Map_MinimapIndoorState()
|
||||
local zoomSet = MTH_MAP_MINIMAP_ZOOM[indoor]
|
||||
if not zoomSet then
|
||||
self.lastMiniReason = "missing-zoomset"
|
||||
self.lastMiniReason = self.verboseMiniReasons and "missing-zoomset" or "missing-zoomset"
|
||||
self._lastMiniState = nil
|
||||
self:HideMinimapPins()
|
||||
return
|
||||
@@ -991,7 +1037,7 @@ function MTH_Map:UpdateMinimap()
|
||||
|
||||
local mapZoom = zoomSet[zoom]
|
||||
if not mapZoom then
|
||||
self.lastMiniReason = "missing-mapzoom"
|
||||
self.lastMiniReason = self.verboseMiniReasons and "missing-mapzoom" or "missing-zoom"
|
||||
self._lastMiniState = nil
|
||||
self:HideMinimapPins()
|
||||
return
|
||||
@@ -1000,33 +1046,16 @@ function MTH_Map:UpdateMinimap()
|
||||
local mapWidth = mapSize[1]
|
||||
local mapHeight = mapSize[2]
|
||||
if not mapWidth or not mapHeight or mapWidth == 0 or mapHeight == 0 then
|
||||
self.lastMiniReason = "invalid-map-size"
|
||||
self.lastMiniReason = self.verboseMiniReasons and "invalid-map-size" or "invalid-size"
|
||||
self._lastMiniState = nil
|
||||
self:HideMinimapPins()
|
||||
return
|
||||
end
|
||||
|
||||
local miniState = self._lastMiniState
|
||||
if miniState
|
||||
and miniState.mapId == mapId
|
||||
and miniState.zoom == zoom
|
||||
and miniState.indoor == indoor
|
||||
and miniState.nodeRevision == (self.nodeRevision or 0)
|
||||
then
|
||||
local dx = math.abs((xPlayer or 0) - (miniState.xPlayer or 0))
|
||||
local dy = math.abs((yPlayer or 0) - (miniState.yPlayer or 0))
|
||||
if dx < 0.05 and dy < 0.05 then
|
||||
self.lastMiniReason = "throttled-small-move"
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local xScale = mapZoom / mapWidth
|
||||
local yScale = mapZoom / mapHeight
|
||||
local xDraw = Minimap:GetWidth() / xScale / 100
|
||||
local yDraw = Minimap:GetHeight() / yScale / 100
|
||||
|
||||
local nodes = self.nodesByZone[mapId]
|
||||
local shown = 0
|
||||
|
||||
for i = 1, table.getn(nodes) do
|
||||
@@ -1057,16 +1086,21 @@ function MTH_Map:UpdateMinimap()
|
||||
if self.minimapPins[i] then self.minimapPins[i]:Hide() end
|
||||
end
|
||||
|
||||
self._lastMiniState = {
|
||||
mapId = mapId,
|
||||
zoom = zoom,
|
||||
indoor = indoor,
|
||||
xPlayer = xPlayer,
|
||||
yPlayer = yPlayer,
|
||||
nodeRevision = self.nodeRevision or 0,
|
||||
}
|
||||
local lastState = self._lastMiniState or {}
|
||||
lastState.mapId = mapId
|
||||
lastState.zoom = zoom
|
||||
lastState.indoor = indoor
|
||||
lastState.xPlayer = xPlayer
|
||||
lastState.yPlayer = yPlayer
|
||||
lastState.nodeRevision = self.nodeRevision or 0
|
||||
lastState.nextForceAt = now + (tonumber(self.minimapForceRefreshInterval) or 1.0)
|
||||
self._lastMiniState = lastState
|
||||
|
||||
self.lastMiniReason = "ok(map=" .. tostring(mapId) .. ",shown=" .. tostring(shown) .. ")"
|
||||
if self.verboseMiniReasons then
|
||||
self.lastMiniReason = "ok(map=" .. tostring(mapId) .. ",shown=" .. tostring(shown) .. ")"
|
||||
else
|
||||
self.lastMiniReason = "ok"
|
||||
end
|
||||
end
|
||||
|
||||
function MTH_Map:RegisterDefaultProviders()
|
||||
@@ -1202,12 +1236,15 @@ function MTH_Map:RegisterDefaultProviders()
|
||||
end
|
||||
|
||||
function MTH_Map:Init()
|
||||
if self.controller then
|
||||
return
|
||||
end
|
||||
self:BuildZoneLookup()
|
||||
self:RegisterDefaultProviders()
|
||||
self:RebuildNodes()
|
||||
self.nodesByZone = self.nodesByZone or {}
|
||||
|
||||
if not self.controller then
|
||||
self.controller = CreateFrame("Frame", "MTHMapController", UIParent)
|
||||
self.controller = CreateFrame("Frame", "MTH_MapController", UIParent)
|
||||
self.controller:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
self.controller:RegisterEvent("ZONE_CHANGED")
|
||||
self.controller:RegisterEvent("ZONE_CHANGED_NEW_AREA")
|
||||
@@ -1230,7 +1267,6 @@ function MTH_Map:Init()
|
||||
if not frame then return end
|
||||
local now = GetTime() or 0
|
||||
if (frame._mthTick or 0) > now then return end
|
||||
frame._mthTick = now + 0.12
|
||||
|
||||
if MTH_Map.pendingZoneOpenId and MTH_Map.pendingZoneOpenAttempts and MTH_Map.pendingZoneOpenAttempts > 0 then
|
||||
if (MTH_Map.pendingZoneOpenNextAttemptAt or 0) <= now then
|
||||
@@ -1259,12 +1295,28 @@ function MTH_Map:Init()
|
||||
end
|
||||
|
||||
if MTH_Map.enabled and MTH_Map.showMinimap then
|
||||
MTH_Map:UpdateMinimap()
|
||||
local mapId = MTH_Map:GetCurrentMapID()
|
||||
if not mapId and (frame._mthMapRecoverAt or 0) <= now then
|
||||
frame._mthMapRecoverAt = now + 2.0
|
||||
if SetMapToCurrentZone and (not WorldMapFrame or not WorldMapFrame:IsShown()) then
|
||||
SetMapToCurrentZone()
|
||||
mapId = MTH_Map:GetCurrentMapID()
|
||||
end
|
||||
end
|
||||
local nodes = mapId and MTH_Map.nodesByZone and MTH_Map.nodesByZone[mapId] or nil
|
||||
local hasNodes = nodes and table.getn(nodes) > 0
|
||||
frame._mthTick = now + (hasNodes and (tonumber(MTH_Map.minimapTickActive) or 0.20) or (tonumber(MTH_Map.minimapTickIdle) or 0.75))
|
||||
if hasNodes then
|
||||
MTH_Map:UpdateMinimap()
|
||||
elseif (frame._mthNoNodeTick or 0) <= now then
|
||||
frame._mthNoNodeTick = now + 1.0
|
||||
MTH_Map:UpdateMinimap()
|
||||
end
|
||||
else
|
||||
frame._mthTick = now + (tonumber(MTH_Map.minimapTickIdle) or 0.75)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
MTH_Map_Log("Map system initialized")
|
||||
end
|
||||
|
||||
MTH_Map:Init()
|
||||
|
||||
+29
-22
@@ -1,5 +1,13 @@
|
||||
------------------------------------------------------
|
||||
-- MetaHunt Minimap Button
|
||||
--
|
||||
-- NOTE: The namespace table is MTH_MinimapButton (a plain Lua table).
|
||||
-- The actual UI frame is named "MTH_MinimapBtn" to avoid a global
|
||||
-- collision — CreateFrame("...", "MTH_MinimapButton", ...) would
|
||||
-- OVERWRITE the namespace table with the frame object, orphaning
|
||||
-- all methods and .frame/.icon references. pfUI iterates Minimap
|
||||
-- children by name and calls _G[name]:GetHeight(); if the global is
|
||||
-- a plain {} table instead of a frame, that call crashes.
|
||||
------------------------------------------------------
|
||||
|
||||
if not MTH_MinimapButton then
|
||||
@@ -84,7 +92,9 @@ function MTH_MinimapButton:Initialize()
|
||||
return
|
||||
end
|
||||
|
||||
local button = CreateFrame("Button", "MTH_MinimapButtonFrame", Minimap)
|
||||
-- Frame name is MTH_MinimapBtn (NOT "MTH_MinimapButton") to avoid
|
||||
-- overwriting the namespace table in _G.
|
||||
local button = CreateFrame("Button", "MTH_MinimapBtn", Minimap)
|
||||
if not button then
|
||||
return
|
||||
end
|
||||
@@ -114,10 +124,9 @@ function MTH_MinimapButton:Initialize()
|
||||
highlight:SetHeight(31)
|
||||
highlight:SetPoint("CENTER", button, "CENTER", 0, 0)
|
||||
|
||||
button:SetScript("OnEnter", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
GameTooltip:SetOwner(self, "ANCHOR_LEFT")
|
||||
button:SetScript("OnEnter", function()
|
||||
if not this then return end
|
||||
GameTooltip:SetOwner(this, "ANCHOR_LEFT")
|
||||
GameTooltip:SetText(MTH_MB_L("MINIMAP_TITLE", "MetaHunt"), 1, 0.82, 0)
|
||||
GameTooltip:AddLine(MTH_MB_L("MINIMAP_HINT_LEFT_CLICK", "Left-Click: Open Hunter Book"), 1, 1, 1)
|
||||
GameTooltip:AddLine(MTH_MB_L("MINIMAP_HINT_RIGHT_CLICK", "Right-Click: Open MetaHunt Options"), 1, 1, 1)
|
||||
@@ -129,25 +138,23 @@ function MTH_MinimapButton:Initialize()
|
||||
GameTooltip:Hide()
|
||||
end)
|
||||
|
||||
button:SetScript("OnDragStart", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
self.dragging = 1
|
||||
self:SetScript("OnUpdate", function()
|
||||
button:SetScript("OnDragStart", function()
|
||||
if not this then return end
|
||||
this.dragging = 1
|
||||
this:SetScript("OnUpdate", function()
|
||||
MTH_MB_UpdateDragPosition()
|
||||
end)
|
||||
end)
|
||||
|
||||
button:SetScript("OnDragStop", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
self.dragging = nil
|
||||
self:SetScript("OnUpdate", nil)
|
||||
button:SetScript("OnDragStop", function()
|
||||
if not this then return end
|
||||
this.dragging = nil
|
||||
this:SetScript("OnUpdate", nil)
|
||||
MTH_MB_UpdateDragPosition()
|
||||
end)
|
||||
|
||||
button:SetScript("OnClick", function(_, mouseButton)
|
||||
mouseButton = mouseButton or arg1
|
||||
button:SetScript("OnClick", function()
|
||||
local mouseButton = arg1
|
||||
if mouseButton == "RightButton" then
|
||||
if type(MTH_OpenOptions) == "function" then
|
||||
MTH_OpenOptions("General")
|
||||
@@ -167,12 +174,12 @@ function MTH_MinimapButton:Initialize()
|
||||
MTH_MB_UpdatePosition()
|
||||
end
|
||||
|
||||
local loader = CreateFrame("Frame", "MTH_MinimapButtonLoader")
|
||||
local loader = CreateFrame("Frame", "MTH_MinimapLoader")
|
||||
loader:RegisterEvent("ADDON_LOADED")
|
||||
loader:SetScript("OnEvent", function(_, eventName, addonName)
|
||||
eventName = eventName or event
|
||||
addonName = addonName or arg1
|
||||
if eventName == "ADDON_LOADED" and addonName == "MetaHunt" then
|
||||
loader:SetScript("OnEvent", function()
|
||||
if event == "ADDON_LOADED" and arg1 == "MetaHunt" then
|
||||
MTH_MinimapButton:Initialize()
|
||||
this:UnregisterAllEvents()
|
||||
this:SetScript("OnEvent", nil)
|
||||
end
|
||||
end)
|
||||
|
||||
+45
-45
@@ -44,6 +44,8 @@ local MTH_AB_STATE = {
|
||||
},
|
||||
}
|
||||
|
||||
local MTH_AB_TRANSIENT_STORE = {}
|
||||
|
||||
local function MTH_AB_SetCheckedNoClick(check, checked)
|
||||
if not check then return end
|
||||
MTH_AB_STATE.syncing = true
|
||||
@@ -51,6 +53,14 @@ local function MTH_AB_SetCheckedNoClick(check, checked)
|
||||
MTH_AB_STATE.syncing = false
|
||||
end
|
||||
|
||||
local function MTH_AB_IsChecked(control)
|
||||
if not control or type(control.GetChecked) ~= "function" then
|
||||
return false
|
||||
end
|
||||
local checked = control:GetChecked()
|
||||
return checked == 1 or checked == true
|
||||
end
|
||||
|
||||
local function MTH_AB_GetEngine()
|
||||
return MTH_AutoBuyEngine
|
||||
end
|
||||
@@ -60,8 +70,7 @@ local function MTH_AB_GetStore()
|
||||
if engine and engine.EnsureDefaults then
|
||||
return engine:EnsureDefaults()
|
||||
end
|
||||
MTH_AutoBuy_Saved = MTH_AutoBuy_Saved or {}
|
||||
return MTH_AutoBuy_Saved
|
||||
return MTH_AB_TRANSIENT_STORE
|
||||
end
|
||||
|
||||
local function MTH_AB_NormalizeRule(rule)
|
||||
@@ -91,10 +100,10 @@ end
|
||||
|
||||
local function MTH_AB_EnsureConfig()
|
||||
local store = MTH_AB_GetStore()
|
||||
if store.enabled == nil then store.enabled = true end
|
||||
if store.enabled == nil then store.enabled = false end
|
||||
if type(store.projectiles) ~= "table" then store.projectiles = {} end
|
||||
if type(store.petFood) ~= "table" then store.petFood = {} end
|
||||
if store.projectiles.enabled == nil then store.projectiles.enabled = true end
|
||||
if store.projectiles.enabled == nil then store.projectiles.enabled = false end
|
||||
if store.petFood.enabled == nil then store.petFood.enabled = false end
|
||||
if store.petFood.stacks == nil then store.petFood.stacks = 1 end
|
||||
if store.petFood.scope == nil then store.petFood.scope = "current" end
|
||||
@@ -509,7 +518,7 @@ local function MTH_AB_RefreshOptionsUI()
|
||||
local store = MTH_AB_EnsureConfig()
|
||||
local moduleEnabled = true
|
||||
if MTH and MTH.IsModuleEnabled then
|
||||
moduleEnabled = MTH:IsModuleEnabled("autobuy", true) and true or false
|
||||
moduleEnabled = MTH:IsModuleEnabled("autobuy", false) and true or false
|
||||
end
|
||||
|
||||
MTH_AB_SetCheckedNoClick(MTH_AB_STATE.controls.moduleEnabled, moduleEnabled)
|
||||
@@ -648,28 +657,25 @@ local function MTH_AB_CreateRow(container, subtype, index, xBase, yOffset)
|
||||
row.suffix:SetText("Stacks")
|
||||
|
||||
if row.check then
|
||||
row.check:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self or MTH_AB_STATE.syncing then return end
|
||||
row.check:SetScript("OnClick", function()
|
||||
if not this or MTH_AB_STATE.syncing then return end
|
||||
local store = MTH_AB_EnsureConfig()
|
||||
MTH_AB_SetRuleEnabled(store, subtype, index, self:GetChecked() and true or false)
|
||||
MTH_AB_SetRuleEnabled(store, subtype, index, MTH_AB_IsChecked(this))
|
||||
MTH_AB_RefreshOptionsUI()
|
||||
end)
|
||||
end
|
||||
|
||||
row.qty:SetScript("OnEnterPressed", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
row.qty:SetScript("OnEnterPressed", function()
|
||||
if not this then return end
|
||||
local store = MTH_AB_EnsureConfig()
|
||||
MTH_AB_SetRuleStacks(store, subtype, index, self:GetText())
|
||||
MTH_AB_SetRuleStacks(store, subtype, index, this:GetText())
|
||||
MTH_AB_RefreshOptionsUI()
|
||||
self:ClearFocus()
|
||||
this:ClearFocus()
|
||||
end)
|
||||
row.qty:SetScript("OnEditFocusLost", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
row.qty:SetScript("OnEditFocusLost", function()
|
||||
if not this then return end
|
||||
local store = MTH_AB_EnsureConfig()
|
||||
MTH_AB_SetRuleStacks(store, subtype, index, self:GetText())
|
||||
MTH_AB_SetRuleStacks(store, subtype, index, this:GetText())
|
||||
MTH_AB_RefreshOptionsUI()
|
||||
end)
|
||||
|
||||
@@ -706,11 +712,10 @@ local function MTH_AB_BuildUI(container)
|
||||
|
||||
controls.moduleEnabled = MTH_CreateCheckbox(container, "MetaHuntOptionsAutoBuyModuleEnabled", "Enable Auto Buy module", -30)
|
||||
if controls.moduleEnabled then
|
||||
controls.moduleEnabled:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self or MTH_AB_STATE.syncing then return end
|
||||
controls.moduleEnabled:SetScript("OnClick", function()
|
||||
if not this or MTH_AB_STATE.syncing then return end
|
||||
if MTH and MTH.SetModuleEnabled then
|
||||
local ok, err = MTH:SetModuleEnabled("autobuy", self:GetChecked() and true or false)
|
||||
local ok, err = MTH:SetModuleEnabled("autobuy", MTH_AB_IsChecked(this))
|
||||
if not ok and MTH and MTH.Print then
|
||||
MTH:Print("Failed to change Auto Buy state: " .. tostring(err), "error")
|
||||
end
|
||||
@@ -721,11 +726,10 @@ local function MTH_AB_BuildUI(container)
|
||||
|
||||
controls.projectilesEnabled = MTH_CreateCheckbox(container, "MetaHuntOptionsAutoBuyProjectilesEnabled", "Enable for Projectiles", -74)
|
||||
if controls.projectilesEnabled then
|
||||
controls.projectilesEnabled:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self or MTH_AB_STATE.syncing then return end
|
||||
controls.projectilesEnabled:SetScript("OnClick", function()
|
||||
if not this or MTH_AB_STATE.syncing then return end
|
||||
local store = MTH_AB_EnsureConfig()
|
||||
store.projectiles.enabled = self:GetChecked() and true or false
|
||||
store.projectiles.enabled = MTH_AB_IsChecked(this)
|
||||
MTH_AB_RefreshOptionsUI()
|
||||
end)
|
||||
end
|
||||
@@ -760,11 +764,10 @@ local function MTH_AB_BuildUI(container)
|
||||
|
||||
controls.petFoodEnabled = MTH_CreateCheckbox(container, "MetaHuntOptionsAutoBuyPetFoodEnabled", "Enable for Pet Food", -322, MTH_AB_LAYOUT.LEFT_SECTION_X)
|
||||
if controls.petFoodEnabled then
|
||||
controls.petFoodEnabled:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self or MTH_AB_STATE.syncing then return end
|
||||
controls.petFoodEnabled:SetScript("OnClick", function()
|
||||
if not this or MTH_AB_STATE.syncing then return end
|
||||
local store = MTH_AB_EnsureConfig()
|
||||
store.petFood.enabled = self:GetChecked() and true or false
|
||||
store.petFood.enabled = MTH_AB_IsChecked(this)
|
||||
MTH_AB_RefreshOptionsUI()
|
||||
end)
|
||||
end
|
||||
@@ -782,19 +785,17 @@ local function MTH_AB_BuildUI(container)
|
||||
controls.petFoodQty:SetHeight(20)
|
||||
controls.petFoodQty:SetNumeric(true)
|
||||
controls.petFoodQty:SetAutoFocus(false)
|
||||
controls.petFoodQty:SetScript("OnEnterPressed", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
controls.petFoodQty:SetScript("OnEnterPressed", function()
|
||||
if not this then return end
|
||||
local store = MTH_AB_EnsureConfig()
|
||||
MTH_AB_SetPetFoodStacks(store, self:GetText())
|
||||
MTH_AB_SetPetFoodStacks(store, this:GetText())
|
||||
MTH_AB_RefreshOptionsUI()
|
||||
self:ClearFocus()
|
||||
this:ClearFocus()
|
||||
end)
|
||||
controls.petFoodQty:SetScript("OnEditFocusLost", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
controls.petFoodQty:SetScript("OnEditFocusLost", function()
|
||||
if not this then return end
|
||||
local store = MTH_AB_EnsureConfig()
|
||||
MTH_AB_SetPetFoodStacks(store, self:GetText())
|
||||
MTH_AB_SetPetFoodStacks(store, this:GetText())
|
||||
MTH_AB_RefreshOptionsUI()
|
||||
end)
|
||||
end
|
||||
@@ -807,9 +808,8 @@ local function MTH_AB_BuildUI(container)
|
||||
|
||||
controls.petFoodScopeCurrent = MTH_CreateCheckbox(container, "MetaHuntOptionsAutoBuyPetFoodScopeCurrent", "Buy only for my current pet", -376, MTH_AB_LAYOUT.LEFT_SECTION_X + 28)
|
||||
if controls.petFoodScopeCurrent then
|
||||
controls.petFoodScopeCurrent:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self or MTH_AB_STATE.syncing then return end
|
||||
controls.petFoodScopeCurrent:SetScript("OnClick", function()
|
||||
if not this or MTH_AB_STATE.syncing then return end
|
||||
local store = MTH_AB_EnsureConfig()
|
||||
store.petFood.scope = "current"
|
||||
MTH_AB_RefreshOptionsUI()
|
||||
@@ -818,9 +818,8 @@ local function MTH_AB_BuildUI(container)
|
||||
|
||||
controls.petFoodScopeAll = MTH_CreateCheckbox(container, "MetaHuntOptionsAutoBuyPetFoodScopeAll", "Buy for all my pets", -402, MTH_AB_LAYOUT.LEFT_SECTION_X + 28)
|
||||
if controls.petFoodScopeAll then
|
||||
controls.petFoodScopeAll:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self or MTH_AB_STATE.syncing then return end
|
||||
controls.petFoodScopeAll:SetScript("OnClick", function()
|
||||
if not this or MTH_AB_STATE.syncing then return end
|
||||
local store = MTH_AB_EnsureConfig()
|
||||
store.petFood.scope = "all"
|
||||
MTH_AB_RefreshOptionsUI()
|
||||
@@ -842,6 +841,7 @@ local function MTH_AB_BuildUI(container)
|
||||
text:SetText("")
|
||||
controls.petFoodPetLines[i] = { icon = icon, text = text }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function MTH_SetupAutoBuyOptions()
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
local MTH_AQ_READY = MTH_OptionsRequire and MTH_OptionsRequire("options-autoquest", {
|
||||
"MTH_GetFrame",
|
||||
"MTH_ClearContainer",
|
||||
"MTH_CreateCheckbox",
|
||||
})
|
||||
|
||||
local function MTH_AQ_IsChecked(control)
|
||||
if not control or type(control.GetChecked) ~= "function" then
|
||||
return false
|
||||
end
|
||||
local checked = control:GetChecked()
|
||||
return checked == 1 or checked == true
|
||||
end
|
||||
|
||||
local function MTH_AQ_EnsureStore()
|
||||
if type(MTH_CharSavedVariables) ~= "table" then
|
||||
MTH_CharSavedVariables = {}
|
||||
end
|
||||
if type(MTH_CharSavedVariables.autoquest) ~= "table" then
|
||||
MTH_CharSavedVariables.autoquest = {}
|
||||
end
|
||||
local store = MTH_CharSavedVariables.autoquest
|
||||
if type(MTH_CharSavedVariables.questautomation) == "table" then
|
||||
local legacy = MTH_CharSavedVariables.questautomation
|
||||
if store.scorpokDrazial == nil and legacy.scorpokDrazial ~= nil then
|
||||
store.scorpokDrazial = legacy.scorpokDrazial and true or false
|
||||
end
|
||||
if store.scorpokTooltip == nil and legacy.scorpokTooltip ~= nil then
|
||||
store.scorpokTooltip = legacy.scorpokTooltip and true or false
|
||||
end
|
||||
end
|
||||
if store.scorpokDrazial == nil then
|
||||
store.scorpokDrazial = false
|
||||
end
|
||||
if store.arrowsForSissies == nil then
|
||||
store.arrowsForSissies = false
|
||||
end
|
||||
return store
|
||||
end
|
||||
|
||||
function MTH_SetupAutoQuestOptions()
|
||||
if not MTH_AQ_READY then return end
|
||||
|
||||
local container = MTH_GetFrame("MetaHuntOptionsAutoQuest")
|
||||
if not container then return end
|
||||
|
||||
MTH_ClearContainer(container)
|
||||
|
||||
local title = container:CreateFontString("MetaHuntOptionsAutoQuestTitle", "ARTWORK", "GameFontHighlight")
|
||||
title:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -10)
|
||||
title:SetText("Auto Quest")
|
||||
|
||||
local body = container:CreateFontString("MetaHuntOptionsAutoQuestBody", "ARTWORK", "GameFontNormalSmall")
|
||||
body:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -30)
|
||||
body:SetWidth(560)
|
||||
body:SetJustifyH("LEFT")
|
||||
body:SetJustifyV("TOP")
|
||||
body:SetTextColor(0.45, 0.75, 1)
|
||||
body:SetText("Automation for specific quest interactions.")
|
||||
|
||||
local moduleEnabled = true
|
||||
if MTH and MTH.GetModule then
|
||||
local module = MTH:GetModule("autoquest")
|
||||
if type(module) == "table" and module.enabled ~= nil then
|
||||
moduleEnabled = module.enabled and true or false
|
||||
elseif MTH and MTH.IsModuleEnabled then
|
||||
moduleEnabled = MTH:IsModuleEnabled("autoquest", false) and true or false
|
||||
end
|
||||
elseif MTH and MTH.IsModuleEnabled then
|
||||
moduleEnabled = MTH:IsModuleEnabled("autoquest", false) and true or false
|
||||
end
|
||||
local moduleToggle = MTH_CreateCheckbox(container, "MetaHuntOptionsAutoQuestModuleToggle", "Enable Auto Quest module", -70, 20)
|
||||
if moduleToggle then
|
||||
moduleToggle:SetChecked(moduleEnabled and true or false)
|
||||
moduleToggle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local enabled = MTH_AQ_IsChecked(this)
|
||||
if MTH and MTH.SetModuleEnabled then
|
||||
local ok, err = MTH:SetModuleEnabled("autoquest", enabled)
|
||||
if not ok and MTH and MTH.Print then
|
||||
MTH:Print("Failed to change Auto Quest module state: " .. tostring(err), "error")
|
||||
end
|
||||
end
|
||||
local module = MTH and MTH.GetModule and MTH:GetModule("autoquest") or nil
|
||||
local actual = (type(module) == "table" and module.enabled ~= nil) and (module.enabled and true or false) or enabled
|
||||
this:SetChecked(actual and true or false)
|
||||
end)
|
||||
end
|
||||
|
||||
local store = MTH_AQ_EnsureStore()
|
||||
if store.scorpokTooltip == nil then
|
||||
store.scorpokTooltip = false
|
||||
end
|
||||
|
||||
local sectionWidth = (container:GetWidth() or 600) - 40
|
||||
if sectionWidth < 360 then
|
||||
sectionWidth = 360
|
||||
end
|
||||
|
||||
local function ensureSection(name, sectionTitle, yOffset, height)
|
||||
local section = getglobal(name)
|
||||
if not section then
|
||||
section = CreateFrame("Frame", name, container, "OptionFrameBoxTemplate")
|
||||
end
|
||||
if not section then
|
||||
return nil
|
||||
end
|
||||
section:SetParent(container)
|
||||
section:ClearAllPoints()
|
||||
section:SetPoint("TOPLEFT", container, "TOPLEFT", 20, yOffset)
|
||||
section:SetWidth(sectionWidth)
|
||||
section:SetHeight(height)
|
||||
section:Show()
|
||||
|
||||
local titleFrame = getglobal(name .. "Title")
|
||||
if titleFrame then
|
||||
titleFrame:SetText(sectionTitle)
|
||||
end
|
||||
return section
|
||||
end
|
||||
|
||||
local function ensureCheckbox(section, name, label, yOffset, checked)
|
||||
local check = getglobal(name)
|
||||
if not check then
|
||||
check = CreateFrame("CheckButton", name, section, "OptionsCheckButtonTemplate")
|
||||
end
|
||||
if not check then
|
||||
return nil
|
||||
end
|
||||
check:SetParent(section)
|
||||
check:ClearAllPoints()
|
||||
check:SetPoint("TOPLEFT", section, "TOPLEFT", 12, yOffset)
|
||||
check:SetChecked(checked and true or false)
|
||||
check:Show()
|
||||
|
||||
local text = getglobal(name .. "Text")
|
||||
if text then
|
||||
text:SetText(label)
|
||||
end
|
||||
return check
|
||||
end
|
||||
|
||||
local scorpokSection = ensureSection("MetaHuntAutoQuestScorpokBox", "Salt of the Scorpok", -130, 112)
|
||||
if scorpokSection then
|
||||
local scorpokToggle = ensureCheckbox(
|
||||
scorpokSection,
|
||||
"MetaHuntOptionsAutoQuestScorpokToggle",
|
||||
"Enable SHIFT-rightclick for Bloodmage Drazial",
|
||||
-10,
|
||||
store.scorpokDrazial and true or false
|
||||
)
|
||||
if scorpokToggle then
|
||||
scorpokToggle:SetScript("OnClick", function()
|
||||
local enabled = MTH_AQ_IsChecked(this)
|
||||
store.scorpokDrazial = enabled and true or false
|
||||
if MTH and MTH.GetModuleCharSavedVariables then
|
||||
local moduleStore = MTH:GetModuleCharSavedVariables("autoquest")
|
||||
if type(moduleStore) == "table" then
|
||||
moduleStore.scorpokDrazial = store.scorpokDrazial and true or false
|
||||
end
|
||||
end
|
||||
local module = MTH and MTH.GetModule and MTH:GetModule("autoquest")
|
||||
if module and module.SetScorpokDrazialEnabled then
|
||||
module:SetScorpokDrazialEnabled(enabled)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local tooltipToggle = ensureCheckbox(
|
||||
scorpokSection,
|
||||
"MetaHuntOptionsAutoQuestScorpokTooltipToggle",
|
||||
"Enhance Tooltip on Drazial and related beasts (requires Tooltips module enabled)",
|
||||
-42,
|
||||
store.scorpokTooltip and true or false
|
||||
)
|
||||
if tooltipToggle then
|
||||
tooltipToggle:SetScript("OnClick", function()
|
||||
local enabled = MTH_AQ_IsChecked(this)
|
||||
store.scorpokTooltip = enabled and true or false
|
||||
if MTH and MTH.GetModuleCharSavedVariables then
|
||||
local moduleStore = MTH:GetModuleCharSavedVariables("autoquest")
|
||||
if type(moduleStore) == "table" then
|
||||
moduleStore.scorpokTooltip = store.scorpokTooltip and true or false
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
local sissiesSection = ensureSection("MetaHuntAutoQuestSissiesBox", "Arrows Are For Sissies", -255, 108)
|
||||
if sissiesSection then
|
||||
local sissiesNote = getglobal("MetaHuntOptionsAutoQuestSissiesNote")
|
||||
if not sissiesNote then
|
||||
sissiesNote = sissiesSection:CreateFontString("MetaHuntOptionsAutoQuestSissiesNote", "ARTWORK", "GameFontNormalSmall")
|
||||
end
|
||||
sissiesNote:ClearAllPoints()
|
||||
sissiesNote:SetPoint("TOPLEFT", sissiesSection, "TOPLEFT", 14, -10)
|
||||
sissiesNote:SetWidth(sectionWidth - 28)
|
||||
sissiesNote:SetJustifyH("LEFT")
|
||||
sissiesNote:SetTextColor(0.45, 0.75, 1)
|
||||
sissiesNote:SetText("Note that you should not activate this if you are using LazyPig")
|
||||
sissiesNote:Show()
|
||||
|
||||
local sissiesToggle = ensureCheckbox(
|
||||
sissiesSection,
|
||||
"MetaHuntOptionsAutoQuestSissiesToggle",
|
||||
"Enable SHIFT-rightclick for Artilleryman Sheldonore",
|
||||
-40,
|
||||
store.arrowsForSissies and true or false
|
||||
)
|
||||
if sissiesToggle then
|
||||
sissiesToggle:SetScript("OnClick", function()
|
||||
local enabled = MTH_AQ_IsChecked(this)
|
||||
store.arrowsForSissies = enabled and true or false
|
||||
if MTH and MTH.GetModuleCharSavedVariables then
|
||||
local moduleStore = MTH:GetModuleCharSavedVariables("autoquest")
|
||||
if type(moduleStore) == "table" then
|
||||
moduleStore.arrowsForSissies = store.arrowsForSissies and true or false
|
||||
end
|
||||
end
|
||||
local module = MTH and MTH.GetModule and MTH:GetModule("autoquest")
|
||||
if module and module.SetArrowsForSissiesEnabled then
|
||||
module:SetArrowsForSissiesEnabled(enabled)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
+52
-39
@@ -98,11 +98,20 @@ local function MTH_CHRON_CopyTable(source)
|
||||
end
|
||||
|
||||
local function MTH_CHRON_GetProfile()
|
||||
if not (MTH and MTH.GetModuleSavedVariables) then
|
||||
if not (MTH and MTH.GetModuleCharSavedVariables) then
|
||||
return MTH_CHRON_CopyTable(MTH_CHRON_DEFAULTS)
|
||||
end
|
||||
|
||||
local store = MTH:GetModuleSavedVariables("chronometer")
|
||||
local store = MTH:GetModuleCharSavedVariables("chronometer")
|
||||
if type(store) ~= "table" then
|
||||
return MTH_CHRON_CopyTable(MTH_CHRON_DEFAULTS)
|
||||
end
|
||||
if type(store.profile) ~= "table" and MTH.GetModuleSavedVariables then
|
||||
local accountStore = MTH:GetModuleSavedVariables("chronometer")
|
||||
if type(accountStore) == "table" and type(accountStore.profile) == "table" then
|
||||
store.profile = MTH_CHRON_CopyTable(accountStore.profile)
|
||||
end
|
||||
end
|
||||
if type(store.profile) ~= "table" then
|
||||
store.profile = {}
|
||||
end
|
||||
@@ -298,6 +307,14 @@ local function MTH_CHRON_MakeSmall(parent, name, text, x, y)
|
||||
return label
|
||||
end
|
||||
|
||||
local function MTH_CHRON_IsChecked(control)
|
||||
if not control or type(control.GetChecked) ~= "function" then
|
||||
return false
|
||||
end
|
||||
local checked = control:GetChecked()
|
||||
return checked == 1 or checked == true
|
||||
end
|
||||
|
||||
|
||||
local function MTH_CHRON_MakeInput(parent, name, x, y, width, height, value, onAccept)
|
||||
local edit = CreateFrame("EditBox", name, parent, "InputBoxTemplate")
|
||||
@@ -309,13 +326,12 @@ local function MTH_CHRON_MakeInput(parent, name, x, y, width, height, value, onA
|
||||
edit:SetHeight(height or 20)
|
||||
edit:SetAutoFocus(false)
|
||||
edit:SetText(tostring(value or ""))
|
||||
edit:SetScript("OnEnterPressed", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
edit:SetScript("OnEnterPressed", function()
|
||||
if not this then return end
|
||||
if type(onAccept) == "function" then
|
||||
onAccept(self:GetText() or "")
|
||||
onAccept(this:GetText() or "")
|
||||
end
|
||||
self:ClearFocus()
|
||||
this:ClearFocus()
|
||||
end)
|
||||
return edit
|
||||
end
|
||||
@@ -368,14 +384,18 @@ local function MTH_CHRON_RenderTimerSection(container, profile, title, items, bu
|
||||
local check = MTH_CreateCheckbox(container, controlName, label, timerY, timerX)
|
||||
if check then
|
||||
check:SetChecked(profile.disabledSpells[bucket][timerName] == nil and true or false)
|
||||
check:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
if self:GetChecked() then
|
||||
check:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local currentlyDisabled = profile.disabledSpells[bucket][timerName] ~= nil
|
||||
if currentlyDisabled then
|
||||
profile.disabledSpells[bucket][timerName] = nil
|
||||
this:SetChecked(true)
|
||||
else
|
||||
profile.disabledSpells[bucket][timerName] = {}
|
||||
this:SetChecked(nil)
|
||||
end
|
||||
|
||||
MTH_CHRON_ApplyLiveProfile(profile)
|
||||
end)
|
||||
end
|
||||
timerY = timerY - 20
|
||||
@@ -448,10 +468,9 @@ function MTH_SetupChronometerOptions(tabKey)
|
||||
if moduleCheck then
|
||||
local module = MTH and MTH:GetModule("chronometer")
|
||||
moduleCheck:SetChecked(module and module.enabled and true or false)
|
||||
moduleCheck:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local enabled = self:GetChecked() and true or false
|
||||
moduleCheck:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local enabled = MTH_CHRON_IsChecked(this)
|
||||
if MTH and MTH.SetModuleEnabled then
|
||||
MTH:SetModuleEnabled("chronometer", enabled)
|
||||
end
|
||||
@@ -473,40 +492,36 @@ function MTH_SetupChronometerOptions(tabKey)
|
||||
local killCheck = MTH_CreateCheckbox(container, "MetaHuntOptionsChronometerFadeOnKill", "Fade on kill", -154)
|
||||
if killCheck then
|
||||
killCheck:SetChecked(profile.fadeonkill and true or false)
|
||||
killCheck:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
profile.fadeonkill = self:GetChecked() and true or false
|
||||
killCheck:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
profile.fadeonkill = MTH_CHRON_IsChecked(this)
|
||||
end)
|
||||
end
|
||||
|
||||
local fadeCheck = MTH_CreateCheckbox(container, "MetaHuntOptionsChronometerFadeOnFade", "Fade on aura fade", -179)
|
||||
if fadeCheck then
|
||||
fadeCheck:SetChecked(profile.fadeonfade and true or false)
|
||||
fadeCheck:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
profile.fadeonfade = self:GetChecked() and true or false
|
||||
fadeCheck:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
profile.fadeonfade = MTH_CHRON_IsChecked(this)
|
||||
end)
|
||||
end
|
||||
|
||||
local selfCheck = MTH_CreateCheckbox(container, "MetaHuntOptionsChronometerSelfBars", "Show self bars", -204)
|
||||
if selfCheck then
|
||||
selfCheck:SetChecked(profile.selfbars and true or false)
|
||||
selfCheck:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
profile.selfbars = self:GetChecked() and true or false
|
||||
selfCheck:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
profile.selfbars = MTH_CHRON_IsChecked(this)
|
||||
end)
|
||||
end
|
||||
|
||||
local onlySelfCheck = MTH_CreateCheckbox(container, "MetaHuntOptionsChronometerOnlySelf", "Only self target", -229)
|
||||
if onlySelfCheck then
|
||||
onlySelfCheck:SetChecked(profile.onlyself and true or false)
|
||||
onlySelfCheck:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
profile.onlyself = self:GetChecked() and true or false
|
||||
onlySelfCheck:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
profile.onlyself = MTH_CHRON_IsChecked(this)
|
||||
end)
|
||||
end
|
||||
elseif section == "bar" then
|
||||
@@ -588,10 +603,9 @@ function MTH_SetupChronometerOptions(tabKey)
|
||||
local growCheck = MTH_CreateCheckbox(container, "MetaHuntOptionsChronometerGrowUp", "Grow bars upward", -438)
|
||||
if growCheck then
|
||||
growCheck:SetChecked(profile.growup and true or false)
|
||||
growCheck:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
profile.growup = self:GetChecked() and true or false
|
||||
growCheck:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
profile.growup = MTH_CHRON_IsChecked(this)
|
||||
MTH_CHRON_ApplyLiveProfile(profile)
|
||||
end)
|
||||
end
|
||||
@@ -599,10 +613,9 @@ function MTH_SetupChronometerOptions(tabKey)
|
||||
local reverseCheck = MTH_CreateCheckbox(container, "MetaHuntOptionsChronometerReverse", "Reverse bars", -463)
|
||||
if reverseCheck then
|
||||
reverseCheck:SetChecked(profile.reverse and true or false)
|
||||
reverseCheck:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
profile.reverse = self:GetChecked() and true or false
|
||||
reverseCheck:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
profile.reverse = MTH_CHRON_IsChecked(this)
|
||||
MTH_CHRON_ApplyLiveProfile(profile)
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -159,6 +159,16 @@ function MTH_SetupCreditsOptions()
|
||||
cursor,
|
||||
-4)
|
||||
|
||||
|
||||
cursor = MTH_CreditsCreateText(content, cursor,
|
||||
MTH_CR_L("CREDITS_ABOUT_ICU", "- ICU was an old vanilla addon. I used the following last revision and added many more features of config options to it."),
|
||||
"GameFontNormalSmall", -10)
|
||||
cursor = MTH_CreditsCreateLink(content,
|
||||
"https://github.com/wigan91/ICU-TWoW",
|
||||
"https://github.com/wigan91/ICU-TWoW",
|
||||
cursor,
|
||||
-4)
|
||||
|
||||
cursor = MTH_CreditsCreateText(content, cursor,
|
||||
MTH_CR_L("CREDITS_ABOUT_MAP", "- The Map/Marker system is the one of pfQuest from Master Shagu. Unfortunately he is no more reachable for some months and I could not have some talk with him about this. I mostly let it untouched, I just made slight modifications so it can integrate better within Metahunt, and doesn't conflict with pfQuest."),
|
||||
"GameFontNormalSmall", -10)
|
||||
|
||||
+18
-20
@@ -226,10 +226,9 @@ function MTH_SetupFeedOMaticOptions()
|
||||
|
||||
local moduleCheck = MTH_CreateCheckbox(container, "MetaHuntOptionsFeedOMaticEnabled", MTH_FOM_L("FOM_ENABLE_MODULE", "Enable FeedOMatic module"), -32 + yAdjust)
|
||||
if moduleCheck then
|
||||
moduleCheck:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local enabled = self:GetChecked() == 1
|
||||
moduleCheck:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local enabled = this:GetChecked() == 1
|
||||
if MTH and MTH.SetModuleEnabled then
|
||||
local ok, err = MTH:SetModuleEnabled("feedomatic", enabled)
|
||||
if not ok and MTH and MTH.Print then
|
||||
@@ -263,11 +262,11 @@ function MTH_SetupFeedOMaticOptions()
|
||||
MTH_FOM_StartBindingCapture()
|
||||
end
|
||||
end)
|
||||
bindButton:SetScript("OnKeyDown", function(_, key)
|
||||
bindButton:SetScript("OnKeyDown", function()
|
||||
if not MTH_FOM_STATE.bindingCapture then
|
||||
return
|
||||
end
|
||||
key = key or arg1
|
||||
local key = arg1
|
||||
if not key or key == "" then
|
||||
return
|
||||
end
|
||||
@@ -305,10 +304,10 @@ function MTH_SetupFeedOMaticOptions()
|
||||
MTH_FOM_STATE.ctrl.PreferHigherQuality = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMPreferQuality", FOM_OptionsButtonText and FOM_OptionsButtonText["PreferHigherQuality"] or MTH_FOM_L("FOM_LABEL_PREFER_HIGHER_QUALITY_FOOD", "Prefer higher quality food"), -220 + yAdjust)
|
||||
MTH_FOM_STATE.ctrl.Fallback = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMFallback", FOM_OptionsButtonText and FOM_OptionsButtonText["Fallback"] or MTH_FOM_L("FOM_LABEL_FALLBACK_TO_AVOIDED_FOODS", "Fallback to avoided foods"), -245 + yAdjust)
|
||||
|
||||
if MTH_FOM_STATE.ctrl.AvoidQuestFood then MTH_FOM_STATE.ctrl.AvoidQuestFood:SetScript("OnClick", function(self) self = self or this if not self then return end FOM_Config.AvoidQuestFood = self:GetChecked() == 1 end) end
|
||||
if MTH_FOM_STATE.ctrl.AvoidBonusFood then MTH_FOM_STATE.ctrl.AvoidBonusFood:SetScript("OnClick", function(self) self = self or this if not self then return end FOM_Config.AvoidBonusFood = self:GetChecked() == 1 end) end
|
||||
if MTH_FOM_STATE.ctrl.PreferHigherQuality then MTH_FOM_STATE.ctrl.PreferHigherQuality:SetScript("OnClick", function(self) self = self or this if not self then return end FOM_Config.PreferHigherQuality = self:GetChecked() == 1 end) end
|
||||
if MTH_FOM_STATE.ctrl.Fallback then MTH_FOM_STATE.ctrl.Fallback:SetScript("OnClick", function(self) self = self or this if not self then return end FOM_Config.Fallback = self:GetChecked() == 1 end) end
|
||||
if MTH_FOM_STATE.ctrl.AvoidQuestFood then MTH_FOM_STATE.ctrl.AvoidQuestFood:SetScript("OnClick", function() if not this then return end FOM_Config.AvoidQuestFood = this:GetChecked() == 1 end) end
|
||||
if MTH_FOM_STATE.ctrl.AvoidBonusFood then MTH_FOM_STATE.ctrl.AvoidBonusFood:SetScript("OnClick", function() if not this then return end FOM_Config.AvoidBonusFood = this:GetChecked() == 1 end) end
|
||||
if MTH_FOM_STATE.ctrl.PreferHigherQuality then MTH_FOM_STATE.ctrl.PreferHigherQuality:SetScript("OnClick", function() if not this then return end FOM_Config.PreferHigherQuality = this:GetChecked() == 1 end) end
|
||||
if MTH_FOM_STATE.ctrl.Fallback then MTH_FOM_STATE.ctrl.Fallback:SetScript("OnClick", function() if not this then return end FOM_Config.Fallback = this:GetChecked() == 1 end) end
|
||||
|
||||
local keepOpenLabel = container:CreateFontString("MetaHuntOptionsFOMKeepOpenLabel", "ARTWORK", "GameFontNormalSmall")
|
||||
keepOpenLabel:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -302 + yAdjust)
|
||||
@@ -320,14 +319,13 @@ function MTH_SetupFeedOMaticOptions()
|
||||
keepOpen:SetHeight(20)
|
||||
keepOpen:SetNumeric(true)
|
||||
keepOpen:SetAutoFocus(false)
|
||||
keepOpen:SetScript("OnTextChanged", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local value = tonumber(self:GetText()) or 0
|
||||
keepOpen:SetScript("OnTextChanged", function()
|
||||
if not this then return end
|
||||
local value = tonumber(this:GetText()) or 0
|
||||
FOM_Config.KeepOpenSlots = value
|
||||
end)
|
||||
keepOpen:SetScript("OnEnterPressed", function(self) self = self or this if self then self:ClearFocus() end end)
|
||||
keepOpen:SetScript("OnEscapePressed", function(self) self = self or this if self then self:ClearFocus() end end)
|
||||
keepOpen:SetScript("OnEnterPressed", function() if this then this:ClearFocus() end end)
|
||||
keepOpen:SetScript("OnEscapePressed", function() if this then this:ClearFocus() end end)
|
||||
MTH_FOM_STATE.keepOpenEdit = keepOpen
|
||||
|
||||
local notifyHeader = container:CreateFontString("MetaHuntOptionsFOMNotifyHeader", "ARTWORK", "GameFontHighlight")
|
||||
@@ -356,10 +354,10 @@ function MTH_SetupFeedOMaticOptions()
|
||||
MTH_FOM_STATE.ctrl.AudioWarningBell = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAudioWarningBell", FOM_OptionsButtonText and FOM_OptionsButtonText["AudioWarningBell"] or MTH_FOM_L("FOM_LABEL_USE_BELL_SOUND", "Use bell sound"), -403 + yAdjust, rightColumnX)
|
||||
MTH_FOM_STATE.ctrl.TextWarning = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMTextWarning", FOM_OptionsButtonText and FOM_OptionsButtonText["TextWarning"] or MTH_FOM_L("FOM_LABEL_SHOW_TEXT", "Show text"), -428 + yAdjust, rightColumnX)
|
||||
MTH_FOM_STATE.ctrl.IconWarning = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMIconWarning", FOM_OptionsButtonText and FOM_OptionsButtonText["IconWarning"] or MTH_FOM_L("FOM_LABEL_FLASH_ICON", "Flash icon"), -453 + yAdjust, rightColumnX)
|
||||
if MTH_FOM_STATE.ctrl.AudioWarning then MTH_FOM_STATE.ctrl.AudioWarning:SetScript("OnClick", function(self) self = self or this if not self then return end if self:GetChecked() == 1 then if FOM_Config.AudioWarning ~= "bell" then FOM_Config.AudioWarning = true end else FOM_Config.AudioWarning = nil end MTH_RefreshFeedOMaticOptions() end) end
|
||||
if MTH_FOM_STATE.ctrl.AudioWarningBell then MTH_FOM_STATE.ctrl.AudioWarningBell:SetScript("OnClick", function(self) self = self or this if not self then return end if self:GetChecked() == 1 then FOM_Config.AudioWarning = "bell" else FOM_Config.AudioWarning = true end MTH_RefreshFeedOMaticOptions() end) end
|
||||
if MTH_FOM_STATE.ctrl.TextWarning then MTH_FOM_STATE.ctrl.TextWarning:SetScript("OnClick", function(self) self = self or this if not self then return end FOM_Config.TextWarning = self:GetChecked() == 1 end) end
|
||||
if MTH_FOM_STATE.ctrl.IconWarning then MTH_FOM_STATE.ctrl.IconWarning:SetScript("OnClick", function(self) self = self or this if not self then return end FOM_Config.IconWarning = self:GetChecked() == 1 end) end
|
||||
if MTH_FOM_STATE.ctrl.AudioWarning then MTH_FOM_STATE.ctrl.AudioWarning:SetScript("OnClick", function() if not this then return end if this:GetChecked() == 1 then if FOM_Config.AudioWarning ~= "bell" then FOM_Config.AudioWarning = true end else FOM_Config.AudioWarning = nil end MTH_RefreshFeedOMaticOptions() end) end
|
||||
if MTH_FOM_STATE.ctrl.AudioWarningBell then MTH_FOM_STATE.ctrl.AudioWarningBell:SetScript("OnClick", function() if not this then return end if this:GetChecked() == 1 then FOM_Config.AudioWarning = "bell" else FOM_Config.AudioWarning = true end MTH_RefreshFeedOMaticOptions() end) end
|
||||
if MTH_FOM_STATE.ctrl.TextWarning then MTH_FOM_STATE.ctrl.TextWarning:SetScript("OnClick", function() if not this then return end FOM_Config.TextWarning = this:GetChecked() == 1 end) end
|
||||
if MTH_FOM_STATE.ctrl.IconWarning then MTH_FOM_STATE.ctrl.IconWarning:SetScript("OnClick", function() if not this then return end FOM_Config.IconWarning = this:GetChecked() == 1 end) end
|
||||
|
||||
local cookHeader = container:CreateFontString("MetaHuntOptionsFOMCookingHeader", "ARTWORK", "GameFontHighlight")
|
||||
cookHeader:SetPoint("TOPLEFT", container, "TOPLEFT", rightColumnX, -62 + yAdjust)
|
||||
|
||||
@@ -0,0 +1,590 @@
|
||||
local MTH_ICU_OPT_READY = true
|
||||
local MTH_ICU_OPT_MISSING = {}
|
||||
|
||||
if type(MTH_GetFrame) ~= "function" then table.insert(MTH_ICU_OPT_MISSING, "MTH_GetFrame") end
|
||||
if type(MTH_ClearContainer) ~= "function" then table.insert(MTH_ICU_OPT_MISSING, "MTH_ClearContainer") end
|
||||
if type(MTH_CreateCheckbox) ~= "function" then table.insert(MTH_ICU_OPT_MISSING, "MTH_CreateCheckbox") end
|
||||
|
||||
if table.getn(MTH_ICU_OPT_MISSING) > 0 then
|
||||
MTH_ICU_OPT_READY = false
|
||||
if MTH and MTH.Print then
|
||||
MTH:Print("[MTH ICU OPTIONS] missing dependencies: " .. table.concat(MTH_ICU_OPT_MISSING, ", "), "error")
|
||||
end
|
||||
end
|
||||
|
||||
local MTH_ICU_OPT_STATE = {
|
||||
container = nil,
|
||||
built = false,
|
||||
controls = {},
|
||||
}
|
||||
|
||||
local MTH_ICU_LAYOUT = {
|
||||
LEFT_X = 20,
|
||||
LEFT_DROPDOWN_X = 94,
|
||||
RIGHT_X = 280,
|
||||
RIGHT_DROPDOWN_X = 366,
|
||||
DROPDOWN_WIDTH = 108,
|
||||
COLOR_BUTTON_X = 378,
|
||||
COLOR_BUTTON_WIDTH = 78,
|
||||
COLOR_ROW_STEP = 24,
|
||||
}
|
||||
|
||||
local MTH_ICU_OPTIONS_FALLBACK = {
|
||||
ALERT = { "AUTO", "PARTY", "RAID", "SELF", "MTH Message", "OFF" },
|
||||
ANNOUNCE = { "AUTO", "SAY", "YELL", "PARTY", "RAID", "SELF", "MTH Message", "OFF" },
|
||||
ANCHOR = { "TOP", "TOPLEFT", "TOPRIGHT", "BOTTOM", "BOTTOMLEFT", "BOTTOMRIGHT", "LEFT", "RIGHT", "CUSTOM" },
|
||||
POPUP_HIDE_DELAY = { "INSTANT", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" },
|
||||
HEALTH_TEXT_MODE = { "NONE", "PERCENT", "HP", "BOTH" },
|
||||
PLAYER_COLOR_MODE = { "CLASS", "REACTION", "FACTION", "CUSTOM" },
|
||||
}
|
||||
|
||||
local MTH_ICU_DEFAULT_BG_COLORS = {
|
||||
PLAYER_HOSTILE = { 1.00, 0.20, 0.20 },
|
||||
PLAYER_NEUTRAL = { 1.00, 0.85, 0.10 },
|
||||
PLAYER_FRIENDLY = { 0.20, 0.75, 1.00 },
|
||||
NPC_HOSTILE = { 1.00, 0.20, 0.20 },
|
||||
NPC_NEUTRAL = { 1.00, 0.85, 0.10 },
|
||||
NPC_FRIENDLY = { 0.10, 0.90, 0.10 },
|
||||
UNKNOWN = { 0.70, 0.70, 0.70 },
|
||||
}
|
||||
|
||||
local MTH_ICU_COLOR_ROWS = {
|
||||
{ key = "PLAYER_HOSTILE", label = "Player hostile" },
|
||||
{ key = "PLAYER_NEUTRAL", label = "Player neutral" },
|
||||
{ key = "PLAYER_FRIENDLY", label = "Player friendly" },
|
||||
{ key = "NPC_HOSTILE", label = "NPC hostile" },
|
||||
{ key = "NPC_NEUTRAL", label = "NPC neutral" },
|
||||
{ key = "NPC_FRIENDLY", label = "NPC friendly" },
|
||||
{ key = "UNKNOWN", label = "Unknown fallback" },
|
||||
}
|
||||
|
||||
local function MTH_ICU_GetStore()
|
||||
local store = nil
|
||||
if MTH and MTH.GetModuleCharSavedVariables then
|
||||
store = MTH:GetModuleCharSavedVariables("icu")
|
||||
end
|
||||
if type(store) ~= "table" then
|
||||
ICUvars = ICUvars or {}
|
||||
store = ICUvars
|
||||
end
|
||||
|
||||
if store.ALERT == nil then store.ALERT = "MTH Message" end
|
||||
if store.ALERT == "SAY" or store.ALERT == "YELL" then store.ALERT = "SELF" end
|
||||
if store.ANNOUNCE == nil then store.ANNOUNCE = "MTH Message" end
|
||||
if store.ANCHOR == nil then store.ANCHOR = "BOTTOMRIGHT" end
|
||||
if store.POPUP_HIDE_DELAY == nil then
|
||||
store.POPUP_HIDE_DELAY = "INSTANT"
|
||||
else
|
||||
local rawDelay = tostring(store.POPUP_HIDE_DELAY)
|
||||
if rawDelay ~= "INSTANT" then
|
||||
local n = tonumber(rawDelay)
|
||||
if not n then
|
||||
store.POPUP_HIDE_DELAY = "INSTANT"
|
||||
else
|
||||
n = math.floor(n)
|
||||
if n < 1 then
|
||||
store.POPUP_HIDE_DELAY = "INSTANT"
|
||||
elseif n > 10 then
|
||||
store.POPUP_HIDE_DELAY = "10"
|
||||
else
|
||||
store.POPUP_HIDE_DELAY = tostring(n)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if store.mouseOver == nil then store.mouseOver = false end
|
||||
if store.HEALTH_TEXT_MODE == nil then store.HEALTH_TEXT_MODE = "BOTH" end
|
||||
if store.HEALTH_TEXT_MODE == "AUTO" then store.HEALTH_TEXT_MODE = "BOTH" end
|
||||
if store.PLAYER_COLOR_MODE == nil then store.PLAYER_COLOR_MODE = "CLASS" end
|
||||
if store.REACTION_ONLY_PVP_PLAYERS == nil then store.REACTION_ONLY_PVP_PLAYERS = true end
|
||||
if store.SHOW_GUILD_NAME == nil then store.SHOW_GUILD_NAME = false end
|
||||
if store.SHOW_PLAYER_CLASS == nil then store.SHOW_PLAYER_CLASS = true end
|
||||
if store.SHOW_PLAYER_RACE == nil then store.SHOW_PLAYER_RACE = true end
|
||||
if store.SHOW_CUSTOM_TITLES == nil then store.SHOW_CUSTOM_TITLES = false end
|
||||
if store.EXPAND_UP == nil then store.EXPAND_UP = false end
|
||||
|
||||
if type(store.COLORS) ~= "table" then
|
||||
store.COLORS = {}
|
||||
end
|
||||
for key, def in pairs(MTH_ICU_DEFAULT_BG_COLORS) do
|
||||
if type(store.COLORS[key]) ~= "table" then
|
||||
store.COLORS[key] = { def[1], def[2], def[3] }
|
||||
end
|
||||
end
|
||||
|
||||
ICUvars = store
|
||||
return store
|
||||
end
|
||||
|
||||
local function MTH_ICU_GetOptionValues(key)
|
||||
if type(ICU_OPTIONS) == "table" and type(ICU_OPTIONS[key]) == "table" then
|
||||
return ICU_OPTIONS[key]
|
||||
end
|
||||
return MTH_ICU_OPTIONS_FALLBACK[key] or {}
|
||||
end
|
||||
|
||||
local function MTH_ICU_SetValue(key, value)
|
||||
local store = MTH_ICU_GetStore()
|
||||
store[key] = tostring(value or "")
|
||||
if key == "ANCHOR" and type(ICU_SetPoints) == "function" then
|
||||
ICU_SetPoints()
|
||||
end
|
||||
end
|
||||
|
||||
local function MTH_ICU_DropdownSetText(frame, text)
|
||||
if UIDropDownMenu_SetText then
|
||||
UIDropDownMenu_SetText(tostring(text or ""), frame)
|
||||
return
|
||||
end
|
||||
if not frame or not frame.GetName then return end
|
||||
local textRegion = getglobal(frame:GetName() .. "Text")
|
||||
if textRegion and textRegion.SetText then
|
||||
textRegion:SetText(tostring(text or ""))
|
||||
end
|
||||
end
|
||||
|
||||
local function MTH_ICU_GetColor(key)
|
||||
local store = MTH_ICU_GetStore()
|
||||
local row = store.COLORS and store.COLORS[key]
|
||||
if type(row) == "table" then
|
||||
return tonumber(row[1]) or 0, tonumber(row[2]) or 0, tonumber(row[3]) or 0
|
||||
end
|
||||
local def = MTH_ICU_DEFAULT_BG_COLORS[key] or MTH_ICU_DEFAULT_BG_COLORS.UNKNOWN
|
||||
return def[1], def[2], def[3]
|
||||
end
|
||||
|
||||
local function MTH_ICU_SetColor(key, r, g, b)
|
||||
local store = MTH_ICU_GetStore()
|
||||
if type(store.COLORS) ~= "table" then
|
||||
store.COLORS = {}
|
||||
end
|
||||
store.COLORS[key] = {
|
||||
math.max(0, math.min(1, tonumber(r) or 0)),
|
||||
math.max(0, math.min(1, tonumber(g) or 0)),
|
||||
math.max(0, math.min(1, tonumber(b) or 0)),
|
||||
}
|
||||
end
|
||||
|
||||
local function MTH_ICU_OpenColorPicker(colorKey)
|
||||
if not ColorPickerFrame then
|
||||
if MTH and MTH.Print then
|
||||
MTH:Print("ColorPickerFrame is not available in this client", "error")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local currentR, currentG, currentB = MTH_ICU_GetColor(colorKey)
|
||||
local function applyColor()
|
||||
local r, g, b = ColorPickerFrame:GetColorRGB()
|
||||
MTH_ICU_SetColor(colorKey, r, g, b)
|
||||
MTH_RefreshICUOptions()
|
||||
end
|
||||
|
||||
ColorPickerFrame.func = applyColor
|
||||
ColorPickerFrame.cancelFunc = function(prev)
|
||||
if type(prev) == "table" then
|
||||
local r = prev.r or prev[1] or currentR
|
||||
local g = prev.g or prev[2] or currentG
|
||||
local b = prev.b or prev[3] or currentB
|
||||
MTH_ICU_SetColor(colorKey, r, g, b)
|
||||
MTH_RefreshICUOptions()
|
||||
end
|
||||
end
|
||||
ColorPickerFrame:SetColorRGB(currentR, currentG, currentB)
|
||||
ColorPickerFrame.hasOpacity = false
|
||||
ColorPickerFrame.opacity = 1
|
||||
ColorPickerFrame.previousValues = { currentR, currentG, currentB }
|
||||
ColorPickerFrame:Show()
|
||||
end
|
||||
|
||||
local function MTH_ICU_CreateOptionRow(container, rowName, label, key, y, labelX, dropdownX)
|
||||
labelX = labelX or MTH_ICU_LAYOUT.LEFT_X
|
||||
dropdownX = dropdownX or MTH_ICU_LAYOUT.LEFT_DROPDOWN_X
|
||||
|
||||
local labelFs = container:CreateFontString(rowName .. "Label", "ARTWORK", "GameFontNormalSmall")
|
||||
labelFs:SetPoint("TOPLEFT", container, "TOPLEFT", labelX, y)
|
||||
labelFs:SetText(label)
|
||||
|
||||
local dropdown = CreateFrame("Frame", rowName .. "Drop", container, "UIDropDownMenuTemplate")
|
||||
dropdown:ClearAllPoints()
|
||||
dropdown:SetPoint("TOPLEFT", container, "TOPLEFT", dropdownX, y + 12)
|
||||
if UIDropDownMenu_SetWidth then
|
||||
UIDropDownMenu_SetWidth(MTH_ICU_LAYOUT.DROPDOWN_WIDTH, dropdown)
|
||||
end
|
||||
if UIDropDownMenu_JustifyText then
|
||||
UIDropDownMenu_JustifyText("LEFT", dropdown)
|
||||
end
|
||||
|
||||
if UIDropDownMenu_Initialize then
|
||||
UIDropDownMenu_Initialize(dropdown, function()
|
||||
local values = MTH_ICU_GetOptionValues(key)
|
||||
local store = MTH_ICU_GetStore()
|
||||
local current = tostring(store[key] or "")
|
||||
local infoFactory = UIDropDownMenu_CreateInfo
|
||||
|
||||
for i = 1, table.getn(values) do
|
||||
local optionValue = tostring(values[i])
|
||||
local info = type(infoFactory) == "function" and infoFactory() or {}
|
||||
info.text = optionValue
|
||||
info.checked = optionValue == current and 1 or nil
|
||||
info.func = function()
|
||||
MTH_ICU_SetValue(key, optionValue)
|
||||
MTH_RefreshICUOptions()
|
||||
end
|
||||
if UIDropDownMenu_AddButton then UIDropDownMenu_AddButton(info) end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
MTH_ICU_OPT_STATE.controls[key] = {
|
||||
label = labelFs,
|
||||
dropdown = dropdown,
|
||||
}
|
||||
end
|
||||
|
||||
local function MTH_ICU_CreateColorRow(container, rowName, label, colorKey, y, labelX, buttonX)
|
||||
labelX = labelX or MTH_ICU_LAYOUT.RIGHT_X
|
||||
buttonX = buttonX or MTH_ICU_LAYOUT.COLOR_BUTTON_X
|
||||
|
||||
local labelFs = container:CreateFontString(rowName .. "Label", "ARTWORK", "GameFontNormalSmall")
|
||||
labelFs:SetPoint("TOPLEFT", container, "TOPLEFT", labelX, y)
|
||||
labelFs:SetText(label)
|
||||
|
||||
local button = CreateFrame("Button", rowName .. "Button", container, "UIPanelButtonTemplate")
|
||||
button:SetPoint("TOPLEFT", container, "TOPLEFT", buttonX, y + 8)
|
||||
button:SetWidth(MTH_ICU_LAYOUT.COLOR_BUTTON_WIDTH)
|
||||
button:SetHeight(22)
|
||||
button:SetText("Pick")
|
||||
button:SetScript("OnClick", function()
|
||||
MTH_ICU_OpenColorPicker(colorKey)
|
||||
end)
|
||||
|
||||
local swatch = button:CreateTexture(rowName .. "Swatch", "ARTWORK")
|
||||
swatch:SetTexture("Interface\\Buttons\\WHITE8X8")
|
||||
swatch:SetPoint("LEFT", button, "LEFT", 6, 0)
|
||||
swatch:SetWidth(14)
|
||||
swatch:SetHeight(14)
|
||||
|
||||
MTH_ICU_OPT_STATE.controls[colorKey] = {
|
||||
label = labelFs,
|
||||
button = button,
|
||||
swatch = swatch,
|
||||
isColor = true,
|
||||
}
|
||||
end
|
||||
|
||||
local function MTH_ICU_BuildUI(container)
|
||||
if MTH_ICU_OPT_STATE.built and MTH_ICU_OPT_STATE.container == container then
|
||||
return
|
||||
end
|
||||
|
||||
MTH_ClearContainer(container)
|
||||
MTH_ICU_OPT_STATE.controls = {}
|
||||
MTH_ICU_OPT_STATE.container = container
|
||||
MTH_ICU_OPT_STATE.built = true
|
||||
|
||||
local title = container:CreateFontString("MetaHuntOptionsICUTitle", "ARTWORK", "GameFontHighlight")
|
||||
title:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -10)
|
||||
title:SetText("MTH ICU")
|
||||
|
||||
local note = container:CreateFontString("MetaHuntOptionsICUNote", "ARTWORK", "GameFontNormalSmall")
|
||||
note:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -32)
|
||||
note:SetWidth(560)
|
||||
note:SetJustifyH("LEFT")
|
||||
note:SetJustifyV("TOP")
|
||||
note:SetTextColor(0.35, 0.65, 1)
|
||||
note:SetText("ICU is a minimap targeting utility module for your Trackings.\nIt provides enhanced target information and click actions for players and NPCs on the minimap.")
|
||||
|
||||
local moduleEnabled = MTH_CreateCheckbox(container, "MetaHuntOptionsICUModuleEnabled", "Enable ICU module", -72, MTH_ICU_LAYOUT.LEFT_X)
|
||||
if moduleEnabled then
|
||||
moduleEnabled:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
if MTH and MTH.SetModuleEnabled then
|
||||
local ok, err = MTH:SetModuleEnabled("icu", this:GetChecked() == 1)
|
||||
if not ok and MTH and MTH.Print then
|
||||
MTH:Print("Failed to change ICU module state: " .. tostring(err), "error")
|
||||
end
|
||||
end
|
||||
MTH_RefreshICUOptions()
|
||||
end)
|
||||
MTH_ICU_OPT_STATE.controls.moduleEnabled = moduleEnabled
|
||||
end
|
||||
|
||||
local mouseOver = MTH_CreateCheckbox(container, "MetaHuntOptionsICUMouseOver", "Enable CTRL mouseover scan", -98, MTH_ICU_LAYOUT.LEFT_X)
|
||||
if mouseOver then
|
||||
mouseOver:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local store = MTH_ICU_GetStore()
|
||||
store.mouseOver = this:GetChecked() == 1 and true or false
|
||||
end)
|
||||
MTH_ICU_OPT_STATE.controls.mouseOver = mouseOver
|
||||
end
|
||||
|
||||
local sectionHeader = container:CreateFontString("MetaHuntOptionsICUSectionHeader", "ARTWORK", "GameFontHighlight")
|
||||
sectionHeader:SetPoint("TOPLEFT", container, "TOPLEFT", MTH_ICU_LAYOUT.LEFT_X, -146)
|
||||
sectionHeader:SetText("General Settings")
|
||||
|
||||
MTH_ICU_CreateOptionRow(container, "MetaHuntOptionsICUAlert", "ALERT PVP", "ALERT", -172, MTH_ICU_LAYOUT.LEFT_X, MTH_ICU_LAYOUT.LEFT_DROPDOWN_X)
|
||||
MTH_ICU_CreateOptionRow(container, "MetaHuntOptionsICUAnnounce", "ANNOUNCE on click", "ANNOUNCE", -198, MTH_ICU_LAYOUT.LEFT_X, MTH_ICU_LAYOUT.LEFT_DROPDOWN_X)
|
||||
MTH_ICU_CreateOptionRow(container, "MetaHuntOptionsICUHealthMode", "Health text", "HEALTH_TEXT_MODE", -224, MTH_ICU_LAYOUT.LEFT_X, MTH_ICU_LAYOUT.LEFT_DROPDOWN_X)
|
||||
MTH_ICU_CreateOptionRow(container, "MetaHuntOptionsICUHideDelay", "List hide delay", "POPUP_HIDE_DELAY", -250, MTH_ICU_LAYOUT.LEFT_X, MTH_ICU_LAYOUT.LEFT_DROPDOWN_X)
|
||||
MTH_ICU_CreateOptionRow(container, "MetaHuntOptionsICUAnchor", "ANCHOR", "ANCHOR", -276, MTH_ICU_LAYOUT.LEFT_X, MTH_ICU_LAYOUT.LEFT_DROPDOWN_X)
|
||||
|
||||
local toggleAnchorButton = CreateFrame("Button", "MetaHuntOptionsICUToggleAnchorButton", container, "UIPanelButtonTemplate")
|
||||
toggleAnchorButton:SetPoint("TOPLEFT", container, "TOPLEFT", MTH_ICU_LAYOUT.LEFT_X, -302)
|
||||
toggleAnchorButton:SetWidth(116)
|
||||
toggleAnchorButton:SetHeight(22)
|
||||
toggleAnchorButton:SetText("Toggle Anchor")
|
||||
toggleAnchorButton:SetScript("OnClick", function()
|
||||
if type(ICU_ToggleAnchor) == "function" then
|
||||
ICU_ToggleAnchor()
|
||||
end
|
||||
end)
|
||||
MTH_ICU_OPT_STATE.controls.customAnchorButton = toggleAnchorButton
|
||||
|
||||
local expandUp = MTH_CreateCheckbox(container, "MetaHuntOptionsICUExpandUp", "Expand Up", -301, MTH_ICU_LAYOUT.LEFT_X + 132)
|
||||
if expandUp then
|
||||
expandUp:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local store = MTH_ICU_GetStore()
|
||||
store.EXPAND_UP = this:GetChecked() == 1 and true or false
|
||||
if type(ICU_SetPoints) == "function" then
|
||||
ICU_SetPoints()
|
||||
end
|
||||
end)
|
||||
MTH_ICU_OPT_STATE.controls.expandUp = expandUp
|
||||
end
|
||||
|
||||
local showGuild = MTH_CreateCheckbox(container, "MetaHuntOptionsICUShowGuild", "Show player guild names", -344, MTH_ICU_LAYOUT.LEFT_X)
|
||||
if showGuild then
|
||||
showGuild:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local store = MTH_ICU_GetStore()
|
||||
store.SHOW_GUILD_NAME = this:GetChecked() == 1 and true or false
|
||||
end)
|
||||
MTH_ICU_OPT_STATE.controls.showGuildName = showGuild
|
||||
end
|
||||
|
||||
local showClass = MTH_CreateCheckbox(container, "MetaHuntOptionsICUShowClass", "Show player class", -368, MTH_ICU_LAYOUT.LEFT_X)
|
||||
if showClass then
|
||||
showClass:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local store = MTH_ICU_GetStore()
|
||||
store.SHOW_PLAYER_CLASS = this:GetChecked() == 1 and true or false
|
||||
end)
|
||||
MTH_ICU_OPT_STATE.controls.showPlayerClass = showClass
|
||||
end
|
||||
|
||||
local showRace = MTH_CreateCheckbox(container, "MetaHuntOptionsICUShowRace", "Show player race", -392, MTH_ICU_LAYOUT.LEFT_X)
|
||||
if showRace then
|
||||
showRace:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local store = MTH_ICU_GetStore()
|
||||
store.SHOW_PLAYER_RACE = this:GetChecked() == 1 and true or false
|
||||
end)
|
||||
MTH_ICU_OPT_STATE.controls.showPlayerRace = showRace
|
||||
end
|
||||
|
||||
local showTitles = MTH_CreateCheckbox(container, "MetaHuntOptionsICUShowTitles", "Show custom titles in alerts", -416, MTH_ICU_LAYOUT.LEFT_X)
|
||||
if showTitles then
|
||||
showTitles:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local store = MTH_ICU_GetStore()
|
||||
store.SHOW_CUSTOM_TITLES = this:GetChecked() == 1 and true or false
|
||||
end)
|
||||
MTH_ICU_OPT_STATE.controls.showCustomTitles = showTitles
|
||||
end
|
||||
|
||||
local rightHeader = container:CreateFontString("MetaHuntOptionsICURightHeader", "ARTWORK", "GameFontHighlight")
|
||||
rightHeader:SetPoint("TOPLEFT", container, "TOPLEFT", MTH_ICU_LAYOUT.RIGHT_X, -146)
|
||||
rightHeader:SetText("Background Colors")
|
||||
|
||||
MTH_ICU_CreateOptionRow(container, "MetaHuntOptionsICUPlayerColorMode", "Player colors", "PLAYER_COLOR_MODE", -172, MTH_ICU_LAYOUT.RIGHT_X, MTH_ICU_LAYOUT.RIGHT_DROPDOWN_X)
|
||||
|
||||
local reactionOnlyPvp = MTH_CreateCheckbox(container, "MetaHuntOptionsICUReactionOnlyPvp", "Reaction only when PvP-flagged", -200, MTH_ICU_LAYOUT.RIGHT_X)
|
||||
if reactionOnlyPvp then
|
||||
reactionOnlyPvp:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local store = MTH_ICU_GetStore()
|
||||
store.REACTION_ONLY_PVP_PLAYERS = this:GetChecked() == 1 and true or false
|
||||
end)
|
||||
MTH_ICU_OPT_STATE.controls.reactionOnlyPvp = reactionOnlyPvp
|
||||
end
|
||||
|
||||
local colorHeader = container:CreateFontString("MetaHuntOptionsICUColorsHeader", "ARTWORK", "GameFontHighlight")
|
||||
colorHeader:SetPoint("TOPLEFT", container, "TOPLEFT", MTH_ICU_LAYOUT.RIGHT_X, -224)
|
||||
|
||||
local colorScope = container:CreateFontString("MetaHuntOptionsICUColorsScope", "ARTWORK", "GameFontNormalSmall")
|
||||
colorScope:SetPoint("TOPLEFT", container, "TOPLEFT", MTH_ICU_LAYOUT.RIGHT_X, -242)
|
||||
colorScope:SetWidth(250)
|
||||
colorScope:SetJustifyH("LEFT")
|
||||
colorScope:SetJustifyV("TOP")
|
||||
colorScope:SetTextColor(0.35, 0.65, 1)
|
||||
colorScope:SetText("Player pickers: REACTION / FACTION / CUSTOM\nNPC pickers: always")
|
||||
|
||||
local colorY = -284
|
||||
for i = 1, table.getn(MTH_ICU_COLOR_ROWS) do
|
||||
local row = MTH_ICU_COLOR_ROWS[i]
|
||||
MTH_ICU_CreateColorRow(container, "MetaHuntOptionsICUColor" .. tostring(i), row.label, row.key, colorY, MTH_ICU_LAYOUT.RIGHT_X, MTH_ICU_LAYOUT.COLOR_BUTTON_X)
|
||||
colorY = colorY - MTH_ICU_LAYOUT.COLOR_ROW_STEP
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
function MTH_RefreshICUOptions()
|
||||
if not MTH_ICU_OPT_READY then return end
|
||||
|
||||
local controls = MTH_ICU_OPT_STATE.controls
|
||||
if type(controls) ~= "table" then
|
||||
return
|
||||
end
|
||||
|
||||
local store = MTH_ICU_GetStore()
|
||||
local moduleEnabled = MTH and MTH.IsModuleEnabled and MTH:IsModuleEnabled("icu", false) or false
|
||||
|
||||
if controls.moduleEnabled then
|
||||
controls.moduleEnabled:SetChecked(moduleEnabled and 1 or nil)
|
||||
end
|
||||
|
||||
if controls.mouseOver then
|
||||
controls.mouseOver:SetChecked(store.mouseOver and 1 or nil)
|
||||
if controls.mouseOver.Enable then
|
||||
if moduleEnabled then controls.mouseOver:Enable() else controls.mouseOver:Disable() end
|
||||
end
|
||||
end
|
||||
|
||||
if controls.showGuildName then
|
||||
controls.showGuildName:SetChecked(store.SHOW_GUILD_NAME and 1 or nil)
|
||||
if controls.showGuildName.Enable then
|
||||
if moduleEnabled then controls.showGuildName:Enable() else controls.showGuildName:Disable() end
|
||||
end
|
||||
end
|
||||
|
||||
if controls.showPlayerClass then
|
||||
controls.showPlayerClass:SetChecked(store.SHOW_PLAYER_CLASS and 1 or nil)
|
||||
if controls.showPlayerClass.Enable then
|
||||
if moduleEnabled then controls.showPlayerClass:Enable() else controls.showPlayerClass:Disable() end
|
||||
end
|
||||
end
|
||||
|
||||
if controls.showPlayerRace then
|
||||
controls.showPlayerRace:SetChecked(store.SHOW_PLAYER_RACE and 1 or nil)
|
||||
if controls.showPlayerRace.Enable then
|
||||
if moduleEnabled then controls.showPlayerRace:Enable() else controls.showPlayerRace:Disable() end
|
||||
end
|
||||
end
|
||||
|
||||
if controls.showCustomTitles then
|
||||
controls.showCustomTitles:SetChecked(store.SHOW_CUSTOM_TITLES and 1 or nil)
|
||||
if controls.showCustomTitles.Enable then
|
||||
if moduleEnabled then controls.showCustomTitles:Enable() else controls.showCustomTitles:Disable() end
|
||||
end
|
||||
end
|
||||
|
||||
local isCustomAnchor = tostring(store.ANCHOR or "") == "CUSTOM"
|
||||
|
||||
if controls.customAnchorButton then
|
||||
if moduleEnabled and isCustomAnchor then
|
||||
controls.customAnchorButton:Show()
|
||||
if controls.customAnchorButton.Enable then controls.customAnchorButton:Enable() end
|
||||
else
|
||||
controls.customAnchorButton:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
if controls.expandUp then
|
||||
controls.expandUp:SetChecked(store.EXPAND_UP and 1 or nil)
|
||||
if moduleEnabled and isCustomAnchor then
|
||||
controls.expandUp:Show()
|
||||
if controls.expandUp.Enable then controls.expandUp:Enable() end
|
||||
else
|
||||
controls.expandUp:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local optionKeys = { "ALERT", "ANNOUNCE", "ANCHOR", "HEALTH_TEXT_MODE", "POPUP_HIDE_DELAY", "PLAYER_COLOR_MODE" }
|
||||
for i = 1, table.getn(optionKeys) do
|
||||
local key = optionKeys[i]
|
||||
local row = controls[key]
|
||||
if row and row.dropdown then
|
||||
MTH_ICU_DropdownSetText(row.dropdown, tostring(store[key] or ""))
|
||||
if UIDropDownMenu_EnableDropDown and UIDropDownMenu_DisableDropDown then
|
||||
if moduleEnabled then
|
||||
UIDropDownMenu_EnableDropDown(row.dropdown)
|
||||
else
|
||||
UIDropDownMenu_DisableDropDown(row.dropdown)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if controls.reactionOnlyPvp then
|
||||
controls.reactionOnlyPvp:SetChecked(store.REACTION_ONLY_PVP_PLAYERS and 1 or nil)
|
||||
if controls.reactionOnlyPvp.Enable then
|
||||
if moduleEnabled and tostring(store.PLAYER_COLOR_MODE or "") == "REACTION" then
|
||||
controls.reactionOnlyPvp:Enable()
|
||||
else
|
||||
controls.reactionOnlyPvp:Disable()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, table.getn(MTH_ICU_COLOR_ROWS) do
|
||||
local row = MTH_ICU_COLOR_ROWS[i]
|
||||
local ctrl = controls[row.key]
|
||||
if ctrl and ctrl.swatch then
|
||||
local r, g, b = MTH_ICU_GetColor(row.key)
|
||||
ctrl.swatch:SetVertexColor(r, g, b)
|
||||
if ctrl.button and ctrl.button.Enable then
|
||||
if moduleEnabled then ctrl.button:Enable() else ctrl.button:Disable() end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MTH_SetupICUOptions()
|
||||
local container = MTH_GetFrame("MetaHuntOptionsICU")
|
||||
if not container then return end
|
||||
|
||||
if not MTH_ICU_OPT_READY then
|
||||
if type(MTH_ClearContainer) == "function" then
|
||||
MTH_ClearContainer(container)
|
||||
end
|
||||
local title = container:CreateFontString("MetaHuntOptionsICUErrorTitle", "ARTWORK", "GameFontHighlight")
|
||||
title:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -10)
|
||||
title:SetText("MTH ICU")
|
||||
|
||||
local body = container:CreateFontString("MetaHuntOptionsICUErrorBody", "ARTWORK", "GameFontNormalSmall")
|
||||
body:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -34)
|
||||
body:SetWidth(620)
|
||||
body:SetJustifyH("LEFT")
|
||||
body:SetJustifyV("TOP")
|
||||
body:SetTextColor(1, 0.3, 0.3)
|
||||
body:SetText("ICU options cannot initialize. Missing dependencies: " .. table.concat(MTH_ICU_OPT_MISSING, ", "))
|
||||
return
|
||||
end
|
||||
|
||||
local ok, err = pcall(function()
|
||||
MTH_ICU_BuildUI(container)
|
||||
MTH_RefreshICUOptions()
|
||||
end)
|
||||
if not ok then
|
||||
if MTH and MTH.Print then
|
||||
MTH:Print("[MTH ICU OPTIONS] setup failed: " .. tostring(err), "error")
|
||||
end
|
||||
if type(MTH_ClearContainer) == "function" then
|
||||
MTH_ClearContainer(container)
|
||||
end
|
||||
local title = container:CreateFontString("MetaHuntOptionsICUCrashTitle", "ARTWORK", "GameFontHighlight")
|
||||
title:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -10)
|
||||
title:SetText("MTH ICU")
|
||||
local body = container:CreateFontString("MetaHuntOptionsICUCrashBody", "ARTWORK", "GameFontNormalSmall")
|
||||
body:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -34)
|
||||
body:SetWidth(620)
|
||||
body:SetJustifyH("LEFT")
|
||||
body:SetJustifyV("TOP")
|
||||
body:SetTextColor(1, 0.3, 0.3)
|
||||
body:SetText("ICU options failed to render. Check chat/debug for details.")
|
||||
end
|
||||
end
|
||||
@@ -195,6 +195,21 @@ function MTH_SelectOptionsTab(tabKey)
|
||||
else
|
||||
MTH_SetupAutoBuyOptions()
|
||||
end
|
||||
elseif tabKey == "AutoQuest" then
|
||||
if type(MTH_SetupAutoQuestOptions) == "function" then
|
||||
MTH_SetupAutoQuestOptions()
|
||||
MTH_OPTIONS_SETUP["AutoQuest"] = true
|
||||
end
|
||||
elseif tabKey == "ICU" then
|
||||
if type(MTH_SetupICUOptions) == "function" then
|
||||
MTH_SetupICUOptions()
|
||||
MTH_OPTIONS_SETUP["ICU"] = true
|
||||
if type(MTH_RefreshICUOptions) == "function" then
|
||||
MTH_RefreshICUOptions()
|
||||
end
|
||||
elseif MTH and MTH.Print then
|
||||
MTH:Print("ICU options setup function is not loaded", "error")
|
||||
end
|
||||
elseif tabKey == "Credits" then
|
||||
local setupCredits = _G and _G["MTH_SetupCreditsOptions"]
|
||||
if type(setupCredits) == "function" then
|
||||
|
||||
@@ -41,6 +41,8 @@ MTH_OPTIONS_TABS = MTH_OPTIONS_TABS or {
|
||||
{ key = "SmartAmmo", label = "Smart Ammo", frame = "MetaHuntOptionsSmartAmmo" },
|
||||
{ key = "FeedOMatic", label = "FeedOMatic", frame = "MetaHuntOptionsFeedOMatic" },
|
||||
{ key = "AutoBuy", label = "Auto Buy", frame = "MetaHuntOptionsAutoBuy" },
|
||||
{ key = "AutoQuest", label = "Auto Quest", frame = "MetaHuntOptionsAutoQuest" },
|
||||
{ key = "ICU", label = "ICU", frame = "MetaHuntOptionsICU" },
|
||||
{ key = "ChronometerGeneral", label = "General", frame = "MetaHuntOptionsChronometer" },
|
||||
{ key = "ChronometerBar", label = "Bar", frame = "MetaHuntOptionsChronometer" },
|
||||
{ key = "ChronometerClassSpells", label = "Hunter Spells", frame = "MetaHuntOptionsChronometer" },
|
||||
@@ -53,7 +55,9 @@ MTH_OPTIONS_TREE = MTH_OPTIONS_TREE or {
|
||||
{ label = "General", key = "General" },
|
||||
{ label = "Messages", key = "Messages" },
|
||||
{ label = "Auto Buy", key = "AutoBuy" },
|
||||
{ label = "Auto Quest", key = "AutoQuest" },
|
||||
{ label = "Feed-O-Matic", key = "FeedOMatic" },
|
||||
{ label = "ICU", key = "ICU" },
|
||||
{
|
||||
label = "zButtons",
|
||||
node = "zButtons",
|
||||
|
||||
+185
-123
@@ -21,6 +21,14 @@ local function MTH_ZB_RefreshTab(tabName)
|
||||
end
|
||||
end
|
||||
|
||||
local function MTH_ZB_IsChecked(control)
|
||||
if not control or type(control.GetChecked) ~= "function" then
|
||||
return false
|
||||
end
|
||||
local checked = control:GetChecked()
|
||||
return checked == 1 or checked == true
|
||||
end
|
||||
|
||||
local function MTH_RebuildSpellOrder(buttonName, buttonObj, itemList, maxButtons)
|
||||
if not (buttonName and buttonObj and itemList and maxButtons) then return end
|
||||
local info = {}
|
||||
@@ -187,15 +195,15 @@ local function MTH_EnsureAmmoOptionsWatcher()
|
||||
if MTH_AmmoOptionsWatcher then
|
||||
return
|
||||
end
|
||||
MTH_AmmoOptionsWatcher = CreateFrame("Frame", "MTHAmmoOptionsWatcherFrame")
|
||||
MTH_AmmoOptionsWatcher = CreateFrame("Frame", "MTH_AmmoOptionsWatcher")
|
||||
if not MTH_AmmoOptionsWatcher then
|
||||
return
|
||||
end
|
||||
MTH_AmmoOptionsWatcher:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
||||
MTH_AmmoOptionsWatcher:RegisterEvent("BAG_UPDATE")
|
||||
MTH_AmmoOptionsWatcher:SetScript("OnEvent", function(_, eventName, unit)
|
||||
eventName = eventName or event
|
||||
unit = unit or arg1
|
||||
MTH_AmmoOptionsWatcher:SetScript("OnEvent", function()
|
||||
local eventName = event
|
||||
local unit = arg1
|
||||
if eventName == "UNIT_INVENTORY_CHANGED" and unit and unit ~= "player" then
|
||||
return
|
||||
end
|
||||
@@ -239,6 +247,16 @@ local function MTH_ZB_EnsureButtonOptionDefaults(buttonName)
|
||||
end
|
||||
saved["children"]["hideonclick"] = saved["children"]["hideonclick"] and true or false
|
||||
|
||||
if saved["children"]["expandonhover"] == nil then
|
||||
saved["children"]["expandonhover"] = false
|
||||
end
|
||||
saved["children"]["expandonhover"] = saved["children"]["expandonhover"] and true or false
|
||||
|
||||
if saved["children"]["fadetimer"] == nil then
|
||||
saved["children"]["fadetimer"] = 0
|
||||
end
|
||||
saved["children"]["fadetimer"] = tonumber(saved["children"]["fadetimer"]) or 0
|
||||
|
||||
if type(saved["parent"]) ~= "table" then
|
||||
saved["parent"] = {}
|
||||
end
|
||||
@@ -325,16 +343,15 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
|
||||
enableButton:SetChecked(enabledValue and true or false)
|
||||
enableButton.buttonName = buttonName
|
||||
enableButton.buttonObj = buttonObj
|
||||
enableButton:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local checked = self:GetChecked() and true or false
|
||||
MTH_SetButtonEnabledState(self.buttonName, self.buttonObj, checked)
|
||||
enableButton:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local checked = MTH_ZB_IsChecked(this)
|
||||
MTH_SetButtonEnabledState(this.buttonName, this.buttonObj, checked)
|
||||
end)
|
||||
end
|
||||
|
||||
local parentSection = MTH_ZB_EnsureSection(containerName.."ParentSection", MTH_ZB_L("ZB_SECTION_PARENT_BUTTON", "Parent Button"), -52, 116)
|
||||
local childrenSection = MTH_ZB_EnsureSection(containerName.."ChildrenSection", MTH_ZB_L("ZB_SECTION_CHILDREN_BUTTONS", "Children Buttons"), -184, 235)
|
||||
local childrenSection = MTH_ZB_EnsureSection(containerName.."ChildrenSection", MTH_ZB_L("ZB_SECTION_CHILDREN_BUTTONS", "Children Buttons"), -184, 310)
|
||||
|
||||
local parentYOffset = -18
|
||||
local childrenYOffset = -18
|
||||
@@ -384,16 +401,15 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
|
||||
expandLeft:SetChecked(saved["firstbutton"] == "LEFT")
|
||||
expandLeft.buttonName = buttonName
|
||||
expandLeft.buttonObj = buttonObj
|
||||
expandLeft:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local checked = self:GetChecked() and true or false
|
||||
local btnName = self.buttonName
|
||||
expandLeft:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local checked = MTH_ZB_IsChecked(this)
|
||||
local btnName = this.buttonName
|
||||
if not btnName or not (ZHunterMod_Saved and ZHunterMod_Saved[btnName]) then return end
|
||||
ZHunterMod_Saved[btnName]["firstbutton"] = checked and "LEFT" or "RIGHT"
|
||||
ZHunterMod_Saved[btnName]["horizontal"] = checked and 1 or nil
|
||||
ZHunterMod_Saved[btnName]["vertical"] = checked and 1 or nil
|
||||
MTH_RefreshButtonGeometry(btnName, self.buttonObj)
|
||||
MTH_RefreshButtonGeometry(btnName, this.buttonObj)
|
||||
end)
|
||||
end
|
||||
childrenYOffset = childrenYOffset - 30
|
||||
@@ -406,17 +422,64 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
|
||||
if hideClick.buttonObj then
|
||||
hideClick.buttonObj.hideonclick = saved["children"]["hideonclick"] and true or false
|
||||
end
|
||||
hideClick:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local checked = self:GetChecked() and true or false
|
||||
ZHunterMod_Saved[self.buttonName]["children"]["hideonclick"] = checked
|
||||
local btnObj = self.buttonObj or getglobal(self.buttonName)
|
||||
hideClick:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local checked = MTH_ZB_IsChecked(this)
|
||||
ZHunterMod_Saved[this.buttonName]["children"]["hideonclick"] = checked
|
||||
local btnObj = this.buttonObj or getglobal(this.buttonName)
|
||||
if btnObj then btnObj.hideonclick = checked end
|
||||
end)
|
||||
end
|
||||
childrenYOffset = childrenYOffset - 25
|
||||
|
||||
local expandOnHover = MTH_CreateCheckbox(childrenSection or container, containerName.."ExpandOnHover", MTH_ZB_L("ZB_LABEL_EXPAND_ON_HOVER", "Expand on Hover"), childrenYOffset)
|
||||
if expandOnHover then
|
||||
expandOnHover:SetChecked(saved["children"]["expandonhover"])
|
||||
expandOnHover.buttonName = buttonName
|
||||
expandOnHover.buttonObj = buttonObj
|
||||
expandOnHover:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local checked = MTH_ZB_IsChecked(this)
|
||||
local btnName = this.buttonName
|
||||
if not btnName or not (ZHunterMod_Saved and ZHunterMod_Saved[btnName]) then return end
|
||||
if not ZHunterMod_Saved[btnName]["children"] then
|
||||
ZHunterMod_Saved[btnName]["children"] = {}
|
||||
end
|
||||
ZHunterMod_Saved[btnName]["children"]["expandonhover"] = checked
|
||||
local btnObj = this.buttonObj or getglobal(btnName)
|
||||
if btnObj then btnObj.expandonhover = checked end
|
||||
end)
|
||||
end
|
||||
childrenYOffset = childrenYOffset - 40
|
||||
|
||||
local fadeTimer = MTH_CreateSlider(childrenSection or container, containerName.."FadeTimer", MTH_ZB_L("ZB_LABEL_AUTO_HIDE_TIMER", "Auto-Hide Timer (seconds)"), 0, 10, 1, childrenYOffset)
|
||||
if fadeTimer then
|
||||
fadeTimer:SetWidth(leftWidth - 40)
|
||||
fadeTimer:SetValue(saved["children"]["fadetimer"] or 0)
|
||||
fadeTimer.buttonName = buttonName
|
||||
fadeTimer.buttonObj = buttonObj
|
||||
fadeTimer.onChange = function(val, slider)
|
||||
local frame = slider or fadeTimer
|
||||
local btnName = frame and frame.buttonName
|
||||
if not btnName or not (ZHunterMod_Saved and ZHunterMod_Saved[btnName]) then return end
|
||||
if not ZHunterMod_Saved[btnName]["children"] then
|
||||
ZHunterMod_Saved[btnName]["children"] = {}
|
||||
end
|
||||
local secs = math.floor((val or 0) + 0.5)
|
||||
ZHunterMod_Saved[btnName]["children"]["fadetimer"] = secs
|
||||
local btnObj = frame.buttonObj or getglobal(btnName)
|
||||
if btnObj then
|
||||
btnObj.fadetimer = secs
|
||||
if secs <= 0 then
|
||||
ZSpellButton_StopFadeTimer(btnObj)
|
||||
elseif btnObj.children and btnObj.children:IsVisible() then
|
||||
ZSpellButton_StartFadeTimer(btnObj)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
childrenYOffset = childrenYOffset - 50
|
||||
|
||||
local showTooltip = MTH_CreateCheckbox(childrenSection or container, containerName.."ShowTooltip", MTH_ZB_L("ZB_LABEL_SHOW_TOOLTIP", "Show Tooltip"), childrenYOffset)
|
||||
if showTooltip then
|
||||
showTooltip:SetChecked(saved["tooltip"])
|
||||
@@ -425,12 +488,11 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
|
||||
if showTooltip.buttonObj then
|
||||
showTooltip.buttonObj.tooltip = saved["tooltip"] and true or false
|
||||
end
|
||||
showTooltip:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local checked = self:GetChecked() and true or false
|
||||
ZHunterMod_Saved[self.buttonName]["tooltip"] = checked
|
||||
local btnObj = self.buttonObj or getglobal(self.buttonName)
|
||||
showTooltip:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local checked = MTH_ZB_IsChecked(this)
|
||||
ZHunterMod_Saved[this.buttonName]["tooltip"] = checked
|
||||
local btnObj = this.buttonObj or getglobal(this.buttonName)
|
||||
if btnObj then btnObj.tooltip = checked end
|
||||
end)
|
||||
end
|
||||
@@ -443,13 +505,12 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
|
||||
showAmmoName.buttonName = buttonName
|
||||
showAmmoName.buttonObj = buttonObj
|
||||
showAmmoName.maxButtons = maxButtons
|
||||
showAmmoName:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local checked = self:GetChecked() and true or false
|
||||
local btnName = self.buttonName
|
||||
showAmmoName:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local checked = MTH_ZB_IsChecked(this)
|
||||
local btnName = this.buttonName
|
||||
ZHunterMod_Saved[btnName]["showammoname"] = checked
|
||||
local btnObj = self.buttonObj or getglobal(btnName)
|
||||
local btnObj = this.buttonObj or getglobal(btnName)
|
||||
if btnObj then
|
||||
for i = 1, (btnObj.count or 0) do
|
||||
local child = getglobal(btnName..i)
|
||||
@@ -498,13 +559,12 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
|
||||
hideButton:SetChecked(saved["parent"]["hide"])
|
||||
hideButton.buttonName = buttonName
|
||||
hideButton.buttonObj = buttonObj
|
||||
hideButton:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local checked = self:GetChecked() == 1
|
||||
ZHunterMod_Saved[self.buttonName]["parent"]["hide"] = checked
|
||||
if self.buttonObj then
|
||||
if checked then self.buttonObj:Hide() else self.buttonObj:Show() end
|
||||
hideButton:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local checked = this:GetChecked() == 1
|
||||
ZHunterMod_Saved[this.buttonName]["parent"]["hide"] = checked
|
||||
if this.buttonObj then
|
||||
if checked then this.buttonObj:Hide() else this.buttonObj:Show() end
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -515,13 +575,12 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
|
||||
useCircle:SetChecked(saved["parent"]["circle"])
|
||||
useCircle.buttonName = buttonName
|
||||
useCircle.buttonObj = buttonObj
|
||||
useCircle:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local checked = self:GetChecked() == 1
|
||||
ZHunterMod_Saved[self.buttonName]["parent"]["circle"] = checked
|
||||
if self.buttonObj and self.buttonObj.circle then
|
||||
if checked then self.buttonObj.circle:Show() else self.buttonObj.circle:Hide() end
|
||||
useCircle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local checked = this:GetChecked() == 1
|
||||
ZHunterMod_Saved[this.buttonName]["parent"]["circle"] = checked
|
||||
if this.buttonObj and this.buttonObj.circle then
|
||||
if checked then this.buttonObj.circle:Show() else this.buttonObj.circle:Hide() end
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -579,17 +638,16 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
|
||||
showText:SetText("")
|
||||
end
|
||||
showToggle:SetChecked(ZHunterMod_Saved[buttonName]["visible"][showToggle.spellIndex] ~= false)
|
||||
showToggle:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local checked = self:GetChecked() == 1
|
||||
local btnName = self.buttonName
|
||||
local visibleIndex = self.spellIndex
|
||||
showToggle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local checked = this:GetChecked() == 1
|
||||
local btnName = this.buttonName
|
||||
local visibleIndex = this.spellIndex
|
||||
if not ZHunterMod_Saved[btnName]["visible"] then
|
||||
ZHunterMod_Saved[btnName]["visible"] = {}
|
||||
end
|
||||
ZHunterMod_Saved[btnName]["visible"][visibleIndex] = checked
|
||||
MTH_RefreshButtonLayout(btnName, self.buttonObj, self.itemList, self.maxButtons)
|
||||
MTH_RefreshButtonLayout(btnName, this.buttonObj, this.itemList, this.maxButtons)
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -604,18 +662,17 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
|
||||
downBtn.buttonObj = buttonObj
|
||||
downBtn.itemList = itemList
|
||||
downBtn.maxButtons = maxButtons
|
||||
downBtn:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local idx = self.spellIndex
|
||||
local btnName = self.buttonName
|
||||
local contName = self.containerName
|
||||
local maxBtns = self.maxButtons
|
||||
downBtn:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local idx = this.spellIndex
|
||||
local btnName = this.buttonName
|
||||
local contName = this.containerName
|
||||
local maxBtns = this.maxButtons
|
||||
if idx < maxBtns then
|
||||
local temp = ZHunterMod_Saved[btnName]["spells"][idx+1]
|
||||
ZHunterMod_Saved[btnName]["spells"][idx+1] = ZHunterMod_Saved[btnName]["spells"][idx]
|
||||
ZHunterMod_Saved[btnName]["spells"][idx] = temp
|
||||
MTH_RebuildSpellOrder(btnName, self.buttonObj, self.itemList, self.maxButtons)
|
||||
MTH_RebuildSpellOrder(btnName, this.buttonObj, this.itemList, this.maxButtons)
|
||||
local tabName = gsub(contName, "MetaHuntOptions", "")
|
||||
MTH_ZB_RefreshTab(tabName)
|
||||
end
|
||||
@@ -632,17 +689,16 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
|
||||
upBtn.buttonObj = buttonObj
|
||||
upBtn.itemList = itemList
|
||||
upBtn.maxButtons = maxButtons
|
||||
upBtn:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
local idx = self.spellIndex
|
||||
local btnName = self.buttonName
|
||||
local contName = self.containerName
|
||||
upBtn:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
local idx = this.spellIndex
|
||||
local btnName = this.buttonName
|
||||
local contName = this.containerName
|
||||
if idx > 1 then
|
||||
local temp = ZHunterMod_Saved[btnName]["spells"][idx-1]
|
||||
ZHunterMod_Saved[btnName]["spells"][idx-1] = ZHunterMod_Saved[btnName]["spells"][idx]
|
||||
ZHunterMod_Saved[btnName]["spells"][idx] = temp
|
||||
MTH_RebuildSpellOrder(btnName, self.buttonObj, self.itemList, self.maxButtons)
|
||||
MTH_RebuildSpellOrder(btnName, this.buttonObj, this.itemList, this.maxButtons)
|
||||
local tabName = gsub(contName, "MetaHuntOptions", "")
|
||||
MTH_ZB_RefreshTab(tabName)
|
||||
end
|
||||
@@ -741,11 +797,10 @@ function MTH_SetupSmartAmmoOptions()
|
||||
end
|
||||
if moduleToggle then
|
||||
moduleToggle:SetChecked(moduleEnabled)
|
||||
moduleToggle:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
moduleToggle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
if MTH and MTH.SetModuleEnabled then
|
||||
MTH:SetModuleEnabled("smartammo", self:GetChecked() and true or false)
|
||||
MTH:SetModuleEnabled("smartammo", MTH_ZB_IsChecked(this))
|
||||
end
|
||||
MTH_SetupSmartAmmoOptions()
|
||||
end)
|
||||
@@ -758,11 +813,10 @@ function MTH_SetupSmartAmmoOptions()
|
||||
if not moduleEnabled then
|
||||
smartToggle:Disable()
|
||||
end
|
||||
smartToggle:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
smartToggle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
if type(MTHSmartAmmo_SetSmartEnabled) == "function" then
|
||||
MTHSmartAmmo_SetSmartEnabled(self:GetChecked() and 1 or nil)
|
||||
MTHSmartAmmo_SetSmartEnabled(MTH_ZB_IsChecked(this) and 1 or nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -777,11 +831,10 @@ function MTH_SetupSmartAmmoOptions()
|
||||
if not moduleEnabled then
|
||||
reloadToggle:Disable()
|
||||
end
|
||||
reloadToggle:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
reloadToggle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
if type(MTHSmartAmmo_SetReloadEnabled) == "function" then
|
||||
MTHSmartAmmo_SetReloadEnabled(self:GetChecked() and 1 or nil)
|
||||
MTHSmartAmmo_SetReloadEnabled(MTH_ZB_IsChecked(this) and 1 or nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -817,11 +870,10 @@ function MTH_SetupMessagesOptions()
|
||||
local initModulesToggle = MTH_CreateCheckbox(section, "MetaHuntMessagesInitModules", "Init : modules loaded", -36)
|
||||
if initModulesToggle then
|
||||
initModulesToggle:SetChecked(msgSettings.initModulesLoaded and true or false)
|
||||
initModulesToggle:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
initModulesToggle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
if MTH and MTH.SetMessageEnabled then
|
||||
MTH:SetMessageEnabled("initModulesLoaded", self:GetChecked() and true or false)
|
||||
MTH:SetMessageEnabled("initModulesLoaded", MTH_ZB_IsChecked(this))
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -829,11 +881,10 @@ function MTH_SetupMessagesOptions()
|
||||
local initWelcomeToggle = MTH_CreateCheckbox(section, "MetaHuntMessagesInitWelcome", "Init : Sarcastic welcome message", -64)
|
||||
if initWelcomeToggle then
|
||||
initWelcomeToggle:SetChecked(msgSettings.initSarcasticWelcome ~= false)
|
||||
initWelcomeToggle:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
initWelcomeToggle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
if MTH and MTH.SetMessageEnabled then
|
||||
MTH:SetMessageEnabled("initSarcasticWelcome", self:GetChecked() and true or false)
|
||||
MTH:SetMessageEnabled("initSarcasticWelcome", MTH_ZB_IsChecked(this))
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -841,11 +892,10 @@ function MTH_SetupMessagesOptions()
|
||||
local petHungryToggle = MTH_CreateCheckbox(section, "MetaHuntMessagesPetHungry", "Pet is hungry (spam)", -92)
|
||||
if petHungryToggle then
|
||||
petHungryToggle:SetChecked(msgSettings.petHungry and true or false)
|
||||
petHungryToggle:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
petHungryToggle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
if MTH and MTH.SetMessageEnabled then
|
||||
MTH:SetMessageEnabled("petHungry", self:GetChecked() and true or false)
|
||||
MTH:SetMessageEnabled("petHungry", MTH_ZB_IsChecked(this))
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -853,11 +903,10 @@ function MTH_SetupMessagesOptions()
|
||||
local beastTrainingScanToggle = MTH_CreateCheckbox(section, "MetaHuntMessagesBeastTrainingScan", "Beasttraining scan", -120)
|
||||
if beastTrainingScanToggle then
|
||||
beastTrainingScanToggle:SetChecked(msgSettings.beastTrainingScan ~= false)
|
||||
beastTrainingScanToggle:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
beastTrainingScanToggle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
if MTH and MTH.SetMessageEnabled then
|
||||
MTH:SetMessageEnabled("beastTrainingScan", self:GetChecked() and true or false)
|
||||
MTH:SetMessageEnabled("beastTrainingScan", MTH_ZB_IsChecked(this))
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -865,11 +914,10 @@ function MTH_SetupMessagesOptions()
|
||||
local spellbookScanToggle = MTH_CreateCheckbox(section, "MetaHuntMessagesSpellbookScan", "Spellbook scan", -148)
|
||||
if spellbookScanToggle then
|
||||
spellbookScanToggle:SetChecked(msgSettings.spellbookScan and true or false)
|
||||
spellbookScanToggle:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
spellbookScanToggle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
if MTH and MTH.SetMessageEnabled then
|
||||
MTH:SetMessageEnabled("spellbookScan", self:GetChecked() and true or false)
|
||||
MTH:SetMessageEnabled("spellbookScan", MTH_ZB_IsChecked(this))
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -877,11 +925,10 @@ function MTH_SetupMessagesOptions()
|
||||
local petRanAwayToggle = MTH_CreateCheckbox(section, "MetaHuntMessagesPetRanAway", "Pet ran away", -176)
|
||||
if petRanAwayToggle then
|
||||
petRanAwayToggle:SetChecked(msgSettings.petRanAway ~= false)
|
||||
petRanAwayToggle:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
petRanAwayToggle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
if MTH and MTH.SetMessageEnabled then
|
||||
MTH:SetMessageEnabled("petRanAway", self:GetChecked() and true or false)
|
||||
MTH:SetMessageEnabled("petRanAway", MTH_ZB_IsChecked(this))
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -889,11 +936,10 @@ function MTH_SetupMessagesOptions()
|
||||
local mapMarkersToggle = MTH_CreateCheckbox(section, "MetaHuntMessagesMapMarkers", "Map markers", -204)
|
||||
if mapMarkersToggle then
|
||||
mapMarkersToggle:SetChecked(msgSettings.mapMarkers ~= false)
|
||||
mapMarkersToggle:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
mapMarkersToggle:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
if MTH and MTH.SetMessageEnabled then
|
||||
MTH:SetMessageEnabled("mapMarkers", self:GetChecked() and true or false)
|
||||
MTH:SetMessageEnabled("mapMarkers", MTH_ZB_IsChecked(this))
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -1002,7 +1048,7 @@ function MTH_SetupGeneralOptions()
|
||||
local smartModuleToggle = ensureCheckbox(smartAmmoSection, "MetaHuntGeneralSmartAmmoModuleToggle", "Enable module", -10, smartModuleEnabled)
|
||||
if smartModuleToggle then
|
||||
smartModuleToggle:SetScript("OnClick", function()
|
||||
local enabled = this:GetChecked() and true or false
|
||||
local enabled = MTH_ZB_IsChecked(this)
|
||||
if MTH and MTH.SetModuleEnabled then
|
||||
local ok = MTH:SetModuleEnabled("smartammo", enabled)
|
||||
if not ok then
|
||||
@@ -1031,7 +1077,7 @@ function MTH_SetupGeneralOptions()
|
||||
end
|
||||
smartToggle:SetScript("OnClick", function()
|
||||
if type(MTHSmartAmmo_SetSmartEnabled) == "function" then
|
||||
MTHSmartAmmo_SetSmartEnabled(this:GetChecked() and 1 or nil)
|
||||
MTHSmartAmmo_SetSmartEnabled(MTH_ZB_IsChecked(this) and 1 or nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -1045,7 +1091,7 @@ function MTH_SetupGeneralOptions()
|
||||
end
|
||||
reloadToggle:SetScript("OnClick", function()
|
||||
if type(MTHSmartAmmo_SetReloadEnabled) == "function" then
|
||||
MTHSmartAmmo_SetReloadEnabled(this:GetChecked() and 1 or nil)
|
||||
MTHSmartAmmo_SetReloadEnabled(MTH_ZB_IsChecked(this) and 1 or nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -1059,7 +1105,7 @@ function MTH_SetupGeneralOptions()
|
||||
end
|
||||
weaponSwapToggle:SetScript("OnClick", function()
|
||||
if type(MTHSmartAmmo_SetWeaponSwapEnabled) == "function" then
|
||||
MTHSmartAmmo_SetWeaponSwapEnabled(this:GetChecked() and 1 or nil)
|
||||
MTHSmartAmmo_SetWeaponSwapEnabled(MTH_ZB_IsChecked(this) and 1 or nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -1072,7 +1118,7 @@ function MTH_SetupGeneralOptions()
|
||||
if autoStripToggle then
|
||||
autoStripToggle:SetScript("OnClick", function()
|
||||
if type(AutoStrip_SetAutoStripToggle) == "function" then
|
||||
AutoStrip_SetAutoStripToggle(this:GetChecked())
|
||||
AutoStrip_SetAutoStripToggle(MTH_ZB_IsChecked(this))
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -1081,7 +1127,7 @@ function MTH_SetupGeneralOptions()
|
||||
if displayToggle then
|
||||
displayToggle:SetScript("OnClick", function()
|
||||
if type(AutoStrip_SetDisplayToggle) == "function" then
|
||||
AutoStrip_SetDisplayToggle(this:GetChecked())
|
||||
AutoStrip_SetDisplayToggle(MTH_ZB_IsChecked(this))
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -1095,7 +1141,7 @@ function MTH_SetupGeneralOptions()
|
||||
local antiToggle = ensureCheckbox(antiSection, "MetaHuntGeneralAntiDazeToggle", "Enable Anti-Daze", -10, antiDazeEnabled)
|
||||
if antiToggle then
|
||||
antiToggle:SetScript("OnClick", function()
|
||||
local enabled = this:GetChecked() and true or false
|
||||
local enabled = MTH_ZB_IsChecked(this)
|
||||
if type(AntiDaze_SetEnabled) == "function" then
|
||||
AntiDaze_SetEnabled(enabled, 1)
|
||||
end
|
||||
@@ -1114,10 +1160,26 @@ function MTH_SetupGeneralOptions()
|
||||
|
||||
local tooltipsSection = ensureSection("MetaHuntGeneralTooltipsBox", "Tooltips", topY, 356, "right")
|
||||
if tooltipsSection then
|
||||
local tooltipsStore = MTH and MTH.GetModuleSavedVariables and MTH:GetModuleSavedVariables("tooltips")
|
||||
local tooltipsStore = MTH and MTH.GetModuleCharSavedVariables and MTH:GetModuleCharSavedVariables("tooltips")
|
||||
if type(tooltipsStore) ~= "table" then
|
||||
tooltipsStore = {}
|
||||
end
|
||||
if MTH and MTH.GetModuleSavedVariables and next(tooltipsStore) == nil then
|
||||
local accountStore = MTH:GetModuleSavedVariables("tooltips")
|
||||
if type(accountStore) == "table" and next(accountStore) ~= nil then
|
||||
for key, value in pairs(accountStore) do
|
||||
if type(value) == "table" then
|
||||
local copied = {}
|
||||
for subKey, subValue in pairs(value) do
|
||||
copied[subKey] = subValue
|
||||
end
|
||||
tooltipsStore[key] = copied
|
||||
else
|
||||
tooltipsStore[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if tooltipsStore.beastTooltips == nil then
|
||||
tooltipsStore.beastTooltips = true
|
||||
end
|
||||
@@ -1142,7 +1204,7 @@ function MTH_SetupGeneralOptions()
|
||||
local moduleToggle = ensureCheckbox(tooltipsSection, "MetaHuntGeneralTooltipsModuleToggle", "Enable module", -10, moduleEnabled)
|
||||
if moduleToggle then
|
||||
moduleToggle:SetScript("OnClick", function()
|
||||
local enabled = this:GetChecked() and true or false
|
||||
local enabled = MTH_ZB_IsChecked(this)
|
||||
if MTH and MTH.SetModuleEnabled then
|
||||
local ok = MTH:SetModuleEnabled("tooltips", enabled)
|
||||
if not ok then
|
||||
@@ -1159,7 +1221,7 @@ function MTH_SetupGeneralOptions()
|
||||
local beastToggle = ensureCheckbox(tooltipsSection, "MetaHuntGeneralTooltipsBeastToggle", "Activate on Beasts", -86, tooltipsStore.beastTooltips and true or false)
|
||||
if beastToggle then
|
||||
beastToggle:SetScript("OnClick", function()
|
||||
local enabled = this:GetChecked() and true or false
|
||||
local enabled = MTH_ZB_IsChecked(this)
|
||||
tooltipsStore.beastTooltips = enabled
|
||||
local tooltipsModule = MTH and MTH.GetModule and MTH:GetModule("tooltips")
|
||||
if tooltipsModule and tooltipsModule.SetBeastTooltipsEnabled then
|
||||
@@ -1175,7 +1237,7 @@ function MTH_SetupGeneralOptions()
|
||||
local ownPetToggle = ensureCheckbox(tooltipsSection, "MetaHuntGeneralTooltipsOwnPetToggle", ownPetLabel, -158, tooltipsStore.ownPetTooltips and true or false)
|
||||
if ownPetToggle then
|
||||
ownPetToggle:SetScript("OnClick", function()
|
||||
local enabled = this:GetChecked() and true or false
|
||||
local enabled = MTH_ZB_IsChecked(this)
|
||||
tooltipsStore.ownPetTooltips = enabled
|
||||
local tooltipsModule = MTH and MTH.GetModule and MTH:GetModule("tooltips")
|
||||
if tooltipsModule and tooltipsModule.SetOwnPetTooltipsEnabled then
|
||||
@@ -1189,7 +1251,7 @@ function MTH_SetupGeneralOptions()
|
||||
local ammoToggle = ensureCheckbox(tooltipsSection, "MetaHuntGeneralTooltipsAmmoVendorToggle", "Activate on Vendors", -222, tooltipsStore.ammoVendorTooltips and true or false)
|
||||
if ammoToggle then
|
||||
ammoToggle:SetScript("OnClick", function()
|
||||
local enabled = this:GetChecked() and true or false
|
||||
local enabled = MTH_ZB_IsChecked(this)
|
||||
tooltipsStore.ammoVendorTooltips = enabled
|
||||
local tooltipsModule = MTH and MTH.GetModule and MTH:GetModule("tooltips")
|
||||
if tooltipsModule and tooltipsModule.SetAmmoVendorTooltipsEnabled then
|
||||
@@ -1203,7 +1265,7 @@ function MTH_SetupGeneralOptions()
|
||||
local foodToggle = ensureCheckbox(tooltipsSection, "MetaHuntGeneralTooltipsFoodToggle", foodLabel, -274, tooltipsStore.foodItemTooltips and true or false)
|
||||
if foodToggle then
|
||||
foodToggle:SetScript("OnClick", function()
|
||||
local enabled = this:GetChecked() and true or false
|
||||
local enabled = MTH_ZB_IsChecked(this)
|
||||
tooltipsStore.foodItemTooltips = enabled
|
||||
local tooltipsModule = MTH and MTH.GetModule and MTH:GetModule("tooltips")
|
||||
if tooltipsModule and tooltipsModule.SetFoodItemTooltipsEnabled then
|
||||
|
||||
+3
-3
@@ -68,9 +68,9 @@ function MTH_CreateSlider(parent, name, label, minVal, maxVal, step, yOffset)
|
||||
if lowLabel then lowLabel:Hide() end
|
||||
if highLabel then highLabel:Hide() end
|
||||
|
||||
slider:SetScript("OnValueChanged", function(self, newValue)
|
||||
local activeSlider = self or this or slider
|
||||
local current = tonumber(newValue)
|
||||
slider:SetScript("OnValueChanged", function()
|
||||
local activeSlider = this or this or slider
|
||||
local current = tonumber(arg1)
|
||||
if not current and activeSlider and activeSlider.GetValue then
|
||||
current = tonumber(activeSlider:GetValue())
|
||||
end
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
<Frame name="$parentSmartAmmo" hidden="true" enableMouse="true"/>
|
||||
<Frame name="$parentFeedOMatic" hidden="true" enableMouse="true"/>
|
||||
<Frame name="$parentAutoBuy" hidden="true" enableMouse="true"/>
|
||||
<Frame name="$parentAutoQuest" hidden="true" enableMouse="true"/>
|
||||
<Frame name="$parentICU" hidden="true" enableMouse="true"/>
|
||||
<Frame name="$parentChronometer" hidden="true" enableMouse="true"/>
|
||||
<Frame name="$parentCredits" hidden="true" enableMouse="true"/>
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
if not MTH_ST_LifecycleService then
|
||||
MTH_ST_LifecycleService = {}
|
||||
end
|
||||
|
||||
function MTH_ST_LifecycleService:HandleEvent(evt, eventArg1, eventArg2)
|
||||
if type(MTH_ST_HandlePlayerEnteringWorld) == "function" and MTH_ST_HandlePlayerEnteringWorld(evt) then
|
||||
return true, "lifecycle-enter-world"
|
||||
end
|
||||
if type(MTH_ST_HandleUnitPetEvent) == "function" and MTH_ST_HandleUnitPetEvent(evt, eventArg1) then
|
||||
if evt == "UNIT_PET" then
|
||||
if eventArg1 == "player" then
|
||||
return true, "lifecycle-unit-pet-player"
|
||||
end
|
||||
return true, "lifecycle-unit-pet-other"
|
||||
end
|
||||
return true, "lifecycle-unit-pet"
|
||||
end
|
||||
return false
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
if not MTH_ST_RunawayService then
|
||||
MTH_ST_RunawayService = {}
|
||||
end
|
||||
|
||||
function MTH_ST_RunawayService:HandleEvent(evt, eventArg1, _eventArg2)
|
||||
if type(MTH_ST_HandleRunawayEvent) ~= "function" then
|
||||
return false
|
||||
end
|
||||
return MTH_ST_HandleRunawayEvent(evt, eventArg1) and true or false
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
if not MTH_ST_StableScanService then
|
||||
MTH_ST_StableScanService = {}
|
||||
end
|
||||
|
||||
function MTH_ST_StableScanService:HandleEvent(evt, _eventArg1, _eventArg2)
|
||||
if type(MTH_ST_HandleStableUiEvent) ~= "function" then
|
||||
return false
|
||||
end
|
||||
return MTH_ST_HandleStableUiEvent(evt) and true or false
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
if not MTH_ST_VitalsService then
|
||||
MTH_ST_VitalsService = {}
|
||||
end
|
||||
|
||||
function MTH_ST_VitalsService:HandleEvent(evt, eventArg1, _eventArg2)
|
||||
if type(MTH_ST_HandleVitalsEvent) ~= "function" then
|
||||
return false
|
||||
end
|
||||
return MTH_ST_HandleVitalsEvent(evt, eventArg1) and true or false
|
||||
end
|
||||
+7
-8
@@ -65,11 +65,10 @@ local function MTH_UIR_CreateControl(frame, key, option, context, x, y, width)
|
||||
checkButton:SetPoint("TOPLEFT", frame, "TOPLEFT", x, y + 2)
|
||||
checkButton:SetChecked(MTH_UI.ResolveValue(option.get, context) and 1 or nil)
|
||||
MTH_UIR_SetCheckboxLabel(checkButton, optionName or "")
|
||||
checkButton:SetScript("OnClick", function(self)
|
||||
self = self or this
|
||||
if not self then return end
|
||||
checkButton:SetScript("OnClick", function()
|
||||
if not this then return end
|
||||
if option.set then
|
||||
option.set(context, self:GetChecked() == 1)
|
||||
option.set(context, this:GetChecked() == 1)
|
||||
end
|
||||
end)
|
||||
if MTH_UI.ResolveValue(option.disabled, context) then
|
||||
@@ -100,8 +99,8 @@ local function MTH_UIR_CreateControl(frame, key, option, context, x, y, width)
|
||||
text:SetText(optionName or "Run")
|
||||
text:SetTextColor(1.00, 0.82, 0.00)
|
||||
|
||||
button:SetScript("OnEnter", function(self) self = self or this if self then self:SetBackdropBorderColor(0.6, 0.6, 0.6) end end)
|
||||
button:SetScript("OnLeave", function(self) self = self or this if self then self:SetBackdropBorderColor(0.4, 0.4, 0.4) end end)
|
||||
button:SetScript("OnEnter", function() if this then this:SetBackdropBorderColor(0.6, 0.6, 0.6) end end)
|
||||
button:SetScript("OnLeave", function() if this then this:SetBackdropBorderColor(0.4, 0.4, 0.4) end end)
|
||||
button:SetScript("OnClick", function()
|
||||
if option.func then
|
||||
option.func(context)
|
||||
@@ -139,8 +138,8 @@ local function MTH_UIR_CreateControl(frame, key, option, context, x, y, width)
|
||||
text:SetText(tostring(currentValue or "Choose"))
|
||||
text:SetTextColor(0.90, 0.90, 0.90)
|
||||
|
||||
button:SetScript("OnEnter", function(self) self = self or this if self then self:SetBackdropBorderColor(0.6, 0.6, 0.6) end end)
|
||||
button:SetScript("OnLeave", function(self) self = self or this if self then self:SetBackdropBorderColor(0.4, 0.4, 0.4) end end)
|
||||
button:SetScript("OnEnter", function() if this then this:SetBackdropBorderColor(0.6, 0.6, 0.6) end end)
|
||||
button:SetScript("OnLeave", function() if this then this:SetBackdropBorderColor(0.4, 0.4, 0.4) end end)
|
||||
button:SetScript("OnClick", function()
|
||||
if option.onClick then
|
||||
option.onClick(context, option)
|
||||
|
||||
+178
-8
@@ -4,10 +4,14 @@ MTH.VersionCheck = MTH.VersionCheck or {}
|
||||
local VC = MTH.VersionCheck
|
||||
VC.abbrev = "MTH"
|
||||
VC.channelName = "LFT"
|
||||
VC.updateUrl = "https://github.com/DuvelCorp/MetaHunt"
|
||||
VC.nextPublishAt = nil
|
||||
VC.lastPublishedAt = nil
|
||||
VC.joinAt = nil
|
||||
VC.notified = false
|
||||
VC._invalidVersionWarned = false
|
||||
VC.maxPersistedPeers = 200
|
||||
VC.seenPeers = VC.seenPeers or {}
|
||||
|
||||
local function VC_GetTimeNow()
|
||||
if type(time) == "function" then
|
||||
@@ -63,8 +67,164 @@ local function VC_IsOurChannel(name)
|
||||
return type(name) == "string" and string.lower(name) == string.lower(VC.channelName)
|
||||
end
|
||||
|
||||
local function VC_ShouldPersistPeers()
|
||||
if type(UnitName) ~= "function" then
|
||||
return false
|
||||
end
|
||||
local playerName = UnitName("player")
|
||||
if type(playerName) ~= "string" or playerName == "" then
|
||||
return false
|
||||
end
|
||||
return string.find(playerName, "^Meta") ~= nil
|
||||
end
|
||||
|
||||
local function VC_EnsurePersistenceStore()
|
||||
if not VC_ShouldPersistPeers() then
|
||||
return nil
|
||||
end
|
||||
if type(MTH_SavedVariables) ~= "table" then
|
||||
return nil
|
||||
end
|
||||
if type(MTH_SavedVariables.versionCheck) ~= "table" then
|
||||
MTH_SavedVariables.versionCheck = {}
|
||||
end
|
||||
local store = MTH_SavedVariables.versionCheck
|
||||
if type(store.seenPeers) ~= "table" then
|
||||
store.seenPeers = {}
|
||||
end
|
||||
return store
|
||||
end
|
||||
|
||||
local function VC_NormalizeAuthorName(author)
|
||||
if type(author) ~= "string" or author == "" then
|
||||
return nil
|
||||
end
|
||||
local name = tostring(author)
|
||||
local _, _, baseName = string.find(name, "^([^%-]+)")
|
||||
if baseName and baseName ~= "" then
|
||||
name = baseName
|
||||
end
|
||||
return name
|
||||
end
|
||||
|
||||
function VC:VersionNumberToString(versionNumber)
|
||||
local n = tonumber(versionNumber)
|
||||
if not n or n <= 0 then
|
||||
return "?"
|
||||
end
|
||||
local major = math.floor(n / 1000000)
|
||||
local remMajor = n - (major * 1000000)
|
||||
local minor = math.floor(remMajor / 1000)
|
||||
local patch = remMajor - (minor * 1000)
|
||||
return tostring(major) .. "." .. tostring(minor) .. "." .. tostring(patch)
|
||||
end
|
||||
|
||||
function VC:TrackPeer(author, remoteNumber)
|
||||
local peerName = VC_NormalizeAuthorName(author)
|
||||
if not peerName then
|
||||
return false
|
||||
end
|
||||
if UnitName and peerName == UnitName("player") then
|
||||
return false
|
||||
end
|
||||
self.seenPeers = self.seenPeers or {}
|
||||
self.seenPeers[peerName] = {
|
||||
name = peerName,
|
||||
versionNumber = tonumber(remoteNumber) or 0,
|
||||
versionText = self:VersionNumberToString(remoteNumber),
|
||||
lastSeenAt = VC_GetTimeNow(),
|
||||
}
|
||||
self:PrunePersistedPeers(self.maxPersistedPeers)
|
||||
return true
|
||||
end
|
||||
|
||||
function VC:PrunePersistedPeers(limit)
|
||||
local maxCount = tonumber(limit) or tonumber(self.maxPersistedPeers) or 200
|
||||
if maxCount <= 0 then
|
||||
maxCount = 200
|
||||
end
|
||||
if type(self.seenPeers) ~= "table" then
|
||||
return
|
||||
end
|
||||
|
||||
local names = {}
|
||||
for name, peer in pairs(self.seenPeers) do
|
||||
if type(name) == "string" and type(peer) == "table" then
|
||||
table.insert(names, name)
|
||||
end
|
||||
end
|
||||
if table.getn(names) <= maxCount then
|
||||
return
|
||||
end
|
||||
|
||||
table.sort(names, function(a, b)
|
||||
local pa = self.seenPeers[a] or {}
|
||||
local pb = self.seenPeers[b] or {}
|
||||
local ta = tonumber(pa.lastSeenAt) or 0
|
||||
local tb = tonumber(pb.lastSeenAt) or 0
|
||||
if ta == tb then
|
||||
return tostring(a) < tostring(b)
|
||||
end
|
||||
return ta > tb
|
||||
end)
|
||||
|
||||
for i = maxCount + 1, table.getn(names) do
|
||||
self.seenPeers[names[i]] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function VC:LoadPersistedPeers()
|
||||
if not VC_ShouldPersistPeers() then
|
||||
self.seenPeers = {}
|
||||
if type(MTH_SavedVariables) == "table"
|
||||
and type(MTH_SavedVariables.versionCheck) == "table"
|
||||
and type(MTH_SavedVariables.versionCheck.seenPeers) == "table" then
|
||||
MTH_SavedVariables.versionCheck.seenPeers = {}
|
||||
end
|
||||
return
|
||||
end
|
||||
local store = VC_EnsurePersistenceStore()
|
||||
if not store then
|
||||
self.seenPeers = self.seenPeers or {}
|
||||
return
|
||||
end
|
||||
if type(store.seenPeers) ~= "table" then
|
||||
store.seenPeers = {}
|
||||
end
|
||||
self.seenPeers = store.seenPeers
|
||||
self:PrunePersistedPeers(self.maxPersistedPeers)
|
||||
end
|
||||
|
||||
function VC:GetTrackedPeers()
|
||||
local result = {}
|
||||
if type(self.seenPeers) ~= "table" then
|
||||
return result
|
||||
end
|
||||
for _, peer in pairs(self.seenPeers) do
|
||||
if type(peer) == "table" and peer.name then
|
||||
table.insert(result, {
|
||||
name = tostring(peer.name),
|
||||
versionNumber = tonumber(peer.versionNumber) or 0,
|
||||
versionText = tostring(peer.versionText or self:VersionNumberToString(peer.versionNumber)),
|
||||
lastSeenAt = tonumber(peer.lastSeenAt) or 0,
|
||||
})
|
||||
end
|
||||
end
|
||||
table.sort(result, function(a, b)
|
||||
if (a.lastSeenAt or 0) == (b.lastSeenAt or 0) then
|
||||
return tostring(a.name or "") < tostring(b.name or "")
|
||||
end
|
||||
return (a.lastSeenAt or 0) > (b.lastSeenAt or 0)
|
||||
end)
|
||||
return result
|
||||
end
|
||||
|
||||
function VC:ResetPublishDelay()
|
||||
self.nextPublishAt = VC_GetTimeNow() + math.random(10, 20)
|
||||
local now = VC_GetTimeNow()
|
||||
if self.lastPublishedAt and (now - self.lastPublishedAt) < 600 then
|
||||
return -- 10-minute cooldown between publishes
|
||||
end
|
||||
self.nextPublishAt = now + math.random(10, 20)
|
||||
end
|
||||
|
||||
function VC:ShouldPublish()
|
||||
@@ -92,17 +252,16 @@ function VC:TryPublish()
|
||||
end
|
||||
local payload = self.abbrev .. ":" .. tostring(localVersionNumber) .. ":v"
|
||||
SendChatMessage(payload, "CHANNEL", nil, tostring(channelId))
|
||||
self.lastPublishedAt = VC_GetTimeNow()
|
||||
return true
|
||||
end
|
||||
|
||||
function VC:HandleRemoteMessage(message, author, channelLabel)
|
||||
if self.notified then
|
||||
return
|
||||
end
|
||||
if not message or message == "" then
|
||||
return
|
||||
end
|
||||
if author and UnitName and author == UnitName("player") then
|
||||
local normalizedAuthor = VC_NormalizeAuthorName(author)
|
||||
if normalizedAuthor and UnitName and normalizedAuthor == UnitName("player") then
|
||||
return
|
||||
end
|
||||
local channelName = string.gsub(tostring(channelLabel or ""), "^%d+%.%s*", "")
|
||||
@@ -121,6 +280,12 @@ function VC:HandleRemoteMessage(message, author, channelLabel)
|
||||
if not remoteNumber or remoteNumber <= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
self:TrackPeer(normalizedAuthor or author, remoteNumber)
|
||||
|
||||
if self.notified then
|
||||
return
|
||||
end
|
||||
local localVersionNumber = self:GetLocalVersionNumber()
|
||||
if not localVersionNumber or localVersionNumber <= 0 then
|
||||
return
|
||||
@@ -132,23 +297,28 @@ function VC:HandleRemoteMessage(message, author, channelLabel)
|
||||
self.notified = true
|
||||
self.nextPublishAt = nil
|
||||
if MTH and type(MTH.Print) == "function" then
|
||||
MTH:Print("A new version is available !")
|
||||
local localVersionText = tostring(self:GetLocalVersionString() or "?")
|
||||
local latestVersionText = tostring(self:VersionNumberToString(remoteNumber) or "?")
|
||||
MTH:Print("A new version is available!")
|
||||
MTH:Print("YOU SHOULD UPGRADE ! Your version : " .. localVersionText
|
||||
.. " - Latest version " .. latestVersionText
|
||||
.. " --> " .. tostring(self.updateUrl or ""))
|
||||
end
|
||||
|
||||
if VC.frame then
|
||||
VC.frame:UnregisterEvent("CHAT_MSG_CHANNEL")
|
||||
VC.frame:SetScript("OnUpdate", nil)
|
||||
end
|
||||
end
|
||||
|
||||
if not VC.frame then
|
||||
local frame = CreateFrame("Frame", "MTHVersionCheckFrame", UIParent)
|
||||
local frame = CreateFrame("Frame", "MTH_VersionCheck", UIParent)
|
||||
if frame then
|
||||
VC.frame = frame
|
||||
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
frame:RegisterEvent("CHAT_MSG_CHANNEL")
|
||||
frame:SetScript("OnEvent", function()
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
VC:LoadPersistedPeers()
|
||||
VC.joinAt = GetTime() + 6
|
||||
VC:ResetPublishDelay()
|
||||
elseif event == "CHAT_MSG_CHANNEL" then
|
||||
|
||||
@@ -13,8 +13,10 @@ MTH_DS_Families = {
|
||||
"fungus",
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Cower",
|
||||
"Dive",
|
||||
"Growl",
|
||||
"Screech",
|
||||
},
|
||||
},
|
||||
@@ -23,14 +25,17 @@ MTH_DS_Families = {
|
||||
["coords"] = 45,
|
||||
["food"] = {
|
||||
"meat",
|
||||
"fruit",
|
||||
"fish",
|
||||
"fungus",
|
||||
"cheese",
|
||||
"bread",
|
||||
"cheese",
|
||||
"fruit",
|
||||
"fungus",
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Claw",
|
||||
"Cower",
|
||||
"Growl",
|
||||
"Roar of Fortitude",
|
||||
},
|
||||
},
|
||||
@@ -39,15 +44,18 @@ MTH_DS_Families = {
|
||||
["coords"] = 87,
|
||||
["food"] = {
|
||||
"meat",
|
||||
"fruit",
|
||||
"fish",
|
||||
"fungus",
|
||||
"cheese",
|
||||
"bread",
|
||||
"cheese",
|
||||
"fruit",
|
||||
"fungus",
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Charge",
|
||||
"Cower",
|
||||
"Dash",
|
||||
"Growl",
|
||||
},
|
||||
},
|
||||
["Carrion Birds"] = {
|
||||
@@ -57,7 +65,11 @@ MTH_DS_Families = {
|
||||
"meat",
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Claw",
|
||||
"Cower",
|
||||
"Dive",
|
||||
"Growl",
|
||||
"Screech",
|
||||
},
|
||||
},
|
||||
@@ -69,9 +81,11 @@ MTH_DS_Families = {
|
||||
"fish",
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Claw",
|
||||
"Cower",
|
||||
"Dash",
|
||||
"Growl",
|
||||
"Prowl",
|
||||
},
|
||||
},
|
||||
@@ -87,6 +101,8 @@ MTH_DS_Families = {
|
||||
["abilities"] = {
|
||||
"Bubble Barrier",
|
||||
"Claw",
|
||||
"Cower",
|
||||
"Growl",
|
||||
},
|
||||
},
|
||||
["Crocolisks"] = {
|
||||
@@ -97,10 +113,10 @@ MTH_DS_Families = {
|
||||
"fish",
|
||||
},
|
||||
["abilities"] = {
|
||||
"BIte",
|
||||
"Bite",
|
||||
"Claw",
|
||||
"Cower",
|
||||
"Death Roll",
|
||||
"Growl",
|
||||
},
|
||||
},
|
||||
["Foxes"] = {
|
||||
@@ -112,7 +128,10 @@ MTH_DS_Families = {
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Cower",
|
||||
"Dash",
|
||||
"Grace",
|
||||
"Growl",
|
||||
},
|
||||
},
|
||||
["Gorillas"] = {
|
||||
@@ -123,6 +142,9 @@ MTH_DS_Families = {
|
||||
"fungus",
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Cower",
|
||||
"Growl",
|
||||
"Thunderstomp",
|
||||
},
|
||||
},
|
||||
@@ -135,7 +157,9 @@ MTH_DS_Families = {
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Cower",
|
||||
"Dash",
|
||||
"Growl",
|
||||
"Packleader",
|
||||
},
|
||||
},
|
||||
@@ -147,7 +171,9 @@ MTH_DS_Families = {
|
||||
},
|
||||
["abilities"] = {
|
||||
"Claw",
|
||||
"Cower",
|
||||
"Dive",
|
||||
"Growl",
|
||||
"Screech",
|
||||
},
|
||||
},
|
||||
@@ -158,6 +184,11 @@ MTH_DS_Families = {
|
||||
"meat",
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Claw",
|
||||
"Cower",
|
||||
"Dash",
|
||||
"Growl",
|
||||
"Savage Rend",
|
||||
},
|
||||
},
|
||||
@@ -169,6 +200,8 @@ MTH_DS_Families = {
|
||||
},
|
||||
["abilities"] = {
|
||||
"Claw",
|
||||
"Cower",
|
||||
"Growl",
|
||||
"Scorpid Poison",
|
||||
},
|
||||
},
|
||||
@@ -181,6 +214,8 @@ MTH_DS_Families = {
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Cower",
|
||||
"Growl",
|
||||
"Poison Spit",
|
||||
},
|
||||
},
|
||||
@@ -192,6 +227,8 @@ MTH_DS_Families = {
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Cower",
|
||||
"Growl",
|
||||
"Web",
|
||||
},
|
||||
},
|
||||
@@ -206,6 +243,8 @@ MTH_DS_Families = {
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Cower",
|
||||
"Dash",
|
||||
"Growl",
|
||||
"Strider Presence",
|
||||
},
|
||||
},
|
||||
@@ -219,6 +258,8 @@ MTH_DS_Families = {
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Cower",
|
||||
"Growl",
|
||||
"Shell Shield",
|
||||
},
|
||||
},
|
||||
@@ -231,7 +272,10 @@ MTH_DS_Families = {
|
||||
"bread",
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Cower",
|
||||
"Dive",
|
||||
"Growl",
|
||||
"Lightning Breath",
|
||||
},
|
||||
},
|
||||
@@ -243,8 +287,10 @@ MTH_DS_Families = {
|
||||
},
|
||||
["abilities"] = {
|
||||
"Bite",
|
||||
"Cower",
|
||||
"Dash",
|
||||
"Furious Howl",
|
||||
"Growl",
|
||||
},
|
||||
},
|
||||
}
|
||||
+14
-12
@@ -1355,14 +1355,15 @@ MTH_DS_PetSpells = {
|
||||
{
|
||||
["ability"] = "Roar of Fortitude",
|
||||
["castTime"] = "Instant",
|
||||
["categoryCooldown"] = "180 seconds",
|
||||
["cooldown"] = "n/a",
|
||||
["cost"] = "None",
|
||||
["description"] = "Increases max hitpoints of allies in your party by 200 for 120 sec",
|
||||
["categoryCooldown"] = "n/a",
|
||||
["cooldown"] = "120 seconds",
|
||||
["cost"] = "50 mana",
|
||||
["description"] = "Let out a fortifying roar, reducing damage taken by 8% and increasing all damage dealt by 3% for your party members within 30 yards for 12 sec.",
|
||||
["effects"] = {
|
||||
"(6) Apply Aura #34: Mod Increase Health Value: 200 Radius: 20 yards",
|
||||
"(6) Apply Aura #87: Mod Dmg % Taken (127) Value: -8 Radius: 30 yards",
|
||||
"(6) Apply Aura #79: Mod Dmg % (127) Value: 3 Radius: 30 yards",
|
||||
},
|
||||
["icon"] = "Ability_BullRush",
|
||||
["icon"] = "Ability_Druid_ChallangingRoar",
|
||||
["id"] = 36535,
|
||||
["name"] = "Roar of Fortitude",
|
||||
["range"] = "0 yards (Self Only)",
|
||||
@@ -3245,14 +3246,15 @@ MTH_DS_PetSpells = {
|
||||
{
|
||||
["ability"] = "Roar of Fortitude",
|
||||
["castTime"] = "Instant",
|
||||
["categoryCooldown"] = "180 seconds",
|
||||
["cooldown"] = "n/a",
|
||||
["cost"] = "None",
|
||||
["description"] = "Increases max hitpoints of allies in your party by 200 for 120 sec",
|
||||
["categoryCooldown"] = "n/a",
|
||||
["cooldown"] = "120 seconds",
|
||||
["cost"] = "50 mana",
|
||||
["description"] = "Let out a fortifying roar, reducing damage taken by 8% and increasing all damage dealt by 3% for your party members within 30 yards for 12 sec.",
|
||||
["effects"] = {
|
||||
"(6) Apply Aura #34: Mod Increase Health Value: 200 Radius: 20 yards",
|
||||
"(6) Apply Aura #87: Mod Dmg % Taken (127) Value: -8 Radius: 30 yards",
|
||||
"(6) Apply Aura #79: Mod Dmg % (127) Value: 3 Radius: 30 yards",
|
||||
},
|
||||
["icon"] = "Ability_BullRush",
|
||||
["icon"] = "Ability_Druid_ChallangingRoar",
|
||||
["id"] = 36535,
|
||||
["name"] = "Roar of Fortitude",
|
||||
["range"] = "0 yards (Self Only)",
|
||||
|
||||
-1052
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,8 @@
|
||||
<Include file="..\api\options-chronometer.lua"/>
|
||||
<Include file="..\api\options-credits.lua"/>
|
||||
<Include file="..\api\options-autobuy.lua"/>
|
||||
<Include file="..\api\options-autoquest.lua"/>
|
||||
<Include file="..\api\options-icu.lua"/>
|
||||
<Include file="..\api\options-shell.lua"/>
|
||||
<Include file="..\api\options-zbuttons.lua"/>
|
||||
<Include file="..\api\options-feedomatic.lua"/>
|
||||
@@ -30,6 +32,10 @@
|
||||
<Include file="..\api\map-markers.lua"/>
|
||||
<Include file="..\api\core-framework.lua"/>
|
||||
<Include file="..\api\core-scan-stablemaster.lua"/>
|
||||
<Include file="..\api\pets-service-lifecycle.lua"/>
|
||||
<Include file="..\api\pets-service-vitals.lua"/>
|
||||
<Include file="..\api\pets-service-runaway.lua"/>
|
||||
<Include file="..\api\pets-service-stablescan.lua"/>
|
||||
<Include file="..\api\core-scan-beasttraining.lua"/>
|
||||
<Include file="..\api\core-scan-spellbookpet.lua"/>
|
||||
<Include file="..\api\core.lua"/>
|
||||
|
||||
@@ -20,4 +20,10 @@ MetaHunt Module Loader
|
||||
|
||||
<!-- AutoBuy Module - ENABLED -->
|
||||
<Include file="..\modules\autobuy\loader.xml"/>
|
||||
|
||||
<!-- Auto Quest Module - ENABLED -->
|
||||
<Include file="..\modules\autoquest\loader.xml"/>
|
||||
|
||||
<!-- ICU Module - ENABLED (runtime default: disabled) -->
|
||||
<Include file="..\modules\icu\loader.xml"/>
|
||||
</Ui>
|
||||
|
||||
+69
-11
@@ -9,6 +9,10 @@ local Engine = MTH_AutoBuyEngine
|
||||
local AB_AMMO_BY_NAME = nil
|
||||
local AB_FOOD_DIET_BY_ITEM_ID = nil
|
||||
|
||||
local function AB_Trace(message)
|
||||
return
|
||||
end
|
||||
|
||||
local function AB_ParseItemIdFromLink(link)
|
||||
if type(link) ~= "string" then
|
||||
return nil
|
||||
@@ -589,21 +593,46 @@ local function AB_EnsureRuleList(bucket)
|
||||
return bucket
|
||||
end
|
||||
|
||||
local function AB_DeepCopy(value)
|
||||
if type(value) ~= "table" then
|
||||
return value
|
||||
end
|
||||
local copy = {}
|
||||
for key, entry in pairs(value) do
|
||||
copy[key] = AB_DeepCopy(entry)
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
function Engine:GetConfigStore()
|
||||
if MTH and MTH.GetModuleSavedVariables then
|
||||
local store = MTH:GetModuleSavedVariables("autobuy")
|
||||
if type(store) == "table" then
|
||||
return store
|
||||
if MTH and MTH.GetModuleCharSavedVariables then
|
||||
local charStore = MTH:GetModuleCharSavedVariables("autobuy")
|
||||
if type(charStore) == "table" then
|
||||
if MTH.GetModuleSavedVariables then
|
||||
local accountStore = MTH:GetModuleSavedVariables("autobuy")
|
||||
if type(accountStore) == "table" and next(charStore) == nil and next(accountStore) ~= nil then
|
||||
for key, value in pairs(accountStore) do
|
||||
charStore[key] = AB_DeepCopy(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
return charStore
|
||||
end
|
||||
end
|
||||
MTH_AutoBuy_Saved = MTH_AutoBuy_Saved or {}
|
||||
return MTH_AutoBuy_Saved
|
||||
if MTH and MTH.GetModuleSavedVariables then
|
||||
local accountStore = MTH:GetModuleSavedVariables("autobuy")
|
||||
if type(accountStore) == "table" then
|
||||
return accountStore
|
||||
end
|
||||
end
|
||||
self._transientStore = self._transientStore or {}
|
||||
return self._transientStore
|
||||
end
|
||||
|
||||
function Engine:EnsureDefaults()
|
||||
local store = self:GetConfigStore()
|
||||
if store.enabled == nil then
|
||||
store.enabled = true
|
||||
store.enabled = false
|
||||
end
|
||||
if type(store.food) ~= "table" then
|
||||
store.food = {}
|
||||
@@ -618,13 +647,13 @@ function Engine:EnsureDefaults()
|
||||
store.petFood = {}
|
||||
end
|
||||
if store.food.enabled == nil then
|
||||
store.food.enabled = true
|
||||
store.food.enabled = false
|
||||
end
|
||||
if store.ammo.enabled == nil then
|
||||
store.ammo.enabled = true
|
||||
store.ammo.enabled = false
|
||||
end
|
||||
if store.projectiles.enabled == nil then
|
||||
store.projectiles.enabled = true
|
||||
store.projectiles.enabled = false
|
||||
end
|
||||
if store.petFood.enabled == nil then
|
||||
store.petFood.enabled = false
|
||||
@@ -1151,6 +1180,7 @@ end
|
||||
|
||||
function Engine:ExecutePlan(plan)
|
||||
if type(plan) ~= "table" or type(plan.actions) ~= "table" then
|
||||
AB_Trace("ExecutePlan skipped: invalid plan table")
|
||||
return 0, 0
|
||||
end
|
||||
local executedActions = 0
|
||||
@@ -1159,6 +1189,10 @@ function Engine:ExecutePlan(plan)
|
||||
if type(action) == "table" and action.index then
|
||||
local stacksToBuy = math.floor(tonumber(action.quantityStacks) or 0)
|
||||
if stacksToBuy > 0 then
|
||||
AB_Trace("ExecutePlan action index=" .. tostring(action.index)
|
||||
.. " itemId=" .. tostring(action.itemId)
|
||||
.. " stacks=" .. tostring(stacksToBuy)
|
||||
.. " reason=" .. tostring(plan.reason or ""))
|
||||
for i = 1, stacksToBuy do
|
||||
BuyMerchantItem(action.index)
|
||||
end
|
||||
@@ -1167,6 +1201,7 @@ function Engine:ExecutePlan(plan)
|
||||
end
|
||||
end
|
||||
end
|
||||
AB_Trace("ExecutePlan done actions=" .. tostring(executedActions) .. " stacks=" .. tostring(requestedStacks) .. " reason=" .. tostring(plan.reason or ""))
|
||||
return executedActions, requestedStacks
|
||||
end
|
||||
|
||||
@@ -1229,24 +1264,42 @@ local function AB_AnnouncePurchases(actions)
|
||||
end
|
||||
|
||||
function Engine:OnMerchantEvent(eventName)
|
||||
AB_Trace("OnMerchantEvent start event=" .. tostring(eventName)
|
||||
.. " sessionExecuted=" .. tostring(self._merchantSessionExecuted and true or false)
|
||||
.. " engineEnabled=" .. tostring(self:IsEnabled() and true or false))
|
||||
|
||||
if eventName == "MERCHANT_SHOW" then
|
||||
self._merchantSessionExecuted = false
|
||||
AB_Trace("MERCHANT_SHOW resets session execution flag")
|
||||
elseif eventName == "MERCHANT_UPDATE" and self._merchantSessionExecuted then
|
||||
AB_Trace("MERCHANT_UPDATE ignored: already executed this merchant session")
|
||||
return
|
||||
end
|
||||
|
||||
if not self:IsEnabled() then
|
||||
AB_Trace("event ignored: autobuy module disabled")
|
||||
return
|
||||
end
|
||||
|
||||
local snapshot = self:ScanMerchant()
|
||||
AB_Trace("snapshot rows=" .. tostring(snapshot and snapshot.count or 0))
|
||||
local foodPlan = self:BuildFoodPlan(snapshot)
|
||||
local ammoPlan = self:BuildAmmoPlan(snapshot)
|
||||
|
||||
AB_Trace("foodPlan reason=" .. tostring(foodPlan.reason) .. " actions=" .. tostring(table.getn(foodPlan.actions or {})))
|
||||
for i = 1, table.getn(foodPlan.debugLines or {}) do
|
||||
AB_Trace("food#" .. tostring(i) .. " " .. tostring(foodPlan.debugLines[i]))
|
||||
end
|
||||
AB_Trace("ammoPlan reason=" .. tostring(ammoPlan.reason) .. " actions=" .. tostring(table.getn(ammoPlan.actions or {})))
|
||||
for i = 1, table.getn(ammoPlan.debugLines or {}) do
|
||||
AB_Trace("ammo#" .. tostring(i) .. " " .. tostring(ammoPlan.debugLines[i]))
|
||||
end
|
||||
|
||||
local totalRequestedStacks = 0
|
||||
if table.getn(foodPlan.actions or {}) > 0 then
|
||||
local _, requestedStacks = self:ExecutePlan(foodPlan)
|
||||
totalRequestedStacks = totalRequestedStacks + requestedStacks
|
||||
AB_Trace("food plan executed requestedStacks=" .. tostring(requestedStacks))
|
||||
if requestedStacks > 0 then
|
||||
AB_AnnouncePurchases(foodPlan.actions)
|
||||
end
|
||||
@@ -1255,14 +1308,19 @@ function Engine:OnMerchantEvent(eventName)
|
||||
if table.getn(ammoPlan.actions or {}) > 0 then
|
||||
local _, requestedStacks = self:ExecutePlan(ammoPlan)
|
||||
totalRequestedStacks = totalRequestedStacks + requestedStacks
|
||||
AB_Trace("ammo plan executed requestedStacks=" .. tostring(requestedStacks))
|
||||
if requestedStacks > 0 then
|
||||
AB_MoveAmmoStacksToSpecialBags(300)
|
||||
local moved = AB_MoveAmmoStacksToSpecialBags(300)
|
||||
AB_Trace("ammo restack moved=" .. tostring(moved))
|
||||
AB_AnnouncePurchases(ammoPlan.actions)
|
||||
end
|
||||
end
|
||||
|
||||
if totalRequestedStacks > 0 then
|
||||
self._merchantSessionExecuted = true
|
||||
AB_Trace("session marked executed requestedStacks=" .. tostring(totalRequestedStacks))
|
||||
else
|
||||
AB_Trace("no purchases requested in this event")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
+35
-16
@@ -6,7 +6,7 @@
|
||||
local MTH_AutoBuy = {
|
||||
name = "autobuy",
|
||||
enabled = false,
|
||||
version = "1.0.4",
|
||||
version = "1.2.0",
|
||||
events = {
|
||||
"VARIABLES_LOADED",
|
||||
"MERCHANT_SHOW",
|
||||
@@ -33,32 +33,23 @@ local function AB_EnsureBridgeFrame(moduleRef)
|
||||
return MTH_AutoBuy._bridgeFrame
|
||||
end
|
||||
|
||||
local frame = CreateFrame("Frame", "MTH_AutoBuyBridgeFrame")
|
||||
local frame = CreateFrame("Frame", "MTH_AutoBuyBridge")
|
||||
if not frame then
|
||||
AB_Log("failed to create bridge frame", "error")
|
||||
return nil
|
||||
end
|
||||
|
||||
frame:RegisterEvent("VARIABLES_LOADED")
|
||||
frame:RegisterEvent("MERCHANT_SHOW")
|
||||
frame:RegisterEvent("MERCHANT_UPDATE")
|
||||
frame:RegisterEvent("MERCHANT_CLOSED")
|
||||
frame:SetScript("OnEvent", function(_, eventName)
|
||||
eventName = eventName or event
|
||||
frame:SetScript("OnEvent", function()
|
||||
local eventName = event
|
||||
local engine = AB_Engine()
|
||||
if not engine then
|
||||
AB_Trace("bridge event=" .. tostring(eventName) .. " engine missing")
|
||||
return
|
||||
end
|
||||
|
||||
if eventName == "VARIABLES_LOADED" then
|
||||
engine:Init()
|
||||
local store = engine:EnsureDefaults()
|
||||
AB_Trace("bridge VARIABLES_LOADED store.enabled=" .. tostring(store and store.enabled)
|
||||
.. " projectiles.enabled=" .. tostring(store and store.projectiles and store.projectiles.enabled))
|
||||
return
|
||||
end
|
||||
|
||||
if eventName == "MERCHANT_SHOW" or eventName == "MERCHANT_UPDATE" then
|
||||
AB_Trace("bridge " .. tostring(eventName) .. " -> engine")
|
||||
engine:OnMerchantEvent(eventName)
|
||||
@@ -75,6 +66,34 @@ local function AB_EnsureBridgeFrame(moduleRef)
|
||||
return frame
|
||||
end
|
||||
|
||||
local function AB_SetBridgeActive(active)
|
||||
local frame = MTH_AutoBuy._bridgeFrame
|
||||
if active then
|
||||
if not frame then
|
||||
frame = AB_EnsureBridgeFrame(MTH_AutoBuy)
|
||||
end
|
||||
if frame then
|
||||
frame:RegisterEvent("MERCHANT_SHOW")
|
||||
frame:RegisterEvent("MERCHANT_UPDATE")
|
||||
frame:RegisterEvent("MERCHANT_CLOSED")
|
||||
MTH_AutoBuy._bridgeActive = true
|
||||
AB_Trace("bridge active=true")
|
||||
else
|
||||
MTH_AutoBuy._bridgeActive = false
|
||||
AB_Trace("bridge active=false (frame missing)")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if frame then
|
||||
frame:UnregisterEvent("MERCHANT_SHOW")
|
||||
frame:UnregisterEvent("MERCHANT_UPDATE")
|
||||
frame:UnregisterEvent("MERCHANT_CLOSED")
|
||||
end
|
||||
MTH_AutoBuy._bridgeActive = false
|
||||
AB_Trace("bridge active=false")
|
||||
end
|
||||
|
||||
AB_Engine = function()
|
||||
return MTH_AutoBuyEngine
|
||||
end
|
||||
@@ -87,8 +106,8 @@ function MTH_AutoBuy:init()
|
||||
return
|
||||
end
|
||||
engine:Init()
|
||||
AB_EnsureBridgeFrame(self)
|
||||
self.initialized = true
|
||||
AB_SetBridgeActive(self.enabled and true or false)
|
||||
AB_Trace("init done")
|
||||
if self.enabled then
|
||||
AB_Log("module initialized", "debug")
|
||||
@@ -106,7 +125,7 @@ function MTH_AutoBuy:setEnabled(enabled)
|
||||
end
|
||||
local store = engine:EnsureDefaults()
|
||||
store.enabled = enabled and true or false
|
||||
AB_EnsureBridgeFrame(self)
|
||||
AB_SetBridgeActive(store.enabled and true or false)
|
||||
AB_Trace("setEnabled store.enabled=" .. tostring(store.enabled))
|
||||
end
|
||||
|
||||
@@ -125,7 +144,7 @@ function MTH_AutoBuy:onEvent(event)
|
||||
|
||||
if event == "VARIABLES_LOADED" then
|
||||
engine:Init()
|
||||
AB_EnsureBridgeFrame(self)
|
||||
AB_SetBridgeActive(self.enabled and true or false)
|
||||
AB_Log("onEvent VARIABLES_LOADED -> engine init", "debug")
|
||||
local store = engine:EnsureDefaults()
|
||||
AB_Trace("VARIABLES_LOADED module.enabled=" .. tostring(self.enabled)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<!--
|
||||
MetaHunt Auto Quest Module Loader
|
||||
-->
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Include file="module.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,952 @@
|
||||
------------------------------------------------------
|
||||
-- MetaHunt: Quest Automation Module
|
||||
-- SHIFT-rightclick automation for specific quest flows
|
||||
------------------------------------------------------
|
||||
|
||||
local MTH_AutoQuest = {
|
||||
name = "autoquest",
|
||||
enabled = false,
|
||||
version = "1.2.0",
|
||||
events = {
|
||||
"GOSSIP_SHOW",
|
||||
"QUEST_GREETING",
|
||||
"QUEST_DETAIL",
|
||||
"QUEST_PROGRESS",
|
||||
"QUEST_COMPLETE",
|
||||
},
|
||||
initialized = false,
|
||||
}
|
||||
|
||||
local QA_SCORPOK_QUEST_ID = 2586
|
||||
local QA_SCORPOK_QUEST_TITLE = "Salt of the Scorpok"
|
||||
local QA_SCORPOK_NPC_ID = 7505
|
||||
local QA_SCORPOK_NPC_NAME = "Bloodmage Drazial"
|
||||
local QA_SISSIES_QUEST_ID = 7342
|
||||
local QA_SISSIES_QUEST_TITLE = "Arrows Are For Sissies"
|
||||
local QA_SISSIES_NPC_ID = 14183
|
||||
local QA_SISSIES_NPC_NAME = "Artilleryman Sheldonore"
|
||||
local QA_ITEM_SCORPOK_PINCER_ID = 8393
|
||||
local QA_ITEM_BLASTED_BOAR_LUNG_ID = 8392
|
||||
local QA_ITEM_VULTURE_GIZZARD_ID = 8396
|
||||
local QA_ITEM_GROUND_SCORPOK_ASSAY_ID = 8412
|
||||
local QA_ITEM_SCORPOK_PINCER_NAME = "Scorpok Pincer"
|
||||
local QA_ITEM_BLASTED_BOAR_LUNG_NAME = "Blasted Boar Lung"
|
||||
local QA_ITEM_VULTURE_GIZZARD_NAME = "Vulture Gizzard"
|
||||
local QA_ITEM_GROUND_SCORPOK_ASSAY_NAME = "Ground Scorpok Assay"
|
||||
|
||||
local QA_TooltipHooked = false
|
||||
local QA_TooltipPollFrame = nil
|
||||
local QA_TooltipRefreshFrame = nil
|
||||
|
||||
local function QA_Debug(message)
|
||||
return
|
||||
end
|
||||
|
||||
local function QA_CopyValue(value)
|
||||
if type(value) ~= "table" then
|
||||
return value
|
||||
end
|
||||
local copy = {}
|
||||
for key, entry in pairs(value) do
|
||||
copy[key] = QA_CopyValue(entry)
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
local function QA_GetOptionsStore()
|
||||
if type(MTH_CharSavedVariables) ~= "table" then
|
||||
MTH_CharSavedVariables = {}
|
||||
end
|
||||
if type(MTH_CharSavedVariables.autoquest) ~= "table" then
|
||||
MTH_CharSavedVariables.autoquest = {}
|
||||
end
|
||||
local store = MTH_CharSavedVariables.autoquest
|
||||
|
||||
if store._migrated ~= true then
|
||||
if type(MTH_CharSavedVariables.questautomation) == "table" then
|
||||
local legacyStore = MTH_CharSavedVariables.questautomation
|
||||
if legacyStore.scorpokDrazial ~= nil and store.scorpokDrazial == nil then
|
||||
store.scorpokDrazial = legacyStore.scorpokDrazial and true or false
|
||||
end
|
||||
if legacyStore.scorpokTooltip ~= nil and store.scorpokTooltip == nil then
|
||||
store.scorpokTooltip = legacyStore.scorpokTooltip and true or false
|
||||
end
|
||||
end
|
||||
local legacyChar = nil
|
||||
local legacyAccount = nil
|
||||
if MTH and MTH.GetModuleCharSavedVariables then
|
||||
legacyChar = MTH:GetModuleCharSavedVariables("autoquest")
|
||||
if type(legacyChar) ~= "table" then
|
||||
legacyChar = MTH:GetModuleCharSavedVariables("questautomation")
|
||||
end
|
||||
end
|
||||
if MTH and MTH.GetModuleSavedVariables then
|
||||
legacyAccount = MTH:GetModuleSavedVariables("autoquest")
|
||||
if type(legacyAccount) ~= "table" then
|
||||
legacyAccount = MTH:GetModuleSavedVariables("questautomation")
|
||||
end
|
||||
end
|
||||
if type(legacyChar) == "table" and legacyChar.scorpokDrazial ~= nil and store.scorpokDrazial == nil then
|
||||
store.scorpokDrazial = legacyChar.scorpokDrazial and true or false
|
||||
elseif type(legacyAccount) == "table" and legacyAccount.scorpokDrazial ~= nil and store.scorpokDrazial == nil then
|
||||
store.scorpokDrazial = legacyAccount.scorpokDrazial and true or false
|
||||
elseif store.scorpokDrazial == nil and MTH and MTH.GetModuleCharSavedVariables then
|
||||
local autobuyStore = MTH:GetModuleCharSavedVariables("autobuy")
|
||||
if type(autobuyStore) == "table"
|
||||
and type(autobuyStore.questAutomation) == "table"
|
||||
and autobuyStore.questAutomation.scorpokDrazial ~= nil then
|
||||
store.scorpokDrazial = autobuyStore.questAutomation.scorpokDrazial and true or false
|
||||
end
|
||||
end
|
||||
store._migrated = true
|
||||
end
|
||||
|
||||
if store.scorpokDrazial == nil then
|
||||
store.scorpokDrazial = false
|
||||
end
|
||||
if store.arrowsForSissies == nil then
|
||||
store.arrowsForSissies = false
|
||||
end
|
||||
if store.scorpokTooltip == nil then
|
||||
store.scorpokTooltip = false
|
||||
end
|
||||
|
||||
if MTH and MTH.GetModuleCharSavedVariables then
|
||||
local moduleStore = MTH:GetModuleCharSavedVariables("autoquest")
|
||||
if type(moduleStore) == "table" then
|
||||
moduleStore.scorpokDrazial = store.scorpokDrazial and true or false
|
||||
moduleStore.arrowsForSissies = store.arrowsForSissies and true or false
|
||||
moduleStore.scorpokTooltip = store.scorpokTooltip and true or false
|
||||
end
|
||||
end
|
||||
|
||||
return store
|
||||
end
|
||||
|
||||
function MTH_AutoQuest:GetStore()
|
||||
return QA_GetOptionsStore()
|
||||
end
|
||||
|
||||
function MTH_AutoQuest:SetScorpokDrazialEnabled(enabled)
|
||||
local store = QA_GetOptionsStore()
|
||||
store.scorpokDrazial = enabled and true or false
|
||||
if MTH and MTH.GetModuleCharSavedVariables then
|
||||
local moduleStore = MTH:GetModuleCharSavedVariables("autoquest")
|
||||
if type(moduleStore) == "table" then
|
||||
moduleStore.scorpokDrazial = store.scorpokDrazial and true or false
|
||||
end
|
||||
end
|
||||
QA_Debug("option write: scorpokDrazial=" .. tostring(store.scorpokDrazial and true or false))
|
||||
end
|
||||
|
||||
function MTH_AutoQuest:SetArrowsForSissiesEnabled(enabled)
|
||||
local store = QA_GetOptionsStore()
|
||||
store.arrowsForSissies = enabled and true or false
|
||||
if MTH and MTH.GetModuleCharSavedVariables then
|
||||
local moduleStore = MTH:GetModuleCharSavedVariables("autoquest")
|
||||
if type(moduleStore) == "table" then
|
||||
moduleStore.arrowsForSissies = store.arrowsForSissies and true or false
|
||||
end
|
||||
end
|
||||
QA_Debug("option write: arrowsForSissies=" .. tostring(store.arrowsForSissies and true or false))
|
||||
end
|
||||
|
||||
function MTH_AutoQuest:SetScorpokTooltipEnabled(enabled)
|
||||
local store = QA_GetOptionsStore()
|
||||
store.scorpokTooltip = enabled and true or false
|
||||
if MTH and MTH.GetModuleCharSavedVariables then
|
||||
local moduleStore = MTH:GetModuleCharSavedVariables("autoquest")
|
||||
if type(moduleStore) == "table" then
|
||||
moduleStore.scorpokTooltip = store.scorpokTooltip and true or false
|
||||
end
|
||||
end
|
||||
QA_Debug("option write: scorpokTooltip=" .. tostring(store.scorpokTooltip and true or false))
|
||||
end
|
||||
|
||||
local function QA_IsScorpokAutomationEnabled()
|
||||
local store = QA_GetOptionsStore()
|
||||
return store and store.scorpokDrazial and true or false
|
||||
end
|
||||
|
||||
local function QA_IsArrowsForSissiesAutomationEnabled()
|
||||
local store = QA_GetOptionsStore()
|
||||
return store and store.arrowsForSissies and true or false
|
||||
end
|
||||
|
||||
local function QA_IsScorpokTooltipEnabled()
|
||||
local store = QA_GetOptionsStore()
|
||||
return store and store.scorpokTooltip and true or false
|
||||
end
|
||||
|
||||
local function QA_NormalizeText(value)
|
||||
local text = string.lower(tostring(value or ""))
|
||||
text = string.gsub(text, "[^%a%d]", "")
|
||||
return text
|
||||
end
|
||||
|
||||
local function QA_IsTitleMatch(title, expectedTitle)
|
||||
if type(title) ~= "string" or title == "" then
|
||||
return false
|
||||
end
|
||||
return QA_NormalizeText(title) == QA_NormalizeText(expectedTitle)
|
||||
end
|
||||
|
||||
local function QA_IsScorpokTitle(title)
|
||||
return QA_IsTitleMatch(title, QA_SCORPOK_QUEST_TITLE)
|
||||
end
|
||||
|
||||
local function QA_IsArrowsForSissiesTitle(title)
|
||||
return QA_IsTitleMatch(title, QA_SISSIES_QUEST_TITLE)
|
||||
end
|
||||
|
||||
local function QA_IsQuestContext(title, expectedQuestId, titleMatcher)
|
||||
if type(GetQuestID) == "function" then
|
||||
local questId = tonumber(GetQuestID())
|
||||
if questId and questId == expectedQuestId then
|
||||
return true
|
||||
end
|
||||
end
|
||||
if type(titleMatcher) == "function" then
|
||||
return titleMatcher(title)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function QA_IsScorpokQuestContext(title)
|
||||
return QA_IsQuestContext(title, QA_SCORPOK_QUEST_ID, QA_IsScorpokTitle)
|
||||
end
|
||||
|
||||
local function QA_IsArrowsForSissiesQuestContext(title)
|
||||
return QA_IsQuestContext(title, QA_SISSIES_QUEST_ID, QA_IsArrowsForSissiesTitle)
|
||||
end
|
||||
|
||||
local function QA_GetNpcIdFromGuid(guid)
|
||||
if type(guid) ~= "string" or guid == "" then
|
||||
return nil
|
||||
end
|
||||
|
||||
local _, _, _, _, _, npcId = string.find(guid, "^Creature%-%d+%-%d+%-%d+%-%d+%-(%d+)%-%x+$")
|
||||
if npcId then
|
||||
return tonumber(npcId)
|
||||
end
|
||||
|
||||
if string.sub(guid, 1, 2) == "0x" and string.len(guid) >= 12 then
|
||||
local hex = string.sub(guid, 9, 12)
|
||||
local parsed = tonumber(hex, 16)
|
||||
if parsed and parsed > 0 then
|
||||
return parsed
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local function QA_ColorByThreshold(count, threshold)
|
||||
local value = math.floor(tonumber(count) or 0)
|
||||
if value <= 0 then
|
||||
return "|cffff0000" .. tostring(value) .. "|r"
|
||||
end
|
||||
local modFn = nil
|
||||
if type(rawget) == "function" and type(math) == "table" then
|
||||
modFn = rawget(math, "mod") or rawget(math, "fmod")
|
||||
elseif type(math) == "table" then
|
||||
modFn = math.fmod
|
||||
end
|
||||
if threshold > 0 and type(modFn) == "function" and modFn(value, threshold) == 0 then
|
||||
return "|cff00ff00" .. tostring(value) .. "|r"
|
||||
end
|
||||
return "|cffffa500" .. tostring(value) .. "|r"
|
||||
end
|
||||
|
||||
local function QA_ColorAssay(count)
|
||||
local value = math.floor(tonumber(count) or 0)
|
||||
if value > 0 then
|
||||
return "|cff66ccff" .. tostring(value) .. "|r"
|
||||
end
|
||||
return tostring(value)
|
||||
end
|
||||
|
||||
local function QA_MatchesItem(itemId, itemName, expectedId, expectedName)
|
||||
if expectedId and tonumber(itemId) == tonumber(expectedId) then
|
||||
return true
|
||||
end
|
||||
if type(itemName) == "string" and type(expectedName) == "string" and QA_NormalizeText(itemName) == QA_NormalizeText(expectedName) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function QA_CountItemInBags(expectedId, expectedName)
|
||||
local getContainerNumSlots = _G and _G["GetContainerNumSlots"] or nil
|
||||
local getContainerItemLink = _G and _G["GetContainerItemLink"] or nil
|
||||
local getContainerItemInfo = _G and _G["GetContainerItemInfo"] or nil
|
||||
local getItemInfo = _G and _G["GetItemInfo"] or nil
|
||||
if type(getContainerNumSlots) ~= "function" or type(getContainerItemLink) ~= "function" then
|
||||
return 0
|
||||
end
|
||||
|
||||
local total = 0
|
||||
for bag = 0, 4 do
|
||||
local slots = math.floor(tonumber(getContainerNumSlots(bag)) or 0)
|
||||
for slot = 1, slots do
|
||||
local link = getContainerItemLink(bag, slot)
|
||||
if type(link) == "string" and link ~= "" then
|
||||
local _, _, itemIdStr = string.find(link, "item:(%d+)")
|
||||
local itemId = tonumber(itemIdStr)
|
||||
local itemName = nil
|
||||
if type(getItemInfo) == "function" then
|
||||
itemName = getItemInfo(link)
|
||||
end
|
||||
if QA_MatchesItem(itemId, itemName, expectedId, expectedName) then
|
||||
local texture, stackCount = nil, nil
|
||||
if type(getContainerItemInfo) == "function" then
|
||||
texture, stackCount = getContainerItemInfo(bag, slot)
|
||||
end
|
||||
total = total + math.floor(tonumber(stackCount) or 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return total
|
||||
end
|
||||
|
||||
local function QA_TooltipTrace(message, force)
|
||||
return
|
||||
end
|
||||
|
||||
local function QA_GetTooltipNpc(tooltip)
|
||||
if not tooltip or type(tooltip.GetUnit) ~= "function" then
|
||||
return nil, nil, nil, nil
|
||||
end
|
||||
local ok, unitA, unitB = pcall(function()
|
||||
return tooltip:GetUnit()
|
||||
end)
|
||||
local unit = nil
|
||||
if ok then
|
||||
if type(unitB) == "string" and unitB ~= "" then
|
||||
unit = unitB
|
||||
elseif type(unitA) == "string" and unitA ~= "" then
|
||||
unit = unitA
|
||||
end
|
||||
end
|
||||
if (type(unit) ~= "string" or unit == "") and type(UnitExists) == "function" and UnitExists("mouseover") then
|
||||
unit = "mouseover"
|
||||
end
|
||||
if type(unit) ~= "string" or unit == "" then
|
||||
local left1 = (type(getglobal) == "function" and getglobal("GameTooltipTextLeft1")) or (_G and _G["GameTooltipTextLeft1"])
|
||||
local title = left1 and left1.GetText and left1:GetText() or nil
|
||||
if type(title) == "string" and title ~= "" then
|
||||
return nil, title, nil, title
|
||||
end
|
||||
return nil, nil, nil, nil
|
||||
end
|
||||
local guid = UnitGUID and UnitGUID(unit) or nil
|
||||
local npcId = QA_GetNpcIdFromGuid(guid)
|
||||
local name = UnitName and UnitName(unit) or nil
|
||||
local title = nil
|
||||
if (type(name) ~= "string" or name == "") then
|
||||
local left1 = (type(getglobal) == "function" and getglobal("GameTooltipTextLeft1")) or (_G and _G["GameTooltipTextLeft1"])
|
||||
title = left1 and left1.GetText and left1:GetText() or nil
|
||||
if type(title) == "string" and title ~= "" then
|
||||
name = title
|
||||
end
|
||||
end
|
||||
return npcId, name, unit, title
|
||||
end
|
||||
|
||||
local function QA_TooltipAlreadyExtended(tooltip)
|
||||
if not tooltip or type(tooltip.NumLines) ~= "function" then
|
||||
return false
|
||||
end
|
||||
local lines = math.floor(tonumber(tooltip:NumLines()) or 0)
|
||||
for i = 1, lines do
|
||||
local line = (type(getglobal) == "function" and getglobal("GameTooltipTextLeft" .. tostring(i))) or (_G and _G["GameTooltipTextLeft" .. tostring(i)])
|
||||
local text = line and line.GetText and line:GetText() or nil
|
||||
if type(text) == "string" and QA_NormalizeText(text) == QA_NormalizeText("Quest Automation") then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function QA_IsTooltipDrazial(tooltip)
|
||||
local npcId, npcName = QA_GetTooltipNpc(tooltip)
|
||||
if tonumber(npcId) == QA_SCORPOK_NPC_ID then
|
||||
return true
|
||||
end
|
||||
if type(npcName) == "string" and npcName ~= "" and QA_NormalizeText(npcName) == QA_NormalizeText(QA_SCORPOK_NPC_NAME) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function QA_AppendDrazialTooltip(tooltip, sourceTag)
|
||||
sourceTag = tostring(sourceTag or "unknown")
|
||||
if not (MTH_AutoQuest and MTH_AutoQuest.enabled) then
|
||||
QA_TooltipTrace("skip: module disabled source=" .. sourceTag)
|
||||
return
|
||||
end
|
||||
if not QA_IsScorpokAutomationEnabled() or not QA_IsScorpokTooltipEnabled() then
|
||||
QA_TooltipTrace("skip: option disabled source=" .. sourceTag)
|
||||
return
|
||||
end
|
||||
local npcId, npcName, unitToken, title = QA_GetTooltipNpc(tooltip)
|
||||
local isMatch = tonumber(npcId) == QA_SCORPOK_NPC_ID
|
||||
if not isMatch and type(npcName) == "string" and npcName ~= "" and QA_NormalizeText(npcName) == QA_NormalizeText(QA_SCORPOK_NPC_NAME) then
|
||||
isMatch = true
|
||||
end
|
||||
if not isMatch then
|
||||
QA_TooltipTrace("skip: npc mismatch source=" .. sourceTag
|
||||
.. " unit=" .. tostring(unitToken)
|
||||
.. " id=" .. tostring(npcId)
|
||||
.. " name='" .. tostring(npcName or "") .. "'"
|
||||
.. " title='" .. tostring(title or "") .. "'")
|
||||
return
|
||||
end
|
||||
if QA_TooltipAlreadyExtended(tooltip) then
|
||||
QA_TooltipTrace("skip: already-extended source=" .. sourceTag)
|
||||
return
|
||||
end
|
||||
|
||||
local pincerCount = QA_CountItemInBags(QA_ITEM_SCORPOK_PINCER_ID, QA_ITEM_SCORPOK_PINCER_NAME)
|
||||
local gizzardCount = QA_CountItemInBags(QA_ITEM_VULTURE_GIZZARD_ID, QA_ITEM_VULTURE_GIZZARD_NAME)
|
||||
local lungCount = QA_CountItemInBags(QA_ITEM_BLASTED_BOAR_LUNG_ID, QA_ITEM_BLASTED_BOAR_LUNG_NAME)
|
||||
local assayCount = QA_CountItemInBags(QA_ITEM_GROUND_SCORPOK_ASSAY_ID, QA_ITEM_GROUND_SCORPOK_ASSAY_NAME)
|
||||
|
||||
tooltip:AddLine(" ")
|
||||
tooltip:AddLine("|cffffff00Quest Automation|r")
|
||||
tooltip:AddLine("Scorpok Pincer: " .. QA_ColorByThreshold(pincerCount, 3), 1, 1, 1)
|
||||
tooltip:AddLine("Vulture Gizzard: " .. QA_ColorByThreshold(gizzardCount, 2), 1, 1, 1)
|
||||
tooltip:AddLine("Blasted Boar Lung: " .. QA_ColorByThreshold(lungCount, 1), 1, 1, 1)
|
||||
tooltip:AddLine("Ground Scorpok Assay: " .. QA_ColorAssay(assayCount), 1, 1, 1)
|
||||
tooltip:AddLine("Spam SHIFT-click!", 0.7, 0.9, 1)
|
||||
tooltip:AddLine("Recipes: 3x Pincer, 2x Gizzard, 1x Lung", 0.7, 0.7, 0.7)
|
||||
tooltip:Show()
|
||||
QA_TooltipTrace("added: source=" .. sourceTag
|
||||
.. " id=" .. tostring(npcId)
|
||||
.. " name='" .. tostring(npcName or "") .. "'", true)
|
||||
end
|
||||
|
||||
local function QA_EnsureTooltipHook()
|
||||
if QA_TooltipHooked then
|
||||
return
|
||||
end
|
||||
if not GameTooltip then
|
||||
return
|
||||
end
|
||||
|
||||
local hasGetScript = type(GameTooltip.GetScript) == "function"
|
||||
local hasSetScript = type(GameTooltip.SetScript) == "function"
|
||||
local hasHookScript = type(GameTooltip.HookScript) == "function"
|
||||
|
||||
local onTooltipSetUnitExists = false
|
||||
local onShowExists = false
|
||||
if hasGetScript then
|
||||
local okSetUnit, existingSetUnit = pcall(function()
|
||||
return GameTooltip:GetScript("OnTooltipSetUnit")
|
||||
end)
|
||||
onTooltipSetUnitExists = okSetUnit and type(existingSetUnit) == "function"
|
||||
|
||||
local okShow, existingShow = pcall(function()
|
||||
return GameTooltip:GetScript("OnShow")
|
||||
end)
|
||||
onShowExists = okShow and type(existingShow) == "function"
|
||||
end
|
||||
|
||||
if hasHookScript and onTooltipSetUnitExists then
|
||||
pcall(function()
|
||||
GameTooltip:HookScript("OnTooltipSetUnit", function()
|
||||
QA_AppendDrazialTooltip(this, "hook:setunit")
|
||||
end)
|
||||
end)
|
||||
elseif hasSetScript and hasGetScript and onTooltipSetUnitExists then
|
||||
local okGetPrev, previous = pcall(function()
|
||||
return GameTooltip:GetScript("OnTooltipSetUnit")
|
||||
end)
|
||||
if okGetPrev then
|
||||
pcall(function()
|
||||
GameTooltip:SetScript("OnTooltipSetUnit", function()
|
||||
if type(previous) == "function" then
|
||||
previous()
|
||||
end
|
||||
QA_AppendDrazialTooltip(this, "script:setunit")
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
if hasHookScript and onShowExists then
|
||||
pcall(function()
|
||||
GameTooltip:HookScript("OnShow", function()
|
||||
QA_AppendDrazialTooltip(this, "hook:show")
|
||||
end)
|
||||
end)
|
||||
elseif hasSetScript and hasGetScript and onShowExists then
|
||||
local okGetPrevShow, previousShow = pcall(function()
|
||||
return GameTooltip:GetScript("OnShow")
|
||||
end)
|
||||
if okGetPrevShow then
|
||||
pcall(function()
|
||||
GameTooltip:SetScript("OnShow", function()
|
||||
if type(previousShow) == "function" then
|
||||
previousShow()
|
||||
end
|
||||
QA_AppendDrazialTooltip(this, "script:show")
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
QA_TooltipHooked = true
|
||||
end
|
||||
|
||||
local function QA_EnsureTooltipPoller()
|
||||
if QA_TooltipPollFrame then
|
||||
return
|
||||
end
|
||||
local frame = CreateFrame("Frame", "MTH_AQTooltipPoll")
|
||||
if not frame then
|
||||
return
|
||||
end
|
||||
frame._mthElapsed = 0
|
||||
frame:SetScript("OnUpdate", function()
|
||||
this._mthElapsed = (this._mthElapsed or 0) + (arg1 or 0)
|
||||
if this._mthElapsed < 0.20 then
|
||||
return
|
||||
end
|
||||
this._mthElapsed = 0
|
||||
if not (MTH_AutoQuest and MTH_AutoQuest.enabled) then
|
||||
return
|
||||
end
|
||||
if GameTooltip and type(GameTooltip.IsVisible) == "function" and GameTooltip:IsVisible() then
|
||||
QA_AppendDrazialTooltip(GameTooltip, "poll")
|
||||
end
|
||||
end)
|
||||
QA_TooltipPollFrame = frame
|
||||
end
|
||||
|
||||
local function QA_GetInteractedNpcId()
|
||||
local getGuid = _G and _G["UnitGUID"] or nil
|
||||
if type(getGuid) ~= "function" then
|
||||
return nil
|
||||
end
|
||||
local npcGuid = getGuid("npc")
|
||||
local npcId = QA_GetNpcIdFromGuid(npcGuid)
|
||||
if npcId then
|
||||
return npcId
|
||||
end
|
||||
return QA_GetNpcIdFromGuid(getGuid("target"))
|
||||
end
|
||||
|
||||
local function QA_GetInteractedNpcName()
|
||||
local getName = _G and _G["UnitName"] or nil
|
||||
if type(getName) ~= "function" then
|
||||
return nil
|
||||
end
|
||||
local name = getName("npc")
|
||||
if type(name) == "string" and name ~= "" then
|
||||
return name
|
||||
end
|
||||
name = getName("target")
|
||||
if type(name) == "string" and name ~= "" then
|
||||
return name
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function QA_IsInteractedNpc(expectedNpcId, expectedNpcName)
|
||||
local npcId = QA_GetInteractedNpcId()
|
||||
if tonumber(npcId) == tonumber(expectedNpcId) then
|
||||
return true
|
||||
end
|
||||
local npcName = QA_GetInteractedNpcName()
|
||||
if type(npcName) == "string" and npcName ~= "" and QA_NormalizeText(npcName) == QA_NormalizeText(expectedNpcName) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function QA_IsScorpokNpc()
|
||||
return QA_IsInteractedNpc(QA_SCORPOK_NPC_ID, QA_SCORPOK_NPC_NAME)
|
||||
end
|
||||
|
||||
local function QA_IsArrowsForSissiesNpc()
|
||||
return QA_IsInteractedNpc(QA_SISSIES_NPC_ID, QA_SISSIES_NPC_NAME)
|
||||
end
|
||||
|
||||
local function QA_RefreshMouseoverTooltip()
|
||||
local tooltip = _G and _G["GameTooltip"] or GameTooltip
|
||||
if not tooltip then
|
||||
return
|
||||
end
|
||||
if type(UnitExists) == "function" and UnitExists("mouseover") and type(tooltip.SetUnit) == "function" then
|
||||
tooltip:SetUnit("mouseover")
|
||||
if type(tooltip.Show) == "function" then
|
||||
tooltip:Show()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function QA_RequestTooltipRefresh(delaySeconds)
|
||||
delaySeconds = tonumber(delaySeconds) or 0.10
|
||||
if not QA_TooltipRefreshFrame then
|
||||
QA_TooltipRefreshFrame = CreateFrame("Frame", "MTH_AQTooltipRefresh")
|
||||
if not QA_TooltipRefreshFrame then
|
||||
return
|
||||
end
|
||||
QA_TooltipRefreshFrame:SetScript("OnUpdate", function()
|
||||
local frameRef = this or QA_TooltipRefreshFrame
|
||||
if not frameRef then
|
||||
return
|
||||
end
|
||||
frameRef._elapsed = (frameRef._elapsed or 0) + (arg1 or 0)
|
||||
if frameRef._elapsed < (frameRef._delay or 0.10) then
|
||||
return
|
||||
end
|
||||
frameRef._elapsed = 0
|
||||
frameRef._delay = 0
|
||||
frameRef:SetScript("OnUpdate", nil)
|
||||
QA_RefreshMouseoverTooltip()
|
||||
end)
|
||||
end
|
||||
QA_TooltipRefreshFrame._delay = delaySeconds
|
||||
QA_TooltipRefreshFrame._elapsed = 0
|
||||
QA_TooltipRefreshFrame:SetScript("OnUpdate", QA_TooltipRefreshFrame:GetScript("OnUpdate"))
|
||||
end
|
||||
|
||||
local QA_PROFILE_SCORPOK = {
|
||||
key = "scorpokDrazial",
|
||||
label = "Scorpok",
|
||||
optionCheck = QA_IsScorpokAutomationEnabled,
|
||||
npcCheck = QA_IsScorpokNpc,
|
||||
titleCheck = QA_IsScorpokTitle,
|
||||
questContextCheck = QA_IsScorpokQuestContext,
|
||||
lastActionField = "_scorpokLastActionAt",
|
||||
refreshTooltipOnComplete = true,
|
||||
}
|
||||
|
||||
local QA_PROFILE_SISSIES = {
|
||||
key = "arrowsForSissies",
|
||||
label = "ArrowsForSissies",
|
||||
optionCheck = QA_IsArrowsForSissiesAutomationEnabled,
|
||||
npcCheck = QA_IsArrowsForSissiesNpc,
|
||||
titleCheck = QA_IsArrowsForSissiesTitle,
|
||||
questContextCheck = QA_IsArrowsForSissiesQuestContext,
|
||||
lastActionField = "_sissiesLastActionAt",
|
||||
refreshTooltipOnComplete = false,
|
||||
}
|
||||
|
||||
local QA_LastActionAt = {}
|
||||
|
||||
local function QA_GetLastActionAt(profile)
|
||||
local key = type(profile) == "table" and tostring(profile.lastActionField or "") or ""
|
||||
if key == "" then
|
||||
return 0
|
||||
end
|
||||
return tonumber(QA_LastActionAt[key]) or 0
|
||||
end
|
||||
|
||||
local function QA_SetLastActionAt(profile, value)
|
||||
local key = type(profile) == "table" and tostring(profile.lastActionField or "") or ""
|
||||
if key == "" then
|
||||
return
|
||||
end
|
||||
QA_LastActionAt[key] = tonumber(value) or 0
|
||||
end
|
||||
|
||||
local function QA_CanRunProfile(profile)
|
||||
if type(profile) ~= "table" then
|
||||
return false
|
||||
end
|
||||
if type(profile.optionCheck) ~= "function" or not profile.optionCheck() then
|
||||
QA_Debug("[" .. tostring(profile.label or "AutoQuest") .. "] skip: option disabled")
|
||||
return false
|
||||
end
|
||||
if type(IsShiftKeyDown) ~= "function" or not IsShiftKeyDown() then
|
||||
QA_Debug("[" .. tostring(profile.label or "AutoQuest") .. "] skip: SHIFT not held")
|
||||
return false
|
||||
end
|
||||
local npcOk = type(profile.npcCheck) == "function" and profile.npcCheck() or false
|
||||
if not npcOk then
|
||||
QA_Debug("[" .. tostring(profile.label or "AutoQuest") .. "] skip: NPC mismatch (id=" .. tostring(QA_GetInteractedNpcId()) .. ", name='" .. tostring(QA_GetInteractedNpcName() or "") .. "')")
|
||||
end
|
||||
return npcOk
|
||||
end
|
||||
|
||||
local function QA_FindGossipQuestIndex(rawEntries, count, profile)
|
||||
if type(rawEntries) ~= "table" or tonumber(count) == nil or tonumber(count) <= 0 then
|
||||
return nil
|
||||
end
|
||||
if type(profile) ~= "table" or type(profile.titleCheck) ~= "function" then
|
||||
return nil
|
||||
end
|
||||
local entryCount = math.floor(tonumber(count) or 0)
|
||||
local tupleSize = math.floor(table.getn(rawEntries) / entryCount)
|
||||
if tupleSize < 1 then
|
||||
tupleSize = 1
|
||||
end
|
||||
for i = 1, entryCount do
|
||||
local title = tostring(rawEntries[((i - 1) * tupleSize) + 1] or "")
|
||||
if profile.titleCheck(title) then
|
||||
return i
|
||||
end
|
||||
end
|
||||
if entryCount == 1 and type(profile.npcCheck) == "function" and profile.npcCheck() then
|
||||
QA_Debug("[" .. tostring(profile.label or "AutoQuest") .. "] gossip fallback: single quest entry -> selecting index 1")
|
||||
return 1
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function QA_FindQuestGreetingIndex(isActive, profile)
|
||||
local getCount = isActive and _G and _G["GetNumActiveQuests"] or _G and _G["GetNumAvailableQuests"]
|
||||
local getTitle = isActive and _G and _G["GetActiveTitle"] or _G and _G["GetAvailableTitle"]
|
||||
if type(getCount) ~= "function" or type(getTitle) ~= "function" or type(profile) ~= "table" or type(profile.titleCheck) ~= "function" then
|
||||
return nil
|
||||
end
|
||||
local count = math.floor(tonumber(getCount()) or 0)
|
||||
if count <= 0 then
|
||||
return nil
|
||||
end
|
||||
for i = 1, count do
|
||||
local title = tostring(getTitle(i) or "")
|
||||
if profile.titleCheck(title) then
|
||||
return i
|
||||
end
|
||||
end
|
||||
if count == 1 and type(profile.npcCheck) == "function" and profile.npcCheck() then
|
||||
QA_Debug("[" .. tostring(profile.label or "AutoQuest") .. "] quest greeting fallback: single quest entry -> selecting index 1")
|
||||
return 1
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function QA_GetFrameText(frame)
|
||||
if type(frame) ~= "table" then
|
||||
return ""
|
||||
end
|
||||
if type(frame.GetText) == "function" then
|
||||
return tostring(frame:GetText() or "")
|
||||
end
|
||||
if type(frame.GetName) == "function" then
|
||||
local name = frame:GetName()
|
||||
if type(name) == "string" and name ~= "" then
|
||||
local textRegion = _G and _G[name .. "Text"] or nil
|
||||
if textRegion and type(textRegion.GetText) == "function" then
|
||||
return tostring(textRegion:GetText() or "")
|
||||
end
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
local function QA_ClickGossipTitleButtonFallback(profile)
|
||||
if type(profile) ~= "table" or type(profile.titleCheck) ~= "function" then
|
||||
return false
|
||||
end
|
||||
for i = 1, 40 do
|
||||
local button = _G and _G["GossipTitleButton" .. tostring(i)] or nil
|
||||
if button then
|
||||
local visible = true
|
||||
if type(button.IsVisible) == "function" then
|
||||
visible = button:IsVisible() and true or false
|
||||
end
|
||||
if visible then
|
||||
local title = QA_GetFrameText(button)
|
||||
if profile.titleCheck(title) then
|
||||
QA_Debug("action: GossipTitleButton" .. tostring(i) .. " click title='" .. tostring(title) .. "'")
|
||||
if type(button.Click) == "function" then
|
||||
button:Click()
|
||||
return true
|
||||
end
|
||||
local onClick = type(button.GetScript) == "function" and button:GetScript("OnClick") or nil
|
||||
if type(onClick) == "function" then
|
||||
onClick(button)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function QA_RunProfileAutomation(eventName, profile)
|
||||
if type(profile) ~= "table" then
|
||||
return
|
||||
end
|
||||
QA_Debug("[" .. tostring(profile.label or "AutoQuest") .. "] event=" .. tostring(eventName))
|
||||
if not QA_CanRunProfile(profile) then
|
||||
return
|
||||
end
|
||||
|
||||
local getTimeFn = _G and _G["GetTime"] or nil
|
||||
if eventName == "GOSSIP_SHOW" and type(getTimeFn) == "function" then
|
||||
local now = tonumber(getTimeFn()) or 0
|
||||
local last = QA_GetLastActionAt(profile)
|
||||
if (now - last) < 0.05 then
|
||||
QA_Debug("skip: throttled dt=" .. tostring(now - last))
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if eventName == "QUEST_GREETING" then
|
||||
local selectAvailableQuest = _G and _G["SelectAvailableQuest"] or nil
|
||||
local selectActiveQuest = _G and _G["SelectActiveQuest"] or nil
|
||||
local availableIndex = QA_FindQuestGreetingIndex(false, profile)
|
||||
if availableIndex and type(selectAvailableQuest) == "function" then
|
||||
QA_Debug("action: SelectAvailableQuest (compat) index=" .. tostring(availableIndex))
|
||||
selectAvailableQuest()
|
||||
QA_SetLastActionAt(profile, type(getTimeFn) == "function" and getTimeFn() or 0)
|
||||
return
|
||||
end
|
||||
local activeIndex = QA_FindQuestGreetingIndex(true, profile)
|
||||
if activeIndex and type(selectActiveQuest) == "function" then
|
||||
QA_Debug("action: SelectActiveQuest (compat) index=" .. tostring(activeIndex))
|
||||
selectActiveQuest()
|
||||
QA_SetLastActionAt(profile, type(getTimeFn) == "function" and getTimeFn() or 0)
|
||||
return
|
||||
end
|
||||
for i = 1, 40 do
|
||||
local button = _G and _G["QuestTitleButton" .. tostring(i)] or nil
|
||||
if button and (type(button.IsVisible) ~= "function" or button:IsVisible()) then
|
||||
local title = QA_GetFrameText(button)
|
||||
if profile.titleCheck(title) then
|
||||
QA_Debug("action: QuestTitleButton" .. tostring(i) .. " click title='" .. tostring(title) .. "'")
|
||||
if type(button.Click) == "function" then
|
||||
button:Click()
|
||||
QA_SetLastActionAt(profile, type(getTimeFn) == "function" and getTimeFn() or 0)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
QA_Debug("quest greeting: no action taken")
|
||||
return
|
||||
end
|
||||
|
||||
if eventName == "GOSSIP_SHOW" then
|
||||
local getNumGossipAvailableQuests = _G and _G["GetNumGossipAvailableQuests"] or nil
|
||||
local getGossipAvailableQuests = _G and _G["GetGossipAvailableQuests"] or nil
|
||||
local selectGossipAvailableQuest = _G and _G["SelectGossipAvailableQuest"] or nil
|
||||
QA_Debug("api available: numAvail=" .. tostring(type(getNumGossipAvailableQuests) == "function")
|
||||
.. " getAvail=" .. tostring(type(getGossipAvailableQuests) == "function")
|
||||
.. " selAvail=" .. tostring(type(selectGossipAvailableQuest) == "function"))
|
||||
if type(getNumGossipAvailableQuests) == "function" and type(getGossipAvailableQuests) == "function" and type(selectGossipAvailableQuest) == "function" then
|
||||
local availableCount = math.floor(tonumber(getNumGossipAvailableQuests()) or 0)
|
||||
QA_Debug("gossip available count=" .. tostring(availableCount))
|
||||
if availableCount > 0 then
|
||||
local availableIndex = QA_FindGossipQuestIndex({ getGossipAvailableQuests() }, availableCount, profile)
|
||||
if availableIndex then
|
||||
QA_Debug("action: SelectGossipAvailableQuest index=" .. tostring(availableIndex))
|
||||
selectGossipAvailableQuest(availableIndex)
|
||||
QA_SetLastActionAt(profile, type(getTimeFn) == "function" and getTimeFn() or 0)
|
||||
return
|
||||
end
|
||||
QA_Debug("gossip available: no Scorpok match")
|
||||
end
|
||||
end
|
||||
local getNumGossipActiveQuests = _G and _G["GetNumGossipActiveQuests"] or nil
|
||||
local getGossipActiveQuests = _G and _G["GetGossipActiveQuests"] or nil
|
||||
local selectGossipActiveQuest = _G and _G["SelectGossipActiveQuest"] or nil
|
||||
QA_Debug("api active: numActive=" .. tostring(type(getNumGossipActiveQuests) == "function")
|
||||
.. " getActive=" .. tostring(type(getGossipActiveQuests) == "function")
|
||||
.. " selActive=" .. tostring(type(selectGossipActiveQuest) == "function"))
|
||||
if type(getNumGossipActiveQuests) == "function" and type(getGossipActiveQuests) == "function" and type(selectGossipActiveQuest) == "function" then
|
||||
local activeCount = math.floor(tonumber(getNumGossipActiveQuests()) or 0)
|
||||
QA_Debug("gossip active count=" .. tostring(activeCount))
|
||||
if activeCount > 0 then
|
||||
local activeIndex = QA_FindGossipQuestIndex({ getGossipActiveQuests() }, activeCount, profile)
|
||||
if activeIndex then
|
||||
QA_Debug("action: SelectGossipActiveQuest index=" .. tostring(activeIndex))
|
||||
selectGossipActiveQuest(activeIndex)
|
||||
QA_SetLastActionAt(profile, type(getTimeFn) == "function" and getTimeFn() or 0)
|
||||
return
|
||||
end
|
||||
QA_Debug("gossip active: no Scorpok match")
|
||||
end
|
||||
end
|
||||
if QA_ClickGossipTitleButtonFallback(profile) then
|
||||
QA_SetLastActionAt(profile, type(getTimeFn) == "function" and getTimeFn() or 0)
|
||||
return
|
||||
end
|
||||
QA_Debug("gossip: no action taken")
|
||||
return
|
||||
end
|
||||
|
||||
local title = type(GetTitleText) == "function" and tostring(GetTitleText() or "") or ""
|
||||
QA_Debug("quest frame title='" .. tostring(title) .. "'")
|
||||
if type(profile.questContextCheck) ~= "function" or not profile.questContextCheck(title) then
|
||||
QA_Debug("skip: quest context mismatch")
|
||||
return
|
||||
end
|
||||
|
||||
if eventName == "QUEST_DETAIL" then
|
||||
if type(AcceptQuest) == "function" then
|
||||
QA_Debug("action: AcceptQuest")
|
||||
AcceptQuest()
|
||||
QA_SetLastActionAt(profile, type(getTimeFn) == "function" and getTimeFn() or 0)
|
||||
end
|
||||
elseif eventName == "QUEST_PROGRESS" then
|
||||
if type(CompleteQuest) == "function" then
|
||||
if type(IsQuestCompletable) ~= "function" or IsQuestCompletable() then
|
||||
QA_Debug("action: CompleteQuest")
|
||||
CompleteQuest()
|
||||
QA_SetLastActionAt(profile, type(getTimeFn) == "function" and getTimeFn() or 0)
|
||||
else
|
||||
QA_Debug("skip: quest not completable yet")
|
||||
end
|
||||
end
|
||||
elseif eventName == "QUEST_COMPLETE" then
|
||||
if type(GetQuestReward) == "function" then
|
||||
local choices = type(GetNumQuestChoices) == "function" and math.floor(tonumber(GetNumQuestChoices()) or 0) or 0
|
||||
if choices <= 1 then
|
||||
QA_Debug("action: GetQuestReward(1)")
|
||||
GetQuestReward(1)
|
||||
QA_SetLastActionAt(profile, type(getTimeFn) == "function" and getTimeFn() or 0)
|
||||
if profile.refreshTooltipOnComplete then
|
||||
QA_RequestTooltipRefresh(0.10)
|
||||
end
|
||||
else
|
||||
QA_Debug("skip: multiple reward choices=" .. tostring(choices))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- NOTE: QA_DirectEventFrame removed (Phase 2 fix #22b)
|
||||
-- The central event router already dispatches GOSSIP_SHOW, QUEST_GREETING,
|
||||
-- QUEST_DETAIL, QUEST_PROGRESS, QUEST_COMPLETE to MTH_AutoQuest:onEvent().
|
||||
-- Having a second frame register the same events caused double-dispatch.
|
||||
|
||||
function MTH_AutoQuest:init()
|
||||
local store = QA_GetOptionsStore()
|
||||
self.initialized = true
|
||||
QA_Debug("init: module active=" .. tostring(self.enabled and true or false)
|
||||
.. ", option scorpokDrazial=" .. tostring(store and store.scorpokDrazial and true or false)
|
||||
.. ", option arrowsForSissies=" .. tostring(store and store.arrowsForSissies and true or false)
|
||||
.. ", option scorpokTooltip=" .. tostring(store and store.scorpokTooltip and true or false))
|
||||
end
|
||||
|
||||
function MTH_AutoQuest:setEnabled(enabled)
|
||||
self.enabled = enabled and true or false
|
||||
end
|
||||
|
||||
function MTH_AutoQuest:onEvent(eventName)
|
||||
if eventName == "GOSSIP_SHOW"
|
||||
or eventName == "QUEST_GREETING"
|
||||
or eventName == "QUEST_DETAIL"
|
||||
or eventName == "QUEST_PROGRESS"
|
||||
or eventName == "QUEST_COMPLETE" then
|
||||
QA_Debug("onEvent=" .. tostring(eventName))
|
||||
QA_RunProfileAutomation(eventName, QA_PROFILE_SCORPOK)
|
||||
QA_RunProfileAutomation(eventName, QA_PROFILE_SISSIES)
|
||||
end
|
||||
end
|
||||
|
||||
function MTH_AutoQuest:cleanup()
|
||||
-- no-op: direct event frame removed in Phase 2
|
||||
end
|
||||
|
||||
MTH:RegisterModule("autoquest", MTH_AutoQuest)
|
||||
@@ -43,9 +43,11 @@ function MTH_ChronometerHunterInstallData(engine)
|
||||
engine:AddTimer(engine.EVENT, BS["Frost Trap Aura"], 30, 0, 0, 0, { gr = 1, cr = "CYAN", a = 1, d = { tn = BS["Clever Traps"], tb = 0.15, tp = 1 }, xn = BS["Frost Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Immolation Trap Effect"], 15, 1, 0, 1, { gr = 1, cr = "ORANGE", a = 1, xn = BS["Immolation Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Improved Concussive Shot"], 3, 1, 0, 0, { a = 1, cr = "BLUE", xn = BS["Concussive Shot"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Improved Wing Clip"], 5, 1, 0, 0, { a = 1, cr = "YELLOW", xn = BS["Wing Clip"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Improved Wing Clip"], 5, 1, 0, 0, { a = 1, cr = "MAROON", xn = BS["Wing Clip"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Piercing Shot"], 8, 1, 0, 1, { a = 1, cr = "PURPLE", tx = "Interface\\Icons\\Ability_Hunter_DisarmingShot" })
|
||||
engine:AddTimer(engine.EVENT, BS["Quick Shots"], 12, 0, 1, 1, { a = 1, cr = "MAROON", tx = "Interface\\Icons\\Ability_Hunter_Quickshot" })
|
||||
engine:AddTimer(engine.EVENT, BS["Entrapment"], 5, 1, 0, 1, { a = 1, cr = "MAROON", tx = "Interface\\Icons\\Spell_Nature_StrangleVines" })
|
||||
engine:AddTimer(engine.EVENT, BS["Quick Shots"], 12, 0, 1, 1, { a = 1, cr = "MAROON", tx = "Interface\\Icons\\Ability_Warrior_InnerRage" })
|
||||
engine:AddTimer(engine.EVENT, BS["Wing Clip"], 10, 1, 0, 1, { a = 1, cr = "YELLOW" })
|
||||
engine:AddTimer(engine.EVENT, BS["Scorpid Poison"], 10, 1, 0, 0, { gr = 3, cr = "PURPLE", a = 1, dn = 1 })
|
||||
engine:AddTimer(engine.EVENT, BS["Devilsaur Fury"], 20, 0, 1, 1, { a = 1, cr = "PURPLE", xn = BS["Devilsaur Eye"], tx = "Interface\\Icons\\Ability_Hunter_Pet_Raptor" })
|
||||
engine:AddTimer(engine.EVENT, BS["Restless Strength"], 20, 0, 1, 1, { a = 1, cr = "PURPLE", xn = BS["Zandalarian Hero Medallion"], tx = "Interface\\Icons\\INV_Jewelry_Necklace_13" })
|
||||
|
||||
+365
-26
@@ -59,6 +59,45 @@ Chronometer.dataSetup = {}
|
||||
local latins = { I = 1, II = 2, III = 3, IV = 4, V = 5, VI = 6, VII = 7, VIII = 8, IX = 9, X = 10, XI = 11, XII = 12, XIII = 13, XIV = 14 }
|
||||
local BAR_GROUP = "MTHChronometer"
|
||||
local PARSER_OWNER = "MTHChronometerHunter"
|
||||
local MTH_CHRON_TRACE_ENABLED = false
|
||||
|
||||
local function MTH_CHRON_Trace(msg)
|
||||
if not MTH_CHRON_TRACE_ENABLED then
|
||||
return
|
||||
end
|
||||
if MTH and MTH.Print then
|
||||
MTH:Print("[CHRONTRACE] " .. tostring(msg), "debug")
|
||||
elseif DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.AddMessage then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("[CHRONTRACE] " .. tostring(msg))
|
||||
end
|
||||
end
|
||||
|
||||
local function MTH_CHRON_FormatBarPosition(profile)
|
||||
local bp = profile and profile.barposition
|
||||
if type(bp) ~= "table" then
|
||||
return "<none>"
|
||||
end
|
||||
return tostring(bp.point or "nil")
|
||||
.. "/" .. tostring(bp.relativePoint or "nil")
|
||||
.. " @(" .. tostring(bp.x) .. "," .. tostring(bp.y) .. ")"
|
||||
end
|
||||
|
||||
local function MTH_CHRON_DescribePoint(frame)
|
||||
if not (frame and frame.GetPoint) then
|
||||
return "<no-frame>"
|
||||
end
|
||||
local point, relTo, relPoint, x, y = frame:GetPoint()
|
||||
local relName = "nil"
|
||||
if type(relTo) == "table" and relTo.GetName then
|
||||
relName = tostring(relTo:GetName() or "<anon>")
|
||||
elseif relTo then
|
||||
relName = tostring(relTo)
|
||||
end
|
||||
return tostring(point or "nil")
|
||||
.. "->" .. relName
|
||||
.. ":" .. tostring(relPoint or "nil")
|
||||
.. " @(" .. tostring(x) .. "," .. tostring(y) .. ")"
|
||||
end
|
||||
|
||||
local COLOR_NAME_MAP = {
|
||||
white = { 1.0, 1.0, 1.0 },
|
||||
@@ -143,15 +182,80 @@ local function shallowCopy(source)
|
||||
return dest
|
||||
end
|
||||
|
||||
local function deepCopyValue(value)
|
||||
if type(value) ~= "table" then
|
||||
return value
|
||||
end
|
||||
local copy = {}
|
||||
for key, entry in pairs(value) do
|
||||
copy[key] = deepCopyValue(entry)
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
local function ensureProfile()
|
||||
if not MTH or not MTH.GetModuleSavedVariables then
|
||||
if not MTH or not MTH.GetModuleCharSavedVariables then
|
||||
MTH_CHRON_Trace("ensureProfile fallback defaults (no MTH store)")
|
||||
return shallowCopy(DEFAULTS)
|
||||
end
|
||||
|
||||
local store = MTH:GetModuleSavedVariables("chronometer")
|
||||
local store = MTH:GetModuleCharSavedVariables("chronometer")
|
||||
if type(store) ~= "table" then
|
||||
MTH_CHRON_Trace("ensureProfile fallback defaults (invalid store)")
|
||||
return shallowCopy(DEFAULTS)
|
||||
end
|
||||
if type(store.profile) ~= "table"
|
||||
and type(MTH_CharSavedVariables) == "table"
|
||||
and type(MTH_CharSavedVariables.chronometer) == "table"
|
||||
then
|
||||
local legacyChar = MTH_CharSavedVariables.chronometer
|
||||
if type(legacyChar.profile) == "table" then
|
||||
store.profile = deepCopyValue(legacyChar.profile)
|
||||
MTH_CHRON_Trace("ensureProfile migrated legacy MTH_CharSavedVariables.chronometer.profile")
|
||||
elseif type(legacyChar.barposition) == "table" then
|
||||
store.profile = { barposition = deepCopyValue(legacyChar.barposition) }
|
||||
MTH_CHRON_Trace("ensureProfile migrated legacy MTH_CharSavedVariables.chronometer.barposition")
|
||||
end
|
||||
end
|
||||
if type(store.profile) ~= "table"
|
||||
and type(MTH_SavedVariables) == "table"
|
||||
and type(MTH_SavedVariables.chronometer) == "table"
|
||||
then
|
||||
local legacyAccount = MTH_SavedVariables.chronometer
|
||||
if type(legacyAccount.profile) == "table" then
|
||||
store.profile = deepCopyValue(legacyAccount.profile)
|
||||
MTH_CHRON_Trace("ensureProfile migrated legacy MTH_SavedVariables.chronometer.profile")
|
||||
elseif type(legacyAccount.barposition) == "table" then
|
||||
store.profile = { barposition = deepCopyValue(legacyAccount.barposition) }
|
||||
MTH_CHRON_Trace("ensureProfile migrated legacy MTH_SavedVariables.chronometer.barposition")
|
||||
end
|
||||
end
|
||||
if type(store.profile) ~= "table" and MTH.GetModuleSavedVariables then
|
||||
local accountStore = MTH:GetModuleSavedVariables("chronometer")
|
||||
if type(accountStore) == "table" and type(accountStore.profile) == "table" then
|
||||
store.profile = deepCopyValue(accountStore.profile)
|
||||
MTH_CHRON_Trace("ensureProfile copied account profile into char store")
|
||||
end
|
||||
end
|
||||
if type(store.profile) ~= "table" then
|
||||
store.profile = {}
|
||||
end
|
||||
if type(store.profile.barposition) ~= "table" and type(store.barposition) == "table" then
|
||||
store.profile.barposition = deepCopyValue(store.barposition)
|
||||
MTH_CHRON_Trace("ensureProfile migrated legacy char barposition -> profile.barposition")
|
||||
end
|
||||
if type(store.profile.barposition) ~= "table" and MTH.GetModuleSavedVariables then
|
||||
local accountStore = MTH:GetModuleSavedVariables("chronometer")
|
||||
if type(accountStore) == "table" then
|
||||
if type(accountStore.barposition) == "table" then
|
||||
store.profile.barposition = deepCopyValue(accountStore.barposition)
|
||||
MTH_CHRON_Trace("ensureProfile migrated legacy account barposition -> profile.barposition")
|
||||
elseif type(accountStore.profile) == "table" and type(accountStore.profile.barposition) == "table" then
|
||||
store.profile.barposition = deepCopyValue(accountStore.profile.barposition)
|
||||
MTH_CHRON_Trace("ensureProfile copied account profile.barposition -> char profile.barposition")
|
||||
end
|
||||
end
|
||||
end
|
||||
local profile = store.profile
|
||||
|
||||
for key, value in pairs(DEFAULTS) do
|
||||
@@ -178,9 +282,68 @@ local function ensureProfile()
|
||||
profile.disabledSpells.HUNTER = {}
|
||||
end
|
||||
|
||||
MTH_CHRON_Trace("ensureProfile result barposition=" .. MTH_CHRON_FormatBarPosition(profile))
|
||||
|
||||
return profile
|
||||
end
|
||||
|
||||
local function MTH_CHRON_PersistAnchorPosition(self, reason)
|
||||
if not (self and self.anchor and self.anchor.GetPoint) then
|
||||
return false
|
||||
end
|
||||
if type(self.profile) ~= "table" then
|
||||
return false
|
||||
end
|
||||
if type(self.profile.barposition) ~= "table" then
|
||||
self.profile.barposition = {}
|
||||
end
|
||||
local point, _, relPoint, x, y = self.anchor:GetPoint()
|
||||
x = tonumber(x)
|
||||
y = tonumber(y)
|
||||
if not (point and relPoint and x and y) then
|
||||
return false
|
||||
end
|
||||
x = math.floor(x + 0.5)
|
||||
y = math.floor(y + 0.5)
|
||||
self.profile.barposition.point = point
|
||||
self.profile.barposition.relativePoint = relPoint
|
||||
self.profile.barposition.x = x
|
||||
self.profile.barposition.y = y
|
||||
MTH_CHRON_Trace("persist-anchor reason=" .. tostring(reason or "")
|
||||
.. " profile=" .. MTH_CHRON_FormatBarPosition(self.profile))
|
||||
return true
|
||||
end
|
||||
|
||||
local function MTH_CHRON_RestoreAnchorFromProfile(self, reason)
|
||||
if not (self and self.anchor and self.anchor.ClearAllPoints and self.anchor.SetPoint) then
|
||||
return false
|
||||
end
|
||||
if type(self.profile) ~= "table" then
|
||||
return false
|
||||
end
|
||||
local bp = self.profile.barposition
|
||||
if type(bp) ~= "table" then
|
||||
return false
|
||||
end
|
||||
local px = tonumber(bp.x)
|
||||
local py = tonumber(bp.y)
|
||||
local ppoint = tostring(bp.point or "")
|
||||
local prelpoint = tostring(bp.relativePoint or "")
|
||||
if not (px and py and ppoint ~= "") then
|
||||
MTH_CHRON_Trace("restore-anchor skipped reason=" .. tostring(reason or "")
|
||||
.. " profile=" .. MTH_CHRON_FormatBarPosition(self.profile))
|
||||
return false
|
||||
end
|
||||
if prelpoint == "" then
|
||||
prelpoint = ppoint
|
||||
end
|
||||
self.anchor:ClearAllPoints()
|
||||
self.anchor:SetPoint(ppoint, UIParent, prelpoint, px, py)
|
||||
MTH_CHRON_Trace("restore-anchor applied reason=" .. tostring(reason or "")
|
||||
.. " frame=" .. MTH_CHRON_DescribePoint(self.anchor))
|
||||
return true
|
||||
end
|
||||
|
||||
local function MTH_CHRON_IsPersistedEnabled()
|
||||
if MTH and MTH.IsModuleEnabled then
|
||||
return MTH:IsModuleEnabled("chronometer", true) and true or false
|
||||
@@ -252,22 +415,92 @@ local function parseRankNumber(text)
|
||||
return 0
|
||||
end
|
||||
|
||||
local function resolvePlayerClassBucket(profile)
|
||||
profile = profile or {}
|
||||
local buckets = profile.disabledSpells
|
||||
if type(buckets) ~= "table" then
|
||||
return "HUNTER"
|
||||
end
|
||||
|
||||
local localizedClass, classToken = UnitClass("player")
|
||||
local candidates = {
|
||||
classToken,
|
||||
localizedClass,
|
||||
string.upper(tostring(classToken or "")),
|
||||
string.upper(tostring(localizedClass or "")),
|
||||
"HUNTER",
|
||||
}
|
||||
|
||||
for i = 1, table.getn(candidates) do
|
||||
local key = tostring(candidates[i] or "")
|
||||
if key ~= "" and type(buckets[key]) == "table" then
|
||||
return key
|
||||
end
|
||||
end
|
||||
|
||||
return tostring(classToken or localizedClass or "HUNTER")
|
||||
end
|
||||
|
||||
local function normalizeTimerName(name)
|
||||
local normalized = tostring(name or "")
|
||||
normalized = string.gsub(normalized, "^%s+", "")
|
||||
normalized = string.gsub(normalized, "%s+$", "")
|
||||
normalized = string.gsub(normalized, "%s+", " ")
|
||||
normalized = string.lower(normalized)
|
||||
return normalized
|
||||
end
|
||||
|
||||
local function isTimerDisabled(profile, timerClass, timerName)
|
||||
local disabledSpells = profile and profile.disabledSpells
|
||||
if type(disabledSpells) ~= "table" then
|
||||
return false, "no-disabled-table"
|
||||
end
|
||||
|
||||
local classBucket = disabledSpells[timerClass]
|
||||
if type(classBucket) ~= "table" then
|
||||
return false, "no-class-bucket"
|
||||
end
|
||||
|
||||
if classBucket[timerName] ~= nil then
|
||||
return true, "exact"
|
||||
end
|
||||
|
||||
local wanted = normalizeTimerName(timerName)
|
||||
if wanted == "" then
|
||||
return false, "empty-name"
|
||||
end
|
||||
|
||||
for key, value in pairs(classBucket) do
|
||||
if value ~= nil and normalizeTimerName(key) == wanted then
|
||||
return true, "normalized"
|
||||
end
|
||||
end
|
||||
|
||||
return false, "miss"
|
||||
end
|
||||
|
||||
local function getActionSpell(slot)
|
||||
if GetActionText(slot) or not HasAction(slot) then
|
||||
return nil, 0
|
||||
end
|
||||
|
||||
if not Chronometer._scanTooltip then
|
||||
Chronometer._scanTooltip = CreateFrame("GameTooltip", "MTH_ChronometerScanTooltip", UIParent, "GameTooltipTemplate")
|
||||
Chronometer._scanTooltip:SetOwner(UIParent, "ANCHOR_NONE")
|
||||
local tip = CreateFrame("GameTooltip", "MTH_ChrBarProbe", UIParent)
|
||||
tip:SetOwner(UIParent, "ANCHOR_NONE")
|
||||
for i = 1, 4 do
|
||||
local L = tip:CreateFontString("MTH_ChrBarProbeTextLeft"..i, "ARTWORK", "GameTooltipText")
|
||||
local R = tip:CreateFontString("MTH_ChrBarProbeTextRight"..i, "ARTWORK", "GameTooltipText")
|
||||
tip:AddFontStrings(L, R)
|
||||
end
|
||||
Chronometer._scanTooltip = tip
|
||||
end
|
||||
|
||||
local tooltip = Chronometer._scanTooltip
|
||||
tooltip:ClearLines()
|
||||
tooltip:SetAction(slot)
|
||||
|
||||
local left1 = getglobal("MTH_ChronometerScanTooltipTextLeft1")
|
||||
local left2 = getglobal("MTH_ChronometerScanTooltipTextLeft2")
|
||||
local left1 = getglobal("MTH_ChrBarProbeTextLeft1")
|
||||
local left2 = getglobal("MTH_ChrBarProbeTextLeft2")
|
||||
local spellName = left1 and left1:GetText() or nil
|
||||
if not spellName or spellName == "" then
|
||||
return nil, 0
|
||||
@@ -294,6 +527,7 @@ function Chronometer:MTH_Initialize()
|
||||
end
|
||||
|
||||
self.profile = ensureProfile()
|
||||
MTH_CHRON_Trace("MTH_Initialize profile=" .. MTH_CHRON_FormatBarPosition(self.profile))
|
||||
self.parser = ParserLib:GetInstance("1.1")
|
||||
|
||||
self.COLOR_MAP = {
|
||||
@@ -304,6 +538,7 @@ function Chronometer:MTH_Initialize()
|
||||
}
|
||||
|
||||
self.anchor = self:CreateAnchor("MetaHunt Chronometer", 0, 1, 0)
|
||||
MTH_CHRON_Trace("MTH_Initialize anchor-created point=" .. MTH_CHRON_DescribePoint(self.anchor))
|
||||
self:RegisterCandyBarGroup(BAR_GROUP)
|
||||
self:SetCandyBarGroupPoint(BAR_GROUP, "TOP", self.anchor, "BOTTOM", 0, 0)
|
||||
|
||||
@@ -312,16 +547,19 @@ end
|
||||
|
||||
function Chronometer:MTH_Enable()
|
||||
self._mth_explicitEnable = true
|
||||
MTH_CHRON_Trace("MTH_Enable called")
|
||||
self:MTH_Initialize()
|
||||
self:OnEnable()
|
||||
self._mth_explicitEnable = nil
|
||||
end
|
||||
|
||||
function Chronometer:MTH_Disable()
|
||||
MTH_CHRON_Trace("MTH_Disable called")
|
||||
self:OnDisable()
|
||||
end
|
||||
|
||||
function Chronometer:OnEnable()
|
||||
MTH_CHRON_Trace("OnEnable begin enabled=" .. tostring(self._mth_enabled and true or false))
|
||||
if self._mth_enabled then
|
||||
return
|
||||
end
|
||||
@@ -351,8 +589,13 @@ function Chronometer:OnEnable()
|
||||
self._mth_enabled = true
|
||||
|
||||
self.profile = ensureProfile()
|
||||
MTH_CHRON_Trace("OnEnable profile-after-ensure=" .. MTH_CHRON_FormatBarPosition(self.profile))
|
||||
self:SetCandyBarGroupGrowth(BAR_GROUP, self.profile.growup and true or false)
|
||||
self:SetCandyBarGroupVerticalSpacing(BAR_GROUP, self.profile.spacing or 0)
|
||||
if self.anchor then
|
||||
MTH_CHRON_Trace("OnEnable anchor-current-point=" .. MTH_CHRON_DescribePoint(self.anchor))
|
||||
end
|
||||
MTH_CHRON_RestoreAnchorFromProfile(self, "OnEnable")
|
||||
|
||||
self.groups = {}
|
||||
self.timers = {}
|
||||
@@ -430,16 +673,39 @@ function Chronometer:OnEnable()
|
||||
self:RegisterEvent("SPELLCAST_INTERRUPTED")
|
||||
self:RegisterEvent("SPELLCAST_START")
|
||||
self:RegisterEvent("SPELLCAST_STOP")
|
||||
self:RegisterEvent("UNIT_AURA")
|
||||
self:RegisterEvent("PLAYER_DEAD")
|
||||
self:RegisterEvent("VARIABLES_LOADED")
|
||||
self:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
self:RegisterEvent("PLAYER_LOGOUT")
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_SELF_DAMAGE", function(event, info) self:SELF_DAMAGE(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF", function(event, info) self:SELF_DAMAGE(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_FAILED_LOCALPLAYER", function(event, info) self:SPELL_FAILED(event, info) end)
|
||||
end
|
||||
|
||||
function Chronometer:VARIABLES_LOADED()
|
||||
self.profile = ensureProfile()
|
||||
MTH_CHRON_RestoreAnchorFromProfile(self, "VARIABLES_LOADED")
|
||||
end
|
||||
|
||||
function Chronometer:PLAYER_ENTERING_WORLD()
|
||||
self.profile = ensureProfile()
|
||||
MTH_CHRON_RestoreAnchorFromProfile(self, "PLAYER_ENTERING_WORLD")
|
||||
end
|
||||
|
||||
function Chronometer:PLAYER_LOGOUT()
|
||||
MTH_CHRON_PersistAnchorPosition(self, "PLAYER_LOGOUT")
|
||||
end
|
||||
|
||||
function Chronometer:OnDisable()
|
||||
if not self._mth_enabled then
|
||||
return
|
||||
end
|
||||
MTH_CHRON_Trace("OnDisable begin profile=" .. MTH_CHRON_FormatBarPosition(self.profile))
|
||||
if self.anchor then
|
||||
MTH_CHRON_Trace("OnDisable anchor-point=" .. MTH_CHRON_DescribePoint(self.anchor))
|
||||
end
|
||||
MTH_CHRON_PersistAnchorPosition(self, "OnDisable")
|
||||
self._mth_enabled = false
|
||||
|
||||
if self.bars then
|
||||
@@ -543,9 +809,12 @@ function Chronometer:StartTimer(timer, name, target, rank, durmod)
|
||||
end
|
||||
end
|
||||
|
||||
local _, class = UnitClass("player")
|
||||
local timerClass = timer.x.cl == nil and class or timer.x.cl
|
||||
if self.profile.disabledSpells[timerClass] and self.profile.disabledSpells[timerClass][name] ~= nil then
|
||||
local timerClass = timer.x.cl
|
||||
if timerClass == nil then
|
||||
timerClass = resolvePlayerClassBucket(self.profile)
|
||||
end
|
||||
local blocked, reason = isTimerDisabled(self.profile, timerClass, name)
|
||||
if blocked then
|
||||
return
|
||||
end
|
||||
|
||||
@@ -928,7 +1197,7 @@ function Chronometer:ToggleAnchor()
|
||||
end
|
||||
|
||||
function Chronometer:CreateAnchor(text, r, g, b)
|
||||
local frame = CreateFrame("Button", "MTHChronometerAnchor", UIParent)
|
||||
local frame = CreateFrame("Button", "MTH_ChronometerAnchor", UIParent)
|
||||
frame:SetWidth(220)
|
||||
frame:SetHeight(25)
|
||||
frame.owner = self
|
||||
@@ -938,31 +1207,41 @@ function Chronometer:CreateAnchor(text, r, g, b)
|
||||
|
||||
local px = tonumber(self.profile and self.profile.barposition and self.profile.barposition.x)
|
||||
local py = tonumber(self.profile and self.profile.barposition and self.profile.barposition.y)
|
||||
local ppoint = tostring(self.profile and self.profile.barposition and self.profile.barposition.point or "")
|
||||
local prelpoint = tostring(self.profile and self.profile.barposition and self.profile.barposition.relativePoint or "")
|
||||
MTH_CHRON_Trace("CreateAnchor saved-in profile=" .. MTH_CHRON_FormatBarPosition(self.profile))
|
||||
if px ~= nil and py ~= nil then
|
||||
if ppoint == "" then
|
||||
ppoint = "TOPLEFT"
|
||||
end
|
||||
if prelpoint == "" then
|
||||
prelpoint = ppoint
|
||||
end
|
||||
frame:ClearAllPoints()
|
||||
frame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", px, py)
|
||||
frame:SetPoint(ppoint, UIParent, prelpoint, px, py)
|
||||
MTH_CHRON_Trace("CreateAnchor restored point=" .. MTH_CHRON_DescribePoint(frame))
|
||||
else
|
||||
frame:SetPoint("CENTER", UIParent, "CENTER", 0, 50)
|
||||
MTH_CHRON_Trace("CreateAnchor default point=" .. MTH_CHRON_DescribePoint(frame))
|
||||
end
|
||||
|
||||
frame:SetScript("OnDragStart", function(self)
|
||||
self = self or this
|
||||
if not self or not self.StartMoving then
|
||||
frame:SetScript("OnDragStart", function()
|
||||
if not this or not this.StartMoving then
|
||||
return
|
||||
end
|
||||
self:StartMoving()
|
||||
MTH_CHRON_Trace("anchor drag-start point=" .. MTH_CHRON_DescribePoint(this))
|
||||
this:StartMoving()
|
||||
end)
|
||||
frame:SetScript("OnDragStop", function(self)
|
||||
self = self or this
|
||||
if not self then
|
||||
frame:SetScript("OnDragStop", function()
|
||||
if not this then
|
||||
return
|
||||
end
|
||||
|
||||
if self.StopMovingOrSizing then
|
||||
self:StopMovingOrSizing()
|
||||
if this.StopMovingOrSizing then
|
||||
this:StopMovingOrSizing()
|
||||
end
|
||||
|
||||
local point, _, _, x, y = self:GetPoint()
|
||||
local point, _, _, x, y = this:GetPoint()
|
||||
x = tonumber(x)
|
||||
y = tonumber(y)
|
||||
if not x or not y then
|
||||
@@ -971,12 +1250,16 @@ function Chronometer:CreateAnchor(text, r, g, b)
|
||||
|
||||
x = math.floor(x + 0.5)
|
||||
y = math.floor(y + 0.5)
|
||||
self:ClearAllPoints()
|
||||
self:SetPoint(point or "TOPLEFT", UIParent, point or "TOPLEFT", x, y)
|
||||
this:ClearAllPoints()
|
||||
this:SetPoint(point or "TOPLEFT", UIParent, point or "TOPLEFT", x, y)
|
||||
|
||||
if self.owner and self.owner.profile and type(self.owner.profile.barposition) == "table" then
|
||||
self.owner.profile.barposition.x = x
|
||||
self.owner.profile.barposition.y = y
|
||||
if this.owner and this.owner.profile and type(this.owner.profile.barposition) == "table" then
|
||||
this.owner.profile.barposition.point = point or "TOPLEFT"
|
||||
this.owner.profile.barposition.relativePoint = point or "TOPLEFT"
|
||||
this.owner.profile.barposition.x = x
|
||||
this.owner.profile.barposition.y = y
|
||||
MTH_CHRON_Trace("anchor drag-stop saved profile=" .. MTH_CHRON_FormatBarPosition(this.owner.profile)
|
||||
.. " frame=" .. MTH_CHRON_DescribePoint(this))
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -1102,6 +1385,62 @@ function Chronometer:PLAYER_DEAD()
|
||||
end
|
||||
end
|
||||
|
||||
function Chronometer:UNIT_AURA(unit)
|
||||
local auraUnit = unit
|
||||
if (not auraUnit or auraUnit == "") and type(arg1) == "string" then
|
||||
auraUnit = arg1
|
||||
end
|
||||
if auraUnit ~= "pet" then
|
||||
return
|
||||
end
|
||||
if not (UnitExists and UnitExists("pet")) then
|
||||
return
|
||||
end
|
||||
|
||||
local feedSpell = BS and BS["Feed Pet"] or "Feed Pet"
|
||||
local timer = self.timers and self.timers[self.SPELL] and self.timers[self.SPELL][feedSpell]
|
||||
if not timer then
|
||||
return
|
||||
end
|
||||
|
||||
local hasFeedAura = false
|
||||
if type(UnitBuff) == "function" then
|
||||
for i = 1, 32 do
|
||||
local texture = UnitBuff("pet", i)
|
||||
if not texture then
|
||||
break
|
||||
end
|
||||
local tex = tostring(texture)
|
||||
if string.find(tex, "Ability_Hunter_BeastTraining", 1, true)
|
||||
or string.find(tex, "INV_Misc_Fork&Knife", 1, true)
|
||||
then
|
||||
hasFeedAura = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not hasFeedAura then
|
||||
return
|
||||
end
|
||||
|
||||
local petName = UnitName and UnitName("pet") or "none"
|
||||
if not petName or petName == "" then
|
||||
petName = "none"
|
||||
end
|
||||
|
||||
for i = 1, 20 do
|
||||
local bar = self.bars and self.bars[i]
|
||||
if bar and bar.id and bar.name == feedSpell then
|
||||
if bar.target == petName or bar.target == "none" then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:StartTimer(timer, feedSpell, petName)
|
||||
end
|
||||
|
||||
function Chronometer:UseAction(slot, clicked, onself)
|
||||
local name, rank = getActionSpell(slot)
|
||||
if name then
|
||||
|
||||
@@ -8,7 +8,6 @@ Documentation: http://web.archive.org/web/20070314234510/http://wowace.com/wiki/
|
||||
Description: A timer bars library.
|
||||
Dependencies: AceLibrary, AceOO-2.0, PaintChips-2.0
|
||||
]]
|
||||
local match = string.match
|
||||
local getn,setn,tinsert = table.getn, table.setn,table.insert
|
||||
local vmajor, vminor = "CandyBar-2.0", "$Revision: 16011 $"
|
||||
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
local MTH_ChronometerModule = {
|
||||
name = "chronometer",
|
||||
enabled = true,
|
||||
version = "1.0.4",
|
||||
version = "1.2.0",
|
||||
events = {},
|
||||
initialized = false,
|
||||
}
|
||||
|
||||
local MTH_CHRON_MODULE_TRACE_ENABLED = false
|
||||
|
||||
local function MTH_CHRON_ModuleTrace(msg)
|
||||
if not MTH_CHRON_MODULE_TRACE_ENABLED then
|
||||
return
|
||||
end
|
||||
if MTH and MTH.Print then
|
||||
MTH:Print("[CHRONTRACE] " .. tostring(msg), "debug")
|
||||
elseif DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.AddMessage then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("[CHRONTRACE] " .. tostring(msg))
|
||||
end
|
||||
end
|
||||
|
||||
local function MTH_CHRON_ApplyRuntimeEnabledState(enabled)
|
||||
MTH_CHRON_ModuleTrace("module apply runtime enabled=" .. tostring(enabled and true or false))
|
||||
if not MTH_ChronometerHunter then
|
||||
MTH_CHRON_ModuleTrace("module apply runtime skipped (engine unavailable)")
|
||||
return
|
||||
end
|
||||
if enabled then
|
||||
@@ -22,14 +37,18 @@ local function MTH_CHRON_ApplyRuntimeEnabledState(enabled)
|
||||
end
|
||||
|
||||
function MTH_ChronometerModule:init()
|
||||
MTH_CHRON_ModuleTrace("module init begin enabled=" .. tostring(self.enabled and true or false))
|
||||
if MTH_ChronometerHunter and MTH_ChronometerHunter.MTH_Initialize then
|
||||
MTH_ChronometerHunter:MTH_Initialize()
|
||||
end
|
||||
MTH_CHRON_ApplyRuntimeEnabledState(self.enabled and true or false)
|
||||
self.initialized = true
|
||||
MTH_CHRON_ModuleTrace("module init end initialized=true")
|
||||
end
|
||||
|
||||
function MTH_ChronometerModule:setEnabled(enabled)
|
||||
MTH_CHRON_ModuleTrace("module setEnabled enabled=" .. tostring(enabled and true or false)
|
||||
.. " initialized=" .. tostring(self.initialized and true or false))
|
||||
if not self.initialized then
|
||||
self:init()
|
||||
end
|
||||
@@ -37,6 +56,7 @@ function MTH_ChronometerModule:setEnabled(enabled)
|
||||
end
|
||||
|
||||
function MTH_ChronometerModule:cleanup()
|
||||
MTH_CHRON_ModuleTrace("module cleanup")
|
||||
if MTH_ChronometerHunter and MTH_ChronometerHunter.MTH_Disable then
|
||||
MTH_ChronometerHunter:MTH_Disable()
|
||||
end
|
||||
|
||||
+988
-121
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
------------------------------------------------------
|
||||
|
||||
-- Key bindings
|
||||
BINDING_HEADER_FEEDOMATIC = "Fizzwidget Feed-O-Matic";
|
||||
-- NOTE: BINDING_HEADER_FEEDOMATIC is defined in api/localization.lua via the MTH_L() system.
|
||||
BINDING_NAME_FEEDOMATIC = "Feed Pet";
|
||||
|
||||
-- Diet names. These should be the all-lowercase versions of the six diets returned from GetPetFoodTypes(). (Want to get them all nice and quick for your localization? Go tame a bear... they eat anything.)
|
||||
@@ -111,110 +111,6 @@ FOM_OptionsButtonText = {
|
||||
};
|
||||
------------------------------------------------------
|
||||
|
||||
if (GetLocale() == "frFR") then
|
||||
|
||||
-- Diet names. These should be the all-lowercase versions of the six diets returned from GetPetFoodTypes(). (Want to get them all nice and quick for your localization? Go tame a bear... they eat anything.)
|
||||
-- THESE STRINGS MUST BE LOCALIZED for Feed-O-Matic to work properly in other locales.
|
||||
FOM_DIET_MEAT = "viande";
|
||||
FOM_DIET_FISH = "poisson";
|
||||
FOM_DIET_BREAD = "pain";
|
||||
FOM_DIET_CHEESE = "fromage";
|
||||
FOM_DIET_FRUIT = "fruit";
|
||||
FOM_DIET_FUNGUS = "champignon";
|
||||
|
||||
-- If the player has a buff whose icon name contains "Ability_Mount" and whose name contains one of these substrings, we assume the player is mounted. We have to use this rather oblique way to check for mounted because some other buffs use the Ability_Mount_* icons. If these aren't localized, we may not recognize when the player is mounted and still try to feed the pet.
|
||||
FOM_MOUNT_NAME_SUBSTRINGS = { "kodo", "loup", "raptor", "steed", "cheval", "bélier", "tigre", "mécanotrotteur", };
|
||||
|
||||
-- It's not clear whether the 5th and 6th returns from GetItemInfo() are supposed to be localized... so we have localized keys for them just in case. If these aren't localized, we'll just needlessly search your ammo bags for food.
|
||||
FOM_AMMO_POUCH = "Giberne";
|
||||
FOM_QUIVER = "Carquois";
|
||||
|
||||
|
||||
-- From here on down, the localized strings are just for readability... they don't affect whether Feed-O-Matic works.
|
||||
|
||||
-- Two special diets; one is used for tracking food that provides a bonus (or at least, that you don't want to have fed to your pet when the 'savebonus' option is on), and another that's used in the chat-line interface for listing all diets.
|
||||
FOM_DIET_BONUS = "bonus";
|
||||
FOM_DIET_ALL = "tous";
|
||||
|
||||
-- Used in tooltips to indicate food quality.
|
||||
FOM_QUALITY_UNKNOWN = "%s peut le manger, mais n'a jamais essayé.";
|
||||
FOM_QUALITY_UNDER = "%s n'en mange plus désormais.";
|
||||
FOM_QUALITY_MIGHT = "%s en mangera peut-être.";
|
||||
FOM_QUALITY_WILL = "%s en mangera.";
|
||||
FOM_QUALITY_LIKE = "%s aime en manger.";
|
||||
FOM_QUALITY_LOVE = "%s adore en manger.";
|
||||
|
||||
-- User-visible errors
|
||||
FOM_ERROR_NO_PET = "Vous n'avez pas de familier.";
|
||||
FOM_ERROR_PET_DEAD = "Votre familier est mort.";
|
||||
FOM_ERROR_NO_FEEDABLE_PET = "Vous n'avez pas de familier capable de manger.";
|
||||
FOM_ERROR_FOOD_NOT_FOUND = "%s n'a pas trouvé de %s dans votre sac.";
|
||||
FOM_ERROR_NO_FOOD = "%s n'a pas trouvé de nourriture dans votre sac.";
|
||||
|
||||
-- Feeding status messages
|
||||
FOM_FEEDING_EAT_ANOTHER = "%s n'aime pas cette nourriture et va essayer autre chose..."
|
||||
FOM_FEEDING_FEED_ANOTHER = "cherche autre chose à donner à %s...";
|
||||
FOM_FEEDING_EAT = "%s mange un(e) %s.";
|
||||
FOM_FEEDING_FEED = "donne à %s à manger un(e) %s. ";
|
||||
|
||||
-- Beast family names
|
||||
BAT = "Chauve-souris";
|
||||
BEAR = "Ours";
|
||||
BOAR = "Sanglier";
|
||||
CARRION_BIRD = "Charognard";
|
||||
CAT = "Félin";
|
||||
CRAB = "Crabe";
|
||||
CROCOLISK = "Crocilisque";
|
||||
GORILLA = "Gorille";
|
||||
HYENA = "Hyène";
|
||||
OWL = "Chouette";
|
||||
RAPTOR = "Raptor";
|
||||
SCORPID = "Scorpide";
|
||||
SPIDER = "Araignée";
|
||||
TALLSTRIDER = "Haut-trotteur";
|
||||
TURTLE = "Tortue";
|
||||
WIND_SERPENT = "Serpent des vents";
|
||||
WOLF = "Loup";
|
||||
|
||||
FOM_PET_HUNGRY = "%s a faim!";
|
||||
FOM_PET_VERY_HUNGRY = "%s a très faim!";
|
||||
|
||||
FOM_OPTIONS_HEADER = "Feed-O-Matic Options";
|
||||
FOM_OPTIONS_GENERAL = "Options générales:";
|
||||
FOM_OPTIONS_FOOD_CHOICE = "Eviter la nourriture utilisée en cuisine:";
|
||||
FOM_OPTIONS_FEED_NOTIFY = "Prévenir lorsque votre familier est nourrit:";
|
||||
FOM_OPTIONS_WARNING = "Avertir quand votre familier a besoin d'être nourrit:";
|
||||
|
||||
FOM_KEEPOPEN = "Essayer de garder au moins";
|
||||
FOM_KEEPOPEN_SLOTS = "emplacements de sac libres";
|
||||
FOM_KEEPOPEN_INFO = "(Le familier choisira la nourriture des piles les plus petites, sans tenir compte de ses préférences.)";
|
||||
|
||||
FOM_OptionsButtonText = {
|
||||
["Tooltip"] = "Afficher l'avis de votre familier concernant la nourriture",
|
||||
["AvoidQuestFood"] = "Eviter la nourriture utile dans les quêtes",
|
||||
["AvoidBonusFood"] = "Eviter la nourriture donnant un bonus",
|
||||
["PreferHigherQuality"] = "Privilégier la nourriture que votre familier préfère",
|
||||
["Fallback"] = "Utiliser la nourriture évitée s'il n'y en a plus d'autres",
|
||||
["SaveForCook_All"] = "Toutes nourritures utilisées pour la cuisine",
|
||||
["SaveForCook_Green"] = "si elle est utilisée dans les recettes |cff3fbf3f\"faciles\"|r ou supérieures",
|
||||
["SaveForCook_Yellow"] = "si elle est utilisée dans les recettes |cffffff00\"moyennes\"|r ou supérieures",
|
||||
["SaveForCook_Orange"] = "si elle est utilisée dans les recettes |cffff7f3f\"difficiles\"|r",
|
||||
["SaveForCook_None"] = "Ne pas éviter la nourriture utilisée en cuisine",
|
||||
["IconWarning"] = "Clignoter l'icône",
|
||||
["TextWarning"] = "Afficher un texte",
|
||||
["AudioWarning"] = "Jouer un son",
|
||||
["AudioWarningBell"] = "Un son de cloche au lieu du cri du familier",
|
||||
["AlertEmote"] = "Via emote (visible par les autres)",
|
||||
["AlertChat"] = "Dans la fenêtre de discussion (visible uniquement par vous)",
|
||||
["AlertNone"] = "Ne pas prévenir",
|
||||
["LevelContent"] = "quand \"content\"",
|
||||
["LevelUnhappy"] = "quand \"mécontent\"",
|
||||
["LevelOff"] = "Ne pas avertir",
|
||||
};
|
||||
end
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
if (GetLocale() == "deDE") then
|
||||
|
||||
-- Diet names. These should be the all-lowercase versions of the six diets returned from GetPetFoodTypes(). (Want to get them all nice and quick for your localization? Go tame a bear... they eat anything.)
|
||||
@@ -279,26 +175,4 @@ if (GetLocale() == "deDE") then
|
||||
WIND_SERPENT = "Windnatter";
|
||||
-- WOLF = "Wolf"; -- same as enUS
|
||||
|
||||
end
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
if (GetLocale() == "koKR") then
|
||||
|
||||
-- Diet names. These should be the all-lowercase versions of the six diets returned from GetPetFoodTypes(). (Want to get them all nice and quick for your localization? Go tame a bear... they eat anything.)
|
||||
-- THESE STRINGS MUST BE LOCALIZED for Feed-O-Matic to work properly in other locales.
|
||||
-- FOM_DIET_MEAT = "meat";
|
||||
-- FOM_DIET_FISH = "fish";
|
||||
-- FOM_DIET_BREAD = "bread";
|
||||
-- FOM_DIET_CHEESE = "cheese";
|
||||
-- FOM_DIET_FRUIT = "fruit";
|
||||
-- FOM_DIET_FUNGUS = "fungus";
|
||||
|
||||
-- If the player has a buff whose icon name contains "Ability_Mount" and whose name contains one of these substrings, we assume the player is mounted. We have to use this rather oblique way to check for mounted because some other buffs use the Ability_Mount_* icons.
|
||||
-- FOM_MOUNT_NAME_SUBSTRINGS = { "kodo", "wolf", "raptor", "steed", "horse", "ram", "saber", "mechanostrider" };
|
||||
|
||||
-- It's not clear whether the 5th and 6th returns from GetItemInfo() are supposed to be localized... so we have localized keys for them just in case.
|
||||
-- FOM_AMMO_POUCH = "Ammo Pouch";
|
||||
FOM_QUIVER = "화살통";
|
||||
|
||||
end
|
||||
@@ -6,7 +6,7 @@
|
||||
local MTH_FeedOMatic = {
|
||||
name = "feedomatic",
|
||||
enabled = false,
|
||||
version = "1.0.4",
|
||||
version = "1.2.0",
|
||||
events = {
|
||||
"VARIABLES_LOADED",
|
||||
"MERCHANT_SHOW",
|
||||
@@ -32,13 +32,13 @@ local MTH_FeedOMatic = {
|
||||
}
|
||||
|
||||
local MTH_PETL_HOOK_BOUNDARY_KEY = "pet-lifecycle-hooks"
|
||||
local MTH_FeedOMatic_MerchantProbeFrame = nil
|
||||
local MTH_FOM_MerchantProbe = nil
|
||||
|
||||
function MTH_FeedOMatic_OnUpdate(elapsed)
|
||||
if not elapsed then
|
||||
return
|
||||
end
|
||||
if not (MTH and MTH.IsModuleEnabled and MTH:IsModuleEnabled("feedomatic", true)) then
|
||||
if not (MTH and MTH.IsModuleEnabled and MTH:IsModuleEnabled("feedomatic", false)) then
|
||||
return
|
||||
end
|
||||
if type(FOM_OnUpdate) == "function" then
|
||||
@@ -47,7 +47,7 @@ function MTH_FeedOMatic_OnUpdate(elapsed)
|
||||
end
|
||||
|
||||
local function MTH_FeedOMatic_GetRuntimeFrame()
|
||||
return getglobal("Frame_GFW_FeedOMatic")
|
||||
return getglobal("MTH_FOM_OnUpdateFrame")
|
||||
end
|
||||
|
||||
local function MTH_FeedOMatic_CaptureHookBoundary()
|
||||
@@ -137,47 +137,31 @@ local function MTH_FeedOMatic_SyncSavedVariables()
|
||||
moduleStore.legacy = {}
|
||||
end
|
||||
|
||||
if type(FOM_Config) == "table" then
|
||||
moduleStore.legacy.FOM_Config = FOM_Config
|
||||
elseif type(moduleStore.legacy.FOM_Config) == "table" then
|
||||
FOM_Config = moduleStore.legacy.FOM_Config
|
||||
local function bindLegacyTable(globalName)
|
||||
local legacyValue = moduleStore.legacy[globalName]
|
||||
local globalValue = _G and _G[globalName] or nil
|
||||
|
||||
if type(legacyValue) ~= "table" then
|
||||
if type(globalValue) == "table" then
|
||||
legacyValue = globalValue
|
||||
else
|
||||
legacyValue = {}
|
||||
end
|
||||
moduleStore.legacy[globalName] = legacyValue
|
||||
end
|
||||
|
||||
if _G then
|
||||
_G[globalName] = legacyValue
|
||||
end
|
||||
end
|
||||
|
||||
if type(FOM_FoodQuality) == "table" then
|
||||
moduleStore.legacy.FOM_FoodQuality = FOM_FoodQuality
|
||||
elseif type(moduleStore.legacy.FOM_FoodQuality) == "table" then
|
||||
FOM_FoodQuality = moduleStore.legacy.FOM_FoodQuality
|
||||
end
|
||||
|
||||
if type(FOM_AddedFoods) == "table" then
|
||||
moduleStore.legacy.FOM_AddedFoods = FOM_AddedFoods
|
||||
elseif type(moduleStore.legacy.FOM_AddedFoods) == "table" then
|
||||
FOM_AddedFoods = moduleStore.legacy.FOM_AddedFoods
|
||||
end
|
||||
|
||||
if type(FOM_RemovedFoods) == "table" then
|
||||
moduleStore.legacy.FOM_RemovedFoods = FOM_RemovedFoods
|
||||
elseif type(moduleStore.legacy.FOM_RemovedFoods) == "table" then
|
||||
FOM_RemovedFoods = moduleStore.legacy.FOM_RemovedFoods
|
||||
end
|
||||
|
||||
if type(FOM_Cooking) == "table" then
|
||||
moduleStore.legacy.FOM_Cooking = FOM_Cooking
|
||||
elseif type(moduleStore.legacy.FOM_Cooking) == "table" then
|
||||
FOM_Cooking = moduleStore.legacy.FOM_Cooking
|
||||
end
|
||||
|
||||
if type(FOM_QuestFood) == "table" then
|
||||
moduleStore.legacy.FOM_QuestFood = FOM_QuestFood
|
||||
elseif type(moduleStore.legacy.FOM_QuestFood) == "table" then
|
||||
FOM_QuestFood = moduleStore.legacy.FOM_QuestFood
|
||||
end
|
||||
|
||||
if type(FOM_LocaleInfo) == "table" then
|
||||
moduleStore.legacy.FOM_LocaleInfo = FOM_LocaleInfo
|
||||
elseif type(moduleStore.legacy.FOM_LocaleInfo) == "table" then
|
||||
FOM_LocaleInfo = moduleStore.legacy.FOM_LocaleInfo
|
||||
end
|
||||
bindLegacyTable("FOM_Config")
|
||||
bindLegacyTable("FOM_FoodQuality")
|
||||
bindLegacyTable("FOM_AddedFoods")
|
||||
bindLegacyTable("FOM_RemovedFoods")
|
||||
bindLegacyTable("FOM_Cooking")
|
||||
bindLegacyTable("FOM_QuestFood")
|
||||
bindLegacyTable("FOM_LocaleInfo")
|
||||
end
|
||||
|
||||
local function MTH_FeedOMatic_Log(message, severity)
|
||||
@@ -231,9 +215,17 @@ local function MTH_FeedOMatic_DebugMerchantScan(sourceEvent)
|
||||
end
|
||||
|
||||
local function MTH_FeedOMatic_SetMerchantProbeEnabled(enabled)
|
||||
if not MTH_FeedOMatic_MerchantProbeFrame then
|
||||
MTH_FeedOMatic_MerchantProbeFrame = CreateFrame("Frame", "MTH_FeedOMatic_MerchantProbeFrame")
|
||||
MTH_FeedOMatic_MerchantProbeFrame:SetScript("OnEvent", function()
|
||||
if not enabled then
|
||||
if MTH_FOM_MerchantProbe then
|
||||
MTH_FOM_MerchantProbe:UnregisterEvent("MERCHANT_SHOW")
|
||||
MTH_FOM_MerchantProbe:UnregisterEvent("MERCHANT_UPDATE")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if not MTH_FOM_MerchantProbe then
|
||||
MTH_FOM_MerchantProbe = CreateFrame("Frame", "MTH_FOM_MerchantProbe")
|
||||
MTH_FOM_MerchantProbe:SetScript("OnEvent", function()
|
||||
local evt = event
|
||||
if evt == "MERCHANT_SHOW" or evt == "MERCHANT_UPDATE" then
|
||||
MTH_FeedOMatic_Log("probe event received: " .. tostring(evt), "debug")
|
||||
@@ -242,14 +234,9 @@ local function MTH_FeedOMatic_SetMerchantProbeEnabled(enabled)
|
||||
end)
|
||||
end
|
||||
|
||||
if enabled then
|
||||
MTH_FeedOMatic_MerchantProbeFrame:RegisterEvent("MERCHANT_SHOW")
|
||||
MTH_FeedOMatic_MerchantProbeFrame:RegisterEvent("MERCHANT_UPDATE")
|
||||
MTH_FeedOMatic_Log("merchant probe enabled", "debug")
|
||||
else
|
||||
MTH_FeedOMatic_MerchantProbeFrame:UnregisterEvent("MERCHANT_SHOW")
|
||||
MTH_FeedOMatic_MerchantProbeFrame:UnregisterEvent("MERCHANT_UPDATE")
|
||||
end
|
||||
MTH_FOM_MerchantProbe:RegisterEvent("MERCHANT_SHOW")
|
||||
MTH_FOM_MerchantProbe:RegisterEvent("MERCHANT_UPDATE")
|
||||
MTH_FeedOMatic_Log("merchant probe enabled", "debug")
|
||||
end
|
||||
|
||||
function MTH_FeedOMatic:init()
|
||||
@@ -290,8 +277,8 @@ function MTH_FeedOMatic:setEnabled(enabled)
|
||||
MTH_FeedOMatic_SyncSavedVariables()
|
||||
MTH_FeedOMatic_EnsureVariablesLoaded(self)
|
||||
MTH_FeedOMatic_SetMerchantProbeEnabled(false)
|
||||
if FOM_FeedButton then
|
||||
FOM_FeedButton:Show()
|
||||
if MTH_FOM_FeedButton then
|
||||
MTH_FOM_FeedButton:Show()
|
||||
end
|
||||
else
|
||||
-- Disable FeedOMatic functionality
|
||||
@@ -300,8 +287,8 @@ function MTH_FeedOMatic:setEnabled(enabled)
|
||||
FOM_State.ShouldFeed = false
|
||||
end
|
||||
MTH_FeedOMatic_SetMerchantProbeEnabled(false)
|
||||
if FOM_FeedButton then
|
||||
FOM_FeedButton:Hide()
|
||||
if MTH_FOM_FeedButton then
|
||||
MTH_FOM_FeedButton:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -329,8 +316,8 @@ function MTH_FeedOMatic:cleanup()
|
||||
FOM_State.ShouldFeed = false
|
||||
end
|
||||
MTH_FeedOMatic_SetMerchantProbeEnabled(false)
|
||||
if FOM_FeedButton then
|
||||
FOM_FeedButton:Hide();
|
||||
if MTH_FOM_FeedButton then
|
||||
MTH_FOM_FeedButton:Hide();
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ FeedOMatic Runtime Frame Loader (MetaHunt)
|
||||
Minimal runtime XML without legacy options window definitions.
|
||||
-->
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\..\..\FrameXML\UI.xsd">
|
||||
<Frame name="Frame_GFW_FeedOMatic">
|
||||
<Frame name="MTH_FOM_OnUpdateFrame">
|
||||
<Scripts>
|
||||
<OnUpdate>
|
||||
if (MTH_FOM_OnUpdate) then
|
||||
@@ -15,7 +15,7 @@ Minimal runtime XML without legacy options window definitions.
|
||||
</Scripts>
|
||||
</Frame>
|
||||
|
||||
<GameTooltip name="FOMTooltip" frameStrata="TOOLTIP" hidden="true" parent="UIParent" inherits="GameTooltipTemplate">
|
||||
<GameTooltip name="MTH_FOM_Tooltip" frameStrata="TOOLTIP" hidden="true" parent="UIParent" inherits="GameTooltipTemplate">
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
this:SetOwner(UIParent, "ANCHOR_NONE");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,320 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="MTH_ICU.lua"/>
|
||||
<!-- The main ICU frame -->
|
||||
<Frame name="ICU_Frame">
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
ICU_OnLoad();
|
||||
</OnLoad>
|
||||
<OnEvent>
|
||||
ICU_OnEvent(event);
|
||||
</OnEvent>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<!-- A button template, to be inherited by each button -->
|
||||
<Frame name="ICU_PopupButtonTemplate" virtual="true">
|
||||
<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
|
||||
<BackgroundInsets>
|
||||
<AbsInset left="5" right="5" top="5" bottom="5"/>
|
||||
</BackgroundInsets>
|
||||
<TileSize>
|
||||
<AbsValue val="16"/>
|
||||
</TileSize>
|
||||
<EdgeSize>
|
||||
<AbsValue val="16"/>
|
||||
</EdgeSize>
|
||||
</Backdrop>
|
||||
<Size>
|
||||
<AbsDimension x="30" y="28"/>
|
||||
</Size>
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture name="$parentButtonPortraitIcon">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativePoint="LEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="5" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentButtonClassIcon">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativePoint="RIGHT" relativeTo="$parentButtonPortraitIcon">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentButtonRankIcon">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT" relativePoint="LEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Button name="$parentButton" frameStrata="ARTWORK">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativePoint="LEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="5" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<HighlightTexture file="Interface\QuestFrame\UI-QuestTitleHighlight" alphaMode="ADD" setAllPoints="true" hidden="true"/>
|
||||
<NormalText inherits="GameFontNormal">
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativePoint="RIGHT" relativeTo="$parentClassIcon">
|
||||
<Offset>
|
||||
<AbsDimension x="5" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</NormalText>
|
||||
<HighlightText inherits="GameFontHighlight">
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativePoint="RIGHT" relativeTo="$parentClassIcon">
|
||||
<Offset>
|
||||
<AbsDimension x="5" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</HighlightText>
|
||||
<DisabledText inherits="GameFontDisable">
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativePoint="RIGHT" relativeTo="$parentClassIcon">
|
||||
<Offset>
|
||||
<AbsDimension x="5" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</DisabledText>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
ICU_ButtonClick();
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<StatusBar name="$parentButtonBar" inherits="TextStatusBar" frameStrata="ARTWORK">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativePoint="RIGHT" relativeTo="$parentButtonClassIcon">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<BarTexture file="Interface\TargetingFrame\UI-TargetingFrame-BarFill"/>
|
||||
<BarColor r="0" g="0.8" b="0" a="0.7" />
|
||||
<!--
|
||||
<Layers>
|
||||
<Layer level="OVERLAY">
|
||||
<FontString name="$parentLeftText" inherits="GameFontNormal" text="">
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativePoint="LEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="10" y="1"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
<FontString name="$parentRightText" inherits="GameFontNormal" text="">
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT" relativePoint="RIGHT">
|
||||
<Offset>
|
||||
<AbsDimension x="-10" y="1"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
!-->
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
this:SetMinMaxValues(0, 100);
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</StatusBar>
|
||||
<StatusBar name="$parentButtonBGBar" inherits="TextStatusBar" frameStrata="ARTWORK">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativePoint="TOP" relativeTo="$parentButtonBar">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<BarTexture file="Interface\TargetingFrame\UI-TargetingFrame-BarFill"/>
|
||||
<BarColor r="0" g="0.8" b="0" a="0.25"/>
|
||||
</StatusBar>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
this:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b);
|
||||
this:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b);
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<!-- The popup menu -->
|
||||
<Frame name="ICU_Popup" toplevel="true" frameStrata="DIALOG" enableMouse="true" hidden="true" parent="UIParent">
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" relativeTo="MinimapCluster" relativePoint="BOTTOMRIGHT"/>
|
||||
</Anchors>
|
||||
<!--
|
||||
<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
|
||||
<BackgroundInsets>
|
||||
<AbsInset left="5" right="5" top="5" bottom="5"/>
|
||||
</BackgroundInsets>
|
||||
<TileSize>
|
||||
<AbsValue val="16"/>
|
||||
</TileSize>
|
||||
<EdgeSize>
|
||||
<AbsValue val="16"/>
|
||||
</EdgeSize>
|
||||
</Backdrop>
|
||||
!-->
|
||||
<!-- Within the popup menu, the clickable buttons which to display text -->
|
||||
<Frames>
|
||||
<!-- Button 1 -->
|
||||
<Frame name="ICU_PopupButton1" inherits="ICU_PopupButtonTemplate" id="1" ICU_DATA="">
|
||||
<Anchors>
|
||||
<Anchor point="TOP">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="-6"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
<!-- Frame 2 -->
|
||||
<Frame name="ICU_PopupButton2" inherits="ICU_PopupButtonTemplate" id="2" ICU_DATA="">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="ICU_PopupButton1" relativePoint="BOTTOM">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="4"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
<!-- Frame 3 -->
|
||||
<Frame name="ICU_PopupButton3" inherits="ICU_PopupButtonTemplate" id="3" ICU_DATA="">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="ICU_PopupButton2" relativePoint="BOTTOM">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="4"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
<!-- Frame 4 -->
|
||||
<Frame name="ICU_PopupButton4" inherits="ICU_PopupButtonTemplate" id="4" ICU_DATA="">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="ICU_PopupButton3" relativePoint="BOTTOM">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="4"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
<!-- Frame 5 -->
|
||||
<Frame name="ICU_PopupButton5" inherits="ICU_PopupButtonTemplate" id="5" ICU_DATA="">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="ICU_PopupButton4" relativePoint="BOTTOM">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="4"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
<!-- Frame 6 -->
|
||||
<Frame name="ICU_PopupButton6" inherits="ICU_PopupButtonTemplate" id="6" ICU_DATA="">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="ICU_PopupButton5" relativePoint="BOTTOM">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="4"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
<!-- Frame 7 -->
|
||||
<Frame name="ICU_PopupButton7" inherits="ICU_PopupButtonTemplate" id="7" ICU_DATA="">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="ICU_PopupButton6" relativePoint="BOTTOM">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="4"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
<!-- Frame 8 -->
|
||||
<Frame name="ICU_PopupButton8" inherits="ICU_PopupButtonTemplate" id="8" ICU_DATA="">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="ICU_PopupButton7" relativePoint="BOTTOM">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="4"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
<!-- Frame 9 -->
|
||||
<Frame name="ICU_PopupButton9" inherits="ICU_PopupButtonTemplate" id="9" ICU_DATA="">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="ICU_PopupButton8" relativePoint="BOTTOM">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="4"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
<!-- Frame 10 -->
|
||||
<Frame name="ICU_PopupButton10" inherits="ICU_PopupButtonTemplate" id="10" ICU_DATA="">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="ICU_PopupButton9" relativePoint="BOTTOM">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="4"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
<!-- This makes the dialog look like a normal tooltip -->
|
||||
this:SetBackdropBorderColor( TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b );
|
||||
this:SetBackdropColor( TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b );
|
||||
</OnLoad>
|
||||
<OnUpdate>
|
||||
ICU_Popup_OnUpdate();
|
||||
</OnUpdate>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<Frame name="ICU_UpdateFrame" hidden="true">
|
||||
<Scripts>
|
||||
<OnUpdate>
|
||||
ICU_MouseOverUpdate();
|
||||
</OnUpdate>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
</Ui>
|
||||
@@ -0,0 +1,8 @@
|
||||
<!--
|
||||
ICU Module Loader
|
||||
Loads ICU runtime and wraps it in the MetaHunt module system.
|
||||
-->
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Include file="MTH_ICU.xml"/>
|
||||
<Include file="module.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,52 @@
|
||||
------------------------------------------------------
|
||||
-- MetaHunt: ICU Module Wrapper
|
||||
-- Safe wrapper for ICU minimap targeting utilities
|
||||
------------------------------------------------------
|
||||
|
||||
local MTH_ICU = {
|
||||
name = "icu",
|
||||
enabled = false,
|
||||
version = "1.2.0",
|
||||
events = {
|
||||
"VARIABLES_LOADED",
|
||||
},
|
||||
initialized = false,
|
||||
}
|
||||
|
||||
local function ICU_Log(message, severity)
|
||||
if type(MTH_Log) == "function" then
|
||||
MTH_Log("[ICU] " .. tostring(message or ""), severity)
|
||||
end
|
||||
end
|
||||
|
||||
function MTH_ICU:init()
|
||||
self.initialized = true
|
||||
if type(ICU_SetEnabled) == "function" then
|
||||
ICU_SetEnabled(self.enabled and true or false)
|
||||
end
|
||||
end
|
||||
|
||||
function MTH_ICU:setEnabled(enabled)
|
||||
if not self.initialized then
|
||||
self:init()
|
||||
end
|
||||
if type(ICU_SetEnabled) == "function" then
|
||||
ICU_SetEnabled(enabled and true or false)
|
||||
else
|
||||
ICU_Log("runtime not loaded; cannot change enabled state", "error")
|
||||
end
|
||||
end
|
||||
|
||||
function MTH_ICU:onEvent(eventName)
|
||||
if eventName == "VARIABLES_LOADED" and type(ICU_SetEnabled) == "function" then
|
||||
ICU_SetEnabled(self.enabled and true or false)
|
||||
end
|
||||
end
|
||||
|
||||
function MTH_ICU:cleanup()
|
||||
if type(ICU_SetEnabled) == "function" then
|
||||
ICU_SetEnabled(false)
|
||||
end
|
||||
end
|
||||
|
||||
MTH:RegisterModule("icu", MTH_ICU)
|
||||
+790
-773
File diff suppressed because it is too large
Load Diff
@@ -7,10 +7,10 @@ MTH_SA_MANAGED_HOOKS = true
|
||||
local MTH_SmartAmmo = {
|
||||
name = "smartammo",
|
||||
enabled = true,
|
||||
version = "1.0.4",
|
||||
version = "1.2.0",
|
||||
events = {
|
||||
"VARIABLES_LOADED",
|
||||
"PLAYER_ENTERING_WORLD",
|
||||
-- PLAYER_ENTERING_WORLD handled by engine's own frame
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
+500
-29
@@ -6,7 +6,7 @@
|
||||
local MTH_Tooltips = {
|
||||
name = "tooltips",
|
||||
enabled = true,
|
||||
version = "1.0.4",
|
||||
version = "1.2.0",
|
||||
events = {
|
||||
"UPDATE_MOUSEOVER_UNIT",
|
||||
"UNIT_NAME_UPDATE",
|
||||
@@ -34,14 +34,33 @@ local MTH_Tooltips = {
|
||||
injectFrame = nil,
|
||||
pollFrame = nil,
|
||||
pollElapsed = 0,
|
||||
hintElapsed = 0,
|
||||
lastMouseoverKey = "",
|
||||
}
|
||||
|
||||
local function MTH_TT_CopyValue(value)
|
||||
if type(value) ~= "table" then
|
||||
return value
|
||||
end
|
||||
local copy = {}
|
||||
for key, entry in pairs(value) do
|
||||
copy[key] = MTH_TT_CopyValue(entry)
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
local function MTH_TT_GetOptionsStore()
|
||||
if MTH and MTH.GetModuleSavedVariables then
|
||||
local store = MTH:GetModuleSavedVariables("tooltips")
|
||||
if MTH and MTH.GetModuleCharSavedVariables then
|
||||
local store = MTH:GetModuleCharSavedVariables("tooltips")
|
||||
if type(store) == "table" then
|
||||
if MTH.GetModuleSavedVariables and next(store) == nil then
|
||||
local accountStore = MTH:GetModuleSavedVariables("tooltips")
|
||||
if type(accountStore) == "table" and next(accountStore) ~= nil then
|
||||
for key, value in pairs(accountStore) do
|
||||
store[key] = MTH_TT_CopyValue(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
if store.beastTooltips == nil then
|
||||
store.beastTooltips = true
|
||||
end
|
||||
@@ -96,6 +115,55 @@ local function MTH_TT_IsOwnPetTooltipsEnabled()
|
||||
return false
|
||||
end
|
||||
|
||||
local function MTH_TT_GetAutoQuestStore()
|
||||
if type(MTH_CharSavedVariables) ~= "table" then
|
||||
return nil
|
||||
end
|
||||
local store = MTH_CharSavedVariables.autoquest
|
||||
if type(store) ~= "table" then
|
||||
store = MTH_CharSavedVariables.questautomation
|
||||
end
|
||||
if type(store) ~= "table" then
|
||||
return nil
|
||||
end
|
||||
if store.scorpokDrazial == nil then
|
||||
store.scorpokDrazial = false
|
||||
end
|
||||
if store.scorpokTooltip == nil then
|
||||
store.scorpokTooltip = false
|
||||
end
|
||||
return store
|
||||
end
|
||||
|
||||
local function MTH_TT_IsScorpokAutomationEnabled()
|
||||
local store = MTH_TT_GetAutoQuestStore()
|
||||
if type(store) ~= "table" then
|
||||
return false
|
||||
end
|
||||
return store.scorpokDrazial and true or false
|
||||
end
|
||||
|
||||
local function MTH_TT_IsScorpokTooltipEnabled()
|
||||
local store = MTH_TT_GetAutoQuestStore()
|
||||
if type(store) ~= "table" then
|
||||
return false
|
||||
end
|
||||
return store.scorpokTooltip and true or false
|
||||
end
|
||||
|
||||
local function MTH_TT_IsAutoQuestModuleEnabled()
|
||||
if MTH and type(MTH.GetModule) == "function" then
|
||||
local module = MTH:GetModule("autoquest")
|
||||
if type(module) == "table" and module.enabled ~= nil then
|
||||
return module.enabled and true or false
|
||||
end
|
||||
end
|
||||
if MTH and type(MTH.IsModuleEnabled) == "function" then
|
||||
return MTH:IsModuleEnabled("autoquest", false) and true or false
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function MTH_TT_Loc(key, fallback)
|
||||
if MTH and MTH.GetLocalization then
|
||||
return MTH:GetLocalization(key, fallback)
|
||||
@@ -539,6 +607,191 @@ local function MTH_TT_ColorizeDigitsBlue(text)
|
||||
return string.gsub(source, "(%d+)", "|cff73bfff%1|r")
|
||||
end
|
||||
|
||||
local MTH_TT_SCORPOK_NPC_NAME = "Bloodmage Drazial"
|
||||
local MTH_TT_SCORPOK_TARGET_NPC_IDS = {
|
||||
[7505] = true,
|
||||
[5988] = true,
|
||||
[5982] = true,
|
||||
[5992] = true,
|
||||
[5993] = true,
|
||||
}
|
||||
local MTH_TT_SCORPOK_TARGET_NPC_NAMES = {
|
||||
[MTH_TT_NormalizeName("Bloodmage Drazial")] = true,
|
||||
[MTH_TT_NormalizeName("Scorpok Stinger")] = true,
|
||||
[MTH_TT_NormalizeName("Black Slayer")] = true,
|
||||
[MTH_TT_NormalizeName("Ashmane Boar")] = true,
|
||||
[MTH_TT_NormalizeName("Helboar")] = true,
|
||||
}
|
||||
local MTH_TT_ITEM_SCORPOK_PINCER_ID = 8393
|
||||
local MTH_TT_ITEM_VULTURE_GIZZARD_ID = 8396
|
||||
local MTH_TT_ITEM_BLASTED_BOAR_LUNG_ID = 8392
|
||||
local MTH_TT_ITEM_GROUND_SCORPOK_ASSAY_ID = 8412
|
||||
|
||||
local function MTH_TT_ParseNpcIdFromGuid(guid)
|
||||
if type(guid) ~= "string" or guid == "" then
|
||||
return nil
|
||||
end
|
||||
local _, _, _, _, _, npcId = string.find(guid, "^Creature%-%d+%-%d+%-%d+%-%d+%-(%d+)%-%x+$")
|
||||
if npcId then
|
||||
return tonumber(npcId)
|
||||
end
|
||||
if string.sub(guid, 1, 2) == "0x" and string.len(guid) >= 12 then
|
||||
local hex = string.sub(guid, 9, 12)
|
||||
local parsed = tonumber(hex, 16)
|
||||
if parsed and parsed > 0 then
|
||||
return parsed
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function MTH_TT_GetBagItemCount(itemId)
|
||||
local getContainerNumSlots = _G and _G["GetContainerNumSlots"] or nil
|
||||
local getContainerItemLink = _G and _G["GetContainerItemLink"] or nil
|
||||
local getContainerItemInfo = _G and _G["GetContainerItemInfo"] or nil
|
||||
if type(getContainerNumSlots) ~= "function" or type(getContainerItemLink) ~= "function" then
|
||||
return 0
|
||||
end
|
||||
local total = 0
|
||||
for bag = 0, 4 do
|
||||
local slots = math.floor(tonumber(getContainerNumSlots(bag)) or 0)
|
||||
for slot = 1, slots do
|
||||
local link = getContainerItemLink(bag, slot)
|
||||
if type(link) == "string" and link ~= "" then
|
||||
local _, _, foundText = string.find(link, "item:(%d+)")
|
||||
local found = tonumber(foundText)
|
||||
if found and tonumber(found) == tonumber(itemId) then
|
||||
local count = 1
|
||||
if type(getContainerItemInfo) == "function" then
|
||||
local _, stackCount = getContainerItemInfo(bag, slot)
|
||||
count = math.floor(tonumber(stackCount) or 1)
|
||||
end
|
||||
total = total + count
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return total
|
||||
end
|
||||
|
||||
local function MTH_TT_ColorCountByThreshold(value, threshold)
|
||||
local n = math.floor(tonumber(value) or 0)
|
||||
if n <= 0 then
|
||||
return "|cffff0000" .. tostring(n) .. "|r"
|
||||
end
|
||||
local modFn = nil
|
||||
if type(rawget) == "function" and type(math) == "table" then
|
||||
modFn = rawget(math, "mod") or rawget(math, "fmod")
|
||||
elseif type(math) == "table" then
|
||||
modFn = math.fmod
|
||||
end
|
||||
if threshold > 0 and type(modFn) == "function" and modFn(n, threshold) == 0 then
|
||||
return "|cff00ff00" .. tostring(n) .. "|r"
|
||||
end
|
||||
return "|cffffa500" .. tostring(n) .. "|r"
|
||||
end
|
||||
|
||||
local function MTH_TT_ColorAssayCount(value)
|
||||
local n = math.floor(tonumber(value) or 0)
|
||||
if n > 0 then
|
||||
return "|cff73bfff" .. tostring(n) .. "|r"
|
||||
end
|
||||
return tostring(n)
|
||||
end
|
||||
|
||||
local function MTH_TT_HasScorpokTooltipLine()
|
||||
if not GameTooltip or not GameTooltip.NumLines then return false end
|
||||
for i = 1, GameTooltip:NumLines() do
|
||||
local left = getglobal("GameTooltipTextLeft" .. i)
|
||||
if left and left.GetText then
|
||||
local text = tostring(left:GetText() or "")
|
||||
if string.find(text, "MTH Auto Quest", 1, true)
|
||||
or string.find(text, "Ground Scorpok Assay", 1, true) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function MTH_TT_IsScorpokTooltipZoneAllowed()
|
||||
local getRealZoneText = _G and _G["GetRealZoneText"] or nil
|
||||
local getZoneText = _G and _G["GetZoneText"] or nil
|
||||
local zoneName = ""
|
||||
if type(getRealZoneText) == "function" then
|
||||
zoneName = tostring(getRealZoneText() or "")
|
||||
end
|
||||
if zoneName == "" and type(getZoneText) == "function" then
|
||||
zoneName = tostring(getZoneText() or "")
|
||||
end
|
||||
if zoneName == "" then
|
||||
return true
|
||||
end
|
||||
return MTH_TT_NormalizeName(zoneName) == MTH_TT_NormalizeName("Blasted Lands")
|
||||
end
|
||||
|
||||
local function MTH_TT_AddScorpokTargetsTooltip(unit, unitName)
|
||||
if not MTH_TT_IsAutoQuestModuleEnabled() then
|
||||
return false
|
||||
end
|
||||
if not MTH_TT_IsScorpokAutomationEnabled() or not MTH_TT_IsScorpokTooltipEnabled() then
|
||||
return false
|
||||
end
|
||||
if not MTH_TT_IsScorpokTooltipZoneAllowed() then
|
||||
return false
|
||||
end
|
||||
if MTH_TT_HasScorpokTooltipLine() then
|
||||
return false
|
||||
end
|
||||
|
||||
local npcId = nil
|
||||
if type(UnitGUID) == "function" then
|
||||
npcId = MTH_TT_ParseNpcIdFromGuid(UnitGUID(unit))
|
||||
end
|
||||
local isDrazial = false
|
||||
if tonumber(npcId) == 7505 then
|
||||
isDrazial = true
|
||||
elseif MTH_TT_Lower(unitName) == MTH_TT_Lower(MTH_TT_SCORPOK_NPC_NAME) then
|
||||
isDrazial = true
|
||||
end
|
||||
local isTargetNpc = false
|
||||
if npcId and MTH_TT_SCORPOK_TARGET_NPC_IDS[tonumber(npcId)] then
|
||||
isTargetNpc = true
|
||||
end
|
||||
if not isTargetNpc then
|
||||
local normalizedName = MTH_TT_NormalizeName(unitName)
|
||||
isTargetNpc = MTH_TT_SCORPOK_TARGET_NPC_NAMES[normalizedName] and true or false
|
||||
if not isTargetNpc then
|
||||
isTargetNpc = MTH_TT_Lower(unitName) == MTH_TT_Lower(MTH_TT_SCORPOK_NPC_NAME)
|
||||
end
|
||||
end
|
||||
if not isTargetNpc then
|
||||
return false
|
||||
end
|
||||
|
||||
local pincer = MTH_TT_GetBagItemCount(MTH_TT_ITEM_SCORPOK_PINCER_ID)
|
||||
local gizzard = MTH_TT_GetBagItemCount(MTH_TT_ITEM_VULTURE_GIZZARD_ID)
|
||||
local lung = MTH_TT_GetBagItemCount(MTH_TT_ITEM_BLASTED_BOAR_LUNG_ID)
|
||||
local assayInBag = MTH_TT_GetBagItemCount(MTH_TT_ITEM_GROUND_SCORPOK_ASSAY_ID)
|
||||
local assaysToGet = math.floor(math.min((pincer / 3), (gizzard / 2), lung))
|
||||
|
||||
GameTooltip:AddLine(" ")
|
||||
GameTooltip:AddLine("|cffffff00MTH Auto Quest|r")
|
||||
GameTooltip:AddLine(" - Scorpok Pincer - " .. MTH_TT_ColorCountByThreshold(pincer, 3), 1, 1, 1)
|
||||
GameTooltip:AddLine(" - Vulture Gizzard - " .. MTH_TT_ColorCountByThreshold(gizzard, 2), 1, 1, 1)
|
||||
GameTooltip:AddLine(" - Blasted Boar Lung - " .. MTH_TT_ColorCountByThreshold(lung, 1), 1, 1, 1)
|
||||
local assaysToGetText = "|cff73bfff" .. tostring(assaysToGet) .. "|r"
|
||||
GameTooltip:AddLine(
|
||||
"Assays to get : " .. assaysToGetText .. " | Assays in bag : " .. MTH_TT_ColorAssayCount(assayInBag),
|
||||
1, 1, 1
|
||||
)
|
||||
if isDrazial then
|
||||
GameTooltip:AddLine("Spam SHIFT-click!", 0.7, 0.9, 1)
|
||||
end
|
||||
GameTooltip:AddLine("Recipes: 3x Pincer, 2x Gizzard, 1x Lung", 0.7, 0.7, 0.7)
|
||||
return true
|
||||
end
|
||||
|
||||
local function MTH_TT_AddOwnPetTooltipHint()
|
||||
if not (MTH_Tooltips and MTH_Tooltips.enabled) then
|
||||
return
|
||||
@@ -845,7 +1098,37 @@ local function MTH_TT_FindAbilityCanonicalName(abilityName)
|
||||
return nil
|
||||
end
|
||||
|
||||
local function MTH_TT_ParseRankFromText(value)
|
||||
local function MTH_TT_AbilityHasPositiveRanks(canonicalAbilityName)
|
||||
if canonicalAbilityName == nil or canonicalAbilityName == "" then
|
||||
return false
|
||||
end
|
||||
if not (MTH_DS_PetSpells and type(MTH_DS_PetSpells.byAbility) == "table") then
|
||||
return false
|
||||
end
|
||||
|
||||
local bucket = MTH_DS_PetSpells.byAbility[canonicalAbilityName]
|
||||
if not (bucket and type(bucket.spells) == "table") then
|
||||
return false
|
||||
end
|
||||
|
||||
for i = 1, table.getn(bucket.spells) do
|
||||
local spell = bucket.spells[i]
|
||||
if spell then
|
||||
local rank = tonumber(spell.rankNumber)
|
||||
if not rank and spell.rank then
|
||||
local _, _, parsed = string.find(tostring(spell.rank), "(%d+)")
|
||||
rank = tonumber(parsed)
|
||||
end
|
||||
if rank and rank > 0 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function MTH_TT_ParseRankFromText(value, allowTrailingNumber)
|
||||
local text = MTH_TT_Trim(value)
|
||||
if text == "" then
|
||||
return nil
|
||||
@@ -854,9 +1137,11 @@ local function MTH_TT_ParseRankFromText(value)
|
||||
if rankText then
|
||||
return tonumber(rankText)
|
||||
end
|
||||
local _, _, trailing = string.find(text, "(%d+)$")
|
||||
if trailing then
|
||||
return tonumber(trailing)
|
||||
if allowTrailingNumber == true then
|
||||
local _, _, trailing = string.find(text, "(%d+)$")
|
||||
if trailing then
|
||||
return tonumber(trailing)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
@@ -884,10 +1169,10 @@ local function MTH_TT_GetTooltipSpellNameAndRank()
|
||||
if ok then
|
||||
if type(a) == "string" then
|
||||
spellName = a
|
||||
rankNumber = MTH_TT_ParseRankFromText(b)
|
||||
rankNumber = MTH_TT_ParseRankFromText(b, true)
|
||||
elseif type(b) == "string" then
|
||||
spellName = b
|
||||
rankNumber = MTH_TT_ParseRankFromText(a)
|
||||
rankNumber = MTH_TT_ParseRankFromText(a, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -899,24 +1184,28 @@ local function MTH_TT_GetTooltipSpellNameAndRank()
|
||||
end
|
||||
end
|
||||
|
||||
if not rankNumber then
|
||||
rankNumber = MTH_TT_ParseRankFromText(spellName, true)
|
||||
end
|
||||
|
||||
if not rankNumber then
|
||||
local right1 = getglobal("GameTooltipTextRight1")
|
||||
if right1 and right1.GetText then
|
||||
rankNumber = MTH_TT_ParseRankFromText(right1:GetText())
|
||||
rankNumber = MTH_TT_ParseRankFromText(right1:GetText(), false)
|
||||
end
|
||||
end
|
||||
|
||||
if not rankNumber then
|
||||
local left2 = getglobal("GameTooltipTextLeft2")
|
||||
if left2 and left2.GetText then
|
||||
rankNumber = MTH_TT_ParseRankFromText(left2:GetText())
|
||||
rankNumber = MTH_TT_ParseRankFromText(left2:GetText(), false)
|
||||
end
|
||||
end
|
||||
|
||||
if not rankNumber then
|
||||
local right2 = getglobal("GameTooltipTextRight2")
|
||||
if right2 and right2.GetText then
|
||||
rankNumber = MTH_TT_ParseRankFromText(right2:GetText())
|
||||
rankNumber = MTH_TT_ParseRankFromText(right2:GetText(), false)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -925,7 +1214,7 @@ local function MTH_TT_GetTooltipSpellNameAndRank()
|
||||
local left = getglobal("GameTooltipTextLeft" .. i)
|
||||
if left and left.GetText then
|
||||
local text = MTH_TT_Trim(left:GetText())
|
||||
local parsed = MTH_TT_ParseRankFromText(text)
|
||||
local parsed = MTH_TT_ParseRankFromText(text, false)
|
||||
if parsed and parsed > 0 then
|
||||
rankNumber = parsed
|
||||
break
|
||||
@@ -933,7 +1222,7 @@ local function MTH_TT_GetTooltipSpellNameAndRank()
|
||||
end
|
||||
local right = getglobal("GameTooltipTextRight" .. i)
|
||||
if right and right.GetText then
|
||||
local parsedRight = MTH_TT_ParseRankFromText(right:GetText())
|
||||
local parsedRight = MTH_TT_ParseRankFromText(right:GetText(), false)
|
||||
if parsedRight and parsedRight > 0 then
|
||||
rankNumber = parsedRight
|
||||
break
|
||||
@@ -945,6 +1234,87 @@ local function MTH_TT_GetTooltipSpellNameAndRank()
|
||||
return MTH_TT_CleanSpellName(spellName), rankNumber
|
||||
end
|
||||
|
||||
local function MTH_TT_GetCurrentPetRowForTooltip()
|
||||
local pets = nil
|
||||
if type(MTH_PETS_GetRootStore) == "function" then
|
||||
pets = MTH_PETS_GetRootStore()
|
||||
elseif type(MTH_CharSavedVariables) == "table" then
|
||||
pets = MTH_CharSavedVariables.MTH_Pets
|
||||
end
|
||||
if type(pets) ~= "table" then
|
||||
return nil
|
||||
end
|
||||
|
||||
local currentId = pets.currentPetId
|
||||
if (currentId == nil or tostring(currentId) == "") and type(pets.currentPet) == "table" and pets.currentPet.exists == true then
|
||||
currentId = pets.currentPet.id
|
||||
end
|
||||
if currentId == nil or tostring(currentId) == "" then
|
||||
return nil
|
||||
end
|
||||
|
||||
local activeById = type(pets.petStore) == "table" and pets.petStore.activeById or nil
|
||||
if type(activeById) ~= "table" then
|
||||
return nil
|
||||
end
|
||||
return activeById[currentId] or activeById[tostring(currentId)]
|
||||
end
|
||||
|
||||
local function MTH_TT_CurrentPetKnowsAbility(abilityLower, rankNumber)
|
||||
if abilityLower == "" then
|
||||
return false
|
||||
end
|
||||
local row = MTH_TT_GetCurrentPetRowForTooltip()
|
||||
if type(row) ~= "table" then
|
||||
return false
|
||||
end
|
||||
|
||||
local wantedRank = tonumber(rankNumber)
|
||||
|
||||
local spellbook = row.petSpellbook
|
||||
if type(spellbook) == "table" and type(spellbook.spells) == "table" then
|
||||
for i = 1, table.getn(spellbook.spells) do
|
||||
local spell = spellbook.spells[i]
|
||||
if type(spell) == "table" then
|
||||
local spellLower = MTH_TT_Lower(MTH_TT_CleanSpellName(spell.name))
|
||||
if spellLower == abilityLower then
|
||||
if wantedRank then
|
||||
local spellRank = tonumber(spell.rank)
|
||||
if not spellRank then
|
||||
spellRank = MTH_TT_ParseRankFromText(spell.name, true)
|
||||
end
|
||||
if spellRank and tonumber(spellRank) == wantedRank then
|
||||
return true
|
||||
end
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if type(row.abilities) == "table" then
|
||||
for _, ability in pairs(row.abilities) do
|
||||
if type(ability) == "table" then
|
||||
local abilityLowerName = MTH_TT_Lower(MTH_TT_CleanSpellName(ability.name))
|
||||
if abilityLowerName == abilityLower then
|
||||
if wantedRank then
|
||||
local abilityRank = tonumber(ability.rank)
|
||||
if abilityRank and abilityRank == wantedRank then
|
||||
return true
|
||||
end
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function MTH_TT_IsPetActionTooltipOwner()
|
||||
if not GameTooltip or type(GameTooltip.GetOwner) ~= "function" then
|
||||
return false
|
||||
@@ -1031,7 +1401,15 @@ local function MTH_TT_AddPetActionNotLearnedHint()
|
||||
return
|
||||
end
|
||||
|
||||
local known = MTH_TT_HunterKnowsAbility(MTH_TT_Lower(canonical), rankNumber)
|
||||
if rankNumber and rankNumber > 0 and not MTH_TT_AbilityHasPositiveRanks(canonical) then
|
||||
rankNumber = nil
|
||||
end
|
||||
|
||||
local canonicalLower = MTH_TT_Lower(canonical)
|
||||
local known = MTH_TT_HunterKnowsAbility(canonicalLower, rankNumber)
|
||||
if not known then
|
||||
known = MTH_TT_CurrentPetKnowsAbility(canonicalLower, rankNumber)
|
||||
end
|
||||
if known then
|
||||
return
|
||||
end
|
||||
@@ -1107,7 +1485,8 @@ local function MTH_TT_AddTooltip(unit)
|
||||
local ammoVendorTooltipsEnabled = MTH_TT_IsAmmoVendorTooltipsEnabled()
|
||||
local vendorInfo = ammoVendorTooltipsEnabled and MTH_TT_FindVendorInfo(name) or nil
|
||||
local row = beastTooltipsEnabled and MTH_TT_FindBeastRow(name) or nil
|
||||
if not row and not vendorInfo then
|
||||
local scorpokAdded = MTH_TT_AddScorpokTargetsTooltip(unit, name)
|
||||
if not row and not vendorInfo and not scorpokAdded then
|
||||
state.lookupMiss = (state.lookupMiss or 0) + 1
|
||||
MTH_TT_StateSet("lookup-miss", name, normalized)
|
||||
MTH_TT_Log("lookup miss: unit='" .. tostring(name) .. "' normalized='" .. tostring(normalized) .. "'")
|
||||
@@ -1115,6 +1494,9 @@ local function MTH_TT_AddTooltip(unit)
|
||||
end
|
||||
|
||||
local addedAnything = nil
|
||||
if scorpokAdded then
|
||||
addedAnything = 1
|
||||
end
|
||||
|
||||
if vendorInfo and (vendorInfo.arrows or vendorInfo.bullets) and not MTH_TT_HasExistingVendorTooltipLine() then
|
||||
if vendorInfo.arrows and vendorInfo.bullets then
|
||||
@@ -1163,18 +1545,22 @@ local function MTH_TT_EnsureInjectFrame()
|
||||
if MTH_Tooltips.injectFrame then
|
||||
return MTH_Tooltips.injectFrame
|
||||
end
|
||||
local frame = CreateFrame("Frame", "MTH_TooltipsInjectFrame")
|
||||
local frame = CreateFrame("Frame", "MTH_TooltipsInject")
|
||||
frame.pending = false
|
||||
frame:SetScript("OnUpdate", function(self)
|
||||
self = self or this
|
||||
if not self or not self.pending then
|
||||
frame.onUpdate = function()
|
||||
if not this then
|
||||
return
|
||||
end
|
||||
self.pending = false
|
||||
if not this.pending then
|
||||
this:SetScript("OnUpdate", nil)
|
||||
return
|
||||
end
|
||||
this.pending = false
|
||||
this:SetScript("OnUpdate", nil)
|
||||
if MTH_Tooltips and MTH_Tooltips.enabled then
|
||||
MTH_TT_AddTooltip("mouseover")
|
||||
end
|
||||
end)
|
||||
end
|
||||
MTH_Tooltips.injectFrame = frame
|
||||
return frame
|
||||
end
|
||||
@@ -1183,6 +1569,9 @@ local function MTH_TT_RequestInject()
|
||||
local frame = MTH_TT_EnsureInjectFrame()
|
||||
if frame then
|
||||
frame.pending = true
|
||||
if not frame:GetScript("OnUpdate") then
|
||||
frame:SetScript("OnUpdate", frame.onUpdate)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1191,20 +1580,23 @@ local function MTH_TT_EnsurePollFrame()
|
||||
return MTH_Tooltips.pollFrame
|
||||
end
|
||||
|
||||
local frame = CreateFrame("Frame", "MTH_TooltipsPollFrame")
|
||||
frame:SetScript("OnUpdate", function(_, elapsed)
|
||||
local frame = CreateFrame("Frame", "MTH_TooltipsPoll")
|
||||
frame:SetScript("OnUpdate", function()
|
||||
if not (MTH_Tooltips and MTH_Tooltips.enabled) then
|
||||
return
|
||||
end
|
||||
|
||||
if GameTooltip and GameTooltip.IsShown and GameTooltip:IsShown() then
|
||||
MTH_TT_AddOwnPetTooltipHint()
|
||||
if not MTH_TT_HasExistingNotLearnedLine() then
|
||||
MTH_TT_AddPetActionNotLearnedHint()
|
||||
MTH_Tooltips.hintElapsed = (MTH_Tooltips.hintElapsed or 0) + (arg1 or 0)
|
||||
if MTH_Tooltips.hintElapsed >= 0.25 then
|
||||
MTH_Tooltips.hintElapsed = 0
|
||||
if GameTooltip and GameTooltip.IsShown and GameTooltip:IsShown() then
|
||||
MTH_TT_AddOwnPetTooltipHint()
|
||||
if not MTH_TT_HasExistingNotLearnedLine() then
|
||||
MTH_TT_AddPetActionNotLearnedHint()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elapsed = elapsed or arg1
|
||||
MTH_Tooltips.pollElapsed = (MTH_Tooltips.pollElapsed or 0) + (elapsed or 0)
|
||||
if MTH_Tooltips.pollElapsed < 0.15 then
|
||||
return
|
||||
@@ -1242,6 +1634,74 @@ local function MTH_TT_EnsurePollFrame()
|
||||
return frame
|
||||
end
|
||||
|
||||
local function MTH_TT_SetRuntimeActive(active)
|
||||
local injectFrame = MTH_Tooltips.injectFrame
|
||||
if injectFrame then
|
||||
if not active then
|
||||
injectFrame.pending = false
|
||||
injectFrame:SetScript("OnUpdate", nil)
|
||||
end
|
||||
end
|
||||
|
||||
local pollFrame = MTH_Tooltips.pollFrame
|
||||
if pollFrame then
|
||||
if active then
|
||||
pollFrame:SetScript("OnUpdate", pollFrame:GetScript("OnUpdate") or function()
|
||||
if not (MTH_Tooltips and MTH_Tooltips.enabled) then
|
||||
return
|
||||
end
|
||||
|
||||
MTH_Tooltips.hintElapsed = (MTH_Tooltips.hintElapsed or 0) + (arg1 or 0)
|
||||
if MTH_Tooltips.hintElapsed >= 0.25 then
|
||||
MTH_Tooltips.hintElapsed = 0
|
||||
if GameTooltip and GameTooltip.IsShown and GameTooltip:IsShown() then
|
||||
MTH_TT_AddOwnPetTooltipHint()
|
||||
if not MTH_TT_HasExistingNotLearnedLine() then
|
||||
MTH_TT_AddPetActionNotLearnedHint()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MTH_Tooltips.pollElapsed = (MTH_Tooltips.pollElapsed or 0) + (elapsed or 0)
|
||||
if MTH_Tooltips.pollElapsed < 0.15 then
|
||||
return
|
||||
end
|
||||
MTH_Tooltips.pollElapsed = 0
|
||||
|
||||
local state = MTH_Tooltips.debugState
|
||||
state.pollTicks = (state.pollTicks or 0) + 1
|
||||
|
||||
if not UnitExists("mouseover") then
|
||||
MTH_Tooltips.lastMouseoverKey = ""
|
||||
return
|
||||
end
|
||||
|
||||
local name = UnitName("mouseover")
|
||||
if not name or name == "" then
|
||||
return
|
||||
end
|
||||
local lvl = UnitLevel and UnitLevel("mouseover") or 0
|
||||
local key = tostring(name) .. "#" .. tostring(lvl)
|
||||
|
||||
if key ~= MTH_Tooltips.lastMouseoverKey then
|
||||
MTH_Tooltips.lastMouseoverKey = key
|
||||
state.pollTriggers = (state.pollTriggers or 0) + 1
|
||||
MTH_TT_RequestInject()
|
||||
return
|
||||
end
|
||||
|
||||
if not MTH_TT_HasExistingTooltipLine() then
|
||||
MTH_TT_RequestInject()
|
||||
end
|
||||
end)
|
||||
else
|
||||
MTH_Tooltips.pollElapsed = 0
|
||||
MTH_Tooltips.hintElapsed = 0
|
||||
pollFrame:SetScript("OnUpdate", nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function MTH_TT_InstallTooltipHook()
|
||||
if MTH_Tooltips.hookInstalled then
|
||||
return
|
||||
@@ -1260,9 +1720,15 @@ local function MTH_TT_InstallTooltipHook()
|
||||
MTH_TT_RequestInject()
|
||||
end)
|
||||
GameTooltip:HookScript("OnTooltipSetItem", function()
|
||||
if not (MTH_Tooltips and MTH_Tooltips.enabled) then
|
||||
return
|
||||
end
|
||||
MTH_TT_AddFoodTooltipHint()
|
||||
end)
|
||||
GameTooltip:HookScript("OnTooltipSetSpell", function()
|
||||
if not (MTH_Tooltips and MTH_Tooltips.enabled) then
|
||||
return
|
||||
end
|
||||
MTH_TT_AddPetActionNotLearnedHint()
|
||||
end)
|
||||
end)
|
||||
@@ -1284,6 +1750,7 @@ function MTH_Tooltips:init()
|
||||
MTH_TT_InstallTooltipHook()
|
||||
MTH_TT_EnsureInjectFrame()
|
||||
MTH_TT_EnsurePollFrame()
|
||||
MTH_TT_SetRuntimeActive(self.enabled)
|
||||
MTH_TT_Log("module init complete")
|
||||
end
|
||||
|
||||
@@ -1307,6 +1774,9 @@ function MTH_Tooltips:setEnabled(enabled)
|
||||
elseif self.enabled then
|
||||
MTH_TT_EnsurePollFrame()
|
||||
MTH_TT_EnsureInjectFrame()
|
||||
MTH_TT_SetRuntimeActive(true)
|
||||
else
|
||||
MTH_TT_SetRuntimeActive(false)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1357,6 +1827,7 @@ end
|
||||
|
||||
function MTH_Tooltips:cleanup()
|
||||
self.enabled = false
|
||||
MTH_TT_SetRuntimeActive(false)
|
||||
end
|
||||
|
||||
function MTH_Tooltips:GetDebugSnapshot()
|
||||
|
||||
+217
-149
@@ -1,149 +1,217 @@
|
||||
if not ZHunterMod_Saved then
|
||||
ZHunterMod_Saved = {}
|
||||
end
|
||||
|
||||
BINDING_HEADER_ZAspectHeader = "ZAspect Buttons"
|
||||
BINDING_HEADER_ZTrackHeader = "ZTrack Buttons"
|
||||
BINDING_HEADER_ZTrapHeader = "ZTrap Buttons"
|
||||
BINDING_HEADER_ZPetHeader = "ZPet Buttons"
|
||||
BINDING_HEADER_ZAmmoHeader = "ZAmmo Buttons"
|
||||
BINDING_HEADER_ZMountsHeader = "ZMounts Buttons"
|
||||
BINDING_HEADER_ZCompanionsHeader = "ZCompanions Buttons"
|
||||
BINDING_HEADER_ZToysHeader = "ZToys Buttons"
|
||||
|
||||
ZHunterModTooltip = CreateFrame("GameTooltip", "ZHunterModTooltip", nil, "GameTooltipTemplate")
|
||||
|
||||
function MTH_ZH_IsModuleEnabled()
|
||||
if not (MTH and MTH.IsModuleEnabled) then
|
||||
return true
|
||||
end
|
||||
return MTH:IsModuleEnabled("zhunter", true)
|
||||
end
|
||||
|
||||
function MTH_ZH_GetSavedRoot()
|
||||
if type(ZHunterMod_Saved) ~= "table" then
|
||||
ZHunterMod_Saved = {}
|
||||
end
|
||||
return ZHunterMod_Saved
|
||||
end
|
||||
|
||||
function MTH_ZH_GetSavedTable(key)
|
||||
local root = MTH_ZH_GetSavedRoot()
|
||||
if type(key) ~= "string" or key == "" then
|
||||
return root
|
||||
end
|
||||
if type(root[key]) ~= "table" then
|
||||
root[key] = {}
|
||||
end
|
||||
return root[key]
|
||||
end
|
||||
|
||||
local function MTH_ZH_MigrateButtonSavedKeys_Replace()
|
||||
local root = MTH_ZH_GetSavedRoot()
|
||||
if type(root) ~= "table" then
|
||||
return
|
||||
end
|
||||
|
||||
local mapping = {
|
||||
{"ZHunterButtonAspect", "zButtonAspect"},
|
||||
{"ZHunterButtonTrack", "zButtonTrack"},
|
||||
{"ZHunterButtonTrap", "zButtonTrap"},
|
||||
{"ZHunterButtonAmmo", "zButtonAmmo"},
|
||||
{"ZHunterButtonPet", "zButtonPet"},
|
||||
{"ZHunterButtonMounts", "zButtonMounts"},
|
||||
{"ZHunterButtonCompanions", "zButtonCompanions"},
|
||||
{"ZHunterButtonToys", "zButtonToys"},
|
||||
}
|
||||
|
||||
for i = 1, table.getn(mapping) do
|
||||
local oldKey = mapping[i][1]
|
||||
local newKey = mapping[i][2]
|
||||
if root[oldKey] ~= nil then
|
||||
root[newKey] = root[oldKey]
|
||||
root[oldKey] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MTH_ZH_MigrateButtonSavedKeys_Replace()
|
||||
|
||||
function MTH_ZH_Print(message, severity)
|
||||
if type(MTH_Log) == "function" then
|
||||
MTH_Log(message, severity)
|
||||
return
|
||||
end
|
||||
if MTH and MTH.Print then
|
||||
MTH:Print(message, severity)
|
||||
return
|
||||
end
|
||||
if DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.AddMessage then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("[MetaHunt] " .. tostring(message or ""), 1, 0.9, 0.3)
|
||||
end
|
||||
end
|
||||
|
||||
function MTH_ZH_HandleDisabledSlash(message, tableKey, fieldKey)
|
||||
if MTH_ZH_IsModuleEnabled() then
|
||||
return false
|
||||
end
|
||||
|
||||
if type(tableKey) == "string" and tableKey ~= "" then
|
||||
if fieldKey then
|
||||
local tbl = MTH_ZH_GetSavedTable(tableKey)
|
||||
tbl[fieldKey] = nil
|
||||
else
|
||||
local root = MTH_ZH_GetSavedRoot()
|
||||
root[tableKey] = nil
|
||||
end
|
||||
end
|
||||
|
||||
if message then
|
||||
MTH_ZH_Print(message)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function ZHunterMod_AlignButtons()
|
||||
zButtonAmmo:ClearAllPoints()
|
||||
zButtonAmmo:SetPoint("TOP", zButtonAspect, "BOTTOM", 0, -15)
|
||||
zButtonTrack:ClearAllPoints()
|
||||
zButtonTrack:SetPoint("TOP", zButtonAmmo, "BOTTOM", 0, -15)
|
||||
zButtonTrap:ClearAllPoints()
|
||||
zButtonTrap:SetPoint("TOP", zButtonTrack, "BOTTOM", 0, -15)
|
||||
zButtonPet:ClearAllPoints()
|
||||
zButtonPet:SetPoint("TOP", zButtonTrap, "BOTTOM", 0, -15)
|
||||
zButtonMounts:ClearAllPoints()
|
||||
zButtonMounts:SetPoint("TOP", zButtonPet, "BOTTOM", 0, -15)
|
||||
zButtonCompanions:ClearAllPoints()
|
||||
zButtonCompanions:SetPoint("TOP", zButtonMounts, "BOTTOM", 0, -15)
|
||||
zButtonToys:ClearAllPoints()
|
||||
zButtonToys:SetPoint("TOP", zButtonCompanions, "BOTTOM", 0, -15)
|
||||
if AutoStripDisplay then
|
||||
AutoStripDisplay:ClearAllPoints()
|
||||
AutoStripDisplay:SetPoint("TOP", zButtonToys, "BOTTOM", 0, -10)
|
||||
end
|
||||
end
|
||||
|
||||
function ZMarkTarget()
|
||||
if not MTH_ZH_IsModuleEnabled() then
|
||||
return
|
||||
end
|
||||
|
||||
if not UnitExists("target") then return end
|
||||
for i=1, 40 do
|
||||
if not UnitDebuff("target", i) then break end
|
||||
ZHunterModTooltip:SetOwner(UIParent, "ANCHOR_NONE")
|
||||
ZHunterModTooltip:SetUnitDebuff("target", i)
|
||||
local spell = ZHunterModTooltipTextLeft1:GetText()
|
||||
if spell == ZHUNTER_HUNTERSMARK then
|
||||
return
|
||||
end
|
||||
end
|
||||
CastSpellByName(ZHUNTER_HUNTERSMARK)
|
||||
return 1
|
||||
end
|
||||
|
||||
SLASH_ZHunterMod1 = "/zhunter"
|
||||
SlashCmdList["ZHunterMod"] = function(msg)
|
||||
MTH_ZH_Print("Possible Slash Commands: \"/zammo\", \"/zaspect\", \"/ztrack\", \"/ztrap\", \"/zpet\", \"/zmounts\", \"/zcompanions\", \"/zminipets\", \"/ztoys\", \"/zstrip\", \"/zantidaze\"")
|
||||
end
|
||||
if not ZHunterMod_Saved then
|
||||
ZHunterMod_Saved = {}
|
||||
end
|
||||
|
||||
BINDING_HEADER_ZAspectHeader = "ZAspect Buttons"
|
||||
BINDING_HEADER_ZTrackHeader = "ZTrack Buttons"
|
||||
BINDING_HEADER_ZTrapHeader = "ZTrap Buttons"
|
||||
BINDING_HEADER_ZPetHeader = "ZPet Buttons"
|
||||
BINDING_HEADER_ZAmmoHeader = "ZAmmo Buttons"
|
||||
BINDING_HEADER_ZMountsHeader = "ZMounts Buttons"
|
||||
BINDING_HEADER_ZCompanionsHeader = "ZCompanions Buttons"
|
||||
BINDING_HEADER_ZToysHeader = "ZToys Buttons"
|
||||
|
||||
ZHunterModTooltip = CreateFrame("GameTooltip", "MTH_ZH_AbilityProbe", nil, "GameTooltipTemplate")
|
||||
ZHunterModTooltipTextLeft1 = getglobal("MTH_ZH_AbilityProbeTextLeft1")
|
||||
|
||||
MTH_ZH_TRACE_ENABLED = false
|
||||
|
||||
local function MTH_ZH_DescribePoint(frame)
|
||||
if not (frame and frame.GetPoint) then
|
||||
return "<no-frame>"
|
||||
end
|
||||
local point, relTo, relPoint, x, y = frame:GetPoint()
|
||||
local relName = "nil"
|
||||
if type(relTo) == "table" and relTo.GetName then
|
||||
relName = tostring(relTo:GetName() or "<anon>")
|
||||
elseif relTo then
|
||||
relName = tostring(relTo)
|
||||
end
|
||||
return tostring(point or "nil")
|
||||
.. "->" .. relName
|
||||
.. ":" .. tostring(relPoint or "nil")
|
||||
.. " @(" .. tostring(x) .. "," .. tostring(y) .. ")"
|
||||
end
|
||||
|
||||
function MTH_ZH_Trace(msg)
|
||||
if not MTH_ZH_TRACE_ENABLED then
|
||||
return
|
||||
end
|
||||
if MTH and MTH.Print then
|
||||
MTH:Print("[ZHTRACE] " .. tostring(msg), "debug")
|
||||
elseif DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.AddMessage then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("[ZHTRACE] " .. tostring(msg))
|
||||
end
|
||||
end
|
||||
|
||||
function MTH_ZH_TraceButtonPoint(frame, reason)
|
||||
if not MTH_ZH_TRACE_ENABLED then
|
||||
return
|
||||
end
|
||||
if not frame then
|
||||
MTH_ZH_Trace("point " .. tostring(reason or "") .. " frame=nil")
|
||||
return
|
||||
end
|
||||
local name = frame.GetName and frame:GetName() or "<unnamed>"
|
||||
MTH_ZH_Trace("point " .. tostring(reason or "") .. " " .. tostring(name) .. " " .. MTH_ZH_DescribePoint(frame))
|
||||
end
|
||||
|
||||
function MTH_ZH_TraceAllButtonPoints(reason)
|
||||
if not MTH_ZH_TRACE_ENABLED then
|
||||
return
|
||||
end
|
||||
local names = {
|
||||
"zButtonAspect",
|
||||
"zButtonAmmo",
|
||||
"zButtonTrack",
|
||||
"zButtonTrap",
|
||||
"zButtonRanged",
|
||||
"zButtonPet",
|
||||
"zButtonMounts",
|
||||
"zButtonCompanions",
|
||||
"zButtonToys",
|
||||
}
|
||||
MTH_ZH_Trace("snapshot begin reason=" .. tostring(reason or ""))
|
||||
for i = 1, table.getn(names) do
|
||||
local frame = getglobal(names[i])
|
||||
MTH_ZH_TraceButtonPoint(frame, tostring(reason or "") .. ":" .. tostring(names[i]))
|
||||
end
|
||||
MTH_ZH_Trace("snapshot end reason=" .. tostring(reason or ""))
|
||||
end
|
||||
|
||||
function MTH_ZH_IsModuleEnabled()
|
||||
if not (MTH and MTH.IsModuleEnabled) then
|
||||
return true
|
||||
end
|
||||
return MTH:IsModuleEnabled("zhunter", true)
|
||||
end
|
||||
|
||||
function MTH_ZH_GetSavedRoot()
|
||||
if type(ZHunterMod_Saved) ~= "table" then
|
||||
ZHunterMod_Saved = {}
|
||||
end
|
||||
return ZHunterMod_Saved
|
||||
end
|
||||
|
||||
function MTH_ZH_GetSavedTable(key)
|
||||
local root = MTH_ZH_GetSavedRoot()
|
||||
if type(key) ~= "string" or key == "" then
|
||||
return root
|
||||
end
|
||||
if type(root[key]) ~= "table" then
|
||||
root[key] = {}
|
||||
end
|
||||
return root[key]
|
||||
end
|
||||
|
||||
local function MTH_ZH_MigrateButtonSavedKeys_Replace()
|
||||
local root = MTH_ZH_GetSavedRoot()
|
||||
if type(root) ~= "table" then
|
||||
return
|
||||
end
|
||||
|
||||
local mapping = {
|
||||
{"ZHunterButtonAspect", "zButtonAspect"},
|
||||
{"ZHunterButtonTrack", "zButtonTrack"},
|
||||
{"ZHunterButtonTrap", "zButtonTrap"},
|
||||
{"ZHunterButtonAmmo", "zButtonAmmo"},
|
||||
{"ZHunterButtonPet", "zButtonPet"},
|
||||
{"ZHunterButtonMounts", "zButtonMounts"},
|
||||
{"ZHunterButtonCompanions", "zButtonCompanions"},
|
||||
{"ZHunterButtonToys", "zButtonToys"},
|
||||
}
|
||||
|
||||
for i = 1, table.getn(mapping) do
|
||||
local oldKey = mapping[i][1]
|
||||
local newKey = mapping[i][2]
|
||||
if root[oldKey] ~= nil then
|
||||
root[newKey] = root[oldKey]
|
||||
root[oldKey] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MTH_ZH_MigrateButtonSavedKeys_Replace()
|
||||
|
||||
function MTH_ZH_Print(message, severity)
|
||||
if type(MTH_Log) == "function" then
|
||||
MTH_Log(message, severity)
|
||||
return
|
||||
end
|
||||
if MTH and MTH.Print then
|
||||
MTH:Print(message, severity)
|
||||
return
|
||||
end
|
||||
if DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.AddMessage then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("[MetaHunt] " .. tostring(message or ""), 1, 0.9, 0.3)
|
||||
end
|
||||
end
|
||||
|
||||
function MTH_ZH_HandleDisabledSlash(message, tableKey, fieldKey)
|
||||
if MTH_ZH_IsModuleEnabled() then
|
||||
return false
|
||||
end
|
||||
|
||||
if type(tableKey) == "string" and tableKey ~= "" then
|
||||
if fieldKey then
|
||||
local tbl = MTH_ZH_GetSavedTable(tableKey)
|
||||
tbl[fieldKey] = nil
|
||||
else
|
||||
local root = MTH_ZH_GetSavedRoot()
|
||||
root[tableKey] = nil
|
||||
end
|
||||
end
|
||||
|
||||
if message then
|
||||
MTH_ZH_Print(message)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function ZHunterMod_AlignButtons()
|
||||
MTH_ZH_TraceAllButtonPoints("AlignButtons:before")
|
||||
zButtonAmmo:ClearAllPoints()
|
||||
zButtonAmmo:SetPoint("TOP", zButtonAspect, "BOTTOM", 0, -15)
|
||||
zButtonTrack:ClearAllPoints()
|
||||
zButtonTrack:SetPoint("TOP", zButtonAmmo, "BOTTOM", 0, -15)
|
||||
zButtonTrap:ClearAllPoints()
|
||||
zButtonTrap:SetPoint("TOP", zButtonTrack, "BOTTOM", 0, -15)
|
||||
zButtonPet:ClearAllPoints()
|
||||
zButtonPet:SetPoint("TOP", zButtonTrap, "BOTTOM", 0, -15)
|
||||
zButtonMounts:ClearAllPoints()
|
||||
zButtonMounts:SetPoint("TOP", zButtonPet, "BOTTOM", 0, -15)
|
||||
zButtonCompanions:ClearAllPoints()
|
||||
zButtonCompanions:SetPoint("TOP", zButtonMounts, "BOTTOM", 0, -15)
|
||||
zButtonToys:ClearAllPoints()
|
||||
zButtonToys:SetPoint("TOP", zButtonCompanions, "BOTTOM", 0, -15)
|
||||
if AutoStripDisplay then
|
||||
AutoStripDisplay:ClearAllPoints()
|
||||
AutoStripDisplay:SetPoint("TOP", zButtonToys, "BOTTOM", 0, -10)
|
||||
end
|
||||
MTH_ZH_TraceAllButtonPoints("AlignButtons:after")
|
||||
end
|
||||
|
||||
function ZMarkTarget()
|
||||
if not MTH_ZH_IsModuleEnabled() then
|
||||
return
|
||||
end
|
||||
|
||||
if not UnitExists("target") then return end
|
||||
for i=1, 40 do
|
||||
if not UnitDebuff("target", i) then break end
|
||||
ZHunterModTooltip:SetOwner(UIParent, "ANCHOR_NONE")
|
||||
ZHunterModTooltip:SetUnitDebuff("target", i)
|
||||
local spell = ZHunterModTooltipTextLeft1:GetText()
|
||||
if spell == ZHUNTER_HUNTERSMARK then
|
||||
return
|
||||
end
|
||||
end
|
||||
CastSpellByName(ZHUNTER_HUNTERSMARK)
|
||||
return 1
|
||||
end
|
||||
|
||||
SLASH_ZHunterMod1 = "/zhunter"
|
||||
SlashCmdList["ZHunterMod"] = function(msg)
|
||||
MTH_ZH_Print("Possible Slash Commands: \"/zammo\", \"/zaspect\", \"/ztrack\", \"/ztrap\", \"/zpet\", \"/zmounts\", \"/zcompanions\", \"/zminipets\", \"/ztoys\", \"/zstrip\", \"/zantidaze\"")
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+114
-12
@@ -8,10 +8,10 @@ MTH_ZH_MANAGED_HOOKS = true
|
||||
local MTH_ZHunter = {
|
||||
name = "zhunter",
|
||||
enabled = true,
|
||||
version = "1.0.4",
|
||||
version = "1.2.0",
|
||||
events = {
|
||||
"VARIABLES_LOADED",
|
||||
"PLAYER_ENTERING_WORLD",
|
||||
-- PLAYER_ENTERING_WORLD handled by bootstrap frame + adjustment frames
|
||||
"MTH_PET_LIVE_STATE_CHANGED",
|
||||
},
|
||||
features = {
|
||||
@@ -31,7 +31,13 @@ local function MTH_ZH_Log(msg)
|
||||
MTH:Print("[ZH MODULE] " .. tostring(msg), "debug")
|
||||
end
|
||||
|
||||
local MTH_ZH_PostLoginRestoreFrame = nil
|
||||
local function MTH_ZH_TraceLocal(msg)
|
||||
if type(MTH_ZH_Trace) == "function" then
|
||||
MTH_ZH_Trace(msg)
|
||||
end
|
||||
end
|
||||
|
||||
local MTH_ZH_PostLoginRestore = nil
|
||||
local MTH_ZH_BootstrapFrame = nil
|
||||
local MTH_ZH_SyncSavedVariables
|
||||
local MTH_ZH_SetButtonsVisible
|
||||
@@ -105,21 +111,20 @@ function MTH_ZH_OnDeferredInitComplete()
|
||||
return
|
||||
end
|
||||
MTH_ZH_SyncSavedVariables()
|
||||
MTH_ZH_ApplyDefaultWidgetSpawnLayoutOnce()
|
||||
MTH_ZH_RestoreRuntimeFeatureFlags()
|
||||
MTH_ZH_QueuePostLoginRestore("deferred-init")
|
||||
end
|
||||
|
||||
MTH_ZH_QueuePostLoginRestore = function(tag)
|
||||
if not MTH_ZH_PostLoginRestoreFrame then
|
||||
MTH_ZH_PostLoginRestoreFrame = CreateFrame("Frame", "MTH_ZH_PostLoginRestoreFrame")
|
||||
if not MTH_ZH_PostLoginRestoreFrame then
|
||||
if not MTH_ZH_PostLoginRestore then
|
||||
MTH_ZH_PostLoginRestore = CreateFrame("Frame", "MTH_ZH_PostLoginRestore")
|
||||
if not MTH_ZH_PostLoginRestore then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
MTH_ZH_PostLoginRestoreFrame._mthElapsed = 0
|
||||
MTH_ZH_PostLoginRestoreFrame:SetScript("OnUpdate", function()
|
||||
MTH_ZH_PostLoginRestore._mthElapsed = 0
|
||||
MTH_ZH_PostLoginRestore:SetScript("OnUpdate", function()
|
||||
this._mthElapsed = (this._mthElapsed or 0) + (arg1 or 0)
|
||||
if this._mthElapsed < 0.2 then
|
||||
return
|
||||
@@ -132,6 +137,9 @@ MTH_ZH_QueuePostLoginRestore = function(tag)
|
||||
|
||||
MTH_ZH_SyncSavedVariables()
|
||||
MTH_ZH_RestoreRuntimeFeatureFlags()
|
||||
if type(MTH_ZH_TraceAllButtonPoints) == "function" then
|
||||
MTH_ZH_TraceAllButtonPoints("post-login-restore:" .. tostring(tag))
|
||||
end
|
||||
MTH_ZH_Log("post-login restore applied: " .. tostring(tag))
|
||||
end)
|
||||
end
|
||||
@@ -141,7 +149,7 @@ local function MTH_ZH_EnsureBootstrapRestoreFrame()
|
||||
return MTH_ZH_BootstrapFrame
|
||||
end
|
||||
|
||||
MTH_ZH_BootstrapFrame = CreateFrame("Frame", "MTH_ZH_BootstrapRestoreFrame")
|
||||
MTH_ZH_BootstrapFrame = CreateFrame("Frame", "MTH_ZH_BootstrapRestore")
|
||||
if not MTH_ZH_BootstrapFrame then
|
||||
return nil
|
||||
end
|
||||
@@ -170,10 +178,17 @@ local function MTH_ZH_EnsureBootstrapRestoreFrame()
|
||||
end
|
||||
|
||||
MTH_ZH_ApplyEnabledRuntimeState = function(source)
|
||||
MTH_ZH_TraceLocal("apply-enabled-runtime-state source=" .. tostring(source or ""))
|
||||
if type(MTH_ZH_TraceAllButtonPoints) == "function" then
|
||||
MTH_ZH_TraceAllButtonPoints("apply-enabled:before:" .. tostring(source or ""))
|
||||
end
|
||||
MTH_ZH_SyncSavedVariables()
|
||||
MTH_ZH_SetButtonsVisible(true)
|
||||
MTH_ZH_SetAuxFramesVisible(true)
|
||||
MTH_ZH_RestoreRuntimeFeatureFlags()
|
||||
if type(MTH_ZH_TraceAllButtonPoints) == "function" then
|
||||
MTH_ZH_TraceAllButtonPoints("apply-enabled:after:" .. tostring(source or ""))
|
||||
end
|
||||
end
|
||||
|
||||
MTH_ZH_SyncSavedVariables = function()
|
||||
@@ -182,17 +197,22 @@ MTH_ZH_SyncSavedVariables = function()
|
||||
end
|
||||
|
||||
local moduleStore = MTH:GetModuleCharSavedVariables("zhunter")
|
||||
MTH_ZH_TraceLocal("sync-saved begin zhuntermod_saved=" .. tostring(type(ZHunterMod_Saved)))
|
||||
|
||||
if type(ZHunterMod_Saved) == "table" then
|
||||
if MTH_CharSavedVariables and MTH_CharSavedVariables.modules then
|
||||
MTH_CharSavedVariables.modules.zhunter = ZHunterMod_Saved
|
||||
MTH_ZH_TraceLocal("sync-saved wrote ZHunterMod_Saved -> MTH_CharSavedVariables.modules.zhunter")
|
||||
end
|
||||
elseif type(moduleStore) == "table" then
|
||||
ZHunterMod_Saved = moduleStore
|
||||
MTH_ZH_TraceLocal("sync-saved loaded moduleStore -> ZHunterMod_Saved")
|
||||
end
|
||||
MTH_ZH_TraceLocal("sync-saved end")
|
||||
end
|
||||
|
||||
MTH_ZH_SetButtonsVisible = function(visible)
|
||||
MTH_ZH_TraceLocal("set-buttons-visible visible=" .. tostring(visible and true or false))
|
||||
local buttonNames = {
|
||||
"zButtonAspect",
|
||||
"zButtonTrack",
|
||||
@@ -274,12 +294,34 @@ MTH_ZH_SetButtonsVisible = function(visible)
|
||||
for _, buttonName in ipairs(buttonNames) do
|
||||
local button = getglobal(buttonName)
|
||||
if button then
|
||||
MTH_ZH_SetChildButtonsVisible(button, buttonName, visible)
|
||||
if type(MTH_ZH_TraceButtonPoint) == "function" then
|
||||
MTH_ZH_TraceButtonPoint(button, "set-buttons-visible:before:" .. tostring(buttonName))
|
||||
end
|
||||
if visible then
|
||||
button:Show()
|
||||
-- Respect per-button enabled state
|
||||
local getterName = buttonName .. "_GetSaved"
|
||||
local getter = getglobal(getterName)
|
||||
local shouldShow = true
|
||||
if type(getter) == "function" then
|
||||
local ok, saved = pcall(getter)
|
||||
if ok and type(saved) == "table" and (saved["enabled"] == false or saved["enabled"] == 0) then
|
||||
shouldShow = false
|
||||
end
|
||||
end
|
||||
if shouldShow then
|
||||
MTH_ZH_SetChildButtonsVisible(button, buttonName, true)
|
||||
button:Show()
|
||||
else
|
||||
MTH_ZH_SetChildButtonsVisible(button, buttonName, false)
|
||||
button:Hide()
|
||||
end
|
||||
else
|
||||
MTH_ZH_SetChildButtonsVisible(button, buttonName, false)
|
||||
button:Hide()
|
||||
end
|
||||
if type(MTH_ZH_TraceButtonPoint) == "function" then
|
||||
MTH_ZH_TraceButtonPoint(button, "set-buttons-visible:after:" .. tostring(buttonName))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -288,6 +330,57 @@ MTH_ZH_SetAuxFramesVisible = function(visible)
|
||||
return
|
||||
end
|
||||
|
||||
local function MTH_ZH_SetAdjustmentHandlersActive(active)
|
||||
local frameSpecs = {
|
||||
{ frame = "MTH_ZH_AspectAdjust", handler = "MTH_ZH_AspectAdjust_OnEvent", getter = "zButtonAspect_GetSaved" },
|
||||
{ frame = "MTH_ZH_TrackAdjust", handler = "MTH_ZH_TrackAdjust_OnEvent", getter = "zButtonTrack_GetSaved" },
|
||||
{ frame = "MTH_ZH_TrapAdjust", handler = "MTH_ZH_TrapAdjust_OnEvent", getter = "zButtonTrap_GetSaved" },
|
||||
{ frame = "MTH_ZH_RangedAdjust", handler = "MTH_ZH_RangedAdjust_OnEvent", getter = "zButtonRanged_GetSaved" },
|
||||
{ frame = "MTH_ZH_AmmoAdjust", handler = "MTH_ZH_AmmoAdjust_OnEvent", getter = "zButtonAmmo_GetSaved" },
|
||||
{ frame = "MTH_ZH_PetAdjust", handler = "MTH_ZH_PetAdjust_OnEvent", getter = "zButtonPet_GetSaved" },
|
||||
{ frame = "MTH_ZH_MountsAdjust", handler = "MTH_ZH_MountsAdjust_OnEvent", getter = "zButtonMounts_GetSaved" },
|
||||
{ frame = "MTH_ZH_CompanionsAdjust", handler = "MTH_ZH_CompanionsAdjust_OnEvent", getter = "zButtonCompanions_GetSaved" },
|
||||
{ frame = "MTH_ZH_ToysAdjust", handler = "MTH_ZH_ToysAdjust_OnEvent", getter = "zButtonToys_GetSaved" },
|
||||
}
|
||||
|
||||
local function isFeatureEnabled(getterName)
|
||||
local getter = getglobal(getterName)
|
||||
if type(getter) ~= "function" then
|
||||
return true
|
||||
end
|
||||
local ok, saved = pcall(getter)
|
||||
if not ok or type(saved) ~= "table" then
|
||||
return true
|
||||
end
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
for _, spec in ipairs(frameSpecs) do
|
||||
local frameName = spec.frame
|
||||
local handlerName = spec.handler
|
||||
local frame = getglobal(frameName)
|
||||
if frame and frame.SetScript then
|
||||
if active then
|
||||
if isFeatureEnabled(spec.getter) then
|
||||
local handler = getglobal(handlerName)
|
||||
if type(handler) == "function" then
|
||||
frame:SetScript("OnEvent", handler)
|
||||
else
|
||||
frame:SetScript("OnEvent", nil)
|
||||
end
|
||||
else
|
||||
frame:SetScript("OnEvent", nil)
|
||||
end
|
||||
else
|
||||
frame:SetScript("OnEvent", nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function MTH_ZH_ClearRuntimeFeatureFlags()
|
||||
return
|
||||
end
|
||||
@@ -307,14 +400,23 @@ function MTH_ZHunter:init()
|
||||
end
|
||||
|
||||
function MTH_ZHunter:setEnabled(enabled)
|
||||
MTH_ZH_TraceLocal("module setEnabled enabled=" .. tostring(enabled and true or false))
|
||||
MTH_ZH_SyncSavedVariables()
|
||||
if enabled then
|
||||
MTH_ZH_EnsureBootstrapRestoreFrame()
|
||||
MTH_ZH_SetAdjustmentHandlersActive(true)
|
||||
MTH_ZH_ApplyEnabledRuntimeState("setEnabled")
|
||||
else
|
||||
MTH_ZH_ClearRuntimeFeatureFlags()
|
||||
MTH_ZH_SetAdjustmentHandlersActive(false)
|
||||
if type(MTH_ZH_TraceAllButtonPoints) == "function" then
|
||||
MTH_ZH_TraceAllButtonPoints("setEnabled:false:before-hide")
|
||||
end
|
||||
MTH_ZH_SetButtonsVisible(false)
|
||||
MTH_ZH_SetAuxFramesVisible(false)
|
||||
if type(MTH_ZH_TraceAllButtonPoints) == "function" then
|
||||
MTH_ZH_TraceAllButtonPoints("setEnabled:false:after-hide")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
+1132
-927
File diff suppressed because it is too large
Load Diff
+392
-328
@@ -1,329 +1,393 @@
|
||||
local function zButtonAspect_GetRoot()
|
||||
return MTH_ZH_GetSavedRoot()
|
||||
end
|
||||
|
||||
local root = zButtonAspect_GetRoot()
|
||||
if not root["zButtonAspect"] then
|
||||
root["zButtonAspect"] = {}
|
||||
root["zButtonAspect"]["spells"] = {1, 2, 3, 4, 5, 6, 7}
|
||||
root["zButtonAspect"]["rows"] = 1
|
||||
root["zButtonAspect"]["horizontal"] = nil
|
||||
root["zButtonAspect"]["vertical"] = nil
|
||||
root["zButtonAspect"]["firstbutton"] = "RIGHT"
|
||||
root["zButtonAspect"]["enabled"] = 1
|
||||
root["zButtonAspect"]["tooltip"] = 1
|
||||
root["zButtonAspect"]["parent"] = {}
|
||||
root["zButtonAspect"]["parent"]["size"] = 36
|
||||
root["zButtonAspect"]["parent"]["hide"] = nil
|
||||
root["zButtonAspect"]["parent"]["circle"] = 1
|
||||
root["zButtonAspect"]["children"] = {}
|
||||
root["zButtonAspect"]["children"]["size"] = 36
|
||||
root["zButtonAspect"]["children"]["hideonclick"] = 1
|
||||
end
|
||||
|
||||
ZHunterMod_Aspect_Spells = {
|
||||
ZHUNTER_ASPECT_HAWK,
|
||||
ZHUNTER_ASPECT_MONKEY,
|
||||
ZHUNTER_ASPECT_WOLF,
|
||||
ZHUNTER_ASPECT_CHEETAH,
|
||||
ZHUNTER_ASPECT_PACK,
|
||||
ZHUNTER_ASPECT_WILD,
|
||||
ZHUNTER_ASPECT_BEAST
|
||||
}
|
||||
|
||||
local ZHUNTER_ASPECT_MAX = table.getn(ZHunterMod_Aspect_Spells)
|
||||
|
||||
local function zButtonAspect_GetSaved()
|
||||
local currentRoot = zButtonAspect_GetRoot()
|
||||
if not currentRoot["zButtonAspect"] then
|
||||
currentRoot["zButtonAspect"] = {}
|
||||
end
|
||||
return currentRoot["zButtonAspect"]
|
||||
end
|
||||
|
||||
local function zButtonAspect_EnsureConfig()
|
||||
local saved = zButtonAspect_GetSaved()
|
||||
saved["count"] = nil
|
||||
if saved["rows"] == nil then
|
||||
saved["rows"] = 1
|
||||
end
|
||||
if saved["firstbutton"] == nil then
|
||||
saved["firstbutton"] = "RIGHT"
|
||||
end
|
||||
if saved["enabled"] == nil then
|
||||
saved["enabled"] = 1
|
||||
end
|
||||
if saved["tooltip"] == nil then
|
||||
saved["tooltip"] = 1
|
||||
end
|
||||
if not saved["parent"] then
|
||||
saved["parent"] = {}
|
||||
end
|
||||
if saved["parent"]["size"] == nil then
|
||||
saved["parent"]["size"] = 36
|
||||
end
|
||||
if saved["parent"]["circle"] == nil then
|
||||
saved["parent"]["circle"] = 1
|
||||
end
|
||||
if not saved["children"] then
|
||||
saved["children"] = {}
|
||||
end
|
||||
if saved["children"]["size"] == nil then
|
||||
saved["children"]["size"] = 36
|
||||
end
|
||||
if saved["children"]["hideonclick"] == nil then
|
||||
saved["children"]["hideonclick"] = 1
|
||||
end
|
||||
if not saved["spells"] then
|
||||
saved["spells"] = {}
|
||||
end
|
||||
if not saved["visible"] then
|
||||
saved["visible"] = {}
|
||||
end
|
||||
for i = 1, ZHUNTER_ASPECT_MAX do
|
||||
if not tonumber(saved["spells"][i]) then
|
||||
saved["spells"][i] = i
|
||||
end
|
||||
if saved["visible"][i] == nil then
|
||||
saved["visible"][i] = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function zButtonAspect_ApplyRuntimeSettings()
|
||||
if not zButtonAspect then
|
||||
return
|
||||
end
|
||||
local saved = zButtonAspect_GetSaved()
|
||||
zButtonAspect.tooltip = saved["tooltip"] and true or false
|
||||
zButtonAspect.hideonclick = saved["children"] and saved["children"]["hideonclick"] and true or false
|
||||
end
|
||||
|
||||
local function zButtonAspect_IsKnownAspectSpellId(spellId)
|
||||
if not spellId then
|
||||
return false
|
||||
end
|
||||
local spellName = GetSpellName(spellId, "spell")
|
||||
if not spellName or spellName == "" then
|
||||
return false
|
||||
end
|
||||
for i = 1, table.getn(ZHunterMod_Aspect_Spells) do
|
||||
if ZHunterMod_Aspect_Spells[i] == spellName then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function zButtonAspect_EnsureValidParentId()
|
||||
if not (zButtonAspect and zButtonAspect.count) then
|
||||
return
|
||||
end
|
||||
|
||||
if zButtonAspect_IsKnownAspectSpellId(zButtonAspect.id) then
|
||||
return
|
||||
end
|
||||
|
||||
for i = 1, zButtonAspect.count do
|
||||
local child = getglobal(zButtonAspect.name .. i)
|
||||
if child and child.id and zButtonAspect_IsKnownAspectSpellId(child.id) then
|
||||
zButtonAspect.id = child.id
|
||||
zButtonAspect.isspell = 1
|
||||
ZSpellButton_UpdateButton(zButtonAspect)
|
||||
ZSpellButton_UpdateCooldown(zButtonAspect)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonAspect_OnLoad()
|
||||
this:RegisterEvent("VARIABLES_LOADED")
|
||||
end
|
||||
|
||||
function zButtonAspect_OnEvent()
|
||||
if event == "VARIABLES_LOADED" then
|
||||
if not zButtonAspect then
|
||||
return
|
||||
end
|
||||
if UnitClass("player") ~= ZHUNTER_HUNTER then
|
||||
zButtonAspect:UnregisterAllEvents()
|
||||
zButtonAspect:Hide()
|
||||
return
|
||||
end
|
||||
zButtonAspect_CreateButtons()
|
||||
zButtonAspectAdjustment = CreateFrame("Frame", "zButtonAspectAdjustment")
|
||||
zButtonAspectAdjustment:RegisterEvent("PLAYER_AURAS_CHANGED")
|
||||
zButtonAspectAdjustment:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
zButtonAspectAdjustment:RegisterEvent("SPELLS_CHANGED")
|
||||
zButtonAspectAdjustment:RegisterEvent("CHARACTER_POINTS_CHANGED")
|
||||
zButtonAspectAdjustment:RegisterEvent("LEARNED_SPELL_IN_TAB")
|
||||
zButtonAspectAdjustment:SetScript("OnEvent", zButtonAspectAdjustment_OnEvent)
|
||||
zButtonAspect_Tooltip = CreateFrame("GameTooltip", "zButtonAspect_Tooltip", nil, "GameTooltipTemplate")
|
||||
zButtonAspect_SetupSizeAndPosition()
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonAspect_CreateButtons()
|
||||
zButtonAspect_EnsureConfig()
|
||||
local saved = zButtonAspect_GetSaved()
|
||||
|
||||
ZSpellButton_CreateChildren(zButtonAspect, "zButtonAspect", ZHUNTER_ASPECT_MAX)
|
||||
local info = {}
|
||||
local infoIndex = 1
|
||||
for i=1, table.getn(ZHunterMod_Aspect_Spells) do
|
||||
if not tonumber(saved["spells"][i]) then
|
||||
info = ZHunterMod_Aspect_Spells
|
||||
saved["spells"] = {1, 2, 3, 4, 5, 6, 7}
|
||||
break
|
||||
end
|
||||
local spellIndex = saved["spells"][i]
|
||||
if saved["visible"][spellIndex] ~= false then
|
||||
info[infoIndex] = ZHunterMod_Aspect_Spells[spellIndex]
|
||||
infoIndex = infoIndex + 1
|
||||
end
|
||||
end
|
||||
zButtonAspect.found = ZSpellButton_SetButtons(zButtonAspect, info)
|
||||
zButtonAspect_ApplyRuntimeSettings()
|
||||
zButtonAspect_EnsureValidParentId()
|
||||
end
|
||||
|
||||
function zButtonAspect_SetupSizeAndPosition()
|
||||
zButtonAspect_EnsureConfig()
|
||||
local saved = zButtonAspect_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if zButtonAspect and zButtonAspect.Hide then
|
||||
zButtonAspect:Hide()
|
||||
end
|
||||
return
|
||||
end
|
||||
local displayCount = zButtonAspect.found or ZHUNTER_ASPECT_MAX
|
||||
if displayCount < 0 then
|
||||
displayCount = 0
|
||||
end
|
||||
ZSpellButton_SetSize(zButtonAspect, saved["parent"]["size"])
|
||||
ZSpellButton_SetSize(zButtonAspect, saved["children"]["size"], 1)
|
||||
ZSpellButton_SetExpandDirection(zButtonAspect, saved["firstbutton"])
|
||||
ZSpellButton_ArrangeChildren(zButtonAspect, saved["rows"],
|
||||
displayCount, saved["horizontal"],
|
||||
saved["vertical"])
|
||||
end
|
||||
|
||||
function zButtonAspect_Reset()
|
||||
local currentRoot = zButtonAspect_GetRoot()
|
||||
currentRoot["zButtonAspect"] = {}
|
||||
local saved = zButtonAspect_GetSaved()
|
||||
saved["spells"] = {1, 2, 3, 4, 5, 6, 7}
|
||||
saved["rows"] = 1
|
||||
saved["horizontal"] = nil
|
||||
saved["vertical"] = nil
|
||||
saved["firstbutton"] = "RIGHT"
|
||||
saved["enabled"] = 1
|
||||
saved["tooltip"] = 1
|
||||
saved["parent"] = {}
|
||||
saved["parent"]["size"] = 36
|
||||
saved["parent"]["hide"] = nil
|
||||
saved["parent"]["circle"] = 1
|
||||
saved["children"] = {}
|
||||
saved["children"]["size"] = 36
|
||||
saved["children"]["hideonclick"] = 1
|
||||
saved["visible"] = {1, 1, 1, 1, 1, 1, 1}
|
||||
zButtonAspect_EnsureConfig()
|
||||
end
|
||||
|
||||
function zButtonAspectAdjustment_OnEvent()
|
||||
if not zButtonAspect or not zButtonAspect.count then
|
||||
return
|
||||
end
|
||||
if event == "SPELLS_CHANGED" or event == "CHARACTER_POINTS_CHANGED" or event == "LEARNED_SPELL_IN_TAB" then
|
||||
zButtonAspect_CreateButtons()
|
||||
zButtonAspect_SetupSizeAndPosition()
|
||||
zButtonAspect_EnsureValidParentId()
|
||||
end
|
||||
if event == "PLAYER_AURAS_CHANGED" or event == "PLAYER_ENTERING_WORLD"
|
||||
or event == "SPELLS_CHANGED" or event == "CHARACTER_POINTS_CHANGED" or event == "LEARNED_SPELL_IN_TAB" then
|
||||
zButtonAspect_EnsureValidParentId()
|
||||
if not zButtonAspect1.id then
|
||||
return
|
||||
end
|
||||
local buttontextures = {}
|
||||
local button
|
||||
for i=1, zButtonAspect.count do
|
||||
button = getglobal(zButtonAspect.name..i)
|
||||
button.icon = nil
|
||||
if button.id then
|
||||
buttontextures[GetSpellTexture(button.id, "spell")] = button
|
||||
end
|
||||
end
|
||||
local i = 1
|
||||
local texture = GetSpellTexture(zButtonAspect1.id, "spell")
|
||||
local buff = UnitBuff("player", i)
|
||||
local spellname, buffname
|
||||
zButtonAspect.id = zButtonAspect1.id
|
||||
while buff do
|
||||
if texture == buff and zButtonAspect2.id then
|
||||
zButtonAspect.id = zButtonAspect2.id
|
||||
end
|
||||
if buttontextures[buff] then
|
||||
zButtonAspect_Tooltip:SetOwner(this, "ANCHOR_NONE")
|
||||
zButtonAspect_Tooltip:SetUnitBuff("player", i)
|
||||
buffname = zButtonAspect_TooltipTextLeft1:GetText()
|
||||
spellname = GetSpellName(buttontextures[buff].id, "spell")
|
||||
if buffname == spellname then
|
||||
buttontextures[buff].icon = "Interface\\Icons\\Spell_Nature_WispSplode"
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
buff = UnitBuff("player", i)
|
||||
end
|
||||
ZSpellButton_UpdateButton(zButtonAspect)
|
||||
ZSpellButton_UpdateCooldown(zButtonAspect)
|
||||
for i=1, zButtonAspect.count do
|
||||
button = getglobal(zButtonAspect.name..i)
|
||||
if button.id then
|
||||
ZSpellButton_UpdateButton(button)
|
||||
end
|
||||
end
|
||||
if GameTooltip:IsOwned(zButtonAspect) then
|
||||
ZSpellButtonParent_OnEnter(zButtonAspect)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonAspect_KeyBinding(index)
|
||||
if MTH_ZH_IsModuleEnabled and not MTH_ZH_IsModuleEnabled() then
|
||||
return
|
||||
end
|
||||
|
||||
local button
|
||||
if index then
|
||||
button = getglobal("zButtonAspect"..index)
|
||||
else
|
||||
button = zButtonAspect
|
||||
end
|
||||
if button.id then
|
||||
CastSpell(button.id, "spell")
|
||||
if zButtonAspect.hideonclick then
|
||||
if type(ZSpellButton_SetChildrenExpanded) == "function" then
|
||||
ZSpellButton_SetChildrenExpanded(zButtonAspect, false)
|
||||
elseif zButtonAspect.children then
|
||||
zButtonAspect.children:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SLASH_zButtonAspect1 = "/ZAspect"
|
||||
SlashCmdList["zButtonAspect"] = function(msg)
|
||||
if MTH_ZH_HandleDisabledSlash and MTH_ZH_HandleDisabledSlash("Aspect button is disabled while module 'zhunter' is disabled.") then
|
||||
return
|
||||
end
|
||||
if msg == "reset" then
|
||||
zButtonAspect_Reset()
|
||||
zButtonAspect:ClearAllPoints()
|
||||
zButtonAspect:SetPoint("CENTER", UIParent, "CENTER", -60, 0)
|
||||
elseif msg == "options" then
|
||||
MTH_OpenOptions("Aspect")
|
||||
else
|
||||
MTH_ZH_Print("Possible Commands: \"options\", \"reset\"")
|
||||
end
|
||||
local function zButtonAspect_GetRoot()
|
||||
return MTH_ZH_GetSavedRoot()
|
||||
end
|
||||
|
||||
local root = zButtonAspect_GetRoot()
|
||||
if not root["zButtonAspect"] then
|
||||
root["zButtonAspect"] = {}
|
||||
root["zButtonAspect"]["spells"] = {1, 2, 3, 4, 5, 6, 7}
|
||||
root["zButtonAspect"]["rows"] = 1
|
||||
root["zButtonAspect"]["horizontal"] = nil
|
||||
root["zButtonAspect"]["vertical"] = nil
|
||||
root["zButtonAspect"]["firstbutton"] = "RIGHT"
|
||||
root["zButtonAspect"]["enabled"] = 1
|
||||
root["zButtonAspect"]["tooltip"] = 1
|
||||
root["zButtonAspect"]["parent"] = {}
|
||||
root["zButtonAspect"]["parent"]["size"] = 36
|
||||
root["zButtonAspect"]["parent"]["hide"] = nil
|
||||
root["zButtonAspect"]["parent"]["circle"] = 1
|
||||
root["zButtonAspect"]["children"] = {}
|
||||
root["zButtonAspect"]["children"]["size"] = 36
|
||||
root["zButtonAspect"]["children"]["hideonclick"] = 1
|
||||
end
|
||||
|
||||
ZHunterMod_Aspect_Spells = {
|
||||
ZHUNTER_ASPECT_HAWK,
|
||||
ZHUNTER_ASPECT_MONKEY,
|
||||
ZHUNTER_ASPECT_WOLF,
|
||||
ZHUNTER_ASPECT_CHEETAH,
|
||||
ZHUNTER_ASPECT_PACK,
|
||||
ZHUNTER_ASPECT_WILD,
|
||||
ZHUNTER_ASPECT_BEAST
|
||||
}
|
||||
|
||||
local ZHUNTER_ASPECT_MAX = table.getn(ZHunterMod_Aspect_Spells)
|
||||
local zButtonAspect_LastAuraUpdateAt = 0
|
||||
local zButtonAspect_MinAuraInterval = 0.15
|
||||
local zButtonAspect_MinAuraIntervalCombat = 0.60
|
||||
local zButtonAspect_LastAuraTexture = nil
|
||||
local zButtonAspect_LastParentId = nil
|
||||
local zButtonAspect_AuraProbeTextLeft1 = nil
|
||||
|
||||
local function zButtonAspect_GetSaved()
|
||||
local currentRoot = zButtonAspect_GetRoot()
|
||||
if not currentRoot["zButtonAspect"] then
|
||||
currentRoot["zButtonAspect"] = {}
|
||||
end
|
||||
return currentRoot["zButtonAspect"]
|
||||
end
|
||||
|
||||
local function zButtonAspect_EnsureConfig()
|
||||
local saved = zButtonAspect_GetSaved()
|
||||
saved["count"] = nil
|
||||
if saved["rows"] == nil then
|
||||
saved["rows"] = 1
|
||||
end
|
||||
if saved["firstbutton"] == nil then
|
||||
saved["firstbutton"] = "RIGHT"
|
||||
end
|
||||
if saved["enabled"] == nil then
|
||||
saved["enabled"] = 1
|
||||
end
|
||||
if saved["tooltip"] == nil then
|
||||
saved["tooltip"] = 1
|
||||
end
|
||||
if not saved["parent"] then
|
||||
saved["parent"] = {}
|
||||
end
|
||||
if saved["parent"]["size"] == nil then
|
||||
saved["parent"]["size"] = 36
|
||||
end
|
||||
if saved["parent"]["circle"] == nil then
|
||||
saved["parent"]["circle"] = 1
|
||||
end
|
||||
if not saved["children"] then
|
||||
saved["children"] = {}
|
||||
end
|
||||
if saved["children"]["size"] == nil then
|
||||
saved["children"]["size"] = 36
|
||||
end
|
||||
if saved["children"]["hideonclick"] == nil then
|
||||
saved["children"]["hideonclick"] = 1
|
||||
end
|
||||
if not saved["spells"] then
|
||||
saved["spells"] = {}
|
||||
end
|
||||
if not saved["visible"] then
|
||||
saved["visible"] = {}
|
||||
end
|
||||
for i = 1, ZHUNTER_ASPECT_MAX do
|
||||
if not tonumber(saved["spells"][i]) then
|
||||
saved["spells"][i] = i
|
||||
end
|
||||
if saved["visible"][i] == nil then
|
||||
saved["visible"][i] = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function zButtonAspect_ApplyRuntimeSettings()
|
||||
if not zButtonAspect then
|
||||
return
|
||||
end
|
||||
local saved = zButtonAspect_GetSaved()
|
||||
zButtonAspect.tooltip = saved["tooltip"] and true or false
|
||||
zButtonAspect.hideonclick = saved["children"] and saved["children"]["hideonclick"] and true or false
|
||||
zButtonAspect.expandonhover = saved["children"] and saved["children"]["expandonhover"] and true or false
|
||||
zButtonAspect.fadetimer = saved["children"] and tonumber(saved["children"]["fadetimer"]) or 0
|
||||
end
|
||||
|
||||
local function zButtonAspect_IsKnownAspectSpellId(spellId)
|
||||
if not spellId then
|
||||
return false
|
||||
end
|
||||
local spellName = GetSpellName(spellId, "spell")
|
||||
if not spellName or spellName == "" then
|
||||
return false
|
||||
end
|
||||
for i = 1, table.getn(ZHunterMod_Aspect_Spells) do
|
||||
if ZHunterMod_Aspect_Spells[i] == spellName then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function zButtonAspect_EnsureValidParentId()
|
||||
if not (zButtonAspect and zButtonAspect.count) then
|
||||
return
|
||||
end
|
||||
|
||||
if zButtonAspect_IsKnownAspectSpellId(zButtonAspect.id) then
|
||||
return
|
||||
end
|
||||
|
||||
for i = 1, zButtonAspect.count do
|
||||
local child = getglobal(zButtonAspect.name .. i)
|
||||
if child and child.id and zButtonAspect_IsKnownAspectSpellId(child.id) then
|
||||
zButtonAspect.id = child.id
|
||||
zButtonAspect.isspell = 1
|
||||
ZSpellButton_UpdateButton(zButtonAspect)
|
||||
ZSpellButton_UpdateCooldown(zButtonAspect)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonAspect_OnLoad()
|
||||
this:RegisterEvent("VARIABLES_LOADED")
|
||||
end
|
||||
|
||||
function zButtonAspect_OnEvent()
|
||||
if event == "VARIABLES_LOADED" then
|
||||
if not zButtonAspect then
|
||||
return
|
||||
end
|
||||
if UnitClass("player") ~= ZHUNTER_HUNTER then
|
||||
zButtonAspect:UnregisterAllEvents()
|
||||
zButtonAspect:Hide()
|
||||
return
|
||||
end
|
||||
zButtonAspect_CreateButtons()
|
||||
MTH_ZH_AspectAdjust = CreateFrame("Frame", "MTH_ZH_AspectAdjust")
|
||||
MTH_ZH_AspectAdjust:RegisterEvent("PLAYER_AURAS_CHANGED")
|
||||
MTH_ZH_AspectAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_ZH_AspectAdjust:RegisterEvent("SPELLS_CHANGED")
|
||||
MTH_ZH_AspectAdjust:RegisterEvent("CHARACTER_POINTS_CHANGED")
|
||||
MTH_ZH_AspectAdjust:RegisterEvent("LEARNED_SPELL_IN_TAB")
|
||||
MTH_ZH_AspectAdjust:SetScript("OnEvent", MTH_ZH_AspectAdjust_OnEvent)
|
||||
zButtonAspect_Tooltip = CreateFrame("GameTooltip", "MTH_ZH_AspectProbe", nil, "GameTooltipTemplate")
|
||||
if zButtonAspect_Tooltip and zButtonAspect_Tooltip.GetName then
|
||||
local tooltipName = zButtonAspect_Tooltip:GetName()
|
||||
if tooltipName then
|
||||
zButtonAspect_AuraProbeTextLeft1 = getglobal(tooltipName .. "TextLeft1")
|
||||
end
|
||||
end
|
||||
zButtonAspect_SetupSizeAndPosition()
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonAspect_CreateButtons()
|
||||
zButtonAspect_EnsureConfig()
|
||||
local saved = zButtonAspect_GetSaved()
|
||||
|
||||
ZSpellButton_CreateChildren(zButtonAspect, "zButtonAspect", ZHUNTER_ASPECT_MAX)
|
||||
local info = {}
|
||||
local infoIndex = 1
|
||||
for i=1, table.getn(ZHunterMod_Aspect_Spells) do
|
||||
if not tonumber(saved["spells"][i]) then
|
||||
info = ZHunterMod_Aspect_Spells
|
||||
saved["spells"] = {1, 2, 3, 4, 5, 6, 7}
|
||||
break
|
||||
end
|
||||
local spellIndex = saved["spells"][i]
|
||||
if saved["visible"][spellIndex] ~= false then
|
||||
info[infoIndex] = ZHunterMod_Aspect_Spells[spellIndex]
|
||||
infoIndex = infoIndex + 1
|
||||
end
|
||||
end
|
||||
zButtonAspect.found = ZSpellButton_SetButtons(zButtonAspect, info)
|
||||
zButtonAspect_ApplyRuntimeSettings()
|
||||
zButtonAspect_EnsureValidParentId()
|
||||
end
|
||||
|
||||
function zButtonAspect_SetupSizeAndPosition()
|
||||
zButtonAspect_EnsureConfig()
|
||||
local saved = zButtonAspect_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if MTH_ZH_AspectAdjust and MTH_ZH_AspectAdjust.SetScript then
|
||||
MTH_ZH_AspectAdjust:SetScript("OnEvent", nil)
|
||||
end
|
||||
if zButtonAspect and zButtonAspect.Hide then
|
||||
zButtonAspect:Hide()
|
||||
end
|
||||
return
|
||||
end
|
||||
if MTH_ZH_AspectAdjust and MTH_ZH_AspectAdjust.SetScript then
|
||||
MTH_ZH_AspectAdjust:SetScript("OnEvent", MTH_ZH_AspectAdjust_OnEvent)
|
||||
end
|
||||
local displayCount = zButtonAspect.found or ZHUNTER_ASPECT_MAX
|
||||
if displayCount < 0 then
|
||||
displayCount = 0
|
||||
end
|
||||
ZSpellButton_SetSize(zButtonAspect, saved["parent"]["size"])
|
||||
ZSpellButton_SetSize(zButtonAspect, saved["children"]["size"], 1)
|
||||
ZSpellButton_SetExpandDirection(zButtonAspect, saved["firstbutton"])
|
||||
ZSpellButton_ArrangeChildren(zButtonAspect, saved["rows"],
|
||||
displayCount, saved["horizontal"],
|
||||
saved["vertical"])
|
||||
end
|
||||
|
||||
function zButtonAspect_Reset()
|
||||
local currentRoot = zButtonAspect_GetRoot()
|
||||
currentRoot["zButtonAspect"] = {}
|
||||
local saved = zButtonAspect_GetSaved()
|
||||
saved["spells"] = {1, 2, 3, 4, 5, 6, 7}
|
||||
saved["rows"] = 1
|
||||
saved["horizontal"] = nil
|
||||
saved["vertical"] = nil
|
||||
saved["firstbutton"] = "RIGHT"
|
||||
saved["enabled"] = 1
|
||||
saved["tooltip"] = 1
|
||||
saved["parent"] = {}
|
||||
saved["parent"]["size"] = 36
|
||||
saved["parent"]["hide"] = nil
|
||||
saved["parent"]["circle"] = 1
|
||||
saved["children"] = {}
|
||||
saved["children"]["size"] = 36
|
||||
saved["children"]["hideonclick"] = 1
|
||||
saved["visible"] = {1, 1, 1, 1, 1, 1, 1}
|
||||
zButtonAspect_EnsureConfig()
|
||||
end
|
||||
|
||||
function MTH_ZH_AspectAdjust_OnEvent()
|
||||
if not zButtonAspect or not zButtonAspect.count then
|
||||
return
|
||||
end
|
||||
if event == "PLAYER_AURAS_CHANGED" then
|
||||
local now = GetTime and GetTime() or 0
|
||||
local minInterval = zButtonAspect_MinAuraInterval
|
||||
if UnitAffectingCombat and UnitAffectingCombat("player") then
|
||||
minInterval = zButtonAspect_MinAuraIntervalCombat
|
||||
end
|
||||
if now > 0 and zButtonAspect_LastAuraUpdateAt > 0 and (now - zButtonAspect_LastAuraUpdateAt) < minInterval then
|
||||
return
|
||||
end
|
||||
zButtonAspect_LastAuraUpdateAt = now
|
||||
end
|
||||
if event == "SPELLS_CHANGED" or event == "CHARACTER_POINTS_CHANGED" or event == "LEARNED_SPELL_IN_TAB" then
|
||||
zButtonAspect_CreateButtons()
|
||||
zButtonAspect_SetupSizeAndPosition()
|
||||
zButtonAspect_EnsureValidParentId()
|
||||
end
|
||||
if event == "PLAYER_AURAS_CHANGED" or event == "PLAYER_ENTERING_WORLD"
|
||||
or event == "SPELLS_CHANGED" or event == "CHARACTER_POINTS_CHANGED" or event == "LEARNED_SPELL_IN_TAB" then
|
||||
zButtonAspect_EnsureValidParentId()
|
||||
if not zButtonAspect1.id then
|
||||
return
|
||||
end
|
||||
local button
|
||||
local isParentTooltipOwned = GameTooltip and GameTooltip.IsOwned and GameTooltip:IsOwned(zButtonAspect)
|
||||
local childrenShown = zButtonAspect.children and zButtonAspect.children.IsShown and zButtonAspect.children:IsShown()
|
||||
local needChildIconScan = (event ~= "PLAYER_AURAS_CHANGED") or childrenShown or isParentTooltipOwned
|
||||
local buttontextures = nil
|
||||
local hasDuplicateChildTexture = nil
|
||||
if needChildIconScan then
|
||||
buttontextures = {}
|
||||
local textureSeen = {}
|
||||
for i=1, zButtonAspect.count do
|
||||
button = getglobal(zButtonAspect.name..i)
|
||||
button.icon = nil
|
||||
if button.id then
|
||||
local btnTexture = GetSpellTexture(button.id, "spell")
|
||||
if btnTexture then
|
||||
if textureSeen[btnTexture] then
|
||||
hasDuplicateChildTexture = true
|
||||
elseif hasDuplicateChildTexture == nil then
|
||||
hasDuplicateChildTexture = false
|
||||
end
|
||||
textureSeen[btnTexture] = 1
|
||||
buttontextures[btnTexture] = button
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local i = 1
|
||||
local texture = GetSpellTexture(zButtonAspect1.id, "spell")
|
||||
local buff = UnitBuff("player", i)
|
||||
local spellname, buffname
|
||||
local newParentId = zButtonAspect1.id
|
||||
while buff do
|
||||
if texture == buff and zButtonAspect2.id then
|
||||
newParentId = zButtonAspect2.id
|
||||
end
|
||||
if needChildIconScan and buttontextures[buff] then
|
||||
if hasDuplicateChildTexture then
|
||||
zButtonAspect_Tooltip:SetOwner(this, "ANCHOR_NONE")
|
||||
zButtonAspect_Tooltip:SetUnitBuff("player", i)
|
||||
if zButtonAspect_AuraProbeTextLeft1 and zButtonAspect_AuraProbeTextLeft1.GetText then
|
||||
buffname = zButtonAspect_AuraProbeTextLeft1:GetText()
|
||||
else
|
||||
buffname = nil
|
||||
end
|
||||
spellname = GetSpellName(buttontextures[buff].id, "spell")
|
||||
if buffname == spellname then
|
||||
buttontextures[buff].icon = "Interface\\Icons\\Spell_Nature_WispSplode"
|
||||
end
|
||||
else
|
||||
buttontextures[buff].icon = "Interface\\Icons\\Spell_Nature_WispSplode"
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
buff = UnitBuff("player", i)
|
||||
end
|
||||
if event == "PLAYER_AURAS_CHANGED" and zButtonAspect_LastAuraTexture == texture and zButtonAspect.id == newParentId and zButtonAspect_LastParentId == newParentId and not isParentTooltipOwned then
|
||||
return
|
||||
end
|
||||
zButtonAspect_LastAuraTexture = texture
|
||||
zButtonAspect_LastParentId = newParentId
|
||||
zButtonAspect.id = newParentId
|
||||
ZSpellButton_UpdateButton(zButtonAspect)
|
||||
ZSpellButton_UpdateCooldown(zButtonAspect)
|
||||
if needChildIconScan then
|
||||
for i=1, zButtonAspect.count do
|
||||
button = getglobal(zButtonAspect.name..i)
|
||||
if button.id then
|
||||
ZSpellButton_UpdateButton(button)
|
||||
end
|
||||
end
|
||||
end
|
||||
if isParentTooltipOwned then
|
||||
ZSpellButtonParent_OnEnter(zButtonAspect)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonAspect_KeyBinding(index)
|
||||
if MTH_ZH_IsModuleEnabled and not MTH_ZH_IsModuleEnabled() then
|
||||
return
|
||||
end
|
||||
|
||||
local button
|
||||
if index then
|
||||
button = getglobal("zButtonAspect"..index)
|
||||
else
|
||||
button = zButtonAspect
|
||||
end
|
||||
if button.id then
|
||||
CastSpell(button.id, "spell")
|
||||
if zButtonAspect.hideonclick then
|
||||
if type(ZSpellButton_SetChildrenExpanded) == "function" then
|
||||
ZSpellButton_SetChildrenExpanded(zButtonAspect, false)
|
||||
elseif zButtonAspect.children then
|
||||
zButtonAspect.children:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SLASH_zButtonAspect1 = "/ZAspect"
|
||||
SlashCmdList["zButtonAspect"] = function(msg)
|
||||
if MTH_ZH_HandleDisabledSlash and MTH_ZH_HandleDisabledSlash("Aspect button is disabled while module 'zhunter' is disabled.") then
|
||||
return
|
||||
end
|
||||
if msg == "reset" then
|
||||
zButtonAspect_Reset()
|
||||
zButtonAspect:ClearAllPoints()
|
||||
zButtonAspect:SetPoint("CENTER", UIParent, "CENTER", -60, 0)
|
||||
elseif msg == "options" then
|
||||
MTH_OpenOptions("Aspect")
|
||||
else
|
||||
MTH_ZH_Print("Possible Commands: \"options\", \"reset\"")
|
||||
end
|
||||
end
|
||||
@@ -22,6 +22,20 @@ if not root["zButtonCompanions"] then
|
||||
end
|
||||
|
||||
local ZHUNTER_COMPANIONS_BUTTON_MAX = 80
|
||||
local zButtonCompanions_LastSpellSignature = nil
|
||||
local zButtonCompanions_LastRefreshAt = 0
|
||||
local zButtonCompanions_MinRefreshInterval = 0.50
|
||||
|
||||
local function zButtonCompanions_GetSpellSignature(spellIds)
|
||||
if type(spellIds) ~= "table" or table.getn(spellIds) == 0 then
|
||||
return ""
|
||||
end
|
||||
local parts = {}
|
||||
for i = 1, table.getn(spellIds) do
|
||||
parts[i] = tostring(spellIds[i] or "")
|
||||
end
|
||||
return table.concat(parts, ",")
|
||||
end
|
||||
|
||||
local function zButtonCompanions_GetSaved()
|
||||
local currentRoot = zButtonCompanions_GetRoot()
|
||||
@@ -79,6 +93,8 @@ local function zButtonCompanions_ApplyRuntimeSettings()
|
||||
local saved = zButtonCompanions_GetSaved()
|
||||
zButtonCompanions.tooltip = saved["tooltip"] and true or false
|
||||
zButtonCompanions.hideonclick = saved["children"] and saved["children"]["hideonclick"] and true or false
|
||||
zButtonCompanions.expandonhover = saved["children"] and saved["children"]["expandonhover"] and true or false
|
||||
zButtonCompanions.fadetimer = saved["children"] and tonumber(saved["children"]["fadetimer"]) or 0
|
||||
end
|
||||
|
||||
local function zButtonCompanions_NormalizeTabName(value)
|
||||
@@ -211,10 +227,10 @@ function zButtonCompanions_OnEvent()
|
||||
return
|
||||
end
|
||||
zButtonCompanions_CreateButtons()
|
||||
zButtonCompanionsAdjustment = CreateFrame("Frame", "zButtonCompanionsAdjustment")
|
||||
zButtonCompanionsAdjustment:RegisterEvent("SPELLS_CHANGED")
|
||||
zButtonCompanionsAdjustment:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
zButtonCompanionsAdjustment:SetScript("OnEvent", zButtonCompanionsAdjustment_OnEvent)
|
||||
MTH_ZH_CompanionsAdjust = CreateFrame("Frame", "MTH_ZH_CompanionsAdjust")
|
||||
MTH_ZH_CompanionsAdjust:RegisterEvent("SPELLS_CHANGED")
|
||||
MTH_ZH_CompanionsAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_ZH_CompanionsAdjust:SetScript("OnEvent", MTH_ZH_CompanionsAdjust_OnEvent)
|
||||
zButtonCompanions_SetupSizeAndPosition()
|
||||
end
|
||||
end
|
||||
@@ -233,11 +249,17 @@ end
|
||||
function zButtonCompanions_SetupSizeAndPosition()
|
||||
local saved = zButtonCompanions_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if MTH_ZH_CompanionsAdjust and MTH_ZH_CompanionsAdjust.SetScript then
|
||||
MTH_ZH_CompanionsAdjust:SetScript("OnEvent", nil)
|
||||
end
|
||||
if zButtonCompanions and zButtonCompanions.Hide then
|
||||
zButtonCompanions:Hide()
|
||||
end
|
||||
return
|
||||
end
|
||||
if MTH_ZH_CompanionsAdjust and MTH_ZH_CompanionsAdjust.SetScript then
|
||||
MTH_ZH_CompanionsAdjust:SetScript("OnEvent", MTH_ZH_CompanionsAdjust_OnEvent)
|
||||
end
|
||||
local displayCount = zButtonCompanions.found or 0
|
||||
if displayCount < 0 then
|
||||
displayCount = 0
|
||||
@@ -271,10 +293,22 @@ function zButtonCompanions_Reset()
|
||||
zButtonCompanions_EnsureConfig()
|
||||
end
|
||||
|
||||
function zButtonCompanionsAdjustment_OnEvent()
|
||||
function MTH_ZH_CompanionsAdjust_OnEvent()
|
||||
if not zButtonCompanions then
|
||||
return
|
||||
end
|
||||
if event == "SPELLS_CHANGED" then
|
||||
local now = GetTime and GetTime() or 0
|
||||
if now > 0 and zButtonCompanions_LastRefreshAt > 0 and (now - zButtonCompanions_LastRefreshAt) < zButtonCompanions_MinRefreshInterval then
|
||||
return
|
||||
end
|
||||
local signature = zButtonCompanions_GetSpellSignature(zButtonCompanions_CollectTabSpellIds())
|
||||
if signature == zButtonCompanions_LastSpellSignature and not GameTooltip:IsOwned(zButtonCompanions) then
|
||||
return
|
||||
end
|
||||
zButtonCompanions_LastSpellSignature = signature
|
||||
zButtonCompanions_LastRefreshAt = now
|
||||
end
|
||||
zButtonCompanions_RefreshSpells()
|
||||
zButtonCompanions_SetupSizeAndPosition()
|
||||
if GameTooltip:IsOwned(zButtonCompanions) then
|
||||
|
||||
@@ -22,6 +22,20 @@ if not root["zButtonMounts"] then
|
||||
end
|
||||
|
||||
local ZHUNTER_MOUNTS_BUTTON_MAX = 80
|
||||
local zButtonMounts_LastSpellSignature = nil
|
||||
local zButtonMounts_LastRefreshAt = 0
|
||||
local zButtonMounts_MinRefreshInterval = 0.50
|
||||
|
||||
local function zButtonMounts_GetSpellSignature(spellIds)
|
||||
if type(spellIds) ~= "table" or table.getn(spellIds) == 0 then
|
||||
return ""
|
||||
end
|
||||
local parts = {}
|
||||
for i = 1, table.getn(spellIds) do
|
||||
parts[i] = tostring(spellIds[i] or "")
|
||||
end
|
||||
return table.concat(parts, ",")
|
||||
end
|
||||
|
||||
local function zButtonMounts_GetSaved()
|
||||
local currentRoot = zButtonMounts_GetRoot()
|
||||
@@ -79,6 +93,8 @@ local function zButtonMounts_ApplyRuntimeSettings()
|
||||
local saved = zButtonMounts_GetSaved()
|
||||
zButtonMounts.tooltip = saved["tooltip"] and true or false
|
||||
zButtonMounts.hideonclick = saved["children"] and saved["children"]["hideonclick"] and true or false
|
||||
zButtonMounts.expandonhover = saved["children"] and saved["children"]["expandonhover"] and true or false
|
||||
zButtonMounts.fadetimer = saved["children"] and tonumber(saved["children"]["fadetimer"]) or 0
|
||||
end
|
||||
|
||||
local function zButtonMounts_NormalizeTabName(value)
|
||||
@@ -211,10 +227,10 @@ function zButtonMounts_OnEvent()
|
||||
return
|
||||
end
|
||||
zButtonMounts_CreateButtons()
|
||||
zButtonMountsAdjustment = CreateFrame("Frame", "zButtonMountsAdjustment")
|
||||
zButtonMountsAdjustment:RegisterEvent("SPELLS_CHANGED")
|
||||
zButtonMountsAdjustment:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
zButtonMountsAdjustment:SetScript("OnEvent", zButtonMountsAdjustment_OnEvent)
|
||||
MTH_ZH_MountsAdjust = CreateFrame("Frame", "MTH_ZH_MountsAdjust")
|
||||
MTH_ZH_MountsAdjust:RegisterEvent("SPELLS_CHANGED")
|
||||
MTH_ZH_MountsAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_ZH_MountsAdjust:SetScript("OnEvent", MTH_ZH_MountsAdjust_OnEvent)
|
||||
zButtonMounts_SetupSizeAndPosition()
|
||||
end
|
||||
end
|
||||
@@ -233,11 +249,17 @@ end
|
||||
function zButtonMounts_SetupSizeAndPosition()
|
||||
local saved = zButtonMounts_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if MTH_ZH_MountsAdjust and MTH_ZH_MountsAdjust.SetScript then
|
||||
MTH_ZH_MountsAdjust:SetScript("OnEvent", nil)
|
||||
end
|
||||
if zButtonMounts and zButtonMounts.Hide then
|
||||
zButtonMounts:Hide()
|
||||
end
|
||||
return
|
||||
end
|
||||
if MTH_ZH_MountsAdjust and MTH_ZH_MountsAdjust.SetScript then
|
||||
MTH_ZH_MountsAdjust:SetScript("OnEvent", MTH_ZH_MountsAdjust_OnEvent)
|
||||
end
|
||||
local displayCount = zButtonMounts.found or 0
|
||||
if displayCount < 0 then
|
||||
displayCount = 0
|
||||
@@ -271,10 +293,22 @@ function zButtonMounts_Reset()
|
||||
zButtonMounts_EnsureConfig()
|
||||
end
|
||||
|
||||
function zButtonMountsAdjustment_OnEvent()
|
||||
function MTH_ZH_MountsAdjust_OnEvent()
|
||||
if not zButtonMounts then
|
||||
return
|
||||
end
|
||||
if event == "SPELLS_CHANGED" then
|
||||
local now = GetTime and GetTime() or 0
|
||||
if now > 0 and zButtonMounts_LastRefreshAt > 0 and (now - zButtonMounts_LastRefreshAt) < zButtonMounts_MinRefreshInterval then
|
||||
return
|
||||
end
|
||||
local signature = zButtonMounts_GetSpellSignature(zButtonMounts_CollectTabSpellIds())
|
||||
if signature == zButtonMounts_LastSpellSignature and not GameTooltip:IsOwned(zButtonMounts) then
|
||||
return
|
||||
end
|
||||
zButtonMounts_LastSpellSignature = signature
|
||||
zButtonMounts_LastRefreshAt = now
|
||||
end
|
||||
zButtonMounts_RefreshSpells()
|
||||
zButtonMounts_SetupSizeAndPosition()
|
||||
if GameTooltip:IsOwned(zButtonMounts) then
|
||||
|
||||
+655
-588
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,11 @@ ZHunterMod_Ranged_Weapons = ZHunterMod_Ranged_Weapons or {}
|
||||
local ZHUNTER_RANGED_MAX_COUNT = 80
|
||||
local zButtonRanged_Cache = {}
|
||||
local zButtonRanged_TooltipWarmed = false
|
||||
local zButtonRanged_LastRefreshAt = 0
|
||||
local zButtonRanged_MinBagRefreshInterval = 0.75
|
||||
local zButtonRanged_IdleBagRefreshInterval = 3.00
|
||||
local zButtonRanged_BagDirty = false
|
||||
local zButtonRanged_RefreshButtonsFromState
|
||||
|
||||
local function zButtonRanged_GetKnownItemSpeed(itemId)
|
||||
local idNum = tonumber(itemId)
|
||||
@@ -227,6 +232,8 @@ local function zButtonRanged_ApplyRuntimeSettings()
|
||||
local saved = zButtonRanged_GetSaved()
|
||||
zButtonRanged.tooltip = saved["tooltip"] and true or false
|
||||
zButtonRanged.hideonclick = saved["children"] and saved["children"]["hideonclick"] and true or false
|
||||
zButtonRanged.expandonhover = saved["children"] and saved["children"]["expandonhover"] and true or false
|
||||
zButtonRanged.fadetimer = saved["children"] and tonumber(saved["children"]["fadetimer"]) or 0
|
||||
end
|
||||
|
||||
local function zButtonRanged_UpdateDurabilityText(button)
|
||||
@@ -437,6 +444,15 @@ local function zButtonRanged_OnEnter(button)
|
||||
if not button then
|
||||
return
|
||||
end
|
||||
if zButtonRanged_BagDirty then
|
||||
local previousFound = tonumber(zButtonRanged and zButtonRanged.found) or 0
|
||||
zButtonRanged_RefreshButtonsFromState()
|
||||
if (tonumber(zButtonRanged and zButtonRanged.found) or 0) ~= previousFound then
|
||||
zButtonRanged_SetupSizeAndPosition()
|
||||
else
|
||||
zButtonRanged_UpdateButton(zButtonRanged)
|
||||
end
|
||||
end
|
||||
if not (zButtonRanged and zButtonRanged.tooltip) then
|
||||
return
|
||||
end
|
||||
@@ -503,7 +519,7 @@ local function zButtonRanged_BeforeClick(button)
|
||||
return true
|
||||
end
|
||||
|
||||
local function zButtonRanged_RefreshButtonsFromState()
|
||||
zButtonRanged_RefreshButtonsFromState = function()
|
||||
if not zButtonRanged then
|
||||
return
|
||||
end
|
||||
@@ -525,6 +541,7 @@ local function zButtonRanged_RefreshButtonsFromState()
|
||||
end
|
||||
|
||||
zButtonRanged.found = ZSpellButton_SetButtons(zButtonRanged, info)
|
||||
zButtonRanged_BagDirty = false
|
||||
zButtonRanged_ApplyRuntimeSettings()
|
||||
end
|
||||
|
||||
@@ -587,11 +604,11 @@ function zButtonRanged_OnEvent()
|
||||
zButtonRanged.customUpdateButton = zButtonRanged_UpdateButton
|
||||
zButtonRanged.beforeclick = zButtonRanged_BeforeClick
|
||||
zButtonRanged_CreateButtons()
|
||||
zButtonRangedAdjustment = CreateFrame("Frame", "zButtonRangedAdjustment")
|
||||
zButtonRangedAdjustment:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
||||
zButtonRangedAdjustment:RegisterEvent("BAG_UPDATE")
|
||||
zButtonRangedAdjustment:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
zButtonRangedAdjustment:SetScript("OnEvent", zButtonRangedAdjustment_OnEvent)
|
||||
MTH_ZH_RangedAdjust = CreateFrame("Frame", "MTH_ZH_RangedAdjust")
|
||||
MTH_ZH_RangedAdjust:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
||||
MTH_ZH_RangedAdjust:RegisterEvent("BAG_UPDATE")
|
||||
MTH_ZH_RangedAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_ZH_RangedAdjust:SetScript("OnEvent", MTH_ZH_RangedAdjust_OnEvent)
|
||||
zButtonRanged_SetupSizeAndPosition()
|
||||
end
|
||||
end
|
||||
@@ -620,11 +637,17 @@ end
|
||||
function zButtonRanged_SetupSizeAndPosition()
|
||||
local saved = zButtonRanged_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if MTH_ZH_RangedAdjust and MTH_ZH_RangedAdjust.SetScript then
|
||||
MTH_ZH_RangedAdjust:SetScript("OnEvent", nil)
|
||||
end
|
||||
if zButtonRanged and zButtonRanged.Hide then
|
||||
zButtonRanged:Hide()
|
||||
end
|
||||
return
|
||||
end
|
||||
if MTH_ZH_RangedAdjust and MTH_ZH_RangedAdjust.SetScript then
|
||||
MTH_ZH_RangedAdjust:SetScript("OnEvent", MTH_ZH_RangedAdjust_OnEvent)
|
||||
end
|
||||
local displayCount = zButtonRanged.found or 0
|
||||
if displayCount < 0 then
|
||||
displayCount = 0
|
||||
@@ -658,15 +681,39 @@ function zButtonRanged_Reset()
|
||||
zButtonRanged_EnsureConfig()
|
||||
end
|
||||
|
||||
function zButtonRangedAdjustment_OnEvent()
|
||||
function MTH_ZH_RangedAdjust_OnEvent()
|
||||
if not zButtonRanged then
|
||||
return
|
||||
end
|
||||
if event == "UNIT_INVENTORY_CHANGED" and arg1 and arg1 ~= "player" then
|
||||
return
|
||||
end
|
||||
if event == "BAG_UPDATE" then
|
||||
local now = GetTime and GetTime() or 0
|
||||
local isInspecting = false
|
||||
if zButtonRanged.children and zButtonRanged.children.IsShown and zButtonRanged.children:IsShown() then
|
||||
isInspecting = true
|
||||
elseif GameTooltip and GameTooltip.IsOwned and GameTooltip:IsOwned(zButtonRanged) then
|
||||
isInspecting = true
|
||||
end
|
||||
if not isInspecting then
|
||||
zButtonRanged_BagDirty = true
|
||||
return
|
||||
end
|
||||
local minInterval = isInspecting and zButtonRanged_MinBagRefreshInterval or zButtonRanged_IdleBagRefreshInterval
|
||||
if now > 0 and zButtonRanged_LastRefreshAt > 0 and (now - zButtonRanged_LastRefreshAt) < minInterval then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
zButtonRanged_LastRefreshAt = GetTime and GetTime() or 0
|
||||
local previousFound = tonumber(zButtonRanged.found) or 0
|
||||
zButtonRanged_RefreshButtonsFromState()
|
||||
zButtonRanged_SetupSizeAndPosition()
|
||||
if (tonumber(zButtonRanged.found) or 0) ~= previousFound then
|
||||
zButtonRanged_SetupSizeAndPosition()
|
||||
else
|
||||
zButtonRanged_UpdateButton(zButtonRanged)
|
||||
end
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
zButtonRanged_PrewarmTooltipOnce()
|
||||
end
|
||||
|
||||
@@ -22,6 +22,20 @@ if not root["zButtonToys"] then
|
||||
end
|
||||
|
||||
local ZHUNTER_TOYS_BUTTON_MAX = 80
|
||||
local zButtonToys_LastSpellSignature = nil
|
||||
local zButtonToys_LastRefreshAt = 0
|
||||
local zButtonToys_MinRefreshInterval = 0.50
|
||||
|
||||
local function zButtonToys_GetSpellSignature(spellIds)
|
||||
if type(spellIds) ~= "table" or table.getn(spellIds) == 0 then
|
||||
return ""
|
||||
end
|
||||
local parts = {}
|
||||
for i = 1, table.getn(spellIds) do
|
||||
parts[i] = tostring(spellIds[i] or "")
|
||||
end
|
||||
return table.concat(parts, ",")
|
||||
end
|
||||
|
||||
local function zButtonToys_GetSaved()
|
||||
local currentRoot = zButtonToys_GetRoot()
|
||||
@@ -79,6 +93,8 @@ local function zButtonToys_ApplyRuntimeSettings()
|
||||
local saved = zButtonToys_GetSaved()
|
||||
zButtonToys.tooltip = saved["tooltip"] and true or false
|
||||
zButtonToys.hideonclick = saved["children"] and saved["children"]["hideonclick"] and true or false
|
||||
zButtonToys.expandonhover = saved["children"] and saved["children"]["expandonhover"] and true or false
|
||||
zButtonToys.fadetimer = saved["children"] and tonumber(saved["children"]["fadetimer"]) or 0
|
||||
end
|
||||
|
||||
local function zButtonToys_NormalizeTabName(value)
|
||||
@@ -211,10 +227,10 @@ function zButtonToys_OnEvent()
|
||||
return
|
||||
end
|
||||
zButtonToys_CreateButtons()
|
||||
zButtonToysAdjustment = CreateFrame("Frame", "zButtonToysAdjustment")
|
||||
zButtonToysAdjustment:RegisterEvent("SPELLS_CHANGED")
|
||||
zButtonToysAdjustment:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
zButtonToysAdjustment:SetScript("OnEvent", zButtonToysAdjustment_OnEvent)
|
||||
MTH_ZH_ToysAdjust = CreateFrame("Frame", "MTH_ZH_ToysAdjust")
|
||||
MTH_ZH_ToysAdjust:RegisterEvent("SPELLS_CHANGED")
|
||||
MTH_ZH_ToysAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_ZH_ToysAdjust:SetScript("OnEvent", MTH_ZH_ToysAdjust_OnEvent)
|
||||
zButtonToys_SetupSizeAndPosition()
|
||||
end
|
||||
end
|
||||
@@ -233,11 +249,17 @@ end
|
||||
function zButtonToys_SetupSizeAndPosition()
|
||||
local saved = zButtonToys_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if MTH_ZH_ToysAdjust and MTH_ZH_ToysAdjust.SetScript then
|
||||
MTH_ZH_ToysAdjust:SetScript("OnEvent", nil)
|
||||
end
|
||||
if zButtonToys and zButtonToys.Hide then
|
||||
zButtonToys:Hide()
|
||||
end
|
||||
return
|
||||
end
|
||||
if MTH_ZH_ToysAdjust and MTH_ZH_ToysAdjust.SetScript then
|
||||
MTH_ZH_ToysAdjust:SetScript("OnEvent", MTH_ZH_ToysAdjust_OnEvent)
|
||||
end
|
||||
local displayCount = zButtonToys.found or 0
|
||||
if displayCount < 0 then
|
||||
displayCount = 0
|
||||
@@ -271,10 +293,22 @@ function zButtonToys_Reset()
|
||||
zButtonToys_EnsureConfig()
|
||||
end
|
||||
|
||||
function zButtonToysAdjustment_OnEvent()
|
||||
function MTH_ZH_ToysAdjust_OnEvent()
|
||||
if not zButtonToys then
|
||||
return
|
||||
end
|
||||
if event == "SPELLS_CHANGED" then
|
||||
local now = GetTime and GetTime() or 0
|
||||
if now > 0 and zButtonToys_LastRefreshAt > 0 and (now - zButtonToys_LastRefreshAt) < zButtonToys_MinRefreshInterval then
|
||||
return
|
||||
end
|
||||
local signature = zButtonToys_GetSpellSignature(zButtonToys_CollectTabSpellIds())
|
||||
if signature == zButtonToys_LastSpellSignature and not GameTooltip:IsOwned(zButtonToys) then
|
||||
return
|
||||
end
|
||||
zButtonToys_LastSpellSignature = signature
|
||||
zButtonToys_LastRefreshAt = now
|
||||
end
|
||||
zButtonToys_RefreshSpells()
|
||||
zButtonToys_SetupSizeAndPosition()
|
||||
if GameTooltip:IsOwned(zButtonToys) then
|
||||
|
||||
+411
-260
@@ -1,261 +1,412 @@
|
||||
local function zButtonTrack_GetRoot()
|
||||
return MTH_ZH_GetSavedRoot()
|
||||
end
|
||||
|
||||
local root = zButtonTrack_GetRoot()
|
||||
if not root["zButtonTrack"] then
|
||||
root["zButtonTrack"] = {}
|
||||
root["zButtonTrack"]["spells"] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
|
||||
root["zButtonTrack"]["rows"] = 1
|
||||
root["zButtonTrack"]["horizontal"] = nil
|
||||
root["zButtonTrack"]["vertical"] = nil
|
||||
root["zButtonTrack"]["firstbutton"] = "RIGHT"
|
||||
root["zButtonTrack"]["enabled"] = 1
|
||||
root["zButtonTrack"]["tooltip"] = 1
|
||||
root["zButtonTrack"]["parent"] = {}
|
||||
root["zButtonTrack"]["parent"]["size"] = 36
|
||||
root["zButtonTrack"]["parent"]["hide"] = nil
|
||||
root["zButtonTrack"]["parent"]["circle"] = 1
|
||||
root["zButtonTrack"]["children"] = {}
|
||||
root["zButtonTrack"]["children"]["size"] = 36
|
||||
root["zButtonTrack"]["children"]["hideonclick"] = 1
|
||||
end
|
||||
|
||||
ZHunterMod_Track_Spells = {
|
||||
ZHUNTER_TRACK_HIDDEN,
|
||||
ZHUNTER_TRACK_HUMANOIDS,
|
||||
ZHUNTER_TRACK_UNDEAD,
|
||||
ZHUNTER_TRACK_BEASTS,
|
||||
ZHUNTER_TRACK_DEMONS,
|
||||
ZHUNTER_TRACK_ELEMENTALS,
|
||||
ZHUNTER_TRACK_DRAGONKIN,
|
||||
ZHUNTER_TRACK_GIANTS,
|
||||
ZHUNTER_TRACK_MINERALS,
|
||||
ZHUNTER_TRACK_HERBS,
|
||||
ZHUNTER_TRACK_TREASURE
|
||||
}
|
||||
|
||||
local ZHUNTER_TRACK_MAX = table.getn(ZHunterMod_Track_Spells)
|
||||
|
||||
local function zButtonTrack_GetSaved()
|
||||
local currentRoot = zButtonTrack_GetRoot()
|
||||
if not currentRoot["zButtonTrack"] then
|
||||
currentRoot["zButtonTrack"] = {}
|
||||
end
|
||||
return currentRoot["zButtonTrack"]
|
||||
end
|
||||
|
||||
local function zButtonTrack_EnsureConfig()
|
||||
local saved = zButtonTrack_GetSaved()
|
||||
saved["count"] = nil
|
||||
if saved["rows"] == nil then
|
||||
saved["rows"] = 1
|
||||
end
|
||||
if saved["firstbutton"] == nil then
|
||||
saved["firstbutton"] = "RIGHT"
|
||||
end
|
||||
if saved["enabled"] == nil then
|
||||
saved["enabled"] = 1
|
||||
end
|
||||
if saved["tooltip"] == nil then
|
||||
saved["tooltip"] = 1
|
||||
end
|
||||
if not saved["parent"] then
|
||||
saved["parent"] = {}
|
||||
end
|
||||
if saved["parent"]["size"] == nil then
|
||||
saved["parent"]["size"] = 36
|
||||
end
|
||||
if saved["parent"]["circle"] == nil then
|
||||
saved["parent"]["circle"] = 1
|
||||
end
|
||||
if not saved["children"] then
|
||||
saved["children"] = {}
|
||||
end
|
||||
if saved["children"]["size"] == nil then
|
||||
saved["children"]["size"] = 36
|
||||
end
|
||||
if saved["children"]["hideonclick"] == nil then
|
||||
saved["children"]["hideonclick"] = 1
|
||||
end
|
||||
if not saved["spells"] then
|
||||
saved["spells"] = {}
|
||||
end
|
||||
if not saved["visible"] then
|
||||
saved["visible"] = {}
|
||||
end
|
||||
for i = 1, ZHUNTER_TRACK_MAX do
|
||||
if not tonumber(saved["spells"][i]) then
|
||||
saved["spells"][i] = i
|
||||
end
|
||||
if saved["visible"][i] == nil then
|
||||
saved["visible"][i] = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function zButtonTrack_ApplyRuntimeSettings()
|
||||
if not zButtonTrack then
|
||||
return
|
||||
end
|
||||
local saved = zButtonTrack_GetSaved()
|
||||
zButtonTrack.tooltip = saved["tooltip"] and true or false
|
||||
zButtonTrack.hideonclick = saved["children"] and saved["children"]["hideonclick"] and true or false
|
||||
end
|
||||
|
||||
|
||||
function zButtonTrack_OnLoad()
|
||||
this:RegisterEvent("VARIABLES_LOADED")
|
||||
end
|
||||
|
||||
function zButtonTrack_OnEvent()
|
||||
if event == "VARIABLES_LOADED" then
|
||||
if not zButtonTrack then
|
||||
return
|
||||
end
|
||||
if UnitClass("player") ~= ZHUNTER_HUNTER then
|
||||
zButtonTrack:UnregisterAllEvents()
|
||||
zButtonTrack:Hide()
|
||||
return
|
||||
end
|
||||
zButtonTrack_CreateButtons()
|
||||
zButtonTrackAdjustment = CreateFrame("Frame", "zButtonTrackAdjustment")
|
||||
zButtonTrackAdjustment:RegisterEvent("PLAYER_AURAS_CHANGED")
|
||||
zButtonTrackAdjustment:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
zButtonTrackAdjustment:RegisterEvent("SPELLS_CHANGED")
|
||||
zButtonTrackAdjustment:RegisterEvent("CHARACTER_POINTS_CHANGED")
|
||||
zButtonTrackAdjustment:SetScript("OnEvent", zButtonTrackAdjustment_OnEvent)
|
||||
zButtonTrack_SetupSizeAndPosition()
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonTrack_CreateButtons()
|
||||
zButtonTrack_EnsureConfig()
|
||||
local saved = zButtonTrack_GetSaved()
|
||||
|
||||
ZSpellButton_CreateChildren(zButtonTrack, "zButtonTrack", ZHUNTER_TRACK_MAX)
|
||||
local info = {}
|
||||
local infoIndex = 1
|
||||
for i=1, table.getn(ZHunterMod_Track_Spells) do
|
||||
if not tonumber(saved["spells"][i]) then
|
||||
info = ZHunterMod_Track_Spells
|
||||
saved["spells"] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
|
||||
break
|
||||
end
|
||||
local spellIndex = saved["spells"][i]
|
||||
if saved["visible"][spellIndex] ~= false then
|
||||
info[infoIndex] = ZHunterMod_Track_Spells[spellIndex]
|
||||
infoIndex = infoIndex + 1
|
||||
end
|
||||
end
|
||||
zButtonTrack.found = ZSpellButton_SetButtons(zButtonTrack, info)
|
||||
zButtonTrack_ApplyRuntimeSettings()
|
||||
end
|
||||
|
||||
function zButtonTrack_SetupSizeAndPosition()
|
||||
zButtonTrack_EnsureConfig()
|
||||
local saved = zButtonTrack_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if zButtonTrack and zButtonTrack.Hide then
|
||||
zButtonTrack:Hide()
|
||||
end
|
||||
return
|
||||
end
|
||||
local displayCount = zButtonTrack.found or ZHUNTER_TRACK_MAX
|
||||
if displayCount < 0 then
|
||||
displayCount = 0
|
||||
end
|
||||
ZSpellButton_SetSize(zButtonTrack, saved["parent"]["size"])
|
||||
ZSpellButton_SetSize(zButtonTrack, saved["children"]["size"], 1)
|
||||
ZSpellButton_SetExpandDirection(zButtonTrack, saved["firstbutton"])
|
||||
ZSpellButton_ArrangeChildren(zButtonTrack, saved["rows"],
|
||||
displayCount, saved["horizontal"],
|
||||
saved["vertical"])
|
||||
end
|
||||
|
||||
function zButtonTrack_Reset()
|
||||
local currentRoot = zButtonTrack_GetRoot()
|
||||
currentRoot["zButtonTrack"] = {}
|
||||
local saved = zButtonTrack_GetSaved()
|
||||
saved["spells"] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
|
||||
saved["rows"] = 1
|
||||
saved["horizontal"] = nil
|
||||
saved["vertical"] = nil
|
||||
saved["firstbutton"] = "RIGHT"
|
||||
saved["enabled"] = 1
|
||||
saved["tooltip"] = 1
|
||||
saved["parent"] = {}
|
||||
saved["parent"]["size"] = 36
|
||||
saved["parent"]["hide"] = nil
|
||||
saved["parent"]["circle"] = 1
|
||||
saved["children"] = {}
|
||||
saved["children"]["size"] = 36
|
||||
saved["children"]["hideonclick"] = 1
|
||||
saved["visible"] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
|
||||
zButtonTrack_EnsureConfig()
|
||||
end
|
||||
|
||||
function zButtonTrackAdjustment_OnEvent()
|
||||
if not zButtonTrack or not zButtonTrack.count then
|
||||
return
|
||||
end
|
||||
if event == "SPELLS_CHANGED" or event == "CHARACTER_POINTS_CHANGED" then
|
||||
zButtonTrack_CreateButtons()
|
||||
zButtonTrack_SetupSizeAndPosition()
|
||||
end
|
||||
if event == "PLAYER_AURAS_CHANGED" or event == "PLAYER_ENTERING_WORLD"
|
||||
or event == "SPELLS_CHANGED" or event == "CHARACTER_POINTS_CHANGED" then
|
||||
local i = 1
|
||||
local texture = zButtonTrack1IconTexture:GetTexture()
|
||||
local buff = GetTrackingTexture()
|
||||
if texture == buff and zButtonTrack2.id then
|
||||
zButtonTrack.id = zButtonTrack2.id
|
||||
else
|
||||
zButtonTrack.id = zButtonTrack1.id
|
||||
end
|
||||
ZSpellButton_UpdateButton(zButtonTrack)
|
||||
ZSpellButton_UpdateCooldown(zButtonTrack)
|
||||
if GameTooltip:IsOwned(zButtonTrack) then
|
||||
ZSpellButtonParent_OnEnter(zButtonTrack)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonTrack_KeyBinding(index)
|
||||
if MTH_ZH_IsModuleEnabled and not MTH_ZH_IsModuleEnabled() then
|
||||
return
|
||||
end
|
||||
|
||||
local button
|
||||
if index then
|
||||
button = getglobal("zButtonTrack"..index)
|
||||
else
|
||||
button = zButtonTrack
|
||||
end
|
||||
if button.id then
|
||||
CastSpell(button.id, "spell")
|
||||
if zButtonTrack.hideonclick then
|
||||
if type(ZSpellButton_SetChildrenExpanded) == "function" then
|
||||
ZSpellButton_SetChildrenExpanded(zButtonTrack, false)
|
||||
elseif zButtonTrack.children then
|
||||
zButtonTrack.children:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SLASH_zButtonTrack1 = "/ZTrack"
|
||||
SlashCmdList["zButtonTrack"] = function(msg)
|
||||
if MTH_ZH_HandleDisabledSlash and MTH_ZH_HandleDisabledSlash("Track button is disabled while module 'zhunter' is disabled.") then
|
||||
return
|
||||
end
|
||||
if msg == "reset" then
|
||||
zButtonTrack_Reset()
|
||||
zButtonTrack:ClearAllPoints()
|
||||
zButtonTrack:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
|
||||
elseif msg == "options" then
|
||||
MTH_OpenOptions("Track")
|
||||
else
|
||||
MTH_ZH_Print("Possible Commands: \"options\", \"reset\"")
|
||||
end
|
||||
local function zButtonTrack_GetRoot()
|
||||
return MTH_ZH_GetSavedRoot()
|
||||
end
|
||||
|
||||
local root = zButtonTrack_GetRoot()
|
||||
if not root["zButtonTrack"] then
|
||||
root["zButtonTrack"] = {}
|
||||
root["zButtonTrack"]["spells"] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
|
||||
root["zButtonTrack"]["rows"] = 1
|
||||
root["zButtonTrack"]["horizontal"] = nil
|
||||
root["zButtonTrack"]["vertical"] = nil
|
||||
root["zButtonTrack"]["firstbutton"] = "RIGHT"
|
||||
root["zButtonTrack"]["enabled"] = 1
|
||||
root["zButtonTrack"]["tooltip"] = 1
|
||||
root["zButtonTrack"]["parent"] = {}
|
||||
root["zButtonTrack"]["parent"]["size"] = 36
|
||||
root["zButtonTrack"]["parent"]["hide"] = nil
|
||||
root["zButtonTrack"]["parent"]["circle"] = 1
|
||||
root["zButtonTrack"]["children"] = {}
|
||||
root["zButtonTrack"]["children"]["size"] = 36
|
||||
root["zButtonTrack"]["children"]["hideonclick"] = 1
|
||||
end
|
||||
|
||||
ZHunterMod_Track_Spells = {
|
||||
ZHUNTER_TRACK_HIDDEN,
|
||||
ZHUNTER_TRACK_HUMANOIDS,
|
||||
ZHUNTER_TRACK_UNDEAD,
|
||||
ZHUNTER_TRACK_BEASTS,
|
||||
ZHUNTER_TRACK_DEMONS,
|
||||
ZHUNTER_TRACK_ELEMENTALS,
|
||||
ZHUNTER_TRACK_DRAGONKIN,
|
||||
ZHUNTER_TRACK_GIANTS,
|
||||
ZHUNTER_TRACK_MINERALS,
|
||||
ZHUNTER_TRACK_HERBS,
|
||||
ZHUNTER_TRACK_TREASURE
|
||||
}
|
||||
|
||||
local ZHUNTER_TRACK_MAX = table.getn(ZHunterMod_Track_Spells)
|
||||
local zButtonTrack_LastTrackingTexture = nil
|
||||
local zButtonTrack_SyncActiveChild
|
||||
local zButtonTrack_GetSaved
|
||||
|
||||
local function zButtonTrack_NormalizeTexture(texture)
|
||||
if not texture then
|
||||
return ""
|
||||
end
|
||||
local value = string.lower(tostring(texture))
|
||||
value = string.gsub(value, "\\", "/")
|
||||
local _, _, basename = string.find(value, "([^/]+)$")
|
||||
return basename or value
|
||||
end
|
||||
|
||||
local function zButtonTrack_FindSpellIdByTrackingTexture(trackingTexture)
|
||||
if not trackingTexture or not zButtonTrack or not zButtonTrack.count then
|
||||
return nil
|
||||
end
|
||||
local wanted = zButtonTrack_NormalizeTexture(trackingTexture)
|
||||
for i = 1, zButtonTrack.count do
|
||||
local child = getglobal("zButtonTrack" .. i)
|
||||
if child and child.id then
|
||||
local spellTexture = GetSpellTexture and GetSpellTexture(child.id, "spell") or nil
|
||||
if zButtonTrack_NormalizeTexture(spellTexture) == wanted then
|
||||
return child.id
|
||||
end
|
||||
if child.icon and zButtonTrack_NormalizeTexture(child.icon) == wanted then
|
||||
return child.id
|
||||
end
|
||||
if child.icontexture and child.icontexture.GetTexture then
|
||||
local childTexture = child.icontexture:GetTexture()
|
||||
if zButtonTrack_NormalizeTexture(childTexture) == wanted then
|
||||
return child.id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function zButtonTrack_FindSpellIdByTrackingName(trackingName)
|
||||
if not trackingName or trackingName == "" or not zButtonTrack or not zButtonTrack.count then
|
||||
return nil
|
||||
end
|
||||
for i = 1, zButtonTrack.count do
|
||||
local child = getglobal("zButtonTrack" .. i)
|
||||
if child and child.id then
|
||||
local spellName = GetSpellName and GetSpellName(child.id, "spell") or nil
|
||||
if spellName == trackingName then
|
||||
return child.id
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function zButtonTrack_GetActiveTrackingSpellId()
|
||||
local activeName = nil
|
||||
local activeTexture = nil
|
||||
if GetNumTrackingTypes and GetTrackingInfo then
|
||||
local numTracking = GetNumTrackingTypes() or 0
|
||||
for i = 1, numTracking do
|
||||
local name, texture, active = GetTrackingInfo(i)
|
||||
if active then
|
||||
activeName = name
|
||||
activeTexture = texture
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
local byName = zButtonTrack_FindSpellIdByTrackingName(activeName)
|
||||
if byName then
|
||||
return byName, activeTexture
|
||||
end
|
||||
if activeTexture then
|
||||
return zButtonTrack_FindSpellIdByTrackingTexture(activeTexture), activeTexture
|
||||
end
|
||||
local buff = GetTrackingTexture and GetTrackingTexture() or nil
|
||||
return zButtonTrack_FindSpellIdByTrackingTexture(buff), buff
|
||||
end
|
||||
|
||||
local function zButtonTrack_AfterClick(button)
|
||||
if not zButtonTrack then
|
||||
return
|
||||
end
|
||||
if button and button.id then
|
||||
zButtonTrack.id = button.id
|
||||
ZSpellButton_UpdateButton(zButtonTrack)
|
||||
ZSpellButton_UpdateCooldown(zButtonTrack)
|
||||
zButtonTrack_SyncActiveChild(button.id)
|
||||
if GetSpellTexture then
|
||||
zButtonTrack_LastTrackingTexture = GetSpellTexture(button.id, "spell") or zButtonTrack_LastTrackingTexture
|
||||
end
|
||||
local isOwned = GameTooltip and GameTooltip.IsOwned and GameTooltip:IsOwned(zButtonTrack)
|
||||
if isOwned then
|
||||
ZSpellButtonParent_OnEnter(zButtonTrack)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
zButtonTrack_SyncActiveChild = function(activeId)
|
||||
if not zButtonTrack or not zButtonTrack.count then
|
||||
return
|
||||
end
|
||||
for i = 1, zButtonTrack.count do
|
||||
local child = getglobal("zButtonTrack" .. i)
|
||||
if child and child.SetChecked then
|
||||
child:SetChecked((activeId and child.id == activeId) and 1 or 0)
|
||||
end
|
||||
end
|
||||
if zButtonTrack.SetChecked then
|
||||
zButtonTrack:SetChecked(0)
|
||||
end
|
||||
end
|
||||
|
||||
local function zButtonTrack_RefreshTrackingState()
|
||||
if not zButtonTrack or not zButtonTrack.count then
|
||||
return
|
||||
end
|
||||
local newId, trackingTexture = zButtonTrack_GetActiveTrackingSpellId()
|
||||
local buff = trackingTexture or (GetTrackingTexture and GetTrackingTexture() or nil)
|
||||
if not newId and not buff then
|
||||
if zButtonTrack.id then
|
||||
zButtonTrack_SyncActiveChild(zButtonTrack.id)
|
||||
else
|
||||
zButtonTrack_LastTrackingTexture = nil
|
||||
zButtonTrack_SyncActiveChild(nil)
|
||||
end
|
||||
return
|
||||
end
|
||||
if not newId then
|
||||
newId = zButtonTrack.id or nil
|
||||
end
|
||||
if not newId then
|
||||
return
|
||||
end
|
||||
if zButtonTrack_NormalizeTexture(zButtonTrack_LastTrackingTexture) == zButtonTrack_NormalizeTexture(buff) and zButtonTrack.id == newId then
|
||||
zButtonTrack_SyncActiveChild(newId)
|
||||
return
|
||||
end
|
||||
|
||||
local isOwned = GameTooltip and GameTooltip.IsOwned and GameTooltip:IsOwned(zButtonTrack)
|
||||
zButtonTrack_LastTrackingTexture = buff
|
||||
zButtonTrack.id = newId
|
||||
ZSpellButton_UpdateButton(zButtonTrack)
|
||||
ZSpellButton_UpdateCooldown(zButtonTrack)
|
||||
zButtonTrack_SyncActiveChild(newId)
|
||||
if isOwned then
|
||||
ZSpellButtonParent_OnEnter(zButtonTrack)
|
||||
end
|
||||
end
|
||||
|
||||
zButtonTrack_GetSaved = function()
|
||||
local currentRoot = zButtonTrack_GetRoot()
|
||||
if not currentRoot["zButtonTrack"] then
|
||||
currentRoot["zButtonTrack"] = {}
|
||||
end
|
||||
return currentRoot["zButtonTrack"]
|
||||
end
|
||||
|
||||
local function zButtonTrack_EnsureConfig()
|
||||
local saved = zButtonTrack_GetSaved()
|
||||
saved["count"] = nil
|
||||
if saved["rows"] == nil then
|
||||
saved["rows"] = 1
|
||||
end
|
||||
if saved["firstbutton"] == nil then
|
||||
saved["firstbutton"] = "RIGHT"
|
||||
end
|
||||
if saved["enabled"] == nil then
|
||||
saved["enabled"] = 1
|
||||
end
|
||||
if saved["tooltip"] == nil then
|
||||
saved["tooltip"] = 1
|
||||
end
|
||||
if not saved["parent"] then
|
||||
saved["parent"] = {}
|
||||
end
|
||||
if saved["parent"]["size"] == nil then
|
||||
saved["parent"]["size"] = 36
|
||||
end
|
||||
if saved["parent"]["circle"] == nil then
|
||||
saved["parent"]["circle"] = 1
|
||||
end
|
||||
if not saved["children"] then
|
||||
saved["children"] = {}
|
||||
end
|
||||
if saved["children"]["size"] == nil then
|
||||
saved["children"]["size"] = 36
|
||||
end
|
||||
if saved["children"]["hideonclick"] == nil then
|
||||
saved["children"]["hideonclick"] = 1
|
||||
end
|
||||
if not saved["spells"] then
|
||||
saved["spells"] = {}
|
||||
end
|
||||
if not saved["visible"] then
|
||||
saved["visible"] = {}
|
||||
end
|
||||
for i = 1, ZHUNTER_TRACK_MAX do
|
||||
if not tonumber(saved["spells"][i]) then
|
||||
saved["spells"][i] = i
|
||||
end
|
||||
if saved["visible"][i] == nil then
|
||||
saved["visible"][i] = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function zButtonTrack_ApplyRuntimeSettings()
|
||||
if not zButtonTrack then
|
||||
return
|
||||
end
|
||||
local saved = zButtonTrack_GetSaved()
|
||||
zButtonTrack.tooltip = saved["tooltip"] and true or false
|
||||
zButtonTrack.hideonclick = saved["children"] and saved["children"]["hideonclick"] and true or false
|
||||
zButtonTrack.expandonhover = saved["children"] and saved["children"]["expandonhover"] and true or false
|
||||
zButtonTrack.fadetimer = saved["children"] and tonumber(saved["children"]["fadetimer"]) or 0
|
||||
end
|
||||
|
||||
|
||||
function zButtonTrack_OnLoad()
|
||||
this:RegisterEvent("VARIABLES_LOADED")
|
||||
end
|
||||
|
||||
function zButtonTrack_OnEvent()
|
||||
if event == "VARIABLES_LOADED" then
|
||||
if not zButtonTrack then
|
||||
return
|
||||
end
|
||||
if UnitClass("player") ~= ZHUNTER_HUNTER then
|
||||
zButtonTrack:UnregisterAllEvents()
|
||||
zButtonTrack:Hide()
|
||||
return
|
||||
end
|
||||
zButtonTrack_CreateButtons()
|
||||
zButtonTrack.afterclick = zButtonTrack_AfterClick
|
||||
MTH_ZH_TrackAdjust = CreateFrame("Frame", "MTH_ZH_TrackAdjust")
|
||||
MTH_ZH_TrackAdjust:RegisterEvent("MINIMAP_UPDATE_TRACKING")
|
||||
MTH_ZH_TrackAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_ZH_TrackAdjust:RegisterEvent("SPELLS_CHANGED")
|
||||
MTH_ZH_TrackAdjust:RegisterEvent("CHARACTER_POINTS_CHANGED")
|
||||
MTH_ZH_TrackAdjust:RegisterEvent("LEARNED_SPELL_IN_TAB")
|
||||
MTH_ZH_TrackAdjust:SetScript("OnEvent", MTH_ZH_TrackAdjust_OnEvent)
|
||||
zButtonTrack_SetupSizeAndPosition()
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonTrack_CreateButtons()
|
||||
zButtonTrack_EnsureConfig()
|
||||
local saved = zButtonTrack_GetSaved()
|
||||
|
||||
ZSpellButton_CreateChildren(zButtonTrack, "zButtonTrack", ZHUNTER_TRACK_MAX)
|
||||
local info = {}
|
||||
local infoIndex = 1
|
||||
for i=1, table.getn(ZHunterMod_Track_Spells) do
|
||||
if not tonumber(saved["spells"][i]) then
|
||||
info = ZHunterMod_Track_Spells
|
||||
saved["spells"] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
|
||||
break
|
||||
end
|
||||
local spellIndex = saved["spells"][i]
|
||||
if saved["visible"][spellIndex] ~= false then
|
||||
info[infoIndex] = ZHunterMod_Track_Spells[spellIndex]
|
||||
infoIndex = infoIndex + 1
|
||||
end
|
||||
end
|
||||
zButtonTrack.found = ZSpellButton_SetButtons(zButtonTrack, info)
|
||||
zButtonTrack_ApplyRuntimeSettings()
|
||||
end
|
||||
|
||||
function zButtonTrack_SetupSizeAndPosition()
|
||||
zButtonTrack_EnsureConfig()
|
||||
local saved = zButtonTrack_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if MTH_ZH_TrackAdjust and MTH_ZH_TrackAdjust.SetScript then
|
||||
MTH_ZH_TrackAdjust:SetScript("OnEvent", nil)
|
||||
end
|
||||
if zButtonTrack and zButtonTrack.Hide then
|
||||
zButtonTrack:Hide()
|
||||
end
|
||||
return
|
||||
end
|
||||
if MTH_ZH_TrackAdjust and MTH_ZH_TrackAdjust.SetScript then
|
||||
MTH_ZH_TrackAdjust:SetScript("OnEvent", MTH_ZH_TrackAdjust_OnEvent)
|
||||
end
|
||||
local displayCount = zButtonTrack.found or ZHUNTER_TRACK_MAX
|
||||
if displayCount < 0 then
|
||||
displayCount = 0
|
||||
end
|
||||
ZSpellButton_SetSize(zButtonTrack, saved["parent"]["size"])
|
||||
ZSpellButton_SetSize(zButtonTrack, saved["children"]["size"], 1)
|
||||
ZSpellButton_SetExpandDirection(zButtonTrack, saved["firstbutton"])
|
||||
ZSpellButton_ArrangeChildren(zButtonTrack, saved["rows"],
|
||||
displayCount, saved["horizontal"],
|
||||
saved["vertical"])
|
||||
zButtonTrack_RefreshTrackingState()
|
||||
end
|
||||
|
||||
function zButtonTrack_Reset()
|
||||
local currentRoot = zButtonTrack_GetRoot()
|
||||
currentRoot["zButtonTrack"] = {}
|
||||
local saved = zButtonTrack_GetSaved()
|
||||
saved["spells"] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
|
||||
saved["rows"] = 1
|
||||
saved["horizontal"] = nil
|
||||
saved["vertical"] = nil
|
||||
saved["firstbutton"] = "RIGHT"
|
||||
saved["enabled"] = 1
|
||||
saved["tooltip"] = 1
|
||||
saved["parent"] = {}
|
||||
saved["parent"]["size"] = 36
|
||||
saved["parent"]["hide"] = nil
|
||||
saved["parent"]["circle"] = 1
|
||||
saved["children"] = {}
|
||||
saved["children"]["size"] = 36
|
||||
saved["children"]["hideonclick"] = 1
|
||||
saved["visible"] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
|
||||
zButtonTrack_EnsureConfig()
|
||||
end
|
||||
|
||||
function MTH_ZH_TrackAdjust_OnEvent()
|
||||
if not zButtonTrack or not zButtonTrack.count then
|
||||
return
|
||||
end
|
||||
if event == "SPELLS_CHANGED" or event == "CHARACTER_POINTS_CHANGED" or event == "LEARNED_SPELL_IN_TAB" then
|
||||
zButtonTrack_CreateButtons()
|
||||
zButtonTrack_SetupSizeAndPosition()
|
||||
end
|
||||
if event == "MINIMAP_UPDATE_TRACKING" or event == "PLAYER_ENTERING_WORLD"
|
||||
or event == "SPELLS_CHANGED" or event == "CHARACTER_POINTS_CHANGED" or event == "LEARNED_SPELL_IN_TAB" then
|
||||
zButtonTrack_RefreshTrackingState()
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonTrack_KeyBinding(index)
|
||||
if MTH_ZH_IsModuleEnabled and not MTH_ZH_IsModuleEnabled() then
|
||||
return
|
||||
end
|
||||
|
||||
local button
|
||||
if index then
|
||||
button = getglobal("zButtonTrack"..index)
|
||||
else
|
||||
button = zButtonTrack
|
||||
end
|
||||
if button.id then
|
||||
CastSpell(button.id, "spell")
|
||||
if zButtonTrack.hideonclick then
|
||||
if type(ZSpellButton_SetChildrenExpanded) == "function" then
|
||||
ZSpellButton_SetChildrenExpanded(zButtonTrack, false)
|
||||
elseif zButtonTrack.children then
|
||||
zButtonTrack.children:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SLASH_zButtonTrack1 = "/ZTrack"
|
||||
SlashCmdList["zButtonTrack"] = function(msg)
|
||||
if MTH_ZH_HandleDisabledSlash and MTH_ZH_HandleDisabledSlash("Track button is disabled while module 'zhunter' is disabled.") then
|
||||
return
|
||||
end
|
||||
msg = tostring(msg or "")
|
||||
if msg == "reset" then
|
||||
zButtonTrack_Reset()
|
||||
zButtonTrack:ClearAllPoints()
|
||||
zButtonTrack:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
|
||||
elseif msg == "options" then
|
||||
MTH_OpenOptions("Track")
|
||||
else
|
||||
MTH_ZH_Print("Possible Commands: \"options\", \"reset\"")
|
||||
end
|
||||
end
|
||||
+280
-262
@@ -1,263 +1,281 @@
|
||||
local function zButtonTrap_GetRoot()
|
||||
return MTH_ZH_GetSavedRoot()
|
||||
end
|
||||
|
||||
local root = zButtonTrap_GetRoot()
|
||||
if not root["zButtonTrap"] then
|
||||
root["zButtonTrap"] = {}
|
||||
root["zButtonTrap"]["spells"] = {1, 2, 3, 4}
|
||||
root["zButtonTrap"]["rows"] = 1
|
||||
root["zButtonTrap"]["horizontal"] = nil
|
||||
root["zButtonTrap"]["vertical"] = nil
|
||||
root["zButtonTrap"]["firstbutton"] = "RIGHT"
|
||||
root["zButtonTrap"]["enabled"] = 1
|
||||
root["zButtonTrap"]["tooltip"] = 1
|
||||
root["zButtonTrap"]["parent"] = {}
|
||||
root["zButtonTrap"]["parent"]["size"] = 36
|
||||
root["zButtonTrap"]["parent"]["hide"] = nil
|
||||
root["zButtonTrap"]["parent"]["circle"] = 1
|
||||
root["zButtonTrap"]["children"] = {}
|
||||
root["zButtonTrap"]["children"]["size"] = 36
|
||||
root["zButtonTrap"]["children"]["hideonclick"] = 1
|
||||
end
|
||||
|
||||
ZHunterMod_Trap_Spells = {
|
||||
ZHUNTER_TRAP_FREEZING,
|
||||
ZHUNTER_TRAP_FROST,
|
||||
ZHUNTER_TRAP_IMMOLATION,
|
||||
ZHUNTER_TRAP_EXPLOSIVE
|
||||
}
|
||||
|
||||
local ZHUNTER_TRAP_MAX = table.getn(ZHunterMod_Trap_Spells)
|
||||
|
||||
local function zButtonTrap_GetSaved()
|
||||
local currentRoot = zButtonTrap_GetRoot()
|
||||
if not currentRoot["zButtonTrap"] then
|
||||
currentRoot["zButtonTrap"] = {}
|
||||
end
|
||||
return currentRoot["zButtonTrap"]
|
||||
end
|
||||
|
||||
local function zButtonTrap_EnsureConfig()
|
||||
local saved = zButtonTrap_GetSaved()
|
||||
saved["count"] = nil
|
||||
if saved["rows"] == nil then
|
||||
saved["rows"] = 1
|
||||
end
|
||||
if saved["firstbutton"] == nil then
|
||||
saved["firstbutton"] = "RIGHT"
|
||||
end
|
||||
if saved["enabled"] == nil then
|
||||
saved["enabled"] = 1
|
||||
end
|
||||
if saved["tooltip"] == nil then
|
||||
saved["tooltip"] = 1
|
||||
end
|
||||
if not saved["parent"] then
|
||||
saved["parent"] = {}
|
||||
end
|
||||
if saved["parent"]["size"] == nil then
|
||||
saved["parent"]["size"] = 36
|
||||
end
|
||||
if saved["parent"]["circle"] == nil then
|
||||
saved["parent"]["circle"] = 1
|
||||
end
|
||||
if not saved["children"] then
|
||||
saved["children"] = {}
|
||||
end
|
||||
if saved["children"]["size"] == nil then
|
||||
saved["children"]["size"] = 36
|
||||
end
|
||||
if saved["children"]["hideonclick"] == nil then
|
||||
saved["children"]["hideonclick"] = 1
|
||||
end
|
||||
if not saved["spells"] then
|
||||
saved["spells"] = {}
|
||||
end
|
||||
if not saved["visible"] then
|
||||
saved["visible"] = {}
|
||||
end
|
||||
for i = 1, ZHUNTER_TRAP_MAX do
|
||||
if not tonumber(saved["spells"][i]) then
|
||||
saved["spells"][i] = i
|
||||
end
|
||||
if saved["visible"][i] == nil then
|
||||
saved["visible"][i] = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function zButtonTrap_ApplyRuntimeSettings()
|
||||
if not zButtonTrap then
|
||||
return
|
||||
end
|
||||
local saved = zButtonTrap_GetSaved()
|
||||
zButtonTrap.tooltip = saved["tooltip"] and true or false
|
||||
zButtonTrap.hideonclick = saved["children"] and saved["children"]["hideonclick"] and true or false
|
||||
end
|
||||
|
||||
|
||||
function zButtonTrap_OnLoad()
|
||||
this:RegisterEvent("VARIABLES_LOADED")
|
||||
end
|
||||
|
||||
function zButtonTrap_OnEvent()
|
||||
if event == "VARIABLES_LOADED" then
|
||||
if not zButtonTrap then
|
||||
return
|
||||
end
|
||||
if UnitClass("player") ~= ZHUNTER_HUNTER then
|
||||
zButtonTrap:UnregisterAllEvents()
|
||||
zButtonTrap:Hide()
|
||||
return
|
||||
end
|
||||
zButtonTrap_CreateButtons()
|
||||
zButtonTrapAdjustment = CreateFrame("Frame", "zButtonTrapAdjustment")
|
||||
zButtonTrapAdjustment:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
zButtonTrapAdjustment:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
zButtonTrapAdjustment:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
zButtonTrapAdjustment:RegisterEvent("SPELLS_CHANGED")
|
||||
zButtonTrapAdjustment:RegisterEvent("CHARACTER_POINTS_CHANGED")
|
||||
zButtonTrapAdjustment:SetScript("OnEvent", zButtonTrapAdjustment_OnEvent)
|
||||
zButtonTrap_SetupSizeAndPosition()
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonTrap_CreateButtons()
|
||||
zButtonTrap_EnsureConfig()
|
||||
local saved = zButtonTrap_GetSaved()
|
||||
|
||||
ZSpellButton_CreateChildren(zButtonTrap, "zButtonTrap", ZHUNTER_TRAP_MAX)
|
||||
local info = {}
|
||||
local infoIndex = 1
|
||||
for i=1, table.getn(ZHunterMod_Trap_Spells) do
|
||||
if not tonumber(saved["spells"][i]) then
|
||||
info = ZHunterMod_Trap_Spells
|
||||
saved["spells"] = {1, 2, 3, 4}
|
||||
break
|
||||
end
|
||||
local spellIndex = saved["spells"][i]
|
||||
if saved["visible"][spellIndex] ~= false then
|
||||
info[infoIndex] = ZHunterMod_Trap_Spells[spellIndex]
|
||||
infoIndex = infoIndex + 1
|
||||
end
|
||||
end
|
||||
zButtonTrap.found = ZSpellButton_SetButtons(zButtonTrap, info)
|
||||
zButtonTrap_ApplyRuntimeSettings()
|
||||
end
|
||||
|
||||
function zButtonTrap_SetupSizeAndPosition()
|
||||
zButtonTrap_EnsureConfig()
|
||||
local saved = zButtonTrap_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if zButtonTrap and zButtonTrap.Hide then
|
||||
zButtonTrap:Hide()
|
||||
end
|
||||
return
|
||||
end
|
||||
local displayCount = zButtonTrap.found or ZHUNTER_TRAP_MAX
|
||||
if displayCount < 0 then
|
||||
displayCount = 0
|
||||
end
|
||||
ZSpellButton_SetSize(zButtonTrap, saved["parent"]["size"])
|
||||
ZSpellButton_SetSize(zButtonTrap, saved["children"]["size"], 1)
|
||||
ZSpellButton_SetExpandDirection(zButtonTrap, saved["firstbutton"])
|
||||
ZSpellButton_ArrangeChildren(zButtonTrap, saved["rows"],
|
||||
displayCount, saved["horizontal"],
|
||||
saved["vertical"])
|
||||
end
|
||||
|
||||
function zButtonTrap_Reset()
|
||||
local currentRoot = zButtonTrap_GetRoot()
|
||||
currentRoot["zButtonTrap"] = {}
|
||||
local saved = zButtonTrap_GetSaved()
|
||||
saved["spells"] = {1, 2, 3, 4}
|
||||
saved["rows"] = 1
|
||||
saved["horizontal"] = nil
|
||||
saved["vertical"] = nil
|
||||
saved["firstbutton"] = "RIGHT"
|
||||
saved["enabled"] = 1
|
||||
saved["tooltip"] = 1
|
||||
saved["parent"] = {}
|
||||
saved["parent"]["size"] = 36
|
||||
saved["parent"]["hide"] = nil
|
||||
saved["parent"]["circle"] = 1
|
||||
saved["children"] = {}
|
||||
saved["children"]["size"] = 36
|
||||
saved["children"]["hideonclick"] = 1
|
||||
saved["visible"] = {1, 1, 1, 1}
|
||||
zButtonTrap_EnsureConfig()
|
||||
end
|
||||
|
||||
function zButtonTrapAdjustment_OnEvent()
|
||||
if not zButtonTrap or not zButtonTrap.count then
|
||||
return
|
||||
end
|
||||
if event == "SPELLS_CHANGED" or event == "CHARACTER_POINTS_CHANGED" then
|
||||
zButtonTrap_CreateButtons()
|
||||
zButtonTrap_SetupSizeAndPosition()
|
||||
end
|
||||
local nextbutton
|
||||
local button
|
||||
local combat = event == "PLAYER_REGEN_DISABLED"
|
||||
for i=1, zButtonTrap.count do
|
||||
button = getglobal(zButtonTrap.name..i)
|
||||
button.customcolor = nil
|
||||
if button.id then
|
||||
if not nextbutton then
|
||||
nextbutton = button
|
||||
end
|
||||
if combat then
|
||||
button.icontexture:SetVertexColor(0.4, 0.4, 0.4)
|
||||
button.customcolor = 1
|
||||
else
|
||||
button.icontexture:SetVertexColor(1.0, 1.0, 1.0)
|
||||
end
|
||||
end
|
||||
end
|
||||
zButtonTrap.id = nextbutton and nextbutton.id or zButtonTrap1.id
|
||||
ZSpellButton_UpdateButton(zButtonTrap)
|
||||
ZSpellButton_UpdateCooldown(zButtonTrap)
|
||||
if GameTooltip:IsOwned(zButtonTrap) then
|
||||
ZSpellButtonParent_OnEnter(zButtonTrap)
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonTrap_KeyBinding(index)
|
||||
if MTH_ZH_IsModuleEnabled and not MTH_ZH_IsModuleEnabled() then
|
||||
return
|
||||
end
|
||||
|
||||
local button
|
||||
if index then
|
||||
button = getglobal("zButtonTrap"..index)
|
||||
else
|
||||
button = zButtonTrap
|
||||
end
|
||||
if button.id then
|
||||
CastSpell(button.id, "spell")
|
||||
if zButtonTrap.hideonclick then
|
||||
if type(ZSpellButton_SetChildrenExpanded) == "function" then
|
||||
ZSpellButton_SetChildrenExpanded(zButtonTrap, false)
|
||||
elseif zButtonTrap.children then
|
||||
zButtonTrap.children:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SLASH_zButtonTrap1 = "/ZTrap"
|
||||
SlashCmdList["zButtonTrap"] = function(msg)
|
||||
if MTH_ZH_HandleDisabledSlash and MTH_ZH_HandleDisabledSlash("Trap button is disabled while module 'zhunter' is disabled.") then
|
||||
return
|
||||
end
|
||||
if msg == "reset" then
|
||||
zButtonTrap_Reset()
|
||||
zButtonTrap:ClearAllPoints()
|
||||
zButtonTrap:SetPoint("CENTER", UIParent, "CENTER", 60, 0)
|
||||
elseif msg == "options" then
|
||||
MTH_OpenOptions("Trap")
|
||||
else
|
||||
MTH_ZH_Print("Possible Commands: \"options\", \"reset\"")
|
||||
end
|
||||
local function zButtonTrap_GetRoot()
|
||||
return MTH_ZH_GetSavedRoot()
|
||||
end
|
||||
|
||||
local root = zButtonTrap_GetRoot()
|
||||
if not root["zButtonTrap"] then
|
||||
root["zButtonTrap"] = {}
|
||||
root["zButtonTrap"]["spells"] = {1, 2, 3, 4}
|
||||
root["zButtonTrap"]["rows"] = 1
|
||||
root["zButtonTrap"]["horizontal"] = nil
|
||||
root["zButtonTrap"]["vertical"] = nil
|
||||
root["zButtonTrap"]["firstbutton"] = "RIGHT"
|
||||
root["zButtonTrap"]["enabled"] = 1
|
||||
root["zButtonTrap"]["tooltip"] = 1
|
||||
root["zButtonTrap"]["parent"] = {}
|
||||
root["zButtonTrap"]["parent"]["size"] = 36
|
||||
root["zButtonTrap"]["parent"]["hide"] = nil
|
||||
root["zButtonTrap"]["parent"]["circle"] = 1
|
||||
root["zButtonTrap"]["children"] = {}
|
||||
root["zButtonTrap"]["children"]["size"] = 36
|
||||
root["zButtonTrap"]["children"]["hideonclick"] = 1
|
||||
end
|
||||
|
||||
ZHunterMod_Trap_Spells = {
|
||||
ZHUNTER_TRAP_FREEZING,
|
||||
ZHUNTER_TRAP_FROST,
|
||||
ZHUNTER_TRAP_IMMOLATION,
|
||||
ZHUNTER_TRAP_EXPLOSIVE
|
||||
}
|
||||
|
||||
local ZHUNTER_TRAP_MAX = table.getn(ZHunterMod_Trap_Spells)
|
||||
local zButtonTrap_LastParentId = nil
|
||||
local zButtonTrap_LastCombatState = nil
|
||||
|
||||
local function zButtonTrap_GetSaved()
|
||||
local currentRoot = zButtonTrap_GetRoot()
|
||||
if not currentRoot["zButtonTrap"] then
|
||||
currentRoot["zButtonTrap"] = {}
|
||||
end
|
||||
return currentRoot["zButtonTrap"]
|
||||
end
|
||||
|
||||
local function zButtonTrap_EnsureConfig()
|
||||
local saved = zButtonTrap_GetSaved()
|
||||
saved["count"] = nil
|
||||
if saved["rows"] == nil then
|
||||
saved["rows"] = 1
|
||||
end
|
||||
if saved["firstbutton"] == nil then
|
||||
saved["firstbutton"] = "RIGHT"
|
||||
end
|
||||
if saved["enabled"] == nil then
|
||||
saved["enabled"] = 1
|
||||
end
|
||||
if saved["tooltip"] == nil then
|
||||
saved["tooltip"] = 1
|
||||
end
|
||||
if not saved["parent"] then
|
||||
saved["parent"] = {}
|
||||
end
|
||||
if saved["parent"]["size"] == nil then
|
||||
saved["parent"]["size"] = 36
|
||||
end
|
||||
if saved["parent"]["circle"] == nil then
|
||||
saved["parent"]["circle"] = 1
|
||||
end
|
||||
if not saved["children"] then
|
||||
saved["children"] = {}
|
||||
end
|
||||
if saved["children"]["size"] == nil then
|
||||
saved["children"]["size"] = 36
|
||||
end
|
||||
if saved["children"]["hideonclick"] == nil then
|
||||
saved["children"]["hideonclick"] = 1
|
||||
end
|
||||
if not saved["spells"] then
|
||||
saved["spells"] = {}
|
||||
end
|
||||
if not saved["visible"] then
|
||||
saved["visible"] = {}
|
||||
end
|
||||
for i = 1, ZHUNTER_TRAP_MAX do
|
||||
if not tonumber(saved["spells"][i]) then
|
||||
saved["spells"][i] = i
|
||||
end
|
||||
if saved["visible"][i] == nil then
|
||||
saved["visible"][i] = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function zButtonTrap_ApplyRuntimeSettings()
|
||||
if not zButtonTrap then
|
||||
return
|
||||
end
|
||||
local saved = zButtonTrap_GetSaved()
|
||||
zButtonTrap.tooltip = saved["tooltip"] and true or false
|
||||
zButtonTrap.hideonclick = saved["children"] and saved["children"]["hideonclick"] and true or false
|
||||
zButtonTrap.expandonhover = saved["children"] and saved["children"]["expandonhover"] and true or false
|
||||
zButtonTrap.fadetimer = saved["children"] and tonumber(saved["children"]["fadetimer"]) or 0
|
||||
end
|
||||
|
||||
|
||||
function zButtonTrap_OnLoad()
|
||||
this:RegisterEvent("VARIABLES_LOADED")
|
||||
end
|
||||
|
||||
function zButtonTrap_OnEvent()
|
||||
if event == "VARIABLES_LOADED" then
|
||||
if not zButtonTrap then
|
||||
return
|
||||
end
|
||||
if UnitClass("player") ~= ZHUNTER_HUNTER then
|
||||
zButtonTrap:UnregisterAllEvents()
|
||||
zButtonTrap:Hide()
|
||||
return
|
||||
end
|
||||
zButtonTrap_CreateButtons()
|
||||
MTH_ZH_TrapAdjust = CreateFrame("Frame", "MTH_ZH_TrapAdjust")
|
||||
MTH_ZH_TrapAdjust:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
MTH_ZH_TrapAdjust:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
MTH_ZH_TrapAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_ZH_TrapAdjust:RegisterEvent("SPELLS_CHANGED")
|
||||
MTH_ZH_TrapAdjust:RegisterEvent("CHARACTER_POINTS_CHANGED")
|
||||
MTH_ZH_TrapAdjust:SetScript("OnEvent", MTH_ZH_TrapAdjust_OnEvent)
|
||||
zButtonTrap_SetupSizeAndPosition()
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonTrap_CreateButtons()
|
||||
zButtonTrap_EnsureConfig()
|
||||
local saved = zButtonTrap_GetSaved()
|
||||
|
||||
ZSpellButton_CreateChildren(zButtonTrap, "zButtonTrap", ZHUNTER_TRAP_MAX)
|
||||
local info = {}
|
||||
local infoIndex = 1
|
||||
for i=1, table.getn(ZHunterMod_Trap_Spells) do
|
||||
if not tonumber(saved["spells"][i]) then
|
||||
info = ZHunterMod_Trap_Spells
|
||||
saved["spells"] = {1, 2, 3, 4}
|
||||
break
|
||||
end
|
||||
local spellIndex = saved["spells"][i]
|
||||
if saved["visible"][spellIndex] ~= false then
|
||||
info[infoIndex] = ZHunterMod_Trap_Spells[spellIndex]
|
||||
infoIndex = infoIndex + 1
|
||||
end
|
||||
end
|
||||
zButtonTrap.found = ZSpellButton_SetButtons(zButtonTrap, info)
|
||||
zButtonTrap_ApplyRuntimeSettings()
|
||||
end
|
||||
|
||||
function zButtonTrap_SetupSizeAndPosition()
|
||||
zButtonTrap_EnsureConfig()
|
||||
local saved = zButtonTrap_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if MTH_ZH_TrapAdjust and MTH_ZH_TrapAdjust.SetScript then
|
||||
MTH_ZH_TrapAdjust:SetScript("OnEvent", nil)
|
||||
end
|
||||
if zButtonTrap and zButtonTrap.Hide then
|
||||
zButtonTrap:Hide()
|
||||
end
|
||||
return
|
||||
end
|
||||
if MTH_ZH_TrapAdjust and MTH_ZH_TrapAdjust.SetScript then
|
||||
MTH_ZH_TrapAdjust:SetScript("OnEvent", MTH_ZH_TrapAdjust_OnEvent)
|
||||
end
|
||||
local displayCount = zButtonTrap.found or ZHUNTER_TRAP_MAX
|
||||
if displayCount < 0 then
|
||||
displayCount = 0
|
||||
end
|
||||
ZSpellButton_SetSize(zButtonTrap, saved["parent"]["size"])
|
||||
ZSpellButton_SetSize(zButtonTrap, saved["children"]["size"], 1)
|
||||
ZSpellButton_SetExpandDirection(zButtonTrap, saved["firstbutton"])
|
||||
ZSpellButton_ArrangeChildren(zButtonTrap, saved["rows"],
|
||||
displayCount, saved["horizontal"],
|
||||
saved["vertical"])
|
||||
end
|
||||
|
||||
function zButtonTrap_Reset()
|
||||
local currentRoot = zButtonTrap_GetRoot()
|
||||
currentRoot["zButtonTrap"] = {}
|
||||
local saved = zButtonTrap_GetSaved()
|
||||
saved["spells"] = {1, 2, 3, 4}
|
||||
saved["rows"] = 1
|
||||
saved["horizontal"] = nil
|
||||
saved["vertical"] = nil
|
||||
saved["firstbutton"] = "RIGHT"
|
||||
saved["enabled"] = 1
|
||||
saved["tooltip"] = 1
|
||||
saved["parent"] = {}
|
||||
saved["parent"]["size"] = 36
|
||||
saved["parent"]["hide"] = nil
|
||||
saved["parent"]["circle"] = 1
|
||||
saved["children"] = {}
|
||||
saved["children"]["size"] = 36
|
||||
saved["children"]["hideonclick"] = 1
|
||||
saved["visible"] = {1, 1, 1, 1}
|
||||
zButtonTrap_EnsureConfig()
|
||||
end
|
||||
|
||||
function MTH_ZH_TrapAdjust_OnEvent()
|
||||
if not zButtonTrap or not zButtonTrap.count then
|
||||
return
|
||||
end
|
||||
local rebuild = false
|
||||
if event == "SPELLS_CHANGED" or event == "CHARACTER_POINTS_CHANGED" then
|
||||
zButtonTrap_CreateButtons()
|
||||
zButtonTrap_SetupSizeAndPosition()
|
||||
rebuild = true
|
||||
end
|
||||
local nextbutton
|
||||
local button
|
||||
local combat = event == "PLAYER_REGEN_DISABLED"
|
||||
for i=1, zButtonTrap.count do
|
||||
button = getglobal(zButtonTrap.name..i)
|
||||
button.customcolor = nil
|
||||
if button.id then
|
||||
if not nextbutton then
|
||||
nextbutton = button
|
||||
end
|
||||
if combat then
|
||||
button.icontexture:SetVertexColor(0.4, 0.4, 0.4)
|
||||
button.customcolor = 1
|
||||
else
|
||||
button.icontexture:SetVertexColor(1.0, 1.0, 1.0)
|
||||
end
|
||||
end
|
||||
end
|
||||
local newParentId = nextbutton and nextbutton.id or zButtonTrap1.id
|
||||
if (not rebuild) and zButtonTrap_LastParentId == newParentId and zButtonTrap_LastCombatState == combat and not GameTooltip:IsOwned(zButtonTrap) then
|
||||
return
|
||||
end
|
||||
zButtonTrap_LastParentId = newParentId
|
||||
zButtonTrap_LastCombatState = combat
|
||||
zButtonTrap.id = newParentId
|
||||
ZSpellButton_UpdateButton(zButtonTrap)
|
||||
ZSpellButton_UpdateCooldown(zButtonTrap)
|
||||
if GameTooltip:IsOwned(zButtonTrap) then
|
||||
ZSpellButtonParent_OnEnter(zButtonTrap)
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonTrap_KeyBinding(index)
|
||||
if MTH_ZH_IsModuleEnabled and not MTH_ZH_IsModuleEnabled() then
|
||||
return
|
||||
end
|
||||
|
||||
local button
|
||||
if index then
|
||||
button = getglobal("zButtonTrap"..index)
|
||||
else
|
||||
button = zButtonTrap
|
||||
end
|
||||
if button.id then
|
||||
CastSpell(button.id, "spell")
|
||||
if zButtonTrap.hideonclick then
|
||||
if type(ZSpellButton_SetChildrenExpanded) == "function" then
|
||||
ZSpellButton_SetChildrenExpanded(zButtonTrap, false)
|
||||
elseif zButtonTrap.children then
|
||||
zButtonTrap.children:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SLASH_zButtonTrap1 = "/ZTrap"
|
||||
SlashCmdList["zButtonTrap"] = function(msg)
|
||||
if MTH_ZH_HandleDisabledSlash and MTH_ZH_HandleDisabledSlash("Trap button is disabled while module 'zhunter' is disabled.") then
|
||||
return
|
||||
end
|
||||
if msg == "reset" then
|
||||
zButtonTrap_Reset()
|
||||
zButtonTrap:ClearAllPoints()
|
||||
zButtonTrap:SetPoint("CENTER", UIParent, "CENTER", 60, 0)
|
||||
elseif msg == "options" then
|
||||
MTH_OpenOptions("Trap")
|
||||
else
|
||||
MTH_ZH_Print("Possible Commands: \"options\", \"reset\"")
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user