
/*
 *   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 (tela@tela.bc.ca)
 *   except for v. 1.2 "pow" revisions by Neil 
 *   deMause (neild@echonyc.com)
 *
 *   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!
;

