need to substitute a more relevant response after LISTEN TO BIRD. Here's
how we do it:
+.. include:: /config/typethis.rst
+
.. code-block:: inform
Object bird "baby bird" forest
We'll go through this a step at a time:
+.. Generated by autoindex
+.. index::
+ pair: before; library property
+
#. We've added a new :prop:`before` property to our bird object. The
interpreter looks at the property *before* attempting to perform any
action which is directed specifically at this object::
print "It sounds scared and in need of assistance.^";
return true;
-#. The label is the name of an action, in this case ``Listen``. What we're
- telling the interpreter is: if the action that you're about to perform
- on the bird is a ``Listen``, execute these statements first; if it's any
- other action, carry on as normal. So, if the player types EXAMINE BIRD,
- PICK UP BIRD, PUT BIRD IN NEST, HIT BIRD or FONDLE BIRD, then she'll get
- the standard response. If she types LISTEN TO BIRD, then our two
- statements get executed before anything else happens. We call this
- "trapping" or "intercepting" the action of Listening to the bird.
+.. Generated by autoindex
+.. index::
+ pair: Listen; library action
+
+#. The label is the name of an action, in this case :act:`Listen`. What
+ we're telling the interpreter is: if the action that you're about to
+ perform on the bird is a :act:`Listen`, execute these statements first;
+ if it's any other action, carry on as normal. So, if the player types
+ EXAMINE BIRD, PICK UP BIRD, PUT BIRD IN NEST, HIT BIRD or FONDLE BIRD,
+ then she'll get the standard response. If she types LISTEN TO BIRD,
+ then our two statements get executed before anything else happens. We
+ call this "trapping" or "intercepting" the action of Listening to the
+ bird.
#. The two statements that we execute are, first::
return true;
which tells the interpreter that it doesn't need to do anything else,
- because we've handled the ``Listen`` action ourselves. And the game now
- behaves like this -- perfect:
+ because we've handled the :act:`Listen` action ourselves. And the game
+ now behaves like this -- perfect:
.. code-block:: transcript
Again, that isn't perhaps the most appropriate response, but it's easy to
change:
+.. include:: /config/typethis.rst
+
.. code-block:: inform
Object before_cottage "In front of a cottage"
The situation here is similar to our LISTEN TO BIRD problem, and the
solution we adopt is similar as well:
+.. include:: /config/typethis.rst
+
.. code-block:: inform
Object cottage "tiny cottage" before_cottage
],
has scenery;
-We use a :prop:`before` property to intercept the ``Enter`` action applied to
-the cottage object, so that we can display a more appropriate message.
-This time, however, we've done it using one statement rather than two. It
-turns out that the sequence "``print`` a string which ends with a newline
-character, and then ``return true``" is so frequently needed that there's a
-special statement which does it all. That is, this single statement (where
-you'll note that the string *doesn't* need to end in ``^``)::
+We use a :prop:`before` property to intercept the :act:`Enter` action
+applied to the cottage object, so that we can display a more appropriate
+message. This time, however, we've done it using one statement rather than
+two. It turns out that the sequence "``print`` a string which ends with a
+newline character, and then ``return true``" is so frequently needed that
+there's a special statement which does it all. That is, this single
+statement (where you'll note that the string *doesn't* need to end in
+``^``)::
print_ret "It's such a lovely day -- much too nice to go inside.";
to be achieved by that"). Yet another opportunity to use a :prop:`before`
property, but now with a difference.
+.. include:: /config/typethis.rst
+
.. code-block:: inform
Object tree "tall sycamore tree" clearing
],
has scenery;
-This time, when we intercept the ``Climb`` action applied to the ``tree``
-object, it's not in order to display a better message; it's because we want
-to move the player character to another room, just as if she'd typed UP.
-Relocating the player character is actually quite a complex business, but
-fortunately all of that complexity is hidden: there's a standard
-:term:`library routine` to do the job, not one that we've written, but one
-that's provided as part of the Inform system.
+This time, when we intercept the :act:`Climb` action applied to the
+``tree`` object, it's not in order to display a better message; it's
+because we want to move the player character to another room, just as if
+she'd typed UP. Relocating the player character is actually quite a
+complex business, but fortunately all of that complexity is hidden: there's
+a standard :term:`library routine` to do the job, not one that we've
+written, but one that's provided as part of the Inform system.
.. index::
single: arguments (of a routine)
:term:`argument`.
Although we've moved the player character to another room, we're still in
-the middle of the intercepted ``Climb`` action. As previously, we need to
-tell the interpreter that we've dealt with the action, and so we don't want
-the standard rejection message to be displayed. The ``return true``
+the middle of the intercepted :act:`Climb` action. As previously, we need
+to tell the interpreter that we've dealt with the action, and so we don't
+want the standard rejection message to be displayed. The ``return true``
statement does that, as usual.
Dropping objects from the tree
land nearby might seem a bit improbable; much more likely that it would
fall to the clearing below.
-It looks like we might want to intercept the ``Drop`` action, but not quite
-in the way we've been doing up until now. For one thing, we don't want to
-complicate the definitions of the ``bird`` and the ``nest`` and any other
-objects we may introduce: much better to find a general solution that will
-work for all objects. And second, we need to recognise that not all
+.. Generated by autoindex
+.. index::
+ pair: Drop; library action
+
+It looks like we might want to intercept the :act:`Drop` action, but not
+quite in the way we've been doing up until now. For one thing, we don't
+want to complicate the definitions of the ``bird`` and the ``nest`` and any
+other objects we may introduce: much better to find a general solution that
+will work for all objects. And second, we need to recognise that not all
objects are droppable; the player can't, for example, DROP THE BRANCH.
-The best approach to the second problem is to intercept the ``Drop`` action
-*after* it has occurred, rather than beforehand. That way, we let the
-library take care of objects which aren't being held or which can't be
-dropped, and only become involved once a ``Drop`` has been successful. And
-the best approach to the first problem is to do this particular
+The best approach to the second problem is to intercept the :act:`Drop`
+action *after* it has occurred, rather than beforehand. That way, we let
+the library take care of objects which aren't being held or which can't be
+dropped, and only become involved once a :act:`Drop` has been successful.
+And the best approach to the first problem is to do this particular
interception not on an object-by-object basis, as we have been doing so
-far, but instead for every ``Drop`` which takes place in our troublesome
+far, but instead for every :act:`Drop` which takes place in our troublesome
``top_of_tree`` room. This is what we have to write:
+.. include:: /config/typethis.rst
+
.. code-block:: inform
Object top_of_tree "At the top of the tree"
Let's again take it a step at a time:
+.. Generated by autoindex
+.. index::
+ pair: after; library property
+
#. We've added a new :prop:`after` property to our ``top_of_tree`` object.
The interpreter looks at the property *subsequent to* performing any
action in this room::
move noun to clearing;
return false;
-#. The label is the name of an action, in this case ``Drop``. What we're
- telling the interpreter is: if the action that you've just performed
- here is a ``Drop``, execute these statements before telling the player
- what you've done; if it's any other action, carry on as normal.
+#. The label is the name of an action, in this case :act:`Drop`. What
+ we're telling the interpreter is: if the action that you've just
+ performed here is a :act:`Drop`, execute these statements before telling
+ the player what you've done; if it's any other action, carry on as
+ normal.
#. The two statements that we execute are first::
move noun to clearing;
which takes the object which has just been moved from the :var:`player`
- object to the ``top_of_tree`` object (by the successful ``Drop`` action)
- and moves it again so that its parent becomes the ``clearing`` object.
- That :var:`noun` is a library variable that always contains the internal
- ID of the object which is the target of the current action. If the
- player types DROP NEST, :var:`noun` contains the internal ID of the
+ object to the ``top_of_tree`` object (by the successful :act:`Drop`
+ action) and moves it again so that its parent becomes the ``clearing``
+ object. That :var:`noun` is a library variable that always contains the
+ internal ID of the object which is the target of the current action. If
+ the player types DROP NEST, :var:`noun` contains the internal ID of the
``nest`` object; if she types DROP NESTLING then :var:`noun` contains
the internal ID of the ``bird`` object. Second, we execute::
checked for the bird actually being in the nest; fortunately, that's easy
to do:
+.. include:: /config/typethis.rst
+
.. code-block:: inform
Object branch "wide firm bough" top_of_tree
if (bird in nest && nest in branch) deadflag = 2;
+.. Generated by autoindex
+.. index::
+ pair: deadflag; library variable
+
should now be read as: "Test whether the ``bird`` is currently in (or on)
the ``nest``, *and* whether the ``nest`` is currently on (or in) the
``branch``; if both parts are :const:`true`, set the value of
Object properties
-----------------
+.. Generated by autoindex
+.. index::
+ pair: before; library property
+
Objects can have a :prop:`before` property -- if there is one, the
interpreter looks at it *before* performing an action which in some way
involves that object. Similarly, you can provide an :prop:`after`
at that particular object) but also with rooms (when they intercept actions
aimed at any object in that room).
+.. Generated by autoindex
+.. index::
+ pair: after; library property
+
The value of each :prop:`before` and :prop:`after` property is an embedded
routine. If such a routine ends with ``return false``, the interpreter
then carries on with the next stage of the action which has been
supplement the work done by a standard action with statements of your own,
or you can replace a standard action completely.
+.. Generated by autoindex
+.. index::
+ pair: cant_go; library property
+
Previously, we've seen connection properties used with the internal ID of
the room to which they lead. In this chapter, we showed that the value
could also be a string (explaining why movement in that direction isn't
.. rubric:: Actions
-We've talked a lot about intercepting actions like ``Listen``, ``Enter``,
-``Climb`` and ``Drop``. An action is a generalised representation of
-something to be done, determined by the verb which the player types. For
-example, the verbs HEAR and LISTEN are ways of saying much the same thing,
-and so both result in the same action: ``Listen``. Similarly, verbs like
-ENTER, GET INTO, SIT ON and WALK INSIDE all lead to an action of ``Enter``,
-CLIMB and SCALE lead to Climb, and DISCARD, DROP, PUT DOWN and THROW all
-lead to ``Drop``. This makes life much easier for the designer; although
-Inform defines quite a lot of actions, there are many fewer than there are
-ways of expressing those same actions using English verbs.
-
+.. Generated by autoindex
+.. index::
+ pair: Climb; library action
+ pair: Drop; library action
+ pair: Enter; library action
+ pair: Listen; library action
+
+We've talked a lot about intercepting actions like :act:`Listen`,
+:act:`Enter`, :act:`Climb` and :act:`Drop`. An action is a generalised
+representation of something to be done, determined by the verb which the
+player types. For example, the verbs HEAR and LISTEN are ways of saying
+much the same thing, and so both result in the same action: :act:`Listen`.
+Similarly, verbs like ENTER, GET INTO, SIT ON and WALK INSIDE all lead to
+an action of :act:`Enter`, CLIMB and SCALE lead to Climb, and DISCARD,
+DROP, PUT DOWN and THROW all lead to :act:`Drop`. This makes life much
+easier for the designer; although Inform defines quite a lot of actions,
+there are many fewer than there are ways of expressing those same actions
+using English verbs.
+
+.. Generated by autoindex
.. index::
pair: action; library variable
+ pair: second; library variable
Each action is represented internally by a number, and the value of the
current action is stored in a library variable called, erm, :var:`action`.
PUT NEST ON BRANCH PutOn nest branch
=============================== ====== ======= =======
+.. Generated by autoindex
+.. index::
+ pair: false; library constant
+ pair: true; library constant
+
The value ``nothing`` is a built-in constant (like :const:`true` and
:const:`false`) which means, well, there isn't any object to refer to.
There's a list of standard library actions in :ref:`group-1-actions`,