Glad to hear it. T3 is definitely not simple. The first time I tried to learn it I gave up, frankly. It wasn’t until the second time around that it started to make sense. Templates and macros are a wonderful time-saver, but they DO make it harder for a newcomer to understand how the code is structured.
At this point we should probably mention there is a mechanism known as revealing in TADS (discussed in chapter 7.1.3 Learning T3) which allows you to mark some events or occasions that happened, such as something is done or something is known, that you can query later on. It’s global mechanism, so it will free you from remembering on which object you defined properties such as mentionedStormPort. So for example instead of gert.mentionedStormPort = true you can mark that this happened with calling a macro gReveal(‘mentioned-storm-port’) and later on you can test this occasion with if(gRevealed(‘mentioned-storm-port’)) { … }.
What more, you can mark storm port as mentioned straight from the topic in double quoted string with special tag and save some typing:
[code]+ AskTopic @tStormPort
"Storm Port’s a nice old place… <.reveal mentioned-storm-port> "
;
++ AltTopic
“We live in the most beautiful town in all Amalia…”
isActive = gRevealed('mentioned-storm-port')
;[/code]
That’s awesome. Really good way to store boolean with strings attached. I may look for ways to work that in, as it’s more general. Thanks.
I don’t suppose you could help me with random numbers? I’m not sure if it’s the generation process that’s going wrong, or the way I’ve got the if statements set up. Right now I’m always getting 4 as a value.
[code] if(me.gold >= 12)
{
roomOffered = rand(4) + 1;
“Gert holds out her hand and takes the 12 pieces from you. They jingle as the drop into her palm.
She digs in the front pouch of her apron and hauls out
an old key. You’ll be in room <>1<>2<>3<>4<>. When she finishes
talking you take your leave.
<> You find the room to be quite cozy, but lacking in furnishings.
<> Upon entering you notice this room to be quite quaint, with nice furnishings.
<>You feel a bit of a draft coming from the wall in this room.
<>Two of the walls in this room are decorated with seafaring images.
<> After getting a good night’s rest you head out and return the key to Gert.”;
me.health = me.maxHealth;
me.gold = me.gold - 12;
}else{
"Gert looks at you with a stern look, and says <q>I'm sorry dear, but
it's 12 pieces to stay the night. We've only got so many rooms to
lodge our guests in, dear, or else I could help. Come back when you have the pieces.
<<if !gert.servedComplementaryMeal>> Don't forget we owe you that meal. Take a seat and I'll
bring you a hot plate.</q>";
}[/code]
Thanks,
Jeremy.
Actually I’ve solved that, but created another bug that’s a bit worse off. I moved all my actions into a script file, and saved it with extension .t. I placed that file with my other scripts in the source folder, then dragged the file into the program, where the other scripts are shown in the list tree. Now it’s throwing all kinds of missing semicolon errors, and what not. This is my actions file.
//custom actions
DefineIAction(ExamineWares)
execAction() {
switch(me.location)
{
case leakyTub:
"ale.... 6 \t \t \t lobster....8 \n";
"strong spirits....8 \t lobster chowder....8 \n";
"urchin wine....12 \t baked potatoes....6 \n";
"red wine....12 \t \t seaweed dish....8 \n";
"fish chowder....8 \t baked urchin....12 \n";
"steamed clams....8 \t steamed mussels....8 \n";
"clam platter....12 \t seafood platter....18 \n";
}
}
;
VerbRule(ExamineWares)
'wares' | 'list' 'wares' | 'list' 'goods'| 'list' 'items'
: ExamineWaresAction
verbPhrase = 'check/checking the wares'
;
DefineIAction(RentRoom)
execAction()
{
switch(me.location) {
case leakyTub:
if(me.gold >= 12)
{
roomOffered = rand(1,2,3,4);
"Gert holds out her hand and takes the 12 pieces from you. They jingle as the drop into her palm. She dumps them on
the counter and immediately begins digging in the front pouch of her apron and hauls out
an old key. <q>You'll be in room <<one of>>1<<or>>2<<or>>3<<or>>4<<at random>>. When she finishes
talking you take your leave.";
switch(roomOffered)
{
case 1:
"You find the room to be quite cozy, but lacking in furnishings.";
case 2:
"Upon entering you notice this room to be quite quaint, with nice furnishings.";
case 3:
"You feel a bit of a draft coming from the wall in this room.";
case 4:
"Two of the walls in this room are decorated with seafaring images.";
}
"After getting a good night's rest you head out and return the key to Gert.";
me.health = me.maxHealth;
me.gold = me.gold - 12;
}else{
"Gert looks at you with a stern look, and says <q>I'm sorry dear, but
it's 12 pieces to stay the night. We've only got so many rooms to
lodge our guests in, dear, or else I could help. Come back when you have the pieces.
<<if !gert.servedComplementaryMeal>> Don't forget we owe you that meal. Take a seat and I'll
bring you a hot plate.</q>";
}
default:
"You're not in an inn.";
// end switch
}
// end execAction
}
;
VerbRule(RentRoom)
'rent' | 'rent room'
: RentRoomAction
verbPhrase = 'rent/renting a room'
;
You must distinguish between assignment operator (=) and comparison operator (==). Writing <> really means “store value 1 into variable named roomOffered”.
When you add a new file to project don’t forget to add standard includes and charset definition (those lines starting with # you have in the first file) on top of the new file too. Oh, and there is no definition what is leakyTub.
Ah you had it, thanks. I needed the preprocessor directives. leakyTub is a room defined in another file. Thanks for your help tombasb.
hey,
How do you concatenate strings?
for (local i = 1 ; i <= me.questBook.length() ; ++i)
{
"<b>" me.questBook[i] "</b>\b";
"" me.questDesc[i] "";
}
Thanks.
You can use plus sign to concatenate two single quoted strings, but double quoted strings are not strings in the usual sense, they are commands to print a text, they act like a pointer to an anonymous function (probably I’m not precise here).
But what you want to do is typically programmed using embedded expressions or calling a say function:
for (local i = 1 ; i <= me.questBook.length() ; ++i)
{
"<b><<me.questBook[i]>></b>\b";
say(me.questDesc[i]);
}
You could benefit going through Learning T3 and its coding excursuses.
Something weird about the test. I can’t get inside the loop, even when values are appended to the lists.
ira.questAccepted = true;
me.questBook.append('Mending The Net');
me.questDesc.append('Ira, the local lighthouse keeper, has asked you for a little help. His net is in need of
mending before fishing season, but he\'s in no shape to do it himself. He\'s asked you to go to the lighthouse
and grab his mending shuttle, and fix the net down on the pier. He\'s offered a bit of gold as a reward.');
[code]DefineIAction(QuestBook)
execAction()
{
if(me.questBook.length() >= 1)
{
for (local i = 1 ; i <= me.questBook.length() ; ++i)
{
"<b><<me.questBook[i]>></b>\b";
say(me.questDesc[i]);
}
}else{
"You currently have no quests in your quest book.";
}
}
;
VerbRule(QuestBook)
‘quests’ | ‘quest book’
: QuestBookAction
verbPhrase = ‘quests/examing quest book’
;
[/code]
I’m not sure what type of data structure your questBook and questDesc objects are, and I’m not sure what you mean by “get inside the loop.” But I notice that you have ++i in your loop definition, which means that the first time the loop is entered, the value of i will be 2, not 1. If you want to start the loop with a value for i of 1, you need i++, not ++i.
Does that help?
It doesn’t make a difference, since ‘i’ is not read in the expression, it’s only incremented. Prefix vs postfix increment only differs when it happens in an expression that also reads the value.
Also, the third expression of a for loop is only executed after each iteration, not before
Thanks guys. These are my definitions.
questBook = []
questDesc = []
The control below isn’t firing even though I appended data to the array.
if(me.questBook.length() >= 1)
{
You have this in the loop:
"<b><<me.questBook[i]>></b>\b";
say(me.questDesc[i]);
That certainly looks to me like a usage of i in the body of the loop.
With respect to the possibility that the loop is never being entered … are you saying that the else block is what is printed? Or is nothing being printed? Because if nothing is being printed, then it could be because you have only added ONE item to each book, but you’re starting to print at nonexistent items TWO. I’m totally guessing, because I don’t know how you’re trying to test this code.
For the difference between ++i and i++ it is only significant in statements like if(++i == 5) versus if(i++ == 5) where it is incrementend and then compared vs. compared and then incremented.
For the original problem, there is no problem in the loop, but rather problem when appending new elements into the list. There is a subtle, but very important difference between List and Vector data structures you must understand. List is an immutable data type and calling an operation on it creates and returns a new List object. When you write me.questBook.append(‘Mending The Net’); a new modified list is created as a return value (and it is thrown away) leaving original variable unmodified. You must write me.questBook = me.questBook.append(‘Mending The Net’); for the statement to make an effect or use Vector class. See http://www.tads.org/t3doc/doc/sysman/vector.htm