Import SPIRITWRAK by D. S. Yu
authorJason Self <j@jxself.org>
Mon, 19 Aug 2019 13:46:06 +0000 (06:46 -0700)
committerJason Self <j@jxself.org>
Mon, 19 Aug 2019 13:46:06 +0000 (06:46 -0700)
Release 3

http://mirror.ifarchive.org/if-archive/games/source/inform/spiritw_src.zip

16 files changed:
COPYING [new file with mode: 0644]
README [new file with mode: 0644]
src/ANTHAR.INF [new file with mode: 0644]
src/ARAGAIN.INF [new file with mode: 0644]
src/BORPHEE.INF [new file with mode: 0644]
src/FROSTHAM.INF [new file with mode: 0644]
src/FUBLIO.INF [new file with mode: 0644]
src/GAMBIT2.INF [new file with mode: 0644]
src/GAMBIT3.INF [new file with mode: 0644]
src/GURTH.INF [new file with mode: 0644]
src/MAKESPIR [new file with mode: 0644]
src/MIZNIA.INF [new file with mode: 0644]
src/SPECIAL.INF [new file with mode: 0644]
src/SPIRIT.INF [new file with mode: 0644]
src/SPIRITA.INF [new file with mode: 0644]
src/SUBWAY.INF [new file with mode: 0644]

diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..d159169
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..6d2ba2d
--- /dev/null
+++ b/README
@@ -0,0 +1,20 @@
+This repository contains a copy of SPIRITWRAK by D. S. Yu.
+
+https://ifdb.tads.org/viewgame?id=tqpowvmdoemtooqf
+http://mirror.ifarchive.org/if-archive/games/source/inform/spiritw_src.zip
+
+--
+Copyright (C) 2019 Jason Self <j@jxself.org>
+
+You may copy, redistribute and/or modify this file under the terms of 
+the GNU General Public License as published by the Free Software 
+Foundation, either version 2 of the License, or (at your option) any 
+later version.
+
+This file is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranty of 
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License 
+along with this file. If not, see https://gnu.org/licenses/
diff --git a/src/ANTHAR.INF b/src/ANTHAR.INF
new file mode 100644 (file)
index 0000000..564deca
--- /dev/null
@@ -0,0 +1,2034 @@
+
+! ****************************************************************
+! ANTHAR.INF
+! -- Add-on for SPIRITWRAK
+! (Do not use alone!)
+! ****************************************************************
+
+Object ANTHAR_GUSStop "Entrance to Greater Anthar"
+   with description "You're just west of Greater Anthar on the \
+island nation of Antharia. The bright sunlight \
+seems to make the city streets east of here glitter. \
+A stairway leads down.",
+        name "sunlight" "streets" "glitter" "stairway",
+        d_to ANTHAR_GUSStation,
+        e_to ANTHAR_West, 
+   has light;
+
+Object ANTHAR_West "Anthar West"
+   with description "You are standing in a busy section of \
+West Greater Anthar City. The city seems to thin \
+out to the west. A roadway heads east, \
+the ever-popular Flathead \
+Stadium lies to the northeast, and a pub lies to the \
+south.",
+        name "roadway" "stadium" "pub",
+        w_to ANTHAR_GUSStop,
+        e_to ANTHAR_East,
+        s_to Delbins,
+        in_to Delbins,
+        ne_to Stadium_entrance,
+        cant_go "You walk around the area, take in the local scene, and \
+                 find yourself back here.",
+        before [;
+           Smell:  "You can smell scents of local cooking coming \
+                   from the south.";
+        ],
+   has light;
+
+Object ANTHAR_East "Anthar East"
+   with description "You are standing in a busy section of \
+East Greater Anthar City. The city continues to \
+the west. There is a large odd structure to the \
+east, made mostly of glass. The ever-popular Flathead \
+Stadium lies to the northwest. A short walk down \
+to a waterfront area is to the south.",
+        name "structure" "glass" "stadium" "waterfront",
+        w_to ANTHAR_West,
+        e_to Conservatory_entrance, 
+        s_to ANTHAR_Waterfront,
+        nw_to Stadium_entrance,
+        cant_go "You walk around the area, take in the local scene, and \
+                 find yourself back here.",
+        before [;
+           Smell:  "You smell rather nice floral scents coming \
+                   from the east.";
+        ],
+   has light;
+
+
+Object ANTHAR_Waterfront "Swank Waterfront"
+   with description "A pleasant waterfront walk is your current \
+location. You can see the Great Sea stretching out \
+before you to the south, a breath-taking sight. \
+A rail runs along the south end, preventing \
+an untimely fall into the rock shore below. The \
+city is back to the north.",
+        name "waterfront" "sea" "great" "railing" "rail" "rock" "shore",
+        n_to ANTHAR_East,
+   has light;
+
+Object telescope "viewing telescope" ANTHAR_Waterfront
+   with name "telescope" "viewing" "scope",
+        capacity 1,
+        when_closed "There's a viewing telescope here, attached to the railing.",
+        when_open [ x ;
+              print "There's a viewing telescope here, attached to the \
+railing. One of the lenses seems loose";
+              if (children(self) == 0) ".";
+              else {
+                 print ". Inside you see:^";
+                 x = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
+                 WriteListFrom (child(telescope), x, 1); rtrue;
+              }
+        ],
+        description "A nice tourist toy. Perfect for getting a good view.",
+        before [;
+           Open:  print "You pry loose a lens. ";
+           Close: print "You push the lens back in place. ";
+           Search: 
+              if (self hasnt open) {
+                 print "You take a peak through the telescope";
+                 if (children(self) ~= 0)
+                    " but oddly, there's something blocking your \
+                    view.";
+                 else {
+                 if (random(40)==1)
+                    " and see a ship in the distance! Wait, perhaps not. \
+It's gone.";
+                 " and see a nice expanse of the Great Sea.";
+                 }
+              }
+        ],
+        size 10,
+   has static container openable;
+
+! (Conservatory gardens)
+
+Object Conservatory_entrance "Conservatory Entrance"
+   with description "You stand before the entrance to a large public \
+conservatory. You can enter the greenhouses to the northeast \
+and southeast, or walk back to Anthar to the \
+west.",
+        name "greenhouse" "greenhouses",
+        w_to ANTHAR_East,
+        ne_to Con_Desert_garden,
+        se_to Con_Flower_garden,
+        before [;
+           Smell: "You can smell floral scents from the southeast.";
+        ],
+   has light;
+
+Object Con_Desert_garden "Desert Garden"
+   with description "A nicely arranged collection of desert plants \
+is here in the ~Desert Garden~. Bright sunlight \
+and a sandy ground enhance the overall effect. \
+The conservatory entrance is to the southwest, or \
+more gardens lie to the south and east.",
+        name "sunlight" "plants" "sand" "gardens",
+        sw_to Conservatory_entrance,
+        e_to Con_Forest_garden,
+        s_to Con_Decor_garden, 
+   has light;
+
+
+Object Con_Flower_garden "Flower Garden"
+   with description "A rather lovely flower garden lies before you. \
+The multi-colored flowers are turning the air into \ 
+perfume. The conservatory entrance is northwest, \
+or more greenhouse gardens lie to the north and \
+east. A tiny trail leads south past the flower \
+beds.",
+        name "perfume" "entrance" "trail" "greenhouse",
+        nw_to Conservatory_entrance,
+        e_to Con_Jungle_garden,
+        n_to Con_Decor_garden,
+        s_to Con_storehouse,
+        before [;
+          Smell:  "The bouquet of flowers is quite intoxicating.";
+        ],
+   has light;
+
+Nearby flowers "flowers"
+   with name "flowers" "flower" "garden",
+        description "A lovely assortment of flowers.",
+        before [;
+          Take: "Don't pick the flowers.";
+          Cast: 
+             if (the_spell_was == throck_spell)
+                "Suddenly, a few more flowers spring out of the \
+                ground!";
+        ],
+   has scenery;
+
+Object Con_storehouse "Gardener's Storehouse"
+   with description "This must be a storehouse for the conservatory \
+gardeners. There are soil stains and plant debris all over. \
+The only exit is north.",
+        name "soil" "stains" "debris" "plant",
+        n_to Con_Flower_garden,
+   has light;
+
+Nearby toolshed "toolshed"
+   with name "toolshed" "shed",
+        description "A plain toolshed.",
+        with_key shed_key,
+        capacity 10,
+        size 20,
+        when_closed "A toolshed stands closed against the wall.",
+        when_open [ x;
+         print "The toolshed is open. ";
+         x = children(self);
+         if (x == 0) "It is empty.";
+         print "Inside ";
+         if (x == 1) print "is: "; else print "are: ^";
+         x = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
+         WriteListFrom (child(self), x, 1); 
+         rtrue;
+       ],
+   has static container openable lockable locked;
+
+! (contents of shed)
+Object gardeners_cap "cap" toolshed
+   with name "cap",
+        description "A cap with an odd green emblem stitched on \
+the front that looks like a clover.",
+        size 10,
+   has clothing;
+Object hedge_clipper "hedge clipper" toolshed
+   with name "clipper" "clippers",
+        description "Basically a long pair of scissors.",
+        size 15,
+;
+Object rubber_gloves "rubber gloves" toolshed
+  with name "gloves" "pair" "rubber",
+       article "a pair of",
+       description "A pair of yellow rubber gloves, slightly \
+worn. Good for gardening, or washing dishes, I suppose.",
+       size 10,
+has clothing;
+
+! (cracked -- magic has questionable source, doesn't always work)
+Object p3 "cracked parchment" toolshed
+   class parchment_class,
+   with name "cracked",
+description "~...is true that those who go by the title of \
+'Enchanters' need not wear any holy symbol through which \
+to draw magical power. Indeed, it seems as though the very \
+amulets we must wear are our only link to magical powers \
+at all. Worse yet, the powers are indeed granted from \
+powers above, but the Ancient Ones? I think not. For indeed, \
+I have found places where magic powers will not work, with or \
+without the amulet. Likewise, I have found places where \
+magic works, but praying to the Ancient Ones goes unanswered! \
+What this all...~";
+
+Object Con_Decor_garden "Decorative Plants Garden"
+  with description "\ 
+You are standing in a small well-kept garden. The plots surrounding the \
+paths are filled with a variety of general ground-cover plants, all \
+appropriate for most discerning homeowners. Exits lie north and south.",
+       name "ground-cover" "plots" "flamingo" "tinsel" "ornament",
+       n_to Con_Desert_garden,
+       s_to Con_Flower_Garden,
+  has light;
+
+Object Con_Forest_garden "Forest Garden"
+   with description "A garden path winds through this narrow \
+greenhouse, which is stocked with various forest plants. \
+The path winds back to the west and south.",
+        name "path",
+        w_to Con_Desert_garden,
+        s_to Con_Fountain,
+   has light;
+
+Nearby plants1 "plants"
+   with name "plants" "plant" "tree" "forest",
+        description "You are reminded of a hiking trip you took once.",
+        before [;
+           Cast: 
+              if (the_spell_was == throck_spell)
+                 "The forest seems a bit livelier now.";
+        ],
+   has scenery;
+
+Object Con_Jungle_garden "Jungle Garden"
+   with description "A garden path winds through this \
+long greenhouse, which is filled with plants native to \
+jungle settings. The environment is somewhat \
+humid. The path heads west and north from here.", 
+        name "path" "humid",
+        w_to Con_Flower_garden,
+        n_to Con_Fountain,
+        e_to [;
+          if (waterfall hasnt general)
+             "You can't go that way.";
+          else return Con_Nursery;
+        ],
+        before [;
+           Smell: "You smell flowers to the west.";
+        ],
+   has light;
+
+Nearby plants2 "plants"
+   with name "plants" "plant" "tree" "jungle",
+        description "Reminds you of a picture you once saw of \
+the Miznia jungles.",
+        before [;
+           Cast: 
+              if (the_spell_was == throck_spell)
+                 "The jungle seems a bit livelier now.";
+        ],
+   has scenery;
+
+Object waterfall "small waterfall" Con_Jungle_garden
+   with name "waterfall" "fall" "falls",
+        initial [;
+            if (self hasnt general)
+               print "A nice little waterfall enhances the jungle \
+setting";
+            else 
+               print "A fake waterfall hides a passage";
+            " to the east.";
+        ],
+        description [;
+            print "A small";
+            if (self has general) print " fake";
+            " waterfall drops out of a mock-stucco \
+wall to the east.";
+        ],
+        before [;
+           Pull, Push, Touch, Search, Rub:
+              give self general;
+              "You reach out, expecting to get your hands wet, but \
+              to your surprise, you feel a cloth-like substance. \
+              On closer examination, you realize that the waterfall \
+              is a clever realistic-looking fake, made of cloth \
+              and wood. Stepping around some low plants, you also \
+              notice the waterfall covers a passage east!";
+           ThrownAt:
+              move noun to Con_Jungle_garden;
+              CDefArt(noun); ", to your surprise, literally \
+              bounces off the waterfall, and lands with a thump \
+              nearby.";
+        ],
+   has static;
+
+Object Con_Nursery "Nursery"
+   with description "This small back room is apparently the \
+conservatory nursery. Bits of soil and plant \
+debris are everywhere, along with immature \
+seedling plants. A exit lies west, partially \
+covered by some cloth.",
+         name "soil" "plant" "debris" "seedling" "cloth", 
+        w_to Con_Jungle_garden,
+   has light;
+
+Object smallpot "small flower pot" Con_Nursery
+   with name "pot",
+        description "A small red-ceramic flower pot, \
+ideal for small plants, I suppose.",
+        before [;
+           Push, Take:
+              if ((location == Con_Nursery) && (self hasnt general))  {
+                 give self general;
+                 move shed_key to Con_Nursery;
+                 print "Moving the pot uncovers a small key hidden \
+underneath it.^";
+                 if (action==##Push) rtrue; else rfalse;
+              }
+           LookUnder:
+              if ((location == Con_Nursery) && (self hasnt general))  {
+                 "The pot does appear to be sitting crooked. But \
+                 you can't see whatever is under it.";
+              }
+           Cast:
+              if ((the_spell_was == huncho_spell or luncho_spell) &&
+                  (self hasnt general)) {
+                     give self general;
+                     move shed_key to Con_Nursery;
+                     rfalse;
+                  }                 
+        ],
+        size 15,
+   has container open transparent;
+
+
+Object Con_Fountain "Fountain"
+   with description "A tasteful fountain intercepts a north-south \
+garden trail here.",
+        name "trail",
+        n_to Con_Forest_garden,
+        s_to Con_Jungle_garden,
+        each_turn [;
+          if (random(20) == 1)
+             "^You hear someone whistling nearby, but there doesn't \
+seem to be anyone around.";
+        ],
+   has light;
+
+Nearby fountain "fountain"
+   with name "fountain", 
+        description "A stone basin with a central fountain spout \
+shaped like a fish. There's no water running currently.",
+        before 
+        [ x;
+           Search: 
+              if (self hasnt general) {
+                  give self general;
+              move c3 to self;
+              "You fish in the fountain for a bit and find a coin!";
+              }
+              else {
+                 print "Mostly wet plant debris";
+                 x = children(self);
+                 if (x == 0) 
+                    ", nothing interesting.";
+                 print ". You also notice:^";
+         x = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
+         WriteListFrom (child(self), x, 1); rtrue;
+              }
+           Receive:
+              if (noun has is_coin)
+                 print "Hoping for a little luck, I presume?";
+        ],
+        capacity 10,
+        size 25,
+   has scenery container open;
+
+Object glasses "pair of glasses" Con_Fountain
+   with name "glasses",
+        initial "It looks like someone left their glasses here.",
+        description "Thick lenses and a heavy frame.",
+        before [;
+           Wear: "You put the glasses on for a moment, and it's like \
+                 looking through a fishtank. Deciding \
+                 against continuing your quest without adequate \
+                 vision, you take them off.";
+        ],
+        size 5,
+   has clothing;
+
+Object c3 "coin" class coin_class;
+
+Object shed_key "small key" 
+   with name "key" "small",
+        description "A small metal key.",
+        size 4,
+; 
+
+
+! (Delbin's Pub)
+
+Object Delbins "Delbin's Pub"
+   with description [;
+           print "Delbin's Pub has been a popular food and drink spot in \
+           South Anthar for quite a while. ";
+           if (self hasnt general)
+           print "Usually, you need to \
+           fight off barbarians to find a place to sit. At the moment, \
+           however, the place is unusually quiet. A group of \
+           barbarians seem paralyzed with fear near the back wall, \
+           glancing nervously at the front of the bar.";
+           else print "A group of barbarians \
+           are making a lot of noise nearby.";
+           " The exit is to the north.";
+        ],
+        name "back" "front",
+        number 0,
+        before [;
+          Listen:
+             if (self has general)
+                "The barbarians are a rather noisy bunch.";
+          Go:
+            if ((noun == n_obj) || (noun==out_obj))
+print "Delbin calls out ~Visit us again!~ as you leave.^";
+        ],
+        n_to ANTHAR_West,
+        out_to ANTHAR_West,
+        each_turn [ i ;
+           if (Morgan in Delbins) {
+              i = random(3);
+              if ((i==1) && (Delbins.number == 0)) {
+                Delbins.number = 1;
+                 "^The man in black makes a lightning fast move for the \
+glass of ale, but is countered by an equally fast move by the warrior. \
+~Lose something, thief?~ the woman says. ~No need to get violent, Morgan,~ \
+the thief says.";
+              }
+              if ((i==1) && (Delbins.number == 1)) {
+                Delbins.number = 2;
+                 "^The wizard looks at his companions. ~Say, did I ever \
+show any of you my famous disappearing glass trick?~ He starts to take \
+off his wizard's hat, but the gentleman and ranger stop him. ~Don't \
+even try it, Frobar.~ the woman warrior says.";
+              }
+              if ((i==1) && (Delbins.number == 2)) {
+                Delbins.number = 3;
+                 "^The female ranger fixates on the glass of ale. \
+~Look you two, some of us have better things to do, like fight wars.~ \
+The wizard scowls. ~Oh save it, Morgan.~ he says.";
+              }
+            }
+          ], 
+   has light;
+Nearby barbarians "barbarians"
+   with name "barbarians" "group",
+        description "A group of dirty barbarians. One of them \
+           sees you staring at them, and gives you a dirty look.",
+        life [;
+           default:
+ if (Morgan in Delbins)
+    "The barbarians are somewhat paralyzed with fear at the moment.";
+ else 
+    "The barbarians are far too busy telling rude jokes \
+at the moment.";
+        ],
+   has animate concealed;
+
+Object headdress "headdress" Delbins
+   with name "headdress",
+        initial "A gaudy headdress of some kind is \
+hanging on a nearby wall.",
+        description "A large headdress made of animal fur and colorful \
+bird feathers.",
+        size 15,
+   has clothing;
+
+Object bar "bar" Delbins
+   with name "bar",
+        description "A long flat wood bar that could probably use a \
+washing.",
+        before [;
+           Cast:
+             if (the_spell_was == egdelp_spell) {
+                print "The bar is covered with a waxy film. \
+Delbin notices this and shrugs.";
+             }
+           LetGo:
+             if (noun==ale_glass) {
+                <Take ale_glass>; rtrue; }
+        ],
+   has scenery supporter;
+
+Object ale_glass "glass of ale" bar
+   with name "glass" "ale",
+        description "A small glass filled with an amber liquid.",
+        before [;
+           Take:
+              "You receive cold stares from the three individuals \
+              at the bar. ~Get your own,~ the Ranger says and \
+              pushes you back.";
+           Drink:
+              "You receive cold stares from the three individuals \
+              at the bar. ~Get your own,~ the Thief says and \
+              takes the glass from you before you can bring it \
+              to your lips.";
+           Turn, Push, Pull, Shake:
+              "You receive cold stares from the three individuals \
+              at the bar. ~Get your own,~ the Wizard says and \
+              prevents you."; 
+           ThrownAt:
+              deadflag = 1;
+              CDefArt(noun); " hits the glass and nearly topples it! \
+              A voice from the back of the room says ~Garn! He \
+              nearly ruined a perfectly good glass of ale, he did.~ \
+              The three individuals at the bar turn to you with \
+              angry stares, but before you can respond, some \
+              barbarians pummel you to death for poor bar manners.";
+          Cast:
+             if (the_spell_was == zemdor_spell) {
+                give Delbins general;
+                remove self;
+                Achieved(8);
+                ! set up three NPCs
+                ! -- Morgan, fairly easy
+                move Morgan to Ravine_pass;
+                ! -- Frobar, a little tougher
+                move Frobar to FROBAR_Study;
+                if (Ench_mag in Frobar_mailbox)
+                   move Ench_mag to Frobar;
+                StartDaemon(Frobar);
+                ! -- Thief, trickiest
+                remove Thief;  ! he'll be back
+                if ((Painting_REAL in Museum_north) &&
+                    (glass_wall notin Museum_north))
+                    move Painting_REAL to THIEF_Storeroom;
+                    ! Thief steals painting (no door left behind!)             
+                "You quickly make the zemdor chant and watch the glass \
+of ale start to shimmer! In short time, there are three glasses filled \
+with ale on the bar!^^\
+Morgan the Ranger looks suspiciously at Frobar the Enchanter. \
+~Is this your doing, wizard?~ Frobar shakes his head. ~Surely not, \
+you know I can't do magic anymore.~ He glances briefly in your \
+direction. ~No matter,~ the thief says, and raises a glass. \
+~To the spirit of adventure!~ The three down their glasses quickly. \
+Morgan smiles. ~Now, that's good ale.~ She adjusts her broadsword. \
+~I'm off to the Egreth front. Want to help end a war, Frobar?~ \
+Frobar chuckles. ~Thank you, no. I've got, err, something to do \
+at home,~ he says and quickly leaves. ~Well, then, what about you, \
+thief?~ Morgan asks, and notices that the thief has already slipped \
+away. She shrugs and leaves the bar as well. ~Good hunting!~ Delbin \
+calls after her.";                
+             }
+             if (the_spell_was == huncho_spell or luncho_spell) 
+"You begin the chant, but something about it gets the \
+Enchanter's attention. ~If you have something to say, \
+why don't you share it?~ With a subtle gesture, the Enchanter \
+dispels the chant.";
+        ],
+;
+
+Object rag "dirty rag" bar
+   with name "rag" "dirty",
+        description "A slightly dirty cleaning rag.",
+        !weight 5,
+;
+
+
+! (Flathead stadium)
+
+Object Stadium_entrance "Entrance to Flathead Stadium"
+   with description "Here stands the entrance into the still \
+           popular Flathead Stadium, home to esoteric \
+           sports activities you never fully understood. \
+           Walkways lie southeast and southwest from here, or \
+           you can enter the stadium to the north.",
+        name "stadium" "walkways" "entrance",
+        sw_to ANTHAR_West,
+        se_to ANTHAR_East,
+        n_to Stadium_top,
+        in_to Stadium_top,
+        before [;
+           Listen:  
+       "You can hear the roars of a good crowd from \
+   inside the stadium. Must be playoff season.";
+           Go:
+              if ((noun==n_obj) || (noun==in_obj))
+                print "You walk right into the stadium. The ticket-takers \
+                must be on strike or something.^";
+        ],
+   has light;
+
+! (fake stadium entrance, for "past")
+
+Object Stadium_entrance2 "Entrance to Flathead Stadium"
+   with description "You appear to be in front of Flathead Stadium once \
+again, however something seems different. Even the stadium itself seems \
+dissimilar, newer. Walkways lie southeast and southwest from here, or \
+you can enter the stadium to the north.",
+        name "stadium" "walkways" "entrance",
+        sw_to "A strange feeling compels you to stay.",
+        se_to "A strange feeling compels you to stay.",
+        n_to [;
+            deadflag = 1;
+            "As you head towards the entrance, a mob of crazed fans \
+rushes out of the stadium (~Isn't that Babe Flathead?~ you hear someone \
+scream) and tramples you to death.";
+        ],
+        before [;
+           Listen:  
+              "The place is surprisingly quiet.";
+        ],
+   has light;
+
+
+Object stadium_sign "stadium sign" Stadium_entrance
+   with name "sign",
+        initial "A stadium event sign is pasted to one of the stadium walls here.",
+        description  
+                    "~Today's event:^\
+                       GOLEM FIGHTS!!!^^\
+                       ALL CHALLENGERS WELCOME!!!^\
+                       THREE ROUNDS, THREE BOUTS!^\
+                       BIG CASH FOR THE WINNER!^^\
+                    (All Golems have undefeated records, so^\
+                    only trained golem-wrestlers need apply!)~",
+   has static;
+
+Object stadium_statue "stadium statue" Stadium_entrance
+   with name "statue",
+        initial "A statue depicting the legendary Babe \
+Flathead greets all visitors in front of the stadium.",
+        description 
+           "According to the inscription, this statue honors the legendary Babe Flathead.",
+        before [;
+           LookUnder:
+               if (self has general) 
+                  "Oddly, the statue seems to sit slightly tilted.";
+           Push:
+              if (self has general) {
+                 remove self;
+                 move statue_base to Stadium_entrance;
+                 Achieved(9);
+                 "You give the statue a shove, and it wobbles and falls, \
+breaking into useless dust! A passing sportsfan notices your act \
+of vandalism, and says to a friend, ~Look at that. The guy wins one \
+bout of Golem wrestling, and he thinks he's better than Babe \
+Flathead.~";  
+              }
+              else "The statue seems to be firmly fixed in place.";
+        ],
+   has static;
+
+Object statue_base "square hole" Stadium_entrance2
+   with name "hole" "square",
+        describe "In front of the stadium is a square hole.",
+        description "There's a large square hole in the ground near \
+the front of the stadium.",
+        time_left 0,
+        time_out [;
+!          move stadium_sign to Stadium_entrance;
+!          move stadium_statue to Stadium_entrance;
+          print "^You hear voices behind you, and suddenly, a \
+small crowd of people pass by, pushing a statue.^^\
+~Right there,~ someone shouts, and a few people position the \
+statue into the square hole.";
+          if (children(self) == 0) {
+             print " It fits neatly in place.";
+             remove red_rod_piece;
+          }
+          else {
+             give stadium_statue general;
+             print " It fits, but seems just slightly \
+tilted.";
+          }
+!          remove statue_base;
+!          give Stadium_entrance ~general;
+          Mystical_Cave.number = Mystical_Cave.number + 1;  
+          print "^^~That's perfect,~ you hear a voice say, and \
+the crowd murmurs in agreement. Why, it's Babe Flathead himself! \
+He saunters up towards the statue, which is indeed a good \
+likeness, and starts handing out cigars. ~We'll get to \
+autographs later,~ he says while lighting your cigar as you \
+try to protest. Seconds later, the cigar explodes! You see \
+sparkling stars, which seem to change to purple flashes. You \
+blink.^";
+          PlayerTo(Mystical_Cave);
+        ], 
+        capacity 1,
+        size 15,
+has static container open;     
+
+Object Stadium_top "In Flathead Stadium, upper seats"
+   with description "\
+You are near the top cheap seats of Flathead Stadium. \
+The crowd is busy cheering whatever is going on down on the \
+field. Looking at the field, you see two small dots. The Stadium exit \
+is back south, or you can walk down to the front seats to \
+the north.",
+   name "seats" "crowd" "field" "dots" "fans",
+   s_to Stadium_entrance,
+   n_to Stadium_bottom,
+   d_to Stadium_bottom,
+   e_to "You try to push your way through the fans, but fail.",
+   w_to "You climb over a few seats, but the crowd blocks any \
+         further progress west.",
+   before [;
+       Listen:  "The crowd is deafening.";
+   ],
+has light;
+
+
+Object Stadium_bottom "In Flathead Stadium, lower seats"
+   with description "\
+You are near the good seats in Flathead Stadium. \
+The crowd is busy cheering for the current event on the \
+field. Looking at the field, you see two large dots. The \
+seats continue up and south, or you can walk down to the \
+field below.",
+  name "seats" "crowd" "field" "dots" "fans",
+  s_to Stadium_top,
+  u_to Stadium_top,
+  d_to [;
+     if (burly_man hasnt general)
+"The burly man jumps out of his seat as you try to pass. \ 
+~Hey buddy, I'm saving those seats.~ He points to an entire \
+row of seats below you. ~I've been waiting all season, and \
+I don't want an obstructed view, so look for somewhere else to \
+sit.~ He sits back in his seat.";
+     else return Near_locker_room;
+  ],
+  n_to [;
+     if (burly_man hasnt general)
+"The burly man jumps out of his seat as you try to pass. \ 
+~Hey buddy, I'm saving those seats.~ He points to an entire \
+row of seats below you. ~I've been waiting all season, and \
+I don't want an obstructed view, so look for somewhere else to \
+sit.~ He sits back in his seat.";
+     else return Near_locker_room;
+  ],
+  w_to "You try to push past a couple fans, but the angry looks make you stop.",
+  e_to "You try to push past a couple fans, but the rude looks make you stop.",
+   before [;
+       Listen:  "The crowd is deafening.";
+   ],
+has light;
+
+Object Near_locker_room "Near Locker Room"
+   with description "\
+You are near a locker room under Flathead field. \
+You can enter the locker room to the north, or start the climb back into \
+the roaring crowd to the south.",
+   name "crowd" "field" "fans",
+   s_to Stadium_bottom,
+   u_to Stadium_bottom,
+   n_to Locker_room,
+   each_turn [;
+      if (self hasnt general) {
+         give self general;
+         move pale_scroll to Near_locker_room;
+         "^A couple front row fans are getting a bit boisterous. \
+Several of them throw garbage and paper debris towards the field. \
+You notice something flutter down by your feet.";
+      }
+   ],
+   before [;
+       Listen:  "The crowd is deafening.";
+   ],
+   has light;
+
+Object Locker_room "Locker Room"
+   with description "\
+You are inside a locker room under Flathead field. You can hear the \
+crowds outside. The room is empty. There is an exit \
+to the south, and the entrance to the field is to the north.",
+   name "field" "locker" "lockers",
+   n_to Flathead_field,
+   s_to Near_locker_room,
+   before [;
+       Listen:  "You can hear the crowd outside.";
+   ],
+   has light;
+
+Object Flathead_field "Flathead Field"
+   with description "You're on Flathead field, in front of millions of zany \
+fans, a lifetime dream. Or not. Well, anyway, \
+there's a locker room to the south.",
+   name "field" "fans",
+   s_to [;
+       if (self has general)
+"You head for the showers, but the coach springs out and blocks \
+your way. ~Come on kid, keep your head in the game.~";
+       else return Locker_room;
+   ],
+   each_turn [ i;
+      if (self has general) {
+         i = random(20);
+         if (i == 1) 
+            "^Someone in the crowd yells out, ~Get him a body bag!~ \
+            We assume he was referring to the golem, not you.";
+         if (i == 5)
+            "^The crowd does 'the wave'.";
+         if (i == 7)
+            "^The crowd waves some strange colorful objects. \
+Rather distracting.";
+         if (i == 10)
+            "^Someone in the crowd screams ~Flathead that golem!~";
+      }
+   ],
+   before [;
+       Listen:  "The crowd is deafening.";
+   ],
+   has light;
+
+
+
+
+! ****************
+! People/creatures
+! ****************
+
+Object Christmas_tree_monster "Christmas tree monster" Con_Decor_garden
+   with name "tree" "monster" "Christmas",
+        initial "A Christmas Tree stands in one plot, swaying back and forth.",
+        description "\
+The Christmas Tree monster has obviously seen some good years. It towers \
+above you, wrapped with tinsel that sparkles marvelously. The \
+plastic flamingo ornaments are a rather gaudy touch. Surprisingly, it seems to \
+have taken root in the soil.",
+        each_turn [ i ;
+           i = random(10);
+           if (i==1) 
+"^The Christmas Tree Monster belts out a few bars of 'I'm dreaming \
+of a Black Cavern' arranged by Bing Frozby.";
+           if (i==2)
+"^The Christmas Tree Monster sings a few measures from Berknip's own \
+rendition of 'Silent Night', a rather morbid version.";
+           if (i==3)
+"^The Christmas Tree Monster hums a few notes from 'Dornbeasts \
+Roasting on an Open Pyre'.";
+           if (i==4)
+"^The Christmas Tree Monster whistles a part of 'Frosty the Snow Wight'.";
+           if (i==6)
+"^The Christmas Tree Monster sways in time to 'Let it snow, let it snow, \
+let it snow'.";
+           if (i==8)
+"^The Christmas Tree Monster treats you to an abridged version of \
+Handel's 'Messiah'.";
+        "^The Christmas Tree Monster hums to itself.";  
+        ],
+        before [;
+           Cut:
+              if (hedge_clipper notin player)
+                 "You'll need a gardening implement to do that.";
+              if (self has general)
+                 "The gardener said he'd make you dig for slugs, and \
+                 that doesn't sound too exciting, so let's leave the tree \
+                 alone.";
+              if (self hasnt general) {
+print "You being to clip a few of the lower branches of the Christmas Tree \
+Monster, who bellows in pain!^^\
+Out of nowhere, a short old man appears, wearing full gardener \
+regalia. He drags your hand away from the tree.^^\
+~What are ya trying to do there, kill the thing?~ he says. ";
+                 if ((glasses hasnt moved) || (glasses in Con_Fountain)) {
+                    remove glasses;
+                    remove hedge_clipper;
+"He pulls \
+out a pair of glasses and puts it on. ~Say, I don't know you,~ \
+he says. ~If you want to practice introductory horticulture, do \
+it in someone else's garden!~ He grabs the clippers from your hands \
+and stalks off.";
+                 }
+                 else {
+print "He seems \
+to be squinting at you. ~Who are you sonny?~ he asks. He starts 
+searching his pockets. ~Confound it, lost my glasses again.~ ";
+                    if (gardeners_cap hasnt worn) {
+                       remove hedge_clipper;
+"He squints again, and says, ~Well, whoever you are, the gardens are \
+for looking at, not practicing landscape design!~ He grabs the \
+clippers out of your hands and stalks off.";
+                    }
+                    if (gardeners_cap has worn) {
+                       give self general;
+                       Achieved(10);
+"He looks at you again, and notices your cap. ~You must be one of the \
+new boys. Here, look, I'm not going to show you twice.~ He takes \
+the clippers and delicately clips away several lower branches, all \
+the while singing ~It's beginning to look a lot like Christmas~. \
+He finishes trimming the tree, leaving a nice opening exposing the \
+shrub next to it, and stops singing. ~I'm starting to hate \
+that tune,~ he says under his breath. He hands the clippers back \
+to you and says, ~Now if I catch you doing this wrong again, I'm \
+going to make you dig for slugs, understand?~ He disappears as \
+quickly as he appeared.";
+                   }
+                 }
+              }
+           Cast:
+              "You start chanting, but the tree starts singing \
+              ~Plover the river and frotz the woods~ and you \
+              can't help joining in, ruining your chant.";
+        ],
+        react_before [;
+           Sing:
+              "You song is drowned out by a boisterous chorus \
+              by the tree.";
+        ],
+        life [;
+          Show: 
+             if (noun==toy_volcano)
+                "The tree abruptly stops singing, and seems \
+a trifle flustered for some reason. Moments later, it \
+resumes its chorus.";
+          default: "The tree just keeps on singing.";
+        ],
+   has animate;
+
+! (ok, the bush isn't defined as alive.  But it is...)
+Object dornberry_bush "Dornberry bush" Con_Decor_garden
+   with name "shrub" "bush",
+        initial [; 
+          print "A small shrub sits near and under the Christmas Tree";
+          if (Christmas_tree_monster hasnt general)    
+             ", almost covered by it.";
+          else
+             ".";
+        ],
+        description [;
+                if (self hasnt general)
+"The small shrub looks rather poorly tended. Just a few green leaves \
+distinguish it from the surrounding soil."; 
+                else
+"The small shrub looks quite healthy. A cluster of green leaves and \
+branches make a nice plant. It's still smaller than the tree, though.";
+                ],
+        capacity 1,
+        before [;
+            Cast:
+             if (the_spell_was == throck_spell) {
+                if (Christmas_tree_monster hasnt general)      
+"The shrub seems to shake suddenly! A new leaf grows, searchs for the \
+sunlight, fails, and withers.";
+                if ((Christmas_tree_monster has general) &&
+                    (self hasnt general)) {
+                  give self general;
+                  move dornberries to self;
+"The shrub seems to shake suddenly! A new leaf grows, searchs for the \
+sunlight, and finds it! Another leaf follows, and soon the shrub is \
+sprouting new branches. In the sunlight, flowers appear, and a cycle \
+of missed-out seasons is made-up for in minutes! The shrub is now \
+quite a thriving plant, covered with tiny red fruit.";
+                }
+                if (self has general) 
+                   "The shrub shakes a bit, but the plant remains the \
+                   same. For a Dornberry bush, it's already probably \
+                   the healthiest one you've ever seen.";
+              }
+              Receive:
+                 if (noun ~= dornberries)
+                    "I don't think the shrub can support that.";
+           ],
+   has static supporter;
+
+Object dornberries "bunch of dornberries"
+   with name "dornberries" "berries",
+        description "A bunch of tasty-looking red berries.",
+        !weight 5,
+        size 5,
+   has edible scored;
+
+! (moved here so that it shows up 'last' in room descr)
+Object plaque "plaque" Con_Decor_garden
+   with name "plaque",
+        initial "A small plaque sticks out of the soil near the two plants.",
+        description [;
+        print "The plaque reads:^^";
+        font off;
+print "~CHRISTMAS TREE MONSTER               DORNBERRY BUSH^";
+print "<Jinglebellus Adnauseam>              <Smallus Shrubus>~^";
+        font on;
+        ],
+!          ~CHRISTMAS TREE MONSTER               DORNBERRY BUSH^\
+!         <Jinglebellus Adnauseous>            <Smallus Shrubus>~",
+   has static;
+
+
+! (Characters in Flathead Stadium)
+
+
+Object burly_man "burly man" Stadium_bottom
+   with name "man" "burly",
+        description "A big man who's apparently into sports.",
+        before [;
+  Cast:
+     if ((the_spell_was == foblub_spell) && (self hasnt general)) {
+        give self general;
+        Achieved(11);
+"You begin your sermon. The man starts to tell you to knock \
+it off, but starts to listen with awe. As you finish, the man \
+tries to get up to shake your hand, but realizes he is stuck \
+fast. ~They gotta start cleaning these seats,~ he says.";
+     }
+      if (the_spell_was == espnis_spell) 
+         "You begin a description of the 1700 different kinds of \
+          holy water, but the man seems so enthralled with the \
+          game below, he just isn't paying attention.";
+      ],
+      life [;
+          Show:
+           if (noun==trophy)
+              "~You were amazing pal. Ever think of going pro?~";
+          Ask:
+            if (second=='fight' or 'game' or 'fights')
+               "~It's the three-golem special. One contestant \
+               versus three golems, one after the other. Great \
+               stuff.~";
+          default:
+            "~Give it a rest pal, I'm watching the game.~";
+      ],
+   has animate;
+
+Object coach "tough-looking coach" Locker_room
+   with name "coach",
+        description [;
+print "An old fellow with bushy eyebrows and \
+a gruff demeanor. He's dressed like a sports coach";
+if (trophy in self)
+". You also notice he's holding some sort of trophy.";
+else ".";
+        ],
+        number 1,
+        each_turn [;
+            if (self hasnt general) {
+              if (Flathead_field hasnt general) {
+                 give Flathead_field general;
+print "^The coach looks up and notices you. ~Oh, you must be the \
+replacement,~ he says. He drags you over to the field entrance. \
+~Well, I hoped you're warmed up, cuz you're up.~ He shoves you \
+north. ~Remember, these guys are tough, so give 'em your \
+best stuff.~^";
+                 PlayerTo(Flathead_field);
+              }
+              else {
+                 print "^The coach looks up and notices you. \
+~Where have you been? The ref was about to default \
+it to the golems!~ He shoves you north. ~Now get in there and \
+make me proud.~^";
+                 PlayerTo(Flathead_field);
+              }
+            }
+            if ((self has general) && (coach.number == 1)) {
+               move win_bag to player;
+               coach.number = 2;
+               "^The coach gives you a slap on the back that \
+knocks the wind out of you. ~You did it! I didn't think \
+you had it in you!~ He hands you a small bag. ~Here's the \
+winnings. I went ahead and took out my cut, of course.~^";
+            }  
+        ],
+        life [;
+           ! essentially, the only chances to do 'life' things
+           ! will occur when the coach is lingering around 
+           ! the lockerroom after the match.
+           Attack:
+               "~You want a couple rounds with the old man \
+too? Well, I'm ready.~ For an old coach, he still looks \
+like he's in pretty good shape. You decide against violent \
+action.";
+           Answer: 
+               "The coach merely nods.";
+           Ask:
+               if (second == 'trophy')
+                  "~It's a beauty all right.~";
+               if (second == 'winnings' or 'cut') 
+                  "~It's all there, count it if you want.~";
+               if (second == 'life' or 'game' or 'sport')
+                  "The coach looks momentarily reflective. \
+~Life is all about getting into the game,~ he says. \
+~Remember that, it's not about winning or losing, but \
+giving it your best shot.~";
+           Show:
+             if (noun == cereal1 || 
+                 noun == cereal2 ||
+                 noun == cereal3 ||
+                 noun == cerealbox1 ||
+                 noun == cerealbox2 ||
+                 noun == cerealbox3)
+           "~A bowlful of that each morning is bound to make a \
+champion out of you.~";
+           Order:  
+! *** note2: this seems to contradict documentation,
+! i.e. 'ask coach for trophy' results in noun==trophy and
+!       second==(?)coach or player, not the other way
+!       around.
+               if ((action==##Give) && (noun==trophy) && 
+                   (trophy in self)) {
+                  move trophy to player;
+                  remove self;
+"The coach looks lovingly at the trophy, and then at you. \
+~Fair enough kid, you earned it.~ he says, and gives it \
+to you. ~I've seen a lot of golem-wrestlers in my time, \
+but I gotta say, you're the best golem-wrestler I've ever \
+seen.~ He leaves the locker room to greet his fans.";
+               }
+           default:  "At the moment, it looks like the coach is too busy \
+               writing a Hall of Fame acceptance speech to \
+               pay you much attention.";
+         ],
+         react_before [;
+            Cast:
+              "~What's that you're saying? Speak up, I'm your \
+coach, I'm hear to listen.~";
+         ],
+   has animate transparent;
+
+Object referee "referee" Flathead_field
+   with name "referee" "ref",
+        description "A stout looking man in a funny striped shirt.",
+        each_turn [;
+           if (self hasnt general) {
+              give self general;
+"^The ref blows his whistle and says ~Round 1~. The golem, not \
+needing any encouragement, jumps into the fray.";
+           }
+        ],
+        life [;
+           Attack:
+             "Your opponent is the golem, not the referee.";
+           Ask:
+             if (second == 'time' or 'timeout')
+                "~Sorry, no timeouts!~ the ref says.";
+             if (second == 'foul')
+                "~It looked good to me.~";
+             if (second == 'round') {
+                if (wood_golem in Flathead_field)
+                   "~You're in round 1.~";
+                if (stone_golem in Flathead_field)
+                   "~You're in round 2.~";
+                if (iron_golem in Flathead_field)
+                   "~You're in round 3, the final round.~";
+             }
+           default: "The ref makes some completely \
+bewildering hand signal, that could be an insult, for \
+all you know about wrestling. In any event, nothing happens.";
+        ], 
+        before [;
+           Cast:
+if (the_spell_was == espnis_spell) {
+   deadflag = 1;
+   "You start to relate the advantages of Bingo over Double \
+Fanucci to the ref, and sooner that you can say ~Zounds~, the \
+ref is fast asleep! Unfortunately, the golem takes advantage of \
+this opportunity and breathes poison gas at you! You reflect \
+on this display of poor sportsmanship as you slowly lose \
+consciousness.";
+}
+        ],
+   has animate;
+
+! -- the golems...
+!    In general: To be fair, the golems only have a 1 in 30 chance
+!    of actually hitting.  When they do hit, however, it's pretty
+!    painful.  They also tend to have high HP, although I guess 
+!    theoretically, they could be beaten without spells.
+!    (note: I've tried this with the iron golem and never
+!     succeeded.  The odds are definitely not in the players favor)
+Object wood_golem "dangerous-looking wood golem" Flathead_field
+   with name "golem" "wood",
+        number 20,
+        description "\
+The wood golem stands at about twice your height, an animated statue \
+made completely of wood. He may move like an old cabinet, but \
+watch those hands!",
+        each_turn [ i ;
+           i = random(13);
+           if (i == 13)
+              Player_HP_CUR = Player_HP_CUR - 15;
+           if (Player_HP_CUR <= 0) {
+              deadflag = 1;
+              "^The wood golem jumps forward and flattens you, \
+              which feels similar to getting hit by a falling \
+              redwood tree.";
+           }
+           if (i == 13)
+              "^The golem staggers you with a punch that sends you \
+              reeling!";
+           if (i == 20)  
+"^The wood golem tries to move in for a clinch, and you dance \
+away.";
+           if (i == 10)
+"^The wood golem makes a lumbering swing at your head, and misses!";
+"^The wood golem makes a swipe for you, and misses.";
+        ],
+        before [;
+          Cast:
+            if (the_spell_was == egdelp_spell) {
+               remove self;
+               move stone_golem to Flathead_field;
+"The wood golem is suddenly covered with a waxy buildup! \
+Greatly embarrassed, he turns to call foul, and slips! \
+With a great thud, the golem hits the turf, and knocks \
+himself out cold!^^\
+The ref says ~Knockout!~. The crowd cheers in approval.^^\
+Several dwarves appear and cart the wood golem off. \ 
+Unfortunately, a stone golem soon walks into view!^^\
+The coach yells from the doorway ~You're doing great kid, \
+just hang in there.~^^\
+The ref says ~Round 2!~";
+            }
+        ],
+        life [ i ;
+          Attack:
+            i = random(20);
+            if (i > 10) {
+               wood_golem.number = wood_golem.number - 1;
+               if (wood_golem.number <= 0) {
+               remove self;
+               move stone_golem to Flathead_field;
+"With a thundering blow, you smash the golem into \
+kindling!^^\
+The ref says ~Knockout!~. The crowd cheers in approval.^^\
+Several dwarves appear and cart the wood golem off. \ 
+Unfortunately, a stone golem soon walks into view!^^\
+The coach yells from the doorway ~You're doing great kid, \
+just hang in there.~^^\
+The ref says ~Round 2!~";
+               }
+               else {
+                 print "Good shot! You whack the golem, and splinters fly";
+                 if (wood_golem.number > 10)
+                    ". It didn't seem to slow him down, though.";
+                 else ".";
+               }
+            }
+            "You swing, but miss.";
+        ],      
+   has animate;
+
+Object stone_golem "fierce-looking stone golem" 
+   with name "golem" "stone",
+        number 40,
+        description "\
+The stone golem is quite a towering piece of work. He looks like a crude \
+statue made of animated granite. He probably has all the \
+finesse of a giant boulder, so don't let him pin ya!",
+        each_turn [ i ;
+           i = random(13);
+           if (i == 13)
+              Player_HP_CUR = Player_HP_CUR - 20;
+           if (Player_HP_CUR <= 0) {
+              deadflag = 1;
+              "^The stone golem jumps forward and flattens you, \
+              which feels similar to getting crushed by a giant \
+              boulder.";
+           }
+           if (i == 13)
+              "^The golem hits you with a punch that sends you \
+              reeling!";
+           if (i == 20)  
+              "^The golem jabs with his left, and misses!";
+           "^The golem tries to close, and misses.";
+        ],
+        before [;
+          Cast:
+            if (the_spell_was == tossio_spell) {
+               remove self;
+               move iron_golem to Flathead_field;
+"The golem is suddenly replaced with a pile of steaming \
+linguini alfredo!^^\
+The ref yells ~Takeout!~ The crowd goes wild! \
+Several dwarves appear and serve the pasta to the crowd \
+on platters. Unfortunately, an iron golem soon \
+walks into view! ^^\
+The coach yells out from the safety of the locker room ~Okay kid, drop \
+this golem, and we can celebrate.~^^\
+The ref yells ~Round 3!~";
+            }
+        ],
+        life [ i ;
+          Attack:
+            i = random(20);
+            if (i > 10) {
+               stone_golem.number = stone_golem.number - 1;
+               if (stone_golem.number <= 0) {
+               remove self;
+               move iron_golem to Flathead_field;
+"With a thundering blow, you smash the golem into \
+gravel!^^\
+The ref says ~Knockout!~. The crowd cheers in approval.^^\
+Several dwarves appear and cart the stone golem off. \ 
+Unfortunately, an iron golem soon walks into view!^^\
+The coach yells out from the safety of the locker room ~Okay kid, drop \
+this golem, and we can celebrate.~^^\
+The ref yells ~Round 3!~";
+               }
+               else {
+                 print "Solid blow! Stone chips fly.";
+                 if (stone_golem.number > 10)
+                    ". It didn't seem to slow him down, though.";
+                 else ".";
+               }
+            }
+            "You swing, but miss.";
+        ],      
+   has animate;
+
+Object iron_golem "deadly-looking iron golem" 
+   with name "golem" "iron",
+        number 50,
+        description "\
+The iron golem resembles a huge nightmare made out of iron. \
+Towering at least 30 feet high, this animated iron statue isn't \
+something you'd want to meet in a dark alley, much less \
+in an arena filled with screaming fans.",
+        each_turn [ i ;
+           i = random(13);
+           if (i == 13)
+              Player_HP_CUR = Player_HP_CUR - 30;
+           if (Player_HP_CUR <= 0) {
+              deadflag = 1;
+              "^The iron golem jumps forward and flattens you, \
+              which feels similar to getting mashed by a giant \
+              block of iron. Oww.";
+           }
+           if (i == 13)
+              "^The golem staggers you with a punch that sends you \
+              reeling! That felt quite painful.";
+           if (i == 20)  
+             "^The golem tries to flatten you, and you evade just in time!";
+           "^The golem tries to step on you, and you dodge.";
+        ],
+        before [;
+          Cast:
+            if (the_spell_was == bekdab_spell) {
+               remove self;
+               remove referee;
+               give Flathead_field ~general;
+               give coach general;
+               move trophy to coach;
+               Achieved(12);
+"The golem suddenly develops many unsightly patches of rust. \
+Mortified, the golem calls for his oil trainer, but to no \
+avail! It soon falls apart into several rusty metal pieces!^^\
+The ref calls out ~The winner!~ and holds your hand aloft. \
+The crowd is on its feet! They'd probably be chanting your \
+name, if they knew it.^^\
+Several dwarves appear and drag off the rusty metal plates. \
+The ref explains that the prize money and a championship \
+trophy will be awarded in the \
+locker room, and exits.";
+            }
+        ],
+        life [ i ;
+          Attack:
+            i = random(20);
+            if (i > 10) {
+               iron_golem.number = iron_golem.number - 1;
+               if (iron_golem.number <= 0) {
+               remove self;
+               remove referee;
+               give Flathead_field ~general;
+               give coach general;
+               move trophy to coach;
+               Achieved(12);
+"With a thundering blow, you smash the golem into \
+ball-bearings.^^\
+The ref calls out ~The winner!~ and holds your hand aloft. \
+The crowd is on its feet! They'd probably be chanting your \
+name, if they knew it.^^\
+Several dwarves appear and collect the ball-bearings. \
+The ref explains that the trophy will be awarded in the \
+locker room, and exits.";
+               }
+               else {
+                 print "Solid blow! You make a small dent.";
+                 if (iron_golem.number > 10)
+                    ". It didn't seem to slow him down, though.";
+                 else ".";
+               }
+            }
+            "You swing, but miss.";
+        ],      
+   has animate;
+
+! (Three important NPCs)
+
+Object Morgan "Morgan the Ranger" Delbins
+   with name "ranger" "warrior" "Morgan" "captain" "maiden",
+        number 1,
+        initial [;
+             if (self in Delbins)
+                "There's a warrior-maiden sitting at the bar, her \
+eyes riveted to the glass of ale.";
+             else 
+             "Morgan the Ranger is here.";
+        ],
+        description "She's nearly twice your height, and \
+probably twice your strength too. She's armed and armored in \
+typical military Ranger gear. She gives you the impression of \
+being the type who'd hunt dragons as a hobby -- assuming there were \
+any dragons left to hunt, of course.",
+        each_turn [;
+           if ((self in Ravine_pass) && (Morgan.number == 1)) {
+              Morgan.number = 2;
+              "^The Ranger sees you approach and recognizes you. \
+              ~Well met again, Priest. I have need of your \
+        assistance to end the kobold border war that has been going \
+        on far too long.~ She pauses. ~To the \
+        west and east are two of my lieutenants and their \
+        soldiers, cut off from the rest of us by previous kobold \
+        raids. I have the power to end this war and call a truce, \
+        but to do so, I need \
+        to inform both of my lieutenants to \
+        stop fighting via \
+        windcat message carriers.~ She points to the two windcats \
+        in the wicker cage and the pile of colored flags. \
+        ~The 'red' flags indicate 'attack', the \
+        'blue', truce. When my lieutenants receive the instructions, \
+        they will verify my commands by sending additional messengers \
+        with 'attack' or 'truce' instructions to each other. \
+        Based on the two \
+        received messages, each lieutenant will act accordingly.~ \
+        She slaps you on the back, jolting you to attention. \
+        ~Herein lies my problem, Priest. I know for a fact, that \
+        one of my lieutenants is a traitor, who will \
+        disobey my orders. Any instruction I send to the traitor, \
+        the opposite will be sent by the traitor to my remaining \
+        good lieutenant. The traitor will also take the two orders \
+        he receives and do the opposite, if there is a majority, or \
+        attack outright, if there are messages of 'truce' and 'attack'. \
+        Thankfully, my good lieutenant will faithfully copy my \
+        instructions to the other lieutenant, and will follow orders \
+        received, if there is a majority, or follow a 'truce' if \
+        there are mixed messages. My greatest problem, Priest, is that \
+        I do not know which lieutenant is the traitor! If you \
+        can bring peace once and for all to Southern Egreth, many \
+        will remember your good deeds.~";
+         } 
+        ],
+        life [;
+            Answer:
+               if (special_word == 'hello') {
+                  print "~Hello";
+                  if (Morgan.number == 2)
+                     print " again";
+                  ", priest.~";
+               }
+            Attack, ThrowAt:
+               "She's well-armed and probably dangerous.";
+            Give, Show:
+               "A gracious gesture, perhaps, but she isn't \
+interested.";
+            Kiss:
+               "She nearly splits your skull with the flat of \
+a huge broadsword before you even get close. ~For a man of \
+the cloth, you've got a lot of nerve,~ she says.";
+            Ask:
+               if (((second == 'cat') || (second=='cats') ||
+                    (second == 'windcat') || (second=='windcats')) &&
+                   (Morgan.number == 2))
+                "~Right, the windcats. \
+                The speckled cat will find the lieutenant to the east. \
+                The spotted cat will find the lieutenant to the west.";
+               if (second == 'frobar' or 'wizard' or 'enchanter') {
+                  print "She laughs. ~You've never heard of \
+Frobar, the dullest Enchanter? The Enchanter who was so dull \
+that his fellow wizards forgot to invite him to the last \
+great meeting? This saved him from becoming an amphibian, so \
+perhaps dullness has its virtues";
+                  if (self in Delbins)
+                     ".~ The wizard looks rather insulted. \
+~Oh hush up, Morgan.~ the wizard says.";
+                  else ".~";
+               }
+               if (second == 'thief' or 'gentleman') {
+                  print "She smiles. ~I can't say as I know \
+much about ";
+                  if (self in Delbins)
+                     "this fellow over here,~ she says and \
+gives the gentleman a whack on the back that nearly knocks his \
+teeth out. ~But I hear he's something of a thief.~ ~Nothing \
+of the sort!~ the gentleman protests.";
+                  else 
+                     "that thief fellow. I've been told \
+he has a hideout somewhere, nearly impossible to find.~";
+               }
+               if (second=='kobold' or 'war')
+"~The war wages on, priest, even though the battle was lost \
+long ago, and there were no winners, kobold or man.~";
+               if (second=='dragon' or 'dragons')
+"Morgan becomes momentarily thoughtful. ~Some of the best \
+dragon-hunting I ever did was up in Frostham long ago. \
+Those white frost dragons are quite a vicious lot. Best not \
+to wake a sleeping white dragon unless you have a weapon handy \
+and know how to use it!~";
+            else "~Sorry, I'm not sure about that.~";
+            default: "Morgan the Ranger appears to be \
+thinking important thoughts at the moment.";
+        ],
+        before [;
+            Cast:
+               "~What's that you're mumbling there priest?~";
+        ],
+   has animate female proper;
+
+Object  Frobar "Frobar" Delbins
+ with   name "Frobar" "wizard" "sorcerer" "enchanter",
+        initial [;
+           if (self in Delbins)
+           "There's an old wizard sitting at the bar, his \
+eyes riveted to the glass of ale.";
+           else "Frobar the Enchanter is here.";
+        ],
+        description "A wizardly old figure of a man.",
+        life [;
+         Attack, ThrowAt:
+         "You make a threatening move. The wizard practically yawns! \
+~Just what the world needs, another violent Priest.~ You stop, \
+somewhat embarrassed.";
+         Answer:
+            if (special_word=='hello')
+               "The wizard nods. ~Hello, hello, and all that rubbish.~";
+         Ask:
+            if (self in Delbins)
+               "The wizard is somewhat occupied at the moment.";
+            else {
+               if (second=='magic' or 'mystic') {
+                  print "Frobar scowls. ~Magic? We've seen the last \
+of magic, let me tell you. Does anyone remember what it did \
+for us? Does anyone mention the Enchanters that saved Quendor \
+from certain ruin many a time? Of course not. A bunch of \
+ingrates";
+if (term_paper notin self)
+". I just hope they're teaching the kids at Tech what magic \
+was all about, before we got all this 'new science' stuff everyone's \
+blabbering about.~";                     
+else ".~";
+               }
+               if (second=='golem' or 'golems')
+"Frobar sighs. ~Golems used to be useful, you know. But now, \
+without magic to control them, they go off and get into all \
+sorts of mischief.~";               
+               if (second == 'thief' or 'gentleman') 
+                  "~Some fellow I've had some dealings with \
+in the past. Not a bad chap, but he does like to \
+supplement his income, if you know what I mean. Far \
+too risky a profession for my taste.~";
+               if (second == 'morgan' or 'ranger' or 'warrior')
+                  "~Morgan Grueslayer, top military Ranger \
+in her graduating class, I hear. If she asks you to join \
+her on one of her campaigns, just walk away. All that \
+fighting -- too stressful if you ask me.~";
+               if (second == 'barsap' or 'snaboz')
+!"~I don't even want to talk about it.~";
+"~Don't even get me started.~";
+            }
+         Show:
+            if (self in Delbins)
+               "The wizard is somewhat occupied at the moment.";
+            if (noun == Ench_mag) {
+               move Ench_mag to Frobar;
+               "Frobar snatches the magazine out of your hands. \
+               ~What are you doing with my mail?~ he says, irritated.";
+               }
+            if (noun has is_scroll) 
+               "~A magic scroll, eh? Doesn't do me a lot of good \
+these days.~";
+            if ((noun has is_rod) || (noun has is_sphere)) {
+               print "Frobar looks at ", (the) noun;
+               " for a moment. ~Something \
+more than meets the eye here. Couldn't tell you what, though.~";  
+               } 
+            if (noun==wood_book)
+               "~So, you're a carpenter too?~ Frobar says, somewhat \
+               sarcasticly.";
+            if ((noun==term_paper) && (glossy_scroll in self))
+            {
+               FrobarGetsPaper();
+            }            
+            "~Hmm. Not very interesting.~";                
+
+         Give:
+            if ((noun==term_paper) && (glossy_scroll in self))
+            {
+               if (self notin Delbins)
+               FrobarGetsPaper();
+               else "The wizard pushes your offering aside. \
+~I'm somewhat busy at the moment,~ he says, his eyes glued to \
+the glass of ale.";
+            }            
+            if (noun == Ench_mag) {
+               move Ench_mag to Frobar;
+               "Frobar grabs the magazine. \
+               ~What are you doing with my mail?~ he says, irritated.";
+               }
+            "~No, thank you.~";
+            
+         default: "~I'm rather busy at the moment.~";
+        ],
+        each_turn [ i ;
+            ! Handle Frobar's actions here...ALWAYS CHECK PARENT AND LOCATION
+            
+            if ((self in location) && (player in FROBAR_Bed)) {
+               print "Frobar seems annoyed. ~Get out of my bed!~ he says, \
+               and drags you to your feet. ";
+               <<Exit>>;
+            }
+                         
+            ! Misc housekeeping actions...
+            if (random(3) < 3) {
+            if ((frobar_plant in parent(self)) && (self in location)) 
+                print "^Frobar tends to the plant.^";
+            if (FROBAR_Bed in parent(self) && self in location) 
+                print "^Frobar arranges some quilts on the bed.^";            
+            if (FROBAR_shelves in parent(self) && self in location) 
+                print "^Frobar pulls a book off the shelves, glances through it, and puts it back.^";
+            if (parent(self) == FROBAR_Lounge && self in location) 
+                print "^Frobar dusts the furniture a bit.^";
+            }
+            
+           ! Random self mutterings...
+           i = random(5); 
+           if (self in location && self notin Delbins) {
+              switch(i) {
+              1 : "^Frobar mutters to himself, ~They didn't even invite \
+           me to the Last Enchanter's Guild Meeting.~";
+              2 : "^Frobar mutters to himself, ~Good old dependable Frobar. Bah!~";
+              3 : if (Ench_mag in self)
+                  "^Frobar leafs through a magazine he holds. ~What happened to \
+                  Barsap? Hah! Did they ask me? No, of course not.~";
+                  else
+                  "^Frobar checks his pockets. ~What did I do with this \
+                  month's 'Enchanter Monthly'?~ he muses outloud.";
+              default: rtrue;
+              }
+           }
+        ],
+        daemon [ i j k Mdest Mdir;
+            ! This daemon will only deal with NPC movement...
+            ! (no doors either)
+            if (random(3) ~= 1) rfalse;  ! doesn't always immed. move
+            
+            ! Count the available exits quickly
+            objectloop(i in Compass)
+                if (ZRegion(parent(self).(i.door_dir)) == 1)
+                    k ++;
+            if (k == 0) rtrue;  ! no exits...
+            
+            ! Pick a place to move to.
+            ! In Frobar's case, most of the time he only has one exit.
+            ! Also, we can block the sw exit of home here.
+            if (parent(self) == FROBAR_Foyer) {
+               Mdir = n_obj;
+               Mdest = FROBAR_Parlor;
+               MovePrintNPC(Frobar,Mdest,Mdir);                 
+               rtrue;
+            }   
+                        
+            ! Pick an exit at random and attempt to travel that way
+            j = random(k); k = 0;
+            objectloop(i in Compass) {
+                if (ZRegion(parent(self).(i.door_dir)) == 1) {
+                    k ++;
+                    if (k == j) {              
+                        Mdir = i;          
+                        Mdest = parent(self).(i.door_dir);
+                        MovePrintNPC(Frobar,Mdest,Mdir);  
+                        rtrue;                      
+                    }
+                }
+            }
+        ],
+  has animate proper;
+
+[ FrobarGetsPaper ;
+    Achieved(24);
+    move term_paper to self;
+    move glossy_scroll to player;
+    "Frobar glances over the term paper and his eyes widen. \
+~Wilbur -- why, that's my great nephew!~ He takes the paper and \
+reads. ~So true, so true,~ he mumbles and smiles. ~A fine boy, \
+perhaps he'll become a great man someday, if he stops skipping class. \
+He reminds me of my days at Tech -- all filled with dreams and hopes.~ \
+He pauses, and searches his pockets. ~I even perfected a spell, did \
+you know? Good old loyal, boring Frobar perfected a spell, and, \
+if it hadn't been for that Snaboz show-off who had to go and perfect the \
+izyuk spell, I might have even tried to publish mine.~ He finds a \
+scroll amongst his robes and hands it to you. ~You don't believe me? Here, \
+see for yourself.~";            
+];
+
+Object Thief "thief" Delbins
+   with name "thief" "character" "gentleman",
+        number 1,
+        initial [;
+            if (self in Delbins)
+               "There's a gentleman dressed in black sitting at the \
+bar, his eyes riveted to the glass of ale.";
+        ],
+        description "A lean crafty-looking individual, dressed mostly \
+in black. He seems a bit too scruffy to be a nobleman, but also \
+a bit too distinguished to be a common thug. Probably a thief, I'd \
+guess.",
+        life [;
+         Attack, ThrowAt:
+         "You make a threatening move, but the thief seems to \
+move twice as fast! You find yourself looking at the sharp end \
+of a stiletto. ~I'm too much of a gentleman to harm a Priest,~ \
+the thief says, ~so don't force me to make an exception.~";
+         Answer:
+           if (special_word == 'hello')
+              "The gentleman gives a sharp nod in your direction.";
+         Ask:
+           if (second == 'magistrate')
+"The thief gives you a knowing nod. ~The Aragain magistrate? \
+A honorless cur, if I ever saw one.~";
+           if (second == 'painting')
+"The thief shrugs. ~I hear there's a nice new painting on \
+exhibit at the royal museum. You might want to check it out.~";
+           if (second == 'lock' or 'locks')
+"The thief shrugs. ~Do I look like a locksmith?~";
+
+         Give:
+           if (noun has is_coin || noun==trophy) {
+              move noun to Thief;
+              "Confused, the thief pockets your offering. \
+~Quite generous of you, sir.~ he says.";
+           } 
+
+          default: "The gentleman glances at you with \
+dark suspicious eyes.";
+        ],
+        before [;
+            Cast:
+               "You speak the chant perfectly, but nothing \
+seems to happen! The gentleman smiles and pats his dark cloak, \
+which seems to glow briefly with mystic energy, then fade!";
+        ],
+   has animate;
+
+Object thief_cloak "dark cloak" Thief
+   with name "dark" "cloak",
+        description "A coal-black cloak, which blends into \
+the surrounding shadows.",
+before [;
+            Cast:
+               "You speak the chant perfectly, but nothing \
+seems to happen! The gentleman smiles and pats his dark cloak, \
+which seems to glow briefly with mystic energy, then fade!";
+        ],
+has clothing;        
+
+Object Delbin "Delbin" Delbins
+   with name "Delbin" "bartender" "owner",
+        number 1,
+        initial "Delbin himself is standing behind the bar.",
+        description "Delbin is a stout bald fellow with laughing eyes and \
+a heavy beard. He somehow seems both young and old at the same \
+time.",
+        each_turn [ ;
+           if (random(20) == 1)
+              "^Delbin cleans some glasses behind the bar.";
+        ],
+        react_after [;
+           Take:
+              if (noun == headdress)
+                "~You're welcome to that unsightly thing, sir. \
+Been trying to get rid of it for sometime.~";
+              if (noun == rag)
+                "Delbin give you a curious look, \
+but says nothing.";
+        ],
+        life  
+        [ i ;
+           Attack, Kiss, ThrowAt:  "Leave good old Delbin alone.";
+           Answer:
+              if (special_word == 'hello')
+                 "~Welcome to Delbin's, good sir.~";
+           Give:
+              if (noun has is_coin) {
+                 print "Delbin refuses your offering. \
+~Keep your change, sir. If you're looking for a good tip, \
+I can tell you what I hear.~^^";
+                 <<Ask Delbin 'rumor'>>;
+              }
+              if (noun == rag) {
+move rag to bar;
+"Delbin takes the rag and cleans a spot on the bar, leaving \
+it in a familiar place.";
+              }
+              "Delbin politely refuses.";
+           Show:
+              if (noun == headdress)
+"~There's a good story behind that ugly thing. Maybe if you \
+keep reminding me, I'll remember it.~";
+           print "~A nice ", (name) noun;
+           " you've got yourself there.~";
+           Ask:
+              if (second == 'ale' or 'situation') {
+                 if (Morgan in Delbins) 
+                    "~Quite a situation we've got sir. Those three at \
+the front of the bar all ordered a glass of Special Borphee Ale. Well, \
+with the shutdown of the Brewers Guild in Borphee since the Great \
+Change, I can't keep that particular beverage in stock, but I've got \
+that one left there. Seems none of them's leaving until they decide \
+who gets the ale -- and let me tell you, those three are folks who \
+don't like to be disappointed!~";
+                 "Delbin smiles. ~All out of ale sir. But I suppose \
+ye already knew that?~";
+              }
+              if (second == 'rod')
+                 "Delbin shrugs. ~Sounds vaguely familiar sir, \
+maybe I heard a rumor about it once. Can't really say, though.~";
+              if (second == 'headdress')
+"~There's a good story behind that ugly thing. Maybe if you \
+keep reminding me, I'll remember it.~";
+              if (second == 'rag')
+"~Not much more than a rag, sir.~";
+              if (second == 'minirva')
+                 "~I think that's the name of some old \
+Antharian Sea Goddess. Like a patron saint to sailors, in \
+the old days.~";
+              if (second == 'morgan' or 'warrior' or 'ranger')
+                 "~Morgan Grueslayer's a skilled ranger.~";
+              if (second == 'frobar' or 'wizard' or 'enchanter')
+                 "~Frobar's probably one of the last \
+enchanters around. He's a regular here.~";
+              if (second == 'thief' or 'gentleman')
+                 "~Don't really know that fellow's name. \
+He tips well, though.~";
+              if (second == 'rumor' or 'rumors' or 'story') {
+                 i = random(7);
+                 print "Delbin scratches his ear and says, \
+~Yes, now, what did I hear...~^^";
+                 if (i==1)
+                    "~People tell me this new Flathead king is \
+a fake, plain and simple. Hasn't stopped people from trying to \
+get on his good side, though. Now, I haven't seen the fellow \
+myself, but if you ask me, somebody somewhere is up to no good.~";
+                 if (i==2)
+                    "~They say the kobold war up north is gonna \
+end real soon. I'll believe that when it happens.~";
+                 if (i==3) {
+                    print "~Oh, this one's a good one.";
+                    if (headdress in Delbins)
+                       print " You see that headdress over there? \
+Well, this explorer fellow left it here, along with quite a story. \
+He";
+else print " Some explorer fellow";
+" claimed he found some lost ancient city in the Miznia \
+jungles. Said he made a map to the place, but lost it when bargaining \
+for his life with some jungle natives. I just nodded and let \
+the poor man talk.~";
+                 }
+                 if (i==4)
+                    "~This crazy-looking old fellow stops in \
+the other day. Said that he was a professor, at GUE Tech, but \
+that he was giving that all up! Something about his \
+research going bad, on something he called 'an ethereal gate'. \
+What all of that means, I can't say.~";
+                 if (i==5)
+                    "~Say, you sorta remind me of this other Priest \
+fellow who stopped by here a long long time ago. Delbin \
+never forgets, you know? This fellow, who didn't give a name, \
+told me he was on an important \
+quest for something called -- now what was it -- 'The \
+Rod of the Ancients', or something like that. That \
+mean anything to you?~";
+                 if (i==6) {
+                    print "~An artist friend of mine tells me that \
+this new Leonardo Flathead painting they've recently discovered \
+on display at the Royal Museum has a special secret. They \
+say that Leonardo painted over something else under the canvas, but no one's \
+saying what. They're keeping a watchful eye on it too, just \
+in case curiosity gets the better of some folk. In fact, \
+I hear they've already had a few people trying to steal the \
+thing";
+   if (Thief in Delbins)
+      "!~ The thief suddenly starts to cough, and controls himself.";
+   else "!~";
+                 }
+             ! Add further rumors here...
+                 "Delbin shrugs. ~Guess I'm getting old, \
+nothing comes to mind at the moment. Maybe if you \
+give me a moment, I'll think of something.~";
+              }
+        ],
+        before [;
+           Cast:
+if (the_spell_was == foblub_spell)
+   "You relate a fine sermon to Delbin about spirits -- \
+both the liquid kind and the not-so-liquid kind. Were \
+Delbin sitting rather than standing behind the bar, \
+he might even be glued to his seat by now. ~A fine \
+speech there, reverend.~";
+if (the_spell_was == espnis_spell)
+   "You relate a dull sermon to Delbin about the various \
+types of wood casks used in brewing Mithicus beer. \
+Delbin, being a bartender, is a good listener, and \
+manages to stay awake.";
+        ],
+   has animate proper;
+
+! ****************
+! spells/scrolls
+! ****************
+
+Object musty_scroll "musty scroll" telescope
+  class scroll_class,
+  with name "musty",
+;
+
+Object fiznav_spell "make boat sea-worthy" musty_scroll
+  class spell_class,
+  with name "fiznav",
+       magic [;
+          if (second has animate)
+             "Your chant goes unanswered. It's not intended for \
+              living creatures.";
+          else 
+             "Your chant goes unanswered. It's intended for boats apparently.";
+       ],
+;
+
+Object pale_scroll "pale scroll" 
+  class scroll_class,
+  with name "pale",
+;
+
+Object shazok_spell "call lightning from storm" pale_scroll
+  class spell_class,
+  with name "shazok",
+       magic [;
+             if (second==0 && location==GURTH_Forest) {
+                <<Cast shazok_spell storm1>>;
+             }
+             "Your chant goes unanswered. You need a genuine \
+natural storm, I suppose.";
+       ],
+;
+
+Object glossy_scroll "glossy scroll" Frobar
+   class scroll_class,
+   with name "glossy"
+;
+
+Object feeyuk_spell "allow creature to resist gravity" glossy_scroll
+   class spell_class
+   with name "feeyuk",
+        magic [;
+           if ((second == 0) || (second hasnt animate))
+              "The chant backfires, and your feet feel numb!";
+           if (second == player) {
+              has_resist_gravity = 1;
+              StartTimer(self,75);
+              "You speak the chant in clear tones. Initially, you \
+feel no different. And then, strangely, your back feels better \
+than it has in years, and your step seems lighter!";
+           }
+           CDefArt(second);
+           " is no doubt thankful for the power to resist gravity.";
+        ],
+        time_left 0,
+        time_out [;
+            has_resist_gravity = 0;
+            "You feet feel heavy again."; 
+        ],
+; 
+
+! **********
+! Misc objects
+! **********
+
+Object trophy "trophy"
+   with name "trophy",
+        description "A lovely gold and platinum grail-like trophy that looks \
+          very antique. The letter ~D~ is inscribed on the side. \
+          You notice three odd bumps on the bottom of the circular base.",
+        !weight 20,
+        size 8,
+!        capacity 1,
+!        before [;
+!           Receive:
+!              if (noun hasnt is_sphere)
+!                 "That doesn't seem to fit.";
+!              ! else fancy light tricks
+!        ],
+   has scored;
+! container open transparent;
+
+Object win_bag "bag"
+   with name "bag",
+        description "A small cloth bag.",
+        capacity 50,
+        !weight 10,
+        size 15, 
+   has container open;
+
+Object c20 "coin" win_bag class coin_class;
+Object c21 "coin" win_bag class coin_class;
+Object c22 "coin" win_bag class coin_class;
+Object c23 "coin" win_bag class coin_class;
+Object c24 "coin" win_bag class coin_class;
+Object c25 "coin" win_bag class coin_class;
+Object c26 "coin" win_bag class coin_class;
+Object c27 "coin" win_bag class coin_class;
+Object c28 "coin" win_bag class coin_class;
+Object c29 "coin" win_bag class coin_class;
+!Object c30 "coin" win_bag class coin_class;
+
+   
diff --git a/src/ARAGAIN.INF b/src/ARAGAIN.INF
new file mode 100644 (file)
index 0000000..9c80e1a
--- /dev/null
@@ -0,0 +1,1642 @@
+
+! *******************************************************************
+! ARAGIN.INF
+! -- Add-on for SPIRITWRAK (don't use alone!)
+!    for Aragain city, royal grounds, possibly Barsap's Gambit
+! *******************************************************************
+
+
+Object ARAGAIN_GUSStop "Aragain North"
+   with description "You are just north of the newly \
+built Aragain City. The general vicinity \
+is busy with important-looking people. \
+A stairway goes down here, \
+while a large walkway heads south into Aragain.",
+       name "people" "stairway" "walkway",
+       d_to ARAGAIN_GUSStation,
+       s_to ARAGAIN_Entrance,
+   has light;
+
+Object ARAGAIN_Entrance "Aragain Entrance"
+   with description "Before you is a truly astounding sight. \
+A huge metal gate to the south blocks the entrance into the newly \
+built Aragain Royal Grounds. Worse yet, a seemingly \
+endless line of people stands before the gate. \
+They look like dignitaries, diplomats, or \
+just plain politicians. A walkway heads north.",
+        name "walkway" "pastries",
+        n_to ARAGAIN_GUSStop,
+        s_to ARAGAIN_Entrance_gate,
+        cant_go "The only interesting place seems to be past \
+                that gate.",
+   has light;
+
+Nearby line1 "line"
+   with name "line" "people" "dignitaries" "diplomats" "politicians",
+        description "A god-awful line of well-dressed people. You \
+                    notice that many of them are holding what appear \
+                    to be round pastries of some sort.",
+        life [;
+default: "No one in the line seems to be paying you any attention.";
+        ],
+        before [;
+           Cast:
+              if (the_spell_was == espnis_spell)
+"A few people doze off as you canvass the line. They are \
+quickly replaced by others.";
+        ],
+   has animate concealed;
+
+Object gate_sign "large sign" ARAGAIN_Entrance
+   with initial "There is a large sign bolted to the gate.",
+        name "sign" "large",
+        description [;
+           print "The sign reads:^^\
+~WELCOME TO ARAGAIN!^^\
+As today (and everyday henceforth) has been decreed \
+his royal lordship's birthday, we request that all \
+visitors respect good king Sydney Flathead's wishes \
+and present a cake appropriate for the occasion before \
+entering.";
+           if (self hasnt general) {
+              give self general;
+"~^^Well, that's odd. If memory and Brother \
+TuffBerry's Quendor History lessons serve, the \
+Flathead family died off more than a hundred years \
+ago."; 
+           }
+           else "~"; 
+        ],
+   has static;
+
+Object ARAGAIN_Entrance_gate "huge entrance gate" ARAGAIN_Entrance
+   with name "gate" "entrance",
+        description "A solid steel gate, probably 40 feet tall, \
+complete with spikes at the top and close-set bars.",
+        door_dir [;
+           if (self in ARAGAIN_Entrance)
+               return s_to;
+           else return n_to;
+        ],
+        door_to [;
+           if (self in ARAGAIN_Entrance)
+               return ARAGAIN_Courtyard;
+           else return ARAGAIN_Entrance;
+        ],
+        found_in ARAGAIN_Entrance ARAGAIN_Courtyard,
+        when_open "The massive gate is open.",
+        when_closed "The massive gate is closed.",
+        before [;
+           Open, Push, Pull:
+              if (Entrance_guardian hasnt general)
+                 "The guard shoves you away as you approach the gate. \
+                 He points at the sign. ~No cake, no castle.~";
+           Close:
+              "It must weigh a ton, you can't seem to move it.";
+        ],
+   has static door openable locked;
+
+Object ARAGAIN_Courtyard "Courtyard"
+  with description "You're standing in a lovely courtyard with \
+magnificent topiary designs and real marble walkways. A large \
+gate stands to the north. To the east is a red stone building \
+with spires and columns. To the west is a large flat stone \
+building. To the south is a huge entranceway into what must \
+be the new Royal Palace, which appears to be carved out of the \
+face of a massive mountain.",
+       name "marble" "walkway" "red" "spires" "columns" "flat"
+"entranceway" "mountain" "Palace",
+       n_to ARAGAIN_Entrance_gate,
+       e_to ARAGAIN_Museum,
+       w_to ARAGAIN_Gambit,
+       s_to ARAGAIN_Palace,
+has light;
+
+Nearby topiary "topiary"
+   with name "topiary",
+        description "Cleverly abused shrubs in the shape of giant \
+crowns.",
+   has scenery;
+
+! -- The (rather empty) Royal Museum 
+
+Object ARAGAIN_Museum "Royal Museum"
+   with description "You're in the entrance to a museum. The \
+lighting is rather dim, throwing light shadows all over the \
+walls. There are exhibit rooms to the north and south, or \
+an exit west.",
+   name "lighting" "shadows",
+        w_to ARAGAIN_Courtyard,
+        n_to Museum_north,
+        s_to Museum_south,
+   has light;
+
+Object Museum_north "North Exhibit Room"
+   with description "You are in a small exhibit room designed with \
+dark wood floors and plaster-on-stucco walls. The room is dimly lit by \
+hidden lamps or torches behind recessed wall niches. \
+The exit is south.",
+        name "wood" "plaster" "stucco" "lamps" "torches" "niches",
+        s_to ARAGAIN_Museum,
+        each_turn [;
+          if ((glass_wall in self) && (Thief notin Delbins)) {
+             if (random(10) == 2 or 7)
+                "^You get the odd feeling that there's someone behind \
+you, but when you turn around, you see no one!";
+          }
+        ],
+        before [;
+          Cast:
+if (the_spell_was == huncho_spell or luncho_spell)
+"From nearby, a museum curator walks up and abruptly \
+stops your chant. ~Please don't disturb the other patrons,~ \
+he says and walks off. There doesn't seem to be anyone else \
+around, however.";
+          Blow:
+             if ((noun == whistle) && (glass_wall in self)) {
+                remove glass_wall;
+                print "You produce an extremely high-pitched noise. \
+Suddenly, to the north, a near-invisible wall of glass shatters \
+into a million little shards";
+                if (Thief notin Delbins) {
+                   move Painting_REAL to THIEF_Storeroom;
+                   Painting_REAL.initial = nothing;
+                   move magic_door to Museum_north;
+                   "!^^From out of the shadows, a man dressed \
+in black appears! He performs a half-bow in your direction \
+before deftly prying the painting off the wall! ~I'm a great \
+appreciator of the arts, you understand,~ he says, as with a quick \
+twist of his cape, he melds into the shadows and disappears \
+with the painting!^^As you reflect on the thief's actions, \
+you can't help but notice that he apparently dropped something \
+while making his dramatic exit.";
+                }
+                else "!";
+! -- guards always come and move player to jail room ?
+! -- if thief still in delbins, attempt to get painting is \
+! trapped below, player CANT TAKE IT (as a priest)
+             }
+        ],
+   has light; 
+
+Nearby glass_wall "glass wall"
+   with name "wall" "glass",
+        description "Yes, there's a glass wall covering the \
+north wall, all right. It's exceptionally smooth and transparent.",
+        before [;
+          Attack:
+              "Your blows have no effect, it must be quite thick.";
+        ],
+   has static concealed;
+
+Object Painting_REAL "priceless painting" Museum_north
+   with name "painting",
+        short_name "priceless painting",
+        plural "priceless paintings",
+        initial "There is a priceless painting hanging on the north wall.",
+        description "It's a beautiful oil painting of a dark stormy \
+scene. On the horizon, you can see the edges of mountaintops. Near \
+the top of the painting, two winged figures are carrying a lone \
+individual towards a break in the clouds, where a bright white light \
+seems to emanate.",
+        size 25,
+        before [;
+          Take, Pull, Push, Turn, Attack, Rub, Cut, Touch, Search:
+            if (self in Museum_north) {
+               if (glass_wall in Museum_north)
+ "As you get close to the painting, you find yourself stopped by a \
+nearly-invisible glass wall!";
+               else {
+                  if (action == ##Search)
+                  "You notice a slightly loose part \
+of the canvas in one corner, but the painting is apparently \
+bonded to the wall, which limits your investigation.";
+                  if (action ~= ##Touch)
+                  "You can't seem to move the painting at all. \
+It's somehow bonded to the museum wall!";
+               }
+            }
+            else {
+               if ((action == ##Take) && (self in THIEF_Storeroom) && 
+                   (Painting_FAKE in THIEF_Storeroom))
+                  "They both look so genuine! You can't decide!";
+               if (action == ##Search) {
+                   if ((self in THIEF_Storeroom) && 
+                   (Painting_FAKE in THIEF_Storeroom))
+                   "Search which one? Goodness, you can't decide!";
+                   if (self hasnt general) {
+                      give self general;
+                      move white_scroll to player;
+                      "You notice a slightly loose part \
+of the canvas in one corner. You carefully peel back a part of the \
+canvas from the back and reveal a hidden scroll!";  
+                   }
+               }
+            }
+          Drop:
+            if (location == Museum_north) {
+               ! player returned painting to museum, give him a reward
+               move c4 to player;
+               move self to Museum_north;
+               "A museum curator appears and graciously takes the \
+painting. ~Thank you for recovering this priceless work.~ He \
+gives you a coin. ~The reward. We've been a little short on funds \
+lately.~ The curator somehow attaches the painting to the north wall, \
+and leaves.";               
+            }               
+        ],
+;
+
+Object c4 "coin" class coin_class;
+Object Painting_plaque "plaque" Museum_north
+   with name "plaque",
+        initial [;
+print "A metal plaque is attached to the wall";
+if (Painting_REAL in Museum_north)
+   " next to the painting.";
+else ".";
+        ],
+        description "~ASCENDENCY~   Leonardo Flathead, 777 GUE",
+        before [;
+          Take, Pull, Push, Turn, Attack, Rub, Cut, Touch:
+            if ((self in Museum_north) && (glass_wall in Museum_north))
+ "As you get close to the painting, you find yourself stopped by a \
+nearly-invisible glass wall!";
+        ],
+   has static;
+Object Museum_south "South Exhibit Room"
+   with description "You are in a square exhibit room with \
+wood flooring and plain plaster walls. In the center of the \
+room is an exhibit platform made from a large slab of marble. \
+The room is lit brightly by hidden torches. The exit is north.",
+        name "wood" "plaster" "torches",
+        n_to ARAGAIN_Museum
+   has light;
+
+Nearby museum_dais "platform"
+  with name "platform" "slab" "marble",
+       description "It's a large flat slab of marble, polished \
+smooth, in the center of the floor.",
+       capacity 20,
+  has scenery supporter;
+
+Object TEMPLE_Artifact "flower vase" museum_dais
+   with name "artifact" "vase",
+        initial "There's an ancient wood vase sitting on the marble platform.",
+        description "An extremely narrow short wood vase, possibly for \
+holding long-stemmed flowers. It's clearly of ancient origin, well \
+preserved, with strange carvings and designs \
+of robed figures all over.",
+        capacity 1,
+        before [;
+           Receive:
+              if (noun hasnt is_rod)
+                 "Strangely, it doesn't quite fit.";
+           LetGo:
+              if (self in TEMPLE_1_Opening)
+              "You can't reach the vase, much less the contents of the vase.";
+        ],
+        size 10,
+   has container open;
+
+! -- Okay maze-lovers, you asked for it -- Barsap's Gambit
+
+Object ARAGAIN_Gambit "Warm Room"
+  with description "You are in a long stone room, which is strangely \
+warm. In the very center of the room is a hole, with a ladder \
+down. An outdoor courtyard lies to the east.",
+       name "hole" "courtyard" "ladder",
+       e_to ARAGAIN_Courtyard,
+       d_to GAMBIT_11,
+  has light;
+
+Nearby Gambit_sign "large sign"
+   with initial "There is a large sign posted near the doorway.",
+        name "sign",
+        description "~Welcome to Barsap's Royal Gambit, a \
+delight to entertain all guests to the Aragain Royal Grounds. \
+Please consult your tourbook for rules and regulations regarding \
+this area. His highness, Sydney Flathead, and those in his \
+employ, cannot be held responsible for any accidents or minor
+spills at this location.~",
+   has static;
+
+! (room names -- GAMBIT_XY, where X=level (1,2,3), Y=room #)
+
+
+! -----------------------------------------------------
+! The all-important "CheckGambit" routine.  Called by a 
+! room when a player attempts  to move onto a beam.
+! Various important things need to be passed...
+! RETNS: 0 if cant go, 1 if player fell, 2 if can go
+[ CheckGambit 
+    i   ! niche associated with dir player moving in
+    j   ! niche directly below (if player falls) [0 if lev 3]
+    k   ! 'level' currently on (1, 2 or 3)
+    m   ! (local var)
+   ;
+  ! ** Step one -- check if there's even a beam there at all
+  if (children(i) == 0)
+     return 0;
+  ! ** Step two -- check if the beam is strong enough
+     m = child(i);
+     if (m.number == 99) ! (we have the 'wrong half')
+        m = child(i.counter_niche);
+     if (m.number <= 0) {
+        ! -- nope, beam breaks, we're about to fall
+        ! -- remove broken beam
+        remove child(i); remove child(i.counter_niche);
+        print "As you step onto the wood beam, it breaks with a \
+shuddering crack! ";
+        if (has_resist_gravity == 0) {
+             deadflag = 1;   
+             print "You plummet quickly through the air, ";
+             switch (k) {
+             1: print "pass by two levels of floating cubes and beams, ";
+             2: print "pass by one level of floating cubes and beams, ";
+             }
+             print "and find the bottom of the chamber is filled with \
+ red-hot lava...";
+             return 1;
+        }
+        else {
+           ! -- player will float, but see if there's anything to float to...
+           print "Amazingly, you float downwards like a \
+feather, instead of falling to your death! ";
+           if (k==3) {  ! (j==0) {  on the bottom level
+              deadflag = 1;
+              print "Unfortunately, you float slowly down to \
+the bottom of the chamber, which is filled with red-hot lava.";
+              return 1;
+           }
+           print "You float down towards another network of floating \
+cubes and beams. ";
+           if (children(j) == 0) {  ! no wood beam waiting
+              deadflag = 1;
+              print "You pass between two giant floating cubes, \
+similar to the ones you just left. Sadly, no wood beam seems \
+to connect these particular cubes, and you float downwards ";
+              if (k==1) 
+                print "past yet another level of floating cubes and beams, ";
+              print "to a pit of hot lava.";
+              return 1;
+           }
+           print "You float to another wood beam and your feet \
+land on it, perfectly balanced! ";
+           m = child(j);
+           if (m.number == 99) ! (we have the 'wrong half')
+           m = child(j.counter_niche);
+           if (m.number <= 0) {
+           ! -- beam breaks (again!), player dies
+           ! -- remove broken beam
+           remove child(j); remove child(j.counter_niche);
+           print "Sadly, this wood beam also breaks! You \
+continue to float downwards ";
+           if (k==1)
+              print "past yet another level of floating cubes and beams ";
+           print "into a pit of hot lava.";
+           deadflag = 1;
+           return 1;   
+           }
+           else  {
+             print "^";
+             ! -- beam is ok, decrement strength counter
+             m.number = m.number - 1;
+             ! -- MOVE PLAYER TO NEW BEAM
+             !    set-up new WN_TO and ES_TO
+             if (j.niche_dir == 3 or 4) {
+                WN_TO = parent(j);
+                ES_TO = parent(j.counter_niche);
+             }
+             else {
+                ES_TO = parent(j);
+                WN_TO = parent(j.counter_niche);
+             }
+             !    move to appropriate 'on beam' room
+             !   TODO update beam description....
+             if (j.niche_dir == 2 or 4) {
+                if (k==1)
+                   PlayerTo(GAMBIT_W21);
+                else
+                   PlayerTo(GAMBIT_W31);
+             }
+             else {
+                if (k==1)
+                   PlayerTo(GAMBIT_W22);
+                else
+                   PlayerTo(GAMBIT_W32);
+             }
+             return 1;
+           }
+        }
+     }
+     else {
+        ! -- beam is ok, decrement strength counter
+        m.number = m.number - 1;
+        print "You step gingerly onto the wood beam...^";
+        if (i.niche_dir == 3 or 4) {
+           WN_TO = parent(i);
+           ES_TO = parent(i.counter_niche);
+        }
+        else {
+           ES_TO = parent(i);
+           WN_TO = parent(i.counter_niche);
+        }
+        return 2;
+     }
+]; 
+! -----------------------------------------------------
+
+
+Class Gambit_Room_Lev1_Class
+   with description "You are standing on a large floating white \
+stone cube in a very large underground chamber. The entire place is \
+dimly lit red from somewhere below.",
+        name "white" "stone" "cube" "chamber",
+   has light;
+
+
+Object GAMBIT_11 "On Giant White Cube"
+   with description "As far as you can tell, you are standing on a \
+large white stone cube that somehow floats without visible supports in \
+a terrifyingly large underground chamber. The entire place is \
+dimly lit red from somewhere below. There is a ladder up to a hole \
+high in the ceiling here.",
+        name "white" "stone" "cube" "chamber" "ladder" "hole",
+        u_to ARAGAIN_Gambit,
+        w_to 
+        [ i ;
+          i = CheckGambit(n112,n212,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W1;
+        ],
+        s_to 
+        [ i ;
+          i = CheckGambit(n113,n213,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W2;
+        ],
+   has light;
+
+Object GAMBIT_12 "On Giant White Cube"
+   class Gambit_Room_Lev1_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n124,n224,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W1;
+        ],
+        w_to
+        [ i ;
+          i = CheckGambit(n122,n222,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W1;
+        ],
+        s_to 
+        [ i ;
+          i = CheckGambit(n123,n223,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W2;
+        ],
+;
+
+Object GAMBIT_13 "On Giant White Cube"
+   class Gambit_Room_Lev1_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n134,n234,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W1;
+        ],
+        s_to
+        [ i ;
+          i = CheckGambit(n133,n233,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W2;
+        ],
+;
+
+Object GAMBIT_14 "On Giant White Cube"
+   class Gambit_Room_Lev1_Class
+   with w_to
+        [ i ;
+          i = CheckGambit(n142,n242,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W1;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n141,n241,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W2;
+        ],   
+        s_to 
+        [ i ;
+          i = CheckGambit(n143,n243,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W2;
+        ],   
+;
+
+Object GAMBIT_15 "On Giant White Cube"
+   class Gambit_Room_Lev1_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n154,n254,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W1;
+        ],
+        w_to
+        [ i ;
+          i = CheckGambit(n152,n252,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W1;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n151,n251,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W2;
+        ],   
+        s_to 
+        [ i ;
+          i = CheckGambit(n153,n253,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W2;
+        ],   
+;
+       
+Object GAMBIT_16 "On Giant White Cube"
+   class Gambit_Room_Lev1_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n164,n264,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W1;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n161,n261,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W2;
+        ],   
+        s_to 
+        [ i ;
+          i = CheckGambit(n163,n263,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W2;
+        ],   
+;
+
+Object GAMBIT_17 "On Giant White Cube"
+   class Gambit_Room_Lev1_Class
+   with w_to
+        [ i ;
+          i = CheckGambit(n172,n272,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W1;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n171,n271,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W2;
+        ],   
+;
+
+Object GAMBIT_18 "On Giant White Cube"
+   class Gambit_Room_Lev1_Class
+   with w_to
+        [ i ;
+          i = CheckGambit(n182,n282,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W1;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n181,n281,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W2;
+        ],
+        e_to
+        [ i ;
+          i = CheckGambit(n184,n284,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W1;
+        ],
+;
+
+Object GAMBIT_19 "On Giant White Cube"
+   class Gambit_Room_Lev1_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n194,n294,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W1;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n191,n291,1);
+          if (i ~= 2) return i;
+          else return GAMBIT_W2;
+        ],   
+;
+
+
+! (level 1 niches)
+Object n112 "western niche" GAMBIT_11
+   class niche_class
+   with name "western",
+        counter_niche n124,
+        niche_dir 2,  ! 2 = on western edge of floor
+        ;
+Object n113 "southern niche" GAMBIT_11
+   class niche_class
+   with name "southern",
+        counter_niche n141,
+        niche_dir 3;
+
+Object n124 "eastern niche" GAMBIT_12
+   class niche_class
+   with name "eastern",
+        counter_niche n112,
+        niche_dir 4;
+Object n123 "southern niche" GAMBIT_12
+   class niche_class
+   with name "southern",
+        counter_niche n151,
+        niche_dir 3;
+Object n122 "western niche" GAMBIT_12
+   class niche_class
+   with name "western",
+        counter_niche n134,
+        niche_dir 2;
+
+Object n134 "eastern niche" GAMBIT_13
+   class niche_class
+   with name "eastern",
+        counter_niche n122,
+        niche_dir 4;
+Object n133 "southern niche" GAMBIT_13
+   class niche_class
+   with name "southern",
+        counter_niche n161,
+        niche_dir 3;
+
+Object n141 "northern niche" GAMBIT_14
+   class niche_class
+   with name "northern",
+        counter_niche n113,
+        niche_dir 1;
+Object n142 "western niche" GAMBIT_14
+   class niche_class
+   with name "western",
+        counter_niche n154,
+        niche_dir 2;
+Object n143 "southern niche" GAMBIT_14
+   class niche_class
+   with name "southern",
+        counter_niche n171,
+        niche_dir 3;
+
+Object n151 "northern niche" GAMBIT_15
+   class niche_class
+   with name "northern",
+        counter_niche n123,
+        niche_dir 1;
+Object n154 "eastern niche" GAMBIT_15
+   class niche_class
+   with name "eastern",
+        counter_niche n142,
+        niche_dir 4;
+Object n152 "western niche" GAMBIT_15
+   class niche_class
+   with name "western",
+        counter_niche n164,
+        niche_dir 2;
+Object n153 "southern niche" GAMBIT_15
+   class niche_class
+   with name "southern",
+        counter_niche n181,
+        niche_dir 3;
+
+Object n164 "eastern niche" GAMBIT_16
+   class niche_class
+   with name "eastern",
+        counter_niche n152,
+        niche_dir 4;
+Object n161 "northern niche" GAMBIT_16
+   class niche_class
+   with name "northern",
+        counter_niche n133,
+        niche_dir 1;
+Object n163 "southern niche" GAMBIT_16
+   class niche_class
+   with name "southern",
+        counter_niche n191,
+        niche_dir 3;
+
+Object n171 "northern niche" GAMBIT_17
+   class niche_class
+   with name "northern",
+        counter_niche n143,
+        niche_dir 1;
+Object n172 "western niche" GAMBIT_17
+   class niche_class
+   with name "western",
+        counter_niche n184,
+        niche_dir 2;
+
+Object n181 "northern niche" GAMBIT_18
+   class niche_class
+   with name "northern",
+        counter_niche n153,
+        niche_dir 1;
+Object n182 "western niche" GAMBIT_18
+   class niche_class
+   with name "western",
+        counter_niche n194,
+        niche_dir 2;
+Object n184 "eastern niche" GAMBIT_18
+   class niche_class
+   with name "eastern",
+        counter_niche n172,
+        niche_dir 4;
+
+Object n191 "northern niche" GAMBIT_19
+   class niche_class
+   with name "northern",
+        counter_niche n163,
+        niche_dir 1;
+Object n194 "eastern niche" GAMBIT_19
+   class niche_class
+   with name "eastern",
+        counter_niche n182,
+        niche_dir 4;
+
+! (level 1 initial wood beam layout)
+! wood beam, as two 'halves'
+! (the 'trick' here, is to devise a method of testing for the 
+! correct '.number', without having to constantly update
+! both halves (which, when separated in niches, is impossible)
+! Thus, one half will always have number=99, which indicates
+! 'wrong half to test'.  The other half, which is gained by
+! checking child(self.counter_niche), has the useful .number
+
+! Object e11 "ebony beam" n112 class ebony_beam_class;
+! Object e111 "ebony beam" n124 class ebony_beam_class with number 99;
+Object e12 "ebony beam" n113 class ebony_beam_class;
+Object e121 "ebony beam" n141 class ebony_beam_class with number 99;
+Object e13 "ebony beam" n153 class ebony_beam_class;
+Object e131 "ebony beam" n181 class ebony_beam_class with number 99;
+
+Object p11 "pine beam" n123 class pine_beam_class;
+Object p111 "pine beam" n151 class pine_beam_class with number 99;
+Object p12 "pine beam" n122 class pine_beam_class;
+Object p121 "pine beam" n134 class pine_beam_class with number 99;
+Object p13 "pine beam" n133 class pine_beam_class;
+Object p131 "pine beam" n161 class pine_beam_class with number 99;
+Object p14 "pine beam" n194 class pine_beam_class;
+Object p141 "pine beam" n182 class pine_beam_class with number 99;
+Object p15 "pine beam" n112 class pine_beam_class;
+Object p151 "pine beam" n124 class pine_beam_class with number 99;
+
+! (side note: with balsa beams, 2nd side need not be 99, since 
+! it will always break on the first try, and the default number is 0
+Object b11 "balsa beam" n152 class balsa_beam_class;
+Object b111 "balsa beam" n164 class balsa_beam_class;
+Object b12 "balsa beam" n143 class balsa_beam_class;
+Object b121 "balsa beam" n171 class balsa_beam_class;
+Object b13 "balsa beam" n163 class balsa_beam_class;
+Object b131 "balsa beam" n191 class balsa_beam_class;
+Object b14 "balsa beam" n142 class balsa_beam_class;
+Object b141 "balsa beam" n154 class balsa_beam_class;
+Object b15 "balsa beam" n172 class balsa_beam_class;
+Object b151 "balsa beam" n184 class balsa_beam_class;
+
+               
+! (remaining 2 levels in sep. files)
+Include "gambit2.inf";
+Include "gambit3.inf";
+
+! tricky 'on beam' rooms -- only two for each level
+! change description of fake_beam as appropriate
+Object GAMBIT_W1 "On wood beam"
+   with description "You're walking along a very narrow wood beam that runs \
+east to west into darkness. Below, you can see the dark \
+silhouette of a network of beams and floating cubes. Much \
+farther below you can see a dull red glow.",
+        name "darkness" "network" "silhouette" "cubes" "glow",
+        w_to [; give self ~visited; return WN_TO; ],
+        e_to [; give self ~visited; return ES_TO; ],
+        before [;
+           Jump:
+              "There's barely enough room to walk, much less jump.";
+           Drop:
+              print "Dropping "; DefArt(noun);
+              print " will result in your losing both ";
+              DefArt(noun); 
+              " and probably your balance.";
+        ],
+   has light;
+
+Object GAMBIT_W2 "On wood beam"
+   with description "You're walking along a very narrow wood beam that runs \
+north to south into darkness. Below, you can see the dark \
+silhouette of a network of beams and floating cubes. Much \
+farther below you can see a dull red glow.",
+        name "darkness" "network" "silhouette" "cubes" "glow",
+        n_to [; give self ~visited; return WN_TO; ],
+        s_to [; give self ~visited; return ES_TO; ],
+        before [;
+           Jump:
+              "There's barely enough room to walk, much less jump.";
+           Drop:
+              print "Dropping "; DefArt(noun);
+              print " will result in your losing both ";
+              DefArt(noun); 
+              " and probably your balance.";
+        ],
+   has light;
+
+Object GAMBIT_W21 "On wood beam"
+   with description "You're walking along a very narrow wood beam that runs \
+east to west into darkness. Both above and below, you can see the dark \
+silhouette of a network of beams and floating cubes. \
+Farther below you can see a dull red glow.",
+        name "darkness" "network" "silhouette" "cubes" "glow",
+        w_to [; give self ~visited; return WN_TO; ],
+        e_to [; give self ~visited; return ES_TO; ],
+        before [;
+           Jump:
+              "There's barely enough room to walk, much less jump.";
+           Drop:
+              print "Dropping "; DefArt(noun);
+              print " will result in your losing both ";
+              DefArt(noun); 
+              " and probably your balance.";
+        ],
+   has light;
+
+Object GAMBIT_W22 "On wood beam"
+   with description "You're walking along a very narrow wood beam that runs \
+north to south into darkness. Both above and below, you can see the dark \
+silhouette of a network of beams and floating cubes. \
+Farther below you can see a dull red glow.",
+        name "darkness" "network" "silhouette" "cubes" "glow",
+        n_to [; give self ~visited; return WN_TO; ],
+        s_to [; give self ~visited; return ES_TO; ],
+        before [;
+           Jump:
+              "There's barely enough room to walk, much less jump.";
+           Drop:
+              print "Dropping "; DefArt(noun);
+              print " will result in your losing both ";
+              DefArt(noun); 
+              " and probably your balance.";
+        ],
+   has light;
+
+Object GAMBIT_W31 "On wood beam"
+   with description [;
+     print "You're walking along a very narrow wood beam that runs \
+east to west into darkness. Above you can see a network of floating beams \
+and cubes. Below you can see a red glow";
+     if ((self hasnt general) && (GAMBIT_W32 hasnt general) && 
+         (amulet has worn) && (ES_TO == GAMBIT_37)) {
+        give self general;
+        ".^^Your amulet suddenly gives off a bright flash, then fades!";
+        }
+     else ".";
+],
+        name "darkness" "network" "cubes" "glow",
+        w_to [; give self ~visited; return WN_TO; ],
+        e_to [; give self ~visited; return ES_TO; ],
+        before [;
+           Jump:
+              "There's barely enough room to walk, much less jump.";
+           Drop:
+              print "Dropping "; DefArt(noun);
+              print " will result in your losing both ";
+              DefArt(noun); 
+              " and probably your balance.";
+        ],
+   has light;
+
+Object GAMBIT_W32 "On wood beam"
+   with description [;
+     print "You're walking along a very narrow wood beam that runs \
+north to south into darkness. Above you can see a network of floating beams \
+and cubes. Below you can see a red glow.";
+     if ((self hasnt general) && (GAMBIT_W31 hasnt general) && 
+         (amulet has worn) && (ES_TO == GAMBIT_37)) {
+        give self general;
+        ".^^Your amulet suddenly gives off a bright flash, then fades!";
+        }
+     else ".";
+ ],
+        name "darkness" "network" "cubes" "glow",
+        n_to [; give self ~visited; return WN_TO; ],
+        s_to [; give self ~visited; return ES_TO; ],
+        before [;
+           Jump:
+              "There's barely enough room to walk, much less jump.";
+           Drop:
+              print "Dropping "; DefArt(noun);
+              print " will result in your losing both ";
+              DefArt(noun); 
+              " and probably your balance.";
+        ],
+   has light;
+
+Object fake_beam "wood beam"
+   with name "wood" "beam",
+        description "A long thin wood beam, barely wide enough for \
+        both of your feet.", ! change as appropriate
+        before [;
+           Turn, Search, Rub, LookUnder, Attack, Take, Push, Pull:
+              "You'll have to show me how you intend to do \
+this, since you're standing on the wood beam.";
+        ],
+        found_in GAMBIT_W1 GAMBIT_W2 GAMBIT_W21 GAMBIT_W22
+                 GAMBIT_W31 GAMBIT_W32,
+   has scenery;
+   
+
+
+! -- The Royal Palace, and its strange secret
+
+Object ARAGAIN_Palace "Palace Entrance Hall"
+   with description "A vast hall runs north and south \
+in this massive palace. Royal trappings decorate the walls \
+and ceiling, and red carpet lines the floor. \
+A tremendous open archway exits to the north into some \
+courtyard, while two open solid brass doors mark the \
+entrance south into some audience chamber. Two smaller \
+exits head east and west towards stairways up and down \
+respectively.",
+        name "trappings" "carpet" "archway" "courtyard"
+"brass" "doors",
+        n_to ARAGAIN_Courtyard,
+        s_to Palace_Audience,
+        e_to Palace_office,
+        w_to Palace_Westwing,
+        u_to Palace_office,
+        d_to Palace_Westwing,
+   has light;
+
+Object Palace_Audience "Audience Hall"
+   with description "This is a giant audience hall, equivalent to \
+a large auditorium with a throne on the stage. The hall is \
+filled with luxurious decorations -- red carpeting, expensive \
+chandeliers, sweeping gold-edged drapery. The hall is also \
+currently filled with a large number of dignitaries and \
+important-looking people taking up all the seats. Open brass \
+doors lie to the north.",
+   name "carpeting" "chandeliers" "drapery" "seats" "brass" "doors",
+      n_to ARAGAIN_Palace,
+   has light;
+   
+Nearby audience_people "people"
+   with name "people" "dignitaries" "diplomats",
+        description "Just your average throng of official-looking \
+people. Interestingly, many of them seem to be smeared \
+with flour.",
+        life [;
+           default:  "The audience seems to be too busy waiting \
+for something interesting to happen.";
+        ],
+        before [;
+Cast:
+   if (the_spell_was == foblub_spell)
+      "You give a marvelous sermon on patience. The audience \
+seems glued to their seats, which changes little.";
+   if (the_spell_was == espnis_spell)
+      "You give a rather overdone sermon on patience. A few \
+people in the back rows drop off to sleep.";
+        ],
+   has animate concealed;
+      
+Object throne "throne"
+   with name "throne",
+        description "A large throne.",
+        before [;
+           Enter: "This is no time to be playing king.";
+        ],
+   has scenery enterable;
+
+Object Palace_office "Royal Bedroom"
+   with description "This might have once been a lavish bedroom \
+for royalty. At the moment, it seems like someone has converted \
+it into a private lounge of some sort. A stairway heads down.",
+        name "stairway",
+        d_to ARAGAIN_Palace,
+   has light;
+
+Object cab_key "shiny key" Gov_desk2
+   with name "key" "shiny",
+        !weight 5, 
+        size 5,
+        description "A shiny key.",
+;
+
+Object Palace_cabinet "cabinet" Palace_office
+   with name "cabinet",
+        with_key cab_key,
+        description [;
+           print "A rather new-looking wooden cabinet";
+           if (self has general)
+              ", with a bit of waxy build-up all over it.";
+           else ".";
+        ],
+       when_closed "A wooden cabinet stands against one wall, \
+clearly a new addition to the room.",
+       when_open [ x;
+         print "The wooden cabinet has been opened. ";
+         x = children(self);
+         if (x == 0) "It seems to be empty.";
+         print "It contains:^";
+         ! if (x == 1) print "is "; else print "are:^";
+         x = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
+         WriteListFrom (child(self), x, 1); 
+         rtrue;
+       ],
+       before [;
+          Cast: 
+            if (the_spell_was == egdelp_spell) {
+               give self general;
+               "The cabinet is covered in waxy build-up.";
+            }
+          Open:
+            if ((self hasnt locked) && (self hasnt open)) {
+               print "You give the cabinet a good tug";
+               if (self hasnt general)
+                  ", but the \
+cabinet doors barely budge. The new-looking wood seems \
+to be rather tightly fitted.";
+               else {
+                  give self open;
+                  ". The wax makes the doors open with ease.";  
+               } 
+            }
+       ],
+       size 25,
+       capacity 20,
+   has static container openable lockable locked;
+   
+
+! (warped -- true story of the great battle)
+Object p6 "warped parchment" Palace_cabinet
+   class parchment_class,
+   with name "warped",
+description "~...truth. In fact, the truth too terrible to \
+believe, but believe it I must, for all the evidence I \
+have found indicates that the Ancient Ones went up against \
+the evil elementals and lost! With the Rod in hand, they \
+were defeated by trickery! The Rod was broken and \
+scattered into the world, but can be regained and rejoined \
+by any whose heart and spirit are pure! Did the \
+Ancient Ones forsake the spheres of...~";
+
+
+Object Palace_Westwing "Palace Dungeons"
+   with description "Dark and spooky, the palace dungeons seem \
+empty at the moment. The north portion of the room is sectioned-off \
+by iron bars that form a makeshift cell.",
+   n_to [; <<Enter prison_cell>>; ],
+   u_to ARAGAIN_Palace,
+   has light;
+   
+Nearby prison_cell "prison cell"
+   with name "cell" "bars" "iron",
+       when_open [ x;
+         print "The cell stands open.";
+         x = children(self);
+         if (x == 0) { new_line; rtrue; }
+         print " Inside you notice:^";
+         x = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
+         WriteListFrom (child(self), x, 1); 
+         rtrue;
+       ],
+       when_closed [ x;
+         print "The cell is closed.";
+         x = children(self);
+         if (x == 0) { new_line; rtrue; }
+         print "  Inside you notice:^";
+         x = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
+         WriteListFrom (child(self), x, 1); 
+         rtrue;
+       ],
+        description "A cramped space with a wall of iron bars.",
+        before [;
+        Cast:
+        if (the_spell_was == bekdab_spell) {
+           print "The bars seem to rust a bit";
+           if (self has locked) {
+             give self ~locked;
+             ". You hear a lock mechanism in the cell door break!";
+           }
+           else ".";
+        }
+        Go:
+           if ((noun == s_obj) && (player in prison_cell)) {
+              <Exit prison_cell>; return 2; }
+        ],
+        size 50,
+   has static container openable transparent enterable;   
+   
+
+! *****************
+! Creatures/people
+! *****************
+
+Object Entrance_guardian "Tough-looking Palace guard" ARAGAIN_Entrance
+   with name "guardian" "guard",
+        initial "A tough-looking palace guard is standing by the gate.",
+        description "Typical guard -- big, armed to the teeth, and a \
+sour disposition.",
+        before [;
+           Cast:
+              "The guard stops you in mid-chant by blowing a rather \
+shrill whistle. ~None of that priest mumbo-jumbo on \
+my watch!.~";
+        ],
+        react_before [;
+           Blow:
+              if (noun==whistle)
+"The guard stops you as you are about to blow the whistle. \
+~I blow the whistles around here.~";
+        ],
+        life 
+        [ i ;
+           Attack, ThrowAt:
+              "I'd advise against this. He's probably knows 101 \
+ways to dismember an opponent. \
+Also, he's armed and encased in plate mail.";
+           Ask:
+             if ((noun == 'cake' or 'gate') && (self hasnt general))
+              "~It's pretty simple. Give me a cake, and you get in. \
+That's the rules.~";
+           Show:
+             if ((noun == Baking_Pan) && (cake in Baking_Pan))
+                "~Well, hand it over already.~";
+           Give:
+             ! Now for the fun...
+             if ((noun == Baking_Pan) && (cake notin Baking_Pan))
+                "The guard looks at the pan, and hands it back. \
+~I don't see any cake. What are you, a wise guy or something?~";
+             if ((noun == Baking_Pan) && (cake in Baking_Pan)) {
+                move Baking_Pan to Entrance_guardian;
+                print "The guard grabs the pan, and, to your \
+annoyance, cuts himself a massive slice of cake with his broadsword. \
+The guard takes a bite";
+                ! 1st, check for strange foreign objects
+                objectloop (i in dough) {
+                   if ((i ~= flour) &&
+                       (i ~= sugar_cube) &&
+                       (i ~= baking_powder) &&
+                       (i ~= corbie_egg) &&
+                       (i ~= dornberries) &&
+                       (i ~= butter)) { 
+                   if (i hasnt edible) {
+                   print " and you hear a strange \
+'crunch'. He removes ", (a) i; " from his teeth. ~What's this?~ the \
+guard says, clearly angry. ~I oughta report you to the 'Better \
+Bakers Bureau'.~";  ! hopefully, this will break out of objectloop
+                   }
+                   else {
+                   print ", and chews for a bit. \
+His eyes widen, and he spits the cake out. ~Hey pal, I taste ", (name) i;
+" in this so-called cake of yours! Grues could've done a better job \
+than this!~";
+                   }
+                   }
+                }
+                ! 2nd, check overall quality of cake 
+                if (cake.number ~= 0) {
+                   print ", and chews for a bit. \
+He frowns. ~Sorry pal, this doesn't pass inspection. ";
+                   if (cake.number == 1) 
+                      "It could stand some more cooking.~";
+                   if (cake.number == 2) 
+                      "Did ya burn it or something?~";
+                   if (cake.number == 3) 
+                      "It'd make an okay pancake, though.~";
+                   if (cake.number == 4) 
+                      "It's hard as a rock!~";
+                }
+                ! finally, check that all proper ingredients are there.
+                if ((butter in dough) &&
+                    (sugar_cube in dough) &&
+                    (corbie_egg in dough) &&
+                    (baking_powder in dough) &&
+                    (dornberries in dough) &&
+                    (flour in dough)) { 
+                    ! good cake
+                    give self general;
+                    give ARAGAIN_Entrance_gate open ~locked;
+                    Achieved(4);
+                    ", and smacks \
+his lips. ~Finally, someone who can bake an acceptable cake.~ \
+He unlocks and opens the gate. ~You can pass.~";  
+                }
+                else 
+                  ", and chews for a bit. He seems displeased. \
+~I don't know where you learned to bake, but there's definitely \
+something missing here.~";
+             }
+           default:
+              "The guard is amazingly good at ignoring distractions.";
+        ],
+        each_turn [ i;
+           i = random(25);
+           if (i == 1)
+              "^A couple of dignitaries from Gurth push their way to the \
+front and present a flat object to the guard. The guard frowns. \
+~A fish cake? I don't think so.~ The dignitaries return to the line.";
+           if (i==3)
+              "^The guard paces back and forth.";
+           if (i==5)
+              "^A representative from Borphee steps up and presents \
+a pile of baked dough-bits on a plate to the guard. ~Frobolli cake, eh? \
+Well, this may be popular where you come from, but it ain't popular \
+here.~ The representative walks off.";
+           if (i==7)
+              "^The guard practices his menacing stares.";
+           if (i==8)
+              "^The guard blows his whistle at some people in line.";
+           if (i==9)
+              "^An official presents a nice morgia root pie to the \
+guard. ~A pie?~ the guard says, clearly exasperated. He points at \
+the sign as the official leaves. ~Cakes folks, we're taking C-A-K-E-S.~";
+           if (i==11)
+              "^The guard polishes a spot on his armor.";
+           if (i==13)
+              "^Some dignitary presents the guard with a strange \
+green cake with the words ~EAT ME~ written in frosting. The guard smiles, \
+cuts himself a piece, and suddenly stuffs it into the dignitary's mouth! \
+~You boys are going to have to do better than that,~ he says to the 
+now tiny dignitary, who stalks off.";
+           if (i==15)
+              "^The guard hums a military dirge to himself."; 
+        ],
+has animate;
+
+! -- The evil magistrate
+Object Magistrate "magistrate" Palace_Audience
+    with name "magistrate",
+         initial "There is a royal magistrate here.",
+         description "A rather nasty-looking thin tall fellow with an \
+evil grin.",
+         number 1,
+         life [;
+            Attack, ThrowAt:
+               magroutine1(1); rtrue;
+            Show:
+               if (noun==Gov_ledger && Sydney notin Palace_Audience) {
+                  move Sydney to Palace_Audience;
+                  remove Gov_ledger;
+                  "The Magistrate grabs the ledger and \
+frowns as he reads it. ~Fine, you want a presentation?~ He grabs a \
+young boy who was hiding behind \
+the throne and shoves him forward. ~Presenting his royal \
+Highness, King Sydney Flathead, lost heir to the Flathead monarchy!~ \
+The crowd reaction is somewhat mixed. ~Well, his head does look \
+flat,~ you hear one person say.";
+               }
+               if (noun==cab_key) {
+                  move cab_key to self;
+                  "The magistrate moves with surprising speed and \
+takes the key. ~I was looking for that!~ he says.";
+               }
+               else "~Oh, very interesting.~ he says with heavy \
+sarcasm.";            
+            Give:
+               if (noun==Gov_ledger && Sydney notin Palace_Audience) {
+                  <<Show Gov_ledger Magistrate>>;
+               }
+               if (noun==cab_key) {
+                  move cab_key to self;
+                  "The magistrate takes the key. \
+~I was looking for that!~ he says.";
+               }
+               else "~I have no need for that!~ he says with a sneer.";
+            default: "The magistrate pays you absolutely no attention.";
+         ],
+         react_before [;
+            Cast:
+               if (the_spell_was ~= ledak_spell) {
+               magroutine1(2); rtrue; 
+               }
+         ], 
+         each_turn [ i ;
+         i = random(20);
+             if (Sydney in Palace_Audience) {
+                if (i==1)
+                   "^A diplomat approaches the little boy with a \
+                   document. The Magistrate steps forward and \
+                   stops him. ~Sydney is much too busy to bother \
+                   with that.~ the Magistrate says.";
+             }
+             else {
+                if (i==5)
+                   "^An impatient diplomat shouts out, \
+                   ~Bring out the King!~ The Magistrate smiles \
+                   and says, ~Did anyone make a petition for \
+                   a royal presentation?~ The crowd is silent. \
+                   ~I didn't think so.~";
+             }
+         ],
+ has animate;
+
+! (a short code-space saving routine)
+[ magroutine1 
+   w 
+  ;
+
+  ! remove player's possessions
+  while (child(player) ~= 0) {
+     give child(player) ~worn;
+     move child(player) to Palace_office;
+  }
+  if (w == 1)
+     print "You move quickly, but from nowhere, two royal palace \
+guards appear and wrestle you to the ground. ~Lock this \
+fanatic up!~ ";
+  if (w == 2) 
+     print "You start to chant, but the magistrate has sharp \
+ears, and recognizes your magic! With a quick signal, \
+two royal palace guards appear and wrestle you to the ground. \
+~Lock this babbler up!~ ";
+print "the Magistrate says with a sneer. The guards \
+strip you of your possessions and drag you down to the royal \
+dungeons.^";
+   PlayerTo(prison_cell);
+   give prison_cell ~open locked;
+   rtrue;
+];
+
+
+
+Object Sydney "young child" 
+  with name "child" "boy" "sydney",
+       ! describe "There is a young boy here",
+       description [;
+          print "A little boy dressed in uncomfortable-looking frilly clothes";
+          if (flat_hat in self)
+             ". He's wearing a small red hat."; 
+          else ".";
+       ],
+       before [;
+          Cast:
+             if (the_spell_was == foblub_spell or espnis_spell)
+"The boy seems to miss the subtle nuances of your sermon. All \
+that happens is that now he seems even more nervous than before.";
+       ],
+       life
+       [;
+          Ask, Tell:
+             if (self has general)
+                "Young Sydney Flathead only tucks his head lower and whimpers.";
+             else
+             "Young Sydney Flathead only shrugs.";
+          Answer:
+             if (special_word=='hello' or 'hi') {
+                if (self hasnt general)
+                 "Young Sydney Flathead doesn't respond -- he seems \
+to find you a bit frightening.";
+                else  
+                 "~Hello,~ the young lad says, somewhat shyly.";
+             }
+             "Young Sydney Flathead only stares at you.";
+          Attack, ThrowAt: 
+  give self ~general;
+  deadflag = 1;
+  "The young boy screams in terror as you move to threaten him \
+  (shame on you!). Several guards appear out of nowhere, and club \
+  you to death for attempting regicide.";
+          Give:
+             if (noun==stuffed_toy) {
+                give self general;
+                move stuffed_toy to self;
+                "Tentatively, the boy takes the stuffed toy. You \
+catch the glimpse of a sad smile as he holds it tightly.";
+             }
+             "Young Sydney cowers and shakes his head.";
+          Order:
+             if (action==##Give) {
+                if (noun==flat_hat) {
+                   if (self has general) {
+                      remove Magistrate;
+                      remove self;
+                      move flat_hat to player;
+                      move brown_sphere to player;
+                      "Little Sydney smiles and removes the hat and \
+hands it to you. You notice his head is actually round, and the hat \
+was cleverly hiding this.^^\
+~He's no Flathead!~ someone in the audience hall yells out. A distinct \
+murmur of discontent rises from the crowd. The Magistrate slowly \
+backs away. ~Wait! I can explain!~ the Magistrate \
+starts, but soon runs screaming out of the hall, with several angry diplomats \
+hot on his heels!^^\
+~Thank you, kind sir,~ someone behind you says. You turn around. \
+Little Sydney is happily in the arms of a kindly-looking couple. The woman \
+continues. ~Our son was kidnaped, a little while ago. We've \
+been waiting here, hoping to get him back. You did a very brave thing.~ \
+The man steps forward holding some small object. \
+~A priest fellow, such as yourself, told me a long time \
+ago that one day, someone would help us in our time of need, and that \
+I should give him this.~ He gives you a strange round object. \
+~It's the least we can do.~ he says. The couple leaves the hall, \
+with the little boy laughing in their arms."; 
+                   }
+                   else "Little Sydney shrinks back and holds on to his \
+hat. He stares at you fearfully.";
+                }
+                "Little Sydney shrinks back and stares at you fearfully.";
+             }
+             "Sydney shakes his head fretfully.";
+       ],
+  has animate transparent;
+
+
+
+! *****************
+! scrolls/spells
+! *****************
+
+Object crumpled_scroll "crumpled scroll" Palace_cabinet
+  class scroll_class,
+  with name "crumpled",
+;
+
+Object ledak_spell "detect forgery" crumpled_scroll
+  class spell_class,
+  with name "ledak",
+       magic [;
+            if ((location==Palace_Audience) &&
+                (Sydney in Palace_Audience) &&
+                ((second == 0) || (second == Sydney))) {
+"You notice a soft yellow glow around the young boy. \
+The glow fades."; 
+            }
+            if (second==0)
+               "The place appears to be free of forgeries, at the \
+moment.";
+            else {
+               if (second==player) "You appear to be the geniune thing.";
+               CDefArt(second);
+               " appears to be the genuine thing.";
+            }
+       ],
+;
+
+! ****************
+! Misc objects
+! ****************
+
+Object flat_hat "red hat" Sydney
+   with name "hat" "red",
+        description "A little red hat with no brim. It's unusually \
+flat at the top.",
+        before [;
+          Wear:
+            "It's too small for your head.";
+        ],
+        size 10,
+   has clothing;
+
+Object brown_sphere "brown sphere"
+   class sphere_class,
+   with name "brown",
+        description "A tiny perfect brown sphere, made of some strange \
+unknown metal.",
+;
+
+! THIEF'S magic door
+! Contains an unusual amount of properties...
+Object magic_door "strange door"
+   with name "door" "strange",
+        !weight 20,
+        size 30,
+        description [;
+           print "A small door labeled ~STAIRS~, of all \
+things";
+           if (self hasnt static)
+              ". Oddest of all is the fact that it isn't \
+attached to anything!";
+           else ".";
+        ],
+        door_dir [;
+           if (self has static) {
+              if (location == Skyscraper) return e_to;
+              else return w_to;
+           }
+        ],
+        door_to [;
+           if (self has static) {
+              if (location == Skyscraper) return THIEF_Bottom_of_staircase;
+              else return Skyscraper;
+           }
+        ],
+        found_in [;
+           if (self has static) {
+              if (location == Skyscraper or THIEF_Bottom_of_staircase)
+                 rtrue;
+              else rfalse; 
+           }
+           ! else rtrue????
+        ],
+        describe [;
+           ! we force a describe routine here, rather than use
+           ! when_open/closed due to the results that happen
+           ! after an obj has been moved (which the door will be).
+           if (self hasnt static)
+              "^There's an unattached door lying on the ground here.";
+           else {
+              if (self has open) {
+              print "^There's an open door to the";
+              if (location == Skyscraper) 
+                 " east.";
+              else 
+                 " west.";
+              }
+              else {
+              print "^There's a closed door";
+              if (location == Skyscraper) 
+                 " in the eastern wall.";
+              else 
+                 " to the west.";
+              }
+           }
+        ],
+        time_left 0,
+        time_out [;
+           ! after timeout -- Thief locks the door
+           give self ~open locked;
+           if ((location == THIEF_Bottom_of_staircase) ||
+               (location == THIEF_Ent) ||
+               (location == THIEF_Foyer) ||
+               (location == THIEF_Lounge) ||
+               (location == THIEF_Storeroom)) {
+               print "^Suddenly, out of the shadows springs a \
+gentleman dressed in black! ~How did you get in here!~ he \
+cries. Quicker than lightning, he envelopes you in his dark \
+cape, which seems to fade into shadows, leaving you in...^";
+               PlayerTo(Skyscraper);
+               rtrue;
+           }
+           if (location == Skyscraper)
+              "^Out of the shadows, a gentleman dressed in \
+black appears! He sees the door to the east and seems \
+somewhat annoyed. ~Much too busy for unexpected guests,~ \
+you hear him say as he slips through the door and closes \
+it behind him. Moments later you hear the sound of a lock \
+closing on the other side.^"; 
+        ],
+        before [;
+           Enter:
+              if (self has static) {
+                 if (location == Skyscraper) <<Go e_obj>>;
+                 else <<Go w_obj>>;
+              }
+              else
+                "Since the door doesn't currently lead anywhere, \
+entering it seems pointless.";
+           Open:
+             if (self hasnt static)
+                "The door opens onto...thin air. Without a \
+doorway to attach to, it's not terribly useful, it appears.";
+             if ((self has static) && (self hasnt open) &&
+                 (self hasnt general)) {
+                 give self general;
+                 give self open;
+                 StartTimer(magic_door,15);
+                "The door opens. There's a dark chamber \
+on the other side, which seems all but impossible, given \
+that the wall previously appeared solid!";     
+             } 
+           Close:
+             if (self hasnt static)
+                "You close the door, which at this moment \
+means you turn the movable door to a new angle. Without a \
+doorway to attach to, it's not terribly useful, it seems.";
+           Drop:
+             if (location == Skyscraper) {
+                move self to Skyscraper;
+                give self static;
+                Skyscraper.e_to = magic_door;
+                THIEF_Bottom_of_staircase.w_to = magic_door;
+                "As you drop the door, it leaps off the ground \
+and flies towards the eastern wall! Amazingly, it seems to \
+attach itself to the eastern wall!";
+             }
+        ],
+  has door openable;
+
+
diff --git a/src/BORPHEE.INF b/src/BORPHEE.INF
new file mode 100644 (file)
index 0000000..dd0b71a
--- /dev/null
@@ -0,0 +1,1725 @@
+
+! *************************************************************
+! BORPHEE.INF -- add-on for SPIRITWRAK
+! *************************************************************
+
+! (Single global variable to store progress of 'Trophy room puzzle'
+global trophy_stage = 0;  ! equals 'stage' completed, up to 4(th)
+
+Object BORPHEE_GUSStop "Downtown New Borphee"
+   with description "You're right in the middle of downtown \
+New Borphee -- perhaps the busiest, most crowded \
+city you've ever seen. Huge brand-new buildings \
+and throngs of fast-moving people make the whole \
+scene somewhat surreal. The streets head north to \
+a business district, while a set of stairs here leads \ 
+down.",
+        name "buildings" "throngs" "crowd" "people" "streets" "district"
+"stairs",
+        n_to BORPHEE_BD,
+        d_to BORPHEE_GUSStation,
+        cant_go "You walk around downtown a bit, are appalled by the \
+             sights, and hastily return here.",
+     !   w_to "You walk around downtown a bit, are disturbed by the \
+     !        sights, and hastily return here.",
+   has light;
+
+Object BORPHEE_BD "Business District"
+   with description "You're in a crowded business district filled \
+with busy people. The city thins out a bit to the north, \
+while city streets head west and south. Directly to the east is a \
+building so tall it makes you dizzy just looking at it.",
+        name "building" "crowd" "streets" "people",
+        s_to BORPHEE_GUSStop,
+        n_to BORPHEE_burbs,
+        w_to BORPHEE_CS,
+        e_to Skyscraper,
+        each_turn [;
+           if (self hasnt general) {
+              give self general;
+              move flour_scroll to BORPHEE_BD;
+              "^A number of people rudely brush past you and \
+accidentally knock you down. A kindly old lady helps you \
+to your feet. ~I think you dropped that,~ she says, pointing \
+to a paper object nearby that doesn't seem familiar. She \
+walks off, and is soon lost in the crowd.";
+           }
+        ],
+   has light;
+
+Object BORPHEE_CS "City Streets"
+   with description "You're on some busy side street in New Borphee. \
+There's a crowded walk back east. To the north is the \
+entrance to some sort of open area, with a large open arch.",
+        name "street" "walk" "area",
+        e_to BORPHEE_BD,
+        n_to GUE_Gate,
+   has light;
+
+Nearby fake_arch "arch"
+   with name "open" "arch",
+        description "A large metal and stone arch. You'll have \
+to get closer to see anything more.",
+   has scenery;
+
+Object Skyscraper "Inside Skyscraper"
+   with description "You're inside a gigantic \
+skyscraper. The marble and brass fixtures and trim \
+exude professionalism. There's a small open chamber \
+to the north. City streets are to the west.",
+        name "marble" "brass" "fixtures" "trim" "skyscraper"
+"streets" "chamber",
+        w_to BORPHEE_BD,
+        e_to "You can't go that way.",   ! but later...
+        n_to Elevator,
+        before [;
+            Go:
+                if (noun == n_obj)
+                  print "As you enter the small chamber, metal \
+                       doors suddenly spring forward and close \
+                       behind you!^";
+        ],
+   has light;
+
+Object ss_sign "sign" Skyscraper
+   with initial "There is a large sign posted near the small chamber.",
+        name "sign",
+        description [;
+           print "The sign reads:^^\
+~ELEVATOR UNDER CONSTRUCTION^PLEASE USE STAIRS.";
+           if ((self hasnt general) && (magic_door notin Skyscraper)) {
+              give self general;
+           "~^^Oddly, there don't seem to be any stairs."; 
+           }
+           else "~"; 
+        ],
+   has static;
+
+Object Elevator "Inside Elevator"
+   with description "You are inside a cramped metal room, with \
+featureless walls. There are no obvious exits.",
+        s_to "The doors seem to be closed tight.",
+        each_turn [;
+           if (random(20) == 1) {
+              print "^Suddenly, the doors spring open! You \
+dive out.";
+              PlayerTo(SkyScraper);
+              rtrue;
+           }
+        ],
+;   
+
+Object elevator_sign "sign" Elevator
+   with name "sign",
+        initial "There's a small paper sign attached to a wall.",
+        description "~Shep:^^Put the elevator buttons _here_.^^-T~",
+   has static;
+
+! (Not real doors, of course)
+!Object elevator_doors "doors" Elevator
+!   with name "doors" "door",
+!        description "Solid-looking metal sliding doors.",
+!        before [;
+!            Push, Pull, Open: 
+!              "Try as you might, the doors are shut fast.";
+!            Close:
+!              "They appear to already be closed.";
+!        ],
+!   has scenery;
+Object BORPHEE_burbs "Suburbs"
+   with description "A suburb starts here, in contrast to the start \
+of a big downtown to the south. For a residential area, \
+it's surprisingly crowded. A main street runs \
+north-south here.",
+        name "suburb" "downtown" "street",
+        n_to BORPHEE_Outskirts,
+        s_to BORPHEE_BD,
+   has light;
+
+Object BORPHEE_Outskirts "Outskirts"
+   with description "New Borphee stops here, although it probably \
+won't for long. A rough trail leads off into some \
+woods to the northwest, or you can enter the city to \
+the south.",
+        name "trail" "woods" "city",
+        s_to BORPHEE_burbs,
+        nw_to BORPHEE_forest,
+        ne_to "Accardi-By-The-Sea is closed to visitors these days.",
+   has light;
+
+Object BORPHEE_forest "Forest"
+   with description "Deep forest surrounds you. A rough trail runs \
+north and southeast.",
+        name "forest" "trail",
+        se_to BORPHEE_Outskirts,
+        n_to Over_river,
+   has light;
+
+Object Over_river "Over River"
+   with description "You're on a nice new bridge crossing some \
+large river below. Trails lead north and south into \
+woods.",
+        name "bridge" "trails" "woods",
+        n_to Forest_trail,
+        s_to BORPHEE_forest,
+        before [;
+          Jump:  "Bridge-jumping carries a stiff fine around here.";
+        ],
+   has light;
+
+Object c5 "coin" Over_river class coin_class;
+
+Object Phee_river "river" Over_river
+   with name "river" "Phee",
+        description "Just a large east-west river.",
+        before [;
+           Receive:
+             remove noun;
+             print "You drop "; DefArt(noun); " into the river and \
+                    watch it disappear.";
+           Search, LetGo, Rub, Take, Push, Pull, Touch, Squeeze, Turn, Shake:
+"The river is far below the bridge.";
+        ],
+   has scenery container;
+
+Object Forest_trail "Forest Trail"
+   with description "A beaten trail cuts through some very dense \
+forest running north and south.",
+   name "trail" "forest",
+      s_to Over_river,
+      n_to Ravine_pass,
+  has light;
+  
+Object Ravine_pass "Ravine Pass"
+   with description "A forest ravine opens into some sort of clearing \
+to the north here, or a trail heads south.",
+   name "ravine" "forest" "clearing" "trail",
+      s_to Forest_trail,
+      n_to [;
+        if (army in self)
+           "The group of soldiers won't let you pass.";
+        else return Forest_clearing;
+      ],
+   has light;
+   
+Nearby army "group of soldiers"
+   with name "group" "soldiers" "army",
+        description "A group of well-armed soldiers, who look a little \
+        haggard.",
+        life [;
+           Attack: "Forget it.";
+           default: "The soldiers are a little too weary to pay you any \
+direct attention at the moment.";
+        ],
+   has animate;
+
+! (A rather mangled version of the Byzantine Generals Problem)
+! (actually, completely different -- i.e., the BGP is unsolvable
+!  with three armies...)
+
+Object wicker_cage "wicker cage" Ravine_pass
+   with name "cage" "wicker",
+        description "A wicker cage, with two compartments, and a lever \
+attached to the front.",
+        capacity 3,
+        size 20,
+        before [;
+          Open: 
+            "You can't seem to pry open the cage door by hand.";
+        ],
+        add_to_scope cage_lever,
+   has static container transparent;
+
+Object cage_lever "lever"
+   with name "lever",
+        description "A wooden lever attached to the cage.",
+        before [;
+           Pull:
+             if (Morgan in Delbins)
+                "A soldier slaps your hand away. ~That windcat \
+                messenger box belongs to our Captain, \
+                Morgan Grueslayer, so don't mess with it!~";
+             if (Morgan notin Ravine_pass)
+                "You pull the lever and watch the cage door \
+                momentarily open, then shut.";  
+             if ((children(E_windcat) == 0) || (children(W_windcat) == 0))
+                "Morgan stops you and points at the windcats. ~An \
+instruction must be sent with both of the cats, using the signal flags!~";
+             print "Morgan stops your hand, just as you are about to \
+pull the lever. She looks at the cats. \
+~Are you quite sure, Priest?~^^\
+Now, that seems like a reasonable question. So, are you?  ";
+                 if (YesOrNo() == 0) "You pause, to reconsider.";
+                 else {
+                    remove E_windcat;
+                    remove W_windcat;
+                    remove army;
+                    remove Morgan;  
+                    print "You nod and yank the lever. The cage door \
+ latch is loosened enough for both windcats to break free! The \
+ spotted windcat tears off to the west, and the speckled cat \
+ zips off to the east!^^There is a somewhat stressful pause.^^";
+                  ! simply put, the flags must both be red
+                  if (((rf1 in E_windcat) && (rf2 in W_windcat)) ||
+                      ((rf2 in E_windcat) && (rf1 in W_windcat))) {
+                      Achieved(13);
+ "Simultaneously, from the east and west, a three horn signal sounds! \
+ Morgan smiles triumphantly. ~A truce has been declared! The \
+ war has ended!~ The army soldiers yell a round of ~Three cheers!~ \
+ before heading off. Morgan shakes your hand \
+ with almost enough force to break it. ~Well done indeed, Priest. \
+ Your wisdom only compliments your tranquil nature.~ She walks off, \
+ seeking the next challenge."; 
+                 }   
+                 else {
+                    move battle to Forest_clearing;
+ "Suddenly, from somewhere, a single horn note sounds! The sounds \
+ of a fight to the north are soon heard. Morgan \
+ gives you a sad, tired look. ~Perhaps it was meant to be,~ she \
+ says, as she and the army quickly march north to join their \
+ comrades.";
+                 }
+              }
+        ],
+   has static;
+
+
+Object rf1 "red flag" Ravine_pass
+   class flag_class,
+   with name "red",
+        plural "red flags",
+        description "A red square of cloth.";
+Object rf2 "red flag" Ravine_pass
+   class flag_class,
+   with name "red",
+        plural "red flags",
+        description "A red square of cloth.";
+Object bf1 "blue flag" Ravine_pass
+   class flag_class,
+   with name "blue",
+        plural "blue flags",
+        description "A blue square of cloth.";
+Object bf2 "blue flag" Ravine_pass
+   class flag_class,
+   with name "blue",
+        plural "blue flags",
+        description "A blue square of cloth.";
+
+Object E_windcat "speckled windcat" wicker_cage
+   with name "windcat" "cat" "speckled",
+        description "A sleek, speckled salt-and-pepper windcat, with \
+large paws.",
+        capacity 1,
+                 before [;
+                    Take:
+                       "The windcat hisses and struggles until you desist.";
+                    Receive:
+                      if (noun hasnt is_flag)
+                         "I don't think the windcat would appreciate that.";
+        Push, Pull, Attack, Squeeze, Turn:
+                         "I don't think the windcat would appreciate that.";
+        Rub, Touch:  "The windcat purrs.";
+                 ],
+   has supporter;                
+        
+Object W_windcat "spotted windcat" wicker_cage
+   with name "windcat" "cat" "spotted",
+        description "A sleek, spotted black-and-white windcat, with \
+large paws.",
+        capacity 1,
+                 before [;
+                    Take:
+                       "The windcat hisses and struggles until you desist.";
+                    Receive:
+                      if (noun hasnt is_flag)
+                         "I don't think the windcat would appreciate that.";
+        Push, Pull, Attack, Squeeze, Turn:
+                         "I don't think the windcat would appreciate that.";
+        Rub, Touch:  "The windcat purrs.";
+                 ],
+   has supporter;                
+   
+Object Forest_clearing "Forest Clearing"
+   with description "A open clearing is surrounded by forest trees here. \
+A ravine pass is to the south, and a short trail heads northwest. \
+You can just see a small cave opening to the northeast.",
+   name "clearing" "forest" "trees" "ravine" "pass" "trail" "cave",
+   s_to Ravine_pass,
+   nw_to [;
+      if (battle in self)
+         "You're not getting past that bloody battle (intact).";
+      else return Forest_brambles;
+   ],
+   ne_to [;
+     if (battle in self)
+        "You're not getting past that bloody battle (intact).";
+     else return Forest_cave;
+   ],
+   has light;
+   
+Object battle "bloody battle"
+   with name "battle" "war" "warriors",
+        initial "There's a violent battle taking place in the middle \
+of the field.",
+        description "It's a fierce battle. Kobolds and soldiers are locked \
+in mortal combat. Getting too close would be certain death.",
+        life [;
+           Attack:  
+              deadflag = 1;
+           "You give a yell and plunge into the battle, and get \
+skewered by a kobold arrow moments later.";
+default: "At the moment, everyone seems rather occupied.";
+        ],
+   has animate;
+   
+Object Forest_brambles "Forest Brambles"
+   with description "There's a small area of forest surrounded by \
+brambles and shrubs here. A trail leads southeast.",
+   name "forest" "brambles" "shrubs" "trail",
+   se_to Forest_clearing,
+   has light;
+   
+Object Forest_cave "In front of cave"
+   with description "A small cave mouth enters into darkness to the \
+north here. A clearing lies to the southwest.",
+   name "cave" "mouth" "darkness" "clearing",
+   sw_to Forest_clearing,
+   n_to CAVE_NSTUNNEL,
+   has light;
+   
+Object CAVE_NSTUNNEL "North-South Tunnel"
+   with description "You're in a natural cave tunnel running north and \
+south. To the south you can see a glimmer of daylight.",
+   name "glimmer" "daylight" "tunnel",
+   s_to Forest_cave,
+   n_to CAVE_INTER,
+   ;
+   
+Object CAVE_INTER "Tunnel Intersection"
+   with description "Several natural cave tunnels intersect here, \
+running north, south, and east.",
+   name "tunnel" "tunnels",
+   s_to CAVE_NSTUNNEL,
+   n_to CAVE_CURVE,
+   e_to CAVE_NCREVASSE,
+   ;
+   
+!Object CAVE_BARE "Bare Cavern",
+!   with description "A bare cavern.  The exit is east.",
+!   e_to CAVE_INTER,
+!   ;
+   
+Object CAVE_CURVE "Twisting Tunnel",
+   with description "A natural cave tunnel makes short twists and \
+turns here, running south and east.",
+   name "tunnel" "twists" "turns",
+   s_to CAVE_INTER,
+   e_to CAVE_DAMP,
+   ;
+   
+Object CAVE_DAMP "Damp Cave"
+   with description "You're in a small cave with noticeably damp walls. \
+Exits lie to the west and south.",
+   name "cave" "damp",
+   w_to CAVE_CURVE,
+   s_to CAVE_NCREVASSE,
+   ;
+   
+Object CAVE_NCREVASSE "Sloping Tunnel"
+   with description "You're in a windy tunnel that gradually slopes up to the \
+east, or down to the west. A cold breeze blows from a tunnel to the north.",
+   name "tunnel" "breeze",
+   w_to CAVE_INTER,
+   n_to CAVE_DAMP,
+   e_to CAVE_WINDY,
+   d_to CAVE_INTER,
+   u_to CAVE_WINDY,
+   ;
+            
+Object CAVE_WINDY "Windy Tunnel"
+   with description "A strange wind seems to howl through this \
+winding tunnel heading east and west. A crack in the tunnel \
+wall exposes an exit north.",
+   name "wind" "tunnel" "crack",
+   w_to CAVE_NCREVASSE,
+   e_to CAVE_BARE2,
+   n_to Ancient_Tunnel,
+   before [;
+      Listen: "A light wind howls through this tunnel.";
+   ],
+   ;
+
+Object CAVE_BARE2 "Bare Cavern",
+   with description "A bare cavern. The exit is west.",
+   w_to CAVE_WINDY,
+   ;
+   
+! (torn -- planes are reachable)
+Object p4 "torn parchment" CAVE_BARE2
+   class parchment_class,
+   with name "torn",
+description "~...places no mortal man should go, \
+There are planes of existence far beyond our own, that \
+connect and interlace, so that even mortal man may \
+tread upon the featureless gray of <smudge>. But, \
+I believe that there may be other planes, perhaps \
+where the Implementors are said to live. Are these \
+places just parts of existing planes or planes unto \
+themselves? I do not...~";
+
+Object Ancient_Tunnel "Ancient Hallway"
+   with description "You're in a stone hallway, clearly man-made. \
+The dust and musty smell indicate the place hasn't \
+been used in quite some time. The corridor runs north, while the \
+south wall has a large crack, creating a dark opening.",
+   name "dust" "hallway" "crack" "opening",
+   s_to CAVE_WINDY,
+   n_to End_of_hall,
+   before [;
+      Smell: "The air smells a bit musty and stale.";
+   ],
+   ;
+   
+Object End_of_hall "End of Hallway"
+   with description "You're at the north end of a long stone hallway. \
+You can follow the hallway back south, or you can take a set of \
+cracked stone stairs up.",
+   name "hallway" "stairs",
+   s_to Ancient_Tunnel,
+   u_to Domed_chamber,
+   ;
+   
+Object Domed_chamber "Domed Chamber"
+   with description [;
+   print "You are in a large man-made underground chamber, with a \
+perfectly domed high ceiling. Smooth stone archways lead to rooms to the \
+north, south, east and west. Stone cut steps lead down. In the very \
+center of the ceiling you notice a strange circular depression in \
+the stone";
+   if ((self hasnt general) && (amulet has worn)) {
+      give self general;
+      ".^^Your amulet suddenly gives off a flash of purple light, then fades!";
+   }
+   else ".";
+   ],
+   name "dome" "archways" "steps" "ceiling",
+   d_to End_of_hall,
+   n_to TROPHY_N,
+   e_to TROPHY_E,
+   s_to TROPHY_S,
+   w_to TROPHY_W,
+   u_to "The ceiling is too far above you.";
+   
+Nearby fake_depression "depression"
+   with name "depression" "circle" "hole",
+        description "It looks like a slightly recessed circular depression \
+in the ceiling. It's hard to tell from here if it was something cut out of \
+the stone, or perhaps it's a separate piece.",
+   has scenery;
+
+! (Player can only get here in end game, and probably doesn't want to be here either)
+Object TROPHY_SECRET "Secret Trophy Room"
+   with description "You're in a small domed stone room. The only exit, \
+unfortunately, is a hole in the stone floor to a floor of another chamber \
+far below. Engraved in the wall is: ~LORD DUNCANTHRAX'S PRIVATE TROPHY \
+ROOM~.",
+   number 0,
+   name "hole",
+   each_turn [;
+      if (TROPHY_SECRET.number == 0) {
+         TROPHY_SECRET.number = 1;
+         TROPHY_SECRET.description = "You're in a small domed stone room. \
+There appear to be no exits -- the hole in the floor appears to have been \
+sealed with stone. Engraved in \
+the wall is: ~LORD DUNCANTHRAX'S PRIVATE TROPHY ROOM~.";
+         give self ~light ~visited;
+         "^Lord Duncanthrax and some of his soldiers are here.^^\
+Duncanthrax looks up and sees you. ~Who is that?~ he asks. ~Looks like a \
+priest,~ a soldier says. ~Wonderful. First, the black paint, and now, \
+a priest breaks into my trophy room.~ He sighs. ~Will no one rid me of \
+this meddlesome priest?~ One of the soldiers takes the hint and knocks \
+you out cold.^^You awake a short time later.";
+      }      
+      else {   
+      deadflag = 1;
+      "^You soon run out of air in the sealed stone room.";
+      }
+   ],
+has light;
+   
+Object TROPHY_N "North Trophy Room"
+   with description "This is a bare cubical stone chamber. Some worn black \
+lettering on the wall reads: ~THE EAST CHAMBER IS NOT THE FIRST TROPHY \
+ROOM~. An archway exits south.",
+   name "archway" "stone",
+   s_to Domed_chamber,
+;
+
+Object TROPHY_E "East Trophy Room"
+   with description "This is a bare cubical stone chamber. Some worn black \
+lettering on the wall reads: ~THE NORTH CHAMBER HAS SILVER LETTERING~. \
+An archway exits west.",
+   name "archway" "stone",
+   w_to Domed_chamber,
+;
+! sigh: logic bug in rel 1.  Try the following stmt below instead.  Note
+! that two solutions are possible in this case...
+! on the wall reads: ~THE NORTH CHAMBER HAS GOLD LETTERING AND THE SOUTH \
+! CHAMBER IS THE SECOND TROPHY ROOM~.  \
+
+Object TROPHY_S "South Trophy Room"
+   with description "This is a bare cubical stone chamber. Some worn black \
+lettering on the wall reads: ~THE EAST CHAMBER HAS SILVER LETTERING AND \
+I HAVE GOLD LETTERING~. An archway exits north.",
+   name "archway" "stone",
+   n_to Domed_chamber,
+;
+
+Object TROPHY_W "West Trophy Room"
+   with description "This is a bare cubical stone chamber. Some worn black \
+lettering on the wall reads: ~EITHER I AM THE SECOND TROPHY ROOM AND THE \
+NORTH CHAMBER IS THE LAST TROPHY ROOM, OR I HAVE GOLD LETTERING~. \
+An archway exits east.",
+   name "archway" "stone",
+   e_to Domed_chamber,
+;
+
+Object lettering "lettering"
+   with name "lettering" "black" "writing",
+        description [; <Look>; ],
+        found_in TROPHY_N TROPHY_E TROPHY_S TROPHY_W,
+   has scenery;
+
+! (Now, the special key depressions
+! AUTHOR NOTE: Originally, I represented all 4 by one object.  I
+! switched to four identical but separate objects to simplify the 
+! ease of have the trophy still sitting in the given depression
+! (potentially increasing the likelihood that the player might 
+! drop the trophy in more than once, thereby fouling the puzzle)
+Object Nkey_depression "circular depression" TROPHY_N
+   class trophy_dep_class,
+   with before [;
+         Receive:
+            if (noun ~= trophy)
+               "That doesn't quite fit.";
+            else {
+               if (trophy_stage == 3) {
+                 ! got it --- drop rod if in chamber
+                 trophy_stage = 0;  ! could get 'reset'
+                 print "You hear a click";
+                 move trophy to self;
+                 if (white_rod_piece in TROPHY_SECRET) {
+                    Achieved(14);
+                    move white_rod_piece to Domed_chamber;
+                    move air_spirit to Domed_chamber;
+                    Domed_chamber.description = "You are in a large man-made underground chamber, with a \
+perfectly domed high ceiling. Smooth stone archways lead to rooms to the \
+north, south, east and west. Stone cut steps lead down. In the very \
+center of the ceiling you notice a circular hole.";
+                    fake_depression.description = "It's a small circular hole shrouded in darkness.";
+                    ", followed by a dull thump \
+                    from the south.";
+                 }
+                 else ".";                 
+               }
+               else {
+                  trophy_stage = 0;  ! reset
+                  move trophy to self;
+                  "You hear a click.";
+               }
+            }
+         ],
+;
+        
+Object Ekey_depression "circular depression" TROPHY_E
+   class trophy_dep_class,
+   with before [;
+         Receive:
+            if (noun ~= trophy)
+               "That doesn't quite fit.";
+            else {
+               move trophy to self;
+               if (trophy_stage == 0)  trophy_stage = 1;  
+               else  trophy_stage = 0;  ! reset
+                  "You hear a click.";
+            }
+         ],
+;
+               
+Object Skey_depression "circular depression" TROPHY_S
+   class trophy_dep_class,
+   with before [;
+         Receive:
+            if (noun ~= trophy)
+               "That doesn't quite fit.";
+            else {
+               move trophy to self;
+               if (trophy_stage == 2)  trophy_stage = 3;  
+               else  trophy_stage = 0;  ! reset
+                  "You hear a click.";
+            }
+         ],
+;
+
+Object Wkey_depression "circular depression" TROPHY_W
+   class trophy_dep_class,
+   with before [;
+         Receive:
+            if (noun ~= trophy)
+               "That doesn't quite fit.";
+            else {
+               move trophy to self;
+               if (trophy_stage == 1)  trophy_stage = 2;  
+               else  trophy_stage = 0;  ! reset
+                  "You hear a click.";
+            }
+         ],
+;
+           
+! (GUE Tech -- with new curriculum...)
+Object GUE_Gate "GUE Entrance"
+   with description "You're standing under an open archway that has \
+the letters ~GUE TECH~ prominently displayed in \
+twisted brass and copper. A busy street lies to the \
+south, and the campus quad opens up to the north.",
+        name "letters" "street" "quad",
+        s_to BORPHEE_CS,
+        n_to GUE_QuadS,
+   has light;
+
+Nearby GUE_arch "archway"
+   with name "arch" "archway",
+        description "It's an elaborate metal and stone affair that \
+probably cost a fortune. On one side, an inscription reads \
+~Forburn Gate~.",
+   has scenery;
+
+Object GUE_QuadS "South Quad"
+   with description "You're walking across a grassy field. More \
+lawn lies to the north, while an archway exits the area to the \
+south. To the west is a low stone building with the word \
+~GYMNASIUM~ etched in stone across the entrance. To the east \
+is a old brick building covered in ivy.",
+        name "grass" "field" "lawn" "archway" "building" 
+"ivy",
+        s_to GUE_Gate,
+        n_to GUE_Quad,
+        w_to GUE_Gym,
+        e_to GUE_Hum,
+   has light;
+
+Object GUE_Quad "Center of Quad"
+   with description "The center of the campus is a nicely tended \
+green lawn with a bronze statue in the center. \
+Paths lead north and south across grassy fields. \
+To the west is a small brick building. To the east \
+is a large stone building with a lintel roof and the \
+words ~WOOMAX LIBRARY~ enscribed across the entrance.",
+        name "lawn" "grass" "fields" "building" "lintel",
+        s_to GUE_QuadS,
+        n_to GUE_QuadN,
+        w_to GUE_Cafe,
+        e_to GUE_Library,
+        each_turn [ i ;
+            i = random(20);
+            if (i==8 or 17)
+               "^Some students walk by. They must be upperclassmen, \
+as they don't even look in your direction.";
+            if (i==9 or 14)
+               "^Some students walk by. They must be underclassmen, \
+as some of them look at you with puzzled expressions.";
+        ],
+   has light;
+
+Nearby belboz_statue "statue"
+   with name "statue" "bronze",
+        description "An old bronze statue of a wise-looking \
+man in wizard's clothes with a stern, disapproving look. An inscription \
+at the base reads ~BELBOZ AT MITHICUS~.",
+   has scenery;
+
+Object GUE_QuadN "North Quad"
+   with description "You're walking across a grassy field. More \
+lawn lies to the south, while a large building that resembles a \
+auditorium of some sort is north. An inscription near the entrance \
+reads ~ENCHANTER HALL~. To the west you see a small house-like \
+building. To the east you see a low stone building, clearly new \
+and rather modern looking in contrast to its surroundings.",
+   name "grass" "field" "lawn" "building" "auditorium",
+        s_to GUE_Quad,
+        n_to GUE_Enchanter_hall,
+        w_to GUE_Dorms,
+        e_to GUE_Labs,
+   has light;
+
+Object GUE_Gym "Gymnasium"
+   with description "There's a large field house here, filled with \
+gym equipment and helpful rubber mats. The exit is east.",
+        e_to GUE_QuadS,
+        before [;
+           Jump:  "You do a bit of exercise.";
+        ],
+   has light;
+
+Nearby gym_stuff "equipment"
+   with description "Various things useful to those who exercise.",
+        name "equipment" "mats",
+        before [;
+            Pull, Push: "You do a bit of exercise.";
+        ],
+   has scenery;
+
+Object dorm_key "flat key" GUE_Gym
+   with name "key" "flat" "dorm",
+        initial "Someone left a key here.",
+        description "A flat metal key with ~102~ marked on one side.",
+        !weight 5,
+        size 5,
+;
+
+Object GUE_Hum "Humanities Building"
+   with description "You're in the humanities building, which is \
+vacant and closed for the summer. The exit is west.",
+       w_to GUE_QuadS,
+   has light;
+
+Object History_book "history book" GUE_Hum
+   with name "book" "history",
+      initial "Someone left a history book here.",
+      description "It's a biography on the life and times of \
+      Duncanthrax the Bellicose. Most of it chronicles fairly \
+      dry stuff about his much publicized conquests of the \
+      Eastlands and his famous battles. There is an interesting  \
+      bit about some secret trophy chamber that Duncanthrax \
+      had constructed near the end of his reign, but for more \
+      details, I'd suggest ~look up (word) in book~ specifically.",
+      before 
+      [ w1; Consult:
+            if (consult_words > 1)
+               "The index is rather terse, try limiting your lookup \
+               to one word.";
+            wn = consult_from; w1 = NextWord();
+            switch (w1) {
+               'trophy', 'secret':
+               "Apparently, in 680 GUE, Duncanthrax grew increasingly \
+               withdrawn. At this time, of foremost importance to him was his collection of \
+               various battle trophys and awards he had bestowed to \
+               himself (for unusual valor on the field of battle) \
+               over the years. He decided to construct a hidden \
+               underground chamber south of Egreth to sequester this \
+               collection, which would be locked in a most clever means. \
+               He decided to order the construction of \
+               a ~four-room key~ which, when a miniature trophy \
+               was inserted and removed (once) in a special keyhole in each \
+               of the four rooms (in a specific order), would unlock a holding chamber \
+               in a center room containing his prized trophies. \ 
+               Priding himself on his logic skills, he requested that \
+               two captured foreigners produce a logic puzzle plainly \
+               inscribed in the four key rooms themselves that would \
+               detail the exact order that the key rooms were to be \
+               ~applied~. A Prevaricon, \
+               who could not help but write untruths, was given a can of \
+               gold paint, while a Veritassi, who could only write the \
+               truth, was given a can of silver paint. Imagine \
+               Duncanthrax's rage when he discovered that the two \
+               prisoners had secretly painted over their gold and \
+               silver key phrases with _black_ paint! \
+               The prisoners were \
+               summarily executed, of course, but Duncanthrax sealed \
+               off the chamber and researchers can only guess at \
+               the final fate of the trophy collection of Duncanthrax.";
+               'Zilbo':
+               "Zilbo the third was overthrown in the great revolt lead \
+               by Duncanthrax in 659 GUE. The biographers suggest \
+               reading their companion text ~How Zilbo Came to Mithicus~.";
+               'Griffspotter', 'Antharia':
+               "In 665 GUE, Duncanthrax humiliated the Antharian naval \
+               Armada in the famous battle at Fort Griffspotter. \
+               (Well, okay, there's quite a bit more in the book about \
+               this battle, but remember, you're a priest, not a \
+               navy sailor.)";
+               'Diablo', 'Massacre':
+               "In 666 GUE, Duncanthrax invaded Zorbel Pass in the \
+               Eastlands and severely trounced a local militia of \
+               trolls armed with clubs and garlic. The key \
+               significance of this victory on Duncanthrax's \
+               conquest of the Eastlands, as well as the immediate \
+               recall of all vampiric soldiers in Duncanthrax's \
+               military force, cannot be understated.";
+               'Ogre', 'battle', 'duel':
+               "In late 666 GUE, Duncanthrax was engaged in a fierce \
+               battle with forces near Globby Hills. In a brilliant \
+               tactical move, Duncanthrax goaded the opposing force \
+               into decided the fate of the battle on a single duel -- \
+               himself versus their champion. Unfortunately for \
+               Duncanthrax, the Globby Hill champion turned out to \
+               be an Ogre of immense size. In an attempted diversion, \
+               Duncanthrax was quoted as saying to the Ogre, \
+               ~It's all right, we're with Silvermane.~ The Ogre \
+               was quoted as responding with ~Huh?~. Duncanthrax then, \
+               perhaps in a moment of sheer bravado, was heard to \
+               say ~Your shoes are untied.~ As the Ogre bent down \
+               to examine his unshod feet, Duncanthrax gave the \
+               signal, and the Ogre was buried under a massive \
+               pile of granola.";               
+               'Silvermane':
+               "Silvermane, the book notes, was the name of \
+               Duncanthrax's pet Dire Wolf.";
+               'Index', 'index':
+               "There appear to be notable entries on ~trophy~, \ 
+               ~Zilbo~, ~Griffspotter~, ~Diablo~, ~Ogre~, and \
+               ~Silvermane~.";
+               default:
+                 "You can't find anything interesting about that.";               
+             }               
+          ],
+       !weight 20,
+       size 15,
+;
+Object GUE_Cafe "Cafeteria"
+   with description "A small cramped area with lots of tables and \
+chairs and food stains. The exit is east.",
+        name "table" "tables" "chair" "chairs" "food" "stains",
+        e_to GUE_Quad,
+   has light;
+
+Nearby cafe_mess "mess"
+   with name "mess" "cups" "napkins" "junk",
+        initial "Someone must've had a late night recently, as \
+there is quite a mess of coffee cups, napkins, and other junk \
+on one table.",
+        before [;
+            Search:
+               if (self hasnt general) {
+                  give self general;
+              move sugar_cube to GUE_Cafe;
+              move decaf_coffee_can to GUE_Cafe;
+              "You dig through the mess and find an \
+unopened can of coffee and a sugar-cube.";
+            }
+            Take:
+              "There's too much to carry.";
+            Rub, Push, Pull, Turn, Touch, Shake:
+"You mess with the mess. Nothing happens.";
+        ],
+   has static;
+
+Object sugar_cube "sugar cube"
+   with name "sugar" "cube",
+        short_name "sugar cube",
+        description "A perfect featureless white cube (of sugar).",
+        !weight 5,
+        size 5,
+   has edible;
+
+Object GUE_Library "Library"
+   with description "A student library is here, filled with \
+various texts. The exit is west.",
+        w_to [ x y z ;
+             objectloop (x in player) {
+             if ((x == marked_scroll) && (librarian hasnt general))
+"Some strange invisible force stops you as you try \
+to leave. The librarian doesn't look up, but merely says, \ 
+~If you want to check something out, I'll \
+need to see some ID first.~";
+! (now, instead of doing recursive tree traverse, I do two levels
+! of checking, to save code space, since there aren't that many
+! workable containers in this game)
+             if (children(x) > 0) {
+                objectloop (y in x) {
+                   if ((y == marked_scroll) && (librarian hasnt general))
+"Some strange invisible force stops you as you try \
+to leave. The librarian doesn't look up, but merely says, \ 
+~If you want to check something out, I'll \
+need to see some ID first.~";
+                   if (children(y) > 0) {
+                      objectloop (z in y) {
+                         if ((z == marked_scroll) && (librarian hasnt general))
+"Some strange invisible force stops you as you try \
+to leave. The librarian doesn't look up, but merely says, \ 
+~If you want to check something out, I'll \
+need to see some ID first.~";
+                      }
+                   }
+                }
+             }
+             }
+             return GUE_Quad;
+! if ((marked_scroll notin GUE_Library) && (librarian hasnt general)) 
+        ],
+   has light;
+
+
+Object magazine_lib "wrinkled magazine" GUE_Library
+   with name "magazine" "wrinkled" "report",
+        initial "There's a wrinkled magazine (~US News and Dungeon Report~) here.",
+        description "SPIRITWRAK Author notes:^\
+3/96 -- Initial (beta) release. Functionally complete, some \
+nagging bugs and typos may still be present.^\
+4/96 -- Second release. Reported bugs fixed. A few puzzles \
+added, some removed.^\
+6/96 -- Third release. Bug fix release.",
+        size 15;
+        
+        
+
+Object GUE_Dorms "Dorms"
+   with description "You're in a short hallway inside some student \
+dormitories. The exit is east.",
+        e_to GUE_QuadN,
+        n_to dorm_doorN,
+        s_to dorm_doorS,
+        w_to "You wander the halls a bit and return here.",
+   has light;
+
+Object dorm_doorN "northern door" GUE_Dorms
+   with name "door" "northern",
+        when_closed "There's a closed door to the north.",
+        when_open "There's an open door to the north.",
+        description "A wooden door with a keylock. A note \
+attached to it says ~DOING WORK ABROAD~.",
+        with_key dorm_key,
+        door_dir n_to,
+        door_to GUE_dormroom,
+        after [;
+           Open:
+              give dorm_doorN2 open;
+           Close:
+              give dorm_doorN2 ~open;
+        ],
+    has static door openable lockable locked;
+
+
+Object dorm_doorS "southern door" GUE_Dorms
+   with name "door" "southern",
+        when_closed "There's a closed door to the south.",
+        description "A wooden door with a keylock. A note \
+attached to it says ~BEWARE OF DOG~.",
+        door_dir n_to,
+        door_to GUE_Dorms,  ! doesn't really go anywhere  
+        before [;
+           Open:
+              deadflag = 1;
+              "As you open the door, an enormous hellhound jumps \
+out! The unusual watchdog creeps back into the room and closes the \
+door -- after having mauled you to pieces, of course.";
+        ],
+    has static door openable lockable;
+
+Object GUE_ID1 "dirty ID card" GUE_Dorms
+  with name "ID" "card" "dirty",
+       description "A slightly dirty ID card. There's a picture \
+of some woman with short dark hair and glasses, and the name \
+~Stephanie~ on the front.",
+       size 5,
+;
+Object GUE_ID2 "clean ID card" 
+  with name "ID" "card" "clean",
+       description "An ID card with a picture \
+of some young student and the name \
+~Harold~ written on the front.",
+       size 5,
+;
+
+Object GUE_dormroom "Dorm room"
+   with description "A cramped room, mostly empty, with some \
+bare furnishings.",
+   name "furnishings" "desk" "chair" "bed",
+        s_to dorm_doorN2,
+   has light;
+
+! (due to short name confusion ("northern door"), 2nd half
+! of this door done separately)
+Object dorm_doorN2 "door" GUE_dormroom
+   with name "door",
+        when_closed "There's a closed door to the south.",
+        when_open "There's an open door to the south.",
+        description "An unremarkable wooden door.",  
+!        with_key dorm_key,
+        door_dir s_to,
+        door_to GUE_Dorms,
+        after [;
+           Open:
+             give dorm_doorN open ~locked;
+           Close:
+             give dorm_doorN ~open;
+        ],
+        before [;
+           Lock:
+              "You can't lock the door from this side.";
+           Unlock:
+              "You can't unlock the door from this side.";
+        ],
+    has static door openable lockable;
+
+!Nearby dormroom_furnishings "furnishings"
+!   with name "furnishings" "desk" "chair" "bed",
+!        description "Minimal furnishings -- a desk and chair, \
+!a small bed.  Almost reminds you of the Monastery.",
+!   has scenery;
+
+Object textbook "textbook" GUE_dormroom
+   with name "book" "textbook" "text",
+        initial "A forgotten textbook is lying in one corner of \
+the room.",
+        description [;
+           if (self hasnt open)
+            "The cover reads ~Ancient Mythology~.";
+           else
+              "~A colorful myth among ancient races has been \
+called 'The myth of the Four Brothers' by Elder Kroonwatz \
+(the famous Royal Chronicler). The story states that at the dawn of time, four \
+evil gods, who were brothers, sought dominance over that \
+which would become our world. Great battles were fought \
+between forces of light and darkness, and these \
+brothers were often victorious. \
+Fortunately for us, they \
+could not cooperate with each other, and \
+fought amongst themselves in petty power \
+struggles, driven individually by power and greed. 
+Indeed, legends state that on occassions, the brothers \
+would seek ways to actually destroy their own siblings, \
+along with the forces of good. \
+One brother constructed a strange artifact that would \
+have given him great power, but was discovered by agents of good. \
+He was imprisoned within the very object he built. The remaining \
+three, facing certain defeat without the combined strength of their \
+trapped brother, fled into planes unknown, but made a pact \
+that if the brother were ever freed, and the artifact of \
+power returned to him, the four would \
+agree to make their final attack against the forces of good. \
+Kroonwatz points out the obvious parallels with various other \
+mythologies that foretell the end of the known world.~";
+        ],
+        !weight 20,
+        size 15,
+        before [;
+           Open:
+             if (self hasnt general) {
+                give self general;
+                give self open;
+                move GUE_ID2 to parent(player);
+                "As you open the book, a small card flies out and lands \
+at your feet.";
+             }
+        ],
+   has openable;
+
+Object GUE_Enchanter_hall "Enchanter Hall (top)"
+   with description "You're at the top of a large auditorium which \
+is empty. You can walk down a long aisle to the \
+front of the hall, or out to the south.",
+        name "aisle" "seats",
+        s_to GUE_QuadN,
+        d_to GUE_Enchanter_hall_front,
+        n_to GUE_Enchanter_hall_front,
+   has light;
+
+Object GUE_Enchanter_hall_front "Enchanter Hall (bottom)"
+   with description [;
+   print "You're at the very front of a large \
+auditorium. From here you can look south and sees rows upon \
+rows of empty seats focused on the stage-like area where you now \
+stand. You can walk back into the seats to the south";
+   if (hall_switch has on)
+      ". A soft dim glow highlights your current area.";
+   else ".";
+   ],
+   name "rows" "seats" "glow",
+        s_to GUE_Enchanter_hall,
+        u_to GUE_Enchanter_hall,
+   has light;
+
+Nearby hall_switch "switch"
+   with name "switch",
+        initial "There's a curious switch in the wall here.",
+        description "A small switch in the far wall.",
+        before [;
+           SwitchOn:
+              if (self hasnt on) {
+              give self on;
+              print "You hear a click. A dim light now makes the \
+nearby area less gloomy.^";
+              }
+              else "It seems to be on already.";
+              if (self hasnt general) {
+                 give self general;
+                 move notebook to hall_desk;
+                 "^A student creeps out of the shadows. He looks \
+at you sheepishly. ~Sorry I haven't been to class all semester, \
+Professor,~ he begins. ~Anyway, here's my final paper.~ He puts \
+a notebook on the desk. ~All this stuff about the new 'science' \
+-- I don't know what all the fuss \
+is about. Magic was okay too, wasn't it? There's a part in my \
+conclusion where --~ He stops and looks at the notebook. ~Well, \
+anyhow.~ he says, and disappears back into the shadows."; 
+              }
+              else rtrue;
+           SwitchOff:
+              if (self has on) {
+              give self ~on;
+              "The dim light fades.";
+              }
+              else "It seems to be off already.";
+        ], 
+   has static switchable;
+
+Object hall_desk "large desk" GUE_Enchanter_hall_front
+   with name "desk",
+        description "A long desk sits in the middle of this area.",
+        capacity 30,
+   has static supporter;
+
+Object notebook "notebook"
+   with name "notebook",
+        capacity 3,
+        description "A plain white notebook with some loose pages.",
+        !weight 10,
+        size 10,
+        before [;
+           Receive:
+                if ((noun ~= term_paper) && (noun hasnt is_scroll)) 
+                   "You can't put that into the notebook.";
+        ],
+   has container openable;
+
+Object term_paper "term paper" notebook
+   with name "paper" "term",
+        !weight 5,
+        size 10,
+        description "~Magic, so what's it good for?~ by \
+Wilbur Lunchbox. It's a long-winded haphazard writing about \
+the virtues of magic in a time of science. Some of the topic \
+sentences are particularly clumsy. However, there's an insightful \
+bit at the end about how under certain circumstances, magic and \
+science become indistinguishable.",
+;
+
+Object GUE_Labs "Science Center"
+   with description "You are in a short hallway of some new \
+building. The words ~SCIENCE CENTER~ are painted on one wall. \
+The hallway opens to rooms to the east, or you can escape to the west.",
+        name "words",
+        w_to GUE_QuadN,
+        e_to GUE_Labs_Eng,
+   has light;
+
+Object GUE_Labs_Eng "Engineering Labs"
+   with description "\
+You shudder as you look around this area. \
+Clearly a place of science, piles of heavy machinery and strange \
+delicate-looking tools and artifacts are everywhere here. Hallways \
+run west and east.",
+        name "machinery" "tools" "artifacts",
+        w_to GUE_Labs,
+        e_to GUE_Labs_Office,
+        s_to GUE_Lab_door,
+   has light; 
+
+Object wood_book "research paper" GUE_Labs_Eng
+   with name "paper" "research",
+        description "~On the Structural Strength of Woods~, \
+a short, fairly dry research paper. Apparently, the researcher was testing \
+the breaking point of various woods. The conclusions reached \
+are summed up in the final paragraph:^^\
+~In summary, our findings indicate that out of the materials \
+tested, Ebony wood is clearly the best choice, and Balsa wood \
+clearly the worst. Balsa wood structures broke immediately when \
+even the slightest weight was tested on them. Pine wood structures \
+fared slightly better, holding light weights, but tended to break \
+on repeated stress. Ebony wood structures were approximately twice \
+as strong as Pine structures, holding up to at least one repeated \
+stress test before breaking.~",
+        !weight 5, 
+        size 15;
+
+Object GUE_Labs_Office "Office"
+  with description "You're in a small office of some sort. The \
+only exit is west.",
+       w_to GUE_Labs_Eng,
+  has light;
+
+Nearby Lab_desk "desk" 
+   with name "desk",
+        initial "A small desk sits in one corner here.",
+        description "It's quite tiny really.",
+   has static supporter;
+
+Object Lab_journal "lab journal" Lab_desk 
+   with name "journal" "lab",
+        description "Some loose handwritten pages read:^\
+^~...DAY 14)  We've put the artifact in the south lab. Still \
+^             no idea what it does, but I'm sure I can find \
+^             some lab student who can figure it out. \
+^    DAY 20)  My lab assistant Peabody believes that it's \
+^             some sort of 'mystical gate'. \
+^             Clearly this is hogwash. However \
+^             my grant has been awarded, so I have allowed \
+^             Peabody to continue work. \
+^    DAY 25)  Peabody demonstrated something fantastic today. \
+^             He took my briefcase and put it on \
+^             the artifact and in a white flash, it was gone! \
+^    DAY 27)  This is my last entry. I am leaving the University \
+^             tomorrow. Peabody, in my request to retrieve my briefcase \
+^             stepped onto the artifact, and was gone! I've read \
+^             his recent research notes, and if he's right, he's \
+^             now lost in a place unimaginable! I've locked the  \
+^             artifact away and destroyed the combination -- I pray no \
+^             one ever sees it again!...~\
+^ (The journal breaks off here)",
+       !weight 15,
+       size 15,
+;
+
+Object GUE_Lab_door "lab door"
+   with name "door" "lab",
+        when_closed [;
+             print "There's a closed heavy metal door to the";
+             if (self in GUE_Labs_Eng)
+             " south.";
+             else " north.";
+        ],
+        when_open [;
+             print "There's an open metal door to the";
+             if (self in GUE_Labs_Eng)
+             " south.";
+             else " north.";
+        ],
+        description "A large door made of some shiny hard metal. \
+                    There are no obvious handles or hinges.",
+        door_dir [;
+             if (self in GUE_Labs_Eng) return s_to;
+             else return n_to;
+        ], 
+        door_to [;
+             if (self in GUE_Labs_Eng) return GUE_Labs_SECRET;
+             else return GUE_Labs_Eng;
+        ],
+        before [;
+             Close:
+               if (self has open) {
+                  left_dial.number = random(9);
+                  right_dial.number = random(9);
+                  center_dial.number = random(9);
+                  give self ~open locked;
+                  "You close the door and hear some mechanisms spin.";
+               } 
+        ],
+        found_in GUE_Labs_Eng GUE_Labs_SECRET,
+    has static door openable lockable locked;
+
+! (and now a combination lock, which is probably going to be more 
+!  of an effort to code than for the player to figure out)
+Object special_lock "set of dials" GUE_Labs_Eng
+    with name "dials",
+         initial "There's an odd set of dials in the wall near the \
+metal door.",
+         description [;
+           print "Three dials are in a left-to-right row. Above \
+each dial is a tiny square window with some number visible behind it. \
+The windows currently read: ~",left_dial.number,center_dial.number, right_dial.number;
+"~. Right next to the set of dials is a small green button. \
+Letters right above the dials read: ~FrobozzCo~."; 
+    ],
+    has static transparent;
+
+Class dial_class
+   with name "dial",
+        number 0,
+        description [; 
+            print "A small dial. The window above reads ~", self.number;
+            "~.";
+        ],
+   has static;
+        
+
+Object left_dial "left dial" special_lock
+   class dial_class
+   with name "left",
+        before [;
+            Turn:
+              left_dial.number = left_dial.number + 1;
+              if (left_dial.number > 9) left_dial.number = 0;
+              print "The left window now reads: ~", left_dial.number; 
+               "~.";
+            SetTo:
+              if ((second < 0) || (second > 9))
+                 "The left dial apparently only goes from 0 to 9.";
+              else left_dial.number = second;
+              print "The left window now reads: ~", left_dial.number; 
+               "~.";
+        ],
+;
+Object center_dial "center dial" special_lock
+   class dial_class
+   with name "center" "middle",
+        before [;
+            Turn:
+              center_dial.number = center_dial.number + 1;
+              if (center_dial.number > 9) center_dial.number = 0;
+              print "The center window now reads: ~", center_dial.number; 
+               "~.";
+            SetTo:
+              if ((second < 0) || (second > 9))
+                 "The center dial apparently only goes from 0 to 9.";
+              else center_dial.number = second;
+              print "The center window now reads: ~", center_dial.number; 
+               "~.";
+        ],
+;
+Object right_dial "right dial" special_lock
+   class dial_class
+   with name "right",
+        before [;
+            Turn:
+              right_dial.number = right_dial.number + 1;
+              if (right_dial.number > 9) right_dial.number = 0;
+              print "The right window now reads: ~", right_dial.number; 
+               "~.";
+            SetTo:
+              if ((second < 0) || (second > 9))
+                 "The right dial apparently only goes from 0 to 9.";
+              else right_dial.number = second;
+              print "The right window now reads: ~", right_dial.number; 
+               "~.";
+        ],
+;
+
+Object green_button "green button" special_lock
+   with name "button" "green",
+        number 0,
+        weight 0,
+        description "A small green button next to the dials.",
+        before [;
+           Push:
+              ! a simple game of mastermind.  NOTE: I hate mastermind...
+              if (GUE_Lab_door has open)
+                 "You hear a short buzzing noise.";
+              if ((left_dial.number == 7) &&
+                  (center_dial.number == 3) &&
+                  (right_dial.number == 4)) {
+                 give GUE_Lab_door ~locked open;
+                 Achieved(15);
+                 "You hear three clicks, and the door swings open!";
+              }
+              ! observe the bizarre numerical method of tracking guesses...
+              ! ('0' implies wrong)
+              ! (As with regular mastermind, we first check for all
+              ! 'right # and right spot' and build a bitstring that
+              ! indicates this (i.e. 700 combo would give 100 bitstring).
+              ! Then, we scan over the slots that were not marked as 
+              ! 'right # and right spot' to check for 'right #, wrong 
+              ! spot'.  If, notably, we already found that number in
+              ! the 1st scan, we do _not_ treat it as 'right #, wrong
+              ! spot' (i.e. 777 should give us 1 click, not 1 click,
+              ! 2 thunks).
+              ! -- Author's note:  There is no doubt a simpler method
+              ! to do this, and you Inform junkies should feel free
+              ! to let me know this, however I found this method to
+              ! be easy to code, easy to understand, and pretty
+              ! robust.
+              green_button.number = 0;  ! RESET
+              green_button.weight = 0;  ! (# of 'thunks')
+              ! FIRST SCAN
+              if (left_dial.number == 7) green_button.number = 100; 
+              if (center_dial.number == 3) 
+                 green_button.number = green_button.number + 10;
+              if (right_dial.number == 4)
+                 green_button.number = green_button.number + 1;
+              ! SECOND SCAN
+              if (green_button.number ~= 100 or 101 or 110) {
+                 if (green_button.number ~= 11) {
+                 if ((left_dial.number == 3) && 
+                     (green_button.number ~= 10))
+                     green_button.weight = green_button.weight + 1; ! 'add a thunk' 
+                 if ((left_dial.number == 4) && 
+                     (green_button.number ~= 1))
+                     green_button.weight = green_button.weight + 1; ! 'add a thunk' 
+                 }
+              }
+              if (green_button.number ~= 10 or 11 or 110) {
+                 if (green_button.number ~= 101) {
+                 if ((center_dial.number == 7) && 
+                     (green_button.number ~= 100))
+                     green_button.weight = green_button.weight + 1; ! 'add a thunk' 
+                 if ((center_dial.number == 4) && 
+                     (green_button.number ~= 1))
+                     green_button.weight = green_button.weight + 1; ! 'add a thunk' 
+                 }
+              }
+              if (green_button.number ~= 1 or 11 or 101) {
+                 if (green_button.number ~= 110) {
+                 if ((right_dial.number == 7) && 
+                     (green_button.number ~= 100))
+                     green_button.weight = green_button.weight + 1; ! 'add a thunk' 
+                 if ((right_dial.number == 3) && 
+                     (green_button.number ~= 10))
+                     green_button.weight = green_button.weight + 1; ! 'add a thunk' 
+                 }
+              }
+              ! Print number of clicks and thunks
+              if (green_button.number == 0 && green_button.weight == 0)
+                 "Nothing happens.";
+              if (green_button.number == 1 or 10 or 100) {
+                 print "You hear a single click";
+                 if (green_button.weight == 0) ".";
+                 else print " followed by ";
+              }
+              else {
+                 if (green_button.number == 11 or 101 or 110) {
+                    print "You hear two clicks";
+                    if (green_button.weight == 0) ".";
+                    else print " followed by ";
+                 }
+                 else {
+                    print "You hear ";
+                 }
+              }
+              EnglishNumber(green_button.weight);
+              if (green_button.weight == 1) 
+              " thunk.";
+              else " thunks.";
+
+         ],
+   has static;
+
+
+
+Object GUE_Labs_SECRET "Strange Lab"
+   with description "This is an odd room, cramped even by lab \
+standards. The place seems to have been cleared out recently.",
+   n_to GUE_Lab_door,
+has light;
+
+
+! *************
+! critters/people
+! *************
+
+Object librarian "librarian" GUE_Library
+   with name "librarian" "student" "Stephanie",
+        description "A young woman with short dark hair and \
+gold-framed glasses.",
+        life [;
+           Attack, ThrowAt:
+              "Attacking librarians is not very becoming of \
+              a priest.";
+           Show, Give:
+              if (noun == glasses)
+                 "~Thanks no, I already have a pair.~";
+              if (noun == GUE_ID1) {
+                 remove GUE_ID1;
+                 "The librarian snatches the ID out of your hand. \
+~Where'd you get my ID?~ she says. ~I've been looking for it \
+everywhere.~";
+              }
+              if (noun == GUE_ID2) {
+                 print "The librarian peers at the ID. ~Hi ";
+                 if (self has general)
+                 "again, Harold,~ she says.";
+                 else {
+                 give self general;
+                 "Harold,~ \
+she says. ~I heard you were going to be away for a least two \
+more years. Got tired of Mithicus, eh? Well, anyway, remember to \
+return anything you borrow after summer session is over.~ She \
+scribbles something down in a notebook.";
+                 }
+              } 
+           default: "The librarian is currently too busy \
+cataloging books.";
+        ],
+        react_before [;
+             Cast:
+                "The librarian frowns as you start to chant. \
+~Quiet! This is a library, you know.~ she says.";
+             Blow:
+              if (noun==whistle)
+                 "You make an unusually high-pitched noise. \
+The librarian frowns. ~Please! This is a library, you know.~";
+             Yell:
+                 "The librarian frowns. ~Please! This is a library, you know.~";
+             Sneeze:
+                 "~You should see the school nurse about that cold.~";
+        ],
+   has animate female;
+
+
+Object kobold "large kobold" Forest_brambles
+   with name "kobold" "large",
+        initial "There appears to be a wounded kobold here, resting \
+        against a shrub.",
+        description "He's a pretty tough looking kobold. The large wound \
+        in his shoulder clearly has him in a foul mood.",
+        each_turn [;
+           if (random(20) == 1)
+              "^The kobold swipes at you with a club in his good arm, \
+              but due to his condition, doesn't come close.";
+        ],
+        life [;
+           Attack,ThrowAt: "Attacking a defenseless wounded would be somewhat \
+unsporting.";
+           default: "The kobold hisses at you and spits out some words that \
+           you can't understand at all.";
+        ],
+        before [;
+           Cast:
+              if (the_spell_was == espnis_spell or foblub_spell)
+                 "The kobold cannot understand your language.  The \
+                 chant fails.";
+              if (the_spell_was == taclor_spell) {
+                 move green_sphere to Forest_brambles;
+                 remove self;
+                 "You begin your chant, and the kobold seems stricken with \
+                fear. Soon, however, the kobold stands up and looks at \
+                his healed shoulder with wonder. He starts to say something, \
+                realizes you don't speak kobold, and stops. Puzzled by \
+                your actions, he stares at you for a moment, then searchs \
+                his jerkin, finding a small object which he tosses at your \
+                feet. He walks off into the deep forest, and vanishes."; 
+              }
+        ], 
+   has animate;
+
+Object air_spirit "air spirit" 
+  with name "spirit",
+       description "It looks like a small, animated tornado capable \
+       of taking you for quite a spin.",
+       each_turn [ i ;
+       ! spirit attack
+       ! (in general, the 4 spirits are _very_ dangerous.
+       ! There's a 1/5 chance of killing outright, and 2
+       ! chances of doing 10 and 5 points of damage respectively.
+       ! In short, the player needs to realize it's time to swanko,
+       ! and do so, quickly)
+       if (self hasnt general) {
+          give self general ~concealed;    
+          "^You hear a strange intake of air from the hole above \
+          your head. Without warning, a small tornado seems to \
+          flow in from above. It seems to be sentient!";
+       }
+       i = random(5);
+       if (i == 1) {
+          deadflag = 1;
+          "^The air creature moves with amazing speed! \
+          It surrounds you in a mass of whirling winds, and you \
+          find yourself spinning helplessly. The speed increases, \
+          and you are soon torn apart!";
+       }
+       if (i == 2) 
+          Player_HP_CUR = Player_HP_CUR - 10;
+       if (i==3) 
+          Player_HP_CUR = Player_HP_CUR - 5;
+       if (Player_HP_CUR <= 0) {
+          deadflag = 1;
+          "^The last blow from the air spirit was too much for \
+          you, I'm afraid to say. You are picked up and \
+          tossed against the wall in a lifeless heap by a \
+          massive gust of wind.";
+       } 
+       print "^The air spirit ";
+       if (i==2)
+          "picks you up in a powerful gust \
+          of wind and sends you flying across the chamber! Ouch.";
+       if (i==3)
+          "surrounds you with flying dust and \
+          debris, momentarily choking you! You break free \
+          just in time.";
+       "charges, but you evade the moving tornado.";
+       ],
+       before [;
+          Cast:
+            if (the_spell_was == swanko_spell) {
+               remove self;
+               "As you speak the chant, the air spirit falls back \
+               in fear! You finish the chant, and the air spirit \
+               slowly dissipates and grows smaller, until the \
+               creature vanishes completely.";
+            }
+            print "A sharp gust of wind practically \
+            tears your chant out of your lungs.^"; 
+       ],
+       life [ ;
+          Attack:   
+            print "You ";
+            if (random(20) >= 8)
+            "strike the air creature, but your attack passes \
+            harmlessly through it! Strange laughter seems to \
+            echo from everywhere.";
+            "attack the air spirit, but miss!";
+          default: "It's too busy trying to kill you.";
+       ],
+   has animate concealed;
+
+
+! *************
+! scrolls/spells
+! *************
+
+Object flour_scroll "flour-coated scroll" 
+   class scroll_class,
+   with name "flour-coated",
+;
+
+Object gloth_spell "fold dough 83 times" flour_scroll
+   class spell_class,
+   with name "gloth",
+        magic [;
+           if (second has animate)
+              "Well, when you see a living creature made out of \
+              dough around here, let me know.";
+           "The chant fails. I suppose you probably need actual dough \
+           for it to work.";
+        ],
+;
+
+Object marked_scroll "pen-marked scroll" GUE_Library
+   class scroll_class,
+   with name "pen-marked",
+        initial "There's a pen-marked scroll sitting amongst some books here.",
+;
+
+Object taclor_spell "heal wounds" marked_scroll
+   class spell_class,
+   with name "taclor",
+        magic [;
+          if (second == 0)
+             "The chant searches for a body to heal, and fails.";
+          if (second == player) {
+             Player_HP_CUR = Player_HP_MAX;
+             "You speak the chant, and feel a warm glow surround you. \
+             In moments, you feel physically renewed!";
+          }
+          if (second hasnt animate) {
+             print "It's apparently beyond your powers to \
+             heal "; DefArt(second); ".";
+          }
+          else {
+             CDefArt(second);
+             " is no doubt grateful for the gift of better health.";
+          }                                     
+        ],
+;       
+
+
+! *************
+! interesting objects
+! *************
+Object white_rod_piece "white rod piece" TROPHY_SECRET
+  class rod_class,
+  with name "white",
+       initial "In the center of the room is a short white rod.",
+       description "It's a short section of a rod made of some \
+undeterminable hard substance, \
+colored cloud-white. A piece of the Rod of the Ancients, no doubt!",
+;
+
+Object green_sphere "green sphere"
+   class sphere_class,
+   with name "green",
+        description "A tiny perfect green sphere, made of some strange \
+           unknown metal.",
+;
diff --git a/src/FROSTHAM.INF b/src/FROSTHAM.INF
new file mode 100644 (file)
index 0000000..691db7e
--- /dev/null
@@ -0,0 +1,1162 @@
+
+! **************************************************************
+! frostham.inf
+! ------------
+! Frostham locations in SPIRITWRAK, included in spirit.inf
+! (Do not compile and/or use separately!)
+! **************************************************************
+
+Object FROSTHAM_Outskirts "Frostham Outskirts"
+   with description [;
+           print  "You are at the northern outskirts of Frostham. \
+The city proper is to the south. A few \
+snow covered residences are nearby. \
+A trail leads into a valley to the north";
+           if (self hasnt general) {
+              give self general;
+ ".^^The last time you saw Frostham was before you \
+entered the Monastery -- many years ago at least. \
+Oddly, it seemed bigger and less desolate then.";
+           }
+           else ".";
+        ],
+        name "city" "snow" "residences" "trail" "valley",
+        n_to Valley_trail,
+        s_to FROSTHAM_2,
+        cant_go "You walk around the local area a bit, finding \  
+                 nothing of interest.",
+   has light;
+
+Object FROSTHAM_2 "Frostham"
+   with description "You are in Frostham City, the famous winter-\
+lover's haven. The once booming ski vacation spot seems \
+to be a bit more run-down than in times past. \
+The city thins out towards the north, while \
+another section of town is to the south. To the west is \
+a large wood structure. To the southwest is a small \
+building. To the southeast is another small building, possibly a \
+store.",
+        name "wood" "structure" "building" "store",
+        n_to FROSTHAM_Outskirts,
+        w_to FROSTHAM_Resort,
+        sw_to FROSTHAM_Governer1,
+        s_to FROSTHAM_GUSStop,
+        se_to FROSTHAM_Store,
+        cant_go "You walk around the local streets a bit, finding \  
+                 nothing of interest.",
+        each_turn [ i ;
+           if (GROC_hall1 has general)
+              i = CheckHall();
+! Why check the grocery hallway here?  
+! Conceptually, if the player dies in the hallway (rather
+! difficult, but possible by swearing, for example),
+! the hallway should 'adjust' itself to the new weight.
+! I simply check this here, because the player must go
+! this way to reach the hallway for a second time.
+        ],
+   has light;
+
+Object FROSTHAM_Store "General Store"
+   with description [; 
+print "This appears to be a small grocery store, \
+strangely abandoned at the moment. Shelves line the walls, \
+although, since no one is minding \
+the store, the current stock seems to be a bit depleted. \
+You notice an exit south marked ~EMPLOYEES ONLY~ that \
+appears to lead to ";
+if (GROC_hall1.number == 1)
+print "some hallway.";
+else
+print "a dark hole.";
+" The way back out is to the northwest.";
+],
+        name "stock" "shelves",
+        nw_to FROSTHAM_2,
+        s_to [;
+if (GROC_hall1.number == 1) return GROC_hall1;
+else 
+   "You pull back before falling into what appears to be a deep \
+pit of some sort beyond the south exit."; 
+],
+   after [ i ;
+      Go:
+         if (noun == n_obj) {
+            i = CheckHall();
+            if (i == 1)
+               print "You hear a grinding noise from behind \
+you.^";
+         }
+   ],
+   has light;   
+
+Class Barrel_class
+   with name "crate",
+        before [;
+           Take, Pull, Turn: "It's rather heavy.";
+           Push:  "It's heavy, but you manage to make it slide \
+along the floor a bit.";
+           PushDir:
+if (location == FROSTHAM_Store && second == nw_obj)
+   "A portion of the door seal blocks the crate from going outside.";
+if (location == GROC_hall1 && second == s_obj) {
+   print "^You give the crate a good shove.^";
+   move self to GROC_hall2;
+   <<Go s_obj>>;
+}
+if (location == GROC_hall1 && second == n_obj) {
+   print "^You give the crate a good shove.^";
+   move self to FROSTHAM_Store;
+   <<Go n_obj>>;
+}
+if (location == GROC_hall2 && second == n_obj) {
+   print "^You give the crate a good shove.^";
+   move self to GROC_hall1;
+   <<Go n_obj>>;
+}
+if (location == FROSTHAM_Store && second == s_obj && GROC_hall1.number == 1) {
+   print "^You give the crate a good shove.^";
+   move self to GROC_hall1;
+   <<Go s_obj>>;
+}
+! (we do our own version to allow the CheckHall() to
+! work properly)
+AllowPushDir(); rtrue;
+        ],   
+   has static;
+
+Object BARREL1 "dusty crate" FROSTHAM_Store
+   class Barrel_class,
+   with name "dusty",
+        description "A dust-covered crate.",
+;
+Object BARREL2 "moldy crate" FROSTHAM_Store
+   class Barrel_class,
+   with name "moldy",
+        description "A mold-covered crate.",
+;
+Object BARREL3 "filthy crate" FROSTHAM_Store
+   class Barrel_class,
+   with name "filthy",
+        description "A filth-covered crate.",
+;
+
+Object GROC_hall1 "North end of Hallway"
+   with name "end" "hallway",
+        number 1,
+        description [;
+          print "You're at the north end of a short N-S hall. \
+The hallway";
+ switch (GROC_hall1.number) {
+ 1: print " slopes sharply upwards to the south. \
+You notice two dark doorways above you along the northern wall, \
+one above the other, \
+but no obvious means of getting to them";
+ 2: print " travels evenly to the south. \
+You notice a dark doorway above you along the northern wall, \
+but no obvious means of getting to it";
+ 3: print " slopes sharply downwards to the south";
+ }
+ ". To the north is an exit."; 
+],
+   each_turn [;
+      if (self hasnt general) {
+         give self general;
+         "^The hallway suddenly creaks underfoot! The floor \
+shakes briefly and dust seems to rise from cracks near the \
+walls. Apparently, your unexpected presence has jarred \
+some old mechanisms back to life!";
+      }
+   ],
+   n_to [;
+switch (GROC_hall1.number) {
+   1: return FROSTHAM_Store;
+   2: return GROC_stockroom;
+   3: return GROC_attic;
+}
+   ], 
+   after [ i ;
+      Go:
+         if (noun == n_obj or s_obj) {
+            i = CheckHall();
+            if (i == 2)
+print "^You hear a low grinding noise. \
+The hallway underfoot suddenly shifts and drops!^";
+         }
+   ],
+   s_to GROC_hall2,
+   before [;
+      Jump:  "You jump for a bit. The floor feels strangely \
+unsteady.";
+   ],
+   has light;
+
+
+Object GROC_hall2 "South end of Hallway"
+   with name "end" "hallway",
+        number 3,
+        description [;
+          print "You're at the south end of a short N-S hall \
+that seems to lead nowhere. The hallway";
+ switch (GROC_hall2.number) {
+ 1: "  slopes sharply upwards to the north.";
+ 2: "  travels evenly to the north.";
+ 3: "  slopes sharply downwards to the north.";
+ }
+ ],
+   after [ i ;
+      Go:
+         if (noun == s_obj) {
+            i = CheckHall();
+            if (i == 1)
+print "^You hear a low grinding noise. \
+The hallway underfoot suddenly shifts and drops!^";
+         }
+   ],
+   before [;
+      Jump:  "You jump for a bit. The floor feels strangely \
+unsteady.";
+   ],
+   n_to GROC_hall1,
+   has light;
+
+! (Routine for checking 'weights' of two sides of hallway)
+! (assumes called from room's _after_ routine, thus all
+! barrels and players are in their after_turn places)
+! RETURNS: 0 if no change
+!          1 if NORTH END now higher than before
+!          2 if NORTH END now lower than before
+[ CheckHall
+    i ! local total of weight points for north end
+    j ! local total of weight points for south end
+    k ! local -- orig setting of north end (.number)
+    ;
+  i = 0;  j = 0;
+  k = GROC_hall1.number;
+  if (player in GROC_hall1) 
+     i = i + 2;
+  if (player in GROC_hall2) 
+     j = j + 2;
+  if (BARREL1 in GROC_hall1) i = i + 1;
+  if (BARREL1 in GROC_hall2) j = j + 1;
+  if (BARREL2 in GROC_hall1) i = i + 1;
+  if (BARREL2 in GROC_hall2) j = j + 1;
+  if (BARREL3 in GROC_hall1) i = i + 1;
+  if (BARREL3 in GROC_hall2) j = j + 1;
+  if (i == j) {
+     GROC_hall1.number = 2;
+     GROC_hall2.number = 2;
+  }
+  if (i > j) {
+     GROC_hall1.number = 1;
+     GROC_hall2.number = 3;
+  }
+  if (i < j) {
+     GROC_hall1.number = 3;
+     GROC_hall2.number = 1;
+  }
+  if (GROC_hall1.number == k)
+     return 0;
+  if (GROC_hall1.number > k)
+     return 1;
+  if (GROC_hall1.number < k)
+     return 2;
+];  
+
+
+Object GROC_stockroom "Stockroom" 
+    with description [; 
+print "This is a tiny poorly lit room, that \
+is covered in dust. An exit south leads to a"; 
+if (GROC_hall1.number == 2) print " short hallway"; 
+else print " dark hole"; 
+if (GROC_attic has general) 
+   print ". Above, a hole has been exposed in the ceiling structure"; 
+"."; 
+     ],  
+      name "dust", 
+      u_to [; if (GROC_attic hasnt general)
+"You can't go that way.";
+           else return GROC_attic;
+        ],
+        s_to [;
+if (GROC_hall1.number == 2) return GROC_hall1;
+else 
+   "You pull back before falling into what appears to be a deep \
+pit of some sort beyond the south exit."; 
+        ],
+   after [ i ;
+      Go:
+         if (noun == n_obj) {
+            i = CheckHall();
+            if (i == 2 or 1)
+               print "You hear a low grinding noise behind you.^";
+         }
+   ],
+        has light;
+
+Object GROC_attic "Attic"
+   with description [;
+print "This is an exceptionally cramped attic, obviously \
+unused for some time. The floorboards are starting to crack.";
+if (self has general)
+   print " One section of the floor is particularly poor, and has \
+a gaping hole leading downwards into darkness.";
+" An exit heads south.";
+        ],       
+        name "sag" "crack" "hole",
+        d_to [;
+           if (GROC_attic hasnt general)
+"You can't go that way.";
+           else return GROC_stockroom;
+        ],
+        s_to [;
+if (GROC_hall1.number == 3) return GROC_hall1;
+else 
+   "You pull back at the edge of the exit. The floor, it \
+appears, is too far below you!";
+        ],
+   after [ i ;
+      Go:
+         if (noun == n_obj) {
+            i = CheckHall();
+            if (i == 2)
+               print "You hear a low grinding noise behind you.^";
+         }
+   ],
+        has light;
+
+Object attic_floorboards "floorboards" GROC_attic
+   with name "boards" "floorboards",
+        description [;
+print "Some badly rotting floorboards";
+if (GROC_attic has general)
+   " with a noticeable hole in one section.";
+else {
+   if (self has general)
+      " with a noticeable sag in one section.";
+   else ".";
+}
+        ],
+   before [;
+     Take: "They're nailed into the floor.";
+     Push, Pull, Attack, Shake:
+if (self has general)
+   "The floor shakes a bit, but nothing else happens.";
+else {
+   move loose_board to GROC_stockroom;
+   give self general;
+   "The floor shakes under your abuse, and suddenly, a \
+portion in the middle sags considerably! But nothing else \
+happens.";
+}
+   ],     
+   has scenery;
+
+Object loose_board "loose board"
+   with name "loose" "board",
+        initial "You notice a loose board, partially \
+broken, hanging from the ceiling structure.",
+        description "A portion of the ceiling boards \
+has apparently broken loose.",
+        before [;
+           Pull, Attack, Shake:
+give GROC_attic general;
+remove self;
+"You give the board a good couple of yanks. The board \
+soon breaks off, taking a small portion of the ceiling \
+with it! After the dust settles, you notice the rather \
+poor remodeling job you've done to the ceiling.";
+        ], 
+has static;
+
+
+! (the coffee was moved to the cafe in Borphee)
+Object decaf_coffee_can "can of decaf coffee" 
+   with name "can" "coffee" "decaf",
+        description "The can reads: ~Frobozz coffee crystals~^^\
+                    ~Rich, mountain-grown flavor.~^^DECAFFEINATED.",
+        before [;
+           Open:
+            "You'd need a good can-opener for that.";
+        ],
+        size 15,
+;
+   
+Object icebox_key "square key" GROC_attic
+   with name "key" "square",
+   size 5,
+;   
+   
+   
+Object icebox "icebox" GROC_stockroom
+   with name "icebox" "box",
+        description "A rather old-looking icebox.",
+        capacity 10,
+        size 20,
+        with_key icebox_key,
+        when_closed "A dust-covered icebox stands closed against \
+the northern wall.",
+        when_open [ x;
+         print "The icebox is open. ";
+         x = children(self);
+         if (x == 0) "It is also empty.";
+         print "Inside ";
+         if (x == 1) print "is: "; else print "are: ^";
+         x = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
+         WriteListFrom (child(self), x, 1); 
+         rtrue;
+       ],
+   has static container openable lockable locked;
+
+Object cerealbox1 "blue cereal box" icebox
+   with name "box" "blue" "Crunchies",
+        description "A blue paper box with lettering that reads:^^\
+                    ~Grueslayer Crunchies!^^\
+                    (It's not just for adventurers anymore!)^^\
+                    [Free bonus scroll surprise inside!]~^^\
+                    Writing on the box reads ~50zm~.",
+        size 10, capacity 5,
+        before [;
+           Receive:
+              if (noun == cerealbox2 or cerealbox3) {
+                 "That doesn't quite fit.";
+              }
+           Cast:
+              if (the_spell_was == zemdor_spell) {
+                 if (self hasnt general) {
+                    give self general;
+                    move cerealbox2 to parent(cerealbox1);
+                    move cerealbox3 to parent(cerealbox1);
+                    Achieved(1);
+                    "The box of cereal suddenly seems to dance with magic! \
+                    Before your very eyes, the box suddenly splits into \
+                    three boxes! The magic fades, but the boxes remain.";
+                 }
+                 else
+                    "The magic fights against the cereal box, but fails. \
+                    I guess you can only triplicate once.";
+              }
+        ],                            
+   has container openable;
+   
+Object cerealbox2 "navy-blue cereal box"
+   with name "box" "navy-blue" "Sugarglobs",
+        description "A navy-blue paper box with lettering that reads:^^\
+                    ~Frobozz Super Sugar Globs!^^\
+                    (Seventeen times the sugar of any other cereal!)^^\
+                    [Free bonus Frobozz toy inside!]~^^\
+                    Writing on the box reads ~50zm~.",
+        !weight 10,
+        size 10, capacity 5,
+        before [;
+           Receive:
+              if (noun == cerealbox1 or cerealbox3) {
+                 "That doesn't quite fit.";
+              }
+        ],        
+   has container openable;
+
+Object cerealbox3 "royal-blue cereal box"
+   with name "box" "royal-blue" "Dornflakes",
+        description "A royal-blue paper box with lettering that reads:^^\
+                    ~Dornflakes^^\
+                    (Just like Grandma Dimwit used to make!)^^\
+                    [Free bonus Frobozz toy inside!]~^^\
+                    Writing on the box reads ~50zm~.",
+        !weight 10,
+        size 10, capacity 5,
+        before [;
+           Receive:
+              if (noun == cerealbox1 or cerealbox2) {
+                 "That doesn't quite fit.";
+              }
+        ],        
+   has container openable;
+      
+! A Breakfast cereal class -- what a concept   
+Class cereal_class   
+   with name "cereal",
+        description "A quantity of overly-sweetened breakfast cereal.",
+        !weight 5,
+        size 8,
+        before [;
+           Eat:  
+              remove self;
+              "You consume the cereal. The sugar rush occurs five seconds \
+              later and ends just as quickly.";
+        ],
+   has edible;
+   
+Object cereal1 "crunchy cereal" cerealbox1
+   class cereal_class
+   with name "crunchy";      
+Object cereal2 "sugary cereal" cerealbox2
+   class cereal_class
+   with name "sugary";      
+Object cereal3 "flaky cereal" cerealbox3
+   class cereal_class
+   with name "flaky";   
+   
+Object baking_powder "packet of baking powder" icebox
+   with name "powder" "baking" "packet",
+        short_name "packet of baking powder",
+        description "A single-use packet of baking powder from \
+~Port Foozle Bakers Guild~ products.",
+        !weight 5,
+        size 5,
+        before [;
+           Eat:
+             remove self;
+             "You eat the baking powder. Yuck.";
+        ],
+   has edible;
+
+Object butter "stick of butter" icebox
+   with name "butter" "stick" "fat",
+        description "A good-sized stick of butter.",
+        !weight 5,
+        size 5,
+        before [;
+           Eat:
+             remove self;
+             print "You eat the entire stick of butter.";
+             if (random(20) < 15)
+" Your heart will no doubt thank you for that someday.";
+             deadflag = 1;
+             " The sudden \
+intake of concentrated fat is too much of a shock to your \
+system, and an important artery somewhere bursts.";
+        ],
+   has edible;
+
+Object FROSTHAM_Resort "Ski Resort"
+   with description "You are inside a large ski resort. Perhaps \
+                    it's not ski-season, as the entire place is \
+                    basically empty. Frostham city lies to the \
+                    east.",
+        name "resort" "city" "ski" "skis" "earmuff" "earmuffs",
+        e_to FROSTHAM_2,
+        out_to FROSTHAM_2,
+        w_to "You don't have a lift-ticket. Also, you don't have \
+             skis. Most importantly, however, the slopes look \
+             pretty lousy.",
+   has light;
+
+Object FROSTHAM_Governer1 "Governor's House, Waiting Room"
+   with description "You are in a waiting room in the house of the Frostham \
+                    Governor. The carpet is surprisingly plush. \
+                    The walls have been painted a rather bland \
+                    peach-like color. The furnishings \
+                    are also colored peach, which complements the \
+                    walls without being too nouveau. The way out \
+                    is to the northeast.",
+        name "carpet" "furnishings",
+        ne_to FROSTHAM_2,
+        out_to FROSTHAM_2,
+        s_to Gov_door,
+        after [;
+           Go:
+              if (noun==n_obj) {
+                 give Gov_door ~open locked;
+                 print "You hear the door slam and lock behind you.^";
+              }
+        ],
+   has light;
+
+Object Gov_couch "couch" FROSTHAM_Governer1 
+   with name "couch" "peach",
+        initial "A comfortable-looking peach-colored couch is here.",
+        description "It looks pretty comfy, but the color wouldn't \
+have been your first choice.",
+        before [;
+           Search:
+              if (self hasnt general) {
+                 give self general;
+                 move c1 to FROSTHAM_Governer1;
+                 "You rummage through the cushions and a coin falls out!";
+              }
+              "You find nothing of interest.";
+        ],
+   has static enterable supporter;
+
+Object travel_posters "travel brochure" FROSTHAM_Governer1
+   with name "brochure" "travel",
+        description "The brochure has pictures of various cheerful-looking \
+                     people in rather cheerful-looking places. \
+                     Bold lettering reads ~FEEL BETTER IN MIZNIA~, \
+                     ~IT'S ARAGAIN, AGAIN~, \
+                     and ~NEW BORPHEE, EVERYONE'S FAVORITE CITY~",
+        size 10,
+   ;
+
+Object c1 "coin" class coin_class;
+
+Object Gov_desk1 "desk" FROSTHAM_Governer1
+   with name "desk" "waiting" "room",
+        description "A fairly plain-looking desk",
+   has scenery supporter;
+
+Object Gov_ledger "ledger" Gov_desk1
+   with name "ledger",
+        description [;
+           if (receptionist in FROSTHAM_Governer1) 
+              "The receptionist seems to be using it at the moment.";
+           "The ledger reads:^^\
+           ~ -- New signed petition for presentation and coronation of \
+new King delivered to Aragain Magistrate, awaiting word of \
+event schedule.~^^That's all. I guess the governor hasn't been \
+very busy as of late.";
+        ],
+        !weight 20,
+        size 15,
+        before [;
+           Take: 
+              if (receptionist in FROSTHAM_Governer1) 
+                 "The receptionist gives you a rather menacing look.";
+        ],
+;
+
+
+Object alarm_clock "alarm clock" Gov_desk1
+   with name "clock" "alarm",
+        description [; 
+print "A small round desk-clock, with a set of bells \
+on the top, and a small pull-knob on the back. \
+Strangely, the clock seems to be stopped. Two hands, black and golden, \
+are sitting at ",alarm_clock.number," and ",
+alarm_clock_dial.number;
+        " respectively.";
+                     ],
+        article "an",
+        number 9,   ! setting of the clock hand
+        time_left 0,
+        time_out [ x ;
+           alarm_clock.number = alarm_clock.number + 1;
+           if (alarm_clock.number > 12) alarm_clock.number = 1;
+           x = TestScope(alarm_clock,player);
+           if (x==1) print "^The alarm clock suddenly makes an \
+awful grinding noise";
+           if (alarm_clock.number == alarm_clock_dial.number) {
+              ! alarm goes off
+              if (x==1) print ", followed by a ear-splitting clang!^";
+              ! certain events follow:
+              ! if receptionist still in office and self in office,
+              ! receptionist leaves (if player in office, he'll
+              ! see this, or see it outside the office)
+              if ((receptionist in FROSTHAM_Governer1) &&
+          (((self in FROSTHAM_Governer1) || (self in Gov_desk1)) ||
+           ((self in player) && (player in FROSTHAM_Governer1))) ) {
+                 remove receptionist;  ! a long lunch hour, apparently...
+                 ! give alarm_clock general;
+                 Achieved(2);
+                 if (player in FROSTHAM_Governer1) 
+                    "^The receptionist suddenly jumps from her \
+seat and rushes out of the room, screaming ~Lunchtime!~";
+                 if (player in FROSTHAM_2)
+                    "^You see a woman rush out of the building \
+to the southwest, and quickly vanish.";
+                 rtrue;
+              }
+              ! future: boutique in Miznia -- brings salesman to front
+              if (((self in MIZNIA_Boutique) || (self in player)) && 
+                   (player in MIZNIA_Boutique)) {
+                   print "^From somewhere in the back of the \
+store, a tailor rushes out and";
+                   if (MIZNIA_Boutique hasnt general) {
+                      give MIZNIA_Boutique general;
+                      move fancy_scroll to player;
+                      Achieved(23);
+" sees you. ~We've got a rather \
+busy schedule,~ he explains, ~but let me see what I can do.~  \
+He gives you a somewhat unapproving look. ~The ascetic-monk \
+look is out, you know. Here.~ He pins a rolled paper object \
+to your clothes. ~The latest craze -- wearing magic scrolls. \
+Beats using them nowadays, I hear. Now, like I said, we're \
+very busy.~ He goes off to the back of the store."; 
+                   }
+                   else 
+" recognizes you. \
+~I've done all I can for you right now,~ he explains as \
+goes off to the back of the store."; 
+              }
+              rtrue;
+           }
+           else if (x==1) "!";
+        ],
+        size 5,
+        add_to_scope alarm_clock_dial alarm_clock_bells alarm_clock_hands,
+   has transparent;
+
+Object alarm_clock_dial "knob" 
+   with name "pull" "knob",
+        description "A small, pullable knob on the back of the clock.",
+        number 12,
+        before [;
+           Push:
+              print "The knob ";
+              if (self has general) {
+                 give self ~general;
+                 "pushes in a short bit.";
+              }
+              else "is as far in as it can go.";
+           Pull:
+              print "The knob ";
+              if (self hasnt general) {
+                 give self general;
+                 "pulls out a short bit.";
+              }
+              else "is as far out as it can go.";
+           Turn:
+              if (self hasnt general) {
+                 ! wind clock
+                 StartTimer(alarm_clock,1); 
+                 "The knob turns -- barely. You \
+hear a small clicking noise as well.";
+              }
+              else {
+                 ! set alarm hand
+                 alarm_clock_dial.number = alarm_clock_dial.number + 1;
+                 if (alarm_clock_dial.number > 12)
+                    alarm_clock_dial.number = 1;
+                 print "The knob turns easily. You notice the \
+golden hand on the front sweep to ",alarm_clock_dial.number;
+                 ".";
+              }
+            !  if (alarm_clock hasnt general) {
+            !  }
+            !  "It doesn't turn anymore.  I guess the receptionist \
+            !  broke the clock (not that it was in good shape to \
+            !  begin with).";
+       ],
+   has static;
+
+Object alarm_clock_hands "hands"
+   with name "hand" "hands"
+   has static;
+
+Object alarm_clock_bells "bells"
+   with name "bell" "bells"
+   has static;
+
+Object FROSTHAM_Governer2 "Governor's Office"
+   with description "You are in a rather spacious office. The \
+carpeting is quite plush, and all the furnishings seem \
+excessively lavish.",
+        name "carpeting" "furnishings", 
+        n_to Gov_door,
+   has light;
+
+Object Gov_desk2 "desk" FROSTHAM_Governer2
+   with name "desk" "office",
+        description "A fairly impressive looking desk, made from \
+                    a massive lacquered piece of black oak wood.",
+        before [;
+          Cast:
+           if (the_spell_was == egdelp_spell)
+              "The desk is covered with a ugly waxy film. \
+The governor looks extremely annoyed and wipes the desk clean with \
+a stack of papers.";
+          Push, Pull, Rub, Attack, Search:
+              "~Do you mind?~ the governor says.";
+        ],
+   has scenery supporter;
+
+Object Gov_door "door" 
+   with name "door" "office",
+        when_closed [;
+             print "There's a closed door to the ";
+             if (self in FROSTHAM_Governer1) 
+                   "south.";
+             else "north.";
+        ],
+        when_open [;
+             print "There's an open door to the ";
+             if (self in FROSTHAM_Governer1) 
+                   "south.";
+             else "north.";
+        ],
+        description "It's just a thick door.",
+        door_dir [ ; if (location==FROSTHAM_Governer1) return s_to;
+                    return n_to;
+                 ],
+        door_to [ ; if (location==FROSTHAM_Governer1)
+                      return FROSTHAM_Governer2;
+                   return FROSTHAM_Governer1;
+                ],
+        before [ ;
+           Open:
+              if ((location==FROSTHAM_Governer1) &&
+                  (receptionist in FROSTHAM_Governer1))
+              "The receptionist puts a hand in your way and says, \
+               ~The governor is currently busy.~";
+           Close:
+              if (location==FROSTHAM_Governer2)
+                 "~Close it on your way _out_~, the governor snarls.";
+        ],
+        found_in FROSTHAM_Governer1 FROSTHAM_Governer2,
+   has static door openable lockable;
+
+Object FROSTHAM_GUSStop "Subway Entrance"
+   with description "You're near the southern end of the city. \
+                     The rest of the city lies to the north. \
+                     There's also a rather conspicuous \
+                     stairway down here.",
+        name "stairway",
+        n_to FROSTHAM_2,
+        u_to "You can't go that way.",
+        d_to FROSTHAM_GUSStation,
+        cant_go "You walk around the local streets a bit, finding \  
+                 nothing of interest.",
+   has light; 
+
+            
+! ******************************************************************
+! People/Creatures
+! ******************************************************************
+
+Object ski_instructor "ski instructor" FROSTHAM_Resort
+   with name "instructor" "dude" "skier" "guy" "tall" "lanky",
+        initial [;
+           print "A tall lanky guy is here, holding two colorful \
+skis. He seems to be ";
+           if (waxy_scroll in self)
+               "waxing them with a scroll.";
+            "concentrating greatly on waxing \
+            his skis."; 
+        ],
+        description "A tall lanky guy, like I said. He's \
+            decked out in fancy bright winter clothes.",
+        life [;
+           Attack, ThrowAt:
+              "~Dude, you must chill.~";
+           Answer, Tell:
+             if (special_word == 'hello' or 'hi')
+                "The skier gives you the 'thumbs-up' sign. \
+~Hey, dude.~";
+             else "~Uh, whatever, dude.~";
+           Show:
+             if (noun==rag)
+                "~Hey dude, can I borrow that?~";
+             "~Uh, whatever, dude.~";
+           Order:
+             if (action==##Give) {
+             if (noun=='skis')
+                "~No way, dude.~";
+             if (((noun==waxy_scroll) && (self hasnt general)) ||
+                 ((noun==rag) && (self has general)))
+                "~I'm using it, dude.~";
+             }
+             "~Dude, I have no idea what you're talking about.~";
+           Ask: 
+             if (second=='rag')
+                "~A rag makes an excellent ski-maintenance accessory, dude.~";
+             if ((second=='scroll' or 'waxy') && (self hasnt general))
+                "~Something I found at the top of a run. \
+                 Doesn't work too well, but hey, I gotta wax.~";
+             if (second=='skis') 
+                "~My rad Grayslopes Slaloms. If you don't wax 'em \
+                 every 30 seconds, they lose their speed.~";  
+             if ((second=='slopes') || (second=='slope') ||
+                 (second=='powder') || (second=='runs') ||
+                 (second=='skiing'))
+                "The skier takes you aside. ~Listen dude, \
+                between you and me, the slopes here rot. They \
+                used to be way better. But you know, I hear there \
+                are some _killer_ drops up north.~";
+             "~Dude, I have no idea what you're talking about.~";
+           Give:
+             if (noun==rag) {
+                move waxy_scroll to FROSTHAM_Resort;
+                move rag to self;
+                give self general;
+                Achieved(3);
+                "The skier gladly takes the rag and starts \
+                polishing immediately. He lets the scroll \
+                fall to the ground. ~Excellent man, thanks!~";
+             }
+             "~No thanks, dude.~";
+           default: "At the moment, the skier is too busy waxing.";
+        ],
+        each_turn [;
+            if (waxy_scroll notin self && self hasnt general) {
+                Achieved(3);
+                remove self;
+                "^~Dude, like, that scroll thing just \
+vanished! What a cosmic experience!~ On that note, \
+the skier opts to head for the slopes, and leaves to the west.";
+            }
+            if (random(20) < 5)
+               "^The skier polishes a spot on his skis.";
+        ], 
+        before [;
+           Cast:
+              if (the_spell_was == foblub_spell or espnis_spell)
+                 "A pair of fluffy earmuffs the skier is wearing \
+prevents him from hearing the full impact of your sermon.";
+        ],
+   has animate transparent;
+
+Object receptionist "receptionist" FROSTHAM_Governer1
+   with name "receptionist",
+        initial "A receptionist sits behind a desk, engrossed in \
+                the ledger.",
+        description "A gruff-looking lady who apparently is far \
+                more interested in her work than you.",
+        each_turn [;
+           if (receptionist hasnt general) {
+              give receptionist general;
+              "^Without even looking up, the receptionist says, \
+              ~The governor is busy right now.~";
+           }
+           if (random(10) == 1)
+              "^The receptionist turns a page in the ledger.";
+        ],
+        life [;
+           Answer, Order:
+              print "The receptionist";
+              if (special_word=='hello')
+                 ", without looking up, says \
+                 ~Can I help you?~.";
+              " seems to be ignoring you.";
+           Ask:
+              print "The receptionist";
+              if (second=='governor')
+                 ", without looking up, says \
+                 ~He's very busy right now.~.";
+              " shrugs.";
+           default:
+              "The receptionist seems to be ignoring you.";
+        ],   
+        react_before [;
+           Cast: 
+"The receptionist, in a rather shrill voice says, \
+~If you're gonna wait, do it quietly,~ disrupting your chant.";
+           Blow:
+if (noun==whistle)
+"You make an unusually high-pitched noise. The receptionist, \
+in a rather shrill voice says, \
+~If you're gonna wait, do it quietly.~";
+           Sneeze:
+"~If you want to spread germs, do it outside.~";
+           Yell:
+"~If you're gonna wait, do it quietly.~";
+           Sing:
+"~We're not holding auditions, you know.~";
+        ],
+   has animate female;
+
+Object governor "governor" FROSTHAM_Governer2
+   with name "governor" "gov",
+        initial "The governor of Frostham is sitting behind a \
+                 desk here, trying to look busy.",
+        description "A sour-looking man who tries his best not \
+                 to notice you.",
+        each_turn [ i ;
+           if (governor hasnt general) {
+              give governor general;
+              move c2 to player;
+              "^The governor scowls as you enter. ~What do you want?~ \
+               he says, and doesn't wait for a response. ~Oh, I know. \
+               More complaints about the snow, I suppose? Well \
+               look, I didn't ask for this job. Do you want it? I \
+               didn't think so.~ He shoves something into your hand. \
+               ~Here, buy yourself a cup of coffee, and stop \
+               bothering me.~";
+           }
+           i = random(4);
+           print "^The governor ";
+           if (i == 1) 
+              "thumbs through some papers.";
+           if (i==2)
+              "balances a pencil on his nose.";
+           if (i==3)
+              "scribbles something meaningless.";
+           if (i==4)
+              "looks up and notices you. ~Don't you \
+              have anything else to do?~ he says.";
+        ],
+        life [;
+           Ask:
+              if (second=='key' or 'shiny') {
+                 print "~Some key an important visitor \
+forgot while visiting. Probably useless now";
+                 if (parent(cab_key) == player)
+                    print ". You can keep it, for all I care";
+                 ".~";
+              }
+              if (second=='receptionist')
+                 "~I think she's out to lunch,~ he says, \
+with obvious annoyance.";
+              if (second=='magistrate' or 'king' or 'sydney')
+                 "He looks at you suspiciously. \
+~Never heard of him,~ he says.";
+              if (second=='ledger')
+                 "~I think my receptionist has it.~";
+              if (second=='pencil')
+                 "~Please! I'm a very busy man!~";
+              "~Sorry, that's not my problem. Now run along.~";
+           Kiss:
+              "The governor brushes you off. ~Are you \
+planning on running for office or something?~";
+           Attack, ThrowAt:
+              deadflag = 1;
+              "As you make a threatening move, the governor \
+presses some unseen switch behind his desk. Before you \
+know it, a hidden trapdoor opens in the floor and you \
+plunge to your death. A good politician is always \
+prepared, it seems...";
+           Tell:
+              "~Sure, sure. Scram, will you?~";
+           Answer, Order:
+              if (special_word=='hello')
+                 "~Yeah, sure. So what's your problem?~";
+              "The governor is busy trying to look busy.";
+           Give:
+              "Bribing a politician, eh?";
+           Show:
+              if (noun==Gov_ledger)
+                 "~Hey, return that to the receptionist!~"; 
+              "~Please! I'm a very busy man!~";
+        ],
+        react_after [;
+           Take:
+              if (noun == cab_key)
+                 "~Oh sure, just go ahead and take things \
+from my office. See if I care.~";
+        ],
+        before [;
+           Cast:
+             if (the_spell_was == foblub_spell)
+                "Actually, the governor seems pretty glued to his \
+seat already. In any event, nothing seems to happen.";
+             if (the_spell_was == espnis_spell)
+                "The governor seems to nod off, but only for \
+a second.";
+        ],
+   has animate transparent;
+
+
+! ***************
+! More objects...
+! ***************
+
+Object pencil "pencil" governor
+   with name "pencil";
+
+Object c2 "coin" class coin_class;
+
+! (cereal box prizes)
+Object whistle "whistle" cerealbox2
+   with name "whistle",
+        description "A tiny plastic whistle.",
+        !weight 1,
+        size 1,
+        before [;
+           Blow: 
+              "You make an unusually high-pitched noise.";
+        ],
+;
+! (a fancier packaged prize :)
+Object plastic_wrapper "plastic wrapper" cerealbox3
+   with name "wrapper" "plastic",
+        description "A small plastic see-through package.",
+        before [;
+           Open:
+              while (child(self)~=0) move child(self) to parent(self);
+              remove plastic_wrapper;
+              "The wrapper rips open with ease, and disintegrates, \
+              leaving the contents behind.";
+        ],
+        !weight 0,
+        size 5,
+   has container openable transparent;
+   
+Object toy_volcano "toy volcano" plastic_wrapper
+   with name "toy" "volcano",
+        description "A strange thing indeed -- a miniature \
+              ceramic toy, that has been painted and shaped \
+              in painstaking detail to look like a volcano.",
+        !weight 5,
+        size 5,
+;
+
+Object volcano_note "instruction notice" plastic_wrapper
+   with name "notice" "instruction",
+        article "an",
+        description "~Frobozz Instant Volcano~^^\
+        (parental supervision recommended)^^\
+        To use:  Just add a good quantity of water! We suggest \
+        a very large safety radius.~",
+        size 5,
+;
+        
+
+
+! ******************
+! Scrolls and spells
+! ******************
+
+Object waxy_scroll "waxy scroll" ski_instructor
+   class scroll_class,
+   with name "waxy",
+;
+
+Object egdelp_spell "create waxy build-up on wood" waxy_scroll
+   class spell_class,
+   with name "egdelp",
+        magic [;
+           if (second ~= 0 && second ~= player) {
+           CDefArt(second); " looks pretty polished as is."; }
+           else { "The chant, seeking wood to polish, fails."; }
+        ],
+;
+
+Object sugar_scroll "sugar-coated scroll" cerealbox1
+   class scroll_class,
+   with name "sugar-coated" "coated",
+;
+
+Object zemdor_spell "triplicate object" sugar_scroll
+   class spell_class,
+   with name "zemdor",
+        number 0,
+        magic [;
+           if (second == 0)
+              "The chant, seeking a locus for \
+triplication, fails.";
+           if (second has animate)
+              "The chant, not designed for living creatures, fails.";
+           if (second has is_spell)
+"This violates certain unwritten laws of magic.";
+           if (second has is_coin) {
+              ! new twist for zemdor, as sugg. by player
+              print "The coin shimmers suddenly! You blink in \
+                 disbelief as the coin seems to split \
+                 into three copies of itself! ";
+              if (self hasnt general) {
+                 give self general;
+                 move c12 to parent(second);
+                 move c13 to parent(second);
+                 "You notice there are now three coins where \
+there was once but one!";   
+              }
+              "Suddenly, a financial nymph appears! She gives \
+you a denunciatory look. ~Line 7234-6 of the Pierpont \
+tax laws clearly states that repeated unauthorized \
+triplication of monetary \
+items is strictly forbidden,~ she says, and takes the \
+the two newly created coins before disappearing.";
+           }
+           print (The) second, " shimmers suddenly! You blink in \
+                 disbelief as ", (the) second, " seems to split \
+                 into three copies of itself! ";
+                 "But, as you finish the chant, \
+                 the mystic energy seems to fade, and the copies \
+                 coalesce back into one unchanged object. The \
+chant fails.";
+        ],
+;
+
+Object c12 "coin" class coin_class;
+Object c13 "coin" class coin_class;
+
diff --git a/src/FUBLIO.INF b/src/FUBLIO.INF
new file mode 100644 (file)
index 0000000..f121240
--- /dev/null
@@ -0,0 +1,1043 @@
+
+! ******************************************************************
+! FUBLIO.INF
+! ----------
+! Add-on file for SPIRITWRAK
+! -- Contains South Fublio Valley locations, items and creatures
+! ******************************************************************
+
+Object FUBLIO_GUSStop "Southern Fublio Valley"
+   with description "You are in a southern region of Fublio \
+Valley, where someone apparently decided to start \
+a city. So far, a couple huts and farmhouses are the \
+result. A rather run-down farmhouse lies to the \
+southwest, a trail runs through grasslands to \
+the south and a smaller trail runs along the hills to the \
+southeast. To the north, you see a decrepit old \
+building. There is also a stairway into the ground here.",
+        name "huts" "farmhouses" "farmhouse" "trail" "grasslands"
+"hills" "stairway",
+        d_to FUBLIO_GUSStation,
+        sw_to Farm,
+        s_to Grasslands,
+        se_to Fublio_forest,
+        n_to Fublio_bank,
+        cant_go "You amble around the local area a bit, and return here.",
+   has light;
+   
+Object Fublio_bank "Abandoned Bank"
+   with description "You're inside what must have once been a \
+small branch office of the once indestructible Bank of Zork. \
+However, the place has clearly been abandoned, and age has not \
+been kind. Even the required portrait of J. Pierpont Flathead \
+has been pilfered. An exit lies south.",
+   s_to [;
+! first case, r & (!p & !q & !s)
+      if ((children(r_vault) == 20) &&
+          (children(p_vault) == 0) &&
+          (children(q_vault) == 0) &&
+          (children(s_vault) == 0)) return FUBLIO_GUSStop;
+! second case, (p & s) & (q & !r)
+      if (((children(s_vault) > 0) && 
+           (children(p_vault) == children(s_vault))) &&
+          ((children(q_vault) == (children(p_vault) + 5)) &&
+           (children(r_vault) ~= 20))) 
+         return FUBLIO_GUSStop;
+      "A buzzer sounds, and some mysterious force \
+prevents you from leaving!";
+   ],   
+   has light;
+
+Class vault_class
+   with name "vault",
+   description "Basically a hollow rectangular hole cut \
+into the wall.",
+   before [;
+      Receive:
+if (noun hasnt is_coin)
+   "A strange force pushes your hand away.";
+   ],
+   capacity 100,
+   size 10,
+has static container open transparent;      
+
+Object p_vault "interest vault" Fublio_bank
+   class vault_class,
+   with name "interest",
+        initial [;
+          print "An vault labeled ~INTEREST PAID~ is \
+open in the wall";
+if (children(self) > 0) {
+   print ". Inside";
+   WriteListFrom(child(self), FULLINV_BIT + ENGLISH_BIT + ISARE_BIT);
+}
+".";
+        ],
+;
+Object q_vault "overhead vault" Fublio_bank
+   class vault_class,
+   with name "overhead",
+        initial [;
+print "An vault labeled ~OVERHEAD~ is \
+open in the wall";
+if (children(self) > 0) {
+   print ". Inside";
+   WriteListFrom(child(self), FULLINV_BIT + ENGLISH_BIT + ISARE_BIT);
+}
+".";
+        ],
+;
+Object r_vault "basis vault" Fublio_bank
+   class vault_class,
+   with name "basis",
+        initial [;
+print "An vault labeled ~BASIS~ is \
+open in the wall";
+if (children(self) > 0) {
+   print ". Inside";
+   WriteListFrom(child(self), FULLINV_BIT + ENGLISH_BIT + ISARE_BIT);
+}
+".";
+        ],
+;
+Object s_vault "loans vault" Fublio_bank
+   class vault_class,
+   with name "loans",
+        initial [;
+print "An vault labeled ~LOANS~ is \
+open in the wall";
+if (children(self) > 0) {
+   print ". Inside";
+   WriteListFrom(child(self), FULLINV_BIT + ENGLISH_BIT + ISARE_BIT);
+}
+".";
+        ],
+;
+
+
+Object bank_memo "bank memo" Fublio_bank
+    with name "memo",
+description "BANK WORKER GUIDELINES^^\
+If at any point, account activity has been suspended \
+(i.e. all regular account vaults have no funds) then \
+it must be ensured that 20 zorkmids remain in basis, \
+for potential loan requests.^^\
+Otherwise, vaults must be maintained as follows:^^\
+For interest waiting to be paid, the amount must \
+equal the amount held in the loan payments vault. \
+If this amount goes over the loan payments, talk \
+to your local gnome manager to see about getting \
+some outstanding loans paid back.^^\
+Overhead should be kept at the amount in interest,
+plus five.^^\
+Loan payments should be kept at a positive amount.^^\
+Make sure that both the loan and interest vaults \
+are maintained properly, and at the same time, the \
+overhead vault is maintained while the basis vault \
+is kept at a non-suspended bank amount. If this \
+is not the case, you may need to put some overtime \
+in to straighten out the bank funds.",
+   size 15;
+
+Object c30 "coin" r_vault class coin_class;
+Object c31 "coin" r_vault class coin_class;
+Object c32 "coin" r_vault class coin_class;
+Object c33 "coin" r_vault class coin_class;
+Object c34 "coin" r_vault class coin_class;
+Object c35 "coin" r_vault class coin_class;
+Object c36 "coin" r_vault class coin_class;
+Object c37 "coin" r_vault class coin_class;
+Object c38 "coin" r_vault class coin_class;
+Object c39 "coin" r_vault class coin_class;
+Object c40 "coin" r_vault class coin_class;
+Object c41 "coin" r_vault class coin_class;
+Object c42 "coin" r_vault class coin_class;
+Object c43 "coin" r_vault class coin_class;
+Object c44 "coin" r_vault class coin_class;
+Object c45 "coin" r_vault class coin_class;
+Object c46 "coin" r_vault class coin_class;
+Object c47 "coin" r_vault class coin_class;
+Object c48 "coin" r_vault class coin_class;
+Object c49 "coin" r_vault class coin_class;
+
+Object Farm "Farm"
+   with description "You're standing in front of a small farmhouse. \
+A trail leads northeast, a sand bar lies to the southwest, \
+and another trail heads east.",
+        name "trail",
+        ne_to FUBLIO_GUSStop,
+        sw_to Veg_fields,
+        e_to Grasslands,
+   has light;
+   
+Nearby farmhouse "farmhouse"
+   with name "farmhouse" "house",
+        description "A small farmhouse, barely a shack.",
+        before [;
+           Enter: "The farmhouse is run-down enough already without you \
+                  stomping around in it.";
+        ],
+   has scenery;   
+   
+Object Veg_fields "Oyster Farm"
+   with description [;
+           print "A coastline sand bar curves west a short distance \
+here, ending in a shoal of large rocks. Nearby, \
+someone has dug some shallow holes in the \
+sand, probably farming for live Rotund Oysters, a popular \
+Eastland delicacy.";
+           if (self hasnt general)
+"Unfortunately, the oyster \
+beds are too far inland, and they appear to be \
+empty. A bit to the west you can see a small \
+shoreline cave in the rocks.";
+           else
+"The oyster \
+beds are filled with water (similar to a good portion \
+of the shoal) and look well stocked!";
+            ],
+             name "sand" "bar" "shoal" "rocks" "cave",
+             before [;
+Fill: "Seawater is hardly a rare commodity these days.";
+             ],
+            ne_to Farm,
+             w_to [;
+               if (self hasnt general) {
+                  print "You try to head towards the cave, but \
+the unstable rocks and sea waves make it "; 
+                  if (FUBLIO_Cave hasnt general) {
+                  give FUBLIO_Cave general;
+                  print "difficult \
+to get there from here. Suddenly, a rock slips from underfoot! \
+You fall...^";
+                  return FUBLIO_Cave;
+                  }
+                  else 
+                  print "impossible \
+to get there from here.^"; return 1;
+               } 
+               else
+                  "Any remainder of the sand bar west is \
+now submerged by a high tide or rise in the sea.";
+             ],
+   has light;
+   
+Nearby oyster_beds "oyster beds"
+   with name "beds" "holes" "hole",
+        description [; 
+          print "Some shallow";
+          if (Veg_fields hasnt general)
+            ", mostly empty holes in the sand.";
+            " holes in the sand, filled with sea water.";
+        ],
+        before [;
+           Search:
+              if (Veg_fields has general)
+                 "You find a couple immature oysters, and throw \
+them back."; 
+           Receive:
+              "Someone is obviously trying to use these holes \
+for oyster farming. Best to leave them as you found them.";
+        ],
+   has scenery;
+
+Object FUBLIO_Cave "Dark Damp Cave"
+   with description [;
+        print "You seem to be in some underground cave. ";
+        if (FUBLIO_Cave.number == 1)
+"There are no visible exits. You feel rather claustrophobic. \
+You also hear some unexpected noises.";
+        else 
+"There is a small dark tunnel leading south. \
+You hear the sounds of rushing water from somewhere nearby.";
+        ],
+        number 1,
+        name "tunnel",
+        s_to [;
+           if (FUBLIO_Cave.number == 1)
+              "You can't go that way.";
+           if (FUBLIO_Cave.number == 3)
+              "The dark tunnel becomes blocked after a short distance \
+by a great tidal swell! The sea has risen above the entrance!";              
+           else {
+              print "^You crawl through the dark tunnel, which \
+seems to snake back and forth. After what seems like an \
+eternity, you see daylight, and stumble forward. You find \
+yourself on the sand bar again! Looking back, you can't \
+locate the tunnel you just left at all!^";
+              FUBLIO_Cave.number = 3;
+              return Veg_fields;
+           } 
+        ],
+        before [;
+          Listen: "You hear the sounds of the sea all around you.";
+          Smell: "You smell the musty odor of the sea.";
+        ],
+;
+
+
+
+Object Grasslands "Grassland Beach"
+   with description [;
+        if (self hasnt general)
+          print "A nice beach with lots of tall grasses hides \
+behind a short dune here. The Great Sea stretches out \
+to the south.";
+        else 
+           print "A deep marsh hides behind a short dune here. The Great Sea \
+        is making some inroads here, apparently. That volcano in \
+        the water to the south may have had something to do with it.";
+        " From here, you can go north, west or east. \
+        You can just glimpse some sort of tower-like structure \ 
+        far across the bay in the east.";
+        ],
+        name "beach" "grasses" "dune" "marsh" "sea" "tower",
+        w_to [;
+             if (player in sailboat)
+                "You'll have to get out of the sailboat first.";
+             else return Farm;
+             ],
+        e_to [;
+             if (player in sailboat)
+                "You'll have to get out of the sailboat first.";
+             else return Fublio_forest;
+             ],
+        n_to [;
+             if (player in sailboat)
+                "You'll have to get out of the sailboat first.";
+             else return FUBLIO_GUSStop;
+             ],
+        s_to [;
+             if (player in sailboat) return On_Fublio_bay;
+             else
+                "The tides here make swimming unadvisable.";
+             ],
+        before [;
+             Swim:  
+                "The tides here make swimming unadvisable.";
+        ],
+  has light;
+  
+Nearby sailboat "small sailboat"
+   with name "sailboat" "boat",
+        description [; 
+           if (self hasnt general)
+              "A nice little sailboat that looks pretty sea-worthy. \
+The word ~MINIRVA~ is painted on one side.";
+           "A badly damaged sailboat. Several places bear deep \
+cracks, as though the boat had been tossed in a violent storm.";
+        ],
+        before [;
+           Go:
+              if (self has general) {
+                 print "In it's current condition, this boat is lucky to \
+                 be floating.^";
+                 return 2;  ! disallow movement but say nothing
+                 }
+              else rtrue;
+           Cast:
+              if (the_spell_was == fiznav_spell) {
+                 print "You perform a nice liturgy to the Sea Gods,";
+                 if (self has general) {
+                 give self ~general;
+                 Achieved(6);
+                 " and before your very eyes, the sailboat repairs itself!";
+                 }
+                 else " however the boat seems unchanged.";
+              }
+           Take: 
+              "That's too cumbersome to carry.";
+        ],
+        capacity 15,                                                          
+        size 30,
+   has enterable static container open;
+   
+! Object c6 "coin" sailboat class coin_class;
+
+Object On_Fublio_bay "On Fublio Bay"
+   with description [;
+        print "You are sailing on Fublio Bay. A shoreline lies \
+to the north. You could probably sail out of the bay \
+to the south, but I'd advise against it, \
+the winds aren't very strong. To the northeast \
+you can see ";
+        if (self hasnt general)
+           "the tip \
+           of a peninsula where a lighthouse tower is standing.";
+        else 
+           "a partially submerged lighthouse tower. \
+           Also, to the southeast is a small volcanic island where \
+           you could probably land.";
+        ],
+        name "shoreline" "bay" "peninsula" "tower" "lighthouse"
+"island",
+        n_to Grasslands,
+        s_to Lost_at_sea,
+        ne_to [;
+           if (self hasnt general)
+              "The winds blow the wrong way, and you end up back here.";
+           else return Lighthouse2;
+        ],
+        se_to [;
+           if (self hasnt general)
+              "You can't go that way.";
+           else return Volcano_island;
+        ],
+        before [;
+           Go:
+              if (noun==s_obj)
+                 print "^A sudden gust of wind sends your small craft \
+                   skimming out of control!^";
+           Swim, Exit:
+              if (player in sailboat)
+                 "The water's pretty deep here. I'd stay in the boat.";
+           Fill: "Seawater is hardly a rare commodity these days.";
+        ],
+        each_turn [;
+           if (seawater.number == 5) {
+              seawater.number = 10;
+              "^Many large bubbles are coming from somewhere deep in the \
+              seawater near you, as though the water was boiling! Also, \
+              you see some dark shape in the depths below rising!";
+           }
+           if (seawater.number == 4) {
+              seawater.number = 5;
+              "^There appears to be a steady stream of bubbles coming from \
+              somewhere deep in the water near you! Also, you see something \
+              dark rising from the depths below you!";
+           }
+           if (seawater.number == 3) {
+              seawater.number = 4;
+              "^You notice a few small bubbles rise to the surface of the sea.";
+           }
+           if (seawater.number == 2)
+              seawater.number = 3;
+        ],
+        
+   has light;
+
+Object Lost_at_sea "Lost at Sea"
+   with description [;
+          print "You're lost at sea. The winds are completely dead. \
+They managed to take you quite a ways out before they died, \
+however, and it's currently hard to tell which way land was \
+from here";
+         if (self has general)
+           ". Oddly, there's a volcano far out to the south, \
+           still smoldering from a recent eruption.";      
+         else ".";
+        ],
+        name "sea" "winds" "land",
+           cant_go "The winds are dead, and you're not going anywhere.",
+        before [;
+           Swim, Exit:
+              if (player in sailboat)
+                 "The water's pretty deep here. I'd stay in the boat.";
+           Fill: "Seawater is hardly a rare commodity these days.";
+        ],
+        each_turn [;
+           if (seawater.number == 9) {
+              seawater.number = 11;
+              "^Many large bubbles are coming from somewhere deep in the \
+              seawater near you, as though the water was boiling! Also, \
+              you see some dark shape in the depths below rising!";
+           }
+           if (seawater.number == 8) {
+              seawater.number = 9;
+              "^There appears to be a steady stream of bubbles coming from \
+              somewhere deep in the water near you.";
+           }
+           if (seawater.number == 7) {
+              seawater.number = 8;
+              "^You notice a small bubble rise to the surface of the sea.";
+           }
+           if (seawater.number == 6)
+              seawater.number = 7;
+        ],
+   has light;
+   
+Object Fublio_forest "On Peninsula"
+   with description [;
+        print "You stand ";
+        if (self hasnt general)
+         "in a clearing on a grassland peninsula. A \
+          trail leads northwest from here, and another leads west. \
+          Off to the \
+          southeast, there's an entrance into what looks like an old \
+          abandoned lighthouse, just at the tip of the peninsula.";
+        if (self has general)
+         "on the southeast tip of a grassland peninsula. A \
+          trail leads northwest from here, and another leads west. Off to the \
+          southeast, you can see the top of what looks like a \
+          lighthouse, partially submerged in the Great Sea.";
+        ],
+        name "clearing" "grassland" "peninsula" "trail" 
+"tower" "lighthouse" "sea",
+        nw_to FUBLIO_GUSStop,
+        w_to Grasslands,
+        se_to [;
+              if (self has general)
+              "Looks like you'd need a boat to get out to that \
+              lighthouse now."; 
+              else return Lighthouse1;
+              ],
+   has light;
+  
+Object Lighthouse1 "Bottom of Lighthouse"
+   with description [;
+        print "You're inside an ancient lighthouse. The place \
+           must have been deserted quite a long time ago, and \
+           is now a mess of broken stone, cobwebs and seabird \
+           droppings. The rest of the peninsula is back \
+           northwest. You can see a hole above where a stairway \
+           probably entered an upper floor of the place, but \
+           the stairway itself crumbled into dust long ago";
+           if ((self hasnt general) && (amulet has worn)) {
+              give self general;
+           ".^^Your amulet suddenly gives off a bright purple flash, then \
+           returns to normal!";
+           }
+           else ".";
+       ],
+       name "stone" "cobwebs" "droppings" "hole",
+       nw_to Fublio_forest,
+       u_to "The hole is too far above you.",
+   has light;
+! more scenery stuff.  This one's key though
+! (Sidenote:  Here's an example of a situation where one would probably
+! want an object that could be both a supporter and a container --
+! i.e. objects that float or sink could be handled easily.) 
+Object seawater "water"
+   with name "water" "sea" "ocean",
+        description "Salty blue-green water surrounds you.",
+        time_left 0,
+        number 1,
+        weight 0,
+        size 100,
+        before [;
+           ThrownAt, Receive:
+              if (noun == toy_volcano) {
+                 if (location == On_Fublio_bay)  {
+                    seawater.number = 2;
+                    seawater.weight = 1;
+                 }
+                 else {
+                    seawater.number = 6;
+                    seawater.weight = 2;
+                 }
+                 StartTimer(self,3);
+                 remove toy_volcano;
+                 "The toy volcano drops into the water and sinks like a stone.";
+              }                            
+              else {
+                 remove noun;
+                 if (noun == umbrella && umbrella has open)
+                    "The umbrella seems to float on the water like a \
+cloth dome for a short bit, but eventually sinks into the water.";
+                 CDefArt(noun); " sinks into the water and is soon out of sight.";
+              }              
+           Push, Pull, Turn, Take, Attack, Rub, Squeeze: "The sea water runs through your fingers.";
+           Taste, Drink: "It's just salty sea water.";
+           Search, LookUnder:
+              if (seawater.weight > 0 && seawater.number < 12)
+                 "There's something down there all right!";
+              else {
+                 if (random(10) < 2)
+                    "You glimpse a large grouper swimming under the \
+water, and watch it swim away.";
+                 else
+                    "The water seems choppy and deep. You notice \
+nothing beneath the waves at the moment.";
+              }
+        ],
+        found_in On_Fublio_bay Lost_at_sea,
+        time_out [ ;
+           ! a fairly simple event here, but nonetheless dramatic...
+           ! -- 1st, if we dropped the volcano in the bay (correct)
+           ! set water descriptions so that player won't see bubbles
+           seawater.number = 12;           
+           ! set CAVE number for endgame
+           FUBLIO_Cave.number = 3;
+           if (seawater.weight == 1) {
+           ! first, set up all room generals so that descriptions are 
+           ! changed.
+           give Grasslands general;
+           give Veg_fields general;
+           give Fublio_forest general;
+           give farmer general;  ! he'll give player sphere next encounter
+           give sailboat general;  ! damages sailboat, regardless of where it is
+           move sailboat to Grasslands;
+           ! Modify On_Fublio_bay paths, new one to island, new one to tower.
+           give On_Fublio_bay general;
+           ! Now, check location.  Certain areas will kill player in 
+           ! tidalwave.  Certain areas will cause an audible explosion.
+           ! Remainder do nothing (but shouldn't happen)
+           if (location == Veg_fields or Grasslands or Lighthouse1) {
+              deadflag = 1;
+              "^There's a massive explosion from the south! You turn \
+              and rub your eyes in disbelief. There's a \
+              volcano rising out of the sea! Unfortunately, \
+              there's also a large tidalwave headed your way \
+              (caused by volcanic eruption at sea, no doubt) which \
+              engulfs you as you try to scramble for higher ground! \
+              You struggle valiantly, but drown in deep water.";              
+           }
+           if (location == FUBLIO_GUSStop or Farm or Fublio_forest) {
+              "^You hear a massive explosion from the south! \
+              It sounded pretty far off, but whatever it was, it \
+              was loud.";           
+           }
+           if (location == On_Fublio_bay) {
+              deadflag = 1;
+                   "^Suddenly, the water around you literally lifts you into \
+                   the sky in an enormous explosion! The last thing you \
+                   see is the emerging mouth of an active and hungry volcano!";
+                         }        
+           if (location == Lost_at_sea) {
+              deadflag = 1;
+              "^You hear a large explosion off to the north! \
+A massive tidal swell rushes by and tosses your small craft violently, \
+knocking you into the water. As you watch the waves carry the boat
+away, a giant grouper swims up and swallows you."; 
+           }             
+           }
+           ! -- else, we dropped it in the sea (bummer)
+           ! (this implies that 1) only the sea descrp will change, 
+           ! 2) the player is still stuck at sea, and will be killed 
+           ! for his trouble.
+         else {
+            give sailboat general;  ! just keeping with the story...
+            give Lost_at_sea general;
+            move sailboat to Grasslands;  ! made it back to shore somehow...
+            deadflag = 1;
+            "^Suddenly, the water around you literally lifts you into \
+            the sky in an enormous explosion! The last thing you \
+            see is the emerging mouth of an active and hungry volcano!";
+         }        
+        ],
+   has scenery container open;
+
+
+Object Lighthouse2 "Near Submerged Lighthouse"
+   with description [;
+          print "You're on the outside of what looks like the upper \
+           part of a lighthouse, sticking straight out of the sea. \
+           The lighthouse is broken in many places, and several areas \
+           provide ledge-space to stand on. In fact, you could probably \
+           climb into the lighthouse through one of many large \
+           cracks in the walls to the east. The rest of Fublio bay \
+           is back southwest";
+          if ((self has general) || (Lighthouse1 has general) || 
+              (amulet hasnt worn))
+           ".";
+           else {
+              give self general;
+           ".^^Your amulet suddenly gives off a bright purple flash, then \
+           returns to normal!";
+          }                             
+        ],
+        name "lighthouse" "cracks",
+        e_to [;
+           if (player in sailboat) 
+              "You'll need to get out of the boat first.";
+           else return In_lighthouse;
+        ],
+     !   in_to [;
+     !      if (player in sailboat) 
+     !         "You'll need to get out of the boat first.";
+     !      else return In_lighthouse;
+     !   ],
+        sw_to [;
+           if (player notin sailboat)
+              "The water looks pretty choppy. I'd suggest you use a \
+              sea-going vessel of some sort.";
+           else return On_Fublio_bay;
+        ],
+    has light;
+    
+    
+Object Volcano_island "Volcanic Island"
+   with description "You're on the north shore of a small volcanic \
+         island in the middle of Fublio bay. A little more \
+         shore lies to the south. The bay spreads out before \
+         you to the northwest.",
+        name "bay",
+        nw_to [;
+           if (player notin sailboat)
+              "The water looks pretty choppy. I'd suggest you use a \
+              sea-going vessel of some sort.";
+           else return On_Fublio_bay;
+        ],
+        s_to [;
+           if (player in sailboat) 
+              "You'll need to get out of the boat first.";
+           else return Island2;
+        ],
+        before [;
+           Swim:  "Near a still-active volcano? Not wise.";
+        ],
+   has light;                    
+
+Object Island2 "South Part of Island"
+   with description "You're on a southern section of a small \
+          volcanic island in the middle of Fublio bay. Most \
+          of the area here is lava-rock, still warm. You can \
+          see a more open shore to the north.",
+        name "bay" "rock" "lava" "shore",
+        n_to Volcano_island,
+        before [;
+           Swim:  "Near a still-active volcano? Not wise.";
+        ],
+   has light; 
+
+Nearby shipwreck "old shipwreck"
+   with name "shipwreck" "wreck" "ship",
+        initial "An old shipwreck is almost embedded in the lava \
+             here.",
+        description "It looks like an old navy vessel, \
+             stuck fast in the surrounding rock. Its obviously \
+             been underwater for some time, as it is covered in \
+             barnacles and seaweed. The hull has partially rotted apart \
+             in many places.",
+        before [;
+           Enter:
+              "You find that anything left to enter in the wreck \
+              has pretty much decayed away.";
+           Cast:
+              if (the_spell_was == fiznav_spell) 
+                 "You perform a nice ritual to the Sea Gods, and \
+                 before your very eyes, the ship attempts to repair \
+                 itself! But there's too much damage, and not \
+                 even the aid of the Sea Gods can fix this craft. \
+                 The chant fails.";
+           Search: 
+              if (self has general) {
+                 move green_rod_piece to parent(self);
+                 give self ~general;
+                 Achieved(7);
+                 "Something about the old boat rings a familiar tune. \
+You check near something that might have once been a mast, and \
+uncover a familiar green rod!";
+              }
+        ],
+   has static;   
+
+Object In_lighthouse "Lighthouse, upper level"
+   with description "You're inside an abandoned lighthouse, on what \
+          must be an upper floor. The whole interior is lifeless and \
+          barren. There's a large broken crack in the western wall. \
+          You also notice a hole in the floor nearby, which might \
+          have been an exitway a long, long time ago.",
+       name "crack" "hole",
+       w_to [;
+          if (water_spirit in self)
+             "The water spirit buffets you with water and \
+             prevents you from leaving.";
+          else return Lighthouse2;
+       ],
+       d_to [;
+          deadflag = 1;
+          "You drop through the hole, and land in cold dark water! \
+          Trapped in an enclosed pool of seawater, with the hole \
+          too far above you, you drown shortly afterwards.";
+       ],   
+       before [;
+          Listen:  "You hear some sloshing noises from below the floor.";
+       ],
+has light;
+
+
+
+! ************
+! creatures
+! ************
+
+Object farmer "farmer" Farm
+   with name "farmer",
+        initial "There's a tired-looking farmer here.",
+        description "It looks like he's been working pretty hard \
+                     in the sun.",
+        each_turn [;
+           if (self hasnt general) {
+              if (random(10) == 1)
+                 "^~'Forget zucchini,' they told me, 'Go into oyster \
+                 farming. You'll make a fortune.' Ha!~";
+           }
+           else {
+              remove farmer;
+              move silver_sphere to player;
+              "^The farmer sees you approach and rushes to \
+              greet you. ~I saw what you did, sir, yes indeed. \
+              A mighty crazy thing to do, calling a volcano outa \
+              the water like that. But you did it! And \
+              my oyster beds thank you kindly! I'd like to \
+              repay the favor, but I'm only a poor farmer.~ He \
+              pauses, then searches his pockets. ~Here,~ he says, \
+              putting something in your hand. ~Found it digging in \
+              the sand. Don't know what it is, but I'll bet you \
+              can use it.~ He smiles and disappears into the \
+              farmhouse.";
+           }
+        ], 
+        life [;
+           Attack, ThrowAt:
+              "Something about attacking a down-on-his-luck \
+farmer just doesn't seem right, so you stop.";
+           Answer:
+              if (special_word == 'hello')
+                 "The farmer nods in your direction. \
+~How do, stranger?~";
+           Ask:
+              if (second == 'oyster' or 'farm' or 'oysters')
+                 "~Did a foolish thing, sir, tried my luck with \
+                 oyster farming this year. The place is too far \
+                 from the sea, and I can't get any oysters in my \
+                 beds, 'cause there's no water to grow 'em in.~";
+           Show:
+              if (noun has is_sphere)
+                 "~Hey, I seen something like that once.~";
+           Give, Tell:
+              "The farmer smiles, but shakes his head.";
+           default:  "The farmer is preoccupied with something as \
+he squints into the sun.";
+        ],             
+        before [;
+           Cast:
+             if (the_spell_was == foblub_spell or espnis_spell)
+"~I'm just a simple farmer, sir. I'm afraid you're losing me \
+with your fancy words.~"; 
+        ],
+   has animate;
+
+Object water_spirit "water spirit" In_Lighthouse
+  with name "spirit",
+       description "It looks like a large moving mass of seawater, \
+                  in a somewhat man-like shape.",
+       each_turn [ i ;
+       ! spirit attack
+       ! (in general, the 4 spirits are _very_ dangerous.
+       ! There's a 1/5 chance of killing outright, and 2
+       ! chances of doing 10 and 5 points of damage respectively.
+       ! In short, the player needs to realize it's time to swanko,
+       ! and do so, quickly)
+       if (self hasnt general) {
+            give self general ~concealed;    
+            "^Suddenly, water seeps in from the west, and forms \
+            into a large vaguely-humanoid shape before your very \
+            eyes!";
+       }
+       i = random(5);
+       if (i == 1) {
+          deadflag = 1;
+          "^The water creature moves quickly, and smothers you \
+          in water! You try to escape, but the creature has \
+          amazing strength and weight! The spirit soon \
+          envelopes your head, and you drown...";
+       }
+       if (i == 2) 
+          Player_HP_CUR = Player_HP_CUR - 10;
+       if (i==3) 
+          Player_HP_CUR = Player_HP_CUR - 5;
+       if (Player_HP_CUR <= 0) {
+          deadflag = 1;
+          "^The last blow from the water spirit was too much for \
+          you, I'm afraid to say. You sink to the ground, to \
+          weak to defend yourself, as the spirit slowly oozes \
+          towards you for the final blow...";
+       } 
+       print "^The water spirit ";
+       if (i==2)
+          "blasts you with a jet of seawater! \
+          It feels like a battering ram just used you for a \
+          practice drawbridge!";
+       if (i==3)
+          "buffets you with small jets of water! \
+          You feel exposed areas of skin getting rubbed raw by \
+          the force of the water!";
+       "forms into a small wave and tries to \
+       crush you, but you evade just in time!";
+       ],
+       before [;
+          Cast:
+            if (the_spell_was == swanko_spell) {
+               remove self;
+               "As you speak the chant, the water spirit falls back \
+               in fear! You finish the chant, and the water spirit \
+               makes one last attempt to smother you, but dissipates \
+               with a splash!";
+            }
+            print "The creature makes a banshee-howl as you chant.^"; 
+       ],
+       life [ ;
+          Attack: 
+            print "You ";
+            if (random(20) >= 8)
+            "strike the water creature, but your attack passes \
+            harmlessly through it! You hear a strange noise from \
+            the creature -- akin to a drowning man laughing.";
+            "attack the water spirit, but miss!";
+          default: "It's too busy trying to kill you.";
+       ],
+   has animate concealed;
+
+Object mad_hermit "mad hermit" FUBLIO_Cave
+   with name "hermit" "madman" "mad",
+        description "He looks quite crazed -- his wild eyes \
+are almost unbearable to watch. His clothes are complete \
+tatters, and he looks rather emaciated.",
+        each_turn [ i ;
+        i = random(10);
+        switch(i) {
+        1: "^The hermit stares at you and screams. \
+~Demon, trickster -- you'll not fool me again!~";
+        2: "^The hermit smiles at you. ~Come to pay \
+your respects to an old man, Humboz? I know it's you.~";
+        3: "^The hermit shrinks into a corner and weeps. ~No more, no more. I \
+can help you no more.~"; 
+        4: "^The hermit hums a little tune.";
+        5: "^The hermit talks to someone or thing unseen. \
+~Closer, closer, nary a sound betray...~";
+        6: "^The hermit grabs your shoulder. ~I am hampered,~ \
+he pleads with you, ~by the lack of an algebraic solution! \
+That was where I went wrong!~";
+        7: "^The hermit babbles something about a shining \
+tower on a hill.";
+        8: "^The hermit pauses. ~Listen, do you hear them? \
+The voices -- everywhere!~";
+        default: "^The hermit giggles for no reason.";
+        }  
+        ],
+        life [;
+          Answer:
+            if (special_word=='hello')
+               "~We meet again, do we not?~";
+          Ask:
+            switch (second) {
+            'exit', 'outside':  "The hermit laughs. \
+~You want to leave already? Very well, you'll find \
+the exit where you came in.~";
+            'entrance': 
+               print "The hermit chuckles. ~Forgotten where \
+you came in? It hasn't gone anywhere.";  
+               if (FUBLIO_Cave.number == 1) {
+                  FUBLIO_Cave.number = 2;
+                  "~ He points at a space in the south wall, which \
+you realize is actually a well-hidden tunnel.";  
+               }
+               else "~";
+          !  'sack': "~A fine pet, mine and mine forever.~";
+            'food', 'fish': "~My friends of the deep, they \
+sacrifice themselves for me, as I will some day for them.~";
+            default: "~Many are the secrets you keep.~";
+            }
+          Give:
+            if (noun has edible) {
+               print "The hermit greedily takes ", (the) noun, " and \
+gobbles it quickly";
+               remove noun;
+               if (p1 in self) {
+                  move p1 to player;
+                  print ". ~Good, yes. \
+I have something for you -- something you will treasure as I have.~ He \
+gives you a piece of parchment.";
+               }
+               "."; 
+            }
+            "~No, no, I already have many of those.~";
+          Attack, ThrowAt, Order:
+            "The hermit cowers in one corner of \
+the cave, screaming. You stop, and reconsider.";
+          Kiss:
+            "Tears run down the hermit's cheek.";
+          Show, Tell:
+            if (noun has edible)
+               "The hermit visibly salivates.";
+            "The hermit gibbers maniacally."; 
+        ],
+        before [;
+           Cast:
+       "The hermit joins in with your chanting, and \
+twists the meaning of the words! You quickly stop.";
+        ],
+        time_left 0,
+        time_out [;
+           deadflag = 1;
+           "^The hermit seems to recognize you through his madness! \
+~You have returned! The Big Man! Biggest of them all! \
+Returned to deliver me from my prison. I had never forsaken \
+you!~^^\
+~Wait,~ you protest, ~stop this madness!~^^\
+But the crazed hermit continues. He prostrates in front \
+of you and babbles incoherently. ~I put all my faith \
+in you -- I have to leave here, before I go insane! \
+The others, they abandoned hope. But not me. No! \
+You have always had our best interests in mind.~^^\
+He begins an eerie, frenetic song that jars your very soul. \
+You watch the water level start to rise near the southern \
+entrance, and wait for the end.";
+        ],           
+   has animate transparent;
+
+
+! ************
+! spells/scrolls
+! ************
+
+Object spotted_scroll "spotted scroll" FUBLIO_Cave
+  class scroll_class,
+  with name "spotted",
+;
+
+Object bekdab_spell "turn iron to rust" spotted_scroll
+  class spell_class,
+  with name "bekdab",
+       magic [;
+             "Your chant goes unanswered. I guess you need pure iron.";
+       ],
+;
+
+! ************
+! Misc objects
+! ************
+
+
+Object sack "fur sack" sailboat
+   with name "sack" "fur",
+        description "A fairly large sack made of furs and animal \
+hides.",
+        ! weight 20, 
+        size 24,
+        ! capacity 20,
+   has container openable;
+
+! (wet -- Anabais is one of four evil elemental powers)
+Object p1 "wet parchment" mad_hermit
+   class parchment_class,
+   with name "wet",
+description "~...evidence that there are more demons like \
+the evil Anabais! In fact, I suspect that four demons, not \
+one, faced the Ancient Ones in spiritual battle at the \
+dawn of time! To suspect this is...~";
+
+
+! 1st rod piece -- GRAY
+Object gray_rod_piece "gray rod piece" In_Lighthouse
+  class rod_class,
+  with name "gray",
+       initial "In the center of the room is a short gray rod.",
+       description "It's a short section of a rod made of some \
+undeterminable hard substance, \
+colored gray like murky water. A piece of the Rod of \
+the Ancients, no doubt!",
+;
+
+! 1st sphere - SILVER
+Object silver_sphere "silver sphere"
+   class sphere_class,
+   with name "silver",
+        description "A tiny perfect silver sphere, made of some strange \
+           unknown metal.",
+;
+
diff --git a/src/GAMBIT2.INF b/src/GAMBIT2.INF
new file mode 100644 (file)
index 0000000..05f4037
--- /dev/null
@@ -0,0 +1,353 @@
+
+! (level 2)
+
+Class Gambit_Room_Lev2_Class
+   with description "You are on the surface of a floating stone \
+cube. You can barely see another cube floating far above you in the \ 
+dim red light that illuminates the entire area.",
+        name "stone" "cube" "light",
+has light;
+
+Object GAMBIT_21 "On Giant White Cube"
+   class Gambit_Room_Lev2_Class
+   with w_to
+        [ i ;
+          i = CheckGambit(n212,n312,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W21;
+        ],
+        s_to 
+        [ i ;
+          i = CheckGambit(n213,n313,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W22;
+        ],
+;
+
+Object GAMBIT_22 "On Giant White Cube"
+   class Gambit_Room_Lev2_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n224,n324,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W21;
+        ],
+        w_to
+        [ i ;
+          i = CheckGambit(n222,n322,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W21;
+        ],
+        s_to 
+        [ i ;
+          i = CheckGambit(n223,n323,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W22;
+        ],
+;
+
+Object GAMBIT_23 "On Giant White Cube"
+   class Gambit_Room_Lev2_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n234,n334,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W21;
+        ],
+        s_to
+        [ i ;
+          i = CheckGambit(n233,n333,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W22;
+        ],
+;
+
+Object GAMBIT_24 "On Giant White Cube"
+   class Gambit_Room_Lev2_Class
+   with w_to
+        [ i ;
+          i = CheckGambit(n242,n342,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W21;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n241,n341,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W22;
+        ],   
+        s_to 
+        [ i ;
+          i = CheckGambit(n243,n343,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W22;
+        ],   
+;
+
+Object GAMBIT_25 "On Giant White Cube"
+   class Gambit_Room_Lev2_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n254,n354,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W21;
+        ],
+        w_to
+        [ i ;
+          i = CheckGambit(n252,n352,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W21;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n251,n351,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W22;
+        ],   
+        s_to 
+        [ i ;
+          i = CheckGambit(n253,n353,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W22;
+        ],   
+;
+       
+Object GAMBIT_26 "On Giant White Cube"
+   class Gambit_Room_Lev2_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n264,n364,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W21;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n261,n361,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W22;
+        ],   
+        s_to 
+        [ i ;
+          i = CheckGambit(n263,n363,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W22;
+        ],   
+;
+
+Object GAMBIT_27 "On Giant White Cube"
+   class Gambit_Room_Lev2_Class
+   with w_to
+        [ i ;
+          i = CheckGambit(n272,n372,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W21;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n271,n371,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W22;
+        ],   
+;
+
+Object GAMBIT_28 "On Giant White Cube"
+   class Gambit_Room_Lev2_Class
+   with w_to
+        [ i ;
+          i = CheckGambit(n282,n382,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W21;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n281,n381,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W22;
+        ],
+        e_to
+        [ i ;
+          i = CheckGambit(n284,n384,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W21;
+        ],
+;
+
+Object GAMBIT_29 "On Giant White Cube"
+   class Gambit_Room_Lev2_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n294,n394,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W21;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n281,n381,2);
+          if (i ~= 2) return i;
+          else return GAMBIT_W22;
+        ],   
+;
+
+
+! (level 2 niches)
+Object n213 "southern niche" GAMBIT_21
+   class niche_class
+   with name "southern",
+        counter_niche n241,
+        niche_dir 3;
+Object n212 "western niche" GAMBIT_21
+   class niche_class
+   with name "western",
+        counter_niche n224,
+        niche_dir 2;
+
+Object n224 "eastern niche" GAMBIT_22
+   class niche_class
+   with name "eastern",
+        counter_niche n212,
+        niche_dir 4;
+Object n223 "southern niche" GAMBIT_22
+   class niche_class
+   with name "southern",
+        counter_niche n251,
+        niche_dir 3;
+Object n222 "western niche" GAMBIT_22
+   class niche_class
+   with name "western",
+        counter_niche n234,
+        niche_dir 2;
+
+Object n234 "eastern niche" GAMBIT_23
+   class niche_class
+   with name "eastern",
+        counter_niche n222,
+        niche_dir 4;
+Object n233 "southern niche" GAMBIT_23
+   class niche_class
+   with name "southern",
+        counter_niche n261,
+        niche_dir 3;
+
+Object n241 "northern niche" GAMBIT_24
+   class niche_class
+   with name "northern",
+        counter_niche n213,
+        niche_dir 1;
+Object n242 "western niche" GAMBIT_24
+   class niche_class
+   with name "western",
+        counter_niche n254,
+        niche_dir 2;
+Object n243 "southern niche" GAMBIT_24
+   class niche_class
+   with name "southern",
+        counter_niche n271,
+        niche_dir 3;
+
+Object n251 "northern niche" GAMBIT_25
+   class niche_class
+   with name "northern",
+        counter_niche n223,
+        niche_dir 1;
+Object n254 "eastern niche" GAMBIT_25
+   class niche_class
+   with name "eastern",
+        counter_niche n242,
+        niche_dir 4;
+Object n252 "western niche" GAMBIT_25
+   class niche_class
+   with name "western",
+        counter_niche n264,
+        niche_dir 2;
+Object n253 "southern niche" GAMBIT_25
+   class niche_class
+   with name "southern",
+        counter_niche n281,
+        niche_dir 3;
+
+Object n264 "eastern niche" GAMBIT_26
+   class niche_class
+   with name "eastern",
+        counter_niche n252,
+        niche_dir 4;
+Object n261 "northern niche" GAMBIT_26
+   class niche_class
+   with name "northern",
+        counter_niche n233,
+        niche_dir 1;
+Object n263 "southern niche" GAMBIT_26
+   class niche_class
+   with name "southern",
+        counter_niche n291,
+        niche_dir 3;
+
+Object n271 "northern niche" GAMBIT_27
+   class niche_class
+   with name "northern",
+        counter_niche n243,
+        niche_dir 1;
+Object n272 "western niche" GAMBIT_27
+   class niche_class
+   with name "western",
+        counter_niche n284,
+        niche_dir 2;
+
+Object n281 "northern niche" GAMBIT_28
+   class niche_class
+   with name "northern",
+        counter_niche n253,
+        niche_dir 1;
+Object n282 "western niche" GAMBIT_28
+   class niche_class
+   with name "western",
+        counter_niche n294,
+        niche_dir 2;
+Object n284 "eastern niche" GAMBIT_28
+   class niche_class
+   with name "eastern",
+        counter_niche n272,
+        niche_dir 4;
+
+Object n291 "northern niche" GAMBIT_29
+   class niche_class
+   with name "northern",
+        counter_niche n263,
+        niche_dir 1;
+Object n294 "eastern niche" GAMBIT_29
+   class niche_class
+   with name "eastern",
+        counter_niche n282,
+        niche_dir 4;
+
+! (level 2 initial wood beam layout)
+
+Object e21 "ebony beam" n282 class ebony_beam_class;
+Object e211 "ebony beam" n294 class ebony_beam_class with number 99;
+
+Object p21 "pine beam" n213 class pine_beam_class;
+Object p211 "pine beam" n241 class pine_beam_class with number 99;
+Object p22 "pine beam" n243 class pine_beam_class;
+Object p221 "pine beam" n271 class pine_beam_class with number 99;
+Object p23 "pine beam" n242 class pine_beam_class;
+Object p231 "pine beam" n254 class pine_beam_class with number 99;
+Object p24 "pine beam" n252 class pine_beam_class;
+Object p241 "pine beam" n264 class pine_beam_class with number 99;
+
+! (side note: with balsa beams, 2nd side need not be 99, since 
+! it will always break on the first try, and the default number is 0
+Object b21 "balsa beam" n212 class balsa_beam_class;
+Object b211 "balsa beam" n224 class balsa_beam_class;
+Object b22 "balsa beam" n222 class balsa_beam_class;
+Object b221 "balsa beam" n234 class balsa_beam_class;
+Object b23 "balsa beam" n223 class balsa_beam_class;
+Object b231 "balsa beam" n251 class balsa_beam_class;
+Object b24 "balsa beam" n233 class balsa_beam_class;
+Object b241 "balsa beam" n261 class balsa_beam_class;
+Object b25 "balsa beam" n253 class balsa_beam_class;
+Object b251 "balsa beam" n281 class balsa_beam_class;
+Object b26 "balsa beam" n263 class balsa_beam_class;
+Object b261 "balsa beam" n291 class balsa_beam_class;
+Object b27 "balsa beam" n272 class balsa_beam_class;
+Object b271 "balsa beam" n284 class balsa_beam_class;
+
diff --git a/src/GAMBIT3.INF b/src/GAMBIT3.INF
new file mode 100644 (file)
index 0000000..a8a534b
--- /dev/null
@@ -0,0 +1,463 @@
+
+! (level 3)
+
+Class Gambit_Room_Lev3_Class
+   with description "You are on the surface of a floating stone \
+cube. The red light from below seems a bit brighter here.",
+        name "stone" "cube" "light",
+has light;
+
+Object GAMBIT_31 "On Giant White Cube"
+   class Gambit_Room_Lev3_Class
+   with w_to
+        [ i ;
+          i = CheckGambit(n312,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W31;
+        ],
+        s_to 
+        [ i ;
+          i = CheckGambit(n313,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W32;
+        ],
+;
+
+Object GAMBIT_32 "On Giant White Cube"
+   class Gambit_Room_Lev3_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n324,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W31;
+        ],
+        w_to
+        [ i ;
+          i = CheckGambit(n322,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W31;
+        ],
+        s_to 
+        [ i ;
+          i = CheckGambit(n323,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W32;
+        ],
+;
+
+Object GAMBIT_33 "On Giant White Cube"
+   class Gambit_Room_Lev3_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n334,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W31;
+        ],
+        s_to
+        [ i ;
+          i = CheckGambit(n333,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W32;
+        ],
+;
+
+Object GAMBIT_34 "On Giant White Cube"
+   class Gambit_Room_Lev3_Class
+   with w_to
+        [ i ;
+          i = CheckGambit(n342,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W31;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n341,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W32;
+        ],   
+        s_to 
+        [ i ;
+          i = CheckGambit(n343,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W32;
+        ],   
+;
+
+Object GAMBIT_35 "On Giant White Cube"
+   class Gambit_Room_Lev3_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n354,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W31;
+        ],
+        w_to
+        [ i ;
+          i = CheckGambit(n352,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W31;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n351,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W32;
+        ],   
+        s_to 
+        [ i ;
+          i = CheckGambit(n353,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W32;
+        ],   
+;
+       
+Object GAMBIT_36 "On Giant White Cube"
+   class Gambit_Room_Lev3_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n364,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W31;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n361,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W32;
+        ],   
+        s_to 
+        [ i ;
+          i = CheckGambit(n363,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W32;
+        ],   
+;
+
+Object GAMBIT_37 "On Giant White Cube"
+   class Gambit_Room_Lev3_Class
+   with w_to
+        [ i ;
+          i = CheckGambit(n372,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W31;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n371,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W32;
+        ],   
+;
+
+Object GAMBIT_38 "On Giant White Cube"
+   class Gambit_Room_Lev3_Class
+   with w_to
+        [ i ;
+          i = CheckGambit(n382,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W31;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n381,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W32;
+        ],
+        e_to
+        [ i ;
+          i = CheckGambit(n384,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W31;
+        ],
+;
+
+Object GAMBIT_39 "On Giant White Cube"
+   class Gambit_Room_Lev3_Class
+   with e_to
+        [ i ;
+          i = CheckGambit(n394,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W31;
+        ],
+        n_to 
+        [ i ;
+          i = CheckGambit(n381,0,3);
+          if (i ~= 2) return i;
+          else return GAMBIT_W32;
+        ],   
+;
+
+
+! (level 3 niches)
+Object n313 "southern niche" GAMBIT_31
+   class niche_class
+   with name "southern",
+        counter_niche n341,
+        niche_dir 3;
+Object n312 "western niche" GAMBIT_31
+   class niche_class
+   with name "western",
+        counter_niche n324,
+        niche_dir 2;
+
+Object n324 "eastern niche" GAMBIT_32
+   class niche_class
+   with name "eastern",
+        counter_niche n312,
+        niche_dir 4;
+Object n323 "southern niche" GAMBIT_32
+   class niche_class
+   with name "southern",
+        counter_niche n351,
+        niche_dir 3;
+Object n322 "western niche" GAMBIT_32
+   class niche_class
+   with name "western",
+        counter_niche n334,
+        niche_dir 2;
+
+Object n334 "eastern niche" GAMBIT_33
+   class niche_class
+   with name "eastern",
+        counter_niche n322,
+        niche_dir 4;
+Object n333 "southern niche" GAMBIT_33
+   class niche_class
+   with name "southern",
+        counter_niche n361,
+        niche_dir 3;
+
+Object n341 "northern niche" GAMBIT_34
+   class niche_class
+   with name "northern",
+        counter_niche n313,
+        niche_dir 1;
+Object n342 "western niche" GAMBIT_34
+   class niche_class
+   with name "western",
+        counter_niche n354,
+        niche_dir 2;
+Object n343 "southern niche" GAMBIT_34
+   class niche_class
+   with name "southern",
+        counter_niche n371,
+        niche_dir 3;
+
+Object n351 "northern niche" GAMBIT_35
+   class niche_class
+   with name "northern",
+        counter_niche n323,
+        niche_dir 1;
+Object n354 "eastern niche" GAMBIT_35
+   class niche_class
+   with name "eastern",
+        counter_niche n342,
+        niche_dir 4;
+Object n352 "western niche" GAMBIT_35
+   class niche_class
+   with name "western",
+        counter_niche n364,
+        niche_dir 2;
+Object n353 "southern niche" GAMBIT_35
+   class niche_class
+   with name "southern",
+        counter_niche n381,
+        niche_dir 3;
+
+Object n364 "eastern niche" GAMBIT_36
+   class niche_class
+   with name "eastern",
+        counter_niche n352,
+        niche_dir 4;
+Object n361 "northern niche" GAMBIT_36
+   class niche_class
+   with name "northern",
+        counter_niche n333,
+        niche_dir 1;
+Object n363 "southern niche" GAMBIT_36
+   class niche_class
+   with name "southern",
+        counter_niche n391,
+        niche_dir 3;
+
+Object n371 "northern niche" GAMBIT_37
+   class niche_class
+   with name "northern",
+        counter_niche n343,
+        niche_dir 1;
+Object n372 "western niche" GAMBIT_37
+   class niche_class
+   with name "western",
+        counter_niche n384,
+        niche_dir 2;
+
+Object n381 "northern niche" GAMBIT_38
+   class niche_class
+   with name "northern",
+        counter_niche n353,
+        niche_dir 1;
+Object n382 "western niche" GAMBIT_38
+   class niche_class
+   with name "western",
+        counter_niche n394,
+        niche_dir 2;
+Object n384 "eastern niche" GAMBIT_38
+   class niche_class
+   with name "eastern",
+        counter_niche n372,
+        niche_dir 4;
+
+Object n391 "northern niche" GAMBIT_39
+   class niche_class
+   with name "northern",
+        counter_niche n363,
+        niche_dir 1;
+Object n394 "eastern niche" GAMBIT_39
+   class niche_class
+   with name "eastern",
+        counter_niche n382,
+        niche_dir 4;
+
+! (level 3 initial wood beam layout)
+! wood beam, as two 'halves'
+
+Object p31 "pine beam" n322 class pine_beam_class;
+Object p311 "pine beam" n334 class pine_beam_class with number 99;
+
+! (side note: with balsa beams, 2nd side need not be 99, since 
+! it will always break on the first try, and the default number is 0
+Object b31 "balsa beam" n312 class balsa_beam_class;
+Object b311 "balsa beam" n324 class balsa_beam_class;
+Object b32 "balsa beam" n313 class balsa_beam_class;
+Object b321 "balsa beam" n341 class balsa_beam_class;
+Object b33 "balsa beam" n323 class balsa_beam_class;
+Object b331 "balsa beam" n351 class balsa_beam_class;
+Object b34 "balsa beam" n333 class balsa_beam_class;
+Object b341 "balsa beam" n361 class balsa_beam_class;
+Object b35 "balsa beam" n342 class balsa_beam_class;
+Object b351 "balsa beam" n354 class balsa_beam_class;
+Object b36 "balsa beam" n352 class balsa_beam_class;
+Object b361 "balsa beam" n364 class balsa_beam_class;
+Object b37 "balsa beam" n343 class balsa_beam_class;
+Object b371 "balsa beam" n371 class balsa_beam_class;
+Object b38 "balsa beam" n353 class balsa_beam_class;
+Object b381 "balsa beam" n381 class balsa_beam_class;
+Object b39 "balsa beam" n363 class balsa_beam_class;
+Object b391 "balsa beam" n391 class balsa_beam_class;
+Object b3a "balsa beam" n372 class balsa_beam_class;
+Object b3a1 "balsa beam" n384 class balsa_beam_class;
+Object b3b "balsa beam" n382 class balsa_beam_class;
+Object b3b1 "balsa beam" n394 class balsa_beam_class;
+
+
+! extra goodies...
+
+Object Gambit_hole "large round hole" GAMBIT_37
+   with name "hole" "round",
+        initial "In the center of the room is a large round \
+hole, going straight down through the floating cube.",
+        description "A large round hole cut straight through the \
+giant cube you stand on. All you need is a huge square peg.",
+        size 30,
+        before [;
+          Enter:
+            if (fire_spirit in GAMBIT_37)
+               "The towering fire spirit blocks your way!";
+            print "^You close your eyes and jump straight \
+into the hole! There is a bright flash of light...^";
+            Achieved(5);
+            PlayerTo(GAMBIT_11);
+            return 2;
+          Receive:
+            if (fire_spirit in GAMBIT_37)
+               "The towering fire spirit is in your way!";
+            move noun to GAMBIT_11;
+            print "You drop "; DefArt(noun); 
+            " into the hole. There is a bright flash of light, and \
+the object disappears!";
+          Rub, Push, Pull, Touch, Squeeze, Turn, Shake:
+"I don't know how to do that to a giant hole.";
+        ],
+        after [;
+          Search:
+             if (fire_spirit in GAMBIT_37)
+               "The towering fire spirit fills the hole currently!";
+else "Looking through the hole, you can see a reddish haze \
+far below.";
+        ],
+   has static container open enterable;
+
+! rod piece -- SMOKE
+Object smoke_rod_piece "smoke rod piece" GAMBIT_37
+  class rod_class,
+  with name "smoke",
+       initial "Sitting on the floor is a short smoke-colored rod.",
+       description "It's a short section of a rod made of some \
+undeterminable hard substance, \
+colored smoke. A piece of the Rod of \
+the Ancients, no doubt!",
+;
+
+
+Object fire_spirit "fire spirit" GAMBIT_37
+  with name "spirit",
+       description "It looks like a tower of animated flame.",
+       each_turn [ i ;
+       ! spirit attack
+       ! (in general, the 4 spirits are _very_ dangerous.
+       ! There's a 1/5 chance of killing outright, and 2
+       ! chances of doing 10 and 5 points of damage respectively.
+       ! In short, the player needs to realize it's time to swanko,
+       ! and do so, quickly)
+       if (self hasnt general) {
+            give self general ~concealed;    
+            "^Suddenly, a flash of flame bursts through the hole \
+in the center of the cube! A living tower of flame attacks!";            
+       }
+       i = random(5);
+       if (i == 1) {
+          deadflag = 1;
+          "^The fire creature engulfs you in a deadly inferno! \
+You are burned to a crisp.";          
+       }
+       if (i == 2) 
+          Player_HP_CUR = Player_HP_CUR - 10;
+       if (i==3) 
+          Player_HP_CUR = Player_HP_CUR - 5;
+       if (Player_HP_CUR <= 0) {
+          deadflag = 1;
+          "^The last blow from the fire spirit was too much for \
+you, I'm afraid to say. The spirit senses your \
+weakness and engulfs you in flame.";          
+       } 
+       print "^The fir spirit ";
+       if (i==2)
+          "singes you with a jet of fire!";
+       if (i==3) {
+          "sends a small ball of \
+flame your way! You get slightly burned!";          
+       }
+       "tries to torch you in a sheet of \
+flame, but you evade just in time!";       
+       ],
+       before [;
+          Cast:
+            if (the_spell_was == swanko_spell) {
+               remove self;
+               "As you speak the chant, the fire spirit falls back \
+in fear! You finish the chant, and the fire spirit \
+dissipates into harmless smoke, banished!";
+            }
+            print "Crackling flame drowns out your chant.^";
+       ],
+       life [ ;
+          Attack: 
+            if (random(20) >= 8)
+            "You strike the fire creature, but your attack passes \
+            harmlessly through it! You hear a crackling noise \
+that could pass for laughter.";            
+            "You attack the fire spirit, but miss!";
+          default: "It's too busy trying to kill you.";
+       ],
+   has animate concealed;   
diff --git a/src/GURTH.INF b/src/GURTH.INF
new file mode 100644 (file)
index 0000000..8d420a0
--- /dev/null
@@ -0,0 +1,925 @@
+
+! **************************************************************
+! GURTH.INF -- Add-on for SPIRITWRAK
+! (all rights reserved, copyright 1996, D. Yu
+! **************************************************************
+
+! (author note to self -- Gurth currently isn't going to be too
+! exciting -- I'm running out of .z5 code space.  The main 
+! planned features are:
+!   1) The abandoned house with the oven for baking the cake
+!   2) A deep forest area somewhat north of the city where
+!      a sphere piece will be hidden  
+
+! The string array for labels on the GUE Oven dial (may be changed)
+Array OVEN_settings table [;
+   "Warm Soup"; 
+   "Hot Chocolate"; 
+   "Pizza"; 
+   "Cake";
+   "Fish";
+   "Roast Chicken";
+   "Baked Potato";
+   "Rib Roast";
+   "Thermo-nuclear Flash";
+];
+
+Object GURTH_GUSStop "Gurth City Streets"
+   with description "A foggy sky covers the ever-busy city of \
+Gurth. A road heads southeast into a larger \
+portion of the city, and stairs lead down here.",
+        name "fog" "sky" "road" "stairs",
+        d_to GURTH_GUSStation,
+        se_to GURTH_NDistrict,
+   has light;
+
+Object umbrella "umbrella" GURTH_GUSStop
+   with name "umbrella",
+        description [;
+           if (self has open)
+              print "An open";
+           else print "A closed";
+           " black-cloth umbrella.";
+        ],
+        !weight 25,
+        size 16,
+        article "an",
+        before [;
+           Open:
+              if (parent(self) == player) {
+              give self open;
+              umbrella.size = 20;
+              "You snap the umbrella open.";
+              }
+              else "You need to be holding the umbrella to do that.";
+           Close:
+              if (parent(self) == player) {
+              give self ~open;
+              umbrella.size = 16;
+              "You snap the umbrella closed.";
+              }
+              else "You need to be holding the umbrella to do that.";
+        ],
+   has openable;
+
+Object GURTH_NDistrict "North District"
+   with description "Probably the safest district in Gurth, the \
+North District is mostly cobblestone roads and barricaded \
+buildings. A main road heads south, or forks northwest and \
+northeast.",
+        name "cobblestone" "buildings" "road",
+        nw_to GURTH_GUSStop,
+        s_to GURTH_MDistrict,
+        ne_to GURTH_Forest,
+   has light;
+
+Object GURTH_Forest "Forest Edge"
+   with description "Dark forest meets dark city outskirts here. \
+The only exit is along an old path to the southwest -- \
+the forest is too thick for travel otherwise. \
+Rain falls periodically from a dark stormy sky.",
+        name "forest" "path" "rain",
+        sw_to GURTH_NDistrict,
+        each_turn [;
+        if (random(10) < 4) {
+           "^A rumble of thunder booms overhead.";
+        }
+        ],
+        before [;
+           Listen:
+              if (Treant in GURTH_Forest)
+                 "You hear muffled cries for help from \
+somewhere inside the log cabin!";
+        ],
+   has light;
+
+Object storm1 "storm" GURTH_Forest
+   with name "storm" "clouds" "sky" "dark",
+        description "It does look a bit stormy overhead.",
+        before [;
+           Cast:
+              if (the_spell_was == shazok_spell) {
+                 print "A bolt of lightning rips down from the \
+clouds overhead as you finish your chant! It strikes ";
+                 if (Treant in GURTH_Forest) {
+                    print "the angry treant! \
+A portion of its top branches catch fire! Howling in pain, \
+the creature runs off into the woods and disappears!";
+                    SaveWoodsman();
+                    rtrue;
+                 }
+                 else {
+                    deadflag = 1;
+                    "you, frying you to a crisp!";
+                 }
+              }
+        ],
+   has scenery;
+
+Object Treant "angry treant" GURTH_Forest
+   with name "treant" "angry" "blighted",
+        description "Treants are basically animated trees. They \
+are considered mythical creatures, usually solitary and quite \
+rare. This particular treant looks similar to a great elm tree. \
+You notice that it seems covered with spots of some sort of \
+blight.",
+   article "an",
+   each_turn [ i ;
+     i = random(20);
+     print "^The treant ";
+     if (i > 10) {
+        if (WOOD_House.number == 3) {
+           WOOD_House.number = 4;
+           remove self;  
+           "pounds the cabin, and it collapses into \
+splinters! The treant grabs a hapless woodsman from the \
+wreckage and stalks off into the forest with his victim!";
+        }
+        else {
+          WOOD_House.number = WOOD_House.number + 1;
+          "hammers on the house and you hear a \
+crack! The cabin sustains some damage!";
+        }        
+     }
+     else "angrily attacks the wood cabin, which shakes \
+with the continued blows.";
+   ],        
+   before [;
+      Cast:
+         if (the_spell_was == egdelp_spell) {
+            deadflag = 1;
+            "The treant is covered with a waxy buildup, which \
+washes off in the rain. The treant, already \
+rather incensed, turns his attentions to you and mauls you \
+with two giant branches/arms.";
+         }
+         if (the_spell_was == throck_spell) {
+            deadflag = 1;
+            "The treant grows a bit bigger. His current bad \
+mood seems to increase proportionately! He turns his attentions \
+to you and pounds you with two huge branches/arms.";
+         }
+         if (the_spell_was == taclor_spell) {
+            print "The treant seems to turn a shade of deep \
+green, and the patches of blight disappear! The ancient tree \
+creature pauses, regards you solemnly, and then walks \
+off into the forest.";
+            SaveWoodsman();
+            rtrue;
+         } 
+   ],
+   has animate;
+
+Object WOOD_House "log cabin" GURTH_Forest
+   with name "cabin" "log" "house",
+        description [; 
+            print "A small house built of logs";
+            switch (self.number) {
+            0: print ".";
+            1: print ". It looks slightly damaged.";
+            2: print ". It looks partially damaged, the roof logs \
+are broken in several places.";
+            3: print ". It looks very damaged. One wall is \
+nearly broken through.";
+            default: print " that has collapsed into little more \
+than a pile of broken logs."; 
+            } 
+            if (self has general)
+               " You notice some area of wood have spots of wax \
+on them.";
+            new_line;
+            rtrue;
+        ],
+        before [;
+           Enter:
+              if (Treant in GURTH_Forest)
+              "The angry treant seems to be in the way.";
+              "It's just a tiny log cabin that probably \
+has nothing interesting inside.";
+           Cast:
+              if (the_spell_was == egdelp_spell) {
+                 give self general;
+                 "The outside of the cabin is now covered \
+with spots of waxy buildup.";
+              }
+        ],
+        number 0,
+   has static;
+
+[ SaveWoodsman ;
+   remove Treant;
+   move red_sphere to player;
+   "^^Moments later, a woodsman appears from the battered log \
+cabin. ~Much thanks, sir,~ he says. ~Appears I mistook that \
+treant for a dead tree and tried to cut it down. Can't say \
+he took it too well.~ he says sheepishly. ~Say, you don't \
+look like you're from around these parts. Kinda like this \
+funny thing I found in the woods the other day.~ He hands \
+you a strange round object. ~Maybe you know what to do with \
+it?~ He hefts a small hatchet over his shoulder. ~Well, \
+back to do a little logging,~ he says, as he walks off into the \
+deep forest, whistling.";
+];
+
+Object GURTH_MDistrict "Market District"
+   with description "The famous Gurth Market District is as noisy, \
+crowded, and dangerous as it ever was. A cobblestone road heads \
+north and south here.",
+        name "cobblestone" "road",
+        n_to GURTH_NDistrict,
+        s_to GURTH_SDistrict,
+        e_to "~Get out 'o me way!~ some rude fellow says as you \
+try to pass.",
+        w_to "~No push'n, no shov'n!~ some old hag screams at you, \
+and promptly shoves you back.",
+        each_turn [;
+           if ((random(10) < 5) && (self hasnt general)) {
+              give self general;
+              move c7 to self;
+              "^A clumsy hawker stumbles into you as he \
+crosses the street, hustling off without so much as an \
+apology. You notice he dropped something in his hurry.";
+           }
+        ],
+        has light;
+
+Object c7 "coin" class coin_class;
+
+Object GURTH_SDistrict "South District"
+   with description "The general gloomy atmosphere is more noticeable \
+than ever here, in the extremely dangerous South District. The \
+general area is filled with boarded-up houses, and a few shifty-eyed \
+characters are the only people milling about here. A road leads \
+north. To the east is an abandoned flat, probably in better shape \
+than the rest.",
+        name "houses" "characters" "people" "road" "flat",
+        n_to GURTH_MDistrict,
+        s_to [;
+           print "You wander down ";
+           if (random(20) == 5) {
+              deadflag = 1;
+              "a back alleyway, and are immediately \
+assaulted by a group of vicious thugs, who batter you senseless.";
+           }
+           else "an alleyway, find a dead-end, and return \
+here.";
+        ],
+        w_to [;
+           print "You wander down ";
+           if (random(20) == 5) {
+              deadflag = 1;
+              "a sidestreet, and are immediately \
+assaulted by a group of vicious thugs. One of them seems to \
+recognize you. ~That's the Preacher-man who got Davey arrested! \
+Let's show 'em what we think'o that!~ They proceed to beat you senseless.";
+           }
+           else "a sidestreet, find a dead-end, and return \
+here.";
+        ],
+        e_to GURTH_House,
+   has light;
+
+Object GURTH_House "Front of House"
+   with description "You're standing at the rotting front steps of \
+a small flat. The front door to the east has been battered down and \
+you could probably walk right in, or return to the street to \
+the west.",
+        name "street" "steps" "flat",
+        w_to GURTH_SDistrict,
+        e_to House_Ent,
+        in_to House_Ent,
+   has light;
+
+Object GURTH_House2 "Front of House"
+   with description  "You're standing near a small construction site. \
+A city street lies west, and a construction ditch is east.",
+        name "street" "ditch",
+        w_to [;
+               deadflag = 1;
+              "You step into the street, and several locals \
+give you strange looks. The surrounding neighborhood seems \
+new and busy -- various construction sites mark the \
+work of enterprising shop-keepers of the area.^^\
+~Watch out there!~ someone cries. A sudden \
+pile of bricks falls from a nearby scaffolding, and \
+crushes you.";
+        ],
+        e_to Construction_site,
+   has light;                      
+
+
+Object bad_brick "dusty brick" GURTH_House2
+   with name "brick" "dusty" "old",
+        initial "An old discarded brick lies nearby.",
+        description "An old brick, slightly cracked in several places.",
+        size 15,
+        time_left 0,
+        time_out [;
+           ! Construction Worker appears
+           if ((good_brick in Construction_site) || 
+               ((good_brick notin Construction_site) && 
+                (bad_brick notin Construction_site))) {
+              remove good_brick; 
+              foundation_wall.number = 1;
+           }
+           else {
+              remove bad_brick;
+              foundation_wall.number = 2;
+           }
+           if (location == Construction_site) {
+              print "^From behind some scaffolding, a construction \
+worker appears. He walks to a part of the ditch and starts to \
+make some finishing touches on part of a low wall. \
+He finds a brick nearby and applies it to the wall with \
+a good patch of mortar.";
+              if (foundation_wall.number == 1) 
+" Brushing himself off, he walks off \
+and is soon out of sight.";
+              else 
+" He looks at the patch somewhat \
+unsatisfied, but shrugs, and walks off, soon out of sight.";
+           }
+           else 
+              "^You hear some brief noises from the east."; 
+        ],
+;
+
+Object Construction_site "Construction Site"
+with description "This is a long square ditch that is \
+likely to be the starting point for some building. It is \
+framed by wood slats and short brick walls. The only way \
+out is to the west.",
+   name "ditch" "slats" "wood",
+   w_to GURTH_House2,
+   has light;
+
+Object good_brick "thick brick" Construction_site
+   with name "brick" "thick",
+        !weight 30, 
+        size 15,
+        initial "A thick brick lies nearby.",
+        description "A thick brick, solid as a rock.",
+;
+
+Object foundation_wall "portion of wall" Construction_site
+   with name "wall" "foundation" "portion" "hole" "recess",
+        initial "You notice a foundation side wall \
+in the ditch.",
+        number 0,
+        size 15,
+        description [;
+           switch (self.number) {
+           0: "It looks somewhat unfinished. Part of it \
+is open into a dark recess in the side of the ditch.";
+           1: "The wall is a finished work of brick and \
+mortar. It looks quite strong.";
+           2: "The wall is a finished work of brick and \
+mortar. You see a spot where the brickwork seems a bit \
+lower in quality.";
+           } 
+        ],
+        before [;
+           Receive:
+              if (self.number > 0)
+                 "The wall is currently sealed shut.";
+              else {
+                 move noun to self;
+                 print "You put ", (the) noun, " into the ";
+                 "small hole in the wall.";
+              }
+           Search, LetGo:
+              if (self.number > 0)
+                 "The wall is currently sealed shut.";
+           Attack:
+              if (self.number == 0) {
+                 deadflag = 1;
+                 "You kick at the wall. Unfortunately, it wasn't \
+all that stable, and the wall falls apart, burying you under a \
+pile of loose bricks.";
+              } 
+              if (self.number == 1) {
+                 remove foundation;
+                 print "You try to break the wall, but only end up \
+hurting your hand. ";
+              }
+              else {
+              give foundation general;
+              print "You knock on the weak portion of the \
+wall, and produce a slight crack, that no doubt will \
+cause the homeowners some worry in the future. ";
+              }
+!              give GURTH_House ~general;
+              while (child(player) ~= 0) remove child(player);
+!              while (child(GURTH_House) ~= 0) remove child(GURTH_House);
+print "The wall seems to start to glow a purple color, and you \
+step back, to find your surroundings replaced by cold natural \
+cave walls.^";
+              Mystical_Cave.number = Mystical_Cave.number + 1;
+              PlayerTo(Mystical_Cave);
+              rtrue;
+        ],
+   has static container open;
+
+Object House_Ent "Entrance Room"
+   with description "A bare room, with peeling paint and rotting, \
+water-stained walls. There's a room to the east, and a rickety \
+stairway down. The outdoors lie west.",
+        name "paint" "stairway" "outdoors",
+        e_to House_Kitchen,
+        d_to House_Basement,
+        w_to GURTH_House,
+        out_to GURTH_House,
+   has light;
+
+Object House_Basement "Basement"
+   with description "A musty, smelly basement. Stairs head up.",
+        name "stairs",
+        u_to House_Ent,
+        before [;
+           Smell: "It's smells musty down here, as though \
+the place has been unused for quite some time.";
+        ],
+;
+
+Object House_switchbox "dusty metal box" House_Basement
+   with name "dusty" "metal" "box",
+        when_closed "There's a dusty metal box attached to the wall here.",
+        when_open [ x;
+         print "There's an open metal box attached to the wall here. ";
+         x = children(self);
+         if (x == 0) "It seems to be empty.";
+         print "It contains:^";
+         x = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
+         WriteListFrom (child(self), x, 1); 
+         rtrue;
+        ],
+        capacity 3,
+        size 10,
+        description "A dusty metal box, attached to the wall.",
+        before [;
+           Open, Push, Pull, Turn, Touch:
+              if (GHOST in House_Basement)
+                 "Slowly, but quite deliberately, the zombie \
+prevents you from getting near the box.";
+        ],
+   has static container openable;
+
+
+Object wire "thin wire" House_switchbox
+   with name "wire" "thin",
+        ! initial "Inside the box is a loose wire.",
+        description "A thin stiff string of metal.",
+        !weight 2,
+        size 1,  ! must fit in subway gate slot...
+        before [;
+          Cast:
+if ((the_spell_was == huncho_spell or luncho_spell) &&
+   (self hasnt general))
+"Your chant goes unanswered.";
+          Take, Push, Pull, Touch, Rub, Squeeze:
+             if (self hasnt general) {
+                if (rubber_gloves has worn) {
+                   if (action==##Take) give self general;
+                   print "As you touch the wire, you notice a \
+bright spark! Good thing you were wearing rubber gloves! ";
+                }
+                else {
+                   print "As your fingers get near the wire, \
+a bright spark of electricity ";
+                   if (random(10) < 4) {
+                   deadflag = 1;
+                   move GHOST to House_Basement;
+"arcs into your hand! The results are quite shocking, I'm afraid.";
+                   }
+                   else
+"flashes near your fingers! You pull back just in time.";
+                }
+             }
+        ],
+;        
+
+Object foundation "foundation" House_Basement
+   with name "foundation" "break" "hole",
+        initial "A large break in the wall exposes a good portion of \
+        the house's foundation.",
+        description "Water damage, or simply age, has exposed a large \
+        hole in one of the walls, through which you can see exposed \
+        wood and brick, part of the foundation of the house.",
+        before [;
+           Receive:
+              "No need to put things in the foundation like that.";
+           Search:
+              if (self hasnt general)
+                 "You briefly search the decaying foundation, but find nothing.";
+              else {
+                 print "You dig around in a familiar spot in the hole ";
+                 give self ~general;
+                 if (children(foundation_wall) == 0)
+                    "but find nothing.";
+                 Achieved(17);
+                 while (child(foundation_wall) ~= 0)
+                     move child(foundation_wall) to House_Basement;
+                 "and find something!"; 
+              }
+        ],
+   has static;
+   
+Object House_Kitchen "Kitchen"
+   with description "You're in the kitchen, by the looks of things. \
+Some broken cabinets are on the wall. Light from partially boarded-up \
+windows lets you see the rotting wood floors. Rooms lie to the \
+north and west.",
+        name "cabinets" "windows" "wood",
+        w_to House_Ent,
+        n_to House_Pantry,
+   has light;
+
+! (An oven, a typical inform object)
+Object OVEN "GUE-Automatic oven" House_Kitchen
+   with name "oven" "GUE-Automatic",
+        when_closed "Strangely untouched and undamaged, a GUE-Automatic oven is \
+sitting closed in a corner of the room.",
+        capacity 1,
+        when_open [ x;
+         print "Strangely untouched and undamaged, a GUE-Automatic oven is \
+sitting open in a corner of the room.";
+         x = children(self);
+         if (x == 0) " It seems to be empty.";
+         print "  It contains:^";
+         x = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
+         WriteListFrom (child(self), x, 1); 
+         rtrue;
+        ],
+        size 15,
+        description "A FrobozzCo best-seller -- this small green oven is \
+perfect for those adventurers who want a home-cooked meal, but are short \
+on time and space. There's a dial and a button \
+on the top.",
+        before 
+        [ x ;
+           Open:
+              if (self hasnt open) {
+              give self open;
+              print "You open the oven, ";
+              x = children(self);
+              if (x==0) "which is empty.";
+              print "revealing:^";
+              x = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
+              WriteListFrom (child(self), x, 1); 
+              rtrue; }             
+        ], 
+        add_to_scope oven_dial oven_button,
+   has static container openable;
+            
+Object oven_dial "oven dial" 
+   with name "dial",
+        number 5,
+        description [;
+          print "A round dial with small printed words. A line on the \
+oventop marks which dial setting is currently active, which at the \
+moment is ~", (string) OVEN_settings-->(oven_dial.number); "~.";
+        ],
+        before [;
+          Turn:
+            oven_dial.number = oven_dial.number + 1;
+            if (oven_dial.number > 9) oven_dial.number = 1;
+            print "The line is now pointing to ~", (string) OVEN_settings-->(oven_dial.number);
+            "~ on the dial.";
+          SetTo:
+            "The dial has somewhat unusual \
+settings. You'll need to turn to the one you want.";
+        ],
+   has static;
+
+Object oven_button "oven button" 
+   with name "button" "black",
+        number 0,
+        description "A small round black button on the top of the oven.",
+        before [;
+           Push:
+              if (OVEN has open)
+                 "There is an irritated buzz.";
+              else {
+                 print "You press the button and hear a low spinning noise. \
+Suddenly, the oven makes a ";
+              if (oven_dial.number == 9) {
+                 ! Ye old nuclear flash setting
+                 if (children(OVEN) ~= 0)
+                    remove child(OVEN);       
+"tremendous 'bang', and nearly springs off \
+the floor! A bright flash of light seems to originate from somewhere \
+inside the oven! Then, just as suddenly, everything is quiet again.";
+              } 
+              ! check object in oven
+              ! if obj exists, check for edible
+              ! or cake, mutate appropriately.
+              if (children(OVEN) ~= 0) {
+                 if ((Baking_Pan in oven) && (cake in Baking_Pan)) {
+                    ! we're no doubt cooking the cake again.
+                    ! as a nice feature of the GUE auto, if the cake
+                    ! was undone, and the oven setting == 4, give
+                    ! the cake the 'done' result
+                    if ((cake.number == 1) && (oven_dial.number == 4))
+                       cake.number = 0;
+                    ! otherwise, nothing changes
+                 }
+                 if ((Baking_Pan in oven) && (dough in Baking_Pan)) {
+                    ! first, check oven setting (too cold or too hot)
+                    ! if setting ok, check number of times folded
+                    ! (too few, too many).  Move 'cake' to pan, make
+                    ! dough child of cake, and set the 'result' number
+                    ! of cake accordingly (0, ok, 1 underdone, 2
+                    ! overdone, 3 underfolded, 4 overfolded) 
+                    ! (assumption is that dough will be only thing
+                    ! in pan [add's are trapped by dough]
+                    move dough to cake;   ! Zen cooking...
+                    move cake to Baking_Pan;
+                    if (oven_dial.number == 4) {
+                       if (dough.number < 83)
+                          cake.number = 3;
+                       if (dough.number > 83)
+                          cake.number = 4;
+                       else cake.number = 0;   ! well done baker
+                    }
+                    else {
+                       if (oven_dial.number < 4)
+                          cake.number = 1;
+                       if (oven_dial.number > 4)
+                          cake.number = 2;
+                    } 
+                 }
+              }
+"a loud 'pop' and nearly springs off \
+the floor! Then, just as suddenly, everything is quiet again.";
+              }
+        ],
+   has static;
+
+Object House_Pantry "Pantry"
+   with description "This was once probably a pantry of some \
+sort. It's now a bare closet-sized room. The exit is south.",
+   s_to House_Kitchen,
+   has light;
+    
+Object Baking_Pan "baking pan" House_Pantry  
+   with name "pan" "baking",
+        description "It's a nice round flat-bottomed ceramic pan.",
+        capacity 20,
+        !weight 10,
+        size 14,
+        before 
+        [ i ;
+          Mix:
+             if (children(Baking_Pan) == 0)
+                "There doesn't seem to be anything in the pan to mix.";
+             else {
+                if (cake in Baking_Pan)
+                   "You can't mix anything with the already baked cake in the pan.";
+                ! if the dough is already in the pan, add the 
+                ! 'new children', if any
+                if (dough in Baking_Pan) {
+                   i = 0;
+                   move dough to OVEN;  ! Temp
+                   while (child(Baking_Pan) ~= 0) {
+                         i = i + 1;
+                         move child(Baking_Pan) to dough;
+                   }
+                   move dough to Baking_Pan;
+                   if (i == 0) 
+                      "You need to add something to the pan if you \
+want to mix something new into the dough.";
+                   "You mix in the new ingredients into the dough.";
+                }
+                ! Minimally, if the flour, butter and egg are in the 
+                ! pan, 'dough' will be produced 
+                if ((flour notin Baking_Pan) || 
+                    (corbie_egg notin Baking_Pan) ||
+                    (butter notin Baking_Pan))
+                   "You mix the contents of the pan around a bit, but \
+some things don't quite coagulate, and the contents remain unmixed.";
+                else {
+                   while (child(Baking_Pan) ~= 0) {
+                        move child(Baking_Pan) to dough;
+                   }
+                   move dough to Baking_Pan;
+                   "You start mixing. Like magic, in short time you \
+have a doughy mixture in the pan."; 
+                } 
+             }
+          LetGo:
+             if (noun == dough or cake) { 
+                CDefArt(noun); " is stuck fast in the pan and \
+                you can't get it out.";
+             }
+             else {
+             ! we've modified certain ingredient objs that we want \
+             ! to 'preserve' in the pan.
+                if ((noun == flour) || (noun == sugar_cube) ||
+                    (noun == baking_powder) || (noun == butter) ||
+                    (noun == corbie_egg) || (noun==dornberries)) 
+                   "It's somewhat scattered about in the pan right \
+now, and you can't quite remove it cleanly.";
+             }
+          Receive:
+             if (cake in self)
+                "The cake takes up the entire space in the pan.";
+             ! -- trap and nicely parse putting
+             ! ingredients in pan, will require modifying 
+             ! 'short_name's of various ingredients.
+             if (noun == flour) {
+                flour.short_name = "pile of flour";
+                move flour to Baking_Pan;
+                flour.description = "A heap of white flour.";
+                "You break open the bag and add the flour to the pan."; 
+             }
+             if (noun == sugar_cube) {
+                sugar_cube.short_name = "quantity of sugar";
+                move sugar_cube to Baking_Pan;
+                sugar_cube.description = "Some sugar scattered about.";
+                "You crumble the sugar cube into the pan.";
+             }
+             if (noun == baking_powder) {
+                baking_powder.short_name = "small sprinkling of baking powder";
+                move baking_powder to Baking_Pan;
+                baking_powder.description = "A small pile of very fine white powder.";
+                "You open the packet and add the powder to the pan.";
+             }
+             if (noun == corbie_egg) {
+                corbie_egg.short_name = "bit of raw egg";
+                move corbie_egg to Baking_Pan;
+                corbie_egg.description = "The yolk and the white parts from an egg.";
+                "You crack the egg and drop the gooey contents into the \
+                pan, discarding the shell.";
+             }
+        ],
+   has container open;
+
+Object pan_sticker "sticker" Baking_Pan
+   with name "sticker",
+        initial "There's a sticker stuck to the bottom of the pan.",
+        description "\
+Frobozz Magic Baking Pan^^\
+HELLO, BAKER!^^\
+To mix ingredients placed in pan, simply say 'MIX PAN'. \
+Baked goods should be removed with a Frobozz Magic \
+Spatula.",
+        !weight 1,
+        size 5,
+;
+
+Object dough "lump of dough"
+   with name "dough",
+        number 0,   ! equals the number of times folded
+        !weight 10,
+        size 14,
+        description "It looks like a nice beige lump of uncooked dough.", 
+        before [;
+          Eat, Taste:
+             if (action==##Eat) remove self;
+             "Ugg. Raw dough.";
+          Cast:
+             if (the_spell_was == gloth_spell) {
+                dough.number = dough.number + 83;
+                if (dough.number > 500) dough.number = 500;
+                "As you speak the chant, the dough seems to \
+twinkle! With a sudden puff of flour, the dough spins and \
+neatly kneads itself many times!";
+             }
+          Fold:
+             dough.number = dough.number + 1;
+             print "You roll up your sleeves and start kneading. \
+The dough "; 
+             if (dough.number > 500) dough.number = 500;
+             if (dough.number < 50)
+                "folds easily.";
+             if (dough.number > 200)
+                "has the consistency of a soft rock.";
+             "is pliable.";
+        ], 
+   has edible;
+
+Object cake "cake" 
+   with name "cake",
+        number 0,  
+! number = condition:
+! 0 ok, 1 undercooked, 2 overck, 3 underfld, 4 overfld
+        description [;
+              print "It's a ";
+              switch (cake.number) {
+                1: "somewhat raw-looking cake.";
+                2: "nice-looking cake, except that it \
+looks a little burned.";
+                default: "nice-looking cake.";
+                ! The player will have to taste the cake to check the
+                ! 'fold quality'.
+              }
+        ],
+        before [;
+           Eat:
+                remove self;
+                "Not bad. Unfortunately, it looks like you can't have \
+your cake and eat it too.";
+           Taste:
+              print "You taste a tiny bit of the cake. ";
+              switch (cake.number) {
+                1: "It tastes a bit underdone.";
+                2: "It tastes a little burned.";
+                3: "It's a little too soft.";
+                4: "It's a bit tough.";
+                default: "It tastes great!";
+              }
+           ], 
+        !weight 10,
+        size 14,
+   has edible;
+
+
+
+! ***************
+! animated beings
+! ***************
+
+Object GHOST "frightening zombie" House_Basement
+   with name "zombie" "frightening",
+        description "A frightening gaunt member of the \
+living dead, with pale skin, and even paler eyes.",
+        before [;
+           Cast:
+              if (the_spell_was == wigro_spell) {
+                 remove self;
+                 "The zombie crumbles into dust, turned.";
+              }
+        ],
+        life [;
+           ThrowAt:
+              if (noun==holywater) {
+                 remove holywater; remove self;
+                 "The vial breaks into shards, scattering \
+holy water all over the zombie. The zombie shrieks, and \
+crumbles into dust."; 
+              }
+           Attack: "Your attack knocks it back, but it \
+seems completely unharmed, somehow!";
+           Give:
+if (noun==rubber_gloves) {
+   move wire to House_Basement;
+   move rubber_gloves to House_Basement;
+   give rubber_gloves ~worn;
+   give wire general;
+   give House_switchbox open;
+   remove self;
+   "The zombie seems to regard the gloves, and slowly puts \
+them on. It proceeds to open the metal box and remove a \
+loose wire, producing a few sparks in the process. Finally, \
+it places the loose wire on the floor, satisfied. It \
+slowly crumbles into dust, but you just manage to hear, \
+~Thanks, I've been trying to get rid of that wire for ages,~ \
+in the faintest of whispers.";
+}    
+           default: "Zombies are usually not very responsive to \
+those among the living. This one is no exception.";
+        ],
+   has animate;
+
+! ***************
+! spells/scrolls
+! ***************
+
+Object gray_scroll "gray scroll" House_Basement
+  class scroll_class,
+  with name "gray",
+;
+
+Object tossio_spell "turn granite to pasta" gray_scroll
+  class spell_class,
+  with name "tossio",
+       magic [;
+         if ((location == THIEF_Storeroom) && 
+             (second == w_obj) && (THIEF_Storeroom hasnt general)) {
+         give THIEF_Storeroom general;
+         move pasta to THIEF_Storeroom;
+         move c50 to THIEF_Storeroom;
+         "As you finish the chant, the granite wall is replaced \
+by a large mass of pasta. A hidden section of the room is revealed, \
+along with the mass of gold coins it was holding! The coins spill \
+out, and nearly flood the room.^^In a flash, a large group of \
+financial nymphs appear on the scene. ~It looks like we found the \
+missing GUS earnings,~ one nymph says to another. Producing large \
+sacks, they quickly collect the mass of coins and disappear with a \
+twinkle.^^Moments later, a single coin falls out of a crack in the \
+previously hidden alcove, rolling to a stop near your feet.";
+         }
+         "Your chant goes unanswered. I guess you need pure granite.";
+       ],
+;
+
+! ***************
+! misc items
+! ***************
+
+Object red_sphere "red sphere"
+   class sphere_class
+   with name "red",
+        description "A tiny perfect red sphere, made of some strange \
+         unknown metal.",
+;
diff --git a/src/MAKESPIR b/src/MAKESPIR
new file mode 100644 (file)
index 0000000..ff19015
--- /dev/null
@@ -0,0 +1,6 @@
+./inform '$huge' '$MAX_OBJECTS=850' '$MAX_SYMBOLS=8150' '$MAX_CLASSES=25' '$MAX_DICT_ENTRIES=1500' '$MAX_ZCODE_SIZE=200000' '$MAX_BANK_SIZE=5000' spirit
+#./inform '$huge' '$MAX_OBJECTS=800' spirit
+
+# The below cmd version should only be used for creating 
+# abbreviations (this will take a while too)
+#./inform -u '$huge' '$MAX_OBJECTS=800' '$MAX_TRANSCRIPT_SIZE=300000' '$MAX_SYMBOLS=8000' '$MAX_CLASSES=20' '$MAX_DICT_ENTRIES=1500' '$MAX_ZCODE_SIZE=200000' spirit
diff --git a/src/MIZNIA.INF b/src/MIZNIA.INF
new file mode 100644 (file)
index 0000000..6a18b50
--- /dev/null
@@ -0,0 +1,892 @@
+! *******************************************************************
+! MIZNIA -- add-on for SPIRITWRAK
+! *******************************************************************
+
+
+Object MIZNIA_GUSStop "Mizniaport"
+   with description "The Great Change certainly hasn't changed the \
+ultra-swank city of Mizniaport. The entire place is filled with \
+splashy color and a disturbing sense of moderness. There's a \
+stairway down here, while side walkways head west and \
+northeast.",
+        name "color" "moderness" "stairway" "walkway" "walkways",
+        d_to MIZNIA_GUSStation,
+        w_to MIZNIA_Park,
+        ne_to FROBAR_Ent,
+    has light;
+    
+Object MIZNIA_Park "Miznia Suburbs"
+   with description "Overly cozy-looking homes sprout up all over \
+the place here. Ridiculously \
+well-trimmed front lawns remind you that you're still in Miznia. \
+A nice pebble path heads east and west. You see the entrance to \
+a swank-looking boutique to the south.",
+        name "homes" "lawns" "pebble" "path",
+        e_to MIZNIA_GUSStop,
+        w_to MIZNIA_Outskirts,
+        s_to MIZNIA_Boutique,
+        in_to MIZNIA_Boutique,
+   has light;
+
+Object MIZNIA_Boutique "Swank Boutique"
+   with description "A ultra-swank accessory store, filled with \
+flashy items for the fashion-unconscious shopper. \
+An exit lies north.",
+        name "items" "accessory",
+        out_to MIZNIA_Park,
+        n_to MIZNIA_Park,
+   has light;
+
+Object boutique_sign "small sign" MIZNIA_Boutique
+   with description "The sign reads ~PLEASE RING BELL FOR SERVICE~",
+        name "small" "sign",
+   has static;
+   
+Object MIZNIA_Outskirts "City Limits"
+   with description "The city stops here abruptly. The Miznia jungle \
+makes its presence known for real here, forming a natural barrier. A \
+path leads east, while an almost overgrown path leads into the jungle \
+to the southwest.",
+        name "path" "jungle" "barrier",
+        e_to MIZNIA_Park,
+        sw_to Jungle_Edge,
+   has light;
+  
+Object c8 "coin" MIZNIA_Boutique class coin_class;
+
+Object Jungle_Edge "Edge of Jungle"
+   with description "Wild birds and wilder vegetation distract you from \
+a faint trail through the jungle here. The path leads northeast and \
+southwest.",
+        name "birds" "vegetation" "trail",
+        ne_to MIZNIA_Outskirts,
+        sw_to Deep_Jungle,
+   has light;
+
+Object Deep_Jungle "Deep Jungle"
+   with description "You're in very deep jungle, just on the verge of \
+getting lost. Your surroundings are green and untamed. A path \
+leads northeast, while a muddy path heads south.",
+        name "mud" "path",
+        ne_to Jungle_Edge,
+        s_to Swamp,
+   has light;
+
+Object Swamp "Swamp"
+   with description [;
+          print "You're knee-deep in a murky swamp. Huge swamp grasses \
+wall you in";
+          if (self has general)
+             print ", except for a section to the west";
+          ". Drier land is north or south.";
+        ],
+        name "swamp" "land",
+        n_to Deep_Jungle,
+        s_to Jungle_Clearing,
+        w_to [;
+           if (self hasnt general)
+              "You can't go that way.";
+           else return Jungle_Ruins;
+        ],
+   has light;
+
+Nearby grasses "grasses"
+   with name "grass" "grasses",
+        description "Tall, thick swampgrass.",
+        before [;
+           Push, Pull, Cut, Attack:
+               "The grass is extremely hardy.";
+           Search:
+               if ((Jungle_Map notin player))
+                  "You hunt around in the grasses for a while and find nothing.";
+               else {
+                  give Swamp general;
+                  Achieved(21);
+                  "You check the jungle map. Sure enough, there's a loose \
+patch of grass that you could duck under to the west.";
+               }
+           Cast:
+               if (the_spell_was == throck_spell)
+                  "Grasses don't grow much more than this.";
+        ],
+   has scenery;
+
+
+Object Jungle_Clearing "Jungle Clearing"
+   with description "The Jungle clears out a bit here, so you can actually \
+see patches of sky and walk ten paces without running into a tree. There's \
+a path into the jungle undergrowth to the north. \
+You notice a group of jungle natives gathered here.",
+        name "sky" "path",
+        number 1,
+        n_to Swamp,
+        each_turn [ ;
+           if (Jungle_Clearing.number == 2) {
+              move Shaman to Jungle_Clearing;
+              Jungle_Clearing.number = 5;
+              "^A single native tribesman breaks away from the group and \
+approaches you.";
+           }
+           if (Jungle_Clearing.number == 1)
+              Jungle_Clearing.number = 2; 
+        ],
+   has light;
+
+Nearby natives "natives"
+   with name "natives" "group",
+        description "A group of jungle natives in elaborate feather and \
+        fur clothing. They appear to be armed with large spears.",
+        life [;
+default:  "The group of natives looks at you with distrusting stares.";
+        ],
+        before [;
+Cast: 
+   if (the_spell_was == espnis_spell or foblub_spell)
+"They can't understand your language, thus the meaning of \
+the sermon is lost on them.";
+        ],
+   has animate concealed;
+   
+        
+        
+Object Jungle_Ruins "Hidden Ruins"
+   with description "Hidden here in some extremely deep jungle \
+        are the ruins of some ancient civilization. Broken sandstone \
+        structures are nearly covered with jungle vines and mosses. \
+        There is a partially intact structure to the north. \
+        It seems to be a short pyramid-like building, with a single \
+        dark entrance hidden amongst vines. Definitely a find to \
+        write the Monastery about, or at least your local \
+        Archeology Guild.",
+        name "sandstone" "structures" "structure" "vines" 
+"pyramid" "entrance" "mosses",
+        e_to Swamp,
+        n_to TEMPLE_Ent,
+   has light;
+   
+! (The ancient temple, unlit, of course)
+Object TEMPLE_Ent "Pyramid Entrance"
+   with description "A damp, dark, unmarked stone room. You can hear \
+        the sounds of the jungle from the exit to the south. There \
+        are dark passages north and east.",
+        s_to Jungle_Ruins,
+        e_to TEMPLE_Statue_room,
+        n_to TEMPLE_Trap,
+        before [;
+           Listen: "You hear noises of the jungle from the south.";
+        ],
+;
+  
+Object TEMPLE_Statue_room "Statue Room"
+   with description "A tiny dark chamber, with a passage west.",
+        w_to TEMPLE_Ent,
+;
+
+Nearby TEMPLE_Statue "large statue"
+   with name "statue",
+        description "A stone statue of some ancient \
+        warrior, probably intended to frighten off visitors.",
+        before [;        
+           ! manual dealing with PushDir (only 3 possible locs anyway)
+           PushDir:
+              if (self has general)
+                 "The statue is stuck fast and doesn't budge.";
+              if ((self in TEMPLE_Statue_room) && (second == w_obj)) {
+               print "^There's a grinding noise as you push the statue west.^";
+               AllowPushDir(); rtrue;
+              }
+              if ((self in TEMPLE_Ent) && (second == s_obj))
+                 "^The statue doesn't appear to fit through the \
+                 entranceway.";
+              if ((self in TEMPLE_Ent) && 
+                  ((second == n_obj) || (second == e_obj))) {
+                 print "^There's a grinding noise as you push the statue.^";
+                 AllowPushDir(); rtrue;
+              }
+              if ((self in TEMPLE_Trap) && (second == s_obj)) {
+               print "^There's a grinding noise as you push the statue south.^";
+                 AllowPushDir(); rtrue;
+              }
+              if ((self in TEMPLE_Trap) && (second == n_obj)) {
+                 give self general;
+                 move rollers to TEMPLE_Trap;
+                 "You start to push the statue north, and hear a strange \
+                 click. Suddenly, two enormous stone rolling pins slide \
+                 down from the east and west sides of the room! \
+                 Desperately, you topple the statue and hide behind it. \
+                 You hear a huge crash!^^\
+                 You open your eyes, surprised to find yourself not \
+                 squashed into pancake. The statue has wedged itself \
+                 neatly between the two giant rollers, effectively \
+                 blocking them!";
+              }
+              "You can't push the statue that way.";
+            Take:
+              "The statue rocks back and forth a bit, but is \
+far too heavy to take.";
+            Push:
+              print "The statue ";
+              if (self hasnt general)
+              "rocks back and forth a bit.";
+              else "seems to be stuck.";
+           ],                 
+   has static;
+   
+Object TEMPLE_Trap "Strange Chamber"
+   with description "This is an odd long hallway running north and south. \
+The stone floor is noticeably concave, sloping upwards to \
+the east and west. It's like being in a long stone \
+channel.",
+        name "slope" "channel",
+        s_to TEMPLE_Ent,
+        e_to "The floor gets too steep, and you slide back down.",
+        w_to "The floor gets too steep, and you slide back down.",        
+        n_to [;
+           if (TEMPLE_Statue hasnt general) {
+              deadflag = 1;
+              "You head north, and hear a strange click. Suddenly, \
+              two huge stone rolling pins roll down from the east \
+              and west sides of the room! Desperately, you try to \
+              escape, but the hall is too long, and the stone \
+              rollers too fast. You are crushed to jelly.";
+           }
+           else {
+              print "You step over and around the jammed rollers and \
+              the statue and head north.^";
+              return TEMPLE_1;
+           }
+        ],
+;
+
+Object rollers "stone rollers"
+   with name "roller" "rollers" "stone",
+        initial "There are two stone rollers pinned against the statue.",
+        description "Massive stone rolling pins.",
+        before [;
+Push, Pull, Attack, Turn, Shake, Squeeze:
+"The rollers are huge and stuck fast.";
+        ],
+   has static;
+   
+Object TEMPLE_1 "Bare Chamber"
+   with description "You are in a bare stone chamber with passages leading \
+north, east, south and west. A stone ladder also heads upwards through a \
+dark hole in the ceiling.",
+       name "ladder" "hole",
+       s_to TEMPLE_Trap,
+       n_to TEMPLE_1N,
+       e_to TEMPLE_1E,
+       w_to TEMPLE_1W,
+       u_to TEMPLE_2,
+;       
+        
+Object TEMPLE_1W "Small Chamber"
+   with description "You're in a small bare chamber. On one of the walls, \
+   you notice an engraving, almost worn away with age. It seems to be a \
+   picture of a jungle village, and you recognize the pyramid you are currently in. \
+   An exit lies east.",
+      e_to TEMPLE_1,
+;
+
+Object TEMPLE_1N "Small Chamber"
+   with description "You're in a rather bare chamber. On one of the walls, \
+   you see a worn engraving depicting a group of robed figures standing in \
+   some chamber. They are carrying several long reeds. An exit lies south.",
+        s_to TEMPLE_1,
+;
+
+Object TEMPLE_1E "Small Chamber"
+   with description "You're in a small stone chamber. In the center of the \
+   floor is a strange funnel-like depression, which starts as a large \
+   circular opening, and narrows into a very small tunnel below, \
+   probably no wider than your hand. You also see a small round hole \
+   in the ceiling above. An exit heads west.",
+      w_to TEMPLE_1,
+      d_to "You'd never fit down that opening.",
+      u_to "You can't reach the hole, and besides, you'd never fit through \
+it if you could.",
+;
+
+Object TEMPLE_1_HOLEU "hole" TEMPLE_1E
+   with name "hole",
+        description "You see a dark small hole in the center of the \
+ceiling.",
+        before [;
+Rub, Push, Pull, Touch, Receive, LetGo, Search:
+"The hole is far above your head.";
+        ],
+   has scenery;
+
+Object TEMPLE_1_Opening "opening" TEMPLE_1E
+   with name "opening" "funnel" "depression" "tunnel",
+        description "A smooth funnel in the stone in the floor, that descends \
+        into darkness as it narrows.",
+        describe [ x;
+           print "^The opening ";
+           if (children(self) == 0)
+              "appears to be empty.";
+           else {
+         print "contains:^";
+         x = children(self);
+         x = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
+         WriteListFrom (child(self), x, 1); 
+         rtrue;
+           }
+        ],
+        before [;
+           Receive:
+             if (noun ~= TEMPLE_Artifact)  {
+                print "That doesn't quite fit -- ";
+                if (noun.size > TEMPLE_Artifact.size)
+                   "the funnel becomes too narrow too quickly.";
+                else "strangely...";
+             }
+           LetGo:
+              "You stick your hand down the small hole, but it must be \
+              quite deep, and you can't quite reach.";
+         ],
+         capacity 1,
+         size 10,
+   has static container open;
+   
+Object TEMPLE_2 "Bare Chamber"
+   with description "You are in a bare stone chamber with passages leading \
+north, east, south and west. A stone ladder leads upwards and downwards \
+into dark holes.",
+       name "ladder" "hole",
+       s_to TEMPLE_2S,
+       n_to TEMPLE_2N,
+       e_to TEMPLE_2E,
+       w_to TEMPLE_2W,
+       u_to TEMPLE_3,
+       d_to TEMPLE_1,
+;   
+
+Object TEMPLE_2N "Small Chamber"
+  with description "You're in a small bare chamber. Engravings on the \
+  wall show several robed figures in a low domed chamber. Some of \
+  the figures are pushing what appears to be reeds down a small hole \
+  in the ground, while others stand by and seem to be praying or \
+  engaged in some ceremony. In a separate scene, similar robed \
+  figures can be seen throwing some poor bound individual off the \
+  top of the pyramid, apparently in some sort of ritualistic \
+  sacrifice. An exit heads south.",
+     s_to TEMPLE_2,
+;
+
+Object TEMPLE_2W "Small Chamber"
+   with description "You're in a small bare chamber. Engravings on \
+   the wall depict several robed figures in a room mostly filled \
+   with water. The figures are watching reeds that seem to fall \
+   from the sky and land in the water. Several reeds are floating \
+   towards an apparent drain in the water, where a few reeds that are thin \
+   enough fall through with the flow of the water. An exit lies east.",
+      e_to TEMPLE_2,
+;
+
+Object TEMPLE_2S "Small Chamber"
+   with description "You're in a rather small chamber. Engravings on \
+   the walls depict several robed figures in a strange room with a \
+   circular depression in the ground, filled with water. Water also \
+   flows into the pool in a thin stream from some undrawn source above. \
+   With the stream of water, a few reeds appear to be falling. A single \
+   figure is collecting the reeds as they fall and placing them in \
+   a long thin vase or container. The significance of \
+   this is uncertain. An exit lies north.",
+      n_to TEMPLE_2,
+;
+
+Object TEMPLE_engravings "engravings"
+   with name "engravings" "engraving",
+        description [; <Look>; ],
+        found_in TEMPLE_1W TEMPLE_1N TEMPLE_2N TEMPLE_2W TEMPLE_2S,
+   has scenery;
+
+Object TEMPLE_2E "Small Chamber"
+   with description [;
+   print "You're in a bare stone chamber which is partially \
+filled with a sunken pool of dirty blackish water. Near the south wall \
+is a depression in the floor that was probably a drain for the pool, given the \
+apparent water stains; however the level of the pool is below \
+the point where it would overflow into the drain. Near the center \
+of the ceiling is a small round hole, right above the pool. An \
+exit lies west";
+   if ((self hasnt general) && (TEMPLE_3 hasnt general) &&
+        (amulet has worn)) {
+      give self general;
+      ".^^Your amulet suddenly gives off a bright purple flash!";
+   }
+   else ".";
+   ],
+   name "stains",
+   before [;
+      Fill:
+"The blackish water seems like something you really don't want.";
+   ],  
+   w_to TEMPLE_2,
+;  
+   
+Object TEMPLE_2_HOLEU "hole" TEMPLE_2E
+   with name "hole",
+        description "You see a dark small hole in the center of the \
+ceiling.",
+        before [;
+Rub, Push, Pull, Touch, Receive, LetGo, Search:
+"The hole is far above your head.";
+        ],
+   has scenery;
+
+Object TEMPLE_2_Opening "opening" TEMPLE_2E
+   with name "opening" "drain" "depression",
+        description "A smooth drain opening in the stone in the floor, \
+        that descends into darkness.",
+        before [;
+           Receive:
+             if ((noun ~= TEMPLE_Artifact) && (noun hasnt is_rod)) ! TODO ADD?
+              "Oddly, that doesn't fit through the small round drain.";
+             else {
+                if (children(TEMPLE_1_Opening) == 0) 
+                   move noun to TEMPLE_1_Opening;
+                if (TEMPLE_Artifact in TEMPLE_1_Opening &&
+                    children(TEMPLE_Artifact) == 0)
+                   move noun to TEMPLE_Artifact;
+                else move noun to TEMPLE_1E;  
+                CDefArt(noun); " drops into the drain and disappears \
+                out of sight. Moments later you hear a thump from \
+                somewhere below.";
+             }
+         ],
+         capacity 1,
+         size 10,
+   has scenery container open;
+
+Object TEMPLE_Pool "pool" TEMPLE_2E
+   with name "pool" "water",
+        describe [;
+print "^The black pool is disturbingly calm";
+if (umbrella in self)
+   ". Floating on the surface is a black open umbrella.";
+else ".";
+        ],
+        description [;
+           print "Murky black water that seems disturbingly calm";
+           if (umbrella notin self)
+           ".";
+           else
+           ". Floating on the surface is a black open umbrella.";
+           ],
+        before [;
+           Cast:
+              if (the_spell_was == frotz_spell)
+                 "There's a strange gurgling noise as you finish the \
+                 chant, and the black water starts to glow! But, \
+                 to your horror, the inky water seems to absorb the \
+                 light and return to its original blackness! The \
+                 chant fails.";
+                 
+          Enter:
+             deadflag = 1;
+             "You notice the water seems unusually cold as you enter \
+             the pool. Without warning, something grabs your legs and \
+             pulls you under! In pitch black liquid that seems to \
+             absorb all light, you can't defend yourself, or even \
+             see your adversary, who devours you shortly.";
+          Search:
+             "You can't see a thing, the water is blacker than night.";
+          Receive:
+             if (noun == toy_volcano) {
+                remove noun;
+                "You drop the toy volcano into the black pool and \
+watch it sink. Moments later, a large large bubble rises, and \
+pops at the surface, followed by a strange, belch-like noise!";
+             }
+             if ((noun ~= umbrella) || (umbrella hasnt open)) {
+             remove noun;
+             CDefArt(noun); 
+print " falls into the pool and slowly sinks into the black water. \
+Suddenly, ", (the) noun, " seems to get pulled into the pool, \
+and is soon gone! Something dwells in that pool, apparently, \
+hidden well in a cover of"; " blackness!";
+             }
+             else {
+                move umbrella to TEMPLE_Pool;
+                give umbrella ~light;  ! a 'special-effect'?
+                "The open umbrella sits in the pool, floating on the \
+                surface like a cloth dome.";
+             }                      
+        ],
+        size 25,
+   has static container open;
+
+               
+Object TEMPLE_3 "Collapsed Chamber"
+   with description [;
+   print "You are in a stone chamber that has broken and \
+   eroded walls in several places. Broken stones and dirt are everywhere. \
+   It appears there was once an open archway east, however the heavy stones \
+   that framed it have collapsed. A tiny hole remains, \
+   but it would be an exceptionally tight squeeze. \
+   A stone ladder leads downwards into a dark hole";
+   if ((self hasnt general) && (TEMPLE_2E hasnt general) &&
+       (amulet has worn)) {
+      give self general;
+      ".^^Your amulet suddenly gives off a bright purple flash!";
+   }
+   else ".";
+   ],
+   name "stones" "dirt" "archway" "ladder" "hole",
+       e_to [;
+          if (children(player) ~= 0)
+             "You try to squeeze through the hole, to \
+             no avail. You're carrying too much to fit.";
+          else return TEMPLE_3E;
+       ],
+       d_to TEMPLE_2,
+;
+
+Object TEMPLE_3E "Low Chamber"
+   with description "You're in a tiny low room, dimly lit by strange \
+   glowing lichens and mosses. A tiny exit lies west between some \
+   collapsed rock -- it looks like a very tight squeeze. The room is \
+   otherwise filled with broken rock and the like. A tiny round hole \
+   is in the very center of the floor.",
+   name "lichens" "mosses" "rock",
+   w_to [;
+      if (children(player) ~= 0)
+             "You try to squeeze through the hole, to \
+             no avail. You're carrying too much to fit.";
+          else return TEMPLE_3;
+       ],
+   d_to "You can barely fit your hand in the hole.",
+has light;
+              
+Nearby TEMPLE_3_Opening "opening"
+   with name "opening" "hole" "tiny" "round",
+        description "A smooth round hole in the stone in the floor \
+        that descends into darkness.",
+        before [;
+           Receive:
+             if (noun hasnt is_rod)  
+                "Oddly, that doesn't quite fit.";
+             else {
+                print "The rod slips through with ease. \
+Moments later you";
+                if (umbrella notin TEMPLE_Pool) {
+                   remove noun;  
+                   " hear a splash from somewhere below.";
+                }
+                else {
+                if (children(TEMPLE_1_Opening) == 0) 
+                   move noun to TEMPLE_1_Opening;
+                else {
+                if (TEMPLE_Artifact in TEMPLE_1_Opening &&
+                    children(TEMPLE_Artifact) == 0) 
+                   move noun to TEMPLE_Artifact;
+                else move noun to TEMPLE_1E;  
+                Achieved(22);
+                }
+                !   if (TEMPLE_Artifact notin TEMPLE_1_Opening)
+                !      move noun to TEMPLE_1_Opening;
+                !   else 
+                !      move noun to TEMPLE_Artifact;
+                   " hear a thump from below, followed by a rattling noise, \
+                   and finally another thump, much fainter.";
+                }
+             }
+         ],
+         capacity 1,
+         size 10,
+   has scenery container open;
+
+
+! (Super Zmart) (REMOVED)
+
+Object stuffed_toy "stuffed toy" MIZNIA_Park
+   with name "toy" "stuffed" "alligator",
+        initial "A stuffed toy has been left unattended on someone's lawn.",
+        description "A cute little stuffed toy alligator.",
+        !weight 5,
+        size 15,
+;
+
+
+   
+Object FROBAR_Ent "In Front of Swank House"
+   with description "You're in front of a rather swank looking house to the \
+        northeast. To the southwest is the rest of Mizniaport.",
+        name "house",
+        sw_to MIZNIA_GUSStop,
+        ne_to [;
+           if (Frobar in Delbins)
+              "You walk up to the front door, only to find it locked.";
+           else return FROBAR_Foyer;
+        ],
+        in_to [;
+           if (Frobar in Delbins)
+              "You walk up to the front door, only to find it locked.";
+           else return FROBAR_Foyer;
+        ],
+   has light;
+   
+Nearby Frobar_mailbox "mailbox"
+   with name "mailbox" "box",
+        description "A mailbox stands in front of the house. The letter \
+        ~F~ is on one side.",
+        capacity 5,
+        size 15,
+        ! block a receive here?
+   has static container openable;
+   
+Object Ench_mag "copy of ~Enchanter Monthly~" Frobar_mailbox
+   with name "magazine" "monthly" "enchanter" "copy",
+        description "~Enchanter Monthly~ has been somewhat lacking in \
+        quality content these days (The absence of magic probably \
+        being a large factor behind this). For filler, the editors have \
+        been turning in mostly tabloid drivel articles about ~What ever \
+        happened to so-and-so?~. This month's cover story \
+        suggests that Barsap the magician was actually turned into a tortoise \
+        during the Great Cataclysm, and underwent a slow mutation into a \
+        newt.",
+        !weight 5, 
+        size 15,
+;
+              
+
+
+
+! **********
+! critters/people
+! **********
+
+Object Shaman "jungle shaman"
+   with name "shaman" "tribesman" "native",
+        description [;
+print "A jungle native with a rather elaborate costume \
+        make of bird feathers and animal hides. He seems old, but wise";
+if (self hasnt general) 
+        ". Unlike the rest of the natives, this one is not wearing a \
+        fancy feather-and-fur headdress.";
+else ".";
+        ],        
+        life [;
+           Order:
+              if ((action==##Give) && (noun==Jungle_Map) && (Jungle_Map in self))
+                 "You try to convey your desire for the map with \
+                 gestures. The shaman seems to understand. He \
+                 points to the map, then you. Then, he raises his \
+                 hand in a 'stop' gesture. Then, he points to his \
+                 bare head.";
+              "The shaman does not seem to understand.";
+           Give:
+              if (noun==headdress) {
+                 move Jungle_Map to player;
+                 move headdress to Shaman;
+                 give self general;
+                 "The shaman takes the headdress and places it on his \
+                 head. He smiles, and gives you a strange map in return.";
+              }
+              "The shaman smiles and shakes his head.";
+           Attack, ThrowAt:
+              deadflag = 1;
+              "As you make a threatening move, several of the natives \
+              step forward and pierce your body with stout spears. \
+              It appears they've had bad dealings with outsiders \
+              before.";
+           Show: 
+            if (noun == headdress)
+               "The shaman nods and points to the headdress, then \
+               himself.";
+             "The shaman says something in a language you've never \
+             heard before.";             
+           default: "You can't seem to communicate with him; their \
+           language is completely foreign to you.";           
+        ],
+        before [;
+           Cast:
+              if (the_spell_was == foblub_spell or espnis_spell)
+                 "You begin the sermon, but the shaman and natives \
+                 seem very puzzled by your speech, and clearly \
+                 can't understand a word you're saying. The chant \
+                 fails.";
+        ],
+   has animate;  ! transparent?
+   
+Object Jungle_Map "jungle map" Shaman
+   with name "map" "jungle",
+        description [;
+        print "The map is somewhat crudely drawn:^^";
+        font off;
+        spaces 23; print "xxxx^";
+        spaces 23; print "xxxx^";
+        spaces 23; print "XXXX^";
+        spaces 22; print "/^";
+        spaces 18; print "XXXX^";
+        spaces 18; print "XXXX^";
+        spaces 18; print "XXXX^";
+        spaces 20; print "I^";
+        spaces 18; print "oooo^";
+        spaces 12; print "<#>---oooo^";
+        spaces 18; print "oooo^";
+        spaces 20; print "I^";
+        spaces 18; print "XXXX^";
+        spaces 18; print "XXXX^";
+        spaces 18; print "XXXX^";
+        font on;
+        ],
+         ! weight 10, 
+        size 10,
+;
+
+Object earth_spirit "earth spirit" TEMPLE_3 ! TEMPLE_3E
+  with name "spirit",
+       description "It looks like a large moving mass of mud and earth, \
+                  in a somewhat man-like shape.",
+       each_turn [ i ;
+       ! spirit attack
+       ! (in general, the 4 spirits are _very_ dangerous.
+       ! There's a 1/5 chance of killing outright, and 2
+       ! chances of doing 10 and 5 points of damage respectively.
+       ! In short, the player needs to realize it's time to swanko,
+       ! and do so, quickly)
+       if (self hasnt general) {
+          give self general ~concealed;    
+          "^Some of the dirt and mud in one corner stirs! A form \
+          made of mud and earth suddenly rises to attack!";
+       }
+       i = random(5);
+       if (i == 1) {
+          deadflag = 1;
+          "^The earth creature moves quickly, and blinds you with \
+          a spray of dirt! You clear your eyes, only to see the \
+          brown mass move forward and bury you! You struggle, but \
+          suffocate in short time.";
+       }
+       if (i == 2) 
+          Player_HP_CUR = Player_HP_CUR - 10;
+       if (i==3) 
+          Player_HP_CUR = Player_HP_CUR - 5;
+       if (Player_HP_CUR <= 0) {
+          deadflag = 1;
+          "^The last blow from the earth spirit was too much for \
+          you, I'm afraid to say. The spirit slowly sludges \
+          towards you for the final blow...";
+       } 
+       print "^The earth spirit ";
+       if (i==2)
+          "clubs you with a heavy pseudopod \
+          made of animated soil and rock. Ouch!";
+       if (i==3) {
+          print "throws some loose soil and sand in \
+          your face! The attack knocks you back, and \
+          you fall into the chamber below!";
+          PlayerTo(TEMPLE_2);
+          rtrue;          
+       }
+       "sends a spray of sharp rocks \
+       your way, and you just dodge in time!";
+       ],
+       before [;
+          Cast:
+            if (the_spell_was == swanko_spell) {
+               remove self;
+               "As you speak the chant, the earth spirit falls back \
+               in fear! You finish the chant, and the earth spirit \
+               collapses into a heap of dirt and mud, banished!";
+            }
+            print "The creature makes a banshee-howl as you chant.^"; 
+       ],
+       life [ ;
+          Attack: 
+            print "You ";
+            if (random(20) >= 8)
+            "strike the earth creature, but your attack passes \
+            harmlessly through it! You hear a strange noise from \
+            the creature -- akin to mad laughter from someone \
+            trapped underground in a coffin.";
+            "attack the earth spirit, but miss!";
+          default: "It's too busy trying to kill you.";
+       ],
+   has animate concealed;   
+        
+! **********
+! spells/scrolls
+! **********
+
+! TODO (Dan, why is this declared _here_?)
+Object white_scroll "white scroll" 
+  class scroll_class,
+  with name "white",
+;
+
+Object huncho_spell "send object to higher plane" white_scroll
+  class spell_class,
+  with name "huncho",
+       magic [;
+          if (second == 0)
+"You see a brief flash of light, but nothing happens.";
+          if (second == player) {
+             print "You finish the chant";
+!             if ((location == ATRII_8) && (ATRII_8 hasnt general) &&
+! (white_rod_piece in player) && (black_rod_piece in player) &&
+! (smoke_rod_piece in player) && (gray_rod_piece in player)) {
+             if ((location == ATRII_8) && (ATRII_8 hasnt general)) {
+               give ATRII_8 general;
+               spell_block = 1;
+               print " and notice the \
+white streaks of light above widen, as though a rift was \
+being torn in the sky! You feel a force pulling you \
+upwards, into the unknown!^";
+               StartTimer(Imp_Liv,10);
+               PlayerTo(Imp_Liv);
+               rtrue;
+             }
+             else 
+                ", and see a short-lived flash
+of light above, but nothing else.";
+          }
+          if (second has animate) {
+             "You feel a slight rumbling overhead, but nothing else \
+happens.";
+          }
+          else {
+             if ((second hasnt static) && (second hasnt scenery) &&
+                 (in_atrii == 0)) {
+                if (second has clothing) give second ~worn;
+                move second to ATRII_8;
+                print "There is a flash of light, and "; DefArt(second); 
+                " suddenly vanishes!";
+             }
+             "Your chant goes unanswered.";
+          }
+      ],
+;
+
+Object muddy_scroll "muddy scroll" Deep_Jungle
+  class scroll_class,
+  with name "muddy",
+       initial "Partially buried in the mud is a scroll.",
+;
+
+Object throck_spell "grow plant" muddy_scroll
+  class spell_class,
+  with name "throck",
+       magic [;
+             "Your chant goes unanswered. It's intended for plants only.";
+       ],
+;
+
+! **********
+! misc objs
+! **********
+
+
+! 'earth' rod piece -- BLACK
+Object black_rod_piece "black rod piece" TEMPLE_3E
+  class rod_class,
+  with name "black",
+       initial "In the center of the room is a short black rod.",
+       description "It's a short section of a rod made of some \
+undeterminable hard substance, \
+colored an inky black. A piece of the Rod of \
+the Ancients, I'd warrant!",
+;
diff --git a/src/SPECIAL.INF b/src/SPECIAL.INF
new file mode 100644 (file)
index 0000000..1d22b5c
--- /dev/null
@@ -0,0 +1,1736 @@
+! *********************************************************************
+! SPECIAL.INF  -- Add-on for SPIRITWRAK
+! Contains: 'specials' that I wanted to keep separate from
+! the other 'city-based' .INF files (Atrii, NPC homes)
+! *********************************************************************
+
+! ----------------- (Frobar's home) -------------------------
+
+Object FROBAR_Foyer "Entrance Foyer"
+   with description "You are in the Entrance Foyer of a \
+small but tasteful home. The exit is to the southwest. \
+The general area is tastefully done in maroon carpeting \
+and brass fixtures. Another room lies to the north.",
+   name "maroon" "carpeting" "brass" "fixtures",
+   sw_to FROBAR_Ent,
+   out_to FROBAR_Ent,
+   n_to FROBAR_Parlor,
+   has light;
+   
+Object FROBAR_Parlor "Parlor"
+   with description "You are in a very decorative parlor. \
+Various furnishings of high quality are arranged around \
+an enormous rug with intricate golden symbols in the weave \
+design. Open doorways lead south, north, east and west.",
+   name "rug" "doorways" "furnishings" "symbols",
+   s_to FROBAR_Foyer,
+   n_to FROBAR_Bedroom,
+   e_to FROBAR_Study,
+   w_to FROBAR_Lounge,
+   has light;
+
+Object frobar_plant "large potted plant" FROBAR_Parlor
+   with name "plant" "large" "potted",
+   initial "A large potted plant sits in one corner.",
+   description "A well-tended house-plant.",
+   before [;
+      Cast:
+         if (the_spell_was == throck_spell) {
+            "The plant seems even healthier now.";   
+!            if (Frobar in FROBAR_Bedroom) 
+! (couldn't think of a proper reaction...:)
+         }
+   ],        
+   has static;
+                    
+Object FROBAR_Lounge "Lounge"
+   with description "A large room here apparently serves as a lounge \
+for entertaining. The walls and furniture all have interesting \
+design work that gives an impression of dignified age. A doorway \
+heads east.",
+   name "furniture" "doorway",
+   e_to FROBAR_Parlor,
+   has light;
+   
+Object FROBAR_Study "Study"
+   with description "This is a study room with fancy wood paneling and \
+plush carpeting. There is an exit to the west.",
+   name "wood" "paneling" "carpeting",
+   w_to FROBAR_Parlor,
+   has light;
+
+Nearby FROBAR_shelves "large bookshelf"
+   with name "shelves" "shelf" "bookshelf",
+        initial "A large bookshelf takes up most of the north wall.",
+        description "It's filled with odds and ends, mostly uninteresting.",
+        capacity 30,
+   has static supporter;
+
+Object FROBAR_Journal "plain journal" FROBAR_shelves
+   with name "journal" "plain",
+   ! weight 15, 
+   size 15,
+   description "This is a short journal of notes that \
+Frobar was keeping. The contents are quite dull, mostly \
+consisting of entries like ~Remember to water plant~ and \
+so forth. In fact, the only non-trivial entry follows:^^\
+~Perhaps today I will go visit Barsap's latest creation. \
+Then again, maybe I won't. This so-called 'Gambit' of his \
+is supposed to be some silly diversion where people can \
+hop around floating platforms trying to reach the southeast \
+corner \
+platform on the bottom level, just so they can get \
+teleported back to the top, and start all over again! \
+Can this be a monetarily beneficial thing? I doubt it.~";
+
+! (twisted -- four ancient ones)
+Object p5 "twisted parchment" FROBAR_shelves
+   class parchment_class,
+   with name "twisted",
+description "~...understand. I, like many of the Order, \
+have understood that the greatest Saints of our Order were \
+the Three, those Three that we know as the Ancient Ones. \
+Why then, do I find in ancient cairns, in hidden temples, \
+and in versions of the Scriptures found in unsettled lands, \
+that _four_ beings that called themselves the Ancient Ones \
+did do battle with evil and were defeated? This surely is \
+not to be believed, but I...~";
+
+Object FROBAR_Desk "large wood desk" FROBAR_Study
+   with name "desk",
+        description "A massive wood desk carved from a single block of wood.",
+        capacity 20,
+   has static supporter;
+   
+Object FROBAR_Bedroom "Bedroom"
+   with description "A nice cozy bedroom. The exit is south.",
+   s_to FROBAR_Parlor,
+   has light;
+   
+Object FROBAR_bed "large bed" FROBAR_Bedroom
+   with name "bed",
+        description "A large comfortable-looking bed.",
+        before [;
+           LookUnder: "Sorry, no monsters here.";
+        ],
+   has static enterable supporter;
+   
+!Object FROBAR_Painting "large painting" FROBAR_Bedroom
+!   with name "painting",
+!        initial "There is a large painting hanging on the wall.",
+!        description [;
+!        if (self hasnt general)
+!        "It appears to be an oil painting of a \
+!        scroll on a table.  A small note on the frame says, \
+!        ~Still-life with Scroll, -FF, 791~";
+!        else
+!        "It appears to be an oil painting of a \
+!        table.  A small note on the frame says, \
+!        ~Still-life, -FF, 791~";
+!        ],
+!        before [;
+!           Touch, Rub, Push:
+!              if (self hasnt general) {
+!                 give self general;
+!                 move painted_scroll to player;
+!                 Achieved(23);
+!                 print "As you touch the painting, your hands \
+!run across the scroll, and the oil takes on a three-dimensional \
+!quality!  You ignore the strange sensations as you reach \
+!into the painting, and withdraw the scroll";
+!                 if (Frobar in FROBAR_Bedroom) 
+!                    "!  Frobar watches the events over your \
+!shoulder, and seems puzzled.  ~Now, why didn't I ever think to try \
+!that,~ he muses.";
+!                 else "!";
+!              }
+!              else 
+!                 "The painting seems to be nothing more than \
+!an oil painting now.";
+!        ],
+!   has static;
+
+! ----------------- (Thief's home) -------------------------
+   
+Object THIEF_Bottom_of_staircase "Wondrous Stairway"
+   with description "An enormous spiral staircase seems to wind miles \
+above your head in this curious column-like chamber. Strange \
+points of light brighten the chamber from above. \
+To the west is a small exit.",
+   name "points" "light" "staircase" "stairway" "stairs",
+! TODO -- fix this weirdness...
+   u_to THIEF_Ent,
+   w_to "You can't go that way.",  ! but later...
+   before [;
+      Go: 
+         if (noun == u_obj)
+            print "^You begin the long trek upwards. Strangely, \
+            the stair seems to twist and move as you step on it, \
+            turning like a corkscrew, until you are \
+            graciously deposited at the top, far above your \
+            previous location.^";
+   ],
+   has light;
+         
+   
+Object THIEF_Ent "Fancy Hall"
+   with description "This must be an apartment or penthouse in the \
+skyscraper. You are in a very high hall, with black slate stone \
+walls that seem to reflect shadows everywhere. There is a room \
+to the north. The southern edge of this room drops off into the \
+darkness, followed by a long spiral staircase. The ceiling overhead \
+seems to have tiny points of light like a night sky.",
+     name "slate" "shadows" "staircase" "points" "light",
+     d_to THIEF_Bottom_of_staircase,
+     n_to THIEF_Foyer,
+   has light;
+
+Object THIEF_Foyer "Magnificent Foyer"
+   with description "This is an exceptionally grand entrance foyer, \
+with sweeping arched ceilings and sparkling chandeliers. The \
+room is dimly lit. Open hallways lead south and west.",
+   name "chandeliers",
+   s_to THIEF_Ent,
+   w_to THIEF_Lounge,
+   has light;
+   
+Object THIEF_Lounge "Fancy Lounge"
+   with description "A tastefully overdone lounge with tapestries \
+and gold enamel finished walls. The room is dimly lit, although \
+you see no windows or other sources of light. Open hallways lead \
+east and west.",
+   name "tapestries" "enamel",
+   e_to THIEF_Foyer,
+   w_to THIEF_Storeroom,
+   has light;
+
+Object THIEF_Journal "short journal" THIEF_Lounge
+   with name "journal",
+   initial "There's an open journal sitting here.",
+   ! weight 15, 
+   size 15,
+   description "This appears to be a short collection of notes:^^\
+   ~TIPS ON CRACKING THE NEW FROBOZZCO 3-DIAL COMBO LOCKS: ^\
+   Remember, there's a slight flaw in the design. For every \
+   correct number in the correct dial, pressing the opening button \
+   with cause a small click. Dials with the correct number in the \
+   wrong dial place will cause a small thunk. The lock mechanism \
+   scans for correct numbers in correct places first, and then \
+   for correct numbers in the wrong place in the 'remaining dials'. \
+   Simple! But don't forget, closing the locks will automatically \
+   lock and reset the dials!^^\
+   NEW FLATHEAD PAINTING: ^\
+   I've completed making the copy of the new Leonardo Flathead painting, \
+   received courtesy of the Royal Museum. Glad to say my skills in \
+   art forgery are undiminished -- I can barely tell the difference \
+   between the two myself! I'll soon replace the original with the \
+   copy, and no one will be the wiser!~";
+         
+
+Object THIEF_Storeroom "Workroom"
+   with description [;
+      print "A sight to inspire even the most avaricious, this \
+       storeroom is filled with all sorts of rare and precious treasures. \
+       A hallway leads east";
+      if (self hasnt general)
+         print ". You notice that the west wall appears to be made of \
+solid granite";
+      ".";
+   ],
+   name "hallway",
+   e_to THIEF_Lounge,
+   before [;
+      Examine:
+         if ((noun == w_obj) && (self hasnt general))
+            "The west wall is a solid piece of granite, which \
+seems very odd, considering the other walls are clearly made of \
+slate.";
+      Cast:
+         if ((the_spell_was==ledak_spell) && (Painting_FAKE in self)) {
+            if (Painting_REAL in self)
+               print "One of the paintings";
+            else print "The painting";
+            remove Painting_FAKE;
+            " is surrounded by a yellow glow! It crumbles into \
+dust!";
+         }
+   ],
+   has light;   
+   
+Nearby THIEF_treasure "precious treasures"
+   with name "treasure" "jewels" "gemstones" "artifacts",
+        description "Piles of rare gemstones, precious jewelry, \
+        priceless artifacts, and other treasures line the walls \
+        here.",
+        before [;
+           Take:
+           "Fortunately, your high moral standing allows you \
+           the benefit of having no need for such materials of excess.";
+        ],
+   has scenery;
+
+Object pasta "pile of fettucini carbonari"
+   with name "pile" "fettucini" "carbonari" "pasta",
+        description "A large pile of fettucini dripping in \
+carbonari sauce.",
+        before [;
+           Eat:
+              if (self hasnt general) {
+                 give self general;
+                 "You manage to stuff yourself with pasta, \
+but there's still quite a lot left."; 
+              }
+              else 
+                 "You've already had enough of this stuff \
+to last a lifetime. Just the thought of eating more is enough to \
+make you queasy.";
+        ],
+        size 16,        
+   has edible;
+
+Object c50 "coin" class coin_class;
+   
+Object Painting_FAKE "priceless painting" THIEF_Storeroom
+   with name "painting",
+        plural "priceless paintings",
+        short_name "priceless painting",
+        description "It's a beautiful oil painting of a dark stormy \
+scene. On the horizon, you can see the edges of mountaintops. Near \
+the top of the painting, two winged figures are carrying a lone \
+individual towards a break in the clouds, where a bright white light \
+seems to emanate.",
+        ! weight 25, 
+        size 25,
+        before [;
+        Drop:
+            if (location == Museum_north) { ! player returned fake painting to museum! 
+               remove self;
+               "A museum curator appears and takes the \
+painting. With an expert eye, he looks closely at it. ~This is \
+a fake! I warn you sir, art forgery is a dangerous game.~ He \
+leaves, much disgusted.";              
+            }
+        Take:
+            if (Painting_REAL in parent(self))
+               "They both look so genuine! You can't decide!";
+        Cast:
+            if (the_spell_was == ledak_spell) {
+               remove self;
+               "One of the paintings is surrounded by a bright \
+yellow glow, and disintegrates!";
+            }
+        Search:
+               if (Painting_REAL in parent(self))
+                  "Search which one? Goodness, you can't decide!";
+        ],        
+        ;
+                   
+
+! -------------ETHEREAL PLANE OF ATRII ------------
+
+Object ATRII_1 "Ethereal Plane of Atrii"
+   with description "Standing on a featureless gray plane that \
+   stretches to the infinite horizon against a gray sky, you \
+   can only conclude one thing -- you're on the Ethereal Plane \
+   of Atrii. Well, at least it fits the description Brother \
+   Palemon gave you. It seems like you could go in any \
+   direction from here.",
+   cant_go "An invisible force blocks your way!",
+   name "plane" "horizon" "sky",
+   sw_to ATRII_2,
+   se_to ATRII_3,
+   has light;
+   
+Object ATRII_2 "Ethereal Plane of Atrii"
+   with description "Flat, featureless gray is in every direction \
+   you look. Stranger still is the upright rectangular hole in the \
+   fabric of space that stands in the center of this area. \
+   Otherwise, you could wander this gray dimension in any direction, \
+   it seems.",
+   cant_go "An invisible force blocks your way!",
+   ne_to ATRII_1,
+   sw_to ATRII_4,
+   e_to ATRII_3,
+   s_to ATRII_6,
+   has light;
+   
+Nearby ATRII_2_hole "rectangular hole"
+   with name "hole" "rectangle" "opening",
+        description "Surely you are in a place where the very laws of \
+        nature and the Gods work by different rules! Here stands a \
+        rectangular hole, seemingly torn out of the very space you \
+        stand in. You see some curious metal chamber through the \
+        opening, but there is nothing behind the opening.",
+        before [;
+           Enter:
+              print "^You step through and feel your stomach twist. \
+              You stumble past a set of open metal doors into...^";
+              in_atrii = 0;
+              PlayerTo(Skyscraper);
+              return 2;  ! allow, but print nothing...
+        ],
+   has scenery enterable;
+   
+Object ATRII_3 "Ethereal Plane of Atrii"
+   with description "Flat, featureless gray is in every direction \
+   you look. Stranger still is the flat, glass-like square in the \
+   center of the 'floor' of this area. \
+   Otherwise, you could wander this gray dimension in any direction, \
+   it seems.",
+   cant_go "An invisible force blocks your way!",
+   nw_to ATRII_1,
+   w_to ATRII_2,
+   se_to ATRII_5,
+   s_to ATRII_7,
+   has light;
+   
+Nearby ATRII_3_ice "square of ice"
+   with name "square" "ice" "glass-like",
+        description "It looks and feels like a perfect square of ice, \
+        flush with the featureless gray surface you stand on.",
+        before [;
+           Enter:
+ print "You step onto the square, and before you know it, your \
+surroundings shift and start to fade! You feel a \
+sudden chilling wind. The ice seems to lengthen and stretch. The \
+gray plane slowly turns white and bumpy.^";
+              in_atrii = 0;
+              PlayerTo(Frozen_river2);
+              return 2;
+        ],
+   has scenery enterable;
+    
+Object ATRII_4 "Ethereal Plane of Atrii"
+   with description "Flat, featureless gray is in every direction \
+you look. Stranger still is the large black hole to the south. \
+Otherwise, you could wander this gray dimension in any direction, \
+it seems.",
+   cant_go "An invisible force blocks your way!",
+   ne_to ATRII_2,
+   se_to ATRII_6,
+   s_to [; <<Enter ATRII_4_hole>>; ],
+   has light;
+   
+Nearby ATRII_4_hole "black hole"
+   with name "hole" "black",
+        description "It looks like a large hole, probably twice your \
+        height. It's completely black and featureless.",
+        before [;
+           Enter:
+             print "^You step into the black hole. You stumble \
+       forward, surrounded by blacker-than-night darkness.^";
+             in_atrii = 0;
+             PlayerTo(Subway_Tunnel);
+             return 2;
+        ],
+   has scenery enterable;
+   
+! (secret subway tunnel)
+Object Subway_Tunnel "Dark Tunnel"
+   with description "You're in a large dark tunnel that seems \
+   to run north and south. To the south you see light. There \
+   seem to be two metal tracks running along the ground.",
+       s_to GURTH_GUSPlatform,
+       n_to "You walk north, and run into a invisible force!",
+       before [;
+          Go:
+             if (noun==s_obj) {
+                Achieved(25);
+                print "^You step out into an underground chamber. \
+    A burly uniformed figure sees you exit the tunnel and yells, \
+    ~Hey, no playing in the tunnels, pal!~^";
+             }
+       ],
+       each_turn [ i ;
+          i = random(40);
+          if (i > 35)
+             "^You hear a rumbling noise echoed from somewhere, and \
+             the entire tunnel seems to shake! Then, all is quiet.";
+          if (i == 17 or 18) {
+             deadflag = 1;
+             "^Suddenly, without warning, a huge train car appears \
+             heading south! It plows straight into you!";
+          }
+          if (i==6 or 7) 
+             "^Suddenly, a huge train car appears heading north! \
+             You barely avoid getting pulverized! Strangely, \
+             you watch as the train continues north, and \
+             seems disappear into blackness nearby. It's as \
+             though the train was simply removed from the tunnel \
+             somehow.";
+       ],
+;
+
+Nearby ST_tracks "tracks"
+   with name "tracks" "tracks" "metal",
+        description "Two long metal tracks, running north and south. \
+        There's something oddly familiar about them.",
+   has scenery;
+               
+Object ATRII_5 "Ethereal Plane of Atrii"
+   with description "Flat, featureless gray is in every direction \
+   you look. It seems like you could go in any \
+   direction from here.",
+   cant_go "An invisible force blocks your way!",
+   nw_to ATRII_3,
+   sw_to ATRII_7
+   has light;
+   
+Object p9 "ripped parchment" ATRII_5
+   class parchment_class,
+   with name "ripped",
+description "~...now know that the Rod we believe is \
+the Rod of the Ancients, sequestered in our Monastery, is \
+an artifact of evil! Imprisoned inside, \
+true to the scriptures (at least this much is, what \
+isn't, I can nowadays say is much) we know, is Anabais. \
+What is worse, is that this very Rod is an artifact of \
+evil power created by Anabais, in the image of the True \
+Rod of the Ancients, which he planned to use to aid \
+him in his evil gains! \
+Were that evil one free again, and had about him both \
+his brothers and his Rod of Evil, we would witness a \
+reckoning \
+greater than Quendor has ever known! I take relief in \
+the knowledge that he will never be freed, and he will \
+never regain his implement of evil; only an innocent \
+being can break the false rod and \
+free him from his prison, and subsequently, \
+the false rod cannot be regained by Anabais through his \
+own will, or another evil being. \
+In fact, only a being of good again can gather \
+the resulting pieces, and only through this being \
+can Anabais regain his evil artifact, for...~";
+
+
+Object ATRII_6 "Ethereal Plane of Atrii"
+   with description "Flat, featureless gray is in every direction \
+   you look. It seems like you could go in any \
+   direction from here.",
+   cant_go "An invisible force blocks your way!",
+   nw_to ATRII_4,
+   e_to ATRII_7,
+   n_to ATRII_2,
+   se_to ATRII_8,
+   has light;
+   
+Object ATRII_7 "Ethereal Plane of Atrii"
+   with description "Flat, featureless gray is in every direction \
+   you look. Stranger still is the odd-shaped depression in the gray \
+   plane here. \
+   Otherwise, you could wander this gray dimension in any direction, \
+   it seems.",
+   cant_go "An invisible force blocks your way!",
+   ne_to ATRII_5,
+   w_to ATRII_6,
+   sw_to ATRII_8,
+   n_to ATRII_3,
+   has light;
+
+Nearby ATRII_7_depression "depression"
+   with name "depression" "cavity",
+        description "It's a large elongated depression in the gray 'floor'. \
+        The cavity has a flat bottom, and somewhat cigar-like shape.",
+        before [;
+           Enter:
+              print "^You step into the depression. Your very \
+              surroundings start to fade, replaced by sunlight that \
+              makes you squint! The gray plane undulates and \
+              buckles and turns into a great body of water \
+              before your very eyes.^";
+              in_atrii = 0;
+              PlayerTo(sailboat); ! useful if the player 'lost' the boat at sea.
+              return 2;
+        ],
+   has scenery enterable;
+   
+Object ATRII_8 "Ethereal Plane of Atrii"
+   with description "Flat, featureless gray is in every direction \
+   you look. Directly overhead, you notice odd streaks of \
+   light. From here, you could wander this gray dimension in any direction, \
+   it seems.",
+   name "streaks",
+   cant_go "An invisible force blocks your way!",
+   nw_to ATRII_6,
+   ne_to ATRII_7,
+   has light;
+! ----------- Special Implementor's Residence -----------
+
+Object Imp_Liv "Strange Room"
+   with description [;
+      print "You ";
+      if (player in Imp_Curtains)
+         "can't see much behind these curtains.";
+      else "feel a great sense of dread! Surely, given the way \
+you got here, this must be the domicile of a dreaded Implementor! \
+The entire place feels strange and \
+alien and, well, ~modern~. There's some sort of kitchen to the \
+east. Long curtains cover what must be a window to the south.";
+        ],
+        number 1,
+        e_to Imp_Kitchen,
+        w_to Imp_door,
+        s_to [; <<Enter Imp_Curtains>>; ],
+        each_turn [ ;
+        if (Imp in Imp_Bedroom) {
+           if (Imp_Liv.number == 3) {
+              StartDaemon(Imp); 
+              Imp_Liv.number = 4;
+           }
+           else "^You hear some faint noises to the west.";
+        }
+        ! create some noises if player in curtains
+        if (player in Imp_Curtains) {
+           if (Imp in Imp_Liv)
+              "^You hear some faint noises nearby.";
+           if (Imp in Imp_Kitchen)
+              "^You hear some faint noises to the east.";
+        }
+        ],
+        time_left 0,
+        time_out [;
+            ! if player hasn't 'listened' twice to start Imp, 
+            ! start him anyway (otherwise, in truth, player 
+            ! would be permanently stuck in (my) apartment.
+            if (Imp_Liv.number < 4) {
+              StartDaemon(Imp);
+              Imp_Liv.number = 4;
+            }
+        ], 
+        before [;
+           ! if player actually listens, better noises...
+           Listen:
+        if (Imp in Imp_Bedroom) {
+           if (Imp hasnt general) { ! i.e. -- awake
+              if (Imp_Liv.number == 1) {
+                 Imp_Liv.number = 2;
+                 "It sounds like someone is talking to himself to \
+the west. You hear: ~Now, wait just a second here, the player object \
+is gone! How did that happen?~";
+              }
+              if (Imp_Liv.number == 2) {
+                 Imp_Liv.number = 3;
+                 "It sounds like someone is talking to himself to \
+the west. You hear: ~That can't be right. I must be getting tired. \
+Think I'll make myself a nice hot cup of coffee.~";
+! on next turn via Imp_Liv.each_turn, Imp daemon will be started...
+              }
+              ! otherwise, Imp has already made his rounds and
+              ! returned to bedroom, _not_ falling asleep
+              "You hear someone whistling a merry tune to the west."; 
+           }
+           else
+              "You hear someone snoring loudly to the west.";
+        }
+        if (Imp in Imp_Liv) {
+           if (Imp.number == 1)
+              "You hear someone walking nearby. The footsteps \
+soon fade to the east.";
+           if (Imp.number == 4)
+              "You hear someone walking nearby. The footsteps \
+soon fade to the west.";
+        }
+        if (Imp in Imp_Kitchen) {
+           ! This assumes the daemon will run before the player turn.
+           if (Imp.number == 2) {
+           switch (Imp.weight) {
+           118: print "You hear an irritated voice say, \ 
+~What happened to my coffee maker?~ Slightly softer, you \ 
+hear ~Well, I guess I'll have that iced tea.~";
+           119, 122: print "You hear a voice to the east say, \ 
+~Looks like I've got coffee, thank goodness.~";
+           121: print "You hear a voice to the east say, \ 
+~Great, I'm all out of coffee. Good thing I still have some \ 
+iced tea.~";
+           }  
+           " Shortly after this, you hear sounds of someone to \
+the east starting some kitchen activity.";
+           }
+           else "You hear some brief busy noises from the west, \
+followed by what sounds like someone drinking something. Shortly \
+thereafter, you hear the sounds of someone walking into the area \
+from the east.";
+        }
+        ],
+   has light;       
+
+Nearby Imp_Curtains "set of curtains"
+   with name "curtain" "curtains",
+        description "Some heavy-cloth curtains along the south wall.",
+        before [;
+           Open: "You draw back the curtains and see a sight that \
+beggars the mind! Through the windows, the night sky falls across \
+some unknown landscape, dotted with strange bright points of light. \
+Tall buildings seem to be everywhere. Whatever world you've stumbled \
+onto, it certainly is not your own! You hastily close \
+the curtains.";
+           Enter: print "In an attempt to hide, you part the curtains. ";
+        ],
+   has static enterable;
+
+Object Imp_Kitchen "Strange Kitchen"
+   with description "A room that could be a kitchen, \
+if it didn't seem completely strange. Harsh bright lights seem to \
+be coming from some unknown source. Strange-looking white countertops and \
+cabinets fill the area, along with a curious white closet-like object. \
+A room lies to the west.",
+   name "cabinet" "cabinets" "closet" "refrigerator" "countertops",
+        w_to Imp_Liv,
+   has light;
+   
+Object Coffee_maker "curious machine" Imp_Kitchen
+   with name "machine" "curious",
+        description "A white plastic device that seems to \
+encase a glass pitcher or kettle of some sort. Most odd.",
+        ! weight 15, 
+        size 15,
+;
+
+Object regular_coffee_can "can of regular coffee" Imp_Kitchen
+   with name "can" "coffee" "regular",
+        description [;
+                    "The can reads: ~Brand-X coffee crystals~^^\
+                    ~Rich, mountain-grown flavor.~";
+        ],
+        before [;
+           Open:
+            "You'd need a good can-opener for that.";
+        ],
+        ! weight 15, 
+        size 15,
+;
+
+
+Object Imp_Bedroom "Strange Bedroom"
+   with description "A very curious small bedroom. \
+   A white desk sits here amongst other odd furnishings.",
+   name "furnishings" "bed" "chair",
+   e_to Imp_door,
+   has light;
+   
+!Nearby Imp_Bed "furnishings"   
+!   with name "furnishings" "bed" "chair",
+!        description "Some weird bedroom furniture.",
+!   has scenery;
+
+Object Imp_Desk "desk" Imp_Bedroom
+   with name "desk",
+        description "A white desk, with a strange, modern look.",
+        capacity 6,
+   has scenery supporter;
+
+Object Imp_Computer "strange machine" Imp_Desk
+   with name "machine" "computer",
+        description 
+        [ ;
+           print "It's a strange metal box. On top, perhaps connected in some \
+way, is another metal box with a glass plate on the front. Strange wires \
+seem to be attached to the boxes somehow. \
+In front of the boxes is an odd plastic \
+flat object with rows and rows of plastic buttons labeled every letter in \
+the alphabet";
+           if (self hasnt general) {
+              give self general;
+              print ".^^Looking closer, you notice curious glowing \
+letters on the glass plate. You read the letters, and \
+feel drawn to respond...^^\
+SPIRITWRAK DEVELOPMENT SYSTEM:^\
+(AUTOMATIC OBJECT GARBAGE-COLLECTION)^\
+REMOVE OBJECT IMPENETRABLE_STEEL_WALL? (Y/N) ";
+if (YesOrNo() == 0)  "You press a button labeled ~N~. The strange box \
+emits a tiny beep, and the glass plate is covered with fantastic colorful \
+designs.";
+else {
+       ! set-up the secret room 
+       remove steel_wall;
+       give cave_intersection general;
+        Achieved(18);
+"You press a button labeled ~Y~. The strange box \
+emits a tiny beep, and the glass plate is covered with fantastic colorful \
+designs.";
+     }           
+           }
+           else ". The glass plate currently has strange glowing colorful \
+patterns displayed on it.";                                 
+        ],        
+   has static;
+   
+[ ImpSendBack ;
+    print "~I'm afraid you'll have to go back.~ The Implementor \
+snaps his fingers, and suddenly, you're back in...^";    
+    spell_block = 0;
+    StopDaemon(Imp);
+    StopTimer(Imp_Liv);
+    PlayerTo(ATRII_8);
+];   
+   
+Nearby Imp_door "door"
+   with name "door",
+        when_closed [;
+             if (self in Imp_Liv) {
+                if (player notin Imp_Curtains)
+                   "There's a closed door to the west.";
+                else rtrue;
+             }
+             else "There's a closed door to the east.";
+        ],
+        when_open [;
+             if (self in Imp_Liv) {
+                if (player notin Imp_Curtains)
+                   "There's an open door to the west.";
+                else rtrue;
+             }
+             else "There's an open door to the east.";
+        ],
+        description "A plain-looking door. A note \
+attached to it says ~DO NOT DISTURB, IMPLEMENTOR AT WORK~.",
+        door_dir [;
+             if (self in Imp_Liv) return w_to;
+             else return e_to;
+        ], 
+        door_to [;
+             if (self in Imp_Liv) return Imp_Bedroom;
+             else return Imp_Liv;
+        ],
+        found_in Imp_Liv Imp_Bedroom,
+        before [;
+        Open:
+           if ((Imp in Imp_Bedroom) && (Imp hasnt general)) {
+              print "You open the door, revealing a small room with \
+what must be an Implementor sitting behind a desk. The Implementor looks \
+up, startled. ~You're here?~ he says, observantly. ";
+              ImpSendBack();     
+              return 1;                    
+           }             
+        ],
+    has static door openable;
+
+   
+! *************** And, for my final trick, the endgame **************
+
+Object Mystical_Cave "Mystical Cave"
+   with description "You've entered a wondrous natural cave, lit \
+everywhere by reflected light from some sort of purple crystalline substance \
+in the walls. A tunnel exits to the northwest.",
+   name "reflected" "crystal" "crystalline" "substance",
+   number 0,
+   nw_to [;
+      if (Mystical_Cave.number ~= 4)
+         "The purple light in the chamber seems to pulse with energy, \
+and find your way blocked by an invisible force!";
+      else {
+         spell_block = 0;
+         ! fill with things, if necc.
+         print "As you leave, a sudden tremor shakes the \
+cave! You just narrowly avoid a sudden cave-in behind you!^";
+         give cave_intersection ~general;
+         return cave_intersection;      
+      }
+   ],
+   has light;         
+   
+Nearby purple_sphere "purple sphere"
+   with name "sphere" "purple",
+        initial "There's a purple crystal sphere partially embedded \
+in the rock floor here.",
+        description "A large purple sphere that seems to pulse with \
+strange energy.",
+        before [;
+          Push, Touch, Rub:
+            ! various endgame trickery...
+            if (silver_rod_piece in player) {
+               while (child(player)~=0) {
+                  give child(player) ~worn;
+                  move child(player) to Mystical_Cave;
+               }
+               move silver_rod_piece to player;
+               spell_block = 1;
+               print "The sphere pulses with angry energy! It seems to \
+be fighting the silver rod piece you hold! With a sudden burst, you \
+feel your mind reel and your very surroundings change!^";
+               give stone_marker general;
+!               give snowy_intersection general ~visited;
+               give snowy_intersection general;
+               StartTimer(White_Dragon,3);
+               PlayerTo(Dragon_Cave);
+               rtrue;
+            }
+            if (green_rod_piece in player) {
+               while (child(player)~=0) {
+                  give child(player) ~worn;
+                  move child(player) to Mystical_Cave;
+               }
+               move green_rod_piece to player;
+               spell_block = 1;
+               print "The sphere pulses with angry energy! It seems to \
+be fighting the green rod piece you hold! With a sudden burst, you \
+feel your mind reel and your very surroundings change!^";
+               StartTimer(captain,3);
+               PlayerTo(On_Boat);
+               rtrue;
+            }
+            if (red_rod_piece in player) {
+               while (child(player)~=0) {
+                  give child(player) ~worn;
+                  move child(player) to Mystical_Cave;
+               }
+               move red_rod_piece to player;
+               spell_block = 1;
+               print "The sphere pulses with angry energy! It seems to \
+be fighting the red rod piece you hold! With a sudden burst, you \
+feel your mind reel and your very surroundings change!^";
+!               give Stadium_entrance general ~visited;
+!               remove stadium_sign;
+!               remove stadium_statue;
+!               move statue_base to Stadium_entrance;
+               StartTimer(statue_base,2);
+               PlayerTo(Stadium_entrance2);
+               rtrue;
+            }
+            if (brown_rod_piece in player) {
+               while (child(player)~=0) {
+                  give child(player) ~worn;
+                  move child(player) to Mystical_Cave;
+               }
+               move brown_rod_piece to player;
+               spell_block = 1;
+               print "The sphere pulses with angry energy! It seems to \
+be fighting the brown rod piece you hold! With a sudden burst, you \
+feel your mind reel and your very surroundings change!^";
+!               give GURTH_House general ~visited;
+!               move bad_brick to GURTH_House;
+               StartTimer(bad_brick,7);
+               PlayerTo(GURTH_House2);
+               rtrue;
+            }
+            ! default...
+            "A purple blast of force throws you back!";
+        ],
+   has static;                   
+
+Object skeleton "skeleton" Mystical_Cave
+   with name "skeleton" "bones",
+        initial "Lying in one corner of the room is a skeleton.",
+        description "Just some bones, not much else, is all.",
+        before [;
+           Pull, Push, Turn, ThrownAt, Touch, Attack, Rub,
+Cut, Shake, Squeeze, Kiss:
+              remove self;
+              "The skeleton crumbles into dust, as though \
+many years of time had suddenly caught up with it in one \
+moment.";
+        ],
+has static;
+
+! (black -- final parchment of Palemon's final words)
+Object p8 "blackened parchment" Mystical_Cave
+   class parchment_class,
+   with name "blackened",
+description "~I write these final words not in the hope \
+that others will find and heed them, for this is too great \
+a hope in my moment of death, but rather, to try and maintain my mind and soul \
+in the face of the terror I now know is the truth.^^\
+For how can a man survive, knowing that his entire life, \
+his entire belief, has been a ruse, a dupe, from the \
+early beginning? That he has merely been a pawn in a \
+working of evil that cannot be stopped?^^\
+I have fought all manner of terrors, and recovered that which \
+I know is the _true_ Rod of the Ancients, broken and scattered \
+eons ago in the face of great evil. I sought also those \
+ancient spheres that the Four Ancients never had the chance to \
+use against the evil four elemental demons, but alas, I could \
+not find them all, and sequestered those which I did with \
+good people that the elemental evil could not touch.^^\
+Alas, my quest has ended here. I lie trapped here, \
+with the pieces of the true Rod in hand, unable to go forward, trapped by the \
+elemental mystic locks on the rod that prevent it from leaving this \
+very room, yet unable to go back, to leave the rod here and \
+deny the very real danger of the defeat of the Ancients, of \
+the power that the evil elementals hold.^^\
+What is a faith destroyed? Who can help me to believe, in my moment \
+of disbelief?^^\
+--P--~"; 
+
+
+
+
+Object Dragon_Cave "Giant Cavern"
+   with description "You find yourself in a huge cavern. To the west \
+is a large exit that looks out into a void of snow-covered mountains.",
+        name "mountains",
+        w_to "You hesitate. The cave seems to just \
+exit off the side of a mountain, and all you can see below is whiteness. \
+It could be a long way down.",
+        d_to [; <<Jump>>; ],
+        out_to [; <<Jump>>; ],
+        before [;
+            Jump:
+               print "You close your eyes and leap out of the cave! \
+You plummet through silent white winds. \
+Moments later, you fall right into an enormous snowbank, and \
+roll downwards, into...^";
+               PlayerTo(snowy_intersection2);
+               rtrue;
+        ],
+   has light;
+
+Object On_Boat "On strange boat"
+   with description "You are on a long open boat, riding the waves of \
+some great sea. The boat seems to be filled with sailors from \
+some militia.",
+        name "waves" "sea" "mast" "floorboards" "ship" "boat",
+        before [;
+           Drop:
+              if (captain has general) {
+                 if (noun==green_rod_piece) {
+                    remove green_rod_piece;  ! it'll be back           
+                    give shipwreck general;
+                    Mystical_Cave.number = Mystical_Cave.number + 1;
+                    StopTimer(captain);
+                    StopTimer(militia);
+                    print "You drop the green rod and watch it roll near \
+a mast and get stuck in the floorboards.^^\
+There's a load crack! The ship is breaking apart! Sailors \
+scramble in vain for safety! You hang onto the side of the \
+boat, but the vessel rocks wildly, and you fall into the waters. \
+^^As you sink, you notice the waters seem to change to a purplish \
+hue, and you find yourself back in...^";
+                    PlayerTo(Mystical_Cave);
+                    rtrue;
+                 }
+              } 
+              else  
+                "The sailors are holding you fast, so you \
+can't do this at the moment.";
+        ],
+   has light;
+
+Nearby militia "sailors"
+   with name "sailors" "militia" "navy",
+        description "A bunch of dour-looking navy sailors.",
+        time_left 0,
+        time_out [;
+           deadflag = 1;
+           "The ship breaks asunder! Sailors scramble madly \
+and fall into the violent waves! You hear \
+the captain scream ~Blast! I can't swim!~ before the \
+waters cover you completely.";
+        ],
+   has scenery;
+
+Object ENDGAME_ROOM "Nothingness"
+   with description "Nothingness surrounds you. Yet, you feel like \
+your conscious being extends into worlds and dimensions never \
+imagined. You float in a void of total being.",
+        number 0,  ! number of elementals banished
+        each_turn [;
+           switch (ENDGAME_timer.number) {
+           0:  ENDGAME_timer.number = 1; 
+               if (black_elemental in ENDGAME_ROOM) 
+               "^Echoing in your mind, you hear a voice, that you \
+somehow know is from the black sphere. ~Give me the rod priest, \
+and you shall be immortalized as a symbol to an entire civilization!~";
+           1:  ENDGAME_timer.number = 2; 
+               if (smoke_elemental in ENDGAME_ROOM) 
+               "^Echoing in your mind, you hear a voice, that you \
+somehow know is from the smoke-colored sphere. ~Give me the rod priest, \
+and I shall let you be witness to a feat of great magic, never \
+before witnessed!~";
+           2:  ENDGAME_timer.number = 3; 
+               if (gray_elemental in ENDGAME_ROOM) 
+               "^Echoing in your mind, you hear a voice, that you \
+somehow know is from the gray-colored sphere. ~Give me the rod priest, \
+and I will grant you power over all who surround you!~";
+           3:  ENDGAME_timer.number = 4; 
+               if (white_elemental in ENDGAME_ROOM) 
+               "^Echoing in your mind, you hear a voice, that you \
+somehow know is from the white sphere. ~Give me the rod priest, \
+and you will gain the attention of one of the more powerful \
+figures of your time!~";
+           }
+        ],  
+has light;
+
+Object ENDGAME_timer "void" ENDGAME_ROOM
+   with name "void" "nothingness",
+        description "The absence of anything. Yet, at the same \
+time, the sense that everything possible is near.",
+        number 0,
+        time_left 0,
+        time_out [;
+           deadflag = 1;
+           if (ENDGAME_ROOM.number < 3)
+              print "The spheres nearby suddenly converge";
+           else print "The sphere nearby suddenly converges";
+           " towards you! In your mind, you hear \
+~Hesitation, foolish priest, was the downfall of the Ancient \
+Ones~ before you feel the full force of the void.";
+        ],  
+   has scenery;
+
+! *** fake room/encounter for bad ending #x
+Object badend1 "On Giant Cube"
+   with description "You stand on a single giant floating white \
+cube, in the middle of some dimly lit cavern. \
+^^A small newt floats nearby, concentrating on something.^^\
+The newt suddenly opens its eyes! ~What?~ it croaks in \
+surprise. ~Who are you? You've broken my concentration on \
+the spell, you fool!~ the newt croaks. You feel the cube \
+shift, then stop floating! You plummet into the lava you \
+feared was below..."
+   has light;
+
+Object badend2 "Top of Pyramid"
+   with description "You are on top of a pyramid in some \
+ancient city. You see dense jungle to the horizon. \
+An ancient civilization spreads before you, in all its \
+mysterious glory.^^Several robed figures surround you.^^\
+Suddenly, you realize you are tightly bound! One of the \
+figures points towards the horizon and makes a complicated \
+gesture. In a language you do not understand, he seems \
+to make a prayer to some nameless god! Fearing the \
+inevitable, you struggle mightily, but to no avail. \ 
+In moments, the group of robed figures hurls you off the \
+pyramid to your death!"
+   has light;
+
+! *************
+! Creatures
+! *************
+
+Object Imp "Implementor" Imp_Bedroom
+   with name "Implementor",
+        article "an",
+        description [;
+           print "Some Implementor. Looks more like a oddly-dressed \
+young man badly in need of a haircut";
+           if (self has general)
+              ". He's also sound asleep!";
+           else ".";
+        ],
+        describe [;
+           print "^Someone you assume must be an Implementor \
+is here";
+           if (self has general)
+              ", sound asleep.";
+           else ".";
+        ],           
+        number 0,
+        weight 120,  !  about right
+            life [;
+                ! if asleep, which is usually the case
+               if (self has general) {
+                  if (action==##WakeOther or ##Attack) {
+                     print "You manage to rouse the Implementor from his \
+slumber. He stares at you, bewildered. ~What are you doing here?~ \
+he asks. ";
+ImpSendBack(); rtrue;
+           }
+                  else
+                  "He appears to be sound asleep right now, and isn't very \
+responsive.";
+           }
+!              else {
+! (I suppose this is unnecessary. -- i.e. the player shouldn't be able to 
+! interact with the implementor unless the implementor is asleep)
+!                 print "Well, that got his attention. The Implementor \
+!looks completely startled. ~What are you doing here?~  he says. ";
+!ImpSendBack(); rtrue;
+!           }                             
+            ],
+            daemon [;
+               ! ASSUMPTION -- daemon started by start event
+                StopTimer(Imp_Liv);
+               if (Imp.number == 0) {
+                  give Imp_door open;
+                  if ((player in Imp_Liv) && (player notin Imp_Curtains)) {
+                     print "^The door to the west suddenly flies open! \
+A somewhat bedraggled Implementor steps out! He spots you and his \
+jaw drops. ~You, here?~ he says. ";
+ImpSendBack(); rtrue;
+              }                      
+              else 
+                 print "^You hear a door open to the west.^";
+              Imp.number = 1;
+              move Imp to Imp_Liv;
+              }
+           else {
+              ! first a little 'lazy' clause that kicks the player
+              ! out if the Imp is moving around and the player isn't
+              ! in the curtains
+              if ((Imp.number < 5) && (player notin Imp_Curtains)) {
+                 if (Imp in location) print "^The Implementor ";
+                 else print "^From nearby, an Implementor rushes up and \
+";
+                 print " grabs you by the shoulder! \
+~What are you doing here?~ he \
+says. "; ImpSendBack(); return 1;
+              }
+              ! now, otherwise, we move the Imp and set his
+              ! number accordingly.  Room descs and 'Listen'
+              ! traps in Imp_Liv will need to use this info  
+              switch (Imp.number) {
+              ! [step 1, moving to Kitchen]
+              1: move Imp to Imp_Kitchen;
+                 Imp.number = 2;
+                 if (Coffee_maker notin Imp_Kitchen) Imp.weight = 118;
+                 else {
+                    if (regular_coffee_can in Imp_Kitchen) {
+                       Imp.weight = 119;
+                       remove regular_coffee_can;
+                    }
+                    else {
+                       if (decaf_coffee_can in Imp_Kitchen) {
+                          Imp.weight = 122;
+                          remove decaf_coffee_can;
+                       }
+                       else {
+                       ! no coffee, gosh darn it
+                          Imp.weight = 121;
+                       }
+                    }
+                 }
+                 return 0;
+              ! [step 2, making/drinking the beverage]
+              2: Imp.number = 3;
+              ! [step 3, leaving kitchen, back to living room]
+              3: Imp.number = 4;
+                 move Imp to Imp_Liv;
+              ! [step 4, goes back into bedroom]
+              4: Imp.number = 5;
+                 give Imp_door ~open;
+                 if (player in Imp_Curtains) 
+                    print "^You hear a door close to the west.^";
+                 move Imp to Imp_Bedroom;
+!                 move coffee_cup to Imp_Bedroom;
+                 if (Imp.weight == 122)
+                    give Imp general;  ! asleep
+                 StopDaemon(Imp);
+              }                         
+           }        
+            ],
+has animate;
+
+!Object coffee_cup "large cup"
+!   with name "cup" "large",
+!        description "A large mug, with the residue of some brown liquid \
+!left in it.",
+        ! weight 5, 
+!        size 4,
+!   has container open;        
+
+! MOVEPRINTNPC routine, from Gareth Rees' 'THIEF.INF' 
+! (TODO -- you really don't need this, since only Frobar moves in this fashion)
+[ MovePrintNPC n dest dir;
+    if (n in location) {
+        print "^", (The) n, " walks off";
+        if (dir ~= in_obj or out_obj or u_obj && dir ~= d_obj)
+            print " to the ", (DirectionName) dir.door_dir;
+        print ".^";
+    }
+    if (dest == 0) remove n;  ! This seems odd - if dest bogus, 'unlink' NPC?
+    else move n to dest;        
+    if (n in location)
+        print "^", (The) n, " walks in.^";
+];
+
+Object White_Dragon "White Dragon" Dragon_Cave
+   with name "dragon" "white" "giant",
+        describe [;
+           print "There is a gigantic white dragon here";
+           if (self has general)
+              " sleeping peacefully.";
+           "!";
+        ],
+        description "A giant white dragon, the size of a small house.",
+        time_left 0,
+        time_out [;
+           give self ~general;
+           if (location == Dragon_Cave) {
+              deadflag = 1;
+              "^The dragon suddenly snorts and wakes! It sees you \
+and attacks! In moments, you are no more...";
+           }
+           else {
+              remove self;
+              give stone_marker ~general;
+              move stone_marker_top to snowy_intersection2;  
+              "^You hear a roar from the east! From out of the \
+sky, a giant white dragon descends! It draws near, spots you, \
+and bellows in rage! You shrink back, and pray for a quick but \
+painless end.^^There is a loud crack! The dragon, in trying to \
+land, almost impales itself on the obelisk marker! Part of the \
+marker breaks off, and the dragon flies off, whimpering in pain!"; 
+           }          
+        ],
+        life [;
+        Attack, ThrowAt, WakeOther:
+deadflag = 1;
+"You disturb the sleeping dragon, who promptly makes you wish \
+you hadn't.";
+        default: "Best not to disturb the dragon, I'd guess.";
+        ],
+  has animate;
+
+Object captain "sea captain" On_Boat
+   with name "captain",
+        description "A rough-looking navy captain.",
+        number 0,
+        each_turn [;
+           if (self hasnt general) {
+              if (captain.number == 0) {
+                 captain.number = 1;
+                 "^You suddenly realize that you are being \
+held fast by two navy sailors! The captain walks forward and \
+points his cutlass near your ear.^^\
+~What we have here, lads, is a stowaway!~ Some sailor cries out \
+~Overboard with the stowaway!~ The captain smiles. \
+~Now, we was planning on feeding you to the groupers, \
+but we could use a scullion in the hold. One things for sure, \
+ye ain't finding passage on this ship if ye ain't aligned with \
+the Antharian Navy cause!~ Some sailor cries out \
+(unnecessarily) ~The Antharian Navy cause!~. ~So, tell us lad, \
+are ye with us? If ye are true, you'll tell me the Antharian \
+Navy patron saint! So speak quickly, lad, if ye wish to stay \
+dry!~";
+              }
+              else "^~Speak up fellow! We havn't got all day!~";
+           } 
+        ],
+        time_left 0,
+        time_out [;
+           deadflag = 1;
+           "The captain sighs. ~Into the water with ye, then,~ \
+he says, and the two sailors push you roughly overboard. \
+You land in the sea with a splash, and struggle to stay afloat. \
+The ship sails off, but oddly, moments later, it seems to \
+stall and start to sink! Before you get a chance to reflect on \
+this, a large grouper swallows you whole.";
+        ], 
+        life [;
+           if (self has general)
+              "The captain's a bit too busy trying to save \
+a sinking ship.";
+           Answer:
+             if (noun=='minirva') {
+                give self general;
+                StopTimer(self);
+                StartTimer(militia,2);
+                "~Aye, that's right. Escort the new scullion \
+down to the hold where --~^^\
+The captain's orders are cut short by a sudden grinding noise, \
+and the boat rocks violently! ~Reef, captain!~ you hear someone \
+cry. ~Blast!~ the captain says, ~quickly men, we've got to --~ \
+But it's too late. The boat starts to tip and sway, and \
+the two sailors release you and hastily try to help raise the \
+rigging!";
+             }
+             else {
+                if (noun=='duncanthrax') {
+                  deadflag = 1;
+                  "The sailors suddenly pale at the mention of \
+Lord Duncanthrax. ~A traitor in our midst, eh?~ the captain \
+shouts and beheads you with one stroke.";
+                }
+                if (noun=='ulysses' or 'odysseus')
+                   "~Nay lad, me thinks that \
+was a sailor.~";                   
+                else "~Nay lad, that doesn't sound right.~";
+             }
+           Attack, ThrowAt, Kiss, Show, Give:
+             "Given that you are in the grips of several \
+strong navy sailors, this is impossible.";
+        ],
+   has animate;
+
+! ***** THE EVIL ELEMENTALS
+Object black_elemental "black sphere" ENDGAME_ROOM
+   with name "anabais" "black" "sphere" "earth",
+        description "A black sphere of energy.",
+        life [;
+           ThrowAt:
+              if (noun==brown_sphere) {
+                 remove self; remove brown_sphere;
+                 ENDGAME_ROOM.number = ENDGAME_ROOM.number + 1;
+                 if (ENDGAME_ROOM.number == 4) {
+                    GameWinner(); rtrue; }
+                 "The black sphere howls in rage and is no more!";
+              }
+           Give:
+              if (noun==TRUEROD) {
+                 remove TRUEROD;
+                 print "You feel a strange foreboding feeling as \
+the black sphere seems to engulf the rod, then you! Your \
+surroundings change once again!^";
+                 deadflag = 1;
+                 PlayerTo(badend2);
+                 rtrue;
+              }
+           default: "The black sphere is unresponsive.";
+        ], 
+   has animate; 
+
+Object smoke_elemental "smoke-colored sphere" ENDGAME_ROOM
+   with name "smoke" "sphere" "fire", ! TODO new name...
+        description "A smoke-filled sphere of energy.",
+        life [;
+           ThrowAt:
+              if (noun==red_sphere) {
+                 remove self; remove red_sphere;
+                 ENDGAME_ROOM.number = ENDGAME_ROOM.number + 1;
+                 if (ENDGAME_ROOM.number == 4) {
+                    GameWinner(); rtrue; }
+                 "The smoke-filled sphere howls in rage and is no more!";
+              }
+           Give:
+              if (noun==TRUEROD) {
+                 remove TRUEROD;
+                 print "You feel a strange foreboding feeling as \
+the smoke-filled sphere seems to engulf the rod, then you! Your \
+surroundings change once again!^";
+                 deadflag = 1;
+                 PlayerTo(badend1);
+                 rtrue;
+              }
+           default: "The smoke-filled sphere is unresponsive.";
+        ], 
+   has animate; 
+
+Object gray_elemental "gray sphere" ENDGAME_ROOM
+   with name "gray" "sphere" "water", ! TODO new name
+        description "A gray sphere of energy.",
+        life [;
+           ThrowAt:
+              if (noun==green_sphere) {
+                 remove self; remove green_sphere;
+                 ENDGAME_ROOM.number = ENDGAME_ROOM.number + 1;
+                 if (ENDGAME_ROOM.number == 4) {
+                    GameWinner(); rtrue; }
+                 "The gray sphere howls in rage and is no more!";
+              }
+           Give:
+              if (noun==TRUEROD) {
+                 remove TRUEROD;
+                 print "You feel a strange foreboding feeling as \
+the gray sphere seems to engulf the rod, then you! Your \
+surroundings change once again!^";
+                 PlayerTo(FUBLIO_Cave);  
+                 StartTimer(mad_hermit,3);
+                 rtrue;
+              }
+           default: "The gray sphere is unresponsive.";
+        ], 
+   has animate; 
+
+Object white_elemental "white sphere" ENDGAME_ROOM
+   with name  "white" "sphere" "air",  ! TODO new name
+        description "A white sphere of energy.",
+        life [;
+           ThrowAt:
+              if (noun==silver_sphere) {
+                 remove self; remove silver_sphere;
+                 ENDGAME_ROOM.number = ENDGAME_ROOM.number + 1;
+                 if (ENDGAME_ROOM.number == 4) {
+                    GameWinner(); rtrue; }
+                 "The white sphere howls in rage and is no more!";
+              }
+           Give:
+              if (noun==TRUEROD) {
+                 remove TRUEROD;
+                 print "You feel a strange foreboding feeling as \
+the white sphere seems to engulf the rod, then you! Your \
+surroundings change once again!^";
+                 PlayerTo(TROPHY_SECRET);  
+                 rtrue;
+              }
+           default: "The white sphere is unresponsive.";
+        ], 
+   has animate; 
+
+
+! ******************
+! scrolls/spells 
+! ******************
+
+Object fancy_scroll "fancy scroll" 
+  class scroll_class,
+  with name "fancy",
+;
+
+Object wigro_spell "turn undead" fancy_scroll
+   class spell_class,
+   with name "wigro",
+   magic [;
+      "You speak the chant. Nothing seems to happen.";
+   ],
+;
+
+Object briefcase "briefcase" Subway_Tunnel
+   with name "briefcase" "case",
+        description "A somewhat battered brown-leather briefcase.",
+        capacity 5,
+        ! weight 20, 
+        size 15,
+   has container openable;
+
+Object red_scroll "red scroll" briefcase
+  class scroll_class,
+  with name "red",
+;
+
+Object luncho_spell "send object to lower plane" red_scroll
+  class spell_class,
+  with name "luncho",
+       magic [;
+          if (second == 0)
+"You see a brief flash of smoke, but nothing happens.";
+          if (second has animate)
+             "You feel a slight rumbling beneath your feet, but nothing else \
+happens.";
+          else {
+             if ((second hasnt static) && (second hasnt scenery)) {
+                if (second has clothing) give second ~worn;
+                if (in_atrii == 1) {
+                   move second to MON_Chapel2;
+                }
+                else
+                move second to Hades_5;
+                print "There is a sudden puff of smoke, and "; DefArt(second); 
+                " suddenly vanishes!";
+             }
+             "Your chant goes unanswered.";
+          }
+      ],
+;
+
+! ******************
+! special obs
+! ******************
+
+Object Atrii_gate "strange contraption" GUE_Labs_SECRET
+   with name "contraption" "plate" "disc" "strange",
+        description "It looks like a large, slightly convex round disc \
+        made of some silvery material.",
+        before [;
+           Enter:
+              print "As you step onto the silvery disc, you feel a \
+              strange jolt run through your body. A bright white \
+              flash blinds you momentarily!^^You blink, trying to \
+              register your surroundings.^";
+              in_atrii = 1;
+              PlayerTo(ATRII_1);
+              return 2;
+           Receive:
+              move noun to ATRII_1;
+              CDefArt(noun); " suddenly disappears in a bright \
+              flash of light as you place it on the silver disc!";              
+           Push, Pull, Touch, Take:
+              "As you reach for the strange contraption, you notice \
+              white sparks of something arc from the silver surface \
+              to your fingers! You hastily draw back.";              
+        ],
+   has static supporter enterable;
+
+! *** the true rod pieces, and the golden rod (after joined)
+Object silver_rod_piece "silver rod piece" Mystical_Cave
+   class rod_class,
+   with name "silver",
+        description "A strange short section of rod colored \
+silver.",
+        before [;
+           Join:
+              if (location ~= Mystical_Cave) {
+              if (second == TRUEROD) 
+                 <<Join TRUEROD self>>;
+              if ((second == brown_rod_piece) ||
+                 (second == red_rod_piece) ||
+                 (second == green_rod_piece)) {
+                 if (TRUEROD.number == 0) {
+                    TRUEROD.number = 1;
+                    move TRUEROD to parent(self);
+                    remove self;  remove second;
+                    "There is a dazzling golden light as \
+you join the two rod pieces! What remains is a new, strange \
+rod piece!"; 
+                 }
+                 else "There is a dazzling burst of \
+golden light. However, the pieces will not join, and seem \
+to be seeking out something else...";
+              }
+              }
+              else "Some strange purple flash of force \
+blocks your efforts.";
+        ],
+;
+Object red_rod_piece "red rod piece" Mystical_Cave
+   class rod_class,
+   with name "red",
+        description "A strange short section of rod colored \
+red.",
+        before [;
+           Join:
+              if (location ~= Mystical_Cave) {
+              if (second == TRUEROD) 
+                 <<Join TRUEROD self>>;
+              if ((second == silver_rod_piece) ||
+                 (second == brown_rod_piece) ||
+                 (second == green_rod_piece)) {
+                 if (TRUEROD.number == 0) {
+                    TRUEROD.number = 1;
+                    move TRUEROD to parent(self);
+                    remove self;  remove second;
+                    "There is a dazzling golden light as \
+you join the two rod pieces! What remains is a new, strange \
+rod piece!"; 
+                 }
+                 else "There is a dazzling burst of \
+golden light. However, the pieces will not join, and seem \
+to be seeking out something else...";
+              }
+              }
+              else "Some strange purple flash of force \
+blocks your efforts.";
+        ],
+;
+Object green_rod_piece "green rod piece" Mystical_Cave
+   class rod_class,
+   with name "green",
+        description "A strange short section of rod colored \
+green.",
+        before [;
+           Join:
+              if (location ~= Mystical_Cave) {
+              if (second == TRUEROD) 
+                 <<Join TRUEROD self>>;
+              if ((second == silver_rod_piece) ||
+                 (second == red_rod_piece) ||
+                 (second == brown_rod_piece)) {
+                 if (TRUEROD.number == 0) {
+                    TRUEROD.number = 1;
+                    move TRUEROD to parent(self);
+                    remove self;  remove second;
+                    "There is a dazzling golden light as \
+you join the two rod pieces! What remains is a new, strange \
+rod piece!"; 
+                 }
+                 else "There is a dazzling burst of \
+golden light. However, the pieces will not join, and seem \
+to be seeking out something else...";
+              }
+              }
+              else "Some strange purple flash of force \
+blocks your efforts.";
+        ],
+;
+Object brown_rod_piece "brown rod piece" Mystical_Cave
+   class rod_class,
+   with name "brown",
+        description "A strange short section of rod colored \
+brown.",
+        before [;
+           Join:
+              if (location ~= Mystical_Cave) {
+              if (second == TRUEROD) 
+                 <<Join TRUEROD self>>;
+              if ((second == silver_rod_piece) ||
+                 (second == red_rod_piece) ||
+                 (second == green_rod_piece)) {
+                 if (TRUEROD.number == 0) {
+                    TRUEROD.number = 1;
+                    move TRUEROD to parent(self);
+                    remove self;  remove second;
+                    "There is a dazzling golden light as \
+you join the two rod pieces! What remains is a new, strange \
+rod piece!"; 
+                 }
+                 else "There is a dazzling burst of \
+golden light. However, the pieces will not join, and seem \
+to be seeking out something else...";
+              }
+              }
+              else "Some strange purple flash of force \
+blocks your efforts.";
+        ],
+;
+Object TRUEROD "golden rod" 
+   class rod_class,
+   with name "golden",
+        number 0,
+        description [;
+           print "A wondrous, shimmering golden rod";
+           if (TRUEROD.number < 3) 
+              " that seems slightly short.";
+           else "."; 
+        ],
+        before [;
+           Wave:
+             if (TRUEROD.number == 3) {
+                deadflag = 1;
+! TODO -- this is essentially another 'win', but not a good one
+                "You wave the rod, and feel a sudden blast of force! \
+The spheres howl in terror and \
+suddenly explode! The jolt of power from the rod sends you \
+hurtling through space, and you are lost in an endless \
+tumble through the void..."; 
+             }
+           Join:
+             if ((second == silver_rod_piece) ||
+                 (second == red_rod_piece) ||
+                 (second == green_rod_piece) ||
+                 (second == brown_rod_piece)) {
+                remove second;
+                TRUEROD.number = TRUEROD.number + 1;
+                print "You feel a strange surge of \
+mystic energy as you join the rod pieces. ", (The) second,  " \
+joins with the golden rod";
+                if (TRUEROD.number == 3) {
+                   Achieved(19);
+                   print "!^^Time and space seem to grind to \
+a halt.^^\
+Your surroundings and the very ground you stand on shatter like \
+planes of glass, revealing a strange, new dimension...^";
+                   spell_block = 1;
+                   PlayerTo(ENDGAME_ROOM);
+                   StartTimer(ENDGAME_timer,12);
+                   rtrue;
+                }
+                else "!";
+             } 
+        ],
+;
+
+! *** The results of winning the game ***
+[ GameWinner ;
+   Achieved(26);
+   print "The last sphere howls in rage and disappears!";
+   deadflag = 2;
+   " You scream in agony as the void that surrounds you \
+seems to implode! You feel yourself dissipating into the \
+surrounding nothingness. ~Is this my reward?~ you scream, \
+~Is this, then, the end?~^^\
+A white light makes you open your eyes.^^\
+You are lying on a beach. The Great Sea laps at your \
+tattered garments. Slowly, you rise to your knees.^^\
+The sun, like a bloated, radiant bird, is sinking below the \
+wave on the horizon. Another day is coming to an end.^^\
+A voice startles you. ~Tis a fine spot for watching \
+sunsets.~ You turn to see Morgan the Ranger, Frobar and \
+the Thief nearby. The Thief helps you to your feet, and Frobar \
+glances your way. ~I sensed a great upheaval in the \
+fabric of time and space not long ago. I gather you \
+have quite a story to tell,~ he says. ~We \
+probably can relate to much of what you have seen, \
+although your unwavering faith is something we \
+desire to understand.~ Morgan explains, ~Belief in the \
+face of the unbelievable is an enviable strength.~ \
+The Thief chuckles quietly. \
+~Perhaps you will join us at Delbins, where we will \
+partake in a belief of fine cuisine while you tell all?~ he says. \
+He notices your weary expression and \
+adds with surprising seriousness, ~Not that I \
+prepose to offer advice from one as myself, \
+but humbly, I admit, that many a time, a belief in myself \
+was often sufficient.~ He pauses. \
+~Gods or no, now, you make your own destiny.~";
+];
diff --git a/src/SPIRIT.INF b/src/SPIRIT.INF
new file mode 100644 (file)
index 0000000..2430f34
--- /dev/null
@@ -0,0 +1,3075 @@
+! *****************************************************************
+! SPIRITWRAK -- An exercise in copyright infringement :)
+! 
+!    Release 1, 12/95 -- 3/96 
+!    Release 2, 3/96 --  
+!    Release 3, 4/96 --  
+!    Copyright (C) 1996, D. S. Yu
+!
+!    This program is free software; you can redistribute it and/or modify
+!    it under the terms of the GNU General Public License as published by
+!    the Free Software Foundation; either version 2 of the License, or
+!    (at your option) any later version.
+!
+!    This program is distributed in the hope that it will be useful,
+!    but WITHOUT ANY WARRANTY; without even the implied warranty of
+!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!    GNU General Public License for more details.
+!
+!    You should have received a copy of the GNU General Public License
+!    along with this program; if not, write to the Free Software
+!    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+!
+!    To contact the author (Dan Yu), send email to dsyu@holonet.net.
+!
+! *****************************************************************
+
+! SPECIAL THANKS:
+!   Mr. Blank, Lebling, Meretzky, Moriarty for the Zork universe.
+!   Graham Nelson for Inform, and for various code I've shamelessly cribbed.
+
+! NUTRITION NOTE:  No Microsoft(tm) products were used in the 
+! construction of this game
+
+! ** inform compile switches here **
+Switches exv5b;
+
+! ** abbreviations
+Include "spirita.inf"; 
+
+! ** Story Constants **
+Constant Story "SPIRITWRAK";
+Constant Headline "^An Interactive Fantasy Adventure^\
+                  Copyright (C) 1996, by D.S. Yu.^\
+Portions copyright Graham Nelson.^^\
+'SPIRITWRAK' comes with ABSOLUTELY NO WARRANTY ^\
+This is free software, and you are welcome to redistribute it \
+under conditions as described in the GNU General Public License as published by \
+the Free Software Foundation; either version 2 of the License, or \
+(at your option) any later version.^^";
+
+Release 3;
+
+! ** Scoring System
+Constant MAX_SCORE 250;
+Constant NUMBER_TASKS 27;
+Constant TASKS_PROVIDED;
+Constant OBJECT_SCORE 2;
+! Constant ROOM_SCORE 1;
+! Global task_scores initial t1 t2 t3.....
+Array task_scores -> 2 5 5 5 10 15 5 5 5 5 5 5 10 10 10 5 5 5 10 10 5 5 10 5 5 5 10; 
+
+! ** Player inventory and weight system
+Constant MAX_CARRIED 15;  ! Max of 15 items carried at start
+         ! This can be changed on the fly by adjusting player.capacity
+Property weight; 
+! Entire weight system removed 3/16/96, however certain puzzles
+! inadvertently depend on this, so...
+Property size;
+
+global Player_HP_MAX = 20; ! number of hp MAX (should be 20 + score)
+global Player_HP_CUR = 20; ! number of hp left (< MAX)
+global Player_Lives_Left = 3;  ! number of resurrects left 
+global in_hades = 0;           ! Is the player in Hades? (we certainly hope not)
+global in_atrii = 0;           ! Is the player in Atrii? 
+! global all_my_spells data 32;   array for spells in spell book
+Array all_my_spells -> 64;  ! array for spells in spell book
+global has_resist_gravity = 0; ! is player resisting gravity?(see feeyuk spell)
+global spell_block = 0;        ! block spell-related stuff (end-game)
+
+! Any actions that are replaced get mentioned here
+Replace PraySub;
+Replace StrongSub;
+Replace InsertSub;  ! for relative sizes
+
+! *** Include Parser and VerbLib
+Include "Parser";
+Include "VerbLib";
+
+! -- two global location ptrs for Barsap's Gambit
+global WN_TO;
+global ES_TO;
+
+! ******************* CLASS DEFS *****************
+
+! ** rod (part) class and attribute
+Attribute is_rod;
+
+Class rod_class
+   with name "rod",
+        description "A thin rod made from some undeterminable material.",
+        !weight 10,
+        size 10,
+        before [;
+           Cast:
+              "You complete the chant, but the rod lies unaffected! \
+              Perhaps it is protected from magic somehow?";
+           Join:
+              if (second has is_rod)
+                 "You try to bring the rods together, but a \
+sudden blast of energy prevents you, and stings your hands!";
+! (note that true rod pieces have their own Join befores, which
+! should, in theory, get called instead of this one).
+        ],
+   has is_rod scored;
+
+Class parchment_class
+   with name "parchment",
+        description "A piece of blank parchment.",
+        !weight 10,
+        size 15,
+;
+
+Attribute is_sphere;
+
+Class sphere_class
+   with name "sphere",
+        description "A small hard sphere made from some undeterminable material.",
+        !weight 5,
+        size 3,
+        before [;
+           Cast:
+              "You complete the chant, but the sphere lies unaffected! \
+              Perhaps it is protected from magic somehow?";
+        ],
+   has is_sphere scored;
+
+Attribute is_flag;
+
+Class flag_class
+   with name "flag" "cloth",
+        plural "flags",
+        description "A short square piece of colored cloth.",
+        !weight 10,        
+        size 15,
+   has is_flag;
+
+Class trophy_dep_class
+   with name "depression" "niche" "hole" "keyhole",
+      initial [;
+print "There is a circular depression in the center of the floor";
+if (trophy in self)
+   ". Sitting in the depression is a trophy.";
+else ".";
+      ],
+      description [;
+print "A small circular depression in the center \
+      of the stone floor";
+if (trophy in self)
+     ". At the moment, the depression holds a trophy.";
+else ". There seem to be three small concave \
+      marks in the otherwise flat stone of the depression.";
+      ],
+      size 8,
+      capacity 1,
+has static container open;
+   
+Attribute is_niche;
+Property counter_niche;  
+Property niche_dir;  ! assoc with the dir a niche is facing.
+
+Class niche_class 
+   with name "niche",
+        capacity 1,
+        niche_dir 1,  ! default north
+        description "It looks like a chiseled-out niche in the floor.",
+        initial [;
+           switch (self.niche_dir) {
+           1: print "There's a square niche in the northern edge of the floor here";
+           2: print "There's a square niche in the western edge of the floor here";
+           3: print "There's a square niche in the southern edge of the floor here";
+           4: print "There's a square niche in the eastern edge of the floor here";
+           }
+           if (children(self) ~= 0) {
+              print ". Resting in the niche is ";
+              InDefArt(child(self));
+              print " that extends into the darkness";
+! weird -- There is no "CInDefArt(), equiv to (A) obj, which
+! is probably pretty simple...
+           }
+           ".";
+        ],
+        before 
+        [ j ;
+          Receive:
+            if (noun hasnt is_wood_beam)
+                 "That's not going to stay in the niche.";
+            else {
+               ! (odd capacity check, seems like I'm stepping in front...)
+               if (children(self) ~= 0)
+                  "The niche space is currently full.";
+               ! place both pieces in niches
+               j = child(noun);  ! child piece (whichever)
+               move j to self.counter_niche;
+               move noun to self;
+               "You carefully place one end of the beam in the niche and \
+               extend the other end into the darkness. You feel something \
+               solid support the far end!";
+            }
+          LetGo:
+            ! (reconstruct wood beam) Assumption is that noun must have 
+            ! wood_beam attrib.
+            move child(self.counter_niche) to child(self);
+            move child(self) to player;
+            "Taken.";
+        ],  
+        has static container open is_niche; 
+
+! ** multiple coins, cribbed from "Balances"
+Attribute is_coin;
+Class  coin_class
+  with name "coin",
+       description "A round metal disc, with ~1zm~ stamped on both sides.",
+       !weight 1,
+       size 1,
+       parse_name
+       [ i j w;
+         if (parser_action==##TheSame)
+         {   if ((parser_one.&name)-->0 == (parser_two.&name)-->0) return -1;
+             return -2;
+         }
+         w=(self.&name)-->0;
+         for (::i++)
+         {   j=NextWord();
+             if (j=='coins') parser_action=##PluralFound;
+             else if (j~='coin' or w) return i;
+         }
+       ], 
+       plural "coins",
+  has  is_coin;
+
+! ** Spell-casting system, again cribbed from Graham's "Balances",
+!    except stuffy priests call them 'chants'...
+! ----------------------------------------------------------------------------
+!   Now the whole spell-casting system
+! ----------------------------------------------------------------------------
+
+Attribute is_spell;
+Attribute known_about;
+Attribute is_scroll;    
+Attribute is_spell_book;
+Property magic;
+Fake_Action SayName;
+
+[ SpellName obj; print (address) (obj.&name)-->0; ];
+
+Class  spell_class
+  with name "spell" "spells" "chant" "chants", article "the", number 0,
+       short_name
+       [; SpellName(self); print " chant"; give self known_about; rtrue;
+       ],
+       before
+       [; 
+  !        SayName: SpellName(self); print " chant:  ", object self;
+          SayName: SpellName(self); print " chant:  ", self;
+                   give self known_about; rtrue;
+          Examine: <SayName self>; ".";
+       ],
+       size 0,
+  has  is_spell;
+
+Object memory "memory"
+  with capacity 5,   ! will change periodically, given God-granted powers...
+       number 1,
+       size 0,
+       before
+       [ i j k;
+         Examine:
+           if (spell_block == 1)
+               "Currently, your mystic powers don't seem to be working.";
+           objectloop (i in self) if (i.number==100) j++;
+           if (j>0)
+           {   print "The ";
+               objectloop (i in self)
+                   if (i.number==100)
+                   {   k++; SpellName(i);
+                       if (k==j-1) print " and ";
+                       if (k<j-1) print ", ";
+                   }
+               if (j==1) print " chant is"; else print " chants are";
+               print " yours forever. Other than that, y";
+           }
+           else print "Y";
+           print "ou have ";
+           j=0; k=0;
+           objectloop (i in self) if (i.number<100) j++;
+           if (j>0)
+           {   print "the ";
+               objectloop (i in self)
+                   if (i.number<100)
+                   {   k++;
+                       PrintShortName(i);
+                       if (i.number==2) print " (twice)";
+                       if (i.number==3) print " (thrice)";
+                       if (i.number==4) print " (four times)";
+                       if (i.number>=5) print " (many times)";
+                       if (k==j-1) print " and ";
+                       if (k<j-1) print ", ";
+                   }
+           }
+           else print "no chants";
+           " prepared.";
+         Insert:
+           if (spell_block==1)
+               "Currently, your mystic powers don't seem to be working.";
+           if (second.number==100) "You always know that chant.";
+           self.number=self.number+1;
+           print "Making a quick prayer to the Gods, you prepare the ";
+           SpellName(second);
+           print " chant";
+           if (second notin self) second.number=0;
+           move second to self;
+           second.number=second.number+1;
+           if (second.number==1) print ".";
+           if (second.number==2) print " once again.";
+           if (second.number==3) print " a third time.";
+           if (second.number>3) print " yet another time.";
+           if (self.number <= self.capacity) { new_line; rtrue; }
+           i=youngest(self); <Remove self i>;
+           "^A voice booms out ~Do not try to exceed your powers, mortal!~";
+         Remove:
+           if (second notin self || second.number==100) rtrue;
+           if (self.number>0) self.number=self.number-1;
+           second.number=second.number-1;
+           if (second.number==0) remove second;
+           rtrue;
+       ];
+
+Object gnusto_spell "copy a chant into your prayer book" memory
+ class spell_class
+  with name "gnusto",
+       number 100,
+       magic
+       [ i a_book;
+            if (spell_block==1)
+               "Currently, your mystic powers don't seem to be working.";
+            if (amulet hasnt worn)
+               "You speak the chant, and absolutely nothing happens!";
+            if (second has is_spell_book)
+               "Unlike scrolls, prayer books are magically guarded against \
+                the 'theft' of their lore.";
+            if (second==0 || second hasnt is_scroll)
+               "Your chant goes unanswered.";
+            if (second notin player)
+                "A gnusto chant would require close scrutiny of the scroll \
+                 it is to copy, which you do not seem to be holding.";
+            objectloop (i in player)
+                if (i has is_spell_book) a_book=i;
+            if (a_book==0)
+                "Your chant fails, as you have no prayer book.";
+            i=child(second);
+            if (i==0 || i hasnt is_spell)
+            {   print "Your chant fails, as "; DefArt(second);
+                " is illegible.";
+            }
+            <Learn a_book i>; remove second;
+            print "Your prayer book begins to shake! Slowly, ornately, \
+                   the words of "; DefArt(i); " are inscribed, \
+                   into the book with a violet glow. \
+                   The book's brightness fades, but the chant remains! \
+                   However, the scroll on which it was written vanishes as \
+                   the last word is copied.";
+       ];
+
+Class  spell_book_class
+  with magic 0,
+       capacity 20,
+       size 15, 
+       before
+       [ p i; Open, Close:
+              CDefArt(self); " will always open to the desired page thanks \
+              to the powers of the Gods, may they never forget us.";
+          Attack:
+              print "When you are done, "; DefArt(self); " remains unmarred.";
+          Learn:
+              if (self.magic==0) "(This prayer book has no pages.)";
+              p = self.magic;
+              for (i=0:i<self.capacity && (p-->i)~=0:i++) ;
+              if (i==self.capacity) rtrue;
+              p-->i = second;
+              rtrue;
+       ],
+       after
+       [ p i j; Examine:
+              if (self.magic==0) "(This prayer book has no pages.)";
+              p = self.magic;
+              for (i=0:i<self.capacity && (p-->i)~=0:i++)
+              {   j=p-->i; <Examine j>;
+              }
+              rtrue;
+       ],
+  has  is_spell_book;
+
+Class  scroll_class
+  with parse_name
+       [ i j k; j=-1;
+              if (self has general)
+              {   if (child(self)~=0 && child(self) has is_spell)
+                      j=(child(self).&name)-->0; else j='illegible';
+              }
+              for (::) {
+                 k = NextWord();
+                 if (k=='scrolls') parser_action = ##PluralFound;
+                 if ((k=='scrolls' or 'scroll' or j) || (k==(self.&name)-->0))
+                    i++;
+                 else return i;
+              }
+              ! while (NextWord()==j or 'scroll' or (self.&name)-->0) i++;
+              ! return i;
+       ],
+       before
+       [ i; Examine:
+            i=child(self);
+            give self general;
+            if (i==0 || i hasnt is_spell)
+                "The scroll has faded, and you cannot read it.";
+            print "The scroll reads ~"; <SayName i>; "~.";
+       ],
+       invent
+       [;   if (inventory_stage==2 && self has general)
+            {   if (child(self)==0 || child(self) hasnt is_spell)
+                    print " (which is illegible)";
+                else
+                {   print " (of "; DefArt(child(self)); print ")"; }
+            }
+       ],
+       size 10,
+  has scored is_scroll;
+
+! NOTE: This routine has a slight bug (as cribbed from GN's
+! Balances, rel2) in that Examine, if the routine reaches
+! scope_stage 3, prints a rather confusing msg.  However,
+! the appropriate msg is printed for, say, Learn, if the
+! spell is unknown/out-of-scope.  Oddly, action can't
+! be checked at stage 3, so I copied a second version of
+! the routine for Examine only.  -DY
+! 3/19 update: Checking Graham's release 3 of Balances, 
+! I stumble across the "action_to_be" var.  Most useful.
+[ ReadableSpell i j k;
+  if (scope_stage==1) return 1;
+  if (scope_stage==2)
+  {   objectloop (i in player)
+          if (i has is_spell_book)
+          {   for (k=0:k<i.capacity && (i.magic)-->k~=0:k++)
+              {   j=(i.magic)-->k; PlaceInScope(j);
+              }
+          }
+      rtrue;
+  }
+  if (action_to_be == ##Examine) 
+     "You can't see any such thing.";
+  !"You have never seen or heard of such a chant.";
+  "You can't see such a chant, if that is indeed a chant.";
+];
+
+[ SpellsSub; <Examine memory>; ];  ! for our case, 'chants' will work also
+
+[ LearnSub; if (location==thedark)
+                print "(The magic purple glow of the chants casts enough light \
+                        that you can read them.)^";
+            <Insert memory noun>;
+];
+
+global the_spell_was = gnusto_spell;
+
+[ CastOneSub; <Cast the_spell_was noun>; ];
+
+! Property long unmagic;
+
+
+! (wood beams and niches -- for Barsap's Gambit)
+! (put after 'the_spell_was' global defined)
+
+Attribute is_wood_beam;
+
+Class wood_beam_class
+  with name "wood" "beam",
+       plural "beams",
+       description "A long thin wooden beam.",
+       !weight 10,
+       size 50,
+       number 0,   ! number is the 'strength left' qualifier
+       before [;
+          Cast:
+          if (the_spell_was == egdelp_spell)
+             "The wood beam is covered in a waxy film! Thinking \
+better of this, you hastily wipe off the offending build-up.";
+          if ((the_spell_was == luncho_spell or huncho_spell) &&
+              (parent(self) has is_niche)) {
+          ! reconstruct beam before teleporting
+          ! due to problem below, I'm denying this...
+"Your chant goes unanswered.";
+           !  move child(parent(self).counter_niche) to self;
+           !  <<Cast the_spell_was self>>; 
+           ! NOTE NOTE This may recursively explode...
+          }
+       ],
+  has is_wood_beam;
+
+Class balsa_beam_class
+   class wood_beam_class,
+   with name "balsa",
+        plural "balsa wood beams",
+        description "A long thin balsa wood beam.",
+        number 0;  ! always breaks
+
+Class pine_beam_class
+   class wood_beam_class,
+   with name "pine",
+        plural "pine wood beams",
+        description "A long thin pine wood beam.",
+        number 1;
+        
+Class ebony_beam_class
+   class wood_beam_class,
+   with name "ebony",
+        article "an",
+        plural "ebony wood beams",
+        description "A long thin ebony wood beam.",
+        number 2;
+                
+[ CastSub k;
+  the_spell_was = noun; <Remove memory noun>;
+
+!  if (noun has general)
+!  {   give noun ~general;
+!      if (RunRoutines(noun,unmagic)~=0) rfalse;
+!      "Nothing happens.";
+!  }
+
+  if (amulet hasnt worn)
+     "You speak the chant, and absolutely nothing happens!";     
+  if (spell_block==1)
+     "Currently, your mystic powers don't seem to be working.";
+  if (in_hades == 1)
+     "Your Gods can't save you now...";
+  if (second~=0)
+  {   ResetVagueWords(second);                     ! Set "it", "him", "her"
+      if (RunRoutines(second,before)~=0) rfalse;   ! Run before routine(s)
+  }
+  k = random(10);
+  if (k<=3) {
+     if (k==1)
+        "You speak the chant, but the Gods are not kind this time, as nothing happens!";
+     if (k==2 or 3)
+        "You speak the chant, but something sounds wrong. Nothing happens \
+this time."; 
+  }
+  if (RunRoutines(noun,magic)~=0) rfalse;
+  "Nothing happens.";
+];
+
+[ InScope i;
+  if (verb_word=='c,cast' or 'cast')
+      objectloop (i in memory) PlaceInScope(i);
+  rfalse;
+];
+
+[ ParserError x i flag vb;
+  if (etype==VERB_PE or ASKSCOPE_PE)
+  {   if (etype==ASKSCOPE_PE)
+      {   if (verb_word=='cast') vb=1;
+          if (verb_word=='learn' or 'memorise' or 'memorize') vb=2;
+          if (verb_word=='copy') vb=3;
+          if (vb==0) { etype=CANTSEE_PE; rfalse; }
+      }
+      wn=verb_wordnum; if (vb~=0) wn++;
+      x=NextWordStopped();
+      for (i=player+1:i<=top_object:i++)
+          if (i has is_spell && Refers(i,x)==1
+              && i has known_about) flag=1;
+      if (flag==1)
+      {   if (vb==0 or 1)
+             "You haven't got that chant prepared. [Type ~spells~ \
+              or ~chants~ to see what you do have prepared.]";
+          if (vb==2)
+             "Your training is such that you can only prepare such a chant \
+              with the aid of a prayer book containing it.";
+          if (vb==3)
+             "You have no text of that chant to copy.";
+      }
+      if (vb==1)
+         "You haven't prepared that chant, if indeed it is a chant.";
+      if (vb==2 or 3)
+         "You haven't access to that chant, if indeed it is a chant.";
+  }
+  rfalse;
+];
+
+! Random attempt to code a ChooseObjects for the
+! coin choosing problem often seen in the Bank of Zork
+[ ChooseObjects obj code;
+  if (code < 2) rfalse;
+  if ((action_to_be == ##Remove or ##Insert) &&
+      (obj has is_coin) && (obj in player)) return 9;
+  return 0;
+];
+
+[ UnknownVerb word i;
+  objectloop (i in memory)
+      if (word==(i.&name)-->0) { the_spell_was = i; return 'c,cast'; }
+  rfalse;
+];
+
+[ PrintVerb v;
+  if (v=='c,cast') { print "cast a chant at"; rtrue; }
+  rfalse;
+];
+
+! ----------------------------------------------------------------------------
+!   The player's spell book, and initial spells (to go with gnusto):
+! ----------------------------------------------------------------------------
+
+Object prayer_book "prayer book"
+ class spell_book_class,
+  with name "prayer" "book" "my" "spellbook",
+       description "Mystical Chants^";
+
+Object frotz_spell "cause an object to give off light"
+ class spell_class,
+  with name "frotz",
+       magic
+       [;  if (second==0) "There is a brief, blinding flash of light.";
+           if (second has animate)
+               "The chant, not designed for living creatures, is denied.";
+           if (parent(second)==compass)
+               "The chant fails.";
+           give second light;
+      print "There is an almost blinding flash of light as "; DefArt(second);
+      print " begins to glow! It slowly fades to a less painful level, but ";
+      DefArt(second); " is now quite usable as a light source.";
+       ],
+;
+
+! ** Start of locations (and other objs) **
+
+! ***********************************************************************
+! **
+! ** LOCATIONS INSIDE MONESTARY (Mostly)
+! **
+! ***********************************************************************
+
+Object MON_Chapel1 "Monastery Chapel"
+      with description "You are standing in a monastery chapel. \
+All around you, fellow Brothers of the Order are standing, chanting. \
+The eerie droning voices seem to reverberate into the air. At the \
+front of the chapel, Brother Joseph stands in deep concentration, \
+holding the Rod of the Ancients.",
+      name "brothers",
+      number 0,
+      each_turn [ ;
+          MON_Chapel1.number = MON_Chapel1.number + 1;
+          Startup1(MON_Chapel1.number);
+      ],
+      before [ ;
+          if (action==##Listen) "You hear heavy chanting";
+          if (action==##look) rfalse;
+          if (action==##Wait) rfalse;
+          "You are caught up in the collective chanting, and cannot break \
+           your concentration to do much of anything else.";
+      ],
+      has light;
+    
+! A fake obj to handle 'look at Joseph'
+Object MON_FAKE "the Order" MON_Chapel1
+   with name "Joseph" "rod" "brothers",
+   description [; <<Look>>;],
+has scenery;
+
+! A somewhat bulky routine to set our stage.  
+[ Startup1 currturn;
+   if (currturn <= 1) {
+      print "^Brother Joseph now speaks directly to the entire Order.^^\ 
+      ~Fellow Brothers, the year, as you know, is 976 GUE. \
+      A difficult time indeed. Ten years have passed since the Cataclysm \
+      brought forth by the Circle of Enchanters changed our world forever. \
+      The outside world as we know it is in turmoil. A period of great \
+      change is upon all of us.~^";
+      rtrue;
+   }
+   if (currturn == 2) {
+      print "^Brother Joseph continues speaking.^^\
+      ~Our order has always maintained the strictest secrecy. Few \
+      outside of our order know of our existence. \
+      We are the keepers of the mystic balance \
+      that which embodies pure magic that can keep our world \
+      safe. It has always been thus -- we watch over all \
+      of Quendor, never interfering in the affairs of others, yet \
+      striving to maintain harmony.~^";
+      rtrue;
+   }
+   if (currturn == 3) {
+      print "^Brother Joseph continues speaking.^^\
+      ~But we can no longer depend on enchantments to keep \ 
+      outsiders at bay. Magic as we know it is dying. The dreaded \
+      Age of Science is already upon us, and in short time, our \
+      order will be discovered, and the balance will be no more. Many of \
+      our order have gone out into the world in secret, in attempts \
+      to repair what has been broken, but alas, this appears to be \
+      impossible.~^"; 
+      rtrue;  
+   }
+   if (currturn == 4) {
+      print "^Brother Joseph continues.^^\
+      ~I have brought you all forth today to say that although we \
+      cannot protect the future of Quendor, we can protect ourselves!~ \
+      He holds the Rod of the Ancients high. ~This holy Rod, which \
+      the Ancient Ones used to defeat the demon Anabais, \
+      has the power to protect our order. I have discovered a lost mystic \
+      cube!~ He holds a white, featureless cube high in his other hand. \
+      ~This cube, when joined with the Rod of the Ancients, will \
+      preserve our order forever, sequestering all of us in another time, \
+      another place!~^";
+      rtrue;
+   }
+   if (currturn >= 5) {
+      print "^There is a momentous pause. ^^\
+      Brother Joseph looks at the entire Order. \
+      ~May the Gods smile down upon us on this day! We go now, \
+      into the unknown!~ He triumphantly joins the white cube to \
+      the end of the Rod of the Ancients.^^\
+      There is a sudden, blinding white flash! The chanting is instantly \
+      broken by a tremendous thunderclap! Brother Joseph is suddenly \
+      thrown back by a great force, and to your horror, the Rod of the \
+      Ancients breaks apart! Four pieces now float serenely above the \
+      altar, above a strange black globe that seems to crackle with energy.^^\
+      ~AT LAST!~^^\
+      The voice comes from nowhere and everywhere. The black sphere \
+      pulsates with lightning.^^\
+      ~ANABAIS IS FREE AGAIN!~ The voice pauses. \
+      ~I see you found my fake mystic cube \
+      Joseph. I knew that someday, someone would find it, and free \
+      me from my prison!~ The voice pauses again. ~To show my gratitude, I'm \
+      scattering this broken symbol to the corners of the world!~ \
+      The pieces of the rod suddenly disappear!^^\
+      ~Watch out!~ someone cries. \
+      The black sphere suddenly expands with alarming speed. \  
+      Seconds later, a violent explosion seems to jar the very \
+      ground you stand on, and a black void covers all.^^\
+      You awaken in your room in a cold sweat. Was it all a terrible \
+      dream? The day beckons...^";
+      PlayerTo(MON_your_quarters);
+      ! remove MON_Chapel1;  clean up memory (NOTE: This is futile)
+      rfalse;
+   }
+];
+
+
+Object MON_your_quarters "Your Quarters"
+   with name "furnishing" "furnishings",
+   description "You are in your room in the Monastery. It is \
+sparsely furnished, but certainly feels like home. The exit \
+is north.",
+   n_to MON_f1hall1,
+   has light;
+
+Object note "note" MON_your_quarters
+with name "note",
+        description "The note, in a hastily written scrawl, reads:^\
+            ~Please stop by the chapel as soon as you can.^\
+            -- Joseph~",
+        !weight 1,
+        size 5, 
+;
+
+!Object staff "staff" MON_your_quarters
+!   with name "staff" "walking" "trusty" "stick",
+!        initial "Your trusty walking staff is right where you left it.",
+!        description "A stout piece of pine you found while on a nature \
+!                     walk, this staff has served you well on many journeys.",
+        !weight 20,
+!        size 20,
+!;
+
+Object sleeppallet "sleeping pallet" MON_your_quarters
+   with name "pallet" "sleeping" "roll",
+   description "This is your sleeping pallet, a short portable sleeping roll \
+               made of straw. It's softer than it looks.",
+   size 25,
+   react_before [;
+      Go: if (player in self) "You'll have to get off the sleeping \
+pallet first.";
+   ],
+   has supporter enterable;
+
+Object MON_f1hall1 "Hallway (near your quarters)"
+   with description "You are in a hallway running west and east. The \
+vaulted ceilings are a nice touch. Your \
+quarters are to the south.",
+   name "vaulted" "ceiling",
+   s_to MON_your_quarters,
+   w_to MON_f1hall2,
+   e_to MON_f1hall3,
+   has light;
+
+Object MON_f1hall3 "Hallway (near quarters of Palemon and TuffBerry)"
+   with description "You are in a hallway running west and east. \
+Brother TuffBerry's quarters lie to the south. Brother Palemon's \
+quarters are to the north.",
+   w_to MON_f1hall1,
+   e_to MON_f1hall4,
+   n_to MON_Palemon_quarters,
+   s_to MON_Tuffberry_quarters,
+   has light;
+   
+Object MON_f1hall4 "Hallway (east end)"
+   with description "You are at the east end of an east-west hallway. \
+Brother Joseph's quarters lie to the north, and Brother Toolbox's \
+quarters lie to the south.",
+! The acolyte chambers lie to the east.",
+   w_to MON_f1hall3,
+   ! n_to MON_Joseph_quarters,
+   n_to "It doesn't look like Joseph is in. Perhaps you can find \
+him elsewhere.",
+   s_to MON_Toolbox_quarters,
+!   e_to MON_acolyte_chambers,
+   has light;
+      
+! Object MON_acolyte_chambers "Acolyte Chambers"
+!    with description "You are in a long chamber that serves as the home \
+! for the many devoted acolytes of the Order.  The room is currently \
+! empty.",
+!    w_to MON_f1hall4,
+!    has light;
+   
+Object MON_f1hall2 "Hallway (west end)"
+   with description "You are at the west end of an east-west hallway. \
+There are stairs up and down here, and an exit to the west.",
+   name "stairs",
+   e_to MON_f1hall1,
+   u_to MON_f2hall1,
+   d_to MON_f0hall1,
+   w_to MON_garden,
+   has light;     
+
+Object MON_garden "Monastery Gardens"
+   with description "You are in the Monastery gardens, where various \ 
+shrubs and conifers are covered in a light blanket of snow. \
+An open cloister lies to the west, while \
+a doorway heads east.",
+   name "cloister" "doorway" "shrubs" "conifers",
+   w_to MON_cloister,
+   e_to MON_f1hall2,
+   has light;
+!Nearby shrubs "snow-covered shrubs"
+!   with name "shrubs" "shrub" "snow-covered" "conifers" "conifer" "plants",
+!        description "Good thing they're evergreen.",
+!   has scenery;
+   
+Object sand "sand" MON_garden
+   with name "sand",
+        initial "A small area in the snow has been cleared for late winter \
+planting, and some sand has been sprinkled here and there.",
+        description "A handful of sand, nothing more, nothing less.",
+        !weight 5,
+        size 5,
+        article "some",
+;
+
+Object MON_cloister "Cloister Walkway"
+   with description "You are in an open cloister, that runs along the \
+Monastery gardens to the east. To the north is the main wing of the \
+Monastery. To the south is the entrance hall.",
+   name "cloister",
+   e_to MON_garden,
+   n_to MON_Main_hall,
+   s_to MON_Entrance_hall,
+   has light;
+   
+Object MON_Entrance_hall "Entrance Hall"
+   with description "This is the large entrance hall to the Monastery. \
+Many a devoted visitor has passed through this place. \
+There is an exit to the outside world to the \
+south, and the rest of the Monastery lies to the north.",
+   s_to Cliff_face, out_to Cliff_face,
+   n_to MON_cloister,
+   before [;
+      Go:
+         if ((noun==s_obj) || (noun==out_obj))
+            print "You are surprised by a cold blast of wind as you leave the Monastery!^";
+   ],
+   after [;
+      Go:
+         if ((noun==in_obj) || (noun==n_obj))
+            print "You are greeted by relatively warm and cozy air.^";
+   ],
+   has light;
+
+Object MON_Main_hall "Main Hall"
+   with description "This is the main hall of worship in the Monastery. \
+A large domed ceiling hides some sort of lighting that create a warm yet \
+serene atmosphere. A covered walk to the rest of the Monastery lies to \
+the south. To the north is the Monastery chapel. A brazier sits in \
+the center of the room.",
+        name "dome" "ceiling" "lighting" "atmosphere",
+        s_to MON_cloister,
+        n_to MON_Chapel2,
+   has light;
+   
+Nearby brazier "brazier"
+   with name "brazier",
+        description "This is a silver incense brazier, somewhat similar to \
+an ornamental bowl on a tripod. Brother Palemon supposedly \
+found it on one of his many journeys.",
+        before [;
+           Take:
+              "That's been in the Monastery for years. People would \
+              be upset if you took it.";
+           Receive:
+      !        if (noun~=incense)
+               if (noun has is_sphere) {
+                  print "As you place the sphere in the brazier, \
+you feel a strange sensation. Suddenly, the brazier is filled \
+with ";
+                  if (noun == brown_sphere)
+                     print "earthworms!";
+                  if (noun == green_sphere)
+                     print "seawater!";
+                  if (noun == red_sphere)
+                     print "burning embers!";
+                  if (noun == silver_sphere)
+                     print "white vapors!";
+                  " No, wait, it's empty again. You hastily \
+withdraw the sphere, and try to clear your mind.";
+               }
+               else "That doesn't seem quite appropriate.";                 
+        ],
+        size 9,
+   has scenery container open;
+
+Object MON_Chapel2 "Monastery Chapel"
+   with description "You are in the Monastery Chapel, the site of the \
+recent appearance of the legendary Anabais. Signs of the \
+recent visit include the slightly scorched walls, and the \
+reek of brimstone. Wood pews are arranged in a circle \
+around the central altar. The exit is south.",
+   name "pews" "scorched",
+   s_to MON_Main_hall,
+   before [;
+      Smell:
+         "You detect the faint odor of brimstone.";
+!      Yell: 
+!         if ((parent(Joseph)==MON_Chapel2) && (Joseph hasnt general))
+!            "Shhh.  You don't want to abruptly disturb Joseph like that.";
+!      Go: 
+!         if (noun==s_obj) {
+!            if ((parent(Joseph)==MON_Chapel2) && (Joseph has general) &&
+!                (WeightOf(Joseph) > 140)) {
+!               if (WeightOf(Joseph) == 149) {
+!                  Joseph.weight = 139;
+!                  print "^As you leave, Brother Joseph calls out \
+!                   ~Oh, and take something for that cold!~^";
+!                   rfalse;
+!               }
+!               if (WeightOf(Joseph) == 148) {
+!                  Joseph.weight = 139;
+!                  print "^As you leave, Brother Joseph calls out \
+!                  ~Oh, and remember -- reading the scriptures \
+!                  is one sure way of maintaining an active mind!~^";
+!                  rfalse;
+!               }
+!               if (WeightOf(Joseph) == 147) {
+!                  Joseph.weight = 139;
+!                  print "^As you leave, Brother Joseph calls out \
+!                  ~Oh, and remember -- mirth is wonderful for the soul, \
+!                  in moderation, of course.~^";
+!                  rfalse;
+!               }
+               ! add in any others here...
+!            }
+!         }
+!      Sneeze:
+!              if (Joseph hasnt general) {
+!                 give Joseph general;
+!                 Joseph.weight = 149;
+!                 JosephWakeAction();
+!                 rtrue;
+!              }
+!      Yawn:
+!              if (Joseph hasnt general) {
+!                 give Joseph general;
+!                 Joseph.weight = 148;
+!                 JosephWakeAction();
+!                 rtrue;
+!              }
+!      Laugh:
+!              if (Joseph hasnt general) {
+!                 give Joseph general;
+!                 Joseph.weight = 147;
+!                 JosephWakeAction();
+!                 rtrue;
+!              }                                          
+!      Drop:
+!              if (Joseph hasnt general) {
+!                 give Joseph general;
+!                 Joseph.weight = 146;
+!                 JosephWakeAction();
+!                 move (inp1) to MON_Chapel2;
+!                 rtrue;
+!              }                                          
+    ],
+   has light;
+   
+! And now, the incredible shrinking Brother Joseph...
+! Modified 3/16 -- this puzzle seems to be unpopular...
+Object Joseph "Joseph" MON_Chapel2
+   with name "Brother" "Joseph",
+        description "Brother Joseph is a pale man, with gray eyes, a fine \
+            beard, and a finer disposition.",
+!        weight 150,
+        number 0,  ! used to hold count of (fake) rod pieces received
+        describe [;
+!           if (self hasnt general)
+!            "Brother Joseph is kneeling in front of the remains of the altar, \
+!            his eyes closed, deep in meditation.";
+!           else
+              "Brother Joseph is here, standing by the altar.";
+        ],
+        life [;
+!           if ((WeightOf(Joseph) == 150) && ((action ~= ##Attack) || 
+!                                             (action ~= ##WakeOther)))
+!              "Perhaps it's best not to bother him, he seems very \
+!              deep in meditation.";
+!           WakeOther:
+!              if (WeightOf(Joseph) == 150)
+!                 "Joseph isn't asleep, just meditating.  You may need to \
+!do something subtle to rouse him.";
+           Attack, ThrowAt:
+              deadflag = 1;
+              Player_Lives_Left = 0;
+"Your blow sends Brother Joseph staggering back.^^\
+Brother Joseph gets up and brushes himself off, and glares \
+at you. Ro-roo, I think you made him mad. \
+You remember, of course, that Brother Joseph is a renowned \
+full-contact martial artist?^^\
+~Impudent wretch! I'll show you how we deal with non-believers here!~\
+^^Suddenly, Brother Joseph produces a gigantic mallet from \
+beneath his robes and clobbers you into a pulp.";
+           Ask:
+              if (second=='amulet')
+                 "~Don't leave the Monastery without it!~";
+              if (second=='joseph')
+                 "Joseph smiles. ~I believe we've been introduced.~";
+              if (second=='rod')
+                 "~We must recover the Rod before it is too late!~";
+              if (second=='anabais')
+                 "~Beware the demon!  He is most cunning and dangerous!~";
+              if (second=='scriptures')
+                 "~Study the holy scriptures, and you will be rewarded.~";
+              if (second=='palemon' or 'tuffberry' or 'toolbox')
+                 "~I fear I know not where his feet now tread.~";
+              "~I don't know anything about that. Perhaps you should \
+              consult our library upstairs?~";
+
+           Tell:
+              "~Do tell.~";
+           Show:
+              if (noun has is_rod)
+                 "~Have you succeeded in retrieving the Rod? If so, \
+do what you feel is right.~";
+                 
+           Give:
+              if (noun has is_rod) {
+                 if ((noun==black_rod_piece) || (noun==white_rod_piece) ||
+                     (noun==smoke_rod_piece) || (noun==gray_rod_piece)) {
+                    Joseph.number = Joseph.number + 1;
+                    remove noun;
+                    print "Joseph takes the rod piece. ";
+                    if (Joseph.number==4) {
+                       ! trouble -- got the whole fake rod to Joseph...
+                       deadflag = 1;
+                       Player_Lives_Left = 0; 
+                       "~The Order will \
+remember your acts of bravery forever,~ Joseph says, as he brings out \
+all four rod pieces and tries to join them together. A sudden burst \
+of light blinds you!^^\
+When you can see again, a large black sphere of malevolent energy \
+floats nearby! Joseph, either dead or stunned, lies in one corner \
+of the room. The four rod pieces are floating above the sphere.^^\
+~Foolish little priest,~ a evil voice says in you mind. ~You \
+have only brought upon yourself your own undoing. With my rod returned \
+by an innocent, the pact is complete. Come forth, my brothers, \
+for our time of power is at hand!~^^\
+The last thing you hear is mocking laughter, before the world \
+as you know it comes to a close.";
+                    } 
+                    else 
+                    "~Well done, brave Priest!~ he says.";
+                 }
+                 else
+"Joseph looks at the rod piece and seems puzzled. ~This isn't any part \
+of the Rod of the Ancients that I've ever seen. And yet, it seems similar.~ \
+He hands it back to you. ~In this, my teachings can help you no \
+further.~";
+              }
+              else "Joseph waves off your offering. ~You may \
+need that in your quest.~";
+           Answer, Order:
+              if (special_word=='hello' or 'hi') 
+                 "Joseph smiles. ~Hello.~";
+           default:
+              "At the moment, Joseph seems to be \
+preoccupied with spiritual matters.";
+        ],                     
+        before [;
+           Cast:
+             "Brother Joseph stops you in mid-chant. ~That won't be necessary~";             
+        ],
+        each_turn [;
+           if (self hasnt general) {
+              give self general;
+           move Amulet to player;
+           "^Joseph smiles as you enter. \
+~I'm glad you found me. As you know, thanks to the old \
+fool standing before you, the demon Anabais is loose upon \
+the world once more. He has broken the Rod of the Ancients \
+which was keeping our house and Order protected from outsiders. \
+It is a sorry day for us all.~ Joseph pauses for a moment. \
+~You are our final hope in a time of chaos. Brothers \
+Palemon, TuffBerry and Toolbox have left the Order, and only \
+you remain. I must now ask you to serve the Order which you \
+have so faithfully served in the past. No short order this, for \
+our continued existence depends on it, but you must go out into \
+a world gone mad alone, and retrieve the four broken pieces of \
+the Rod of the Ancients, and return them here to me, so that we \
+can rid the world of the evil we have loosed!~^^Brother Joseph \
+pauses and searches his robes.^^~Here, you will need this,~ he \
+says, giving you a strange amulet. ~Without this amulet, the \
+Ancient Ones cannot give you the mystic aid that you will most \
+certainly need. But I waste much time. Go now, and may the \
+Gods smile upon us all.~";
+           }
+        ],
+   has animate proper;
+    
+Object Amulet "holy amulet" 
+   with name "amulet" "holy",
+        description "This small golden amulet and chain seem to \
+shimmer with a strange mystic saffron energy. The \
+pendant portion of the amulet is in the shape of a small \
+golden cube.",
+ !       weight 10,
+        size 7,
+        before [;
+           Wear:
+              if (self hasnt worn) { give self worn;
+              "As you place the amulet around your neck, \
+              you feel a strange sense of mystic power.";
+              } 
+              else "You're already wearing that.";
+        ],              
+   has clothing scored;
+           
+! [ JosephWakeAction;
+!      print "^You make a subtle noise^^\
+!           Brother Joseph opens his eyes, breathes deeply, and smiles.^^\
+!            ~I'm glad you found me.  As you know, thanks to the old \
+!            fool standing before you, the demon Anabais is loose upon \
+!            the world once more.  He has broken the Rod of the Ancients \
+!            which was keeping our house and Order protected from outsiders. \
+!          It is a sorry day for us all.~  Joseph pauses for a moment. \
+!          ~You are our final hope in a time of chaos.  Brothers \
+!          Palemon, TuffBerry and Toolbox have left the Order, and only \
+!          you remain.  I must now ask you to serve the Order which you \
+!          have so faithfully served in the past.  No short order this, for \
+!          our continued existence depends on it, but you must go out into \
+!          a world gone mad alone, and retrieve the four broken pieces of \
+!          the Rod of the Ancients, and return them here to me, so that we \
+!          can rid the world of the evil we have loosed!~^^Brother Joseph \
+!          pauses and searches his robes.^^~Here, you will need this,~ he \
+!          says, giving you a strange amulet.  ~Without this amulet, the \
+!          Ancient Ones cannot give you the mystic aid that you will most \
+!          certainly need.  But I waste much time.  Go now, and may the \
+!          Gods smile upon us all.~";
+!     move Amulet to player;
+!     rtrue;
+!];
+
+Object altar "altar" 
+   with name "altar" "damaged" "cube",
+      description "The altar is roughly the shape of a five foot \
+         white cube. The top edges appear to be singed black and there \
+         are cracks and chips all over.",
+   found_in MON_Chapel1 MON_Chapel2,
+   before [;
+      Search:
+         if (self hasnt general) {
+            give self general;
+            move holywater to player;
+            "You uncover a vial of holy water.";
+         }
+   ],
+   has scenery supporter;
+
+Object holywater "vial of holy water"
+   with name "holy" "water" "vial",
+        description "A small glass vial of holy water.",
+        before [;
+           Eat: "You might want to try drinking it instead.";
+           Drink: remove self;
+              Player_HP_CUR = Player_HP_MAX;
+              "You quaff the holy water with a simple ceremony. \
+You feel physically and spiritually refreshed."; 
+        ],
+        size 5,
+;
+   
+Object MON_Palemon_quarters "Brother Palemon's Quarters"
+   with description [;
+        print "You are in Brother Palemon's quarters, which \
+           have been left unattended ever since Brother Palemon's \
+           unexplained disappearance many years ago";
+        if (self has general)
+           print ". To the west, a small secret door in the wall leads \
+            into darkness";
+        ". The exit is south.";
+        ],        
+   s_to MON_f1hall3,
+   w_to [;
+      if (self hasnt general)
+         "You can't go that way.";      
+      else return MON_Hidden_sanctum;
+   ],
+   before [;
+      Push:
+        if (noun == w_obj) {
+           if (self hasnt general) {
+              give self general;
+              "Pushing the west wall reveals a hidden secret door! \
+You've been in these quarters before, but certainly never noticed \
+anything like this!";
+              }
+              else "Nothing happens."; 
+           }
+       Touch, Rub:
+          if ((noun == w_obj) && (self hasnt general))
+             "Oddly, a section of the west wall feels slightly thin.";
+   ],
+   has light;
+   
+Object journal "thin journal" MON_Palemon_quarters
+   with name "journal" "thin",
+        description "This journal is very strange indeed. Brother \
+        Palemon seems to have been very preoccupied up to the point \
+        of his disappearance with strange accursed places that he \
+        claims are located all over Quendor. He also makes several \
+        references to evil 'spirits' found in these places. You also \
+        notice that several pages of parchment near the back of \
+        the journal have been torn out.",
+        !weight 20,
+        size 15,
+;
+
+Object MON_Hidden_sanctum "Hidden Sanctum"
+   with description "You are standing in a small chamber that obviously hasn't \
+been used in quite some time -- the cobwebs and dust are several \
+layers thick. There is a short crawl east.",
+   name "cobwebs" "dust",
+   e_to MON_Palemon_quarters,
+;   
+
+Object dusty_scroll "dusty scroll" MON_Hidden_sanctum
+   class scroll_class,
+   with name "dusty",
+;
+
+Object foblub_spell "deliver magnificent sermon (glue audience to seats)" dusty_scroll
+   class spell_class,
+   with name "foblub",
+        magic [;
+           if (second hasnt animate)
+              "Your sermon goes unheard.";
+           if (second == player)
+              "Well, I know you like listening to yourself, but \
+isn't this a bit much?";
+           "You give a wonderful sermon about how one's future \
+           affects one's past, but no one seems to be listening."; 
+        ],
+;
+
+      
+Object MON_TuffBerry_quarters "Brother TuffBerry's Quarters"
+   with description "You are in Brother TuffBerry's quarters, vacant \
+since he undertook his quest for Joseph not long ago. The \
+exit is north.",
+   n_to MON_f1hall3,
+   has light;
+   
+Object page "torn page" MON_TuffBerry_quarters
+   with name "torn" "page",
+        !weight 5,
+        size 5,
+           description "This page was apparently \
+torn from a larger document of some sort. All that is left \
+now reads:^^\
+           ~...fear. Just today I heard again something below \
+           me when I was meditating upstairs. \
+           It sounded like a person, or something alive at least \
+           was just below, trying to quietly move around unnoticed. \   
+           Clearly this is \
+           impossible, and yet I cannot doubt what I heard. \
+           Palemon tells me I'm hearing spirits, but little does \
+           he know that I once heard the same noises in his \
+           very chambers! He was not around at the time, but \
+           to the west, behind the wall, I...~",
+;           
+        
+
+!Object MON_Joseph_quarters "Brother Joseph's Quarters"
+!   with description "You are in Brother Joseph's quarters.  The hallway lies \
+!           to the south.",
+!   s_to MON_f1hall4,
+!   has light;
+   
+Object MON_Toolbox_quarters "Brother Toolbox's Quarters"
+   with description "You are in Brother Toolbox's quarters, vacant \
+ever since he left the order due to differences many years \
+ago. The exit is north.",
+   n_to MON_f1hall4,
+   has light;
+
+Object tb_diary "diary" MON_Toolbox_quarters
+   with name "diary" "toolbox",
+        description "\
+        ~-- <944 GUE> Today Brother Joseph tried to explain the \
+        essence of how we channel magic energy through our \
+        amulets. To me, this seems to pale in comparison with \
+        the seemingly innate abilities of those who call \
+        themselves Enchanters. Joseph did show me a nice \
+        trick, however. He brought the Rod of the Ancients near \
+        my amulet, and the amulet gave off a sudden purple flash of light! \
+        I'll have to try that one on the Acolytes tomorrow.~^^\
+        (there isn't much else of interest until the \
+        very last entry, which is not dated)^^\        
+        ~-- So long diary. I'm now off to seek greater spiritual \
+        guidance in Thriff. I hear the summers there are very nice \
+        too.~",
+        !weight 12,
+        size 12,
+;
+   
+Object folded_scroll "folded scroll" MON_Toolbox_quarters
+   class scroll_class,
+   with name "folded",
+;
+
+Object espnis_spell "deliver dull sermon (cause sleep)" folded_scroll
+   class spell_class,
+   with name "espnis",
+        magic [;
+           if (second hasnt animate)
+              "Your sermon goes unheard.";
+           if (second == player)
+              "A preacher boring himself to sleep with his \
+own sermon? This doesn't seem prudent.";
+           CDefArt(second); 
+           " listens as you begin your sermon about the general \
+              religious practices of the royal families of the past, but \
+              only stifles a yawn when you finish.";  
+        ],
+;
+   
+   
+Object MON_f2hall1 "Hallway (second floor, west)"
+   with description "You are in a hallway on the second floor \
+           of the Monastery. The hallway continues east, while \
+           stairs lead downwards.",
+        name "stairs",
+        d_to MON_f1hall2,
+        e_to MON_f2hall2,
+   has light;
+   
+Object MON_f2hall2 "Hallway (second floor, east)"
+   with description "You are in a hallway on the second floor \
+           of the Monastery that runs east-to-west. To the \
+           north is the private meditation room. To the east \
+           is the Monastery library. To the northeast is an \
+           entrance to the steeple room.",
+        w_to MON_f2hall1,
+        n_to MON_priv_med_room,
+        e_to MON_Library,
+        ne_to MON_Steeple_room,
+   has light;
+   
+Object MON_priv_med_room "Private Meditation Room"
+   with description "You are in a small bare chamber that is \
+           used for private meditation and worship. The only \
+           exit lies to the south.",
+        s_to MON_f2hall2,
+   has light;
+   
+Object MON_Library "Monastery Library"
+   with description "You are in the Monastery library, a cozy, \
+           almost cramped room with shelves of various books. \
+           The exit is to the west.",
+        w_to MON_f2hall2,
+   has light;
+
+Object lib_shelves "shelves" MON_Library
+   with name "shelves" "bookshelves",
+        description "Just some bookshelves.",
+   has scenery supporter;
+   
+! *** LIBRARY BOOKS
+
+! Scriptures:
+! -- Of course, this is a ruse created from the deviations of 
+! Anabais.  Grounded in some fact though.  Each section has a
+! lie, which may not initially be obvious.  Truthful sections 
+! are scattered over Quendor.
+Object HolyScriptures1 "a copy of the Holy Scriptures" lib_shelves
+   with name "holy" "scriptures" "copy",
+        description "This sacred tome details the teachings and \
+beliefs of the Order, of which it's certainly always good \
+practice to re-familiarize yourself with. The scriptures are \
+divided into several sections. Sections that \
+can be consulted in greater detail include:^^\
+~Doctrines~^\
+~Demons~^\
+~Spirits~^\
+~(Book of the) Mystical~^\
+~(Book of the) Planes~^\
+~(Book of the) Ancients~^\
+~Legend of the Rod~",
+        before [ w1; Consult:
+        if (consult_words > 1)
+               "You'll have to consult the sacred book by \
+individual section.";               
+            wn = consult_from; w1 = NextWord();
+            switch (w1) {
+               'doctrines', 'doctrine', 'canon':
+"~THE SACRED DOCTRINES OF THE ORDER OF BALANCE:^^\
+Thou shalt strive to achieve balance in a world filled with unbalance.^\
+Thou shalt pray to the Deities in moments of inner reflection.^\
+Thou shalt not harm innocents nor aid them -- this is the way of balance.~"; 
+! TODO add add
+               'demons', 'demon', 'anabais':
+"~Fear not, mortal men^\
+though your world be filled with demons^\
+and the wicked.^^\
+Thou alone can prevail^\
+as The Ancient Ones^\
+against Anabais, the trickster^\
+were victorious.~";               
+! LIE - The ancient ones lost to Anabais and the other demons
+               'spirits', 'spirit':
+"~Before the dawn of time, know that our world was \
+filled with evil spirits of the elements, \
+until mankind came upon the land and vanquished them \
+forever.~";
+! LIE - spirits still exist.
+               'mystic', 'mystical', 'magic', 'chant':
+"~If one is true of doubts, then a believer in the \
+great Harmony can draw upon the powers of the Ancients \
+and perform feats of mystic power anywhere. Remember that in \
+so doing, thou must act only as the channel of mystical \
+power for the Ancient Ones.~";               
+! LIE - powers don't work everywhere, and not always.
+               'planes', 'plane', 'atrii', 'hades':
+"~Let not the ways of the mortal life \
+dissuade the knowledge of higher and lower planes \
+of existence.^^\
+For, beyond mortal reach are places where those who \
+have truly served the Order and those who have truly \
+forsaken the Harmony of Balance will find themselves \
+in death. These are the Ethereal Plane of Atrii and \
+the plane of the damned -- Hades.~";               
+! LIE - don't have to die to reach Atrii.
+               'ancients', 'ancient':
+"~Trust in The Ancient Ones, those Three who showed mankind the \
+way of Balance and Harmony.~";
+! LIE - Four ancient ones existed.
+               'rod', 'legend':
+"~Anabais foresaw his own demise when he dared to \
+challenge the Ancient Ones. From powers of light and \
+darkness, the Ancient Ones constructed that holy Rod that \
+we know only as the Rod of the Ancients, and did smite \
+the demon Anabais so grievously, that they did imprison \
+him in that very Rod, where he could do no harm. This \
+very Rod was made of pieces of ancient elemental energy, \
+once separated. Only the powers of the Ancients could \
+bring them together.~";               
+! LIE - Anabais never imprisoned, etc.
+               default: "There doesn't seem to be a section \
+about that.";               
+            }
+          Cast:
+             if (the_spell_was == ledak_spell) {
+                remove self;
+                "The scriptures are surrounded by a \
+yellow glow. To your horror, the tome evaporates into nothing!";
+             }
+        ],
+        !weight 20, 
+        size 15,
+has proper;
+     
+! *** parchments
+! (Several scraps of
+! Palemon's journal are scattered around Quendor, 
+! contradicting the ancient scriptures) 
+
+! (faded -- spirits exist)
+Object p2 "faded parchment" MON_Hidden_sanctum
+   class parchment_class,
+   with name "faded",
+description "~...are real! I have seen much evidence in the \
+jungles of Miznia, marshes of Fublio Valley, the ruins \
+of old Egreth and in Aragain itself! I believe that \
+they are associated with certain basic elements in the \
+surrounding area. But they dare not show themselves now, \
+not while magic is strong! Woe unto us, should the powers \
+of magic cease, as there would be nothing to stop their \
+terror...~",
+;
+
+Object MON_Steeple_room "Steeple Room"
+   with description "You are in a round room with colored-glass \
+           windows. Wood beams line the walls and rise to form \
+           a short point in the peaked ceiling above. A small \
+           walkway returns to the southwest. A long wood table \
+           sits in the center of the room.",
+        name "windows" "glass" "beams" "walkway" "handle" "latch",
+        sw_to MON_f2hall2,
+        !out_to MON_Steeple_roof,        
+        out_to steeple_window,        
+        before [;
+           Go: 
+              if ((noun == out_obj) && (steeple_window has open)) {
+                 if (random(10) < 3) {
+                    print "^You climb out the open window and somehow manage \
+                          not to fall.^";
+                 }
+                 else {
+                    deadflag = 1;
+print "^You climb out the open window, but slip on the icy sill";
+if (has_resist_gravity == 0) ", and plummet to the ground!";
+else 
+"! As you float slowly downwards, you can't help but notice the \
+hungry-looking winter dire wolf below, waiting for you to land...";
+                 }
+              }              
+        ],
+   has light;
+   
+Object MON_Steeple_roof "Steeple Roof"
+   with description "You are on a very narrow ledge outside \
+           the Monastery steeple. The snow and wind are doing \
+           their best to send you to a ungracious death below. The \
+           steeple roof is quite sharply slanted.",
+        in_to steeple_window,
+        name "roof" "ledge" "wind",
+        cant_go "It's hard enough staying on the ledge.",
+        before [;
+           Jump:
+             deadflag = 1;
+             if (has_resist_gravity==0)
+             "Well, if you insist. The ground breaks most of the \
+             bones in your body, including the important ones.";
+             else
+             "You float downwards gracefully, into the waiting \
+jaws of a winter dire wolf."; ! <shrug>
+        ],
+   has light;        
+   
+Object steeple_window "steeple window" 
+   with name "window" "rose" "steeple",
+        found_in MON_Steeple_room MON_Steeple_roof,
+        description [;
+           print "A large rose-colored glass window";
+           if (location==MON_Steeple_room) 
+              ", with a handle and latch";
+           ".";
+        ],
+        describe [;
+           if (location==MON_Steeple_room) {
+              if (self has open)
+                 "Someone has left a rose-colored window open and some \
+snow drifts in.";
+              "A large rose-colored window lets some light in.";
+           }
+           if (location==MON_Steeple_roof) {
+              if (self has open)                
+                 "A window opens into the steeple proper.";
+              "A large rose-colored window is partially covered with snow here.";
+           }
+        ],
+        door_dir [;
+           if (location==MON_Steeple_room) return out_to;
+           return in_to;
+        ],
+        door_to [;
+           if (location==MON_Steeple_room) return MON_Steeple_roof;
+           return MON_Steeple_room;
+        ],
+        before [;
+           Enter:
+              if (location==MON_Steeple_room) <<Go out_obj>>;
+              else <<Go in_obj>>;
+           Open:
+              if ((self hasnt open) && (location==MON_Steeple_roof))
+                 "Unfortunately, the window opens inward, and the latch \
+                 and handle are on the inside.";
+              if ((self hasnt open) && (location==MON_Steeple_room)) {
+                 give self open;
+                 "You turn and yank the window handle and pull. \
+                  A rush of wind and snow greets you as you open \
+                  the window.";
+              }
+           Close:
+              if ((self has open) && (location==MON_Steeple_roof))
+                 "It doesn't seem to want to stay shut. You can't \
+quite reach the window latch from out here.";                 
+           Attack:
+              "The window glass remains unmarred. It's probably made of \
+              that especially thick lead-glass that the Monastery got \
+              because Brother Toolbox kept complaining about drafts.";
+           Push:
+              if (self hasnt open)
+                 "It doesn't budge.";
+           Search:
+              "The window looks out into a winter wonderland.";
+        ],        
+   has static door openable;
+
+Object steeple_table "long table" MON_Steeple_room
+   with name "table" "long" "steeple",
+        description "This long wood table has been used for various \
+           private meetings and impromptu get-togethers between \
+           members of the Order in the past.",
+   has scenery supporter;   
+   
+Object MON_f0hall1 "Hallway (basement)"
+   with description "You are in a hallway in the Monastery basement. \
+           The hallway continues to the east, and stairs lead upwards.",
+        name "stairs",
+   u_to MON_f1hall2,
+   e_to MON_Refectory,
+   has light;
+
+Object MON_Refectory "Refectory"
+   with description "You are in the Refectory, the general dining \
+area for members of the Order. You grimace at the lingering scent of \
+Brother Pufpistery's favorite dish -- Borphbelly stew. \
+Several large oak tables and benches adorn this otherwise \
+bare room. An exit lies to the west, the kitchen is to \
+the north, and another exit lies to the east.",
+        name "oak" "tables" "benches", 
+   w_to MON_f0hall1,
+   n_to MON_Kitchen,
+   e_to MON_Storeroom,
+   before [;
+      Smell: "Even the faintest lingering scent of Borphbelly stew \
+is enough to make you feel like fasting.";
+   ],
+   has light;
+   
+Object MON_Kitchen "Monastery Kitchen"
+   with description "You are in Brother Pufpistery's domain -- the \
+dreaded acolyte kitchen. A huge soup \
+cauldron sits unused nearby. The refectory is \
+south.",
+   s_to MON_Refectory,
+   before [;
+      Smell: "The lingering scent of Borphbelly stew \
+is stronger here, unfortunately.";
+   ],
+   has light;
+
+Object cauldrons "cauldron" MON_Kitchen
+   with name "cauldron" "vat",
+        description "This large iron soup cauldron has the \
+           unmistakable odor of Borphbelly stew. Ugg.",
+        size 25,
+        capacity 10,
+        before [;
+           Cast:
+             if (the_spell_was == bekdab_spell)
+                "The soup cauldron rusts a bit.";
+        ],
+   has scenery container open;
+
+Object preparing_table "preparing table" MON_Kitchen
+   with name "table" "preparing",
+        description "A heavy wood table with a well-used look.",
+        before [;
+           Cast:
+              if (the_spell_was == egdelp_spell)
+                 "The table is now covered in a waxy film. \
+All things considered, it actually looks cleaner now.";
+        ],
+   has static supporter;
+   
+Object recipe_paper "scrap of paper" preparing_table
+   with name "scrap" "recipe" "paper",
+        description "It's a recipe torn from an issue of \
+             ~Better Homes and Caverns~:^^\
+             GUILDMASTER SNEFFLE'S PRIZE WINNING BIRTHDAY CAKE \
+             ^^\
+             Ingredients:^^\
+             -- 1 small sack of flour^\
+             -- 1 large sugar cube^\
+             -- 1 packet of baking powder^\
+             -- 1 stick butter^\
+             -- 1 large corbie egg^\
+             -- Dornberries, to taste^^\
+             Mix the ingredients together. Fold the resulting \
+             mixture the correct number of times (a single gloth \
+             spell should do the trick). Bake in a GUE \
+             Automatic oven on the ~cake~ setting.^^\
+             Guildmaster Sneffle claims that ~the dornberries are \
+             the secret to making a cake even the King would be \
+             impressed with.~ He also notes that ~improper folding \
+             of the dough will produce very poor results.~",
+   !weight 1,
+   size 5,
+;
+      
+Object MON_Storeroom "Storeroom"
+   with description "You are in a small cramped storeroom, stocked \
+with various crates and barrels of foodstuffs. \
+The refectory is west.",
+        name "crate" "crates" "foodstuffs",
+        w_to MON_Refectory,
+        d_to secret_trapdoor,
+        each_turn [;
+           if ((random(20) == 1) && (secret_trapdoor notin MON_Storeroom))
+              print "^A tiny mouse scurries into view, then disappears \
+                    under a barrel.^";
+        ],
+        before [;
+           Go:
+              if (noun==d_obj)
+                 if (secret_trapdoor hasnt general)
+                    "You can't go that way.";
+        ],
+   has light;
+   
+Object crate1 "large barrel" MON_Storeroom
+   with name "barrel",
+        description "A large wooden barrel labeled ~DRIED PRUNES~.",
+        before [;
+           Cast:
+              if (the_spell_was==egdelp_spell)
+                 "The barrel is covered with a light \
+waxy film.";
+           Take, Remove:
+              "The barrel is far too bulky to take.";
+           Open:
+              "You'd probably need a hacksaw to do that. Besides, \
+              look what it says it contains.";
+           Push, Pull:
+              if (secret_trapdoor hasnt general) {
+                 give secret_trapdoor general;
+                 move secret_trapdoor to MON_Storeroom;
+                 "Well whaddya know, a trapdoor...";                           
+              }
+        ],
+   has supporter;   
+   
+Object flour "sack of flour" crate1
+   with name "flour" "sack",
+        short_name "sack of flour",
+        description "A small sack of flour, all-purpose.",
+        !weight 15,
+        size 14,
+   has edible;
+           
+Object MON_Caverns "Caverns"
+   with description "You are in an low underground cavern, made of roughly \
+worked stone. An even lower tunnel travels east.",
+        name "stone" "worked" "tunnel",
+        u_to secret_trapdoor2,
+        e_to cave_intersection,
+;       
+
+! A two-way initially hidden trapdoor, which affects rooms.
+! To my great chagrin, I couldn't code this in one obj (sigh).
+! I admit it, this is my first Inform project.
+Object secret_trapdoor "trapdoor"
+   with name "trapdoor" "trap" "door",
+        description "A wooden trapdoor in the floor.",
+        door_to MON_Caverns,
+        door_dir d_to,
+        describe [;
+           if (self has open)
+              "A trapdoor opens into darkness below.";
+           "There is a closed trapdoor in the floor here.";
+        ],
+        before [;
+           Enter: <<Go d_obj>>;
+           Open:
+               give MON_Caverns light;
+               give secret_trapdoor2 open;
+               rfalse;
+           Close:
+               give MON_Caverns ~light;
+               give secret_trapdoor2 ~open;
+               rfalse;
+        ],
+     has static door openable;
+     
+Object secret_trapdoor2 "trapdoor" MON_Caverns
+   with name "trapdoor" "trap" "door",
+        description "A wooden trapdoor in the ceiling.",
+        door_to MON_Storeroom,
+        door_dir u_to,
+        describe [;
+           if (self has open)
+              "Light gleams in from an open trapdoor above.";
+           "You notice a closed trapdoor in the ceiling.";
+        ],
+        before [;
+           Enter: <<Go u_obj>>;
+           Open:
+               give MON_Caverns light; 
+               give secret_trapdoor open;
+               rfalse;
+           Close:
+               give MON_Caverns ~light; 
+               give secret_trapdoor ~open;
+               rfalse;
+        ],
+     has static door openable;
+     
+Object cave_intersection "Cave Intersection"
+   with description [; 
+           print "You are in a large open cavern. The rough \
+           limestone here was probably eroded by underground springs \
+           to form the somewhat circular chamber you now stand in. \
+           Oddly, there seems to have been a recent cave-in, as \
+           piles of rubble line the walls. A tunnel \
+           snakes off to the west";
+           if (self has general)
+           ". To the southeast, there is a wide square hole!";
+           else ".";
+           ],
+           name "limestone" "rubble" "tunnel",
+  ! cant_go "There's too much rubble",           
+   w_to MON_Caverns,
+   se_to [;
+           if (self hasnt general) rfalse;
+           if (self has general) return Mystical_Cave;
+   ],
+   before [;
+      Go:
+         if ((noun == se_obj) && (self has general)) {
+            if ((white_rod_piece in player) && 
+            (black_rod_piece in player) &&
+            (gray_rod_piece in player) &&
+            (smoke_rod_piece in player)) {
+            remove white_rod_piece;
+            remove black_rod_piece;
+            remove gray_rod_piece;
+            remove smoke_rod_piece;
+            Player_Lives_Left = 0;   ! hope you saved...
+            spell_block = 1;  ! going into the endgame...
+            print "^As you enter the tunnel, a strange \
+light surrounds you! The four rod pieces you were \
+carrying crumble into dust!^";                       
+            }
+            else
+            "Well, the hole to the southeast seems obvious \
+enough. But, some mysterious force blocks the way! \
+Try as you might, you can't seem to enter it!";
+         }
+     ],            
+;
+           
+Object steel_wall "steel wall" cave_intersection
+   with name "steel" "wall",
+      description "A ten-by-ten slab of solid steel, this wall \
+         must be at least a foot thick, and is accented by \
+         large steel rivets that bolt it to the surrounding \
+         rock.",
+      initial "To the southeast, a huge steel wall demonstrates \
+               a marked contrast to the otherwise drab surroundings.",
+      before [;
+         Open:  "I presume you have a blow-torch handy?";
+         Push, Pull, Turn: "Not surprisingly, it doesn't move an inch.";
+         LookUnder: "It's flush with the rock floor.";
+         Cast: "The wall seems to absorb and nullify all magic!";
+      ],         
+   has static;
+        
+         
+! ***********************************************************************
+! ** 
+! ** GRAY MOUNTAINS AREA NEARBY MONESTARY   
+! **
+! ***********************************************************************
+   
+Object Cliff_face "Cliff Face"
+   with description "You are standing near the top of a snowy mountain peak. \
+The wind is quite cold and is making your teeth chatter. \
+The general vicinity is mostly snow and rock; however, the \
+entrance into the Monastery is to the north, all but hidden from view \
+by the enormous slabs of snow-covered rock that make up the \
+cliff face. There is a rough but obvious trail leading down \
+the mountain to the south. There is also another trail that \
+winds even further up the mountain peak almost hidden in the \
+snow to the east.",
+   name "peak" "wind" "rock" "structure" "slabs" "trail",
+   n_to MON_Entrance_hall, in_to MON_Entrance_hall,
+   s_to rocky_trail, d_to rocky_trail,
+   e_to Covered_trail, u_to Covered_trail,
+   has light;
+   
+Object Covered_trail "Covered Trail"
+   with description "You are climbing up a small trail that gets periodically \
+lost in great bluffs of snow. The swirling snow makes seeing \
+an unusual effort. The trail leads downwards to a cliff face \
+to the west, and rises towards the mountain top to the north.",
+        name "bluffs" "trail",
+   w_to Cliff_face, d_to Cliff_face,
+   n_to Mountain_peak, u_to Mountain_peak,
+   has light;
+
+Object Mountain_peak "Mountain Peak"
+   with description [;
+        print "You are standing on the top of a peak of the Gray \
+Mountains. A cold wind blows snow everywhere, obscuring what \
+would otherwise surely be a wonderful view of the surrounding \
+countryside. You can just make out some buildings to the far \
+south in Frostham. A snowy bluff marks the way back down";   
+        if (self hasnt general)
+", or to the west, there appears to be a snowy outcropping. It seems to \
+hang precariously over the edge of the mountain, however.";
+        else ".";
+   ],
+   name "wind" "peak" "mountains" "countryside" "buildings" "bluff",
+   d_to Covered_trail,
+   w_to [;
+      if (self has general)
+         "Looks like the outcropping completely collapsed!";
+      return Snowy_outcropping;
+   ],
+   before [;
+      Go:
+       if ((noun==w_obj) && (self hasnt general) && (player notin sleeppallet)) {
+!                 if (WeightOf(player) > 25) {
+           if (children(player) > 0) {
+             print "As you start to tread out to the outcropping, you feel \
+                the snow beneath your feet shifting under your sudden \
+                 weight! You ";
+             if (random(10) > 6) {
+                deadflag = 1;
+                "start to turn back, but the entire \
+                outcropping suddenly tilts under your weight, sending \
+                 you hurtling off the edge into oblivion!";
+             }
+             else {
+                "beat a hasty retreat back to the peak.";
+             }
+          }                     
+          print "You carefully make your way onto the outcropping.^";
+       }
+      Jump: 
+         "Not advisable, it's probably a long way down...";
+   ],   
+   has light;
+                  
+Object Snowy_outcropping "Snowy Outcropping"
+   with description        
+           "You are standing on a snow-covered outcropping. \
+           You are almost waist-deep in snow, and the blisteringly cold \
+           winds aren't helping. The outcropping juts out alarmingly \
+           over the western edge of the mountain. In fact, you can see the \
+           Monastery steeple below this ledge. \
+           The main portion of the mountain peak lies to the east.",
+   name "winds" "steeple" "peak",
+   e_to Mountain_peak,
+   each_turn [;
+        if (random(5)<=3)
+           "^There is an ominous creaking noise somewhere underfoot.";
+        "^Some snow falls off the outermost edge of the outcropping.";
+   ],
+   before [;
+        Go:
+           if (noun==e_obj)
+              print "You cautiously make your way back to the mountain top^";
+           if (noun==d_obj)
+              "That's not a very sound idea.";
+        Jump:
+           "Let's not be suicidal.";
+        Yell: 
+           Outcrop_break(1); rtrue;
+        Sneeze: 
+           Outcrop_break(2); rtrue;
+        Drop:
+           deadflag = 1;
+           "You must have disturbed something! The entire outcropping \
+           breaks away in an avalanche, and you plummet to your death!";
+        Take, Touch, Push, Pull:
+           if (noun==dirty_scroll) {
+              if (random(10) > 5) {
+              deadflag = 1;
+              give Mountain_peak general;
+              remove Snowy_Outcropping;
+              move dirty_scroll to MON_Steeple_roof;  ! it's still obtainable...
+              "As you reach for the scroll, the entire outcropping lurches \
+              alarmingly! Without warning, it \
+              breaks away in an avalanche, and you plummet to your death!";
+              }
+              "As you reach for the scroll, you hear a disturbing rumbling \ 
+              from somewhere underfoot, and you step back hastily.";
+           }
+        Answer:
+           if (inp2==player) {
+              Outcrop_break(1); rtrue;
+           }
+           "To who/whom, exactly?";
+   ],
+   has light;               
+[ Outcrop_break type;
+   if (type == 1) 
+      print "You give the best bellow you can muster, given the current \
+           weather conditions.";  
+   if (type == 2)
+      print "Understandable, given the weather conditions.";
+   print  " Unfortunately, you seem to have disturbed \
+           something, as the entire outcropping gives way in a brief but \
+           powerful avalanche! You tumble through the air, followed by \
+           a large quantity of snow! But suddenly, you see the \
+           Monastery steeple rushing up to meet you!^^THUMP!^^\
+           You lie dazed for a moment. Miraculously, the dirty scroll \
+           lands next to you!^";
+      give Mountain_peak general;
+      move dirty_scroll to MON_Steeple_roof;
+      remove Snowy_Outcropping;
+      PlayerTo(MON_Steeple_roof);  
+      rfalse;    
+];
+
+Object dirty_scroll "dirty scroll" Snowy_outcropping
+ class scroll_class,
+  with name "dirty",             
+       initial [;
+           if (location==Snowy_outcropping)
+              "There is a dirty scroll here, practically buried in the snow!";
+           "There is a dirty scroll here.";
+       ],
+;
+
+Object swanko_spell "banish spirit" dirty_scroll
+ class spell_class,
+  with name "swanko",
+       magic
+       [;  
+       if (second==0)
+"The chant, looking for a locus of spiritual energy, fails.";
+          "The general vicinity seems pretty free of spirits now.";
+       ],
+;
+
+Object rocky_trail "Rocky Mountain Trail"
+   with description "You are on a rocky mountain trail \
+           that winds up and down a mountain. Patches of \
+           snow can be found here and there. The trail \
+           continues down the mountain to the south, or \
+           up to the north.",
+        name "trail",
+        d_to snowy_intersection,
+        s_to snowy_intersection,
+        u_to cliff_face,
+        n_to cliff_face,
+   has light;
+
+Object snowy_intersection "Snowy Intersection"
+   with description "You are at a snow-filled crossroads \
+           in a mountain trail. Paths lead north towards \
+           the top of the mountain, east, west, and south \
+           towards the base of the mountain.",
+        name "trail" "mountain",
+        n_to rocky_trail,
+        s_to North_of_river,
+        e_to "The path east is blocked after a short distance by a huge snow drift.",
+        w_to Top_of_drop,
+   has light;
+
+Object stone_marker "stone marker"
+   with initial "There is a large stone marker here, in \
+           the center of the intersection.",
+        name "stone" "marker" "obelisk",
+        description [;
+           print "This odd stone structure, partially \
+           covered in snow, looks quite old and mysterious. \
+           It's about seven feet tall, and is shaped like \
+           an obelisk";
+           if (self hasnt general)
+           ", with the top partially broken off.";
+           else ".";
+        ],
+        found_in snowy_intersection snowy_intersection2,
+   has static;
+
+! (second snowy intersection -- in the "past")   
+Object snowy_intersection2 "Snowy Intersection"
+   with description "You are at a snow-filled crossroads \
+           in a mountain trail. Paths lead north towards \
+           the top of the mountain, east, west, and south \
+           towards the base of the mountain.^^Something \
+           seems familiar, yet different, about this place.",
+        name "trail" "mountain",
+n_to "The path north ends after a short distance.",
+s_to "The path north ends after a short distance.",
+w_to "The path north ends after a short distance.",
+e_to "The path east is blocked after a short distance by a huge snow drift.",
+   has light;
+        
+
+Object stone_marker_top "broken stone top"
+   with name "top" "stone" "pinnacle" "broken",
+        capacity 1,
+        size 10,
+        description "The top pinnacle from the stone marker. \
+You notice that it's partially hollow inside.",
+        before [;
+           Receive:
+              if ((noun==silver_rod_piece) && 
+                  (snowy_intersection has general)) {
+                 move silver_rod_piece to self;
+                 give snowy_intersection ~general;
+                 remove self;
+                 give snow general;
+                 print "As you place the rod piece in the \
+broken stone piece, you sense a force from above pull you \
+skywards! In moments, you are high above the snow covered \
+mountains, nearing the sky, which you notice is strangely \
+purple!^";
+                 PlayerTo(Mystical_Cave);
+              !   spell_block = 0;
+                 Mystical_Cave.number = Mystical_Cave.number + 1;
+                 rtrue;
+              }
+        ],
+   has container static open;                
+
+Object Top_of_drop "Top of Snowy Slope"
+   with description "You're at the top of a short downwards slope into \
+           a snowy area below. A path leads east. You could also \
+           slide down the slope. A lone tree stands here, overlooking \
+           the slope.",
+        name "slope",
+        e_to snowy_intersection,
+        d_to Bottom_of_drop,
+        w_to Bottom_of_drop,
+        u_to [;
+          if (tree1 has general) <<Climb tree1>>;
+        ],
+   has light;
+   
+Object tree1 "tree" Top_of_drop
+   with name "tree",
+        description "A leafless, bare tree, with what might be a bird's \
+nest in it.",
+        before [;
+           Climb:                         
+              if (self hasnt general) give self general;
+              print "You clamber up the tree.^";
+              PlayerTo(Top_of_tree); rtrue;
+        ],
+   has scenery;
+   
+Object nest1 "nest" Top_of_drop
+   with name "nest",
+        description "Even from down here, it's a pretty big nest. \
+           Thankfully, no big birds seem to be present.",
+        before [;
+           Search: "You can't see into it from down here.";
+           ThrownAt: 
+                 move noun to Top_of_drop;
+                 "You take aim, but miss.";
+           Receive, LetGo, Rub, Turn, Take, Push, Pull, Touch, Attack, Shake: "You can't reach it.";
+           Search, LookUnder: "From down here, it's hard to see anything \
+but the bottom of the nest.";
+        ],
+   has scenery;
+   
+Object Bottom_of_drop "Bottom of Snowy Slope"
+   with description "You've made your way down to a small snow-covered \
+           clearing, ringed by pine trees. The only exit is back up the \
+           slope.",
+        name "clearing" "pine" "trees" "slope",
+        u_to Top_of_drop,
+        e_to Top_of_drop,
+   has light;
+   
+Object boulder "large boulder" Bottom_of_drop
+   with name "boulder" "rock",
+        initial "There's a large boulder here, sitting squat in the \
+           middle of the clearing.",
+        description "A big, snow-covered rock.",
+        before [;
+           Push, Pull, Turn: "It must weight a ton.";
+           Receive: 
+              if (noun==sleeppallet) {
+                 move sleeppallet to boulder;
+                 "You drape the pallet over the boulder.";
+              }
+        ],
+   has static supporter;
+   
+Object egg_shards "egg shards"
+   with name "shards",
+        initial "There's some broken eggshell shards here, scattered all \
+                over. Some gooey egg stuff too.",
+        description "Some large pieces of shell is all.",
+        !weight 5,
+        size 5,
+;    
+              
+Object Top_of_tree "Top of tree"
+   with description "You're on top of the tree, on some lower branches \
+           that seem pretty stable.",
+        d_to Top_of_drop,
+   has light;
+   
+Object tree2 "tree" Top_of_tree
+   with name "tree",
+        description "Overall, there's nothing terribly special about this tree.",
+   has scenery;   
+   
+Object nest2 "nest" Top_of_tree
+   with name "nest",
+        initial [;
+           print "There's a large bird's nest a bit farther out on a \
+           nearby branch";
+           if (corbie_egg in self)
+              print ". There appears to be an egg in it";
+           ".";
+        ],          
+        description "Given the size and Brother Joseph's lessons \
+           in ornithology, you'd guess that it's a corbie's nest. \
+           It looks abandoned.",
+        before [;
+           ThrownAt:
+              move noun to Top_of_drop;
+              print "Your throw goes a little wide, and ";
+              DefArt(noun); print " lands ";
+              ! if (WeightOf(noun) > 10)
+              !    "with a thump below.";
+              ! else "below.";
+              "below.";
+           Take:  "It's way out on a thinner branch that probably \
+                 won't support your weight.";
+           Receive: "You can't quite reach it to put anything in it.";
+           Push, Pull, Rub, Touch, Attack, Shake: "You can't reach it.";
+           LookUnder: "It seems to be sitting on some branches.";
+        ],           
+        size 10,
+   has static container open transparent;
+   
+Object corbie_egg "corbie egg" nest2
+   with name "egg",
+        short_name "corbie egg",
+        description "A large speckled corbie egg.",
+        !weight 8,
+        size 5,
+        before [;
+           Take, Rub, Push, Pull, Touch, Squeeze, Turn, Shake:
+              if (parent(self) == nest2)
+                 "You can't reach it."; 
+           LookUnder:
+              if (parent(self) == nest2)
+                 "It seems to be in a nest.";
+           ThrownAt:
+              if (parent(self) == nest2) {
+                 move egg_shards to Top_of_drop;         
+                 move noun to Top_of_drop;
+                 remove self;
+                 "Good toss! A bit too strong though. With a dull \
+                 crack, your throw breaks the egg, and pieces of \
+                 shell and egg goop fall to the ground below.";
+              }
+           Attack:
+              move egg_shards to parent(player);
+              remove self;
+              "The egg breaks easily, covering you with egg goop. \
+What a mess.";
+        ],
+has edible scored;           
+
+Object branch "branch" Top_of_tree
+   with name "branch" "branches",
+        description "Some leafless thin tree branches.",
+        before [;
+           Push, Pull, Turn, Shake:  
+              if (corbie_egg in nest2) {
+                 print "You give the branches a good shake. The egg pops \
+                 free and tumbles to the ground below! You see the egg \
+                 land in a soft patch of snow, and roll down the slope! \
+                 Moments later, you hear a dull ";
+                 if (sleeppallet in boulder) {
+                    move corbie_egg to Bottom_of_drop;
+                    "thump from below.";
+                 }
+                 else {
+                    remove corbie_egg;
+                    move egg_shards to Bottom_of_drop;
+                    "crack from below.";
+                 }
+              }
+              "You give the branches a good yank. A bit of snow falls.";
+        ],
+  has scenery;
+
+   
+! Some scenery 'fluff'
+Object snow "snow"
+   with name "snow",
+        description "Cold, white and not in short supply.",
+   found_in Mountain_peak Covered_trail Cliff_face Snowy_outcropping MON_garden
+            snowy_intersection rocky_trail Top_of_drop Bottom_of_drop,
+   before [;
+      Take:  "It melts into nothing soon after.";
+      Touch: "It's crisply cold.";
+      Search:
+         if ((self has general) && (location == snowy_intersection)) {
+            give self ~general;
+            Achieved(16);
+            move stone_marker_top to snowy_intersection;
+            "Remembering where the stone marker top fell, you brush \
+aside some snow. Sure enough, there it is!";
+         }            
+   ],            
+   has scenery;
+
+
+
+Object North_of_river "North of Frozen River"
+   with description "You are standing just north of a frozen river \
+(probably a tributary of Lake Dinge). You can just see \
+the south bank from here, where the trail seems to \
+continue. There doesn't seem to be a bridge, however. \
+A trail also continues north.",
+   name "river" "lake" "bank" "trail",
+   s_to Frozen_river,
+   n_to snowy_intersection,
+  has light;
+  
+  
+Object Frozen_river "On Frozen River"
+   with description "You are standing on a wide smooth river of ice. \
+The river 'runs' east to west, and there are banks to the \
+north and south.",
+   name "bank" "banks",
+   n_to North_of_river,
+   s_to South_of_river,
+   e_to "You slide eastwards, and lose your footing, going nowhere.",
+   w_to "You slide westwards, and slip, going nowhere.",
+   before [;
+      Drop:
+         if (noun==sand) {
+            move sand to Frozen_river;
+            Achieved(0);
+            "You scatter the sand onto the ice.";
+         }
+      Go:
+         if (noun==s_obj) {
+            if (player notin sleeppallet) {
+            if (sand notin Frozen_river)
+               "You slide and flounder helplessly on the ice!";
+            else
+               print "You tread lightly on the sand covered portion of \
+                   the ice, and scramble to the south bank.^";
+            }
+         }
+      Jump:
+         deadflag = 1;
+         "You bravely jump, but without warning, the ice cracks in many \
+         places, and you fall into the freezing river, becoming a human \
+         popsicle in a short amount of time.";
+   ],
+   has light;
+
+! (special -- accessible only from Atrii -- put useful item here)
+Object Frozen_river2 "On Frozen River"
+   with description "You are standing on a wide smooth river of ice. \
+The river 'runs' east to west. To the north and south \
+are huge snow bluffs that obscure most of the surrounding \
+countryside.", 
+   e_to "You step eastwards but lose your footing, going nowhere.",
+   w_to Frozen_river,
+   before [;
+      Go:
+         if (noun==w_obj) 
+            print "^As you step west, a slight downwards slope \
+in the ice sends you sliding uncontrollably.^";
+      Jump:
+         deadflag = 1;
+         "You bravely jump, but without warning, the ice cracks in many \
+         places, and you fall into the freezing river, becoming a human \
+         popsicle in a short amount of time.";
+   ],
+   has light;
+   
+! (scrawled -- clue to using spheres)
+Object p7 "scrawled parchment" Frozen_river2
+   class parchment_class,
+   with name "scrawled",
+description "~Red beats smoke,^\
+Silver bests clouds,^\
+Green defeats depths,^\
+Brown stops earth.~";
+
+Object river_ice "river ice"
+   with name "ice" "river",
+        description "The ice is thick and quite smooth.",
+        found_in Frozen_river Frozen_river2,
+        before [;
+! just trap all receives as drops
+           Receive:
+             <<Drop noun>>;
+        ],
+   has scenery supporter;
+   
+Object South_of_river "South of Frozen River"
+   with description "You are standing just south of a frozen river. \
+You can just see the north bank from here, where the trail seems to \
+continue. The only way to get there is across the river. \
+A trail heads south into a valley.",
+        name "river" "bank" "trail",
+   n_to Frozen_river,
+   s_to Valley_trail,
+   has light;
+
+Object Valley_trail "Valley Trail"
+   with description "You are walking along a valley trail, just \
+           below a portion of the Gray Mountain ranges. You can \
+           see the beginnings of a city to the south, while the \
+           trail winds further into the mountain ranges to the \
+           north.",
+        name "trail" "ranges" "mountain" "city",
+   n_to South_of_river,
+   s_to FROSTHAM_Outskirts,
+   has light;
+
+! (An interesting object, with possible uses...)
+!Object bathroom_scale "bathroom scale" 
+!   with name "scale" "bathroom",
+!        description [;
+!           if (player in bathroom_scale)
+!              "This is an odd small flat white device, with a tiny \
+!               glass window at one end that you can see a numbered dial \
+!               through.  The dial currently reads -- wait, that \
+!               can't be right.  The thing must be broken.";
+!           print "This is an odd small flat white device, with a tiny \
+!               glass window at one end that you can see a numbered dial \
+!               through.  The dial currently reads: <", 
+!               (WeightOf(self) - 10), " Ughs>.^"; rtrue;
+!        ],
+!        weight 10,
+!   has supporter enterable;
+
+
+! ***********************************************************************
+! ** (at this point, for clarity and my sanity, I'm going to build 
+! **  the remaining locations & objects in separate files, included
+! **  here.  Hopefully, the files will be somewhat organized based on
+! **  general location/town/situation, etc.
+! ***********************************************************************
+
+Include "frostham.inf";
+Include "aragain.inf";
+Include "anthar.inf";
+Include "fublio.inf";
+Include "borphee.inf";
+Include "miznia.inf";
+Include "gurth.inf";
+Include "subway.inf";
+Include "special.inf";
+
+! ***********************************************************************
+! **
+! ** HADES, in a newer format
+! **
+! ***********************************************************************
+
+Class Hades_Room_Class
+   with description "You are floating in an empty space. Surrounding you \
+           on all sides is a great wall of flame. It would almost seem \
+           like you are trapped inside a ball of fire.",
+        name "fire" "ball" "space" "flame",
+        before [;
+           if ((action~=##Go) && (action~=##Look) && (action~=##Wait))
+              "You currently lack the means to do that.";  ! can't do much in Hades...
+           Go:
+              give self ~visited; ! cheat, easier than routines for each dir...
+              print "^You find yourself floating through the flaming wall! \
+                    As you pass through you feel a gut-wrenching sensation. \
+                    Well, perhaps you would if you currently had a gut, or \
+                    sensations for that matter. Let's just say you feel \
+                    something akin to a gut-wrenching sensation, and leave \
+                    it at that.^";
+        ],
+     has light;
+  
+Object Hades_1 "Hades"
+   class Hades_Room_Class
+   with u_to  Hades_1,
+        d_to  Hades_1,
+        n_to  Hades_1,
+        s_to  Hades_1,
+        e_to  Hades_1,
+        w_to  Hades_1,
+        in_to  Hades_1,
+        out_to  Hades_1,
+        ne_to  Hades_2,
+        nw_to  Hades_1,
+        se_to  Hades_1,
+        sw_to  Hades_1,
+        each_turn [;
+           if (random(10) == 1)
+              "^A wisp of smoke appears to the northeast, then fades.";
+        ],
+;
+                   
+Object Hades_2 "Hades"
+   class Hades_Room_Class
+   with u_to  Hades_1,
+        d_to  Hades_1,
+        n_to  Hades_2,
+        s_to  Hades_3,
+        e_to  Hades_1,
+        w_to  Hades_2,
+        in_to  Hades_1,
+        out_to  Hades_1,
+        ne_to  Hades_2,
+        nw_to  Hades_1,
+        se_to  Hades_2,
+        sw_to  Hades_2,
+        each_turn [;
+           if (random(10) == 1)
+              "^A wisp of smoke appears to the south, then fades.";
+        ],
+;
+     
+Object Hades_3 "Hades"
+   class Hades_Room_Class
+   with u_to  Hades_4,
+        d_to  Hades_3,
+        n_to  Hades_2,
+        s_to  Hades_1,
+        e_to  Hades_1,
+        w_to  Hades_2,
+        in_to  Hades_3,
+        out_to  Hades_1,
+        ne_to  Hades_2,
+        nw_to  Hades_1,
+        se_to  Hades_3,
+        sw_to  Hades_3,
+        each_turn [;
+           if (random(10) == 1)
+              "^A wisp of smoke appears above, then fades.";
+        ],
+;
+     
+Object Hades_4 "Hades"
+   class Hades_Room_Class
+   with u_to  Hades_3,
+        d_to  Hades_3,
+        n_to  Hades_5,
+        s_to  Hades_2,
+        e_to  Hades_1,
+        w_to  Hades_4,
+        in_to  Hades_4,
+        out_to  Hades_1,
+        ne_to  Hades_1,
+        nw_to  Hades_3,
+        se_to  Hades_3,
+        sw_to  Hades_1,
+        each_turn [;
+           if (random(10) == 1)
+              "^A wisp of smoke appears to the north, then fades.";
+        ],
+;
+     
+Object Hades_5 "Hades"
+   with description "You are floating in an empty space. Surrounding you \
+           on all sides is a great wall of flame. It would almost seem \
+           like you are trapped inside a ball of fire.",
+        name "fire" "space",
+        u_to  Hades_1,
+        d_to  Hades_3,
+        n_to  Hades_2,
+        s_to  Hades_4,
+        e_to  Hades_4,
+        w_to  Hades_5,
+!        in_to  Hades_1,
+        out_to  Hades_1,
+        ne_to  Hades_1,
+        nw_to  Hades_3,
+        se_to  Hades_3,
+        sw_to  Hades_2,
+        before [;
+           if ((action~=##Go) && (action~=##Look) && 
+               (action~=##Wait) && (action~=##Enter) &&
+               (action~=##Take) && (action~=##Examine))
+              "You currently lack the means to do that.";
+           Go:
+              if (noun==in_obj) {
+                 Revive_Player1();
+                 rtrue;
+              }
+              give self ~visited;
+              print "^You find yourself floating through the flaming wall! \
+                    As you pass through you feel a gut-wrenching sensation. \
+                    Well, perhaps you would if you currently had a gut, or \
+                    sensations for that matter. Let's just say you feel \
+                    something akin to a gut-wrenching sensation, and leave \
+                    it at that.^";
+        ],
+     has light;           
+     
+Object Hades_flameball "Ball of flame" Hades_5
+   with name "ball" "sphere" "flame",
+        initial [;
+           print "In the center of the room is a ";
+           if (Player_Lives_Left >= 3)
+              "large flaming sphere.";
+           if (Player_Lives_Left == 2)
+              "medium-sized flaming sphere.";
+           "small flaming sphere.";
+        ],
+        description "It's rather hypnotic -- a perfect sphere made entirely of orange-red fire.",
+        before [;
+           Enter: 
+              Revive_Player1();
+              rtrue;
+        ],                
+   has enterable static open;
+   
+[ Revive_Player1 ;
+     print "You find yourself drawn into flaming sphere. The \
+            ball of flame engulfs you completely, and you feel \
+            nothing as inky blackness surrounds you.^^\
+            ~You have revived him!~ you hear a voice say.^^\
+            You open your eyes. You are lying on a long wooden \
+            table in the Monastery Steeple room. Several members \
+            of the Order are gathered around you, and Brother \
+            Joseph helps you to your feet.^^\
+            ~We were able to bring you back to the world of the \
+            living,~ Joseph says, ~but I fear our powers are waning, \
+            and we may not succeed if we try again. Your quest \
+            continues!~^^\
+            The group files out, leaving you alone in the room.^";
+     in_hades = 0;
+     Player_Lives_Left--;
+     Player_HP_CUR = Player_HP_MAX;  ! Healed up
+     give steeple_window ~open;  ! one of the acolytes was too cold...
+     PlayerTo(MON_Steeple_room);
+];
+
+    
+! ***********************************************************************
+! **
+! ** INITIALIZE AND OTHER STARTUP, place player, place objs, etc
+! **
+! ***********************************************************************
+
+[ Initialise;
+  
+  thedark.description =
+     "It is pitch black. You are likely to be eaten by a grue.";
+     
+  prayer_book.magic = all_my_spells;
+  <Learn prayer_book gnusto_spell>;
+  <Learn prayer_book frotz_spell>;
+  move prayer_book to player;
+  location=MON_Chapel1;
+
+!  (FOR TESTING ONLY)
+!move amulet to player;
+!<Learn prayer_book huncho_spell>;
+!<Learn prayer_book feeyuk_spell>;
+!<Learn prayer_book ledak_spell>;
+!<Learn prayer_book egdelp_spell>;
+!<Learn prayer_book tossio_spell>;
+!move TEMPLE_Artifact to player;
+!move umbrella to player;
+!move sack to player;
+!move c1 to player;
+!move magic_door to player;
+!location = ANTHAR_GUSStation;
+!location=Skyscraper;
+!spell_block = 1;
+!<Learn prayer_book bekdab_spell>;
+!<Learn prayer_book egdelp_spell>;
+!<Learn prayer_book tossio_spell>;
+!move decaf_coffee_can to player;
+!location=ATRII_1;
+];
+
+
+! ***********************************************************************
+! **
+! ** Some special routines, which should be after Initialise
+! **
+! ***********************************************************************
+
+! The Afterlife -- or, a fine time in Hades
+[ AfterLife i;
+   if (Player_Lives_Left <= 0) {
+      print "^^A blackness surrounds you, replaced by more blackness...^^";
+      rfalse;
+   }
+   else {
+      deadflag = 0;  ! not dead yet
+      ! move inventory to place of death
+      i=parent(player);
+      while (child(player)~=0) {
+         give child(player) ~worn;
+         move child(player) to i;
+      }
+      spell_block = 0;
+      in_atrii = 0;
+      in_hades = 1;   
+      print "^^A blackness surrounds you, only to be replaced by...^^";
+      i = random(4);
+      if (i==2) { PlayerTo(Hades_2); rtrue; }
+      if (i==3) { PlayerTo(Hades_3); rtrue; }
+      else { PlayerTo(Hades_1); rtrue; }
+   }
+];   
+
+
+[ DarkToDark i;
+     i = random(10);
+     if (i < 4) {
+        print "^Hmm, perhaps the Grues really are migrating with the \
+               Great Change.^";
+        rtrue;
+     }
+     if (i >= 4) {
+        deadflag = 1;
+        "^Well, don't say I didn't warn you. Something horrible \
+with slavering fangs lurks up and devours you!";
+        rtrue;
+     }
+];
+                    
+
+! [ WeightOf obj t i;
+!       t = obj.weight;
+!       objectloop (i in obj)  t=t+WeightOf(i);
+!       return t;
+! ];              
+! Now, rules for capacity still hold (slightly unrealistic), but we
+! can now check WeightOf(player) in those situations that need it.
+
+[ PrintRank;
+   print ", earning you the rank of ";
+   if (score < 0) "Wanna-be Altar-boy";
+!   if (score >= 500) "Truly Enlightened One";
+!   if (score >= 495) "Benevolent One";
+!   if (score >= 490) "Faithful One";
+!   if (score >= 395) "Simple Man";
+! fill fill
+   if (score >= 250) "Enlightened One";
+   if (score >= 225) "Patriarch";
+   if (score >= 200) "Cardinal";
+   if (score >= 150) "Lama";
+   if (score >= 125) "Cleric";
+   if (score >= 100) "High Priest";
+   if (score >= 90) "Priest";
+   if (score >= 75) "Monk";
+   if (score >= 50) "Brother";
+   if (score >= 30) "Acolyte";
+   if (score >= 20) "Aspirant";
+   if (score >= 10) "Devoted";
+   if (score >= 5) "Believer";
+   "Non-believer";
+];
+
+[ PrintTaskName ach;
+    switch (ach) {
+    0: "using sand to get across the river";
+    1: "triplicating the cereal box";
+    2: "setting the alarm clock";
+    3: "getting the waxy scroll from the skier";
+    4: "giving the palace guard a good cake";
+    5: "solving Barsap's Gambit";
+    6: "fixing the sailboat";
+    7: "finding the rod in the shipwreck";
+    8: "triplicating the ale";
+    9: "finding the rod under the statue";
+    10: "pruning the Christmas Tree Monster";
+    11: "getting past the burly sports fan";
+    12: "winning the three Golem bouts";
+    13: "ending the kobold war";
+    14: "unlocking Duncanthrax's Trophy chamber";
+    15: "unlocking the Lab door";
+    16: "finding the rod in the top of the marker";
+    17: "finding the rod in the house foundation";
+    18: "removing the impenetrable steel wall";
+    19: "joining the True Rod";
+    20: "getting past the broken subway gate";
+    21: "finding the hidden path to the temple";
+    22: "getting the rod through the temple";
+!    23: "finding the scroll in Frobar's painting";
+    23: "getting the scroll from the boutique";
+    24: "getting the scroll from Frobar";
+    25: "getting into the subway tunnel";
+    26: "banishing the four evil elementals";
+! add, if desired
+    } 
+];
+
+! *** NEW ACTION ROUTINES
+
+[ PraySub i;
+     if ((in_hades == 1) || (in_atrii == 1) || (spell_block==1))
+        "You make a prayer and feel no spiritual response! \
+        Have the Deities forsaken you? Or have you found a \
+        place where even the Gods cannot provide guidance?";
+     else {
+        i = random(100);
+        if (Player_HP_MAX ~= (20 + score)) 
+           Player_HP_MAX = (20 + score);
+        ! consider increasing memory/spell capacity here
+        if (i==97) {
+           Player_HP_CUR = Player_HP_MAX;  ! Healed
+           "You make a quick but respectful prayer to the \
+           Deities above, asking for Divine Guidance in your \
+           quest. A saffron glow surrounds you and you feel \
+           spiritually and physically renewed!";
+        }
+        "You make a quick but respectful prayer to the \
+        Deities above, asking for Divine Guidance in your \
+        quest. You finish and feel spiritually renewed.";
+     } 
+];
+
+[ DiagnoseSub i;
+     if (Player_HP_CUR > Player_HP_MAX) ! (This should never happen)
+        "You feel superhuman!";
+     if (Player_HP_CUR == Player_HP_MAX)
+        "You are in good health.";
+     if (Player_HP_CUR == 1)
+        "You are near death's door.";    
+     if (Player_HP_CUR < 5)
+        "You feel extremely weak.";
+     if (Player_HP_CUR < 10)
+        "You feel weak.";
+     i = (Player_HP_MAX / Player_HP_CUR);
+     if (i >= 4)
+        "You feel slightly weak";
+     if (i >= 2) 
+        "You've been better, but you'll be okay.";
+     "You feel okay.";   
+];
+
+[ StrongSub i;
+     i = random(20);
+     if (i > 15) {
+        deadflag = 1;
+        "Such language from a priest such as yourself! \
+         The ground rumbles, and a bolt of blue wrath from the \
+         Deities strikes you dead!";
+     }
+     "Such language from a priest such as yourself! \
+         The ground rumbles suddenly!";
+];
+
+! [ LiftSub ;
+!    if (noun has static)
+!       "That's fixed in place.";
+!    if (noun has scenery)
+!       "You're unable to.";
+!    if (noun has animate)
+!       "That would be less than courteous.";
+!    print "You lift "; DefArt(noun); " and put it back in \
+!          it's original position.  Nothing obvious happens.";
+! ];
+
+[ ShakeSub ;
+   if (noun has animate)
+      "Get a hold of yourself. No need to go around shaking living \
+things like that.";
+   "Nothing happens.";
+];
+
+! (new insert routine, which is the same as old, except that
+! we also check relative sizes of objects) 
+[ InsertSub;
+  receive_action = ##Insert;
+  if (second==d_obj ) <<Drop noun>>;
+  if (parent(noun)~=player) return L__M(##Insert,1);
+
+  if (second>1)
+  {   action=##Receive;
+      if (RunRoutines(second,before)~=0) { action=##Insert; rtrue; }
+      action=##Insert;
+  }
+  if (second hasnt container) return L__M(##Insert,2);
+  if (second hasnt open)      return L__M(##Insert,3);
+  if (IndirectlyContains(noun,second)==1) return L__M(##Insert,5);
+  if (noun has worn)
+  {   L__M(##Insert,6);
+      <Disrobe noun>; if (noun has worn) rtrue;
+  }
+
+  if (children(second)>=ValueOrRun(second,capacity))
+      return L__M(##Insert,7,second);
+
+  if (noun.size > second.size) {
+     CDefArt(noun); print " appears to be too large to put in ";
+     DefArt(second); ".";
+  }
+  move noun to second;
+
+  if (AfterRoutines()==1) rtrue;
+
+  if (second>1)
+  {   action=##Receive;
+      if (RunRoutines(second,after)~=0) { action=##Insert; rtrue; }
+      action=##Insert;
+  }
+  if (keep_silent==1) rtrue;
+  if (multiflag==1) return L__M(##Insert,8);
+  L__M(##Insert,9,noun);
+];    
+
+[ FoldSub ;
+   "I fail to see what you're trying to accomplish by doing this.";
+];
+
+[ MixSub;
+   "I fail to see what you're trying to accomplish by doing this.";
+];
+
+![ SpecialDialSub;
+!   if (noun hasnt numberdial)
+!      "You can't seem to do that.";
+!   if ((second > 9) || (second < 0))
+!      print "It appears that the valid range for ",noun; " is 0 to 9";
+!   noun.number = second;
+!   if (noun.number > 9) noun.number = 0;  
+! a special restriction in this case
+!   print "You set ",noun," to ",second; ".";
+!]; 
+   
+[ JoinSub;
+   "This doesn't seem terribly productive.";
+];
+
+[ MeditateSub;
+   "You close your eyes and focus your mind inwards. \
+Mere moments of time seem to pass like eons. You \
+open your eyes.";
+];
+
+[ YellSub;
+         "ARRGH!";
+];       
+[ SneezeSub;
+     "You make a rather sickly noise.";
+];
+[ YawnSub;
+     if (Frobar in location)
+        "~Stop that!~ Frobar says, ~It's contagious.~";
+     else "Tired?";
+];
+[ XyzzySub;
+     "A hollow voice says, ~Cool!~";
+];
+[ BegSub;
+     "Please, no begging.";
+];
+[ LaughSub;
+     "Was it that funny?";
+]; 
+
+[ HelpSub;
+   "Hello Player!^^\
+SPIRITWRAK, An Interactive Fantasy Adventure^\
+If you're new to interactive fiction games, I lack the \
+space here to give an adequate description, but in short, \
+you're a character in a story, able to interact with \
+objects, places and other things (using regular english \
+sentences) in order to reach your goal, which is to \
+figure out how to ~solve~ the story. For a real \
+description, you might want to check out documents \
+located at ftp.gmd.de.^^\
+For those more experienced players, if you're looking \
+for on-line clues, etc., sadly, you won't find them \
+(the Z5 code is getting rather obscenely large as I \
+write this). A short verb list is contained in the \
+README file that you should have received with this \
+game (or should be able to find at the same place you \
+found this game). Beyond that, if you're truly \
+desperate, you can post a note on the rec.arts.int-fiction \
+usenet newsgroup, or send me email.^^\
+Thanks for playing! ^^\
+-- D. S. Yu [dsyu@@64holonet.net]";
+];
+
+Include "Grammar"; ! (Include grammar _after_ action defs, if we replace any)
+
+! **** Extensions
+!Extend "turn" first  
+!  * noun "to" number   -> SpecialDial;
+Extend "examine" first
+                * scope=ReadableSpell            -> Examine;
+
+
+
+! **** Action defs
+
+Verb "diagnose" "health" "status"
+   *     ->    Diagnose;
+    
+Verb "spells" "memory" "chants"
+                *                                -> Spells;
+Verb "learn" "memorise" "memorize" "prepare"
+                * scope=ReadableSpell            -> Learn;
+Verb "c,cast"
+                *                                -> CastOne
+                * noun                           -> CastOne;
+Verb "cast" "chant"
+                * is_spell                       -> Cast
+                * is_spell "at" noun             -> Cast
+                * is_spell "on" noun             -> Cast;
+Verb "yell" "scream" "bellow"
+   *            -> Yell;
+Verb "sneeze" "cough"
+       *       -> Sneeze;
+Verb "yawn"
+       *       -> Yawn;
+Verb "laugh" "chuckle"
+   *            -> Laugh;
+Verb "play"
+   * held       -> Blow;
+Verb "clip" "trim"
+   * noun       -> Cut;
+! Verb "lift" "raise"
+!    * noun       -> Lift;   
+Verb "shake" "yank"
+   * noun       -> Shake;
+Verb "fold"
+   * noun       -> Fold;
+Verb "mix" "stir"
+   * noun       -> Mix;
+Verb "join" "connect"
+   * noun "to" noun -> Join
+   * noun "with" noun -> Join;
+Verb meta "help" "hint"
+   *            -> Help;      
+
+! ** (nonsense verbs below, can be removed without affecting game)   
+Verb "xyzzy" "plugh" "treasure" "plover" "yoho"
+       *       -> Xyzzy;
+Verb "beg"
+        *       -> Beg;
+Verb "meditate"
+        *       -> Meditate;
+      
+end;
+! fin.
+
diff --git a/src/SPIRITA.INF b/src/SPIRITA.INF
new file mode 100644 (file)
index 0000000..5a93ebc
--- /dev/null
@@ -0,0 +1,75 @@
+! ******************
+! Abbreviations, as produced by using '-u' option for 
+! optimal abbreviations under Inform 5.5
+! ******************
+! LOG
+! -- 2/11/96 -- first created
+! -- 3/16/96 -- hacked by hand
+
+!Abbreviate ".  ";
+Abbreviate ". ";
+Abbreviate ", ";
+Abbreviate " the ";
+Abbreviate "The";
+Abbreviate "You";
+Abbreviate "ing";
+Abbreviate "'s an odd metal gate that only comes up to about your waist";
+Abbreviate "and";
+Abbreviate "On Giant White Cube";
+Abbreviate "s you";
+Abbreviate " st";
+Abbreviate " you";
+! Abbreviate " that";
+Abbreviate " that ";
+Abbreviate " to";
+Abbreviate " through";
+Abbreviate " no";
+Abbreviate " of";
+Abbreviate " do";
+Abbreviate " train";
+Abbreviate " he";
+Abbreviate " in";
+Abbreviate " li";
+Abbreviate " lo";
+Abbreviate " on";
+Abbreviate " some";
+Abbreviate "'s a";
+Abbreviate " le";
+Abbreviate " for";
+Abbreviate " ch";
+Abbreviate " mo";
+Abbreviate " ou";
+Abbreviate " thi";
+Abbreviate " see";
+Abbreviate " gr";
+Abbreviate " ma";
+Abbreviate " clo";
+Abbreviate " ro";
+! Abbreviate " en";
+Abbreviate " an";
+Abbreviate " with";
+Abbreviate " nich";
+Abbreviate " sa";
+Abbreviate "south";
+Abbreviate " flo";
+Abbreviate " la";
+Abbreviate " sh";
+Abbreviate " ne";
+Abbreviate " br";
+Abbreviate " ca";
+Abbreviate " pa";
+Abbreviate " su";
+Abbreviate " fi";
+Abbreviate " ba";
+Abbreviate " be";
+Abbreviate " from";
+Abbreviate " wal";
+Abbreviate " sp";
+Abbreviate "Brother Joseph";
+Abbreviate "the";
+Abbreviate "round";
+Abbreviate "all";
+Abbreviate " se";
+Abbreviate "you";
+Abbreviate "rang";
+Abbreviate " are";
diff --git a/src/SUBWAY.INF b/src/SUBWAY.INF
new file mode 100644 (file)
index 0000000..4994d04
--- /dev/null
@@ -0,0 +1,2033 @@
+
+! ******************************************************************
+! subway.inf
+! ----------
+! Add-on file for SPIRITWRAK
+! -- Contains Great Underground Subway system (trains and tunnels 
+!    and various denizens)
+! ******************************************************************
+
+! First, some globals (sigh)
+! Two for each train line -- one indicates 'direction' of train,
+! the second indicates the current 'location' of train.
+global PURPLELINE_dir = 0;  ! 0 North, 1 South
+global PURPLELINE_loc = 1;  ! 1-10, frostham to fublio
+global ORANGELINE_dir = 0;  ! 0 West, 1 East
+global ORANGELINE_loc = 1;  ! 1-10, Aragain to Gurth 
+global GREENLINE_dir = 0; ! 0 North, 1 South
+global GREENLINE_loc = 1; ! 1-10, New Borphee to Miznia
+
+! (Subway stops in each city are named as part of the city in
+!  caps, concat'd with "_GUSStation".  All are (of course)
+! underground.
+
+Object FROSTHAM_GUSStation "Frostham GUS Station"
+   with description [;
+         print "You are standing ";
+         if (self hasnt general) {
+           give self general; 
+           "in a dimly lit underground \
+           chamber. There seems \
+           to be a much larger room to the southeast, which is \
+           unfortunately almost completely blocked by a long metal \
+           barricade and gate. Stairs lead up to the outside.";
+         }
+         "at the entrance to the Frostham \
+          Great Underground Subway (GUS) station. The train \
+          platform lies past the gate to the southeast, or \
+          stairs lead up into the city.";
+       ],
+       name "stairs" "platform",
+       u_to FROSTHAM_GUSStop,
+       se_to FG_Gate,
+       before [;
+          Go:
+             if (noun==se_obj) {
+                if (FG_Gate_slot hasnt general)
+                  "A strange buzzing noise sounds as you try \ 
+                  to pass through the gate, and an invisible \
+                  force blocks your way!";
+                else {
+                  give FG_Gate_slot ~general; 
+                  print "You saunter through the apparently open gate.^";
+                }
+             }
+       ],
+   has light;
+
+
+Object ARAGAIN_GUSStation "Aragain GUS Station"
+   with description "You are standing at the entrance to the Aragain \
+Great Underground Subway (GUS) station. The train \
+platform lies past the gate to the southeast, or \
+stairs lead up into the city. Some lettering on the \
+wall reads ~TRANSFER STATION~.",
+       name "stairs" "platform",
+       u_to ARAGAIN_GUSStop,
+       se_to AG_Gate,
+       before [;
+          Go:
+             if (noun==se_obj) {
+                if (AG_Gate_slot hasnt general)
+                  "A strange buzzing noise sounds as you try \ 
+                  to pass through the gate, and an invisible \
+                  force blocks your way!";
+                else {
+                  give AG_Gate_slot ~general; 
+                  print "You saunter through the apparently open gate.^";
+                }
+             }
+       ],
+   has light;
+
+Object FUBLIO_GUSStation "Fublio Valley GUS Station"
+   with description "You are standing at the entrance to the \
+South Fublio Valley \
+Great Underground Subway (GUS) station. The train \
+platform lies past the gate to the southeast, or \
+stairs lead up into the city.",
+       name "stairs" "platform",
+       u_to FUBLIO_GUSStop,
+       se_to FublioG_Gate,
+       before [;
+          Go:
+             if (noun==se_obj) {
+                if (FublioG_Gate_slot hasnt general)
+                  "A strange buzzing noise sounds as you try \ 
+                  to pass through the gate, and an invisible \
+                  force blocks your way!";
+                else {
+                  give FublioG_Gate_slot ~general; 
+                  print "You saunter through the apparently open gate.^";
+                }
+             }
+       ],
+   has light;
+
+! (Orange stations - one)
+Object ANTHAR_GUSStation "Greater Anthar GUS Station"
+   with description "You are standing at the entrance to the Greater Anthar \
+Great Underground Subway (GUS) station. The train \
+platform lies past the gate to the south, or \
+stairs lead up into the city.",
+       name "stairs" "platform",
+       u_to ANTHAR_GUSStop,
+       s_to AntharG_Gate,
+       before [;
+          Go:
+             if (noun==s_obj) {
+                if (AntharG_Gate_slot hasnt general)
+                  "A strange buzzing noise sounds as you try \ 
+                  to pass through the gate, and an invisible \
+                  force blocks your way!";
+                else {
+                  give AntharG_Gate_slot ~general; 
+                  print "You saunter through the apparently open gate.^";
+                }
+             }
+       ],
+   has light;
+   
+! (Green stations - three)
+Object GURTH_GUSStation "Gurth City GUS Station"
+   with description "You are standing at the entrance to the Gurth City \
+Great Underground Subway (GUS) station. The train \
+platform lies past the gate to the southwest, or \
+stairs lead up into the city. Some lettering on the \
+wall reads ~TRANSFER STATION~.",
+       name "stairs" "platform",
+       u_to GURTH_GUSStop,
+       sw_to GurthG_Gate,
+       before [;
+          Go:
+             if (noun==u_obj)
+                print "You are greeted by a light rain as you leave the \
+station.^";
+             if (noun==sw_obj) {
+                if (GurthG_Gate hasnt general) ! note diff
+                  "A strange buzzing noise sounds as you try \ 
+                  to pass through the gate, and an invisible \
+                  force blocks your way!";
+                else {
+                  give GurthG_Gate ~general; 
+                  print "You saunter through the apparently open gate.^";
+                }
+             }
+       ],
+   has light;
+
+Object BORPHEE_GUSStation "New Borphee GUS Station"
+   with description "You are standing at the entrance to the New Borphee \
+Great Underground Subway (GUS) station. The train \
+platform lies past the gate to the southwest, or \
+stairs lead up into the city.",
+       name "stairs" "platform",
+       u_to BORPHEE_GUSStop,
+       sw_to BorpheeG_Gate,
+       before [;
+          Go:
+             if (noun==u_obj)
+                print "You enter the city and are nearly \
+                      flattened by crowds rushing past.^";
+             if (noun==sw_obj) {
+                if (BorpheeG_Gate_slot hasnt general) 
+                  "A strange buzzing noise sounds as you try \ 
+                  to pass through the gate, and an invisible \
+                  force blocks your way!";
+                else {
+                  give BorpheeG_Gate_slot ~general; 
+                  print "You saunter through the apparently open gate.^";
+                }
+             }
+       ],
+   has light;
+
+Object MIZNIA_GUSStation "Miznia GUS Station"
+   with description "You are standing at the entrance to the Miznia \
+Great Underground Subway (GUS) station. The train \
+platform lies past the gate to the southwest, or \
+stairs lead up into the city.",
+       name "stairs" "platform",
+       u_to MIZNIA_GUSStop,
+       sw_to MizniaG_Gate,
+       before [;
+          Go:
+             if (noun==sw_obj) {
+                if (MizniaG_Gate_slot hasnt general) 
+                  "A strange buzzing noise sounds as you try \ 
+                  to pass through the gate, and an invisible \
+                  force blocks your way!";
+                else {
+                  give MizniaG_Gate_slot ~general; 
+                  print "You saunter through the apparently open gate.^";
+                }
+             }
+       ],
+   has light;
+
+Object FROSTHAM_GUSPlatform "Frostham Train Platform"
+   with description [;
+           print "You are standing in a long underground \
+           chamber. The east side of the room contains a \
+           lowered set of what appear to be train tracks. \           
+           The tracks run south into a dark tunnel. \
+           Along one wall painted lettering \
+           reads ~FROSTHAM STATION~. \
+           A short walkway leads northwest, to a metal fence";
+          if (self has general)
+           ". There is a large train car sitting on the tracks \
+           to the east.";
+          else ".";
+        ],
+        name "tunnel",
+        nw_to FG_Gate,
+        s_to "A helpful subway worker says ~Hey pal, get outa there!~",
+        e_to PURPLELINE_car,
+        in_to PURPLELINE_car,
+        before [;
+           Go:
+!              if (noun == nw_obj)
+!                print "You saunter through the apparently open gate.^";
+              if ((self hasnt general) &&
+                  (noun == e_obj or in_obj))
+              "You'd fall onto the tracks if you went that way.";              
+        ],     
+        each_turn [ i ;
+           if (self hasnt general) {
+              i = random(10);
+              if (i==1 or 2 or 3) {
+                 give self general;
+                 PURPLELINE_loc = 1;            
+                 PURPLELINE_dir = 1;    ! will be heading south
+                 "^Suddenly, from the south, a train emerges from \
+                 the tunnel! It pulls to a screeching halt, the \
+                 doors open, and several people rush out and exit \
+                 the station.";
+              }
+              if (i==10) 
+                 "^You hear a distant rumbling noise from the south.";
+           }
+           else {
+              if (self has general) {
+                 if (PURPLELINE_loc == 2) {
+                    give self ~general;
+                    "^The train doors close, and the train rolls off \
+                    to the south."; 
+                 }
+                 else {
+                    PURPLELINE_loc = 2;
+                    "^A few exit the train, and hurry out \
+                    of the station. You hear a voice from inside the \
+                    train say, ~Doors will be closing, please stand \
+                    clear.~";
+                 }
+              }
+           }
+        ],        
+   has light;
+
+
+! (Classes for gates and slots)
+Class GUS_Gate_Class
+   with name "gate" "metal",
+   initial "A metal gate bisects the fence.",
+   door_dir nw_to,
+   door_to FROSTHAM_GUSPlatform,
+   before [; 
+      Climb, JumpOver: "A subway worker yells ~Hey pal, no fare-jumpers!";
+      Open:  "It looks like it's already open.";
+      Close:  "There doesn't seem to be anything to close.";
+      Enter: "You'll have to walk in the appropriate direction to go through it.";    
+   ],
+   description "It's an odd metal gate that only comes up to about \
+your waist. Odder still is the fact that there's \
+no door on the gate, just two metal sides",
+   has static door transparent open;
+Class GUS_Gate_Slot_Class
+   with name "slot" "metal" "thin" "small",
+       description "You see a rather small, thin slot that seems to be \
+almost cut into one of the metal sides of the gate.",
+       before [;
+          LetGo: "There's no way to get anything out of that tiny, \
+thin slot.";
+          Receive:
+             if (noun has is_coin) {
+                give self general;
+                remove noun;  ! collection
+                "The coin slides into the slot with a satisfying thunk.";
+             }
+             "It doesn't look like that's going to fit into the slot."; 
+       ],
+       size 1,
+   has scenery container open;
+   
+Object FG_Gate "platform gate"
+   class GUS_Gate_Class,
+   with initial [;
+           if (location==FROSTHAM_GUSStation)
+              "A metal gate bisects the fence to the southeast.";
+           "A metal gate bisects the fence to the northwest.";
+        ],
+        door_dir [;
+           if (location==FROSTHAM_GUSStation)
+              return se_to;
+           return nw_to;
+        ],
+        door_to [;
+           if (location==FROSTHAM_GUSStation)
+              return FROSTHAM_GUSPlatform;
+           return FROSTHAM_GUSStation;
+        ],
+        before [; 
+           Enter:
+              if (location==FROSTHAM_GUSStation) <<Go se_obj>>;
+              else <<Go nw_obj>>;
+        ],
+        description [;
+        print "It's an odd metal gate that only comes up to about \
+               your waist. Odder still is the fact that there's \
+               no door on the gate, just two metal sides";
+        if (location == FROSTHAM_GUSStation)
+           ". There's a thin slot on one of the sides.";
+        else ".";
+        ],
+        found_in FROSTHAM_GUSStation FROSTHAM_GUSPlatform,
+;
+   
+   
+      
+Object FG_Gate_slot "metal slot" FG_Gate
+   class GUS_Gate_Slot_Class
+   with description [;
+          if (location == FROSTHAM_GUSPlatform)
+             "You can't see any such thing.";
+          if (location == FROSTHAM_GUSStation)
+             "You see a rather small, thin slot that seems to be \
+almost cut into one of the metal sides of the gate.";
+     ],
+       before [;
+          if (location == FROSTHAM_GUSPlatform)
+                "You can't see any such thing.";
+       ],
+;
+   
+   
+Object AG_Gate "platform gate"
+   class GUS_Gate_Class
+   with initial [;
+           if (location==ARAGAIN_GUSStation)
+              "A metal gate bisects the fence to the southeast.";
+           "A metal gate bisects the fence to the northwest.";
+        ],
+        door_dir [;
+           if (location==ARAGAIN_GUSStation)
+              return se_to;
+           return nw_to;
+        ],
+        door_to [;
+           if (location==ARAGAIN_GUSStation)
+              return ARAGAIN_GUSPlatform;
+           return ARAGAIN_GUSStation;
+        ],
+        before [; 
+           Enter:
+              if (location==FROSTHAM_GUSStation) <<Go se_obj>>;
+              else <<Go nw_obj>>;
+        ],
+        description [;
+       print "It's an odd metal gate that only comes up to about \
+               your waist. Odder still is the fact that there's \
+               no door on the gate, just two metal sides";
+           if (location == ARAGAIN_GUSStation)
+              ". There's a thin slot on one of the sides.";
+           else ".";
+        ],
+        found_in ARAGAIN_GUSStation ARAGAIN_GUSPlatform,
+;
+   
+Object AG_Gate_slot "metal slot" AG_Gate
+   class GUS_Gate_Slot_Class
+   with description [;
+          if (location == ARAGAIN_GUSPlatform)
+             "You can't see any such thing.";
+          if (location == ARAGAIN_GUSStation)
+             "You see a rather small, thin slot that seems to be \
+almost cut into one of the metal sides of the gate.";
+     ],
+       before [;
+          if (location == ARAGAIN_GUSPlatform)
+                "You can't see any such thing.";
+       ],
+;
+   
+   
+Object FublioG_Gate "platform gate"
+   class GUS_Gate_Class
+   with initial [;
+           if (location==FUBLIO_GUSStation)
+              "A metal gate bisects the fence to the southeast.";
+           "A metal gate bisects the fence to the northwest.";
+        ],
+        door_dir [;
+           if (location==FUBLIO_GUSStation)
+              return se_to;
+           return nw_to;
+        ],
+        door_to [;
+           if (location==FUBLIO_GUSStation)
+              return FUBLIO_GUSPlatform;
+           return FUBLIO_GUSStation;
+        ],
+        before [; 
+           Enter:
+              if (location==FUBLIO_GUSStation) <<Go se_obj>>;
+              else <<Go nw_obj>>;
+        ],
+        description [;
+       print "It's an odd metal gate that only comes up to about \
+            your waist. Odder still is the fact that there's \
+            no door on the gate, just two metal sides";
+           if (location == FUBLIO_GUSStation)
+              ". There's a thin slot on one of the sides.";
+           else ".";
+        ],
+        found_in FUBLIO_GUSStation FUBLIO_GUSPlatform,
+;
+   
+Object FublioG_Gate_slot "metal slot" FublioG_Gate
+   class GUS_Gate_Slot_Class
+   with description [;
+          if (location == FUBLIO_GUSStation)
+             "You see a rather small, thin slot that seems to be \
+             almost cut into one of the metal sides of the gate.";
+!! See if this works instead...
+          "You can't see any such thing.";
+       ],
+       before [;
+          if (location == FUBLIO_GUSPlatform)
+             "You can't see any such thing.";
+       ],
+;
+
+! (Orange gates (1))
+Object AntharG_Gate "platform gate"
+   class GUS_Gate_Class
+   with initial [;
+           if (location==ANTHAR_GUSStation)
+              "A metal gate bisects the fence to the south.";
+           "A metal gate bisects the fence to the north.";
+        ],
+        door_dir [;
+           if (location==ANTHAR_GUSStation)
+              return s_to;
+           return n_to;
+        ],
+        door_to [;
+           if (location==ANTHAR_GUSStation)
+              return ANTHAR_GUSPlatform;
+           return ANTHAR_GUSStation;
+        ],
+        before [; 
+           Enter:
+              if (location==ANTHAR_GUSStation) <<Go s_obj>>;
+              else <<Go n_obj>>;
+        ],
+        description [;
+        print "It's an odd metal gate that only comes up to about \
+            your waist. Odder still is the fact that there's \
+            no door on the gate, just two metal sides";
+           if (location == ANTHAR_GUSStation)
+               ". There's a thin slot on one of the sides.";
+           else ".";
+        ],
+        found_in ANTHAR_GUSStation ANTHAR_GUSPlatform,
+;
+   
+Object AntharG_Gate_slot "metal slot" AntharG_Gate
+   class GUS_Gate_Slot_Class
+   with description [;
+          if (location == ANTHAR_GUSStation)
+             "You see a rather small, thin slot that seems to be \
+             almost cut into one of the metal sides of the gate.";
+          "You can't see any such thing.";
+       ],
+       before [;
+          if (location == ANTHAR_GUSPlatform) 
+             "You can't see any such thing.";
+       ],
+;   
+
+
+! (Green gates (3))
+Object BorpheeG_Gate "platform gate"
+   class GUS_Gate_Class
+   with initial [;
+           if (location==BORPHEE_GUSStation)
+              "A metal gate bisects the fence to the southwest.";
+           "A metal gate bisects the fence to the northeast.";
+        ],
+        door_dir [;
+           if (location==BORPHEE_GUSStation)
+              return sw_to;
+           return ne_to;
+        ],
+        door_to [;
+           if (location==BORPHEE_GUSStation)
+              return BORPHEE_GUSPlatform;
+           return BORPHEE_GUSStation;
+        ],
+        before [; 
+           Enter:
+              if (location == BORPHEE_GUSStation) <<Go sw_obj>>;
+              else <<Go ne_obj>>;
+        ],
+        description [;
+            print "It's an odd metal gate that only comes up to about \
+               your waist. Odder still is the fact that there's \
+               no door on the gate, just two metal sides";
+           if (location == BORPHEE_GUSStation)
+              ". There's a thin slot on one of the sides.";
+           else ".";
+        ],
+        found_in BORPHEE_GUSStation BORPHEE_GUSPlatform,
+;
+   
+Object BorpheeG_Gate_slot "metal slot" BorpheeG_Gate
+   class GUS_Gate_Slot_Class
+   with description [;
+          if (location == BORPHEE_GUSStation)
+             "You see a rather small, thin slot that seems to be \
+             almost cut into one of the metal sides of the gate.";
+          "You can't see any such thing.";
+       ],
+       before [;
+          if (location == BORPHEE_GUSPlatform) 
+             "You can't see any such thing.";
+       ],
+;
+   
+! (NOTE: Gurth is different, read: broken)   
+Object GurthG_Gate "platform gate"
+   class GUS_Gate_Class
+   with initial [;
+           if (location==GURTH_GUSStation)
+              "A metal gate bisects the fence to the southwest.";
+           "A metal gate bisects the fence to the northeast.";
+        ],
+        door_dir [;
+           if (location==GURTH_GUSStation)
+              return sw_to;
+           return ne_to;
+        ],
+        door_to [;
+           if (location==GURTH_GUSStation)
+              return GURTH_GUSPlatform;
+           return GURTH_GUSStation;
+        ],
+        before [; 
+           Enter:  if (location == GURTH_GUSStation) <<Go sw_obj>>;
+                   else <<Go ne_obj>>;
+        ],
+        description [;
+           print "It's an odd metal gate that only comes up to about \
+            your waist. Odder still is the fact that there's \
+            no door on the gate, just two metal sides";
+           if (location == GURTH_GUSStation)
+              ". There's a thin slot on one of the sides that looks \
+              slightly dented.";
+           else ".";
+        ],
+        found_in GURTH_GUSStation GURTH_GUSPlatform,
+;
+   
+Object GurthG_Gate_slot "metal slot" GurthG_Gate
+   class GUS_Gate_Slot_Class
+   with name "dented",
+       description [;
+          if (location == GURTH_GUSStation)
+             "You see a rather small, thin slot that seems to be \
+             almost cut into one of the metal sides of the gate. \
+             It looks slightly dented.";
+          "You can't see any such thing.";
+       ],
+       before [;
+          if (location == GURTH_GUSPlatform)
+             "You can't see any such thing.";
+          Receive:
+             if (noun has is_coin) {
+                give self general;
+                remove noun;
+                "The coin slides into the slot, but you hear a strange click \
+                almost immediately.^^\
+                A subway nymph suddenly appears. She looks at the gate \
+                disapprovingly. ~Broken again? I thought they \
+                just fixed it. Well, fine.~ She seems rather annoyed. \
+                ~We'll get someone to look at it, eventually. Bye!~ She \
+                disappears.";
+             }
+             if (noun==wire) {
+                if (self hasnt general)
+                   "You poke the wire in the slot for a bit, but nothing \
+                   happens.";
+                if (self has general) {
+                   give self ~general;
+                   Achieved(20);
+                   give GurthG_Gate general;
+                   "You poke around in the slot, and manage to free something! \
+                   There is a solid thunk-like noise.";
+                }             
+             }
+             "It doesn't look like that's going to fit into the slot."; 
+       ],
+;   
+
+Object MizniaG_Gate "platform gate"
+   class GUS_Gate_Class
+   with initial [;
+           if (location==MIZNIA_GUSStation)
+              "A metal gate bisects the fence to the southwest.";
+           "A metal gate bisects the fence to the northeast.";
+        ],
+        door_dir [;
+           if (location==MIZNIA_GUSStation)
+              return sw_to;
+           return ne_to;
+        ],
+        door_to [;
+           if (location==MIZNIA_GUSStation)
+              return MIZNIA_GUSPlatform;
+           return MIZNIA_GUSStation;
+        ],
+        before [; 
+           Enter: if (location==MIZNIA_GUSStation) <<Go sw_obj>>;
+                  else <<Go ne_obj>>;
+        ],
+        description [;
+           print "It's an odd metal gate that only comes up to about \
+            your waist. Odder still is the fact that there's \
+            no door on the gate, just two metal sides";
+           if (location == MIZNIA_GUSStation)
+              ". There's a thin slot on one of the sides.";
+           else ".";
+        ],
+        found_in MIZNIA_GUSStation MIZNIA_GUSPlatform,
+;
+   
+Object MizniaG_Gate_slot "metal slot" MizniaG_Gate
+   class GUS_Gate_Slot_Class
+   with description [;
+          if (location == MIZNIA_GUSStation)
+             "You see a rather small, thin slot that seems to be \
+             almost cut into one of the metal sides of the gate.";
+          "You can't see any such thing.";
+       ],
+       before [;
+          if (location==MIZNIA_GUSPlatform)
+             "You can't see any such thing.";
+       ],
+;
+
+
+   
+!Object FS_Platform_sign2 "laminated paper" FROSTHAM_GUSPlatform
+!   with name "paper" "laminated" "safety",
+!      initial "A small stiff-looking piece of paper is attached to the west wall.",
+!      description "The paper reads: ^^\
+!      GREAT UNDERGROUND SUBWAY STATION RULES:^
+!      1) No going onto tracks.^
+!      2) No going into tunnels on foot unless authorized.",
+!   has static;
+   
+Object train_tracks "train tracks"
+   with name "tracks" "train",
+        description "A pair of large metal train tracks.",
+        found_in FROSTHAM_GUSPlatform ARAGAIN_GUSPlatform FUBLIO_GUSPlatform
+                 ARAGAIN_GUSPlatform2,
+   has scenery;
+   
+   
+Object ARAGAIN_GUSPlatform "Aragain Train Platform"
+   with description [;
+           print "You are standing in a long underground \
+           chamber. The east side of the room contains a \
+           lowered set of what appear to be train tracks. \
+           The tracks run north and south into dark tunnels. \
+           Along one wall painted lettering \
+           reads ~ARAGAIN STATION~. \
+           A short walkway leads northwest, to a metal fence. \
+           There is also a stairway down here";
+          if (self has general)
+           ". In addition, there is a large train car sitting on the tracks \
+           to the east.";
+          else ".";
+        ],
+        name "tunnel" "tunnels" "stairway",
+        nw_to AG_Gate,
+        s_to "A helpful subway worker says ~Hey pal, get outa there!~",
+        n_to "A helpful subway worker says ~Hey pal, get outa there!~",
+        e_to PURPLELINE_car,
+        d_to ARAGAIN_GUSPlatform2,
+        in_to PURPLELINE_car,
+        before [;
+           Go:
+!              if (noun == nw_obj)
+!                print "You saunter through the apparently open gate.^";
+              if ((self hasnt general) &&
+                  (noun == e_obj or in_obj))
+              "You'd fall onto the tracks if you went that way.";              
+        ],     
+        each_turn [ i ;
+           if (self hasnt general) {
+              i = random(10);
+              if (i==1 or 3 or 5) {
+                 give self general;
+                 PURPLELINE_loc = 5;            
+                 PURPLELINE_dir = 1;    ! will be heading south
+                 "^Suddenly, from the north, a train emerges from \
+                 the tunnel! It pulls to a screeching halt, the \
+                 doors open, and several people rush out and exit \
+                 the station.";
+              }
+              if (i==2 or 4 or 6) {
+                 give self general;
+                 PURPLELINE_loc = 5;            
+                 PURPLELINE_dir = 0;    ! will be heading north
+                 "^Suddenly, from the south, a train emerges from \
+                 the tunnel! It pulls to a screeching halt, the \
+                 doors open, and several people rush out and exit \
+                 the station.";
+              }
+              if (i==9)
+                 "^You hear a distant rumbling noise from the north.";
+              if (i==10) 
+                 "^You hear a distant rumbling noise from the south.";
+           }
+           else {
+              if (self has general) {
+                 if (PURPLELINE_loc == 6) {
+                    give self ~general;
+                    "^The train doors close, and the train rolls off."; 
+                 }
+                 else {
+                    PURPLELINE_loc = 6;
+                    "^A few exit the train, and hurry out \
+                    of the station. You hear a voice from inside the \
+                    train say, ~Doors will be closing, please stand \
+                    clear.~";
+                 }
+              }
+           }
+        ],        
+   has light;
+Object ARAGAIN_GUSPlatform2 "Aragain Train Platform (lower)"
+   with description [;
+           print "You are standing in a long underground \
+           chamber. The south side of the room contains a \
+           lowered set of what appear to be train tracks. \
+           The tracks run west into a dark tunnel. \
+           Along one wall painted lettering \
+           reads ~ARAGAIN STATION~. \
+           A set of stairs leads up out of the gloom";
+          if (self has general)
+           ". There is a large train car sitting on the tracks \
+           to the south.";
+          else ".";
+        ],
+        name "tunnel" "stairs",
+        w_to "A helpful subway worker says ~Hey pal, get outa there!~",
+        s_to ORANGELINE_car,
+        in_to ORANGELINE_car,
+        u_to ARAGAIN_GUSPlatform,
+        before [;
+           Go:
+              if ((self hasnt general) &&
+                  (noun == s_obj or in_obj))
+              "You'd fall onto the tracks if you went that way.";              
+        ],     
+        each_turn [ i ;
+           if (self hasnt general) {
+              i = random(10);
+              if (i==1 or 3 or 5) {
+                 give self general;
+                 ORANGELINE_loc = 9;            
+                 ORANGELINE_dir = 0;    ! will be heading west
+                 "^Suddenly, from the west, a train emerges from \
+                 the tunnel! It pulls to a screeching halt, the \
+                 doors open, and several people rush out and up \
+                 the stairs.";
+              }
+              if (i==10) 
+                 "^You hear a distant rumbling noise from the west.";
+           }
+           else {
+              if (self has general) {
+                 if (ORANGELINE_loc == 10) {
+                    give self ~general;
+                    "^The train doors close, and the train heads off \
+                    to the west."; 
+                 }
+                 else {
+                    ORANGELINE_loc = 10;
+                    "^A few people exit the train, and hurry up the stairs. \
+                    You hear a voice from inside the \
+                    train say, ~Doors will be closing, please stand \
+                    clear.~";
+                 }
+              }
+           }
+        ],        
+   has light;      
+   
+   
+Object FUBLIO_GUSPlatform "Fublio Valley Train Platform"
+   with description [;
+           print "You are standing in a long underground \
+           chamber. The east side of the room contains a \
+           lowered set of what appear to be train tracks. \
+           The tracks run north into a dark tunnel. \
+           Along one wall painted lettering \
+           reads ~FUBLIO VALLEY STATION~. \
+           A short walkway leads northwest, to a metal fence";
+          if (self has general)
+           ". There is a large train car sitting on the tracks \
+           to the east.";
+          else ".";
+        ],
+        name "tunnel",
+        nw_to FublioG_Gate,
+        n_to "A helpful subway worker says ~Hey pal, get outa there!~",
+        e_to PURPLELINE_car,
+        in_to PURPLELINE_car,
+        before [;
+           Go:
+!              if (noun == nw_obj)
+!                print "You saunter through the apparently open gate.^";
+              if ((self hasnt general) &&
+                  (noun == e_obj or in_obj))
+              "You'd fall onto the tracks if you went that way.";              
+        ],     
+        each_turn [ i ;
+           if (self hasnt general) {
+              i = random(10);
+              if (i==1 or 3 or 4) {
+                 give self general;
+                 PURPLELINE_loc = 10;            
+                 PURPLELINE_dir = 0;    ! will be heading north
+                 "^Suddenly, from the north, a train emerges from \
+                 the tunnel! It pulls to a screeching halt, the \
+                 doors open, and several people rush out and exit \
+                 the station.";
+              }
+              if (i==10) 
+                 "^You hear a distant rumbling noise from the north.";
+           }
+           else {
+              if (self has general) {
+                 if (PURPLELINE_loc == 9) {
+                    give self ~general;
+                    "^The train doors close, and the train rolls off \
+                    to the north."; 
+                 }
+                 else {
+                    PURPLELINE_loc = 9;
+                    "^A few people exit the train, and hurry out \
+                    of the station. You hear a voice from inside the \
+                    train say, ~Doors will be closing, please stand \
+                    clear.~";
+                 }
+              }
+           }
+        ],        
+   has light;      
+
+   
+! *** Orange line platforms
+
+
+Object GURTH_GUSPlatform2 "Gurth City Train Platform (lower)"
+   with description [;
+           print "You are standing in a long underground \
+           chamber. The south side of the room contains a \
+           lowered set of what appear to be train tracks. \
+           The tracks run east into a dark tunnel. \
+           Along one wall painted lettering \
+           reads ~GURTH CITY STATION~. \
+           A set of stairs leads up out of the gloom";
+          if (self has general)
+           ". There is a large train car sitting on the tracks \
+           to the south.";
+          else ".";
+        ],
+        name "tunnel" "stairs", 
+        e_to "A helpful subway worker says ~Hey pal, get outa there!~",
+        s_to ORANGELINE_car,
+        in_to ORANGELINE_car,
+        u_to GURTH_GUSPlatform,
+        before [;
+           Go:
+              if ((self hasnt general) &&
+                  (noun == s_obj or in_obj))
+              "You'd fall onto the tracks if you went that way.";              
+        ],     
+        each_turn [ i ;
+           if (self hasnt general) {
+              i = random(10);
+              if (i==1 or 2 or 4) {
+                 give self general;
+                 ORANGELINE_loc = 1;            
+                 ORANGELINE_dir = 1;    ! will be heading east
+                 "^Suddenly, from the east, a train emerges from \
+                 the tunnel! It pulls to a screeching halt, the \
+                 doors open, and several people rush out and up \
+                 the stairs.";
+              }
+              if (i==10) 
+                 "^You hear a distant rumbling noise from the east.";
+           }
+           else {
+              if (self has general) {
+                 if (ORANGELINE_loc == 2) {
+                    give self ~general;
+                    "^The train doors close, and the train heads off \
+                    to the east."; 
+                 }
+                 else {
+                    ORANGELINE_loc = 2;
+                    "^A few people exit the train, and hurry up the stairs. \
+                    You hear a voice from inside the \
+                    train say, ~Doors will be closing, please stand \
+                    clear.~";
+                 }
+              }
+           }
+        ],        
+   has light;      
+   
+Object ANTHAR_GUSPlatform "Greater Anthar Train Platform"
+   with description [;
+           print "You are standing in a long underground \
+           chamber. The south side of the room contains a \
+           lowered set of what appear to be train tracks. \
+           The tracks run east and west into dark tunnels. \
+           Along one wall painted lettering \
+           reads ~ANTHAR STATION~. \
+           A short walkway leads north, to a metal fence";
+          if (self has general)
+           ". There is a large train car sitting on the tracks \
+           to the south.";
+          else ".";
+        ],
+        name "tunnel" "tunnels" "walkway",
+        n_to AntharG_Gate,
+        e_to "A helpful subway worker says ~Hey pal, get outa there!~",
+        w_to "A helpful subway worker says ~Hey pal, get outa there!~",        
+        s_to ORANGELINE_car,
+        in_to ORANGELINE_car,
+        before [;
+           Go:
+!              if (noun == n_obj)
+!                print "You saunter through the apparently open gate.^";
+              if ((self hasnt general) &&
+                  (noun == s_obj or in_obj))
+              "You'd fall onto the tracks if you went that way.";              
+        ],     
+        each_turn [ i ;
+           if (self hasnt general) {
+              i = random(10);
+              if (i==1 or 4 or 5) {
+                 give self general;
+                 ORANGELINE_loc = 5;            
+                 ORANGELINE_dir = 1;    ! will be heading east
+                 "^Suddenly, from the west, a train emerges from \
+                 the tunnel! It pulls to a screeching halt, the \
+                 doors open, and several people rush out and exit \
+                 the station.";
+              }
+              if (i==2 or 3 or 6) {
+                 give self general;
+                 ORANGELINE_loc = 5;            
+                 ORANGELINE_dir = 0;    ! will be heading west
+                 "^Suddenly, from the east, a train emerges from \
+                 the tunnel! It pulls to a screeching halt, the \
+                 doors open, and several people rush out and exit \
+                 the station.";
+              }
+              if (i==9)
+                 "^You hear a distant rumbling noise from the east.";
+              if (i==10) 
+                 "^You hear a distant rumbling noise from the west.";
+           }
+           else {
+              if (self has general) {
+                 if (ORANGELINE_loc == 6) {
+                    give self ~general;
+                    "^The train doors close, and the train rolls off."; 
+                 }
+                 else {
+                    ORANGELINE_loc = 6;
+                    "^A few people exit the train, and hurry out \
+                    of the station. You hear a voice from inside the \
+                    train say, ~Doors will be closing, please stand \
+                    clear.~";
+                 }
+              }
+           }
+        ],        
+   has light;
+
+
+! *** Green line platforms
+
+Object BORPHEE_GUSPlatform "New Borphee Train Platform"
+   with description [;
+           print "You are standing in a long underground \
+           chamber. The west side of the room contains a \
+           lowered set of what appear to be train tracks. \
+           The tracks run south into a dark tunnel. \
+           Along one wall painted lettering \
+           reads ~NEW BORPHEE STATION~. \
+           A short walkway leads northeast, to a metal fence";
+          if (self has general)
+           ". There is a large train car sitting on the tracks \
+           to the west.";
+          else ".";
+        ],
+        name "tunnel" "walkway",
+        ne_to BorpheeG_Gate,
+        s_to "A helpful subway worker says ~Hey pal, get outa there!~",
+        w_to GREENLINE_car,
+        in_to GREENLINE_car,
+        before [;
+           Go:
+!              if (noun == ne_obj)
+!                print "You saunter through the apparently open gate.^";
+              if ((self hasnt general) &&
+                  (noun == w_obj or in_obj))
+              "You'd fall onto the tracks if you went that way.";              
+        ],     
+        each_turn [ i ;
+           if (self hasnt general) {
+              i = random(10);
+              if (i==1 or 2 or 3) {
+                 give self general;
+                 GREENLINE_loc = 1;            
+                 GREENLINE_dir = 1;    ! will be heading south
+                 "^Suddenly, from the south, a train emerges from \
+                 the tunnel! It pulls to a screeching halt, the \
+                 doors open, and several people rush out and exit \
+                 the station.";
+              }
+              if (i==10) 
+                 "^You hear a distant rumbling noise from the south.";
+           }
+           else {
+              if (self has general) {
+                 if (GREENLINE_loc == 2) {
+                    give self ~general;
+                    "^The train doors close, and the train rolls off \
+                    to the south."; 
+                 }
+                 else {
+                    GREENLINE_loc = 2;
+                    "^A few people exit the train, and hurry out \
+                    of the station. You hear a voice from inside the \
+                    train say, ~Doors will be closing, please stand \
+                    clear.~";
+                 }
+              }
+           }
+        ],        
+   has light;      
+
+Object MIZNIA_GUSPlatform "Miznia Train Platform"
+   with description [;
+           print "You are standing in a long underground \
+           chamber. The west side of the room contains a \
+           lowered set of what appear to be train tracks. \
+           The tracks run north into a dark tunnel. \
+           Along one wall painted lettering \
+           reads ~MIZNIA STATION~. \
+           A short walkway leads northeast, to a metal fence";
+          if (self has general)
+           ". There is a large train car sitting on the tracks \
+           to the west.";
+          else ".";
+        ],
+        name "tunnel" "walkway",
+        ne_to MizniaG_Gate,
+        n_to "A helpful subway worker says ~Hey pal, get outa there!~",
+        w_to GREENLINE_car,
+        in_to GREENLINE_car,
+        before [;
+           Go:
+!              if (noun == ne_obj)
+!                print "You saunter through the apparently open gate.^";
+              if ((self hasnt general) &&
+                  (noun == w_obj or in_obj))
+              "You'd fall onto the tracks if you went that way.";              
+        ],     
+        each_turn [ i ;
+           if (self hasnt general) {
+              i = random(10);
+              if (i==1 or 2 or 3) {
+                 give self general;
+                 GREENLINE_loc = 9;            
+                 GREENLINE_dir = 0;    ! will be heading south
+                 "^Suddenly, from the north, a train emerges from \
+                 the tunnel! It pulls to a screeching halt, the \
+                 doors open, and several people rush out and exit \
+                 the station.";
+              }
+              if (i==10) 
+                 "^You hear a distant rumbling noise from the north.";
+           }
+           else {
+              if (self has general) {
+                 if (GREENLINE_loc == 10) {
+                    give self ~general;
+                    "^The train doors close, and the train rolls off \
+                    to the north."; 
+                 }
+                 else {
+                    GREENLINE_loc = 10;
+                    "^A few people exit the train, and hurry out \
+                    of the station. You hear a voice from inside the \
+                    train say, ~Doors will be closing, please stand \
+                    clear.~";
+                 }
+              }
+           }
+        ],        
+   has light;      
+
+Object GURTH_GUSPlatform "Gurth City Train Platform"
+   with description [;
+           print "You are standing in a long underground \
+           chamber. The west side of the room contains a \
+           lowered set of what appear to be train tracks. \
+           The tracks run north and south into dark tunnels. \
+           Along one wall painted lettering \
+           reads ~GURTH CITY STATION~. \
+           A short walkway leads northeast, to a metal fence. \
+           There is also a stairway down here";
+          if (self has general)
+           ". There is a large train car sitting on the tracks \
+           to the west.";
+          else ".";
+        ],
+        name "tunnel" "tunnels" "walkway" "stairway",
+        ne_to GurthG_Gate,
+        s_to "A helpful subway worker says ~Hey pal, get outa there!~",
+        n_to "A helpful subway worker says ~Hey pal, get outa there!~",
+        w_to GREENLINE_car,
+        d_to GURTH_GUSPlatform2,
+        in_to GREENLINE_car,
+        before [;
+           Go:
+!              if (noun == ne_obj)
+!                print "You saunter through the apparently open gate.^";
+              if ((self hasnt general) &&
+                  (noun == w_obj or in_obj))
+              "You'd fall onto the tracks if you went that way.";              
+        ],     
+        each_turn [ i ;
+           if (self hasnt general) {
+              i = random(10);
+              if (i==1 or 3) {
+                 give self general;
+                 GREENLINE_loc = 5;            
+                 GREENLINE_dir = 1;    ! will be heading south
+                 "^Suddenly, from the north, a train emerges from \
+                 the tunnel! It pulls to a screeching halt, the \
+                 doors open, and several people rush out and exit \
+                 the station.";
+              }
+              if (i==2 or 4) {
+                 give self general;
+                 GREENLINE_loc = 5;            
+                 GREENLINE_dir = 0;    ! will be heading north
+                 "^Suddenly, from the south, a train emerges from \
+                 the tunnel! It pulls to a screeching halt, the \
+                 doors open, and several people rush out and exit \
+                 the station.";
+              }
+              if (i==9)
+                 "^You hear a distant rumbling noise from the north.";
+              if (i==10) 
+                 "^You hear a distant rumbling noise from the south.";
+           }
+           else {
+              if (self has general) {
+                 if (GREENLINE_loc == 6) {
+                    give self ~general;
+                    "^The train doors close, and the train rolls off."; 
+                 }
+                 else {
+                    GREENLINE_loc = 6;
+                    "^A few people exit the train, and hurry out \
+                    of the station. You hear a voice from inside the \
+                    train say, ~Doors will be closing, please stand \
+                    clear.~";
+                 }
+              }
+           }
+        ],        
+   has light;    
+
+! **************************
+! TRAINS
+! Some notes:
+!     While it may seem more logical to implement the trains with
+!     an 'enterable' property, I decided to implement them as 
+!     'rooms' instead.  Mainly, I did this because:
+!     1) I wanted total control of the "movement" of the train.
+!     2) I wanted to fill the cars with various people/things.
+!     3) I wanted seats on the train :)
+!     Again, this is all probably possible with 'vehicles', I
+!     just saw things slightly differently.
+!     Be warned, the logic in moving the train is probably one
+!     of the more unfathomable things I've ever coded.
+! **************************
+
+! *** The purple line (Eastlands)
+
+Object PURPLELINE_car "Subway car"
+   with description "You are in an underground train car. Various \
+           people fill the train, some in uncomfortable-looking seats.",
+        name "car" "people",
+        w_to FROSTHAM_GUSPlatform,  ! we adjust this, see below
+        out_to FROSTHAM_GUSPlatform,
+        after [;
+         Go:
+          if (noun == e_obj or in_obj) {
+           ! determine boarding location, direction train was
+           ! traveling 
+           give self general; ! we're off and moving...
+           print "^You enter the train car. The doors slam shut behind you.^";
+           if (PURPLELINE_loc == 1 or 2) {
+              ! Frostham, south
+             give FROSTHAM_GUSPlatform ~general;
+             PURPLELINE_loc = 3; ! leaving
+           }
+           if (PURPLELINE_loc == 5 or 6) {
+              ! Aragain
+              ! give ARAGAIN_GUSPlatform ~general;
+              if (PURPLELINE_dir == 1) {
+                 ! South
+                 PURPLELINE_loc = 7;
+              }
+              else {
+                 ! North
+                 PURPLELINE_loc = 4;
+              }
+           }
+           if (PURPLELINE_loc == 9 or 10) {
+              ! Fublio, north
+              ! give FUBLIO_GUSPlatform ~general;
+              PURPLELINE_loc = 8;
+           }
+          }
+        ],
+        before [;
+          Go:
+            if (noun == w_obj or out_obj) {
+               if (self has general)
+                  "The train is moving right now. Better wait til \
+                  it stops to get off.";               
+               if (thug in self)
+                  "As you try to get off, the thug gets in your way. \
+                  ~Going somewhere, Padre?~.";
+            }
+        ],
+        each_turn [;
+          ! check location of train, print appropriate msg, 
+          ! and increment location of train, given direction
+          if (PURPLELINE_loc == 1) {
+            ! reached Frostham, dir = S, not moving
+            give self ~general;
+            give FROSTHAM_GUSPlatform general;
+            PURPLELINE_dir = 1;
+            PURPLELINE_loc = 2;
+            PURPLELINE_car.w_to = FROSTHAM_GUSPlatform;
+            PURPLELINE_car.out_to = FROSTHAM_GUSPlatform;
+            "^The train suddenly lurches to a stop! A voice from \
+            somewhere overhead says ~Frostham station, watch your \
+            step please.~";
+          }
+          if (PURPLELINE_loc == 2) {
+            ! still in Frostham, not moving
+            PURPLELINE_loc = 3;
+            "^A voice overhead says ~Doors will be closing, please \
+             stand clear.~";
+          }
+          if (PURPLELINE_loc == 3) {
+            if (PURPLELINE_dir == 1) {
+               ! moving away from Frostham
+               give self general;
+               give FROSTHAM_GUSPlatform ~general;
+               PURPLELINE_loc = 4;
+               "^The train starts to move, quickly exiting the station \
+               going south.";
+            }
+            if (PURPLELINE_dir == 0) {
+               ! moving towards Frostham
+               PURPLELINE_loc = 1;  ! We will 'arrive' in Frostham next
+               "^The train rumbles as it moves.";
+            }
+          }
+          if (PURPLELINE_loc == 4) {
+            if (PURPLELINE_dir == 0) {
+               ! We're leaving Aragain
+               PURPLELINE_loc = 3;
+               give self general;
+               give ARAGAIN_GUSPlatform ~general;
+               "^The train starts to move, quickly exiting the station \
+               going north.";
+            }
+            if (PURPLELINE_dir == 1) {
+               PURPLELINE_loc = 5; 
+               "^The train rumbles as it moves.";
+            }
+          }
+          if (PURPLELINE_loc == 5) {
+            ! reached Aragain, stop the train
+            give self ~general;
+            give ARAGAIN_GUSPlatform general;
+            PURPLELINE_loc = 6;  ! we'll be stopping for 1 turn
+            PURPLELINE_car.w_to = ARAGAIN_GUSPlatform;
+            PURPLELINE_car.out_to = ARAGAIN_GUSPlatform;
+            "^The train suddenly lurches to a stop! A voice from \
+            somewhere overhead says ~Aragain station, watch your \
+            step please.~";
+          }
+          if (PURPLELINE_loc == 6) {
+            ! about to leave Aragain station
+            if (PURPLELINE_dir == 0) 
+               PURPLELINE_loc = 4;
+            else
+               PURPLELINE_loc = 7;
+            "^A voice overhead says ~Doors will be closing, please \
+             stand clear.~";
+          }
+          if (PURPLELINE_loc == 7) {
+             if (PURPLELINE_dir == 1) {
+               ! We're leaving Aragain
+               PURPLELINE_loc = 8;
+               give self general;
+               give ARAGAIN_GUSPlatform ~general;
+               "^The train starts to move, quickly exiting the station \
+               going south.";
+            }
+            if (PURPLELINE_dir == 0) {
+               PURPLELINE_loc = 5;   ! we will arrive in Aragain shortly...
+               "^The train rumbles as it moves.";
+            }
+          }
+          if (PURPLELINE_loc == 8) {
+            if (PURPLELINE_dir == 0) {
+               ! we're leaving Fublio
+               PURPLELINE_loc = 7;
+               give self general;
+               give FUBLIO_GUSPlatform ~general;
+               "^The train starts to move, quickly exiting the station \
+               going north.";
+            }
+            if (PURPLELINE_dir == 1) {
+               PURPLELINE_loc = 10;  ! will arrive in Fublio (BACKWARDS!!)
+               "^The train rumbles as it moves.";
+            }
+          }
+          if (PURPLELINE_loc == 9) {
+            ! still waiting in Fublio
+            PURPLELINE_loc = 8;
+            "^A voice overhead says ~Doors will be closing, please \
+             stand clear.~";
+          }
+          if (PURPLELINE_loc == 10) {
+            ! arriving in Fublio
+            PURPLELINE_loc = 9;   
+            PURPLELINE_dir = 0; ! north
+            give self ~general;
+            give FUBLIO_GUSPlatform general;
+            PURPLELINE_car.w_to = FUBLIO_GUSPlatform;
+            PURPLELINE_car.out_to = FUBLIO_GUSPlatform;
+            "^The train suddenly lurches to a stop! A voice from \
+            somewhere overhead says ~Fublio station, watch your \
+            step please.~";
+          }
+        ],
+   has light;
+
+Class Train_Car_Seat_Class
+   with name "seat" "seats",
+   description "There seem to be a few seats that haven't been taken.",
+   before [;
+      Enter:
+         if (random(10) < 3)
+            "As you attempt to grab an open seat, someone rudely \
+            beats you to it.";
+   ],
+has scenery enterable;
+
+
+Object PURPLELINE_car_seats "subway seat" PURPLELINE_car
+   class Train_Car_Seat_Class
+   with before [;
+           Search:
+              if (self hasnt general) {
+                 give self general;
+                 move c9 to player;
+                 "Good fortune is your friend! You notice a \
+forgotten coin stuck in a seat crack, and fend off two \
+passengers to grab it.";
+              }
+        ],
+;
+
+
+! *** ORANGE LINE CAR (Gurth to Aragain)
+
+
+Object ORANGELINE_car "Subway car"
+   with description "You are in an underground train car. Various \
+           people fill the train, some in uncomfortable-looking seats.",
+        name "car" "people",
+        n_to ANTHAR_GUSPlatform,  ! we adjust this, see below
+        out_to ANTHAR_GUSPlatform,
+        after [;
+         Go:
+          if (noun == s_obj or in_obj) {
+           ! determine boarding location, direction train was
+           ! traveling 
+           give self general;  ! we're off and moving...
+           print "^You squeeze onto the train car. The doors close behind you.^";
+           if (ORANGELINE_loc == 1 or 2) {
+              ! Gurth, east
+             give GURTH_GUSPlatform2 ~general;
+             ORANGELINE_loc = 3; ! leaving
+           }
+           if (ORANGELINE_loc == 5 or 6) {
+              ! Anthar
+              give ANTHAR_GUSPlatform ~general;
+              if (ORANGELINE_dir == 1) {
+                 ! east
+                 ORANGELINE_loc = 7;
+              }
+              else {
+                 ! west
+                 ORANGELINE_loc = 4;
+              }
+           }
+           if (ORANGELINE_loc == 9 or 10) {
+              ! Aragain, west
+              give ARAGAIN_GUSPlatform2 ~general;
+              ORANGELINE_loc = 8;
+           }
+          }
+        ],
+        before [;
+          Go:
+            if (noun == n_obj or out_obj) {
+               if (self has general)
+                  "The train is moving right now. Better wait til \
+                  it stops to get off.";               
+            }
+        ],
+        each_turn [;
+          ! check location of train, print appropriate msg, 
+          ! and increment location of train, given direction
+          if (ORANGELINE_loc == 1) {
+            ! reached Gurth, dir = S, not moving
+            give self ~general;
+            give GURTH_GUSPlatform2 general;
+            ORANGELINE_dir = 1;
+            ORANGELINE_loc = 2;
+            ORANGELINE_car.n_to = GURTH_GUSPlatform2;
+            ORANGELINE_car.out_to = GURTH_GUSPlatform2;
+            "^The train suddenly lurches to a stop! A voice from \
+            somewhere overhead says ~Gurth City station, watch your \
+            step please.~";
+          }
+          if (ORANGELINE_loc == 2) {
+            ! still in Gurth, not moving
+            ORANGELINE_loc = 3;
+            "^A voice overhead says ~Doors will be closing, please \
+             stand clear.~";
+          }
+          if (ORANGELINE_loc == 3) {
+            if (ORANGELINE_dir == 1) {
+               ! moving away from Gurth
+               give self general;
+               give GURTH_GUSPlatform2 ~general;
+               ORANGELINE_loc = 4;
+               "^The train starts to move, quickly exiting the station \
+               going east.";
+            }
+            if (ORANGELINE_dir == 0) {
+               ! moving towards Gurth
+               ORANGELINE_loc = 1;  ! We will 'arrive' in Gurth next
+               "^The train rumbles as it moves.";
+            }
+          }
+          if (ORANGELINE_loc == 4) {
+            if (ORANGELINE_dir == 0) {
+               ! We're leaving Anthar
+               ORANGELINE_loc = 3;
+               give self general;
+               give ANTHAR_GUSPlatform ~general;
+               "^The train starts to move, quickly exiting the station \
+               going west.";
+            }
+            if (ORANGELINE_dir == 1) {
+               ORANGELINE_loc = 5; 
+               "^The train rumbles as it moves.";
+            }
+          }
+          if (ORANGELINE_loc == 5) {
+            ! reached Anthar, stop the train
+            give self ~general;
+            give ANTHAR_GUSPlatform general;
+            ORANGELINE_loc = 6;  ! we'll be stopping for 1 turn
+            ORANGELINE_car.n_to = ANTHAR_GUSPlatform;
+            ORANGELINE_car.out_to = ANTHAR_GUSPlatform;
+            "^The train suddenly lurches to a stop! A voice from \
+            somewhere overhead says ~Greater Anthar station, watch your \
+            step please.~";
+          }
+          if (ORANGELINE_loc == 6) {
+            ! about to leave Anthar station
+            if (ORANGELINE_dir == 0) 
+               ORANGELINE_loc = 4;
+            else
+               ORANGELINE_loc = 7;
+            "^A voice overhead says ~Doors will be closing, please \
+             stand clear.~";
+          }
+          if (ORANGELINE_loc == 7) {
+             if (ORANGELINE_dir == 1) {
+               ! We're leaving Anthar
+               ORANGELINE_loc = 8;
+               give self general;
+               give ANTHAR_GUSPlatform ~general;
+               "^The train starts to move, quickly exiting the station \
+               going east.";
+            }
+            if (ORANGELINE_dir == 0) {
+               ORANGELINE_loc = 5;   ! we will arrive in anthar shortly...
+               "^The train rumbles as it moves.";
+            }
+          }
+          if (ORANGELINE_loc == 8) {
+            if (ORANGELINE_dir == 0) {
+               ! we're leaving Aragain
+               ORANGELINE_loc = 7;
+               give self general;
+               give ARAGAIN_GUSPlatform2 ~general;
+               "^The train starts to move, quickly exiting the station \
+               going west.";
+            }
+            if (ORANGELINE_dir == 1) {
+               ORANGELINE_loc = 9;  ! will arrive in Aragain
+               "^The train rumbles as it moves.";
+            }
+          }
+          if (ORANGELINE_loc == 10) {
+            ! still waiting in Aragain
+            ORANGELINE_loc = 8;
+            "^A voice overhead says ~Doors will be closing, please \
+             stand clear.~";
+          }
+          if (ORANGELINE_loc == 9) {
+            ! arriving in Aragain
+            ORANGELINE_loc = 10;   
+            ORANGELINE_dir = 0; ! west
+            give self ~general;
+            give ARAGAIN_GUSPlatform2 general;
+            ORANGELINE_car.n_to = ARAGAIN_GUSPlatform2;
+            ORANGELINE_car.out_to = ARAGAIN_GUSPlatform2;
+            "^The train suddenly lurches to a stop! A voice from \
+            somewhere overhead says ~Aragain station, watch your \
+            step please.~";
+          }
+        ],
+   has light;
+
+Object ORANGELINE_car_seats "subway seat" ORANGELINE_car
+   class Train_Car_Seat_Class
+   with before [;
+           Search:
+              if (self hasnt general) {
+                 give self general;
+                 move c10 to player;
+                 "Good fortune is your friend! You notice a \
+forgotten coin stuck in a seat crack, and fend off two \
+passengers to grab it.";
+              }
+        ],
+;
+
+
+! *** GREEN LINE (Borphee to Miznia)
+
+Object GREENLINE_car "Subway car"
+   with description "You are in an underground train car. Various \
+           people fill the train, some in uncomfortable-looking seats.",
+        name "car" "people",
+        e_to BORPHEE_GUSPlatform,  ! we adjust this, see below
+        out_to BORPHEE_GUSPlatform,
+        after [;
+         Go:
+          if (noun == w_obj or in_obj) {
+           ! determine boarding location, direction train was
+           ! traveling 
+           give self general;  ! we're off and moving
+           print "^You shove your way onto train car. The doors close behind you.^";
+           if (GREENLINE_loc == 1 or 2) {
+              ! Borphee, south
+             give BORPHEE_GUSPlatform ~general;
+             GREENLINE_loc = 3; ! leaving
+           }
+           if (GREENLINE_loc == 5 or 6) {
+              ! Gurth
+              give GURTH_GUSPlatform ~general;
+              if (GREENLINE_dir == 1) {
+                 ! South
+                 GREENLINE_loc = 7;
+              }
+              else {
+                 ! North
+                 GREENLINE_loc = 4;
+              }
+           }
+           if (GREENLINE_loc == 9 or 10) {
+              ! Miznia, north
+              give MIZNIA_GUSPlatform ~general;
+              GREENLINE_loc = 8;
+           }
+          }
+        ],
+        before [;
+          Go:
+            if (noun == e_obj or out_obj) {
+               if (self has general)
+                  "The train is moving right now. Better wait til \
+                  it stops to get off.";               
+               if (yupple in self)
+                  "As you try to get off, the yupple jumps up and gets in your \
+                  way. ~Wait, wait, we have so much to talk about!~.";
+            }
+        ],
+        each_turn [;
+          ! check location of train, print appropriate msg, 
+          ! and increment location of train, given direction
+          if (GREENLINE_loc == 1) {
+            ! reached Borphee, dir = S, not moving
+            give self ~general;
+            give BORPHEE_GUSPlatform general;
+            GREENLINE_dir = 1;
+            GREENLINE_loc = 2;
+            GREENLINE_car.e_to = BORPHEE_GUSPlatform;
+            GREENLINE_car.out_to = BORPHEE_GUSPlatform;
+            "^The train suddenly lurches to a stop! A voice from \
+            somewhere overhead says ~New Borphee station, watch your \
+            step please.~";
+          }
+          if (GREENLINE_loc == 2) {
+            ! still in Borphee, not moving
+            GREENLINE_loc = 3;
+            "^A voice overhead says ~Doors will be closing, please \
+             stand clear.~";
+          }
+          if (GREENLINE_loc == 3) {
+            if (GREENLINE_dir == 1) {
+               ! moving away from Borphee
+               give self general;
+               give BORPHEE_GUSPlatform ~general;
+               GREENLINE_loc = 4;
+               "^The train starts to move, quickly exiting the station \
+               going south.";
+            }
+            if (GREENLINE_dir == 0) {
+               ! moving towards BORPHEE
+               GREENLINE_loc = 1;  
+               "^The train rumbles as it moves.";
+            }
+          }
+          if (GREENLINE_loc == 4) {
+            if (GREENLINE_dir == 0) {
+               ! We're leaving gurth
+               GREENLINE_loc = 3;
+               give self general;
+               give GURTH_GUSPlatform ~general;
+               "^The train starts to move, quickly exiting the station \
+               going north.";
+            }
+            if (GREENLINE_dir == 1) {
+               GREENLINE_loc = 5; 
+               "^The train rumbles as it moves.";
+            }
+          }
+          if (GREENLINE_loc == 5) {
+            ! reached Gurth, stop the train
+            give self ~general;
+            give GURTH_GUSPlatform general;
+            GREENLINE_loc = 6;  ! we'll be stopping for 1 turn
+            GREENLINE_car.e_to = GURTH_GUSPlatform;
+            GREENLINE_car.out_to = GURTH_GUSPlatform;
+            "^The train suddenly lurches to a stop! A voice from \
+            somewhere overhead says ~Gurth City station, watch your \
+            step please.~";
+          }
+          if (GREENLINE_loc == 6) {
+            ! about to leave gurth station
+            if (GREENLINE_dir == 0) 
+               GREENLINE_loc = 4;
+            else
+               GREENLINE_loc = 7;
+            "^A voice overhead says ~Doors will be closing, please \
+             stand clear.~";
+          }
+          if (GREENLINE_loc == 7) {
+             if (GREENLINE_dir == 1) {
+               ! We're leaving gurth
+               GREENLINE_loc = 8;
+               give self general;
+               give GURTH_GUSPlatform ~general;
+               "^The train starts to move, quickly exiting the station \
+               going south.";
+            }
+            if (GREENLINE_dir == 0) {
+               GREENLINE_loc = 5;   ! we will arrive in gurth shortly...
+               "^The train rumbles as it moves.";
+            }
+          }
+          if (GREENLINE_loc == 8) {
+            if (GREENLINE_dir == 0) {
+               ! we're leaving Miznia
+               GREENLINE_loc = 7;
+               give self general;
+               give MIZNIA_GUSPlatform ~general;
+               "^The train starts to move, quickly exiting the station \
+               going north.";
+            }
+            if (GREENLINE_dir == 1) {
+               GREENLINE_loc = 9;  
+               "^The train rumbles as it moves.";
+            }
+          }
+          if (GREENLINE_loc == 10) {
+            ! still waiting in Miznia
+            GREENLINE_loc = 8;
+            "^A voice overhead says ~Doors will be closing, please \
+             stand clear.~";
+          }
+          if (GREENLINE_loc == 9) {
+            ! arriving in Miznia
+            GREENLINE_loc = 10;   
+            GREENLINE_dir = 0; ! north
+            give self ~general;
+            give MIZNIA_GUSPlatform general;
+            GREENLINE_car.e_to = MIZNIA_GUSPlatform;
+            GREENLINE_car.out_to = MIZNIA_GUSPlatform;
+            "^The train suddenly lurches to a stop! A voice from \
+            somewhere overhead says ~Miznia station, watch your \
+            step please.~";
+          }
+        ],
+   has light;
+
+Object GREENLINE_car_seats "subway seat" GREENLINE_car
+   class Train_Car_Seat_Class
+   with before [;
+           Search:
+              if (self hasnt general) {
+                 give self general;
+                 move c11 to player;
+                 "Good fortune is your friend! You notice a \
+forgotten coin stuck in a seat crack, and fend off two \
+passengers to grab it.";
+              }
+        ],
+;
+
+
+! *** A fake scenery item, to describe the subway cars from outside ***
+Object subway_car_fake "subway car"
+   with name "car" "train",
+       description [;
+          print "It's a rather large, sleek-looking train car, oddly colored ";
+          if (((location==FROSTHAM_GUSPlatform) && (FROSTHAM_GUSPlatform has general)) ||
+              ((location==ARAGAIN_GUSPlatform) && (ARAGAIN_GUSPlatform has general)) ||
+              ((location==FUBLIO_GUSPlatform) && (FUBLIO_GUSPlatform has general))) 
+             "purple.";
+          if (((location==ANTHAR_GUSPlatform) && (ANTHAR_GUSPlatform has general)) ||
+              ((location==ARAGAIN_GUSPlatform2) && (ARAGAIN_GUSPlatform2 has general)) ||
+              ((location==GURTH_GUSPlatform2) && (GURTH_GUSPlatform2 has general))) 
+             "orange.";
+          if (((location==BORPHEE_GUSPlatform) && (BORPHEE_GUSPlatform has general)) ||
+              ((location==GURTH_GUSPlatform) && (GURTH_GUSPlatform has general)) ||
+              ((location==MIZNIA_GUSPlatform) && (MIZNIA_GUSPlatform has general))) 
+             "green.";
+           "You can't see any such thing.";
+       ],
+   found_in FROSTHAM_GUSPlatform ARAGAIN_GUSPlatform FUBLIO_GUSPlatform
+   ANTHAR_GUSPlatform ARAGAIN_GUSPlatform2 GURTH_GUSPlatform2
+   BORPHEE_GUSPlatform GURTH_GUSPlatform MIZNIA_GUSPlatform,   
+   before [;
+      Enter:
+         "A subway nymph suddenly appears. ~Remember passengers, to \
+         board the subway cars, you just have to go 'in', or in the \
+         appropriate direction of the car. Bye!~";
+   ],
+   has scenery;
+                            
+Object metal_fence "metal fence"
+   with name "fence" "barricade",
+        description "It looks like a smooth metal fence.",
+        before [;
+           Climb, JumpOver: 
+              "A subway worker yells ~Hey pal, no fare-jumpers!";
+        ],
+   found_in FROSTHAM_GUSPlatform ARAGAIN_GUSPlatform FUBLIO_GUSPlatform
+            FROSTHAM_GUSStation ARAGAIN_GUSStation FUBLIO_GUSStation
+   ANTHAR_GUSPlatform BORPHEE_GUSPlatform GURTH_GUSPlatform MIZNIA_GUSPlatform
+   ANTHAR_GUSStation BORPHEE_GUSStation GURTH_GUSStation MIZNIA_GUSStation,   
+   has scenery;            
+   
+
+! **************************
+! People/denizens/creatures
+! **************************
+      
+! Thug, on PURPLE LINE
+Object thug "sinister-looking thug" PURPLELINE_car
+   with name "thug" "hoodlum" "Davey",
+        description "A thug, clearly. Some scrapper with an attitude, \
+          and the desire to use it.",
+        each_turn [ i ;
+           if (self hasnt general) {
+              give self general;
+              "^The sinister-looking thug notices you from the back \
+              of the car, and approaches. ~Well, well, well,~ he \
+              says, ~what do we have here?~.";
+           }
+           i = random(4);
+           if (i==1)
+              "^The thug pokes you in the ribs.";
+           if (i==2)
+              "^The thug snarls at you. ~Hey, I'm talking to you, \
+              Preacher-man.~";
+           if (i==3)
+              "^The thug tries to act friendly, and fails.";
+           if (i==4)
+              "^The thug scowls. ~You gonna tell me the error of \
+              my ways, Padre?~";
+        ],
+        life [;
+           Attack:
+              "As you move to show the rake a lesson, you notice \
+              several more thugs in the background, eyeing your every \
+              move. The thug smiles as you back-off, cautiously.";      
+           default:  "The thug is too busy being sinister.";
+        ],
+        before [;
+           Cast:
+              if (the_spell_was == espnis_spell) {
+                 remove thug;
+                 "You begin to extol the virtues of bedtime prayers, \
+                 and the thug starts to yawn. Soon, his eyes blink \
+                 slowly, and before long, he nods off to sleep! Two \
+                 subway police officers, hiding until now, get up the \
+                 nerve to capture the snoring thug, and drag him \
+                 off, disappearing into the throng of people.";
+              }
+              if (the_spell_was == foblub_spell) {
+                 "You give the thug a timely sermon on the \
+folly of crime in a moral society. He seems momentarily \
+fascinated. Too bad he wasn't actually sitting in anything."; 
+              }
+        ],        
+   has animate;
+        
+! Annoying Yupple, on GREEN LINE (kinda a cross between a yuppie and a yipple)
+Object yupple "annoying yupple" GREENLINE_car
+   with name "yupple" "annoying",
+        description "A young yupple, immaculately dressed in a pinstripe \
+          three-piece suit and tie.",
+        article "an", 
+        each_turn [ i ;
+           if (self hasnt general) {
+              give self general;
+              "^The annoying-looking yupple notices you from the back \
+              of the car, and approaches. ~A priest,~ he \
+              says, ~Just the person I was looking for.~ He \
+              squeezes into a seat near you.";
+           }
+           i = random(4);
+           if (i==1)
+              "^The yupple talks unceasingly about rainfall in some \
+              place called ~the Amazon basin~.";
+           if (i==2)
+              "^The yupple smiles brightly. ~There's so much I have to \
+              talk about!~";
+           if (i==3)
+              "^The yupple drones on about the science behind large \
+              corporate takeovers.";
+           if (i==4)
+              "^The yupple laughs -- a sound somewhat like a snoring \
+              bloodworm. ~So the guy says, 'I thought you meant my _wife_.' \
+              Get it? Wife?~";
+        ],
+        life [;
+           Attack:
+              "Much as you'd like to, that's just something the \
+              Order would probably frown upon.";              
+        ],
+        before [;
+           Cast:
+              if (the_spell_was == espnis_spell) {
+                 "You give a sermon on the dangers of \
+improper bathtub caulking, but the yupple seems quite \
+fascinated. ~That reminds me of...~ You cringe.";
+              }
+              if (the_spell_was == foblub_spell) {
+                 remove self;
+                 "You draw a stunning parallel between corporate \
+morality and monarchy ruling. The yupple's jaw drops. ~I've got \
+to tell my boss that,~ he says, and tries to leave his seat, \
+but finds himself stuck fast. Several passengers nearby \
+take the opportunity to remove the yupple (seat included) to \
+a different part of the train.";
+              }
+        ],        
+   has animate;
+
+
+! **************************
+! misc objects
+! **************************
+
+Object c9 "coin" class coin_class;
+Object c10 "coin" class coin_class;
+Object c11 "coin" class coin_class;
+
+! (Some common objects associated with GUS)
+Object GUS_sign "Sign" 
+   with name "sign" "circular" "pole" "GUS",
+        initial "Standing on a tall pole next to the stairs is \
+                 a circular sign.",
+        description "The sign reads ~GUS~, and has an arrow \
+                     pointing down.",
+        found_in FROSTHAM_GUSStop ARAGAIN_GUSStop ANTHAR_GUSStop
+                 FUBLIO_GUSStop BORPHEE_GUSStop MIZNIA_GUSStop
+                 GURTH_GUSStop,
+   has static;
+
+
+Object GUS_brochure "subway brochure" FROSTHAM_Governer1
+   with name "brochure" "subway" "GUS",
+        description "\
+           ~The Great Underground Subway~^^
+           Adventurers who really need to get where they're going \
+           in a hurry are going to love GUS! The new underground \
+           high-speed rail system can be your personal ride to the \
+           major travel points in Quendor, for just one mere zorkmid! \
+           For Eastland travel to Frostham, Aragain and Fublio Valley, \
+           the Purple line is at your service! For Westland travel \
+           to New Borphee, Gurth City and Miznia, just jump on board \
+           the Green line! And for you folks who need to get across \
+           the Great Sea in a hurry, don't forget the Orange line, \
+           stopping off at Aragain, Anthar and Gurth City! Remember, \
+           there's no costs for transferring between lines either. \
+           So don't delay, take the GUS today!",
+    ! weight 5, 
+    size 10,
+;
+        
+Object newspaper "newspaper" PURPLELINE_car
+   with name "newspaper" "paper",
+        initial "There's a discarded newspaper in a seat nearby.",
+        description "A copy of ~The Fublio Tribune~, with \
+        news, sports and feature sections to read about.",
+        before
+            [ w1; Consult:
+            if (consult_words > 1)
+               "Try reading about 'news', 'sports' or 'features'.";
+            wn = consult_from; w1 = NextWord();
+            switch (w1) {
+               'news', 'headline', 'headlines':
+                  "The news section has three major stories. \
+The headliner is the continued failure to resolve peace in the \
+Kobold war in southern Egreth. Recently, various troops have \
+been cut-off from the main camps by clever kobold raiding groups. \
+^^A second story details the shocking death of a GUE Tech student \
+found in the subway tunnels in Gurth City Station, the apparent \
+victim of a GUS train. ~Don't know how he got in there.~ a \
+subway worker is quoted as saying.^^\
+Finally, a sad local news story about a nice couple in Fublio \
+valley who recently were victims of the kidnaping of their son. No \
+leads as of yet.";
+               'sports':
+               "Apparently, the golem brothers at Flathead \
+Stadium have amassed an amazing 322-0 win streak.";
+               'features', 'feature':
+               "The paper points out that culture seekers \
+should check out the newly discovered Leonardo Flathead \
+painting on exhibit at the Royal Museum.";     
+               'ads', 'classified':
+               "~FOR SALE: A new IF game -- 'SPIRITWRAK'. \
+               Price: $0.00~";
+               'comics', 'funnies':
+               "No comics section. Bummer.";
+               default: "You can't find anything in the paper about that.";             
+            }
+            ],
+        ! weight 15, 
+        size 15,
+;
+
+! **************************
+! spells & scrolls
+! **************************