From 6c2381d65c14d1fd569aaf110bd95943c8ff8016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Jaro=C5=A1?= Date: Fri, 28 Mar 2025 10:45:45 +0100 Subject: [PATCH] POC: Boss tactics --- Addon/Code/FontUtils.lua | 4 +- CzechQuests.lua | 280 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 271 insertions(+), 13 deletions(-) diff --git a/Addon/Code/FontUtils.lua b/Addon/Code/FontUtils.lua index bf037ad..15d05a3 100644 --- a/Addon/Code/FontUtils.lua +++ b/Addon/Code/FontUtils.lua @@ -17,8 +17,8 @@ end addon.API.CreateCzechFont = CreateCzechFont local function UpdateCzechFont(FontString, name, size) - local _, _, flags = FontString:GetFont() - FontString:SetFont(FontPath .. name, size, flags) + local _, currentSize, flags = FontString:GetFont() + FontString:SetFont(FontPath .. name, size or currentSize, flags) end addon.API.UpdateCzechFont = UpdateCzechFont diff --git a/CzechQuests.lua b/CzechQuests.lua index 9806a61..d2b2383 100644 --- a/CzechQuests.lua +++ b/CzechQuests.lua @@ -41,18 +41,276 @@ local function InitStore() CzechQuestsAddon_Store.config.SPEECH_FRAME_POSITION_Y = CzechQuestsAddon_Store.config.SPEECH_FRAME_POSITION_Y or 0 end --- Event handler frame -local frame = CreateFrame("Frame") -local function OnEvent(self, event, addonName, ...) - if event == "ADDON_LOADED" and addonName == 'CzechQuests' then - InitStore() - addon.API.InitOptions() - addon.API.InitQuests() - addon.API.InitSpeeches() - self:UnregisterEvent("ADDON_LOADED") + + + + +-- Proměnná, která sleduje stav CustomTab +local isCustomTabSelected = false + +local currentTabId = 0 +local prevTabId = 0 +local encounterId = nil + +local difficulty = nil + + +local function AddCustomEncounterTab() + if not EncounterJournal or not EncounterJournal.encounter or not EncounterJournal.encounter.info then + return end + + -- Kontrola a vytvoření vlastního obsahu + if not EncounterJournal.encounter.info.CustomContent then + local customContent = CreateFrame("Frame", "EncounterJournalCustomContent", EncounterJournal.encounter.info) + customContent:SetAllPoints(EncounterJournal.encounter.info.overviewScroll) + customContent:Hide() + + local label = addon.API.CreateCzechFont( + customContent, + CzechQuestsAddon_Store.config.QUEST_TEXT_FONT_NAME, + 12 + ) + + label:SetTextColor(0.251, 0.145, 0.012) -- Hnědavě šedá barva + + + label:SetPoint("TOPLEFT", customContent, "TOPLEFT", 2, -10) + label:SetWidth(330) + label:SetText("Geargrinder encounter se skládá ze dvou fází. V první fázi je boss chráněn Protective Plating, zatímco získává energii a přivolává bikery. Hráči musí eliminovat bikery a využít jejich motorky k odstranění Protective Plating. Jakmile je pancíř odstraněn, boss přechází do Mechanical Breakdown, kde je zranitelný, ale snaží se opravit. DPS musí eliminovat opraváře, tankové musí udržet bosse a healeři se musí vypořádat s vysokým raid-wide poškozením.") + + local i = 0 + local infoHeader = CreateFrame("FRAME", "EncounterJournalInfoHeader"..i, customContent, "EncounterInfoTemplate") + infoHeader:SetSize(330, 30) + + infoHeader.button.title:SetText("Tank") -- Nastaví text tlačítka + infoHeader.button.title:SetPoint("TOPLEFT", infoHeader, "TOPLEFT", 22, -7); + infoHeader.button.title:SetWidth(220) -- Nastavte šířku podle potřeby + + -- Skrytí ikon a dalších prvků tlačítka + infoHeader.button.abilityIcon:Hide() -- Skryje ikonu schopnosti + infoHeader.button.portrait:Hide() -- Skryje portrét + infoHeader.button.icon2:Hide() -- Skryje druhou ikonu + infoHeader.button.icon3:Hide() -- Skryje třetí ikonu + infoHeader.button.icon4:Hide() -- Skryje čtvrtou ikonu + + -- Nastavení počátečního textu a vzhledu tlačítka + infoHeader.button.expandedIcon:SetPoint("TOPLEFT", infoHeader.button, "TOPLEFT", 5, -6); + infoHeader.button.expandedIcon:SetText("+") -- Ikona pro "rozbalit" + infoHeader.expanded = false -- Default: není rozbaleno + + + -- Skrytí dalších prvků spojených s obsahem + for i = 1, #infoHeader.Bullets do + infoHeader.Bullets[i]:Hide() + end + wipe(infoHeader.Bullets) -- Vyčistíme seznam bullets + + + for index, icon in ipairs(infoHeader.button.icons) do + local iconFlag = iconFlags and iconFlags[index]; + icon:Hide(); + end + + infoHeader:SetPoint("BOTTOMLEFT", label, "BOTTOMLEFT", 0, -40) + + addon.API.UpdateCzechFont(infoHeader.description, CzechQuestsAddon_Store.config.QUEST_TEXT_FONT_NAME) + + -- Nastavení obsahu a jeho zobrazení + infoHeader.description:SetText("|cffffffffTank Buster|r - Geargrinder udeří tanka silným fyzickým útokem, způsobí vysoké poškození, knockback a stacking debuff zvyšující utržené poškození. Tank musí použít defenzivní cooldowny a včas swapovat bosse s druhým tankem.") + infoHeader.description:SetWidth(infoHeader:GetWidth() - 20) + infoHeader.description:Hide() -- Výchozí stav: skryto + infoHeader.overviewDescription:Hide() -- Skryje popis přehledu (overview + + + infoHeader.descriptionBG:Hide(); + infoHeader.descriptionBGBottom:Hide(); + + -- Přizpůsobíme klikací funkci pro rozbalení/sbalení + infoHeader.button:SetScript("OnClick", function(self) + local parent = self:GetParent() + parent.expanded = not parent.expanded -- Přepneme logiku mezi rozbaleným a sbaleným + + -- Logika pro rozbalení + if parent.expanded then + self.expandedIcon:SetText("-") -- Ikona pro "sbalit" + self.expandedIcon:SetPoint("TOPLEFT", infoHeader.button, "TOPLEFT", 5, -5); + parent.description:Show() -- Zobrazíme popis + parent.descriptionBG:Show() -- Zobrazíme popis + parent.descriptionBGBottom:Show() -- Zobrazíme popis + else + self.expandedIcon:SetText("+") -- Ikona pro "rozbalit" + self.expandedIcon:SetPoint("TOPLEFT", infoHeader.button, "TOPLEFT", 5, -6); + parent.description:Hide() -- Skryjeme popis + parent.descriptionBG:Hide() -- Zobrazíme popis + parent.descriptionBGBottom:Hide() -- Zobrazíme popis + end + end) + + + EncounterJournal.encounter.info.CustomContent = customContent + end + + + + -- Funkce pro deaktivaci CustomTab + local function DeselectCustomTab() + isCustomTabSelected = false + end + + + local function SelectCustomTab() + -- Nastavíme stav CustomTab jako aktivní + isCustomTabSelected = true + + -- Skryjeme všechny záložky + --EncounterJournal.encounter.info.overviewScroll:Hide() + EncounterJournal.encounter.info.detailsScroll:Hide() + EncounterJournal.encounter.info.LootContainer:Hide() + EncounterJournal.encounter.info.model:Hide() + + EncounterJournal.encounter.info['overviewScroll']:Hide(); + EncounterJournal.encounter.info['overviewTab'].selected:Hide(); + EncounterJournal.encounter.info['overviewTab'].unselected:Show(); + EncounterJournal.encounter.info['overviewTab']:UnlockHighlight(); + + + EncounterJournal.encounter.info['LootContainer']:Hide(); + EncounterJournal.encounter.info['lootTab'].selected:Hide(); + EncounterJournal.encounter.info['lootTab'].unselected:Show(); + EncounterJournal.encounter.info['lootTab']:UnlockHighlight(); + + + EncounterJournal.encounter.info['detailsScroll']:Hide(); + EncounterJournal.encounter.info['bossTab'].selected:Hide(); + EncounterJournal.encounter.info['bossTab'].unselected:Show(); + EncounterJournal.encounter.info['bossTab']:UnlockHighlight(); + + + EncounterJournal.encounter.info['model']:Hide(); + EncounterJournal.encounter.info['modelTab'].selected:Hide(); + EncounterJournal.encounter.info['modelTab'].unselected:Show(); + EncounterJournal.encounter.info['modelTab']:UnlockHighlight(); + + EncounterJournal.encounter.info.CustomTab.selected:Show(); + + + if EncounterJournal.encounter.info.creatureButtons then + for _, button in pairs(EncounterJournal.encounter.info.creatureButtons) do + button:Hide() + end + end + + EncounterJournal.encounter.info.encounterTitle:Show() + EncounterJournal.encounter.info.difficulty:Show() + + EncounterJournal.encounter.info.rightShadow:Show() + + -- Vyplnění obsahu naší tabulky + local bossName = EJ_GetEncounterInfo(encounterId) + print(bossName) + + -- Zobrazíme vlastní obsah + EncounterJournal.encounter.info.CustomContent:Show() + end + + -- Kontrola a vytvoření vlastního tlačítka + if not EncounterJournal.encounter.info.CustomTab then + local customTab = CreateFrame("Button", "EncounterJournalCustomTab", EncounterJournal.encounter.info, "EncounterTabTemplate") + customTab:SetPoint("TOP", EncounterJournal.encounter.info.modelTab, "BOTTOM", -3, -12) + customTab:SetSize(50, 40) + customTab.tooltip = "Taktika" + + -- Přidání textury (zelená koule) do layoutu záložky + local icon = customTab:CreateTexture(nil, "OVERLAY") + icon:SetSize(20, 20) -- Velikost ikony (koule) + icon:SetPoint("CENTER", customTab, "CENTER", 0, 0) -- Pozice vlevo od textu + icon:SetTexture("Interface\\COMMON\\Indicator-Yellow") -- Použití textury zelené koule + + customTab:SetEnabled(false); + customTab:GetDisabledTexture():SetDesaturated(true); + + -- Vytvoření selected textury (vybraný stav) + local selectTexture = customTab:CreateTexture(nil, "BACKGROUND") + selectTexture:SetTexture("Interface\\EncounterJournal\\UI-EncounterJournalTextures") -- Základní textura + selectTexture:SetAllPoints(customTab) -- Umístění na střed + -- TexCoords pro "selected", pokud existují (nahraďte správnými souřadnicemi) + selectTexture:SetBlendMode("ADD") + selectTexture:SetDrawLayer("OVERLAY") + selectTexture:SetTexCoord(0, 0.126953125, 0.90234375, 0.9599609375)-- Ukázkové hodnoty (upravit dle specifikace) + selectTexture:Hide() + customTab.selected = selectTexture -- Přidáme jako vlastnost rámce + + -- Kliknutí na vlastní záložku + customTab:SetScript("OnClick", function(self) + currentTabId = 0 + SelectCustomTab() + end) + + customTab.icon = icon + + + EncounterJournal.encounter.info.CustomTab = customTab + end + + -- Hook na přepnutí bosse + hooksecurefunc("EncounterJournal_DisplayEncounter", function(encounterID) + encounterId = encounterID + EncounterJournal.encounter.info.CustomTab:SetEnabled(true); + EncounterJournal.encounter.info.CustomTab:GetDisabledTexture():SetDesaturated(false); + + -- Pokud je CustomTab vybrána, při změně bosse zachováme zvýraznění + if isCustomTabSelected then + SelectCustomTab() + else + DeselectCustomTab() + end + end) + + hooksecurefunc("EncounterJournal_SetTab", function(tabId) + if currentTabId ~= tabId then + isCustomTabSelected = false + EncounterJournal.encounter.info.CustomTab.selected:Hide(); + end + prevTabId = currentTabId + currentTabId = tabId + EncounterJournal.encounter.info.CustomContent:Hide() + end) + + -- Hook na přepnutí bosse + hooksecurefunc("EncounterJournalBossButton_OnClick", function(encounterID) + if prevTabId == 0 then + currentTabId = 0 + SelectCustomTab() + end + end) + + -- Hook na přepnutí bosse + hooksecurefunc("EncounterJournal_UpdateDifficulty", function(dif) + difficulty = dif + if prevTabId == 0 and encounterId then + currentTabId = 0 + SelectCustomTab() + end + end) + + -- Hook na přepnutí bosse + hooksecurefunc("EncounterJournal_DisplayInstance", function(encounterID) + EncounterJournal.encounter.info.CustomTab:SetEnabled(false); + EncounterJournal.encounter.info.CustomTab:GetDisabledTexture():SetDesaturated(true); + EncounterJournal.encounter.info.CustomTab.selected:Hide(); + end) end --- Register the event +-- Sledujeme Blizzard Encounter Journal události +local frame = CreateFrame("Frame") +frame:RegisterEvent("PLAYER_ENTERING_WORLD") frame:RegisterEvent("ADDON_LOADED") -frame:SetScript("OnEvent", OnEvent) \ No newline at end of file +frame:RegisterEvent("EJ_DIFFICULTY_UPDATE") -- Událost pro změnu obtížnosti + + +frame:SetScript("OnEvent", function(self, event, addonName) + if event == "ADDON_LOADED" then + AddCustomEncounterTab() + end +end)