Thread Tools Display Modes
07-25-13, 04:15 AM   #1
AnrDaemon
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 156
Is it possible to obtain quest title by questID ?

Is it possible to obtain quest title by questID ?
I'm digging through API, but with no result so far.

To clarify: Arbitrary questID. I have no idea, if character have the quest, or if it is even available to character.
  Reply With Quote
07-25-13, 12:21 PM   #2
ckaotik
A Fallenroot Satyr
 
ckaotik's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 29
Unhappy

I have been wondering the same thing for quite a while and couldn't find anything either
Even addons like DataStore save the quest title to their database when accepting/completing quests or from the player's quest log.

Same goes for QuestIsDaily and QuestIsWeekly (both only available on quest dialogs) and GetQuestLink (quest log based). Would love to have a GetQuestInfo(questID) function, but so far no luck.
__________________
It all starts to make a creepy kind of sense. Avatar
  Reply With Quote
07-25-13, 01:06 PM   #3
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
How about using this on a hidden tooltip object and reading the first line of the tooltip? http://wowprogramming.com/docs/widge...p/SetHyperlink
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
07-25-13, 01:47 PM   #4
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
This is a perfect use-case for a metatable and tooltip scanning:

Code:
local MyScanningTooltip = CreateFrame("GameTooltip", "MyScanningTooltip", UIParent, "GameTooltipTemplate")

local QuestTitleFromID = setmetatable({}, { __index = function(t, id)
	MyScanningTooltip:SetOwner(UIParent, "ANCHOR_NONE")
	MyScanningTooltip:SetHyperlink("quest:"..id)
	local title = MyScanningTooltipTextLeft1:GetText()
	MyScanningTooltip:Hide()
	if title and title ~= RETRIEVING_DATA then
		t[id] = title
		return title
	end
end })
Put that at/near the top of your file, and then just do a simple table lookup with the ID to get the name:

Code:
print(QuestTitleFromID[30318])
-- prints "Chasing the Chicken"
If the ID is invalid, or your game client doesn't have the info yet and has to query the server (not sure if this can even happen for quests), you will get nil instead of the quest name; if you're sure your ID was valid, you can just look it up again and your client should have the data by then.

You can use the same technique to get the localized name of anything else where there is no relevant API (eg. if you want item or spell names, just use GetItemInfo or GetSpellInfo). For example, there was recently a thread demonstrating this technique for getting localized NPC names from their mobIDs.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
07-25-13, 02:28 PM   #5
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
When you set the tooltip to a quest ID it has to request the information from the server if it hasn't been cached yet, it's similar to getting item information.

You can use OnTooltipSetQuest which triggers when the tooltip actually receives new information.

Note that the event can fire multiple times for the same quest because the tooltip may contain the name of items in the "Requirements" section and each item name requires another server request.

I had written a more complicated example that retrieved the entire quest text but there probably isn't any point in posting it.

Last edited by semlar : 07-25-13 at 02:35 PM.
  Reply With Quote
07-25-13, 10:37 PM   #6
AnrDaemon
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 156
Does that mean that I can do something like

Lua Code:
  1. local frame = CreateFrame("GameTooltip", "MyPrivateStuff_QuestInfoTooltipFrame", UIParent, "GameTooltipTemplate")
  2.  
  3. function frame:GetQuestTitle()
  4.   local title = MyPrivateStuff_QuestInfoTooltipFrameTextLeft1:GetText()
  5.   DEFAULT_CHAT_FRAME:AddMessage(self["message"]:format(title))
  6.   self:SetScript("OnTooltipSetQuest", nil)
  7. end
  8.  
  9. -- Add some slashes sausage
  10. local function commandHandler(msg, self)
  11.   local argv = { strsplit(" ", strtrim(msg)) }
  12.   if argv[1] == "quest" then
  13.     if IsQuestFlaggedCompleted(argv[2]) then
  14.       frame["message"] = ("Quest |cffffff00|Hquest:%d|h[%%s]|h|r flagged as completed."):format(argv[2])
  15.     else
  16.       frame["message"] = ("Quest |cffffff00|Hquest:%d|h[%%s]|h|r is not completed or not available to character."):format(argv[2])
  17.     end
  18.     frame:SetScript("OnTooltipSetQuest", frame.GetQuestTitle)
  19.     frame:SetOwner(UIParent, "ANCHOR_NONE")
  20.     frame:SetHyperlink("quest:" .. argv[2])
  21.   end
  22. end
  23.  
  24. SlashCmdList["MYPRIVATESTUFF"] = commandHandler
  25. SLASH_MYPRIVATESTUFF1 = '/my'
? Anyone see anything apparently wrong with such logic? Or I can go for field testing?

Last edited by AnrDaemon : 07-25-13 at 11:20 PM.
  Reply With Quote
07-26-13, 01:00 AM   #7
AnrDaemon
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 156
Aww, stupid... After bashing over a wall of air, it finally worked quite nicely.

Lua Code:
  1. local tooltip = CreateFrame("GameTooltip", "MyPrivateStuff_QTipFrame", UIParent, "GameTooltipTemplate")
  2.  
  3. function tooltip:GetQuestTitle()
  4.   local title = MyPrivateStuff_QTipFrameTextLeft1:GetText()
  5.   DEFAULT_CHAT_FRAME:AddMessage(self["message"]:format(title))
  6.   self:SetScript("OnTooltipSetQuest", nil)
  7. end
  8.  
  9. -- activation code
  10.     if IsQuestFlaggedCompleted(argv[2]) then
  11.       tooltip["message"] = ("Quest |cffffff00|Hquest:%d|h[%%s]|h|r flagged as completed."):format(argv[2])
  12.     else
  13.       tooltip["message"] = ("Quest |cffffff00|Hquest:%d|h[%%s]|h|r is not completed or not available to character."):format(argv[2])
  14.     end
  15.     DEFAULT_CHAT_FRAME:AddMessage("Retrieving quest information...")
  16.     tooltip:SetOwner(UIParent, "ANCHOR_NONE")
  17.     tooltip:SetScript("OnTooltipSetQuest", tooltip.GetQuestTitle)
  18.     tooltip:SetHyperlink("quest:" .. argv[2])

Tested on quest id:25323, it properly spit only one line. (Without unsetting OnTooltipSetQuest, it prints a second line, when quest item data is accessed, as semlar pointed out earlier.)
  Reply With Quote
07-26-13, 01:18 AM   #8
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
If you don't need the quest name immediately (eg. you can wait for OnTooltipSetQuest to happen) then that will work, though I'd suggest cleaning it up some. In no particular order:
  • Making a table in your slash command handler like that is pretty horrifying.
  • There's no need to set and un-set the script, since your code is the only code that's going to be setting hyperlinks to that tooltip. If you're worried about it, check the self.message value instead.
  • "self" isn't a very good thing to call the second arg passed to your slash handler, since that arg refers to the editbox the user typed the command in, and not to any "self" as used anywhere else in your addon.
  • You can cut the number of calls to string.format in half.
  • You should :Hide() your tooltip after getting the text.

Code:
local frame = CreateFrame("GameTooltip", "MyPrivateStuff_QuestInfoTooltipFrame", UIParent, "GameTooltipTemplate")

frame:SetScript("OnTooltipSetQuest", function(self)
	if not self.message then return end
	local title = MyPrivateStuff_QuestInfoTooltipFrameTextLeft1:GetText()
	self:Hide()
	DEFAULT_CHAT_FRAME:AddMessage(format(self.message, self.linkID, title))
	self.message, self.linkID = nil, nil
end

SLASH_MYPRIVATESTUFF1 = "/my"
SlashCmdList["MYPRIVATESTUFF"] = function(msg, editBox)
	local linkType, linkID = strsplit(" ", msg)
	if linkType == "quest" then
		if IsQuestFlaggedCompleted(linkID) then
			frame.message = "Quest |cffffff00|Hquest:%d|h[%%s]|h|r flagged as completed."
		else
			frame.message = "Quest |cffffff00|Hquest:%d|h[%%s]|h|r is not completed or not available to character."
		end
		frame.linkID = linkID
		DEFAULT_CHAT_FRAME:AddMessage("Retrieving quest information...")
		frame:SetOwner(UIParent, "ANCHOR_NONE")
		frame:SetHyperlink("quest:" .. linkID)
	else
		frame.message, frame.linkID = nil, nil
	end
end
Edit: You posted a revision while I was posting mine, but most of the above is (probably) still applicable. Also, either your new code should be throwing errors left and right because you're using argv in a scope where it's not defined, or that isn't your real code.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 07-26-13 at 01:21 AM.
  Reply With Quote
07-26-13, 04:55 AM   #9
AnrDaemon
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 156
Originally Posted by Phanx View Post
If you don't need the quest name immediately (eg. you can wait for OnTooltipSetQuest to happen) then that will work, though I'd suggest cleaning it up some. In no particular order:
Yes, I largely don't need it immediately. Certainly not in the same frame - I have no intention to get WoW stuck on every other window opening.
Though, that previous example with metatable will be a little better for when I need to store and handle a list of quest names during a single session.

* Making a table in your slash command handler like that is pretty horrifying
You refer to
Code:
local argv = { strsplit(" ", strtrim(msg)) }
?
Then how do you suggest I prepare it? I have no idea, how many words will be in parameters.

* There's no need to set and un-set the script, since your code is the only code that's going to be setting hyperlinks to that tooltip. If you're worried about it, check the self.message value instead.
I'm unsetting it to prevent repeated access to handler, where I don't want it. also to save some processing. Of course, I could just pupulate some other variable with necessary data, and use it from some other function... Isn't that "a bit" too much of overhead?

* "self" isn't a very good thing to call the second arg passed to your slash handler, since that arg refers to the editbox the user typed the command in, and not to any "self" as used anywhere else in your addon.
"self" Is always the first argument passed to class function. Where do you see it as second?

* You can cut the number of calls to string.format in half.
Yes, I can. I just left it this way to reduce amount of unrelated stuff referenced in far-reaching places.

* You should :Hide() your tooltip after getting the text.
I never Show() it in first place. However, I can set OnShow = Hide, if you insist.

Edit: You posted a revision while I was posting mine, but most of the above is (probably) still applicable. Also, either your new code should be throwing errors left and right because you're using argv in a scope where it's not defined, or that isn't your real code.
That is a part of real code, a part of real slashcommand handler. (There's lots more of unrelated stuff handled, I just extracted the relevant block for demonstration.)

Last edited by AnrDaemon : 07-26-13 at 05:01 AM.
  Reply With Quote
07-26-13, 10:04 PM   #10
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by AnrDaemon View Post
You refer to
Code:
local argv = { strsplit(" ", strtrim(msg)) }
?
Then how do you suggest I prepare it? I have no idea, how many words will be in parameters.
According to the code you posted, your code only supports two parameters, and the first one must always be "quest". If your code actually supports other commands, you'll have to post your real code for a real example of how to do it without making tables left and right, but it's definitely possible, just the way I showed you in the code I posted.

Originally Posted by AnrDaemon View Post
"self" Is always the first argument passed to class function. Where do you see it as second?
In the code you posted, you named the second variable received by your slash command handler function "self".

Originally Posted by AnrDaemon View Post
I never Show() it in first place. However, I can set OnShow = Hide, if you insist.
Calling SetHyperlink on the tooltip automatically shows it. You just don't see it appear because you didn't give it a position, so it's appearing in a nonexistent location. Just call :Hide() on it, which is the proper method of "cleaning up" a tooltip after you've read it.

Originally Posted by AnrDaemon View Post
That is a part of real code, a part of real slashcommand handler. (There's lots more of unrelated stuff handled, I just extracted the relevant block for demonstration.)
Posting random parts of your code is nothing but a huge waste of time for anyone who tries to help you. If you want help, post your entire, actual code. We aren't mind readers. We can't magically know that what you posted is only 10% of your code, or what is in the other 90% of your code. Clearly you do not actually want help, so I'm done trying to help you. Maybe someone else has more patience for your time-wasting than I do. Good luck.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
07-27-13, 12:08 AM   #11
AnrDaemon
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 156
Originally Posted by Phanx View Post
According to the code you posted, your code only supports two parameters, and the first one must always be "quest". If your code actually supports other commands, you'll have to post your real code for a real example of how to do it without making tables left and right, but it's definitely possible, just the way I showed you in the code I posted.
Yeah, sorry for confusion.

In the code you posted, you named the second variable received by your slash command handler function "self".
Aww, blind my eyes. Found it. That's really wrong way to handle things, indeed.

Calling SetHyperlink on the tooltip automatically shows it.
I was afraid of that, on a second thought. Fixed now.

Posting random parts of your code is nothing but a huge waste of time for anyone who tries to help you. If you want help, post your entire, actual code. We aren't mind readers. We can't magically know that what you posted is only 10% of your code, or what is in the other 90% of your code. Clearly you do not actually want help, so I'm done trying to help you. Maybe someone else has more patience for your time-wasting than I do. Good luck.
Now, that's the kind of attitude, which I like.
Yes, I don't need any more help, than you've provided already. Thank you.
Even less I need to be spoon-fed with complete solutions. I'm not brain-damaged, and I still capable of producing my own solutions provided enough strarting information. Which you did. Thank you once more.
You even helped me to realize subtle mistakes in my code, which I did not know, and pointed out a major oversight. Great thank you for that.
You was of a very big help. Thank you once more.

Last edited by AnrDaemon : 07-27-13 at 12:14 AM.
  Reply With Quote
07-27-13, 12:41 AM   #12
ckaotik
A Fallenroot Satyr
 
ckaotik's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 29
Lightbulb

And this is why I love WoWInterface's developer community. Never thought of using the almighty SetTooltipHyperlink("quest:"..questID) treatment.
Here's another thank you!
__________________
It all starts to make a creepy kind of sense. Avatar
  Reply With Quote
07-27-13, 09:06 PM   #13
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by AnrDaemon View Post
Even less I need to be spoon-fed with complete solutions. I'm not brain-damaged, and I still capable of producing my own solutions provided enough strarting information.
It's not about "spoon-feeding complete solutions". It's about the fact that I spent a good amount of time critiquing your code, but had you just posted your whole code in the first place, half of those critiques would have been invalid or significantly different. You wasted your time cherry-picking some parts of your code to post, and I wasted my time critiquing fake code and trying to explain to you why things were problems, when they weren't actually problems in your real code. It would have been faster for you, and less annoying for everyone, to just post your whole file and say "please don't solve the problem, just give me a hint!"
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
08-04-13, 11:50 AM   #14
AnrDaemon
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 156
Sorry, but your incrimination makes little sense. I posted my code, when it was written. I didn't held it back on purpose, or anything of that kind.
  Reply With Quote
07-03-18, 12:18 AM   #15
McRoell
A Defias Bandit
Join Date: Jul 2018
Posts: 2
Sorry for pulling this thread out of hibernation, but I've encountered a problem with that "frame:SetScript" part(I guess) I'm not able to solve.

Originally Posted by Phanx View Post
Code:
local frame = CreateFrame("GameTooltip", "MyPrivateStuff_QuestInfoTooltipFrame", UIParent, "GameTooltipTemplate")

frame:SetScript("OnTooltipSetQuest", function(self)
	if not self.message then return end
	local title = MyPrivateStuff_QuestInfoTooltipFrameTextLeft1:GetText()
	self:Hide()
	DEFAULT_CHAT_FRAME:AddMessage(format(self.message, self.linkID, title))
	self.message, self.linkID = nil, nil
end
I've used the complete code provided by Phanx 1:1 into my LUA-Script. Every time on Login (or Reload) I receive an Error regarding a missing ")" for closing purpose - details below.

As far as I (as a newbie) understand the code, the error should refer to the "frame:SetScript" statement, but I'm not sure on that and much less how to solve that.

Error Message
Code:
Message: Interface\AddOns\McR_Queststat\mcr_queststat.lua:28: ')' expected (to close '(' at line 20) near 'SLASH_MYPRIVATESTUFF1'
Time: Tue Jul  3 07:53:23 2018
Count: 1
Stack: Interface\AddOns\McR_Queststat\mcr_queststat.lua:28: ')' expected (to close '(' at line 20) near 'SLASH_MYPRIVATESTUFF1'
[C]: ?

Locals:
TIA

McRoell
  Reply With Quote
07-03-18, 12:50 AM   #16
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,871
Code:
frame:SetScript("OnTooltipSetQuest", function(self)
	if not self.message then return end
	local title = MyPrivateStuff_QuestInfoTooltipFrameTextLeft1:GetText()
	self:Hide()
	DEFAULT_CHAT_FRAME:AddMessage(format(self.message, self.linkID, title))
	self.message, self.linkID = nil, nil
end)
Phanx left off the final ) after the last end.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 07-03-18 at 01:51 AM.
  Reply With Quote
07-03-18, 05:52 AM   #17
AnrDaemon
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 156
I strongly suggest an editor capable of structure highlighting, not just keywords.
  Reply With Quote
07-03-18, 11:04 PM   #18
McRoell
A Defias Bandit
Join Date: Jul 2018
Posts: 2
Originally Posted by Fizzlemizz View Post
[code]Phanx left off the final ) after the last end.
Thank you.
I slightly guessed it but had an other issue with that code - usage - which was spoiling my efforts. Thanks to your confirmation I'm all-clear now.

McRoell
  Reply With Quote
04-27-20, 09:46 AM   #19
Nikita S. Doroshenko
A Cyclonian
 
Nikita S. Doroshenko's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2015
Posts: 45
Maybe someone knows if it's possible somehow to obtain localized string on different installed languages for quest titles, descriptions, unit titles.
I think it's possible to do with Blizzard API https://develop.battle.net/documenta...game-data-apis
But I wonder if it's possible for example GET quest Title, Description for es_ES, and de_DE ingame?

I have an idea of making an addon that will help players to learn a foreign language, but I'm not sure what will be the best way to get multiple localization data at the same time. And make addon easy to maintain in case of new content and updates.
  Reply With Quote
04-27-20, 10:21 AM   #20
Ketho
A Pyroguard Emberseer
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,026
Originally Posted by Nikita S. Doroshenko View Post
But I wonder if it's possible for example GET quest Title, Description for es_ES, and de_DE ingame?

I don't think that's possible in-game. You'd only get the info for your current locale
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Is it possible to obtain quest title by questID ?

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off