1 ===============================
2 William Tell: the end is nigh
3 ===============================
9 | *Q was a queen, who wore a silk slip;*
10 | *R was a robber, and wanted a whip.*
14 .. image:: /images/picQ.png
21 uite a few objects still remain undefined, so we'll talk about them first.
22 Then, we'll explain how to make additions to Inform's standard repertoire
23 of verbs, and how to define the actions which those verbs trigger.
28 The ``marketplace`` room is unremarkable, and the ``tree`` growing there
29 has only one feature of interest::
31 Room marketplace "Marketplace near the square"
33 "Altdorf's marketplace, close by the town square, has been hastily
34 cleared of stalls. A troop of soldiers has pushed back the crowd
35 to leave a clear space in front of the lime tree, which has been
36 growing here for as long as anybody can remember. Usually it
37 provides shade for the old men of the town, who gather below to
38 gossip, watch the girls, and play cards. Today, though, it
39 stands alone... apart, that is, from Walter, who has been lashed
40 to the trunk. About forty yards away, you are restrained by two
42 cant_go "What? And leave your son tied up here?";
44 Object tree "lime tree" marketplace
45 with name 'lime' 'tree',
46 description "It's just a large tree.",
49 if (BowOrArrow(second) == true) {
51 print_ret "Your hand shakes a little, and your arrow flies
52 high, hitting the trunk a few inches above Walter's
59 The tree's ``before`` property is intercepting a ``FireAt`` action, which
60 we'll define in a few moments. This action is the result of a command like
61 SHOOT AT TREE WITH BOW -- we could simulate it with the statement
62 ``<<FireAt tree bow>>`` -- and it needs extra care to ensure that the
63 ``second`` object is a feasible weapon. To deal with silly commands like
64 SHOOT AT TREE WITH HELGA, we must test that ``second`` is the bow, one of
65 the arrows, or ``nothing`` (from just SHOOT AT TREE). Since this is quite
66 a complex test, and one that we'll be making in several places, it's
67 sensible to write a routine to do the job. Which we'll do shortly -- but
68 first, a general introduction to working with routines.
70 .. _working-with-routines:
72 A diversion: working with routines
73 ==================================
75 A standalone routine, like the familiar routines embedded as the value of a
76 property such as ``before`` or ``each_turn``, is simply a set of statements
77 to be executed. The major differences are in content, in timing, and in
78 the default return value:
80 * Whereas an embedded routine has to contain statements which do something
81 appropriate for that associated property variable, a standalone routine
82 can contain statements which do anything you wish. You have total
83 freedom as to what the routine actually does and what value it returns.
85 * An embedded routine is called when the interpreter is dealing with that
86 property of that object; you provide the routine, but you don't directly
87 control when it's called. A standalone routine, however, is completely
88 under your control; it runs only when you explicitly call it.
90 * If an embedded routine executes all of its statements and reaches the
91 final ``];`` without encountering some form of ``return`` statement, it
92 returns the value ``false``. In the same circumstances, a standalone
93 routine returns the value ``true``. There's a good reason for this
94 difference -- it usually turns out to be the natural default behaviour --
95 but it can sometimes baffle newcomers. To avoid confusion, we've always
96 included explicit ``return`` statements in our routines.
98 What this generally boils down to is: *if* you have a collection of
99 statements which perform some specific task *and* you need to execute those
100 same statements in more than one place in your game, *then* it often makes
101 sense to turn those statements into a standalone routine. The advantages
102 are: you write the statements only once, so any subsequent changes are
103 easier to make; also, your game becomes simpler and easier to read. We'll
104 look at some simple examples; first consider these unexciting foodstuffs::
106 Object "stale ham sandwich"
107 with name 'stale' 'ham' 'sandwich',
108 description "It doesn't look at all appetising.",
111 Object "elderly jam doughnut"
112 with name 'elderly' 'jam' 'jelly' 'doughnut' 'donut',
113 description "It doesn't look at all appetising.",
116 The ``description``\s are identical: perhaps we could display them using a
119 [ Inedible; print_ret "It doesn't look at all appetising."; ];
121 Object "stale ham sandwich"
122 with name 'stale' 'ham' 'sandwich',
123 description [; Inedible(); ],
126 Object "elderly jam doughnut"
127 with name 'elderly' 'jam' 'jelly' 'doughnut' 'donut',
128 description [; Inedible(); ],
131 This isn't a very realistic approach -- there are more elegant ways of
132 avoiding typing the same string twice -- but it works, and it illustrates
133 how we can define a routine to do something useful, and then call it
136 Here's another simple example showing how, by returning a value, a routine
137 can report back to the piece of code which called it. We've once or twice
138 used the test ``if (self has visited) ...``; we could create a routine
139 which performs that same check and then returns ``true`` or ``false`` to
140 indicate what it discovered::
143 if (self has visited) return true;
147 Then, we'd rewrite our test as ``if (BeenHereBefore() == true) ...``; no
148 shorter or quicker, but maybe more descriptive of what's going on. One
149 more example of using routines. As well as testing ``if (self has visited)
150 ...`` we've also tested ``if (location has visited) ...`` a few times, so
151 we *could* write another routine to perform that check::
154 if (location has visited) return true;
158 However, the two routines are very similar; the only difference is the name
159 of the variable -- ``self`` or ``location`` -- which is being checked. A
160 better approach might be to rework our ``BeenHereBefore`` routine so that
161 it does both jobs, but we somehow need to tell it which variable's value is
162 to be checked. That's easy: we design the routine so that it expects an
165 [ BeenToBefore this_room;
166 if (this_room has visited) return true;
170 Notice that the argument's name is one that we've invented to be
171 descriptive of its content; it doesn't matter if we define it as "``x``",
172 "``this_room``" or "``hubba_hubba``". Whatever its name, the argument acts
173 as a placeholder for a value (here, one of the variables ``self`` or
174 ``location``) which we must supply when calling the routine::
176 if (BeenToBefore(self) == true) ...
178 if (BeenToBefore(location) == true) ...
180 In the first line, we supply ``self`` as the routine's argument. The
181 routine doesn't care where the argument came from; it just sees a value
182 which it knows as ``this_room``, and which it then uses to test for the
183 ``visited`` attribute. On the second line we supply ``location`` as the
184 argument, but the routine just sees another value in its ``this_room``
185 variable. ``this_room`` is called a :term:`local variable` of the
186 ``BeenToBefore`` routine, one that must be set to a suitable value each
187 time that the routine is called. In this example routine, the value needs
188 to be a room object; we could also check an explicit named room::
190 if (BeenToBefore(mid_square) == true) ...
194 #. All routines terminate sooner or later, either because you explicitly
195 write a ``return``, ``rtrue`` or ``rfalse`` statement, or because
196 execution reaches the ``]`` marking the routine's end.
198 #. All routines return a value, which can be ``true``, or ``false``, or any
199 other number. This value is determined by the ``return``, ``rtrue`` or
200 ``rfalse`` statement, or by the the ``]`` marking the routine's end (in
201 which case the default STEF rule applies: Standalone routines return
202 True, Embedded routines return False). We gave this example of an
203 embedded routine in :ref:`adding-props`. The ``return false`` statement
204 is redundant: we could remove it without affecting the routine's
205 behaviour, because the ``]`` acts like a ``return false``::
208 if (location == street or below_square or south_square or
209 mid_square or north_square or marketplace) return true;
213 On the other hand, just because a routine returns a value doesn't mean
214 you always *have* to use it; you can simply ignore the value if you want
215 to. The ``TooFarAway`` routine that we showed you earlier in this
216 chapter contains a ``print_ret`` statement and so always returns
217 ``true``, but we didn't take any notice; the sole purpose of the routine
218 was to display some text. Compare this with the ``BeenToBefore``
219 routine, which does nothing *except* return a value; if we'd ignored
220 that, then calling the routine would have been a waste of time.
222 For some embedded routines, the value returned by the routine is important;
223 for others it doesn't matter. We've so far seen the following properties
224 whose value can be an embedded routine:
226 ========================= ===========================
227 Return value is important Return value doesn't matter
228 ========================= ===========================
229 ``after [; ... ],`` ``cant_go [; ... ],``
230 ``before [; ... ],`` ``description [; ... ],``
231 ``found_in [; ... ],`` ``each_turn [; ... ],``
232 ``n_to [; ... ]``, et al ``initial [; ... ],``
233 ========================= ===========================
235 For full details on which library property values can be embedded routines,
236 and which return values are significant, see :ref:`object-props` and
237 :dm4:`Appendix §A2 <sa2.html>` of the |DM4|.
239 Return to the marketplace
240 =========================
242 After all that introduction, finally back to the ``FireAt`` action. We
243 want to check on the characteristics of an object, possibly then displaying
244 a message. We don't know exactly *which* object is to be checked, so we
245 need to write our routine in a generalised way, capable of checking any
246 object which we choose; that is, we'll supply the object to be checked as
247 an argument. Here's the routine::
250 if (o == bow or nothing || o ofclass Arrow) return true;
251 print "That's an unlikely weapon, isn't it?^";
255 The routine is designed to inspect any object which is passed to it as its
256 argument ``o``; that is, we could call the routine like this::
258 BowOrArrow(stallholder)
262 Given the ``bow`` object, or any object which we defined as class
263 ``Arrow``, it will silently ``return true`` to signify agreement that this
264 object can be fired. However, given an object like Helga, the apple or the
265 tree, it will print a message and ``return false`` to signify that this
266 object is not a suitable weapon. The test that we make is::
268 if (o == bow or nothing || o ofclass Arrow) ...
270 which is merely a slightly shorter way of saying this::
272 if (o == bow || o == nothing || o ofclass Arrow) ...
274 The result is that we ask three questions: Is ``o`` the ``bow`` object?
275 *Or* is it ``nothing``? Or, using the ``ofclass`` test, is it any object
276 which is a member of the ``Arrow`` class?
278 What this means is that the value returned by the call ``BowOrArrow(bow)``
279 is ``true``, while the value returned by the call ``BowOrArrow(tree)`` is
280 ``false``. Or, more generally, the value returned by the call
281 ``BowOrArrow(second)`` will be either ``true`` or ``false``, depending on
282 the characteristics of the object defined by the value of the variable
283 ``second``. So, we can write this set of statements in an object's
284 ``before`` property::
286 if (BowOrArrow(second) == true) {
287 This object deals with having an arrow fired at it
291 and the effect is either
293 * ``second`` is a weapon: ``BowOrArrow`` displays nothing and returns a
294 value of ``true``, the ``if`` statement reacts to that value and executes
295 the following statements to produce an appropriate response to the
296 fast-approaching arrow; or
298 * ``second`` isn't a weapon: ``BowOrArrow`` displays a standard "don't be
299 silly" message and returns a value of ``false``, the ``if`` statement
300 reacts to that value and ignores the following statements. Then
302 * in both cases, the ``return true`` statement terminates the object's
303 interception of the ``FireAt`` action.
305 That whole ``BowOrArrow()`` bit was rather complex, but the rest of the
306 ``FireAt`` action is straightforward. Once the tree has determined that
307 it's being shot at by something sensible, it can just set ``deadflag`` to 3
308 -- the "You have screwed up" ending, display a message, and be done.
313 There's nothing in Gessler's definition that we haven't already encountered::
315 NPC governor "governor" marketplace
316 with name 'governor' 'vogt' 'Hermann' 'Gessler',
318 "Short, stout but with a thin, mean face, Gessler relishes the
319 power he holds over the local community.",
321 print "Gessler is watching from a safe distance,
322 a sneer on his face.^";
323 if (location hasnt visited)
324 print_ret "^~It appears that you need to be taught a lesson,
325 fool. Nobody shall pass through the square without paying
326 homage to His Imperial Highness Albert; nobody, hear me?
327 I could have you beheaded for treason, but I'm going to
328 be lenient. If you should be so foolish again, you can
329 expect no mercy, but this time, I'll let you go free...
330 just as soon as you demonstrate your archery skills by
331 hitting this apple from where you stand. That shouldn't
332 prove too difficult; here, sergeant, catch. Balance it on
333 the little bastard's head.~";
337 print_ret "You cannot bring yourself to speak to him.";
341 if (BowOrArrow(second) == true) {
343 print_ret "Before the startled soldiers can react, you turn
344 and fire at Gessler; your arrow pierces his heart,
345 and he dies messily. A gasp, and then a cheer,
346 goes up from the crowd.";
352 Like most NPCs, Gessler has a ``life`` property which deals with actions
353 applicable only to animate objects. This one responds merely to ``Talk``
354 (as in TALK TO THE GOVERNOR).
359 Since he's been with you throughout, it's really about time we defined
363 with name 'son' 'your' 'boy' 'lad' 'Walter',
365 if (location == marketplace)
366 print_ret "He stares at you, trying to appear brave and
367 remain still. His arms are pulled back and tied behind
368 the trunk, and the apple nestles amid his blond hair.";
370 print_ret "A quiet, blond lad of eight summers, he's fast
371 learning the ways of mountain folk.";
377 print_ret "~Thank you, Papa.~";
379 if (location == marketplace)
380 print_ret "~Stay calm, my son, and trust in God.~";
382 print_ret "You point out a few interesting sights.";
385 Examine,Listen,Salute,Talk:
388 if (location == marketplace) {
389 if (BowOrArrow(second) == true) {
391 print_ret "Oops! Surely you didn't mean to do that?";
398 if (location == marketplace)
399 print_ret "Your guards won't permit it.";
403 found_in [; return true; ],
404 has male proper scenery transparent;
406 His attributes are ``male`` (he's your son, after all), ``proper`` (so the
407 interpreter doesn't mention "the your son"), ``scenery`` (so he's not
408 listed in every room description), and ``transparent`` (because you see
409 right through him). No, that's wrong: a ``transparent`` object isn't made
410 of glass; it's one whose possessions are visible to you. We've done that
411 because we'd still like to be able to EXAMINE APPLE even when Walter is
412 carrying it. Without the ``transparent`` attribute, it would be as though
413 the apple was in his pocket or otherwise out of sight; the interpreter
414 would reply "You can't see any such thing".
416 Walter has a ``found_in`` property which automatically moves him to the
417 player's location on each turn. We can get away with this because in such
418 a short and simple game, he does indeed follow you everywhere. In a more
419 realistic model world, NPCs often move around independently, but we don't
420 need such complexity here.
422 Several of Walter's properties test whether ``(location == marketplace)``;
423 that is, is the player (and hence Walter) currently in that room? The
424 events in the marketplace are such that specialised responses are more
425 appropriate there than our standard ones.
427 Walter's ``life`` property responds to ``Give`` (as in GIVE APPLE TO
428 WALTER) and Talk (as in TALK TO YOUR SON); during ``Give``, we increment
429 the library variable ``score``, thus rewarding the player's generous good
430 nature. His ``before`` property is perhaps a little confusing. It's
433 #. The ``Examine``, ``Listen``, ``Salute`` and ``Talk`` actions are always
434 available (a ``Talk`` action then gets passed to Walter's ``life``
437 #. The ``FireAt`` action is permitted in the ``marketplace``, albeit with
438 unfortunate results. Elsewhere, it triggers the standard ``FireAt``
439 response of "Unthinkable!"
441 #. All other actions are prevented in the ``marketplace``, and allowed to
442 run their standard course (thanks to the ``return false``) elsewhere.
444 The apple's moment of glory has arrived! Its ``before`` property responds
445 to the ``FireAt`` action by setting ``deadflag`` to 2. When that happens,
446 the game is over; the player has won. ::
451 if (location == marketplace)
452 print_ret "At this distance you can barely see it.";
454 print_ret "The apple is blotchy green and brown.";
458 print_ret "An apple is worth quite a bit --
459 better hang on to it.";
461 print_ret "Helga intended it for Walter...";
463 if (location == marketplace) {
464 if (BowOrArrow(second) == true) {
467 print_ret "Slowly and steadily, you place an arrow in
468 the bow, draw back the string, and take aim with
469 more care than ever in your life. Holding your
470 breath, unblinking, fearful, you release the
471 arrow. It flies across the square towards your
472 son, and drives the apple against the trunk of
473 the tree. The crowd erupts with joy;
474 Gessler looks distinctly disappointed.";
482 And with that, we've defined all of the objects. In doing so, we've added
483 a whole load of new nouns and adjectives to the game's dictionary, but no
484 verbs. That's the final task.
491 The Inform library delivers a standard set of nearly a hundred actions
492 which players can perform; around twenty of those are "meta-actions" (like
493 SAVE and QUIT) aimed at the interpreter itself, and the remainder operate
494 within the model world. Having such a large starting set is a great
495 blessing; it means that many of the actions which players might attempt are
496 already catered for, either by the interpreter doing something useful, or
497 by explaining why it's unable to. Nevertheless, most games find the need
498 to define additional actions, and "William Tell" is no exception. We'll be
499 adding four actions of our own: ``Untie``, ``Salute``, ``FireAt`` and
504 It's not the most useful action, but it is the simplest. In the
505 marketplace, when Walter is lashed to the tree, it's possible that players
506 might be tempted to try to UNTIE WALTER; unlikely, but as we've said
507 before, anticipating the improbable is part of the craft of IF. For this,
508 and for all new actions, two things are required. We need a grammar
509 definition, spelling out the structure of the English sentences which we're
512 Verb 'untie' 'unfasten' 'unfix' 'free' 'release'
515 and we need a routine to handle the action in the default situation (where
516 the action isn't intercepted by an object's ``before`` property). ::
518 [ UntieSub; print_ret "You really shouldn't try that."; ];
520 The grammar is less complex than it perhaps at first appears:
522 #. The English verbs UNTIE, UNFASTEN, UNFIX, FREE and RELEASE are
525 #. The asterisk ``*`` indicates the start of a pattern defining what
526 word(s) might follow the verb.
528 #. In this example, there's only one pattern: the "``noun``" token
529 represents an object which is currently in scope -- in the same room as
532 #. The ``->`` indicates an action to be triggered.
534 #. If players type something that matches the pattern -- one of those five
535 verbs followed by an object in scope -- the interpreter triggers an
536 ``Untie`` action, which by default is handled by a routine having the
537 same name as the action, with ``Sub`` appended. In this example, that's
538 the ``UntieSub`` routine.
540 #. The grammar is laid out this way just to make it easier to read. All those
541 spaces aren't important; we could equally have typed::
543 Verb 'untie' 'unfasten' 'unfix' 'free' 'release' * noun -> Untie;
545 We can illustrate how this works in the Altdorf street:
547 .. code-block:: transcript
550 The narrow street runs north towards the town square. Local folk are pouring
551 into the town through the gate to the south, shouting greetings, offering
552 produce for sale, exchanging news, enquiring with exaggerated disbelief about
553 the prices of the goods displayed by merchants whose stalls make progress even
556 "Stay close to me, son," you say, "or you'll get lost among all these people."
559 What do you want to untie?
562 You can't see any such thing.
565 You don't need to worry about the local people.
568 You really shouldn't try that.
570 The illustration shows four attempted usages of the new action. In the
571 first, the player omits to mention an object; the interpreter knows (from
572 that ``noun`` in the grammar which implies that the action needs a direct
573 object) that something is missing, so it issues a helpful prompt. In the
574 second, the player mentions an object that isn't in scope (in fact, there's
575 no dog anywhere in the game, but the interpreter isn't about to give *that*
576 away to the player). In the third, the object is in scope, but its
577 ``before`` property intercepts the ``Untie`` action (and indeed, since this
578 object is of the class ``Prop``, all actions apart from ``Examine``) to
579 display a customised rejection message. Finally, the fourth usage refers
580 to an object which *doesn't* intercept the action, so the interpreter calls
581 the default action handler -- ``UntieSub`` -- which displays a
582 general-purpose refusal to perform the action.
584 The principles presented here are those that you should generally employ:
585 write a generic action handler which either refuses to do anything (see,
586 for example SQUASH or HIT), or performs the action without affecting the
587 state of the model world (see, for example, JUMP or WAVE); then, intercept
588 that non-action (generally using a ``before`` property) for those objects
589 which might make a legitimate target for the action, and instead provide a
590 more specific response, either performing or rejecting the action.
592 In the case of ``Untie``, there are no objects which can be untied in this
593 game, so we always generate a refusal of some sort.
597 The next action is ``Salute``, provided in case Wilhelm chooses to defer to
598 the hat on the pole. Here's the default action handler::
601 if (noun has animate) print_ret (The) noun, " acknowledges you.";
602 print_ret (The) noun, " takes no notice.";
605 You'll notice that this is slightly more intelligent than our ``Untie``
606 handler, since it produces different responses depending on whether the
607 object being saluted -- stored in the ``noun`` variable -- is ``animate``
608 or not. But it's basically doing the same job. And here's the grammar::
610 Verb 'bow' 'nod' 'kowtow' 'genuflect'
611 * 'at'/'to'/'towards' noun -> Salute;
613 Verb 'salute' 'greet' 'acknowledge'
616 This grammar says that:
618 #. The English verbs BOW, NOD, KOWTOW, GENUFLECT, SALUTE, GREET and
619 ACKNOWLEDGE are synonymous.
621 #. The first four (but not the last three) can then be followed by any of
622 the prepositions AT, TO or TOWARDS: words in apostrophes ``'...'`` are
623 matched literally, with the slash ``/`` separating alternatives.
625 #. After that comes the name of an object which is currently in scope -- in
626 the same room as the player.
628 #. If players type something that matches one of those patterns, the
629 interpreter triggers a ``Salute`` action, which by default is dealt with
630 by the ``SaluteSub`` routine.
632 So, we're allowing BOW AT HAT and KOWTOW TOWARDS HAT, but not simply NOD
633 HAT. We're allowing SALUTE HAT but not GREET TO HAT. It's not perfect,
634 but it's a fair attempt at defining some new verbs to handle salutation.
636 But suppose that we think of still other ways in which players might
637 attempt this (remember, they don't know which verbs we've defined; they're
638 just stabbing in the dark, trying out things that seem as though they ought
639 to work). How about PAY HOMAGE TO HAT, or maybe WAVE AT HAT? They sound
640 pretty reasonable, don't they? Except that, if we'd written::
642 Verb 'bow' 'nod' 'kowtow' 'genuflect' 'wave'
643 * 'at'/'to'/'towards' noun -> Salute;
645 we'd have caused a compilation error: two different verb definitions refer
646 to "wave". ``Grammar.h``, one of the library files whose contents a
647 beginner might find useful to study, contains these lines::
649 Verb 'give' 'pay' 'offer' 'feed'
650 * held 'to' creature -> Give
651 * creature held -> Give reverse
652 * 'over' held 'to' creature -> Give;
658 The problem is that the verbs PAY and WAVE are already defined by the
659 library, and Inform's rule is that a verb can appear in only one ``Verb``
660 definition. The wrong solution: edit ``Grammar.h`` to *physically* add
661 lines to the existing definitions (it's almost never a good idea to make
662 changes to the standard library files). The right solution: use ``Extend``
663 to *logically* add those lines. If we write this in our source file::
666 * 'homage' 'to' noun -> Salute;
669 * 'at' noun -> Salute;
671 then the effect is exactly as if we'd edited ``Grammar.h`` to read like
674 Verb 'give' 'pay' 'offer' 'feed'
675 * held 'to' creature -> Give
676 * creature held -> Give reverse
677 * 'over' held 'to' creature -> Give
678 * 'homage' 'to' noun -> Salute;
683 * 'at' noun -> Salute;
685 and now players can PAY (or GIVE, or OFFER) HOMAGE to any object. (Because
686 GIVE, PAY, OFFER and FEED are defined as synonyms, players can also FEED
687 HOMAGE, but it's unlikely that anybody will notice this minor aberration;
688 players are usually too busy trying to figure out *logical* possibilities.)
692 As usual, we'll first show you the default handler for this action::
696 print_ret "What, just fire off an arrow at random?";
697 if (BowOrArrow(second) == true)
698 print_ret "Unthinkable!";
703 Some designers frown on the use of a rhetorical question like that,
704 since it may provoke a reply from the player. Admittedly the default
705 response from YES and NO covers the situation, but it might be better
706 design practice to reword the message as a statement rather than a
709 Here is the associated grammar::
711 Verb 'fire' 'shoot' 'aim'
714 * 'at' noun -> FireAt
715 * 'at' noun 'with' noun -> FireAt
716 * noun 'with' noun -> FireAt
717 * noun 'at' noun -> FireAt reverse;
719 This is the most complex grammar that we'll write, and the first one
720 offering several different options for the words which follow the initial
721 verb. The first line of grammar::
725 is going to let us type FIRE (or SHOOT, or AIM) by itself. The second
730 supports FIRE BOW or FIRE ARROW (or something less sensible like
731 FIRE TREE). The third line::
733 * 'at' noun -> FireAt
735 accepts FIRE AT APPLE, FIRE AT TREE, and so on. Note that there's only one
736 semicolon in all of the grammar, right at the very end.
738 The first two statements in ``FireAtSub`` deal with the first line of
739 grammar: FIRE (or SHOOT, or AIM) by itself. If the player types just that,
740 both ``noun`` and ``second`` will contain ``nothing``, so we reject the
741 attempt with the "at random?" message. Otherwise, we've got at least a
742 ``noun`` value, and possibly a ``second`` value also, so we make our
743 standard check that ``second`` is something that can be fired, and then
744 reject the attempt with the "Unthinkable!" message.
746 There are a couple of reasons why you might find this grammar a bit tricky.
747 The first is that on some lines the word ``noun`` appears twice: you need
748 to remember that in this context ``noun`` is a parsing token which matches
749 any single object visible to the player. Thus, the line::
751 * 'at' noun 'with' noun -> FireAt
753 is matching FIRE AT :samp:`{some_visible_target}` WITH
754 :samp:`{some_visible_weapon}`; perhaps confusingly, the value of the target
755 object is then stored in variable ``noun``, and the value of the weapon
756 object in variable ``second``.
758 The second difficulty may be the final grammar line. Whereas on the
759 preceding lines, the first ``noun`` matches a target object and the second
760 ``noun``, if present, matches a weapon object, that final line matches FIRE
761 :samp:`{some_visible_weapon}` AT :samp:`{some_visible_target}` -- the two
762 objects are mentioned in the wrong sequence. If we did nothing, our
763 ``FireAtSub`` would get pretty confused at this point, but we can swap the
764 two objects back into the expected order by adding that ``reverse`` keyword
765 at the end of the line, and then ``FireAtSub`` will work the same in all
768 Before leaving the ``FireAt`` action, we'll add one more piece of grammar::
770 Extend 'attack' replace
773 This uses the ``Extend`` directive which we've just met, this time with a
774 ``replace`` keyword. The effect is to substitute the new grammar defined
775 here for that contained in ``Grammar.h``, so that ATTACK, KILL, MURDER and
776 all the other violent synonyms now trigger our ``FireAt`` action instead of
777 the Library's standard ``Attack`` action. We're doing this so that, in the
778 Marketplace, KILL GESSLER and MURDER WALTER have the same unfortunate
779 results as FIRE AT GESSLER and SHOOT WALTER.
783 The final action that we define -- ``Talk`` -- provides a simple system of
784 canned conversation, a low-key replacement for the standard ``Answer``,
785 ``Ask`` and ``Tell`` actions. The default ``TalkSub`` handler is closely
786 based on ``TellSub`` (defined in library file ``verblibm.h``, should you be
787 curious), and does three things:
789 #. Deals with TALK TO ME or TALK TO MYSELF.
791 #. Checks (a) whether the creature being talked to has a ``life``
792 property, (b) whether that property is prepared to process a ``Talk``
793 action, and (c) if the ``Talk`` processing returns ``true``. If all
794 three checks succeed then ``TalkSub`` need do nothing more; if one or
795 more of them fails then ``TalkSub`` simply...
797 #. Displays a general "nothing to say" refusal to talk. ::
800 if (noun == player) print_ret "Nothing you hear surprises you.";
801 if (RunLife(noun,##Talk) ~= false) return;
802 print_ret "At the moment, you can't think of anything to say.";
807 That second condition ``(RunLife(noun,##Talk) ~= false)`` is a bit of
808 a stumbling block, since it uses ``RunLife`` -- an undocumented
809 internal library routine -- to offer the ``Talk`` action to the NPC's
810 ``life`` property. We've decided to use it in exactly the same way
811 as the ``Tell`` action does, without worrying too much about how it
812 works (though it looks as though ``RunLife`` returns some ``true``
813 value if the ``life`` property has intercepted the action, ``false``
814 if it hasn't). The ``~=`` operator means "not equal to".
816 The grammar is straightforward::
818 Verb 'talk' 't//' 'converse' 'chat' 'gossip'
819 * 'to'/'with' creature -> Talk
822 Notice the use of ``'t//'`` to define T as a synonym for TALK, another way
823 to make life a little easier for the player. (Actually, doing this
824 introduces a minor problem: if the player types just T then the library
825 prompts "Whom do you want to t to?" The fix for this involves enhancing an
826 internal library routine called ``LanguageVerb`` -- not complex, but a
827 little too heavy for our second game.)
829 Here's the simplest ``Talk`` handler that we've seen -- it's from Gessler
830 the governor. Any attempt to TALK TO GESSLER will provoke "You cannot
831 bring yourself to speak to him". ::
834 Talk: print_ret "You cannot bring yourself to speak to him.";
837 Walter's ``Talk`` handler is only slightly more involved::
841 if (location == marketplace)
842 print_ret "~Stay calm, my son, and trust in God.~";
843 print_ret "You point out a few interesting sights.";
846 And Helga's is the most sophisticated (though that isn't saying much)::
848 times_spoken_to 0, ! for counting the conversation topics
851 self.times_spoken_to = self.times_spoken_to + 1;
852 switch (self.times_spoken_to) {
853 1: score = score + 1;
854 print_ret "You warmly thank Helga for the apple.";
855 2: print_ret "~See you again soon.~";
861 This handler uses Helga's ``times_spoken_to`` property -- not a library
862 property, it's one that we invented, like the ``mid_square.warnings_count``
863 and ``pole.has_been_saluted`` properties -- to keep track of what's been
864 said, permitting two snatches of conversation (and awarding a point) before
865 falling back on the embarrassing silences implied by "You can't think of
868 That's the end of our little fable; you'll find a transcript and the full
869 source in :doc:`/appendices/c`. And now, it's time to meet -- Captain