Harden skip gossip matching and lifecycle

This commit is contained in:
Dusk-92
2026-08-26 15:36:14 +02:00
parent 4e2e344df9
commit 8af2af4ede
+131 -121
View File
@@ -1,128 +1,138 @@
local L, T = ShaguTweaks.L, ShaguTweaks.T local T = ShaguTweaks.T
local API = ShaguTweaks.API
local module = ShaguTweaks:register({ local module = ShaguTweaks:register({
title = T["Skip Gossip Text"], title = T["Skip Gossip Text"],
description = T["Skip gossip text when interacting with NPCs unless holding shift."], description = T["Skip gossip text when interacting with NPCs unless holding shift."],
expansions = { ["vanilla"] = true, ["tbc"] = nil }, expansions = { ["vanilla"] = true, ["tbc"] = nil },
category = nil, category = nil,
enabled = nil, enabled = nil,
}) })
module.enable = function(self) local professions = {
local actions = CreateFrame("Frame", nil, UIParent) battlemaster = true,
taxi = true,
trainer = true,
vendor = true,
banker = true,
}
local professions = { local ignore = {
"battlemaster", ["Goblin Brainwashing Device"] = true,
"taxi", }
"trainer",
"vendor",
"banker",
}
local phrases = { -- Strip spacing and punctuation while preserving non-ASCII letters. Using
-- Bank -- %W here can erase Cyrillic text entirely on the 1.12 Lua client, causing
"I would like to check my deposit box", -- unrelated ruRU gossip options to compare as the same empty string.
local function NormalizePhrase(text)
-- Vanilla if not text then return end
"Teleport me to the Molten Core", return string.gsub(text, "[%s%p]", "")
end
-- Turtle WoW
-- Alliance local phrases = {
"Please open a portal to Alah'Thalas", -- Bank
"Please open a portal to Stormwind", "I would like to check my deposit box",
-- Horde
"Open a portal to Amani'Alor", -- Vanilla
"Teleport me to the Molten Core",
-- ruRU
"Я хотел бы проверить свою ячейку.", -- Bank -- Turtle WoW
"*Прикоснуться к нестабильному кристаллу Провала.*", -- MC entrance -- Alliance
"\*Положить руку на сферу.\*", -- BWL entrance "Please open a portal to Alah'Thalas",
--"Thank you, Stable Master. Please take the animal.", -- AV quest locales_broadcast_text id6681 "Please open a portal to Stormwind",
"Благодарю тебя. Пожалуйста, возьми питомца.", -- AV quest locales_broadcast_text id6681 -- Horde
"С удовольствием. Уж очень они воняют!", -- AV quest "Open a portal to Amani'Alor",
"Конфета или Жизнь!",
} -- ruRU
"Я хотел бы проверить свою ячейку.", -- Bank
local ignore = { "*Прикоснуться к нестабильному кристаллу Провала.*", -- MC entrance
-- npcs named here will be ignored "\\*Положить руку на сферу.\\*", -- BWL entrance
"Goblin Brainwashing Device", --"Thank you, Stable Master. Please take the animal.", -- AV quest locales_broadcast_text id6681
} "Благодарю тебя. Пожалуйста, возьми питомца.", -- AV quest locales_broadcast_text id6681
"С удовольствием. Уж очень они воняют!", -- AV quest
function actions:Gossip() "Конфета или Жизнь!",
if actions.gossip then }
local name = GossipFrameNpcNameText:GetText()
local GossipOptions = {} local normalizedPhrases = {}
local title for i = 1, table.getn(phrases) do
local phrase = NormalizePhrase(phrases[i])
title,GossipOptions[1],_,GossipOptions[2],_,GossipOptions[3],_,GossipOptions[4],_,GossipOptions[5] = GetGossipOptions() if phrase and phrase ~= "" then
normalizedPhrases[phrase] = true
-- Ported from LazyPig: "title" here is actually the text of the end
-- FIRST gossip option. Keep an unmutated copy before the end
-- word-stripping below, so we can gate the talent trainer
-- confirmation on it. module.enable = function(self)
local rawTitle = title -- Reuse a single event frame so repeated enable() calls cannot stack gossip
-- handlers and select the same option more than once.
if name then if not self.actions then
for _, npc in pairs(ignore) do self.actions = CreateFrame("Frame", nil, UIParent)
if name == npc then end
return true
end local actions = self.actions
end
end function actions:Gossip()
if not actions.gossip then return end
-- Ported from LazyPig: if a "binder" (innkeeper hearthstone)
-- option is present and we are NOT currently at our bind local name = GossipFrameNpcNameText:GetText()
-- point, don't auto-skip anything in this menu at all. if name and ignore[name] then
for i = 1, 5 do return true
if not GossipOptions[i] then break end end
if GossipOptions[i] == "binder" then
local bind = GetBindLocation() local title, option1, _, option2, _, option3, _, option4, _, option5 = GetGossipOptions()
if not (bind == GetSubZoneText() or bind == GetZoneText() local rawTitle = title
or bind == GetRealZoneText() or bind == GetMinimapZoneText()) then
return -- Ported from LazyPig: if a "binder" (innkeeper hearthstone) option is
end -- present and we are NOT currently at our bind point, don't auto-skip
end -- anything in this menu at all.
end local bind
if option1 == "binder" or option2 == "binder" or option3 == "binder"
for i = 1, 5 do or option4 == "binder" or option5 == "binder" then
if not GossipOptions[i] then break end bind = GetBindLocation()
if not (bind == GetSubZoneText() or bind == GetZoneText()
if GossipOptions[i] == "gossip" then or bind == GetRealZoneText() or bind == GetMinimapZoneText()) then
title = string.gsub(title, "%W", "") return
end
for _, phrase in pairs(phrases) do end
phrase = string.gsub(phrase, "%W", "")
-- "title" is the text of the first gossip option. Keep this historical
if phrase == title then -- LazyPig behavior, but normalize it once instead of once per option and
SelectGossipOption(i) -- once per configured phrase.
break local normalizedTitle = NormalizePhrase(title)
end
end local function HandleOption(optionType, index)
elseif GossipOptions[i] == "trainer" and rawTitle == "Reset my talents." then if not optionType then return end
-- Ported from LazyPig: don't auto-confirm a talent
-- reset, always require a manual click. if optionType == "gossip" then
else if normalizedTitle and normalizedPhrases[normalizedTitle] then
for _, profession in pairs(professions) do SelectGossipOption(index)
if profession == GossipOptions[i] then return true
SelectGossipOption(i) end
break elseif optionType == "trainer" and rawTitle == "Reset my talents." then
end -- Never auto-confirm a talent reset; always require a manual click.
end return
end elseif professions[optionType] then
end SelectGossipOption(index)
end return true
end end
end
actions:RegisterEvent("GOSSIP_SHOW")
actions:RegisterEvent("GOSSIP_CLOSED") if HandleOption(option1, 1) then return end
actions:SetScript("OnEvent", function() if HandleOption(option2, 2) then return end
if (event == "GOSSIP_SHOW") then if HandleOption(option3, 3) then return end
actions.gossip = true if HandleOption(option4, 4) then return end
if not IsShiftKeyDown() then HandleOption(option5, 5)
actions:Gossip() end
end
elseif (event == "GOSSIP_CLOSED") then actions:RegisterEvent("GOSSIP_SHOW")
actions.gossip = nil actions:RegisterEvent("GOSSIP_CLOSED")
end actions:SetScript("OnEvent", function()
end) if event == "GOSSIP_SHOW" then
actions.gossip = true
if not API.IsShiftKeyDown() then
actions:Gossip()
end
elseif event == "GOSSIP_CLOSED" then
actions.gossip = nil
end
end)
end end