New feature: Boss tactics
All checks were successful
forgejo/Czech Quests/addon/pipeline/head This commit looks good

This commit is contained in:
Roman Jaroš 2025-03-29 07:44:17 +01:00
parent 6c2381d65c
commit 9fe284c18e
11 changed files with 21493 additions and 271 deletions

View file

@ -116,6 +116,22 @@ local function InitSpeeches()
end
local function InitTactics()
local function Update(name, value)
CzechQuestsAddon_Store.config[name] = value
addon.TacticFrame:UpdateSettings()
end
local layout = Options.layout
layout:AddInitializer(CreateSettingsListSectionHeaderInitializer("Taktiky"))
CreateCheckbox("TACTIC_ENABLED", "Zapnout", Update)
CreateDropdown("TACTIC_TEXT_FONT_NAME", "Pismo *", addon.API.GetFontContainer, Update)
CreateSlider("TACTIC_TEXT_FONT_SIZE", "Velikost pisma *", 10, 30, 1, Update)
end
local function InitOthers()
local layout = Options.layout
layout:AddInitializer(CreateSettingsListSectionHeaderInitializer("Ostatni"))
@ -131,6 +147,7 @@ local function InitOptions()
InitQuests()
InitSpeeches()
InitTactics()
InitOthers()
Settings.RegisterAddOnCategory(category)

214
Addon/Code/Tactic.lua Executable file
View file

@ -0,0 +1,214 @@
local _, addon = ...
local TACTIC_TAB_ID = 9
local CURRENT_TAB_ID = 0
local PREVIOUS_TAB_ID = 0
local ENCOUNTER_ID = 0
local DIFFICULTY = 0
local function HideOtherContent()
local frames = { "overviewScroll", "LootContainer", 'detailsScroll', 'model', 'encounterTitle' }
for _, frame in ipairs(frames) do
EncounterJournal.encounter.info[frame]:Hide();
end
local tabs = { "overviewTab", "lootTab", "bossTab", "modelTab" }
for _, tab in ipairs(tabs) do
EncounterJournal.encounter.info[tab].selected:Hide();
EncounterJournal.encounter.info[tab].unselected:Show();
EncounterJournal.encounter.info[tab]:UnlockHighlight();
end
if EncounterJournal.encounter.info.creatureButtons then
for _, button in pairs(EncounterJournal.encounter.info.creatureButtons) do
button:Hide()
end
end
addon.TacticFrame:ClearHeaders()
end
local function RenderBossTactics(frame, bossName)
HideOtherContent()
local bossData = addon.data.tactic[bossName]
local difficulty = 'lfr' -- 17
if DIFFICULTY == 14 then
difficulty = 'normal'
elseif DIFFICULTY == 15 then
difficulty = 'heroic'
elseif DIFFICULTY == 16 then
difficulty = 'mythic'
elseif DIFFICULTY == 1 then
difficulty = 'normal'
elseif DIFFICULTY == 2 then
difficulty = 'heroic'
elseif DIFFICULTY == 23 then
difficulty = 'mythic'
end
local tactic = bossData and bossData[1][difficulty] or nil
if not tactic then
frame.summary:SetText("Boss " .. bossName .. " nemá pro tuto obtížnost přeloženou taktiku.")
frame:GetParent():Show()
return
end
local function CreateHeaderDescription(data)
local description = ""
for _, item in ipairs(data) do
description = description
.. item.name .. "\n"
.. "|cff003366" .. item.description .. "|r "
.. "|cff004400" .. item.howTo .. "|r "
.. "|cff8b0000" .. item.dangerous .. "|r"
.. "\n\n"
end
return description
end
frame.summary:SetText(tactic.summary)
local tankHeader = frame:CreateHeader()
tankHeader.button.title:SetText("Tank")
tankHeader.description:SetText(CreateHeaderDescription(tactic.tank))
local healHeader = frame:CreateHeader()
healHeader.button.title:SetText("Healer")
healHeader.description:SetText(CreateHeaderDescription(tactic.heal))
local dpsHeader = frame:CreateHeader()
dpsHeader.button.title:SetText("DPS")
dpsHeader.description:SetText(CreateHeaderDescription(tactic.dps))
frame:GetParent():Show()
frame:UpdateHeaderPositions()
end
local function CreateCreaturesDropdown()
local frame = addon.TacticFrame
local encounterName = EJ_GetEncounterInfo(ENCOUNTER_ID)
local options = {}
local selectedValue = nil
for i = 1, 10 do
local id, name = EJ_GetCreatureInfo(i);
if id then
if addon.data.tactic[name] then
table.insert(options, { name, name })
end
end
end
if #options > 0 then
selectedValue = options[1][2]
end
local function IsSelected(value)
return value == selectedValue
end
local function SetSelected(value)
if value then
RenderBossTactics(addon.TacticFrame, value)
end
selectedValue = value
end
MenuUtil.CreateRadioMenu(frame.dropdown, IsSelected, SetSelected, unpack(options))
if #options > 0 then
SetSelected(selectedValue)
end
if #options == 0 then
frame.summary:SetText("V souboji " .. encounterName .. " není boss, který má přeloženou taktikou.")
frame:GetParent():Show()
frame.dropdown:Hide()
end
end
local function HideTacticNpcs()
addon.TacticFrame:GetParent():Hide()
addon.TacticFrame.dropdown:Hide()
end
local function ShowTacticNpcs()
CURRENT_TAB_ID = TACTIC_TAB_ID
HideOtherContent()
local frame = addon.TacticFrame
frame.tab:SetHighlight(true);
frame.dropdown:Show()
EncounterJournal.encounter.info.rightShadow:Show()
EncounterJournal.encounter.info.difficulty:Show()
CreateCreaturesDropdown()
end
local function SetupCustomTab()
addon.TacticFrame.tab:SetScript("OnClick", function()
ShowTacticNpcs()
end)
hooksecurefunc("EncounterJournal_DisplayEncounter", function(encounterID)
ENCOUNTER_ID = encounterID
addon.TacticFrame.tab:SetActive(true);
if CURRENT_TAB_ID == TACTIC_TAB_ID then
ShowTacticNpcs()
end
end)
hooksecurefunc("EncounterJournal_DisplayInstance", function()
addon.TacticFrame.tab:SetActive(false);
end)
hooksecurefunc("EncounterJournal_SetTab", function(tabId)
if CURRENT_TAB_ID ~= tabId then
addon.TacticFrame.tab:SetHighlight(false);
end
PREVIOUS_TAB_ID = CURRENT_TAB_ID
CURRENT_TAB_ID = tabId
HideTacticNpcs()
end)
hooksecurefunc("EncounterJournalBossButton_OnClick", function(encounterID)
if PREVIOUS_TAB_ID == TACTIC_TAB_ID then
ShowTacticNpcs()
end
end)
hooksecurefunc("EncounterJournal_UpdateDifficulty", function(difficulty)
DIFFICULTY = difficulty
if PREVIOUS_TAB_ID == TACTIC_TAB_ID and ENCOUNTER_ID then
ShowTacticNpcs()
end
end)
end
local function InitTactics()
local frame = addon.TacticFrame
-- Register EncounterJournal events
frame:RegisterEvent("ADDON_LOADED")
frame:SetScript("OnEvent", function(self, event, addonName)
if not CzechQuestsAddon_Store.config.TACTIC_ENABLED then
return
end
if addonName == 'Blizzard_EncounterJournal' then
addon.TacticFrame:Init()
SetupCustomTab()
end
end)
end
addon.API.InitTactics = InitTactics

201
Addon/Code/TacticFrame.lua Executable file
View file

@ -0,0 +1,201 @@
local _, addon = ...
local TacticFrame = CreateFrame("Frame", nil)
TacticFrame:Hide()
addon.TacticFrame = TacticFrame
TacticFrame.headers = {}
local NEXT_HEADER_ID = 0
function TacticFrame:Init()
local frame = self
if not EncounterJournal or not EncounterJournal.encounter or not EncounterJournal.encounter.info then
return
end
local scrollFrame = CreateFrame("ScrollFrame", "$parentOverviewScrollFrame", EncounterJournal.encounter.info, "ScrollFrameTemplate")
scrollFrame:SetSize(330, 370)
scrollFrame:SetPoint("TOPLEFT", EncounterJournal.encounter.info.overviewScroll, "TOPLEFT", 0, -7)
scrollFrame.scrollBarX = -25
scrollFrame.scrollBarTopY = -6
scrollFrame.scrollBarBottomY = 6
frame:SetParent(scrollFrame)
frame:SetSize(scrollFrame:GetWidth() - 10, 1)
frame:Show()
scrollFrame:SetScrollChild(frame)
frame.summary = addon.API.CreateCzechFont(
frame,
CzechQuestsAddon_Store.config.TACTIC_TEXT_FONT_NAME,
CzechQuestsAddon_Store.config.TACTIC_TEXT_FONT_SIZE
)
frame.summary:SetTextColor(0.251, 0.145, 0.012)
frame.summary:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, 0)
frame.summary:SetWidth(scrollFrame:GetWidth() - 10)
local dropdown = CreateFrame("DropdownButton", nil, EncounterJournal.encounter.info, "WowStyle1DropdownTemplate")
dropdown:SetPoint("BOTTOMRIGHT", EncounterJournal.encounter.info.encounterTitle, "BOTTOMRIGHT", 2, -2)
dropdown:SetWidth(200)
dropdown:Hide()
frame.dropdown = dropdown
frame:UpdateSettings()
frame:InitTab()
end
function TacticFrame:UpdateSettings()
local frame = self
addon.API.UpdateCzechFont(
frame.summary,
CzechQuestsAddon_Store.config.TACTIC_TEXT_FONT_NAME,
CzechQuestsAddon_Store.config.TACTIC_TEXT_FONT_SIZE
)
for _, header in ipairs(self.headers) do
addon.API.UpdateCzechFont(
header.description,
CzechQuestsAddon_Store.config.TACTIC_TEXT_FONT_NAME,
CzechQuestsAddon_Store.config.TACTIC_TEXT_FONT_SIZE
)
end
end
function TacticFrame:InitTab()
local frame = self
local tab = CreateFrame("Button", "EncounterJournalCustomTab", EncounterJournal.encounter.info, "EncounterTabTemplate")
tab:SetPoint("TOP", EncounterJournal.encounter.info.modelTab, "BOTTOM", -3, -12)
tab:SetSize(50, 40)
tab.tooltip = "Taktika"
local selected = tab:CreateTexture(nil, "BACKGROUND")
selected:SetTexture("Interface\\EncounterJournal\\UI-EncounterJournalTextures")
selected:SetAllPoints(tab)
selected:SetBlendMode("ADD")
selected:SetDrawLayer("OVERLAY")
selected:SetTexCoord(0, 0.126953125, 0.90234375, 0.9599609375)
selected:Hide()
tab.selected = selected
function tab:SetActive(enable)
self:SetEnabled(enable);
self:GetDisabledTexture():SetDesaturated(not enable);
end
function tab:SetHighlight(enable)
if not enable then
self.selected:Hide();
else
self.selected:Show();
end
end
frame.tab = tab
end
function TacticFrame:CreateHeader()
local frame = self
local id = NEXT_HEADER_ID + 1
NEXT_HEADER_ID = id
local HeaderFrame = CreateFrame("FRAME", "CzechQuestsTacticHeader" .. id, frame, "EncounterInfoTemplate")
HeaderFrame:SetSize(self:GetParent():GetWidth() - 10, 30)
addon.API.UpdateCzechFont(
HeaderFrame.description,
CzechQuestsAddon_Store.config.TACTIC_TEXT_FONT_NAME,
CzechQuestsAddon_Store.config.TACTIC_TEXT_FONT_SIZE
)
HeaderFrame.button.abilityIcon:Hide()
HeaderFrame.button.portrait:Hide()
HeaderFrame.button.icon2:Hide()
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.button.title:SetPoint("TOPLEFT", HeaderFrame, "TOPLEFT", 40, -7);
HeaderFrame.button.title:SetWidth(self:GetParent():GetWidth() - 110)
for i = 1, #HeaderFrame.Bullets do
HeaderFrame.Bullets[i]:Hide()
end
wipe(HeaderFrame.Bullets)
for _, icon in ipairs(HeaderFrame.button.icons) do
icon:Hide();
end
HeaderFrame.description:SetWidth(HeaderFrame:GetWidth() - 20)
HeaderFrame.description:Hide()
HeaderFrame.overviewDescription:Hide()
HeaderFrame.descriptionBG:Hide()
HeaderFrame.descriptionBGBottom:Hide()
function HeaderFrame:Open()
local parent = self
parent.button.expandedIcon:SetText("-")
parent.button.expandedIcon:SetPoint("TOPLEFT", HeaderFrame.button, "TOPLEFT", 10, -5);
parent.description:Show()
parent.descriptionBG:Show()
parent.descriptionBGBottom:Show()
end
function HeaderFrame:Close()
local parent = self
parent.button.expandedIcon:SetText("+")
parent.button.expandedIcon:SetPoint("TOPLEFT", HeaderFrame.button, "TOPLEFT", 10, -6);
parent.description:Hide()
parent.descriptionBG:Hide()
parent.descriptionBGBottom:Hide()
end
HeaderFrame.button:SetScript("OnClick", function(self)
local parent = self:GetParent()
parent.expanded = not parent.expanded
if parent.expanded then
parent:Open()
else
parent:Close()
end
frame:UpdateHeaderPositions()
end)
table.insert(self.headers, HeaderFrame)
return HeaderFrame
end
function TacticFrame:UpdateHeaderPositions()
local yOffset = -40
for _, header in ipairs(self.headers) do
header:SetPoint("BOTTOMLEFT", self.summary, "BOTTOMLEFT", 0, yOffset)
if header.expanded then
yOffset = yOffset - header.description:GetHeight() - 50
else
yOffset = yOffset - 30
end
end
end
function TacticFrame:ClearHeaders()
for _, header in ipairs(self.headers) do
header:Hide()
header:SetParent(nil)
header = nil
end
wipe(self.headers)
end