-------------------------------------------------------------------------------- -- Nanami-UI: Darkmoon Faire Buff Guide (暗月马戏团 Buff 指引) -- Automatically shows a guide when talking to Sayge, or via /dmf command -------------------------------------------------------------------------------- SFrames.DarkmoonGuide = SFrames.DarkmoonGuide or {} local DG = SFrames.DarkmoonGuide local GUIDE_WIDTH = 420 local GUIDE_HEIGHT = 520 local _A = SFrames.ActiveTheme local SAYGE_NAMES = { ["Sayge"] = true, ["塞格"] = true, ["赛格"] = true, ["Сэйдж"] = true, } -- Buff data: { buff name, q1 answer, q2 answer, description, optional alt path } local BUFF_DATA = { { buff = "+10% 伤害", q1 = 1, q2 = 1, star = true, tip = "DPS首选" }, { buff = "+25 全抗性", q1 = 1, q2 = 2, star = false, tip = "PvP/坦克可选", q1_alt = 2, q2_alt = 3 }, { buff = "+10% 护甲", q1 = 1, q2 = 3, star = false, tip = "坦克可选", q1_alt = 4, q2_alt = 3 }, { buff = "+10% 精神", q1 = 2, q2 = 1, star = false, tip = "治疗回蓝", q1_alt = 4, q2_alt = 2 }, { buff = "+10% 智力", q1 = 2, q2 = 2, star = false, tip = "法系/治疗", q1_alt = 4, q2_alt = 1 }, { buff = "+10% 耐力", q1 = 3, q2 = 1, star = false, tip = "坦克/PvP" }, { buff = "+10% 力量", q1 = 3, q2 = 2, star = false, tip = "战士/圣骑" }, { buff = "+10% 敏捷", q1 = 3, q2 = 3, star = false, tip = "盗贼/猎人" }, } local Q1_LABELS = { [1] = "第一项: 我会正面迎战", [2] = "第二项: 我会说服对方", [3] = "第三项: 我会帮助别人", [4] = "第四项: 我会独自思考", } local Q2_LABELS = { [1] = "选第一项", [2] = "选第二项", [3] = "选第三项", } -------------------------------------------------------------------------------- -- Frame creation -------------------------------------------------------------------------------- local function CreateGuideFrame() if DG.frame then return DG.frame end local f = CreateFrame("Frame", "NanamiDarkmoonGuide", UIParent) f:SetWidth(GUIDE_WIDTH) f:SetHeight(GUIDE_HEIGHT) f:SetPoint("CENTER", UIParent, "CENTER", 0, 40) f:SetFrameStrata("FULLSCREEN_DIALOG") f:SetFrameLevel(500) f:SetMovable(true) f:EnableMouse(true) f:SetClampedToScreen(true) f:RegisterForDrag("LeftButton") f:SetScript("OnDragStart", function() this:StartMoving() end) f:SetScript("OnDragStop", function() this:StopMovingOrSizing() end) SFrames:CreateRoundBackdrop(f) local _pbg = _A.panelBg or { 0.06, 0.05, 0.08, 0.96 } local _pbd = _A.panelBorder or { 0.45, 0.25, 0.55, 1 } f:SetBackdropColor(_pbg[1], _pbg[2], _pbg[3], _pbg[4]) f:SetBackdropBorderColor(_pbd[1], _pbd[2], _pbd[3], _pbd[4]) table.insert(UISpecialFrames, "NanamiDarkmoonGuide") if WorldMapFrame then local origOnHide = WorldMapFrame:GetScript("OnHide") WorldMapFrame:SetScript("OnHide", function() if origOnHide then origOnHide() end if f:IsShown() then f:Hide() end end) end -- Title bar local titleBar = CreateFrame("Frame", nil, f) titleBar:SetHeight(32) titleBar:SetPoint("TOPLEFT", f, "TOPLEFT", 8, -8) titleBar:SetPoint("TOPRIGHT", f, "TOPRIGHT", -8, -8) titleBar:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8", edgeFile = "Interface\\Buttons\\WHITE8X8", tile = false, tileSize = 0, edgeSize = 1, insets = { left = 1, right = 1, top = 1, bottom = 1 } }) local _hbg = _A.headerBg or { 0.12, 0.08, 0.15, 0.9 } local _hbd = _A.headerBorder or { 0.5, 0.3, 0.6, 0.6 } titleBar:SetBackdropColor(_hbg[1], _hbg[2], _hbg[3], _hbg[4]) titleBar:SetBackdropBorderColor(_hbd[1], _hbd[2], _hbd[3], _hbd[4]) local titleIcon = titleBar:CreateTexture(nil, "ARTWORK") titleIcon:SetTexture("Interface\\Icons\\INV_Misc_Orb_02") titleIcon:SetWidth(20) titleIcon:SetHeight(20) titleIcon:SetPoint("LEFT", titleBar, "LEFT", 8, 0) local titleText = SFrames:CreateFontString(titleBar, 14, "LEFT") titleText:SetPoint("LEFT", titleIcon, "RIGHT", 6, 0) titleText:SetTextColor(_A.title[1], _A.title[2], _A.title[3]) titleText:SetText("暗月马戏团 Buff 指引") -- Close button local closeBtn = CreateFrame("Button", nil, f) closeBtn:SetWidth(20) closeBtn:SetHeight(20) closeBtn:SetPoint("TOPRIGHT", f, "TOPRIGHT", -12, -13) closeBtn:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8", edgeFile = "Interface\\Buttons\\WHITE8X8", tile = false, tileSize = 0, edgeSize = 1, insets = { left = 1, right = 1, top = 1, bottom = 1 } }) local _cbg = _A.closeBtnBg or { 0.3, 0.08, 0.08, 0.9 } local _cbd = _A.closeBtnBorder or { 0.6, 0.2, 0.2, 0.8 } local _cbgH = _A.closeBtnHoverBg or { 0.5, 0.1, 0.1, 0.95 } local _cbdH = _A.closeBtnHoverBorder or { 0.8, 0.3, 0.3, 1 } closeBtn:SetBackdropColor(_cbg[1], _cbg[2], _cbg[3], _cbg[4]) closeBtn:SetBackdropBorderColor(_cbd[1], _cbd[2], _cbd[3], _cbd[4]) local closeIco = SFrames:CreateIcon(closeBtn, "close", 12) closeIco:SetDrawLayer("OVERLAY") closeIco:SetPoint("CENTER", closeBtn, "CENTER", 0, 0) closeIco:SetVertexColor(1, 0.7, 0.7) closeBtn:SetScript("OnClick", function() f:Hide() end) closeBtn:SetScript("OnEnter", function() this:SetBackdropColor(_cbgH[1], _cbgH[2], _cbgH[3], _cbgH[4]) this:SetBackdropBorderColor(_cbdH[1], _cbdH[2], _cbdH[3], _cbdH[4]) end) closeBtn:SetScript("OnLeave", function() this:SetBackdropColor(_cbg[1], _cbg[2], _cbg[3], _cbg[4]) this:SetBackdropBorderColor(_cbd[1], _cbd[2], _cbd[3], _cbd[4]) end) -- NPC info section local npcSection = CreateFrame("Frame", nil, f) npcSection:SetHeight(48) npcSection:SetPoint("TOPLEFT", titleBar, "BOTTOMLEFT", 0, -8) npcSection:SetPoint("TOPRIGHT", titleBar, "BOTTOMRIGHT", 0, -8) local npcLine1 = SFrames:CreateFontString(npcSection, 11, "LEFT") npcLine1:SetPoint("TOPLEFT", npcSection, "TOPLEFT", 4, 0) npcLine1:SetPoint("TOPRIGHT", npcSection, "TOPRIGHT", -4, 0) npcLine1:SetTextColor(_A.sectionTitle[1], _A.sectionTitle[2], _A.sectionTitle[3]) npcLine1:SetText("NPC: |cffffffffSayge (塞格)|r - 暗月马戏团占卜师") local npcLine2 = SFrames:CreateFontString(npcSection, 10, "LEFT") npcLine2:SetPoint("TOPLEFT", npcLine1, "BOTTOMLEFT", 0, -4) npcLine2:SetPoint("TOPRIGHT", npcLine1, "BOTTOMRIGHT", 0, -4) npcLine2:SetTextColor(_A.dimText[1], _A.dimText[2], _A.dimText[3]) npcLine2:SetText("与赛格对话选择不同答案可获得不同2小时Buff (表中 X→Y = 第1题选X, 第2题选Y)") -- Separator local sep1 = f:CreateTexture(nil, "ARTWORK") sep1:SetTexture("Interface\\Buttons\\WHITE8X8") sep1:SetHeight(1) sep1:SetPoint("TOPLEFT", npcSection, "BOTTOMLEFT", 0, -4) sep1:SetPoint("TOPRIGHT", npcSection, "BOTTOMRIGHT", 0, -4) local _sep = _A.separator or { 0.4, 0.25, 0.5, 0.5 } sep1:SetVertexColor(_sep[1], _sep[2], _sep[3], _sep[4]) -- Column headers local headerY = -104 local colBuff = 12 local colOpt1 = 150 local colOpt2 = 260 local colTip = 355 local hBuff = SFrames:CreateFontString(f, 11, "LEFT") hBuff:SetPoint("TOPLEFT", f, "TOPLEFT", colBuff, headerY) hBuff:SetTextColor(_A.sectionTitle[1], _A.sectionTitle[2], _A.sectionTitle[3]) hBuff:SetText("Buff效果") local hOpt1 = SFrames:CreateFontString(f, 11, "LEFT") hOpt1:SetPoint("TOPLEFT", f, "TOPLEFT", colOpt1, headerY) hOpt1:SetTextColor(_A.sectionTitle[1], _A.sectionTitle[2], _A.sectionTitle[3]) hOpt1:SetText("选项1") local hOpt2 = SFrames:CreateFontString(f, 11, "LEFT") hOpt2:SetPoint("TOPLEFT", f, "TOPLEFT", colOpt2, headerY) hOpt2:SetTextColor(_A.sectionTitle[1], _A.sectionTitle[2], _A.sectionTitle[3]) hOpt2:SetText("选项2") local hTip = SFrames:CreateFontString(f, 11, "LEFT") hTip:SetPoint("TOPLEFT", f, "TOPLEFT", colTip, headerY) hTip:SetTextColor(_A.sectionTitle[1], _A.sectionTitle[2], _A.sectionTitle[3]) hTip:SetText("备注") -- Header separator local sep2 = f:CreateTexture(nil, "ARTWORK") sep2:SetTexture("Interface\\Buttons\\WHITE8X8") sep2:SetHeight(1) sep2:SetPoint("TOPLEFT", f, "TOPLEFT", 10, headerY - 14) sep2:SetPoint("TOPRIGHT", f, "TOPRIGHT", -10, headerY - 14) local _sep2c = _A.separator or { 0.35, 0.2, 0.45, 0.4 } sep2:SetVertexColor(_sep2c[1], _sep2c[2], _sep2c[3], _sep2c[4]) -- Buff rows local rowStart = headerY - 22 local rowHeight = 24 for i, data in ipairs(BUFF_DATA) do local y = rowStart - (i - 1) * rowHeight -- Alternate row background if math.fmod(i, 2) == 0 then local rowBg = f:CreateTexture(nil, "BACKGROUND") rowBg:SetTexture("Interface\\Buttons\\WHITE8X8") rowBg:SetHeight(rowHeight) rowBg:SetPoint("TOPLEFT", f, "TOPLEFT", 8, y + 4) rowBg:SetPoint("TOPRIGHT", f, "TOPRIGHT", -8, y + 4) local _rbg = _A.sectionBg or { 0.15, 0.1, 0.2, 0.3 } rowBg:SetVertexColor(_rbg[1], _rbg[2], _rbg[3], 0.3) end -- Star marker for recommended if data.star then local star = SFrames:CreateFontString(f, 10, "LEFT") star:SetPoint("TOPLEFT", f, "TOPLEFT", colBuff - 10, y) local _stc = _A.title or { 1.0, 0.84, 0.0 } star:SetTextColor(_stc[1], _stc[2], _stc[3]) star:SetText("*") end -- Buff name local buffName = SFrames:CreateFontString(f, 11, "LEFT") buffName:SetPoint("TOPLEFT", f, "TOPLEFT", colBuff, y) if data.star then local _hl = _A.accentLight or { 0.4, 1.0, 0.4 } buffName:SetTextColor(_hl[1], _hl[2], _hl[3]) else buffName:SetTextColor(_A.text[1], _A.text[2], _A.text[3]) end buffName:SetText(data.buff) -- Option 1 path (q1→q2) local opt1Text = SFrames:CreateFontString(f, 11, "CENTER") opt1Text:SetPoint("TOPLEFT", f, "TOPLEFT", colOpt1, y) local _o1c = _A.title or { 1, 0.82, 0.5 } opt1Text:SetTextColor(_o1c[1], _o1c[2], _o1c[3]) opt1Text:SetText(data.q1 .. " → " .. data.q2) -- Option 2 path (alt q1→q2) or "/" local opt2Text = SFrames:CreateFontString(f, 11, "CENTER") opt2Text:SetPoint("TOPLEFT", f, "TOPLEFT", colOpt2, y) if data.q1_alt then local _o2c = _A.accentDark or { 0.7, 0.82, 1.0 } opt2Text:SetTextColor(_o2c[1], _o2c[2], _o2c[3]) opt2Text:SetText(data.q1_alt .. " → " .. data.q2_alt) else opt2Text:SetTextColor(_A.dimText[1], _A.dimText[2], _A.dimText[3]) opt2Text:SetText("/") end -- Tip local tipText = SFrames:CreateFontString(f, 10, "LEFT") tipText:SetPoint("TOPLEFT", f, "TOPLEFT", colTip, y) tipText:SetTextColor(_A.dimText[1], _A.dimText[2], _A.dimText[3]) tipText:SetText(data.tip) end -- Separator before Q1 detail local sep3 = f:CreateTexture(nil, "ARTWORK") sep3:SetTexture("Interface\\Buttons\\WHITE8X8") sep3:SetHeight(1) local detailY = rowStart - table.getn(BUFF_DATA) * rowHeight - 4 sep3:SetPoint("TOPLEFT", f, "TOPLEFT", 10, detailY) sep3:SetPoint("TOPRIGHT", f, "TOPRIGHT", -10, detailY) local _sep3c = _A.separator or { 0.4, 0.25, 0.5, 0.5 } sep3:SetVertexColor(_sep3c[1], _sep3c[2], _sep3c[3], _sep3c[4]) -- Q1 dialogue detail header local q1Header = SFrames:CreateFontString(f, 11, "LEFT") q1Header:SetPoint("TOPLEFT", f, "TOPLEFT", 12, detailY - 10) q1Header:SetTextColor(_A.sectionTitle[1], _A.sectionTitle[2], _A.sectionTitle[3]) q1Header:SetText("第一题选项对照:") -- Q1 options local q1y = detailY - 28 for idx, label in pairs(Q1_LABELS) do local line = SFrames:CreateFontString(f, 10, "LEFT") line:SetPoint("TOPLEFT", f, "TOPLEFT", 18, q1y - (idx - 1) * 16) line:SetTextColor(_A.text[1], _A.text[2], _A.text[3]) line:SetText("|cffffcc66" .. idx .. ".|r " .. label) end -- Q2 dialogue detail header local q2HeaderY = q1y - 4 * 16 - 8 local q2Header = SFrames:CreateFontString(f, 11, "LEFT") q2Header:SetPoint("TOPLEFT", f, "TOPLEFT", 12, q2HeaderY) q2Header:SetTextColor(_A.sectionTitle[1], _A.sectionTitle[2], _A.sectionTitle[3]) q2Header:SetText("第二题: 根据上表 \"X → Y\" 中的Y选对应项 (共3项)") -- Tip at bottom local tipY = q2HeaderY - 24 local bottomTip = SFrames:CreateFontString(f, 10, "LEFT") bottomTip:SetPoint("TOPLEFT", f, "TOPLEFT", 12, tipY) bottomTip:SetPoint("TOPRIGHT", f, "TOPRIGHT", -12, tipY) local _btc = _A.title or { 1.0, 0.84, 0.0 } bottomTip:SetTextColor(_btc[1], _btc[2], _btc[3]) bottomTip:SetText("* 推荐: 大部分职业选 +10% 伤害 (第1题选1, 第2题选1)") local bottomTip2 = SFrames:CreateFontString(f, 10, "LEFT") bottomTip2:SetPoint("TOPLEFT", bottomTip, "BOTTOMLEFT", 0, -6) bottomTip2:SetPoint("TOPRIGHT", bottomTip, "BOTTOMRIGHT", 0, -6) bottomTip2:SetTextColor(_A.dimText[1], _A.dimText[2], _A.dimText[3]) bottomTip2:SetText("输入 /dmf 可随时打开此面板 | 可拖动移动 | ESC关闭") f:Hide() DG.frame = f return f end -------------------------------------------------------------------------------- -- Toggle -------------------------------------------------------------------------------- function DG:Toggle() local f = CreateGuideFrame() if f:IsShown() then f:Hide() else f:Show() end end function DG:Show() local f = CreateGuideFrame() f:Show() end function DG:Hide() if DG.frame then DG.frame:Hide() end end -------------------------------------------------------------------------------- -- Slash command: /dmf -------------------------------------------------------------------------------- SLASH_DARKMOONGUIDE1 = "/dmf" SLASH_DARKMOONGUIDE2 = "/darkmoon" SlashCmdList["DARKMOONGUIDE"] = function() DG:Toggle() end -------------------------------------------------------------------------------- -- Auto-show when talking to Sayge -------------------------------------------------------------------------------- local detector = CreateFrame("Frame", "NanamiDarkmoonDetector", UIParent) detector:RegisterEvent("GOSSIP_SHOW") detector:SetScript("OnEvent", function() local npcName = UnitName("npc") if npcName and SAYGE_NAMES[npcName] then DG:Show() end end) DEFAULT_CHAT_FRAME:AddMessage("SF: Loading DarkmoonGuide.lua...")