X-Git-Url: https://jxself.org/git/?p=ibg.git;a=blobdiff_plain;f=chapters%2F13.rst;h=65df6a616f34c5a6aef4f6d02b192727b7ed48af;hp=914c5cb3f844a386bc4a0bd12770df94af3bdd2c;hb=2a223f38ada318aa468e46210b7f92941816100e;hpb=b0349e3ed37cf820a223eb890eafbbc21eaf765c diff --git a/chapters/13.rst b/chapters/13.rst index 914c5cb..65df6a6 100644 --- a/chapters/13.rst +++ b/chapters/13.rst @@ -26,7 +26,7 @@ Additional catering garnish We must not forget a couple of tiny details in the café room: -.. code-block:: inform6 +.. code-block:: inform Object food "Benny's snacks" cafe with name 'food' 'pastry' 'pastries' 'sandwich' 'sandwiches' 'snack' @@ -49,7 +49,7 @@ We must not forget a couple of tiny details in the café room: And a not-so-trivial object: -.. code-block:: inform6 +.. code-block:: inform Object coffee "cup of coffee" benny with name 'cup' 'of' 'coffee' 'steaming' 'cappuccino' @@ -95,7 +95,7 @@ orders property. Since the removed coffee object does not belong to Benny, it's not a noun that the player can ASK Benny FOR. By making it a child of the barman (who has the ``transparent`` attribute set), the coffee is still an object that players can refer to. We ensure that they -don't get more cups thanks to Benny's ``coffee_asked_for property``, +don't get more cups thanks to Benny's ``coffee_asked_for`` property, which will remain ``true`` after the first time. We also ensure that Benny doesn't ask for money from players who have @@ -121,7 +121,7 @@ erm, bogged down with details of the room's function or plumbing. There's not a lot about the toilet room and its contents, though there will be some tricky side effects: -.. code-block:: inform6 +.. code-block:: inform Room toilet "Unisex toilet" with description @@ -190,7 +190,7 @@ there's no light to see by. However, let's define first the light switch mentioned in the room's description to aid players in their dressing duties. -.. code-block:: inform6 +.. code-block:: inform Appliance light_switch "light switch" toilet with name 'light' 'switch', @@ -216,7 +216,9 @@ Please notice the appearance of new attributes ``switchable`` and ``on``. switchable enables the object to be turned on and off, and is typical of lanterns, computers, television sets, radios, and so on. The library automatically extends the description of these objects by -indicating if they are currently on or off:: +indicating if they are currently on or off: + +.. code-block:: transcript > X LIGHT SWITCH A notorious ACHIEVEMENT of technological SCIENCE, elegant yet EASY to use. @@ -224,7 +226,9 @@ indicating if they are currently on or off:: Two new actions are ready to use, ``SwitchOn`` and ``SwitchOff``. Left to themselves, they toggle the object's state between ON and OFF and -display a message like:: +display a message like: + +.. code-block:: transcript You switch the brass lantern on. @@ -235,7 +239,7 @@ attribute, which is set or cleared automatically as needed. You can, of course, set or clear it manually like any other attribute, with the ``give`` statement: -.. code-block:: inform6 +.. code-block:: inform give self on; @@ -243,7 +247,7 @@ course, set or clear it manually like any other attribute, with the and check if a ``switchable`` object is on or off with the test: -.. code-block:: inform6 +.. code-block:: inform if (light_switch has on) ... @@ -252,14 +256,14 @@ and check if a ``switchable`` object is on or off with the test: A ``switchable`` object is OFF by default. However, you’ll notice that the has line of the object definition includes ``~on`` : -.. code-block:: inform6 +.. code-block:: inform has switchable ~on; Surely that’s saying "not-on"? Surely that's what would have happened anyway if the line hadn't mentioned the attribute at all? -.. code-block:: inform6 +.. code-block:: inform has switchable; @@ -281,7 +285,9 @@ a room with the ``light`` attribute set. It doesn't have to be the room itself (though this is usually convenient). After setting the ``light`` attribute, we display a customised message, -to avoid the default:: +to avoid the default: + +.. code-block:: transcript You switch the light switch on. @@ -294,7 +300,7 @@ in a ``before`` property and redirect it to ``SwitchOn`` and .. note:: - remember what we said about class inheritance? No matter what you + Remember what we said about class inheritance? No matter what you define in the class, the object’s definition has priority. The class ``Appliance`` defines a response for the ``Push`` action, but we override it here with a new behaviour. @@ -318,7 +324,7 @@ perhaps it would be a good idea to append a little code to the door object to account for this. A couple of lines in the after property will suffice: -.. code-block:: inform6 +.. code-block:: inform after [ ks; Unlock: @@ -343,7 +349,7 @@ players are never aware of this glowing artefact. .. note:: - now, could they? Well, if players could TAKE the light switch (which + Now, could they? Well, if players could TAKE the light switch (which we have forbidden) and then did INVENTORY, the trick would be given away, because all objects with the ``light`` attribute set are listed as ``(providing light)`` . @@ -422,7 +428,7 @@ example to fix our particular problem. In the section "``Entry point routines``" of our game -- after the ``Initialise`` routine, for instance -- include the following lines: -.. code-block:: inform6 +.. code-block:: inform [ InScope person; if (person == player && location == thedark && real_location == toilet) { @@ -432,12 +438,12 @@ instance -- include the following lines: return false; ]; -``InScope(actor_obj_id)`` is an entry point routine that can tamper with -the scope rules for the given ``actor_obj_id`` (either the player -character or a NPC). We define it with one variable (which we name as we -please; it's also a good idea to name variables in an intuitive way to -remind us of what they represent), ``person`` , and then we make a -complex test to see if the player is actually in the toilet and in the +:samp:`InScope({actor_obj_id})` is an entry point routine that can tamper +with the scope rules for the given :samp:`{actor_obj_id}` (either the +player character or a NPC). We define it with one variable (which we name +as we please; it's also a good idea to name variables in an intuitive way +to remind us of what they represent), ``person`` , and then we make a +complex test to see if the player is actually in the toilet and in the dark. We have told you that the library variable ``location`` holds the @@ -451,7 +457,7 @@ player is in *even when there is no light to see by*. So the test: -.. code-block:: inform6 +.. code-block:: inform if (person == player && location == thedark && real_location == toilet) ... @@ -459,15 +465,15 @@ is stating: if the specified actor is the ``player`` character *and* he finds himself in the dark *and* he actually happens to be in the toilet... -Then we make a call to one of the library routines, -``PlaceInScope(obj_id)``, which has a very descriptive name: it places -in scope the given object. In our case, we want both the door and the -light switch to be within reach of the player, hence both additional -lines. Finally, we must ``return false``, because we want the normal -scope rules for the defined actor -- the player -- to apply to the rest -of the objects of the game (if we returned ``true``, players would find -that they are able to interact with very little indeed). Now we get a -friendlier and more logical response: +Then we make a call to one of the library routines, +:samp:`PlaceInScope({obj_id})`, which has a very descriptive name: it +places in scope the given object. In our case, we want both the door and +the light switch to be within reach of the player, hence both additional +lines. Finally, we must ``return false``, because we want the normal scope +rules for the defined actor -- the player -- to apply to the rest of the +objects of the game (if we returned ``true``, players would find that they +are able to interact with very little indeed). Now we get a friendlier and +more logical response: .. code-block:: transcript @@ -495,16 +501,15 @@ key has disappeared, engulfed by the darkness -- unless the player thinks to turn on the light switch, thereby placing the key in scope once more. -Why don't we add a ``PlaceInScope(toilet_key)`` to the above routine? -Well, for starters, the key can be moved around (as opposed to the door -or the light switch, which are fixed items in the toilet room). Suppose -the player opens the door of the toilet, but drops the key in the café, -then enters the toilet and closes the door. The condition is met and the -key is placed in scope, when it's in another room. Second, this is a -simple game with just a few objects, so you can define a rule for each -of them; but in any large game, you might like to be able to refer to -objects in bunches, and make general rules that apply to all (or some) -of them. +Why don't we add a :samp:`PlaceInScope({toilet_key})` to the above routine? +Well, for starters, the key can be moved around (as opposed to the door or +the light switch, which are fixed items in the toilet room). Suppose the +player opens the door of the toilet, but drops the key in the café, then +enters the toilet and closes the door. The condition is met and the key is +placed in scope, when it's in another room. Second, this is a simple game +with just a few objects, so you can define a rule for each of them; but in +any large game, you might like to be able to refer to objects in bunches, +and make general rules that apply to all (or some) of them. We need to add code to the ``InScope`` routine, telling the game to place in scope all objects that we drop in the dark, so that we might @@ -518,7 +523,7 @@ every object that the player has picked up at one time in the game; have ``moved``. Here is the reworked ``InScope`` routine. There are a couple of new concepts to look at: -.. code-block:: inform6 +.. code-block:: inform [ InScope person item; if (person == player && location == thedark && real_location == toilet) { @@ -539,35 +544,25 @@ need to specify the toilet, because we want this rule to apply to all dark rooms (well, the only dark room in the game *is* the toilet, but we are trying to provide a general rule). -.. todo:: - - Lots of italicized typewriter stuff here... - -.. code-block:: inform6 - - objectloop (variable) statement; - -is a loop statement, one of the four defined in Inform. A loop statement -is a construct that allows you to run several times through a statement -(or a statement block). ``objectloop`` performs the ``statement`` once -for every object defined in the (``variable``) . If we were to code: - -.. code-block:: inform6 + :samp:`objectloop (variable) {statement};` - objectloop (item) statement; +is a loop statement, one of the four defined in Inform. A loop statement is +a construct that allows you to run several times through a statement (or a +statement block). ``objectloop`` performs the :samp:`{statement}` once for +every object defined in the (:samp:`{variable}`) . If we were to code: -then the ``statement`` would be executed once for each object in the -game. However, we want to perform the statement only for those objects -whose parent object is the same as the player's parent object: that is, -for objects in the same room as the player, so we instead code: + :samp:`objectloop (item) {statement};` -.. code-block:: inform6 +then the :samp:`{statement}` would be executed once for each object in the +game. However, we want to perform the statement only for those objects +whose parent object is the same as the player's parent object: that is, for +objects in the same room as the player, so we instead code: - objectloop (item in parent(player)) statement; + :samp:`objectloop (item in parent(player)) {statement};` -What is the actual ``statement`` that we'll repeatedly execute? +What is the actual :samp:`{statement}` that we'll repeatedly execute? -.. code-block:: inform6 +.. code-block:: inform if (item has moved) PlaceInScope(item); @@ -592,7 +587,7 @@ Amazing techicolour dreamcoats This leaves us the clothing items themselves, which will require a few tailored actions. Let's see first the ordinary garments of John Covarth: -.. code-block:: inform6 +.. code-block:: inform Object clothes "your clothes" with name 'ordinary' 'street' 'clothes' 'clothing', @@ -693,7 +688,7 @@ change into the hero's suit, after which we'll prevent a change back into ordinary clothes. So now we are dealing with a Captain Fate in full costume: -.. code-block:: inform6 +.. code-block:: inform Object costume "your costume" with name 'captain' 'captain^s' 'fate' 'fate^s' 'costume' 'suit', @@ -735,7 +730,7 @@ All the objects of our game are defined. Now we must add a couple of lines to the ``Initialise`` routine to make sure that the player does not start the game naked: -.. code-block:: inform6 +.. code-block:: inform [ Initialise; #Ifdef DEBUG; pname_verify(); #Endif; ! suggested by pname.h @@ -762,7 +757,7 @@ The designer of the package has made a debugging tool (a routine) to check for errors when using his library, and he tells us how to use it. So we include the suggested lines into our ``Initialise`` routine: -.. code-block:: inform6 +.. code-block:: inform #Ifdef DEBUG; pname_verify(); #Endif; @@ -798,7 +793,7 @@ line. Therefore, we must define a ``DeathMessage`` routine as we did in "William Tell", to write our customised messages and assign them to ``deadflag`` values greater than 2. -.. code-block:: inform6 +.. code-block:: inform [ DeathMessage; if (deadflag == 3) print "Your secret identity has been revealed"; @@ -812,7 +807,7 @@ Finally, we need to extend the existing grammar, to allow for a couple of things. We have already seen that we need a verb CHANGE. We'll make it really simple: -.. code-block:: inform6 +.. code-block:: inform [ ChangeSub; if (noun has pluralname) print "They're"; @@ -838,7 +833,7 @@ One might reasonably imagine that the ``default`` line at the end of the ``Give`` action in the orders property handles every input not already specified: -.. code-block:: inform6 +.. code-block:: inform orders [; Give: @@ -848,14 +843,14 @@ specified: food: ! code for the food... menu: ! code for the menu... default: - "~I don't + "~I don't think that's on the menu, sir.~"; } ], Not so. The library grammar that deals with ASK BENNY FOR... is this (specifically, the last line): -.. code-block:: inform6 +.. code-block:: inform Verb 'ask' * creature 'about' topic -> Ask @@ -876,7 +871,7 @@ takes very little to allow Benny to use his default line for *any* undefined input from the player. We need to extend the existing ASK grammar: -.. code-block:: inform6 +.. code-block:: inform Extend 'ask' * creature 'for' topic -> AskFor;