addon/Addon/Code/Speech.lua
Roman Jaroš 4087c853a1
All checks were successful
forgejo/Czech Quests/addon/pipeline/head This commit looks good
Refactor message removal logic and introduce unique queue IDs.
2025-05-04 10:58:10 +02:00

133 lines
No EOL
4 KiB
Lua
Executable file

local _, addon = ...
local messages = {}
local GAP = 2
local queueCounter = 0
local function ShowSpeech(Frame, offsetY)
Frame:ClearAllPoints()
Frame:SetPoint("BOTTOMLEFT", addon.SpeechFrame, "BOTTOMLEFT", 0, offsetY)
Frame:SetHeight(Frame.Message:GetStringHeight() + 10)
return Frame
end
local function ReflowMessages(requery)
local offsetY = 0
if #messages == 0 then
addon.SpeechFrame:Hide()
return
end
for i = #messages, 1, -1 do
local Frame = messages[i]
ShowSpeech(Frame, offsetY)
local height = Frame.Message:GetStringHeight()
if height == 0 and not requery then
Frame:Hide()
C_Timer.After(0.5, function()
ReflowMessages(true)
end)
return
end
offsetY = offsetY + Frame:GetHeight() + GAP
end
end
local function RemoveMessage(queueId)
for _, fs in ipairs(messages) do
if fs.queueId == queueId and not fs._removing then
fs._removing = true
if fs:IsShown() and (fs:GetAlpha() or 1) > 0.01 then
local animation = fs:CreateAnimationGroup()
local fadeOut = animation:CreateAnimation("Alpha")
fadeOut:SetFromAlpha(fs:GetAlpha() or 1)
fadeOut:SetToAlpha(0)
fadeOut:SetDuration(1)
animation:SetScript("OnFinished", function()
fs:Hide()
for idx, msg in ipairs(messages) do
if msg.queueId == fs.queueId then
table.remove(messages, idx)
break
end
end
C_Timer.After(0, function() ReflowMessages() end)
end)
animation:Play()
else
fs:Hide()
for idx, msg in ipairs(messages) do
if msg.queueId == fs.queueId then
table.remove(messages, idx)
break
end
end
C_Timer.After(0, function() ReflowMessages() end)
end
break
end
end
end
local function AddMessage(sender, message)
addon.SpeechFrame:Show()
local text = string.format("|cffffd200%s|r\n%s", sender, message)
local MessageFrame = addon.SpeechFrame:CreateMessage()
MessageFrame.Message:SetText(text)
queueCounter = queueCounter + 1
MessageFrame.queueId = queueCounter
table.insert(messages, MessageFrame)
C_Timer.After(0.1, function()
ReflowMessages()
end)
C_Timer.After(15, function()
RemoveMessage(MessageFrame.queueId)
end)
end
addon.API.AddSpeechMessage = AddMessage
local function ShowSpeechTranslation(sender, message)
local text = CzechQuestsAddon:GetData("speech", sender .. "_" .. message)
if text == nil and CzechQuestsAddon_Store.config.SPEECH_ORIGINAL_WHEN_MISSING then
text = message
end
if text ~= nil then
AddMessage(sender, text)
end
end
local function InitSpeeches()
local frame = addon.SpeechFrame
-- Register Speech events
frame:RegisterEvent("PLAYER_LOGIN")
frame:RegisterEvent("CHAT_MSG_MONSTER_SAY")
frame:RegisterEvent("CHAT_MSG_MONSTER_YELL")
frame:RegisterEvent("CHAT_MSG_MONSTER_EMOTE")
frame:RegisterEvent("CHAT_MSG_MONSTER_PARTY")
frame:RegisterEvent("CHAT_MSG_MONSTER_WHISPER")
frame:SetScript("OnEvent", function(self, event, message, sender)
if not CzechQuestsAddon_Store.config.SPEECH_ENABLED then
return
end
if event == "PLAYER_LOGIN" then
frame:Init()
end
if event == "CHAT_MSG_MONSTER_SAY"
or event == "CHAT_MSG_MONSTER_YELL"
or event == "CHAT_MSG_MONSTER_EMOTE"
or event == "CHAT_MSG_MONSTER_PARTY"
or event == "CHAT_MSG_MONSTER_WHISPER" then
ShowSpeechTranslation(sender, message)
end
end)
end
addon.API.InitSpeeches = InitSpeeches