/*
*   Wizard's Toolkit 1.2 (wizard.t)
*
*   Sometimes, when debugging an adventure,
*   it's useful to have a small set of tools
*   that let you do things the player can't
*   ordinarily do. These shortcuts can be
*   extremely useful in cutting down test
*   time, as they help you skip sections of
*   a game that you know are fine. Here are
*   a few verbs that I've found quite helpful
*   for testing games.
*
*   "Snarf" lets you pick up any takeable
*   object, regardless of whether or not it's
*   visible. "Zarvo" reports on the location
*   of any specified object. "Pow" transports
*   the player directly to any location in the
*   game. And "Mega" and "Unmega" turn the
*   player into a glowing superhuman, or revert
*   the player to normal.
*
*   The easiest thing to do is to incorporate
*   all these bits of code into a separate file,
*   and have that file loaded in by the compiler:
*
*  #include <wizard.t>
*
*   Then, when you've finished your testing and
*   are ready to release your game on an
*   unsuspecting world, you can edit out the
*   link to the debug file and recompile your
*   game.
*
*   Requires TADS compiler 2.1 or higher.
*
*   This code by Neil K. Guy ([email protected])
*   except for v. 1.2 "pow" revisions by Neil
*   deMause ([email protected])
*
*   You may distribute, modify and copy this
*   file as much as you like, but it cannot
*   be bought or sold. Please include this
*   notice and a list of any changes you made
*   if you choose to distribute it.
*
*   Version History:
*
*   Written 2/05/93 Neil K.
*   Revised 9/15/93 Neil K. (version 1.0)
*   Revised 11/11/93 Neil K. (version 1.1)
*   Revised 1/11/96 Neil deMause and Neil K. (version 1.2)
*
*   Version 1.1 fixes a small embarrassing bug in the pow verb.
*   Version 1.2 allows "powing" without giving noun properties
*   to all your locations, and expands "mega" to apply to all actors.
*
*/


/*
*   snarfVerb
*
*   This verb lets you pick up any takeable
*   item, even if it's not accessible to you -
*   say it's in a different room or inside a
*   closed container or whatever.
*
*   I gave it the silly name "snarf" as "snarf"
*   is not a verb I'm likely to use in the actual
*   game for anything. You can, of course,
*   change this to something more serious.
*
*   Essentially all this verb does is call the
*   standard takeVerb for the object in question.
*   The reason I have it do that instead of, say,
*   moving the object directly into the player's
*   inventory is because this way I can rely on
*   the standard take verb checks to ensure that
*   the player isn't trying to pick up a fixed or
*   floating object or whatever. It also means
*   that the player can't pick up more items than
*   he or she normally can. (unless the "mega"
*   verb has been used; see below.)
*
*   However "snarf" differs from the normal take
*   verb in that instead of checking to see if
*   the object in question is reachable or not
*   it simply lets you take any object that's
*   anywhere in the game. It does this by
*   overriding the "validDo" method.
*
*   The validDoList feature was added to
*   version 2.0.8 of TADS to help speed up
*   disambiguation in some circumstances.
*   Check out the TADSVER file that came
*   with TADS to learn more.
*
*/

snarfVerb: deepverb
 verb = 'snarf'
 sdesc = "snarf"
 doAction = 'Take'
     // Call the normal take method.
 validDo( actor, obj, seqno ) = { return( true ); }
     // Any object is valid, even if it's not visible.
 validDoList = nil
;


/*
*   zarvoVerb
*
*   Another useful verb with a silly name.
*   Zarvo lets you find an object anywhere
*   in the game without touching it. Zarvoing
*   an object simply prints that object's
*   current location's sdesc.
*
*   In order to do its magic, zarvo needs to
*   add a couple of methods to the standard
*   "thing" object. It does so through use of
*   the "modify" feature added in version
*   2.1 of TADS. Consult the TADSVER file
*   that came with TADS for more information
*   on this feature.
*
*   The new zarvo methods simply print
*   where the object can be found. However
*   it's necessary to do a verDoZarvo first
*   as some objects (floating objects, or
*   objects in the never-never land of
*   "location = nil") do not have a location
*   and thus no location sdesc. Trying to
*   print an non-existent sdesc would
*   result in a runtime error.
*
*/

zarvoVerb: deepverb
 verb = 'zarvo' 'v'
 sdesc = "zarvo"
 doAction = 'Zarvo'
 validDo( actor, obj, seqno ) = { return( true ); }
 validDoList = nil
;

modify thing
 verDoZarvo( actor ) =
 {
   if ( self.location = nil or isclass( self, floatingItem ) )
   {
     "I'm afraid you can't zarvo "; self.thedesc;
     " because, for obscure technical reasons,
     that object isn't anywhere in particular. ";
   }
      // Objects with nil locations and floaters aren't eligible.
 }
 doZarvo( actor ) =
 {
   caps(); self.thedesc;
   " can be found in the location called \"";
   self.location.sdesc; ".\" ";
 }
;


/*
*
*   powVerb.
*
*   This is a particularly useful verb when
*   testing that zaps you directly to a
*   specific location as though you'd
*   teleported there. Saves a lot of walking
*   around. To use it simply add type "pow"
*   followed by the location to which you
*   wish to pow. Like the snarf verb, we
*   modify the validDo method so that any
*   room can be chosen - even if it's not
*   visible from the current location.
*
*   We modify the "thing" object, however, to
*   ensure that the player doesn't try to
*   pow to a non-location object, such as a
*   glass of water or a solid brick wall. We
*   also modify the "room" object so that the
*   now-standard verDoPow method (inherited
*   from the thing object) is overridden.
*
*   Finally we add a doPow method to the room
*   object. We also do a quick check to make
*   sure that the player isn't seated - if
*   so, we get 'em to stand up or get out
*   first to avoid problems. Then we transport
*   them directly to the chosen location. In
*   homage to the classic "Adventure" we
*   surround the player with a nice orange
*   cloud of smoke.
*
*   There's one more time-consuming thing that
*   you, as implementor, have to do to get this
*   all to work. And that is you have to assign
*   appropriate nouns and adjectives to each
*   room you want to be powable. If you don't
*   then all this coding will be in vain, as
*   none of the rooms can be referred to by the
*   player!

*
*   [NOTE: For version 1.2, I changed the "modify
*   thing" code so that typing "pow item" for non-
*   room objects will now take you to that object's
*   location. This means that you can now "pow" to
*   any room with at least one object in it, even if
*   you haven't taken the step of assigning nouns
*   to your rooms. -Neil deMause]
*
*   There has been one small change in this code
*   from version 1.0 of wizard.t to version 1.1.
*   The earlier version modified the game state
*   by making the player stand up in the verDoPow
*   method for a room. This is *not* a good idea.
*   In fact it's a particularly bad idea.
*
*   I'm not sure how it slipped in, to be honest,
*   since I know one should never change the game
*   state in verb verify methods. Really! Not only
*   is it bad form but it can end up with undesirable
*   side effects as the parser (and theoretically
*   any adv.t routine that wants to) silently calls
*   the verify method. Any change in game state
*   could thus be triggered unintentionally.
*
*   Thanks to Lars Joedal for pointing out this
*   particularly heinous coding crime!
*
*/

powVerb: deepverb
 verb = 'pow'
 sdesc = "pow"
 doAction = 'Pow'
 validDo( actor, obj, seqno ) = { return( true ); }
 validDoList( actor, prep, dobj ) = { return( true ); }
;

modify thing
 verDoPow( actor ) = {}
       doPow(actor) =
       {
       if (self.location) self.location.doPow(actor);
       // refer non-room items to their locations
       else "That isn't anywhere!";
       }
;

modify room
 verDoPow( actor ) = {}
 doPow( actor ) =
 {
   if ( actor.location.location )
   {
     actor.location.doUnboard( actor );
   }
   // Make player stand up if seated.

   "%You% %are% engulfed in a cloud of orange smoke.
   Coughing and gasping, %you% emerge%s% from the smoke
   and find that %your% surroundings have changed... \b";

   actor.travelTo( self );
 }
;


/*
*
*   megaVerb and unMegaVerb.
*
*   Sometimes in a game you need to pick up
*   and carry a whole plethora of items, as the
*   standard definition for the "Me" object has
*   set limits as to the number of objects (maxbulk)
*   and the total weight of objects (maxweight)
*   the player can carry. This is obviously important
*   from both a realism standpoint and also a puzzle-
*   making one. However it can be a total pain in
*   in the neck when testing.
*
*   One of the features of the mega verb is that
*   it increases the strength and carrying ability
*   of the player to superhuman levels. Use the
*   unmega command to restore the player to
*   his or her normal abilities.
*
*   The other feature of the verb involves dark rooms.
*   Sometimes when playing it's a hassle to have to
*   carry a torch or other light source all the time.
*   However, through the miracle of the mega verb,
*   the player can set him or herself literally
*   glowing, thereby obviating the light source problem.
*   People who've played any of the Infocom fantasies
*   will recognize this as a kind of "frotz me" command.
*   Again, unmega makes the player normal once more.
*
*   Since the preinit() function in std.t compiles a
*   list of all possible light-providing objects in the
*   game, it's necessary to modify the movableActor
*   object (the most basic actor; all actors inherit
*   properties from movableActor) and set the islamp
*   property to true. Then, to set the actor actually
*   alight, it's necessary to set the islit property
*   to true, which is precisely what the megaVerb does.
*
*/

megaVerb: sysverb
 verb = 'mega'
 sdesc = "mega"
 action( actor ) =
 {
   if ( actor.maxbulk = 100 )
   {
     "%You\'re% already imbued with superhuman abilities! ";
         // simple check to see if the player's already mega.
   }
   else
   {
     "Phreeeow! %You% suddenly %have% superhuman strength,
     and %you\'re% surrounded by a strange ethereal glow
     which permits %you% to enter darkened places with
     impunity! ";
     actor.oldbulk := actor.maxbulk;
     actor.maxbulk := 100;
         // Ten times normal carrying ability.
     actor.oldweight := actor.maxweight;
     actor.maxweight := 100;
         // Ten times normal weight carrying ability.
     actor.islit := true;
         // ...and let there be light!
   }
 }
;

unMegaVerb: sysverb
 verb = 'unmega'
 sdesc = "unmega"
 action( actor ) =
 {
   if ( actor.maxbulk = actor.oldbulk or actor.oldbulk = 0 )
   {
     "%You\'re% already a mere mortal! ";
   }
   else
   {
     "Phreeeow! %You\'re% a puny human once more! %You\'re%
     also no longer doing that human lightbulb thing. ";
     actor.maxbulk := actor.oldbulk;
     actor.maxweight := actor.oldweight;
     actor.islit := nil;
   }
 }
;

modify movableActor
       islamp = true
       // Turn all actors into lamps!
;