1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-03 07:24:58 +03:00
inform7/docs/WorldModelKit/S-ord.html
2022-05-23 21:45:09 +01:00

735 lines
97 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>OrderOfPlay Template</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../indocn.html">indoc</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
<li><a href="../inrtpsn.html">inrtps</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inweb/index.html">inweb</a></li>
<li><a href="../../../intest/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'OrderOfPlay Template' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../extensions.html">Kits</a></li><li><a href="index.html">WorldModelKit</a></li><li><b>OrderOfPlay Template</b></li></ul></div>
<p class="purpose">The sequence of events in play: the Main routine which runs the startup rulebook, the turn sequence rulebook and the shutdown rulebook; and most of the I6 definitions of primitive rules in those rulebooks.</p>
<ul class="toc"><li><a href="S-ord.html#SP1">&#167;1. Main</a></li><li><a href="S-ord.html#SP2">&#167;2. Virtual Machine Startup Rule</a></li><li><a href="S-ord.html#SP3">&#167;3. Initial Situation</a></li><li><a href="S-ord.html#SP4">&#167;4. Initialise Memory Rule</a></li><li><a href="S-ord.html#SP5">&#167;5. Position Player In Model World Rule</a></li><li><a href="S-ord.html#SP6">&#167;6. Parse Command Rule</a></li><li><a href="S-ord.html#SP7">&#167;7. Treat Parser Results</a></li><li><a href="S-ord.html#SP8">&#167;8. Generate Action Rule</a></li><li><a href="S-ord.html#SP9">&#167;9. Generate Multiple Actions</a></li><li><a href="S-ord.html#SP10">&#167;10. Timed Events Rule</a></li><li><a href="S-ord.html#SP11">&#167;11. Setting Timed Events</a></li><li><a href="S-ord.html#SP12">&#167;12. Setting Time Of Day</a></li><li><a href="S-ord.html#SP13">&#167;13. Advance Time Rule</a></li><li><a href="S-ord.html#SP14">&#167;14. Note Object Acquisitions Rule</a></li><li><a href="S-ord.html#SP15">&#167;15. Resurrect Player If Asked Rule</a></li><li><a href="S-ord.html#SP16">&#167;16. Ask The Final Question Rule</a></li><li><a href="S-ord.html#SP17">&#167;17. Read The Final Answer Rule</a></li><li><a href="S-ord.html#SP18">&#167;18. Immediately Restart VM Rule</a></li><li><a href="S-ord.html#SP19">&#167;19. Immediately Restore Saved Game Rule</a></li><li><a href="S-ord.html#SP20">&#167;20. Immediately Quit Rule</a></li><li><a href="S-ord.html#SP21">&#167;21. Immediately Undo Rule</a></li><li><a href="S-ord.html#SP22">&#167;22. Print Obituary Headline Rule</a></li><li><a href="S-ord.html#SP23">&#167;23. Print Final Score Rule</a></li><li><a href="S-ord.html#SP24">&#167;24. Display Final Status Line Rule</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Main. </b>This is where every I6 story file begins execution: it can end either by
returning, or by a <span class="extract"><span class="extract-syntax">quit</span></span> statement or equivalent opcode. (In I7 this does
indeed happen when the quitting the game action is carried out, or when QUIT
is typed as a reply to the final question; it's only if the user has altered
the shutdown rulebook that we might ever actually return from <span class="extract"><span class="extract-syntax">Main</span></span>.)
The return value from <span class="extract"><span class="extract-syntax">Main</span></span> is not meaningful.
</p>
<p class="commentary">The <span class="extract"><span class="extract-syntax">EarlyInTurnSequence</span></span> flag is used to enforce the requirement that the
"parse command rule" and "generate action rule" do nothing unless the
turn sequence rulebook is being followed directly from <span class="extract"><span class="extract-syntax">Main</span></span>, an anomaly
explained in the Standard Rules.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">Global</span><span class="plain-syntax"> </span><span class="identifier-syntax">EarlyInTurnSequence</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">Global</span><span class="plain-syntax"> </span><span class="identifier-syntax">IterationsOfTurnSequence</span><span class="plain-syntax">;</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">Main</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">say__pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">say__pc</span><span class="plain-syntax"> | </span><span class="identifier-syntax">PARA_NORULEBOOKBREAKS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">FollowRulebook</span><span class="plain-syntax">(</span><span class="identifier-syntax">STARTUP_RB</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">say__pc</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">PARA_NORULEBOOKBREAKS</span><span class="plain-syntax">) </span><span class="identifier-syntax">say__pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">say__pc</span><span class="plain-syntax"> - </span><span class="identifier-syntax">PARA_NORULEBOOKBREAKS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="reserved-syntax">true</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deadflag</span><span class="plain-syntax"> == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EarlyInTurnSequence</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">action</span><span class="plain-syntax"> = ##</span><span class="identifier-syntax">Wait</span><span class="plain-syntax">; </span><span class="identifier-syntax">meta</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">; </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> = </span><span class="reserved-syntax">nothing</span><span class="plain-syntax">; </span><span class="identifier-syntax">second</span><span class="plain-syntax"> = </span><span class="reserved-syntax">nothing</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">actor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">player</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">FollowRulebook</span><span class="plain-syntax">(</span><span class="identifier-syntax">TURN_SEQUENCE_RB</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">IterationsOfTurnSequence</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FollowRulebook</span><span class="plain-syntax">(</span><span class="identifier-syntax">SHUTDOWN_RB</span><span class="plain-syntax">) == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Virtual Machine Startup Rule. </b>We delegate to the appropriate VM-specific section of code for the real work.
The printing of three blank lines at the start of play is traditional: on early
Z-machine interpreters such as InfoTaskForce and Zip it was a necessity because
of the way they buffered output. On modern windowed ones it still helps to
space the opening text better.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">VIRTUAL_MACHINE_STARTUP_R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CarryOutActivity</span><span class="plain-syntax">(</span><span class="identifier-syntax">STARTING_VIRTUAL_MACHINE_ACT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">VM_Initialise</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="comment-syntax">It is now safe for the paragraph breaking between rules mechanism to work</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">say__pc</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">PARA_NORULEBOOKBREAKS</span><span class="plain-syntax">) </span><span class="identifier-syntax">say__pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">say__pc</span><span class="plain-syntax"> - </span><span class="identifier-syntax">PARA_NORULEBOOKBREAKS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^^^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Initial Situation. </b>The array <span class="extract"><span class="extract-syntax">InitialSituation</span></span> is compiled by Inform and contains:
</p>
<ul class="items"><ul class="items"><li>(0) The object number for the player, which is usually <span class="extract"><span class="extract-syntax">selfobj</span></span>.
</li><li>(1) The object in or on which the player begins, if he does. (This will
always be an enterable container or supporter, or <span class="extract"><span class="extract-syntax">nothing</span></span>.)
</li><li>(2) The room in which the player begins, which is usually the first
room created in the source text.
</li><li>(3) The initial time of day, which is usually 9 AM.
</li></ul>
</li></ul>
<p class="commentary">The start object and start room are meaningful only if the player's object
is compiled outside of the object tree (as can happen if the source text
reads, say, "Mrs Bridges is a woman. The player is Mrs Bridges."): in
other circumstances they are often correct, but this must not be relied on.
</p>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Initialise Memory Rule. </b>This rule amalgamates some minimal initialisations which all need to happen
before we can risk using some of the more exotic I7 kinds:
</p>
<ul class="items"><li>(a) The language definition might call for initialisation, although the
default language of play (English) does not.
</li><li>(b) A handful of variables are filled in. <span class="extract"><span class="extract-syntax">I7_LOOKMODE</span></span> is a constant
created by the use options "use full-length room descriptions" or
"use abbreviated room descriptions", but otherwise not existing. It is
particularly important that <span class="extract"><span class="extract-syntax">player</span></span> have the correct value, as the
process of initialising the memory heap uses the player as the presumed
actor when creating memory representations of literal stored actions
where no actor was specified; this is why <span class="extract"><span class="extract-syntax">player</span></span> is initialised here
and not in the "position player in model world rule" below. The other
interesting point here is that we explicitly set <span class="extract"><span class="extract-syntax">location</span></span> and
<span class="extract"><span class="extract-syntax">real_location</span></span> to <span class="extract"><span class="extract-syntax">nothing</span></span>, which is certainly incorrect, even though
we know better. We do this so that the "update chronological records rule"
cannot see where the player is: see the Standard Rules for an explanation
of why this is, albeit perhaps dubiously, a good thing.
</li><li>(c) We start the machinery needed to check that property accesses are
valid during play.
</li><li>(d) And we initialise the memory allocation heap, and expand the literal
constants, as hinted above: these are called "block constants" since
they occupy blocks of memory.
</li></ul>
<p class="commentary">The <span class="extract"><span class="extract-syntax">not_yet_in_play</span></span> flag, which is cleared when the first command is
about to be read from the keyboard, suppresses the standard status line
text: thus, if there is some long text to read before the player finds out
where he is, the surprise will not be spoiled.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">INITIALISE_MEMORY_R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">TARGET_GLULX</span><span class="plain-syntax">; </span><span class="identifier-syntax">VM_PreInitialise</span><span class="plain-syntax">(); #</span><span class="identifier-syntax">Endif</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">Ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">LanguageInitialise</span><span class="plain-syntax">; </span><span class="identifier-syntax">LanguageInitialise</span><span class="plain-syntax">(); #</span><span class="identifier-syntax">Endif</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">not_yet_in_play</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lookmode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KIT_CONFIGURATION_LOOKMODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">player</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InitialSituation</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">PLAYER_OBJECT_INIS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">the_time</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InitialSituation</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">START_TIME_INIS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">real_location</span><span class="plain-syntax"> = </span><span class="reserved-syntax">nothing</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">location</span><span class="plain-syntax"> = </span><span class="reserved-syntax">nothing</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HeapInitialise</span><span class="plain-syntax">(); </span><span class="comment-syntax">Create a completely unused memory allocation heap</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StackFramingInitialise</span><span class="plain-syntax">(); </span><span class="comment-syntax">Create an empty stack</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CreateDynamicRelations</span><span class="plain-syntax">(); </span><span class="comment-syntax">Create relation structures on the heap</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. Position Player In Model World Rule. </b>This seems as good a place as any to write down the invariant we attempt
to maintain for the player's position variables:
</p>
<ul class="items"><li>(1) The <span class="extract"><span class="extract-syntax">player</span></span> variable is the object through which the player plays,
which is always a person: its value is always set by starting from <span class="extract"><span class="extract-syntax">selfobj</span></span>
and then making a sequence of 0 or more <span class="extract"><span class="extract-syntax">ChangePlayer(new_value)</span></span> calls.
(This enables us to make sure it has the correct property values for
printed name and so forth.)
</li><li>(2) The <span class="extract"><span class="extract-syntax">location</span></span> is always either the current room, a valid I7 room, or
<span class="extract"><span class="extract-syntax">thedark</span></span>, which is not a valid I7 object but is distinguishable both from
all I7 objects and from <span class="extract"><span class="extract-syntax">nothing</span></span>. The <span class="extract"><span class="extract-syntax">real_location</span></span> is always the current
room, which is always a valid I7 room. <span class="extract"><span class="extract-syntax">location</span></span> equals <span class="extract"><span class="extract-syntax">thedark</span></span> if and
only if the player does not have light to see by; the routine
<span class="extract"><span class="extract-syntax">SilentlyConsiderLight</span></span> updates this without printing any messages to
announce the fall or lifting of darkness (hence "silently").
</li><li>(3) The <span class="extract"><span class="extract-syntax">player</span></span> object is always in the subtree of <span class="extract"><span class="extract-syntax">real_location</span></span>, and
is always in a chain \(O_1 &lt; O_2 &lt; ... &lt; O_n\) where \(O_1\) is the player,
\(O_n\) is <span class="extract"><span class="extract-syntax">real_location</span></span>, \(n\geq 2\) and \(O_2, ..., O_{n-1}\) are all either
enterable containers, enterable supporters, or component parts of such.
The routine <span class="extract"><span class="extract-syntax">LocationOf</span></span>, applied to the player object, always agrees with
<span class="extract"><span class="extract-syntax">real_location</span></span>.
</li><li>(4) "Floating" objects, such as backdrops and two-sided doors, are in
theory present in more than one room at once. In practice they can only be
in a single position in the I6 object tree at any one time. The rule is that
if they are theoretically present in the <span class="extract"><span class="extract-syntax">real_location</span></span>, then they are
actually present in the subtree of <span class="extract"><span class="extract-syntax">real_location</span></span>. The routine
<span class="extract"><span class="extract-syntax">MoveFloatingObjects</span></span> updates this, and must be called whenever the player
moves from one room to another.
</li><li>(5) Any objects carried by the player have the I6 <span class="extract"><span class="extract-syntax">moved</span></span> attribute set.
The <span class="extract"><span class="extract-syntax">SACK_OBJECT</span></span> variable is always set to the object of kind "player's
holdall" which the player has most recently been carrying, or had as
a component part of himself. The "note object acquisitions" rule updates
this.
</li></ul>
<p class="commentary">These invariants are usually all false before the following rule is executed;
they are all true once it has completed. In addition, because the global
action variables usually hold details of the action most recently carried
out, we initialise these as if the most recent action had been the player
waiting. (Nobody ought to use these variables at this point, but in case
they do use them by accident in a "when play begins" rule, we want Inform
to behave predictably and without type-unsafe values entering code.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">POSITION_PLAYER_IN_MODEL_R</span><span class="plain-syntax"> </span><span class="identifier-syntax">player_to_be</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">player</span><span class="plain-syntax"> = </span><span class="identifier-syntax">selfobj</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">player_to_be</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InitialSituation</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">PLAYER_OBJECT_INIS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">location</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LocationOf</span><span class="plain-syntax">(</span><span class="identifier-syntax">player_to_be</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">location</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">location</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InitialSituation</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">START_ROOM_INIS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">InitialSituation</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">START_OBJECT_INIS</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">move</span><span class="plain-syntax"> </span><span class="identifier-syntax">player_to_be</span><span class="plain-syntax"> </span><span class="reserved-syntax">to</span><span class="plain-syntax"> </span><span class="identifier-syntax">InitialSituation</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">START_OBJECT_INIS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">move</span><span class="plain-syntax"> </span><span class="identifier-syntax">player_to_be</span><span class="plain-syntax"> </span><span class="reserved-syntax">to</span><span class="plain-syntax"> </span><span class="identifier-syntax">location</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">player_to_be</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">player</span><span class="plain-syntax">) { </span><span class="reserved-syntax">remove</span><span class="plain-syntax"> </span><span class="identifier-syntax">selfobj</span><span class="plain-syntax">; </span><span class="identifier-syntax">ChangePlayer</span><span class="plain-syntax">(</span><span class="identifier-syntax">player_to_be</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> { </span><span class="identifier-syntax">real_location</span><span class="plain-syntax"> = </span><span class="identifier-syntax">location</span><span class="plain-syntax">; </span><span class="identifier-syntax">SilentlyConsiderLight</span><span class="plain-syntax">(); }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NOTE_OBJECT_ACQUISITIONS_R</span><span class="plain-syntax">(); </span><span class="identifier-syntax">MoveFloatingObjects</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">actor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">player</span><span class="plain-syntax">; </span><span class="identifier-syntax">act_requester</span><span class="plain-syntax"> = </span><span class="reserved-syntax">nothing</span><span class="plain-syntax">; </span><span class="identifier-syntax">actors_location</span><span class="plain-syntax"> = </span><span class="identifier-syntax">real_location</span><span class="plain-syntax">; </span><span class="identifier-syntax">action</span><span class="plain-syntax"> = ##</span><span class="identifier-syntax">Wait</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">InitialSituation</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">DONE_INIS</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. Parse Command Rule. </b>This section contains only two primitive rules from the turn sequence
rulebook, the matched pair of the "parse command rule" and the
"generate action rule"; the others are found in the sections on Light
and Time.
</p>
<p class="commentary">We use almost identically the same parser as that in the I6 library, since
it is a well-proven and understood algorithm. The I6 parser returns some of
its results in a supplied array (here <span class="extract"><span class="extract-syntax">parser_results</span></span>, though the I6
library used to call this <span class="extract"><span class="extract-syntax">inputobjs</span></span>), but others are in global variables:
</p>
<ul class="items"><li>(1) The <span class="extract"><span class="extract-syntax">parser_results</span></span> array holds four words, used as indexed by the
constants below.
<ul class="items"><li>(a) The action can be a valid I6 action number, or an I6 "fake
action", a concept not used overtly in I7. Most valid I6 actions
correspond exactly to I7 actions, but in principle it is possible to
define (say) extra debugging commands entirely at the I6 level.
</li><li>(b) The count <span class="extract"><span class="extract-syntax">NO_INPS_PRES</span></span> is always 0, 1 or 2, and then that many
of the next two words are meaningful.
</li><li>(c) Each of the "inp" values is either 0, meaning "put the
multiple object list here"; or 1, meaning "not an object but a
value"; or a valid I6 object. (We use the scoping rules to ensure
that any I6 object visible to the parser is also a valid I7 object, so
&mdash; unlike with actions &mdash; we need not distinguish between the two.)
</li></ul>
<li>(2) The global variable <span class="extract"><span class="extract-syntax">actor</span></span> is set to the person asked to carry out
the command, or is the same as <span class="extract"><span class="extract-syntax">player</span></span> if nobody was mentioned. Thus it
will be the object for Floyd in the command FLOYD, GET PERMIT, but will be
just <span class="extract"><span class="extract-syntax">player</span></span> in the command EAST.
</li><li>(3) The global variables <span class="extract"><span class="extract-syntax">special_number1</span></span> and, if necessary, <span class="extract"><span class="extract-syntax">special_number2</span></span>
hold values corresponding to the first and second of the "inps" to be
returned as 1. Thus, if one of the "inps" is a value and the other is
an object, then <span class="extract"><span class="extract-syntax">special_number1</span></span> is that value; only if both are values
rather than objects will <span class="extract"><span class="extract-syntax">special_number2</span></span> be used. There is no indication
of the kind of these values: I6 is typeless.
</li><li>(4) At most one of the "inps" is permitted to be 1, referring to a multiple
object list. (And a multiple value list is forbidden.) If this happens, the
list of objects is stored in an I6 table array (i.e., with the 0th word
being the number of subsequent words) called <span class="extract"><span class="extract-syntax">multiple_object</span></span>, and the
parser will have set the <span class="extract"><span class="extract-syntax">toomany_flag</span></span> if an overflow occurred &mdash; that is,
if the list was truncated because it originally called for more than 63
objects.
</li><li>(5) The global variable <span class="extract"><span class="extract-syntax">meta</span></span> is set if the action is one marked as such
in the I6 grammar. A confusion in the design of I6 is that being out of world,
as we would say in I7 terms, is associated not with an action as such but
with the command verb triggering it. (This in practice caused no trouble
since we never used, say, the word SAVE for both saving the game and saving,
I don't know, box top coupons.) The state of <span class="extract"><span class="extract-syntax">meta</span></span> returned by the I6
parser does not quite correspond to I7's "out of world" concept, so we
will alter it in a few cases.
</li></ul>
<p class="commentary">Some of these conventions are a little odd-looking now: why not simply
have a larger results array, rather than this pile of occasionally
used variables? The reasons are purely historical: the I6 parser
developed gradually over about a decade.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">ACTION_PRES</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">NO_INPS_PRES</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">INP1_PRES</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">INP2_PRES</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">; </span><span class="comment-syntax">Parser.i6t code assumes this is INP1_PRES + 1</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">PARSE_COMMAND_R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">EarlyInTurnSequence</span><span class="plain-syntax"> == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">; </span><span class="comment-syntax">Prevent use outside top level</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">not_yet_in_play</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Parser__parse</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TreatParserResults</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Treat Parser Results. </b>We don't quite use the results exactly as they are returned by the parser:
we make modifications in a few special cases.
</p>
<ul class="items"><li>(1) <span class="extract"><span class="extract-syntax">##MistakeAction</span></span> is a valid I6 action, but not an I7 one. It is used to
implement "Understand ... as a mistake", which provides a short-cut way
for I7 source text to specify responses to mistaken guesses at the syntax
expected for commands. It can therefore result from a whole variety of
different commands, some of which might be flagged <span class="extract"><span class="extract-syntax">meta</span></span>, others not.
We forcibly set the <span class="extract"><span class="extract-syntax">meta</span></span> flag: a mistake in guessing the command always
happens out of world.
</li><li>(2) A command in the form PERSON, TELL ME ABOUT SOMETHING is altered to
the action resulting from ASK PERSON ABOUT SOMETHING, so that <span class="extract"><span class="extract-syntax">##Tell</span></span>
is converted to <span class="extract"><span class="extract-syntax">##Ask</span></span> in these cases.
</li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">TreatParserResults</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parser_results</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">ACTION_PRES</span><span class="plain-syntax"> == ##</span><span class="identifier-syntax">MistakeAction</span><span class="plain-syntax">) </span><span class="identifier-syntax">meta</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parser_results</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">ACTION_PRES</span><span class="plain-syntax"> == ##</span><span class="identifier-syntax">Tell</span><span class="plain-syntax"> &amp;&amp;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parser_results</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">INP1_PRES</span><span class="plain-syntax"> == </span><span class="identifier-syntax">player</span><span class="plain-syntax"> &amp;&amp; </span><span class="identifier-syntax">actor</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">player</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parser_results</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">ACTION_PRES</span><span class="plain-syntax"> = ##</span><span class="identifier-syntax">Ask</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parser_results</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">INP1_PRES</span><span class="plain-syntax"> = </span><span class="identifier-syntax">actor</span><span class="plain-syntax">; </span><span class="identifier-syntax">actor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">player</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Generate Action Rule. </b>For what are, again, historical reasons to do with the development of I6,
the current action is recorded in a slate of global variables:
</p>
<ul class="items"><li>(1) <span class="extract"><span class="extract-syntax">actor</span></span> is as above; <span class="extract"><span class="extract-syntax">action</span></span> is the I6 action number or fake action
number, though in I7 usage no fake actions should ever reach this point.
</li><li>(2) <span class="extract"><span class="extract-syntax">act_requester</span></span> is the person requesting that the actor should perform
the action, or <span class="extract"><span class="extract-syntax">nothing</span></span> if the action is the actor's own choice. In the
command FLOYD, MOP FLOOR, the <span class="extract"><span class="extract-syntax">act_requester</span></span> is the player and the actor
is Floyd; but when an action arises from a try phrase in I7, such as
"try Floyd mopping the floor", <span class="extract"><span class="extract-syntax">act_requester</span></span> is <span class="extract"><span class="extract-syntax">nothing</span></span> because
it is Floyd's own decision to do this. (The computer, of course, represents
the will-power of all characters other than the player.)
</li><li>(3) <span class="extract"><span class="extract-syntax">inp1</span></span> and <span class="extract"><span class="extract-syntax">inp2</span></span> are global variables whose contents mean the same
as those of <span class="extract"><span class="extract-syntax">parser_results--&gt;INP1_PRES</span></span> and <span class="extract"><span class="extract-syntax">parser_results--&gt;INP2_PRES</span></span>.
(This is not duplication, because actions also arise from "try" rather
than the parser.)
</li><li>(4) The variable <span class="extract"><span class="extract-syntax">multiflag</span></span> is set during the processing of a multiple
object list, and clear otherwise. (It is used for instance by the Standard
Rules to give more concise reports of some successful actions.) Note that
it remains set during any knock-on actions caused by actions in the multiple
object list: the following rule is the only place where <span class="extract"><span class="extract-syntax">multiflag</span></span> is
set or cleared.
</li><li>(5) <span class="extract"><span class="extract-syntax">noun</span></span> and <span class="extract"><span class="extract-syntax">second</span></span> are global variables which are equal to <span class="extract"><span class="extract-syntax">inp1</span></span> and
<span class="extract"><span class="extract-syntax">inp2</span></span> when the latter hold valid object numbers, and are equal to <span class="extract"><span class="extract-syntax">nothing</span></span>
otherwise. (This is not duplication either, because it provides us with
type-safe access to objects: there is no KOV which can safely represent
<span class="extract"><span class="extract-syntax">inp1</span></span> and <span class="extract"><span class="extract-syntax">inp2</span></span>, but <span class="extract"><span class="extract-syntax">noun</span></span> and <span class="extract"><span class="extract-syntax">second</span></span> are valid for the I7 kind of
value "object".)
</li></ul>
<p class="commentary">In the following rule, we create this set of variables for the action or
multiple action(s) suggested by the parser: each action is sent on to
<span class="extract"><span class="extract-syntax">BeginAction</span></span> for processing. Once done, we reset the above variables
in what might seem an odd way: we allow straightforward actions by the
player to remain in the variables, but convert requests to other people
to the neutral "waiting" action carried out by the player (which is the
zero value for actions). Now, in a better world, we would always erase
the action like this, because an action once completed ought to be forgotten.
The value of <span class="extract"><span class="extract-syntax">noun</span></span> ought to be visible only during the action's processing.
</p>
<p class="commentary">But in practice many I7 users write "every turn" rules which are predicated
on what the turn's main action was: say, "Every turn when going: ..."
The every turn stage is not until later in the turn sequence, so such rules
can only work if we keep the main parser-generated action of the turn in
the action variables when we finish up here: so that's what we do.
(Note that <span class="extract"><span class="extract-syntax">BeginAction</span></span> preserves the values of the action variables,
storing copies on the stack, so whatever may have happened during processing,
we finish this routine with the same action variable values that we set at
the beginning.)
</p>
<p class="commentary">Finally, note that an out of world action stops the turn sequence early, at
the end of action generation: this is what prevents the time of day advancing,
every turn rules from firing, and so forth &mdash; see the Standard Rules.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">GENERATE_ACTION_R</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">EarlyInTurnSequence</span><span class="plain-syntax"> == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">; </span><span class="comment-syntax">Prevent use outside top level</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EarlyInTurnSequence</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">action</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parser_results</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">ACTION_PRES</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">act_requester</span><span class="plain-syntax"> = </span><span class="reserved-syntax">nothing</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">actor</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">player</span><span class="plain-syntax">) </span><span class="identifier-syntax">act_requester</span><span class="plain-syntax"> = </span><span class="identifier-syntax">player</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inp1</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">inp2</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">multiflag</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parser_results</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">NO_INPS_PRES</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inp1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parser_results</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">INP1_PRES</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inp1</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">multiflag</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parser_results</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">NO_INPS_PRES</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inp2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parser_results</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">INP2_PRES</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inp2</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">multiflag</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inp1</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> = </span><span class="reserved-syntax">nothing</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inp1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inp2</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">second</span><span class="plain-syntax"> = </span><span class="reserved-syntax">nothing</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">second</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inp2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multiflag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multiple_object</span><span class="plain-syntax">--&gt;0 == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">actor</span><span class="plain-syntax"> == </span><span class="identifier-syntax">player</span><span class="plain-syntax">) { </span><span class="identifier-syntax">GENERATE_ACTION_RM</span><span class="plain-syntax">(</span><span class="character-syntax">'B'</span><span class="plain-syntax">); </span><span class="reserved-syntax">new_line</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">toomany_flag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">toomany_flag</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">actor</span><span class="plain-syntax"> == </span><span class="identifier-syntax">player</span><span class="plain-syntax">) { </span><span class="identifier-syntax">GENERATE_ACTION_RM</span><span class="plain-syntax">(</span><span class="character-syntax">'A'</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">multiple_object</span><span class="plain-syntax">--&gt;0;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">FollowRulebook</span><span class="plain-syntax">(</span><span class="identifier-syntax">MULTIPLE_ACTION_PROCESSING_RB</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">multiple_object</span><span class="plain-syntax">--&gt;0 == </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">multiflag</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inp1</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">noun</span><span class="plain-syntax"> = </span><span class="identifier-syntax">multiple_object</span><span class="plain-syntax">--&gt;1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">inp2</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">parser_results</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">NO_INPS_PRES</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">second</span><span class="plain-syntax"> = </span><span class="identifier-syntax">multiple_object</span><span class="plain-syntax">--&gt;1;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multiple_object</span><span class="plain-syntax">--&gt;0 == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multiflag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">GenerateMultipleActions</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">multiflag</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">BeginAction</span><span class="plain-syntax">(</span><span class="identifier-syntax">action</span><span class="plain-syntax">, </span><span class="identifier-syntax">noun</span><span class="plain-syntax">, </span><span class="identifier-syntax">second</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">actor</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">player</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">act_requester</span><span class="plain-syntax">)) </span><span class="identifier-syntax">action</span><span class="plain-syntax"> = ##</span><span class="identifier-syntax">Wait</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">actor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">player</span><span class="plain-syntax">; </span><span class="identifier-syntax">act_requester</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">meta</span><span class="plain-syntax">) { </span><span class="identifier-syntax">RulebookSucceeds</span><span class="plain-syntax">(); </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Generate Multiple Actions. </b>So this routine is used to issue the individual actions necessary when
a multiple object list has been supplied as either the noun or second noun
part of an action generated by the parser. Note that we stop processing
the list in the event of the game ending, or of the <span class="extract"><span class="extract-syntax">location</span></span> variable
changing its value, which can happen either through movement of the player,
or through passage from darkness to light or vice versa.
</p>
<p class="commentary">We use <span class="extract"><span class="extract-syntax">RunParagraphOn</span></span> to omit skipped lines as paragraph breaks between
the results from any item in the list: this is both more condensed on screen
in ordinary lists, and might allow the user to play tricks such as gathering
up reports from a list and delivering them later in some processed way.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">GenerateMultipleActions</span><span class="plain-syntax"> </span><span class="identifier-syntax">initial_location</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax"> </span><span class="identifier-syntax">item</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">initial_location</span><span class="plain-syntax"> = </span><span class="identifier-syntax">location</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k</span><span class="plain-syntax">=1: </span><span class="identifier-syntax">k</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">multiple_object</span><span class="plain-syntax">--&gt;0: </span><span class="identifier-syntax">k</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">multiple_object</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">k</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RunParagraphOn</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inp1</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">inp1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">; </span><span class="identifier-syntax">BeginAction</span><span class="plain-syntax">(</span><span class="identifier-syntax">action</span><span class="plain-syntax">, </span><span class="identifier-syntax">item</span><span class="plain-syntax">, </span><span class="identifier-syntax">second</span><span class="plain-syntax">, </span><span class="identifier-syntax">item</span><span class="plain-syntax">); </span><span class="identifier-syntax">inp1</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> { </span><span class="identifier-syntax">inp2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">item</span><span class="plain-syntax">; </span><span class="identifier-syntax">BeginAction</span><span class="plain-syntax">(</span><span class="identifier-syntax">action</span><span class="plain-syntax">, </span><span class="identifier-syntax">noun</span><span class="plain-syntax">, </span><span class="identifier-syntax">item</span><span class="plain-syntax">, </span><span class="identifier-syntax">item</span><span class="plain-syntax">); </span><span class="identifier-syntax">inp2</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deadflag</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">location</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">initial_location</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">player</span><span class="plain-syntax"> == </span><span class="identifier-syntax">actor</span><span class="plain-syntax">) { </span><span class="identifier-syntax">ACTION_PROCESSING_INTERNAL_RM</span><span class="plain-syntax">(</span><span class="character-syntax">'J'</span><span class="plain-syntax">); </span><span class="reserved-syntax">new_line</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Timed Events Rule. </b>A timed event is a rule stored in the <span class="extract"><span class="extract-syntax">TimedEventsTable</span></span>, an I6 table array:
zero entries in this table are ignored, and the sequence is significant
only if more than one event goes off at the same moment, in which case
earlier entries go off first. Each rule in the table has a corresponding
timer value in <span class="extract"><span class="extract-syntax">TimedEventTimesTable</span></span>. If this is negative, it represents
a number of turns to go before the event happens &mdash; or properly speaking, the
number of times the timed events rule is invoked. Otherwise the timer value
must be a valid time of day at which the event happens (note that valid times
are all non-negative integers). We allow a bracket of 30 minutes after the
event time proper; this is designed to cope with situations in which the
user sets some timed events, then advances the clock by hand (or uses a
long step time, say in which each turn equates to 20 minutes).
</p>
<p class="commentary">Because an event is struck out of the table just before it is fired, it
will not continue to go off the rest of the half-hour. Moreover, because
the striking out happens {\it before} rather than after the rule fires, a
rule can re-time itself to go off again later, somewhat like the snooze
feature on an alarm clock, without the risk of it going off again
immediately in the same use of the timed events rule: there is guaranteed
to be a blank slot in the timer array at or before the current position
because we have just blanked one.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">TIMED_EVENTS_R</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax"> </span><span class="identifier-syntax">event_timer</span><span class="plain-syntax"> </span><span class="identifier-syntax">fire</span><span class="plain-syntax"> </span><span class="identifier-syntax">rule</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=1: </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=(</span><span class="identifier-syntax">TimedEventsTable</span><span class="plain-syntax">--&gt;0): </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">rule</span><span class="plain-syntax">=</span><span class="identifier-syntax">TimedEventsTable</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">i</span><span class="plain-syntax">) ~= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">event_timer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TimedEventTimesTable</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="identifier-syntax">fire</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">event_timer</span><span class="plain-syntax">&lt;0) {</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">TimedEventTimesTable</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">i</span><span class="plain-syntax">)++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TimedEventTimesTable</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">fire</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">the_time</span><span class="plain-syntax"> - </span><span class="identifier-syntax">event_timer</span><span class="plain-syntax"> + </span><span class="identifier-syntax">TWENTY_FOUR_HOURS</span><span class="plain-syntax">) % </span><span class="identifier-syntax">TWENTY_FOUR_HOURS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">d</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">d</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">30</span><span class="plain-syntax">)) </span><span class="identifier-syntax">fire</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fire</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TimedEventsTable</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">FollowRulebook</span><span class="plain-syntax">(</span><span class="identifier-syntax">rule</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. Setting Timed Events. </b>This is the corresponding routine which adds events to the timer tables, and
is used to define phrases like "the cuckoo clock explodes in 7 turns from
now" or "the cuckoo clock explodes at 4 PM". Here the <span class="extract"><span class="extract-syntax">rule</span></span> would be
"cuckoo clock explodes", and the <span class="extract"><span class="extract-syntax">event_time</span></span> would either be 4 PM with
<span class="extract"><span class="extract-syntax">absolute_time</span></span> set, or simply 7 with <span class="extract"><span class="extract-syntax">absolute_time</span></span> clear.
</p>
<p class="commentary">Note that the same event can occur only once in the timer tables: a new
setting for its firing overwrites an old one. (This ensures that the table
does not slowly balloon in size if the user has not been careful to ensure
that events always fire.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">SetTimedEvent</span><span class="plain-syntax"> </span><span class="identifier-syntax">rule</span><span class="plain-syntax"> </span><span class="identifier-syntax">event_time</span><span class="plain-syntax"> </span><span class="identifier-syntax">absolute_time</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=1: </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=(</span><span class="identifier-syntax">TimedEventsTable</span><span class="plain-syntax">--&gt;0): </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rule</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TimedEventsTable</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">i</span><span class="plain-syntax">) { </span><span class="identifier-syntax">b</span><span class="plain-syntax">=</span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">b</span><span class="plain-syntax">==0) &amp;&amp; (</span><span class="identifier-syntax">TimedEventsTable</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="identifier-syntax">b</span><span class="plain-syntax">=</span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">b</span><span class="plain-syntax">==0) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">RunTimeProblem</span><span class="plain-syntax">(</span><span class="identifier-syntax">RTP_TOOMANYEVENTS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TimedEventsTable</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rule</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">absolute_time</span><span class="plain-syntax">) </span><span class="identifier-syntax">TimedEventTimesTable</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><span class="identifier-syntax">event_time</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">TimedEventTimesTable</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">b</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">event_time</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Setting Time Of Day. </b>This is the old I6 library routine <span class="extract"><span class="extract-syntax">SetTime</span></span>, which is no longer used in I7
at present; but might be, some day.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">Global</span><span class="plain-syntax"> </span><span class="identifier-syntax">time_step</span><span class="plain-syntax">;</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">SetTime</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax"> </span><span class="identifier-syntax">s</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">the_time</span><span class="plain-syntax"> = </span><span class="identifier-syntax">t</span><span class="plain-syntax">; </span><span class="identifier-syntax">time_rate</span><span class="plain-syntax"> = </span><span class="identifier-syntax">s</span><span class="plain-syntax">; </span><span class="identifier-syntax">time_step</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">s</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">time_step</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">-</span><span class="identifier-syntax">s</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Advance Time Rule. </b>This rule advances the two measures of the passing of time: the number of
<span class="extract"><span class="extract-syntax">turns</span></span> of play, and <span class="extract"><span class="extract-syntax">the_time</span></span> of day.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">ADVANCE_TIME_R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">turns</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">the_time</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">time_rate</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">the_time</span><span class="plain-syntax"> = </span><span class="identifier-syntax">the_time</span><span class="plain-syntax">+</span><span class="identifier-syntax">time_rate</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">time_step</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">time_step</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">the_time</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">time_step</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">time_rate</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">the_time</span><span class="plain-syntax"> = </span><span class="identifier-syntax">the_time</span><span class="plain-syntax"> % </span><span class="identifier-syntax">TWENTY_FOUR_HOURS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. Note Object Acquisitions Rule. </b>See the Standard Rules for comment on this.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">NOTE_OBJECT_ACQUISITIONS_R</span><span class="plain-syntax"> </span><span class="identifier-syntax">obj</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">objectloop</span><span class="plain-syntax"> (</span><span class="identifier-syntax">obj</span><span class="plain-syntax"> </span><span class="reserved-syntax">in</span><span class="plain-syntax"> </span><span class="identifier-syntax">player</span><span class="plain-syntax">) </span><span class="reserved-syntax">give</span><span class="plain-syntax"> </span><span class="identifier-syntax">obj</span><span class="plain-syntax"> </span><span class="identifier-syntax">moved</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">objectloop</span><span class="plain-syntax"> (</span><span class="identifier-syntax">obj</span><span class="plain-syntax"> </span><span class="reserved-syntax">has</span><span class="plain-syntax"> </span><span class="identifier-syntax">concealed</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">IndirectlyContains</span><span class="plain-syntax">(</span><span class="identifier-syntax">player</span><span class="plain-syntax">, </span><span class="identifier-syntax">obj</span><span class="plain-syntax">)) </span><span class="reserved-syntax">give</span><span class="plain-syntax"> </span><span class="identifier-syntax">obj</span><span class="plain-syntax"> ~</span><span class="identifier-syntax">concealed</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">Ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">RUCKSACK_CLASS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">objectloop</span><span class="plain-syntax"> (</span><span class="identifier-syntax">obj</span><span class="plain-syntax"> </span><span class="reserved-syntax">in</span><span class="plain-syntax"> </span><span class="identifier-syntax">player</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">obj</span><span class="plain-syntax"> </span><span class="reserved-syntax">ofclass</span><span class="plain-syntax"> </span><span class="identifier-syntax">RUCKSACK_CLASS</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">SACK_OBJECT</span><span class="plain-syntax"> = </span><span class="identifier-syntax">obj</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">objectloop</span><span class="plain-syntax"> (</span><span class="identifier-syntax">obj</span><span class="plain-syntax"> </span><span class="reserved-syntax">ofclass</span><span class="plain-syntax"> </span><span class="identifier-syntax">RUCKSACK_CLASS</span><span class="plain-syntax"> &amp;&amp; </span><span class="identifier-syntax">obj</span><span class="plain-syntax"> </span><span class="reserved-syntax">provides</span><span class="plain-syntax"> </span><span class="identifier-syntax">component_parent</span>
<span class="plain-syntax"> &amp;&amp; </span><span class="identifier-syntax">obj</span><span class="plain-syntax">.</span><span class="identifier-syntax">component_parent</span><span class="plain-syntax"> == </span><span class="identifier-syntax">player</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">SACK_OBJECT</span><span class="plain-syntax"> = </span><span class="identifier-syntax">obj</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">Endif</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Resurrect Player If Asked Rule. </b>If a rule in the "when play ends" rulebook set <span class="extract"><span class="extract-syntax">resurrect_please</span></span>, by executing
the "resume the game" phrase, then this is where we notice that: making
the shutdown rulebook succeed then tells <span class="extract"><span class="extract-syntax">Main</span></span> to fall back into the turn
sequence.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">RESURRECT_PLAYER_IF_ASKED_R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">resurrect_please</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RulebookSucceeds</span><span class="plain-syntax">(); </span><span class="identifier-syntax">resurrect_please</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">deadflag</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">story_complete</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">; </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. Ask The Final Question Rule. </b>And so we come to the bittersweet end: we ask the final question endlessly,
until the player gives a reply which takes drastic enough action to destroy
the current execution context in the VM, for instance by typing QUIT, RESTART,
UNDO or RESTORE. The question and answer are all managed by the activity,
which is defined in I7 source text in the Standard Rules.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">ASK_FINAL_QUESTION_R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="reserved-syntax">true</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CarryOutActivity</span><span class="plain-syntax">(</span><span class="identifier-syntax">DEALING_WITH_FINAL_QUESTION_ACT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DivideParagraphPoint</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">resurrect_please</span><span class="plain-syntax">) </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Read The Final Answer Rule. </b>This erases the current command, so is a technique we couldn't use during
actual play, but here commands are but a distant memory. So we can use the
same buffers for the final question as for game commands.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">READ_FINAL_ANSWER_R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DrawStatusLine</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">KeyboardPrimitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">players_command</span><span class="plain-syntax"> = </span><span class="constant-syntax">100</span><span class="plain-syntax"> + </span><span class="identifier-syntax">WordCount</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">num_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">WordCount</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. Immediately Restart VM Rule. </b>Now for four rules acting on typical responses to the final question.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">IMMEDIATELY_RESTART_VM_R</span><span class="plain-syntax">; @</span><span class="identifier-syntax">restart</span><span class="plain-syntax">; ];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. Immediately Restore Saved Game Rule. </b>It is almost certainly unnecessary to set <span class="extract"><span class="extract-syntax">actor</span></span> to <span class="extract"><span class="extract-syntax">player</span></span> here, but
we do so just in case, because <span class="extract"><span class="extract-syntax">RESTORE_THE_GAME_R</span></span> is protected against
doing anything when it thinks it might have been called erroneously through
a command like "DAPHNE, RESTORE". (Out of world actions should never
be carried out that way, but again, it's a precaution.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">IMMEDIATELY_RESTORE_SAVED_R</span><span class="plain-syntax">; </span><span class="identifier-syntax">actor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">player</span><span class="plain-syntax">; </span><span class="identifier-syntax">RESTORE_THE_GAME_R</span><span class="plain-syntax">(); ];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. Immediately Quit Rule. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">IMMEDIATELY_QUIT_R</span><span class="plain-syntax">; @</span><span class="reserved-syntax">quit</span><span class="plain-syntax">; ];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. Immediately Undo Rule. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">IMMEDIATELY_UNDO_R</span><span class="plain-syntax">; </span><span class="identifier-syntax">Perform_Undo</span><span class="plain-syntax">(); ];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. Print Obituary Headline Rule. </b>Finally, definitions of three primitive rules for the "printing the player's
obituary" activity.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">PRINT_OBITUARY_HEADLINE_R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^^ "</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">VM_Style</span><span class="plain-syntax">(</span><span class="identifier-syntax">ALERT_VMSTY</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"***"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deadflag</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT_OBITUARY_HEADLINE_RM</span><span class="plain-syntax">(</span><span class="character-syntax">'A'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deadflag</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT_OBITUARY_HEADLINE_RM</span><span class="plain-syntax">(</span><span class="character-syntax">'B'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deadflag</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT_OBITUARY_HEADLINE_RM</span><span class="plain-syntax">(</span><span class="character-syntax">'C'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deadflag</span><span class="plain-syntax"> ~= </span><span class="constant-syntax">0</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">" "</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEXT_TY_Say</span><span class="plain-syntax">(</span><span class="identifier-syntax">deadflag</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">" "</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"***"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">VM_Style</span><span class="plain-syntax">(</span><span class="identifier-syntax">NORMAL_VMSTY</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^^^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. Print Final Score Rule. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">PRINT_FINAL_SCORE_R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">KIT_CONFIGURATION_BITMAP</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">USE_SCORING_TCBIT</span><span class="plain-syntax">) </span><span class="identifier-syntax">ANNOUNCE_SCORE_R</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. Display Final Status Line Rule. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">DISPLAY_FINAL_STATUS_LINE_R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sline1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">score</span><span class="plain-syntax">; </span><span class="identifier-syntax">sline2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">turns</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="S-lst.html">&#10094;</a></li><li class="progresssection"><a href="S-msc.html">msc</a></li><li class="progresssection"><a href="S-gll.html">gll</a></li><li class="progresssection"><a href="S-zmc.html">zmc</a></li><li class="progresssection"><a href="S-lgh.html">lgh</a></li><li class="progresssection"><a href="S-lst.html">lst</a></li><li class="progresscurrent">ord</li><li class="progresssection"><a href="S-act.html">act</a></li><li class="progresssection"><a href="S-act2.html">act2</a></li><li class="progresssection"><a href="S-fgr.html">fgr</a></li><li class="progresssection"><a href="S-otf.html">otf</a></li><li class="progresssection"><a href="S-prn.html">prn</a></li><li class="progresssection"><a href="S-wrl.html">wrl</a></li><li class="progresssection"><a href="S-mpr.html">mpr</a></li><li class="progresssection"><a href="S-rtp.html">rtp</a></li><li class="progresssection"><a href="S-tm.html">tm</a></li><li class="progresssection"><a href="S-tst.html">tst</a></li><li class="progresssection"><a href="S-chr.html">chr</a></li><li class="progresssection"><a href="S-str.html">str</a></li><li class="progressnext"><a href="S-act.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>