X-Git-Url: https://jxself.org/git/?p=ibg.git;a=blobdiff_plain;f=chapters%2F11.rst;h=2a7cd8fc131c72c1977d56b241220d168b4bde5a;hp=ec95f79cf3c56bfaccf4c773116c08ca0c3a9951;hb=95b5702817b987123d71d432f81eeb0c7101b59c;hpb=6f29703a02de1ec9cac82267ff0ea24a01679de6 diff --git a/chapters/11.rst b/chapters/11.rst index ec95f79..2a7cd8f 100644 --- a/chapters/11.rst +++ b/chapters/11.rst @@ -4,22 +4,20 @@ Captain Fate: take 2 .. epigraph:: - | *U was a usurer, a miserable elf;* - | *V was a vintner, who drank all himself.* + | |CENTER| *U was a usurer, a miserable elf;* + | |CENTER| *V was a vintner, who drank all himself.* .. only:: html .. image:: /images/picV.png :align: left -.. raw:: latex +|V|\iewed from the inside, Benny's café is warm and welcoming, and packed +with lunchtime customers. We'll try to conjure up some appropriate images, +but the main focus of the room isn't the decor: it's the door leading to +the toilet -- and, perhaps, privacy? - \dropcap{v} - -iewed from the inside, Benny's café is warm and welcoming, and packed -with lunchtime customers. We'll try to conjure up some appropriate -images, but the main focus of the room isn't the decor: it's the door -leading to the toilet -- and, perhaps, privacy? +.. _homely-atmos: A homely atmosphere =================== @@ -32,7 +30,7 @@ the door seems to be locked. .. admonition:: Cultural Note :class: admonition note - not for the first time, this guide betrays its origins. In + Not for the first time, this guide betrays its origins. In European countries the word "toilet" often refers not only to the white porcelain artefact, but also to the room in which it can be found (also, a "bathroom" is for taking a bath, a "restroom" for @@ -41,7 +39,7 @@ the door seems to be locked. We define the café room in simple form: -.. code-block:: inform6 +.. code-block:: inform Room cafe "Inside Benny's cafe" with description @@ -58,7 +56,7 @@ define the door object which lies between the café and the toilet. We've mentioned a counter: -.. code-block:: inform6 +.. code-block:: inform Appliance counter "counter" cafe with name 'counter' 'bar', @@ -74,7 +72,7 @@ We've mentioned a counter: ], has supporter; -That ``before property``, superficially normal, actually conceals a +That ``before`` property, superficially normal, actually conceals a little surprise. By now you should be entirely comfortable with using an object's ``before`` property to intercept an action directed at that object; for example, if the player types HIT COUNTER then the counter's @@ -93,22 +91,23 @@ let the action continue, ``true`` to prevent it. and others that are not. Should these ones that are not be promoted to having a typewriter font? -The Receive action is generated by the library in the PutOnSub action -handler, and also in InsertSub (so a command like PUT BIRD IN NEST sends -a Receive to the nest object). There’s a matching LetGo, generated by -the library from commands like TAKE KEY OFF COUNTER and REMOVE BIRD FROM -NEST. Receive and LetGo are examples of what’s called a **fake action**. +The Receive action is generated by the library in the PutOnSub action +handler, and also in InsertSub (so a command like PUT BIRD IN NEST sends a +Receive to the nest object). There’s a matching LetGo, generated by the +library from commands like TAKE KEY OFF COUNTER and REMOVE BIRD FROM +NEST. Receive and LetGo are examples of what’s called a :term:`fake +action`. .. note:: - in "William Tell" we defined the ``quiver``, way back in "The - player's possessions" on page 83, as an ``open container``. As things - stand, the player can put *any* held object, however inappropriate, - into it. We could have trapped the Receive action to ensure that - arrows are the only acceptable contents (recollect that ``~~``, to be - read as "not", turns true into false and vice versa): + In "William Tell" we defined the ``quiver``, way back in + :ref:`possessions`, as an ``open container``. As things stand, the player + can put *any* held object, however inappropriate, into it. We could have + trapped the Receive action to ensure that arrows are the only acceptable + contents (recollect that ``~~``, to be read as "not", turns true into + false and vice versa): - .. code-block:: inform6 + .. code-block:: inform before [; Drop,Give: @@ -128,7 +127,7 @@ way for the player to accomplish this. We've also mentioned some customers. These are treated as NPCs, reacting to our hero’s performance. -.. code-block:: inform6 +.. code-block:: inform Object customers "customers" cafe with name 'customers' 'people' 'customer' 'men' 'women', @@ -233,13 +232,13 @@ To code a daemon, you need to do three things: the property is always an embedded routine. #. However, daemons do nothing until you activate them. This is easily - achieved with the call ``StartDaemon(obj_id)``, which may happen + achieved with the call :samp:`StartDaemon({obj_id})`, which may happen anywhere (if you want some object's daemon to be active from the beginning of the game,you can make the call in your Initialise routine). #. Once the daemon has finished its mission (if ever) you may stop it - with the call ``StopDaemon(obj_id)``. + with the call :samp:`StopDaemon({obj_id})`. How does our particular daemon work? The appearance of our hero in full crime-fighting wear will make the customers stare at him and make snarky @@ -248,7 +247,7 @@ customers are -- so we need to make certain that the daemon does something interesting only while the player stays in the right place (and hasn’t wandered, say, back into the toilet): -.. code-block:: inform6 +.. code-block:: inform if (location ~= cafe) return; @@ -262,7 +261,7 @@ control the sequence of customers' remarks. When the Captain enters the café room from the toilet for the first time, the value of the property should be zero, so the statement block under the test: -.. code-block:: inform6 +.. code-block:: inform if (self.number_of_comments == 0) { self.number_of_comments = 1; @@ -280,17 +279,13 @@ daemon will continue normally to the next line. We want the customers to indulge in witticisms once they see the costumed Captain, but not on a completely predictable basis. -.. code-block:: inform6 +.. code-block:: inform if (random(2) == 1) ... -.. todo:: - - "expression" in "random(expression)" should be typewriter and italic - ``random`` is an Inform routine used to generate random numbers or to choose randomly between given choices; in the form -``random(expression)`` it returns a random number between 1 and +:samp:`random({expression})` it returns a random number between 1 and ``expression`` inclusive. So our condition is actually stating: if a random choice between 1 and 2 happens to be 1 then perform some action. Remember that a daemon is run once at the end of every turn, so the @@ -315,7 +310,7 @@ the café in their Captain’s outfit, they’ll be coming from the toilet. As a consequence of all this, we add an ``after`` property to the café room object: -.. code-block:: inform6 +.. code-block:: inform Room cafe "Inside Benny's cafe" ... @@ -342,7 +337,7 @@ the player just came from the toilet, so we use an ``after`` property. The first line: -.. code-block:: inform6 +.. code-block:: inform if (noun ~= s_obj) return false; @@ -354,7 +349,7 @@ normal rules for the other available directions. Then we check whether the player character is wearing the costume, in which case it starts the ``daemon`` of the ``customers`` object. The use -of the local first_time_out property ensures that the condition is +of the local ``first_time_out`` property ensures that the condition is ``true`` only once, so the statement block attached to it runs also once. @@ -368,7 +363,7 @@ A door to adore Door objects require some specific properties and attributes. Let's first code a simple door: -.. code-block:: inform6 +.. code-block:: inform Object toilet_door "toilet door" cafe name name 'red' 'toilet' 'door', @@ -426,7 +421,7 @@ and its possible states affect both sides. However, the coding gets a little bit complicated and you''ll have to define routines for most properties: -.. code-block:: inform6 +.. code-block:: inform Object toilet_door "toilet door" with name 'red' 'toilet' 'door', @@ -466,7 +461,7 @@ the cafe", depending on the side we are facing. For this, a ``short_name property`` is the thing. We have already talked about the external name defined as part of an object's header information: -.. code-block:: inform6 +.. code-block:: inform Object toilet_door "toilet door" @@ -474,7 +469,7 @@ That ``toilet door`` will be the name displayed by the game at run-time to refer to the door. With identical effect, this could also have been coded thus: -.. code-block:: inform6 +.. code-block:: inform Object toilet_door with short_name "toilet door", @@ -485,13 +480,14 @@ retain the same external name throughout the game -- and the header information method is perfect in that case -- but if it needs to change, it's easy to write a routine as the value of ``short_name``: -.. code-block:: inform6 +.. code-block:: inform Object toilet_door with name 'red' 'toilet' 'door' short_name [; if (location == cafe) print "door to the toilet"; else print "door to the cafe"; + return true; ], description ... @@ -506,22 +502,18 @@ adjectives -- perhaps a shining/flickering/fading/useless lantern. .. note:: - what's displayed if there isn't an external name in an object's - header? If you've read the section "Compile-as-you-go" on page 233, - you'll recall that the interpreter simply uses the internal - identifier within parentheses; that is, with no external name and no - ``short_name`` property, we might see: - - .. code-block:: inform6 + What's displayed if there isn't an external name in an object's header? + If you've read the section :ref:`compile-as-you-go`, you'll recall that + the interpreter simply uses the internal identifier within parentheses; + that is, with no external name and no ``short_name`` property, we might + see:: You open the (toilet_door). And the same principle applies if we were mistakenly to ``return false`` from this short_name routine: we would get, first, the result of our ``print`` statement, and then the standard rules would display - the internal ID: - - .. code-block:: inform6 + the internal ID:: You open the door to the toilet(toilet_door). @@ -548,7 +540,7 @@ If a few lines of code can make the life of the player easier, it's worth a shot. Let's provide a few improvements to our toilet door in ``before`` and ``after`` properties: -.. code-block:: inform6 +.. code-block:: inform before [ ks; Open: @@ -605,7 +597,9 @@ shouldn’t assume that they want to lock it as well). In all processes there is a library variable called ``keep_silent``, which can be either ``false`` (the normal state) or ``true``; when ``true``, the interpreter does not display the associated message of an -action in progress, so we can avoid things like:: +action in progress, so we can avoid things like: + +.. code-block:: transcript >OPEN DOOR You open the door to the toilet. @@ -620,7 +614,7 @@ safely restore it afterwards. You’ll remember that a local variable in a standalone routine is declared between the routine’s name and the semicolon: -.. code-block:: inform6 +.. code-block:: inform [ BeenToBefore this_room; @@ -628,7 +622,7 @@ In exactly the same way, a local variable in an embedded routine is declared between the ``[`` starting marker of the routine and the semicolon: -.. code-block:: inform6 +.. code-block:: inform before [ ks; @@ -636,7 +630,7 @@ You can declare up to fifteen variables this way -- just separated by spaces -- which are usable only within the embedded routine. When we assign it thus: -.. code-block:: inform6 +.. code-block:: inform ks = keep_silent; @@ -645,7 +639,7 @@ has (either ``true`` or ``false``; we actually don't care). We then set ``keep_silent`` to ``true``, make the desired silent actions, and we assign: -.. code-block:: inform6 +.. code-block:: inform keep_silent = ks; @@ -653,18 +647,18 @@ which restores the value originally stored in ``ks`` to ``keep_silent``. The effect is that we manage to leave it as it was before we tampered with it. -Well, that's about everything about doors. Everything? Well, no, not -really; any object can grow as complex as your imagination allows, but -we’ll drop the subject here. If you care to see more sophisticated -doors, check Exercises 3 and 4 in the *Inform Designer's Manual*, where -an obliging door opens and unlocks by itself if the player simply walks -in its direction. +Well, that's about everything about doors. Everything? Well, no, not +really; any object can grow as complex as your imagination allows, but +we’ll drop the subject here. If you care to see more sophisticated doors, +check Exercises :dm4:`3 and 4 ` in the |DM4|, where an +obliging door opens and unlocks by itself if the player simply walks in its +direction. So far, we have the player in front of a locked door leading to the toilet. A dead end? No, the description mentions a scribbled note on its surface. This one should offer no problem: -.. code-block:: inform6 +.. code-block:: inform Object "scribbled note" cafe with name 'scribbled' 'note', @@ -705,7 +699,7 @@ to ask for it, just as the note explains. Although we'll define Benny in detail throughout the next chapter, here we present a basic definition, largely so that the key has a parent object. -.. code-block:: inform6 +.. code-block:: inform Object benny "Benny" cafe with name 'benny', @@ -746,7 +740,7 @@ to belong to Benny"; however, the same wouldn't apply to other commands like TOUCH KEY and TASTE KEY . So, to prevent any interaction with the key while it’s in Benny’s pockets, we define a ``before`` property. -.. code-block:: inform6 +.. code-block:: inform before [; if (self in benny) @@ -756,21 +750,20 @@ key while it’s in Benny’s pockets, we define a ``before`` property. "Benny is trusting you to look after that key."; ]; -All of the ``before`` properties that we've so far created have -contained one or more labels specifying the actions which they are to -intercept; you'll remember that in "William Tell" we introduced the -``default`` action (see "A class for props" on page 74) to mean "any -value not already catered for". There's one of those labels here, for -the Drop action, but that's preceded by a piece of code that will be -executed at the start of *every* action directed at the key. If it’s -still in Benny’s possession, we display a polite refusal; if the player -has it then we prevent careless disposal; otherwise, the action -continues unhindered. +All of the ``before`` properties that we've so far created have contained +one or more labels specifying the actions which they are to intercept; +you'll remember that in "William Tell" we introduced the ``default`` action +(see :ref:`props-class`) to mean "any value not already catered +for". There's one of those labels here, for the Drop action, but that's +preceded by a piece of code that will be executed at the start of *every* +action directed at the key. If it’s still in Benny’s possession, we display +a polite refusal; if the player has it then we prevent careless disposal; +otherwise, the action continues unhindered. -(In fact, the hat-on-a-pole ``Prop`` introduced on page 91 had this -all-exclusive ``before`` property: +(In fact, the hat-on-a-pole ``Prop`` introduced in :ref:`south-side` had +this all-exclusive ``before`` property: -.. code-block:: inform6 +.. code-block:: inform before [; default: @@ -795,7 +788,7 @@ choose to examine the café from the outside. While it's unlikely that they'll try to examine the toilet room from the outside, it takes very little effort to offer a sensible output just in case: -.. code-block:: inform6 +.. code-block:: inform Object outside_of_toilet "toilet" cafe with name 'toilet' 'bath' 'rest' 'room' 'bathroom' 'restroom',