--kemayo at gmail dot com. local L = AceLibrary("AceLocale-2.2"):new("DetailsFrame") L:RegisterTranslations("enUS", function() return { ["DetailsFrame"] = true, ["Description"] = "Prettier and more informative quest details frame.", ["(done)"] = true, ["(failed)"] = true, ["Given by"] = true, ["Required money: "] = true, ["Text"] = true, ["%s in %s (%d,%d)"] = true, ["Description"] = true, ["Rewards"] = true, ["Choose from:"] = true, ["Always receive:"] = true, ["Spell:"] = true, ["Money: "] = true, ["Nothing."] = true, ["Options"] = true, ["- Share"] = true, ["- Abandon"] = true, ["[ Close ]"] = true, [""] = true, ["bunch-of-directions"] = { "([^%a%d])(north)([^%a%d])", "([^%a%d])(northern)([^%a%d])", "([^%a%d])(west)([^%a%d])", "([^%a%d])(western)([^%a%d])", "([^%a%d])(east)([^%a%d])", "([^%a%d])(eastern)([^%a%d])", "([^%a%d])(south)([^%a%d])", "([^%a%d])(southern)([^%a%d])", "([^%a%d])(northwest)([^%a%d])", "([^%a%d])(northwestern)([^%a%d])", "([^%a%d])(northeast)([^%a%d])", "([^%a%d])(northeastern)([^%a%d])", "([^%a%d])(southwest)([^%a%d])", "([^%a%d])(southwestern)([^%a%d])", "([^%a%d])(southeast)([^%a%d])", "([^%a%d])(southeastern)([^%a%d])", } } end) L:RegisterTranslations("koKR", function() return { ["DetailsFrame"] = "상세 프레임", ["Description"] = "퀘스트 알림창의 퀘스트를 선택하면 상세 내용을 표시해주는 모듈입니다.", ["(done)"] = "(완료)", ["(failed)"] = "(실패)", ["Given by"] = "퀘스트 제공자", ["Required money: "] = "요구 금액: ", ["Text"] = "텍스트", ["%s in %s (%d,%d)"] = "%s (%s) 좌표: %d, %d", ["Description"] = "내용", ["Rewards"] = "보상", ["Choose from:"] = "아래의 보상 중 선택", ["Always receive:"] = "받게 될 보상", ["Spell:"] = "기술:", ["Money: "] = "금액: ", ["Nothing."] = "없음", ["Options"] = "추가 설정", ["- Share"] = "- 퀘스트 공유", ["- Abandon"] = "- 퀘스트 포기", ["[ Close ]"] = "[ 닫기 ]", [""] = "<캐쉬에 없음>", ["bunch-of-directions"] = { "(%s?)(북서쪽)([^%a%d])", "(%s?)(북동쪽)([^%a%d])", "(%s?)(남서쪽)([^%a%d])", "(%s?)(남동쪽)([^%a%d])", "(%s?)(북쪽)([^%a%d])", "(%s?)(서쪽)([^%a%d])", "(%s?)(동쪽)([^%a%d])", "(%s?)(남쪽)([^%a%d])", } } end) local moduleName = "DetailsFrame" local DetailsFrame = nQuestLog:NewModule(moduleName,"AceEvent-2.0") local tablet = AceLibrary("Tablet-2.0") local quixote = AceLibrary("Quixote-1.0") local crayon = AceLibrary("Crayon-2.0") local abacus = AceLibrary("Abacus-2.0") local babbleclass = AceLibrary("Babble-Class-2.2") function DetailsFrame:OnModuleLoad() self.menuName = L["DetailsFrame"] self.description = L["Description"] nQuestLog:RegisterDefaults(moduleName, "profile", { ["enabled"] = true, color = { title = true, level = true, }, detail_data = { fontSizePercent=1.0, detached=true, }, }) end function DetailsFrame:ToggleEnabled(v) self.db.profile.enabled = v if (v) then self:RegisterEvent("Quixote_Quest_Lost", "OnQuest_Lost") self:RegisterEvent("Quixote_Leaderboard_Update", "OnQuest_Leaderboard_Update") else self:UnregisterEvent("Quixote_Quest_Lost", "OnQuest_Lost") self:UnregisterEvent("Quixote_Leaderboard_Update", "OnQuest_Leaderboard_Update") end end function DetailsFrame:OnQuest_Lost(name,id) if self.questid == id then self.questid = nil self:UpdateQuestDetail() end end function DetailsFrame:OnQuest_Leaderboard_Update(name,id) if self.questid == id then self:UpdateQuestDetail() end end function DetailsFrame:ShowLog(questid) if self.questid ~= questid then self.questid = questid else self.questid = nil escapeDetector:Hide() end self:UpdateQuestDetail() end local function itemClick(link) if IsControlKeyDown() then DressUpItemLink(link) elseif IsShiftKeyDown() then if not ChatFrameEditBox:IsVisible() then ChatFrameEditBox:Show() end ChatFrameEditBox:Insert(link) else ShowUIPanel(ItemRefTooltip) if not ItemRefTooltip:IsVisible() then ItemRefTooltip:SetOwner(UIParent, "ANCHOR_PRESERVE") end ItemRefTooltip:SetHyperlink(link) end end function DetailsFrame:MakeTag(level, tag) return "[" .. level .. tag .. "] " end --local escapeDetector function DetailsFrame:UpdateQuestDetail() if not tablet:IsRegistered('nQuestLog_Detail') then local qualitycolors = { [0] = "|cff9d9d9d", [1] = "|cffffffff", [2] = "|cff1eff00", [3] = "|cff0070dd", [4] = "|cffa335ee", [5] = "|cffff8000" } local questgiverPat = '^' .. L["%s in %s (%d,%d)"]:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1"):gsub("%%%%s", "(.*)"):gsub("%%%%d", "(%%d+)") .. '$' local showingDescription = true local function itemClick(link) if IsControlKeyDown() then DressUpItemLink(link) elseif IsShiftKeyDown() then if not ChatFrameEditBox:IsVisible() then ChatFrameEditBox:Show() end ChatFrameEditBox:Insert(link) else ShowUIPanel(ItemRefTooltip) if not ItemRefTooltip:IsVisible() then ItemRefTooltip:SetOwner(UIParent, "ANCHOR_PRESERVE") end ItemRefTooltip:SetHyperlink(link) end end local function hideQuestDetail() self.questid = nil self:UpdateQuestDetail() --tablet:Refresh('nQuestLog_Detail') end local function toggleDescription() showingDescription = not showingDescription tablet:Refresh('nQuestLog_Detail') end local function abandonQuestPopup(questid) local startingQuestLogSelection = GetQuestLogSelection() SelectQuestLogEntry(questid) SetAbandonQuest() local items = GetAbandonQuestItems() if items then StaticPopup_Hide("ABANDON_QUEST") StaticPopup_Show("ABANDON_QUEST_WITH_ITEMS", GetAbandonQuestName(), items) else StaticPopup_Hide("ABANDON_QUEST_WITH_ITEMS") StaticPopup_Show("ABANDON_QUEST", GetAbandonQuestName()) end SelectQuestLogEntry(startingQuestLogSelection) end local directions = L["bunch-of-directions"] -- by woodin 2007.2.9 (Korean Parsing fix) local function colorizeQuestText(text, ...) -- this syntax is parsing of korean -- group 0:all, 1: objective, 2: questgivers, 3:description,.... if ( GetLocale()=="koKR" ) then local parseFormats = { {group = 1, patt ="(%d+)([^%s%|])", repl = "|cff00ff00%1|r%2", }, -- Match numbers {group = 1, patt = "([은|는|을|를|아|한|의]+) ([^%s]+) ([^%s]+)(에게)", repl = "%1 |cffffffff%2 %3|r%4", }, -- Match Quest finisher {group = 1, patt = "([은|는|을|를|아|한|의]+) ([^%s]+)(에게)", repl = "%1 |cffffffff%2|r%3", }, -- Match Quest finisher {group = 1, patt = "([에서|이]+) ([^%s]+) ([^%s]+)(를 )", repl = "%1 |cffffffff%2 %3|r%4", }, -- Match Quest finisher {group = 1, patt = "([에서|이]+) ([^%s]+)(를 )", repl = "%1 |cffffffff%2|r%3", }, -- Match Quest finisher {group = 1, patt = "([의|는]+) ([^%s]+) ([^%s]+)(가 )", repl = "%1 |cffffffff%2 %3|r%4", }, -- Match Quest finisher {group = 1, patt = "([의|는]+) ([^%s]+)(가 )", repl = "%1 |cffffffff%2|r%3", }, -- Match Quest finisher {group = 1, patt = "([의|는]+) ([^%s]+) ([^%s]+)(이 )", repl = "%1 |cffffffff%2 %3|r%4", }, -- Match Quest finisher {group = 1, patt = "([의|는]+) ([^%s]+)(이 )", repl = "%1 |cffffffff%2|r%3", }, -- Match Quest finisher {group = 1, patt = "([의|는]+) ([^%s]+) ([^%s]+)(와 )", repl = "%1 |cffffffff%2 %3|r%4", }, -- Match Quest finisher {group = 1, patt = "([의|는]+) ([^%s]+)(와 )", repl = "%1 |cffffffff%2|r%3", }, -- Match Quest finisher {group = 1, patt = "([의]+) ([^%s]+) ([^%s]+)(에 있는 )", repl = "%1 |cffffffff%2 %3|r%4", }, -- Match Quest finisher {group = 1, patt = "([의]+) ([^%s]+)(에 있는 )", repl = "%1 |cffffffff%2|r%3", }, -- Match Quest finisher } for k in ipairs(parseFormats) do text = text:gsub(parseFormats[k].patt, parseFormats[k].repl) end -- by woodin 2007.2.9 (Korean Parsing fix) else --This is copied in approach from MonkeyQuestLog, note. for i = 1, select('#', ...) do local val = select(i, ...) if val then local val2 = val:gsub("([^%s])", "|cffffffff%1|r") -- color each word so it doesn't mess up later text = text:gsub(val, val2) end end text = text:gsub("([^%a%d%|])(%d+)([^%a%d%|])", "%1|cff00ff00%2|r%3") -- Match numbers text = text:gsub("([^%a%d%|])(%d+)([^%a%d%|])", "%1|cff00ff00%2|r%3") -- Match numbers again text = text:gsub("([%w,]+) (%u[%w'%-]+ %u[%w'%-]+)", "%1 |cffffffff%2|r") -- Match uppercase words. text = text:gsub("([%w,]+) (%u[%w'%-]+)", "%1 |cffffffff%2|r") -- Run it twice or it'll skip words (TODO: figure out a better pattern to avoid this, if possible) end for _, direction in ipairs(directions) do text = text:gsub(direction, "%1|cffffffff%2|r%3") -- Match direction end return text end escapeDetector = CreateFrame("Frame", "nQuestLog_escapeDetector") escapeDetector:SetScript("OnHide", hideQuestDetail) table.insert(UISpecialFrames, escapeDetector:GetName()) tablet:Register('nQuestLog_Detail', 'detachedData', self.db.profile.detail_data, 'dontHook', true, 'hideWhenEmpty', true,-- 'showTitleWhenDetached', true, 'minWidth', 300, 'strata', 'HIGH', 'cantAttach', true, 'children', function() tablet:SetTitle("Detail") if self.questid then local startingQuestLogSelection = GetQuestLogSelection() SelectQuestLogEntry(self.questid) local title, level, tag, suggestedGroup, complete, nObjectives, zone, id = quixote:GetQuest(self.questid) local objective, description = quixote:GetQuestText(self.questid) --Title and objective: if not self.db.profile.color.title then title = crayon:White(title) end if not self.db.profile.color.level then level = crayon:White(questLevel) end local color = GetDifficultyColor(level) -- Modified for nQuestLog local giverName, giverLocation, giverDistance,giverZone if nQuestLog:IsModuleEnabled("QuestGivers") then giverName,giverLocation,giverDistance = nQuestLog:GetModule("QuestGivers"):GetQuestGiver(title) if (giverLocation) then giverZone = giverLocation.zone end end local cat = tablet:AddCategory('columns', 1, 'text', self:MakeTag(level, tag)..title, 'textR', (color and color.r) or 1, 'textG', (color and color.g) or 1, 'textB', (color and color.b) or 1, 'size', tablet:GetHeaderFontSize(), 'justify', 'CENTER', 'func', self.QuestClick, 'arg1', self, 'arg2', id) --Do this instead of closing the tablet because it seems permanently blank on its second open otherwise. if complete then cat:AddLine('text', complete, 'textR', (complete == L["(failed)"]) and 1 or 0, 'textG', (complete == L["(done)"]) and 1 or 0, 'textB', 0, 'justify', 'CENTER') end if suggestedGroup and suggestedGroup > 0 then cat:AddLine('text', (QUEST_SUGGESTED_GROUP_NUM):format(suggestedGroup), 'justify', 'CENTER') end cat:AddLine('text', colorizeQuestText(objective, giverName, giverZone), 'wrap', true) --Leaderboard: if nObjectives > 0 then cat = tablet:AddCategory('columns', 2) for i=1,nObjectives do self:AddLeaderboardToCategory(cat, self.questid, i, tablet:GetNormalFontSize(), 0) end end --Given by? - Modified for nQuestLog if (giverName) then local questgivertext = nQuestLog:GetModule("QuestGivers"):Format_QuestGiver(giverName, giverLocation, giverDistance) if (questgivertext) then cat = tablet:AddCategory('columns', 2, 'text', L["Given by"]) cat:AddLine('text', questgivertext, 'indentation', 2) end if (giverDistance and not self.refreshEvent) then -- We have distance, so we need to schedule a refresh self.refreshEvent = "nQuestLog-DetailsFrame-" .. math.random() self:ScheduleRepeatingEvent(self.refreshEvent, self.UpdateQuestDetail, 1, self) end end --Requires money? if GetQuestLogRequiredMoney() > 0 then cat = tablet:AddCategory('columns', 2, 'text', L["Required money: "]..abacus:FormatMoneyFull(GetQuestLogRequiredMoney()), 'showWithoutChildren', true) end --Description: cat = tablet:AddCategory('columns', 1, 'text', L["Description"], 'func', toggleDescription, 'showWithoutChildren', true, 'checked', true, 'hasCheck', true, 'checkIcon', (not showingDescription) and "Interface\\Buttons\\UI-PlusButton-Up" or "Interface\\Buttons\\UI-MinusButton-Up") if showingDescription then cat:AddLine('text', colorizeQuestText(description, giverName, giverZone), 'wrap', true) end --Rewards: cat = tablet:AddCategory('columns', 2, 'text', L["Rewards"]) local numChoices = GetNumQuestLogChoices(self.questid) -- The ones you choose from local numRewards = GetNumQuestLogRewards(self.questid) -- The ones you always get local rewardMoney = GetQuestLogRewardMoney(self.questid) -- Moolah! local rewardSpellTexture, rewardSpellName = GetQuestLogRewardSpell() -- Sometimes there's a spell if numChoices > 0 or numRewards > 0 or rewardMoney > 0 then if numChoices > 0 then cat:AddLine('text', L["Choose from:"], 'indentation', 2) for i=1, numChoices, 1 do local name, texture, numItems, quality, isUsable = GetQuestLogChoiceInfo(i) cat:AddLine('text', (quality and qualitycolors[quality] or '')..'['..(name or L[""])..']'..((numItems > 1) and (" x"..numItems) or ""), 'indentation', 4, 'checked', true, 'hasCheck', true, 'checkIcon', texture, 'func', itemClick, 'arg1', GetQuestLogItemLink('choice', i)) end end if numRewards > 0 then cat:AddLine('text', L["Always receive:"], 'indentation', 2) for i=1, numRewards, 1 do local name, texture, numItems, quality, isUsable = GetQuestLogRewardInfo(i) cat:AddLine('text', (quality and qualitycolors[quality] or '')..'['..(name or L[""])..']'..((numItems > 1) and (" x"..numItems) or ""), 'indentation', 4, 'checked', true, 'hasCheck', true, 'checkIcon', texture, 'func', itemClick, 'arg1', GetQuestLogItemLink('reward', i)) end end if rewardSpellTexture then cat:AddLine('text', L["Spell:"], 'indentation', 2) cat:AddLine('text', rewardSpellName, 'indentation', 4, 'checked', true, 'hasCheck', true, 'checkIcon', rewardSpellTexture) end if rewardMoney > 0 then cat:AddLine('text', L["Money: "]..abacus:FormatMoneyFull(rewardMoney, true), 'indentation', 2) end else cat:AddLine('text', L["Nothing."], 'indentation', 2) end cat = tablet:AddCategory('columns', 1, 'text', L["Options"]) --Shareable: if GetQuestLogPushable() then cat:AddLine('text', L["- Share"], 'func', 'ShareQuest', 'arg1', self, 'arg2', self.questid,'textR',0,'textG',1,'textB',0) end cat:AddLine('text', L["- Abandon"], 'func', abandonQuestPopup, 'arg1', self.questid,'textR',1,'textG',0,'textB',0.1) cat:AddLine('text', L["[ Close ]"], 'func', hideQuestDetail, 'textR', 1, 'textG', 0.5, 'textB', 0.2, 'justify', 'CENTER') SelectQuestLogEntry(startingQuestLogSelection) end end) tablet:Open('nQuestLog_Detail') end if self.questid then escapeDetector:Show() end tablet:Refresh('nQuestLog_Detail') end function DetailsFrame:AddLeaderboardToCategory(cat, questid, i) local title, level = quixote:GetQuest(questid) local description, qtype, numGot, numNeeded, done = quixote:GetQuestStatusById(questid, i) local r,g,b local thisQuestColor = GetDifficultyColor(level) local function MobmapQuestObj(questobj) if MobMapDotParentFrame then MobMap_ParseQuestObjective(questobj) end end if numGot == nil then self:Print("The author of QuestsFu would very much like to know if you see this message. Email the rest of this line to him at kemayo at gmail dot com.", quixote:GetQuestStatusById(questid, i)) end r,g,b = crayon:GetThresholdColor((qtype == 'reputation' and quixote:GetReactionLevel(numGot) or numGot) / (qtype == 'reputation' and quixote:GetReactionLevel(numNeeded) or numNeeded)) local party = '' for i=1, GetNumPartyMembers(), 1 do local unit = 'party'..i local n = quixote:GetPartyQuestStatus(unit, title, description) if n and type(n) == 'number' then if n == numNeeded then n = 'd' end party = string.format("%s|c00%s%s:%s|r ", party, babbleclass:GetHexColor(UnitClass(unit)), string.sub(UnitName(unit), 1, 3), n) end end cat:AddLine( 'text', ' '..description, 'text2', party .. (done and L["(done)"] or string.format("%s/%s", numGot, numNeeded)), 'textR', r or ((thisQuestColor and thisQuestColor.r) or 1), 'textG', g or ((thisQuestColor and thisQuestColor.g) or 1), 'textB', b or ((thisQuestColor and thisQuestColor.b) or 1), 'text2R', r or ((thisQuestColor and thisQuestColor.r) or 1), 'text2G', g or ((thisQuestColor and thisQuestColor.g) or 1), 'text2B', b or ((thisQuestColor and thisQuestColor.b) or 1), 'size', tablet:GetNormalFontSize()-2, 'size2', tablet:GetNormalFontSize()-2, 'func', MobmapQuestObj, 'arg1', description, 'arg2', questid, 'indentation', 12 ) end function DetailsFrame:ShareQuest(questid) -- Share the quest with nearby party members. local wasSelected = GetQuestLogSelection() SelectQuestLogEntry(questid) if GetQuestLogPushable() and GetNumPartyMembers() > 0 then QuestLogPushQuest() end SelectQuestLogEntry(questid) end