This commit is contained in:
DuvelCorp
2026-02-27 18:57:24 +01:00
parent ee8328e903
commit 2c94650993
85 changed files with 30197 additions and 820 deletions
+6 -2
View File
@@ -1,5 +1,5 @@
MTH_CONST = MTH_CONST or {}
MTH_CONST.version = MTH_CONST.version or "1.0.3"
MTH_CONST.version = MTH_CONST.version or "1.0.4"
MTH_CONST.WEAPON_TYPES = {
BOWS = "Bows",
@@ -18,7 +18,7 @@ MTH_CONST.AMMO = {
SOLID = "Solid Shot",
CRAFTSOLID = "Crafted Solid Shot",
EXPLODING = "Exploding Shot",
MITHRILSLUG = "Hi-impact Mithril Slugs",
MITHRILSLUG = "Hi-Impact Mithril Slugs",
ACCURATE = "Accurate Slugs",
GYROSHOT = "Mithril Gyro-Shot",
ICETHREADED = "Ice Threaded Bullet",
@@ -86,6 +86,8 @@ JUNKSHOT_VIPER = MTH_CONST.AMMO.JUNKSHOTS.VIPER
JUNKSHOT_ARCANE = MTH_CONST.AMMO.JUNKSHOTS.ARCANE
JUNKSHOT_CONCUSSIVE = MTH_CONST.AMMO.JUNKSHOTS.CONCUSSIVE
JUNKSHOT_DISTRACTING = MTH_CONST.AMMO.JUNKSHOTS.DISTRACTING
JUNKSHOT_BAITED = MTH_CONST.AMMO.JUNKSHOTS.BAITED
JUNKSHOT_TRANQ = MTH_CONST.AMMO.JUNKSHOTS.TRANQ
MTH_AMMO_BULLETS = {
BULLETS_LIGHT,
@@ -125,6 +127,8 @@ MTH_AMMO_JUNKSHOTS = {
JUNKSHOT_ARCANE,
JUNKSHOT_CONCUSSIVE,
JUNKSHOT_DISTRACTING,
JUNKSHOT_BAITED,
JUNKSHOT_TRANQ,
}
MTH_AMMO_BULLET_RANK = {}
+88 -6
View File
@@ -1,5 +1,5 @@
MTH = MTH or {
version = "1.0.3",
version = "1.0.4",
name = "MetaHunt",
modules = {},
config = {},
@@ -8,6 +8,15 @@ MTH = MTH or {
local MTH_CHAT_PREFIX = "|cFFFFFFFF[|r|cFFD14A4AMeta|r|cFFABD473Hunt|r|cFFFFFFFF]|r "
local MTH_NON_HUNTER_BLOCK_MESSAGE = "You are not a hunter and you are not allowed here. Disable the add-on for this character."
local MTH_MESSAGE_DEFAULTS = {
initModulesLoaded = false,
initSarcasticWelcome = true,
petHungry = false,
beastTrainingScan = true,
spellbookScan = false,
petRanAway = true,
mapMarkers = true,
}
local function MTH_ClassGateTrace(_step, _detail)
return
@@ -1003,6 +1012,50 @@ function MTH:Print(msg, severity)
return self:Log(msg, severity)
end
function MTH:GetMessageSettings()
if not MTH_SavedVariables then
self:InitSavedVariables()
end
if type(MTH_SavedVariables.messages) ~= "table" then
MTH_SavedVariables.messages = {}
end
local settings = MTH_SavedVariables.messages
for key, defaultValue in pairs(MTH_MESSAGE_DEFAULTS) do
if settings[key] == nil then
settings[key] = defaultValue and true or false
else
settings[key] = settings[key] and true or false
end
end
return settings
end
function MTH:IsMessageEnabled(key, defaultEnabled)
local settings = self:GetMessageSettings()
local value = settings and settings[key]
if value == nil then
if defaultEnabled ~= nil then
value = defaultEnabled and true or false
else
value = true
end
settings[key] = value
end
return value and true or false
end
function MTH:SetMessageEnabled(key, enabled)
if type(key) ~= "string" or key == "" then
return false
end
local settings = self:GetMessageSettings()
if not settings then
return false
end
settings[key] = enabled and true or false
return true
end
function MTH:DebugPrint(msg)
if self.debug then
self:Print("[DEBUG] " .. tostring(msg), "debug")
@@ -1080,6 +1133,16 @@ function MTH:InitSavedVariables()
if not MTH_SavedVariables.modules.zhunter then
MTH_SavedVariables.modules.zhunter = MTH_SavedVariables.zhunter or {}
end
if type(MTH_SavedVariables.messages) ~= "table" then
MTH_SavedVariables.messages = {}
end
for key, defaultValue in pairs(MTH_MESSAGE_DEFAULTS) do
if MTH_SavedVariables.messages[key] == nil then
MTH_SavedVariables.messages[key] = defaultValue and true or false
else
MTH_SavedVariables.messages[key] = MTH_SavedVariables.messages[key] and true or false
end
end
MTH_SavedVariables.feedomatic = MTH_SavedVariables.modules.feedomatic
MTH_SavedVariables.zhunter = MTH_SavedVariables.modules.zhunter
@@ -1249,7 +1312,9 @@ function MTH:AnnounceLoadComplete()
end
self:Print("Check ignition: OK! Version " .. tostring(self.version or "unknown") .. " loaded.")
--self:Print("Modules enabled : " .. moduleList .. ".")
if self:IsMessageEnabled("initModulesLoaded", false) then
self:Print("Modules enabled : " .. moduleList .. ".")
end
local petTrainingStore = nil
if type(MTH_PETS_GetRootStore) == "function" then
@@ -1284,8 +1349,10 @@ function MTH:AnnounceLoadComplete()
end
end
if not hasCompletedPetScan then
local playerLevel = (type(UnitLevel) == "function") and (tonumber(UnitLevel("player")) or 0) or 0
if playerLevel >= 12 then
local rawPlayerLevel = (type(UnitLevel) == "function") and UnitLevel("player") or nil
local playerLevel = tonumber(rawPlayerLevel) or 0
local shouldShowBeastTrainingReminder = (playerLevel >= 12 and playerLevel <= 60)
if shouldShowBeastTrainingReminder then
self:Print("You should open your Beast Training once to save your learned pet abilities.")
self._loadCompleteAnnounced = true
return
@@ -1293,7 +1360,7 @@ function MTH:AnnounceLoadComplete()
end
local welcomeMessages = {
"You are now shipping the latest cutting edge technology.",
"You are now shipping the latest cutting-edge Nelf technology.",
"SHELLS ARE FOR PUSSIES.",
"Sometimes, you just need a little less gun.",
"Repeat 5 times : \"Un chasseur sachant chasser sans son chien\".",
@@ -1380,6 +1447,19 @@ function MTH:AnnounceLoadComplete()
"Your pet follows orders. Pathing follows dark magic.",
"Today’s objective: hit crits and dodge responsibility.",
"Go forth, badboy ranger — leave footprints, not explanations.",
"MetaHunt loaded. Your plan has been forwarded to Quality Control for comedy review.",
"Systems online. Tactical brilliance still listed as a future expansion feature.",
"Hunter detected. Restraint not detected.",
"Startup complete. Your pet is the adult in this relationship.",
"All modules green. Your target selection remains performance art.",
"Welcome back. The dungeon requested a waiver after seeing your login.",
"Interface stable. Decision-making unstable. Proceed.",
"MetaHunt armed. Your confidence has entered the area without supervision.",
"Ready to hunt. Ready to kite. Not ready to explain any of it.",
"Boot successful. Friendly fire is still technically ‘friendly.’",
"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.",
}
local welcomeIndex = 1
@@ -1391,7 +1471,9 @@ function MTH:AnnounceLoadComplete()
welcomeIndex = math.random(1, welcomeCount)
end
end
self:Print(welcomeMessages[welcomeIndex])
if self:IsMessageEnabled("initSarcasticWelcome", true) then
self:Print(welcomeMessages[welcomeIndex])
end
self._loadCompleteAnnounced = true
end
+35 -16
View File
@@ -167,9 +167,14 @@ function MTH_PT_HasBeastTrainingRows()
end
local function MTH_PT_DebugLog(line)
if not MTH_PT_VERBOSE_SCAN_LOGS then return end
local text = "[TRAINSCAN] " .. tostring(line or "")
MTH:Print(text, "debug")
return
end
local function MTH_PT_IsScanMessageEnabled()
if not (MTH and MTH.IsMessageEnabled) then
return true
end
return MTH:IsMessageEnabled("beastTrainingScan", true)
end
local function MTH_PT_MakeTokenFromAbilityRank(abilityName, rankNumber)
@@ -382,10 +387,12 @@ local function MTH_PT_ProcessLearnSystemMessage(rawMessage)
label = label .. " (Rank " .. tostring(rankNumber) .. ")"
end
if MTH and MTH.Print then
if changed then
MTH:Print("Pet ability learned and recorded: " .. label .. ". It is now marked as known in MetaHunt.")
else
MTH:Print("Pet ability learned for current pet: " .. label .. ".")
if MTH:IsMessageEnabled("beastTrainingScan", true) then
if changed then
MTH:Print("Pet ability learned and recorded: " .. label .. ". It is now marked as known in MetaHunt.")
else
MTH:Print("Pet ability learned for current pet: " .. label .. ".")
end
end
end
if changed then
@@ -605,18 +612,24 @@ function MTH_PT_ApplyScan(triggerReason)
for _ in pairs(baseSet) do totalBaselines = totalBaselines + 1 end
if triggerReason == "initial" then
MTH:Print("Initial train scan complete: " .. tostring(totalBaselines) .. " baselines / " .. tostring(totalRanks) .. " ranks recorded for this character.")
if MTH_PT_IsScanMessageEnabled() then
MTH:Print("Initial train scan complete: " .. tostring(totalBaselines) .. " baselines / " .. tostring(totalRanks) .. " ranks recorded for this character.")
end
elseif added > 0 then
table.sort(addedDetails)
local detailsText = table.concat(addedDetails, ", ")
if detailsText ~= "" then
local msg = "New pet data recorded (" .. tostring(added) .. " new rank(s)): " .. detailsText .. ". Known totals for this character: " .. tostring(totalBaselines) .. " ability type(s), " .. tostring(totalRanks) .. " rank(s)."
MTH:Print(msg)
MTH:Print("INFO: " .. msg, "debug")
if MTH_PT_IsScanMessageEnabled() then
MTH:Print(msg)
MTH:Print("INFO: " .. msg, "debug")
end
else
local msg = "New pet data recorded (" .. tostring(added) .. " new rank(s)). Known totals for this character: " .. tostring(totalBaselines) .. " ability type(s), " .. tostring(totalRanks) .. " rank(s)."
MTH:Print(msg)
MTH:Print("INFO: " .. msg, "debug")
if MTH_PT_IsScanMessageEnabled() then
MTH:Print(msg)
MTH:Print("INFO: " .. msg, "debug")
end
end
end
@@ -657,7 +670,7 @@ local function MTH_PT_RunDoubleScan(triggerBase)
if MTH_PT_DebugLog then
MTH_PT_DebugLog("scan skipped: no beast-training rows, trigger=" .. tostring(triggerBase or ""))
end
if feedbackOnOpen and MTH and MTH.Print then
if feedbackOnOpen and MTH and MTH.Print and MTH_PT_IsScanMessageEnabled() then
MTH:Print("Beast Training opened, but scan did not run yet (no scannable rows detected).")
end
return false
@@ -670,7 +683,7 @@ local function MTH_PT_RunDoubleScan(triggerBase)
if MTH_PT_DebugLog then
MTH_PT_DebugLog("scan complete: trigger=" .. tostring(triggerBase or "") .. " ok=" .. tostring(ok and true or false) .. " dt=" .. tostring((t1 or 0) - (t0 or 0)) .. "s")
end
if feedbackOnOpen and MTH and MTH.Print then
if feedbackOnOpen and MTH and MTH.Print and MTH_PT_IsScanMessageEnabled() then
if ok then
local addedCount = tonumber(added) or 0
local msg = "Beast Training scan complete: " .. tostring(baselines or 0) .. " baselines / " .. tostring(ranks or 0) .. " ranks."
@@ -711,16 +724,22 @@ local function MTH_PT_OnEvent(_, evt, eventArg1)
end
if evt == "PLAYER_ENTERING_WORLD" then
local playerLevel = 0
if type(UnitLevel) == "function" then
playerLevel = tonumber(UnitLevel("player")) or 0
end
if UnitClass then
local _, classToken = UnitClass("player")
if classToken ~= "HUNTER" then return end
end
if not MTH_PT_HasAnyLearnedSpells() then
if playerLevel >= 12 and not MTH_PT_HasAnyLearnedSpells() then
local store = MTH_PT_GetStore()
local now = time()
if not store.lastPrompt or (now - store.lastPrompt) > 60 then
store.lastPrompt = now
MTH:Print("No Beast Training scan found for this character. Open Beast Training (right panel) to record pet spell ranks.")
if MTH_PT_IsScanMessageEnabled() then
MTH:Print("No Beast Training scan found for this character. Open Beast Training (right panel) to record pet spell ranks.")
end
end
end
return
+6 -2
View File
@@ -284,11 +284,15 @@ function MTH_CommandPetSpellScan()
local ok, count, changed = MTH_PS_ScanNow("manual")
if not ok then
MTH:Print("Pet spellbook scan failed.")
if not (MTH and MTH.IsMessageEnabled) or MTH:IsMessageEnabled("spellbookScan", false) then
MTH:Print("Pet spellbook scan failed.")
end
MTH_PS_VERBOSE_LOGS = false
return
end
MTH:Print("Pet spellbook scan: " .. tostring(count or 0) .. " spell(s). changed=" .. tostring(changed and true or false))
if not (MTH and MTH.IsMessageEnabled) or MTH:IsMessageEnabled("spellbookScan", false) then
MTH:Print("Pet spellbook scan: " .. tostring(count or 0) .. " spell(s). changed=" .. tostring(changed and true or false))
end
local store = MTH_PS_GetStore()
MTH_PS_DebugPrint("Store status: lastScan=" .. tostring(store.lastScan or 0) .. " lastCount=" .. tostring(store.lastCount or 0) .. " lastTrigger=" .. tostring(store.lastTrigger or "") .. " lastChangeAt=" .. tostring(store.lastChangeAt or 0), true)
MTH_PS_VERBOSE_LOGS = false
+4 -2
View File
@@ -1267,7 +1267,7 @@ local function MTH_PETS_ApplySnapshotToRow(row, snapshot, source, context)
or tonumber(row.tamedAt) ~= nil
or tonumber(row.tameBeastId) ~= nil
or (type(row.tameZone) == "string" and row.tameZone ~= "")
if not hasTameRecord then
if not hasTameRecord and hasPendingTame then
local sourceText = tostring(source or "")
if sourceText == "unit-pet-acquire" or sourceText == "refresh-current-pet" then
row.tameRecorded = true
@@ -1758,7 +1758,9 @@ function MTH_PETS_RecordPetRunaway(source, rawMessage)
if MTH and MTH.Print then
local displayName = MTH_PETS_NormalizeText(petName)
if displayName == "" then displayName = "Unknown" end
MTH:Print("YOUR PET " .. tostring(displayName) .. " HAS RUNAWAY FOREVER :-( Try to feed it better next time.")
if MTH:IsMessageEnabled("petRanAway", true) then
MTH:Print("YOUR PET " .. tostring(displayName) .. " HAS RUNAWAY FOREVER :-( Try to feed it better next time.")
end
end
return true
+9 -1
View File
@@ -224,7 +224,9 @@ end
if type(MTH_CommandPetSpellScan) ~= "function" then
function MTH_CommandPetSpellScan()
local ok, count = MTH_PS_ScanNow("manual-core-fallback")
MTH:Print("Pet spellbook scan: " .. tostring(count or 0) .. " spell(s). ok=" .. tostring(ok and true or false))
if not (MTH and MTH.IsMessageEnabled) or MTH:IsMessageEnabled("spellbookScan", false) then
MTH:Print("Pet spellbook scan: " .. tostring(count or 0) .. " spell(s). ok=" .. tostring(ok and true or false))
end
end
end
@@ -243,6 +245,12 @@ function SlashCmdList.MTH(msg, editbox)
MTH_CommandOptions()
elseif lowerMsg == "book" or lowerMsg == "hunterbook" then
MTH_CommandBook()
elseif lowerMsg == "err" then
if MTH_DebugFrame and type(MTH_DebugFrame.Toggle) == "function" then
MTH_DebugFrame:Toggle()
else
MTH:Print("Debug frame is not available yet")
end
else
MTH:Print("Unknown command: " .. tostring(msg))
MTH:Print("Available: /mth options, /mth book")
+16 -9
View File
@@ -15,6 +15,13 @@ MTH_DebugFrame = {
infoCount = 0
}
local function MTH_DF_L(key, default)
if MTH and MTH.GetLocalization then
return MTH:GetLocalization(key, default)
end
return default or key
end
function MTH_DebugFrame:Initialize()
if self.initialized then
return
@@ -57,14 +64,14 @@ function MTH_DebugFrame:Initialize()
-- Title
local title = self.frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
title:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 20, -15)
title:SetText("MetaHunt Debug - Errors & Messages")
title:SetText(MTH_DF_L("DEBUG_TITLE", "MetaHunt Debug - Errors & Messages"))
-- Close button
local closeButton = CreateFrame("Button", nil, self.frame, "UIPanelButtonTemplate")
closeButton:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -8, -8)
closeButton:SetWidth(22)
closeButton:SetHeight(22)
closeButton:SetText("X")
closeButton:SetText(MTH_DF_L("COMMON_CLOSE_SHORT", "X"))
closeButton:SetScript("OnClick", function() MTH_DebugFrame:Hide() end)
-- Clear button
@@ -72,7 +79,7 @@ function MTH_DebugFrame:Initialize()
clearButton:SetPoint("BOTTOMLEFT", self.frame, "BOTTOMLEFT", 10, 10)
clearButton:SetWidth(100)
clearButton:SetHeight(25)
clearButton:SetText("Clear")
clearButton:SetText(MTH_DF_L("COMMON_CLEAR", "Clear"))
clearButton:SetScript("OnClick", function() MTH_DebugFrame:Clear() end)
-- Select-all button
@@ -80,7 +87,7 @@ function MTH_DebugFrame:Initialize()
copyButton:SetPoint("LEFT", clearButton, "RIGHT", 10, 0)
copyButton:SetWidth(100)
copyButton:SetHeight(25)
copyButton:SetText("Select All")
copyButton:SetText(MTH_DF_L("COMMON_SELECT_ALL", "Select All"))
copyButton:SetScript("OnClick", function() MTH_DebugFrame:SelectAllText() end)
-- Scroll frame + text content with proper vertical scrollbar
@@ -179,9 +186,9 @@ function MTH_DebugFrame:UpdateDisplay()
return
end
local text = "=== Errors Captured: " .. self.captureCount .. " ===\n"
text = text .. "=== Info Captured: " .. (self.infoCount or 0) .. " ===\n"
text = text .. "=== Total in queue: " .. table.getn(self.errors) .. " ===\n\n"
local text = string.format(MTH_DF_L("DEBUG_SUMMARY_ERRORS", "=== Errors Captured: %s ==="), tostring(self.captureCount)) .. "\n"
text = text .. string.format(MTH_DF_L("DEBUG_SUMMARY_INFO", "=== Info Captured: %s ==="), tostring(self.infoCount or 0)) .. "\n"
text = text .. string.format(MTH_DF_L("DEBUG_SUMMARY_QUEUE", "=== Total in queue: %s ==="), tostring(table.getn(self.errors))) .. "\n\n"
for i = 1, table.getn(self.errors) do
local err = self.errors[i]
@@ -238,7 +245,7 @@ function MTH_DebugFrame:Clear()
self:UpdateDisplay()
if self.initialized and self.isVisible then
if MTH and MTH.Print then
MTH:Print("Debug frame cleared")
MTH:Print(MTH_DF_L("DEBUG_CLEARED", "Debug frame cleared"))
end
end
end
@@ -251,7 +258,7 @@ function MTH_DebugFrame:SelectAllText()
self.scrollText:HighlightText(0, -1)
self.scrollText:SetFocus()
if MTH and MTH.Print then
MTH:Print("All text selected - press Ctrl+C to copy")
MTH:Print(MTH_DF_L("DEBUG_ALL_SELECTED", "All text selected - press Ctrl+C to copy"))
end
end
+4 -3
View File
@@ -238,7 +238,8 @@ function MTH_BOOK_BeastMatches(beastId, beast)
end
if MTH_BOOK_STATE.search ~= "" then
local name = MTH_BOOK_SafeLower(beast.name)
local localizedName = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(beastId, beast.name)) or beast.name
local name = MTH_BOOK_SafeLower(localizedName)
local family = MTH_BOOK_SafeLower(beast.family)
local idText = tostring(beastId)
if string.find(name, MTH_BOOK_STATE.search, 1, true) == nil
@@ -260,8 +261,8 @@ function MTH_BOOK_BeastSort(a, b)
local la = MTH_BOOK_ParseLevel(ba.lvl) or 0
local lb = MTH_BOOK_ParseLevel(bb.lvl) or 0
if la ~= lb then return la < lb end
local na = ba.name or ""
local nb = bb.name or ""
local na = (MTH and MTH.GetLocalizedBeastName) and MTH:GetLocalizedBeastName(a, ba.name) or (ba.name or "")
local nb = (MTH and MTH.GetLocalizedBeastName) and MTH:GetLocalizedBeastName(b, bb.name) or (bb.name or "")
if na ~= nb then return na < nb end
return a < b
end
+6 -3
View File
@@ -168,7 +168,8 @@ function MTH_BOOK_NPCMatches(npcId, vendor)
if MTH_BOOK_STATE.search ~= "" then
local functionSummary = MTH_BOOK_GetNPCFunctionSummary(vendor)
local firstZone, firstSubzone = MTH_BOOK_GetNPCZoneSummary(vendor)
local hay = MTH_BOOK_SafeLower(tostring(vendor.name or "") .. " " .. tostring(functionSummary or "") .. " " .. tostring(firstZone or "") .. " " .. tostring(firstSubzone or "") .. " " .. tostring(npcId))
local displayName = (MTH and MTH.GetLocalizedNPCNameById and MTH:GetLocalizedNPCNameById(npcId, vendor.name)) or vendor.name
local hay = MTH_BOOK_SafeLower(tostring(displayName or "") .. " " .. tostring(functionSummary or "") .. " " .. tostring(firstZone or "") .. " " .. tostring(firstSubzone or "") .. " " .. tostring(npcId))
if string.find(hay, MTH_BOOK_STATE.search, 1, true) == nil then
return false
end
@@ -182,8 +183,10 @@ function MTH_BOOK_NPCSort(a, b)
local va = vendors and vendors[a]
local vb = vendors and vendors[b]
if not va or not vb then return a < b end
local na = MTH_BOOK_SafeLower(va.name)
local nb = MTH_BOOK_SafeLower(vb.name)
local vaName = (MTH and MTH.GetLocalizedNPCNameById and MTH:GetLocalizedNPCNameById(a, va.name)) or va.name
local vbName = (MTH and MTH.GetLocalizedNPCNameById and MTH:GetLocalizedNPCNameById(b, vb.name)) or vb.name
local na = MTH_BOOK_SafeLower(vaName)
local nb = MTH_BOOK_SafeLower(vbName)
if na ~= nb then return na < nb end
return a < b
end
+65 -7
View File
@@ -15,10 +15,42 @@ MTH_HUNTERBOOK_TABS.items = {
},
}
MTH_HUNTERBOOK_TABS.projectiles = {
headerLabel = "Projectiles",
columnLabels = { "ID", "Req", "Lvl", "Type", "Name", "DPS", "Source" },
columnLayout = {
{ x = 8, width = 36, align = "LEFT" },
{ x = 44, width = 30, align = "LEFT" },
{ x = 74, width = 30, align = "LEFT" },
{ x = 104, width = 62, align = "LEFT" },
{ x = 166, width = 228, align = "LEFT" },
{ x = 396, width = 44, align = "LEFT" },
{ x = 442, width = 110, align = "LEFT" },
},
}
MTH_HUNTERBOOK_TABS.ammobags = {
headerLabel = "Ammo Bags",
columnLabels = { "ID", "Req", "Lvl", "Slots", "Type", "Name", "Source" },
columnLayout = {
{ x = 8, width = 40, align = "LEFT" },
{ x = 50, width = 36, align = "LEFT" },
{ x = 88, width = 34, align = "LEFT" },
{ x = 124, width = 42, align = "LEFT" },
{ x = 168, width = 80, align = "LEFT" },
{ x = 250, width = 192, align = "LEFT" },
{ x = 444, width = 108, align = "LEFT" },
},
}
function MTH_BOOK_NormalizeItemSubtype(value)
local subtype = MTH_BOOK_SafeLower(value)
subtype = string.gsub(subtype, "^%s+", "")
subtype = string.gsub(subtype, "%s+$", "")
if subtype == "arrows" then return "arrow" end
if subtype == "bullets" then return "bullet" end
if subtype == "ammo pouch" or subtype == "ammo pouches" then return "ammopouch" end
if subtype == "quivers" then return "quiver" end
if subtype == "bows" then return "bow" end
if subtype == "rifle" or subtype == "rifles" then return "gun" end
if subtype == "cross bow" or subtype == "cross-bow" or subtype == "crossbows" or subtype == "xbow" or subtype == "xbows" then return "crossbow" end
@@ -29,11 +61,36 @@ function MTH_BOOK_IsRangedWeaponSubtype(subtype)
return subtype == "bow" or subtype == "gun" or subtype == "crossbow"
end
local function MTH_BOOK_IsProjectileSubtype(subtype)
return subtype == "arrow" or subtype == "bullet"
end
local function MTH_BOOK_IsAmmoBagSubtype(subtype)
return subtype == "quiver" or subtype == "ammopouch"
end
function MTH_BOOK_ItemMatches(itemId, item)
if not item then return false end
if item.notingame then return false end
local itemSubtype = MTH_BOOK_NormalizeItemSubtype(item.subtype)
if not MTH_BOOK_IsRangedWeaponSubtype(itemSubtype) then return false end
local rawSubtype = MTH_BOOK_SafeLower(item.subtype)
rawSubtype = string.gsub(rawSubtype, "^%s+", "")
rawSubtype = string.gsub(rawSubtype, "%s+$", "")
local mode = tostring(MTH_BOOK_STATE and MTH_BOOK_STATE.mode or "items")
if mode == "projectiles" then
if not MTH_BOOK_IsProjectileSubtype(itemSubtype) then return false end
elseif mode == "ammobags" then
local hasSlots = tonumber(item.slots) and tonumber(item.slots) > 0
local looksLikeAmmoBag = MTH_BOOK_IsAmmoBagSubtype(itemSubtype)
or rawSubtype == "ammo pouch"
or rawSubtype == "ammo pouches"
or rawSubtype == "quiver"
or rawSubtype == "quivers"
or hasSlots
if not looksLikeAmmoBag then return false end
else
if not MTH_BOOK_IsRangedWeaponSubtype(itemSubtype) then return false end
end
local selectedSubtype = MTH_BOOK_NormalizeItemSubtype(MTH_BOOK_STATE.itemSubtype)
if selectedSubtype ~= "all" and itemSubtype ~= selectedSubtype then return false end
if MTH_BOOK_STATE.itemOnlyMyLevel then
@@ -48,11 +105,12 @@ function MTH_BOOK_ItemMatches(itemId, item)
if MTH_BOOK_STATE.flag3 and not MTH_BOOK_HasEntries(item.objects) then return false end
if MTH_BOOK_STATE.search ~= "" then
local name = MTH_BOOK_SafeLower(item.name)
local localizedName = (MTH and MTH.GetLocalizedItemName)
and MTH:GetLocalizedItemName(itemId, item.name)
or item.name
local name = MTH_BOOK_SafeLower(localizedName)
local idText = tostring(itemId)
if string.find(name, MTH_BOOK_STATE.search, 1, true) == nil and string.find(idText, MTH_BOOK_STATE.search, 1, true) == nil then
return false
end
if string.find(name, MTH_BOOK_STATE.search, 1, true) == nil and string.find(idText, MTH_BOOK_STATE.search, 1, true) == nil then return false end
end
return true
@@ -66,8 +124,8 @@ function MTH_BOOK_ItemSort(a, b)
local la = ia.level or 0
local lb = ib.level or 0
if la ~= lb then return la < lb end
local na = ia.name or ""
local nb = ib.name or ""
local na = (MTH and MTH.GetLocalizedItemName) and MTH:GetLocalizedItemName(a, ia.name) or (ia.name or "")
local nb = (MTH and MTH.GetLocalizedItemName) and MTH:GetLocalizedItemName(b, ib.name) or (ib.name or "")
if na ~= nb then return na < nb end
return a < b
end
+399 -118
View File
@@ -8,6 +8,11 @@ local function MTH_BOOK_GetTabDefinition(mode)
return MTH_HUNTERBOOK_TABS[tostring(mode or "")]
end
local function MTH_BOOK_IsItemMode(mode)
local resolved = tostring(mode or (MTH_BOOK_STATE and MTH_BOOK_STATE.mode) or "")
return resolved == "items" or resolved == "projectiles" or resolved == "ammobags"
end
MTH_BOOK_Browser = nil
local MTH_BOOK_RefreshFilter
local MTH_BOOK_UpdateResults
@@ -20,6 +25,31 @@ local MTH_BOOK_NPC_DATABASE_URL = "https://database.turtlecraft.gg/?npc=%d"
local MTH_BOOK_ITEM_DATABASE_URL = "https://database.turtlecraft.gg/?item=%d"
local MTH_BOOK_STABLE_CURRENT_ID_CACHE = nil
local MTH_BOOK_FALLBACK_BAG_ITEMS = {
[2101] = { name = "Light Quiver", subtype = "quiver", slots = 6, reqlevel = nil, quality = 1, sourceUrl = "https://database.turtlecraft.gg/?item=2101" },
[2102] = { name = "Small Ammo Pouch", subtype = "ammo pouch", slots = 6, reqlevel = nil, quality = 1, sourceUrl = "https://database.turtlecraft.gg/?item=2102" },
[2662] = { name = "Ribbly's Quiver", subtype = "quiver", slots = 16, reqlevel = 50, quality = 2, sourceUrl = "https://database.turtlecraft.gg/?item=2662" },
[2663] = { name = "Ribbly's Bandolier", subtype = "ammo pouch", slots = 16, reqlevel = 50, quality = 2, sourceUrl = "https://database.turtlecraft.gg/?item=2663" },
[3573] = { name = "Hunting Quiver", subtype = "quiver", slots = 10, reqlevel = nil, quality = 1, sourceUrl = "https://database.turtlecraft.gg/?item=3573" },
[3574] = { name = "Hunting Ammo Sack", subtype = "ammo pouch", slots = 10, reqlevel = nil, quality = 1, sourceUrl = "https://database.turtlecraft.gg/?item=3574" },
[3604] = { name = "Bandolier of the Night Watch", subtype = "ammo pouch", slots = 12, reqlevel = nil, quality = 2, sourceUrl = "https://database.turtlecraft.gg/?item=3604" },
[3605] = { name = "Quiver of the Night Watch", subtype = "quiver", slots = 12, reqlevel = nil, quality = 2, sourceUrl = "https://database.turtlecraft.gg/?item=3605" },
[5439] = { name = "Small Quiver", subtype = "quiver", slots = 8, reqlevel = nil, quality = 1, sourceUrl = "https://database.turtlecraft.gg/?item=5439" },
[5441] = { name = "Small Shot Pouch", subtype = "ammo pouch", slots = 8, reqlevel = nil, quality = 1, sourceUrl = "https://database.turtlecraft.gg/?item=5441" },
[7278] = { name = "Light Leather Quiver", subtype = "quiver", slots = 8, reqlevel = nil, quality = 1, sourceUrl = "https://database.turtlecraft.gg/?item=7278" },
[7279] = { name = "Small Leather Ammo Pouch", subtype = "ammo pouch", slots = 8, reqlevel = nil, quality = 1, sourceUrl = "https://database.turtlecraft.gg/?item=7279" },
[7371] = { name = "Heavy Quiver", subtype = "quiver", slots = 14, reqlevel = 30, quality = 2, sourceUrl = "https://database.turtlecraft.gg/?item=7371" },
[7372] = { name = "Heavy Leather Ammo Pouch", subtype = "ammo pouch", slots = 14, reqlevel = 30, quality = 2, sourceUrl = "https://database.turtlecraft.gg/?item=7372" },
[8217] = { name = "Quickdraw Quiver", subtype = "quiver", slots = 16, reqlevel = 40, quality = 2, sourceUrl = "https://database.turtlecraft.gg/?item=8217" },
[8218] = { name = "Thick Leather Ammo Pouch", subtype = "ammo pouch", slots = 16, reqlevel = 40, quality = 2, sourceUrl = "https://database.turtlecraft.gg/?item=8218" },
[11362] = { name = "Medium Quiver", subtype = "quiver", slots = 10, reqlevel = 10, quality = 1, sourceUrl = "https://database.turtlecraft.gg/?item=11362" },
[11363] = { name = "Medium Shot Pouch", subtype = "ammo pouch", slots = 10, reqlevel = 10, quality = 1, sourceUrl = "https://database.turtlecraft.gg/?item=11363" },
[18714] = { name = "Ancient Sinew Wrapped Lamina", subtype = "quiver", slots = 18, reqlevel = 60, quality = 4, sourceUrl = "https://database.turtlecraft.gg/?item=18714" },
[19319] = { name = "Harpy Hide Quiver", subtype = "quiver", slots = 16, reqlevel = 55, quality = 3, sourceUrl = "https://database.turtlecraft.gg/?item=19319" },
[19320] = { name = "Gnoll Skin Bandolier", subtype = "ammo pouch", slots = 16, reqlevel = 55, quality = 3, sourceUrl = "https://database.turtlecraft.gg/?item=19320" },
[61549] = { name = "Swiftfeather Quiver", subtype = "quiver", slots = 16, reqlevel = 57, quality = 3, sourceUrl = "https://database.turtlecraft.gg/?item=61549" },
}
local function MTH_BOOK_FamiliesTrace(message)
return
end
@@ -64,6 +94,8 @@ local MTH_BOOK_STATE = {
families = { col = nil, asc = true },
abilities = { col = nil, asc = true },
items = { col = nil, asc = true },
projectiles = { col = nil, asc = true },
ammobags = { col = nil, asc = true },
npcs = { col = nil, asc = true },
stable = { col = nil, asc = true },
pethistory = { col = 5, asc = false },
@@ -157,6 +189,29 @@ local MTH_BOOK_ItemSubtypeOptions = {
{ value = "crossbow", label = "Crossbow" },
}
local MTH_BOOK_ItemSubtypeOptionsProjectiles = {
{ value = "all", label = "All Projectiles" },
{ value = "arrow", label = "Arrow" },
{ value = "bullet", label = "Bullet" },
}
local MTH_BOOK_ItemSubtypeOptionsAmmoBags = {
{ value = "all", label = "All Ammo Bags" },
{ value = "quiver", label = "Quiver" },
{ value = "ammopouch", label = "Ammo Pouch" },
}
local function MTH_BOOK_GetItemSubtypeOptions(mode)
local resolved = tostring(mode or MTH_BOOK_STATE.mode or "")
if resolved == "projectiles" then
return MTH_BOOK_ItemSubtypeOptionsProjectiles
end
if resolved == "ammobags" then
return MTH_BOOK_ItemSubtypeOptionsAmmoBags
end
return MTH_BOOK_ItemSubtypeOptions
end
local MTH_BOOK_PetAbilityRanks = {}
local MTH_BOOK_CONTENT_LAYOUT_DEFAULT = {
@@ -247,7 +302,7 @@ local function MTH_BOOK_ApplyContentLayoutForMode()
local layout = MTH_BOOK_CONTENT_LAYOUT_DEFAULT
if MTH_BOOK_STATE.mode == "petabilities" then
layout = MTH_BOOK_CONTENT_LAYOUT_PETABILITIES
elseif MTH_BOOK_STATE.mode == "items" then
elseif MTH_BOOK_IsItemMode() then
layout = MTH_BOOK_CONTENT_LAYOUT_ITEMS
elseif MTH_BOOK_STATE.mode == "npcs" then
layout = MTH_BOOK_CONTENT_LAYOUT_NPCS
@@ -615,8 +670,8 @@ local function MTH_BOOK_OpenSelectedBeastOnMap()
if not MTH_Map or not MTH_Map.FocusVendor then return end
local okNpc = MTH_Map:FocusVendor(npcId, npc)
if not okNpc then return end
if DEFAULT_CHAT_FRAME then
local npcName = npc and npc.name or "Unknown"
if DEFAULT_CHAT_FRAME and MTH:IsMessageEnabled("mapMarkers", true) then
local npcName = (MTH and MTH.GetLocalizedNPCNameById and MTH:GetLocalizedNPCNameById(npcId, npc and npc.name)) or (npc and npc.name) or "Unknown"
MTH:Print("Focused map markers for " .. tostring(npcName) .. " (" .. tostring(npcId) .. ")")
end
return
@@ -630,8 +685,8 @@ local function MTH_BOOK_OpenSelectedBeastOnMap()
return
end
if DEFAULT_CHAT_FRAME then
local beastName = beast and beast.name or "Unknown"
if DEFAULT_CHAT_FRAME and MTH:IsMessageEnabled("mapMarkers", true) then
local beastName = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(beastId, beast and beast.name)) or (beast and beast.name) or "Unknown"
MTH:Print("Focused map markers for " .. tostring(beastName) .. " (" .. tostring(beastId) .. ")")
end
end
@@ -703,6 +758,7 @@ local function MTH_BOOK_ShowAllFilteredBeastsOnMap()
local beastId = tonumber(MTH_BOOK_STATE.results[i])
local beast = beastId and MTH_DS_Beasts and MTH_DS_Beasts[beastId]
if beast and beast.coords then
local beastDisplayName = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(beastId, beast.name)) or beast.name or "Unknown"
for j = 1, table.getn(beast.coords) do
local c = beast.coords[j]
if c and c[1] and c[2] and c[3] then
@@ -718,7 +774,7 @@ local function MTH_BOOK_ShowAllFilteredBeastsOnMap()
zoneId = zoneId,
x = x,
y = y,
title = string.format("%s (%d)", beast.name or "Unknown", beastId),
title = string.format("%s (%d)", beastDisplayName, beastId),
detail = details,
beastId = beastId,
color = { 0.95, 0.82, 0.10 },
@@ -743,7 +799,7 @@ local function MTH_BOOK_ShowAllFilteredBeastsOnMap()
MTH_Map:UpdateWorldMap()
MTH_Map:UpdateMinimap()
if MTH and MTH.Print then
if MTH and MTH.Print and MTH:IsMessageEnabled("mapMarkers", true) then
MTH:Print("Focused map markers for " .. tostring(table.getn(nodes)) .. " beasts in this zone.")
end
end
@@ -769,9 +825,28 @@ local function MTH_BOOK_SyncTopAreaColorWithSelectedTab()
end
function MTH_BOOK_GetItemsTable()
local items = _G["MTH_DS_Items"]
if MTH_BOOK_STATE.mode == "ammobags" then
local bagItems = MTH_DS_BagItems or MTH_DS_Bags
if (not bagItems) and type(getglobal) == "function" then
bagItems = getglobal("MTH_DS_BagItems") or getglobal("MTH_DS_Bags")
end
if bagItems then return bagItems end
return MTH_BOOK_FALLBACK_BAG_ITEMS
end
if MTH_BOOK_STATE.mode == "projectiles" then
local ammoItems = MTH_DS_AmmoItems
if (not ammoItems) and type(getglobal) == "function" then
ammoItems = getglobal("MTH_DS_AmmoItems")
end
if ammoItems then return ammoItems end
return {}
end
local items = MTH_DS_Items
if (not items) and type(getglobal) == "function" then
items = getglobal("MTH_DS_Items")
end
if items then return items end
return MTH_DS_AmmoItems
return MTH_DS_AmmoItems or {}
end
local function MTH_BOOK_CountMap(map)
@@ -781,6 +856,65 @@ local function MTH_BOOK_CountMap(map)
return count
end
local function MTH_BOOK_GetSourceBlockCount(block)
if type(block) ~= "table" then return 0 end
if tonumber(block.count) and tonumber(block.count) > 0 then
return tonumber(block.count)
end
if type(block.entries) == "table" then
return MTH_BOOK_CountMap(block.entries)
end
return MTH_BOOK_CountMap(block)
end
local function MTH_BOOK_BuildAtlasSourceTags(atlas)
local tags = {}
if type(atlas) ~= "table" then return tags end
if atlas.vendor then table.insert(tags, "Vendor") end
if atlas.quest then table.insert(tags, "Quest") end
if atlas.crafted then table.insert(tags, "Crafted") end
if atlas.boss then table.insert(tags, "Boss") end
if atlas.pvp then table.insert(tags, "PvP") end
if atlas.worlddrop then table.insert(tags, "World Drop") end
if atlas.world then table.insert(tags, "World") end
if atlas.event then table.insert(tags, "Event") end
return tags
end
local function MTH_BOOK_GetItemSourceInfo(item)
local info = {
vendors = MTH_BOOK_CountMap(item and item.vendors),
drops = MTH_BOOK_CountMap(item and item.drops),
objects = MTH_BOOK_CountMap(item and item.objects),
sourceTypes = {},
atlasTags = MTH_BOOK_BuildAtlasSourceTags(item and item.atlas_sources),
primary = "-",
}
if type(item) == "table" and type(item.sources) == "table" then
for rawKey, block in pairs(item.sources) do
local template = (type(block) == "table" and block.template) and tostring(block.template) or "?"
table.insert(info.sourceTypes, tostring(rawKey) .. " : " .. template)
end
end
if table.getn(info.sourceTypes) == 0 then
if info.vendors > 0 then table.insert(info.sourceTypes, "sold-by : npc") end
if info.drops > 0 then table.insert(info.sourceTypes, "dropped-by : npc") end
if info.objects > 0 then table.insert(info.sourceTypes, "contained-in : object") end
for i = 1, table.getn(info.atlasTags) do
table.insert(info.sourceTypes, "atlas : " .. tostring(info.atlasTags[i]))
end
end
table.sort(info.sourceTypes)
if table.getn(info.sourceTypes) > 0 then
info.primary = info.sourceTypes[1]
end
return info
end
function MTH_BOOK_HasEntries(map)
if not map then return false end
for _ in pairs(map) do return true end
@@ -813,6 +947,50 @@ end
local function MTH_BOOK_GetItemQualityColorCode(quality)
local q = tonumber(quality)
if not q and type(quality) == "string" then
local lowered = string.lower(quality)
if lowered == "poor" then q = 0 end
if lowered == "common" then q = 1 end
if lowered == "uncommon" then q = 2 end
if lowered == "rare" then q = 3 end
if lowered == "epic" then q = 4 end
if lowered == "legendary" then q = 5 end
if lowered == "artifact" then q = 6 end
end
if q ~= nil and type(GetItemQualityColor) == "function" then
local _, _, _, colorCode = GetItemQualityColor(q)
if colorCode and colorCode ~= "" then
local hex = string.gsub(tostring(colorCode), "|c", "")
hex = string.gsub(hex, "|r", "")
hex = string.gsub(hex, "^#", "")
if string.len(hex) == 8 then return string.upper(hex) end
if string.len(hex) == 6 then return "FF" .. string.upper(hex) end
end
end
if q ~= nil and ITEM_QUALITY_COLORS and ITEM_QUALITY_COLORS[q] then
local c = ITEM_QUALITY_COLORS[q]
if c and c.r and c.g and c.b then
local r = math.floor((tonumber(c.r) or 1) * 255 + 0.5)
local g = math.floor((tonumber(c.g) or 1) * 255 + 0.5)
local b = math.floor((tonumber(c.b) or 1) * 255 + 0.5)
return string.format("FF%02X%02X%02X", r, g, b)
end
end
return "FFFFFFFF"
end
local function MTH_BOOK_GetWeaponLegacyQualityColorCode(quality)
local q = tonumber(quality)
if not q and type(quality) == "string" then
local lowered = string.lower(quality)
if lowered == "poor" then q = 6 end
if lowered == "common" then q = 5 end
if lowered == "uncommon" then q = 4 end
if lowered == "rare" then q = 3 end
if lowered == "epic" then q = 2 end
if lowered == "legendary" then q = 1 end
if lowered == "artifact" then q = 1 end
end
if q == 2 then return "FFAA66FF" end
if q == 3 then return "FF0070DD" end
if q == 4 then return "FF1EFF00" end
@@ -821,6 +999,33 @@ local function MTH_BOOK_GetItemQualityColorCode(quality)
return "FFFFFFFF"
end
local function MTH_BOOK_ParseProjectileDPSFromText(text)
if type(text) ~= "string" or text == "" then return nil end
local lowered = string.lower(text)
local raw = string.match(lowered, "adds%s+([%d]+[%.,]?[%d]*)%s+damage%s+per%s+seconds?")
if not raw then
raw = string.match(lowered, "([%d]+[%.,]?[%d]*)%s+damage%s+per%s+seconds?")
end
if not raw then return nil end
local normalized = string.gsub(raw, ",", ".")
return tonumber(normalized)
end
local function MTH_BOOK_GetProjectileDPSValue(item)
if type(item) ~= "table" then return nil end
local existing = tonumber(item.dps)
if existing then return existing end
local dps = MTH_BOOK_ParseProjectileDPSFromText(item.tooltip)
if not dps then dps = MTH_BOOK_ParseProjectileDPSFromText(item.description) end
if dps then
item.dps = dps
return dps
end
return nil
end
local function MTH_BOOK_GetPlayerReactDefaults()
local faction = UnitFactionGroup and UnitFactionGroup("player")
if faction == "Alliance" then
@@ -1065,11 +1270,12 @@ local function MTH_BOOK_GetSortKey(entry, col)
if MTH_BOOK_STATE.mode == "pets" then
local beast = MTH_DS_Beasts and MTH_DS_Beasts[entry]
if not beast then return nil end
local beastName = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(entry, beast.name)) or beast.name
local traits = MTH_BOOK_ParseBeastTraits(beast)
if col == 1 then return tonumber(entry) or 0 end
if col == 2 then return MTH_BOOK_ParseLevel(beast.lvl) or 0 end
if col == 3 then return MTH_BOOK_SafeLower(beast.family) end
if col == 4 then return MTH_BOOK_SafeLower(beast.name) end
if col == 4 then return MTH_BOOK_SafeLower(beastName) end
if col == 5 then return MTH_BOOK_SafeLower(MTH_BOOK_GetBeastAbilitiesSummary(beast)) end
if col == 6 then return MTH_BOOK_SafeLower(MTH_BOOK_GetBeastZoneSummary(beast)) end
if col == 7 then return traits.rare and 1 or 0 end
@@ -1110,7 +1316,10 @@ local function MTH_BOOK_GetSortKey(entry, col)
local functionSummary = MTH_BOOK_GetNPCFunctionSummary(npc)
local zoneName = MTH_BOOK_GetNPCZoneSummary(npc)
if col == 1 then return tonumber(entry) or 0 end
if col == 2 then return MTH_BOOK_SafeLower(npc.name) end
if col == 2 then
local npcName = (MTH and MTH.GetLocalizedNPCNameById and MTH:GetLocalizedNPCNameById(entry, npc.name)) or npc.name
return MTH_BOOK_SafeLower(npcName)
end
if col == 3 then return react end
if col == 4 then return MTH_BOOK_SafeLower(functionSummary) end
if col == 5 then return MTH_BOOK_SafeLower(zoneName) end
@@ -1143,13 +1352,41 @@ local function MTH_BOOK_GetSortKey(entry, col)
local items = MTH_BOOK_GetItemsTable()
local item = items and items[entry]
if not item then return nil end
local localizedItemName = (MTH and MTH.GetLocalizedItemName)
and MTH:GetLocalizedItemName(entry, item.name)
or item.name
if col == 1 then return tonumber(entry) or 0 end
if col == 2 then return tonumber(item.reqlevel) or 0 end
if col == 3 then return tonumber(item.level) or 0 end
if col == 4 then return MTH_BOOK_SafeLower(item.subtype) end
if col == 5 then return MTH_BOOK_SafeLower(item.name) end
if col == 6 then return tonumber(item.dps) or 0 end
if col == 7 then return tonumber(item.speed) or 0 end
if MTH_BOOK_STATE.mode == "ammobags" then
if col == 4 then return tonumber(item.slots) or 0 end
if col == 5 then return MTH_BOOK_SafeLower(item.subtype) end
if col == 6 then return MTH_BOOK_SafeLower(localizedItemName) end
if col == 7 then
local hasVendors = MTH_BOOK_CountMap(item.vendors) > 0
local hasDrops = MTH_BOOK_CountMap(item.drops) > 0
local hasObjects = MTH_BOOK_CountMap(item.objects) > 0
if hasVendors and (hasDrops or hasObjects) then return "mixed" end
if hasDrops and hasObjects then return "mixed" end
if hasVendors then return "vendor" end
if hasDrops then return "drop" end
if hasObjects then return "object" end
return ""
end
else
if col == 4 then return MTH_BOOK_SafeLower(item.subtype) end
if col == 5 then return MTH_BOOK_SafeLower(localizedItemName) end
if MTH_BOOK_STATE.mode == "projectiles" then
if col == 6 then return MTH_BOOK_GetProjectileDPSValue(item) or 0 end
if col == 7 then
local sourceInfo = MTH_BOOK_GetItemSourceInfo(item)
return MTH_BOOK_SafeLower(sourceInfo and sourceInfo.primary or "")
end
else
if col == 6 then return tonumber(item.dps) or 0 end
if col == 7 then return tonumber(item.speed) or 0 end
end
end
return nil
end
@@ -1227,12 +1464,13 @@ local function MTH_BOOK_BuildResults()
then
if MTH_BOOK_STATE.search == ""
or string.find(abilityLower, MTH_BOOK_STATE.search, 1, true) ~= nil
or string.find(MTH_BOOK_SafeLower(beast.name), MTH_BOOK_STATE.search, 1, true) ~= nil
or string.find(MTH_BOOK_SafeLower((MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(beastId, beast.name)) or beast.name), MTH_BOOK_STATE.search, 1, true) ~= nil
or string.find(MTH_BOOK_SafeLower(beast.family), MTH_BOOK_STATE.search, 1, true) ~= nil
then
local beastDisplayName = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(beastId, beast.name)) or beast.name or "Unknown"
table.insert(results, {
beastId = beastId,
name = beast.name or "Unknown",
name = beastDisplayName,
family = beast.family or "?",
level = beastLevel or 0,
rare = beast.rare and true or false,
@@ -1442,14 +1680,10 @@ local function MTH_BOOK_BuildPetAbilityOptions()
local abilityLower = MTH_BOOK_SafeLower(abilityLabel)
if abilityLower ~= "" and abilityLower ~= "none" and abilityLower ~= "unknown" then
local row = abilityMap[abilityLower]
if not row then
row = { value = abilityLower, label = abilityLabel, ranks = {} }
abilityMap[abilityLower] = row
end
if bucket and bucket.spells then
if row and bucket and bucket.spells then
for i = 1, table.getn(bucket.spells) do
local spell = bucket.spells[i]
if spell then
if spell and MTH_BOOK_SafeLower(spell.learnMethod or "beast") ~= "trainer" then
local rank = tonumber(spell.rankNumber)
if rank and rank > 0 then
row.ranks[rank] = true
@@ -1757,12 +1991,15 @@ local function MTH_BOOK_UpdatePetLearnSourceDropdownText()
end
local function MTH_BOOK_GetItemSubtypeLabelByValue(value)
for i = 1, table.getn(MTH_BOOK_ItemSubtypeOptions) do
local option = MTH_BOOK_ItemSubtypeOptions[i]
local options = MTH_BOOK_GetItemSubtypeOptions()
for i = 1, table.getn(options) do
local option = options[i]
if option and option.value == value then
return option.label
end
end
if MTH_BOOK_STATE.mode == "projectiles" then return "All Projectiles" end
if MTH_BOOK_STATE.mode == "ammobags" then return "All Ammo Bags" end
return "All Ranged"
end
@@ -1785,7 +2022,7 @@ end
local function MTH_BOOK_UpdateQuickFilterControls()
MTH_BOOK_UpdateCheckboxLayoutByMode()
if MTH_BOOK_STATE.mode == "items" then
if MTH_BOOK_IsItemMode() then
MTH_BOOK_STATE.pageSize = 18
elseif MTH_BOOK_STATE.mode == "families" then
MTH_BOOK_STATE.pageSize = 16
@@ -2035,7 +2272,7 @@ local function MTH_BOOK_UpdateQuickFilterControls()
if requireVendor then requireVendor:Show() end
if requireDrop then requireDrop:Show() end
if requireObject then requireObject:Show() end
elseif MTH_BOOK_STATE.mode == "items" then
elseif MTH_BOOK_IsItemMode() then
if searchLabel then searchLabel:Show() end
if minLabel then minLabel:Hide() end
if maxLabel then maxLabel:Hide() end
@@ -2197,7 +2434,7 @@ local function MTH_BOOK_UpdateQuickFilterControls()
if itemSubtypeDropdown then itemSubtypeDropdown:Hide() end
end
if MTH_BOOK_STATE.mode ~= "petabilities" and MTH_BOOK_STATE.mode ~= "items" and petOnlyMyLevel then
if MTH_BOOK_STATE.mode ~= "petabilities" and not MTH_BOOK_IsItemMode() and petOnlyMyLevel then
petOnlyMyLevel:Hide()
end
if MTH_BOOK_STATE.mode ~= "pets" and petInZoneOnly then
@@ -2341,8 +2578,9 @@ local function MTH_BOOK_InitItemSubtypeDropdown()
if not itemDropdown then return end
UIDropDownMenu_Initialize(itemDropdown, function()
for i = 1, table.getn(MTH_BOOK_ItemSubtypeOptions) do
local option = MTH_BOOK_ItemSubtypeOptions[i]
local options = MTH_BOOK_GetItemSubtypeOptions()
for i = 1, table.getn(options) do
local option = options[i]
local info = MTH_BOOK_DropdownCreateInfo()
info.text = option.label
info.func = function()
@@ -2357,7 +2595,7 @@ local function MTH_BOOK_InitItemSubtypeDropdown()
end
end)
UIDropDownMenu_SetWidth(75, itemDropdown)
UIDropDownMenu_SetWidth(120, itemDropdown)
UIDropDownMenu_JustifyText("LEFT", itemDropdown)
MTH_BOOK_UpdateItemSubtypeDropdownText()
end
@@ -2728,8 +2966,9 @@ function MTH_BOOK_UpdateDetail()
local functionSummary = MTH_BOOK_GetNPCFunctionSummary(npc)
local zoneName, subzoneName = MTH_BOOK_GetNPCZoneSummary(npc)
local npcName = (MTH and MTH.GetLocalizedNPCNameById and MTH:GetLocalizedNPCNameById(npcId, npc.name)) or npc.name
local lines = {}
table.insert(lines, "|cFFFFFF00" .. tostring(npc.name or "Unknown") .. "|r")
table.insert(lines, "|cFFFFFF00" .. tostring(npcName or "Unknown") .. "|r")
MTH_BOOK_AddDetailSection(lines, "Identity")
MTH_BOOK_AddDetailKV(lines, "ID", npcId)
MTH_BOOK_AddDetailKV(lines, "React", MTH_BOOK_GetNPCReactBucket(npc.fac))
@@ -2773,7 +3012,8 @@ function MTH_BOOK_UpdateDetail()
return
end
local lines = {}
table.insert(lines, "|cFFFFFF00" .. (beast.name or "Unknown") .. "|r")
local beastDisplayName = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(beastId, beast.name)) or beast.name
table.insert(lines, "|cFFFFFF00" .. (beastDisplayName or "Unknown") .. "|r")
MTH_BOOK_AddDetailSection(lines, "Identity")
MTH_BOOK_AddDetailKV(lines, "ID", beastId)
MTH_BOOK_AddDetailKV(lines, "Family", beast.family or "?")
@@ -2828,9 +3068,10 @@ function MTH_BOOK_UpdateDetail()
end
local lines = {}
table.insert(lines, "|cFFFFFF00" .. tostring(entry.abilityToken) .. "|r")
local beastDisplayName = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(entry.beastId, beast.name)) or beast.name
MTH_BOOK_AddDetailSection(lines, "Identity")
MTH_BOOK_AddDetailKV(lines, "Beast", tostring(beast.name or "Unknown") .. " (ID " .. tostring(entry.beastId) .. ")")
MTH_BOOK_AddDetailKV(lines, "Beast", tostring(beastDisplayName or "Unknown") .. " (ID " .. tostring(entry.beastId) .. ")")
MTH_BOOK_AddDetailKV(lines, "Family", beast.family or "?")
MTH_BOOK_AddDetailSection(lines, "Stats")
@@ -3033,7 +3274,7 @@ function MTH_BOOK_UpdateDetail()
end
local tameBeastId = hasRecordedTame and (tonumber(row.tameBeastId) or (legacyTameContext and tonumber(legacyTameContext.beastId) or nil)) or nil
local tameBeast = tameBeastId and MTH_DS_Beasts and MTH_DS_Beasts[tameBeastId] or nil
local tameBeastName = tostring((tameBeast and tameBeast.name) or (legacyTameContext and legacyTameContext.name) or "-")
local tameBeastName = tostring(((MTH and MTH.GetLocalizedBeastName and tameBeastId and tameBeast and MTH:GetLocalizedBeastName(tameBeastId, tameBeast.name)) or (tameBeast and tameBeast.name)) or (legacyTameContext and legacyTameContext.name) or "-")
local lines = {}
table.insert(lines, "|cFFFFFF00" .. tostring(row.name or "Unknown") .. "|r")
@@ -3089,12 +3330,12 @@ function MTH_BOOK_UpdateDetail()
return
end
local v = MTH_BOOK_CountMap(item.vendors)
local d = MTH_BOOK_CountMap(item.drops)
local o = MTH_BOOK_CountMap(item.objects)
local atlas = item.atlas_sources or {}
local sourceInfo = MTH_BOOK_GetItemSourceInfo(item)
local lines = {}
table.insert(lines, "|cFFFFFF00" .. (item.name or "Unknown") .. "|r")
local localizedItemName = (MTH and MTH.GetLocalizedItemName)
and MTH:GetLocalizedItemName(itemId, item.name)
or item.name
table.insert(lines, "|cFFFFFF00" .. (localizedItemName or "Unknown") .. "|r")
MTH_BOOK_AddDetailSection(lines, "Identity")
MTH_BOOK_AddDetailKV(lines, "ID", itemId)
@@ -3103,25 +3344,21 @@ function MTH_BOOK_UpdateDetail()
MTH_BOOK_AddDetailSection(lines, "Stats")
MTH_BOOK_AddDetailKV(lines, "Level", item.level or "?")
MTH_BOOK_AddDetailKV(lines, "Req Level", item.reqlevel or "-")
if item.slots then MTH_BOOK_AddDetailKV(lines, "Slots", item.slots) end
if item.quality then MTH_BOOK_AddDetailKV(lines, "Quality", item.quality) end
if item.dps then MTH_BOOK_AddDetailKV(lines, "DPS", item.dps) end
if item.speed then MTH_BOOK_AddDetailKV(lines, "Speed", item.speed) end
if item.sourceUrl and item.sourceUrl ~= "" then MTH_BOOK_AddDetailKV(lines, "DB URL", item.sourceUrl) end
MTH_BOOK_AddDetailSection(lines, "Sources")
MTH_BOOK_AddDetailKV(lines, "Vendors", v)
MTH_BOOK_AddDetailKV(lines, "Creature Drops", d)
MTH_BOOK_AddDetailKV(lines, "Object Sources", o)
if atlas.boss or atlas.world or atlas.worlddrop or atlas.quest or atlas.vendor or atlas.pvp or atlas.crafted or atlas.event then
MTH_BOOK_AddDetailSection(lines, "Atlas Hints")
MTH_BOOK_AddDetailKV(lines, "Boss Loot", atlas.boss and "Yes" or "-")
MTH_BOOK_AddDetailKV(lines, "World Sources", atlas.world and "Yes" or "-")
MTH_BOOK_AddDetailKV(lines, "World Drop", atlas.worlddrop and "Yes" or "-")
MTH_BOOK_AddDetailKV(lines, "Quest Reward", atlas.quest and "Yes" or "-")
MTH_BOOK_AddDetailKV(lines, "Vendor / Faction", atlas.vendor and "Yes" or "-")
MTH_BOOK_AddDetailKV(lines, "PvP Reward", atlas.pvp and "Yes" or "-")
MTH_BOOK_AddDetailKV(lines, "Crafted", atlas.crafted and "Yes" or "-")
MTH_BOOK_AddDetailKV(lines, "Event", atlas.event and "Yes" or "-")
if table.getn(sourceInfo.sourceTypes) == 0 then
MTH_BOOK_AddDetailKV(lines, "Source", "-")
elseif table.getn(sourceInfo.sourceTypes) == 1 then
MTH_BOOK_AddDetailKV(lines, "Source", sourceInfo.sourceTypes[1])
else
for i = 1, table.getn(sourceInfo.sourceTypes) do
MTH_BOOK_AddDetailKV(lines, "Source " .. tostring(i), sourceInfo.sourceTypes[i])
end
end
MTH_BOOK_SetDetailText(detail, table.concat(lines, "\n"))
MTH_BOOK_UpdateOpenMapButton()
@@ -3137,6 +3374,8 @@ local function MTH_BOOK_UpdateHeader()
if mode == "families" then modeLabel = "Families" end
if mode == "petabilities" then modeLabel = "Pet Abilities" end
if mode == "items" then modeLabel = "Ranged Weapons" end
if mode == "projectiles" then modeLabel = "Projectiles" end
if mode == "ammobags" then modeLabel = "Ammo Bags" end
if mode == "npcs" then modeLabel = "NPC Finder" end
if mode == "stable" then modeLabel = "Stable" end
if mode == "pethistory" then modeLabel = "Pet History" end
@@ -3177,6 +3416,8 @@ local function MTH_BOOK_GetColumnLabels()
return { "Ability", "Lvl", "Family", "Beast", "Rare" }
elseif MTH_BOOK_STATE.mode == "npcs" then
return { "ID", "Name", "React", "Function", "Zone" }
elseif MTH_BOOK_STATE.mode == "projectiles" then
return { "ID", "Req", "Lvl", "Type", "Name", "DPS", "Source" }
end
return { "ID", "Req", "Lvl", "Type", "Name", "DPS", "Speed", "Source" }
end
@@ -3239,6 +3480,16 @@ local function MTH_BOOK_GetColumnLayout()
{ x = 242, width = 160, align = "LEFT" },
{ x = 404, width = 148, align = "LEFT" },
}
elseif MTH_BOOK_STATE.mode == "projectiles" then
return {
{ x = 8, width = 36, align = "LEFT" },
{ x = 44, width = 30, align = "LEFT" },
{ x = 74, width = 30, align = "LEFT" },
{ x = 104, width = 62, align = "LEFT" },
{ x = 166, width = 228, align = "LEFT" },
{ x = 396, width = 44, align = "LEFT" },
{ x = 442, width = 110, align = "LEFT" },
}
end
return {
@@ -3286,6 +3537,8 @@ local function MTH_BOOK_ApplyColumnLayout(parent)
for row = 1, MTH_BOOK_STATE.pageSize do
local btn = MTH_BOOK_STATE.buttons[row]
if btn and btn.cols then
local itemNameColumn = (MTH_BOOK_STATE.mode == "ammobags") and 6 or 5
local itemNameLayout = layout[itemNameColumn]
local parentWidth = tonumber(parent:GetWidth()) or 0
local rowWidth = parentWidth - 8
if rowWidth < 220 then rowWidth = 220 end
@@ -3310,7 +3563,7 @@ local function MTH_BOOK_ApplyColumnLayout(parent)
if btn.bookLinkButton then
local info = layout[1]
if (MTH_BOOK_STATE.mode == "pets" or MTH_BOOK_STATE.mode == "npcs" or MTH_BOOK_STATE.mode == "items") and info then
if (MTH_BOOK_STATE.mode == "pets" or MTH_BOOK_STATE.mode == "npcs" or MTH_BOOK_IsItemMode()) and info then
btn.bookLinkButton:ClearAllPoints()
btn.bookLinkButton:SetPoint("LEFT", btn, "LEFT", info.x - 4, 0)
btn.bookLinkButton:SetWidth(info.width)
@@ -3324,10 +3577,10 @@ local function MTH_BOOK_ApplyColumnLayout(parent)
if btn.itemLinkButton then btn.itemLinkButton:Hide() end
if btn.nameHoverButton then
if MTH_BOOK_STATE.mode == "items" and layout[5] then
if MTH_BOOK_IsItemMode() and itemNameLayout then
btn.nameHoverButton:ClearAllPoints()
btn.nameHoverButton:SetPoint("LEFT", btn, "LEFT", layout[5].x + 12, 0)
btn.nameHoverButton:SetWidth(layout[5].width - 16)
btn.nameHoverButton:SetPoint("LEFT", btn, "LEFT", itemNameLayout.x + 12, 0)
btn.nameHoverButton:SetWidth(itemNameLayout.width - 16)
btn.nameHoverButton:SetHeight(btn:GetHeight())
btn.nameHoverButton:Show()
else
@@ -3336,14 +3589,14 @@ local function MTH_BOOK_ApplyColumnLayout(parent)
end
if btn.itemIcon then
if MTH_BOOK_STATE.mode == "items" and layout[5] then
if MTH_BOOK_IsItemMode() and itemNameLayout then
btn.itemIcon:ClearAllPoints()
btn.itemIcon:SetPoint("LEFT", btn, "LEFT", layout[5].x - 4, 0)
btn.itemIcon:SetPoint("LEFT", btn, "LEFT", itemNameLayout.x - 4, 0)
btn.itemIcon:Show()
if btn.cols and btn.cols[5] then
btn.cols[5]:ClearAllPoints()
btn.cols[5]:SetPoint("LEFT", btn, "LEFT", layout[5].x + 12, 0)
btn.cols[5]:SetWidth(layout[5].width - 16)
if btn.cols and btn.cols[itemNameColumn] then
btn.cols[itemNameColumn]:ClearAllPoints()
btn.cols[itemNameColumn]:SetPoint("LEFT", btn, "LEFT", itemNameLayout.x + 12, 0)
btn.cols[itemNameColumn]:SetWidth(itemNameLayout.width - 16)
end
else
btn.itemIcon:Hide()
@@ -3357,6 +3610,7 @@ 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
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)
local zone = MTH_BOOK_GetBeastZoneSummary(beast)
@@ -3364,7 +3618,7 @@ local function MTH_BOOK_GetRowValues(entry)
"|cFF33CCFF" .. tostring(entry) .. "|r",
tostring(beast.lvl or "?"),
tostring(beast.family or "?"),
tostring(beast.name or "Unknown"),
tostring(beastDisplayName or "Unknown"),
abilities,
zone,
(traits.rare and "R" or ""),
@@ -3452,9 +3706,10 @@ local function MTH_BOOK_GetRowValues(entry)
local react = MTH_BOOK_GetNPCReactBucket(vendor.fac)
local functionSummary = MTH_BOOK_GetNPCFunctionSummary(vendor)
local zoneName = MTH_BOOK_GetNPCZoneSummary(vendor)
local vendorName = (MTH and MTH.GetLocalizedNPCNameById and MTH:GetLocalizedNPCNameById(entry, vendor.name)) or vendor.name
return {
"|cFF33CCFF" .. tostring(entry) .. "|r",
tostring(vendor.name or "Unknown"),
tostring(vendorName or "Unknown"),
react,
functionSummary,
zoneName,
@@ -3463,46 +3718,54 @@ local function MTH_BOOK_GetRowValues(entry)
local items = MTH_BOOK_GetItemsTable()
local item = items and items[entry]
if not item then return { "", "", "", "", "", "", "", "" } end
local itemName = tostring(item.name or "Unknown")
local colorCode = MTH_BOOK_GetItemQualityColorCode(item.quality)
local sourceText = "-"
local hasVendors = MTH_BOOK_CountMap(item.vendors) > 0
local hasDrops = MTH_BOOK_CountMap(item.drops) > 0
local hasObjects = MTH_BOOK_CountMap(item.objects) > 0
local concreteCount = 0
if hasVendors then concreteCount = concreteCount + 1 end
if hasDrops then concreteCount = concreteCount + 1 end
if hasObjects then concreteCount = concreteCount + 1 end
if concreteCount > 1 then
sourceText = "Mixed"
elseif hasVendors then
sourceText = "Vendor"
elseif hasDrops then
sourceText = "Drop"
elseif hasObjects then
sourceText = "Object"
else
local atlas = item.atlas_sources
if atlas then
if atlas.boss then
sourceText = "Boss"
elseif atlas.quest then
sourceText = "Quest"
elseif atlas.vendor then
sourceText = "Vendor"
elseif atlas.pvp then
sourceText = "PvP"
elseif atlas.crafted then
sourceText = "Crafted"
elseif atlas.worlddrop then
sourceText = "World Drop"
elseif atlas.world then
sourceText = "World"
elseif atlas.event then
sourceText = "Event"
end
if not item then
if MTH_BOOK_STATE.mode == "projectiles" or MTH_BOOK_STATE.mode == "ammobags" then
return { "", "", "", "", "", "", "" }
end
return { "", "", "", "", "", "", "", "" }
end
local itemName = tostring(((MTH and MTH.GetLocalizedItemName)
and MTH:GetLocalizedItemName(entry, item.name)
or item.name) or "Unknown")
local resolvedQuality = item.quality
if not resolvedQuality and MTH_BOOK_STATE.mode == "projectiles" and MTH_DS_ItemOrigins and MTH_DS_ItemOrigins[entry] then
resolvedQuality = MTH_DS_ItemOrigins[entry].quality
end
if not resolvedQuality and type(GetItemInfo) == "function" then
local _, _, runtimeQuality = GetItemInfo(entry)
if runtimeQuality ~= nil then
resolvedQuality = runtimeQuality
item.quality = runtimeQuality
end
end
local colorCode = MTH_BOOK_GetItemQualityColorCode(resolvedQuality)
if MTH_BOOK_STATE.mode == "items" then
colorCode = MTH_BOOK_GetWeaponLegacyQualityColorCode(resolvedQuality)
end
local sourceInfo = MTH_BOOK_GetItemSourceInfo(item)
local sourceText = sourceInfo.primary
if MTH_BOOK_STATE.mode == "ammobags" then
return {
"|cFF33CCFF" .. tostring(entry) .. "|r",
tostring(item.reqlevel or 0),
tostring(item.level or 0),
tostring(item.slots or "-"),
tostring(item.subtype or "?"),
"|c" .. colorCode .. itemName .. "|r",
sourceText,
}
end
if MTH_BOOK_STATE.mode == "projectiles" then
local projectileDps = MTH_BOOK_GetProjectileDPSValue(item)
return {
"|cFF33CCFF" .. tostring(entry) .. "|r",
tostring(item.reqlevel or 0),
tostring(item.level or 0),
tostring(item.subtype or "?"),
"|c" .. colorCode .. itemName .. "|r",
(projectileDps and tostring(projectileDps) or "-"),
sourceText,
}
end
return {
"|cFF33CCFF" .. tostring(entry) .. "|r",
@@ -3751,7 +4014,7 @@ MTH_BOOK_UpdateResults = function()
end
end
if btn.itemIcon then
if MTH_BOOK_STATE.mode == "items" then
if MTH_BOOK_IsItemMode() then
local items = MTH_BOOK_GetItemsTable()
local item = items and items[entry]
if item and item.icon and item.icon ~= "" then
@@ -3945,7 +4208,7 @@ local function MTH_BOOK_UpdateModeLabels()
end
end
if minLabel then
if MTH_BOOK_STATE.mode == "npcs" or MTH_BOOK_STATE.mode == "items" or MTH_BOOK_STATE.mode == "stable" or MTH_BOOK_STATE.mode == "families" or MTH_BOOK_STATE.mode == "pethistory" then
if MTH_BOOK_STATE.mode == "npcs" or MTH_BOOK_IsItemMode() or MTH_BOOK_STATE.mode == "stable" or MTH_BOOK_STATE.mode == "families" or MTH_BOOK_STATE.mode == "pethistory" then
minLabel:Hide()
else
minLabel:Show()
@@ -3953,7 +4216,7 @@ local function MTH_BOOK_UpdateModeLabels()
end
end
if maxLabel then
if MTH_BOOK_STATE.mode == "npcs" or MTH_BOOK_STATE.mode == "items" or MTH_BOOK_STATE.mode == "stable" or MTH_BOOK_STATE.mode == "families" or MTH_BOOK_STATE.mode == "pethistory" then
if MTH_BOOK_STATE.mode == "npcs" or MTH_BOOK_IsItemMode() or MTH_BOOK_STATE.mode == "stable" or MTH_BOOK_STATE.mode == "families" or MTH_BOOK_STATE.mode == "pethistory" then
maxLabel:Hide()
else
maxLabel:Show()
@@ -3963,7 +4226,7 @@ local function MTH_BOOK_UpdateModeLabels()
if getglobal("MTH_BOOK_HideNoAbilitiesText") then getglobal("MTH_BOOK_HideNoAbilitiesText"):SetText("Hide No Abilities") end
if getglobal("MTH_BOOK_PetOnlyMyLevelText") then
if MTH_BOOK_STATE.mode == "items" then
if MTH_BOOK_IsItemMode() then
getglobal("MTH_BOOK_PetOnlyMyLevelText"):SetText("Show only my level")
else
getglobal("MTH_BOOK_PetOnlyMyLevelText"):SetText("Only my level")
@@ -4003,7 +4266,7 @@ end
local function MTH_BOOK_ApplyInputs()
local search = getglobal("MTH_BOOK_Search")
MTH_BOOK_STATE.search = MTH_BOOK_SafeLower(search and search:GetText() or "")
if MTH_BOOK_STATE.mode == "npcs" or MTH_BOOK_STATE.mode == "items" or MTH_BOOK_STATE.mode == "stable" or MTH_BOOK_STATE.mode == "families" or MTH_BOOK_STATE.mode == "pethistory" then
if MTH_BOOK_STATE.mode == "npcs" or MTH_BOOK_IsItemMode() or MTH_BOOK_STATE.mode == "stable" or MTH_BOOK_STATE.mode == "families" or MTH_BOOK_STATE.mode == "pethistory" then
MTH_BOOK_STATE.minLevel = nil
MTH_BOOK_STATE.maxLevel = nil
else
@@ -4029,7 +4292,7 @@ local function MTH_BOOK_ApplyInputs()
MTH_BOOK_STATE.petInZoneOnly = petInZoneOnly and petInZoneOnly:GetChecked() == 1 or false
elseif MTH_BOOK_STATE.mode == "petabilities" then
MTH_BOOK_STATE.petOnlyMyLevel = petOnlyMyLevel and petOnlyMyLevel:GetChecked() == 1 or false
elseif MTH_BOOK_STATE.mode == "items" then
elseif MTH_BOOK_IsItemMode() then
MTH_BOOK_STATE.itemOnlyMyLevel = petOnlyMyLevel and petOnlyMyLevel:GetChecked() == 1 or false
elseif MTH_BOOK_STATE.mode == "npcs" then
MTH_BOOK_STATE.npcHideNoZone = hideUnknown and hideUnknown:GetChecked() == 1 or false
@@ -4077,6 +4340,8 @@ local function MTH_BOOK_UpdateSectionTabs()
local sectionFamilies = getglobal("MTH_BOOK_SectionFamilies")
local sectionPetAbilities = getglobal("MTH_BOOK_SectionPetAbilities")
local sectionItems = getglobal("MTH_BOOK_SectionItems")
local sectionProjectiles = getglobal("MTH_BOOK_SectionProjectiles")
local sectionAmmoBags = getglobal("MTH_BOOK_SectionAmmoBags")
local sectionNPCs = getglobal("MTH_BOOK_SectionNPCs")
local sectionStable = getglobal("MTH_BOOK_SectionStable")
local sectionPetHistory = getglobal("MTH_BOOK_SectionPetHistory")
@@ -4094,6 +4359,8 @@ local function MTH_BOOK_UpdateSectionTabs()
setState(sectionFamilies, MTH_BOOK_STATE.mode == "families")
setState(sectionPetAbilities, MTH_BOOK_STATE.mode == "petabilities")
setState(sectionItems, MTH_BOOK_STATE.mode == "items")
setState(sectionProjectiles, MTH_BOOK_STATE.mode == "projectiles")
setState(sectionAmmoBags, MTH_BOOK_STATE.mode == "ammobags")
setState(sectionNPCs, MTH_BOOK_STATE.mode == "npcs")
setState(sectionStable, MTH_BOOK_STATE.mode == "stable")
setState(sectionPetHistory, MTH_BOOK_STATE.mode == "pethistory")
@@ -4105,10 +4372,12 @@ local function MTH_BOOK_LayoutSectionTabs()
local sectionFamilies = getglobal("MTH_BOOK_SectionFamilies")
local sectionPetAbilities = getglobal("MTH_BOOK_SectionPetAbilities")
local sectionItems = getglobal("MTH_BOOK_SectionItems")
local sectionProjectiles = getglobal("MTH_BOOK_SectionProjectiles")
local sectionAmmoBags = getglobal("MTH_BOOK_SectionAmmoBags")
local sectionNPCs = getglobal("MTH_BOOK_SectionNPCs")
local sectionStable = getglobal("MTH_BOOK_SectionStable")
local sectionPetHistory = getglobal("MTH_BOOK_SectionPetHistory")
if not (tabBar and sectionPets and sectionFamilies and sectionPetAbilities and sectionItems and sectionNPCs) then return end
if not (tabBar and sectionPets and sectionFamilies and sectionPetAbilities and sectionItems and sectionNPCs and sectionProjectiles and sectionAmmoBags) then return end
if sectionStable then
sectionStable:ClearAllPoints()
@@ -4134,9 +4403,15 @@ local function MTH_BOOK_LayoutSectionTabs()
sectionItems:ClearAllPoints()
sectionItems:SetPoint("LEFT", sectionNPCs, "RIGHT", 2, 0)
sectionProjectiles:ClearAllPoints()
sectionProjectiles:SetPoint("LEFT", sectionItems, "RIGHT", 2, 0)
sectionAmmoBags:ClearAllPoints()
sectionAmmoBags:SetPoint("LEFT", sectionProjectiles, "RIGHT", 2, 0)
if sectionPetHistory then
sectionPetHistory:ClearAllPoints()
sectionPetHistory:SetPoint("LEFT", sectionItems, "RIGHT", 2, 0)
sectionPetHistory:SetPoint("LEFT", sectionAmmoBags, "RIGHT", 2, 0)
end
end
@@ -4194,7 +4469,7 @@ local function MTH_BOOK_ResetStateForMode(mode)
elseif mode == "petabilities" then
MTH_BOOK_STATE.petLearnSource = "beast"
MTH_BOOK_STATE.petOnlyMyLevel = true
elseif mode == "items" then
elseif MTH_BOOK_IsItemMode(mode) then
MTH_BOOK_STATE.itemSubtype = "all"
MTH_BOOK_STATE.itemOnlyMyLevel = false
elseif mode == "npcs" then
@@ -4230,7 +4505,7 @@ local function MTH_BOOK_ApplyStateToWidgets(widgets)
if widgets.petOnlyMyLevel then
if MTH_BOOK_STATE.mode == "petabilities" then
widgets.petOnlyMyLevel:SetChecked(MTH_BOOK_STATE.petOnlyMyLevel and 1 or nil)
elseif MTH_BOOK_STATE.mode == "items" then
elseif MTH_BOOK_IsItemMode() then
widgets.petOnlyMyLevel:SetChecked(MTH_BOOK_STATE.itemOnlyMyLevel and 1 or nil)
else
widgets.petOnlyMyLevel:SetChecked(nil)
@@ -4391,7 +4666,7 @@ local function MTH_BOOK_CreateResultButtons(parent)
end)
btn.nameHoverButton:SetScript("OnClick", function()
if not this:GetParent() or not this:GetParent().entry then return end
if MTH_BOOK_STATE.mode == "items" and this:GetParent().entry.itemId and type(IsShiftKeyDown) == "function" and IsShiftKeyDown() then
if MTH_BOOK_IsItemMode() and this:GetParent().entry.itemId and type(IsShiftKeyDown) == "function" and IsShiftKeyDown() then
if MTH_BOOK_InsertItemLinkToChat(this:GetParent().entry.itemId) then
return
end
@@ -4436,7 +4711,7 @@ local function MTH_BOOK_CreateResultButtons(parent)
btn:SetScript("OnClick", function()
if this.entry then
if MTH_BOOK_STATE.mode == "items" and this.entry.itemId and type(IsShiftKeyDown) == "function" and IsShiftKeyDown() then
if MTH_BOOK_IsItemMode() and this.entry.itemId and type(IsShiftKeyDown) == "function" and IsShiftKeyDown() then
if MTH_BOOK_InsertItemLinkToChat(this.entry.itemId) then
return
end
@@ -4506,6 +4781,8 @@ local function MTH_BOOK_WireUI(frame)
local sectionFamilies = getglobal("MTH_BOOK_SectionFamilies")
local sectionPetAbilities = getglobal("MTH_BOOK_SectionPetAbilities")
local sectionItems = getglobal("MTH_BOOK_SectionItems")
local sectionProjectiles = getglobal("MTH_BOOK_SectionProjectiles")
local sectionAmmoBags = getglobal("MTH_BOOK_SectionAmmoBags")
local sectionNPCs = getglobal("MTH_BOOK_SectionNPCs")
local sectionStable = getglobal("MTH_BOOK_SectionStable")
local sectionPetHistory = getglobal("MTH_BOOK_SectionPetHistory")
@@ -4551,6 +4828,8 @@ local function MTH_BOOK_WireUI(frame)
if sectionFamilies then sectionFamilies:SetScript("OnClick", function() MTH_BOOK_SetMode("families") end) end
if sectionPetAbilities then sectionPetAbilities:SetScript("OnClick", function() MTH_BOOK_SetMode("petabilities") end) end
if sectionItems then sectionItems:SetScript("OnClick", function() MTH_BOOK_SetMode("items") end) end
if sectionProjectiles then sectionProjectiles:SetScript("OnClick", function() MTH_BOOK_SetMode("projectiles") end) end
if sectionAmmoBags then sectionAmmoBags:SetScript("OnClick", function() MTH_BOOK_SetMode("ammobags") end) end
if sectionNPCs then sectionNPCs:SetScript("OnClick", function() MTH_BOOK_SetMode("npcs") end) end
if sectionStable then sectionStable:SetScript("OnClick", function() MTH_BOOK_SetMode("stable") end) end
if sectionPetHistory then sectionPetHistory:SetScript("OnClick", function() MTH_BOOK_SetMode("pethistory") end) end
@@ -4559,6 +4838,8 @@ local function MTH_BOOK_WireUI(frame)
MTH_BOOK_StyleSectionTab(sectionFamilies)
MTH_BOOK_StyleSectionTab(sectionPetAbilities)
MTH_BOOK_StyleSectionTab(sectionItems)
MTH_BOOK_StyleSectionTab(sectionProjectiles)
MTH_BOOK_StyleSectionTab(sectionAmmoBags)
MTH_BOOK_StyleSectionTab(sectionNPCs)
MTH_BOOK_StyleSectionTab(sectionStable)
MTH_BOOK_StyleSectionTab(sectionPetHistory)
@@ -4883,7 +5164,7 @@ local function MTH_BOOK_WireUI(frame)
if petOnlyMyLevel then
if MTH_BOOK_STATE.mode == "petabilities" then
petOnlyMyLevel:SetChecked(MTH_BOOK_STATE.petOnlyMyLevel and 1 or nil)
elseif MTH_BOOK_STATE.mode == "items" then
elseif MTH_BOOK_IsItemMode() then
petOnlyMyLevel:SetChecked(MTH_BOOK_STATE.itemOnlyMyLevel and 1 or nil)
else
petOnlyMyLevel:SetChecked(nil)
+21 -9
View File
@@ -120,54 +120,66 @@
</Frame>
<Frame name="$parentTabBar">
<Size><AbsDimension x="620" y="24"/></Size>
<Size><AbsDimension x="728" y="24"/></Size>
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="18" y="-44"/></Offset></Anchor>
</Anchors>
</Frame>
<Button name="$parentSectionStable" inherits="TabButtonTemplate" text="Stable">
<Size><AbsDimension x="86" y="24"/></Size>
<Size><AbsDimension x="64" y="24"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentTabBar"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
</Anchors>
</Button>
<Button name="$parentSectionPetAbilities" inherits="TabButtonTemplate" text="Pet Abilities">
<Size><AbsDimension x="108" y="24"/></Size>
<Size><AbsDimension x="84" y="24"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentSectionStable" relativePoint="RIGHT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor>
</Anchors>
</Button>
<Button name="$parentSectionPets" inherits="TabButtonTemplate" text="Beast Lore">
<Size><AbsDimension x="98" y="24"/></Size>
<Size><AbsDimension x="74" y="24"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentSectionPetAbilities" relativePoint="RIGHT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor>
</Anchors>
</Button>
<Button name="$parentSectionFamilies" inherits="TabButtonTemplate" text="Families">
<Size><AbsDimension x="92" y="24"/></Size>
<Size><AbsDimension x="68" y="24"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentSectionPets" relativePoint="RIGHT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor>
</Anchors>
</Button>
<Button name="$parentSectionNPCs" inherits="TabButtonTemplate" text="NPC Finder">
<Size><AbsDimension x="110" y="24"/></Size>
<Size><AbsDimension x="76" y="24"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentSectionFamilies" relativePoint="RIGHT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor>
</Anchors>
</Button>
<Button name="$parentSectionItems" inherits="TabButtonTemplate" text="Weapons">
<Size><AbsDimension x="104" y="24"/></Size>
<Size><AbsDimension x="70" y="24"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentSectionNPCs" relativePoint="RIGHT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor>
</Anchors>
</Button>
<Button name="$parentSectionPetHistory" inherits="TabButtonTemplate" text="Pet History">
<Size><AbsDimension x="104" y="24"/></Size>
<Button name="$parentSectionProjectiles" inherits="TabButtonTemplate" text="Projectiles">
<Size><AbsDimension x="80" y="24"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentSectionItems" relativePoint="RIGHT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor>
</Anchors>
</Button>
<Button name="$parentSectionAmmoBags" inherits="TabButtonTemplate" text="Ammo Bags">
<Size><AbsDimension x="78" y="24"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentSectionProjectiles" relativePoint="RIGHT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor>
</Anchors>
</Button>
<Button name="$parentSectionPetHistory" inherits="TabButtonTemplate" text="Pet History">
<Size><AbsDimension x="82" y="24"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentSectionAmmoBags" relativePoint="RIGHT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor>
</Anchors>
</Button>
<EditBox name="$parentSearch" inherits="InputBoxTemplate">
<Size><AbsDimension x="180" y="20"/></Size>
+287 -130
View File
@@ -2,103 +2,174 @@
-- MetaHunt Localization System
------------------------------------------------------
MTH.localization = {}
MTH.localization = MTH.localization or {}
MTH.currentLocale = GetLocale()
-- Binding Headers (must be defined early for keybindings)
BINDING_HEADER_FEEDOMATIC = "[MetaHunt] Feed-O-Matic"
BINDING_HEADER_ZAspectHeader = "[MetaHunt] ZAspect Buttons"
BINDING_HEADER_ZTrackHeader = "[MetaHunt] ZTrack Buttons"
BINDING_HEADER_ZTrapHeader = "[MetaHunt] ZTrap Buttons"
BINDING_HEADER_ZPetHeader = "[MetaHunt] ZPet Buttons"
BINDING_HEADER_ZAmmoHeader = "[MetaHunt] ZAmmo Buttons"
local MTH_LOCALE_ALIASES = {
enGB = "enUS",
esMX = "esES",
zhTW = "zhCN",
frFR = "enUS",
}
-- Localization table structure
local L = {}
-- English (default)
if MTH.currentLocale == "enUS" or MTH.currentLocale == "enGB" then
-- FeedOMatic
L.FEEDOMATIC_NAME = "Feed-O-Matic"
L.FEEDOMATIC_DESC = "Helps a Hunter keep his pets well fed"
L.TOOLTIPS_OPTION_FOOD = "Add tooltips on food"
L.TOOLTIPS_OPTION_FOOD_HELP = "Show your current pet's food preference directly in item tooltips."
L.TOOLTIPS_OPTION_OWNPET = "Activate on my pet"
L.TOOLTIPS_OPTION_OWNPET_HELP = "Show your own pet status details in tooltip when hovering your pet context."
L.TOOLTIPS_FOOD_QUALITY_UNKNOWN = "%s can eat this, but hasn't tried it yet."
L.TOOLTIPS_FOOD_QUALITY_UNDER = "%s doesn't like this anymore."
L.TOOLTIPS_FOOD_QUALITY_MIGHT = "%s might eat this."
L.TOOLTIPS_FOOD_QUALITY_WILL = "%s will eat this."
L.TOOLTIPS_FOOD_QUALITY_LIKE = "%s likes to eat this."
L.TOOLTIPS_FOOD_QUALITY_LOVE = "%s loves to eat this."
L.TOOLTIPS_FOOD_MARKER_UNKNOWN = "can eat this, but hasn't tried it yet."
L.TOOLTIPS_FOOD_MARKER_UNDER = "doesn't like this anymore."
L.TOOLTIPS_FOOD_MARKER_MIGHT = "might eat this."
L.TOOLTIPS_FOOD_MARKER_WILL = "will eat this."
L.TOOLTIPS_FOOD_MARKER_LIKE = "likes to eat this."
L.TOOLTIPS_FOOD_MARKER_LOVE = "loves to eat this."
-- zhunter
L.ZHUNTER_NAME = "zhunter"
L.ZHUNTER_DESC = "Various features to make a hunter's life easier"
-- German / Deutsch
elseif MTH.currentLocale == "deDE" then
L.FEEDOMATIC_NAME = "Futter-O-Mat"
L.ZHUNTER_NAME = "zhunter"
L.TOOLTIPS_OPTION_FOOD = "Add tooltips on food"
L.TOOLTIPS_OPTION_FOOD_HELP = "Show your current pet's food preference directly in item tooltips."
L.TOOLTIPS_OPTION_OWNPET = "Activate on my pet"
L.TOOLTIPS_OPTION_OWNPET_HELP = "Show your own pet status details in tooltip when hovering your pet context."
L.TOOLTIPS_FOOD_QUALITY_UNKNOWN = "%s can eat this, but hasn't tried it yet."
L.TOOLTIPS_FOOD_QUALITY_UNDER = "%s doesn't like this anymore."
L.TOOLTIPS_FOOD_QUALITY_MIGHT = "%s might eat this."
L.TOOLTIPS_FOOD_QUALITY_WILL = "%s will eat this."
L.TOOLTIPS_FOOD_QUALITY_LIKE = "%s likes to eat this."
L.TOOLTIPS_FOOD_QUALITY_LOVE = "%s loves to eat this."
L.TOOLTIPS_FOOD_MARKER_UNKNOWN = "can eat this, but hasn't tried it yet."
L.TOOLTIPS_FOOD_MARKER_UNDER = "doesn't like this anymore."
L.TOOLTIPS_FOOD_MARKER_MIGHT = "might eat this."
L.TOOLTIPS_FOOD_MARKER_WILL = "will eat this."
L.TOOLTIPS_FOOD_MARKER_LIKE = "likes to eat this."
L.TOOLTIPS_FOOD_MARKER_LOVE = "loves to eat this."
-- French / Français
elseif MTH.currentLocale == "frFR" then
L.FEEDOMATIC_NAME = "Nourricier"
L.ZHUNTER_NAME = "zhunter"
L.TOOLTIPS_OPTION_FOOD = "Add tooltips on food"
L.TOOLTIPS_OPTION_FOOD_HELP = "Show your current pet's food preference directly in item tooltips."
L.TOOLTIPS_OPTION_OWNPET = "Activate on my pet"
L.TOOLTIPS_OPTION_OWNPET_HELP = "Show your own pet status details in tooltip when hovering your pet context."
L.TOOLTIPS_FOOD_QUALITY_UNKNOWN = "%s can eat this, but hasn't tried it yet."
L.TOOLTIPS_FOOD_QUALITY_UNDER = "%s doesn't like this anymore."
L.TOOLTIPS_FOOD_QUALITY_MIGHT = "%s might eat this."
L.TOOLTIPS_FOOD_QUALITY_WILL = "%s will eat this."
L.TOOLTIPS_FOOD_QUALITY_LIKE = "%s likes to eat this."
L.TOOLTIPS_FOOD_QUALITY_LOVE = "%s loves to eat this."
L.TOOLTIPS_FOOD_MARKER_UNKNOWN = "can eat this, but hasn't tried it yet."
L.TOOLTIPS_FOOD_MARKER_UNDER = "doesn't like this anymore."
L.TOOLTIPS_FOOD_MARKER_MIGHT = "might eat this."
L.TOOLTIPS_FOOD_MARKER_WILL = "will eat this."
L.TOOLTIPS_FOOD_MARKER_LIKE = "likes to eat this."
L.TOOLTIPS_FOOD_MARKER_LOVE = "loves to eat this."
local MTH_SUPPORTED_LOCALES = {
enUS = true,
deDE = true,
esES = true,
ptBR = true,
ruRU = true,
zhCN = true,
}
local function MTH_ResolveLocale(locale)
local resolved = tostring(locale or "enUS")
if MTH_LOCALE_ALIASES[resolved] then
resolved = MTH_LOCALE_ALIASES[resolved]
end
if not MTH_SUPPORTED_LOCALES[resolved] then
resolved = "enUS"
end
return resolved
end
MTH.localization[MTH.currentLocale] = L
local activeLocale = MTH_ResolveLocale(MTH.currentLocale)
local localeData = MTH_LocaleData or {}
local uiLocales = localeData.ui or {}
local uiDefault = uiLocales.enUS or {}
local uiActive = uiLocales[activeLocale] or {}
-- Get localized string
function MTH:GetLocalization(key, default)
if L[key] then
return L[key]
local function MTH_L(key, default)
if uiActive[key] ~= nil then
return uiActive[key]
end
if uiDefault[key] ~= nil then
return uiDefault[key]
end
return default or key
end
MTH.localization[activeLocale] = uiActive
MTH.localization.enUS = uiDefault
BINDING_HEADER_FEEDOMATIC = MTH_L("BINDING_HEADER_FEEDOMATIC", "[MetaHunt] Feed-O-Matic")
BINDING_HEADER_ZAspectHeader = MTH_L("BINDING_HEADER_ZAspectHeader", "[MetaHunt] ZAspect Buttons")
BINDING_HEADER_ZTrackHeader = MTH_L("BINDING_HEADER_ZTrackHeader", "[MetaHunt] ZTrack Buttons")
BINDING_HEADER_ZTrapHeader = MTH_L("BINDING_HEADER_ZTrapHeader", "[MetaHunt] ZTrap Buttons")
BINDING_HEADER_ZPetHeader = MTH_L("BINDING_HEADER_ZPetHeader", "[MetaHunt] ZPet Buttons")
BINDING_HEADER_ZAmmoHeader = MTH_L("BINDING_HEADER_ZAmmoHeader", "[MetaHunt] ZAmmo Buttons")
function MTH:GetLocalization(key, default)
return MTH_L(key, default)
end
local function MTH_GetLocaleVendorNameMap(locale)
local dataLocales = (MTH_LocaleData and MTH_LocaleData.data) or nil
local vendorLocales = dataLocales and dataLocales.vendors or nil
if type(vendorLocales) ~= "table" then
return nil
end
return vendorLocales[locale]
end
local function MTH_GetLocaleItemNameMap(locale)
local dataLocales = (MTH_LocaleData and MTH_LocaleData.data) or nil
local itemLocales = dataLocales and dataLocales.items or nil
if type(itemLocales) ~= "table" then
return nil
end
return itemLocales[locale]
end
local function MTH_GetLocaleBeastNameMap(locale)
local dataLocales = (MTH_LocaleData and MTH_LocaleData.data) or nil
if type(dataLocales) ~= "table" then
MTH_LocaleData = MTH_LocaleData or {}
MTH_LocaleData.data = MTH_LocaleData.data or {}
dataLocales = MTH_LocaleData.data
end
local beastLocales = dataLocales and dataLocales.beasts or nil
if type(beastLocales) ~= "table" then
dataLocales.beasts = {}
beastLocales = dataLocales.beasts
end
if locale == "enUS" then
local enMap = beastLocales.enUS
if type(enMap) ~= "table" then
enMap = {}
beastLocales.enUS = enMap
end
if next(enMap) == nil then
local beasts = _G and _G.MTH_DS_Beasts or MTH_DS_Beasts
if type(beasts) == "table" then
for beastId, beast in pairs(beasts) do
local id = tonumber(beastId)
local name = type(beast) == "table" and tostring(beast.name or "") or ""
if id and name ~= "" and enMap[id] == nil then
enMap[id] = name
end
end
end
end
end
return beastLocales[locale]
end
function MTH:GetLocalizedVendorName(vendorId, defaultName)
local id = tonumber(vendorId)
if not id then
return defaultName or "Unknown"
end
local locale = MTH_ResolveLocale(self.currentLocale or GetLocale() or "enUS")
local localeMap = MTH_GetLocaleVendorNameMap(locale)
if localeMap and localeMap[id] and localeMap[id] ~= "" then
return localeMap[id]
end
local fallbackMap = MTH_GetLocaleVendorNameMap("enUS")
if fallbackMap and fallbackMap[id] and fallbackMap[id] ~= "" then
return fallbackMap[id]
end
return defaultName or "Unknown"
end
function MTH:GetLocalizedNPCNameById(npcId, defaultName)
return self:GetLocalizedVendorName(npcId, defaultName)
end
function MTH:GetLocalizedItemName(itemId, defaultName)
local id = tonumber(itemId)
if not id then
return defaultName or "Unknown"
end
local locale = MTH_ResolveLocale(self.currentLocale or GetLocale() or "enUS")
local localeMap = MTH_GetLocaleItemNameMap(locale)
if localeMap and localeMap[id] and localeMap[id] ~= "" then
return localeMap[id]
end
local fallbackMap = MTH_GetLocaleItemNameMap("enUS")
if fallbackMap and fallbackMap[id] and fallbackMap[id] ~= "" then
return fallbackMap[id]
end
return defaultName or "Unknown"
end
function MTH:GetLocalizedBeastName(beastId, defaultName)
local id = tonumber(beastId)
if not id then
return defaultName or "Unknown"
end
local locale = MTH_ResolveLocale(self.currentLocale or GetLocale() or "enUS")
local localeMap = MTH_GetLocaleBeastNameMap(locale)
if localeMap and localeMap[id] and localeMap[id] ~= "" then
return localeMap[id]
end
local fallbackMap = MTH_GetLocaleBeastNameMap("enUS")
if fallbackMap and fallbackMap[id] and fallbackMap[id] ~= "" then
return fallbackMap[id]
end
return defaultName or "Unknown"
end
-- Module localization helper
function MTH:RegisterModuleLocalization(module_name, localizationTable)
if not self.localization.modules then
@@ -118,60 +189,146 @@ function MTH:GetModuleLocalization(module_name, key, default)
end
local MTH_SPELL_LOCALE = {
enUS = {
["Banish"] = "Banish",
["Bestial Wrath"] = "Bestial Wrath",
["Concussive Shot"] = "Concussive Shot",
["Counterattack"] = "Counterattack",
["Critical Mass"] = "Critical Mass",
["Clever Traps"] = "Clever Traps",
["Deterrence"] = "Deterrence",
["Explosive Trap"] = "Explosive Trap",
["Explosive Trap Effect"] = "Explosive Trap Effect",
["Feed Pet"] = "Feed Pet",
["Flare"] = "Flare",
["Freezing Trap"] = "Freezing Trap",
["Freezing Trap Effect"] = "Freezing Trap Effect",
["Frost Trap"] = "Frost Trap",
["Frost Trap Aura"] = "Frost Trap Aura",
["Hunter's Mark"] = "Hunter's Mark",
["Holy Strength"] = "Holy Strength",
["Immolation Trap"] = "Immolation Trap",
["Immolation Trap Effect"] = "Immolation Trap Effect",
["Improved Concussive Shot"] = "Improved Concussive Shot",
["Improved Wing Clip"] = "Improved Wing Clip",
["Perception"] = "Perception",
["Piercing Shot"] = "Piercing Shot",
["Piercing Shots"] = "Piercing Shots",
["Quick Shots"] = "Quick Shots",
["Rapid Fire"] = "Rapid Fire",
["Scare Beast"] = "Scare Beast",
["Scatter Shot"] = "Scatter Shot",
["Scorpid Poison"] = "Scorpid Poison",
["Scorpid Sting"] = "Scorpid Sting",
["Serpent Sting"] = "Serpent Sting",
["Stoneform"] = "Stoneform",
["Unstable Power"] = "Unstable Power",
["Ephemeral Power"] = "Ephemeral Power",
["Viper Sting"] = "Viper Sting",
["War Stomp"] = "War Stomp",
["Will of the Forsaken"] = "Will of the Forsaken",
["Wing Clip"] = "Wing Clip",
["Wyvern Sting"] = "Wyvern Sting",
["Blood Fury"] = "Blood Fury",
["Berserking"] = "Berserking",
},
}
local MTH_SPELL_ID_BY_TOKEN = {
["Banish"] = 710,
["Bestial Wrath"] = 19574,
["Concussive Shot"] = 5116,
["Counterattack"] = 19306,
["Clever Traps"] = 19239,
["Deterrence"] = 19263,
["Explosive Trap"] = 13813,
["Explosive Trap Effect"] = 13812,
["Feed Pet"] = 6991,
["Flare"] = 1543,
["Freezing Trap"] = 1499,
["Freezing Trap Effect"] = 3355,
["Frost Trap"] = 13809,
["Frost Trap Aura"] = 13810,
["Hunter's Mark"] = 1130,
["Immolation Trap"] = 13795,
["Immolation Trap Effect"] = 13797,
["Improved Concussive Shot"] = 19407,
["Improved Wing Clip"] = 19229,
["Perception"] = 20600,
["Rapid Fire"] = 3045,
["Scare Beast"] = 1513,
["Scatter Shot"] = 19503,
["Scorpid Sting"] = 3043,
["Serpent Sting"] = 1978,
["Stoneform"] = 20594,
["Viper Sting"] = 3034,
["War Stomp"] = 20549,
["Will of the Forsaken"] = 7744,
["Wing Clip"] = 2974,
["Wyvern Sting"] = 19386,
["Blood Fury"] = 20572,
["Berserking"] = 26297,
}
do
local spellLocales = (MTH_LocaleData and MTH_LocaleData.spells) or nil
if type(spellLocales) == "table" then
for localeKey, localeMap in pairs(spellLocales) do
if type(localeMap) == "table" then
MTH_SPELL_LOCALE[localeKey] = localeMap
end
end
end
end
do
local extras = {
enUS = {
["Devilsaur Eye"] = "Devilsaur Eye",
["Devilsaur Fury"] = "Devilsaur Fury",
["Zandalarian Hero Medallion"] = "Zandalarian Hero Medallion",
["Restless Strength"] = "Restless Strength",
["Earthstrike"] = "Earthstrike",
["Badge of the Swarmguard"] = "Badge of the Swarmguard",
["Jom Gabbar"] = "Jom Gabbar",
["Kiss of the Spider"] = "Kiss of the Spider",
["Slayer's Crest"] = "Slayer's Crest",
},
deDE = {
["Devilsaur Eye"] = "Auge eines Teufelssauriers",
["Devilsaur Fury"] = "Zorn des Teufelssauriers",
["Zandalarian Hero Medallion"] = "Zandalarianisches Heldenmedallion",
["Restless Strength"] = "Ruhelose Stärke",
["Earthstrike"] = "Erdschlag",
["Badge of the Swarmguard"] = "Abzeichen der Schwarmwache",
["Jom Gabbar"] = "Jom Gabbar",
["Kiss of the Spider"] = "Kuss der Spinne",
["Slayer's Crest"] = "Jägerspitze",
},
esES = {
["Devilsaur Eye"] = "Ojo de Demosaurio",
["Devilsaur Fury"] = "Furia del devilsaurio",
["Zandalarian Hero Medallion"] = "Zandalarian Hero Medallion",
["Restless Strength"] = "Fuerza agitada",
["Earthstrike"] = "Golpeterra",
["Badge of the Swarmguard"] = "Badge of the Swarmguard",
["Jom Gabbar"] = "Jom Gabbar",
["Kiss of the Spider"] = "Kiss of the Spider",
["Slayer's Crest"] = "Cresta de Matador",
},
frFR = {
["Devilsaur Eye"] = "Oeil de diablosaure",
["Devilsaur Fury"] = "Fureur du diablosaure",
["Zandalarian Hero Medallion"] = "Médaillon de héros zandalarien",
["Restless Strength"] = "Force inconstante",
["Earthstrike"] = "Choc de terre",
["Badge of the Swarmguard"] = "Insigne de garde-essaim",
["Jom Gabbar"] = "Jom Gabbar",
["Kiss of the Spider"] = "Baiser de l'araignée",
["Slayer's Crest"] = "Ecusson de tueur",
},
zhCN = {
["Devilsaur Eye"] = "魔暴龙眼",
["Devilsaur Fury"] = "魔暴龙之怒",
["Zandalarian Hero Medallion"] = "赞达拉英雄徽记",
["Restless Strength"] = "充沛之力",
["Earthstrike"] = "大地之击",
["Badge of the Swarmguard"] = "虫群守卫徽章",
["Jom Gabbar"] = "Jom Gabbar",
["Kiss of the Spider"] = "蜘蛛之吻",
["Slayer's Crest"] = "屠戮者徽记",
},
}
for localeKey, localeMap in pairs(extras) do
if type(MTH_SPELL_LOCALE[localeKey]) ~= "table" then
MTH_SPELL_LOCALE[localeKey] = {}
end
for token, localized in pairs(localeMap) do
if MTH_SPELL_LOCALE[localeKey][token] == nil then
MTH_SPELL_LOCALE[localeKey][token] = localized
end
end
end
end
MTH.Const = MTH.Const or {}
MTH.Const.SpellLocaleMap = MTH_SPELL_LOCALE
MTH.Const.NPCLocaleMap = (MTH_LocaleData and MTH_LocaleData.data and MTH_LocaleData.data.vendors) or {}
MTH.Const.ItemLocaleMap = (MTH_LocaleData and MTH_LocaleData.data and MTH_LocaleData.data.items) or {}
MTH.Const.BeastLocaleMap = (MTH_LocaleData and MTH_LocaleData.data and MTH_LocaleData.data.beasts) or {}
function MTH:LocalizeSpell(spellToken)
local key = tostring(spellToken or "")
if key == "" then
return key
end
local locale = tostring(self.currentLocale or GetLocale() or "enUS")
local getSpellInfo = _G and _G["GetSpellInfo"] or nil
local spellId = MTH_SPELL_ID_BY_TOKEN[key]
if spellId and getSpellInfo then
local spellName = getSpellInfo(spellId)
if spellName and spellName ~= "" then
return spellName
end
end
local locale = MTH_ResolveLocale(self.currentLocale or GetLocale() or "enUS")
local localeMap = MTH_SPELL_LOCALE[locale] or MTH_SPELL_LOCALE.enUS
if localeMap and localeMap[key] then
return localeMap[key]
+16 -8
View File
@@ -572,6 +572,7 @@ function MTH_Map:FocusBeast(beastId, beast)
local cr, cg, cb = MTH_Map_GetFamilyColor(row.family)
local nodes = {}
local firstZoneId = nil
local displayName = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(id, row.name)) or row.name or "Unknown"
for i = 1, table.getn(coords) do
local c = coords[i]
@@ -581,7 +582,7 @@ function MTH_Map:FocusBeast(beastId, beast)
firstZoneId = zoneId
end
local details = string.format("Family: %s\nLevel: %s\nAbilities: %s", row.family or "?", row.lvl or "?", row.abilities or "None")
MTH_Map_AddNode(nodes, c[3], c[1], c[2], string.format("%s (%d)", row.name or "Unknown", id), details, cr, cg, cb, { kind = "beast", beastId = id })
MTH_Map_AddNode(nodes, c[3], c[1], c[2], string.format("%s (%d)", displayName, id), details, cr, cg, cb, { kind = "beast", beastId = id })
end
end
@@ -637,6 +638,7 @@ function MTH_Map:FocusVendor(vendorId, vendor)
local nodes = {}
local firstZoneId = nil
local displayName = (MTH and MTH.GetLocalizedVendorName and MTH:GetLocalizedVendorName(id, row.name)) or row.name or "Unknown"
for i = 1, table.getn(coords) do
local c = coords[i]
if c and c[1] and c[2] and c[3] then
@@ -645,7 +647,7 @@ function MTH_Map:FocusVendor(vendorId, vendor)
firstZoneId = zoneId
end
local details = string.format("React: %s\nLevel: %s\nFunctions: %s", react ~= "" and react or "?", row.lvl or "?", metaTags)
MTH_Map_AddNode(nodes, c[3], c[1], c[2], string.format("%s (%d)", row.name or "Unknown", id), details, cr, cg, cb, { kind = "vendor", vendorId = id })
MTH_Map_AddNode(nodes, c[3], c[1], c[2], string.format("%s (%d)", displayName, id), details, cr, cg, cb, { kind = "vendor", vendorId = id })
end
end
@@ -1087,12 +1089,13 @@ function MTH_Map:RegisterDefaultProviders()
for beastId, beast in pairs(MTH_DS_Beasts) do
local coords = beast and MTH_Map_GetCoordsForUnit(beastId, beast.coords)
if beast and coords and table.getn(coords) > 0 then
local displayName = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(beastId, beast.name)) or beast.name or "Unknown"
local cr, cg, cb = MTH_Map_GetFamilyColor(beast.family)
for i = 1, table.getn(coords) do
local c = coords[i]
if c and c[1] and c[2] and c[3] then
local details = string.format("Family: %s\nLevel: %s\nAbilities: %s", beast.family or "?", beast.lvl or "?", beast.abilities or "None")
MTH_Map_AddNode(nodes, c[3], c[1], c[2], string.format("%s (%d)", beast.name or "Unknown", beastId), details, cr, cg, cb, { kind = "beast", beastId = beastId })
MTH_Map_AddNode(nodes, c[3], c[1], c[2], string.format("%s (%d)", displayName, beastId), details, cr, cg, cb, { kind = "beast", beastId = beastId })
end
end
end
@@ -1111,11 +1114,12 @@ function MTH_Map:RegisterDefaultProviders()
for vendorId, vendor in pairs(MTH_DS_Vendors) do
local coords = vendor and MTH_Map_GetCoordsForUnit(vendorId, vendor.coords)
if vendor and coords and table.getn(coords) > 0 then
local displayName = (MTH and MTH.GetLocalizedVendorName and MTH:GetLocalizedVendorName(vendorId, vendor.name)) or vendor.name or "Unknown"
for i = 1, table.getn(coords) do
local c = coords[i]
if c and c[1] and c[2] and c[3] then
local details = string.format("Faction: %s\nLevel: %s", vendor.fac or "?", vendor.lvl or "?")
MTH_Map_AddNode(nodes, c[3], c[1], c[2], string.format("%s (%d)", vendor.name or "Unknown", vendorId), details, 0.20, 0.90, 1.00, { kind = "vendor", vendorId = vendorId })
MTH_Map_AddNode(nodes, c[3], c[1], c[2], string.format("%s (%d)", displayName, vendorId), details, 0.20, 0.90, 1.00, { kind = "vendor", vendorId = vendorId })
end
end
end
@@ -1136,15 +1140,19 @@ function MTH_Map:RegisterDefaultProviders()
for itemId, item in pairs(items) do
if item and item.drops then
local itemDefaultName = item.name or "Unknown"
local itemDisplayName = (MTH and MTH.GetLocalizedItemName)
and MTH:GetLocalizedItemName(itemId, itemDefaultName)
or itemDefaultName
for creatureId, chance in pairs(item.drops) do
local creature = MTH_DS_Beasts and MTH_DS_Beasts[creatureId]
local coords = MTH_Map_GetCoordsForUnit(creatureId, creature and creature.coords)
local creatureName = nil
if MTH_DS_CreatureCoords and MTH_DS_CreatureCoords[creatureId] and table.getn(MTH_DS_CreatureCoords[creatureId]) > 0 then
creatureName = (MTH_DS_CreatureNames and MTH_DS_CreatureNames[creatureId]) or (creature and creature.name)
creatureName = (MTH_DS_CreatureNames and MTH_DS_CreatureNames[creatureId]) or ((MTH and MTH.GetLocalizedBeastName and creature and MTH:GetLocalizedBeastName(creatureId, creature.name)) or (creature and creature.name))
elseif creature and creature.coords and table.getn(creature.coords) > 0 then
creatureName = creature.name
creatureName = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(creatureId, creature.name)) or creature.name
end
if coords and table.getn(coords) > 0 then
@@ -1155,7 +1163,7 @@ function MTH_Map:RegisterDefaultProviders()
local chanceText = pct and string.format("%.2f%%", pct) or tostring(chance or "?")
local details = string.format(
"Item: %s (%d)\nDrop Creature: %s (%d)\nDrop Chance: %s",
item.name or "Unknown",
itemDisplayName or "Unknown",
tonumber(itemId) or 0,
creatureName or "Unknown",
tonumber(creatureId) or 0,
@@ -1166,7 +1174,7 @@ function MTH_Map:RegisterDefaultProviders()
c[3],
c[1],
c[2],
string.format("%s ← %s", item.name or "Unknown Item", creatureName or "Unknown Creature"),
string.format("%s ← %s", itemDisplayName or "Unknown Item", creatureName or "Unknown Creature"),
details,
1.00,
0.35,
+11 -4
View File
@@ -6,6 +6,13 @@ if not MTH_MinimapButton then
MTH_MinimapButton = {}
end
local function MTH_MB_L(key, default)
if MTH and MTH.GetLocalization then
return MTH:GetLocalization(key, default)
end
return default or key
end
local function MTH_MB_GetStore()
if not MTH_CharSavedVariables then
MTH_CharSavedVariables = {}
@@ -111,10 +118,10 @@ function MTH_MinimapButton:Initialize()
self = self or this
if not self then return end
GameTooltip:SetOwner(self, "ANCHOR_LEFT")
GameTooltip:SetText("MetaHunt", 1, 0.82, 0)
GameTooltip:AddLine("Left-Click: Open Hunter Book", 1, 1, 1)
GameTooltip:AddLine("Right-Click: Open MetaHunt Options", 1, 1, 1)
GameTooltip:AddLine("Drag: Move button", 0.8, 0.8, 0.8)
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)
GameTooltip:AddLine(MTH_MB_L("MINIMAP_HINT_DRAG", "Drag: Move button"), 0.8, 0.8, 0.8)
GameTooltip:Show()
end)
+14 -1
View File
@@ -346,6 +346,15 @@ local function MTH_AB_GetBuyableItems(subtype)
if type(MTH_AutoBuy_GetProjectileItems) == "function" then
local result = MTH_AutoBuy_GetProjectileItems(subtype)
if type(result) == "table" then
for i = 1, table.getn(result) do
local row = result[i]
if type(row) == "table" then
local itemId = tonumber(row.itemId)
if itemId and MTH and MTH.GetLocalizedItemName then
row.name = MTH:GetLocalizedItemName(itemId, row.name)
end
end
end
return result
end
end
@@ -356,9 +365,13 @@ local function MTH_AB_GetBuyableItems(subtype)
for itemId, row in pairs(source) do
if type(row) == "table" and string.lower(tostring(row.subtype or "")) == wanted and type(row.vendors) == "table" then
for _ in pairs(row.vendors) do
local defaultName = tostring(row.name or ("Item " .. tostring(itemId)))
local localizedName = (MTH and MTH.GetLocalizedItemName)
and MTH:GetLocalizedItemName(itemId, defaultName)
or defaultName
table.insert(result, {
itemId = tonumber(itemId) or itemId,
name = tostring(row.name or ("Item " .. tostring(itemId))),
name = tostring(localizedName),
level = tonumber(row.level) or 0,
reqlevel = tonumber(row.reqlevel) or 0,
})
+69 -12
View File
@@ -336,25 +336,36 @@ local function MTH_CHRON_NormalizeSection(tabKey)
return "general"
end
local function MTH_CHRON_RenderTimerSection(container, profile, title, items, bucket)
local timerX = 20
local timerY = -84
MTH_CHRON_MakeTitle(container, "MetaHuntOptionsChronometerTimersHeader", title, timerX, timerY)
local function MTH_CHRON_RenderTimerSection(container, profile, title, items, bucket, opts)
opts = opts or {}
local timerX = opts.x or 20
local timerY = opts.y or -84
local prefix = tostring(opts.prefix or "Main")
MTH_CHRON_MakeTitle(container, "MetaHuntOptionsChronometerTimersHeader" .. prefix, title, timerX, timerY)
timerY = timerY - 24
if table.getn(items) == 0 then
MTH_CHRON_MakeSmall(container, "MetaHuntOptionsChronometerSectionEmpty", "(none)", timerX + 8, timerY)
MTH_CHRON_MakeSmall(container, "MetaHuntOptionsChronometerSectionEmpty" .. prefix, "(none)", timerX + 8, timerY)
return
end
for i = 1, table.getn(items) do
if timerY < -560 then
MTH_CHRON_MakeSmall(container, "MetaHuntOptionsChronometerOverflow", "...more", timerX + 8, timerY)
MTH_CHRON_MakeSmall(container, "MetaHuntOptionsChronometerOverflow" .. prefix, "...more", timerX + 8, timerY)
break
end
local timerName = items[i]
local controlName = "MetaHuntOptionsChronometerTimer" .. tostring(bucket) .. tostring(i)
local check = MTH_CreateCheckbox(container, controlName, tostring(timerName), timerY, timerX)
local row = items[i]
local timerName = row
local label = row
if type(row) == "table" then
timerName = row.key or row.timer or row.name
label = row.label or row.name or row.key
end
timerName = tostring(timerName or "")
label = tostring(label or timerName)
local controlName = "MetaHuntOptionsChronometerTimer" .. prefix .. tostring(bucket) .. tostring(i)
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)
@@ -371,6 +382,43 @@ local function MTH_CHRON_RenderTimerSection(container, profile, title, items, bu
end
end
local MTH_CHRON_HUNTER_TRINKETS = {
{ labelToken = "Devilsaur Eye", timerToken = "Devilsaur Fury" },
{ labelToken = "Zandalarian Hero Medallion", timerToken = "Restless Strength" },
{ labelToken = "Earthstrike", timerToken = "Earthstrike" },
{ labelToken = "Badge of the Swarmguard", timerToken = "Badge of the Swarmguard" },
{ labelToken = "Jom Gabbar", timerToken = "Jom Gabbar" },
{ labelToken = "Kiss of the Spider", timerToken = "Kiss of the Spider" },
{ labelToken = "Slayer's Crest", timerToken = "Slayer's Crest" },
}
local function MTH_CHRON_LocalizeTimerToken(token)
if MTH and MTH.LocalizeSpell then
return tostring(MTH:LocalizeSpell(token) or token)
end
return tostring(token)
end
local function MTH_CHRON_BuildHunterTrinketItems(classEvents)
local eventSet = {}
for i = 1, table.getn(classEvents or {}) do
eventSet[tostring(classEvents[i])] = true
end
local result = {}
for i = 1, table.getn(MTH_CHRON_HUNTER_TRINKETS) do
local def = MTH_CHRON_HUNTER_TRINKETS[i]
local key = MTH_CHRON_LocalizeTimerToken(def.timerToken)
if eventSet[key] then
table.insert(result, {
key = key,
label = MTH_CHRON_LocalizeTimerToken(def.labelToken),
})
end
end
return result
end
function MTH_RefreshChronometerOptions(tabKey)
if not MTH_CHRON_IsReady() then return end
MTH_SetupChronometerOptions(tabKey)
@@ -582,11 +630,20 @@ function MTH_SetupChronometerOptions(tabKey)
else
local classSpells, classEvents, racial = MTH_CHRON_BuildTimerLists()
if section == "classspells" then
MTH_CHRON_RenderTimerSection(container, profile, "Hunter Spells", classSpells, class)
MTH_CHRON_RenderTimerSection(container, profile, "Hunter Spells", classSpells, class, {
x = 20,
y = -84,
prefix = "ClassSpells",
})
MTH_CHRON_RenderTimerSection(container, profile, "Hunter Trinkets", MTH_CHRON_BuildHunterTrinketItems(classEvents), class, {
x = 300,
y = -84,
prefix = "ClassTrinkets",
})
elseif section == "classevents" then
MTH_CHRON_RenderTimerSection(container, profile, "Hunter Events", classEvents, class)
MTH_CHRON_RenderTimerSection(container, profile, "Hunter Events", classEvents, class, { prefix = "ClassEvents" })
elseif section == "racial" then
MTH_CHRON_RenderTimerSection(container, profile, "Racial", racial, "RACIAL")
MTH_CHRON_RenderTimerSection(container, profile, "Racial", racial, "RACIAL", { prefix = "Racial" })
end
end
end
+30 -21
View File
@@ -5,6 +5,13 @@ local MTH_CREDITS_READY = MTH_OptionsRequire and MTH_OptionsRequire("options-cre
local MTH_CREDITS_FONT_DELTA = 2
local function MTH_CR_L(key, default)
if MTH and MTH.GetLocalization then
return MTH:GetLocalization(key, default)
end
return default or key
end
local function MTH_CreditsBumpFont(fs)
if not fs or not fs.GetFont or not fs.SetFont then return end
local path, size, flags = fs:GetFont()
@@ -18,12 +25,12 @@ local function MTH_CreditsInsertLink(url)
if link == "" then return end
if type(MTH_InsertLinkToChat) == "function" and MTH_InsertLinkToChat(link) then
if MTH and MTH.Print then
MTH:Print("Link inserted in chat: " .. link)
MTH:Print(MTH_CR_L("CREDITS_LINK_INSERTED", "Link inserted in chat: ") .. link)
end
return
end
if MTH and MTH.Print then
MTH:Print("Link: " .. link)
MTH:Print(MTH_CR_L("CREDITS_LINK_FALLBACK", "Link: ") .. link)
end
end
@@ -93,7 +100,7 @@ function MTH_SetupCreditsOptions()
local title = container:CreateFontString("MetaHuntOptionsCreditsTitle", "ARTWORK", "GameFontNormal")
title:SetPoint("TOPLEFT", container, "TOPLEFT", 10, -10)
title:SetText("Credits")
title:SetText(MTH_CR_L("CREDITS_TITLE", "Credits"))
title:SetTextColor(1.00, 0.82, 0.00)
local scrollFrame = MTH_GetFrame("MetaHuntOptionsCreditsScroll")
@@ -113,18 +120,20 @@ function MTH_SetupCreditsOptions()
MTH_CreditsClearFrame(content)
scrollFrame:SetScrollChild(content)
local cursor = MTH_CreditsCreateText(content, content, "About the code", "GameFontNormal", -2, 1.00, 0.82, 0.00)
local cursor = MTH_CreditsCreateText(content, content, MTH_CR_L("CREDITS_ABOUT_CODE_TITLE", "About the code"), "GameFontNormal", -2, 1.00, 0.82, 0.00)
cursor = MTH_CreditsCreateText(content, cursor,
MTH_CR_L("CREDITS_ABOUT_CODE_INTRO",
"This addon is, in others, a compilation of old vanilla addons that I loved and played with during years. But most of them had become very buggy with TwoW as new contain was added to the server. \n I fixed, reworked, enhanced, and melted them within a modern modular framework that I created.\n"
.. "I want to make it crystal clear about what work is mine, and what is not and respectfully credit the original authors for the great stuff I've taken from them:",
.. "I want to make it crystal clear about what work is mine, and what is not and respectfully credit the original authors for the great stuff I've taken from them:"),
"GameFontNormalSmall", -10)
cursor = MTH_CreditsCreateText(content, cursor,
"- zBars, Antidaze and Autostrip were core functionalities of Vanilla zHunterMod addon. And I kept the \"z\" naming of bars/buttons to always remember it. On top of this I have created myself zAmmo, zCompanions, zMount, zToys.\nAlso the SmartAmmo feature idea is coming from Zhuntermod: there was a file in it with that functionality, but was like a work-in-progress, totally unfunctional and even \"dangerous\" in its current state, and was not active in the addon. Since it was a fucking great idea, I recoded it mostly from scratch and made it work reliably and safely.",
MTH_CR_L("CREDITS_ABOUT_ZHUNTER",
"- zBars, Antidaze and Autostrip were core functionalities of Vanilla zHunterMod addon. And I kept the \"z\" naming of bars/buttons to always remember it. On top of this I have created myself zAmmo, zCompanions, zMount, zToys.\nAlso the SmartAmmo feature idea is coming from Zhuntermod: there was a file in it with that functionality, but was like a work-in-progress, totally unfunctional and even \"dangerous\" in its current state, and was not active in the addon. Since it was a fucking great idea, I recoded it mostly from scratch and made it work reliably and safely."),
"GameFontNormalSmall", -10)
cursor = MTH_CreditsCreateText(content, cursor,
"- Feed-o-Matic was entirely the work of Fizzwidget. I made it work for Twow, by melting it as a module calling Metahunt core to get pet's state and up-to-date data for new pet families and their diet.",
MTH_CR_L("CREDITS_ABOUT_FEEDOMATIC", "- Feed-o-Matic was entirely the work of Fizzwidget. I made it work for Twow, by melting it as a module calling Metahunt core to get pet's state and up-to-date data for new pet families and their diet."),
"GameFontNormalSmall", -10)
cursor = MTH_CreditsCreateLink(content,
"https://www.wowinterface.com/downloads/info4160-FizzwidgetFeed-O-Matic.html",
@@ -133,7 +142,7 @@ function MTH_SetupCreditsOptions()
-4)
cursor = MTH_CreditsCreateText(content, cursor,
"- Tooltips module is based on Hunter Helper, another vanilla addon of Fizzwidget. I kept the general idea, but there's not much original code left from it in Metahunt as I refactored everything so it plugs on MetaHunt controlled event handlers, can work with Turtle wow data, and is now usable on other things than Beasts.",
MTH_CR_L("CREDITS_ABOUT_TOOLTIPS", "- Tooltips module is based on Hunter Helper, another vanilla addon of Fizzwidget. I kept the general idea, but there's not much original code left from it in Metahunt as I refactored everything so it plugs on MetaHunt controlled event handlers, can work with Turtle wow data, and is now usable on other things than Beasts."),
"GameFontNormalSmall", -10)
cursor = MTH_CreditsCreateLink(content,
"https://legacy-wow.com/vanilla-addons/fizzwidget-hunter-helper/",
@@ -142,7 +151,7 @@ function MTH_SetupCreditsOptions()
-4)
cursor = MTH_CreditsCreateText(content, cursor,
"- Chronometer was an old and very popular vanilla addon working with ACE2 libraries. It has known uncountable iterations by various people over the years, and I can't credit them all of them here. The current version used by Metahunt is based on this Twow conversion made by \"wigan91\". I have reworked it to have it Hunter-focused-only: removed the non-hunter/race stuff, improved the definition for spells/effects config that were not correct, added missing hunter spells (not many), and implemented my own bar color scheme fitting better the hunter spells.",
MTH_CR_L("CREDITS_ABOUT_CHRONOMETER", "- Chronometer was an old and very popular vanilla addon working with ACE2 libraries. It has known uncountable iterations by various people over the years, and I can't credit them all of them here. The current version used by Metahunt is based on this Twow conversion made by \"wigan91\". I have reworked it to have it Hunter-focused-only: removed the non-hunter/race stuff, improved the definition for spells/effects config that were not correct, added missing hunter spells (not many), and implemented my own bar color scheme fitting better the hunter spells."),
"GameFontNormalSmall", -10)
cursor = MTH_CreditsCreateLink(content,
"https://github.com/wigan91/Chronometer-TWoW",
@@ -151,25 +160,25 @@ function MTH_SetupCreditsOptions()
-4)
cursor = MTH_CreditsCreateText(content, cursor,
"- The Map/Marker system is the one of pfQuest from Master Shagu. Unfortunately he is no more reachable for some months and I could not have some talk with him about this. I mostly let it untouched, I just made slight modifications so it can integrate better within Metahunt, and doesn't conflict with pfQuest.",
MTH_CR_L("CREDITS_ABOUT_MAP", "- The Map/Marker system is the one of pfQuest from Master Shagu. Unfortunately he is no more reachable for some months and I could not have some talk with him about this. I mostly let it untouched, I just made slight modifications so it can integrate better within Metahunt, and doesn't conflict with pfQuest."),
"GameFontNormalSmall", -10)
cursor = MTH_CreditsCreateText(content, cursor,
"- The system allowing to fetch itemlinks in game (In the Weapon tab of the Hunter Book notably) is the one of Atlas Twow.",
MTH_CR_L("CREDITS_ABOUT_ATLAS_LINKS", "- The system allowing to fetch itemlinks in game (In the Weapon tab of the Hunter Book notably) is the one of Atlas Twow."),
"GameFontNormalSmall", -10)
cursor = MTH_CreditsCreateText(content, cursor, "About data sources", "GameFontNormal", -14, 1.00, 0.82, 0.00)
cursor = MTH_CreditsCreateText(content, cursor, MTH_CR_L("CREDITS_ABOUT_DATA_TITLE", "About data sources"), "GameFontNormal", -14, 1.00, 0.82, 0.00)
cursor = MTH_CreditsCreateText(content, cursor,
"Metahunt ships with its own Turtle-WoW datastores, limited to hunter stuff only, and most of this data is up-to-date (Feb 2026).\n\n"
.. "Sources used to build the data include:",
MTH_CR_L("CREDITS_ABOUT_DATA_INTRO", "Metahunt ships with its own Turtle-WoW datastores, limited to hunter stuff only, and most of this data is up-to-date (Feb 2026).\n\n"
.. "Sources used to build the data include:"),
"GameFontNormalSmall", -10)
cursor = MTH_CreditsCreateText(content, cursor,
"- pfQuest for Beasts and Ammo vendors NPCs and their spawn points (and beasts respawn times if any). Thank you again Shagu.",
MTH_CR_L("CREDITS_DATA_PFQUEST", "- pfQuest for Beasts and Ammo vendors NPCs and their spawn points (and beasts respawn times if any). Thank you again Shagu."),
"GameFontNormalSmall", -10)
cursor = MTH_CreditsCreateText(content, cursor,
"- This invaluable and very accurate spreadsheet for beasts having pet abilities. A big thanks to all twow players that crafted this! Now you dont need that sheet anymore, you have Metahunt! And the Great Book of Huntards is awesome and accurate also because of YOU.",
MTH_CR_L("CREDITS_DATA_SHEET", "- This invaluable and very accurate spreadsheet for beasts having pet abilities. A big thanks to all twow players that crafted this! Now you dont need that sheet anymore, you have Metahunt! And the Great Book of Huntards is awesome and accurate also because of YOU."),
"GameFontNormalSmall", -10)
cursor = MTH_CreditsCreateLink(content,
"https://docs.google.com/spreadsheets/d/1u33knqlYXvY-jR6pvTd58gyDg8OYEuwYsSoEnIjeA8k/edit?gid=4136205#gid=4136205",
@@ -178,16 +187,16 @@ function MTH_SetupCreditsOptions()
-4)
cursor = MTH_CreditsCreateText(content, cursor,
"- Atlas twow for ranged weapon sources\n\n"
.. "- Twow wiki for pet diet (which was incomplete, missing Serpents and Foxes)",
MTH_CR_L("CREDITS_DATA_OTHER", "- Atlas twow for ranged weapon sources\n\n"
.. "- Twow wiki for pet diet (which was incomplete, missing Serpents and Foxes)"),
"GameFontNormalSmall", -10)
cursor = MTH_CreditsCreateText(content, cursor,
"With that being said, go back hunting fellas!",
MTH_CR_L("CREDITS_CLOSING", "With that being said, go back hunting fellas!"),
"GameFontNormalSmall", -10, 1.00, 0.82, 0.00)
cursor = MTH_CreditsCreateText(content, cursor,
"\n"
.. "Metasploit <Atlantis>, of Nordaanar.",
MTH_CR_L("CREDITS_SIGNATURE", "\n"
.. "Metasploit <Atlantis>, of Nordaanar."),
"GameFontNormalSmall", -10)
end
+48 -41
View File
@@ -14,6 +14,13 @@ local MTH_FOM_STATE = {
ctrl = {},
}
local function MTH_FOM_L(key, default)
if MTH and MTH.GetLocalization then
return MTH:GetLocalization(key, default)
end
return default or key
end
local function MTH_EnsureFOMConfig()
if FOM_Config then
return
@@ -69,16 +76,16 @@ end
local function MTH_FOM_GetBindingDisplayText()
if not GetBindingKey then
return "Unavailable"
return MTH_FOM_L("FOM_BIND_UNAVAILABLE", "Unavailable")
end
local key1, key2 = GetBindingKey("FEEDOMATIC")
if not key1 and not key2 then
return "Unbound"
return MTH_FOM_L("FOM_BIND_UNBOUND", "Unbound")
end
if key1 and key2 then
return key1 .. " / " .. key2
end
return key1 or key2 or "Unbound"
return key1 or key2 or MTH_FOM_L("FOM_BIND_UNBOUND", "Unbound")
end
local function MTH_FOM_UpdateBindingStatus()
@@ -87,9 +94,9 @@ local function MTH_FOM_UpdateBindingStatus()
return
end
if MTH_FOM_STATE.bindingCapture then
bindStatus:SetText("Feed key: press a key... (ESC to clear)")
bindStatus:SetText(MTH_FOM_L("FOM_BIND_STATUS_PROMPT", "Feed key: press a key... (ESC to clear)"))
else
bindStatus:SetText("Feed key: " .. MTH_FOM_GetBindingDisplayText())
bindStatus:SetText(string.format(MTH_FOM_L("FOM_BIND_STATUS_VALUE", "Feed key: %s"), MTH_FOM_GetBindingDisplayText()))
end
end
@@ -100,7 +107,7 @@ local function MTH_FOM_StopBindingCapture()
MTH_FOM_STATE.bindButton:SetPropagateKeyboardInput(true)
end
MTH_FOM_STATE.bindButton:EnableKeyboard(false)
MTH_FOM_STATE.bindButton:SetText("Set Key")
MTH_FOM_STATE.bindButton:SetText(MTH_FOM_L("FOM_BIND_SET_KEY", "Set Key"))
end
MTH_FOM_UpdateBindingStatus()
end
@@ -108,7 +115,7 @@ end
local function MTH_FOM_StartBindingCapture()
MTH_FOM_STATE.bindingCapture = true
if MTH_FOM_STATE.bindButton then
MTH_FOM_STATE.bindButton:SetText("Press key...")
MTH_FOM_STATE.bindButton:SetText(MTH_FOM_L("FOM_BIND_PRESS_KEY", "Press key..."))
MTH_FOM_STATE.bindButton:EnableKeyboard(true)
if MTH_FOM_STATE.bindButton.SetPropagateKeyboardInput then
MTH_FOM_STATE.bindButton:SetPropagateKeyboardInput(false)
@@ -128,13 +135,13 @@ end
local function MTH_FOM_SaveBinding(key)
if not SetBinding or not SaveBindings or not GetBindingKey then
if MTH and MTH.Print then
MTH:Print("Keybinding APIs unavailable.")
MTH:Print(MTH_FOM_L("FOM_ERROR_KEYBIND_API_UNAVAILABLE", "Keybinding APIs unavailable."))
end
return
end
if InCombatLockdown and InCombatLockdown() then
if MTH and MTH.Print then
MTH:Print("Cannot change keybindings during combat.")
MTH:Print(MTH_FOM_L("FOM_ERROR_KEYBIND_COMBAT_LOCKED", "Cannot change keybindings during combat."))
end
MTH_FOM_StopBindingCapture()
return
@@ -207,7 +214,7 @@ function MTH_SetupFeedOMaticOptions()
local title = container:CreateFontString("MetaHuntOptionsFeedOMaticTitle", "ARTWORK", "GameFontHighlight")
title:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -10)
title:SetText("Feed-O-Matic")
title:SetText(MTH_FOM_L("FOM_TITLE", "Feed-O-Matic"))
local statusNotice = container:CreateFontString("MetaHuntOptionsFeedOMaticStatusNotice", "ARTWORK", "GameFontNormalSmall")
statusNotice:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -34)
@@ -215,9 +222,9 @@ function MTH_SetupFeedOMaticOptions()
statusNotice:SetJustifyH("LEFT")
statusNotice:SetJustifyV("TOP")
statusNotice:SetTextColor(0.35, 0.65, 1)
statusNotice:SetText("Feed-O-Matic, created by the great Fizzwidget, is not yet entirely ready for TurtleWoW because I am missing \na reliable list of all foods, mostly impossible to fetch from the DB.\n It still works much better in this version, but all stuff related to Food buff and Cooking isnt fully functional.")
statusNotice:SetText(MTH_FOM_L("FOM_STATUS_NOTICE", "Feed-O-Matic, created by the great Fizzwidget, is not yet entirely ready for TurtleWoW because I am missing \na reliable list of all foods, mostly impossible to fetch from the DB.\n It still works much better in this version, but all stuff related to Food buff and Cooking isnt fully functional."))
local moduleCheck = MTH_CreateCheckbox(container, "MetaHuntOptionsFeedOMaticEnabled", "Enable FeedOMatic module", -32 + yAdjust)
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
@@ -226,7 +233,7 @@ function MTH_SetupFeedOMaticOptions()
if MTH and MTH.SetModuleEnabled then
local ok, err = MTH:SetModuleEnabled("feedomatic", enabled)
if not ok and MTH and MTH.Print then
MTH:Print("Failed to change FeedOMatic state: " .. tostring(err))
MTH:Print(string.format(MTH_FOM_L("FOM_ERROR_TOGGLE_FAILED", "Failed to change FeedOMatic state: %s"), tostring(err)))
end
end
MTH_RefreshFeedOMaticOptions()
@@ -236,18 +243,18 @@ function MTH_SetupFeedOMaticOptions()
local leftHeader = container:CreateFontString("MetaHuntOptionsFeedOMaticGeneralHeader", "ARTWORK", "GameFontHighlight")
leftHeader:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -62 + yAdjust)
leftHeader:SetText("General")
leftHeader:SetText(MTH_FOM_L("FOM_HEADER_GENERAL", "General"))
local bindStatus = container:CreateFontString("MetaHuntOptionsFOMBindStatus", "ARTWORK", "GameFontNormalSmall")
bindStatus:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -80 + yAdjust)
bindStatus:SetText("Feed key: " .. MTH_FOM_GetBindingDisplayText())
bindStatus:SetText(string.format(MTH_FOM_L("FOM_BIND_STATUS_VALUE", "Feed key: %s"), MTH_FOM_GetBindingDisplayText()))
MTH_FOM_STATE.bindStatus = bindStatus
local bindButton = CreateFrame("Button", "MetaHuntOptionsFOMBindButton", container, "UIPanelButtonTemplate")
bindButton:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -100 + yAdjust)
bindButton:SetWidth(90)
bindButton:SetHeight(22)
bindButton:SetText("Set Key")
bindButton:SetText(MTH_FOM_L("FOM_BIND_SET_KEY", "Set Key"))
bindButton:EnableKeyboard(false)
bindButton:SetScript("OnClick", function()
if MTH_FOM_STATE.bindingCapture then
@@ -279,7 +286,7 @@ function MTH_SetupFeedOMaticOptions()
bindClearButton:SetPoint("LEFT", bindButton, "RIGHT", 8, 0)
bindClearButton:SetWidth(70)
bindClearButton:SetHeight(22)
bindClearButton:SetText("Clear")
bindClearButton:SetText(MTH_FOM_L("FOM_BIND_CLEAR", "Clear"))
bindClearButton:SetScript("OnClick", function()
MTH_FOM_SaveBinding(nil)
end)
@@ -291,12 +298,12 @@ function MTH_SetupFeedOMaticOptions()
bindHint:SetJustifyH("LEFT")
bindHint:SetJustifyV("TOP")
bindHint:SetTextColor(0.35, 0.65, 1)
bindHint:SetText("You should assign a key bind for feed-o-matic,\nin order to feed your pet automatically.\nThe key \"P\" is an excellent candidate !")
bindHint:SetText(MTH_FOM_L("FOM_BIND_HINT", "You should assign a key bind for feed-o-matic,\nin order to feed your pet automatically.\nThe key \"P\" is an excellent candidate !"))
MTH_FOM_STATE.ctrl.AvoidQuestFood = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAvoidQuest", FOM_OptionsButtonText and FOM_OptionsButtonText["AvoidQuestFood"] or "Avoid quest foods", -170 + yAdjust)
MTH_FOM_STATE.ctrl.AvoidBonusFood = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAvoidBonus", FOM_OptionsButtonText and FOM_OptionsButtonText["AvoidBonusFood"] or "Avoid bonus foods", -195 + yAdjust)
MTH_FOM_STATE.ctrl.PreferHigherQuality = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMPreferQuality", FOM_OptionsButtonText and FOM_OptionsButtonText["PreferHigherQuality"] or "Prefer higher quality food", -220 + yAdjust)
MTH_FOM_STATE.ctrl.Fallback = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMFallback", FOM_OptionsButtonText and FOM_OptionsButtonText["Fallback"] or "Fallback to avoided foods", -245 + yAdjust)
MTH_FOM_STATE.ctrl.AvoidQuestFood = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAvoidQuest", FOM_OptionsButtonText and FOM_OptionsButtonText["AvoidQuestFood"] or MTH_FOM_L("FOM_LABEL_AVOID_QUEST_FOODS", "Avoid quest foods"), -170 + yAdjust)
MTH_FOM_STATE.ctrl.AvoidBonusFood = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAvoidBonus", FOM_OptionsButtonText and FOM_OptionsButtonText["AvoidBonusFood"] or MTH_FOM_L("FOM_LABEL_AVOID_BONUS_FOODS", "Avoid bonus foods"), -195 + yAdjust)
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
@@ -305,7 +312,7 @@ function MTH_SetupFeedOMaticOptions()
local keepOpenLabel = container:CreateFontString("MetaHuntOptionsFOMKeepOpenLabel", "ARTWORK", "GameFontNormalSmall")
keepOpenLabel:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -302 + yAdjust)
keepOpenLabel:SetText("Keep open bag slots:")
keepOpenLabel:SetText(MTH_FOM_L("FOM_KEEP_OPEN_BAG_SLOTS", "Keep open bag slots:"))
local keepOpen = CreateFrame("EditBox", "MetaHuntOptionsFOMKeepOpen", container, "InputBoxTemplate")
keepOpen:SetPoint("LEFT", keepOpenLabel, "RIGHT", 8, 0)
@@ -325,30 +332,30 @@ function MTH_SetupFeedOMaticOptions()
local notifyHeader = container:CreateFontString("MetaHuntOptionsFOMNotifyHeader", "ARTWORK", "GameFontHighlight")
notifyHeader:SetPoint("TOPLEFT", container, "TOPLEFT", 20, -336 + yAdjust)
notifyHeader:SetText("Notify when feeding")
notifyHeader:SetText(MTH_FOM_L("FOM_HEADER_NOTIFY_WHEN_FEEDING", "Notify when feeding"))
MTH_FOM_STATE.ctrl.AlertEmote = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAlertEmote", FOM_OptionsButtonText and FOM_OptionsButtonText["AlertEmote"] or "Via emote", -360 + yAdjust)
MTH_FOM_STATE.ctrl.AlertChat = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAlertChat", FOM_OptionsButtonText and FOM_OptionsButtonText["AlertChat"] or "In chat", -385 + yAdjust)
MTH_FOM_STATE.ctrl.AlertNone = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAlertNone", FOM_OptionsButtonText and FOM_OptionsButtonText["AlertNone"] or "Don't notify", -410 + yAdjust)
MTH_FOM_STATE.ctrl.AlertEmote = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAlertEmote", FOM_OptionsButtonText and FOM_OptionsButtonText["AlertEmote"] or MTH_FOM_L("FOM_LABEL_NOTIFY_VIA_EMOTE", "Via emote"), -360 + yAdjust)
MTH_FOM_STATE.ctrl.AlertChat = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAlertChat", FOM_OptionsButtonText and FOM_OptionsButtonText["AlertChat"] or MTH_FOM_L("FOM_LABEL_NOTIFY_IN_CHAT", "In chat"), -385 + yAdjust)
MTH_FOM_STATE.ctrl.AlertNone = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAlertNone", FOM_OptionsButtonText and FOM_OptionsButtonText["AlertNone"] or MTH_FOM_L("FOM_LABEL_NOTIFY_NONE", "Don't notify"), -410 + yAdjust)
if MTH_FOM_STATE.ctrl.AlertEmote then MTH_FOM_STATE.ctrl.AlertEmote:SetScript("OnClick", function() MTH_FOM_SetAlert("emote"); MTH_RefreshFeedOMaticOptions() end) end
if MTH_FOM_STATE.ctrl.AlertChat then MTH_FOM_STATE.ctrl.AlertChat:SetScript("OnClick", function() MTH_FOM_SetAlert("chat"); MTH_RefreshFeedOMaticOptions() end) end
if MTH_FOM_STATE.ctrl.AlertNone then MTH_FOM_STATE.ctrl.AlertNone:SetScript("OnClick", function() MTH_FOM_SetAlert("none"); MTH_RefreshFeedOMaticOptions() end) end
local warnHeader = container:CreateFontString("MetaHuntOptionsFOMWarnHeader", "ARTWORK", "GameFontHighlight")
warnHeader:SetPoint("TOPLEFT", container, "TOPLEFT", rightColumnX, -276 + yAdjust)
warnHeader:SetText("Warn when pet needs feeding")
warnHeader:SetText(MTH_FOM_L("FOM_HEADER_WARN_WHEN_PET_NEEDS_FEEDING", "Warn when pet needs feeding"))
MTH_FOM_STATE.ctrl.LevelContent = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMLevelContent", FOM_OptionsButtonText and FOM_OptionsButtonText["LevelContent"] or "When content", -300 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.LevelUnhappy = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMLevelUnhappy", FOM_OptionsButtonText and FOM_OptionsButtonText["LevelUnhappy"] or "When unhappy", -325 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.LevelOff = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMLevelOff", FOM_OptionsButtonText and FOM_OptionsButtonText["LevelOff"] or "Don't warn", -350 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.LevelContent = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMLevelContent", FOM_OptionsButtonText and FOM_OptionsButtonText["LevelContent"] or MTH_FOM_L("FOM_LABEL_WARN_WHEN_CONTENT", "When content"), -300 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.LevelUnhappy = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMLevelUnhappy", FOM_OptionsButtonText and FOM_OptionsButtonText["LevelUnhappy"] or MTH_FOM_L("FOM_LABEL_WARN_WHEN_UNHAPPY", "When unhappy"), -325 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.LevelOff = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMLevelOff", FOM_OptionsButtonText and FOM_OptionsButtonText["LevelOff"] or MTH_FOM_L("FOM_LABEL_DONT_WARN", "Don't warn"), -350 + yAdjust, rightColumnX)
if MTH_FOM_STATE.ctrl.LevelContent then MTH_FOM_STATE.ctrl.LevelContent:SetScript("OnClick", function() MTH_FOM_SetLevel("content"); MTH_RefreshFeedOMaticOptions() end) end
if MTH_FOM_STATE.ctrl.LevelUnhappy then MTH_FOM_STATE.ctrl.LevelUnhappy:SetScript("OnClick", function() MTH_FOM_SetLevel("unhappy"); MTH_RefreshFeedOMaticOptions() end) end
if MTH_FOM_STATE.ctrl.LevelOff then MTH_FOM_STATE.ctrl.LevelOff:SetScript("OnClick", function() MTH_FOM_SetLevel("off"); MTH_RefreshFeedOMaticOptions() end) end
MTH_FOM_STATE.ctrl.AudioWarning = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAudioWarning", FOM_OptionsButtonText and FOM_OptionsButtonText["AudioWarning"] or "Play sound", -378 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.AudioWarningBell = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAudioWarningBell", FOM_OptionsButtonText and FOM_OptionsButtonText["AudioWarningBell"] or "Use bell sound", -403 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.TextWarning = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMTextWarning", FOM_OptionsButtonText and FOM_OptionsButtonText["TextWarning"] or "Show text", -428 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.IconWarning = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMIconWarning", FOM_OptionsButtonText and FOM_OptionsButtonText["IconWarning"] or "Flash icon", -453 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.AudioWarning = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMAudioWarning", FOM_OptionsButtonText and FOM_OptionsButtonText["AudioWarning"] or MTH_FOM_L("FOM_LABEL_PLAY_SOUND", "Play sound"), -378 + yAdjust, rightColumnX)
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
@@ -356,13 +363,13 @@ function MTH_SetupFeedOMaticOptions()
local cookHeader = container:CreateFontString("MetaHuntOptionsFOMCookingHeader", "ARTWORK", "GameFontHighlight")
cookHeader:SetPoint("TOPLEFT", container, "TOPLEFT", rightColumnX, -62 + yAdjust)
cookHeader:SetText("Avoid foods used in cooking")
cookHeader:SetText(MTH_FOM_L("FOM_HEADER_AVOID_FOODS_USED_IN_COOKING", "Avoid foods used in cooking"))
MTH_FOM_STATE.ctrl.SaveCookOrange = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMSaveCookOrange", FOM_OptionsButtonText and FOM_OptionsButtonText["SaveForCook_Orange"] or "Only difficult recipes", -86 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.SaveCookYellow = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMSaveCookYellow", FOM_OptionsButtonText and FOM_OptionsButtonText["SaveForCook_Yellow"] or "Medium or better", -111 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.SaveCookGreen = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMSaveCookGreen", FOM_OptionsButtonText and FOM_OptionsButtonText["SaveForCook_Green"] or "Easy or better", -136 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.SaveCookAll = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMSaveCookAll", FOM_OptionsButtonText and FOM_OptionsButtonText["SaveForCook_All"] or "All foods", -161 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.SaveCookNone = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMSaveCookNone", FOM_OptionsButtonText and FOM_OptionsButtonText["SaveForCook_None"] or "Do not save cooking foods", -186 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.SaveCookOrange = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMSaveCookOrange", FOM_OptionsButtonText and FOM_OptionsButtonText["SaveForCook_Orange"] or MTH_FOM_L("FOM_LABEL_ONLY_DIFFICULT_RECIPES", "Only difficult recipes"), -86 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.SaveCookYellow = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMSaveCookYellow", FOM_OptionsButtonText and FOM_OptionsButtonText["SaveForCook_Yellow"] or MTH_FOM_L("FOM_LABEL_MEDIUM_OR_BETTER", "Medium or better"), -111 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.SaveCookGreen = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMSaveCookGreen", FOM_OptionsButtonText and FOM_OptionsButtonText["SaveForCook_Green"] or MTH_FOM_L("FOM_LABEL_EASY_OR_BETTER", "Easy or better"), -136 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.SaveCookAll = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMSaveCookAll", FOM_OptionsButtonText and FOM_OptionsButtonText["SaveForCook_All"] or MTH_FOM_L("FOM_LABEL_ALL_FOODS", "All foods"), -161 + yAdjust, rightColumnX)
MTH_FOM_STATE.ctrl.SaveCookNone = MTH_CreateCheckbox(container, "MetaHuntOptionsFOMSaveCookNone", FOM_OptionsButtonText and FOM_OptionsButtonText["SaveForCook_None"] or MTH_FOM_L("FOM_LABEL_DO_NOT_SAVE_COOKING_FOODS", "Do not save cooking foods"), -186 + yAdjust, rightColumnX)
if MTH_FOM_STATE.ctrl.SaveCookOrange then MTH_FOM_STATE.ctrl.SaveCookOrange:SetScript("OnClick", function() MTH_FOM_SetCookingLevel(3); MTH_RefreshFeedOMaticOptions() end) end
if MTH_FOM_STATE.ctrl.SaveCookYellow then MTH_FOM_STATE.ctrl.SaveCookYellow:SetScript("OnClick", function() MTH_FOM_SetCookingLevel(2); MTH_RefreshFeedOMaticOptions() end) end
if MTH_FOM_STATE.ctrl.SaveCookGreen then MTH_FOM_STATE.ctrl.SaveCookGreen:SetScript("OnClick", function() MTH_FOM_SetCookingLevel(1); MTH_RefreshFeedOMaticOptions() end) end
+28 -3
View File
@@ -13,6 +13,13 @@ local MTH_OPTIONS_SHELL_READY = MTH_OptionsRequire and MTH_OptionsRequire("optio
"MTH_BuildOptionsTree",
})
local function MTH_OPT_L(key, default)
if MTH and MTH.GetLocalization then
return MTH:GetLocalization(key, default)
end
return default or key
end
local function MTH_RegisterEscClose(frameName)
if not (frameName and UISpecialFrames) then
return
@@ -33,7 +40,7 @@ local function MTH_EnsureOptionsFrame()
MetaHuntOptions = CreateFrame("Frame", "MetaHuntOptions", UIParent, "MetaHuntOptionsTemplate")
if not MetaHuntOptions then
if MTH and MTH.Print then
MTH:Print("[MTH OPTIONS] Failed to create MetaHuntOptions", "error")
MTH:Print(MTH_OPT_L("OPT_ERR_CREATE_OPTIONS_FRAME", "[MTH OPTIONS] Failed to create MetaHuntOptions"), "error")
end
return nil
end
@@ -68,7 +75,7 @@ local function MTH_EnsureOptionsFrame()
closeBtn:SetPoint("TOPRIGHT", MetaHuntOptions, "TOPRIGHT", MTH_OPTIONS_CONST.CLOSE_BTN_OFFSET_X, MTH_OPTIONS_CONST.CLOSE_BTN_OFFSET_Y)
closeBtn:SetWidth(MTH_OPTIONS_CONST.CLOSE_BTN_SIZE)
closeBtn:SetHeight(MTH_OPTIONS_CONST.CLOSE_BTN_SIZE)
closeBtn:SetText("X")
closeBtn:SetText(MTH_OPT_L("COMMON_CLOSE_SHORT", "X"))
closeBtn:SetScript("OnClick", function() MetaHuntOptions:Hide() end)
end
@@ -110,6 +117,17 @@ function MTH_SelectOptionsTab(tabKey)
MTH_SetupGeneralOptions()
MTH_OPTIONS_SETUP["General"] = true
end
elseif tabKey == "Messages" then
if not MTH_OPTIONS_SETUP["Messages"] then
if type(MTH_SetupMessagesOptions) == "function" then
MTH_SetupMessagesOptions()
MTH_OPTIONS_SETUP["Messages"] = true
end
else
if type(MTH_SetupMessagesOptions) == "function" then
MTH_SetupMessagesOptions()
end
end
elseif tabKey == "Pet" then
if not MTH_OPTIONS_SETUP["Pet"] then
MTH_SetupPetOptions()
@@ -130,6 +148,13 @@ function MTH_SelectOptionsTab(tabKey)
MTH_SetupTrapOptions()
MTH_OPTIONS_SETUP["Trap"] = true
end
elseif tabKey == "Ranged" then
if not MTH_OPTIONS_SETUP["Ranged"] then
MTH_SetupRangedOptions()
MTH_OPTIONS_SETUP["Ranged"] = true
else
MTH_SetupRangedOptions()
end
elseif tabKey == "Ammo" then
if not MTH_OPTIONS_SETUP["Ammo"] then
MTH_SetupAmmoOptions()
@@ -185,7 +210,7 @@ function MTH_SelectOptionsTab(tabKey)
MTH_SetupChronometerOptions()
MTH_OPTIONS_SETUP[tabKey] = true
elseif MTH and MTH.Print then
MTH:Print("Chronometer options module not loaded", "error")
MTH:Print(MTH_OPT_L("OPT_ERR_CHRON_NOT_LOADED", "Chronometer options module not loaded"), "error")
end
else
if _G then
+4
View File
@@ -28,10 +28,12 @@ MTH_OPTIONS_CONST = MTH_OPTIONS_CONST or {
MTH_OPTIONS_TABS = MTH_OPTIONS_TABS or {
{ key = "General", label = "General", frame = "MetaHuntOptionsGeneral" },
{ key = "Messages", label = "Messages", frame = "MetaHuntOptionsMessages" },
{ key = "Pet", label = "ZPet", frame = "MetaHuntOptionsPet" },
{ key = "Track", label = "ZTrack", frame = "MetaHuntOptionsTrack" },
{ key = "Aspect", label = "ZAspect", frame = "MetaHuntOptionsAspect" },
{ key = "Trap", label = "ZTrap", frame = "MetaHuntOptionsTrap" },
{ key = "Ranged", label = "ZRanged", frame = "MetaHuntOptionsRanged" },
{ key = "Ammo", label = "ZAmmo", frame = "MetaHuntOptionsAmmo" },
{ key = "Mounts", label = "ZMounts", frame = "MetaHuntOptionsMounts" },
{ key = "Companions", label = "ZCompanions", frame = "MetaHuntOptionsCompanions" },
@@ -49,6 +51,7 @@ MTH_OPTIONS_TABS = MTH_OPTIONS_TABS or {
MTH_OPTIONS_TREE = MTH_OPTIONS_TREE or {
{ label = "General", key = "General" },
{ label = "Messages", key = "Messages" },
{ label = "Auto Buy", key = "AutoBuy" },
{ label = "Feed-O-Matic", key = "FeedOMatic" },
{
@@ -60,6 +63,7 @@ MTH_OPTIONS_TREE = MTH_OPTIONS_TREE or {
{ label = "zAspect", key = "Aspect" },
{ label = "zTrack", key = "Track" },
{ label = "zTrap", key = "Trap" },
{ label = "zRanged", key = "Ranged" },
{ label = "zMounts", key = "Mounts" },
{ label = "zCompanions", key = "Companions" },
{ label = "zToys", key = "Toys" },
+255 -45
View File
@@ -6,6 +6,13 @@ local MTH_ZBUTTONS_READY = MTH_OptionsRequire and MTH_OptionsRequire("options-zb
"MTH_CreateActionButton",
})
local function MTH_ZB_L(key, default)
if MTH and MTH.GetLocalization then
return MTH:GetLocalization(key, default)
end
return default or key
end
local function MTH_ZB_RefreshTab(tabName)
if type(MTH_ResetAndSelectOptionsTab) == "function" then
MTH_ResetAndSelectOptionsTab(tabName)
@@ -150,6 +157,11 @@ local function MTH_GetButtonItemList(buttonName)
end
end
return getglobal("ZHunterMod_Ammo_Buttons") or sharedArrows
elseif buttonName == "zButtonRanged" then
local rangedList = getglobal("ZHunterMod_Ranged_Weapons")
if rangedList and table.getn(rangedList) > 0 then
return rangedList
end
elseif buttonName == "zButtonMounts" or buttonName == "zButtonCompanions" or buttonName == "zButtonToys" then
if ZHunterMod_Saved and ZHunterMod_Saved[buttonName] and ZHunterMod_Saved[buttonName]["spells"] then
return ZHunterMod_Saved[buttonName]["spells"]
@@ -191,6 +203,68 @@ local function MTH_EnsureAmmoOptionsWatcher()
end)
end
local function MTH_ZB_GetDefaultEnabled(buttonName)
if buttonName == "zButtonMounts" or buttonName == "zButtonCompanions" or buttonName == "zButtonToys" or buttonName == "zButtonRanged" then
return false
end
return true
end
local function MTH_ZB_EnsureButtonOptionDefaults(buttonName)
if not (ZHunterMod_Saved and buttonName) then
return nil
end
if type(ZHunterMod_Saved[buttonName]) ~= "table" then
ZHunterMod_Saved[buttonName] = {}
end
local saved = ZHunterMod_Saved[buttonName]
if saved["enabled"] == nil then
saved["enabled"] = MTH_ZB_GetDefaultEnabled(buttonName)
end
saved["enabled"] = saved["enabled"] and true or false
if saved["tooltip"] == nil then
saved["tooltip"] = true
end
saved["tooltip"] = saved["tooltip"] and true or false
if type(saved["children"]) ~= "table" then
saved["children"] = {}
end
if saved["children"]["hideonclick"] == nil then
saved["children"]["hideonclick"] = true
end
saved["children"]["hideonclick"] = saved["children"]["hideonclick"] and true or false
if type(saved["parent"]) ~= "table" then
saved["parent"] = {}
end
if saved["parent"]["hide"] == nil then
saved["parent"]["hide"] = false
end
saved["parent"]["hide"] = saved["parent"]["hide"] and true or false
if saved["parent"]["circle"] == nil then
saved["parent"]["circle"] = true
end
saved["parent"]["circle"] = saved["parent"]["circle"] and true or false
if saved["firstbutton"] ~= "LEFT" and saved["firstbutton"] ~= "RIGHT" then
saved["firstbutton"] = "RIGHT"
end
if buttonName == "zButtonAmmo" then
if saved["showammoname"] == nil then
saved["showammoname"] = true
end
saved["showammoname"] = saved["showammoname"] and true or false
end
return saved
end
local function MTH_SetupButtonOptions(containerName, buttonName, displayName, maxButtons)
local container = MTH_GetFrame(containerName)
if not container then
@@ -205,7 +279,7 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
if not ZHunterMod_Saved or not ZHunterMod_Saved[buttonName] then
local errText = container:CreateFontString(containerName.."Error", "ARTWORK", "GameFontNormal")
errText:SetPoint("CENTER", container, "CENTER", 0, 0)
errText:SetText("Configuration not loaded for "..displayName)
errText:SetText(string.format(MTH_ZB_L("ZB_ERR_CONFIG_NOT_LOADED", "Configuration not loaded for %s"), tostring(displayName)))
errText:SetTextColor(1, 0.5, 0.5)
if MTH and MTH.Print then
MTH:Print("[MTH] zhunter saved data missing for "..buttonName, "error")
@@ -214,6 +288,10 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
end
local buttonObj = getglobal(buttonName)
local saved = MTH_ZB_EnsureButtonOptionDefaults(buttonName)
if not saved then
return
end
local containerWidth = container:GetWidth() or 500
local leftWidth = 260
local rightX = leftWidth + 44
@@ -236,17 +314,15 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
return section
end
if ZHunterMod_Saved[buttonName]["enabled"] == nil then
ZHunterMod_Saved[buttonName]["enabled"] = true
end
local enabledValue = saved["enabled"] and true or false
local enableLabel = tostring(displayName or "")
if string.len(enableLabel) > 0 then
enableLabel = string.lower(string.sub(enableLabel, 1, 1)) .. string.sub(enableLabel, 2)
end
local enableButton = MTH_CreateCheckbox(container, containerName.."EnableButton", "Enable "..enableLabel, -8)
local enableButton = MTH_CreateCheckbox(container, containerName.."EnableButton", string.format(MTH_ZB_L("ZB_LABEL_ENABLE_FMT", "Enable %s"), enableLabel), -8)
if enableButton then
enableButton:SetChecked(ZHunterMod_Saved[buttonName]["enabled"] and true or false)
enableButton:SetChecked(enabledValue and true or false)
enableButton.buttonName = buttonName
enableButton.buttonObj = buttonObj
enableButton:SetScript("OnClick", function(self)
@@ -257,16 +333,16 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
end)
end
local parentSection = MTH_ZB_EnsureSection(containerName.."ParentSection", "Parent Button", -52, 116)
local childrenSection = MTH_ZB_EnsureSection(containerName.."ChildrenSection", "Children Buttons", -184, 235)
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 parentYOffset = -18
local childrenYOffset = -18
local btnSize = MTH_CreateSlider(childrenSection or container, containerName.."ButtonSize", "Button Size", 10, 100, 1, childrenYOffset)
local btnSize = MTH_CreateSlider(childrenSection or container, containerName.."ButtonSize", MTH_ZB_L("ZB_LABEL_BUTTON_SIZE", "Button Size"), 10, 100, 1, childrenYOffset)
if btnSize then
btnSize:SetWidth(leftWidth - 40)
btnSize:SetValue(ZHunterMod_Saved[buttonName]["children"]["size"] or 36)
btnSize:SetValue(saved["children"]["size"] or 36)
btnSize.buttonName = buttonName
btnSize.buttonObj = buttonObj
btnSize.itemList = MTH_GetButtonItemList(buttonName)
@@ -285,10 +361,10 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
end
childrenYOffset = childrenYOffset - 50
local rowCount = MTH_CreateSlider(childrenSection or container, containerName.."RowCount", "Number of Rows", 1, maxButtons, 1, childrenYOffset)
local rowCount = MTH_CreateSlider(childrenSection or container, containerName.."RowCount", MTH_ZB_L("ZB_LABEL_NUMBER_OF_ROWS", "Number of Rows"), 1, maxButtons, 1, childrenYOffset)
if rowCount then
rowCount:SetWidth(leftWidth - 40)
rowCount:SetValue(ZHunterMod_Saved[buttonName]["rows"] or 1)
rowCount:SetValue(saved["rows"] or 1)
rowCount.buttonName = buttonName
rowCount.buttonObj = buttonObj
rowCount.itemList = MTH_GetButtonItemList(buttonName)
@@ -303,12 +379,9 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
end
childrenYOffset = childrenYOffset - 40
if ZHunterMod_Saved[buttonName]["firstbutton"] == nil then
ZHunterMod_Saved[buttonName]["firstbutton"] = "RIGHT"
end
local expandLeft = MTH_CreateCheckbox(childrenSection or container, containerName.."ExpandLeft", "Expand Left (opposite side)", childrenYOffset)
local expandLeft = MTH_CreateCheckbox(childrenSection or container, containerName.."ExpandLeft", MTH_ZB_L("ZB_LABEL_EXPAND_LEFT", "Expand Left (opposite side)"), childrenYOffset)
if expandLeft then
expandLeft:SetChecked(ZHunterMod_Saved[buttonName]["firstbutton"] == "LEFT")
expandLeft:SetChecked(saved["firstbutton"] == "LEFT")
expandLeft.buttonName = buttonName
expandLeft.buttonObj = buttonObj
expandLeft:SetScript("OnClick", function(self)
@@ -325,13 +398,13 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
end
childrenYOffset = childrenYOffset - 30
local hideClick = MTH_CreateCheckbox(childrenSection or container, containerName.."HideOnClick", "Hide Buttons On Click", childrenYOffset)
local hideClick = MTH_CreateCheckbox(childrenSection or container, containerName.."HideOnClick", MTH_ZB_L("ZB_LABEL_HIDE_BUTTONS_ON_CLICK", "Hide Buttons On Click"), childrenYOffset)
if hideClick then
hideClick:SetChecked(ZHunterMod_Saved[buttonName]["children"]["hideonclick"])
hideClick:SetChecked(saved["children"]["hideonclick"])
hideClick.buttonName = buttonName
hideClick.buttonObj = buttonObj
if hideClick.buttonObj then
hideClick.buttonObj.hideonclick = ZHunterMod_Saved[buttonName]["children"]["hideonclick"] and true or false
hideClick.buttonObj.hideonclick = saved["children"]["hideonclick"] and true or false
end
hideClick:SetScript("OnClick", function(self)
self = self or this
@@ -344,13 +417,13 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
end
childrenYOffset = childrenYOffset - 25
local showTooltip = MTH_CreateCheckbox(childrenSection or container, containerName.."ShowTooltip", "Show Tooltip", childrenYOffset)
local showTooltip = MTH_CreateCheckbox(childrenSection or container, containerName.."ShowTooltip", MTH_ZB_L("ZB_LABEL_SHOW_TOOLTIP", "Show Tooltip"), childrenYOffset)
if showTooltip then
showTooltip:SetChecked(ZHunterMod_Saved[buttonName]["tooltip"])
showTooltip:SetChecked(saved["tooltip"])
showTooltip.buttonName = buttonName
showTooltip.buttonObj = buttonObj
if showTooltip.buttonObj then
showTooltip.buttonObj.tooltip = ZHunterMod_Saved[buttonName]["tooltip"] and true or false
showTooltip.buttonObj.tooltip = saved["tooltip"] and true or false
end
showTooltip:SetScript("OnClick", function(self)
self = self or this
@@ -364,12 +437,9 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
childrenYOffset = childrenYOffset - 25
if buttonName == "zButtonAmmo" then
if ZHunterMod_Saved[buttonName]["showammoname"] == nil then
ZHunterMod_Saved[buttonName]["showammoname"] = 1
end
local showAmmoName = MTH_CreateCheckbox(childrenSection or container, containerName.."ShowAmmoName", "Show ammo name", childrenYOffset)
local showAmmoName = MTH_CreateCheckbox(childrenSection or container, containerName.."ShowAmmoName", MTH_ZB_L("ZB_LABEL_SHOW_AMMO_NAME", "Show ammo name"), childrenYOffset)
if showAmmoName then
showAmmoName:SetChecked(ZHunterMod_Saved[buttonName]["showammoname"])
showAmmoName:SetChecked(saved["showammoname"])
showAmmoName.buttonName = buttonName
showAmmoName.buttonObj = buttonObj
showAmmoName.maxButtons = maxButtons
@@ -398,10 +468,10 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
childrenYOffset = childrenYOffset - 35
end
local mainSize = MTH_CreateSlider(parentSection or container, containerName.."MainButtonSize", "Button Size", 10, 100, 1, parentYOffset)
local mainSize = MTH_CreateSlider(parentSection or container, containerName.."MainButtonSize", MTH_ZB_L("ZB_LABEL_BUTTON_SIZE", "Button Size"), 10, 100, 1, parentYOffset)
if mainSize then
mainSize:SetWidth(leftWidth - 40)
mainSize:SetValue(ZHunterMod_Saved[buttonName]["parent"]["size"] or 36)
mainSize:SetValue(saved["parent"]["size"] or 36)
mainSize.buttonName = buttonName
mainSize.buttonObj = buttonObj
mainSize.onChange = function(val, slider)
@@ -423,9 +493,9 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
end
parentYOffset = parentYOffset - 35
local hideButton = MTH_CreateCheckbox(parentSection or container, containerName.."HideButton", "Hide Button", parentYOffset)
local hideButton = MTH_CreateCheckbox(parentSection or container, containerName.."HideButton", MTH_ZB_L("ZB_LABEL_HIDE_BUTTON", "Hide Button"), parentYOffset)
if hideButton then
hideButton:SetChecked(ZHunterMod_Saved[buttonName]["parent"]["hide"])
hideButton:SetChecked(saved["parent"]["hide"])
hideButton.buttonName = buttonName
hideButton.buttonObj = buttonObj
hideButton:SetScript("OnClick", function(self)
@@ -440,9 +510,9 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
end
parentYOffset = parentYOffset - 25
local useCircle = MTH_CreateCheckbox(parentSection or container, containerName.."UseCircle", "Use Circle Button", parentYOffset)
local useCircle = MTH_CreateCheckbox(parentSection or container, containerName.."UseCircle", MTH_ZB_L("ZB_LABEL_USE_CIRCLE_BUTTON", "Use Circle Button"), parentYOffset)
if useCircle then
useCircle:SetChecked(ZHunterMod_Saved[buttonName]["parent"]["circle"])
useCircle:SetChecked(saved["parent"]["circle"])
useCircle.buttonName = buttonName
useCircle.buttonObj = buttonObj
useCircle:SetScript("OnClick", function(self)
@@ -456,18 +526,18 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
end)
end
MTH_SetButtonEnabledState(buttonName, buttonObj, ZHunterMod_Saved[buttonName]["enabled"] and true or false)
MTH_SetButtonEnabledState(buttonName, buttonObj, saved["enabled"] and true or false)
local advHeader = container:CreateFontString(containerName.."AdvHeader", "ARTWORK", "GameFontHighlight")
advHeader:SetPoint("TOPLEFT", container, "TOPLEFT", rightX, -10)
advHeader:SetText("Spell Order")
advHeader:SetText(MTH_ZB_L("ZB_HEADER_SPELL_ORDER", "Spell Order"))
local itemList = MTH_GetButtonItemList(buttonName)
if not itemList or not ZHunterMod_Saved[buttonName]["spells"] then
local noData = container:CreateFontString(containerName.."NoData", "ARTWORK", "GameFontNormalSmall")
noData:SetPoint("TOPRIGHT", container, "TOPRIGHT", -80, -50)
noData:SetText("Spell data not loaded")
noData:SetText(MTH_ZB_L("ZB_TEXT_SPELL_DATA_NOT_LOADED", "Spell data not loaded"))
noData:SetTextColor(1, 0.5, 0.5)
return
end
@@ -608,6 +678,13 @@ function MTH_SetupTrapOptions()
MTH_SetupButtonOptions("MetaHuntOptionsTrap", "zButtonTrap", "ZTrap", 4)
end
function MTH_SetupRangedOptions()
if not MTH_ZBUTTONS_READY then return end
local itemList = MTH_GetButtonItemList("zButtonRanged")
local maxButtons = itemList and table.getn(itemList) or 1
MTH_SetupButtonOptions("MetaHuntOptionsRanged", "zButtonRanged", "ZRanged", maxButtons)
end
function MTH_SetupAmmoOptions()
if not MTH_ZBUTTONS_READY then return end
MTH_EnsureAmmoOptionsWatcher()
@@ -674,7 +751,7 @@ function MTH_SetupSmartAmmoOptions()
end)
end
local smartToggle = MTH_CreateCheckbox(container, "MetaHuntOptionsSmartAmmoEnabled", "Enable Smart Ammo Swaps", -94)
local smartToggle = MTH_CreateCheckbox(container, "MetaHuntOptionsSmartAmmoEnabled", "Enable Junk Shot Swaps", -94)
if smartToggle then
local enabled = type(MTHSmartAmmo_GetSmartEnabled) == "function" and MTHSmartAmmo_GetSmartEnabled() and true or false
smartToggle:SetChecked(enabled)
@@ -710,6 +787,119 @@ function MTH_SetupSmartAmmoOptions()
end
end
function MTH_SetupMessagesOptions()
if not MTH_ZBUTTONS_READY then return end
local container = MTH_GetFrame("MetaHuntOptionsMessages")
if not container then return end
MTH_ClearContainer(container)
local section = CreateFrame("Frame", "MetaHuntMessagesSection", container, "OptionFrameBoxTemplate")
if not section then return end
section:SetPoint("TOPLEFT", container, "TOPLEFT", 8, -8)
section:SetPoint("TOPRIGHT", container, "TOPRIGHT", -8, -8)
section:SetHeight(268)
local titleFrame = getglobal("MetaHuntMessagesSectionTitle")
if titleFrame then
titleFrame:SetText("Messages")
end
local help = section:CreateFontString("MetaHuntMessagesHelp", "ARTWORK")
help:SetFont("Fonts\\FRIZQT__.TTF", 10)
help:SetJustifyH("LEFT")
help:SetPoint("TOPLEFT", section, "TOPLEFT", 14, -12)
help:SetPoint("TOPRIGHT", section, "TOPRIGHT", -14, -12)
help:SetText("Enable or Disable Metahunt chat messages")
local msgSettings = (MTH and MTH.GetMessageSettings and MTH:GetMessageSettings()) or {}
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
if MTH and MTH.SetMessageEnabled then
MTH:SetMessageEnabled("initModulesLoaded", self:GetChecked() and true or false)
end
end)
end
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
if MTH and MTH.SetMessageEnabled then
MTH:SetMessageEnabled("initSarcasticWelcome", self:GetChecked() and true or false)
end
end)
end
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
if MTH and MTH.SetMessageEnabled then
MTH:SetMessageEnabled("petHungry", self:GetChecked() and true or false)
end
end)
end
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
if MTH and MTH.SetMessageEnabled then
MTH:SetMessageEnabled("beastTrainingScan", self:GetChecked() and true or false)
end
end)
end
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
if MTH and MTH.SetMessageEnabled then
MTH:SetMessageEnabled("spellbookScan", self:GetChecked() and true or false)
end
end)
end
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
if MTH and MTH.SetMessageEnabled then
MTH:SetMessageEnabled("petRanAway", self:GetChecked() and true or false)
end
end)
end
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
if MTH and MTH.SetMessageEnabled then
MTH:SetMessageEnabled("mapMarkers", self:GetChecked() and true or false)
end
end)
end
end
function MTH_SetupGeneralOptions()
if not MTH_ZBUTTONS_READY then return end
local parentFrame = MTH_GetFrame("MetaHuntOptionsGeneral")
@@ -806,7 +996,7 @@ function MTH_SetupGeneralOptions()
help:Show()
end
local smartAmmoSection = ensureSection("MetaHuntGeneralSmartAmmoBox", "Smart Ammo", topY, 186, "left")
local smartAmmoSection = ensureSection("MetaHuntGeneralSmartAmmoBox", "Smart Ammo", topY, 254, "left")
if smartAmmoSection then
local smartModuleEnabled = MTH and MTH.IsModuleEnabled and MTH:IsModuleEnabled("smartammo", true)
local smartModuleToggle = ensureCheckbox(smartAmmoSection, "MetaHuntGeneralSmartAmmoModuleToggle", "Enable module", -10, smartModuleEnabled)
@@ -825,10 +1015,16 @@ function MTH_SetupGeneralOptions()
end)
end
ensureHelpText(smartAmmoSection, "MetaHuntGeneralSmartAmmoModuleHelp", "Automatically swaps arrows/bullets based on equipped ranged weapon.", -34)
local moduleHelp = getglobal("MetaHuntGeneralSmartAmmoModuleHelp")
if moduleHelp then
moduleHelp:Hide()
end
local smartEnabled = type(MTHSmartAmmo_GetSmartEnabled) == "function" and MTHSmartAmmo_GetSmartEnabled() and true or false
local smartToggle = ensureCheckbox(smartAmmoSection, "MetaHuntGeneralSmartAmmoEnabledToggle", "Enable Smart Ammo Swaps", -68, smartEnabled)
local smartEnabled = true
if type(MTHSmartAmmo_GetSmartEnabled) == "function" then
smartEnabled = MTHSmartAmmo_GetSmartEnabled() and true or false
end
local smartToggle = ensureCheckbox(smartAmmoSection, "MetaHuntGeneralSmartAmmoEnabledToggle", "Enable Junk Shot Swaps", -58, smartEnabled)
if smartToggle then
if not smartModuleEnabled then
smartToggle:Disable()
@@ -839,7 +1035,7 @@ function MTH_SetupGeneralOptions()
end
end)
end
ensureHelpText(smartAmmoSection, "MetaHuntGeneralSmartAmmoEnabledHelp", "Auto-equips arrows or bullets matching your ranged weapon.", -96)
ensureHelpText(smartAmmoSection, "MetaHuntGeneralSmartAmmoEnabledHelp", "Swaps to low-tier ammo for shots that don't scale on weapon damage, then swaps back to your previous ammo.", -86)
local reloadEnabled = type(MTHSmartAmmo_GetReloadEnabled) == "function" and MTHSmartAmmo_GetReloadEnabled() and true or false
local reloadToggle = ensureCheckbox(smartAmmoSection, "MetaHuntGeneralSmartAmmoReloadToggle", "Enable Auto-Fallback", -126, reloadEnabled)
@@ -854,9 +1050,23 @@ function MTH_SetupGeneralOptions()
end)
end
ensureHelpText(smartAmmoSection, "MetaHuntGeneralSmartAmmoReloadHelp", "Falls back to any available ammo when preferred ammo is missing.", -154)
local weaponSwapEnabled = type(MTHSmartAmmo_GetWeaponSwapEnabled) == "function" and MTHSmartAmmo_GetWeaponSwapEnabled() and true or false
local weaponSwapToggle = ensureCheckbox(smartAmmoSection, "MetaHuntGeneralSmartAmmoWeaponSwapToggle", "Enable Weapon-Swap Auto Ammo", -180, weaponSwapEnabled)
if weaponSwapToggle then
if not smartModuleEnabled then
weaponSwapToggle:Disable()
end
weaponSwapToggle:SetScript("OnClick", function()
if type(MTHSmartAmmo_SetWeaponSwapEnabled) == "function" then
MTHSmartAmmo_SetWeaponSwapEnabled(this:GetChecked() and 1 or nil)
end
end)
end
ensureHelpText(smartAmmoSection, "MetaHuntGeneralSmartAmmoWeaponSwapHelp", "When you swap between gun and bow/crossbow, instantly equips the best matching ammo from your bags.", -208)
end
local stripSection = ensureSection("MetaHuntGeneralAutoStripBox", "Auto-Strip", topY - 202, 122, "left")
local stripSection = ensureSection("MetaHuntGeneralAutoStripBox", "Auto-Strip", topY - 270, 122, "left")
if stripSection then
local autoStripToggle = ensureCheckbox(stripSection, "MetaHuntGeneralAutoStripToggle", "Enable Auto-Strip on Combat Exit", -10, stripSaved["autostrip"] and true or false)
if autoStripToggle then
@@ -879,7 +1089,7 @@ function MTH_SetupGeneralOptions()
ensureHelpText(stripSection, "MetaHuntGeneralAutoStripHelp", "Auto-strip unequips items when combat ends. Requires at least one empty bag slot.", -64)
end
local antiSection = ensureSection("MetaHuntGeneralAntiDazeBox", "Anti-Daze", topY - 338, 96, "left")
local antiSection = ensureSection("MetaHuntGeneralAntiDazeBox", "Anti-Daze", topY - 406, 96, "left")
if antiSection then
local antiDazeEnabled = (AntiDaze_GetEnabled and AntiDaze_GetEnabled()) or false
local antiToggle = ensureCheckbox(antiSection, "MetaHuntGeneralAntiDazeToggle", "Enable Anti-Daze", -10, antiDazeEnabled)
+2
View File
@@ -66,10 +66,12 @@
<!-- Content Areas -->
<Frame name="$parentGeneral" 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"/>
<Frame name="$parentAspect" hidden="true" enableMouse="true"/>
<Frame name="$parentTrap" hidden="true" enableMouse="true"/>
<Frame name="$parentRanged" hidden="true" enableMouse="true"/>
<Frame name="$parentAmmo" hidden="true" enableMouse="true"/>
<Frame name="$parentMounts" hidden="true" enableMouse="true"/>
<Frame name="$parentCompanions" hidden="true" enableMouse="true"/>
+179
View File
@@ -0,0 +1,179 @@
MTH = MTH or {}
MTH.VersionCheck = MTH.VersionCheck or {}
local VC = MTH.VersionCheck
VC.abbrev = "MTH"
VC.channelName = "LFT"
VC.nextPublishAt = nil
VC.joinAt = nil
VC.notified = false
VC._invalidVersionWarned = false
local function VC_GetTimeNow()
if type(time) == "function" then
return time()
end
if type(GetTime) == "function" then
return math.floor(GetTime())
end
return 0
end
function VC:GetLocalVersionString()
if MTH and MTH.version and tostring(MTH.version) ~= "" then
return tostring(MTH.version)
end
local getMeta = _G and _G["GetAddOnMetadata"] or nil
if type(getMeta) == "function" then
local v = getMeta("MetaHunt", "Version")
if v and v ~= "" then
return tostring(v)
end
end
return "0.0.0"
end
function VC:GetLocalVersionNumber()
local versionText = self:GetLocalVersionString()
local _, _, major, minor, patch = string.find(tostring(versionText or ""), "^(%d+)%.(%d+)%.?(%d*)$")
if not major then
return nil
end
major = tonumber(major) or 0
minor = tonumber(minor) or 0
patch = tonumber(patch) or 0
return (major * 1000000) + (minor * 1000) + patch
end
local function VC_GetChannelIdByName(channelName)
if type(GetChannelName) ~= "function" then
return nil
end
local id = nil
local name = nil
id, name = GetChannelName(channelName)
id = tonumber(id)
if id and id > 0 then
return id
end
return nil
end
local function VC_IsOurChannel(name)
return type(name) == "string" and string.lower(name) == string.lower(VC.channelName)
end
function VC:ResetPublishDelay()
self.nextPublishAt = VC_GetTimeNow() + math.random(10, 20)
end
function VC:ShouldPublish()
return self.nextPublishAt and VC_GetTimeNow() >= self.nextPublishAt
end
function VC:TryPublish()
if type(SendChatMessage) ~= "function" then
return false
end
local channelId = VC_GetChannelIdByName(self.channelName)
if not channelId then
if type(JoinChannelByName) == "function" then
JoinChannelByName(self.channelName, "", 0, false)
end
return false
end
local localVersionNumber = self:GetLocalVersionNumber()
if not localVersionNumber or localVersionNumber <= 0 then
if not self._invalidVersionWarned and MTH and type(MTH.Print) == "function" then
self._invalidVersionWarned = true
MTH:Print("Version check disabled: invalid local version format.")
end
return false
end
local payload = self.abbrev .. ":" .. tostring(localVersionNumber) .. ":v"
SendChatMessage(payload, "CHANNEL", nil, tostring(channelId))
return true
end
function VC:HandleRemoteMessage(message, author, channelLabel)
if self.notified then
return
end
if not message or message == "" then
return
end
if author and UnitName and author == UnitName("player") then
return
end
local channelName = string.gsub(tostring(channelLabel or ""), "^%d+%.%s*", "")
if not VC_IsOurChannel(channelName) then
return
end
if string.find(message, self.abbrev .. ":", 1, true) ~= 1 then
return
end
local _, _, addonTag, remoteVersion = string.find(message, "^([^:]+):([^:]+):")
if addonTag ~= self.abbrev then
return
end
local remoteNumber = tonumber(remoteVersion)
if not remoteNumber or remoteNumber <= 0 then
return
end
local localVersionNumber = self:GetLocalVersionNumber()
if not localVersionNumber or localVersionNumber <= 0 then
return
end
if remoteNumber <= localVersionNumber then
return
end
self.notified = true
self.nextPublishAt = nil
if MTH and type(MTH.Print) == "function" then
MTH:Print("A new version is available !")
end
if VC.frame then
VC.frame:UnregisterEvent("CHAT_MSG_CHANNEL")
VC.frame:SetScript("OnUpdate", nil)
end
end
if not VC.frame then
local frame = CreateFrame("Frame", "MTHVersionCheckFrame", UIParent)
if frame then
VC.frame = frame
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
frame:RegisterEvent("CHAT_MSG_CHANNEL")
frame:SetScript("OnEvent", function()
if event == "PLAYER_ENTERING_WORLD" then
VC.joinAt = GetTime() + 6
VC:ResetPublishDelay()
elseif event == "CHAT_MSG_CHANNEL" then
VC:HandleRemoteMessage(arg1, arg2, arg4)
end
end)
frame:SetScript("OnUpdate", function()
if (this._mthTick or 1) > GetTime() then
return
end
this._mthTick = GetTime() + 1
if VC.joinAt and GetTime() >= VC.joinAt then
if not VC_GetChannelIdByName(VC.channelName) and type(JoinChannelByName) == "function" then
JoinChannelByName(VC.channelName, "", 0, false)
end
VC.joinAt = nil
end
if VC:ShouldPublish() then
if VC:TryPublish() then
VC.nextPublishAt = nil
this:SetScript("OnUpdate", nil)
end
end
end)
end
end