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