What happens if we want to script a quest which went like this:
1. Give me grapes from Ancient Greece
2. Give me a laser gun
3. Give me a game
Well, most quests are specific, eg: "Give me grapes from Imbros, give me a 4D laser gun, give me a Battleship game." But what if we wanted to make sure ALL possible items are valid? Well, we could add in if statements. However, this gets tricky when more and more zones are built, and thus more items are valid?
We show how we can do this with one quest array, and how builders can copy and paste the entire script below and adapt it to any such quest.
Let the questarray be an array with 4 variables. First 3 are yes/no variables, and the last denoting whether the quest has been completed before or not.
Here are examples of some arrays
* Example of quest not done
myquestvar: no no no incomplete
* Example of quest where first item and third item has been found, but player hasn't completed it
myquestvar: yes no yes incomplete
* Example of quest where player has completed it at least once before, and is trying again and he only gave the second item
myquestvar: no yes no complete
Now, here is the grand script.
**** CANDIDATE LIST
**** This quest accepts multiple possible items, so update this list
**** accordingly. For example, if someone typos that another item
**** might fit, then add in the new vnum to the array. This is the only
**** change you need! YEAH!
**** Number of different items needed
set numquests 3
**** Item 1
set questitem1 12345 4205 14673
set msg1 Thanks for giving me questitem1
**** Item 2
set questitem2 1222 5070 5323 64325
set msg2 Thanks for giving me item 2!
**** Item 3
set questitem3 503 703
set msg3 Thanks buddy
*** This is it! Edit the above part when more items get added - the below will do everything for you
*** Msg is optional, could add more stuff, but you get the gist.
** We're going to loop through this
** Note: This is not the most efficient way of doing so, but
** we have relatively few quest items. If you want to re-use this code
** for substantially more vnums, one way is to order the arrays in
** increasing order, and do a binary search for appropriate vnums
if %actor.varexists(myquestvar)%
set questvars %actor.myquestvar%
eval statusnum %numquests% + 1
extract status %statusnum% %questvars%
set curritem %object.vnum%
*First loop through all arrays. numquests quest items, so numquests arrays
set arrnum 0
while %arrnum% < %numquests%
eval arrnum %arrnum% + 1
extract itemarray %arrnum% %questvars%
set item%arrnum% %itemarray%
* read this array
* Note: We have to eval this, and not set, otherwise it'll be a string
eval currarray %%questitem%arrnum%%%
* So for example, if arrnum was 1, then
* currarray would be set to 12345 4205 14673 (value of questitem1)
* %echo% %currarray%
* uncomment above to check!
* Now, find the length of this array
set stopping_criteria 1
set start 1
while %stopping_criteria% != stop
extract num %start% %currarray%
if !%num%
eval num %start% - 1
set stopping_criteria stop
endif
eval start %start% + 1
done
* We've got the length of the array stored as %num%
* Now, loop through each item in the array
set j 0
while %j% < %num%
eval j %j% + 1
extract itemtocheck %j% %currarray%
* Finally, we check if it's the same item as what we want
if %curritem% == %itemtocheck%
wait 1s
mjunk %object%
* Perfect, let's set the variable to yes
set item%arrnum% yes
* Again, eval and not set
eval currmsg %%msg%arrnum%%%
say %currmsg%
* Set a variable gotcorrectitem because we want the mob to respond
* if none of the items were right
set gotcorrectitem yes
endif
done
done
* At the end of the loop, we need to do two things
* If no right item was given, then
if !%gotcorrectitem%
wait 1
say No, no, that's all wrong.
say Try to get it right next time.
mjunk %object%
wait 2
emo waves his hands and what you handed him disappears!
halt
endif
* Now, we have to check if all 3 were achieved, and concurrently update
* the new variable. Create loop to rebuild array, and count how many
* correct items
* Create new variable resetquest in case player gets all 3
set j 0
set counter 0
while %j% < %numquests%
eval j %j% + 1
eval curritem %%item%j%%%
if %curritem% == yes
eval counter %counter% + 1
endif
if %j% == 1
set myquestvar %curritem%
set resetquest no
else
set myquestvar %myquestvar% %curritem%
set resetquest %resetquest% no
endif
done
if %counter% < %numquests%
* Can't set status to incomplete, but need to use previous
* one, because player might have done quest before
set myquestvar %myquestvar% %status%
else
* Note, got to reset quest, but must flag complete
set myquestvar %resetquest% complete
* Set complete quest sequence here
%send% %actor% I reward thee!
endif
* Finally, don't forget to remote this
remote myquestvar %actor.id%
else
* If no questflag, giving should not do anything
halt
endif