Admins:ContentQuest
- Last edited 8 years ago by Vlash Nytefall
Admins - Content - Quest
Return to: Admins | Tutorials | Portal | Forum | Project Manager | Bug Tracker
This is a simple quest that will help you get started with the LUA scripting functionality. It will guide you through creating the necessary spawns, lua files and attaching the script files to objects in game.
For more details on Lua functions see the developer reference.
A quest is broken down into two types of scripts, Quest Scripts and Spawn Scripts.
- SpawnScripts - Relate to your NPCs
- Quests - Relate to an overall quest
This quest is a simple go speak to someone quest and we shall call this quest 'Speak to Jodie'.
To start with we are going to set up our first SpawnScript. This will require that you spawn an NPC. So to begin with create the following npc:
/spawn create npc 134 1 1 'Dave'
Now click Dave and add him as a permanent spawn
/spawn add new 'DaveVillageShin' 100
Now that Dave has been added we need to assign him our quest script.
- Open your EQ2Emu directory
- Open the SpawnScripts folder
- Create a folder for your current zone (in our example we are going to use VillageShin)
- Create an empty .lua file 'Dave.lua' in the VillageShin directory
The file should now have the following path 'SpawnScripts/VillageShin/Dave.lua'
- Leave this file blank for now, we will be coming back to this
- Reload your spawns with /reload spawns Dave should repop
Now we need to create our second NPC and spawn script. Create the following npc:
/spawn create npc 132 1 1 'Jodie'
Now click Jodie and add her as a permanent spawn
/spawn add new 'JodieVillageShin' 100
Now that Jodie has been added we need to assign her our quest script.
- Open your EQ2Emu directory
- Open the SpawnScripts folder
- Create a folder for your current zone (in our example we are going to use VillageShin)
- Create an empty .lua file 'Jodie.lua' in the VillageShin directory
The file should now have the following path 'SpawnScripts/VillageShin/Jodie.lua'
- Leave this file blank for now, we will be coming back to this
- Reload your spawns with /reload spawns Jodie should repop
As mentioned above every quest in game requires a Quest Script and a Spawn Script. All quest scripts are stored in the Quests folder.
Now that we have our initiator NPC lets set up a file for his quest
- Open your EQ2Emu directory
- Open the Quests folder
- Create a folder for your current zone (in our example we are going to use VillageShin)
- Create an empty .lua file called 'SpeakToJodie.lua'
Every quest in game requires a database entry. This involves some SQL so you will need to fire up your favourite SQL Query tool.
- Open SQL query tool and connect to your database
- Insert a line into your quests table for this quest
INSERT INTO quests (name,type,zone,level,enc_level,description,completed_text,spawn_id,lua_script) values
('Speak to Jodie',VillageShin,VillageShin,1,0,'Speak to Jodie','I spoke to Jodie',139,'Quests/VillaJodie'/SpeakToJodie.lua');
Note what I did here:
The quests table required the following values:
- name - This is the name of our quest (Speak to Jodie)
- type - This is set to the name of the zone (VillageShin)
- zone - This is the name of the zone the quest starts in (VillageShin)
- level - The level this quest starts at (Level 1 in our case)
- enc_level - set to zero. Needs description
- description - The description of the quest (Speak to Jodie)
- completed_text - The completed description of the quest (I spoke to Jodie)
- spawn_id- set this to the ID of the spawn that gives the quest (spawn id for Dave is 139)
- lua_script - The relative path of the Quest that we created earlier (Quests/VillageShin/SpeakToJodie.lua)
What is important to hold onto here is the QuestID, this is used in the scripts in the next section. Because the Quest ID is an auto generated field in the database you do not have to supply it above. To retrieve the ID that has just been generated when you inserted the quest run the following command in your query tool.
SELECT quest_id,name FROM quests WHERE name = 'Speak To Jodie';
Note down the Quest ID because QuestID will differ between my tables and yours. It is important you replace it wherever it appears below.
In my example the QuestID was 3 so I will be using this number.
Now that we have our QuestID we can edit the scripts. Open up your Quests/VillageShin/SpeakToJodie.lua file in your favourite text editor.
A basic Quest Script is broken down into at least 3 functions:
- function Init(Quest)
- function Accepted(Quest, QuestGiver, Player)
- function Declined(Quest, QuestGiver, Player)
Every function in your script should be terminated with the word 'end'
- Flesh out your Quest script now by creating the following 3 functions in your SpeakToJodie.lua file:
function Init(Quest) end function Accepted(Quest, QuestGiver, Player) end function Declined(Quest, QuestGiver, Player) end
With the following skeleton quest layout we now need to fill in the details for each function.
Init
The init function will execute whenever the quest starts. This is possibly the most important function in the quest.
Remember when you added the Quest to the Quests table above? This is very similar to that table. It defines the core parts of the quest.
Edit this
You require the following functions within your Init Quest:
- AddQuestStepChat(Quest, StepID, StepText, Quantity, TaskGroupText, Icon, ID)
- AddQuestStepCompleteAction(Quest, StepID, "Function Name")
- function Function Name(Quest, QuestGiver, Player)
end
You can find more information on the above functions in the Developer LUA functions page. It is important to note that we must use SetStepComplete with AddQuestStepChat as it will not automatically complete a quest on just a hail. The spawnscript must call the step complete as most quests do not complete on live immediately after hail, it is usually after so many chat messages.
- First get Jodie's NPCID by targetting her and type /spawn details. This is needed for the function AddQuestStepChat (the last value)
In my case the value was 140.
We are now going to flesh out our Quest Init function. Replace your Init function with the following:
<pre> function Init(Quest)
-- Register the Speak to Jodie Quest (Level 1 and in VillageShin) (This is a hallmark quest) RegisterQuest(Quest, "Speak to Jodie", "Hallmark", "Village Shin", 1, "Dave wants me to speak to Jodie.") -- Set the experience reward to 200 SetQuestRewardExp(Quest, 200) -- The minimum required level for this quest is 1 SetQuestPrereqLevel(Quest, 1) -- Step number 1 is speak to Jodie, the quantity is 1 (do once) and the ID is 75 (a note). The ID is 140 for Jodies NPCID. AddQuestStepChat(Quest, 1, "I should give Daves message to Jodie.", 1, "", 10, 140) -- When the task is completed update our book with the following text SetCompletedDescription(Quest, "I spoke to Jodie")
end </pre>
Did you see how I used comments there? Any line starting with -- will be ignored. This is a great way to help you when you are rereading a quest you wrote many months ago.
Also to note is the Icon ID we used for this quest was number 75. See this thread for more details http://www.eq2emulator.net/phpBB3/viewtopic.php?f=9&t=1250
Accepted
You can trigger specific messages when a quest is accepted. In our example we're going to do nothing.
Replace your Accepted function with the following
<pre> function Accepted(Quest, QuestGiver, Player)
-- Do nothing, this is not needed
end </pre>
Declined
If someone declines a quest we may want to persuade them to do it.
Replace your Declined function with the following
<pre> function Declined(Quest, QuestGiver, Player)
-- If the quest giver doesn't exist then skip this (incase he gets killed or is despawned)
if QuestGiver ~= nil then
-- if the distance is too far away don't say anything
if GetDistance(Player, QuestGiver) < 30 then
-- face him/her to talk
FaceTarget(QuestGiver, Player)
-- Say the following line with the players name in the middle
Say(QuestGiver, "Please help me " .. GetName(Player) .. ", Im so busy.")
end
end
end </pre>
The full quest script
<pre> function Init(Quest)
-- Register the Speak to Jodie Quest (Level 1 and in VillageShin) (This is a hallmark quest) RegisterQuest(Quest, "Speak to Jodie", "Hallmark", "Village Shin", 1, "Dave wants me to speak to Jodie.") -- Set the experience reward to 200 SetQuestRewardExp(Quest, 200) -- The minimum required level for this quest is 1 SetQuestPrereqLevel(Quest, 1) -- Step number 1 is speak to Jodie, the quantity is 1 (do once) and the ID is 75 (a note). The ID is 140 for Jodies NPCID. AddQuestStepChat(Quest, 1, "I should give Daves message to Jodie.", 1, "", 10, 140) -- When the task is completed update our book with the following text SetCompletedDescription(Quest, "I spoke to Jodie")
end
function Accepted(Quest, QuestGiver, Player)
-- Do nothing, this is not needed
end
function Declined(Quest, QuestGiver, Player)
-- If the quest giver doesn't exist then skip this (incase he gets killed or is despawned)
if QuestGiver ~= nil then
-- if the distance is too far away don't say anything
if GetDistance(Player, QuestGiver) < 30 then
-- face him/her to talk
FaceTarget(QuestGiver, Player)
-- Say the following line with the players name in the middle
Say(QuestGiver, "Please help me " .. GetName(Player) .. ", Im so busy.")
end
end
end </pre>
Now that we have our quest script ready we can fill in the Jodie.lua and Dave.lua scripts.
Open up the Dave.lua script and insert the following
The full spawn script for Dave
<pre> function spawn(NPC)
-- This NPC should offer Quest ID 3 (change this to yours) ProvidesQuest(NPC, 3)
end
function hailed(NPC, Spawn)
-- face the player FaceTarget(NPC, Spawn) -- play a voice PlayFlavor(NPC, "voiceover/english/voice_emotes/greetings/greetings_1_1002.mp3", "", "", 0, 0, Spawn)
-- begin a dialogue/conversation
conversation = CreateConversation()
-- check if the player has Quest ID 3 (change this to yours)
if HasQuest(Spawn, 3) then
-- If the Quest ID 3 has been completed (change this to yours)
if QuestIsComplete(Spawn, 3) then
-- say great to the message below
AddConversationOption(conversation, "Great!")
-- say thanks to the player for completing quest 3
StartConversation(conversation, NPC, Spawn, "Hello " .. GetName(Spawn) .. ", thank you so much for helping me.")
else
-- they haven't completed quest 3 ask them to hurry up!
AddConversationOption(conversation, "Not yet!")
StartConversation(conversation, NPC, Spawn, "Hello again " .. GetName(Spawn) .. ". did you give my wife the message yet?")
end
else
-- they have already finished quest 3 (change this to yours)
if HasCompletedQuest(Spawn, 3) then
-- just say hey
AddConversationOption(conversation, "Hello!")
-- say hello
StartConversation(conversation, NPC, Spawn, "Hello again " .. GetName(Spawn) )
else
-- they've never completed quest ID 3, they don't have Quest ID 3 and we should offer it to them
-- reply with sure and then fire off Function HelpDave (see below)
AddConversationOption(conversation, "Sure!", "HelpDave")
-- offer quest message
StartConversation(conversation, NPC, Spawn, "Hey there! Can you help me deliver a message to my wife? I must speak to her urgently.")
end
end
end
-- fires when player chats to Dave for first time function HelpDave(NPC, Spawn)
-- offer quest ID 3 (change this to your quest ID) OfferQuest(NPC, Spawn, 3) -- start a conversation/dialogue conversation = CreateConversation() StartConversation(conversation, NPC, Spawn, "That's wonderful, please hurry I must speak to her urgently.") -- do an emote Emote(NPC, " waves.", Spawn)
end </pre>
The full spawn script for Jodie
Open up the Jodie.lua script and insert the following
<pre> function spawn(NPC)
-- does not provide a quest, is only part of one
end
function hailed(NPC, Spawn)
-- do an emote
Emote(NPC, " waves.", Spawn)
-- face them
FaceTarget(NPC, Spawn)
-- start a dialogue
conversation = CreateConversation()
-- do they have QuestID 3? (change this to yours)
if HasQuest(Spawn, 3) then
-- start a conversation with them as they have quest ID 3
AddConversationOption(conversation, "Yep!")
StartConversation(conversation, NPC, Spawn, "Hello " .. GetName(Spawn) .. ". what's that? A message from my husband?")
-- make sure the player has quest ID 3 and pack the quest into a variable
Quest = GetQuest(Spawn, 3)
-- check this variable with the quest in is not null
if Quest ~= nil then
-- they have the quest, they have spoken to the NPC, lets give them their reward
SetStepComplete(Spawn, Quest, 1)
GiveQuestReward(Quest, Spawn)
-- update descriptions to match
UpdateQuestStepDescription(Quest, 1, "I have spoken to Jodie.")
UpdateQuestTaskGroupDescription(Quest, 1, "I have spoken to Jodie.")
UpdateQuestDescription(Quest, "I have spoken to Jodie")
end
else
-- already completed quest in past, lets say hi again
if HasCompletedQuest(Spawn, 3) then
AddConversationOption(conversation, "Hello!")
StartConversation(conversation, NPC, Spawn, "Hello again " .. GetName(Spawn) )
else
-- never accepted her husbands quest, lets add a hint
AddConversationOption(conversation, "I'm not sure!")
StartConversation(conversation, NPC, Spawn, "What a nice day, i wonder how my husband is doing.")
end
end
end </pre>
Target dave and set his spawn script
<pre> /spawn set spawn_script 'SpawnScripts/VillageShin/Dave.lua' </pre>
Target jodie and set her spawn script
<pre> /spawn set spawn_script 'SpawnScripts/VillageShin/Jodie.lua' </pre>
Finally we need to reload the spawnscripts, quest scripts and NPCs so the server can pick up our change
- Reload your scripts
<pre> /reload quests /reload spawnscripts /reload spawns </pre>
Congratulations you now have a working quest!
There are many LUA functions that allow you to build any type of quest. For example you can stack up several quest steps like Chat, Kill, Visit location.
See the LUA functions reference for more information