WoWWiki

This wiki contains inaccurate and out-of-date information. Please head over to https://wowpedia.fandom.com for more accurate and up-to-date game information.

READ MORE

WoWWiki
WoWWiki
Advertisement

Continuation from HOWTO: Use Earth to create a QuestLog.

Summary[]

The goal of this tutorial is to create a fancier quest log. Using the tools provided by Earth's Tree template, along with the functions available in Sea and Chronos, we've created a list of the quests with little trouble. Now we want to display the actual quest text.

  • Coding Time: 30 minutes
  • Tutorial Length: 2-3 hours
  • Difficulty: 3/5

Making the Actual Quest Frame[]

Okay, so we have our QuestLog, with all the Quests inside of it. Now we need to make a quest log. This looks identical to the one in the normal game, so there's minimal screenshots. First, add the XML for the QuestLogFrame:

	<Frame name="PartyQuestsLogFrame" inherits="EarthBookTemplate" hidden="true">
		<Size>
			<AbsDimension x="384" y="492"/>
		</Size>
		<Anchors>
			<Anchor point="TOPLEFT">
				<Offset>
					<AbsDimension x="320" y="0"/>
				</Offset>
			</Anchor>
		</Anchors>
		<Frames>
			<ScrollFrame name="PartyQuestsLogDetailScrollFrame" inherits="UIPanelScrollFrameTemplate">
				<Anchors>
					<Anchor point="TOPLEFT">
						<Offset>
							<AbsDimension x="27" y="-80"/>
						</Offset>
					</Anchor>
				</Anchors>
				<Size>
					<AbsDimension x="296" y="316"/>
				</Size>
				
				<ScrollChild>
				</ScrollChild>
			</ScrollFrame>
		</Frames>
		<Scripts>
			<OnLoad>
				PartyQuests_LogFrame_OnLoad();
			</OnLoad>
		</Scripts>
	</Frame>

Now, inside the <ScrollChild> add:

<Frame name="PartyQuestsLog" inherits="EarthQuestLogTemplate"/>

This is the template we'll be using for the QuestLog.

Once this is done, we now add some code to actually collect the quest information, and return it as a table.

--Get Quest Information --
function PartyQuests_GetPlayerQuestInfo(questID)
	if ( not Sea.wow.questLog.protectQuestLog() ) then 
		return false; 
	end

	local questInfo = {};

	local tooltip = GameTooltip;
	
	-- Expand everything
	ExpandQuestHeader(0);
	
	-- Select it
	SelectQuestLogEntry(questID);

	questInfo.id = questID;
	questInfo.title = GetQuestLogTitle(questID);
	questInfo.failed = IsCurrentQuestFailed();	
	questInfo.description, questInfo.objectives = GetQuestLogQuestText();
	questInfo.timer = GetQuestLogTimeLeft();
	
	questInfo.objectives = {};

	for i=1, GetNumQuestLeaderBoards(), 1 do
	 	local item = {};
 		item.text, item.questType, item.finished = GetQuestLogLeaderBoard(i);
 		table.insert(questInfo.objectives, item);
 	end 

	if ( GetQuestLogRequiredMoney() > 0 ) then
		questInfo.requiredMoney = GetQuestLogRequiredMoney();
	end
	questInfo.rewardMoney = GetQuestLogRewardMoney();

	questInfo.rewards = {};
	questInfo.choices = {};
	
	for i=1, GetNumQuestLogChoices(), 1 do	
		local item = {};
		item.name, item.texture, item.numItems, item.quality, item.isUsable =  GetQuestLogChoiceInfo(i);

		item.info = GetQuestLogItemLink("choice", i );
		
		table.insert(questInfo.choices, item);
	end
	for i=1, GetNumQuestLogRewards(), 1 do
		local item = {};
		item.name, item.texture, item.numItems, item.quality, item.isUsable =  GetQuestLogRewardInfo(i);

		item.info = GetQuestLogItemLink("reward", i );
		
		table.insert(questInfo.rewards, item);
	end

	if ( GetRewardSpell() ) then		
		questInfo.spellReward={};
		questInfo.spellReward.texture, questInfo.spellReward.name =  GetQuestLogRewardSpell();
	end		
	
	-- Unprotect
	Sea.wow.questLog.unprotectQuestLog();		

	return questInfo;
end 

Now we actually change the onClick handler inside of PartyQuests_LoadGui to actually refer to a real function:

local eTree = PartyQuests_ConvertQuestTreeToEnhancedTree(tree, {onClick=PartyQuests_OnQuestClick});

Then we implement that function:

-- Open the specified quest log
function PartyQuests_OnQuestClick(id) 
	if ( id > GetNumQuestLogEntries() ) then
	else
		-- Show the frame here		
	end
end

Now, to show the actual quest, we first check to make sure the Quest it already has isn't the same as the one we're displaying.

	-- Get the current log
	local activeLog = EarthQuestLog_GetQuest("PartyQuestsLog");
	-- Update and display or hide
	if ( not activeLog or not (activeLog.id == id ) 
		or not (getglobal("PartyQuestsLogFrame"):IsVisible()) ) then
		-- Load the quest and update
		EarthQuestLog_LoadQuest("PartyQuestsLog", questInfo);
		EarthQuestLog_Update("PartyQuestsLog");
	
		-- Show the other frame
		ShowUIPanel(getglobal("PartyQuestsLogFrame"));
	else
		HideUIPanel(getglobal("PartyQuestsLogFrame"));
	end
PartyQuests Stage5 S

The working quest log.

Abandon and Share[]

Next, we'll add a couple buttons: One for Abandon and one for Share.

	<Button name="$parentAbandonButton"  inherits="EarthPanelButtonTemplate" text="PARTYQUESTS_BUTTON_ABANDON_TEXT">
		<Size>
			<AbsDimension x="80" y="21"/>
		</Size>
		<Anchors>
			<Anchor point="BOTTOMLEFT" relativeTo="$parent" relativePoint="BOTTOMLEFT">
				<Offset>
					<AbsDimension x="17" y="74"/>
				</Offset>
			</Anchor>
		</Anchors>
		<Scripts>
			<OnLoad>
				PartyQuests_LogFrame_Abandon_OnLoad()
			</OnLoad>
		</Scripts>
	</Button>

And the code to abandon a quest:

--Log Frame Abandon Button --
function PartyQuests_LogFrame_Abandon_OnLoad()
	this.onClick = PartyQuests_LogFrame_Abandon_OnClick;
end
function PartyQuests_LogFrame_Abandon_OnClick()
	if ( not Sea.wow.questLog.protectQuestLog() ) then 
		return false; 
	end 

	-- Expand everything
	ExpandQuestHeader(0);

	if ( PartyQuestsLog.questInfo ) then 	
		-- Select it
		SelectQuestLogEntry(PartyQuestsLog.questInfo.id);	
	
		SetAbandonQuest();
		StaticPopup_Show("ABANDON_QUEST", GetAbandonQuestName());
	end

	-- Unprotect
	Sea.wow.questLog.unprotectQuestLog();
end

Next we add a Share button.

	<Button name="$parentShareButton" inherits="EarthPanelButtonTemplate"  text="PARTYQUESTS_BUTTON_SHARE_TEXT">
		<Size>
			<AbsDimension x="80" y="21"/>
		</Size>
		<Anchors>
			<Anchor point="BOTTOMLEFT" relativeTo="$parent"  relativePoint="BOTTOMLEFT">
				<Offset>
					<AbsDimension x="97" y="74"/>
				</Offset>
			</Anchor>
		</Anchors>
		<Scripts>
			<OnLoad>
				PartyQuests_LogFrame_Share_OnLoad()
			</OnLoad>
 		</Scripts>
	</Button>			

And the code to share quests:

--Log Frame Share Button --
function PartyQuests_LogFrame_Share_OnLoad()
	this.onClick = PartyQuests_LogFrame_Share_OnClick;
end
function PartyQuests_LogFrame_Share_OnClick()
	if ( not Sea.wow.questLog.protectQuestLog() ) then 
		return false; 
	end

	-- Expand everything
	ExpandQuestHeader(0);

	if ( PartyQuestsLog.questInfo ) then 	
		-- Select it
		SelectQuestLogEntry(PartyQuestsLog.questInfo.id);	
	
		QuestLogPushQuest();
	end

	-- Unprotect
	Sea.wow.questLog.unprotectQuestLog();
end

Bonus Points[]

If you want to be extra-special, you can add an overlay to show the number of quests you have total. Put this inside the PartyQuestsLogFrame:

 	<Layers>
 		<Layer level="OVERLAY">
 			<Texture name="$parentCountRight" file="Interface\Common\Common-Input-Border">
				<Size>
					<AbsDimension x="8" y="20"/>
				</Size>
				<Anchors>
					<Anchor point="TOPRIGHT">
						<Offset>
							<AbsDimension x="-47" y="-50"/>
						</Offset>
					</Anchor>
				</Anchors>
				<TexCoords left="0.9375" right="1.0" top="0" bottom="0.625"/>
			</Texture>
			<Texture name="$parentCountMiddle"   file="Interface\Common\Common-Input-Border">
				<Size>
					<AbsDimension x="80" y="20"/>
				</Size>
				<Anchors>
					<Anchor point="RIGHT" relativeTo="$parentCountRight" relativePoint="LEFT"/>
				</Anchors>
				<TexCoords left="0.0625" right="0.9375" top="0" bottom="0.625"/>
			</Texture>
			<Texture name="$parentCountLeft" file="Interface\Common\Common-Input-Border">
				<Size>
					<AbsDimension x="8" y="20"/>
				</Size>
				<Anchors>
					<Anchor point="RIGHT" relativeTo="$parentCountMiddle" relativePoint="LEFT"/>
				</Anchors>
				<TexCoords left="0" right="0.0625" top="0"  bottom="0.625"/>
			</Texture>
			<FontString name="$parentQuestCount" inherits="GameFontNormalSmall">
				<Anchors>
					<Anchor point="RIGHT" relativeTo="$parentCountRight">
						<Offset>
							<AbsDimension x="-6" y="0"/>
						</Offset>
					</Anchor>
				</Anchors>
			</FontString>
		</Layer>
	</Layers>

Then you add the following to make the quest numbers show up:

	local questInfo = PartyQuests_GetPlayerQuestInfo(id);
	local numEntries, numQuests = GetNumQuestLogEntries();
		
  	-- Set the Number of quests:
	PartyQuestsLogFrameQuestCount:SetText(string.format(QUEST_LOG_COUNT_TEMPLATE, numQuests, MAX_QUESTLOG_QUESTS));
	PartyQuestsLogFrameCountMiddle:SetWidth(PartyQuestsLogFrameQuestCount:GetWidth());

Wrap Up[]

PartyQuests Stage6 S

All Done

Thats it. Its not hard, just a lot more work to obtain the quest information.

Advertisement