4 Commits

Author SHA1 Message Date
Duvel 23bb69d094 Merge pull request #7 from DuvelCorp/v1.3.0
V1.3.0 - Last before Twow upgrade
2026-03-19 16:32:36 +01:00
DuvelCorp b2060e0aab V1.3.0 2026-03-19 16:27:21 +01:00
Duvel 609a6bdd83 Merge pull request #6 from DuvelCorp/v1.2.0
v1.2.0
2026-03-11 00:41:30 +01:00
DuvelCorp c0c2c275eb v1.2.0 2026-03-11 00:40:35 +01:00
74 changed files with 26269 additions and 7690 deletions
+38
View File
@@ -2,6 +2,44 @@
All notable changes to MetaHunt will be documented in this file.
## [1.3.0] - 2026-03-19
### Added
- Added a **3D Model Viewer** to the Hunter Book Beast Lore inspector panel. Clicking a beast in the list shows its in-game model.
- Added a standalone **3D Model Viewer** that is shown when cliking the model of a beast in the Beast lore. The model is rotatable with the mouse, and you can browse all models of the same pet family and shows all other beasts that share the same skin, with one-click to jump to any of them in the Beast Lore.
- Added a **Family icon** column to the Beast Lore list, replacing the text family name with the pet family icon for a more compact view.
- Added an **Attack Speed (AS)** column to the Beast Lore list.
- Added `displayId` and `skinId` fields to **all ~1000 beasts** in the MetaHunt datastore. `displayId` was scraped from the Turtle WoW DB, and `skinId` derived from it following an extraction on MPQ game files. This is what powers the model viewer and skin-grouping.
- Added per-family icons to all 19 pet families in the family data table.
- Added missing food types (`raw meat`, `raw fish`) to all pet families that accept `meat` or `fish` respectively (sourced from MPQ data).
- Added **Profile Management** panel (Options → Profiles): save the current addon configuration as a named profile and instantly load it on any character. Profiles cover all module settings (ICU, Chronometer, AutoBuy, AutoQuest, SmartAmmo, Feed-O-Matic, zButtons layout) and per-character module enabled/disabled states.
- Added automatic per-character **config snapshots** saved on every logout (`CharName-RealmName`), visible in the "Copy from Character" section — import any character's snapshot as a loadable profile in one click.
### Fixed
- Fixed the pet feeding counter never incrementing: `MTH_FEED_Trace` was a no-op stub and `FOM_CORE_ATTEMPT_TRACKING_ENABLED` was `false`; both are now active.
- Fixed `FOM_AddFood` not clearing a food from `FOM_RemovedFoods` when the item belongs to the base diet list, which permanently banned it even after an explicit `/fom add`.
- Wired `FOM_ClearItemBans` into the `/fom add` command path: explicitly re-adding a food now clears it from `FOM_RemovedFoods`, FOM quarantine, and core exceptions in one step.
- Removed debug messages forgotten when releasing 1.2.
- Fixed SmartAmmo + **Quiver castbar conflict**: Quiver's castbar was disappearing when both addons were active. Root cause: MetaHunt SmartAmmo was re-installing its hooks every 0.5 seconds, constantly bumping Quiver off the top of the hook chain. Fixed by removing the repeated re-hook and adding a guard that only installs once (or when no other addon is on top).
## [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 010 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
+3 -1
View File
@@ -1,5 +1,5 @@
## Interface: 11200
## Version: 1.1.0
## Version: 1.3.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.
@@ -35,6 +35,8 @@ data\ds-minimap-sizes.lua
data\ds-unit-coords.lua
data\ds-creature-coords.lua
data\ds-beasts-families.lua
data\ds-beasts-families-dbc.lua
data\ds-beasts-skins.lua
data\ds-pet-spells.lua
data\ds-pet-spells-trainer.lua
data\ds-racial.lua
+3 -3
View File
@@ -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()
+2 -2
View File
@@ -112,7 +112,7 @@ end
local function AutoStrip_QueueDeferredRestore(reason)
if not AutoStrip_RestoreFrame then
AutoStrip_RestoreFrame = CreateFrame("Frame", "AutoStripRestoreFrame")
AutoStrip_RestoreFrame = CreateFrame("Frame", "MTH_AutoStripRestore")
if not AutoStrip_RestoreFrame then
return
end
@@ -316,7 +316,7 @@ 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")
+1 -1
View File
@@ -1,5 +1,5 @@
MTH_CONST = MTH_CONST or {}
MTH_CONST.version = MTH_CONST.version or "1.1.0"
MTH_CONST.version = MTH_CONST.version or "1.3.0"
MTH_CONST.WEAPON_TYPES = {
BOWS = "Bows",
+71 -8
View File
@@ -15,6 +15,7 @@ local MTH_FEED_TrackerFrame = nil
local MTH_FEED_ActiveCoreAttemptId = nil
local MTH_FEED_BootstrapFrame = nil
local MTH_FEED_NameToItemCache = {}
local MTH_FEED_InvalidateDietMapCache
local MTH_FEED_HARDCODED_LEVEL_RULES = {
{ minPetLevel = 1, minFoodLevel = 1 },
@@ -28,7 +29,10 @@ local MTH_FEED_HARDCODED_LEVEL_RULES = {
MTH_FEED_TRACE = false
local function MTH_FEED_Trace(message)
return
if not MTH_FEED_TRACE then return end
if type(DEFAULT_CHAT_FRAME) == "table" and DEFAULT_CHAT_FRAME.AddMessage then
DEFAULT_CHAT_FRAME:AddMessage("|cff88aaff[MTH-FeedTrack]|r " .. tostring(message))
end
end
local function MTH_FEED_Now()
@@ -460,6 +464,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 +473,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 +529,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
@@ -610,6 +640,7 @@ end
function MTH_FEED_ReinstallCoreTracking()
local ok = MTH_FEED_InstallCoreHooks()
MTH_FEED_EnsureTrackerFrame()
return ok and true or false
end
@@ -617,19 +648,17 @@ 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
frame:RegisterEvent("VARIABLES_LOADED")
frame:RegisterEvent("PLAYER_LOGIN")
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
frame:SetScript("OnEvent", function(self)
frame:SetScript("OnEvent", function()
MTH_FEED_ReinstallCoreTracking()
if self and self.UnregisterAllEvents then
self:UnregisterAllEvents()
self:SetScript("OnEvent", nil)
end
this:UnregisterAllEvents()
this:SetScript("OnEvent", nil)
end)
MTH_FEED_BootstrapFrame = frame
return frame
@@ -826,7 +855,16 @@ local function MTH_FEED_NormalizeReason(reason, rawMessage)
return "unknown"
end
local MTH_FEED_DietMapCache = nil
MTH_FEED_InvalidateDietMapCache = function()
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
@@ -841,6 +879,7 @@ local function MTH_FEED_GetDietByItemIdMap()
end
end
end
MTH_FEED_DietMapCache = map
return map
end
@@ -1423,6 +1462,30 @@ function MTH_FEED_GetSessionFeedCount(petId)
return tonumber(MTH_FEED_Runtime.sessionFeedsByPetId[petKey]) or 0
end
function MTH_FEED_DebugSessionFeeds()
local pet = MTH_FEED_GetCurrentPetContext()
local petId = pet and pet.petId or "(none)"
local count = MTH_FEED_GetSessionFeedCount(petId)
local hookOk = MTH_FEED_IsCoreHookInstalled()
local frameOk = MTH_FEED_TrackerFrame ~= nil
local activeId = tostring(MTH_FEED_ActiveCoreAttemptId or "nil")
if type(DEFAULT_CHAT_FRAME) == "table" and DEFAULT_CHAT_FRAME.AddMessage then
DEFAULT_CHAT_FRAME:AddMessage("|cff88aaff[MTH-FeedTrack]|r petId=" .. tostring(petId)
.. " feeds=" .. tostring(count)
.. " hookOk=" .. tostring(hookOk)
.. " frameOk=" .. tostring(frameOk)
.. " activeAttempt=" .. activeId)
local anyFeeds = false
for k, v in pairs(MTH_FEED_Runtime.sessionFeedsByPetId) do
anyFeeds = true
DEFAULT_CHAT_FRAME:AddMessage("|cff88aaff[MTH-FeedTrack]|r session petId='" .. tostring(k) .. "' count=" .. tostring(v))
end
if not anyFeeds then
DEFAULT_CHAT_FRAME:AddMessage("|cff88aaff[MTH-FeedTrack]|r (no session feeds recorded)")
end
end
end
function MTH_FEED_RecordUnknownFoodCandidate(payload)
local store = MTH_FEED_EnsureStore()
local itemId = payload and tonumber(payload.itemId) or nil
+70 -37
View File
@@ -1,5 +1,5 @@
MTH = MTH or {
version = "1.1.0",
version = "1.3.0",
name = "MetaHunt",
modules = {},
config = {},
@@ -44,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
@@ -55,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
@@ -192,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
@@ -565,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)
@@ -628,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
@@ -637,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
@@ -1295,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
@@ -1490,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
@@ -1520,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
+8 -12
View File
@@ -802,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")
@@ -813,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
@@ -861,19 +860,16 @@ function MTH_PT_InitBootstrap()
end
frame:RegisterEvent("PET_TRAINING_SHOW")
frame:RegisterEvent("CRAFT_SHOW")
frame:SetScript("OnEvent", function(self, evt)
evt = evt or event
if evt ~= "PET_TRAINING_SHOW" and evt ~= "CRAFT_SHOW" then
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, evt)
end
if self and self.UnregisterAllEvents then
self:UnregisterAllEvents()
self:SetScript("OnEvent", nil)
MTH_PT_OnEvent(MTH_PetTrainingFrame, event)
end
this:UnregisterAllEvents()
this:SetScript("OnEvent", nil)
MTH_PT_BootstrapFrame = nil
end)
MTH_PT_BootstrapFrame = frame
+1 -1
View File
@@ -331,7 +331,7 @@ function MTH_PS_InitService()
return
end
MTH_PS_Frame = CreateFrame("Frame", "MTHPetSpellbookEventFrame")
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")
+69 -41
View File
@@ -179,7 +179,7 @@ local function MTH_ST_EnsureDiagCopyFrame()
if MTH_ST_DiagCopyFrame then
return MTH_ST_DiagCopyFrame
end
local frame = CreateFrame("Frame", "MTHStableDiagCopyFrame", UIParent)
local frame = CreateFrame("Frame", "MTH_StableDiagCopy", UIParent)
if not frame then
return nil
end
@@ -219,11 +219,11 @@ local function MTH_ST_EnsureDiagCopyFrame()
copyButton:SetHeight(24)
copyButton:SetText("Select All")
local scrollFrame = CreateFrame("ScrollFrame", "MTHStableDiagCopyScroll", frame, "UIPanelScrollFrameTemplate")
local scrollFrame = CreateFrame("ScrollFrame", "MTH_StableDiagScroll", frame, "UIPanelScrollFrameTemplate")
scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 16, -48)
scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -36, 44)
local editBox = CreateFrame("EditBox", "MTHStableDiagCopyText", scrollFrame)
local editBox = CreateFrame("EditBox", "MTH_StableDiagText", scrollFrame)
editBox:SetMultiLine(true)
editBox:SetMaxLetters(999999)
editBox:SetFont("Fonts\\FRIZQT__.TTF", 11, "")
@@ -255,13 +255,13 @@ local function MTH_ST_EnsureDiagCopyFrame()
if UISpecialFrames then
local exists = false
for i = 1, table.getn(UISpecialFrames) do
if UISpecialFrames[i] == "MTHStableDiagCopyFrame" then
if UISpecialFrames[i] == "MTH_StableDiagCopy" then
exists = true
break
end
end
if not exists then
table.insert(UISpecialFrames, "MTHStableDiagCopyFrame")
table.insert(UISpecialFrames, "MTH_StableDiagCopy")
end
end
return frame
@@ -2494,15 +2494,6 @@ function MTH_PETS_GetRootStore()
end
local pets = MTH_CharSavedVariables.MTH_Pets
if pets._betaFreshStoreApplied ~= 1 then
pets.petTraining = {}
pets.trainScan = {}
pets.stableScan = {}
pets.currentPet = {}
pets.petStore = {}
pets._betaFreshStoreApplied = 1
pets.updatedAt = time()
end
if type(pets.petTraining) ~= "table" then
pets.petTraining = {}
end
@@ -2519,14 +2510,53 @@ function MTH_PETS_GetRootStore()
MTH_PETS_EnsureSchema(pets)
MTH_PETS_EnsurePetTrainingCompatibility(pets)
MTH_CharSavedVariables.petTraining = pets.petTraining
MTH_CharSavedVariables.trainScan = pets.trainScan
MTH_CharSavedVariables.stableScan = pets.stableScan
MTH_CharSavedVariables.petStore = pets.petStore
-- Migration: remove root-level duplicates that bloated SavedVariables
if pets._migrationCleanup ~= 2 then
MTH_PETS_RunSavedVarCleanup(pets)
pets._migrationCleanup = 2
end
return pets
end
function MTH_PETS_RunSavedVarCleanup(pets)
-- 1. Remove root-level duplicates (data lives inside MTH_Pets only)
if MTH_CharSavedVariables then
MTH_CharSavedVariables.petTraining = nil
MTH_CharSavedVariables.trainScan = nil
MTH_CharSavedVariables.stableScan = nil
MTH_CharSavedVariables.petStore = nil
end
-- 2. Purge pet-updated events (unbounded bloat)
local purged = 0
local stores = { pets.petStore and pets.petStore.activeById, pets.petStore and pets.petStore.historyById }
for _, index in ipairs(stores) do
if type(index) == "table" then
for petId, row in pairs(index) do
if type(row) == "table" and type(row.events) == "table" then
local kept = {}
for _, evt in ipairs(row.events) do
if type(evt) == "table" and evt.type ~= "pet-updated" then
table.insert(kept, evt)
else
purged = purged + 1
end
end
row.events = kept
end
end
end
end
-- 3. Remove stale _betaFreshStoreApplied flag
pets._betaFreshStoreApplied = nil
if purged > 0 and MTH and MTH.Print then
MTH:Print("Cleaned up " .. tostring(purged) .. " stale pet-update records from SavedVariables.", "debug")
end
end
function MTH_PETS_RefreshCurrentPet()
local pets = type(MTH_PETS_GetRootStore) == "function" and MTH_PETS_GetRootStore() or nil
if type(pets) ~= "table" then
@@ -2624,15 +2654,17 @@ function MTH_PETS_RefreshCurrentPet()
row.events = {}
end
local eventType = "pet-updated"
if created and (not hadPetBeforeRefresh) then
eventType = "pet-acquired"
local eventType = "pet-acquired"
if not (created and (not hadPetBeforeRefresh)) then
if cp.id ~= nil and previousCurrentId ~= nil and cp.id ~= previousCurrentId then
eventType = "pet-swapped"
else
eventType = nil -- routine update, don't record
end
end
local shouldRecordLifecycleEvent = (eventType == "pet-acquired")
or (cp.id ~= nil and previousCurrentId ~= nil and cp.id ~= previousCurrentId)
local eventContext = nil
if shouldRecordLifecycleEvent then
if eventType then
eventContext = MTH_PETS_CaptureContext()
table.insert(row.events, {
type = eventType,
@@ -3167,7 +3199,7 @@ end
local function MTH_ST_QueueDeferredStableScan(reason, delaySeconds)
if not MTH_ST_DeferredStableScanFrame then
MTH_ST_DeferredStableScanFrame = CreateFrame("Frame", "MTHDeferredStableScanFrame")
MTH_ST_DeferredStableScanFrame = CreateFrame("Frame", "MTH_DeferredStableScan")
if not MTH_ST_DeferredStableScanFrame then
MTH_ST_TraceRecord("MTH_ST_QueueDeferredStableScan", "scan", "frame-create-failed")
return false
@@ -3270,9 +3302,8 @@ local function MTH_PETS_HandleUnitPetTransition(source)
row.events = {}
end
local eventType = (not hadPet) and "pet-acquired" or "pet-updated"
if eventType == "pet-updated" and source == "UNIT_PET" and MTH_ST_IsStableFrameOpen() then
MTH_ST_PrintStableDiag("swap history-skip reason=stable-open")
else
-- Only record lifecycle events (acquire, rename, abandon), not routine updates
if eventType ~= "pet-updated" then
table.insert(row.events, {
type = eventType,
source = source or transitionSource,
@@ -4120,7 +4151,7 @@ function MTH_ST_InitService()
return
end
MTH_PetLifecycleEventFrame = CreateFrame("Frame", "MTHPetLifecycleEventFrame")
MTH_PetLifecycleEventFrame = CreateFrame("Frame", "MTH_PetLifecycleEvent")
MTH_PetLifecycleEventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
MTH_PetLifecycleEventFrame:RegisterEvent("UNIT_PET")
MTH_PetLifecycleEventFrame:RegisterEvent("PET_BAR_UPDATE")
@@ -4153,29 +4184,26 @@ function MTH_ST_InitBootstrap()
return
end
local frame = CreateFrame("Frame", "MTHPetLifecycleBootstrapFrame")
local frame = CreateFrame("Frame", "MTH_PetLifecycleBoot")
if not frame then
return
end
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
frame:RegisterEvent("PET_STABLE_SHOW")
frame:RegisterEvent("PET_STABLE_UPDATE")
frame:SetScript("OnEvent", function(self, evt)
evt = evt or event
if evt ~= "PLAYER_ENTERING_WORLD" and evt ~= "PET_STABLE_SHOW" and evt ~= "PET_STABLE_UPDATE" then
frame:SetScript("OnEvent", function()
if event ~= "PLAYER_ENTERING_WORLD" and event ~= "PET_STABLE_SHOW" and event ~= "PET_STABLE_UPDATE" then
return
end
if evt == "PET_STABLE_SHOW" or evt == "PET_STABLE_UPDATE" then
MTH_ST_PrintStableDiag("bootstrap evt=" .. tostring(evt) .. " phase=begin")
if event == "PET_STABLE_SHOW" or event == "PET_STABLE_UPDATE" then
MTH_ST_PrintStableDiag("bootstrap evt=" .. tostring(event) .. " phase=begin")
end
MTH_ST_InitService()
if evt == "PET_STABLE_SHOW" or evt == "PET_STABLE_UPDATE" then
MTH_ST_PrintStableDiag("bootstrap evt=" .. tostring(evt) .. " phase=end action=no-scan")
end
if self and self.UnregisterAllEvents then
self:UnregisterAllEvents()
self:SetScript("OnEvent", nil)
if event == "PET_STABLE_SHOW" or event == "PET_STABLE_UPDATE" then
MTH_ST_PrintStableDiag("bootstrap evt=" .. tostring(event) .. " phase=end action=no-scan")
end
this:UnregisterAllEvents()
this:SetScript("OnEvent", nil)
MTH_PetLifecycleBootstrapFrame = nil
end)
MTH_PetLifecycleBootstrapFrame = frame
+57 -9
View File
@@ -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
@@ -301,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
@@ -312,16 +352,24 @@ function SlashCmdList.MTH(msg, editbox)
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 == "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.")
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
+7 -10
View File
@@ -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,16 +366,13 @@ 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
MTH_DF_InstallHooks()
MTH_DebugFrame:Initialize()
if MTH and MTH.Print then
local mode = MTH_DF_IsGlobalCaptureEnabled() and "legacy-global" or "safe-local"
MTH:Print("=== MetaHunt Debug Frame Initialized (" .. mode .. ") ===", "debug")
end
end
end)
+430
View File
@@ -0,0 +1,430 @@
-- hunterbook-model-viewer.lua
-- Embeds a small 3D creature skin preview at the bottom of the Beast Lore /
-- Abilities inspector. Clicking it opens a larger draggable popup with
-- < / > navigation through all skin variants of the selected family.
--
-- Uses MTH_DS_BeastSkins[familyName] generated by .tools/generators/gen_beast_skins.py
-- Skin rendering: PlayerModel:SetUnit(CreatureDisplayInfo.ID)
local function mv_log(msg)
if MTH_DebugFrame and type(MTH_DebugFrame.AddInfo) == "function" then
MTH_DebugFrame:AddInfo("[MV] " .. tostring(msg))
end
end
local function mv_err(msg)
if MTH_DebugFrame and type(MTH_DebugFrame.AddError) == "function" then
MTH_DebugFrame:AddError("[MV] " .. tostring(msg))
end
end
local MTH_MV = {
inited = false,
family = nil,
skins = {},
index = 1,
facing = 0.6,
rotating = false,
rotateLastX = 0,
keepPopup = false,
skinBeastRows = {},
skinListEmpty = nil,
-- small preview (parented to book frame, anchored below MTH_BOOK_DetailBackdrop)
previewFrame = nil,
previewModel = nil,
-- popup
popup = nil,
popupModel = nil,
popupTitle = nil,
popupSkinLabel = nil,
}
-- ---------------------------------------------------------------------------
-- Internal
-- ---------------------------------------------------------------------------
local function MTH_MV_ApplyModel(model, skinId)
if not model or not skinId then
mv_err("ApplyModel: nil model or skinId model="..tostring(model).." id="..tostring(skinId))
return
end
mv_log("ApplyModel id="..tostring(skinId))
model:SetUnit(skinId)
model:SetPosition(0, 0, 0)
model:SetModelScale(1)
local useFacing = (MTH_MV.popupModel ~= nil and model == MTH_MV.popupModel)
model:SetFacing(useFacing and MTH_MV.facing or 0.6)
end
local MTH_MV_BuildSkinBeastList -- forward declaration
local function MTH_MV_DisplayCurrent()
local skin = MTH_MV.skins[MTH_MV.index]
if not skin then return end
local n = table.getn(MTH_MV.skins)
MTH_MV_ApplyModel(MTH_MV.previewModel, skin.id)
MTH_MV_ApplyModel(MTH_MV.popupModel, skin.id)
local indexStr = tostring(MTH_MV.index) .. " / " .. tostring(n)
if MTH_MV.popupSkinLabel then
MTH_MV.popupSkinLabel:SetText(indexStr .. " · " .. tostring(skin.tex or ""))
end
MTH_MV_BuildSkinBeastList(skin.id)
end
MTH_MV_BuildSkinBeastList = function(skinId)
for i = 1, table.getn(MTH_MV.skinBeastRows) do
MTH_MV.skinBeastRows[i]:Hide()
end
if MTH_MV.skinListEmpty then MTH_MV.skinListEmpty:Hide() end
if not skinId or not MTH_DS_Beasts then return end
local matches = {}
for npcId, beast in pairs(MTH_DS_Beasts) do
if type(beast) == "table" and beast.skinId == skinId then
local nm = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(npcId, beast.name)) or beast.name
table.insert(matches, { id = npcId, name = nm or "?", lvl = tostring(beast.lvl or "?") })
end
end
table.sort(matches, function(a, b) return (a.name or "") < (b.name or "") end)
local maxRows = table.getn(MTH_MV.skinBeastRows)
local shown = 0
for i = 1, table.getn(matches) do
if shown >= maxRows then break end
shown = shown + 1
local row = MTH_MV.skinBeastRows[shown]
row._npcId = matches[i].id
row.nameText:SetText(matches[i].name)
row.lvlText:SetText(matches[i].lvl)
row:Show()
end
if shown == 0 and MTH_MV.skinListEmpty then
MTH_MV.skinListEmpty:Show()
end
end
local function MTH_MV_Init()
if MTH_MV.inited then mv_log("Init: already done") return end
mv_log("Init: starting")
local backdrop = getglobal("MTH_BOOK_DetailBackdrop")
if not backdrop then
mv_err("Init: MTH_BOOK_DetailBackdrop not found")
return
end
mv_log("Init: backdrop found, creating previewFrame")
MTH_MV.inited = true
-- ----------------------------------------------------------------
-- Model preview container (sibling of inspector, full column width)
-- Hardcoded offset from book frame TOPLEFT: x=608 (right column),
-- y = -(166 inspector_top + 178 inspector_h + 6 gap) = -350
-- ----------------------------------------------------------------
local bookFrame = backdrop:GetParent()
MTH_MV.previewFrame = CreateFrame("Frame", "MTH_BOOK_SkinPreview", bookFrame)
MTH_MV.previewFrame:SetWidth(136)
MTH_MV.previewFrame:SetHeight(136)
MTH_MV.previewFrame:SetPoint("TOPLEFT", bookFrame, "TOPLEFT", 608, -384)
MTH_MV.previewFrame:SetBackdrop({
bgFile = "Interface\\Buttons\\WHITE8X8",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 12,
insets = {left = 3, right = 3, top = 3, bottom = 3},
})
MTH_MV.previewFrame:SetBackdropColor(0, 0, 0, 0.7)
MTH_MV.previewFrame:SetBackdropBorderColor(0.35, 0.35, 0.35, 0.8)
MTH_MV.previewFrame:Hide()
mv_log("Init: previewFrame created, creating PlayerModel")
-- PlayerModel fills the inner area
MTH_MV.previewModel = CreateFrame("PlayerModel", nil, MTH_MV.previewFrame)
MTH_MV.previewModel:SetPoint("TOPLEFT", MTH_MV.previewFrame, "TOPLEFT", 3, -3)
MTH_MV.previewModel:SetPoint("BOTTOMRIGHT", MTH_MV.previewFrame, "BOTTOMRIGHT", -3, 3)
-- Invisible click overlay → opens popup
local previewBtn = CreateFrame("Button", nil, MTH_MV.previewFrame)
previewBtn:SetAllPoints(MTH_MV.previewFrame)
previewBtn:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square")
previewBtn:SetScript("OnClick", function()
MTH_BOOK_ModelViewer_OpenPopup()
end)
previewBtn:SetScript("OnEnter", function()
GameTooltip:SetOwner(MTH_MV.previewFrame, "ANCHOR_LEFT")
GameTooltip:AddLine("Click to open skin viewer", 1, 1, 1)
GameTooltip:Show()
end)
previewBtn:SetScript("OnLeave", function()
GameTooltip:Hide()
end)
mv_log("Init: previewModel created, creating popup")
-- ----------------------------------------------------------------
-- Popup frame (wider: left side = model viewer, right = beast list)
-- ----------------------------------------------------------------
local popup = CreateFrame("Frame", "MTH_BOOK_ModelPopup", UIParent)
popup:SetWidth(490)
popup:SetHeight(320)
popup:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
popup:SetFrameStrata("TOOLTIP")
popup:SetToplevel(true)
popup:SetMovable(true)
popup:EnableMouse(true)
popup:RegisterForDrag("LeftButton")
popup:SetScript("OnDragStart", function() this:StartMoving() end)
popup:SetScript("OnDragStop", function() this:StopMovingOrSizing() end)
popup:SetScript("OnHide", function() MTH_MV.rotating = false end)
popup:Hide()
popup:SetBackdrop({
bgFile = "Interface\\Buttons\\WHITE8X8",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true, tileSize = 32, edgeSize = 32,
insets = {left = 11, right = 12, top = 12, bottom = 11},
})
popup:SetBackdropColor(0.05, 0.05, 0.08, 0.95)
-- Large model background (left side, x=20)
local modelBg = CreateFrame("Frame", nil, popup)
modelBg:SetWidth(224)
modelBg:SetHeight(226)
modelBg:SetPoint("TOPLEFT", popup, "TOPLEFT", 20, -42)
modelBg:SetBackdrop({
bgFile = "Interface\\Buttons\\WHITE8X8",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 12,
insets = {left = 3, right = 3, top = 3, bottom = 3},
})
modelBg:SetBackdropColor(0, 0, 0, 0.85)
modelBg:SetBackdropBorderColor(0.35, 0.35, 0.35, 0.9)
MTH_MV.popupModel = CreateFrame("PlayerModel", "MTH_BOOK_ModelPopupModel", modelBg)
MTH_MV.popupModel:SetPoint("TOPLEFT", modelBg, "TOPLEFT", 3, -3)
MTH_MV.popupModel:SetPoint("BOTTOMRIGHT", modelBg, "BOTTOMRIGHT", -3, 3)
-- Mouse rotation: drag on the black model area rotates; outside drags the popup
MTH_MV.popupModel:EnableMouse(true)
MTH_MV.popupModel:SetScript("OnMouseDown", function()
MTH_MV.rotating = true
MTH_MV.rotateLastX = GetCursorPosition()
end)
MTH_MV.popupModel:SetScript("OnMouseUp", function()
MTH_MV.rotating = false
end)
MTH_MV.popupModel:SetScript("OnUpdate", function()
if not MTH_MV.rotating then return end
local cx = GetCursorPosition()
local dx = cx - MTH_MV.rotateLastX
MTH_MV.rotateLastX = cx
if dx ~= 0 then
MTH_MV.facing = MTH_MV.facing - dx * 0.03
MTH_MV.popupModel:SetFacing(MTH_MV.facing)
end
end)
-- Title (family name) anchored above the model
MTH_MV.popupTitle = popup:CreateFontString(nil, "OVERLAY", "GameFontNormal")
MTH_MV.popupTitle:SetPoint("TOP", modelBg, "TOP", 0, 18)
MTH_MV.popupTitle:SetTextColor(1, 0.82, 0)
MTH_MV.popupTitle:SetText("Skin Viewer")
-- Close [X] button
local closeBtn = CreateFrame("Button", nil, popup)
closeBtn:SetWidth(22)
closeBtn:SetHeight(22)
closeBtn:SetPoint("TOPRIGHT", popup, "TOPRIGHT", -10, -10)
closeBtn:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square")
local closeLbl = closeBtn:CreateFontString(nil, "OVERLAY", "GameFontNormal")
closeLbl:SetAllPoints(closeBtn)
closeLbl:SetText("X")
closeLbl:SetTextColor(0.9, 0.9, 0.9)
closeBtn:SetScript("OnClick", function() this:GetParent():Hide() end)
-- "Unique Appearance" badge removed (inline texture syntax unsupported in this client)
-- Nav: ◀ label ▶ (kept within the left 264px area)
local prevBtn = CreateFrame("Button", nil, popup, "UIPanelButtonTemplate")
prevBtn:SetWidth(28)
prevBtn:SetHeight(20)
prevBtn:SetPoint("BOTTOMLEFT", popup, "BOTTOMLEFT", 14, 14)
prevBtn:SetText("<")
prevBtn:SetScript("OnClick", function()
local n = table.getn(MTH_MV.skins)
if n < 1 then return end
MTH_MV.index = MTH_MV.index - 1
if MTH_MV.index < 1 then MTH_MV.index = n end
MTH_MV_DisplayCurrent()
end)
local nextBtn = CreateFrame("Button", nil, popup, "UIPanelButtonTemplate")
nextBtn:SetWidth(28)
nextBtn:SetHeight(20)
nextBtn:SetPoint("BOTTOMLEFT", popup, "BOTTOMLEFT", 222, 14)
nextBtn:SetText(">")
nextBtn:SetScript("OnClick", function()
local n = table.getn(MTH_MV.skins)
if n < 1 then return end
MTH_MV.index = MTH_MV.index + 1
if MTH_MV.index > n then MTH_MV.index = 1 end
MTH_MV_DisplayCurrent()
end)
MTH_MV.popupSkinLabel = popup:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
MTH_MV.popupSkinLabel:SetPoint("BOTTOMLEFT", prevBtn, "BOTTOMRIGHT", 4, 0)
MTH_MV.popupSkinLabel:SetPoint("BOTTOMRIGHT", nextBtn, "BOTTOMLEFT", -4, 0)
MTH_MV.popupSkinLabel:SetJustifyH("CENTER")
MTH_MV.popupSkinLabel:SetTextColor(0.9, 0.9, 0.9)
-- ---------------------------------------------------------------
-- Right panel: vertical divider + beast list
-- ---------------------------------------------------------------
local divider = popup:CreateTexture(nil, "ARTWORK")
divider:SetTexture("Interface\\Buttons\\WHITE8X8")
divider:SetVertexColor(0.35, 0.35, 0.35, 0.8)
divider:SetPoint("TOPLEFT", popup, "TOPLEFT", 270, -36)
divider:SetPoint("BOTTOMLEFT", popup, "BOTTOMLEFT", 270, 12)
divider:SetWidth(1)
local listHeader = popup:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
listHeader:SetPoint("TOPLEFT", popup, "TOPLEFT", 278, -18)
listHeader:SetTextColor(1, 0.82, 0)
listHeader:SetText("Beasts with this skin")
local listSep = popup:CreateTexture(nil, "ARTWORK")
listSep:SetTexture("Interface\\Buttons\\WHITE8X8")
listSep:SetVertexColor(0.35, 0.35, 0.35, 0.6)
listSep:SetPoint("TOPLEFT", popup, "TOPLEFT", 278, -30)
listSep:SetPoint("TOPRIGHT", popup, "TOPRIGHT", -10, -30)
listSep:SetHeight(1)
MTH_MV.skinListEmpty = popup:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
MTH_MV.skinListEmpty:SetPoint("TOPLEFT", popup, "TOPLEFT", 278, -38)
MTH_MV.skinListEmpty:SetTextColor(0.5, 0.5, 0.5)
MTH_MV.skinListEmpty:SetText("\226\128\148")
MTH_MV.skinListEmpty:Hide()
-- Beast rows (14 max)
local ROW_X = 278
local ROW_START = -36
local ROW_H = 17
local MAX_ROWS = 14
for i = 1, MAX_ROWS do
local row = CreateFrame("Button", nil, popup)
row:SetPoint("TOPLEFT", popup, "TOPLEFT", ROW_X, ROW_START - (i - 1) * ROW_H)
row:SetWidth(200)
row:SetHeight(ROW_H - 1)
row._npcId = nil
local hl = row:CreateTexture(nil, "HIGHLIGHT")
hl:SetAllPoints(row)
hl:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
hl:SetBlendMode("ADD")
hl:SetAlpha(0.35)
row.nameText = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
row.nameText:SetPoint("LEFT", row, "LEFT", 0, 0)
row.nameText:SetWidth(158)
row.nameText:SetJustifyH("LEFT")
row.lvlText = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
row.lvlText:SetPoint("LEFT", row, "LEFT", 160, 0)
row.lvlText:SetWidth(38)
row.lvlText:SetJustifyH("LEFT")
row.lvlText:SetTextColor(0.7, 0.7, 0.7)
row:SetScript("OnClick", function()
if this._npcId and type(MTH_BOOK_JumpToBeastById) == "function" then
MTH_MV.keepPopup = true
MTH_BOOK_JumpToBeastById(this._npcId)
MTH_MV.keepPopup = false
end
end)
row:Hide()
MTH_MV.skinBeastRows[i] = row
end
MTH_MV.popup = popup
mv_log("Init: complete")
end
-- ---------------------------------------------------------------------------
-- Public API
-- ---------------------------------------------------------------------------
function MTH_BOOK_ModelViewer_SetFamily(family, skinId)
mv_log("SetFamily: "..tostring(family).." skinId="..tostring(skinId))
MTH_MV_Init()
if not MTH_MV.inited then mv_err("SetFamily: init failed") return end
local skins = MTH_DS_BeastSkins and type(MTH_DS_BeastSkins) == "table" and MTH_DS_BeastSkins[family]
if not skins or table.getn(skins) == 0 then
mv_log("SetFamily: no skins for "..tostring(family).." DS type="..type(MTH_DS_BeastSkins or false))
MTH_BOOK_ModelViewer_Clear()
return
end
-- Filter to only skins used by at least one tameable beast
local usedSkinIds = {}
if MTH_DS_Beasts then
for _, beast in pairs(MTH_DS_Beasts) do
if type(beast) == "table" and beast.skinId then
usedSkinIds[beast.skinId] = true
end
end
end
local filteredSkins = {}
for i = 1, table.getn(skins) do
if usedSkinIds[skins[i].id] then
table.insert(filteredSkins, skins[i])
end
end
if table.getn(filteredSkins) == 0 then
MTH_BOOK_ModelViewer_Clear()
return
end
mv_log("SetFamily: "..table.getn(filteredSkins).." tameable skins (filtered from "..table.getn(skins)..")")
MTH_MV.family = family
MTH_MV.skins = filteredSkins
MTH_MV.facing = 0.6
-- If we have a specific skinId, jump to the matching skin entry.
MTH_MV.index = 1
if skinId then
for i = 1, table.getn(filteredSkins) do
if filteredSkins[i].id == skinId then
MTH_MV.index = i
mv_log("SetFamily: skinId "..skinId.." matched skin index "..i)
break
end
end
end
if MTH_MV.popupTitle then
MTH_MV.popupTitle:SetText(tostring(family) .. " — Skins")
end
MTH_MV_DisplayCurrent()
if MTH_MV.previewFrame then MTH_MV.previewFrame:Show() end
MTH_MV_DisplayCurrent()
end
function MTH_BOOK_ModelViewer_Clear()
mv_log("Clear")
if MTH_MV.previewFrame then MTH_MV.previewFrame:Hide() end
if not MTH_MV.keepPopup then
if MTH_MV.popup and MTH_MV.popup:IsShown() then MTH_MV.popup:Hide() end
end
MTH_MV.family = nil
MTH_MV.skins = {}
MTH_MV.index = 1
end
function MTH_BOOK_ModelViewer_OpenPopup()
mv_log("OpenPopup skins="..table.getn(MTH_MV.skins))
MTH_MV_Init()
if not MTH_MV.popup then mv_err("OpenPopup: no popup frame") return end
if table.getn(MTH_MV.skins) == 0 then mv_log("OpenPopup: no skins") return end
MTH_MV.popup:Show()
MTH_MV.popup:Raise()
MTH_MV_DisplayCurrent()
end
+9 -8
View File
@@ -2,17 +2,18 @@ if type(MTH_HUNTERBOOK_TABS) ~= "table" then MTH_HUNTERBOOK_TABS = {} end
MTH_HUNTERBOOK_TABS.pets = {
headerLabel = "Beasts",
columnLabels = { "ID", "Lvl", "Family", "Name", "Abilities", "Zone", "R", "E", "U" },
columnLabels = { "ID", "Lvl", "Fam", "Name", "Abilities", "Zone", "R", "E", "U", "AS" },
columnLayout = {
{ x = 8, width = 28, align = "LEFT" },
{ x = 38, width = 30, align = "LEFT" },
{ x = 68, width = 74, align = "LEFT" },
{ x = 142, width = 130, align = "LEFT" },
{ x = 272, width = 180, align = "LEFT" },
{ x = 452, width = 68, align = "LEFT" },
{ x = 520, width = 10, align = "CENTER" },
{ x = 532, width = 10, align = "CENTER" },
{ x = 544, width = 10, align = "CENTER" },
{ x = 68, width = 18, align = "LEFT" },
{ x = 88, width = 130, align = "LEFT" },
{ x = 220, width = 148, align = "LEFT" },
{ x = 370, width = 80, align = "LEFT" },
{ x = 452, width = 14, align = "CENTER" },
{ x = 468, width = 14, align = "CENTER" },
{ x = 484, width = 14, align = "CENTER" },
{ x = 500, width = 54, align = "LEFT" },
},
}
+18 -3
View File
@@ -13,7 +13,6 @@ MTH_HUNTERBOOK_TABS.families = {
}
local function MTH_BOOKTAB_FamiliesTrace(message)
return
end
local function MTH_BOOKTAB_FamiliesSafeLower(value)
@@ -83,6 +82,7 @@ function MTH_BOOKTAB_BuildFamiliesRows()
for familyName, familyRow in pairs(families) do
if type(familyRow) == "table" then
MTH_BOOKTAB_FamiliesTrace("BUILD " .. tostring(familyName) .. " icon=" .. tostring(familyRow.icon))
local abilities = {}
local seen = {}
@@ -191,6 +191,7 @@ function MTH_BOOKTAB_BuildFamiliesRows()
table.insert(results, {
family = tostring(familyName),
icon = familyRow.icon or nil,
named = tonumber(familyRow.named) or 0,
coords = tonumber(familyRow.coords) or 0,
abilities = abilities,
@@ -289,9 +290,15 @@ function MTH_BOOKTAB_EnsureFamiliesUI()
row:SetPoint("TOPRIGHT", ui.rows[i - 1], "BOTTOMRIGHT", 0, -1)
end
row.familyIcon = row:CreateTexture(nil, "ARTWORK")
row.familyIcon:SetPoint("LEFT", row, "LEFT", 4, 0)
row.familyIcon:SetWidth(16)
row.familyIcon:SetHeight(16)
row.familyIcon:Hide()
row.family = row:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
row.family:SetPoint("LEFT", row, "LEFT", 4, 0)
row.family:SetWidth(106)
row.family:SetPoint("LEFT", row, "LEFT", 24, 0)
row.family:SetWidth(88)
row.family:SetJustifyH("LEFT")
row.named = row:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
@@ -393,6 +400,14 @@ function MTH_BOOKTAB_RenderFamiliesList()
if row then
rowFrame:Show()
rowFrame.family:SetText(tostring(row.family or "-"))
local familyIconPath = row.icon and MTH_BOOK_ResolveIconPath and MTH_BOOK_ResolveIconPath(row.icon) or nil
MTH_BOOKTAB_FamiliesTrace("RENDER " .. tostring(row.family) .. " icon=" .. tostring(row.icon) .. " path=" .. tostring(familyIconPath))
if familyIconPath then
rowFrame.familyIcon:SetTexture(familyIconPath)
rowFrame.familyIcon:Show()
else
rowFrame.familyIcon:Hide()
end
rowFrame.named:SetText(tostring(row.named or 0))
rowFrame.coords:SetText(tostring(row.coords or 0))
rowFrame.diet:SetText(tostring(row.dietText or "-"))
+1 -1
View File
@@ -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
+82 -65
View File
@@ -150,7 +150,7 @@ local function MTH_HB_RequireOpenDeps()
return true
end
local MTH_BOOK_MAX_COLS = 9
local MTH_BOOK_MAX_COLS = 10
local MTH_BOOK_MAX_ROWS = 20
local MTH_BOOK_PetFamilyOptions = {
@@ -222,7 +222,8 @@ local MTH_BOOK_CONTENT_LAYOUT_DEFAULT = {
detailX = 608,
detailY = -166,
detailW = 136,
detailH = 324,
detailH = 208,
detailTextH = 192, -- inspector text only; model viewer sits below in its own frame
}
local MTH_BOOK_CONTENT_LAYOUT_ITEMS = {
@@ -328,7 +329,7 @@ local function MTH_BOOK_ApplyContentLayoutForMode()
detailText:ClearAllPoints()
detailText:SetPoint("TOPLEFT", detailParent, "TOPLEFT", 6, -6)
detailText:SetWidth(layout.detailW - 12)
detailText:SetHeight(layout.detailH - 12)
detailText:SetHeight(layout.detailTextH or (layout.detailH - 12))
end
local sliderHeight = layout.listH - 32
@@ -1281,6 +1282,7 @@ local function MTH_BOOK_GetSortKey(entry, col)
if col == 7 then return traits.rare and 1 or 0 end
if col == 8 then return traits.elite and 1 or 0 end
if col == 9 then return traits.unique and 1 or 0 end
if col == 10 then return tonumber(beast.attackSpeed) or 0 end
end
if MTH_BOOK_STATE.mode == "abilities" then
@@ -2994,9 +2996,14 @@ end
function MTH_BOOK_UpdateDetail()
local detail = getglobal("MTH_BOOK_DetailBackdropDetailText")
if not detail then return end
-- Hide model skin preview when not in a beast-list mode
if MTH_BOOK_STATE.mode ~= "pets" and MTH_BOOK_STATE.mode ~= "abilities" then
if MTH_BOOK_ModelViewer_Clear then MTH_BOOK_ModelViewer_Clear() end
end
local petTop = MTH_BOOK_STATE.petUI and MTH_BOOK_STATE.petUI.detailTop
local petBottom = MTH_BOOK_STATE.petUI and MTH_BOOK_STATE.petUI.detailBottom
if not MTH_BOOK_STATE.selectedEntry then
if MTH_BOOK_ModelViewer_Clear then MTH_BOOK_ModelViewer_Clear() end
if MTH_BOOK_STATE.mode == "petabilities" then
if petTop and petBottom then
MTH_BOOK_SetDetailText(petTop, "|cFFFFD100Baseline|r\n\nSelect a spell baseline from the left list.")
@@ -3090,26 +3097,7 @@ function MTH_BOOK_UpdateDetail()
MTH_BOOK_AddDetailKV(lines, "Rare", beast.rare and "Yes" or "No")
MTH_BOOK_AddDetailKV(lines, "Abilities", beast.abilities or "None")
local fam = MTH_DS_Families and beast.family and MTH_DS_Families[beast.family]
if fam and fam.abilities and table.getn(fam.abilities) > 0 then
MTH_BOOK_AddDetailSection(lines, "Family Pool")
table.insert(lines, " " .. table.concat(fam.abilities, ", "))
end
if beast.coords and table.getn(beast.coords) > 0 then
MTH_BOOK_AddDetailSection(lines, "Locations")
for i = 1, table.getn(beast.coords) do
local c = beast.coords[i]
if c then
local x = tonumber(c[1] or 0) or 0
local y = tonumber(c[2] or 0) or 0
local zoneId = c[3]
table.insert(lines, string.format(" - %s (%.1f, %.1f)", MTH_BOOK_GetZoneName(zoneId), x, y))
end
if i >= 8 then break end
end
end
if MTH_BOOK_ModelViewer_SetFamily then MTH_BOOK_ModelViewer_SetFamily(beast.family, beast.skinId) end
MTH_BOOK_SetDetailText(detail, table.concat(lines, "\n"))
MTH_BOOK_UpdateOpenMapButton()
return
@@ -3145,20 +3133,7 @@ function MTH_BOOK_UpdateDetail()
end
MTH_BOOK_AddDetailKV(lines, "Rare", beast.rare and "Yes" or "No")
if beast.coords and table.getn(beast.coords) > 0 then
MTH_BOOK_AddDetailSection(lines, "Locations")
for i = 1, table.getn(beast.coords) do
local c = beast.coords[i]
if c then
local x = tonumber(c[1] or 0) or 0
local y = tonumber(c[2] or 0) or 0
local zoneId = c[3]
table.insert(lines, string.format(" - %s (%.1f, %.1f)", MTH_BOOK_GetZoneName(zoneId), x, y))
end
if i >= 8 then break end
end
end
if MTH_BOOK_ModelViewer_SetFamily then MTH_BOOK_ModelViewer_SetFamily(beast.family, beast.skinId) end
MTH_BOOK_SetDetailText(detail, table.concat(lines, "\n"))
MTH_BOOK_UpdateOpenMapButton()
return
@@ -3467,7 +3442,7 @@ local function MTH_BOOK_GetColumnLabels()
return tabDef.columnLabels
end
if MTH_BOOK_STATE.mode == "pets" then
return { "ID", "Lvl", "Family", "Name", "Abilities", "Zone", "R", "E", "U" }
return { "ID", "Lvl", "Fam", "Name", "Abilities", "Zone", "R", "E", "U", "AS" }
elseif MTH_BOOK_STATE.mode == "petabilities" then
return { "Ability Name", "Ranks", "Families" }
elseif MTH_BOOK_STATE.mode == "stable" then
@@ -3493,13 +3468,14 @@ local function MTH_BOOK_GetColumnLayout()
return {
{ x = 8, width = 28, align = "LEFT" },
{ x = 38, width = 30, align = "LEFT" },
{ x = 68, width = 74, align = "LEFT" },
{ x = 142, width = 130, align = "LEFT" },
{ x = 272, width = 180, align = "LEFT" },
{ x = 452, width = 68, align = "LEFT" },
{ x = 520, width = 10, align = "CENTER" },
{ x = 532, width = 10, align = "CENTER" },
{ x = 544, width = 10, align = "CENTER" },
{ x = 68, width = 18, align = "LEFT" },
{ x = 88, width = 130, align = "LEFT" },
{ x = 220, width = 148, align = "LEFT" },
{ x = 370, width = 80, align = "LEFT" },
{ x = 452, width = 14, align = "CENTER" },
{ x = 468, width = 14, align = "CENTER" },
{ x = 484, width = 14, align = "CENTER" },
{ x = 500, width = 54, align = "LEFT" },
}
elseif MTH_BOOK_STATE.mode == "petabilities" then
return {
@@ -3660,6 +3636,19 @@ local function MTH_BOOK_ApplyColumnLayout(parent)
btn.cols[itemNameColumn]:SetPoint("LEFT", btn, "LEFT", itemNameLayout.x + 12, 0)
btn.cols[itemNameColumn]:SetWidth(itemNameLayout.width - 16)
end
elseif MTH_BOOK_STATE.mode == "families" and layout[1] then
local familyCol = layout[1]
btn.itemIcon:ClearAllPoints()
btn.itemIcon:SetPoint("LEFT", btn, "LEFT", familyCol.x, 0)
if btn.cols and btn.cols[1] then
btn.cols[1]:ClearAllPoints()
btn.cols[1]:SetPoint("LEFT", btn, "LEFT", familyCol.x + 18, 0)
btn.cols[1]:SetWidth(familyCol.width - 18)
end
elseif MTH_BOOK_STATE.mode == "pets" and layout[3] then
local famCol = layout[3]
btn.itemIcon:ClearAllPoints()
btn.itemIcon:SetPoint("LEFT", btn, "LEFT", famCol.x, 0)
else
btn.itemIcon:Hide()
end
@@ -3671,7 +3660,7 @@ end
local function MTH_BOOK_GetRowValues(entry)
if MTH_BOOK_STATE.mode == "pets" then
local beast = MTH_DS_Beasts and MTH_DS_Beasts[entry]
if not beast then return { "", "", "", "", "", "", "", "", "" } end
if not beast then return { "", "", "", "", "", "", "", "", "", "" } end
local beastDisplayName = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(entry, beast.name)) or beast.name
local traits = MTH_BOOK_ParseBeastTraits(beast)
local abilities = MTH_BOOK_GetBeastAbilitiesSummary(beast)
@@ -3679,13 +3668,14 @@ local function MTH_BOOK_GetRowValues(entry)
return {
"|cFF33CCFF" .. tostring(entry) .. "|r",
tostring(beast.lvl or "?"),
tostring(beast.family or "?"),
"", -- family icon rendered separately
tostring(beastDisplayName or "Unknown"),
abilities,
zone,
(traits.rare and "R" or ""),
(traits.elite and "E" or ""),
(traits.unique and "U" or ""),
tostring(beast.attackSpeed or ""),
}
end
@@ -4090,6 +4080,31 @@ MTH_BOOK_UpdateResults = function()
btn.itemIcon:SetTexture(nil)
btn.itemIcon:Hide()
end
elseif MTH_BOOK_STATE.mode == "families" and type(entry) == "table" and entry.icon then
local iconPath = MTH_BOOK_ResolveIconPath(entry.icon)
if iconPath then
btn.itemIcon:SetTexture(iconPath)
btn.itemIcon:Show()
else
btn.itemIcon:SetTexture(nil)
btn.itemIcon:Hide()
end
elseif MTH_BOOK_STATE.mode == "pets" then
local beast = MTH_DS_Beasts and MTH_DS_Beasts[entry]
local famData = beast and beast.family and MTH_DS_Families and MTH_DS_Families[beast.family]
if famData and famData.icon and famData.icon ~= "" then
local iconPath = MTH_BOOK_ResolveIconPath(famData.icon)
if iconPath then
btn.itemIcon:SetTexture(iconPath)
btn.itemIcon:Show()
else
btn.itemIcon:SetTexture(nil)
btn.itemIcon:Hide()
end
else
btn.itemIcon:SetTexture(nil)
btn.itemIcon:Hide()
end
else
btn.itemIcon:SetTexture(nil)
btn.itemIcon:Hide()
@@ -4614,6 +4629,8 @@ function MTH_BOOK_JumpToBeastById(beastId)
MTH_BOOK_STATE.mode = "pets"
local widgets = MTH_BOOK_GetFilterWidgets()
MTH_BOOK_ResetStateForMode("pets")
MTH_BOOK_STATE.petHideNoAbilities = false
MTH_BOOK_STATE.petHideUnknown = false
MTH_BOOK_STATE.search = tostring(id)
MTH_BOOK_STATE.forcedBeastId = id
MTH_BOOK_ApplyStateToWidgets(widgets)
@@ -5066,19 +5083,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()
@@ -5181,19 +5198,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
+3 -3
View File
@@ -74,7 +74,7 @@
</Frame>
<Frame name="$parentDetailBackdrop">
<Size><AbsDimension x="136" y="324"/></Size>
<Size><AbsDimension x="136" y="155"/></Size>
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="608" y="-166"/></Offset></Anchor>
</Anchors>
@@ -85,7 +85,7 @@
</Backdrop>
<Frames>
<EditBox name="$parentDetailText" autoFocus="false" multiLine="true" text="Select an entry to view details.">
<Size><AbsDimension x="120" y="306"/></Size>
<Size><AbsDimension x="120" y="139"/></Size>
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="8" y="-8"/></Offset></Anchor>
</Anchors>
@@ -96,7 +96,7 @@
<Button name="$parentOpenMapButton" inherits="UIPanelButtonTemplate" text="Open Map" hidden="true">
<Size><AbsDimension x="136" y="22"/></Size>
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="608" y="-496"/></Offset></Anchor>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="608" y="-524"/></Offset></Anchor>
</Anchors>
</Button>
-1
View File
@@ -9,7 +9,6 @@ local MTH_LOCALE_ALIASES = {
enGB = "enUS",
esMX = "esES",
zhTW = "zhCN",
frFR = "enUS",
}
local MTH_SUPPORTED_LOCALES = {
+1 -1
View File
@@ -1244,7 +1244,7 @@ function MTH_Map:Init()
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")
+29 -26
View File
@@ -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,16 +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(self, 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()
if self and self.UnregisterAllEvents then
self:UnregisterAllEvents()
self:SetScript("OnEvent", nil)
end
this:UnregisterAllEvents()
this:SetScript("OnEvent", nil)
end
end)
+30 -40
View File
@@ -657,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, MTH_AB_IsChecked(self))
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)
@@ -715,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", MTH_AB_IsChecked(self))
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
@@ -730,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 = MTH_AB_IsChecked(self)
store.projectiles.enabled = MTH_AB_IsChecked(this)
MTH_AB_RefreshOptionsUI()
end)
end
@@ -769,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 = MTH_AB_IsChecked(self)
store.petFood.enabled = MTH_AB_IsChecked(this)
MTH_AB_RefreshOptionsUI()
end)
end
@@ -791,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
@@ -816,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()
@@ -827,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()
+10 -14
View File
@@ -72,10 +72,9 @@ function MTH_SetupAutoQuestOptions()
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(self)
self = self or this
if not self then return end
local enabled = MTH_AQ_IsChecked(self)
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
@@ -84,7 +83,7 @@ function MTH_SetupAutoQuestOptions()
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
self:SetChecked(actual and true or false)
this:SetChecked(actual and true or false)
end)
end
@@ -151,9 +150,8 @@ function MTH_SetupAutoQuestOptions()
store.scorpokDrazial and true or false
)
if scorpokToggle then
scorpokToggle:SetScript("OnClick", function(self)
self = self or this
local enabled = MTH_AQ_IsChecked(self)
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")
@@ -176,9 +174,8 @@ function MTH_SetupAutoQuestOptions()
store.scorpokTooltip and true or false
)
if tooltipToggle then
tooltipToggle:SetScript("OnClick", function(self)
self = self or this
local enabled = MTH_AQ_IsChecked(self)
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")
@@ -212,9 +209,8 @@ function MTH_SetupAutoQuestOptions()
store.arrowsForSissies and true or false
)
if sissiesToggle then
sissiesToggle:SetScript("OnClick", function(self)
self = self or this
local enabled = MTH_AQ_IsChecked(self)
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")
+29 -38
View File
@@ -326,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
@@ -385,16 +384,15 @@ 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
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
self:SetChecked(true)
this:SetChecked(true)
else
profile.disabledSpells[bucket][timerName] = {}
self:SetChecked(nil)
this:SetChecked(nil)
end
MTH_CHRON_ApplyLiveProfile(profile)
@@ -470,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 = MTH_CHRON_IsChecked(self)
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
@@ -495,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 = MTH_CHRON_IsChecked(self)
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 = MTH_CHRON_IsChecked(self)
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 = MTH_CHRON_IsChecked(self)
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 = MTH_CHRON_IsChecked(self)
onlySelfCheck:SetScript("OnClick", function()
if not this then return end
profile.onlyself = MTH_CHRON_IsChecked(this)
end)
end
elseif section == "bar" then
@@ -610,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 = MTH_CHRON_IsChecked(self)
growCheck:SetScript("OnClick", function()
if not this then return end
profile.growup = MTH_CHRON_IsChecked(this)
MTH_CHRON_ApplyLiveProfile(profile)
end)
end
@@ -621,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 = MTH_CHRON_IsChecked(self)
reverseCheck:SetScript("OnClick", function()
if not this then return end
profile.reverse = MTH_CHRON_IsChecked(this)
MTH_CHRON_ApplyLiveProfile(profile)
end)
end
+18 -20
View File
@@ -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)
+24 -32
View File
@@ -297,11 +297,10 @@ local function MTH_ICU_BuildUI(container)
local moduleEnabled = MTH_CreateCheckbox(container, "MetaHuntOptionsICUModuleEnabled", "Enable ICU module", -72, MTH_ICU_LAYOUT.LEFT_X)
if moduleEnabled then
moduleEnabled:SetScript("OnClick", function(self)
self = self or this
if not self then return end
moduleEnabled:SetScript("OnClick", function()
if not this then return end
if MTH and MTH.SetModuleEnabled then
local ok, err = MTH:SetModuleEnabled("icu", self:GetChecked() == 1)
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
@@ -313,11 +312,10 @@ local function MTH_ICU_BuildUI(container)
local mouseOver = MTH_CreateCheckbox(container, "MetaHuntOptionsICUMouseOver", "Enable CTRL mouseover scan", -98, MTH_ICU_LAYOUT.LEFT_X)
if mouseOver then
mouseOver:SetScript("OnClick", function(self)
self = self or this
if not self then return end
mouseOver:SetScript("OnClick", function()
if not this then return end
local store = MTH_ICU_GetStore()
store.mouseOver = self:GetChecked() == 1 and true or false
store.mouseOver = this:GetChecked() == 1 and true or false
end)
MTH_ICU_OPT_STATE.controls.mouseOver = mouseOver
end
@@ -346,11 +344,10 @@ local function MTH_ICU_BuildUI(container)
local expandUp = MTH_CreateCheckbox(container, "MetaHuntOptionsICUExpandUp", "Expand Up", -301, MTH_ICU_LAYOUT.LEFT_X + 132)
if expandUp then
expandUp:SetScript("OnClick", function(self)
self = self or this
if not self then return end
expandUp:SetScript("OnClick", function()
if not this then return end
local store = MTH_ICU_GetStore()
store.EXPAND_UP = self:GetChecked() == 1 and true or false
store.EXPAND_UP = this:GetChecked() == 1 and true or false
if type(ICU_SetPoints) == "function" then
ICU_SetPoints()
end
@@ -360,44 +357,40 @@ local function MTH_ICU_BuildUI(container)
local showGuild = MTH_CreateCheckbox(container, "MetaHuntOptionsICUShowGuild", "Show player guild names", -344, MTH_ICU_LAYOUT.LEFT_X)
if showGuild then
showGuild:SetScript("OnClick", function(self)
self = self or this
if not self then return end
showGuild:SetScript("OnClick", function()
if not this then return end
local store = MTH_ICU_GetStore()
store.SHOW_GUILD_NAME = self:GetChecked() == 1 and true or false
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(self)
self = self or this
if not self then return end
showClass:SetScript("OnClick", function()
if not this then return end
local store = MTH_ICU_GetStore()
store.SHOW_PLAYER_CLASS = self:GetChecked() == 1 and true or false
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(self)
self = self or this
if not self then return end
showRace:SetScript("OnClick", function()
if not this then return end
local store = MTH_ICU_GetStore()
store.SHOW_PLAYER_RACE = self:GetChecked() == 1 and true or false
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(self)
self = self or this
if not self then return end
showTitles:SetScript("OnClick", function()
if not this then return end
local store = MTH_ICU_GetStore()
store.SHOW_CUSTOM_TITLES = self:GetChecked() == 1 and true or false
store.SHOW_CUSTOM_TITLES = this:GetChecked() == 1 and true or false
end)
MTH_ICU_OPT_STATE.controls.showCustomTitles = showTitles
end
@@ -410,11 +403,10 @@ local function MTH_ICU_BuildUI(container)
local reactionOnlyPvp = MTH_CreateCheckbox(container, "MetaHuntOptionsICUReactionOnlyPvp", "Reaction only when PvP-flagged", -200, MTH_ICU_LAYOUT.RIGHT_X)
if reactionOnlyPvp then
reactionOnlyPvp:SetScript("OnClick", function(self)
self = self or this
if not self then return end
reactionOnlyPvp:SetScript("OnClick", function()
if not this then return end
local store = MTH_ICU_GetStore()
store.REACTION_ONLY_PVP_PLAYERS = self:GetChecked() == 1 and true or false
store.REACTION_ONLY_PVP_PLAYERS = this:GetChecked() == 1 and true or false
end)
MTH_ICU_OPT_STATE.controls.reactionOnlyPvp = reactionOnlyPvp
end
+403
View File
@@ -0,0 +1,403 @@
------------------------------------------------------
-- MetaHunt Profile Management Options Panel
------------------------------------------------------
local MAX_PROFILE_ROWS = 15
local MAX_CHAR_ROWS = 10
local ROW_H = 26
-- Row pools — anonymous frames created once against scroll content, reused each refresh
local gProfileRows = {} -- [i] = { frame, nameText, infoText, loadBtn, delBtn }
local gCharRows = {} -- [i] = { frame, nameText, infoText, copyBtn }
-- Static element refs created once
local gActiveLabel = nil
local gSetupDone = false
-- Pending confirmations — globals so StaticPopup OnAccept can read them
MTH_PROFILE_PENDING_LOAD = nil
MTH_PROFILE_PENDING_DELETE = nil
MTH_PROFILE_PENDING_SAVE = nil
-- ── Static popup dialogs ───────────────────────────────────────────────────
StaticPopupDialogs["MTH_PROFILE_LOAD_CONFIRM"] = {
text = "Load profile \"%s\"?\n\nCurrent settings will be replaced.\nThe UI will reload to apply all changes.",
button1 = "Load & Reload",
button2 = "Cancel",
OnAccept = function()
if MTH_PROFILE_PENDING_LOAD then
local ok, err = MTH_Profile_Load(MTH_PROFILE_PENDING_LOAD)
MTH_PROFILE_PENDING_LOAD = nil
if ok then
ReloadUI()
elseif MTH and MTH.Print then
MTH:Print("Profile load failed: " .. tostring(err), "error")
end
end
end,
timeout = 0, whileDead = 0, hideOnEscape = 1,
}
StaticPopupDialogs["MTH_PROFILE_DELETE_CONFIRM"] = {
text = "Delete profile \"%s\"?\n\nThis cannot be undone.",
button1 = "Delete",
button2 = "Cancel",
OnAccept = function()
if MTH_PROFILE_PENDING_DELETE then
MTH_Profile_Delete(MTH_PROFILE_PENDING_DELETE)
MTH_PROFILE_PENDING_DELETE = nil
MTH_SetupProfilesOptions()
end
end,
timeout = 0, whileDead = 0, hideOnEscape = 1,
}
StaticPopupDialogs["MTH_PROFILE_SAVE_CONFIRM"] = {
text = "Profile \"%s\" already exists.\nOverwrite with current settings?",
button1 = "Overwrite",
button2 = "Cancel",
OnAccept = function()
if MTH_PROFILE_PENDING_SAVE then
MTH_Profile_Save(MTH_PROFILE_PENDING_SAVE)
MTH_PROFILE_PENDING_SAVE = nil
MTH_SetupProfilesOptions()
end
end,
timeout = 0, whileDead = 0, hideOnEscape = 1,
}
-- ── internal helpers ───────────────────────────────────────────────────────
local function PROF_TrimString(s)
if type(s) ~= "string" then return "" end
return string.gsub(s, "^%s*(.-)%s*$", "%1")
end
local function PROF_DoSave(rawName)
local name = PROF_TrimString(rawName)
if string.len(name) == 0 then
if MTH and MTH.Print then MTH:Print("Enter a profile name first.", "error") end
return
end
if string.len(name) > 50 then
if MTH and MTH.Print then MTH:Print("Profile name too long (50 chars max).", "error") end
return
end
local existing = type(MTH_SavedVariables) == "table"
and type(MTH_SavedVariables.profiles) == "table"
and MTH_SavedVariables.profiles[name] ~= nil
if existing then
MTH_PROFILE_PENDING_SAVE = name
StaticPopup_Show("MTH_PROFILE_SAVE_CONFIRM", name)
else
MTH_Profile_Save(name)
if MTH and MTH.Print then MTH:Print("Profile saved: " .. name) end
MTH_SetupProfilesOptions()
end
end
-- ── scroll frames + row pool creation (idempotent) ────────────────────────
local function PROF_EnsureScrollFrames(container)
if not MTH_GetFrame("MetaHuntOptionsProfilesScroll") then
local sf = CreateFrame("ScrollFrame", "MetaHuntOptionsProfilesScroll", container, "UIPanelScrollFrameTemplate")
local sc = CreateFrame("Frame", "MetaHuntOptionsProfilesContent", sf)
sc:SetWidth(510)
sc:SetHeight(MAX_PROFILE_ROWS * ROW_H + 4)
sf:SetScrollChild(sc)
end
if not MTH_GetFrame("MetaHuntOptionsCharScroll") then
local csf = CreateFrame("ScrollFrame", "MetaHuntOptionsCharScroll", container, "UIPanelScrollFrameTemplate")
local csc = CreateFrame("Frame", "MetaHuntOptionsCharContent", csf)
csc:SetWidth(510)
csc:SetHeight(MAX_CHAR_ROWS * ROW_H + 4)
csf:SetScrollChild(csc)
end
end
local function PROF_EnsureProfileRows()
local sc = MTH_GetFrame("MetaHuntOptionsProfilesContent")
if not sc then return end
for i = 1, MAX_PROFILE_ROWS do
if not gProfileRows[i] then
local row = CreateFrame("Frame", nil, sc)
row:SetHeight(ROW_H)
row:SetWidth(510)
row:SetPoint("TOPLEFT", sc, "TOPLEFT", 0, -(i - 1) * ROW_H)
local nameText = row:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
nameText:SetPoint("LEFT", row, "LEFT", 4, 2)
nameText:SetWidth(210)
nameText:SetJustifyH("LEFT")
local infoText = row:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
infoText:SetPoint("LEFT", row, "LEFT", 218, 2)
infoText:SetWidth(155)
infoText:SetJustifyH("LEFT")
infoText:SetTextColor(0.55, 0.55, 0.55)
local loadBtn = CreateFrame("Button", nil, row, "UIPanelButtonTemplate")
loadBtn:SetWidth(58)
loadBtn:SetHeight(20)
loadBtn:SetPoint("RIGHT", row, "RIGHT", -62, 0)
loadBtn:SetText("Load")
local delBtn = CreateFrame("Button", nil, row, "UIPanelButtonTemplate")
delBtn:SetWidth(58)
delBtn:SetHeight(20)
delBtn:SetPoint("RIGHT", row, "RIGHT", 0, 0)
delBtn:SetText("Delete")
gProfileRows[i] = { frame = row, nameText = nameText, infoText = infoText, loadBtn = loadBtn, delBtn = delBtn }
end
end
end
local function PROF_EnsureCharRows()
local csc = MTH_GetFrame("MetaHuntOptionsCharContent")
if not csc then return end
for i = 1, MAX_CHAR_ROWS do
if not gCharRows[i] then
local row = CreateFrame("Frame", nil, csc)
row:SetHeight(ROW_H)
row:SetWidth(510)
row:SetPoint("TOPLEFT", csc, "TOPLEFT", 0, -(i - 1) * ROW_H)
local nameText = row:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
nameText:SetPoint("LEFT", row, "LEFT", 4, 2)
nameText:SetWidth(250)
nameText:SetJustifyH("LEFT")
nameText:SetTextColor(0.70, 0.85, 1.00)
local infoText = row:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
infoText:SetPoint("LEFT", row, "LEFT", 258, 2)
infoText:SetWidth(120)
infoText:SetJustifyH("LEFT")
infoText:SetTextColor(0.55, 0.55, 0.55)
local copyBtn = CreateFrame("Button", nil, row, "UIPanelButtonTemplate")
copyBtn:SetWidth(80)
copyBtn:SetHeight(20)
copyBtn:SetPoint("RIGHT", row, "RIGHT", 0, 0)
copyBtn:SetText("Import")
gCharRows[i] = { frame = row, nameText = nameText, infoText = infoText, copyBtn = copyBtn }
end
end
end
-- ── dynamic refresh functions ──────────────────────────────────────────────
local function PROF_RefreshActive()
if not gActiveLabel then return end
local active = type(MTH_Profile_GetActive) == "function" and MTH_Profile_GetActive()
if active then
gActiveLabel:SetText("Active: |cffffd200" .. active .. "|r")
gActiveLabel:SetTextColor(0.90, 0.90, 0.90)
else
gActiveLabel:SetText("Active: |cff888888Custom (unsaved)|r")
gActiveLabel:SetTextColor(0.90, 0.90, 0.90)
end
gActiveLabel:Show()
end
local function PROF_RefreshProfileList()
PROF_EnsureProfileRows()
local profiles = type(MTH_Profile_GetList) == "function" and MTH_Profile_GetList() or {}
local active = type(MTH_Profile_GetActive) == "function" and MTH_Profile_GetActive()
local n = table.getn(profiles)
local sc = MTH_GetFrame("MetaHuntOptionsProfilesContent")
if sc then
sc:SetHeight(math.max(n * ROW_H + 4, ROW_H))
end
for i = 1, MAX_PROFILE_ROWS do
local row = gProfileRows[i]
if not row then break end
local name = profiles[i]
if name then
-- Name (with active indicator)
if name == active then
row.nameText:SetText(name .. " |cff00cc44[active]|r")
else
row.nameText:SetText(name)
end
-- Info: date saved by who
local p = type(MTH_SavedVariables) == "table"
and type(MTH_SavedVariables.profiles) == "table"
and MTH_SavedVariables.profiles[name]
local info = ""
if type(p) == "table" then
if p.savedAt and p.savedAt ~= "" then
info = p.savedAt
end
end
row.infoText:SetText(info)
-- Wire buttons (SetScript replaces previous handler each refresh)
local rowName = name
row.loadBtn:SetScript("OnClick", function()
MTH_PROFILE_PENDING_LOAD = rowName
StaticPopup_Show("MTH_PROFILE_LOAD_CONFIRM", rowName)
end)
row.delBtn:SetScript("OnClick", function()
MTH_PROFILE_PENDING_DELETE = rowName
StaticPopup_Show("MTH_PROFILE_DELETE_CONFIRM", rowName)
end)
row.frame:Show()
row.loadBtn:Show()
row.delBtn:Show()
else
row.frame:Hide()
end
end
end
local function PROF_RefreshCharList()
PROF_EnsureCharRows()
local chars = type(MTH_Profile_GetCharList) == "function" and MTH_Profile_GetCharList() or {}
local n = table.getn(chars)
local csc = MTH_GetFrame("MetaHuntOptionsCharContent")
if csc then
csc:SetHeight(math.max(n * ROW_H + 4, ROW_H))
end
for i = 1, MAX_CHAR_ROWS do
local row = gCharRows[i]
if not row then break end
local charKey = chars[i]
if charKey then
local snap = type(MTH_SavedVariables) == "table"
and type(MTH_SavedVariables.charSnapshots) == "table"
and MTH_SavedVariables.charSnapshots[charKey]
local info = (type(snap) == "table" and snap.savedAt) and snap.savedAt or ""
row.nameText:SetText(charKey)
row.infoText:SetText(info)
local ck = charKey
row.copyBtn:SetScript("OnClick", function()
local ok, pName = MTH_Profile_CopyFromChar(ck)
if ok then
MTH_SetupProfilesOptions()
if MTH and MTH.Print then
MTH:Print('Imported "' .. ck .. '" as profile "' .. tostring(pName) .. '".')
end
end
end)
row.frame:Show()
row.copyBtn:Show()
else
row.frame:Hide()
end
end
end
-- ── main setup (static elements created once, dynamic lists refreshed every call) ──
function MTH_SetupProfilesOptions()
local container = MTH_GetFrame("MetaHuntOptionsProfiles")
if not container then return end
if not gSetupDone then
-- Title
local title = container:CreateFontString(nil, "ARTWORK", "GameFontNormal")
title:SetPoint("TOPLEFT", container, "TOPLEFT", 6, -6)
title:SetText("Profiles")
title:SetTextColor(1.00, 0.82, 0.00)
-- Active profile indicator
gActiveLabel = container:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
gActiveLabel:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -4)
gActiveLabel:SetWidth(540)
gActiveLabel:SetJustifyH("LEFT")
-- ── Save As section ───────────────────────────────────────────────
local saveHdr = container:CreateFontString(nil, "ARTWORK", "GameFontNormal")
saveHdr:SetPoint("TOPLEFT", gActiveLabel, "BOTTOMLEFT", 0, -10)
saveHdr:SetText("Save current settings as:")
saveHdr:SetTextColor(0.90, 0.90, 0.90)
local eb = CreateFrame("EditBox", "MTH_ProfileNameInput", container, "InputBoxTemplate")
eb:SetWidth(240)
eb:SetHeight(20)
eb:SetMaxLetters(50)
eb:SetAutoFocus(false)
eb:SetPoint("TOPLEFT", saveHdr, "BOTTOMLEFT", 2, -6)
eb:SetScript("OnEnterPressed", function()
PROF_DoSave(this:GetText())
this:SetText("")
this:ClearFocus()
end)
eb:SetScript("OnEscapePressed", function()
this:SetText("")
this:ClearFocus()
end)
local saveBtn = CreateFrame("Button", "MTH_ProfileSaveBtn", container, "UIPanelButtonTemplate")
saveBtn:SetWidth(70)
saveBtn:SetHeight(20)
saveBtn:SetPoint("LEFT", eb, "RIGHT", 6, 0)
saveBtn:SetText("Save")
saveBtn:SetScript("OnClick", function()
local box = MTH_GetFrame("MTH_ProfileNameInput")
if box then
PROF_DoSave(box:GetText())
box:SetText("")
box:ClearFocus()
end
end)
-- ── Saved Profiles section ────────────────────────────────────────
local profHdr = container:CreateFontString(nil, "ARTWORK", "GameFontNormal")
profHdr:SetPoint("TOPLEFT", eb, "BOTTOMLEFT", -2, -12)
profHdr:SetText("Saved Profiles")
profHdr:SetTextColor(1.00, 0.82, 0.00)
local rule1 = container:CreateTexture(nil, "ARTWORK")
rule1:SetPoint("TOPLEFT", profHdr, "BOTTOMLEFT", 0, -3)
rule1:SetWidth(540)
rule1:SetHeight(1)
rule1:SetTexture(0.30, 0.30, 0.30, 0.80)
PROF_EnsureScrollFrames(container)
local sf = MTH_GetFrame("MetaHuntOptionsProfilesScroll")
sf:SetPoint("TOPLEFT", rule1, "BOTTOMLEFT", 0, -4)
sf:SetWidth(530)
sf:SetHeight(170)
sf:Show()
-- ── Copy from Character section ───────────────────────────────────
local charHdr = container:CreateFontString(nil, "ARTWORK", "GameFontNormal")
charHdr:SetPoint("TOPLEFT", sf, "BOTTOMLEFT", 0, -10)
charHdr:SetText("Copy from Character")
charHdr:SetTextColor(1.00, 0.82, 0.00)
local charNote = container:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
charNote:SetPoint("TOPLEFT", charHdr, "BOTTOMLEFT", 0, -2)
charNote:SetWidth(540)
charNote:SetJustifyH("LEFT")
charNote:SetText("Snapshots are saved automatically on logout. Click Import to create a profile from one.")
charNote:SetTextColor(0.60, 0.60, 0.60)
local rule2 = container:CreateTexture(nil, "ARTWORK")
rule2:SetPoint("TOPLEFT", charNote, "BOTTOMLEFT", 0, -3)
rule2:SetWidth(540)
rule2:SetHeight(1)
rule2:SetTexture(0.30, 0.30, 0.30, 0.80)
local csf = MTH_GetFrame("MetaHuntOptionsCharScroll")
csf:SetPoint("TOPLEFT", rule2, "BOTTOMLEFT", 0, -4)
csf:SetWidth(530)
csf:SetHeight(140)
csf:Show()
gSetupDone = true
end
-- Refresh dynamic content every time the panel is opened
PROF_RefreshActive()
PROF_RefreshProfileList()
PROF_RefreshCharList()
end
+5
View File
@@ -117,6 +117,11 @@ function MTH_SelectOptionsTab(tabKey)
MTH_SetupGeneralOptions()
MTH_OPTIONS_SETUP["General"] = true
end
elseif tabKey == "Profiles" then
if type(MTH_SetupProfilesOptions) == "function" then
MTH_SetupProfilesOptions()
MTH_OPTIONS_SETUP["Profiles"] = true
end
elseif tabKey == "Messages" then
if not MTH_OPTIONS_SETUP["Messages"] then
if type(MTH_SetupMessagesOptions) == "function" then
+4 -2
View File
@@ -27,7 +27,8 @@ MTH_OPTIONS_CONST = MTH_OPTIONS_CONST or {
}
MTH_OPTIONS_TABS = MTH_OPTIONS_TABS or {
{ key = "General", label = "General", frame = "MetaHuntOptionsGeneral" },
{ key = "General", label = "General", frame = "MetaHuntOptionsGeneral" },
{ key = "Profiles", label = "Profiles", frame = "MetaHuntOptionsProfiles" },
{ key = "Messages", label = "Messages", frame = "MetaHuntOptionsMessages" },
{ key = "Pet", label = "ZPet", frame = "MetaHuntOptionsPet" },
{ key = "Track", label = "ZTrack", frame = "MetaHuntOptionsTrack" },
@@ -52,7 +53,8 @@ MTH_OPTIONS_TABS = MTH_OPTIONS_TABS or {
}
MTH_OPTIONS_TREE = MTH_OPTIONS_TREE or {
{ label = "General", key = "General" },
{ label = "General", key = "General" },
{ label = "Profiles", key = "Profiles" },
{ label = "Messages", key = "Messages" },
{ label = "Auto Buy", key = "AutoBuy" },
{ label = "Auto Quest", key = "AutoQuest" },
+148 -110
View File
@@ -195,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
@@ -247,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
@@ -333,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 = MTH_ZB_IsChecked(self)
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
@@ -392,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 = MTH_ZB_IsChecked(self)
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
@@ -414,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 = MTH_ZB_IsChecked(self)
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"])
@@ -433,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 = MTH_ZB_IsChecked(self)
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
@@ -451,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 = MTH_ZB_IsChecked(self)
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)
@@ -506,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
@@ -523,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
@@ -587,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
@@ -612,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
@@ -640,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
@@ -749,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", MTH_ZB_IsChecked(self))
MTH:SetModuleEnabled("smartammo", MTH_ZB_IsChecked(this))
end
MTH_SetupSmartAmmoOptions()
end)
@@ -766,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(MTH_ZB_IsChecked(self) and 1 or nil)
MTHSmartAmmo_SetSmartEnabled(MTH_ZB_IsChecked(this) and 1 or nil)
end
end)
end
@@ -785,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(MTH_ZB_IsChecked(self) and 1 or nil)
MTHSmartAmmo_SetReloadEnabled(MTH_ZB_IsChecked(this) and 1 or nil)
end
end)
end
@@ -825,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", MTH_ZB_IsChecked(self))
MTH:SetMessageEnabled("initModulesLoaded", MTH_ZB_IsChecked(this))
end
end)
end
@@ -837,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", MTH_ZB_IsChecked(self))
MTH:SetMessageEnabled("initSarcasticWelcome", MTH_ZB_IsChecked(this))
end
end)
end
@@ -849,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", MTH_ZB_IsChecked(self))
MTH:SetMessageEnabled("petHungry", MTH_ZB_IsChecked(this))
end
end)
end
@@ -861,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", MTH_ZB_IsChecked(self))
MTH:SetMessageEnabled("beastTrainingScan", MTH_ZB_IsChecked(this))
end
end)
end
@@ -873,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", MTH_ZB_IsChecked(self))
MTH:SetMessageEnabled("spellbookScan", MTH_ZB_IsChecked(this))
end
end)
end
@@ -885,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", MTH_ZB_IsChecked(self))
MTH:SetMessageEnabled("petRanAway", MTH_ZB_IsChecked(this))
end
end)
end
@@ -897,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", MTH_ZB_IsChecked(self))
MTH:SetMessageEnabled("mapMarkers", MTH_ZB_IsChecked(this))
end
end)
end
+3 -3
View File
@@ -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
+1
View File
@@ -66,6 +66,7 @@
<!-- Content Areas -->
<Frame name="$parentGeneral" hidden="true" enableMouse="true"/>
<Frame name="$parentProfiles" hidden="true" enableMouse="true"/>
<Frame name="$parentMessages" hidden="true" enableMouse="true"/>
<Frame name="$parentPet" hidden="true" enableMouse="true"/>
<Frame name="$parentTrack" hidden="true" enableMouse="true"/>
+202
View File
@@ -0,0 +1,202 @@
------------------------------------------------------
-- MetaHunt Profile System
-- Captures:
-- MTH_SavedVariables.modules (account-wide option values, e.g. feedomatic)
-- MTH_CharSavedVariables.modules (per-char option values: ICU, Chronometer,
-- AutoBuy, AutoQuest, SmartAmmo, tooltips...)
-- MTH_CharSavedVariables.moduleStates (enabled/disabled per char)
-- ZHunterMod_Saved / MTH_CharSavedVariables.modules.zhunter (zButtons layout)
-- Auto-snapshots current character on PLAYER_LOGOUT into
-- MTH_SavedVariables.charSnapshots["CharName-RealmName"]
------------------------------------------------------
local function MTH_Profile_DeepCopy(orig)
if type(orig) ~= "table" then return orig end
local copy = {}
for k, v in orig do
copy[MTH_Profile_DeepCopy(k)] = MTH_Profile_DeepCopy(v)
end
return copy
end
local function MTH_Profile_EnsureStore()
if type(MTH_SavedVariables) ~= "table" then
MTH_SavedVariables = {}
end
if type(MTH_SavedVariables.profiles) ~= "table" then
MTH_SavedVariables.profiles = {}
end
if type(MTH_SavedVariables.charSnapshots) ~= "table" then
MTH_SavedVariables.charSnapshots = {}
end
end
local function MTH_Profile_GetCharKey()
local name = (type(UnitName) == "function") and UnitName("player") or "Unknown"
local realm = (type(GetRealmName) == "function") and GetRealmName() or "Unknown"
name = (name and name ~= "") and name or "Unknown"
realm = (realm and realm ~= "") and realm or "Unknown"
return name .. "-" .. realm
end
local function MTH_Profile_BuildSnapshot()
local snap = {}
snap.savedBy = MTH_Profile_GetCharKey()
snap.savedAt = (type(date) == "function") and date("%Y-%m-%d %H:%M") or ""
-- Account-wide module option values (e.g. feedomatic)
snap.config = (type(MTH_SavedVariables) == "table"
and type(MTH_SavedVariables.modules) == "table")
and MTH_Profile_DeepCopy(MTH_SavedVariables.modules)
or {}
-- Per-character module option values (ICU, Chronometer, AutoBuy, SmartAmmo, etc.)
snap.charConfig = (type(MTH_CharSavedVariables) == "table"
and type(MTH_CharSavedVariables.modules) == "table")
and MTH_Profile_DeepCopy(MTH_CharSavedVariables.modules)
or {}
-- Per-character module enabled/disabled states
snap.moduleStates = (type(MTH_CharSavedVariables) == "table"
and type(MTH_CharSavedVariables.moduleStates) == "table")
and MTH_Profile_DeepCopy(MTH_CharSavedVariables.moduleStates)
or {}
-- zButtons config — kept as dedicated key for clarity
-- (also lives in charConfig.zhunter but we keep it explicit)
local zh = nil
if type(MTH_CharSavedVariables) == "table"
and type(MTH_CharSavedVariables.modules) == "table"
and type(MTH_CharSavedVariables.modules.zhunter) == "table"
then
zh = MTH_CharSavedVariables.modules.zhunter
elseif type(ZHunterMod_Saved) == "table" then
zh = ZHunterMod_Saved
end
snap.zhunter = zh and MTH_Profile_DeepCopy(zh) or {}
return snap
end
-- Save current settings as a named profile
function MTH_Profile_Save(name)
if type(name) ~= "string" or string.len(name) == 0 then
return false, "invalid name"
end
MTH_Profile_EnsureStore()
MTH_SavedVariables.profiles[name] = MTH_Profile_BuildSnapshot()
return true
end
-- Delete a named profile
function MTH_Profile_Delete(name)
MTH_Profile_EnsureStore()
if MTH_SavedVariables.profiles[name] == nil then return false end
MTH_SavedVariables.profiles[name] = nil
if type(MTH_CharSavedVariables) == "table"
and MTH_CharSavedVariables.activeProfile == name
then
MTH_CharSavedVariables.activeProfile = nil
end
return true
end
-- Apply a profile to SavedVariables; a /reload is required for changes to take full effect
function MTH_Profile_Load(name)
MTH_Profile_EnsureStore()
local p = MTH_SavedVariables.profiles[name]
if type(p) ~= "table" then return false, "profile not found" end
if type(MTH_CharSavedVariables) ~= "table" then MTH_CharSavedVariables = {} end
if type(MTH_CharSavedVariables.modules) ~= "table" then MTH_CharSavedVariables.modules = {} end
-- Apply account-wide module option values (e.g. feedomatic)
if type(p.config) == "table" then
if type(MTH_SavedVariables.modules) ~= "table" then
MTH_SavedVariables.modules = {}
end
for modName, modData in p.config do
MTH_SavedVariables.modules[modName] = MTH_Profile_DeepCopy(modData)
end
end
-- Apply per-character module option values (ICU, Chronometer, AutoBuy, SmartAmmo, etc.)
if type(p.charConfig) == "table" then
for modName, modData in p.charConfig do
MTH_CharSavedVariables.modules[modName] = MTH_Profile_DeepCopy(modData)
end
end
-- Apply module enabled/disabled
if type(p.moduleStates) == "table" then
if type(MTH_CharSavedVariables.moduleStates) ~= "table" then
MTH_CharSavedVariables.moduleStates = {}
end
for k, v in p.moduleStates do
MTH_CharSavedVariables.moduleStates[k] = v
end
end
-- Apply zButtons (also written into charConfig.zhunter above, but keep explicit)
if type(p.zhunter) == "table" then
ZHunterMod_Saved = MTH_Profile_DeepCopy(p.zhunter)
MTH_CharSavedVariables.modules.zhunter = ZHunterMod_Saved
end
MTH_CharSavedVariables.activeProfile = name
return true
end
-- Create a named profile from another character's auto-snapshot
-- profileName defaults to charKey if not provided
function MTH_Profile_CopyFromChar(charKey, profileName)
MTH_Profile_EnsureStore()
local snap = MTH_SavedVariables.charSnapshots[charKey]
if type(snap) ~= "table" then
return false, "no snapshot for " .. tostring(charKey)
end
local name = (type(profileName) == "string" and string.len(profileName) > 0)
and profileName or charKey
MTH_SavedVariables.profiles[name] = MTH_Profile_DeepCopy(snap)
return true, name
end
-- Return sorted list of profile names
function MTH_Profile_GetList()
MTH_Profile_EnsureStore()
local list = {}
for name, _ in MTH_SavedVariables.profiles do
table.insert(list, name)
end
table.sort(list)
return list
end
-- Return sorted list of character snapshot keys
function MTH_Profile_GetCharList()
MTH_Profile_EnsureStore()
local list = {}
for charKey, _ in MTH_SavedVariables.charSnapshots do
table.insert(list, charKey)
end
table.sort(list)
return list
end
-- Return the active profile name for the current character, or nil
function MTH_Profile_GetActive()
if type(MTH_CharSavedVariables) == "table" then
return MTH_CharSavedVariables.activeProfile
end
return nil
end
-- Auto-snapshot on logout so other characters can import this config
local MTH_ProfileEventFrame = CreateFrame("Frame", "MTH_ProfileEventFrame")
MTH_ProfileEventFrame:RegisterEvent("PLAYER_LOGOUT")
MTH_ProfileEventFrame:SetScript("OnEvent", function()
if event == "PLAYER_LOGOUT" then
MTH_Profile_EnsureStore()
MTH_SavedVariables.charSnapshots[MTH_Profile_GetCharKey()] = MTH_Profile_BuildSnapshot()
end
end)
+7 -8
View File
@@ -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)
+8 -2
View File
@@ -6,6 +6,7 @@ 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
@@ -219,7 +220,11 @@ function VC:GetTrackedPeers()
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()
@@ -247,6 +252,7 @@ function VC:TryPublish()
end
local payload = self.abbrev .. ":" .. tostring(localVersionNumber) .. ":v"
SendChatMessage(payload, "CHANNEL", nil, tostring(channelId))
self.lastPublishedAt = VC_GetTimeNow()
return true
end
@@ -305,7 +311,7 @@ function VC:HandleRemoteMessage(message, author, channelLabel)
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")
+153 -91
View File
@@ -19,6 +19,8 @@ if not MTH_DS_Beasts[521] then
{32.6, 25.8, 10},
{64.3, 24, 10},
},
["displayId"] = 11412,
["skinId"] = 720,
}
end
@@ -37,6 +39,8 @@ if not MTH_DS_Beasts[728] then
["coords"] = {
{49.6, 24, 33},
},
["displayId"] = 613,
["skinId"] = 599,
}
end
@@ -54,6 +58,8 @@ if not MTH_DS_Beasts[729] then
["coords"] = {
{32.2, 17.4, 33},
},
["displayId"] = 471,
["skinId"] = 320,
}
end
@@ -85,6 +91,8 @@ if not MTH_DS_Beasts[1199] then
{42.4, 57.9, 1},
{43, 56.5, 1},
},
["displayId"] = 748,
["skinId"] = 748,
}
end
@@ -104,6 +112,8 @@ if not MTH_DS_Beasts[1225] then
{42.5, 64.7, 38},
{20.3, 77.4, 5602},
},
["displayId"] = 706,
["skinId"] = 706,
}
end
@@ -119,6 +129,8 @@ if not MTH_DS_Beasts[1516] then
["coords"] = {
{36.3, 63.9, 33},
},
["displayId"] = 839,
["skinId"] = 809,
}
end
@@ -133,6 +145,8 @@ if not MTH_DS_Beasts[2275] then
["unique"] = true,
["coords"] = {
},
["displayId"] = 11411,
["skinId"] = 246,
}
end
@@ -247,6 +261,8 @@ if not MTH_DS_Beasts[2321] then
{45.9, 22.2, 148},
{29.5, 31.1, 361},
},
["displayId"] = 1042,
["skinId"] = 178,
}
end
@@ -327,6 +343,8 @@ if not MTH_DS_Beasts[2560] then
{37.1, 29.9, 45},
{39.9, 29.9, 45},
},
["displayId"] = 180,
["skinId"] = 180,
}
end
@@ -457,6 +475,8 @@ if not MTH_DS_Beasts[2563] then
{80.7, 83.8, 267},
{79.9, 81, 267},
},
["displayId"] = 1103,
["skinId"] = 1091,
}
end
@@ -491,6 +511,8 @@ if not MTH_DS_Beasts[2578] then
{26.7, 24.8, 45},
{29.1, 19.8, 45},
},
["displayId"] = 10824,
["skinId"] = 388,
}
end
@@ -510,6 +532,8 @@ if not MTH_DS_Beasts[2931] then
["coords"] = {
{56.1, 61.7, 3},
},
["displayId"] = 1210,
["skinId"] = 490,
}
end
@@ -525,6 +549,8 @@ if not MTH_DS_Beasts[3257] then
["coords"] = {
{59.7, 30.3, 17},
},
["displayId"] = 2571,
["skinId"] = 1959,
}
end
@@ -540,6 +566,8 @@ if not MTH_DS_Beasts[3475] then
["coords"] = {
{56.1, 17.4, 17},
},
["displayId"] = 1934,
["skinId"] = 1934,
}
end
@@ -558,6 +586,8 @@ if not MTH_DS_Beasts[3503] then
["coords"] = {
{45.5, 72.5, 17},
},
["displayId"] = 1307,
["skinId"] = 1307,
}
end
@@ -572,6 +602,8 @@ if not MTH_DS_Beasts[3619] then
["unique"] = true,
["coords"] = {
},
["displayId"] = 4472,
["skinId"] = 748,
}
end
@@ -631,6 +663,8 @@ if not MTH_DS_Beasts[3812] then
{9.5, 13.7, 331},
{6.7, 13, 331},
},
["displayId"] = 9566,
["skinId"] = 979,
}
end
@@ -662,6 +696,8 @@ if not MTH_DS_Beasts[4118] then
{26.4, 25.6, 400},
{22.7, 23.7, 400},
},
["displayId"] = 10991,
["skinId"] = 2700,
}
end
@@ -679,6 +715,8 @@ if not MTH_DS_Beasts[4250] then
["coords"] = {
{25.1, 37.2, 400},
},
["displayId"] = 2726,
["skinId"] = 2726,
}
end
@@ -698,6 +736,8 @@ if not MTH_DS_Beasts[4425] then
["coords"] = {
{11, 30.3, 491},
},
["displayId"] = 4735,
["skinId"] = 4735,
}
end
@@ -730,6 +770,8 @@ if not MTH_DS_Beasts[4511] then
{50.6, 37.4, 491},
{48.5, 37.2, 491},
},
["displayId"] = 4713,
["skinId"] = 4713,
}
end
@@ -750,6 +792,8 @@ if not MTH_DS_Beasts[4512] then
{54.1, 57.3, 491},
{48.5, 57.1, 491},
},
["displayId"] = 4714,
["skinId"] = 4714,
}
end
@@ -782,6 +826,8 @@ if not MTH_DS_Beasts[4514] then
{52.3, 40.7, 491},
{45.7, 40.1, 491},
},
["displayId"] = 2453,
["skinId"] = 2450,
}
end
@@ -796,6 +842,8 @@ if not MTH_DS_Beasts[4660] then
["unique"] = true,
["coords"] = {
},
["displayId"] = 2710,
["skinId"] = 2710,
}
end
@@ -862,6 +910,8 @@ if not MTH_DS_Beasts[4693] then
{73.8, 11.2, 405},
{50.4, 82.9, 406},
},
["displayId"] = 10273,
["skinId"] = 507,
}
end
@@ -885,6 +935,8 @@ if not MTH_DS_Beasts[4824] then
{20.6, 38.3, 719},
{23, 38, 719},
},
["displayId"] = 1244,
["skinId"] = 1244,
}
end
@@ -909,6 +961,8 @@ if not MTH_DS_Beasts[4825] then
{60.3, 85.5, 719},
{57.3, 85.3, 719},
},
["displayId"] = 5026,
["skinId"] = 5026,
}
end
@@ -930,6 +984,8 @@ if not MTH_DS_Beasts[5224] then
{73.8, 42.6, 8},
{72, 41.9, 8},
},
["displayId"] = 4767,
["skinId"] = 4317,
}
end
@@ -972,6 +1028,8 @@ if not MTH_DS_Beasts[5260] then
{68.3, 52.1, 357},
{74.7, 51.4, 357},
},
["displayId"] = 3186,
["skinId"] = 3186,
}
end
@@ -989,6 +1047,8 @@ if not MTH_DS_Beasts[5432] then
["coords"] = {
{60.2, 81.6, 440},
},
["displayId"] = 5127,
["skinId"] = 5126,
}
end
@@ -1008,6 +1068,8 @@ if not MTH_DS_Beasts[5842] then
["coords"] = {
{59.6, 8.3, 17},
},
["displayId"] = 1337,
["skinId"] = 1337,
}
end
@@ -1032,6 +1094,8 @@ if not MTH_DS_Beasts[5984] then
{48.3, 17.8, 4},
{56, 17.6, 4},
},
["displayId"] = 8050,
["skinId"] = 2714,
}
end
@@ -1074,6 +1138,8 @@ if not MTH_DS_Beasts[6513] then
{67.7, 13.8, 490},
{68.3, 13.1, 490},
},
["displayId"] = 5294,
["skinId"] = 792,
}
end
@@ -1116,6 +1182,8 @@ if not MTH_DS_Beasts[6514] then
{67.7, 13.8, 490},
{68.3, 13.1, 490},
},
["displayId"] = 844,
["skinId"] = 792,
}
end
@@ -1152,6 +1220,8 @@ if not MTH_DS_Beasts[6516] then
{67.7, 13.8, 490},
{68.3, 13.1, 490},
},
["displayId"] = 5244,
["skinId"] = 792,
}
end
@@ -1170,6 +1240,8 @@ if not MTH_DS_Beasts[6585] then
["coords"] = {
{68.5, 12.7, 490},
},
["displayId"] = 8129,
["skinId"] = 840,
}
end
@@ -1230,6 +1302,8 @@ if not MTH_DS_Beasts[7455] then
{63.3, 27.2, 618},
{65.5, 27, 618},
},
["displayId"] = 6212,
["skinId"] = 6212,
}
end
@@ -1244,6 +1318,8 @@ if not MTH_DS_Beasts[7803] then
["unique"] = true,
["coords"] = {
},
["displayId"] = 2414,
["skinId"] = 2414,
}
end
@@ -1262,6 +1338,8 @@ if not MTH_DS_Beasts[8277] then
["coords"] = {
{61.9, 73.2, 51},
},
["displayId"] = 4458,
["skinId"] = 4457,
}
end
@@ -1275,6 +1353,8 @@ if not MTH_DS_Beasts[8926] then
["attackSpeed"] = "2.0",
["coords"] = {
},
["displayId"] = 7347,
["skinId"] = 2489,
}
end
@@ -1288,6 +1368,8 @@ if not MTH_DS_Beasts[8927] then
["attackSpeed"] = "2.0",
["coords"] = {
},
["displayId"] = 1955,
["skinId"] = 1954,
}
end
@@ -1305,6 +1387,8 @@ if not MTH_DS_Beasts[9622] then
["coords"] = {
{68.1, 12.6, 490},
},
["displayId"] = 8844,
["skinId"] = 3186,
}
end
@@ -1322,6 +1406,8 @@ if not MTH_DS_Beasts[9683] then
["coords"] = {
{66.3, 63.9, 490},
},
["displayId"] = 5242,
["skinId"] = 960,
}
end
@@ -1337,6 +1423,8 @@ if not MTH_DS_Beasts[9684] then
{31.7, 28.7, 440},
{79.4, 49.9, 490},
},
["displayId"] = 11318,
["skinId"] = 675,
}
end
@@ -1355,6 +1443,8 @@ if not MTH_DS_Beasts[10200] then
["coords"] = {
{51.1, 10.7, 618},
},
["displayId"] = 10054,
["skinId"] = 10054,
}
end
@@ -1373,6 +1463,8 @@ if not MTH_DS_Beasts[10356] then
["coords"] = {
{45.6, 47.5, 85},
},
["displayId"] = 7892,
["skinId"] = 7890,
}
end
@@ -1391,6 +1483,8 @@ if not MTH_DS_Beasts[10359] then
["coords"] = {
{88.2, 51.4, 85},
},
["displayId"] = 418,
["skinId"] = 30,
}
end
@@ -1406,6 +1500,8 @@ if not MTH_DS_Beasts[10741] then
["unique"] = true,
["coords"] = {
},
["displayId"] = 10114,
["skinId"] = 1934,
}
end
@@ -1421,6 +1517,8 @@ if not MTH_DS_Beasts[10882] then
["unique"] = true,
["coords"] = {
},
["displayId"] = 10183,
["skinId"] = 2699,
}
end
@@ -1456,6 +1554,8 @@ if not MTH_DS_Beasts[10981] then
{45.2, 53.5, 2597},
{44.9, 51.9, 2597},
},
["displayId"] = 10278,
["skinId"] = 720,
}
end
@@ -1474,6 +1574,8 @@ if not MTH_DS_Beasts[12037] then
["coords"] = {
{83.4, 48.5, 331},
},
["displayId"] = 706,
["skinId"] = 706,
}
end
@@ -1497,6 +1599,8 @@ if not MTH_DS_Beasts[14222] then
{36, 23.7, 267},
{35.3, 11.5, 267},
},
["displayId"] = 1933,
["skinId"] = 1933,
}
end
@@ -1521,6 +1625,8 @@ if not MTH_DS_Beasts[14223] then
{77.5, 38, 130},
{82, 33.4, 130},
},
["displayId"] = 5026,
["skinId"] = 5026,
}
end
@@ -1539,6 +1645,8 @@ if not MTH_DS_Beasts[14234] then
["coords"] = {
{52, 62.9, 15},
},
["displayId"] = 2703,
["skinId"] = 2703,
}
end
@@ -1552,48 +1660,8 @@ if not MTH_DS_Beasts[15041] then
["attackSpeed"] = "1.4",
["coords"] = {
},
}
end
if not MTH_DS_Beasts[36507] then
MTH_DS_Beasts[36507] = {
["name"] = "Spot",
["family"] = "Wolves",
["lvl"] = "1",
["fac"] = "AH",
["abilities"] = "Dash 1",
["attackSpeed"] = "2.0",
["coords"] = {
{68, 46.8, 15},
},
}
end
if not MTH_DS_Beasts[36514] then
MTH_DS_Beasts[36514] = {
["name"] = "Frostsaber Cub",
["family"] = "Cats",
["lvl"] = "1",
["fac"] = "AH",
["abilities"] = "Cower 6",
["attackSpeed"] = "1.5",
["coords"] = {
{48.9, 19, 618},
},
}
end
if not MTH_DS_Beasts[37007] then
MTH_DS_Beasts[37007] = {
["name"] = "Black Widow Hatchling",
["family"] = "Spiders",
["lvl"] = "1",
["fac"] = "AH",
["abilities"] = "None",
["attackSpeed"] = "2.0",
["coords"] = {
{80.7, 62.8, 10},
},
["displayId"] = 15136,
["skinId"] = 711,
}
end
@@ -1608,6 +1676,8 @@ if not MTH_DS_Beasts[50624] then
["coords"] = {
{26.5, 30.9, 15},
},
["displayId"] = 11107,
["skinId"] = 11107,
}
end
@@ -1622,6 +1692,8 @@ if not MTH_DS_Beasts[50627] then
["coords"] = {
{26.5, 30.9, 15},
},
["displayId"] = 11107,
["skinId"] = 11107,
}
end
@@ -1636,6 +1708,8 @@ if not MTH_DS_Beasts[50630] then
["coords"] = {
{26.5, 30.9, 15},
},
["displayId"] = 11107,
["skinId"] = 11107,
}
end
@@ -1658,6 +1732,8 @@ if not MTH_DS_Beasts[60697] then
{93.7, 57.2, 46},
{97.1, 51.2, 46},
},
["displayId"] = 8050,
["skinId"] = 2714,
}
end
@@ -1692,6 +1768,8 @@ if not MTH_DS_Beasts[61096] then
{47.3, 18.8, 5121},
{49.4, 18.2, 5121},
},
["displayId"] = 10991,
["skinId"] = 2700,
}
end
@@ -1710,6 +1788,8 @@ if not MTH_DS_Beasts[61500] then
["coords"] = {
{56.7, 48.3, 5121},
},
["displayId"] = 837,
["skinId"] = 792,
}
end
@@ -1728,6 +1808,8 @@ if not MTH_DS_Beasts[61552] then
["coords"] = {
{45.6, 78, 5179},
},
["displayId"] = 18247,
["skinId"] = 18247,
}
end
@@ -1747,6 +1829,8 @@ if not MTH_DS_Beasts[61554] then
{47.4, 92.2, 130},
{48.9, 22.7, 5179},
},
["displayId"] = 9568,
["skinId"] = 9568,
}
end
@@ -1765,6 +1849,8 @@ if not MTH_DS_Beasts[61699] then
{20.6, 8.9, 139},
{64.2, 67, 5225},
},
["displayId"] = 18430,
["skinId"] = 18430,
}
end
@@ -1794,13 +1880,15 @@ if not MTH_DS_Beasts[61975] then
{20.1, 52.3, 45},
{20.8, 52.2, 45},
},
["displayId"] = 20504,
["skinId"] = 20504,
}
end
if not MTH_DS_Beasts[62066] then
MTH_DS_Beasts[62066] = {
["name"] = "Cavernweb Broodmother",
["family"] = "Spider",
["family"] = "Spiders",
["lvl"] = "27",
["fac"] = "Unknown",
["abilities"] = "None",
@@ -1811,13 +1899,15 @@ if not MTH_DS_Beasts[62066] then
["coords"] = {
{33.6, 44.3, 5601},
},
["displayId"] = 959,
["skinId"] = 955,
}
end
if not MTH_DS_Beasts[62073] then
MTH_DS_Beasts[62073] = {
["name"] = "Cavernweb Spider",
["family"] = "Spider",
["family"] = "Spiders",
["lvl"] = "26-27",
["fac"] = "Unknown",
["abilities"] = "None",
@@ -1835,13 +1925,15 @@ if not MTH_DS_Beasts[62073] then
{31.9, 50.2, 5601},
{35.3, 47.3, 5601},
},
["displayId"] = 959,
["skinId"] = 955,
}
end
if not MTH_DS_Beasts[62074] then
MTH_DS_Beasts[62074] = {
["name"] = "Cavernweb Creeper",
["family"] = "Spider",
["family"] = "Spiders",
["lvl"] = "26-27",
["fac"] = "Unknown",
["abilities"] = "Web",
@@ -1857,13 +1949,15 @@ if not MTH_DS_Beasts[62074] then
{30.3, 48.6, 5601},
{33.2, 47, 5601},
},
["displayId"] = 959,
["skinId"] = 955,
}
end
if not MTH_DS_Beasts[62075] then
MTH_DS_Beasts[62075] = {
["name"] = "Cavernweb Venomspitter",
["family"] = "Spider",
["family"] = "Spiders",
["lvl"] = "27-28",
["fac"] = "Unknown",
["abilities"] = "None",
@@ -1876,6 +1970,8 @@ if not MTH_DS_Beasts[62075] then
{30.3, 50.6, 5601},
{36.3, 48.3, 5601},
},
["displayId"] = 711,
["skinId"] = 711,
}
end
@@ -1937,6 +2033,8 @@ if not MTH_DS_Beasts[62345] then
{40.9, 22.5, 5561},
{41.5, 21.8, 5561},
},
["displayId"] = 833,
["skinId"] = 833,
}
end
@@ -1951,6 +2049,8 @@ if not MTH_DS_Beasts[80250] then
["coords"] = {
{9.7, 16.2, 139},
},
["displayId"] = 18027,
["skinId"] = 18027,
}
end
@@ -2009,6 +2109,8 @@ if not MTH_DS_Beasts[80257] then
{15.2, 59.1, 5602},
{16.7, 58.6, 5602},
},
["displayId"] = 18008,
["skinId"] = 18008,
}
end
@@ -2028,6 +2130,8 @@ if not MTH_DS_Beasts[80259] then
{50, 77.8, 41},
{52.4, 36.6, 41},
},
["displayId"] = 18004,
["skinId"] = 18004,
}
end
@@ -2046,50 +2150,8 @@ if not MTH_DS_Beasts[80260] then
["coords"] = {
{63.6, 15.8, 618},
},
}
end
if not MTH_DS_Beasts[80920] then
MTH_DS_Beasts[80920] = {
["name"] = "Amani Eagle",
["family"] = "Owls",
["lvl"] = "1",
["fac"] = "AH",
["abilities"] = "Screech 1, Claw 2",
["attackSpeed"] = "2.0",
["coords"] = {
{36.4, 18.3, 406},
},
}
end
if not MTH_DS_Beasts[90980] then
MTH_DS_Beasts[90980] = {
["name"] = "Zulian Panther",
["family"] = "Cats",
["lvl"] = "1",
["fac"] = "AH",
["abilities"] = "Dash 3",
["attackSpeed"] = "2.0",
["elite"] = true,
["coords"] = {
{50.3, 28.9, 1977},
},
}
end
if not MTH_DS_Beasts[90981] then
MTH_DS_Beasts[90981] = {
["name"] = "Zulian Panther",
["family"] = "Cats",
["lvl"] = "1",
["fac"] = "AH",
["abilities"] = "Dash 3",
["attackSpeed"] = "2.0",
["elite"] = true,
["coords"] = {
{50.3, 28.9, 1977},
},
["displayId"] = 18244,
["skinId"] = 18244,
}
end
@@ -2097,5 +2159,5 @@ MTH_DS_BeastsExtraMeta = {
generated = "2026-02-15",
baseBeasts = 627,
knownBeastNames = 710,
addedIDs = 80,
addedIDs = 74,
}
+329
View File
@@ -0,0 +1,329 @@
-- MetaHunt: Beast family DBC enrichment (scales, food validation)
-- AUTO-GENERATED by .tools — do not edit by hand.
-- Source DBC(s): CreatureFamily.dbc, ItemPetFood.dbc
-- Generated: 2026-03-17 08:39 UTC
if not MTH_DS_Families then return end
-- DBC ID=1 PetFoodMask=208 scale=[0.70-1.00]
if MTH_DS_Families["Wolves"] then
MTH_DS_Families["Wolves"]["dbcId"] = 1
MTH_DS_Families["Wolves"]["minScale"] = 0.7
MTH_DS_Families["Wolves"]["maxScale"] = 1.0
MTH_DS_Families["Wolves"]["minScaleLevel"] = 1
MTH_DS_Families["Wolves"]["maxScaleLevel"] = 60
MTH_DS_Families["Wolves"]["foodMask"] = 208
MTH_DS_Families["Wolves"]["foodDbc"] = {
"fungus",
"raw meat",
"raw fish",
}
end
-- DBC ID=2 PetFoodMask=209 scale=[0.70-1.10]
if MTH_DS_Families["Cats"] then
MTH_DS_Families["Cats"]["dbcId"] = 2
MTH_DS_Families["Cats"]["minScale"] = 0.7
MTH_DS_Families["Cats"]["maxScale"] = 1.1
MTH_DS_Families["Cats"]["minScaleLevel"] = 1
MTH_DS_Families["Cats"]["maxScaleLevel"] = 60
MTH_DS_Families["Cats"]["foodMask"] = 209
MTH_DS_Families["Cats"]["foodDbc"] = {
"meat",
"fungus",
"raw meat",
"raw fish",
}
end
-- DBC ID=3 PetFoodMask=203 scale=[0.40-0.60]
if MTH_DS_Families["Spiders"] then
MTH_DS_Families["Spiders"]["dbcId"] = 3
MTH_DS_Families["Spiders"]["minScale"] = 0.4
MTH_DS_Families["Spiders"]["maxScale"] = 0.6
MTH_DS_Families["Spiders"]["minScaleLevel"] = 1
MTH_DS_Families["Spiders"]["maxScaleLevel"] = 60
MTH_DS_Families["Spiders"]["foodMask"] = 203
MTH_DS_Families["Spiders"]["foodDbc"] = {
"meat",
"fish",
"bread",
"raw meat",
"raw fish",
}
end
-- DBC ID=4 PetFoodMask=210 scale=[0.60-1.00]
if MTH_DS_Families["Bears"] then
MTH_DS_Families["Bears"]["dbcId"] = 4
MTH_DS_Families["Bears"]["minScale"] = 0.6
MTH_DS_Families["Bears"]["maxScale"] = 1.0
MTH_DS_Families["Bears"]["minScaleLevel"] = 1
MTH_DS_Families["Bears"]["maxScaleLevel"] = 60
MTH_DS_Families["Bears"]["foodMask"] = 210
MTH_DS_Families["Bears"]["foodDbc"] = {
"bread",
"cheese",
"fish",
"fruit",
"fungus",
"meat",
"raw fish",
"raw meat",
}
end
-- DBC ID=5 PetFoodMask=211 scale=[0.60-1.00]
if MTH_DS_Families["Boars"] then
MTH_DS_Families["Boars"]["dbcId"] = 5
MTH_DS_Families["Boars"]["minScale"] = 0.6
MTH_DS_Families["Boars"]["maxScale"] = 1.0
MTH_DS_Families["Boars"]["minScaleLevel"] = 1
MTH_DS_Families["Boars"]["maxScaleLevel"] = 60
MTH_DS_Families["Boars"]["foodMask"] = 211
MTH_DS_Families["Boars"]["foodDbc"] = {
"bread",
"cheese",
"fish",
"fruit",
"fungus",
"meat",
"raw fish",
"raw meat",
}
end
-- DBC ID=6 PetFoodMask=212 scale=[0.40-0.60]
if MTH_DS_Families["Crocolisks"] then
MTH_DS_Families["Crocolisks"]["dbcId"] = 6
MTH_DS_Families["Crocolisks"]["minScale"] = 0.4
MTH_DS_Families["Crocolisks"]["maxScale"] = 0.6
MTH_DS_Families["Crocolisks"]["minScaleLevel"] = 1
MTH_DS_Families["Crocolisks"]["maxScaleLevel"] = 60
MTH_DS_Families["Crocolisks"]["foodMask"] = 212
MTH_DS_Families["Crocolisks"]["foodDbc"] = {
"cheese",
"fungus",
"raw meat",
"raw fish",
}
end
-- DBC ID=7 PetFoodMask=213 scale=[0.50-0.90]
if MTH_DS_Families["Carrion Birds"] then
MTH_DS_Families["Carrion Birds"]["dbcId"] = 7
MTH_DS_Families["Carrion Birds"]["minScale"] = 0.5
MTH_DS_Families["Carrion Birds"]["maxScale"] = 0.9
MTH_DS_Families["Carrion Birds"]["minScaleLevel"] = 1
MTH_DS_Families["Carrion Birds"]["maxScaleLevel"] = 60
MTH_DS_Families["Carrion Birds"]["foodMask"] = 213
MTH_DS_Families["Carrion Birds"]["foodDbc"] = {
"meat",
"cheese",
"fungus",
"raw meat",
"raw fish",
}
end
-- DBC ID=8 PetFoodMask=214 scale=[0.70-1.40]
if MTH_DS_Families["Crabs"] then
MTH_DS_Families["Crabs"]["dbcId"] = 8
MTH_DS_Families["Crabs"]["minScale"] = 0.7
MTH_DS_Families["Crabs"]["maxScale"] = 1.4
MTH_DS_Families["Crabs"]["minScaleLevel"] = 1
MTH_DS_Families["Crabs"]["maxScaleLevel"] = 60
MTH_DS_Families["Crabs"]["foodMask"] = 214
MTH_DS_Families["Crabs"]["foodDbc"] = {
"fish",
"cheese",
"fungus",
"raw meat",
"raw fish",
}
end
-- DBC ID=9 PetFoodMask=215 scale=[0.70-1.00]
if MTH_DS_Families["Gorillas"] then
MTH_DS_Families["Gorillas"]["dbcId"] = 9
MTH_DS_Families["Gorillas"]["minScale"] = 0.7
MTH_DS_Families["Gorillas"]["maxScale"] = 1.0
MTH_DS_Families["Gorillas"]["minScaleLevel"] = 1
MTH_DS_Families["Gorillas"]["maxScaleLevel"] = 60
MTH_DS_Families["Gorillas"]["foodMask"] = 215
MTH_DS_Families["Gorillas"]["foodDbc"] = {
"meat",
"fish",
"cheese",
"fungus",
"raw meat",
"raw fish",
}
end
-- DBC ID=11 PetFoodMask=217 scale=[0.50-0.80]
if MTH_DS_Families["Raptors"] then
MTH_DS_Families["Raptors"]["dbcId"] = 11
MTH_DS_Families["Raptors"]["minScale"] = 0.5
MTH_DS_Families["Raptors"]["maxScale"] = 0.8
MTH_DS_Families["Raptors"]["minScaleLevel"] = 1
MTH_DS_Families["Raptors"]["maxScaleLevel"] = 60
MTH_DS_Families["Raptors"]["foodMask"] = 217
MTH_DS_Families["Raptors"]["foodDbc"] = {
"meat",
"bread",
"fungus",
"raw meat",
"raw fish",
}
end
-- DBC ID=12 PetFoodMask=218 scale=[0.50-0.80]
if MTH_DS_Families["Tallstriders"] then
MTH_DS_Families["Tallstriders"]["dbcId"] = 12
MTH_DS_Families["Tallstriders"]["minScale"] = 0.5
MTH_DS_Families["Tallstriders"]["maxScale"] = 0.8
MTH_DS_Families["Tallstriders"]["minScaleLevel"] = 1
MTH_DS_Families["Tallstriders"]["maxScaleLevel"] = 60
MTH_DS_Families["Tallstriders"]["foodMask"] = 218
MTH_DS_Families["Tallstriders"]["foodDbc"] = {
"fish",
"bread",
"fungus",
"raw meat",
"raw fish",
}
end
-- DBC ID=20 PetFoodMask=236 scale=[0.70-1.00]
if MTH_DS_Families["Scorpids"] then
MTH_DS_Families["Scorpids"]["dbcId"] = 20
MTH_DS_Families["Scorpids"]["minScale"] = 0.7
MTH_DS_Families["Scorpids"]["maxScale"] = 1.0
MTH_DS_Families["Scorpids"]["minScaleLevel"] = 1
MTH_DS_Families["Scorpids"]["maxScaleLevel"] = 60
MTH_DS_Families["Scorpids"]["foodMask"] = 236
MTH_DS_Families["Scorpids"]["foodDbc"] = {
"cheese",
"bread",
"fruit",
"raw meat",
"raw fish",
}
end
-- DBC ID=21 PetFoodMask=251 scale=[0.50-0.80]
if MTH_DS_Families["Turtles"] then
MTH_DS_Families["Turtles"]["dbcId"] = 21
MTH_DS_Families["Turtles"]["minScale"] = 0.5
MTH_DS_Families["Turtles"]["maxScale"] = 0.8
MTH_DS_Families["Turtles"]["minScaleLevel"] = 1
MTH_DS_Families["Turtles"]["maxScaleLevel"] = 60
MTH_DS_Families["Turtles"]["foodMask"] = 251
MTH_DS_Families["Turtles"]["foodDbc"] = {
"meat",
"fish",
"bread",
"fungus",
"fruit",
"raw meat",
"raw fish",
}
end
-- DBC ID=24 PetFoodMask=653 scale=[0.40-0.70]
if MTH_DS_Families["Bats"] then
MTH_DS_Families["Bats"]["dbcId"] = 24
MTH_DS_Families["Bats"]["minScale"] = 0.4
MTH_DS_Families["Bats"]["maxScale"] = 0.7
MTH_DS_Families["Bats"]["minScaleLevel"] = 1
MTH_DS_Families["Bats"]["maxScaleLevel"] = 60
MTH_DS_Families["Bats"]["foodMask"] = 653
MTH_DS_Families["Bats"]["foodDbc"] = {
"meat",
"cheese",
"bread",
"raw fish",
}
end
-- DBC ID=25 PetFoodMask=654 scale=[0.70-0.90]
if MTH_DS_Families["Hyenas"] then
MTH_DS_Families["Hyenas"]["dbcId"] = 25
MTH_DS_Families["Hyenas"]["minScale"] = 0.7
MTH_DS_Families["Hyenas"]["maxScale"] = 0.9
MTH_DS_Families["Hyenas"]["minScaleLevel"] = 1
MTH_DS_Families["Hyenas"]["maxScaleLevel"] = 60
MTH_DS_Families["Hyenas"]["foodMask"] = 654
MTH_DS_Families["Hyenas"]["foodDbc"] = {
"fish",
"cheese",
"bread",
"raw fish",
}
end
-- DBC ID=26 PetFoodMask=655 scale=[0.50-0.80]
if MTH_DS_Families["Owls"] then
MTH_DS_Families["Owls"]["dbcId"] = 26
MTH_DS_Families["Owls"]["minScale"] = 0.5
MTH_DS_Families["Owls"]["maxScale"] = 0.8
MTH_DS_Families["Owls"]["minScaleLevel"] = 1
MTH_DS_Families["Owls"]["maxScaleLevel"] = 60
MTH_DS_Families["Owls"]["foodMask"] = 655
MTH_DS_Families["Owls"]["foodDbc"] = {
"meat",
"fish",
"cheese",
"bread",
"raw fish",
}
end
-- DBC ID=27 PetFoodMask=656 scale=[0.50-0.70]
if MTH_DS_Families["Wind Serpents"] then
MTH_DS_Families["Wind Serpents"]["dbcId"] = 27
MTH_DS_Families["Wind Serpents"]["minScale"] = 0.5
MTH_DS_Families["Wind Serpents"]["maxScale"] = 0.7
MTH_DS_Families["Wind Serpents"]["minScaleLevel"] = 1
MTH_DS_Families["Wind Serpents"]["maxScaleLevel"] = 60
MTH_DS_Families["Wind Serpents"]["foodMask"] = 656
MTH_DS_Families["Wind Serpents"]["foodDbc"] = {
"fungus",
"raw fish",
}
end
-- DBC ID=35 PetFoodMask=1009 scale=[0.60-0.80]
if MTH_DS_Families["Serpents (Cobra)"] then
MTH_DS_Families["Serpents (Cobra)"]["dbcId"] = 35
MTH_DS_Families["Serpents (Cobra)"]["minScale"] = 0.6
MTH_DS_Families["Serpents (Cobra)"]["maxScale"] = 0.8
MTH_DS_Families["Serpents (Cobra)"]["minScaleLevel"] = 1
MTH_DS_Families["Serpents (Cobra)"]["maxScaleLevel"] = 60
MTH_DS_Families["Serpents (Cobra)"]["foodMask"] = 1009
MTH_DS_Families["Serpents (Cobra)"]["foodDbc"] = {
"meat",
"fungus",
"fruit",
"raw meat",
"raw fish",
}
end
-- DBC ID=36 PetFoodMask=1010 scale=[0.70-0.90]
if MTH_DS_Families["Foxes"] then
MTH_DS_Families["Foxes"]["dbcId"] = 36
MTH_DS_Families["Foxes"]["minScale"] = 0.7
MTH_DS_Families["Foxes"]["maxScale"] = 0.9
MTH_DS_Families["Foxes"]["minScaleLevel"] = 1
MTH_DS_Families["Foxes"]["maxScaleLevel"] = 60
MTH_DS_Families["Foxes"]["foodMask"] = 1010
MTH_DS_Families["Foxes"]["foodDbc"] = {
"fish",
"fungus",
"fruit",
"raw meat",
"raw fish",
}
end
+40
View File
@@ -6,6 +6,7 @@ if not MTH_DS then MTH_DS = {} end
MTH_DS_Families = {
["Bats"] = {
["icon"] = "Ability_Hunter_Pet_Bat",
["named"] = 20,
["coords"] = 18,
["food"] = {
@@ -21,6 +22,7 @@ MTH_DS_Families = {
},
},
["Bears"] = {
["icon"] = "Ability_Hunter_Pet_Bear",
["named"] = 45,
["coords"] = 45,
["food"] = {
@@ -30,6 +32,8 @@ MTH_DS_Families = {
"cheese",
"fruit",
"fungus",
"raw meat",
"raw fish",
},
["abilities"] = {
"Bite",
@@ -40,6 +44,7 @@ MTH_DS_Families = {
},
},
["Boars"] = {
["icon"] = "Ability_Hunter_Pet_Boar",
["named"] = 45,
["coords"] = 87,
["food"] = {
@@ -49,6 +54,8 @@ MTH_DS_Families = {
"cheese",
"fruit",
"fungus",
"raw meat",
"raw fish",
},
["abilities"] = {
"Bite",
@@ -59,10 +66,12 @@ MTH_DS_Families = {
},
},
["Carrion Birds"] = {
["icon"] = "Ability_Hunter_Pet_Vulture",
["named"] = 36,
["coords"] = 101,
["food"] = {
"meat",
"raw meat",
},
["abilities"] = {
"Bite",
@@ -74,11 +83,14 @@ MTH_DS_Families = {
},
},
["Cats"] = {
["icon"] = "Ability_Hunter_Pet_Cat",
["named"] = 85,
["coords"] = 88,
["food"] = {
"meat",
"fish",
"raw meat",
"raw fish",
},
["abilities"] = {
"Bite",
@@ -90,6 +102,7 @@ MTH_DS_Families = {
},
},
["Crabs"] = {
["icon"] = "Ability_Hunter_Pet_Crab",
["named"] = 32,
["coords"] = 74,
["food"] = {
@@ -97,6 +110,7 @@ MTH_DS_Families = {
"fish",
"fungus",
"bread",
"raw fish",
},
["abilities"] = {
"Bubble Barrier",
@@ -106,11 +120,14 @@ MTH_DS_Families = {
},
},
["Crocolisks"] = {
["icon"] = "Ability_Hunter_Pet_Crocolisk",
["named"] = 27,
["coords"] = 71,
["food"] = {
"meat",
"fish",
"raw meat",
"raw fish",
},
["abilities"] = {
"Bite",
@@ -120,11 +137,13 @@ MTH_DS_Families = {
},
},
["Foxes"] = {
["icon"] = "ability_hunter_aspectofthefox",
["named"] = 9,
["coords"] = 51,
["food"] = {
"meat",
"fruit",
"raw meat",
},
["abilities"] = {
"Bite",
@@ -135,6 +154,7 @@ MTH_DS_Families = {
},
},
["Gorillas"] = {
["icon"] = "Ability_Hunter_Pet_Gorilla",
["named"] = 24,
["coords"] = 117,
["food"] = {
@@ -149,11 +169,13 @@ MTH_DS_Families = {
},
},
["Hyenas"] = {
["icon"] = "Ability_Hunter_Pet_Hyena",
["named"] = 26,
["coords"] = 36,
["food"] = {
"meat",
"fruit",
"raw meat",
},
["abilities"] = {
"Bite",
@@ -164,10 +186,12 @@ MTH_DS_Families = {
},
},
["Owls"] = {
["icon"] = "Ability_Hunter_Pet_Owl",
["named"] = 16,
["coords"] = 59,
["food"] = {
"meat",
"raw meat",
},
["abilities"] = {
"Claw",
@@ -178,10 +202,12 @@ MTH_DS_Families = {
},
},
["Raptors"] = {
["icon"] = "Ability_Hunter_Pet_Raptor",
["named"] = 51,
["coords"] = 115,
["food"] = {
"meat",
"raw meat",
},
["abilities"] = {
"Bite",
@@ -193,10 +219,12 @@ MTH_DS_Families = {
},
},
["Scorpids"] = {
["icon"] = "Ability_Hunter_Pet_Scorpid",
["named"] = 38,
["coords"] = 36,
["food"] = {
"meat",
"raw meat",
},
["abilities"] = {
"Claw",
@@ -206,11 +234,14 @@ MTH_DS_Families = {
},
},
["Serpents (Cobra)"] = {
["icon"] = "Ability_Hunter_Pet_Serpent1",
["named"] = 10,
["coords"] = 13,
["food"] = {
"meat",
"fish",
"raw meat",
"raw fish",
},
["abilities"] = {
"Bite",
@@ -220,10 +251,12 @@ MTH_DS_Families = {
},
},
["Spiders"] = {
["icon"] = "Ability_Hunter_Pet_Spider",
["named"] = 91,
["coords"] = 213,
["food"] = {
"meat",
"raw meat",
},
["abilities"] = {
"Bite",
@@ -233,6 +266,7 @@ MTH_DS_Families = {
},
},
["Tallstriders"] = {
["icon"] = "Ability_Hunter_Pet_TallStrider",
["named"] = 15,
["coords"] = 112,
["food"] = {
@@ -249,12 +283,14 @@ MTH_DS_Families = {
},
},
["Turtles"] = {
["icon"] = "Ability_Hunter_Pet_Turtle",
["named"] = 25,
["coords"] = 42,
["food"] = {
"fruit",
"fish",
"fungus",
"raw fish",
},
["abilities"] = {
"Bite",
@@ -264,12 +300,14 @@ MTH_DS_Families = {
},
},
["Wind Serpents"] = {
["icon"] = "Ability_Hunter_Pet_WindSerpent",
["named"] = 27,
["coords"] = 42,
["food"] = {
"fish",
"cheese",
"bread",
"raw fish",
},
["abilities"] = {
"Bite",
@@ -280,10 +318,12 @@ MTH_DS_Families = {
},
},
["Wolves"] = {
["icon"] = "Ability_Hunter_Pet_Wolf",
["named"] = 81,
["coords"] = 99,
["food"] = {
"meat",
"raw meat",
},
["abilities"] = {
"Bite",
File diff suppressed because it is too large Load Diff
+874
View File
@@ -0,0 +1,874 @@
-- MetaHunt: Beast appearance skin variants per family
-- AUTO-GENERATED by .tools — do not edit by hand.
-- Source DBC(s): CreatureDisplayInfo.dbc, CreatureModelData.dbc
-- Generated: 2026-03-17 14:49 UTC
-- Total skins: 244 across 19 families
if not MTH_DS then MTH_DS = {} end
MTH_DS_BeastSkins = {
["Bats"] = {
{id=1954, tex="BatSkin01", unique=false, modelPath="Creature\\FelBat\\FelBat.mdx"},
{id=3956, tex="BatSkinBrown01", unique=false, modelPath="Creature\\FelBat\\FelBat.mdx"},
{id=4185, tex="BatSkinViolet01", unique=false, modelPath="Creature\\FelBat\\FelBat.mdx"},
{id=4735, tex="BatSkinWhite01", unique=false, modelPath="Creature\\FelBat\\FelBat.mdx"},
{id=15191, tex="MobatSkinBlue01", unique=true, modelPath="Creature\\mobat\\Mobat.mdx"},
},
["Bears"] = {
{id=706, tex="BearSkinBlack", unique=false, modelPath="Creature\\bear\\Bear.mdx"},
{id=806, tex="BearSkinBlue", unique=false, modelPath="Creature\\bear\\Bear.mdx"},
{id=820, tex="BearSkinDrkBrown", unique=false, modelPath="Creature\\bear\\Bear.mdx"},
{id=822, tex="BearSkinBrown", unique=false, modelPath="Creature\\bear\\Bear.mdx"},
{id=865, tex="BearSkinWhite", unique=false, modelPath="Creature\\bear\\Bear.mdx"},
{id=1082, tex="BearSkinBlackDiseased", unique=true, modelPath="Creature\\bear\\Bear.mdx"},
{id=1083, tex="BearSkinDrkBrownDiseased", unique=false, modelPath="Creature\\bear\\Bear.mdx"},
{id=9492, tex="BearSkinrex2", unique=false, modelPath="Creature\\bear\\Bear.mdx"},
{id=18352, tex="PolarBearCubSkin", unique=true, modelPath="Creature\\bear\\Bear.mdx"},
{id=19113, tex="FatherBear", unique=true, modelPath="Creature\\bear\\Bear.mdx"},
{id=20635, tex="BearSkinBrownDiseased", unique=true, modelPath="Creature\\bear\\Bear.mdx"},
{id=20636, tex="BearSkinBlueDiseased", unique=true, modelPath="Creature\\bear\\Bear.mdx"},
{id=20637, tex="BearSkinWhiteDiseased", unique=true, modelPath="Creature\\bear\\Bear.mdx"},
},
["Boars"] = {
{id=193, tex="BoarSkinIvory", unique=false, modelPath="Creature\\Boar\\Boar.mdx"},
{id=377, tex="BoarSkinBrown", unique=false, modelPath="Creature\\Boar\\Boar.mdx"},
{id=381, tex="BoarSkinBlue", unique=false, modelPath="Creature\\Boar\\Boar.mdx"},
{id=2450, tex="BoarSkinIvoryArmored", unique=false, modelPath="Creature\\Boar\\Boar.mdx"},
{id=3026, tex="BoarSkinCrimson", unique=false, modelPath="Creature\\Boar\\Boar.mdx"},
{id=4713, tex="BoarSkinBrownArmored", unique=false, modelPath="Creature\\Boar\\Boar.mdx"},
{id=4714, tex="BoarSkinBlueArmored", unique=true, modelPath="Creature\\Boar\\Boar.mdx"},
{id=6121, tex="BoarSkinUndead", unique=false, modelPath="Creature\\Boar\\Boar.mdx"},
{id=8869, tex="BoarSkinYellow", unique=false, modelPath="Creature\\Boar\\Boar.mdx"},
{id=18729, tex="QuillBeastBlue", unique=true, modelPath="Creature\\Boar\\Boar.mdx"},
{id=20504, tex="BoarSkinQuel", unique=true, modelPath="Creature\\Boar\\Boar.mdx"},
},
["Carrion Birds"] = {
{id=388, tex="CarrionBirdSkin", unique=false, modelPath="Creature\\CarrionBird\\CarrionBird.mdx"},
{id=410, tex="CarrionBirdSkinBrown", unique=false, modelPath="Creature\\CarrionBird\\CarrionBird.mdx"},
{id=490, tex="CarrionBirdSkinRed", unique=false, modelPath="Creature\\CarrionBird\\CarrionBird.mdx"},
{id=507, tex="CarrionBirdSkinBlue", unique=false, modelPath="Creature\\CarrionBird\\CarrionBird.mdx"},
{id=18390, tex="CarrionBirdSkinWhite", unique=true, modelPath="Creature\\CarrionBird\\CarrionBird.mdx"},
},
["Cats"] = {
{id=320, tex="TigerSkinRed", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=321, tex="TigerSkinBlackStriped", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=599, tex="TigerSkinBlack", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=616, tex="TigerSkinWhite", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=632, tex="TigerSkinYellow", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=748, tex="TigerSkinSnow", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=892, tex="DruidCatSkinBlack", unique=true, modelPath="Creature\\DruidCat\\DruidCat.mdx"},
{id=1056, tex="TigerSkinBrown", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=1057, tex="LionSkinGold", unique=false, modelPath="Creature\\Lion\\Lion.mdx"},
{id=1933, tex="LionessSkinGold", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=1934, tex="LionSkinWhite", unique=false, modelPath="Creature\\Lion\\Lion.mdx"},
{id=3029, tex="TigerSkinDark", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=4424, tex="LionSkinBlack", unique=true, modelPath="Creature\\Lion\\Lion.mdx"},
{id=5448, tex="MaineCoon", unique=true, modelPath="Creature\\Cat\\Cat.mdx"},
{id=5554, tex="OrangeTabby", unique=true, modelPath="Creature\\Cat\\Cat.mdx"},
{id=5555, tex="SilverTabby", unique=true, modelPath="Creature\\Cat\\Cat.mdx"},
{id=5556, tex="Bombay", unique=true, modelPath="Creature\\Cat\\Cat.mdx"},
{id=5585, tex="Birman", unique=false, modelPath="Creature\\Cat\\Cat.mdx"},
{id=5586, tex="CornishRex", unique=true, modelPath="Creature\\Cat\\Cat.mdx"},
{id=9209, tex="Cringer", unique=true, modelPath="Creature\\Cat\\Cat.mdx"},
{id=9230, tex="TigerSkinGreen", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=9949, tex="TigerSkinIce", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=9954, tex="RidingTigerSkinLavender", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=9956, tex="RidingTigerSkinWhitenosaddle", unique=false, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=9958, tex="TigerSkinNostripeWhite", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=9989, tex="White", unique=false, modelPath="Creature\\Cat\\Cat.mdx"},
{id=10054, tex="RidingTigerSkinAqua", unique=false, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=11448, tex="TigerSkinBlackSpotted", unique=false, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=11709, tex="Salome", unique=true, modelPath="Creature\\Cat\\Cat.mdx"},
{id=18027, tex="LynxSkinRed", unique=true, modelPath="Creature\\DruidCat\\DruidCat.mdx"},
{id=18028, tex="LynxSkinYellow", unique=true, modelPath="Creature\\DruidCat\\DruidCat.mdx"},
{id=18389, tex="Boots", unique=true, modelPath="Creature\\Cat\\Cat.mdx"},
{id=18426, tex="RidingTigerSkinYellownosaddle", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=18427, tex="RidingTigerSkinIcenosaddle", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=18428, tex="RidingTigerSkinRednosaddle", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=18429, tex="RidingTigerSkinSnownosaddle", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=18430, tex="RidingTigerSkinGoldnosaddle", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=18431, tex="RidingTigerSkinBrownnosaddle", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=18432, tex="RidingTigerSkinBlacknosaddle", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=18433, tex="RidingTigerSkinDarknosaddle", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=18434, tex="RidingTigerSkinNostripeWhitenosaddle", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=20388, tex="TIGERSKINBLACKGEM", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=20389, tex="TigerSkinDiamond", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=20390, tex="TigerSkinJade", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=20391, tex="TigerSkinRuby", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=20392, tex="TigerSkinSaphire", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=20393, tex="TigerSkinTurquoise", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
{id=20410, tex="LionessSkinEmerald", unique=true, modelPath="Creature\\Tiger\\Tiger.mdx"},
{id=20437, tex="RidingTigerSkinDarknosaddle.blp", unique=true, modelPath="Creature\\FrostSabre\\FrostSabre.mdx"},
},
["Crabs"] = {
{id=342, tex="CrabSkinBronze", unique=false, modelPath="Creature\\Crab\\Crab.mdx"},
{id=979, tex="CrabSkinSaphire", unique=false, modelPath="Creature\\Crab\\Crab.mdx"},
{id=981, tex="CrabSkinIvory", unique=false, modelPath="Creature\\Crab\\Crab.mdx"},
{id=1307, tex="CrabSkinVermillian", unique=false, modelPath="Creature\\Crab\\Crab.mdx"},
{id=18757, tex="CrabSkinDarkDiamond", unique=true, modelPath="Creature\\Crab\\Crab.mdx"},
{id=18758, tex="CrabSkinTrueSilver", unique=true, modelPath="Creature\\Crab\\Crab.mdx"},
},
["Crocolisks"] = {
{id=807, tex="CrocodileSkinSwamp", unique=false, modelPath="Creature\\Crocodile\\Crocodile.mdx"},
{id=833, tex="CrocodileSkinRiver", unique=false, modelPath="Creature\\Crocodile\\Crocodile.mdx"},
{id=925, tex="CrocodileSkinMarsh", unique=false, modelPath="Creature\\Crocodile\\Crocodile.mdx"},
{id=1609, tex="CrocodileSkinAlbino", unique=false, modelPath="Creature\\Crocodile\\Crocodile.mdx"},
},
["Foxes"] = {
{id=18004, tex="MistFoxSkin", unique=true, modelPath="Creature\\Mistfox\\Mistfox.mdx"},
{id=18005, tex="MistFoxSkinArctic", unique=true, modelPath="Creature\\Mistfox\\Mistfox.mdx"},
{id=18006, tex="MistFoxSkinBlack", unique=false, modelPath="Creature\\Mistfox\\Mistfox.mdx"},
{id=18007, tex="MistFoxSkinBrown", unique=true, modelPath="Creature\\Mistfox\\Mistfox.mdx"},
{id=18008, tex="MistFoxSkinRed", unique=false, modelPath="Creature\\Mistfox\\Mistfox.mdx"},
{id=18244, tex="MistFoxSkinSpirit", unique=true, modelPath="Creature\\Mistfox\\Mistfox.mdx"},
{id=18773, tex="MistFoxSkinPink", unique=true, modelPath="Creature\\Mistfox\\Mistfox.mdx"},
{id=19105, tex="MistFoxSkinEvil", unique=true, modelPath="Creature\\Mistfox\\Mistfox.mdx"},
{id=19106, tex="MistFoxSkinGolden", unique=true, modelPath="Creature\\Mistfox\\Mistfox.mdx"},
{id=21282, tex="fox2_black", unique=true, modelPath="Creature\\fox2\\fox2.mdx"},
{id=21283, tex="fox2_blue", unique=true, modelPath="Creature\\fox2\\fox2.mdx"},
{id=21284, tex="fox2_darkred", unique=true, modelPath="Creature\\fox2\\fox2.mdx"},
{id=21285, tex="fox2_green", unique=true, modelPath="Creature\\fox2\\fox2.mdx"},
{id=21286, tex="fox2_orange", unique=true, modelPath="Creature\\fox2\\fox2.mdx"},
{id=21287, tex="fox2_purple", unique=true, modelPath="Creature\\fox2\\fox2.mdx"},
{id=21288, tex="fox2_red", unique=true, modelPath="Creature\\fox2\\fox2.mdx"},
{id=21289, tex="fox2_teal", unique=true, modelPath="Creature\\fox2\\fox2.mdx"},
{id=21290, tex="fox2_white", unique=true, modelPath="Creature\\fox2\\fox2.mdx"},
},
["Gorillas"] = {
{id=792, tex="GorillaSkinSilver", unique=false, modelPath="Creature\\Gorilla\\Gorilla.mdx"},
{id=809, tex="GorillaSkinBlack", unique=false, modelPath="Creature\\Gorilla\\Gorilla.mdx"},
{id=838, tex="GorillaSkinGrey", unique=false, modelPath="Creature\\Gorilla\\Gorilla.mdx"},
{id=840, tex="GorillaSkinWhite", unique=false, modelPath="Creature\\Gorilla\\Gorilla.mdx"},
{id=3186, tex="GorillaSkinRed", unique=false, modelPath="Creature\\Gorilla\\Gorilla.mdx"},
{id=8841, tex="GorillaSkinAmy", unique=true, modelPath="Creature\\Gorilla\\Gorilla.mdx"},
},
["Hyenas"] = {
{id=1534, tex="HyenaSkinOarnge", unique=false, modelPath="Creature\\Hyena\\Hyena.mdx"},
{id=1536, tex="HyenaSkin", unique=false, modelPath="Creature\\Hyena\\Hyena.mdx"},
{id=2709, tex="HyenaSkinRed", unique=false, modelPath="Creature\\Hyena\\Hyena.mdx"},
{id=2710, tex="HyenaSkinYellow", unique=false, modelPath="Creature\\Hyena\\Hyena.mdx"},
{id=2713, tex="HyenaSkinBlue", unique=false, modelPath="Creature\\Hyena\\Hyena.mdx"},
{id=2714, tex="HyenaSkinWhite", unique=false, modelPath="Creature\\Hyena\\Hyena.mdx"},
{id=2726, tex="HyenaSkinBlack", unique=false, modelPath="Creature\\Hyena\\Hyena.mdx"},
},
["Owls"] = {
{id=4566, tex="OwlBrown", unique=false, modelPath="Creature\\Owl\\Owl.mdx"},
{id=4877, tex="OwlGrey", unique=false, modelPath="Creature\\Owl\\Owl.mdx"},
{id=6212, tex="OwlWhite", unique=false, modelPath="Creature\\Owl\\Owl.mdx"},
{id=6298, tex="OwlBlue", unique=true, modelPath="Creature\\Owl\\Owl.mdx"},
{id=6299, tex="OwlBlack", unique=true, modelPath="Creature\\Owl\\Owl.mdx"},
{id=18338, tex="Eagle", unique=false, modelPath="Creature\\Eagle\\Eagle.mdx"},
{id=18339, tex="BrownEagle", unique=true, modelPath="Creature\\Eagle\\Eagle.mdx"},
{id=18368, tex="OwlSpirit", unique=true, modelPath="Creature\\Owl\\Owl.mdx"},
{id=18746, tex="EagleRaven", unique=true, modelPath="Creature\\Eagle\\Eagle.mdx"},
{id=21109, tex="OwlRuby", unique=true, modelPath="Creature\\Owl\\Owl.mdx"},
{id=21110, tex="OwlSapphire", unique=true, modelPath="Creature\\Owl\\Owl.mdx"},
},
["Raptors"] = {
{id=180, tex="RaptorSkinOrange", unique=false, modelPath="Creature\\Raptor\\Raptor.mdx"},
{id=322, tex="RaptorSkinMottledDarkGreen", unique=false, modelPath="Creature\\Raptor\\Raptor.mdx"},
{id=675, tex="RaptorSkinMottledBlueGreen", unique=false, modelPath="Creature\\Raptor\\Raptor.mdx"},
{id=787, tex="RaptorSkinYellow", unique=false, modelPath="Creature\\Raptor\\Raptor.mdx"},
{id=960, tex="RaptorSkinViolet", unique=false, modelPath="Creature\\Raptor\\Raptor.mdx"},
{id=1337, tex="RaptorSkinGrey", unique=false, modelPath="Creature\\Raptor\\Raptor.mdx"},
{id=1959, tex="RaptorSkinRed", unique=false, modelPath="Creature\\Raptor\\Raptor.mdx"},
{id=5291, tex="RidingRaptorSkinObsidian", unique=false, modelPath="Creature\\Raptor\\Raptor.mdx"},
},
["Scorpids"] = {
{id=2414, tex="ScorpionskinPink", unique=false, modelPath="Creature\\Scorpion\\Scorpion.mdx"},
{id=2485, tex="ScorpionskinBeige", unique=false, modelPath="Creature\\Scorpion\\Scorpion.mdx"},
{id=2487, tex="ScorpionskinYellow", unique=false, modelPath="Creature\\Scorpion\\Scorpion.mdx"},
{id=2488, tex="ScorpionskinBlack", unique=false, modelPath="Creature\\Scorpion\\Scorpion.mdx"},
{id=2489, tex="ScorpionskinRed", unique=false, modelPath="Creature\\Scorpion\\Scorpion.mdx"},
{id=2729, tex="ScorpionskinGolden", unique=false, modelPath="Creature\\Scorpion\\Scorpion.mdx"},
{id=2730, tex="ScorpionskinBlue", unique=false, modelPath="Creature\\Scorpion\\Scorpion.mdx"},
{id=7469, tex="SilithidScarabSkinBlack", unique=false, modelPath="Creature\\SILITHIDSCARAB\\SilithidScarab.mdx"},
{id=8971, tex="SilithidScarabSkinRed", unique=false, modelPath="Creature\\SILITHIDSCARAB\\SilithidScarab.mdx"},
{id=9028, tex="SilithidScarabSkinWhite", unique=false, modelPath="Creature\\SILITHIDSCARAB\\SilithidScarab.mdx"},
{id=9469, tex="SilithidScarabSkinYellow", unique=false, modelPath="Creature\\SILITHIDSCARAB\\SilithidScarab.mdx"},
{id=10983, tex="ScorpionskinSilver", unique=false, modelPath="Creature\\Scorpion\\Scorpion.mdx"},
{id=11093, tex="SilithidScarabSkinTeal", unique=false, modelPath="Creature\\SILITHIDSCARAB\\SilithidScarab.mdx"},
{id=11104, tex="SilithidScarabSkinGold", unique=false, modelPath="Creature\\SILITHIDSCARAB\\SilithidScarab.mdx"},
{id=11107, tex="SilithidScarabSkinPurple", unique=false, modelPath="Creature\\SILITHIDSCARAB\\SilithidScarab.mdx"},
{id=11143, tex="SilithidScarabSkinTan", unique=false, modelPath="Creature\\SILITHIDSCARAB\\SilithidScarab.mdx"},
{id=18373, tex="SilithidScarabSkinGreen", unique=true, modelPath="Creature\\SILITHIDSCARAB\\SilithidScarab.mdx"},
{id=21268, tex="ScorpionskinDarkIron", unique=true, modelPath="Creature\\Scorpion\\Scorpion.mdx"},
},
["Serpents (Cobra)"] = {
{id=1206, tex="SnakeSkinBlack", unique=false, modelPath="Creature\\snake\\snake.mdx"},
{id=1986, tex="SnakeSkinDarkGreenYellow", unique=false, modelPath="Creature\\snake\\snake.mdx"},
{id=1987, tex="SnakeSkinYellowBlack", unique=false, modelPath="Creature\\snake\\snake.mdx"},
{id=2954, tex="SnakeSkinRedWhiteBlack", unique=true, modelPath="Creature\\snake\\snake.mdx"},
{id=2955, tex="SnakeSkinWhite", unique=false, modelPath="Creature\\snake\\snake.mdx"},
{id=2956, tex="SnakeSkinBlue", unique=false, modelPath="Creature\\snake\\snake.mdx"},
{id=2957, tex="SnakeSkinBrown", unique=true, modelPath="Creature\\snake\\snake.mdx"},
{id=2958, tex="SnakeSkinGreen", unique=false, modelPath="Creature\\snake\\snake.mdx"},
{id=4305, tex="SerpantSkinWhite", unique=false, modelPath="Creature\\Serpent\\Serpent.mdx"},
{id=4312, tex="SerpantSkinPurple", unique=false, modelPath="Creature\\Serpent\\Serpent.mdx"},
{id=4317, tex="SerpantSkinBlue", unique=false, modelPath="Creature\\Serpent\\Serpent.mdx"},
{id=4435, tex="SerpantSkinGreen", unique=false, modelPath="Creature\\Serpent\\Serpent.mdx"},
{id=6303, tex="SnakeSkinRed", unique=true, modelPath="Creature\\snake\\snake.mdx"},
{id=11034, tex="SerpantSkinOlive", unique=false, modelPath="Creature\\Serpent\\Serpent.mdx"},
{id=15182, tex="SerpantSkinBrown", unique=true, modelPath="Creature\\Serpent\\Serpent.mdx"},
{id=20633, tex="SerpantSkinViolet", unique=true, modelPath="Creature\\Serpent\\Serpent.mdx"},
{id=20634, tex="SerpantSkinRuby", unique=true, modelPath="Creature\\Serpent\\Serpent.mdx"},
{id=21269, tex="SerpentSkinRuby", unique=true, modelPath="Creature\\Serpent\\Serpent.mdx"},
},
["Spiders"] = {
{id=30, tex="MineSpiderSkinSteel", unique=false, modelPath="Creature\\MineSpider\\MineSpider.mdx"},
{id=283, tex="MineSpiderSkinGreen", unique=false, modelPath="Creature\\MineSpider\\MineSpider.mdx"},
{id=336, tex="TarantulaSkinGreen", unique=false, modelPath="Creature\\Tarantula\\Tarantula.mdx"},
{id=366, tex="TarantulaSkinOrange", unique=false, modelPath="Creature\\Tarantula\\Tarantula.mdx"},
{id=513, tex="MineSpiderSkinOlive", unique=false, modelPath="Creature\\MineSpider\\MineSpider.mdx"},
{id=520, tex="TarantulaSkinBrown", unique=false, modelPath="Creature\\Tarantula\\Tarantula.mdx"},
{id=711, tex="MineSpiderSkinWetLands", unique=false, modelPath="Creature\\MineSpider\\MineSpider.mdx"},
{id=955, tex="MineSpiderSkinCave", unique=false, modelPath="Creature\\MineSpider\\MineSpider.mdx"},
{id=963, tex="MineSpiderSkinBlood", unique=false, modelPath="Creature\\MineSpider\\MineSpider.mdx"},
{id=1091, tex="TarantulaSkinGrey", unique=false, modelPath="Creature\\Tarantula\\Tarantula.mdx"},
{id=2536, tex="MineSpiderSkinJungle", unique=false, modelPath="Creature\\MineSpider\\MineSpider.mdx"},
{id=4456, tex="MineSpiderSkinCrystal", unique=false, modelPath="Creature\\MineSpider\\MineSpider.mdx"},
{id=4457, tex="TarantulaSkinMagma", unique=false, modelPath="Creature\\Tarantula\\Tarantula.mdx"},
{id=15937, tex="MineSpiderSkinViolet", unique=true, modelPath="Creature\\MineSpider\\MineSpider.mdx"},
},
["Tallstriders"] = {
{id=38, tex="TallStriderSkinTurquoise", unique=false, modelPath="Creature\\Tallstrider\\TallStrider.mdx"},
{id=178, tex="TallStriderSkinBrown", unique=false, modelPath="Creature\\Tallstrider\\TallStrider.mdx"},
{id=1220, tex="TallStriderSkinGray", unique=false, modelPath="Creature\\Tallstrider\\TallStrider.mdx"},
{id=1221, tex="TallStriderSkinIvory", unique=false, modelPath="Creature\\Tallstrider\\TallStrider.mdx"},
{id=1281, tex="TallStriderSkinPurple", unique=true, modelPath="Creature\\Tallstrider\\TallStrider.mdx"},
{id=1961, tex="TallStriderSkinPink", unique=true, modelPath="Creature\\Tallstrider\\TallStrider.mdx"},
{id=20509, tex="HawkstriderBlue", unique=true, modelPath="Creature\\Hawkstrider\\Hawkstrider.mdx"},
{id=20510, tex="HawkstriderGold", unique=true, modelPath="Creature\\Hawkstrider\\Hawkstrider.mdx"},
{id=20511, tex="HawkstriderGreen", unique=true, modelPath="Creature\\Hawkstrider\\Hawkstrider.mdx"},
{id=20512, tex="HawkstriderRed", unique=true, modelPath="Creature\\Hawkstrider\\Hawkstrider.mdx"},
{id=20513, tex="HawkstriderWhite", unique=true, modelPath="Creature\\Hawkstrider\\Hawkstrider.mdx"},
},
["Turtles"] = {
{id=1244, tex="SeaTurtleSkin", unique=false, modelPath="Creature\\SeaTurtle\\SeaTurtle.mdx"},
{id=2307, tex="SeaTurtleSkinWhite", unique=false, modelPath="Creature\\SeaTurtle\\SeaTurtle.mdx"},
{id=4829, tex="SeaTurtleSkinGrey", unique=false, modelPath="Creature\\SeaTurtle\\SeaTurtle.mdx"},
{id=5026, tex="SeaTurtleSkinRed", unique=false, modelPath="Creature\\SeaTurtle\\SeaTurtle.mdx"},
{id=5126, tex="SeaTurtleSkinBlue", unique=false, modelPath="Creature\\SeaTurtle\\SeaTurtle.mdx"},
{id=16259, tex="TurtleSkinGreen", unique=false, modelPath="Creature\\Turtle\\Turtle.mdx"},
{id=16360, tex="TurtleSkinBrown", unique=true, modelPath="Creature\\Turtle\\Turtle.mdx"},
{id=16361, tex="TurtleSkinBlack", unique=true, modelPath="Creature\\Turtle\\Turtle.mdx"},
},
["Wind Serpents"] = {
{id=1336, tex="WindSerpentSkin", unique=false, modelPath="Creature\\WindSerpent\\WindSerpent.mdx"},
{id=2699, tex="WindSerpentSkinRed", unique=false, modelPath="Creature\\WindSerpent\\WindSerpent.mdx"},
{id=2700, tex="WindSerpentSkinGreen", unique=false, modelPath="Creature\\WindSerpent\\WindSerpent.mdx"},
{id=2703, tex="WindSerpentSkinWhite", unique=false, modelPath="Creature\\WindSerpent\\WindSerpent.mdx"},
{id=3006, tex="WindSerpentSkinBlack", unique=false, modelPath="Creature\\WindSerpent\\WindSerpent.mdx"},
{id=18386, tex="WindSerpentSkinOarnge", unique=true, modelPath="Creature\\WindSerpent\\WindSerpent.mdx"},
{id=20514, tex="ManaWurmSkinBlack", unique=true, modelPath="Creature\\Manawurm\\manawurm.mdx"},
{id=20515, tex="MANAWURMSKINGREEN", unique=true, modelPath="Creature\\Manawurm\\manawurm.mdx"},
{id=20516, tex="ManaWurmSkinPurple", unique=true, modelPath="Creature\\Manawurm\\manawurm.mdx"},
{id=20517, tex="ManaWurmSkinQuel", unique=true, modelPath="Creature\\Manawurm\\manawurm.mdx"},
{id=20518, tex="ManaWurmSkinSilver1", unique=true, modelPath="Creature\\Manawurm\\manawurm.mdx"},
{id=20519, tex="ManaWurmSkinWhite", unique=true, modelPath="Creature\\Manawurm\\manawurm.mdx"},
},
["Wolves"] = {
{id=73, tex="Direwolfskinbrown", unique=true, modelPath="Creature\\DireWolf\\DireWolf.mdx"},
{id=161, tex="WolfSkinCoyote", unique=false, modelPath="Creature\\Wolf\\Wolf.mdx"},
{id=165, tex="WolfSkinTimber", unique=false, modelPath="Creature\\Wolf\\Wolf.mdx"},
{id=246, tex="DireWolfSkinDarkBlack", unique=false, modelPath="Creature\\DireWolf\\DireWolf.mdx"},
{id=644, tex="WolfSkinBlack", unique=false, modelPath="Creature\\Wolf\\Wolf.mdx"},
{id=720, tex="DireWolfSkinLightBlue", unique=false, modelPath="Creature\\DireWolf\\DireWolf.mdx"},
{id=776, tex="WolfSkinArctic", unique=false, modelPath="Creature\\Wolf\\Wolf.mdx"},
{id=868, tex="WolfSkinArcticAlpha", unique=true, modelPath="Creature\\Wolf\\Wolf.mdx"},
{id=1950, tex="WolfSkin_Ghost", unique=true, modelPath="Creature\\Wolf\\Wolf.mdx"},
{id=3916, tex="HoundSkinBlue", unique=false, modelPath="Creature\\DarkHound\\DarkHound.mdx"},
{id=4124, tex="WolfSkinDiseased", unique=false, modelPath="Creature\\Wolf\\Wolf.mdx"},
{id=6195, tex="HoundSkinGrey", unique=false, modelPath="Creature\\DarkHound\\DarkHound.mdx"},
{id=7890, tex="HoundSkinPurple", unique=false, modelPath="Creature\\DarkHound\\DarkHound.mdx"},
{id=8180, tex="HoundSkinRed", unique=false, modelPath="Creature\\DarkHound\\DarkHound.mdx"},
{id=9369, tex="DireWolfSkinReddishBrown", unique=false, modelPath="Creature\\DireWolf\\DireWolf.mdx"},
{id=9564, tex="DireWolfSkinLightGrey", unique=false, modelPath="Creature\\DireWolf\\DireWolf.mdx"},
{id=9567, tex="DireWolfSkinBlueBrown", unique=true, modelPath="Creature\\DireWolf\\DireWolf.mdx"},
{id=9568, tex="DireWolfSkinDarkBrown", unique=false, modelPath="Creature\\DireWolf\\DireWolf.mdx"},
{id=11414, tex="DireWolfSkinDarkGrey", unique=true, modelPath="Creature\\DireWolf\\DireWolf.mdx"},
{id=14312, tex="HoundSkinWhite", unique=false, modelPath="Creature\\DarkHound\\DarkHound.mdx"},
},
}
-- Maps any beast displayId to the canonical skin id used in MTH_DS_BeastSkins
-- Total: 577 entries
MTH_DS_DisplayToSkin = {
[368] = 30,
[372] = 165,
[380] = 165,
[382] = 366,
[389] = 193,
[418] = 30,
[447] = 165,
[471] = 320,
[498] = 366,
[499] = 193,
[503] = 193,
[538] = 513,
[539] = 30,
[545] = 283,
[557] = 161,
[566] = 520,
[598] = 320,
[604] = 165,
[607] = 381,
[613] = 599,
[614] = 320,
[615] = 322,
[633] = 599,
[641] = 342,
[643] = 161,
[647] = 165,
[648] = 322,
[649] = 180,
[651] = 366,
[659] = 513,
[666] = 165,
[670] = 180,
[671] = 180,
[672] = 180,
[673] = 180,
[674] = 322,
[676] = 322,
[677] = 675,
[695] = 322,
[698] = 320,
[699] = 342,
[703] = 377,
[704] = 377,
[707] = 706,
[709] = 336,
[719] = 706,
[741] = 246,
[744] = 381,
[749] = 748,
[755] = 675,
[759] = 336,
[760] = 336,
[762] = 706,
[768] = 283,
[780] = 644,
[781] = 644,
[782] = 644,
[783] = 165,
[784] = 644,
[785] = 776,
[788] = 180,
[801] = 776,
[802] = 776,
[814] = 807,
[815] = 807,
[821] = 520,
[827] = 520,
[831] = 807,
[834] = 833,
[835] = 807,
[837] = 792,
[839] = 809,
[841] = 792,
[842] = 838,
[843] = 838,
[844] = 792,
[845] = 809,
[855] = 776,
[869] = 776,
[902] = 822,
[903] = 165,
[909] = 520,
[910] = 520,
[913] = 865,
[917] = 632,
[918] = 632,
[945] = 180,
[948] = 180,
[949] = 675,
[954] = 748,
[957] = 283,
[958] = 955,
[959] = 955,
[961] = 787,
[982] = 822,
[996] = 979,
[997] = 981,
[998] = 979,
[999] = 981,
[1000] = 979,
[1001] = 981,
[1006] = 822,
[1007] = 806,
[1008] = 632,
[1030] = 720,
[1034] = 807,
[1035] = 925,
[1036] = 925,
[1037] = 833,
[1038] = 925,
[1039] = 833,
[1040] = 38,
[1041] = 178,
[1042] = 178,
[1043] = 632,
[1055] = 632,
[1058] = 1056,
[1059] = 1056,
[1080] = 807,
[1087] = 955,
[1088] = 513,
[1089] = 513,
[1090] = 955,
[1094] = 809,
[1095] = 599,
[1100] = 161,
[1103] = 1091,
[1104] = 1091,
[1105] = 388,
[1106] = 388,
[1157] = 955,
[1160] = 955,
[1164] = 161,
[1167] = 193,
[1192] = 507,
[1207] = 776,
[1208] = 377,
[1210] = 490,
[1219] = 178,
[1222] = 161,
[1228] = 388,
[1229] = 388,
[1250] = 833,
[1251] = 833,
[1259] = 180,
[1283] = 178,
[1284] = 1221,
[1338] = 960,
[1339] = 1337,
[1340] = 1337,
[1535] = 1534,
[1742] = 1336,
[1744] = 960,
[1746] = 1337,
[1747] = 960,
[1873] = 513,
[1938] = 1307,
[1939] = 1307,
[1955] = 1954,
[1960] = 1959,
[1962] = 1959,
[1971] = 1057,
[1972] = 1057,
[1973] = 1057,
[1974] = 1336,
[1975] = 1336,
[1977] = 1057,
[1978] = 1933,
[1989] = 336,
[1990] = 822,
[2031] = 1056,
[2239] = 979,
[2278] = 1056,
[2279] = 616,
[2300] = 1056,
[2301] = 1536,
[2305] = 410,
[2308] = 2307,
[2352] = 246,
[2378] = 822,
[2424] = 366,
[2433] = 30,
[2437] = 599,
[2453] = 2450,
[2486] = 2485,
[2491] = 2488,
[2537] = 2536,
[2538] = 2536,
[2539] = 2536,
[2540] = 283,
[2541] = 283,
[2542] = 366,
[2543] = 366,
[2544] = 366,
[2545] = 366,
[2546] = 366,
[2548] = 925,
[2549] = 925,
[2550] = 807,
[2570] = 1959,
[2571] = 1959,
[2573] = 1959,
[2574] = 1959,
[2609] = 1534,
[2702] = 2699,
[2705] = 2703,
[2706] = 2700,
[2707] = 2700,
[2708] = 2700,
[2711] = 2710,
[2712] = 2710,
[2715] = 2714,
[2716] = 2714,
[2731] = 2730,
[2732] = 2487,
[2741] = 1220,
[2765] = 2729,
[2766] = 2729,
[2850] = 1609,
[2864] = 2488,
[2902] = 1244,
[2995] = 2958,
[2996] = 1609,
[3027] = 3026,
[3030] = 3029,
[3031] = 3029,
[3035] = 3026,
[3126] = 1206,
[3187] = 3186,
[3188] = 3186,
[3200] = 806,
[3201] = 806,
[3202] = 165,
[3203] = 165,
[3204] = 2699,
[3205] = 2699,
[3247] = 2489,
[3248] = 490,
[4065] = 2699,
[4090] = 1609,
[4091] = 2700,
[4167] = 2956,
[4268] = 1206,
[4343] = 1986,
[4440] = 1987,
[4442] = 960,
[4458] = 4457,
[4472] = 748,
[4480] = 4312,
[4613] = 161,
[4615] = 4566,
[4636] = 2710,
[4689] = 2709,
[4716] = 4713,
[4732] = 3956,
[4733] = 4185,
[4734] = 3956,
[4767] = 4317,
[4768] = 4435,
[5027] = 5026,
[5030] = 5026,
[5052] = 2307,
[5066] = 1933,
[5067] = 599,
[5068] = 3029,
[5069] = 632,
[5127] = 5126,
[5242] = 960,
[5244] = 792,
[5245] = 838,
[5290] = 675,
[5292] = 960,
[5294] = 792,
[5295] = 838,
[5296] = 838,
[5510] = 822,
[5557] = 342,
[5558] = 981,
[5559] = 979,
[5560] = 1307,
[5905] = 2488,
[5966] = 4305,
[5985] = 2489,
[6068] = 2488,
[6069] = 2488,
[6070] = 2488,
[6073] = 1091,
[6076] = 1220,
[6082] = 1056,
[6122] = 6121,
[6126] = 1244,
[6196] = 6195,
[6210] = 616,
[6213] = 1091,
[6214] = 1091,
[6248] = 616,
[6300] = 4877,
[6368] = 5126,
[6468] = 5291,
[6805] = 3029,
[6807] = 3026,
[6808] = 336,
[6942] = 1056,
[6943] = 599,
[7046] = 5126,
[7114] = 5126,
[7339] = 644,
[7347] = 2489,
[7348] = 490,
[7349] = 490,
[7409] = 1206,
[7470] = 7469,
[7510] = 4457,
[7511] = 7469,
[7569] = 2703,
[7619] = 7469,
[7691] = 2703,
[7829] = 3006,
[7836] = 4829,
[7837] = 4829,
[7839] = 4829,
[7840] = 4829,
[7891] = 7890,
[7892] = 7890,
[7893] = 7890,
[7894] = 4185,
[7896] = 1954,
[7897] = 4185,
[7906] = 2699,
[8014] = 520,
[8050] = 2714,
[8129] = 840,
[8173] = 2955,
[8174] = 1987,
[8181] = 8180,
[8271] = 4456,
[8472] = 675,
[8473] = 960,
[8808] = 4185,
[8837] = 865,
[8838] = 806,
[8839] = 792,
[8840] = 806,
[8842] = 865,
[8843] = 706,
[8844] = 3186,
[8870] = 381,
[8871] = 8869,
[8969] = 2487,
[8970] = 2487,
[9019] = 8180,
[9020] = 3916,
[9021] = 3916,
[9022] = 7890,
[9029] = 9028,
[9050] = 675,
[9074] = 1954,
[9276] = 1083,
[9277] = 1083,
[9278] = 4124,
[9280] = 4124,
[9287] = 644,
[9354] = 7469,
[9370] = 9369,
[9371] = 9369,
[9372] = 9369,
[9509] = 644,
[9511] = 644,
[9535] = 3956,
[9558] = 644,
[9562] = 246,
[9563] = 246,
[9565] = 981,
[9566] = 979,
[9569] = 9568,
[9570] = 342,
[9571] = 342,
[9572] = 9568,
[9573] = 979,
[9749] = 2488,
[9750] = 4735,
[9755] = 4456,
[9756] = 4456,
[9829] = 513,
[9910] = 30,
[9913] = 2699,
[9929] = 4456,
[9934] = 336,
[9950] = 9949,
[9951] = 9949,
[9953] = 616,
[9955] = 9949,
[9957] = 9949,
[9990] = 9989,
[9992] = 9230,
[9993] = 9230,
[9997] = 4456,
[10015] = 193,
[10031] = 8971,
[10033] = 1954,
[10055] = 1934,
[10113] = 10054,
[10114] = 1934,
[10133] = 840,
[10183] = 2699,
[10209] = 246,
[10270] = 2726,
[10271] = 2726,
[10273] = 507,
[10274] = 776,
[10278] = 720,
[10618] = 865,
[10824] = 388,
[10825] = 410,
[10826] = 507,
[10827] = 490,
[10828] = 6212,
[10829] = 4877,
[10830] = 4877,
[10831] = 4877,
[10832] = 4877,
[10833] = 6212,
[10902] = 2726,
[10903] = 2713,
[10904] = 2713,
[10947] = 2307,
[10984] = 2487,
[10985] = 2487,
[10986] = 2414,
[10987] = 2414,
[10988] = 10983,
[10991] = 2700,
[11029] = 320,
[11031] = 320,
[11032] = 3956,
[11089] = 9469,
[11094] = 11093,
[11098] = 2485,
[11105] = 11104,
[11108] = 11107,
[11144] = 11143,
[11315] = 1959,
[11316] = 787,
[11317] = 960,
[11318] = 675,
[11319] = 322,
[11348] = 366,
[11411] = 246,
[11412] = 720,
[11413] = 9564,
[11415] = 9564,
[11416] = 776,
[11417] = 9564,
[11418] = 9564,
[11419] = 9564,
[11420] = 9369,
[11421] = 246,
[11422] = 720,
[11444] = 9958,
[11445] = 9958,
[11446] = 616,
[11447] = 320,
[11449] = 321,
[11450] = 321,
[11451] = 1056,
[11452] = 599,
[11453] = 11448,
[11454] = 3029,
[11455] = 320,
[11829] = 4735,
[11908] = 820,
[11909] = 820,
[11910] = 599,
[12151] = 11093,
[12156] = 11107,
[12157] = 11104,
[12159] = 9469,
[12433] = 410,
[12966] = 2710,
[13096] = 7469,
[13097] = 10983,
[13111] = 963,
[13589] = 1609,
[14256] = 925,
[14313] = 490,
[14315] = 822,
[14316] = 822,
[14318] = 11448,
[14319] = 507,
[14364] = 9956,
[14557] = 11034,
[14558] = 4435,
[14559] = 4305,
[14562] = 3956,
[14572] = 599,
[14657] = 5126,
[14658] = 4829,
[14659] = 1244,
[14660] = 5026,
[14661] = 2307,
[14780] = 1954,
[14853] = 711,
[14935] = 599,
[14950] = 955,
[14952] = 955,
[15072] = 711,
[15132] = 4317,
[15133] = 4435,
[15135] = 4312,
[15136] = 711,
[15137] = 3006,
[15138] = 320,
[15145] = 833,
[15150] = 4317,
[15151] = 320,
[15180] = 9369,
[15181] = 14312,
[15204] = 9369,
[15227] = 4735,
[15275] = 2699,
[15302] = 3186,
[15327] = 2489,
[15336] = 2485,
[15339] = 11104,
[15383] = 10983,
[15384] = 2729,
[15385] = 10983,
[15422] = 2730,
[15423] = 2730,
[15433] = 2488,
[15464] = 9028,
[15467] = 11104,
[15468] = 11143,
[15469] = 2485,
[15470] = 2729,
[15471] = 2489,
[15533] = 2414,
[15534] = 6212,
[15682] = 11107,
[15878] = 776,
[15929] = 7469,
[15938] = 513,
[15939] = 2536,
[15964] = 14312,
[15969] = 3916,
[16145] = 5126,
[16359] = 16259,
[16622] = 5585,
[18115] = 9492,
[18177] = 18008,
[18353] = 18338,
[18493] = 18006,
[20369] = 18027,
[20370] = 1933,
[20371] = 11448,
[20372] = 321,
[20373] = 9230,
[20374] = 18432,
[20375] = 18431,
[20376] = 18433,
[20377] = 18430,
[20378] = 18427,
[20379] = 18434,
[20380] = 18428,
[20381] = 18429,
[20382] = 9956,
[20383] = 18426,
[20384] = 11448,
[20385] = 321,
[20386] = 9230,
[20387] = 1933,
[20394] = 20388,
[20395] = 20389,
[20396] = 20390,
[20397] = 20391,
[20398] = 20392,
[20399] = 20393,
}
File diff suppressed because it is too large Load Diff
+1264 -1
View File
File diff suppressed because it is too large Load Diff
+163
View File
@@ -0,0 +1,163 @@
-- MetaHunt: Pet spell DBC acquire-method overlay (learnMethod, minRank, nextSpellId)
-- AUTO-GENERATED by .tools — do not edit by hand.
-- Source DBC(s): SkillLineAbility.dbc, SkillLine.dbc
-- Generated: 2026-03-17 07:31 UTC
-- This file patches MTH_DS_PetSpells.allSpells entries with DBC-authoritative
-- learnMethod, minRank, and nextSpellId values.
-- Load order: after ds-pet-spells.lua and ds-pet-spells-trainer.lua
if not MTH_DS_PetSpells or not MTH_DS_PetSpells.allSpells then return end
local _acquire = {
[1747] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[1748] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[1749] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[1750] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[1751] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[1853] = { learnMethod="unknown(1)", minRank=1, nextSpellId=0, skillLineId=261 },
[2975] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[2976] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[2977] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[2980] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[2981] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[2982] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[3666] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[3667] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[4195] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[4196] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[4197] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[4198] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[4199] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[4200] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[4201] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[4202] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[5048] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[5049] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[5149] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[7370] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[14922] = { learnMethod="unknown(1)", minRank=1, nextSpellId=0, skillLineId=261 },
[14923] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[14924] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[14925] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[14926] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[14927] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[16698] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[17254] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[17262] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[17263] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[17264] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[17265] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[17266] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[17267] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[17268] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[23100] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[23111] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[23112] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[23146] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[23149] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[23150] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[23163] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[23166] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[23167] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24424] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24440] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24441] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24451] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24454] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24455] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24463] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24464] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24475] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24476] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24477] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24478] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24490] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24494] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24495] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24508] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24509] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24510] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24511] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24512] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24513] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24514] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24515] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24516] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24547] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24556] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24557] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24558] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24559] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24560] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24561] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24562] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24580] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24581] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24582] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24584] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24588] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24589] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24599] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24607] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24608] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24609] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24631] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24632] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24641] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[24845] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[25013] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[25014] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[25015] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[25016] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[25017] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[25077] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[26065] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[26094] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[26184] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[26185] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[26186] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[26189] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[26190] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[26202] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[28343] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36554] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36555] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36556] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36557] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36558] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36559] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36560] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36561] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36563] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36564] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36565] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36566] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36567] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36568] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36569] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36570] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36571] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36572] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36573] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[36574] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[46023] = { learnMethod="trainer", minRank=0, nextSpellId=0, skillLineId=261 },
[46276] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[46303] = { learnMethod="trainer", minRank=0, nextSpellId=0, skillLineId=261 },
[46304] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[46307] = { learnMethod="trainer", minRank=0, nextSpellId=0, skillLineId=261 },
[46310] = { learnMethod="trainer", minRank=1, nextSpellId=0, skillLineId=261 },
[51154] = { learnMethod="trainer", minRank=0, nextSpellId=0, skillLineId=261 },
[51155] = { learnMethod="trainer", minRank=0, nextSpellId=0, skillLineId=261 },
[51157] = { learnMethod="trainer", minRank=0, nextSpellId=0, skillLineId=261 },
}
for _, spell in ipairs(MTH_DS_PetSpells.allSpells) do
local meta = _acquire[spell.id]
if meta then
spell.learnMethod = meta.learnMethod
spell.minRank = meta.minRank
spell.nextSpellId = meta.nextSpellId
spell.skillLineId = meta.skillLineId
end
end
+37
View File
@@ -0,0 +1,37 @@
-- MetaHunt: Stable slot prices
-- AUTO-GENERATED by .tools — do not edit by hand.
-- Source DBC(s): StableSlotPrices.dbc
-- Generated: 2026-03-17 07:31 UTC
if not MTH_DS then MTH_DS = {} end
MTH_DS_StableSlotPrices = {
[1] = {
["cost_copper"] = 500,
["cost_gold"] = 0,
["cost_silver"] = 5,
["cost_copper_remainder"] = 0,
["display"] = "0g 5s 0c",
},
[2] = {
["cost_copper"] = 50000,
["cost_gold"] = 5,
["cost_silver"] = 0,
["cost_copper_remainder"] = 0,
["display"] = "5g 0s 0c",
},
[3] = {
["cost_copper"] = 2500000,
["cost_gold"] = 250,
["cost_silver"] = 0,
["cost_copper_remainder"] = 0,
["display"] = "250g 0s 0c",
},
[4] = {
["cost_copper"] = 1,
["cost_gold"] = 0,
["cost_silver"] = 0,
["cost_copper_remainder"] = 1,
["display"] = "0g 0s 1c",
},
}
+84
View File
@@ -0,0 +1,84 @@
-- MetaHunt: Zone DBC enrichment (worldBounds, dbcAreaId, dbcMapId, dbcName)
-- AUTO-GENERATED by .tools — do not edit by hand.
-- Source DBC(s): WorldMapArea.dbc, AreaTable.dbc
-- Generated: 2026-03-17 07:31 UTC
if not MTH_DS_Zones then return end
-- WMA ID=301 map=0 'Stormwind'
if MTH_DS_Zones[1519] then
MTH_DS_Zones[1519]["dbcAreaId"] = 1519
MTH_DS_Zones[1519]["dbcMapId"] = 0
MTH_DS_Zones[1519]["dbcName"] = "Stormwind"
MTH_DS_Zones[1519]["worldBounds"] = {
["left"] = 1722.92,
["right"] = -14.58,
["top"] = -7995.8301,
["bottom"] = -9154.1699,
}
end
-- WMA ID=321 map=1 'Ogrimmar'
if MTH_DS_Zones[1637] then
MTH_DS_Zones[1637]["dbcAreaId"] = 1637
MTH_DS_Zones[1637]["dbcMapId"] = 1
MTH_DS_Zones[1637]["dbcName"] = "Ogrimmar"
MTH_DS_Zones[1637]["worldBounds"] = {
["left"] = -3680.6001,
["right"] = -5083.21,
["top"] = 2273.8799,
["bottom"] = 1338.46,
}
end
-- WMA ID=362 map=1 'ThunderBluff'
if MTH_DS_Zones[1638] then
MTH_DS_Zones[1638]["dbcAreaId"] = 1638
MTH_DS_Zones[1638]["dbcMapId"] = 1
MTH_DS_Zones[1638]["dbcName"] = "ThunderBluff"
MTH_DS_Zones[1638]["worldBounds"] = {
["left"] = 516.67,
["right"] = -527.08,
["top"] = -850.0,
["bottom"] = -1545.83,
}
end
-- WMA ID=381 map=1 'Darnassis'
if MTH_DS_Zones[1657] then
MTH_DS_Zones[1657]["dbcAreaId"] = 1657
MTH_DS_Zones[1657]["dbcMapId"] = 1
MTH_DS_Zones[1657]["dbcName"] = "Darnassis"
MTH_DS_Zones[1657]["worldBounds"] = {
["left"] = 2938.3601,
["right"] = 1880.03,
["top"] = 10238.3203,
["bottom"] = 9532.5898,
}
end
-- WMA ID=382 map=0 'Undercity'
if MTH_DS_Zones[1497] then
MTH_DS_Zones[1497]["dbcAreaId"] = 1497
MTH_DS_Zones[1497]["dbcMapId"] = 0
MTH_DS_Zones[1497]["dbcName"] = "Undercity"
MTH_DS_Zones[1497]["worldBounds"] = {
["left"] = 873.19,
["right"] = -86.18,
["top"] = 1877.95,
["bottom"] = 1237.84,
}
end
-- WMA ID=509 map=0 'AlahThalas'
if MTH_DS_Zones[2040] then
MTH_DS_Zones[2040]["dbcAreaId"] = 2040
MTH_DS_Zones[2040]["dbcMapId"] = 0
MTH_DS_Zones[2040]["dbcName"] = "AlahThalas"
MTH_DS_Zones[2040]["worldBounds"] = {
["left"] = -2169.0,
["right"] = -3637.0,
["top"] = 4907.0,
["bottom"] = 3931.0,
}
end
File diff suppressed because it is too large Load Diff
-1052
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -17,6 +17,8 @@
<Include file="..\api\options-autobuy.lua"/>
<Include file="..\api\options-autoquest.lua"/>
<Include file="..\api\options-icu.lua"/>
<Include file="..\api\profile.lua"/>
<Include file="..\api\options-profiles.lua"/>
<Include file="..\api\options-shell.lua"/>
<Include file="..\api\options-zbuttons.lua"/>
<Include file="..\api\options-feedomatic.lua"/>
@@ -29,6 +31,7 @@
<Include file="..\api\hunterbook-tab-npcfinder.lua"/>
<Include file="..\api\hunterbook-tab-stable.lua"/>
<Include file="..\api\hunterbook-tab-pethistory.lua"/>
<Include file="..\api\hunterbook-model-viewer.lua"/>
<Include file="..\api\map-markers.lua"/>
<Include file="..\api\core-framework.lua"/>
<Include file="..\api\core-scan-stablemaster.lua"/>
+4 -7
View File
@@ -6,7 +6,7 @@
local MTH_AutoBuy = {
name = "autobuy",
enabled = false,
version = "1.1.0",
version = "1.3.0",
events = {
"VARIABLES_LOADED",
"MERCHANT_SHOW",
@@ -33,7 +33,7 @@ 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
@@ -42,8 +42,8 @@ local function AB_EnsureBridgeFrame(moduleRef)
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")
@@ -140,12 +140,9 @@ function MTH_AutoBuy:onEvent(event)
return
end
AB_Log("onEvent event=" .. tostring(event) .. " module.enabled=" .. tostring(self.enabled), "debug")
if event == "VARIABLES_LOADED" then
engine:Init()
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)
.. " store.enabled=" .. tostring(store and store.enabled)
+27 -62
View File
@@ -6,7 +6,7 @@
local MTH_AutoQuest = {
name = "autoquest",
enabled = false,
version = "1.1.0",
version = "1.3.0",
events = {
"GOSSIP_SHOW",
"QUEST_GREETING",
@@ -34,7 +34,6 @@ 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_DirectEventFrame = nil
local QA_TooltipHooked = false
local QA_TooltipPollFrame = nil
local QA_TooltipRefreshFrame = nil
@@ -292,7 +291,8 @@ local function QA_CountItemInBags(expectedId, expectedName)
for slot = 1, slots do
local link = getContainerItemLink(bag, slot)
if type(link) == "string" and link ~= "" then
local itemId = tonumber(string.match(link, "item:(%d+)"))
local _, _, itemIdStr = string.find(link, "item:(%d+)")
local itemId = tonumber(itemIdStr)
local itemName = nil
if type(getItemInfo) == "function" then
itemName = getItemInfo(link)
@@ -456,8 +456,8 @@ local function QA_EnsureTooltipHook()
if hasHookScript and onTooltipSetUnitExists then
pcall(function()
GameTooltip:HookScript("OnTooltipSetUnit", function(self)
QA_AppendDrazialTooltip(self, "hook:setunit")
GameTooltip:HookScript("OnTooltipSetUnit", function()
QA_AppendDrazialTooltip(this, "hook:setunit")
end)
end)
elseif hasSetScript and hasGetScript and onTooltipSetUnitExists then
@@ -466,11 +466,11 @@ local function QA_EnsureTooltipHook()
end)
if okGetPrev then
pcall(function()
GameTooltip:SetScript("OnTooltipSetUnit", function(self)
GameTooltip:SetScript("OnTooltipSetUnit", function()
if type(previous) == "function" then
previous(self)
previous()
end
QA_AppendDrazialTooltip(self, "script:setunit")
QA_AppendDrazialTooltip(this, "script:setunit")
end)
end)
end
@@ -478,8 +478,8 @@ local function QA_EnsureTooltipHook()
if hasHookScript and onShowExists then
pcall(function()
GameTooltip:HookScript("OnShow", function(self)
QA_AppendDrazialTooltip(self, "hook:show")
GameTooltip:HookScript("OnShow", function()
QA_AppendDrazialTooltip(this, "hook:show")
end)
end)
elseif hasSetScript and hasGetScript and onShowExists then
@@ -488,11 +488,11 @@ local function QA_EnsureTooltipHook()
end)
if okGetPrevShow then
pcall(function()
GameTooltip:SetScript("OnShow", function(self)
GameTooltip:SetScript("OnShow", function()
if type(previousShow) == "function" then
previousShow(self)
previousShow()
end
QA_AppendDrazialTooltip(self, "script:show")
QA_AppendDrazialTooltip(this, "script:show")
end)
end)
end
@@ -505,17 +505,17 @@ local function QA_EnsureTooltipPoller()
if QA_TooltipPollFrame then
return
end
local frame = CreateFrame("Frame", "MTH_AutoQuestTooltipPollFrame")
local frame = CreateFrame("Frame", "MTH_AQTooltipPoll")
if not frame then
return
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.20 then
frame:SetScript("OnUpdate", function()
this._mthElapsed = (this._mthElapsed or 0) + (arg1 or 0)
if this._mthElapsed < 0.20 then
return
end
self._mthElapsed = 0
this._mthElapsed = 0
if not (MTH_AutoQuest and MTH_AutoQuest.enabled) then
return
end
@@ -591,16 +591,16 @@ end
local function QA_RequestTooltipRefresh(delaySeconds)
delaySeconds = tonumber(delaySeconds) or 0.10
if not QA_TooltipRefreshFrame then
QA_TooltipRefreshFrame = CreateFrame("Frame", "MTH_AutoQuestTooltipRefreshFrame")
QA_TooltipRefreshFrame = CreateFrame("Frame", "MTH_AQTooltipRefresh")
if not QA_TooltipRefreshFrame then
return
end
QA_TooltipRefreshFrame:SetScript("OnUpdate", function(self, elapsed)
local frameRef = self or this or QA_TooltipRefreshFrame
QA_TooltipRefreshFrame:SetScript("OnUpdate", function()
local frameRef = this or QA_TooltipRefreshFrame
if not frameRef then
return
end
frameRef._elapsed = (frameRef._elapsed or 0) + (elapsed or arg1 or 0)
frameRef._elapsed = (frameRef._elapsed or 0) + (arg1 or 0)
if frameRef._elapsed < (frameRef._delay or 0.10) then
return
end
@@ -915,48 +915,14 @@ local function QA_RunProfileAutomation(eventName, profile)
end
end
local function QA_SetDirectEventFrameActive(active)
if not QA_DirectEventFrame then
return
end
if active then
QA_DirectEventFrame:RegisterEvent("GOSSIP_SHOW")
QA_DirectEventFrame:RegisterEvent("QUEST_GREETING")
QA_DirectEventFrame:RegisterEvent("QUEST_DETAIL")
QA_DirectEventFrame:RegisterEvent("QUEST_PROGRESS")
QA_DirectEventFrame:RegisterEvent("QUEST_COMPLETE")
else
QA_DirectEventFrame:UnregisterAllEvents()
end
end
local function QA_EnsureDirectEventFrame(moduleRef)
if QA_DirectEventFrame then
return QA_DirectEventFrame
end
local frame = CreateFrame("Frame", "MTH_AutoQuestEventFrame")
if not frame then
QA_Debug("direct frame create failed")
return nil
end
frame:SetScript("OnEvent", function(_, eventName)
eventName = eventName or event
if not (moduleRef and moduleRef.enabled) then
return
end
QA_Debug("directEvent=" .. tostring(eventName))
QA_RunProfileAutomation(eventName, QA_PROFILE_SCORPOK)
QA_RunProfileAutomation(eventName, QA_PROFILE_SISSIES)
end)
QA_DirectEventFrame = frame
return frame
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_EnsureDirectEventFrame(self)
QA_SetDirectEventFrameActive(self.enabled and true or false)
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)
@@ -965,7 +931,6 @@ end
function MTH_AutoQuest:setEnabled(enabled)
self.enabled = enabled and true or false
QA_SetDirectEventFrameActive(self.enabled and true or false)
end
function MTH_AutoQuest:onEvent(eventName)
@@ -981,7 +946,7 @@ function MTH_AutoQuest:onEvent(eventName)
end
function MTH_AutoQuest:cleanup()
QA_SetDirectEventFrameActive(false)
-- no-op: direct event frame removed in Phase 2
end
MTH:RegisterModule("autoquest", MTH_AutoQuest)
+29 -25
View File
@@ -485,16 +485,22 @@ local function getActionSpell(slot)
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
@@ -1191,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
@@ -1219,25 +1225,23 @@ function Chronometer:CreateAnchor(text, r, g, b)
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
MTH_CHRON_Trace("anchor drag-start point=" .. MTH_CHRON_DescribePoint(self))
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
@@ -1246,16 +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.point = point or "TOPLEFT"
self.owner.profile.barposition.relativePoint = point or "TOPLEFT"
self.owner.profile.barposition.x = x
self.owner.profile.barposition.y = y
MTH_CHRON_Trace("anchor drag-stop saved profile=" .. MTH_CHRON_FormatBarPosition(self.owner.profile)
.. " frame=" .. MTH_CHRON_DescribePoint(self))
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)
@@ -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 -1
View File
@@ -1,7 +1,7 @@
local MTH_ChronometerModule = {
name = "chronometer",
enabled = true,
version = "1.1.0",
version = "1.3.0",
events = {},
initialized = false,
}
+81 -23
View File
@@ -57,7 +57,7 @@ FOM_RealmPlayer = nil;
FOM_LastPetName = nil;
FOM_LastFeedAttempt = nil;
FOM_TRACE_ENABLED = false;
local FOM_CORE_ATTEMPT_TRACKING_ENABLED = false;
local FOM_CORE_ATTEMPT_TRACKING_ENABLED = true;
local FOM_PERF_TRACE_ENABLED = false;
local FOM_PERF_TRACE_HISTORY_LIMIT = 80;
local FOM_PERF_TRACE_SPIKE_MS = 12;
@@ -126,7 +126,10 @@ FOM_FamilyToLegacyMap = {
};
local function FOM_Trace(message)
return;
if not FOM_TRACE_ENABLED then return; end
if type(DEFAULT_CHAT_FRAME) == "table" and DEFAULT_CHAT_FRAME.AddMessage then
DEFAULT_CHAT_FRAME:AddMessage("|cffffff00[FOM-Trace]|r " .. tostring(message));
end
end
local function FOM_PerfNowMs()
@@ -780,7 +783,7 @@ local function FOM_DebugLogMerchantFoods(sourceEvent)
end
end
function FOM_FeedButton_OnClick()
function MTH_FOM_FeedButton_OnClick()
if (arg1 == "RightButton") then
if (MTH_OpenOptions) then
MTH_OpenOptions("FeedOMatic");
@@ -790,7 +793,7 @@ function FOM_FeedButton_OnClick()
end
end
function FOM_FeedButton_OnEnter()
function MTH_FOM_FeedButton_OnEnter()
if ( PetFrameHappiness.tooltip ) then
GameTooltip:SetOwner(PetFrameHappiness, "ANCHOR_RIGHT");
GameTooltip:SetText(PetFrameHappiness.tooltip);
@@ -807,7 +810,7 @@ function FOM_FeedButton_OnEnter()
end
end
function FOM_FeedButton_OnLeave()
function MTH_FOM_FeedButton_OnLeave()
GameTooltip:Hide();
end
@@ -985,13 +988,13 @@ function FOM_OnEvent(event, arg1)
this:RegisterEvent("PLAYER_REGEN_ENABLED");
end
if (FOM_FeedButton == nil) then
FOM_FeedButton = CreateFrame("Button", "FOM_FeedButton", PetFrameHappiness);
FOM_FeedButton:SetAllPoints(PetFrameHappiness);
FOM_FeedButton:RegisterForClicks("LeftButtonUp", "RightButtonUp");
FOM_FeedButton:SetScript("OnClick", FOM_FeedButton_OnClick);
FOM_FeedButton:SetScript("OnEnter", FOM_FeedButton_OnEnter);
FOM_FeedButton:SetScript("OnLeave", FOM_FeedButton_OnLeave);
if (MTH_FOM_FeedButton == nil) then
MTH_FOM_FeedButton = CreateFrame("Button", "MTH_FOM_FeedButton", PetFrameHappiness);
MTH_FOM_FeedButton:SetAllPoints(PetFrameHappiness);
MTH_FOM_FeedButton:RegisterForClicks("LeftButtonUp", "RightButtonUp");
MTH_FOM_FeedButton:SetScript("OnClick", MTH_FOM_FeedButton_OnClick);
MTH_FOM_FeedButton:SetScript("OnEnter", MTH_FOM_FeedButton_OnEnter);
MTH_FOM_FeedButton:SetScript("OnLeave", MTH_FOM_FeedButton_OnLeave);
end
if (FOM_Config.Level == "happy") then
@@ -1236,16 +1239,27 @@ function FOM_DifficultyToNum(level)
end
end
local FOM_CachedPlayerClass = nil
local FOM_OnUpdateElapsed = 0
function FOM_OnUpdate(elapsed)
_, realClass = UnitClass("player");
if (realClass ~= "HUNTER") then return; end
FOM_OnUpdateElapsed = FOM_OnUpdateElapsed + (elapsed or 0)
if FOM_OnUpdateElapsed < 0.05 then
return
end
local dt = FOM_OnUpdateElapsed
FOM_OnUpdateElapsed = 0
if not FOM_CachedPlayerClass then
_, FOM_CachedPlayerClass = UnitClass("player")
end
if (FOM_CachedPlayerClass ~= "HUNTER") then return; end
-- If it's been more than a second since our last tradeskill update,
-- we can allow the event to process again.
FOM_TradeSkillLock.EventTimer = FOM_TradeSkillLock.EventTimer + elapsed;
FOM_TradeSkillLock.EventTimer = FOM_TradeSkillLock.EventTimer + dt;
if (FOM_TradeSkillLock.Locked) then
FOM_TradeSkillLock.EventCooldown = FOM_TradeSkillLock.EventCooldown + elapsed;
FOM_TradeSkillLock.EventCooldown = FOM_TradeSkillLock.EventCooldown + dt;
if (FOM_TradeSkillLock.EventCooldown > FOM_TradeSkillLock.EventCooldownTime) then
FOM_TradeSkillLock.EventCooldown = 0;
@@ -1290,6 +1304,7 @@ function FOM_OnUpdate(elapsed)
.. " pet='" .. tostring(FOM_LastFeedAttempt.petName or "")
.. "' elapsed=" .. string.format("%.2f", elapsedSinceFeed));
FOM_LastFeedAttempt = nil;
FOM_LastFood = nil;
elseif (elapsedSinceFeed >= 2.50) then
local failedAttempt = FOM_LastFeedAttempt;
if (FOM_LastFeedAttempt.coreAttemptId and type(MTH_FEED_RecordBuffOutcome) == "function") then
@@ -1415,8 +1430,8 @@ function FOM_CanFeed()
if ( UnitLevel("player") >= 40 ) then
for _, buffTexture in mountTextureSubStrings do
if ( string.find(buff, buffTexture) ) then
FOMTooltip:SetUnitBuff("player", buffIndex+1);
local msg = FOMTooltipTextLeft1:GetText();
MTH_FOM_Tooltip:SetUnitBuff("player", buffIndex+1);
local msg = MTH_FOM_TooltipTextLeft1:GetText();
if (msg ~= nil) then
msg = string.lower(msg);
for _, mountName in FOM_MOUNT_NAME_SUBSTRINGS do
@@ -1941,6 +1956,7 @@ function FOM_ChatCommandHandler(msg)
if ( cmd == "add" ) then
for _, food in inputFoods do
local foodID = FOM_IDFromLink(food);
FOM_ClearItemBans(foodID);
if ( FOM_AddFood(diet, tonumber(foodID)) ) then
GFWUtils.Print("Added "..food.." to "..GFWUtils.Hilite(capDiet).." list.");
else
@@ -2000,6 +2016,12 @@ function FOM_AddFood(diet, food)
return false;
end
else
-- Item is in the base list; clear it from RemovedFoods if present so it isn't banned
if (FOM_RemovedFoods and FOM_RemovedFoods[diet] and GFWTable.IndexOf(FOM_RemovedFoods[diet], food) ~= 0) then
table.remove( FOM_RemovedFoods[diet], GFWTable.IndexOf(FOM_RemovedFoods[diet], food) );
table.sort( FOM_RemovedFoods[diet] );
return true;
end
return false;
end
@@ -2007,7 +2029,7 @@ end
-- Remove a food from a list
function FOM_RemoveFood(diet, food)
if (FOM_Foods[diet] == nil) then
GFWUtils.DebugLog("FOM_Foods[diet] == nil");
end
@@ -2046,6 +2068,42 @@ function FOM_RemoveFood(diet, food)
end
-- Clear quarantine, core exception blocks, and RemovedFoods ban for a specific item (called when user explicitly re-adds via /fom add)
local function FOM_ClearItemBans(itemID)
local numericItem = tonumber(itemID);
if (numericItem == nil) then return; end
-- Clear from RemovedFoods across all diet lists
if (type(FOM_RemovedFoods) == "table") then
for diet, list in FOM_RemovedFoods do
if (type(list) == "table") then
local idx = GFWTable.IndexOf(list, numericItem);
if (idx ~= 0) then
table.remove(list, idx);
end
end
end
end
-- Clear FOM quarantine (all families)
local store = FOM_EnsureQuarantineStore();
if (type(store) == "table" and type(store.byFamily) == "table") then
for _, byItem in store.byFamily do
if (type(byItem) == "table") then
byItem[numericItem] = nil;
end
end
end
-- Clear core exception/block
if (type(MTH_FEED_GetStore) == "function") then
local coreStore = MTH_FEED_GetStore();
if (coreStore and coreStore.exceptions and type(coreStore.exceptions.byItemId) == "table") then
coreStore.exceptions.byItemId[numericItem] = nil;
coreStore.exceptions.byItemId[tostring(numericItem)] = nil;
end
end
-- Invalidate precompute cache so next feed re-scans
FOM_FEED_SCAN_CACHE = nil;
end
function FOM_IsBGActive()
local bgNum = 1;
local status;
@@ -2567,9 +2625,9 @@ function FOM_IsTemporaryFood(itemLink)
end
return false;
end
FOMTooltip:ClearLines();
FOMTooltip:SetHyperlink(link);
if (FOMTooltipTextLeft2:GetText() == ITEM_CONJURED) then
MTH_FOM_Tooltip:ClearLines();
MTH_FOM_Tooltip:SetHyperlink(link);
if (MTH_FOM_TooltipTextLeft2:GetText() == ITEM_CONJURED) then
if (numericItemId ~= nil) then
FOM_TEMP_FOOD_CACHE[numericItemId] = true;
end
+1 -127
View File
@@ -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
+17 -17
View File
@@ -6,7 +6,7 @@
local MTH_FeedOMatic = {
name = "feedomatic",
enabled = false,
version = "1.1.0",
version = "1.3.0",
events = {
"VARIABLES_LOADED",
"MERCHANT_SHOW",
@@ -32,7 +32,7 @@ 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
@@ -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()
@@ -216,16 +216,16 @@ end
local function MTH_FeedOMatic_SetMerchantProbeEnabled(enabled)
if not enabled then
if MTH_FeedOMatic_MerchantProbeFrame then
MTH_FeedOMatic_MerchantProbeFrame:UnregisterEvent("MERCHANT_SHOW")
MTH_FeedOMatic_MerchantProbeFrame:UnregisterEvent("MERCHANT_UPDATE")
if MTH_FOM_MerchantProbe then
MTH_FOM_MerchantProbe:UnregisterEvent("MERCHANT_SHOW")
MTH_FOM_MerchantProbe:UnregisterEvent("MERCHANT_UPDATE")
end
return
end
if not MTH_FeedOMatic_MerchantProbeFrame then
MTH_FeedOMatic_MerchantProbeFrame = CreateFrame("Frame", "MTH_FeedOMatic_MerchantProbeFrame")
MTH_FeedOMatic_MerchantProbeFrame:SetScript("OnEvent", function()
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")
@@ -234,8 +234,8 @@ local function MTH_FeedOMatic_SetMerchantProbeEnabled(enabled)
end)
end
MTH_FeedOMatic_MerchantProbeFrame:RegisterEvent("MERCHANT_SHOW")
MTH_FeedOMatic_MerchantProbeFrame:RegisterEvent("MERCHANT_UPDATE")
MTH_FOM_MerchantProbe:RegisterEvent("MERCHANT_SHOW")
MTH_FOM_MerchantProbe:RegisterEvent("MERCHANT_UPDATE")
MTH_FeedOMatic_Log("merchant probe enabled", "debug")
end
@@ -277,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
@@ -287,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
@@ -316,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
+2 -2
View File
@@ -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");
+1127 -1127
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -6,7 +6,7 @@
local MTH_ICU = {
name = "icu",
enabled = false,
version = "1.1.0",
version = "1.3.0",
events = {
"VARIABLES_LOADED",
},
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,10 +7,10 @@ MTH_SA_MANAGED_HOOKS = true
local MTH_SmartAmmo = {
name = "smartammo",
enabled = true,
version = "1.1.0",
version = "1.3.0",
events = {
"VARIABLES_LOADED",
"PLAYER_ENTERING_WORLD",
-- PLAYER_ENTERING_WORLD handled by engine's own frame
},
}
+13 -16
View File
@@ -6,7 +6,7 @@
local MTH_Tooltips = {
name = "tooltips",
enabled = true,
version = "1.1.0",
version = "1.3.0",
events = {
"UPDATE_MOUSEOVER_UNIT",
"UNIT_NAME_UPDATE",
@@ -1545,19 +1545,18 @@ 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.onUpdate = function(self)
self = self or this
if not self then
frame.onUpdate = function()
if not this then
return
end
if not self.pending then
self:SetScript("OnUpdate", nil)
if not this.pending then
this:SetScript("OnUpdate", nil)
return
end
self.pending = false
self:SetScript("OnUpdate", nil)
this.pending = false
this:SetScript("OnUpdate", nil)
if MTH_Tooltips and MTH_Tooltips.enabled then
MTH_TT_AddTooltip("mouseover")
end
@@ -1581,14 +1580,13 @@ 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
elapsed = elapsed or arg1
MTH_Tooltips.hintElapsed = (MTH_Tooltips.hintElapsed or 0) + (elapsed or 0)
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
@@ -1648,13 +1646,12 @@ local function MTH_TT_SetRuntimeActive(active)
local pollFrame = MTH_Tooltips.pollFrame
if pollFrame then
if active then
pollFrame:SetScript("OnUpdate", pollFrame:GetScript("OnUpdate") or function(_, elapsed)
pollFrame:SetScript("OnUpdate", pollFrame:GetScript("OnUpdate") or function()
if not (MTH_Tooltips and MTH_Tooltips.enabled) then
return
end
elapsed = elapsed or arg1
MTH_Tooltips.hintElapsed = (MTH_Tooltips.hintElapsed or 0) + (elapsed or 0)
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
+217 -217
View File
@@ -1,217 +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", "ZHunterModScan", nil, "GameTooltipTemplate")
ZHunterModTooltipTextLeft1 = getglobal("ZHunterModScanTextLeft1")
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
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
+36 -20
View File
@@ -8,10 +8,10 @@ MTH_ZH_MANAGED_HOOKS = true
local MTH_ZHunter = {
name = "zhunter",
enabled = true,
version = "1.1.0",
version = "1.3.0",
events = {
"VARIABLES_LOADED",
"PLAYER_ENTERING_WORLD",
-- PLAYER_ENTERING_WORLD handled by bootstrap frame + adjustment frames
"MTH_PET_LIVE_STATE_CHANGED",
},
features = {
@@ -37,7 +37,7 @@ local function MTH_ZH_TraceLocal(msg)
end
end
local MTH_ZH_PostLoginRestoreFrame = nil
local MTH_ZH_PostLoginRestore = nil
local MTH_ZH_BootstrapFrame = nil
local MTH_ZH_SyncSavedVariables
local MTH_ZH_SetButtonsVisible
@@ -116,15 +116,15 @@ function MTH_ZH_OnDeferredInitComplete()
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
@@ -149,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
@@ -297,10 +297,26 @@ MTH_ZH_SetButtonsVisible = function(visible)
if type(MTH_ZH_TraceButtonPoint) == "function" then
MTH_ZH_TraceButtonPoint(button, "set-buttons-visible:before:" .. tostring(buttonName))
end
MTH_ZH_SetChildButtonsVisible(button, buttonName, visible)
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
@@ -316,15 +332,15 @@ end
local function MTH_ZH_SetAdjustmentHandlersActive(active)
local frameSpecs = {
{ frame = "zButtonAspectAdjustment", handler = "zButtonAspectAdjustment_OnEvent", getter = "zButtonAspect_GetSaved" },
{ frame = "zButtonTrackAdjustment", handler = "zButtonTrackAdjustment_OnEvent", getter = "zButtonTrack_GetSaved" },
{ frame = "zButtonTrapAdjustment", handler = "zButtonTrapAdjustment_OnEvent", getter = "zButtonTrap_GetSaved" },
{ frame = "zButtonRangedAdjustment", handler = "zButtonRangedAdjustment_OnEvent", getter = "zButtonRanged_GetSaved" },
{ frame = "zButtonAmmoAdjustment", handler = "zButtonAmmoAdjustment_OnEvent", getter = "zButtonAmmo_GetSaved" },
{ frame = "zButtonPetAdjustment", handler = "zButtonPetAdjustment_OnEvent", getter = "zButtonPet_GetSaved" },
{ frame = "zButtonMountsAdjustment", handler = "zButtonMountsAdjustment_OnEvent", getter = "zButtonMounts_GetSaved" },
{ frame = "zButtonCompanionsAdjustment", handler = "zButtonCompanionsAdjustment_OnEvent", getter = "zButtonCompanions_GetSaved" },
{ frame = "zButtonToysAdjustment", handler = "zButtonToysAdjustment_OnEvent", getter = "zButtonToys_GetSaved" },
{ 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)
File diff suppressed because it is too large Load Diff
+392 -390
View File
@@ -1,391 +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 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
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_AuraProbeScan", 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 zButtonAspectAdjustment and zButtonAspectAdjustment.SetScript then
zButtonAspectAdjustment:SetScript("OnEvent", nil)
end
if zButtonAspect and zButtonAspect.Hide then
zButtonAspect:Hide()
end
return
end
if zButtonAspectAdjustment and zButtonAspectAdjustment.SetScript then
zButtonAspectAdjustment:SetScript("OnEvent", zButtonAspectAdjustment_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 zButtonAspectAdjustment_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
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
+11 -9
View File
@@ -93,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)
@@ -225,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
@@ -247,16 +249,16 @@ end
function zButtonCompanions_SetupSizeAndPosition()
local saved = zButtonCompanions_GetSaved()
if saved["enabled"] == false or saved["enabled"] == 0 then
if zButtonCompanionsAdjustment and zButtonCompanionsAdjustment.SetScript then
zButtonCompanionsAdjustment:SetScript("OnEvent", nil)
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 zButtonCompanionsAdjustment and zButtonCompanionsAdjustment.SetScript then
zButtonCompanionsAdjustment:SetScript("OnEvent", zButtonCompanionsAdjustment_OnEvent)
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
@@ -291,7 +293,7 @@ function zButtonCompanions_Reset()
zButtonCompanions_EnsureConfig()
end
function zButtonCompanionsAdjustment_OnEvent()
function MTH_ZH_CompanionsAdjust_OnEvent()
if not zButtonCompanions then
return
end
+11 -9
View File
@@ -93,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)
@@ -225,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
@@ -247,16 +249,16 @@ end
function zButtonMounts_SetupSizeAndPosition()
local saved = zButtonMounts_GetSaved()
if saved["enabled"] == false or saved["enabled"] == 0 then
if zButtonMountsAdjustment and zButtonMountsAdjustment.SetScript then
zButtonMountsAdjustment:SetScript("OnEvent", nil)
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 zButtonMountsAdjustment and zButtonMountsAdjustment.SetScript then
zButtonMountsAdjustment:SetScript("OnEvent", zButtonMountsAdjustment_OnEvent)
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
@@ -291,7 +293,7 @@ function zButtonMounts_Reset()
zButtonMounts_EnsureConfig()
end
function zButtonMountsAdjustment_OnEvent()
function MTH_ZH_MountsAdjust_OnEvent()
if not zButtonMounts then
return
end
File diff suppressed because it is too large Load Diff
+12 -10
View File
@@ -232,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)
@@ -602,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
@@ -635,16 +637,16 @@ end
function zButtonRanged_SetupSizeAndPosition()
local saved = zButtonRanged_GetSaved()
if saved["enabled"] == false or saved["enabled"] == 0 then
if zButtonRangedAdjustment and zButtonRangedAdjustment.SetScript then
zButtonRangedAdjustment:SetScript("OnEvent", nil)
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 zButtonRangedAdjustment and zButtonRangedAdjustment.SetScript then
zButtonRangedAdjustment:SetScript("OnEvent", zButtonRangedAdjustment_OnEvent)
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
@@ -679,7 +681,7 @@ function zButtonRanged_Reset()
zButtonRanged_EnsureConfig()
end
function zButtonRangedAdjustment_OnEvent()
function MTH_ZH_RangedAdjust_OnEvent()
if not zButtonRanged then
return
end
+11 -9
View File
@@ -93,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)
@@ -225,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
@@ -247,16 +249,16 @@ end
function zButtonToys_SetupSizeAndPosition()
local saved = zButtonToys_GetSaved()
if saved["enabled"] == false or saved["enabled"] == 0 then
if zButtonToysAdjustment and zButtonToysAdjustment.SetScript then
zButtonToysAdjustment:SetScript("OnEvent", nil)
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 zButtonToysAdjustment and zButtonToysAdjustment.SetScript then
zButtonToysAdjustment:SetScript("OnEvent", zButtonToysAdjustment_OnEvent)
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
@@ -291,7 +293,7 @@ function zButtonToys_Reset()
zButtonToys_EnsureConfig()
end
function zButtonToysAdjustment_OnEvent()
function MTH_ZH_ToysAdjust_OnEvent()
if not zButtonToys then
return
end
+411 -409
View File
@@ -1,410 +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 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
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
zButtonTrackAdjustment = CreateFrame("Frame", "zButtonTrackAdjustment")
zButtonTrackAdjustment:RegisterEvent("MINIMAP_UPDATE_TRACKING")
zButtonTrackAdjustment:RegisterEvent("PLAYER_ENTERING_WORLD")
zButtonTrackAdjustment:RegisterEvent("SPELLS_CHANGED")
zButtonTrackAdjustment:RegisterEvent("CHARACTER_POINTS_CHANGED")
zButtonTrackAdjustment:RegisterEvent("LEARNED_SPELL_IN_TAB")
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 zButtonTrackAdjustment and zButtonTrackAdjustment.SetScript then
zButtonTrackAdjustment:SetScript("OnEvent", nil)
end
if zButtonTrack and zButtonTrack.Hide then
zButtonTrack:Hide()
end
return
end
if zButtonTrackAdjustment and zButtonTrackAdjustment.SetScript then
zButtonTrackAdjustment:SetScript("OnEvent", zButtonTrackAdjustment_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 zButtonTrackAdjustment_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
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 -278
View File
@@ -1,279 +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 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
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 zButtonTrapAdjustment and zButtonTrapAdjustment.SetScript then
zButtonTrapAdjustment:SetScript("OnEvent", nil)
end
if zButtonTrap and zButtonTrap.Hide then
zButtonTrap:Hide()
end
return
end
if zButtonTrapAdjustment and zButtonTrapAdjustment.SetScript then
zButtonTrapAdjustment:SetScript("OnEvent", zButtonTrapAdjustment_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 zButtonTrapAdjustment_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
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