vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 -- MetaMapQST
2 -- Written by MetaHawk - aka Urshurak
3  
4 QST_DELAY = 0.5;
5 QST_BUTTONWIDTH = 400;
6  
7 QST_HEADERCOLOUR = "|cFFBFBFFF";
8 QST_TITLECOLOUR = "|cFFFFFFFF";
9 QST_OVERVIEWCOLOUR = "|cFF7F7F7F";
10 QST_SPECIALCOLOUR = "|cFFFFFF00";
11 QST_INITIALCOLOUR = "|cFFD82619";
12 QST_MIDDLECOLOUR = "|cFFFFFF00";
13 QST_COMPLETEDCOLOUR = "|cFF00FF19";
14  
15 QST_Options = {};
16 QST_QuestLog = {};
17 QST_QuestBase = {};
18 QST_QuestList = {};
19 QST_ItemList = {};
20 QST_AcceptQuest = nil;
21 QST_FinishQuest = nil;
22 QST_AbandonQuest = nil;
23  
24 QST_Default = {
25 ["LoadAlways"] = false,
26 ["ShowPlayers"] = false,
27 ["ShowAll"] = false,
28 ["ShowActive"] = false,
29 ["SaveHistory"] = true,
30 ["SaveDesc"] = true,
31 ["SaveRew"] = true,
32 ["Padding"] = 10,
33 ["SortOrder"] = "logtime",
34 }
35  
36 QST_VarsLoaded = false;
37 QST_ButtonTotal = 0;
38 QST_ActivePlayer = "";
39 QST_SelectedPlayer = "";
40 QST_LastRefresh = 0.0;
41 QST_QuestLogUpdate = false;
42 QST_ShowHeader = true;
43 QST_LastSearch = "";
44 QST_QuestDetail = nil;
45  
46 QST_FilterMenu = {
47 [1] = {QST_SORT_TITLE, "SortOrdertitle"},
48 [2] = {QST_SORT_LEVEL, "SortOrderlevel"},
49 [3] = {QST_SORT_LOGGED, "SortOrderlogtime"},
50 [4] = {"", "", 1},
51 [5] = {QST_FILTER_ALL, "ShowAll"},
52 [6] = {QST_FILTER_MAP, "ShowPlayers"},
53 [7] = {QST_FILTER_ACT, "ShowActive"},
54 [8] = {"", "", 1},
55 }
56  
57 function QST_OnLoad()
58 this:RegisterEvent("ADDON_LOADED");
59 this:RegisterEvent("QUEST_LOG_UPDATE");
60 this:RegisterEvent("QUEST_DETAIL");
61 this:RegisterEvent("QUEST_FINISHED");
62 this:RegisterEvent("UNIT_NAME_UPDATE");
63 this:RegisterEvent("PLAYER_LEVEL_UP");
64 this:RegisterEvent("WORLD_MAP_UPDATE");
65 this:RegisterEvent("ZONE_CHANGED_NEW_AREA");
66 this:RegisterEvent("UPDATE_MOUSEOVER_UNIT");
67 end
68  
69 function QST_OnEvent(event)
70 if(event == "ADDON_LOADED" and arg1 == "MetaMapQST") then
71 QST_LoadConfig();
72 elseif(event == "QUEST_DETAIL") then
73 QST_QuestDetail = GetTitleText();
74 elseif(event == "ZONE_CHANGED_NEW_AREA") then
75 QST_RefreshDisplay();
76 elseif(event == "WORLD_MAP_UPDATE" and QST_DisplayFrame:IsVisible()) then
77 QST_RefreshDisplay();
78 elseif(event == "INSTANCE_MAP_UPDATE" and QST_DisplayFrame:IsVisible()) then
79 QST_RefreshDisplay();
80 elseif(event == "PLAYER_LEVEL_UP" and QST_DisplayFrame:IsVisible()) then
81 QST_ShowDisplay();
82 elseif(event == "UNIT_NAME_UPDATE" and QST_DisplayFrame:IsVisible()) then
83 QST_ShowDisplay();
84 elseif(event == "UPDATE_MOUSEOVER_UNIT") then
85 QST_EnhanceTooltip();
86 elseif(event == "QUEST_LOG_UPDATE") then
87 QST_QuestLogUpdate = true;
88 QST_LastRefresh = 0.0;
89 end
90 end
91  
92 function QST_ToggleFrame(mode)
93 if(mode == 2) then return; end
94 if(QST_DisplayFrame:IsVisible()) then
95 MetaMapContainer_ShowFrame();
96 if(mode == 1) then
97 MetaMap_ToggleFrame(WorldMapFrame);
98 end
99 else
100 if(not WorldMapFrame:IsVisible()) then
101 MetaMap_ToggleFrame(WorldMapFrame);
102 end
103 MetaMapContainer_ShowFrame(QST_DisplayFrame);
104 end
105 end
106  
107 function QST_LoadConfig()
108 --- Hooks
109 QST_Orig_afTooltip = aftt_setName;
110 aftt_setName = QST_afTooltip;
111 QST_Orig_ContainerButtonOnEnter = ContainerFrameItemButton_OnEnter;
112 ContainerFrameItemButton_OnEnter = QST_ContainerButtonOnEnter;
113 Orig_QuestAcceptOnClick = QuestDetailAcceptButton_OnClick;
114 QuestDetailAcceptButton_OnClick = QST_QuestAcceptOnClick;
115 Orig_RewardCompleteOnClick = QuestRewardCompleteButton_OnClick;
116 QuestRewardCompleteButton_OnClick = QST_QuestCompleteOnClick;
117 Orig_AbandonQuest = AbandonQuest;
118 AbandonQuest = QST_AbandonQuestOnClick;
119 if(IsAddOnLoaded("Sanity")) then
120 QST_OrigSanityButtonOnEnter = SanityItemButton_OnEnter;
121 SanityItemButton_OnEnter = QST_SanityButtonOnEnter;
122 end
123 --- End Hooks
124 for option, value in QST_Default do
125 if(QST_Options[option] == nil) then QST_Options[option] = value; end
126 end
127 if(QST_QuestLog == nil) then QST_QuestLog = {}; end
128 QST_ActivePlayer = UnitName("player").." of "..GetCVar("realmName");
129 QST_SelectedPlayer = QST_ActivePlayer;
130 QST_UpdateQuests();
131 QST_UpdatePlayer();
132 UIDropDownMenu_Initialize(QST_FilterSelectMenu, QST_FilterMenuInit, "MENU");
133 UIDropDownMenu_SetText(QST_SelectedPlayer, QST_FilterSelect)
134 QST_VarsLoaded = true;
135 end
136  
137 function QST_OnUpdate(arg1)
138 if(not QST_VarsLoaded) then return; end
139 if(QST_QuestLogUpdate == true) then
140 QST_LastRefresh = QST_LastRefresh + arg1;
141 if(QST_LastRefresh > QST_DELAY) then
142 QST_UpdateQuests();
143 QST_LastRefresh = 0.0;
144 QST_QuestLogUpdate = false;
145 end
146 end
147 end
148  
149 function QST_UpdatePlayer()
150 local tempPlayers = {};
151 local t = table.getn(QST_FilterMenu)+1;
152 for index, qData in QST_QuestLog do
153 for player, value in qData.qPlayer do
154 if(tempPlayers[player] == nil) then
155 tempPlayers[player] = 1;
156 end
157 end
158 end
159 for index, qData in QST_QuestBase do
160 for player, value in qData.qPlayer do
161 if(tempPlayers[player] == nil) then
162 tempPlayers[player] = 1;
163 end
164 end
165 end
166 for player, value in tempPlayers do
167 QST_FilterMenu[t] = {player, "player"};
168 t = t +1;
169 end
170 end
171  
172 function QST_UpdateQuests()
173 local qData, qZone;
174 for qIndex=1, GetNumQuestLogEntries(), 1 do
175 local QuestTitle, _, _, isHeader = GetQuestLogTitle(qIndex);
176 if(isHeader) then
177 qZone = QuestTitle;
178 else
179 SelectQuestLogEntry(qIndex);
180 for index, qQuests in QST_QuestLog do
181 if(qQuests.qTitle == QuestTitle and qQuests.qPlayer[QST_ActivePlayer]) then
182 qData = qQuests; break;
183 end
184 end
185 if(qData) then
186 QST_UpdateDataBase(qData, qIndex);
187 else
188 local n = table.getn(QST_QuestLog)+1;
189 QST_QuestLog[n] = {};
190 QST_CreateDatabase(QST_QuestLog[n], qZone, qIndex);
191 end
192 qData = nil;
193 end
194 end
195 QST_SetLogOrder();
196 if(QST_DisplayFrame:IsVisible()) then
197 QST_RefreshDisplay();
198 end
199 end
200  
201 function QST_SetLogOrder()
202 local TmpData = {};
203 local new = 1;
204 for index, value in QST_QuestLog do
205 TmpData[new] = {};
206 TmpData[new] = value;
207 new = new +1;
208 end
209 QST_QuestLog = {};
210 QST_QuestLog = TmpData;
211 end
212  
213 function QST_UpdateDataBase(qData, qIndex)
214 local QuestTitle, QuestLevel, QuestTag, isHeader, isCollapsed, isComplete = GetQuestLogTitle(qIndex);
215 local Description, Objectives = GetQuestLogQuestText();
216 local status = "";
217 if(isComplete == nil) then status = QST_MIDDLECOLOUR..QST_QUEST_ACTIVE;
218 elseif(isComplete < 0) then status = QST_INITIALCOLOUR..QST_QUEST_FAILED;
219 elseif(isComplete == 1) then status = QST_COMPLETEDCOLOUR..QST_QUEST_DONE; end
220  
221 qData.qIndex = qIndex;
222 qData["qPlayer"][QST_ActivePlayer]["qStatus"] = status;
223 if(QST_AcceptQuest and QST_AcceptQuest.Title == QuestTitle) then
224 qData["qNPC"][1] = {};
225 qData["qNPC"][1].qName = QST_AcceptQuest.NPC;
226 qData["qNPC"][1].qZone = QST_AcceptQuest.zone;
227 qData["qNPC"][1].qX = QST_AcceptQuest.xPos;
228 qData["qNPC"][1].qY = QST_AcceptQuest.yPos;
229 QST_AcceptQuest = nil;
230 end
231 QST_UpdateQuestItems(QuestTitle, qData);
232 end
233  
234 function QST_CreateDatabase(qData, qZone, qIndex)
235 local QuestTitle, QuestLevel, QuestTag, isHeader, isCollapsed, isComplete = GetQuestLogTitle(qIndex);
236 local Description, Objectives = GetQuestLogQuestText();
237 local continent, zone = MetaMap_NameToZoneID(qZone);
238 local status = "";
239  
240 if(isComplete == nil) then status = QST_MIDDLECOLOUR..QST_QUEST_ACTIVE;
241 elseif(isComplete < 0) then status = QST_INITIALCOLOUR..QST_QUEST_FAILED;
242 elseif(isComplete == 1) then status = QST_COMPLETEDCOLOUR..QST_QUEST_DONE; end
243 if(zone == 0) then qData["qArea"] = GetRealZoneText(); end
244  
245 qData["qTitle"] = QuestTitle;
246 qData["qZone"] = qZone;
247 qData["qObj"] = Objectives;
248 qData["qDesc"] = Description;
249 qData["qLogtime"] = GetTime();
250 qData["qNote"] = "";
251 qData["qMoney"] = GetQuestLogRewardMoney();
252 qData["qLevel"] = QuestLevel;
253 qData["qTag"] = QuestTag;
254 qData["qIndex"] = qIndex;
255 qData["qPlayer"] = {};
256 qData["qNPC"] = {};
257 qData["qPlayer"][QST_ActivePlayer] = {};
258 qData["qPlayer"][QST_ActivePlayer]["qStatus"] = status;
259  
260 if(GetNumQuestLogRewards() > 0) then
261 qData["qReward"] = {};
262 for index=1, GetNumQuestLogRewards(), 1 do
263 local name, texture, numItems, quality, isUsable = GetQuestLogRewardInfo(index);
264 qData["qReward"][index] = {};
265 qData["qReward"][index]["qAmount"] = numItems;
266 qData["qReward"][index]["qLink"] = GetQuestLogItemLink("reward", index);
267 qData["qReward"][index]["qTex"] = texture;
268 end
269 end
270 if(GetNumQuestLogChoices() > 0) then
271 qData["qChoice"] = {};
272 for index=1, GetNumQuestLogChoices(), 1 do
273 local name, texture, numItems, quality, isUsable = GetQuestLogChoiceInfo(index);
274 qData["qChoice"][index] = {};
275 qData["qChoice"][index]["qAmount"] = numItems;
276 qData["qChoice"][index]["qLink"] = GetQuestLogItemLink("choice", index);
277 qData["qChoice"][index]["qTex"] = texture;
278 end
279 end
280 if(GetQuestLogRewardSpell()) then
281 qData["qSpell"] = {};
282 local texture, name = GetQuestLogRewardSpell();
283 qData["qSpell"] = {};
284 qData["qSpell"]["qLink"] = name;
285 qData["qSpell"]["qTex"] = texture;
286 end
287 if(QST_AcceptQuest and QST_AcceptQuest.Title == QuestTitle) then
288 qData["qNPC"][1] = {};
289 qData["qNPC"][1].qName = QST_AcceptQuest.NPC;
290 qData["qNPC"][1].qZone = QST_AcceptQuest.zone;
291 qData["qNPC"][1].qX = QST_AcceptQuest.xPos;
292 qData["qNPC"][1].qY = QST_AcceptQuest.yPos;
293 QST_AcceptQuest = nil;
294 end
295 QST_UpdateQuestItems(QuestTitle, qData);
296 end
297  
298 function QST_UpdateQuestItems(QuestTitle, qData)
299 if(GetNumQuestLeaderBoards() > 0) then
300 qData["qItems"] = {};
301 for index=1, GetNumQuestLeaderBoards(), 1 do
302 local LeaderBoardText, iType, Finished = GetQuestLogLeaderBoard(index);
303 local i, j, ItemName, NumItems, NumNeeded = string.find(LeaderBoardText, "(.*):%s*([-%d]+)%s*/%s*([-%d]+)%s*$");
304 if(NumItems ~= nil) then
305 local slain = "";
306 i, j = string.find(ItemName, QST_TOOLTIP_SLAIN);
307 if(i ~= nil) then
308 ItemName = string.sub(ItemName, 1, i - 2);
309 slain = " "..QST_TOOLTIP_SLAIN;
310 end
311 qData["qItems"][index] = {};
312 qData["qItems"][index] = ItemName..slain..": "..NumItems.."/"..NumNeeded;
313 QST_ItemList[ItemName] = {};
314 QST_ItemList[ItemName]["qTitle"] = QuestTitle;
315 QST_ItemList[ItemName]["qItems"] = NumItems.."/"..NumNeeded;
316 end
317 end
318 end
319 end
320  
321 function QST_RefreshDisplay()
322 QST_QuestList = {};
323 local qCount2, qTotal2, aCount2, aTotal2 = QST_DisplayInit("QST_QuestBase");
324 local qCount1, qTotal1, aCount1, aTotal1 = QST_DisplayInit("QST_QuestLog");
325 QST_InfoText1:SetText(QST_QUEST_TEXT..": "..qCount1 + qCount2.."/"..qTotal1 + qTotal2);
326 QST_InfoText2:SetText(QST_QUEST_ACTIVE..": "..aCount1 + aCount2.."/"..aTotal1 + aTotal2);
327 QST_SortQuestList(QST_Options.SortOrder);
328 QST_ShowDisplay();
329 end
330  
331 function QST_DisplayInit(qDB)
332 QST_ShowHeader = true;
333 local qBase = getglobal(qDB);
334 local questCount, questTotal, activeCount, activeTotal = 0,0,0,0;
335 local mapContinent, mapZone, _, mapName = MetaMap_GetCurrentMapInfo();
336 QST_HeaderText:SetText(mapName);
337  
338 for index, qData in qBase do
339 local showThis = false;
340 local continent, zone;
341 questTotal = questTotal +1;
342 if(qData.qIndex) then activeTotal = activeTotal +1; end
343 if(qData.qArea) then
344 if(QST_GetLandMark(qData.qZone)) then showThis = true;
345 elseif(qData.qArea == mapName) then showThis = true;
346 else continent, zone = MetaMap_NameToZoneID(qData.qArea); end
347 else
348 continent, zone = MetaMap_NameToZoneID(qData.qZone);
349 end
350 if(mapName == "World") then showThis = true; end
351 if(continent == mapContinent and mapName == "Kalimdor") then showThis = true; end
352 if(continent == mapContinent and mapName == "Eastern Kingdoms") then showThis = true; end
353 if(continent == mapContinent and zone == mapZone) then showThis = true; end
354 if(not QST_Options.ShowPlayers and not qData["qPlayer"][QST_SelectedPlayer]) then showThis = false; end
355 if(QST_Options.ShowActive and not qData.qIndex) then showThis = false; end
356 if(qData.qZone == mapName and not QST_Options.ShowAll) then QST_ShowHeader = false; end
357 if(qData.qArea and qData.qArea == mapName and not QST_Options.ShowAll) then QST_ShowHeader = false; end
358 if(showThis or QST_Options.ShowAll) then
359 if(string.find(string.lower(qData.qTitle),string.lower(QST_LastSearch),1,true)~=nil
360 or string.find(string.lower(qData.qDesc),string.lower(QST_LastSearch),1,true)~=nil
361 or string.find(string.lower(qData.qObj),string.lower(QST_LastSearch),1,true)~=nil
362 or string.find(string.lower(qData.qZone),string.lower(QST_LastSearch),1,true)~=nil
363 or string.find(string.lower(qData.qNote),string.lower(QST_LastSearch),1,true)~=nil) then
364 tinsert(QST_QuestList, {qTitle = qData.qTitle, qZone = qData.qZone, qLevel = qData.qLevel, qLogtime = qData.qLogtime, qDB = qDB, qIndex = index});
365 if(qData["qPlayer"][QST_SelectedPlayer]) then
366 if(string.find(qData["qPlayer"][QST_SelectedPlayer]["qStatus"], "Active")) then activeCount = activeCount +1; end
367 end
368 questCount = questCount + 1;
369 end
370 end
371 end
372 return questCount, questTotal, activeCount, activeTotal;
373 end
374  
375 function QST_SortQuestList(sort)
376 local tmpList = {};
377 local name = "";
378 local tmp = MetaMap_sortType;
379 MetaMap_sortType = METAMAP_SORTBY_NAME;
380 for index, value in QST_QuestList do
381 if(sort == "title") then
382 name = value.qZone..value.qTitle..value.qLevel;
383 elseif(sort == "level") then
384 name = value.qZone..value.qLevel..value.qTitle;
385 else
386 name = value.qZone..value.qLogtime;
387 end
388 tinsert(tmpList, {qTitle = value.qTitle, qZone = value.qZone, qLevel = value.qLevel, qLogtime = value.qLogtime, qDB = value.qDB, qIndex = value.qIndex, name = name});
389 end
390 QST_QuestList = {};
391 table.sort(tmpList, MetaMap_SortCriteria);
392 for index, value in tmpList do
393 tinsert(QST_QuestList, {qTitle = value.qTitle, qZone = value.qZone, qLevel = value.qLevel, qLogtime = value.qLogtime, qDB = value.qDB, qIndex = value.qIndex});
394 end
395 tmpList = nil;
396 MetaMap_sortType = tmp;
397 end
398  
399 function QST_ShowDisplay()
400 local questInfo = "";
401 local buttonID = 1;
402 local setHeader = "";
403 local ScrollHeight = 0;
404  
405 for index, qList in QST_QuestList do
406 local qData = getglobal(qList.qDB)[qList.qIndex];
407 if(QST_ShowHeader and setHeader ~= qData.qZone) then
408 local area = "";
409 local button = QST_CreateButton(buttonID);
410 local buttontext = getglobal("QSTButton"..buttonID.."Text");
411 if(qData.qArea) then area = " ("..qData.qArea..")"; end
412 buttontext:SetText(format(QST_HEADERCOLOUR.."%s|r", qData.qZone..area).."\n");
413 if(buttonID == 1) then
414 button:SetPoint("TOPLEFT", "QST_ScrollChild", "TOPLEFT", 10, -10)
415 else
416 button:SetPoint("TOP", getglobal("QSTButton"..buttonID-1), "BOTTOM", 0, 0)
417 end
418 if(qData.qArea) then
419 button.qMap = qData.qArea;
420 else
421 button.qMap = qData.qZone;
422 end
423 button.qDB = qList.qDB;
424 button.qIndex = qList.qIndex;
425 buttontext:SetWidth(QST_BUTTONWIDTH);
426 button:SetHeight(buttontext:GetHeight() + QST_Options.Padding);
427 button:SetParent("QST_ScrollChild");
428 button:Show();
429 ScrollHeight = ScrollHeight + button:GetHeight();
430 setHeader = qData.qZone;
431 buttonID = buttonID +1;
432 end
433 local button = QST_CreateButton(buttonID);
434 local buttontext = getglobal("QSTButton"..buttonID.."Text");
435 if(buttonID == 1) then
436 button:SetPoint("TOPLEFT", "QST_ScrollChild", "TOPLEFT", 10, -10)
437 else
438 button:SetPoint("TOP", getglobal("QSTButton"..buttonID-1), "BOTTOM", 0, 0)
439 end
440 local col = GetDifficultyColor(qData.qLevel);
441 local cText = "|c%02X%02X%02X%02X%s|r";
442 local R = col.r * 255; local G = col.g * 255; local B = col.b * 255;
443 questInfo = questInfo.." ";
444 if(qData.qTag == ELITE) then
445 questInfo = questInfo..format(cText, 255, R, G, B, "["..qData.qLevel.."+] ");
446 elseif(qData.qTag == QST_DUNGEON) then
447 questInfo = questInfo..format(cText, 255, R, G, B, "["..qData.qLevel.."d] ");
448 elseif(qData.qTag == RAID) then
449 questInfo = questInfo..format(cText, 255, R, G, B, "["..qData.qLevel.."r] ");
450 elseif(qData.qTag == QST_PVP) then
451 questInfo = questInfo..format(cText, 255, R, G, B, "["..qData.qLevel.."p] ");
452 else
453 questInfo = questInfo..format(cText, 255, R, G, B, "["..qData.qLevel.."] ");
454 end
455 questInfo = questInfo..format(QST_TITLECOLOUR.."%s|r", qData.qTitle).."\n";
456 if(qData.qItems) then
457 for x, value in qData.qItems, 1 do
458 questInfo = questInfo.." "..QST_GetColourString(value)..value.."\n";
459 end
460 else
461 questInfo = questInfo.." "..format(QST_OVERVIEWCOLOUR.."%s|r", qData.qObj).."\n";
462 end
463 if(qData.qIndex) then
464 for index, name in QST_FilterMenu do
465 if(qData.qPlayer[name[1]]) then
466 getglobal("QSTButton"..buttonID.."Status"):SetText(qData.qPlayer[name[1]].qStatus);
467 end
468 end
469 else
470 getglobal("QSTButton"..buttonID.."Status"):SetText(QST_QUEST_HISTORY);
471 end
472 if(strlen(qData.qNote) > 0) then
473 getglobal("QSTButton"..buttonID.."Noted"):SetText(QST_HEADERCOLOUR..QST_NOTE_FLAG);
474 end
475 button.qDB = qList.qDB;
476 button.qIndex = qList.qIndex;
477 buttontext:SetText(questInfo);
478 buttontext:SetWidth(QST_BUTTONWIDTH);
479 button:SetHeight(buttontext:GetHeight() + QST_Options.Padding);
480 button:SetParent("QST_ScrollChild");
481 buttontext:Show();
482 button:Show();
483 questInfo = "";
484 buttonID = buttonID + 1;
485 ScrollHeight = ScrollHeight + button:GetHeight();
486 end
487 for i=buttonID, QST_ButtonTotal, 1 do
488 getglobal("QSTButton"..i):Hide()
489 end
490 QST_ScrollChild:SetHeight(ScrollHeight);
491 QST_ScrollFrame:UpdateScrollChildRect()
492 end
493  
494 function QST_FilterMenuInit()
495 for index, menuItem in QST_FilterMenu do
496 local check = nil;
497 local spacer = nil;
498 if(menuItem[3]) then spacer = 1; end
499 if(menuItem[2] == "player") then
500 if(QST_Options.ShowPlayers) then
501 check = 1;
502 elseif(menuItem[1] == QST_SelectedPlayer) then
503 check = 1;
504 end
505 elseif(QST_Options.SortOrder == string.gsub(menuItem[2], "SortOrder", "")) then
506 check = 1;
507 elseif(QST_Options[menuItem[2]]) then
508 check = 1;
509 end
510 local info = {};
511 info.isTitle = spacer;
512 info.notClickable = spacer;
513 info.checked = check;
514 info.text = menuItem[1];
515 info.value = menuItem[2];
516 info.func = QST_FilterMenuOnClick;
517 UIDropDownMenu_AddButton(info);
518 end
519 end
520  
521 function QST_FilterMenuOnClick()
522 if(this.value == "player") then
523 QST_SelectedPlayer = this:GetText();
524 QST_Options.ShowPlayers = false;
525 elseif(string.find(this.value, "SortOrder")) then
526 QST_Options.SortOrder = string.gsub(this.value, "SortOrder", "");
527 QST_SortQuestList(QST_Options.SortOrder);
528 QST_ShowDisplay();
529 return;
530 else
531 QST_ToggleOptions(this.value);
532 end
533 UIDropDownMenu_SetText(this:GetText(), QST_FilterSelect);
534 QST_RefreshDisplay();
535 end
536  
537 function QSTButton_OnEnter()
538 local qData = getglobal(this.qDB)[this.qIndex];
539 if(not qData or QST_RewardFrame:IsVisible() or QST_EditorFrame:IsVisible()) then return; end
540 WorldMapTooltip:SetOwner(QST_DisplayFrame, "ANCHOR_BOTTOMRIGHT", 0, QST_DisplayFrame:GetHeight()* QST_DisplayFrame:GetEffectiveScale());
541 if(IsControlKeyDown()) then
542 WorldMapTooltip:SetText(qData.qTitle, 1, 1, 1, 1);
543 WorldMapTooltip:AddLine(qData.qNote, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1);
544 elseif(IsShiftKeyDown()) then
545 WorldMapTooltip:SetText(qData.qTitle, 1, 1, 1, 1);
546 if(qData.qNPC[1]) then
547 WorldMapTooltip:AddDoubleLine("QuestStart:", QST_COMPLETEDCOLOUR..qData.qNPC[1].qName, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1);
548 end
549 if(qData.qNPC[2]) then
550 WorldMapTooltip:AddDoubleLine("QuestEnd:", QST_COMPLETEDCOLOUR..qData.qNPC[2].qName, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1);
551 end
552 WorldMapTooltip:AddLine(" ", 0, 0, 0, 0);
553 for name, value in qData.qPlayer do
554 WorldMapTooltip:AddDoubleLine(name, value.qStatus, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1);
555 end
556 else
557 WorldMapTooltip:SetText(qData.qTitle, 1, 1, 1, 1);
558 WorldMapTooltip:AddLine(qData.qObj, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1);
559 WorldMapTooltip:AddLine(" ", 0, 0, 0, 0);
560 if(qData.qDesc) then
561 WorldMapTooltip:AddLine(qData.qDesc, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1);
562 end
563 WorldMapTooltip:AddLine(qData.qTag, 1, 0, 1, 1);
564 if(qData.qIndex) then
565 SelectQuestLogEntry(qData.qIndex);
566 for i = 1, GetNumPartyMembers() do
567 if(IsUnitOnQuest(qData.qIndex, "party"..i)) then
568 WorldMapTooltip:AddLine(QST_COMPLETEDCOLOUR..UnitName("party"..i));
569 else
570 WorldMapTooltip:AddLine(QST_INITIALCOLOUR..UnitName("party"..i));
571 end
572 end
573 end
574 end
575 WorldMapTooltip:SetPoint("TOPRIGHT", QST_DisplayFrame, "TOPRIGHT", 0, 0);
576 WorldMapTooltip:Show();
577 end
578  
579 function QSTButton_OnClick(button)
580 local qData = getglobal(this.qDB)[this.qIndex];
581 QST_EditorFrame:Hide()
582 if(this.qMap) then
583 local continent, zone = MetaMap_NameToZoneID(this.qMap, 1);
584 if(continent == 0 and zone > 0) then
585 MetaMap_CurrentMap = zone;
586 MetaMap_Toggle(true);
587 else
588 SetMapZoom(continent, zone);
589 end
590 return;
591 end
592 if(IsShiftKeyDown() and ChatFrameEditBox:IsVisible()) then
593 if(button == "LeftButton") then
594 if(qData.qTag == ELITE) then
595 ChatFrameEditBox:Insert("["..qData.qLevel.."+] "..qData.qTitle.." ");
596 elseif(qData.qTag == QST_DUNGEON) then
597 ChatFrameEditBox:Insert("["..qData.qLevel.."d] "..qData.qTitle.." ");
598 elseif(qData.qTag == RAID) then
599 ChatFrameEditBox:Insert("["..qData.qLevel.."r] "..qData.qTitle.." ");
600 elseif(qData.qTag == QST_PVP) then
601 ChatFrameEditBox:Insert("["..qData.qLevel.."p] "..qData.qTitle.." ");
602 else
603 ChatFrameEditBox:Insert("["..qData.qLevel.."] "..qData.qTitle.." ");
604 end
605 else
606 local ChatItems = "";
607 if(qData.qItems) then
608 for i, value in qData.qItems, 1 do
609 ChatItems = ChatItems.."{"..qData.qItems[i].."} ";
610 end
611 else
612 ChatItems = ChatItems.."{"..qData.qObj.."} ";
613 end
614 ChatFrameEditBox:Insert(ChatItems);
615 end
616 return;
617 elseif(IsControlKeyDown() and qData.qIndex) then
618 if(button == "LeftButton") then
619 SelectQuestLogEntry(qData.qIndex);
620 if(GetQuestLogPushable() and GetNumPartyMembers() > 0) then
621 QuestLogPushQuest();
622 end
623 else
624 SelectQuestLogEntry(qData.qIndex);
625 SetAbandonQuest();
626 StaticPopup_Show("ABANDON_QUEST", GetAbandonQuestName());
627 QST_AbandonQuest = GetAbandonQuestName();
628 end
629 return;
630 else
631 if(button == "LeftButton") then
632 QST_RewardFrameShow(this.qDB, this.qIndex);
633 else
634 QST_QuestNoteShow(this.qDB, this.qIndex);
635 end
636 end
637 end
638  
639 function QST_RewardFrameShow(qDB, qIndex)
640 local qData = getglobal(qDB)[qIndex];
641 local height = 100;
642 local rewardCount, choiceCount, spellCount = 0,0,0;
643 local receiveText = getglobal("QST_RewardItemReceiveText");
644 local chooseText = getglobal("QST_RewardItemChooseText");
645  
646 if(qData.qChoice) then
647 chooseText:Show();
648 height = height + 14
649 for i, choice in qData.qChoice do
650 local _, _, itemLink, itemName = string.find(choice.qLink, "|H(item:%d+:%d+:%d+:%d+)|h%[([^]]+)%]|h|r$");
651 rewardItem = getglobal("QST_RewardItem"..i);
652 rewardItem.type = "choice";
653 rewardItem.rewardType = "item";
654 rewardItem.link = choice.qLink;
655 rewardItem.itemID = itemLink;
656 rewardItem:Show();
657 SetItemButtonCount(rewardItem, choice.qAmount);
658 SetItemButtonTexture(rewardItem, choice.qTex);
659 if(qData.qIndex and qData.qPlayer[QST_ActivePlayer]) then
660 SelectQuestLogEntry(qData.qIndex);
661 _, _, _, _, isUsable = GetQuestLogChoiceInfo(i);
662 if(isUsable) then
663 SetItemButtonTextureVertexColor(rewardItem, 1.0, 1.0, 1.0);
664 else
665 SetItemButtonTextureVertexColor(rewardItem, 0.9, 0, 0);
666 end
667 else
668 SetItemButtonTextureVertexColor(rewardItem, 1.0, 1.0, 1.0);
669 end
670 if(i > 1) then
671 if(mod(i,2) == 1) then
672 rewardItem:SetPoint("TOPLEFT", "QST_RewardItem"..(i - 2), "BOTTOMLEFT", 0, -2);
673 height = height + 40
674 else
675 rewardItem:SetPoint("TOPLEFT", "QST_RewardItem"..(i - 1), "TOPRIGHT", 20, 0);
676 end
677 else
678 rewardItem:SetPoint("TOPLEFT", "QST_RewardItemChooseText", "BOTTOMLEFT", 20, -5);
679 height = height + 40
680 end
681 choiceCount = i;
682 end
683 else
684 chooseText:Hide();
685 end
686 if(qData.qReward or qData.qSpell or (qData.qMoney and qData.qMoney > 0)) then
687 height = height + 16;
688 receiveText:Show();
689 if(qData.qChoice) then
690 local index = choiceCount;
691 if(mod(index, 2) == 0 ) then
692 index = index - 1;
693 end
694 receiveText:SetText(TEXT(REWARD_ITEMS));
695 receiveText:SetPoint("TOPLEFT", "QST_RewardItem"..index, "BOTTOMLEFT", -20, -5);
696 else
697 receiveText:SetText(TEXT(REWARD_ITEMS_ONLY));
698 receiveText:SetPoint("TOPLEFT", "QST_RewardFrame", "TOPLEFT", 20, -45);
699 end
700 if(qData.qReward) then
701 getglobal("QST_RewardItemReceiveText"):Show();
702 for i, reward in qData.qReward do
703 local _, _, itemLink, itemName = string.find(reward.qLink, "|H(item:%d+:%d+:%d+:%d+)|h%[([^]]+)%]|h|r$");
704 rewardItem = getglobal("QST_RewardItem"..(i + choiceCount));
705 rewardItem.type = "reward";
706 rewardItem.rewardType = "item";
707 rewardItem.link = reward.qLink;
708 rewardItem.itemID = itemLink;
709 rewardItem:Show();
710 SetItemButtonCount(rewardItem, reward.qAmount);
711 SetItemButtonTexture(rewardItem, reward.qTex);
712 if(qData.qIndex and qData.qPlayer[QST_ActivePlayer]) then
713 SelectQuestLogEntry(qData.qIndex);
714 _, _, _, _, isUsable = GetQuestLogRewardInfo(i);
715 if(isUsable) then
716 SetItemButtonTextureVertexColor(rewardItem, 1.0, 1.0, 1.0);
717 else
718 SetItemButtonTextureVertexColor(rewardItem, 0.9, 0, 0);
719 end
720 else
721 SetItemButtonTextureVertexColor(rewardItem, 1.0, 1.0, 1.0);
722 end
723 if(i > 1) then
724 if(mod(i,2) == 1) then
725 rewardItem:SetPoint("TOPLEFT", "QST_RewardItem"..((i + choiceCount) - 2), "BOTTOMLEFT", 0, -2);
726 height = height + 40
727 else
728 rewardItem:SetPoint("TOPLEFT", "QST_RewardItem"..((i + choiceCount) - 1), "TOPRIGHT", 20, 0);
729 end
730 else
731 rewardItem:SetPoint("TOPLEFT", "QST_RewardItemReceiveText", "BOTTOMLEFT", 20, -5);
732 height = height + 40
733 end
734 rewardCount = i;
735 end
736 end
737 if(qData.qSpell) then
738 local _, _, itemLink, itemName = string.find(qData.qSpell.qLink, "|H(item:%d+:%d+:%d+:%d+)|h%[([^]]+)%]|h|r$");
739 rewardItem = getglobal("QST_RewardItem"..(rewardCount + choiceCount + 1));
740 rewardItem.rewardType = "spell";
741 rewardItem.name = itemName;
742 rewardItem.itemID = itemLink;
743 rewardItem:Show();
744 SetItemButtonTexture(rewardItem, qData.qSpell.qTex);
745 if(rewardsCount > 0) then
746 if(mod(rewardCount,2) == 0) then
747 rewardItem:SetPoint("TOPLEFT", "QST_RewardItem"..((rewardCount + choiceCount) - 1), "BOTTOMLEFT", 0, -2);
748 height = height + 40
749 else
750 rewardItem:SetPoint("TOPLEFT", "QST_RewardItem"..((rewardCount + choiceCount)), "TOPRIGHT", 20, 0);
751 end
752 else
753 rewardItem:SetPoint("TOPLEFT", "QST_RewardItemReceiveText", "BOTTOMLEFT", 20, -5);
754 height = height + 40
755 end
756 spellCount = 1;
757 end
758 else
759 receiveText:Hide();
760 end
761 local totalRewards = rewardCount + choiceCount + spellCount;
762 for i=totalRewards + 1, 10, 1 do
763 getglobal("QST_RewardItem"..i):Hide();
764 end
765 if(totalRewards > 0 or (qData.qMoney and qData.qMoney > 0)) then
766 MoneyFrame_Update("QST_RewardMoneyFrame", qData.qMoney);
767 local x, y = GetCursorPosition();
768 x = x / UIParent:GetEffectiveScale();
769 y = y / UIParent:GetEffectiveScale();
770 QST_RewardFrame:SetPoint("LEFT", "UIParent", "BOTTOMLEFT", x-20, y);
771 QST_RewardFrame:SetHeight(height);
772 QST_RewardFrame:Show();
773 end
774 end
775  
776 function QST_RewardItemOnClick()
777 if(IsControlKeyDown()) then
778 if(this.rewardType ~= "spell") then
779 MetaMap_ToggleDR(1);
780 DressUpItemLink(this.itemID);
781 DressUpFrame:Show();
782 DressUpItemLink(this.itemID);
783 end
784 elseif(IsShiftKeyDown()) then
785 if(ChatFrameEditBox:IsVisible()) then
786 ChatFrameEditBox:Insert(this.link);
787 end
788 end
789 end
790  
791 function QST_QuestNoteShow(qDB, qIndex)
792 local qData = getglobal(qDB)[qIndex];
793 QST_SaveNote.qDB = qDB;
794 QST_SaveNote.qIndex = qIndex;
795 QST_NotesEditBox:SetText(qData.qNote);
796 QST_EditorFrame:Show();
797 QST_NotesEditBox:SetFocus();
798 end
799  
800 function QST_QuestNoteUpdate()
801 local qData = getglobal(this.qDB)[this.qIndex];
802 qData.qNote = QST_NotesEditBox:GetText();
803 QST_EditorFrame:Hide();
804 QST_ShowDisplay();
805 end
806  
807 function QST_QuestAcceptOnClick()
808 local x, y = GetPlayerMapPosition("player");
809 local questStart = UnitName("target");
810 if(questStart == nil) then questStart = "Quest Item"; end
811 QST_AcceptQuest = {};
812 QST_AcceptQuest.Title = QST_QuestDetail;
813 QST_AcceptQuest.NPC = questStart;
814 QST_AcceptQuest.zone = GetRealZoneText();
815 QST_AcceptQuest.xPos = x;
816 QST_AcceptQuest.yPos = y;
817 QST_QuestDetail = nil;
818 Orig_QuestAcceptOnClick();
819 end
820  
821 function QST_QuestCompleteOnClick()
822 local qIndex, qLog;
823 local x, y = GetPlayerMapPosition("player");
824 local questStart = UnitName("target");
825 if(questStart == nil) then questStart = "Unknown"; end
826 for index, qQuests in QST_QuestLog do
827 if(qQuests.qTitle == GetTitleText() and qQuests.qPlayer[QST_ActivePlayer]) then
828 qIndex = index; qLog = qQuests; break;
829 end
830 end
831 if(qIndex) then
832 if(QST_Options.SaveHistory) then
833 qLog.qIndex = nil;
834 qLog.qPlayer[QST_ActivePlayer].qStatus = QST_COMPLETEDCOLOUR..QST_QUEST_DONE;
835 qLog.qNPC[2] = {};
836 qLog.qNPC[2]["qName"] = questStart;
837 qLog.qNPC[2]["qZone"] = GetRealZoneText;
838 qLog.qNPC[2]["qX"] = x;
839 qLog.qNPC[2]["qY"] = y;
840 for index, qQuests in QST_QuestBase do
841 if(qLog.qTitle == qQuests.qTitle and qLog.qObj == qQuests.qObj) then
842 qBase = qQuests; break;
843 end
844 end
845 if(qBase) then
846 qBase.qNote = qBase.qNote.."\n\n"..qLog.qNote;
847 qBase.qPlayer[QST_ActivePlayer] = {};
848 qBase.qPlayer[QST_ActivePlayer] = qLog.qPlayer[QST_ActivePlayer];
849 qBase.qNPC[2] = qLog.qNPC[2];
850 else
851 if(not QST_Options.SaveDesc) then
852 qLog.qDesc = nil;
853 end
854 if(not QST_Options.SaveRew) then
855 qLog.qReward = nil; qLog.qChoice = nil; qLog.qSpell = nil;
856 end
857 QST_QuestBase[table.getn(QST_QuestBase)+1] = qLog;
858 end
859 end
860 QST_QuestLog[qIndex] = nil;
861 end
862 Orig_RewardCompleteOnClick();
863 end
864  
865 function QST_AbandonQuestOnClick()
866 local qIndex, qLog;
867 for index, qQuests in QST_QuestLog do
868 if(qQuests.qTitle == QST_AbandonQuest and qQuests.qPlayer[QST_ActivePlayer]) then
869 qIndex = index; qLog = qQuests; break;
870 end
871 end
872 if(qIndex) then
873 if(QST_Options.SaveHistory) then
874 qLog.qIndex = nil;
875 qLog.qPlayer[QST_ActivePlayer].qStatus = QST_INITIALCOLOUR..QST_QUEST_ABANDON;
876 for index, qQuests in QST_QuestBase do
877 if(qLog.qTitle == qQuests.qTitle and qLog.qObj == qQuests.qObj) then
878 qBase = qQuests; break;
879 end
880 end
881 if(qBase) then
882 qBase.qNote = qBase.qNote.."\n\n"..qLog.qNote;
883 qBase.qPlayer[QST_ActivePlayer] = {};
884 qBase.qPlayer[QST_ActivePlayer] = qLog.qPlayer[QST_ActivePlayer];
885 else
886 if(not QST_Options.SaveDesc) then
887 qLog.qDesc = nil;
888 end
889 if(not QST_Options.SaveRew) then
890 qLog.qReward = nil; qLog.qChoice = nil; qLog.qSpell = nil;
891 end
892 QST_QuestBase[table.getn(QST_QuestBase)+1] = qLog;
893 end
894 end
895 QST_QuestLog[qIndex] = nil;
896 end
897 Orig_AbandonQuest();
898 end
899  
900 function QST_afTooltip(unit)
901 QST_Orig_afTooltip(unit);
902 QST_EnhanceTooltip();
903 end
904  
905 function QST_ContainerButtonOnEnter()
906 QST_Orig_ContainerButtonOnEnter();
907 QST_EnhanceTooltip();
908 end
909  
910 function QST_SanityButtonOnEnter()
911 QST_OrigSanityButtonOnEnter();
912 QST_EnhanceTooltip();
913 end
914  
915 function QST_EnhanceTooltip()
916 if(GameTooltip == nil) then return; end
917 if(not QST_ItemList) then return; end
918 if(getglobal('GameTooltipTextLeft1'):GetText() ~= nil) then
919 local itemName = string.gsub(getglobal('GameTooltipTextLeft1'):GetText(),"|c........(.*)|?r?","%1");
920 if(QST_ItemList[itemName] == nil) then return; end
921 if(getglobal('GameTooltipTextLeft2'):GetText() ~= ITEM_BIND_QUEST) then
922 GameTooltip:AddLine(ITEM_BIND_QUEST, 1, 1, 1, 1);
923 GameTooltip:SetHeight(GameTooltip:GetHeight() + 14);
924 end
925 GameTooltip:AddLine(QST_ItemList[itemName].qTitle..": "..QST_ItemList[itemName].qItems, 1, 0, 1, 1);
926 length = getglobal(GameTooltip:GetName() .. "TextLeft" .. GameTooltip:NumLines()):GetStringWidth();
927 length = length + 22;
928 GameTooltip:SetHeight(GameTooltip:GetHeight() + 14);
929 if(length > GameTooltip:GetWidth()) then
930 GameTooltip:SetWidth(length);
931 end
932 end
933 end
934  
935 function QST_HintTooltip()
936 WorldMapTooltip:SetOwner(this, "ANCHOR_TOPLEFT");
937 WorldMapTooltip:SetText(QST_TTHINT_H0, 0.2, 0.5, 1, 1);
938 WorldMapTooltip:AddLine(QST_TTHINT_H1, 0, 1, 0, 1);
939 WorldMapTooltip:AddDoubleLine("Shift-onEnter", QST_TTHINT_T0, 1, 1, 1, 1);
940 WorldMapTooltip:AddDoubleLine("Ctrl-onEnter", QST_TTHINT_T1, 1, 1, 1, 1);
941 WorldMapTooltip:AddDoubleLine("Left-Click", QST_TTHINT_T2, 1, 1, 1, 1);
942 WorldMapTooltip:AddDoubleLine("Right-Click", QST_TTHINT_T3, 1, 1, 1, 1);
943 WorldMapTooltip:AddDoubleLine("Shift-Left", QST_TTHINT_T4, 1, 1, 1, 1);
944 WorldMapTooltip:AddDoubleLine("Shift-Right", QST_TTHINT_T5, 1, 1, 1, 1);
945 WorldMapTooltip:AddDoubleLine("Ctrl-Left", QST_TTHINT_T6, 1, 1, 1, 1);
946 WorldMapTooltip:AddDoubleLine("Ctrl-Right", QST_TTHINT_T7, 1, 1, 1, 1);
947 WorldMapTooltip:AddLine(QST_TTHINT_H2, 0, 1, 0, 1);
948 WorldMapTooltip:AddDoubleLine("Shift-Left", QST_TTHINT_T8, 1, 1, 1, 1);
949 WorldMapTooltip:AddDoubleLine("Ctrl-Left", QST_TTHINT_T9, 1, 1, 1, 1);
950 WorldMapTooltip:Show();
951 end
952  
953 function QST_ToggleOptions(key, value)
954 if(value) then
955 QST_Options[key] = value;
956 else
957 QST_Options[key] = not QST_Options[key];
958 end
959 return QST_Options[key];
960 end
961  
962 function QST_CreateButton(id)
963 local button;
964 if(getglobal("QSTButton"..id)) then
965 button = getglobal("QSTButton"..id);
966 button.qMap = nil;
967 button.qTitle = nil;
968 button.qData = nil;
969 getglobal("QSTButton"..id.."Text"):SetText("");
970 getglobal("QSTButton"..id.."Status"):SetText("");
971 getglobal("QSTButton"..id.."Noted"):SetText("");
972 else
973 button = CreateFrame("Button" ,"QSTButton"..id, QST_ScrollChild, "QST_ButtonTemplate");
974 button:SetWidth(QST_ScrollChild:GetWidth());
975 button:SetID(id);
976 QST_ButtonTotal = QST_ButtonTotal +1;
977 end
978 return button;
979 end
980  
981 function QST_GetLandMark(zoneText)
982 for landmarkIndex = 1, GetNumMapLandmarks(), 1 do
983 local name = GetMapLandmarkInfo(landmarkIndex);
984 if(strlower(name) == strlower(zoneText)) then return true; end
985 end
986 return false;
987 end
988  
989 function QST_GetColourString(Text)
990 local i, j, ItemName, NumItems, NumNeeded = string.find(Text, "(.*):%s*([-%d]+)%s*/%s*([-%d]+)%s*$");
991 local colour = {a = 1.0, r = 1.0, g = 1.0, b = 1.0};
992 local colourInitial = {a = 1.0, r = 1.0, g = 1.0, b = 1.0};
993 local colourMid = {a = 1.0, r = 1.0, g = 1.0, b = 1.0};
994 local colourComplete = {a = 1.0, r = 1.0, g = 1.0, b = 1.0};
995 colourInitial.r, colourInitial.g, colourInitial.b, colourInitial.a = QST_TextToRGB(QST_INITIALCOLOUR);
996 colourMid.r, colourMid.g, colourMid.b, colourMid.a = QST_TextToRGB(QST_MIDDLECOLOUR);
997 colourComplete.r, colourComplete.g, colourComplete.b, colourComplete.a = QST_TextToRGB(QST_COMPLETEDCOLOUR);
998  
999 local colourDelta1 = {
1000 a = (colourMid.a - colourInitial.a),
1001 r = (colourMid.r - colourInitial.r),
1002 g = (colourMid.g - colourInitial.g),
1003 b = (colourMid.b - colourInitial.b)
1004 };
1005 local colourDelta2 = {
1006 a = (colourComplete.a - colourMid.a),
1007 r = (colourComplete.r - colourMid.r),
1008 g = (colourComplete.g - colourMid.g),
1009 b = (colourComplete.b - colourMid.b)
1010 };
1011 if (NumItems ~= nil) then
1012 if ((NumItems / NumNeeded) < 0.5) then
1013 colour.r = colourInitial.r + ((NumItems / (NumNeeded / 2)) * colourDelta1.r);
1014 colour.g = colourInitial.g + ((NumItems / (NumNeeded / 2)) * colourDelta1.g);
1015 colour.b = colourInitial.b + ((NumItems / (NumNeeded / 2)) * colourDelta1.b);
1016 else
1017 colour.r = colourMid.r + (((NumItems - (NumNeeded / 2)) / (NumNeeded / 2)) * colourDelta2.r);
1018 colour.g = colourMid.g + (((NumItems - (NumNeeded / 2)) / (NumNeeded / 2)) * colourDelta2.g);
1019 colour.b = colourMid.b + (((NumItems - (NumNeeded / 2)) / (NumNeeded / 2)) * colourDelta2.b);
1020 end
1021 else
1022 i, j, ItemName, NumItems, NumNeeded = string.find(Text, "(.*):%s*([-%a]+)%s*/%s*([-%a]+)%s*$");
1023 if (Items ~= nil) then
1024 if (NumItems == NumNeeded) then
1025 return QST_COMPLETEDCOLOUR;
1026 else
1027 return QST_INITIALCOLOUR;
1028 end
1029 else
1030 return QST_SPECIALCOLOUR;
1031 end
1032 end
1033  
1034 if(colour.r > 1.0) then colour.r = 1.0; end
1035 if(colour.g > 1.0) then colour.g = 1.0; end
1036 if(colour.b > 1.0) then colour.b = 1.0; end
1037 if(colour.r < 0.0) then colour.r = 0.0; end
1038 if(colour.g < 0.0) then colour.g = 0.0; end
1039 if(colour.b < 0.0) then colour.b = 0.0; end
1040  
1041 return QST_RGBtoText(colour.r, colour.g, colour.b, colour.a);
1042 end
1043  
1044 function QST_TextToRGB(strColour)
1045 local i = 3;
1046 local iAlpha = tonumber(string.sub(strColour, i, i + 1), 16);
1047 local iRed = tonumber(string.sub(strColour, i + 2, i + 3), 16);
1048 local iGreen = tonumber(string.sub(strColour, i + 4, i + 5), 16);
1049 local iBlue = tonumber(string.sub(strColour, i + 6, i + 7), 16);
1050 iAlpha = iAlpha / 255;
1051 iRed = iRed / 255;
1052 iGreen = iGreen / 255;
1053 iBlue = iBlue / 255;
1054 return iRed, iGreen, iBlue, iAlpha;
1055 end
1056  
1057 function QST_RGBtoText(iRed, iGreen, iBlue, iAlpha)
1058 local strColour;
1059 iAlpha = floor(iAlpha * 255);
1060 iRed = floor(iRed * 255);
1061 iGreen = floor(iGreen * 255);
1062 iBlue = floor(iBlue * 255);
1063 strColour = format("|c%2x%2x%2x%2x", iAlpha, iRed, iGreen, iBlue);
1064 return strColour;
1065 end