Simple Quest Script

Tutorials on setting up a server, configuring your client, and connecting to an EQ2Emulator server.
Only moderators can start new topics here
Forum rules
Most information about EQ2Emulator and Tutorials can be found at the Project Wiki. Look there for the most current information.
Locked
User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Simple Quest Script

Post by Scatman » Thu Aug 06, 2009 7:18 am

Here's a quest script I did recently. It's an easy quest that involves two steps. The first step is to kill 10 orcs. After you have killed 10 orcs, you need to return to the quest giver for your reward

Code: Select all

--[[
	Script Name	: Quests/Ruins/pawns_in_the_game.lua
	Script Purpose	: Handles the quest, "Pawns in the Game"
	Script Author	: Scatman
	Script Date	    : 2009.07.28
	
	Zone       : The Ruins
	Quest Giver: Captain Arellius
	Preceded by: Reporting for Duty (reporting_for_duty.lua)
	Followed by: Pounding the Enemy (pounding_the_enemy.lua)
--]]

function Init(Quest)
	AddQuestStepKill(Quest, 1, "I must defeat ten Brokentusk pawns to prove my value to the Militia.", 10, 100, "I must aid Freeport by defeating the Brokentusk pawns.", 2489, 1270130, 1270027, 1270039, 1270022, 1270019, 1270087)
	AddQuestStepCompleteAction(Quest, 1, "Step1_Complete_KilledOrcs")
end

function Accepted(Quest, QuestGiver, Player)
	FaceTarget(QuestGiver, Player)
	conversation = CreateConversation()

	PlayFlavor(QuestGiver, "voiceover/english/tutorial_revamp/lieutenant_argosian/fprt_adv04_ruins/revamp/lieutenant_argosian009b.mp3", "", "", 3351588566, 3135177671, Player)
	AddConversationOption(conversation, "I will do so.")
	StartConversation(conversation, QuestGiver, Player, "Get to work, citizen. You have your orders, now carry them out.")
end

function Declined(Quest, QuestGiver, Player)
end

function Step1_Complete_KilledOrcs(Quest, QuestGiver, Player)
	UpdateQuestStepDescription(Quest, 1, "I defeated 10 Brokentusk pawns and proved my worth.")
	UpdateQuestTaskGroupDescription(Quest, 1, "I crushed the Brokentusk pawns as ordered.")
	
	AddQuestStepChat(Quest, 2, "I should report back to Lieutenant Argosian at the first outpost.", 1, "I should return to the lieutenant and tell him of my victory.", 0, 1270031)
	AddQuestStepCompleteAction(Quest, 2, "Quest_Complete")
end

function Quest_Complete(Quest, QuestGiver, Player)
	UpdateQuestStepDescription(Quest, 2, "I have reported back to Lieutenant Argosian.")
	UpdateQuestTaskGroupDescription(Quest, 2, "I have returned to the lieutenant.")
	GiveQuestReward(Quest, Player)
	UpdateQuestDescription(Quest, "Following the orders of Lieutenant Argosian, I defeated a number of the Brokentusk pawns. They were relatively easy prey, so I will ask Argosian for a more challenging assignment.")
end

function Reload(Quest, QuestGiver, Player, Step)
	if Step == 1 then
		Step1_Complete_KilledOrcs(Quest, QuestGiver, Player)
	end
end
__________________________________________________________
So let's break this down into pieces.

Code: Select all

function Init(Quest)
	AddQuestStepKill(Quest, 1, "I must defeat ten Brokentusk pawns to prove my value to the Militia.", 10, 100, "I must aid Freeport by defeating the Brokentusk pawns.", 2489, 1270130, 1270027, 1270039, 1270022, 1270019, 1270087)
	AddQuestStepCompleteAction(Quest, 1, "Step1_Complete_KilledOrcs")
end
The Init(Quest) function is called immediately after you accept the quest. It is responsible for giving the player the first step(s). In this case, we create one quest step that the player must complete. The Quest parameter is actually a C++ reference to this quest. So we tell LUA we want to add a new quest step to our quest. The second parameter in AddQuestStepKill is the step number (in this case it's the first step of the quest). We then give it the step text, tell it not to complete the step until 10 orcs have been killed. The 100 is the percent chance that you get a quest update every time you kill an orc (100% in our case). Next we give it the taskgroup text which is used to group more than one quest step under the same "category" if needed. The 2489 is the icon ID. This is the icon that gets put next to the quest step. See my icon tutorial for information on how to get the icon ID (viewtopic.php?f=9&t=1250). The remaining numbers (127*) are all of the spawn IDs that the player can kill to update this step. You can list 1, 3, 15, 80, however many you wish.

The next function we run is AddQuestStepCompleteAction. This function tells LUA the name of a user-defined function to run once the given step is completed. You need one of these for every step in the quest. The first parameter is of course the reference to the quest. The second is the quest step we want to run this function for. So here we are saying that once step 1 is complete, run the function called "Step1_Complete_KilledOrcs".

Code: Select all

function Accepted(Quest, QuestGiver, Player)
	FaceTarget(QuestGiver, Player)
	conversation = CreateConversation()

	PlayFlavor(QuestGiver, "voiceover/english/tutorial_revamp/lieutenant_argosian/fprt_adv04_ruins/revamp/lieutenant_argosian009b.mp3", "", "", 3351588566, 3135177671, Player)
	AddConversationOption(conversation, "I will do so.")
	StartConversation(conversation, QuestGiver, Player, "Get to work, citizen. You have your orders, now carry them out.")
end

function Declined(Quest, QuestGiver, Player)
end
These two functions are pretty straight forward. They are called upon acceptance or rejection of a quest. If you do not wish to have something happen when a quest is accepted or declined, you should still define these, but leave them blank (like I did for Declined) otherwise World will tell you no function exists when you accept or decline a quest.

Code: Select all

function Step1_Complete_KilledOrcs(Quest, QuestGiver, Player)
	UpdateQuestStepDescription(Quest, 1, "I defeated 10 Brokentusk pawns and proved my worth.")
	UpdateQuestTaskGroupDescription(Quest, 1, "I crushed the Brokentusk pawns as ordered.")
	
	AddQuestStepChat(Quest, 2, "I should report back to Lieutenant Argosian at the first outpost.", 1, "I should return to the lieutenant and tell him of my victory.", 0, 1270031)
	AddQuestStepCompleteAction(Quest, 2, "Quest_Complete")
end
This is the user-defined function that we defined and told LUA to run once we complete step 1. We first want to update the step and taskgroup description of the first step to let the player know the step is complete. When you update the step description, that will be what pops up on the screen. The updated taskgroup description is what you'll see in the quest journal where step 1 used to be. The step will be collapsed up to a single bullet and line with the taskgroup description next to the bullet.

Next, we want a second step defined. This is a chat step and this must be used if you want the little red floating book to appear over your quest NPC's head. The parameters are exactly the same as the kill step except we do not specify the % chance to update the quest step. This is because chat steps MUST be updated via spawnscript. So somewhere in the quest NPC's spawnscript, you will need some logic to determine if you have the quest. If the player has the quest and is on step 2, say this and update the step (check out the LUA functions HasQuest, GetQuestStep, and SetStepComplete). Notice the step icon is 0, meaning there will be no icon, just a square bullet. The last parameter is of course the spawn ID that we want the red floating book to appear over.

After that, we once again tell LUA we want to run the function "Quest_Complete" once step 2 is completed.

Code: Select all

function Quest_Complete(Quest, QuestGiver, Player)
	UpdateQuestStepDescription(Quest, 2, "I have reported back to Lieutenant Argosian.")
	UpdateQuestTaskGroupDescription(Quest, 2, "I have returned to the lieutenant.")
	GiveQuestReward(Quest, Player)
	UpdateQuestDescription(Quest, "Following the orders of Lieutenant Argosian, I defeated a number of the Brokentusk pawns. They were relatively easy prey, so I will ask Argosian for a more challenging assignment.")
end
The last user-defined function. Very similar to the previous except since this is the end of the quest, we do not create any more steps. We do however want to update the step text and taskgroup text for consistency and also so we get that nice little popup telling the player they are finished the step.
We then tell LUA to give the player the quest rewards for this quest. Quest rewards are defined in the `quest_details` database table.

Finally, we want to update the quest description to whatever we want it to say when the quest reward dialog box comes up where you accept your rewards.

Code: Select all

function Reload(Quest, QuestGiver, Player, Step)
	if Step == 1 then
		Step1_Complete_KilledOrcs(Quest, QuestGiver, Player)
	end
end
I often forget this function but it is very important if you want a happy player base because who wants to log off in the middle of a quest and lose all their quest progression? ;) This function is only called by world when a player logs into a zone with an unfinished quest. The step passed in as a parameter is the step that the player has completed. So in our case, if the player has completed step 1 already, we want to run the "Step1_Complete_KilledOrcs" step. We do not need to test to see if step 2 has been completed since it's the last step. If step 2 is completed, that means the player is finished the quest and world will not even have to run this function.

What happens when our quest has more than two steps? Let's say our quest has four steps instead of two. The player finishes step 1, 2, and 3 so the player is on the final step, 4. Our Reload function would look something LIKE this:

Code: Select all

function Reload(Quest, QuestGiver, Player, Step)
	if Step == 1 then
		Step1_Complete_KilledOrcs(Quest, QuestGiver, Player)
	elseif Step == 2 then
		Step2_Complete(Quest, QuestGiver, Player)
	elseif Step == 3 then
		Step3_Complete(Quest, QuestGiver, Player)
	end
end
The way world handles this is: World will say, has the player completed step 1? Checks the database and says yup! he has. So world will now run the Reload function passing in 1 has the Step parameter which will then run the appropriate function based on our logic in the Reload function. Then world will say, has the player completed step 2? Checks the database and says yup! So now world runs the Reload function with 2 has the Step parameter's value and once again, based on our logic, runs step 2's completed function. World will then do the same for the third step.

That's about it for a very simple quest like this. Remember, a spawnscript is absolutely needed for this quest since there is a chat step. As stated before, chat steps can only be updated via the SetStepComplete function. Let me know if you have any questions or something that I did not address.

User avatar
ZexisStryfe
Posts: 1026
Joined: Thu Jul 26, 2007 6:39 am
EQ2Emu Server: Sytherian Legends
Location: Connecticut
Contact:

Re: Simple Quest Script

Post by ZexisStryfe » Thu Aug 06, 2009 10:52 am

Scat, you rockin ways I cannot describe... thanks.
~ EQ2 Emulator Project Manager

Image
Image
Image
"Zexis, from this day forth, you shall be known as... '3 of 6'" - John Adams

User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Re: Simple Quest Script

Post by Scatman » Thu Aug 06, 2009 10:59 am

Once I get home from work I'll post some screen shots of the quest and how the journal looks.

User avatar
Wdneq2
Retired
Posts: 94
Joined: Mon May 18, 2009 5:24 am
EQ2Emu Server: TessEQ2
Characters: Lilrat Gnome Assassin
Stok Ogre Bruiser
Flekrad Drow Shadowknight

Re: Simple Quest Script

Post by Wdneq2 » Thu Aug 06, 2009 5:19 pm

An excellent post.
Cheers for passing on your knowledge
/salute
aka..Woody
Lilrat Gnome Assassin...poking my nose into as much as possible
Stok Ogre Bruiser... Bashing my way round the place
Flekrad DarkElf Shadowknight .... Being an Inky

Generation whY makes me grey

User avatar
ilythor
Retired
Posts: 436
Joined: Sun Oct 14, 2007 3:44 am
EQ2Emu Server: TessEq2
Location: Australia, mate!
Contact:

Re: Simple Quest Script

Post by ilythor » Thu Aug 06, 2009 9:06 pm

Awesome, i'll throw it together when I get home and give it a run!

Thanks Scatman!!!
"Everytime you pull the trigger in space, you will ruin someone's day, somewhere, and eventually, some time."

User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Re: Simple Quest Script

Post by Scatman » Thu Aug 06, 2009 11:16 pm

Note: If you're going to use that quest as an example, either A) make sure you have John's database or B) edit the spawn_ids so they are the correct ones for your server. Also, I did not post the spawnscript for the 2nd step so that is left on you. Sometime this weekend I'll try to get a spawnscript tutorial out here incase you guys need some help with it.

User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Re: Simple Quest Script

Post by Scatman » Thu Aug 06, 2009 11:18 pm

Btw, if anyone has any kind of trouble with the scripting let me know. I'd be more than happy to help anyone out.

Locked

Who is online

Users browsing this forum: No registered users and 0 guests