mirror of
https://github.com/ganelson/inform.git
synced 2024-07-18 06:54:26 +03:00
1650 lines
189 KiB
HTML
1650 lines
189 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>3/rgn</title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
|
|
<!--Weave of '3/tm' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">★</a></li><li><a href="index.html">if</a></li><li><a href="index.html#3">Chapter 3: Space and Time</a></li><li><b>The Map</b></li></ul><p class="purpose">A plugin to provide a geographical model, linking rooms and doors together in oppositely-paired directions.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Definitions</a></li><li><a href="#SP8">§8. Initialisation</a></li><li><a href="#SP10">§10. Inferences</a></li><li><a href="#SP12">§12. Kinds</a></li><li><a href="#SP18">§18. Directions and their numbers</a></li><li><a href="#SP22">§22. The exits array</a></li><li><a href="#SP24">§24. Door connectivity</a></li><li><a href="#SP25">§25. Properties</a></li><li><a href="#SP31">§31. Linguistic extras</a></li><li><a href="#SP35">§35. The map-connector</a></li><li><a href="#SP37">§37. Model completion</a></li><li><a href="#SP38">§38. Redeeming those notices</a></li><li><a href="#SP39">§39. Indexing</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Definitions. </b></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b>The map is a complicated data structure, both because it amounts to a
|
|
ternary relation (though being implemented by many binary ones) and because
|
|
of an ambiguity: a map connection from a room R can lead to another room S,
|
|
to a door, or to nothing. Doors come in two sorts, one and two-sided, and
|
|
checking the physical realism of all this means we need to produce many
|
|
quite specific problem messages.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">We will use quite a lot of temporary work-space to put all of this
|
|
together, but the details can be ignored. If we expected very large numbers
|
|
of objects then it would be worth economising here, but profiling suggests
|
|
that it really isn't.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">map_data</span><span class="plain"> {</span>
|
|
<span class="comment">these are meaningful for doors only</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">map_connection_a</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">map_connection_b</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">map_direction_a</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">map_direction_b</span><span class="plain">;</span>
|
|
|
|
<span class="comment">these are meaningful for directions only</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">direction_index</span><span class="plain">; </span> <span class="comment">counts 0, 1, 2, ..., in order of creation</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">direction_iname</span><span class="plain">; </span> <span class="comment">for the constant instance ref</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">binary_predicate</span><span class="plain"> *</span><span class="identifier">direction_relation</span><span class="plain">; </span> <span class="comment">the corresponding "mapped D of" relation</span>
|
|
|
|
<span class="comment">these are meaningful for rooms only, and are used in making the World index</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">exits</span><span class="plain">[</span><span class="identifier">MAX_DIRECTIONS</span><span class="plain">];</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">exits_set_at</span><span class="plain">[</span><span class="identifier">MAX_DIRECTIONS</span><span class="plain">];</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">spatial_relationship</span><span class="plain">[12];</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">exit_lengths</span><span class="plain">[</span><span class="identifier">MAX_DIRECTIONS</span><span class="plain">];</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">lock_exits</span><span class="plain">[</span><span class="identifier">MAX_DIRECTIONS</span><span class="plain">];</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">vector</span><span class="plain"> </span><span class="identifier">position</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">vector</span><span class="plain"> </span><span class="identifier">saved_gridpos</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">cooled</span><span class="plain">, </span><span class="identifier">shifted</span><span class="plain">, </span><span class="identifier">zone</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">connected_submap</span><span class="plain"> *</span><span class="identifier">submap</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">next_room_in_submap</span><span class="plain">;</span>
|
|
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">world_index_colour</span><span class="plain">; </span> <span class="comment">an HTML colour for the room square (rooms only)</span>
|
|
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">world_index_text_colour</span><span class="plain">; </span> <span class="comment">an HTML colour for the room text (rooms only)</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">map_parameter_scope</span><span class="plain"> </span><span class="identifier">local_map_parameters</span><span class="plain">; </span> <span class="comment">temporary: used in EPS mapping</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">eps_x</span><span class="plain">, </span><span class="identifier">eps_y</span><span class="plain">;</span>
|
|
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">map_data</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure map_data is accessed in 3/mcr, 3/sm2, 3/hm, 3/em and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>It's obvious why the kinds direction and door are special. It's not so
|
|
obvious why "up" and "down" are: the answer is that there are linguistic
|
|
features of these which aren't shared by lateral directions. "Above the
|
|
garden is the treehouse", for instance, does not directly refer to either
|
|
direction, but implies both.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_direction</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_door</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I_up</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I_down</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>Special properties. The I6 implementation of two-way doors and of what, in
|
|
I7, are called backdrops, is quite complicated. See the Inform Designer's Manual,
|
|
fourth edition (the "DM4") for explanations. We are essentially trying to
|
|
program all of that automatically, which is why these awkward multi-purpose
|
|
I6 properties (<code class="display"><span class="extract">door_to</span></code>, <code class="display"><span class="extract">found_in</span></code>, etc.) have no direct I7 equivalents.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_door_dir</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">I6 only</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_door_to</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">I6 only</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_other_side</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">a value property for the other side of a door</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_opposite</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">a value property for the reverse of a direction</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_room_index</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">I6 only: workspace for path-finding through the map</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P_found_in</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">I6 only: needed for multiply-present objects</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>While we could probably represent map knowledge using relation inferences
|
|
in connection with the "mapped D of" relations, it's altogether easier and
|
|
makes for more legible code if we use a special inference type of our own:
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">DIRECTION_INF</span><span class="plain"> 100 </span> <span class="comment">where do map connections from O lead?</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>One useful constant:
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">MAX_WORDS_IN_DIRECTION</span><span class="plain"> (</span><span class="identifier">MAX_WORDS_IN_ASSEMBLAGE</span><span class="plain"> - 4)</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b>These little structures are needed to remember routines to compile later:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">door_dir_notice</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">ddn_iname</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">door</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">R1</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">D1</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">D2</span><span class="plain">;</span>
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">door_dir_notice</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">door_to_notice</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">dtn_iname</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">door</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">R1</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">R2</span><span class="plain">;</span>
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">door_to_notice</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure door_dir_notice is private to this section.</p>
|
|
|
|
<p class="endnote">The structure door_to_notice is private to this section.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. Initialisation. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Map::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_NEW_BASE_KIND_NOTIFY</span><span class="plain">, </span><span class="functiontext">PL::Map::map_new_base_kind_notify</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_NEW_SUBJECT_NOTIFY</span><span class="plain">, </span><span class="functiontext">PL::Map::map_new_subject_notify</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_SET_KIND_NOTIFY</span><span class="plain">, </span><span class="functiontext">PL::Map::map_set_kind_notify</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_SET_SUBKIND_NOTIFY</span><span class="plain">, </span><span class="functiontext">PL::Map::map_set_subkind_notify</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_ACT_ON_SPECIAL_NPS</span><span class="plain">, </span><span class="functiontext">PL::Map::map_act_on_special_NPs</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_CHECK_GOING</span><span class="plain">, </span><span class="functiontext">PL::Map::map_check_going</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_COMPILE_MODEL_TABLES</span><span class="plain">, </span><span class="functiontext">PL::Map::map_compile_model_tables</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_ESTIMATE_PROPERTY_USAGE</span><span class="plain">, </span><span class="functiontext">PL::Map::map_estimate_property_usage</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_LOG_INFERENCE_TYPE</span><span class="plain">, </span><span class="functiontext">PL::Map::map_log_inference_type</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_INFERENCES_CONTRADICT</span><span class="plain">, </span><span class="functiontext">PL::Map::map_inferences_contradict</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_COMPLETE_MODEL</span><span class="plain">, </span><span class="functiontext">PL::Map::map_complete_model</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_NEW_PROPERTY_NOTIFY</span><span class="plain">, </span><span class="functiontext">PL::Map::map_new_property_notify</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_PROPERTY_VALUE_NOTIFY</span><span class="plain">, </span><span class="functiontext">PL::Map::map_property_value_notify</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_INTERVENE_IN_ASSERTION</span><span class="plain">, </span><span class="functiontext">PL::Map::map_intervene_in_assertion</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_ADD_TO_WORLD_INDEX</span><span class="plain">, </span><span class="functiontext">PL::Map::map_add_to_World_index</span><span class="plain">);</span>
|
|
<span class="identifier">PLUGIN_REGISTER</span><span class="plain">(</span><span class="identifier">PLUGIN_ANNOTATE_IN_WORLD_INDEX</span><span class="plain">, </span><span class="functiontext">PL::Map::map_annotate_in_World_index</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::start appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">map_data</span><span class="plain"> *</span><span class="functiontext">PL::Map::new_data</span><span class="plain">(</span><span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">subj</span><span class="plain">) {</span>
|
|
<span class="reserved">map_data</span><span class="plain"> *</span><span class="identifier">md</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">map_data</span><span class="plain">);</span>
|
|
<span class="identifier">md</span><span class="plain">-</span><span class="element">>direction_index</span><span class="plain"> = -1;</span>
|
|
<span class="identifier">md</span><span class="plain">-</span><span class="element">>direction_relation</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">MAX_DIRECTIONS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="identifier">md</span><span class="plain">-</span><span class="element">>exits_set_at</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">md</span><span class="plain">-</span><span class="element">>exits</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">md</span><span class="plain">-</span><span class="element">>map_connection_a</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">md</span><span class="plain">-</span><span class="element">>map_connection_b</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">md</span><span class="plain">-</span><span class="element">>map_direction_a</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">md</span><span class="plain">-</span><span class="element">>map_direction_b</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
|
|
<span class="functiontext">PL::SpatialMap::initialise_mapping_data</span><span class="plain">(</span><span class="identifier">md</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">md</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::new_data is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. Inferences. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_log_inference_type</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">it</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">it</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DIRECTION_INF</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"DIRECTION_INF"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_log_inference_type is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. </b>Two subjects are attached to a direction inference: 1, the destination;
|
|
2, the direction. So at the <code class="display"><span class="extract">CI_DIFFER_IN_INFS1</span></code> level of similarity, two
|
|
different direction inferences disagree about the destination for a given
|
|
direction — this of course is a contradiction.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_inferences_contradict</span><span class="plain">(</span><span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">, </span><span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">B</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">similarity</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">World::Inferences::get_inference_type</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">)) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DIRECTION_INF</span><span class="plain">:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">similarity</span><span class="plain"> == </span><span class="identifier">CI_DIFFER_IN_INFS1</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_inferences_contradict is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. Kinds. </b>These are kind names to do with mapping which Inform provides special
|
|
support for; it recognises the English name when defined by the Standard
|
|
Rules. (So there is no need to translate this to other languages.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">map</span><span class="plain">-</span><span class="identifier">kinds</span><span class="plain">> ::=</span>
|
|
<span class="identifier">direction</span><span class="plain"> |</span>
|
|
<span class="identifier">door</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_new_base_kind_notify</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">new_base</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">map</span><span class="plain">-</span><span class="identifier">kinds</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (<<</span><span class="identifier">r</span><span class="plain">>>) {</span>
|
|
<span class="reserved">case</span><span class="plain"> 0: </span><span class="identifier">K_direction</span><span class="plain"> = </span><span class="identifier">new_base</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 1: </span><span class="identifier">K_door</span><span class="plain"> = </span><span class="identifier">new_base</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_new_base_kind_notify is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. </b>Direction needs to be an abstract object, not a thing or a room, so:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_set_subkind_notify</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">sub</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">super</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">sub</span><span class="plain"> == </span><span class="identifier">K_direction</span><span class="plain">) && (</span><span class="identifier">super</span><span class="plain"> != </span><span class="identifier">K_object</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0)</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DirectionAdrift</span><span class="plain">),</span>
|
|
<span class="string">"'direction' is not allowed to be a kind of anything (other than "</span>
|
|
<span class="string">"'object')"</span><span class="plain">,</span>
|
|
<span class="string">"because it's too fundamental to the way Inform maps out the "</span>
|
|
<span class="string">"geography of the physical world."</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">super</span><span class="plain"> == </span><span class="identifier">K_direction</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0)</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DirectionSubkinded</span><span class="plain">),</span>
|
|
<span class="string">"'direction' is not allowed to have more specific kinds"</span><span class="plain">,</span>
|
|
<span class="string">"because it's too fundamental to the way Inform maps out the "</span>
|
|
<span class="string">"geography of the physical world."</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">K_backdrop</span><span class="plain">) && (</span><span class="identifier">sub</span><span class="plain"> == </span><span class="identifier">K_door</span><span class="plain">) && (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">super</span><span class="plain">, </span><span class="identifier">K_backdrop</span><span class="plain">))) {</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DoorAdrift</span><span class="plain">),</span>
|
|
<span class="string">"'door' is not allowed to be a kind of 'backdrop'"</span><span class="plain">,</span>
|
|
<span class="string">"because it's too fundamental to the way Inform maps out the "</span>
|
|
<span class="string">"geography of the physical world."</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">K_backdrop</span><span class="plain">) && (</span><span class="identifier">sub</span><span class="plain"> == </span><span class="identifier">K_backdrop</span><span class="plain">) && (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">super</span><span class="plain">, </span><span class="identifier">K_door</span><span class="plain">))) {</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BackdropAdrift</span><span class="plain">),</span>
|
|
<span class="string">"'backdrop' is not allowed to be a kind of 'door'"</span><span class="plain">,</span>
|
|
<span class="string">"because it's too fundamental to the way Inform maps out the "</span>
|
|
<span class="string">"geography of the physical world."</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_set_subkind_notify is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§15. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_new_subject_notify</span><span class="plain">(</span><span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">subj</span><span class="plain">) {</span>
|
|
<span class="identifier">CREATE_PF_DATA</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">subj</span><span class="plain">, </span><span class="functiontext">PL::Map::new_data</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_new_subject_notify is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§16. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::object_is_a_direction</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Plugins::Manage::plugged_in</span><span class="plain">(</span><span class="identifier">map_plugin</span><span class="plain">)) && (</span><span class="identifier">K_direction</span><span class="plain">) && (</span><span class="identifier">I</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_direction</span><span class="plain">)))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::object_is_a_direction appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP17"></a><b>§17. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Plugins::Manage::plugged_in</span><span class="plain">(</span><span class="identifier">map_plugin</span><span class="plain">)) && (</span><span class="identifier">K_door</span><span class="plain">) && (</span><span class="identifier">I</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_door</span><span class="plain">)))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::subject_is_a_door</span><span class="plain">(</span><span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span>
|
|
<span class="identifier">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">));</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::object_is_a_door is used in <a href="#SP37_2">§37.2</a>, <a href="#SP37_3">§37.3</a>, <a href="#SP37_4">§37.4</a>, <a href="#SP37_5">§37.5</a>, <a href="#SP37_6">§37.6</a>, <a href="#SP37_7">§37.7</a>, <a href="#SP37_8">§37.8</a>, 3/sm (<a href="3-sm.html#SP32_3_3">§32.3.3</a>, <a href="3-sm.html#SP44">§44</a>), 3/sm2 (<a href="3-sm2.html#SP8_16">§8.16</a>).</p>
|
|
|
|
<p class="endnote">The function PL::Map::subject_is_a_door appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18"></a><b>§18. Directions and their numbers. </b>Directions play a special role because sentences like "east of the treehouse
|
|
is the garden" are parsed differently from sentences like "the nearby place
|
|
property of the treehouse is the garden"; they're also one domain of what
|
|
amounts to the ternary map relation, though we actually implement it as a
|
|
sheaf of binary relations, one for each direction. Anyway:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::is_a_direction</span><span class="plain">(</span><span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K_direction</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">in particular, if we aren't using the IF model</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">InferenceSubjects::is_within</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K_direction</span><span class="plain">));</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::is_a_direction is used in <a href="#SP34">§34</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19"></a><b>§19. </b>When a new direction comes into existence (i.e., not when the underlying
|
|
object <code class="display"><span class="extract">I</span></code> is created, but when its kind is first realised to be "direction"),
|
|
we need to assign it a number:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">registered_directions</span><span class="plain"> = 0; </span> <span class="comment">next direction number to be free</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20"></a><b>§20. </b>These are direction names which Inform provides special support for; it
|
|
recognises the English names when defined by the Standard Rules. (So there is
|
|
no need to translate this to other languages.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">map</span><span class="plain">-</span><span class="identifier">directions</span><span class="plain">> ::=</span>
|
|
<span class="identifier">up</span><span class="plain"> |</span>
|
|
<span class="identifier">down</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21"></a><b>§21. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_set_kind_notify</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">k</span><span class="plain">) {</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kw</span><span class="plain"> = </span><span class="identifier">Instances::to_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((!(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">kw</span><span class="plain">, </span><span class="identifier">K_direction</span><span class="plain">))) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">k</span><span class="plain">, </span><span class="identifier">K_direction</span><span class="plain">))) {</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">IW</span><span class="plain"> = </span><span class="identifier">Instances::get_name</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Vet the direction name for acceptability</span> <span class="cwebmacronumber">21.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">map</span><span class="plain">-</span><span class="identifier">directions</span><span class="plain">>(</span><span class="identifier">IW</span><span class="plain">)) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (<<</span><span class="identifier">r</span><span class="plain">>>) {</span>
|
|
<span class="reserved">case</span><span class="plain"> 0: </span><span class="identifier">I_up</span><span class="plain"> = </span><span class="identifier">I</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 1: </span><span class="identifier">I_down</span><span class="plain"> = </span><span class="identifier">I</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">PL::Naming::object_takes_definite_article</span><span class="plain">(</span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">));</span>
|
|
<<span class="cwebmacro">Assign the object a direction number and a mapped-D-of relation</span> <span class="cwebmacronumber">21.2</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_set_kind_notify is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21_1"></a><b>§21.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Vet the direction name for acceptability</span> <span class="cwebmacronumber">21.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::empty</span><span class="plain">(</span><span class="identifier">IW</span><span class="plain">)) {</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NamelessDirection</span><span class="plain">),</span>
|
|
<span class="string">"nameless directions are not allowed"</span><span class="plain">,</span>
|
|
<span class="string">"so writing something like 'There is a direction.' is forbidden."</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">IW</span><span class="plain">) > </span><span class="constant">MAX_WORDS_IN_DIRECTION</span><span class="plain">) {</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DirectionTooLong</span><span class="plain">),</span>
|
|
<span class="string">"although direction names can be really quite long in today's Inform"</span><span class="plain">,</span>
|
|
<span class="string">"they can't be as long as that."</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP21">§21</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21_2"></a><b>§21.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Assign the object a direction number and a mapped-D-of relation</span> <span class="cwebmacronumber">21.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">registered_directions</span><span class="plain">++;</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">dname</span><span class="plain"> = </span><span class="identifier">InterNames::new</span><span class="plain">(</span><span class="identifier">DIRECTION_OBJECT_INAMEF</span><span class="plain">);</span>
|
|
<span class="identifier">Packaging::house</span><span class="plain">(</span><span class="identifier">dname</span><span class="plain">, </span><span class="identifier">Kinds::Behaviour::package</span><span class="plain">(</span><span class="identifier">K_direction</span><span class="plain">));</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>direction_iname</span><span class="plain"> = </span><span class="identifier">dname</span><span class="plain">;</span>
|
|
<span class="functiontext">PL::MapDirections::make_mapped_predicate</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">dname</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP21">§21</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP22"></a><b>§22. The exits array. </b>The bulk of the map is stored in the arrays called <code class="display"><span class="extract">exits</span></code>, which hold the
|
|
map connections fanning out from each room. The direction numbers carefully
|
|
noted above are keys into these arrays.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">It might look a little wasteful of I7's memory to expand the direction
|
|
inferences, a nicely compact representation, into large and sparse arrays.
|
|
But it's convenient, and profiling suggests that the memory overhead is not
|
|
significant. It also means that the World Index mapping code, which contains
|
|
quite crunchy algorithms, has the fastest possible access to the layout.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="identifier">MAP_EXIT</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">Y</span><span class="plain">) </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">)-</span><span class="element">>exits</span><span class="plain">[</span><span class="identifier">Y</span><span class="plain">]</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Map::build_exits_array</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">d</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">Instances::to_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">K_direction</span><span class="plain">)) {</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>direction_index</span><span class="plain"> = </span><span class="identifier">d</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="constant">DIRECTION_INF</span><span class="plain">) {</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs1</span><span class="plain">, *</span><span class="identifier">infs2</span><span class="plain">;</span>
|
|
<span class="identifier">World::Inferences::get_references</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, &</span><span class="identifier">infs1</span><span class="plain">, &</span><span class="identifier">infs2</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">dir</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">infs1</span><span class="plain">) </span><span class="identifier">to</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">infs1</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">infs2</span><span class="plain">) </span><span class="identifier">dir</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">infs2</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">to</span><span class="plain">) && (</span><span class="identifier">dir</span><span class="plain">)) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">dn</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">dir</span><span class="plain">)-</span><span class="element">>direction_index</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">dn</span><span class="plain"> >= 0) && (</span><span class="identifier">dn</span><span class="plain"> < </span><span class="identifier">MAX_DIRECTIONS</span><span class="plain">)) {</span>
|
|
<span class="identifier">MAP_EXIT</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">dn</span><span class="plain">) = </span><span class="identifier">to</span><span class="plain">;</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>exits_set_at</span><span class="plain">[</span><span class="identifier">dn</span><span class="plain">] = </span><span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::build_exits_array is used in <a href="#SP37">§37</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP23"></a><b>§23. </b>This is easy to translate into I6 (though that's partly because I7 doesn't
|
|
follow the traditional I6 library way to represent the map):
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_compile_model_tables</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Declare I6 constants for the directions</span> <span class="cwebmacronumber">23.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Compile the I6 Map-Storage array</span> <span class="cwebmacronumber">23.2</span>><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_compile_model_tables is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP23_1"></a><b>§23.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Declare I6 constants for the directions</span> <span class="cwebmacronumber">23.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">ndi</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">NO_DIRECTIONS_NRL</span><span class="plain">);</span>
|
|
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="identifier">Packaging::enter_home_of</span><span class="plain">(</span><span class="identifier">ndi</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::named_numeric_constant</span><span class="plain">(</span><span class="identifier">ndi</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">registered_directions</span><span class="plain">);</span>
|
|
<span class="identifier">Packaging::exit</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">K_direction</span><span class="plain">) {</span>
|
|
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="identifier">Packaging::enter_home_of</span><span class="plain">(</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>direction_iname</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::named_iname_constant</span><span class="plain">(</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>direction_iname</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">, </span><span class="identifier">Instances::emitted_iname</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">));</span>
|
|
<span class="identifier">Packaging::exit</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP23">§23</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP23_2"></a><b>§23.2. </b>The <code class="display"><span class="extract">Map_Storage</span></code> array consists only of the <code class="display"><span class="extract">exits</span></code> arrays written out
|
|
one after another. It looks wasteful of memory, since it is almost always
|
|
going to be filled mostly with <code class="display"><span class="extract">0</span></code> entries (meaning: no exit that way). But
|
|
the memory needs to be there because map connections can be added dynamically
|
|
at run-time, so we can't know now how many we will need.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Compile the I6 Map-Storage array</span> <span class="cwebmacronumber">23.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="identifier">Instances::emitted_iname</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">MAP_STORAGE_NRL</span><span class="plain">);</span>
|
|
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="identifier">Packaging::enter_home_of</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::named_array_begin</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">words_used</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">existing_story_file</span><span class="plain">) {</span>
|
|
<span class="identifier">Emit::array_divider</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"minimal, as there are no rooms"</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">words_used</span><span class="plain"> = 4;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">Emit::array_divider</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"one row per room"</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Spatial::object_is_a_room</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">registered_directions</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain"> = </span><span class="identifier">MAP_EXIT</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to</span><span class="plain">)</span>
|
|
<span class="identifier">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">Instances::iname</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">));</span>
|
|
<span class="reserved">else</span>
|
|
<span class="identifier">Emit::array_numeric_entry</span><span class="plain">(0);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">words_used</span><span class="plain">++;</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">divider</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">divider</span><span class="plain">, </span><span class="string">"Exits from: %~I"</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::array_divider</span><span class="plain">(</span><span class="identifier">divider</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">divider</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">Emit::array_end</span><span class="plain">();</span>
|
|
<span class="identifier">Packaging::exit</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
|
|
<span class="identifier">VirtualMachines::note_usage</span><span class="plain">(</span><span class="string">"map"</span><span class="plain">, </span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"map of rooms and doors"</span><span class="plain">,</span>
|
|
<span class="identifier">words_used</span><span class="plain">, 0, </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP23">§23</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24"></a><b>§24. Door connectivity. </b>We've seen how most of the map is represented, in the <code class="display"><span class="extract">exits</span></code> arrays. The
|
|
missing information has to do with doors. If east of the Carousel Room is
|
|
the oak door, then <code class="display"><span class="extract">Map_Storage</span></code> reveals only that fact, and not what's on
|
|
the other side of the door. This will eventually be compiled into the
|
|
<code class="display"><span class="extract">door_to</span></code> property for the oak door object. In the mean time, every door
|
|
object has four pieces of data attached:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Map::get_door_data</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">door</span><span class="plain">, </span><span class="identifier">instance</span><span class="plain"> **</span><span class="identifier">c1</span><span class="plain">, </span><span class="identifier">instance</span><span class="plain"> **</span><span class="identifier">c2</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c1</span><span class="plain">) *</span><span class="identifier">c1</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">door</span><span class="plain">)-</span><span class="element">>map_connection_a</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c2</span><span class="plain">) *</span><span class="identifier">c2</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">door</span><span class="plain">)-</span><span class="element">>map_connection_b</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::get_door_data is used in <a href="#SP39">§39</a>, 3/sm (<a href="3-sm.html#SP44">§44</a>), 3/sm2 (<a href="3-sm2.html#SP8_16">§8.16</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP25"></a><b>§25. Properties. </b>These are property names to do with mapping which Inform provides special
|
|
support for; it recognises the English names when they are defined by the
|
|
Standard Rules. (So there is no need to translate this to other languages.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">map</span><span class="plain">-</span><span class="identifier">properties</span><span class="plain">> ::=</span>
|
|
<span class="identifier">opposite</span><span class="plain"> |</span>
|
|
<span class="identifier">other</span><span class="plain"> </span><span class="identifier">side</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP26"></a><b>§26. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_new_property_notify</span><span class="plain">(</span><span class="identifier">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">map</span><span class="plain">-</span><span class="identifier">properties</span><span class="plain">>(</span><span class="identifier">prn</span><span class="plain">-</span><span class="element">>name</span><span class="plain">)) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (<<</span><span class="identifier">r</span><span class="plain">>>) {</span>
|
|
<span class="reserved">case</span><span class="plain"> 0: </span><span class="identifier">P_opposite</span><span class="plain"> = </span><span class="identifier">prn</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 1: </span><span class="identifier">P_other_side</span><span class="plain"> = </span><span class="identifier">prn</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_new_property_notify is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27"></a><b>§27. </b>We would like to deduce from a sentence like
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>The other side of the iron door is the Black Holding Area.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">that the "Black Holding Area" is a room; otherwise, if it has no map
|
|
connections, Inform may well think it's just an object. This is where that
|
|
deduction is made:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_property_value_notify</span><span class="plain">(</span><span class="identifier">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prn</span><span class="plain"> == </span><span class="identifier">P_other_side</span><span class="plain">) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="identifier">Rvalues::to_object_instance</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="identifier">World::Inferences::draw</span><span class="plain">(</span><span class="constant">IS_ROOM_INF</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">CERTAIN_CE</span><span class="plain">,</span>
|
|
<span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_property_value_notify is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP28"></a><b>§28. </b>The I6 <code class="display"><span class="extract">found_in</span></code> property is a general mechanism for multiply-present
|
|
objects. This causes great complications, and I7 simplifies the model world
|
|
by hiding it from the author, and using it internally to implement backdrops
|
|
and two-sided doors. Two different plugins therefore need access to it (this
|
|
one and Backdrops), and this is where they set it.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Map::set_found_in</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P_found_in</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
|
|
<span class="identifier">P_found_in</span><span class="plain"> = </span><span class="identifier">Properties::Valued::new_nameless</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"found_in"</span><span class="plain">,</span>
|
|
<span class="identifier">K_value</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">World::Inferences::get_prop_state</span><span class="plain">(</span>
|
|
<span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">P_found_in</span><span class="plain">))</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"rival found_in interpretations"</span><span class="plain">);</span>
|
|
<span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">P_found_in</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">),</span>
|
|
<span class="identifier">Rvalues::from_iname</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">), </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::set_found_in is used in <a href="#SP37_8_1">§37.8.1</a>, 3/bck (<a href="3-bck.html#SP18">§18</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29"></a><b>§29. </b>This utility routine which looks for the "opposite"
|
|
property in the linked list of inferences belonging to an object.
|
|
(This is a property of directions.) Crude, but not time-sensitive,
|
|
and there seems little point in writing this any better.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="functiontext">PL::Map::get_value_of_opposite_property</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = </span><span class="identifier">World::Inferences::get_prop_state</span><span class="plain">(</span>
|
|
<span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">P_opposite</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">val</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Rvalues::to_object_instance</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::get_value_of_opposite_property is used in <a href="#SP36">§36</a>, <a href="#SP37_8_4">§37.8.4</a>, <a href="#SP38">§38</a>, 3/sm2 (<a href="3-sm2.html#SP43_1">§43.1</a>, <a href="3-sm2.html#SP43_3">§43.3</a>, <a href="3-sm2.html#SP45">§45</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP30"></a><b>§30. </b>This really is very approximate, but:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_estimate_property_usage</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">k</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">words_used</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">k</span><span class="plain">, </span><span class="identifier">K_door</span><span class="plain">)) *</span><span class="identifier">words_used</span><span class="plain"> += 14;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">k</span><span class="plain">, </span><span class="identifier">K_room</span><span class="plain">)) *</span><span class="identifier">words_used</span><span class="plain"> += 2;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_estimate_property_usage is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP31"></a><b>§31. Linguistic extras. </b>These NPs allow us to refer to the special directions "up" and "down":
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">map</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">-</span><span class="identifier">phrases</span><span class="plain">> ::=</span>
|
|
<span class="identifier">below</span><span class="plain"> |</span>
|
|
<span class="identifier">above</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP32"></a><b>§32. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_act_on_special_NPs</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">map</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">-</span><span class="identifier">phrases</span><span class="plain">>(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">))) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (<<</span><span class="identifier">r</span><span class="plain">>>) {</span>
|
|
<span class="reserved">case</span><span class="plain"> 0:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I_down</span><span class="plain">) {</span>
|
|
<span class="identifier">Assertions::Refiner::noun_from_infs</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I_down</span><span class="plain">));</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 1:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I_up</span><span class="plain">) {</span>
|
|
<span class="identifier">Assertions::Refiner::noun_from_infs</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I_up</span><span class="plain">));</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_act_on_special_NPs is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP33"></a><b>§33. </b>We also add some optional clauses to the "going" action:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_check_going</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain">,</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">by</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">through</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pushing</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Actions::Patterns::check_going</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="string">"from"</span><span class="plain">,</span>
|
|
<span class="identifier">K_room</span><span class="plain">, </span><span class="identifier">K_region</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Actions::Patterns::check_going</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">, </span><span class="string">"to"</span><span class="plain">,</span>
|
|
<span class="identifier">K_room</span><span class="plain">, </span><span class="identifier">K_region</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Actions::Patterns::check_going</span><span class="plain">(</span><span class="identifier">by</span><span class="plain">, </span><span class="string">"by"</span><span class="plain">,</span>
|
|
<span class="identifier">K_thing</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Actions::Patterns::check_going</span><span class="plain">(</span><span class="identifier">through</span><span class="plain">, </span><span class="string">"through"</span><span class="plain">,</span>
|
|
<span class="identifier">K_door</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Actions::Patterns::check_going</span><span class="plain">(</span><span class="identifier">pushing</span><span class="plain">, </span><span class="string">"with"</span><span class="plain">,</span>
|
|
<span class="identifier">K_thing</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_check_going is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP34"></a><b>§34. </b>Consider the sentences:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>A dead end is a kind of room. The Pitch is a room. East is a dead end.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">Inform would ordinarily read the third sentence as saying that the "east"
|
|
object (a direction) has kind "dead end", and would throw a problem message.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">What was actually meant, of course, is that a new instance of "dead end"
|
|
exists to the east of the Pitch; in effect, we read it as:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Z is a dead end. East is Z.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">where Z is a newly created and nameless object.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">But we must be careful not to catch "East is a direction" in the same net
|
|
because, of course, that does set its kind.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_intervene_in_assertion</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">px</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">py</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">) == </span><span class="identifier">PROPER_NOUN_NT</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">) == </span><span class="identifier">COMMON_NOUN_NT</span><span class="plain">)) {</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">left_object</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">);</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">right_kind</span><span class="plain"> = </span><span class="identifier">ParseTree::get_subject</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">PL::Map::is_a_direction</span><span class="plain">(</span><span class="identifier">left_object</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">PL::Map::is_a_direction</span><span class="plain">(</span><span class="identifier">right_kind</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
|
|
<span class="identifier">Assertions::Creator::convert_instance_to_nounphrase</span><span class="plain">(</span><span class="identifier">py</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">px</span><span class="plain">, </span><span class="identifier">nowhere_ANNOT</span><span class="plain">)) {</span>
|
|
<span class="identifier">Problems::Issue::assertion_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NowhereDescribed</span><span class="plain">),</span>
|
|
<span class="string">"'nowhere' cannot be made specific"</span><span class="plain">,</span>
|
|
<span class="string">"and so cannot have specific properties or be of any given kind."</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_intervene_in_assertion is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP35"></a><b>§35. The map-connector. </b>Now we come to the code which creates map connections. This needs special
|
|
treatment only so that asserting M(X, Y) also asserts M'(Y, X), where
|
|
M' is the predicate for the opposite direction to M; but since this
|
|
is only a guess, it drops from <code class="display"><span class="extract">CERTAIN_CE</span></code> to merely <code class="display"><span class="extract">LIKELY_CE</span></code>.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">However, the map-connector can also run in one-way mode, where it doesn't
|
|
make this guess; so we begin with switching in and out.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">oneway_map_connections_only</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Map::enter_one_way_mode</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) { </span><span class="identifier">oneway_map_connections_only</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; }</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Map::exit_one_way_mode</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) { </span><span class="identifier">oneway_map_connections_only</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; }</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::enter_one_way_mode appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function PL::Map::exit_one_way_mode appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP36"></a><b>§36. </b>Note that, in order to make the conjectural reverse map direction, we need
|
|
to look up the "opposite" property of the forward one. This relies on all
|
|
directions having their opposites defined before any map is built, and is the
|
|
reason for Inform's insistence that directions are always created in matched
|
|
pairs.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Map::connect</span><span class="plain">(</span><span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">i_from</span><span class="plain">, </span><span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">i_to</span><span class="plain">,</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">i_dir</span><span class="plain">) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">go_from</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">i_from</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">go_to</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">i_to</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">forwards_dir</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">i_dir</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">forwards_dir</span><span class="plain">, </span><span class="identifier">K_direction</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unknown direction"</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">reverse_dir</span><span class="plain"> = </span><span class="functiontext">PL::Map::get_value_of_opposite_property</span><span class="plain">(</span><span class="identifier">forwards_dir</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">go_from</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(2, </span><span class="identifier">forwards_dir</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(3, </span><span class="identifier">go_to</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_WayFromUnclear</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"On the basis of %1, I'm trying to make a map connection in the "</span>
|
|
<span class="string">"%2 direction to %3, but I can't make sense of where it goes from."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="functiontext">PL::Map::oneway_map_connection</span><span class="plain">(</span><span class="identifier">go_from</span><span class="plain">, </span><span class="identifier">go_to</span><span class="plain">, </span><span class="identifier">forwards_dir</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">reverse_dir</span><span class="plain">) && (</span><span class="identifier">go_to</span><span class="plain">) && (</span><span class="identifier">oneway_map_connections_only</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">reverse_dir</span><span class="plain">, </span><span class="identifier">K_direction</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(1, </span><span class="identifier">forwards_dir</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(2, </span><span class="identifier">reverse_dir</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_OppositeNotDirection</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"I'm trying to make a map connection in the %1 direction, "</span>
|
|
<span class="string">"which means there ought to be map connection back in the "</span>
|
|
<span class="string">"opposite direction. But the opposite of %1 seems to be %2, "</span>
|
|
<span class="string">"which doesn't make sense since %2 isn't a direction. (Maybe "</span>
|
|
<span class="string">"you forgot to say that it was?)"</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="functiontext">PL::Map::oneway_map_connection</span><span class="plain">(</span><span class="identifier">go_to</span><span class="plain">, </span><span class="identifier">go_from</span><span class="plain">, </span><span class="identifier">reverse_dir</span><span class="plain">, </span><span class="identifier">LIKELY_CE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Map::oneway_map_connection</span><span class="plain">(</span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">go_from</span><span class="plain">, </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">go_to</span><span class="plain">,</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">forwards_dir</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">certainty_level</span><span class="plain">) {</span>
|
|
<span class="identifier">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain"> = </span><span class="functiontext">PL::MapDirections::get_mapping_relation</span><span class="plain">(</span><span class="identifier">forwards_dir</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bp</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"map connection in non-direction"</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">x</span><span class="plain"> = </span><span class="identifier">prevailing_mood</span><span class="plain">;</span>
|
|
<span class="identifier">prevailing_mood</span><span class="plain"> = </span><span class="identifier">certainty_level</span><span class="plain">;</span>
|
|
<span class="identifier">Calculus::Propositions::Assert::assert_true_about</span><span class="plain">(</span>
|
|
<span class="identifier">Calculus::Propositions::Abstract::to_set_simple_relation</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">, </span><span class="identifier">go_to</span><span class="plain">),</span>
|
|
<span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">go_from</span><span class="plain">), </span><span class="identifier">certainty_level</span><span class="plain">);</span>
|
|
<span class="identifier">prevailing_mood</span><span class="plain"> = </span><span class="identifier">x</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::connect appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function PL::Map::oneway_map_connection appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37"></a><b>§37. Model completion. </b>And here begins the fun. It's not as easy to write down the requirements for
|
|
the map as might be thought.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_complete_model</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">stage</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">stage</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> 2:</span>
|
|
<<span class="cwebmacro">Give each room a room-index property as workspace for route finding</span> <span class="cwebmacronumber">37.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Ensure that map connections are room-to-room, room-to-door or door-to-room</span> <span class="cwebmacronumber">37.2</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> > 0) </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Ensure that every door has either one or two connections from it</span> <span class="cwebmacronumber">37.3</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> > 0) </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Ensure that no door has spurious other connections to it</span> <span class="cwebmacronumber">37.4</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> > 0) </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Ensure that no door uses both map connections and other side</span> <span class="cwebmacronumber">37.5</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> > 0) </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Ensure that no door is present in a room to which it does not connect</span> <span class="cwebmacronumber">37.6</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> > 0) </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Place any one-sided door inside the room which connects to it</span> <span class="cwebmacronumber">37.7</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Assert found-in, door-to and door-dir properties for doors</span> <span class="cwebmacronumber">37.8</span>><span class="plain">;</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 4: </span><span class="functiontext">PL::Map::build_exits_array</span><span class="plain">(); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_complete_model is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_1"></a><b>§37.1. </b>Every room has a <code class="display"><span class="extract">room_index</span></code> property. It has no meaningful contents at
|
|
the start of play, and we initialise to -1 since this marks the route-finding
|
|
cache as being broken. (Route-finding is one of the few really time-critical
|
|
tasks at run-time, which is why we keep complicating the I7 code to
|
|
accommodate it.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Give each room a room-index property as workspace for route finding</span> <span class="cwebmacronumber">37.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">P_room_index</span><span class="plain"> = </span><span class="identifier">Properties::Valued::new_nameless</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"room_index"</span><span class="plain">, </span><span class="identifier">K_number</span><span class="plain">);</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">minus_one</span><span class="plain"> = </span><span class="identifier">Rvalues::from_int</span><span class="plain">(-1, </span><span class="identifier">EMPTY_WORDING</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Spatial::object_is_a_room</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">))</span>
|
|
<span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">P_room_index</span><span class="plain">,</span>
|
|
<span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">minus_one</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37">§37</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_2"></a><b>§37.2. </b>The following code does little if the source is correct: it mostly
|
|
checks that various mapping impossibilities do not occur.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Ensure that map connections are room-to-room, room-to-door or door-to-room</span> <span class="cwebmacronumber">37.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) {</span>
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="constant">DIRECTION_INF</span><span class="plain">) {</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs1</span><span class="plain">;</span>
|
|
<span class="identifier">World::Inferences::get_references</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, &</span><span class="identifier">infs1</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">infs1</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">PL::Spatial::object_is_a_room</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) && (</span><span class="identifier">to</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">PL::Spatial::object_is_a_room</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
|
|
<span class="identifier">Problems::Issue::contradiction_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BadMapCell</span><span class="plain">),</span>
|
|
<span class="identifier">Instances::get_creating_sentence</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">),</span>
|
|
<span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">), </span><span class="identifier">to</span><span class="plain">,</span>
|
|
<span class="string">"appears to be something which can be reached via a map "</span>
|
|
<span class="string">"connection, but it seems to be neither a room nor a door"</span><span class="plain">,</span>
|
|
<span class="string">"and these are the only possibilities allowed by Inform."</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">PL::Spatial::object_is_a_room</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
|
|
<span class="identifier">Problems::Issue::object_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DoorToNonRoom</span><span class="plain">),</span>
|
|
<span class="identifier">I</span><span class="plain">,</span>
|
|
<span class="string">"seems to be a door opening on something not a room"</span><span class="plain">,</span>
|
|
<span class="string">"but a door must connect one or two rooms (and in particular is "</span>
|
|
<span class="string">"not allowed to connect to another door)."</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37">§37</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_3"></a><b>§37.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Ensure that every door has either one or two connections from it</span> <span class="cwebmacronumber">37.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">connections_in</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">where</span><span class="plain">[3];</span>
|
|
<span class="identifier">where</span><span class="plain">[0] = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">where</span><span class="plain">[1] = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">where</span><span class="plain">[2] = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">to placate <code class="display"><span class="extract">gcc</span></code></span>
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">front_side_inf</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">back_side_inf</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="constant">DIRECTION_INF</span><span class="plain">) {</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs1</span><span class="plain">, *</span><span class="identifier">infs2</span><span class="plain">;</span>
|
|
<span class="identifier">World::Inferences::get_references</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, &</span><span class="identifier">infs1</span><span class="plain">, &</span><span class="identifier">infs2</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">infs1</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">dir</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">infs2</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">connections_in</span><span class="plain"> == 0) {</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_a</span><span class="plain"> = </span><span class="identifier">to</span><span class="plain">;</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_direction_a</span><span class="plain"> = </span><span class="identifier">dir</span><span class="plain">;</span>
|
|
<span class="identifier">where</span><span class="plain">[0] = </span><span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">);</span>
|
|
<span class="identifier">front_side_inf</span><span class="plain"> = </span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">connections_in</span><span class="plain"> == 1) {</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_b</span><span class="plain"> = </span><span class="identifier">to</span><span class="plain">;</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_direction_b</span><span class="plain"> = </span><span class="identifier">dir</span><span class="plain">;</span>
|
|
<span class="identifier">where</span><span class="plain">[1] = </span><span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">);</span>
|
|
<span class="identifier">back_side_inf</span><span class="plain"> = </span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">connections_in</span><span class="plain"> == 2) {</span>
|
|
<span class="identifier">where</span><span class="plain">[2] = </span><span class="identifier">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">connections_in</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">front_side_inf</span><span class="plain">) && (</span><span class="identifier">back_side_inf</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">World::Inferences::get_timestamp</span><span class="plain">(</span><span class="identifier">front_side_inf</span><span class="plain">) ></span>
|
|
<span class="identifier">World::Inferences::get_timestamp</span><span class="plain">(</span><span class="identifier">back_side_inf</span><span class="plain">)) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_a</span><span class="plain">;</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_a</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_b</span><span class="plain">;</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_b</span><span class="plain"> = </span><span class="identifier">X</span><span class="plain">;</span>
|
|
<span class="identifier">X</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_direction_a</span><span class="plain">;</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_direction_a</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_direction_b</span><span class="plain">;</span>
|
|
<span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_direction_b</span><span class="plain"> = </span><span class="identifier">X</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PX</span><span class="plain"> = </span><span class="identifier">where</span><span class="plain">[0]; </span><span class="identifier">where</span><span class="plain">[0] = </span><span class="identifier">where</span><span class="plain">[1]; </span><span class="identifier">where</span><span class="plain">[1] = </span><span class="identifier">PX</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">connections_in</span><span class="plain"> == 0) </span><<span class="cwebmacro">Issue a problem message for a stranded door</span> <span class="cwebmacronumber">37.3.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">connections_in</span><span class="plain"> > 2) </span><<span class="cwebmacro">Issue a problem message for an overactive door</span> <span class="cwebmacronumber">37.3.2</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37">§37</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_3_1"></a><b>§37.3.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue a problem message for a stranded door</span> <span class="cwebmacronumber">37.3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">Problems::Issue::object_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DoorUnconnected</span><span class="plain">),</span>
|
|
<span class="identifier">I</span><span class="plain">,</span>
|
|
<span class="string">"seems to be a door with no way in or out"</span><span class="plain">,</span>
|
|
<span class="string">"so either you didn't mean it to be a door or you haven't specified what's "</span>
|
|
<span class="string">"on each side. You could do this by writing something like 'The blue door is "</span>
|
|
<span class="string">"east of the Library and west of the Conservatory'."</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37_3">§37.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_3_2"></a><b>§37.3.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue a problem message for an overactive door</span> <span class="cwebmacronumber">37.3.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(1, </span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(2, </span><span class="identifier">where</span><span class="plain">[0]);</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(3, </span><span class="identifier">where</span><span class="plain">[1]);</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(4, </span><span class="identifier">where</span><span class="plain">[2]);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DoorOverconnected</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"%1 seems to be a door with three ways out (specified %2, %3 and %4), but "</span>
|
|
<span class="string">"you can only have one or two sides to a door in Inform: a one-sided "</span>
|
|
<span class="string">"door means a door which is only touchable and usable from one side, and an "</span>
|
|
<span class="string">"example might be a window through which one falls to the ground below. If "</span>
|
|
<span class="string">"you really need a three-sided cavity, best to make it a room in its own right."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37_3">§37.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_4"></a><b>§37.4. </b>Since map connections are not always reversible (only most of the time), we
|
|
can't assume that having at most two ways out means there are at most two ways
|
|
in. So we check here that any way in to a door corresponds to one of its ways
|
|
out. (The reverse need not be true: it's possible for a door to lead to a room
|
|
from which there's no way back.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Ensure that no door has spurious other connections to it</span> <span class="cwebmacronumber">37.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Spatial::object_is_a_room</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) {</span>
|
|
<span class="identifier">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
|
|
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="constant">DIRECTION_INF</span><span class="plain">) {</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">infs1</span><span class="plain">;</span>
|
|
<span class="identifier">World::Inferences::get_references</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, &</span><span class="identifier">infs1</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain"> = </span><span class="identifier">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">infs1</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">)) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">exit1</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">to</span><span class="plain">)-</span><span class="element">>map_connection_a</span><span class="plain">;</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">exit2</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">to</span><span class="plain">)-</span><span class="element">>map_connection_b</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">I</span><span class="plain"> != </span><span class="identifier">exit1</span><span class="plain">) && (</span><span class="identifier">exit2</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) {</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(1, </span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(2, </span><span class="identifier">to</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(3, </span><span class="identifier">exit1</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RoomTwistyDoor</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"%1, a room, seems to have a map connection which goes "</span>
|
|
<span class="string">"through %2, a door: but that doesn't seem physically "</span>
|
|
<span class="string">"possible, since %2 seems to connect to %3 in the same "</span>
|
|
<span class="string">"direction. Something's twisty here."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">I</span><span class="plain"> != </span><span class="identifier">exit1</span><span class="plain">) && (</span><span class="identifier">I</span><span class="plain"> != </span><span class="identifier">exit2</span><span class="plain">)) {</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(1, </span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(2, </span><span class="identifier">to</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(3, </span><span class="identifier">exit1</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_object</span><span class="plain">(4, </span><span class="identifier">exit2</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RoomMissingDoor</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"%1, a room, seems to have a map connection which goes "</span>
|
|
<span class="string">"through %2, a door: but that doesn't seem physically "</span>
|
|
<span class="string">"possible, since the rooms on each side of %2 have "</span>
|
|
<span class="string">"been established as %3 and %4."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37">§37</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_5"></a><b>§37.5. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Ensure that no door uses both map connections and other side</span> <span class="cwebmacronumber">37.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_a</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_b</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">World::Inferences::get_prop_state</span><span class="plain">(</span>
|
|
<span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">P_other_side</span><span class="plain">)))</span>
|
|
<span class="identifier">Problems::Issue::object_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BothWaysDoor</span><span class="plain">),</span>
|
|
<span class="identifier">I</span><span class="plain">, </span><span class="string">"seems to be a door whose connections have been given in both "</span>
|
|
<span class="string">"of the alternative ways at once"</span><span class="plain">,</span>
|
|
<span class="string">"by directly giving its map connections (the normal way to set up "</span>
|
|
<span class="string">"a two-sided door) and also by saying what is through it (the normal "</span>
|
|
<span class="string">"way to set up a one-sided door). As a door can't be both one- and "</span>
|
|
<span class="string">"two-sided at once, I'm going to object to this."</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37">§37</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_6"></a><b>§37.6. </b>The Spatial model requires that rooms are free-standing, that is, not in, on
|
|
or part of anything else; but it knows nothing of doors. So if we are not
|
|
careful, the source text could put a door on a shelf, or make it part of a
|
|
robot, or something like that. (Testing showed, in fact, that some authors
|
|
actually wanted to do this, though the result was a horribly inconsistent
|
|
model at run-time.) This is where we apply the kill-joy rule in question:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Ensure that no door is present in a room to which it does not connect</span> <span class="cwebmacronumber">37.6</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) != </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_a</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) != </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_b</span><span class="plain">))</span>
|
|
<span class="identifier">Problems::Issue::object_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DoorInThirdRoom</span><span class="plain">),</span>
|
|
<span class="identifier">I</span><span class="plain">, </span><span class="string">"seems to be a door which is present in a room to which it is not connected"</span><span class="plain">,</span>
|
|
<span class="string">"but this is not allowed. A door must be in one or both of the rooms it is "</span>
|
|
<span class="string">"between, but not in a third place altogether."</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37">§37</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_7"></a><b>§37.7. </b>We don't need to do the following for two-sided doors since they will bypass
|
|
the object tree and use I6's <code class="display"><span class="extract">found_in</span></code> to be present in both rooms connecting
|
|
to them.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Place any one-sided door inside the room which connects to it</span> <span class="cwebmacronumber">37.7</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_b</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">PL::Spatial::progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">) == </span><span class="identifier">NULL</span><span class="plain">))</span>
|
|
<span class="functiontext">PL::Spatial::set_progenitor</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_a</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37">§37</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_8"></a><b>§37.8. </b>At this point we know that the doors are correctly plumbed in, and all we
|
|
need to do is compile properties to implement them. See the DM4 for details
|
|
of how to compile one and two-sided doors in I6. Alternatively, take it on
|
|
trust that there is nothing surprising here.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Assert found-in, door-to and door-dir properties for doors</span> <span class="cwebmacronumber">37.8</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">P_door_dir</span><span class="plain"> = </span><span class="identifier">Properties::Valued::new_nameless</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"door_dir"</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
|
|
<span class="identifier">P_door_to</span><span class="plain"> = </span><span class="identifier">Properties::Valued::new_nameless</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"door_to"</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_OBJECT_INSTANCES</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">PL::Map::object_is_a_door</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">)) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">R1</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_a</span><span class="plain">;</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">R2</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_connection_b</span><span class="plain">;</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">D1</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_direction_a</span><span class="plain">;</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">D2</span><span class="plain"> = </span><span class="identifier">PF_I</span><span class="plain">(</span><span class="identifier">map</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">)-</span><span class="element">>map_direction_b</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R1</span><span class="plain"> && </span><span class="identifier">R2</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Assert found-in for a two-sided door</span> <span class="cwebmacronumber">37.8.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Assert door-dir for a two-sided door</span> <span class="cwebmacronumber">37.8.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Assert door-to for a two-sided door</span> <span class="cwebmacronumber">37.8.3</span>><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R1</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Assert door-dir for a one-sided door</span> <span class="cwebmacronumber">37.8.4</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37">§37</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_8_1"></a><b>§37.8.1. </b>Here <code class="display"><span class="extract">found_in</span></code> is a two-entry list.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Assert found-in for a two-sided door</span> <span class="cwebmacronumber">37.8.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="identifier">Packaging::enter</span><span class="plain">(</span><span class="identifier">Instances::package</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">));</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain"> = </span><span class="identifier">Packaging::supply_iname</span><span class="plain">(</span><span class="identifier">Instances::package</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">INLINE_PR_COUNTER</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::named_array_begin</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">Instances::iname</span><span class="plain">(</span><span class="identifier">R1</span><span class="plain">));</span>
|
|
<span class="identifier">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">Instances::iname</span><span class="plain">(</span><span class="identifier">R2</span><span class="plain">));</span>
|
|
<span class="identifier">Emit::array_end</span><span class="plain">();</span>
|
|
<span class="identifier">InterNames::annotate_i</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">INLINE_ARRAY_IANN</span><span class="plain">, 1);</span>
|
|
<span class="functiontext">PL::Map::set_found_in</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">);</span>
|
|
<span class="identifier">Packaging::exit</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37_8">§37.8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_8_2"></a><b>§37.8.2. </b>Here <code class="display"><span class="extract">door_dir</span></code> is a routine looking at the current location and returning
|
|
always the way to the other room — the one we are not in.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Assert door-dir for a two-sided door</span> <span class="cwebmacronumber">37.8.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">door_dir_notice</span><span class="plain"> *</span><span class="identifier">notice</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">door_dir_notice</span><span class="plain">);</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="identifier">Instances::iname</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="identifier">notice</span><span class="plain">-</span><span class="element">>ddn_iname</span><span class="plain"> = </span><span class="identifier">Packaging::function</span><span class="plain">(</span>
|
|
<span class="identifier">InterNames::one_off</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"tsd_door_dir_fn"</span><span class="plain">, </span><span class="identifier">iname</span><span class="plain">-></span><span class="identifier">eventual_owner</span><span class="plain">),</span>
|
|
<span class="identifier">iname</span><span class="plain">-></span><span class="identifier">eventual_owner</span><span class="plain">,</span>
|
|
<span class="identifier">InterNames::new</span><span class="plain">(</span><span class="identifier">TWO_SIDED_DOOR_DOOR_DIR_INAMEF</span><span class="plain">));</span>
|
|
<span class="identifier">InterNames::to_symbol</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">-</span><span class="element">>ddn_iname</span><span class="plain">);</span>
|
|
<span class="identifier">notice</span><span class="plain">-</span><span class="element">>door</span><span class="plain"> = </span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">notice</span><span class="plain">-</span><span class="element">>R1</span><span class="plain"> = </span><span class="identifier">R1</span><span class="plain">;</span>
|
|
<span class="identifier">notice</span><span class="plain">-</span><span class="element">>D1</span><span class="plain"> = </span><span class="identifier">D1</span><span class="plain">;</span>
|
|
<span class="identifier">notice</span><span class="plain">-</span><span class="element">>D2</span><span class="plain"> = </span><span class="identifier">D2</span><span class="plain">;</span>
|
|
<span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">P_door_dir</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">),</span>
|
|
<span class="identifier">Rvalues::from_iname</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">-</span><span class="element">>ddn_iname</span><span class="plain">), </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37_8">§37.8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_8_3"></a><b>§37.8.3. </b>Here <code class="display"><span class="extract">door_to</span></code> is a routine looking at the current location and returning
|
|
always the other room — the one we are not in.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Assert door-to for a two-sided door</span> <span class="cwebmacronumber">37.8.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">door_to_notice</span><span class="plain"> *</span><span class="identifier">notice</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">door_to_notice</span><span class="plain">);</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="identifier">Instances::iname</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="identifier">notice</span><span class="plain">-</span><span class="element">>dtn_iname</span><span class="plain"> = </span><span class="identifier">Packaging::function</span><span class="plain">(</span>
|
|
<span class="identifier">InterNames::one_off</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"tsd_door_to_fn"</span><span class="plain">, </span><span class="identifier">iname</span><span class="plain">-></span><span class="identifier">eventual_owner</span><span class="plain">),</span>
|
|
<span class="identifier">iname</span><span class="plain">-></span><span class="identifier">eventual_owner</span><span class="plain">,</span>
|
|
<span class="identifier">InterNames::new</span><span class="plain">(</span><span class="identifier">TWO_SIDED_DOOR_DOOR_TO_INAMEF</span><span class="plain">));</span>
|
|
<span class="identifier">InterNames::to_symbol</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">-</span><span class="element">>dtn_iname</span><span class="plain">);</span>
|
|
<span class="identifier">notice</span><span class="plain">-</span><span class="element">>door</span><span class="plain"> = </span><span class="identifier">I</span><span class="plain">;</span>
|
|
<span class="identifier">notice</span><span class="plain">-</span><span class="element">>R1</span><span class="plain"> = </span><span class="identifier">R1</span><span class="plain">;</span>
|
|
<span class="identifier">notice</span><span class="plain">-</span><span class="element">>R2</span><span class="plain"> = </span><span class="identifier">R2</span><span class="plain">;</span>
|
|
<span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">P_door_to</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">),</span>
|
|
<span class="identifier">Rvalues::from_iname</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">-</span><span class="element">>dtn_iname</span><span class="plain">), </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37_8">§37.8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37_8_4"></a><b>§37.8.4. </b>The reversal of direction here looks peculiar, but is correct. Suppose
|
|
the Drainage Room contains a one-sided door called the iron grating, and
|
|
the iron grating is east of the Drainage Room. To get through, the player
|
|
will type EAST. But that means the iron grating has one exit, west to the
|
|
Drainage Room; so Inform looks at this exit, reverses west to east, and
|
|
compiles east into the <code class="display"><span class="extract">door_dir</span></code> property.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">As for what lies beyond the iron grating, that's stored in the "other side"
|
|
property for the door; "other side" is an alias for <code class="display"><span class="extract">door_to</span></code>, which is
|
|
why we don't need to compile <code class="display"><span class="extract">door_to</span></code> here.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Assert door-dir for a one-sided door</span> <span class="cwebmacronumber">37.8.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">backwards</span><span class="plain"> = </span><span class="functiontext">PL::Map::get_value_of_opposite_property</span><span class="plain">(</span><span class="identifier">D1</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">backwards</span><span class="plain">)</span>
|
|
<span class="identifier">Properties::Valued::assert</span><span class="plain">(</span><span class="identifier">P_door_dir</span><span class="plain">, </span><span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">),</span>
|
|
<span class="identifier">Rvalues::from_iname</span><span class="plain">(</span><span class="identifier">Instances::emitted_iname</span><span class="plain">(</span><span class="identifier">backwards</span><span class="plain">)), </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP37_8">§37.8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38"></a><b>§38. Redeeming those notices. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Map::write_door_dir_routines</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">door_dir_notice</span><span class="plain"> *</span><span class="identifier">notice</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">, </span><span class="reserved">door_dir_notice</span><span class="plain">) {</span>
|
|
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="identifier">Routines::begin</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">-</span><span class="element">>ddn_iname</span><span class="plain">);</span>
|
|
<span class="identifier">local_variable</span><span class="plain"> *</span><span class="identifier">loc</span><span class="plain"> = </span><span class="identifier">LocalVariables::add_internal_local_c</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"loc"</span><span class="plain">, </span><span class="string">"room of actor"</span><span class="plain">);</span>
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">loc_s</span><span class="plain"> = </span><span class="identifier">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">loc</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">store_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::ref_symbol</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">loc_s</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::val_iname</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">InterNames::extern</span><span class="plain">(</span><span class="identifier">LOCATION_EXNAMEF</span><span class="plain">));</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">if_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">eq_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::val_symbol</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">loc_s</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::val_iname</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">THEDARK_NRL</span><span class="plain">));</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::code</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">store_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::ref_symbol</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">loc_s</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::val_iname</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">InterNames::extern</span><span class="plain">(</span><span class="identifier">REALLOCATION_EXNAMEF</span><span class="plain">));</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">if_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">eq_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::val_symbol</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">loc_s</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::val_iname</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Instances::iname</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">-</span><span class="element">>R1</span><span class="plain">));</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::code</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">return_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::val_iname</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">,</span>
|
|
<span class="identifier">Instances::iname</span><span class="plain">(</span><span class="functiontext">PL::Map::get_value_of_opposite_property</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">-</span><span class="element">>D1</span><span class="plain">)));</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">return_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::val_iname</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">,</span>
|
|
<span class="identifier">Instances::iname</span><span class="plain">(</span><span class="functiontext">PL::Map::get_value_of_opposite_property</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">-</span><span class="element">>D2</span><span class="plain">)));</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
|
|
<span class="identifier">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PL::Map::write_door_to_routines</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">door_to_notice</span><span class="plain"> *</span><span class="identifier">notice</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">, </span><span class="reserved">door_to_notice</span><span class="plain">) {</span>
|
|
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="identifier">Routines::begin</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">-</span><span class="element">>dtn_iname</span><span class="plain">);</span>
|
|
<span class="identifier">local_variable</span><span class="plain"> *</span><span class="identifier">loc</span><span class="plain"> = </span><span class="identifier">LocalVariables::add_internal_local_c</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"loc"</span><span class="plain">, </span><span class="string">"room of actor"</span><span class="plain">);</span>
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">loc_s</span><span class="plain"> = </span><span class="identifier">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">loc</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">store_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::ref_symbol</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">loc_s</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::val_iname</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">InterNames::extern</span><span class="plain">(</span><span class="identifier">LOCATION_EXNAMEF</span><span class="plain">));</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">if_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">eq_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::val_symbol</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">loc_s</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::val_iname</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">THEDARK_NRL</span><span class="plain">));</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::code</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">store_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::ref_symbol</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">loc_s</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::val_iname</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">InterNames::extern</span><span class="plain">(</span><span class="identifier">REALLOCATION_EXNAMEF</span><span class="plain">));</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">if_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">eq_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::val_symbol</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">loc_s</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::val_iname</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Instances::iname</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">-</span><span class="element">>R1</span><span class="plain">));</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::code</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">return_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::val_iname</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Instances::iname</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">-</span><span class="element">>R2</span><span class="plain">));</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
|
|
<span class="identifier">Emit::inv_primitive</span><span class="plain">(</span><span class="identifier">return_interp</span><span class="plain">);</span>
|
|
<span class="identifier">Emit::down</span><span class="plain">();</span>
|
|
<span class="identifier">Emit::val_iname</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Instances::iname</span><span class="plain">(</span><span class="identifier">notice</span><span class="plain">-</span><span class="element">>R1</span><span class="plain">));</span>
|
|
<span class="identifier">Emit::up</span><span class="plain">();</span>
|
|
|
|
<span class="identifier">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::write_door_dir_routines appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function PL::Map::write_door_to_routines appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP39"></a><b>§39. Indexing. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_add_to_World_index</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">O</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">O</span><span class="plain">) && (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">O</span><span class="plain">, </span><span class="identifier">K_room</span><span class="plain">))) {</span>
|
|
<span class="functiontext">PL::SpatialMap::index_room_connections</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">O</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">PL::Map::map_annotate_in_World_index</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">O</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">O</span><span class="plain">) && (</span><span class="identifier">Instances::of_kind</span><span class="plain">(</span><span class="identifier">O</span><span class="plain">, </span><span class="identifier">K_door</span><span class="plain">))) {</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">B</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="functiontext">PL::Map::get_door_data</span><span class="plain">(</span><span class="identifier">O</span><span class="plain">, &</span><span class="identifier">A</span><span class="plain">, &</span><span class="identifier">B</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">A</span><span class="plain">) && (</span><span class="identifier">B</span><span class="plain">)) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" - <i>door to "</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" - <i>one-sided door to "</span><span class="plain">);</span>
|
|
<span class="identifier">instance</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">A</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain"> == </span><span class="identifier">indexing_room</span><span class="plain">) </span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">B</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">X</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain"> = </span><span class="identifier">World::Inferences::get_prop_state</span><span class="plain">(</span>
|
|
<span class="identifier">Instances::as_subject</span><span class="plain">(</span><span class="identifier">O</span><span class="plain">), </span><span class="identifier">P_other_side</span><span class="plain">);</span>
|
|
<span class="identifier">X</span><span class="plain"> = </span><span class="identifier">Rvalues::to_object_instance</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">X</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"nowhere"</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Instances::index_name</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"</i>"</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function PL::Map::map_add_to_World_index is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<p class="endnote">The function PL::Map::map_annotate_in_World_index is used in <a href="#SP8">§8</a>.</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="3-rgn.html">Back to 'Regions'</a></li><li><a href="3-mcr.html">Continue with 'Map Connection Relations'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</body>
|
|
</html>
|
|
|