Refactor and improve encounter data handling and formatting
All checks were successful
forgejo/Czech Quests/addon/pipeline/head This commit looks good
All checks were successful
forgejo/Czech Quests/addon/pipeline/head This commit looks good
This commit is contained in:
parent
a32b698ebf
commit
f37808207e
8 changed files with 226 additions and 83 deletions
|
@ -48,7 +48,7 @@ local function HideOtherContent()
|
|||
addon.EncounterFrame:ClearHeaders()
|
||||
end
|
||||
|
||||
local function SetAbilityIcon(header, tags)
|
||||
local function SetAbilityTagIcon(header, tags)
|
||||
local result = {}
|
||||
for part in string.gmatch(tags, "([^,]+)") do
|
||||
table.insert(result, part)
|
||||
|
@ -71,6 +71,36 @@ local function SetAbilityIcon(header, tags)
|
|||
end
|
||||
end
|
||||
|
||||
local function SetAbilityIcon(header, name)
|
||||
if ORIGINALS[name] == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local abilityIcon = ORIGINALS[name].abilityIcon or nil
|
||||
if abilityIcon then
|
||||
header.button.abilityIcon:SetTexture(abilityIcon)
|
||||
header.button.abilityIcon:Show()
|
||||
header.button.title:SetPoint("TOPLEFT", header, "TOPLEFT", 45, -7);
|
||||
end
|
||||
end
|
||||
|
||||
local function SetEncounterPortraitIcon(header, name)
|
||||
if ORIGINALS[name] == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local creatureDisplayID = ORIGINALS[name].creatureDisplayID or 0
|
||||
local uiModelSceneID = ORIGINALS[name].uiModelSceneID or 0
|
||||
|
||||
if creatureDisplayID ~= 0 and uiModelSceneID ~= 0 then
|
||||
header.button.portrait.displayInfo = creatureDisplayID;
|
||||
header.button.portrait.uiModelSceneID = uiModelSceneID;
|
||||
SetPortraitTextureFromCreatureDisplayID(header.button.portrait.icon, creatureDisplayID);
|
||||
header.button.portrait:Show()
|
||||
header.button.title:SetPoint("TOPLEFT", header, "TOPLEFT", 50, -7);
|
||||
end
|
||||
end
|
||||
|
||||
local function RenderBossAbilities(data, parent, layer)
|
||||
local frame = addon.EncounterFrame
|
||||
|
||||
|
@ -92,12 +122,17 @@ local function RenderBossAbilities(data, parent, layer)
|
|||
header:SetWidth(frame:GetWidth() - (layer * 20))
|
||||
header.button.title:SetText(name)
|
||||
|
||||
SetAbilityIcon(header, name)
|
||||
SetEncounterPortraitIcon(header, name)
|
||||
|
||||
if tag and tag ~= '???' then
|
||||
SetAbilityIcon(header, tag)
|
||||
SetAbilityTagIcon(header, tag)
|
||||
end
|
||||
|
||||
header.description:SetWidth(header:GetWidth() - 20)
|
||||
header.description:SetText(addon.API.SetAbilityDescription(description, ORIGINALS[name]))
|
||||
header.description:SetText(
|
||||
addon.API.FormatEncounterDescription(description, ORIGINALS[name].description)
|
||||
)
|
||||
if description == "" then header.empty = true end
|
||||
|
||||
table.insert(parent.children, header)
|
||||
|
@ -112,41 +147,42 @@ local function RenderBossAbilities(data, parent, layer)
|
|||
end
|
||||
end
|
||||
|
||||
local function RenderBossEncounter(bossKey, bossName)
|
||||
local function RenderBossEncounter(bossKey, bossName, encounterName)
|
||||
local frame = addon.EncounterFrame
|
||||
HideOtherContent()
|
||||
|
||||
local bossData = CzechQuestsAddon:GetData('encounter', bossKey)
|
||||
|
||||
frame.summary:SetText(
|
||||
addon.API.SetAbilityDescription(bossData.overview, ORIGINALS['Overview'])
|
||||
addon.API.FormatEncounterDescription(bossData.overview, ORIGINALS['Overview'].description)
|
||||
)
|
||||
|
||||
local tankHeader = frame:CreateHeader()
|
||||
tankHeader.button.title:SetText("Tank")
|
||||
local tankDescription = addon.API.SetSummaryDescription(bossData.tank, ORIGINALS['Tanks'])
|
||||
local tankDescription = addon.API.FormatEncounterDescription(bossData.tank, ORIGINALS['Tanks'].description)
|
||||
tankHeader.description:SetText(tankDescription)
|
||||
table.insert(frame.headers, tankHeader)
|
||||
SetAbilityIcon(tankHeader, 'tank')
|
||||
SetAbilityTagIcon(tankHeader, 'tank')
|
||||
|
||||
local healHeader = frame:CreateHeader()
|
||||
healHeader.button.title:SetText("Healer")
|
||||
local healerDescription = addon.API.SetSummaryDescription(bossData.healer, ORIGINALS['Healers'])
|
||||
local healerDescription = addon.API.FormatEncounterDescription(bossData.healer, ORIGINALS['Healers'].description)
|
||||
healHeader.description:SetText(healerDescription)
|
||||
table.insert(frame.headers, healHeader)
|
||||
SetAbilityIcon(healHeader, 'healer')
|
||||
SetAbilityTagIcon(healHeader, 'healer')
|
||||
|
||||
local dpsHeader = frame:CreateHeader()
|
||||
dpsHeader.button.title:SetText("Damage Dealer")
|
||||
local dpsDescription = addon.API.SetSummaryDescription(bossData.dps, ORIGINALS['Damage Dealers'])
|
||||
local dpsDescription = addon.API.FormatEncounterDescription(bossData.dps, ORIGINALS['Damage Dealers'].description)
|
||||
dpsHeader.description:SetText(dpsDescription)
|
||||
table.insert(frame.headers, dpsHeader)
|
||||
SetAbilityIcon(dpsHeader, 'dps')
|
||||
SetAbilityTagIcon(dpsHeader, 'dps')
|
||||
|
||||
local bossHeader = frame:CreateHeader()
|
||||
bossHeader.button.title:SetText(bossName)
|
||||
bossHeader.button.title:SetText(encounterName)
|
||||
bossHeader.empty = true
|
||||
table.insert(frame.headers, bossHeader)
|
||||
SetEncounterPortraitIcon(bossHeader, bossName)
|
||||
RenderBossAbilities(bossData.abilities, bossHeader, 1)
|
||||
|
||||
frame:GetParent():Show()
|
||||
|
@ -155,16 +191,31 @@ end
|
|||
|
||||
local function StoreBossAbilities()
|
||||
ORIGINALS = {}
|
||||
|
||||
local stack, _, _, _, curSectionID = {}, EJ_GetEncounterInfo(ENCOUNTER_ID)
|
||||
|
||||
local _, bossName, description, displayInfo, iconImage, uiModelSceneID = EJ_GetCreatureInfo(1, ENCOUNTER_ID)
|
||||
ORIGINALS[bossName] = {}
|
||||
ORIGINALS[bossName].description = description
|
||||
ORIGINALS[bossName].creatureDisplayID = displayInfo
|
||||
ORIGINALS[bossName].uiModelSceneID = uiModelSceneID
|
||||
ORIGINALS[bossName].abilityIcon = iconImage
|
||||
|
||||
repeat
|
||||
local info = C_EncounterJournal.GetSectionInfo(curSectionID)
|
||||
if not info.filteredByDifficulty then
|
||||
ORIGINALS[info.title] = info.description
|
||||
ORIGINALS[info.title] = {}
|
||||
ORIGINALS[info.title].description = info.description
|
||||
ORIGINALS[info.title].creatureDisplayID = info.creatureDisplayID
|
||||
ORIGINALS[info.title].uiModelSceneID = info.uiModelSceneID
|
||||
ORIGINALS[info.title].abilityIcon = info.abilityIcon
|
||||
end
|
||||
table.insert(stack, info.siblingSectionID)
|
||||
|
||||
if not info.filteredByDifficulty then
|
||||
table.insert(stack, info.firstChildSectionID)
|
||||
end
|
||||
|
||||
curSectionID = table.remove(stack)
|
||||
until not curSectionID
|
||||
end
|
||||
|
@ -173,6 +224,7 @@ local function DetectBossToRender()
|
|||
local frame = addon.EncounterFrame
|
||||
|
||||
local encounterName = EJ_GetEncounterInfo(ENCOUNTER_ID)
|
||||
local _, bossName = EJ_GetCreatureInfo(1, ENCOUNTER_ID)
|
||||
|
||||
local difficulty = 'lfg_raid' -- 17
|
||||
if DIFFICULTY == 14 then
|
||||
|
@ -203,11 +255,11 @@ local function DetectBossToRender()
|
|||
|
||||
if bossKey then
|
||||
StoreBossAbilities()
|
||||
RenderBossEncounter(bossKey, encounterName)
|
||||
RenderBossEncounter(bossKey, bossName, encounterName)
|
||||
end
|
||||
|
||||
if bossKey == nil then
|
||||
frame.summary:SetText("V souboji " .. encounterName .. " není tato obtížnost přeložena.")
|
||||
frame.summary:SetText("Pro souboj " .. encounterName .. " není vytvořen překlad.")
|
||||
frame:GetParent():Show()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
local _, addon = ...
|
||||
|
||||
-- Parse ability information from data
|
||||
local function ParseAbilities(input, delimiter)
|
||||
local result = {}
|
||||
local pattern = "([^" .. delimiter .. "]*)"
|
||||
|
@ -19,37 +20,58 @@ local function ParseAbilities(input, delimiter)
|
|||
end
|
||||
addon.API.ParseAbilities = ParseAbilities
|
||||
|
||||
local function SetAbilityDescription(text, original)
|
||||
local withNumbers = addon.API.FillNumbers(text, original)
|
||||
return addon.API.ColorSpellNames(withNumbers)
|
||||
end
|
||||
addon.API.SetAbilityDescription = SetAbilityDescription
|
||||
-- Replace special marks with actual numbers from original description
|
||||
local function FillNumberPositionPlaceholder(text, sourceText)
|
||||
local numbers = {}
|
||||
local source = addon.API.ClearStringFormatMarks(sourceText)
|
||||
|
||||
local function SetSummaryDescription(text, original)
|
||||
local withNumbers = addon.API.FillNumbers(text, original)
|
||||
|
||||
local lines = {}
|
||||
for part in string.gmatch(withNumbers, "([^\n]+)") do
|
||||
table.insert(lines, part)
|
||||
for num in source:gmatch("(%d[%d,%.]*)") do
|
||||
table.insert(numbers, num)
|
||||
end
|
||||
|
||||
local description = ""
|
||||
for i, line in pairs(lines) do
|
||||
description = description
|
||||
.. "- "
|
||||
.. addon.API.ColorSpellNames(line)
|
||||
.. (i == #lines and "" or "\n\n")
|
||||
end
|
||||
local replacedText = text:gsub("<#(%d+)%?>", function(position)
|
||||
position = tonumber(position)
|
||||
local n = numbers[position]
|
||||
|
||||
return description
|
||||
if n then
|
||||
if source:match("%s+" .. n .. "%s+million") then
|
||||
return n .. "<mil>"
|
||||
elseif source:match("%s+" .. n .. "%s+millions") then
|
||||
return n .. "<mil>"
|
||||
else
|
||||
return n
|
||||
end
|
||||
end
|
||||
|
||||
return "?"
|
||||
end)
|
||||
|
||||
return replacedText
|
||||
end
|
||||
addon.API.SetSummaryDescription = SetSummaryDescription
|
||||
|
||||
-- Prepare description for Encounter ability
|
||||
local function FormatEncounterDescription(text, original)
|
||||
local formated = FillNumberPositionPlaceholder(text, original)
|
||||
formated = addon.API.ParseParagraphs(original, formated)
|
||||
formated = addon.API.ColorSpellNames(formated)
|
||||
|
||||
-- fix [mil]
|
||||
formated = string.gsub(formated, "<mil>", "mil.")
|
||||
|
||||
-- fix 4 s
|
||||
formated = string.gsub(formated, "(%d+) s([%s%.])", "%1s%2")
|
||||
|
||||
return formated
|
||||
end
|
||||
addon.API.FormatEncounterDescription = FormatEncounterDescription
|
||||
|
||||
-- Return specific Encounter Ability data
|
||||
local function GetEncounterAbility(abilityKey)
|
||||
return addon.data.encounter[abilityKey].m or nil
|
||||
end
|
||||
addon.API.GetEncounterAbility = GetEncounterAbility
|
||||
|
||||
-- Get Encounter object
|
||||
local function GetEncounter(bossKey)
|
||||
return {
|
||||
abilities = addon.data.encounter[bossKey] or nil,
|
||||
|
|
|
@ -115,7 +115,6 @@ function EncounterFrame:CreateHeader()
|
|||
HeaderFrame.button.icon3:Hide()
|
||||
HeaderFrame.button.icon4:Hide()
|
||||
|
||||
HeaderFrame.button.expandedIcon:SetPoint("TOPLEFT", HeaderFrame.button, "TOPLEFT", 10, -6);
|
||||
HeaderFrame.button.expandedIcon:SetText("+")
|
||||
HeaderFrame.expanded = false
|
||||
HeaderFrame.empty = false
|
||||
|
@ -141,7 +140,6 @@ function EncounterFrame:CreateHeader()
|
|||
function HeaderFrame:Open()
|
||||
local header = self
|
||||
header.button.expandedIcon:SetText("-")
|
||||
header.button.expandedIcon:SetPoint("TOPLEFT", HeaderFrame.button, "TOPLEFT", 10, -5);
|
||||
if (header.empty == false) then
|
||||
header.description:Show()
|
||||
header.descriptionBG:Show()
|
||||
|
@ -152,7 +150,6 @@ function EncounterFrame:CreateHeader()
|
|||
function HeaderFrame:Close()
|
||||
local header = self
|
||||
header.button.expandedIcon:SetText("+")
|
||||
header.button.expandedIcon:SetPoint("TOPLEFT", HeaderFrame.button, "TOPLEFT", 10, -6);
|
||||
header.description:Hide()
|
||||
header.descriptionBG:Hide()
|
||||
header.descriptionBGBottom:Hide()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
local _, addon = ...
|
||||
|
||||
-- Split original text by break-lines
|
||||
local function SplitParagraphs(text)
|
||||
local paragraphs = {}
|
||||
for paragraph in string.gmatch(text, "([^\n]+)") do
|
||||
|
@ -8,6 +9,7 @@ local function SplitParagraphs(text)
|
|||
return paragraphs
|
||||
end
|
||||
|
||||
-- Split text into sentences
|
||||
local function SplitSentences(paragraph)
|
||||
local sentences = {}
|
||||
for sentence in string.gmatch(paragraph, "([^%.%?!]+[%.%?!]?)[%s]*") do
|
||||
|
@ -19,10 +21,17 @@ local function SplitSentences(paragraph)
|
|||
return sentences
|
||||
end
|
||||
|
||||
-- Put break-lines
|
||||
local function ReplaceMultipleBreakLines(text)
|
||||
return text:gsub("\r?\n+", "\n\n")
|
||||
end
|
||||
|
||||
-- Because decimal numbers contain dot, remove space between those numbers
|
||||
local function FixDecimalNumbers(text)
|
||||
return text:gsub("(%d+)%.%s+(%d+)", "%1.%2")
|
||||
end
|
||||
|
||||
-- Fix translated text break-line based on original
|
||||
local function ParseParagraphs(original_text, translation_text)
|
||||
if original_text == "" or original_text == nil then
|
||||
return translation_text
|
||||
|
@ -58,8 +67,9 @@ local function ParseParagraphs(original_text, translation_text)
|
|||
table.insert(translation_paragraphs, table.concat(collected, " "))
|
||||
end
|
||||
|
||||
return ReplaceMultipleBreakLines(
|
||||
table.concat(translation_paragraphs, "\n")
|
||||
)
|
||||
local multilines = ReplaceMultipleBreakLines(table.concat(translation_paragraphs, "\n"))
|
||||
local fixedDecimalNumbers = FixDecimalNumbers(multilines)
|
||||
|
||||
return fixedDecimalNumbers
|
||||
end
|
||||
addon.API.ParseParagraphs = ParseParagraphs
|
|
@ -1,39 +1,13 @@
|
|||
local _, addon = ...
|
||||
|
||||
local function ClearNumberStringMarks(text)
|
||||
local function ClearStringFormatMarks(text)
|
||||
-- Remove colors (|cffffff...)
|
||||
text = text:gsub("|c%x%x%x%x%x%x%x%x", "")
|
||||
-- Remove H marks
|
||||
text = text:gsub("|H.-|h", "")
|
||||
return text
|
||||
end
|
||||
|
||||
local function FillNumbers(text, sourceText)
|
||||
local numbers = {}
|
||||
local currentIndex = 1
|
||||
|
||||
local source = ClearNumberStringMarks(sourceText)
|
||||
|
||||
for num in source:gmatch("(%d[%d,%.]*)") do
|
||||
table.insert(numbers, num)
|
||||
end
|
||||
|
||||
local replacedText = text:gsub("#%?", function()
|
||||
local n = numbers[currentIndex]
|
||||
currentIndex = currentIndex + 1
|
||||
|
||||
if n and source:match("%s+" .. n .. "%s+million") then
|
||||
return n .. " mil."
|
||||
elseif n and source:match("%s+" .. n .. "%s+million") then
|
||||
return n .. " mil."
|
||||
end
|
||||
|
||||
return n or "?"
|
||||
end)
|
||||
|
||||
return replacedText
|
||||
end
|
||||
addon.API.FillNumbers = FillNumbers
|
||||
addon.API.ClearStringFormatMarks = ClearStringFormatMarks
|
||||
|
||||
local function ColorSpellNames(text, color)
|
||||
return text:gsub("%[(.-)%]", function(match)
|
||||
|
|
|
@ -6,6 +6,23 @@ local function BuildIndex(text)
|
|||
return normalized
|
||||
end
|
||||
|
||||
local function FillNumbers(text, sourceText)
|
||||
local numbers = {}
|
||||
local currentIndex = 1
|
||||
|
||||
for num in sourceText:gmatch("%d+%.?%d*") do
|
||||
table.insert(numbers, num)
|
||||
end
|
||||
|
||||
local replacedText = text:gsub("#%?", function()
|
||||
local n = numbers[currentIndex]
|
||||
currentIndex = currentIndex + 1
|
||||
return n or "?"
|
||||
end)
|
||||
|
||||
return replacedText
|
||||
end
|
||||
|
||||
local function FillPlaceholders(text)
|
||||
if text == nil then
|
||||
return text
|
||||
|
@ -24,9 +41,7 @@ local function GetSpeech(message)
|
|||
local speech = addon.data.speech[index];
|
||||
local text = speech and speech.m or nil
|
||||
if text then
|
||||
return FillPlaceholders(
|
||||
addon.API.FillNumbers(text, message)
|
||||
)
|
||||
return FillPlaceholders(FillNumbers(text, message))
|
||||
else
|
||||
return nil
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue