One last post to explain what the first loop does. If it's complicated, pretend it's a DG function like .contains or replace_word (which are simple - but the code behind them is not so simple).
Think of this loop as a DG function which takes into input all your item#. In the first post, we had item1, item2, ... , item6.
Then, it outputs the number where the vnum occurs, and 0 otherwise.
So, think of this as a "black box". If we had
set item1 111 112 113 114 120
set item2 200 201 214 206
set item3 300 301 333 399
set item4 400 420 490
set item5 500
set item6 666 669
Then if the object vnum was 400, our loop would return the number 4 (because 400 was in item4).
If the object vnum was 206, our loop would return the number 2 (because 206 was in item2).
If the object vnum was 10000, our loop would return the number 0 (because 10000 is not in any of the items).
Returning the number is useful, because we can use this number to check for rewards.
We had (for example)
set speecha1 thank you for the diamonds
set speechb1 blah blah love you
set tp_reward_vec 1 4 3 2 4 9
set exp_reward_vec 1000 3000 1000 1000 4000 4000
Think of the number that the loop returns (or black box) helpful, by identifying what speech to give. Eg, if we had the number 4, then we will give speecha4 and speechb4, the value of the TP in the 4th number (2), and the value of the XP in the 4th number (1000).
So this portion
if %traded_item% != 0
*Great, no rejected items. Now to find which one
wait 1
mjunk %object%
* evals the correct speech corresponding to the traded item
eval tosaypartone %%speecha%traded_item%%%
eval tosayparttwo %%speechb%traded_item%%%
say %tosaypartone%
say %tosayparttwo%
wait 1
* Reward goes here, corresponding to the traded_item
set tp_reward %tp_reward_vec.wordat(%traded_item%)%
nop %actor.trade(%tp_reward%)%
eval d %actor.level%*%exp_reward_vec.wordat(%traded_item%)%
nop %actor.exp(%d%)%
* Halt this script if we have successfully traded!
halt
endif
if you read it line by line, it just checks for the number (in %traded_item%), finds the correct speech to give with
eval tosaypartone %%speecha%traded_item%%%
eval tosayparttwo %%speechb%traded_item%%%
and gives the right TP reward and XP reward in
set tp_reward %tp_reward_vec.wordat(%traded_item%)%
nop %actor.trade(%tp_reward%)%
eval d %actor.level%*%exp_reward_vec.wordat(%traded_item%)%
nop %actor.exp(%d%)%
If you have problems reading this code, here's another way to look at this.
We have the reward code as
if %traded_item% != 0
*Great, no rejected items. Now to find which one
wait 1
mjunk %object%
* evals the correct speech corresponding to the traded item
eval tosaypartone %%speecha%traded_item%%%
eval tosayparttwo %%speechb%traded_item%%%
say %tosaypartone%
say %tosayparttwo%
wait 1
* Reward goes here, corresponding to the traded_item
set tp_reward %tp_reward_vec.wordat(%traded_item%)%
nop %actor.trade(%tp_reward%)%
eval d %actor.level%*%exp_reward_vec.wordat(%traded_item%)%
nop %actor.exp(%d%)%
* Halt this script if we have successfully traded!
halt
endif
There's lots of variables, so let's pretend that we gave object vnum 206. Running the "black box" loop, we have %traded_item% to be 2, because we had
set item2 200 201 214 206
and 206 is inside.
Let's replace %traded_item% in the code by 2 (the value of %traded_item%)
if 2 != 0
*Great, no rejected items. Now to find which one
wait 1
mjunk %object%
* evals the correct speech corresponding to the traded item
eval tosaypartone %%speecha2%%
eval tosayparttwo %%speechb2%%
say %tosaypartone%
say %tosayparttwo%
wait 1
* Reward goes here, corresponding to the traded_item
set tp_reward %tp_reward_vec.wordat(2)%
nop %actor.trade(%tp_reward%)%
eval d %actor.level%*%exp_reward_vec.wordat(2)%
nop %actor.exp(%d%)%
* Halt this script if we have successfully traded!
halt
endif
Okay, we still have more variables now like %%speecha2%%, %%speechb2%%, and %tp_reward_vec.wordat(2)%, etc, but it should be easier to see. If not, we'll go through the code one more time and replace these variables by what we've defined.
if 2 != 0
*Great, no rejected items. Now to find which one
wait 1
mjunk %object%
* evals the correct speech corresponding to the traded item
eval tosaypartone thank you for the rubies
eval tosayparttwo blah blah love you
say %tosaypartone%
say %tosayparttwo%
wait 1
* Reward goes here, corresponding to the traded_item
* because 4 was the word at 2 for the tp_reward_vec
set tp_reward 4
nop %actor.trade(%tp_reward%)%
* because 3000 was the word at 2 for the exp_reward_vec
eval d %actor.level%*3000
nop %actor.exp(%d%)%
* Halt this script if we have successfully traded!
halt
endif
And that's it
------------
This is the loop to find the value of %traded_item% for further info. If it bothers you, pretend it's a DG function that gives you what you want
while %i% <= %max_items%
* look at first itemvec
* Need to eval this!
eval item_to_check %%item%i%%%
set j 1
while %j% != 0
extract curr_item %j% %item_to_check%
if !%curr_item%
* Loop will stop
set j 0
else
if %curr_item% == %currvnum%
set traded_item %i%
break
endif
eval j %j% + 1
endif
done
if %traded_item% != 0
eval i %max_items% + 1
endif
eval i %i% + 1
done
I'm reluctant to say: "Use this code even if you don't understand it", because that's where lots of errors can occur. But in that case, we also shouldn't use cool DG commands like
.contains
.wordat()
.strlen
replace_word
etc, because we don't know how to "script" the equivalent in DG. But we still use them anyway. For example, replace_word as a DG function is easy to understand
set sentence This is a dog and it is barking
replace_word boy 4 %sentence%
will give This is a boy and it is barking. But not many of us will be able to script the equivalent in DG.
set sentence This is a dog and it is barking
* want to replace boy in word 4
set word_to_replace boy
set num_at_replace 4
* After setting sentence, word_to_replace, num_at_replace, then:
* Find the maximum length of this sentence
set len 0
while %len%
eval len %len% + 1
extract tmp %len% %sentence%
if !%tmp%
break
endif
done
eval len %len% - 1
*len is now the length of the sentence (ie number of words)
extract newsentence 1 %sentence%
set i 2
while %i% < %num_at_replace%
extract nextword %i% %sentence%
set newsentence %newsentence% %nextword%
eval i %i% + 1
done
set newsentence %newsentence% %word_to_replace%
eval i %i% + 1
while %i% <= %len%
extract nextword %i% %sentence%
set newsentence %newsentence% %nextword%
eval i %i% + 1
done
However, hold on! This code won't work if we wanted to replace the first word. So the actual code would be something like
set sentence This is a dog and it is barking
* want to replace that in word 1
set word_to_replace that
set num_at_replace 1
* After setting sentence, word_to_replace, num_at_replace, then:
* Find the maximum length of this sentence
set len 0
while %len%
eval len %len% + 1
extract tmp %len% %sentence%
if !%tmp%
break
endif
done
eval len %len% - 1
*len is now the length of the sentence (ie number of words)
if %num_at_replace% == 1
set newsentence %word_to_replace%
set i 2
else
extract newsentence 1 %sentence%
set i 2
while %i% < %num_at_replace%
extract nextword %i% %sentence%
set newsentence %newsentence% %nextword%
eval i %i% + 1
done
set newsentence %newsentence% %word_to_replace%
eval i %i% + 1
endif
while %i% <= %len%
extract nextword %i% %sentence%
set newsentence %newsentence% %nextword%
eval i %i% + 1
done
It's a pain to read, especially without comments. Most builders probably don't understand what that does, and wouldn't dare to use it, but they would use
replace_word
even though it does the same thing.
So maybe you have a question: If we can put that terrible looking loop in the form of
replace_word
then why can't we do the same for
while %i% <= %max_items%
* look at first itemvec
* Need to eval this!
eval item_to_check %%item%i%%%
set j 1
while %j% != 0
extract curr_item %j% %item_to_check%
if !%curr_item%
* Loop will stop
set j 0
else
if %curr_item% == %currvnum%
set traded_item %i%
break
endif
eval j %j% + 1
endif
done
if %traded_item% != 0
eval i %max_items% + 1
endif
eval i %i% + 1
done
?
Well, let's see how replace_word works. The syntax is
replace_word blah 4 sentence
And you can read this as: "We are going to replace the 4th word of sentence by the word blah"
But, what the "black box" loop does is: Given any number of possible traded items (could be 6, could 10, could 2), the loop will return the item number. How would such an input look like if we had such a function? Eg if we wanted to check if vnum 12345 was in item1 to item3, then..
blackboxloop 12345 item1 item2 item3
?
But if we had 10 items, then
blackboxloop 12345 item1 item2 item3 item4 item5 item6 item7 item8 item9 item10
?
What if the builder transposed two numbers, eg
blackboxloop 12345 item2 item1 item3
, would it still return the right number? So maybe it's better if the loop was in DG instead of a function...