X-Git-Url: https://jxself.org/git/?p=ibg.git;a=blobdiff_plain;f=chapters%2F05.rst;h=8e3fb54a703c4207ff4e6f54d864fe1fed53826c;hp=aabd40d68db1c0a1438d1a9d802c3f89e790034a;hb=4381288eeb792adb3672ef747013c02815fa760a;hpb=4261ff48a6357e2af0957f5e1b88bdc022243d16 diff --git a/chapters/05.rst b/chapters/05.rst index aabd40d..8e3fb54 100644 --- a/chapters/05.rst +++ b/chapters/05.rst @@ -74,6 +74,10 @@ how we do it: 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:: @@ -87,14 +91,19 @@ We'll go through this a step at a time: 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:: @@ -107,8 +116,8 @@ We'll go through this a step at a time: 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 @@ -251,13 +260,14 @@ solution we adopt is similar as well: ], 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."; @@ -292,13 +302,13 @@ property, but now with a difference. ], 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) @@ -315,9 +325,9 @@ closing parentheses. That is, instead of just ``PlayerTo()`` we call :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 @@ -330,20 +340,24 @@ the top of the tree. Should she DROP something from up there, having it 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: .. code-block:: inform @@ -360,6 +374,10 @@ far, but instead for every ``Drop`` which takes place in our troublesome 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:: @@ -373,21 +391,22 @@ Let's again take it a step at a time: 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:: @@ -466,6 +485,10 @@ The extended ``if`` statement:: 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 @@ -487,6 +510,10 @@ The new topics that we've encountered here include these: 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` @@ -497,6 +524,10 @@ the ``bird``, ``cottage`` and ``tree`` (when they intercept actions aimed 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 @@ -505,6 +536,10 @@ further for that action. By combining these possibilities, you can 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 @@ -586,19 +621,29 @@ We encountered several new statements: .. 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`. @@ -618,6 +663,11 @@ DROP THE NEST Drop nest nothing 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`,