
    The Pianosa Reference
    Version 1.0
    (c) 1999-2000 John McCall (TenthStone)
    tenthstone@hotmail.com

    Warning: this is a reference, not a primer.  Any attempt to learn
    Pianosa should be accompanied by a copy of the library and any
    Pianosa source code that happens to exist.  Any attempt to learn
    TADS directly with Pianosa is unadvisable at this time.


    Introduction

I suppose anyone reading this paragraph is wondering why I wrote an
alternate library for TADS.  Well, here goes an attempt to explain.

My problem with adv.t is that too often I find myself fighting against
the library, trying to get some basic effect but lacking any good tools
to that end.  I don't mind hacking a library -- my work in progress
has required me to modify Pianosa a good bit, and the more generally
useful of those modifications, like doorwayframe, I've permanently
placed in the library.  But my old adv.t sources were riddled with
hacks and out-and-out replacements -- and that's where I draw the line,
when it's no longer worthwhile to keep patching the old system.

My problem with WorldClass is that I can't figure out how to extend it.
The library tends to work via long, complicated procedures without
any escape hatches;  the fact that it works on a higher level than adv.t
serves only to make the inevitable adjustments that much more difficult
to handle -- see, for example, the monstrosity that is listcontentsX.

I haven't looked very hard at Kevin Forchione's Alt library yet, although
that's something I've been meaning to do.  (Pianosa predated the
unification of Alt by a few months; since then, I've had three major
IF projects (Pianosa, Finch (a library for TADS3), and my work-in-progress
(WIP)), so my IF programming time has been mostly devoted to those).



Why should someone convert to Pianosa?  They shouldn't.  Unless their
work is still far from complete (programming-wise, not writing-wise),
or unless they're absolutely frustrated in their current library, it's
not really worth the effort to actually convert a work in progress.

Why should someone use Pianosa?  Because it's a hacker's library.  Because
I've painstakingly opened as many processes as I could think of to easy
adjustment.  Because it is my hope that that person never need to wage war
against the library again.

Because it's a powerful library, with a large number of features and
options that can fiddle down to the smallest technicality.  Because it's
a simple library, with very few direct requirements if one's willing to
accept the defaults.  Because moving from one extreme towards the other has
been made as painless as I think it can be without sacrificing some of
the power underneath.

Because it's an intelligent library, with a large amount of code devoted
to avoiding unnecessary duplication, while preserving the capability of
fine dinstinctions.

Because it's a creative library, engineered to make it as easy as possible
to write the damn game and stop fiddling with the controls already.

Because it's here.  Because it's good.  Because it's time.



Past, present, future.  What will come of Pianosa in the age of TADS 3?
That's a good question, and the answer depends largely upon whether
TADS 3 becomes widely accepted in the IF community.  I'm not going to
stop supporting it regardless, but if TADS 3 catches on I doubt many
will spend much time on an alternative library for an outmoded old system.

That's all I've got to say about that.

                                        -- TenthStone
                                           Pittsburgh 8-28-2000


    Table of Contents

    Searching this document for the text in the first column should browse
    instantly to that section of the reference.

  Chapter 1     Quick Start
    1.0.            The very quick start
    1.1.            The quick start
  Chapter 2     TADS Programming (not found)
  Chapter 3     The Pianosa Classes
    3.1.0.          thing
    3.1.1.          room
    3.1.2.          container, cover, mask, surface
    3.1.2.3.0.      movableActor
    3.1.3.          other gameworld classes
    3.1.3.12.       Verb
    3.2.            Pianosa defined objects
    3.3.            Inheritance hierarchy
  Chapter 4     The Pianosa Functions
    4.1.            Pianosa defined functions
    4.2.            General functions
    4.3.            External functions
  Chapter 5     The Pianosa Procedures (not found)
  Chapter 6     Supplemental Files
    6.1.            ts_codes.t
    6.2.            ts_funcs.t
    6.3.            ts_grid.t
    6.4.            ts_menu.t
    6.5.            ts_sense.t
    6.6.            ts_std.t


    Chapter 1
    Quick Start


1.0.  The very quick start

I'm going to assume you know how to compile a file, so open ts_basic.t
and compile it.  It should work -- that's all it takes.

And that's the very quick start.

Note that our pathetically bare game is already close to 100KB even
when compiled without debugging symbols.  We'd better add something
to it to make it worthwhile, since all we've got in the world is
a default description which doesn't even make sense.

I'll take you through a quick sample game, but understand this:
the majority of adv.t-designed code will still work in Pianosa, and
most of what doesn't work will work with a quick name-change.  adv.t
method is very sound there, and I've taken care not to disturb it.
Where Pianosa has a marked difference, and where changing libraries
will be hardest, is advanced code, where you're not merely defining
something but where you're trying to achieve something.  That's not
the sort of problem I can guide you through in this kind of reference.
You should first look at the appropriate class's entry here; if the
information you need isn't there, check its superclass(es); if you
still need help, please feel free to contact me at tenthstone@hotmail.com
or better yet, on the newsgroup rec.arts.int-fiction (remember to
put [TADS][Pianosa] in the subject line).  I'm always open to
suggestions, and I always give credit when I remember to.

Anyway, on to the sample game.


1.1.  The quick start

Let's look at what we've got in here already.  #including ts_std.t
gives us Pianosa and the standard definitions package.  version holds
information about the game;  commence() prints startup messages;
startroom is the room we're in.

First, let's annoy all the auteurs and pick our title before we write
our game.  How about, "The House of Locked Doors".  It's nicely
mysterious, yet kitschy enough to qualify for a programming reference.
Besides, I've changed it anyway;  it used to be "The Hidden Button."

Looking up the version object in this reference (try searching for
"version:"), we find that version.sdesc holds the name of the work.
Filling in a little, we have

version: object
    sdesc = "<b>Is Road Like Wish So Empty?</b>"
    bdesc = "<< sdesc >>, unrelease 1 (5 September, 2000)"
    ldesc = "<< sdesc >>
        \nAn interactive English in Three and Twenty Easy Steps for
        native Ashwen speakers, copyright (c) A.D. 2000.
        \n<< versionVerb.ldesc >>"
;

Now we need a commence() function.  Searching here for it gives us one
reference:  it's called by init().  In fact, commence() is responsible for
all the introductory text printed by the game except for the initial
room description (and if you're using random numbers, you might want to
throw in a randomize() call as well).

commence: function {
    "\H+\b
    \bOh by the village winds, there he goes again.  Rising over the
    walls of the night's camp is another of his damned green bubbles.
    Some little girl from the nearby town -- Brinson-on-Gere, is it? --
    comes out to look after the flocks, and Faraj the Great has to
    show off his little magic tricks.
    \bAh, but as long as it amuses the children, you ought not to
    complain.  There's precious little to cheer one in an age like
    this.  You smile softly to yourself, lean on your sword, and
    dream of your own family, safe far from these troubled borderlands.
    \b<q>Wipe that insipid grin off your face, Brac.<q> That sharp crack
    could only be Mirane's voice, and you open your eyes.  There she is
    again, the newest member of your party, only an hour after she left
    to check on the road ahead.
    \bYou look in Mirane's eyes and see no anxiety; the road, then, must
    be clear.  But why has she returned so quickly?  Her smile is a trace
    more smug than usual;  perhaps she's found something interesting.
    You search for a subtle way to coax the information out while still
    allowing her her moment in the sun -- and then you've got it, you
    know exactly what to say, you open your mouth, and you say,
    \b<q>Is road like wish so empty?<q>
    \b
    \b
    \b<< version.ldesc >>
    \b
    \b
    \b";
}

Now on to the third required entry, startroom.  In fact, the code requiring
startroom is in std.t, so if we were working directly with Pianosa, we
wouldn't need startroom at all.  But that's all irrelevent.

Technically speaking, we could use .roomdesc and .statusdesc instead of
.ldesc and .sdesc, respectively;  however, I've gotten into the habit of
using the adv.t conventions, and I only use the Pianosa equivalents
when there's a need to differentiate between the two, as in when the
room object is a physical world object (e.g. a vehicle).

startroom: room
    sdesc = "
    BOOKMARK:  The example game here is not complete
;

    Chapter 3
    The Pianosa Classes


The core of any TADS library is its classes.  I could go on and explain why,
but there's really no point so I won't, subject to later revisions of this
paragraph.

In Pianosa, there are five core classes, representing the five core groups
of gameworld ideas.  A thing is a basic inanimate object.  A container class
object is to meant to hold other objects.  A character can perform actions.
A room is meant to hold characters.  Actions define the player's interface
with the gameworld.  This categorisation will never be mentioned again.
There will be no test.

Partially because of this idea of core classes, but mostly because it makes
organisation simpler, the library is not ordered purely by inheritance and
alphabetisation.  There are three general sets -- thing-derived,
container-class-derived, and other-base-classes.


3.1.    Class reference.
3.1.0.  thing

class thing: object

thing is the central class to the adv.t archiecture, from which Pianosa
derives.  Every phsyical object in the gameworld inherits from thing. It
is therefore somewhat appropriate that most of our time will be spent with
thing.  Other classes which may inherit much, if not all, of their behavior
from thing have properties more specific to themselves described in their
entries.

There is probably no reason to inherit directly from thing in actual game
code, although there's certainly no reason not to.  Movable objects which
can be picked up and carried with the player should be defined as item;
other objects are as like to be fixedthing or a more specific class.

Attributes
.adesc      Displays the name of self preceded by the indefinite article.
            Defined.
.adjective  Vocabulary attribute; should be an unbracketed list of single
            quoted strings. 
.bdesc      Displays a brief description of objects listed seperately
            (see .describealone).  Defined, but better redefined.
.behind     Defines the location of self.  Only one of the following
            properties is applicable at any one time;  priority is in the
            following order: .in, .on, .under, .behind, etc.  Should
            point to a valid container class object.  These properties
            are not updated after preinitialization.
.bulk       Defines the bulk (size) of an object.  Container-class objects
            can set maximum bulks which they can carry.
.cdesc      Displays a cursory description of an object when it is picked
            up (via a "take" or "put in/on/etc." command).  Returns true
            to abort the pick-up.
.circularmessage( object )  Displays a message forbidding a circular object
            scenario (where A is in B which is in A, or even more complex);
            called on the object being moved.
.dart       Displays the correct definite article.  Defined by .isproper.
.describealone  Defines whether self should be listed alone instead of in
            a standard inventory.  If so, .bdesc is called after the
            standard inventory is concluded.
.Dropped( actor )   Displays a message saying that self has been
            successfully dropped by actor.
.followlist     List of all objects which should be sent a follow message
            when this object moves by .moveInto.
.grammarperson  Determines which grammatical "person" this object should
            be conjugated by; used in association with .isplural.  Defined
            as THIRD_PERSON; other options are FIRST_PERSON, SECOND_PERSON.
.iart       Displays the correct indefinite article.  Defined by .isproper
            and .isThem.
.idesc      Displays the name of self as for an inventory listing, with
            .specialdesc appended.  Defined.
.in         See .behind.
.isdesc     Displays self's .sdesc followed by a conjugated form of to be.
            Defined.
.isfixed    Flag determining whether self is fixed or not.  If it is,
            .putInto checks with .Fail before continuing.
.isfollowable   Flag determining whether self can be followed or not;
            referenced only by the doFollow routine itself, and not by the
            actual following routines.
.isher      Flag allowing this object to be referred to as "her".
.ishidden   Flag for an object which should not be listed until it is taken
            by an actor.
.ishim      Flag allowing this object to be referred to as "him".
.ispasttense    Flag marking whether verbs conjugated with self as subject
            should be placed in the past tense or not.  Defined as
            parserGetMe().ispasttense.
.isplural   Flag marking whether verbs conjugated with self as subject
            should be placed in one of the plural forms.
.isproper   Flag marking whether self's .sdesc is a proper noun.
.istaken    Flag marking whether self has been taken by the player as of yet.
            Objects getting their .istaken attribute set true also have the
            .FirstTake message called.
.isthem     Flag allowing this object to be referred to as "them".  Defined
            as self.isplural.
.ldesc      Displays a long description of the object, as displayed when
            examined.  Defined, but better redefined.
.locdesc    Displays a description of self's location.
            Defined as self.locate.posdesc( self.position ).
.Movearound     Displays a message stating what happens when the object is
            moved (e.g. north).  An error message, not a handling method.
.multisdesc     Displays the name of self as it should appear before the
            colon when multiple objects are referenced in one command.
            Defined as .sdesc.  Once a parser mainstay, now only used as
            referenced by .prefixdesc. Example:
                >Take all.
                red hat: Taken.
                blue scarf: Taken.
.noun       Vocabulary attribute; should be an unbracketed list of single
            quoted strings.
.objcount   Defines the number of objects referenced by self.  Roughly defined
            such that if .isThem is true, .objcount is more than one.
            Otherwise, one.  Such is sufficient.
.on         See .behind.
.plural     Vocabulary attribute; should be an unbracketed list of single
            quoted strings. .plural allows groups of objects to be referred
            to at once; it should consist of plural nouns which can then be
            used in this fashion.
.pluraldesc     Displays a plural form of .sdesc by appending .pluralizer.
            Defined.
.pluralidesc    Displays a plural form of .idesc.  Defined.
.pluralizer     Displays what to add to self's .sdesc to make it plural.
            Defined as "s" when self isn't already plural.
.predthedesc    Displays a short description of self, considering that
            it is a predicate object in some sentence. Defined as .thedesc.
.prefixdesc     Displays a short description of self before executing it in
            a multiple-object command.  Defaults to .sdesc.
.Put( actor, position, object )     Displays a message stating that the object
            has been successfully put in a position around object; called by
            the doPutX routines.
.readdesc   Displays what can be seen when self is read (although verDoRead
            must be cleared)
.sdesc      Displays a short description of the object, i.e. a noun phrase
            without article.
.specialdesc    Displays additional information on self to be included in
            a standard inventory.  Defined for clothing and lamps.
.subjthedesc    Displays a short description of self, considering that it
            is the subject of some sentence (should be lowercase). Defined
            as .thedesc.
.Taken( actor ) Displays a message stating that the object has been succesfully
            taken by actor.
.thatdesc   Displays a reference to self as an indefinite pronoun
            (`that'/'those' ).  Defined.
.thedesc    Displays the name of self preceded by the definite article.
            Defined.
.thrudesc   Displays what can seen when self is looked through.
.uberlocate     List determining the location of self, in the form
            [ position object ].
.under      See .behind.
.isdesc     Displays self's .sdesc followed by a conjugated form of to be,
            but in the past tense. Defined.
.weight     Defines the weight of an object.  Container-class objects can set
            maximum weights which they can carry.

Methods
.addadjective( word )
    Adds a word (or list of words) to self's set of adjectives.  Words should
    be single quoted strings.
.addnoun( word )
    Adds a word (or list of words) to self's set of nouns.  Words should be
    single quoted strings.
.addplural( word )
    Adds a word (or list of words) to self's set of plurals.  Words should be
    single quoted strings.
.cantreach( actor )
    Displays a message stating that while self is visible, it is not reachable.
.checkdrop
    Checks with the object to see if anything special should be done before
    the object is moved.  For instance, clothing should be taken off.  It is
    usually called by direct-object movement routines such as .doPutIn and
    .doDrop, but it is not called by .putInto.
.clearloc
    Resets .uberlocate to [ nil nil ].
.deladjective( word )
    Removes a word (or list of words) from self's set of adjectives.  Words
    should be single quoted strings.
.delnoun( word )
    Removes a word (or list of words) from self's set of nouns.  Words should
    be single quoted strings.
.delplural( word )
    Removes a word (or list of words) from self's set of plurals.  Words should
    be single quoted strings.
.distinguish( object )
    Returns whether self can be distinguished from object.  Called by
    contListing(), which considers two items indistinguishable only if
    .isequivalent is true on both and both .distinguish routines return nil.
    By default, calls isIndistinguishable().
.Fail
    Checks whether a fixed object (.isfixed = true) can be moved; if it cannot,
    should display a message and return true.
.Follow( object, destination, position )
    Displays statement that self is following object into a certain position
    around destination.
.hasclass( class )
    Determines whether self has a certain class or not.  I never can remember
    whether it's isclass( object, class ) (it is) or the other way around.
.isaddressable( actor )
    Determines whether self is addressable by actor.  Defaults to .isVisible.
.isheldbyactor
    Determines whether self is being ultimately held by an actor or not.
.isin( object {, position} )
    Determines whether self is located, but not necessarily visible, around
    an object.  If a position is given, either self or some ultimate container
    of self must be held in that position around object.  Compare .isvisiblyin.
.islisted
    Determines whether self should be listed in the standard inventory or not.
.isreachable( actor )
    Determines whether self is reachable by actor.
.isvisible( vantage )
    Determines whether self is visible from vantage.
.isvisiblyin( object {, position} )
    Determines whether self is visible around an object.  If a position is
    given, either self or some ultimate container of self must be held in that
    position around object.  Compare .isin.
.Leaving( actor )
    Message sent to self when actor leaves a room.  Returns true to be removed
    from .leavelist.
.locate
    Determines the location of self.
.locatetree
    Determines the location tree of self, in form [ self, self.position,
    self.locate, self.locate.position, self.locate.locate, ... ].  Recursive.
.Move( target )
    Message sent to self by .putInto to verify movement to target.  Returns
    true to abort movement.
.position
    Determines the position of self relative to .locate.
.sameloc( object )
    Determines whether self is in the same location and position as object.
.Say( actor )
    Displays how actor would refer to self.
.totalweight
    Determines the total weight of this object and all of its contents.
.totalbulk
    Determines the total bulk of this object and all of its contents.
.ultimatelocate
    Determines the ultimate (typically, ultimate visible) location of self.
.verifyremove( actor )
    Verification routine which calls .verGrab all the way up the contents tree
    until it reaches either the actor or nil.  Called by direct-object movement
    verification routines.

Actions
.dropFrom( object {, position {, jostle}} )
    Drops self from a certain object and position (default = In) according to
    .dropping.
.follow( object, desitination {, position} )
    Causes self to follow object into a position (default = In) around
    destination if possible.
.forceInto( object {, position } )
    Moves self into a certain position (default = In) around object (or nil)
    by calling .forceRelease on self's location (if exists) and .forceAccept
    on the target (if exists).
.hearNoise( type )
    Responds to a sound of a certain type.
.jostle( jostle )
    Jostles this object and everything in it.  By default, runs through the
    contents calling the same level of jostle.
.listen( sound, specificity )
    Responds to a speech-sound of a certain type, either directed at self or
    not.
.mixWith( list )
    Mixes self with every object in the list.  Should return true if it moves
    any of the objects.
.moveInto( object {, position} )
    Moves self into a certain position (default = In) around object (or nil),
    first notifying containers via .Grab messages and followers via .follow
    messages and then calling .forceInto.
.putInto( target {, position {, jostle }} )
    Moves self into a certain position (default = In) around object, verifying
    the movement with self (see .routePutInto) and the target (see
    .routebehind), checking for weight and bulk overload, and then one last
    time checking with the source (see .Drop), self (see .Move), jostling
    effects (see .jostle), and the target (see .Take) before calling .moveInto.
    Returns true upon a routing halt or completion; returns nil for failure.
.routePutInto( target, position, jostle )
    Routes wheres self, being put into a certain position around target,
    should really go.  If it should abort the movement, this should return
    true.
.sayTo( actor, sound, specificity )
    Responds to a speech-sound of a certain type, either directed at self or
    not, usually by calling .listen.
.speak( sound )
    Displays a message on how self would cause sound to be emitted.  Returns
    true to abort.

- thing subclasses


3.1.0.0.  dialthing

class dialthing: thing

dialthings are gameworld objects which happen to have dials upon them which
can be set anywhere from .minsetting to .maxsetting, or to strings
corresponding to labels upon the dial.  Unlike most other subclasses,
dialthing supplies its own .ldesc supplying information on the dial's
settings.

Attributes
.maxsetting     Number of the maximum setting on the dial.
.minsetting     Number of the minimum setting on the dial.
.setting    Number of the current setting on the dial.
.settings   List of valid labels on the dial.
.settingsvalues     List of valid settings on the dial corresponding to
            entries in .settings.
.settingsonly   Flag determining whether numbers can be used for the dial
            (nil).  Defaults to nil.

Methods
.validsetting( number_or_string )
    Determines whether the given setting is valid on the dial.


3.1.0.1.  fixedthing

class fixedthing: thing

fixedthings are gameworld objects which happen to be fixed (perhaps
temporarily) within a location.  The default behaviour has .isfixed set true
and .Fail set to return true -- aborting any attempt at movement.

fixedthings are typically important enough to warrant their own
descriptions, so .describealone is set to true.  If tied to a room, they
would also usually be described in the room's description -- so .ishidden
is set true as well to suppress the individual description.

-- fixedthing subclasses


3.1.0.1.0.  buttonthing

class buttonthing: fixedthing

buttonthings are fixed gameworld objects which may be pushed.  By default,
pushing the button toggles .isactive on and off.

Attributes
.isactive   Flag determining whether self is on or off.  Defaults to
            nil (off).
.routebutton    Object to modify the .isactive properties for.  Defaults
            to nil, meaning self.


Actions
.turnOn
    Sets .isactive true and displays a message.
.turnOff
    Sets .isactive nil and displays a message.


3.1.0.1.1.  decoration

class decoration: fixedthing

decorations are fixed gameworld objects which may be examined and nothing
else.  To add another possible action, adding the appropriate verification
routine to the object definition will let it pass through -- but really,
adding other actions is not advisable as seasoned IF players have grown
accustomed to not being able to do anything at all to a decorative object.
While decorations should be added for every object listed in or implied
by the room description, it is often a nice touch to define such objects
as real gameworld objects that may be fairly interacted with.  Any object
of any importance at all should definitely not be declared a decoration.
You've been warned.

Attribute
.Error      Message to the effect that this object is not important. 


3.1.0.1.2.  distantthing

class distantthing: fixedthing

distantthings are gameworld objects that are not really present in this
room, but instead are simply visible from here.  Any attempt at interaction
with the object fails.

Attribute 
.Error      Message to the effect that self is too far away to be dealt
            with like that.


3.1.0.2.  foodthing

class foodthing: thing

foodthings are gameworld objects which happen to be edible.

Attributes
.Eat        Displays message upon consumption.  Returning true aborts the
            action.
.foodvalue  Number specifying how many extra turns the player can last on
            the basis of self. 
.meal       Number specifying how many meals can be made of self. 


3.1.0.3.  item

class item: thing

items are normal gameworld objects which can be moved around at ease. There
is no special code within the class definition; in fact, there is no code
whatsoever.  item is a marker class.

-- item subclasses


3.1.0.3.0.  clothingitem

class clothingitem: item

clothingitems are normal gameworld objects which can be worn by an actor.
The act of wearing is summed up like this: self is held by the wearer
and .isworn is true.

Attribute
.isworn     Flag determining whether the object is being worn or not.
            Defaults nil.

Actions
.remove
    Removes self by setting .isworn nil.
.wear
    Wears self by setting .isworn true.


3.1.0.3.1.  keyitem

class keyitem: item

keyitems are gameworld objects which can be carried around and used to
unlock things.  What they can unlock is not up to the key: it's up to the
door, or the chest, or whatever.  keyitem is an enabler class, simply
defining the verb actions and leaving all the work to the door. 


3.1.0.4.  lightsource

class lightsource: thing

lightsources are gameworld objects which can supply light to a darkened room.
The class supplies code in the .doTurnon routine for turning on the lights,
but that is all.

Attributes
.isactive   Flag determining whether the light is on or not.
.islamp     Flag determining whether the object is a lamp.  All objects with
            this attribute set true at preinit() are assembled into
            global.lampList.
.islit      Alias to .isactive.


3.1.0.5.  liquid

class liquid: thing

liquids are gameworld objects which are liquid in nature.  They can be poured
onto random objects, mixed with other liquids, and spilled if the player
isn't careful.  They can (as defined in Pianosa) be put only in
liquidcontainers.  For all these reasons, liquids can be a pain to put in IF.

Ofttimes, liquid objects can simply be instances of a type of liquid. This
type is defined in an object called the liquidclass which contains rules about
how the liquid functions; for single instances, this object should probably
just be the object itself.

Attributes
.isliquid   Flag declaring for all the world to know that this is, indeed,
            a liquid.
.liquidtype     Determines the liquidclass for self.

Actions
.mixWith( list )
    Mixes self with every object on the list.  Reduces each object to its
    liquidclass, if applicable, and calls .mix on the liquidclass.  Returns
    true if the contents are altered.
.mix( instance, reactant_liquidclass, reactant )
    Mixes self with a reactant.  Should return true if contents are altered.
.spill( jostlelevel )
    Causes self to spill out of its container and by default disappear.


3.1.0.6.  readable

class readable: thing

readables are gameworld objects which happen to be readable.  All this class
does is overwrite thing's verDoRead definition.  The text can be put in
.readdesc.


3.1.0.7.  switchablething

class switchablething: thing

switchablethings are gameworld objects which happen to be turnable on and
off.  They can also be switched (toggled).  They can be turned on in the
dark as long as the .verDarkSwitch property does not display a message.

Attributes
.isactive   Flag determining whether self is switched on or off.
.routeswitch    Defines whether self should be switched (returns nil), or
            whether another object should be (returns that object).

Methods
.verDarkSwitch( actor )
    Verification routine called when the actor's location is dark
    (.islit = nil).

Actions
.turnOff
    Sets .isactive nil and displays a message.
.turnOn
    Sets .isactive true and displays a message.


3.1.1.  room

class room: thing

A room is an object meant to contain actors such as the player character.
Rooms set the maxweight and maxbulk properties nil for In and On.  The
In position describes a state of floating above the floor; the On
position describes a state of lying on the floor.

Direction properties are also tied to the room; they are defined by
the .dirTravel attribute of the Direction objects.  Unlike in Adv.t, these
are meant to be straight objects and not contain code. Any code related with
traveling in a certain direction is in the Go direction property
(.dirGoDirProp on the Direction), which is called with one argument, the
actor doing the traveling.  Although Pianosa does not define any Directions,
ts_std.t includes the standard twelve (compass rose, up/down, enter/exit).
The nomenclature used by that file, although not binding, follows the form
of &north and &goNorth.

Attributes
.ambientlist    String/string list of ambient sound resource names.
.bgambientlist  String/string list of background ambient sound resource names.
.darkdesc   Displays an error message saying that it's too dark to do that.
.darkroomdesc   Displays the long description of the room in the dark.
.darkstatusdesc     Displays the short description of the room in the dark.
.doesecho   Flag determining whether .echonoise is called in this room instead
            of .hearnoise.  Defaults to nil.
.Exitless   Displays a message stating that there is no exit in the intended
            direction.
.exitlist   Property list of the standard exits.
.flooradesc     Displays the short description of the floor, preceded by the
                indefinite article.
.floorldesc     Displays the long description of the floor.
.floorsdesc     Displays the short description of the floor.
.floorthedesc   Displays the short description of the floor, preceded by
                the definite article.
.genadesc   Displays a short epithet for the room, preceded by the indefinite
            article.
.gensdesc   Displays a short epithet for the room, such as "area" or "room".
.genthedesc     Displays a short epithet for the room, preceded by the
            definite article.
.hasambient     Flag determining whether self has ambient sounds or not.
.hasbgambient   Flag determining whether self has background ambient sounds
            or not.
.hasfloor   Flag determining whether self has a floor or not.
.hasmusic   Flag determining whether self has background music or not.
.incontdesc( c )    See container classes.
.isinside   Flag determining whether self is inside or outside.
.isroom     Flag specifying that yes, this is a room.
.isseen     Flag determining whether self has been entered by the player
            character or not.
.issleepable( actor, position )     Flag determining whether actor may
            comfortably sleep here; if not, displays a message.
.killoldambient     Flag determining whether ambient sounds currently queued
            should be removed upon entrance into self.  Defaults to true.
.killoldbgambient   Flag determining whether background ambient sounds
            currently queued should be removed upon entrance into self.
            Defaults to nil.
.killoldmusic   Flag determining whether background music currently queued
            should be removed upon entrance into self.  Defaults to nil.
.leavelist  List of objects to be given a .leaving message when an actor
            leaves self.
.lightson   Flag determining whether the room's lighting is on or not.
            Defaults true.
.musiclist  String/string list of background music resource names.
.notfollowroom  Flag determining whether followers shouldn't follow their
            targets into self.
.incontdesc( c )    See container classes.
.reachable  List of objects which are specifically reachable from self.
.repeatambient  Number of times ambient sounds should repeat or true for
            continual repeat.
.repeatbgambient    Number of times background ambient sounds should repeat
            or true for continual repeat.
.repeatmusic    Number of times background music should repeat or true for
            continual repeat.
.roomdesc   Displays the long description of the room.  Defaults to .ldesc.
.roomdescafter  Displays whatever after the .roomdesc and .bdescs, but before
            the inventories.  Defaults to "\n\t".
.scoredesc  Displays the score description (on the right in the default
            status line) in HTML mode.
.sequenceambient    String value for "sequence" attribute in ambient sound
            definition.  Can be `random', `cycle', or `replace'.  Defaults
            to `random'.
.sequencebgambient  See .sequenceAmbient.
.sequencemusic  See .sequenceAmbient.
.sitloc         Object to be sat in if the command is just "sit"; defaults
            to nil (meaning the floor).
.statusdesc     Displays the short status-line description of the room.
            Default to .sdesc.
.statusLine     Displays the status-line text or, in HTML mode, configures
            the status-line banner.
.tagdesc    The status-line text; defaults to .statusdesc or .darkstatusdesc
            apropos.
.Wait( actor )  Displays a message when the player types "wait".


Methods
.actorlist( actor )
    Finds all actors within the room, the given actor excluded, verifies them
    via .inEveryone, and returns them in a list.
.addleavelist( object )
    Adds the given object to .leavelist.
.cantexit
    Displays a message stating that movement is impossible, either because
    it is blocked in the specified direction (.Exitless) or because it is
    too dark (stumble()).
.cantreachfrom( actor, object )
    Displays a message stating that an object cannot be reached from self by
    actor.  Called by .cantreach.
.Enter
    Displays a message associated with entering self.
.enterRoom( actor, verbosity )
    Does tasks associated with actor's entering self.  verbosity equaling nil
    means that passive messages (like describing the room) should be
    suppressed.  If actor is the player character, calls .Enter, .initSound,
    .lookAround (if verbosity is true), and .firstseen (if .isseen is nil).
.firstseen
    Displays a message associated with entering self for the first time.
.initAmbient
    Initiates ambient sounds for self.  See .hasAmbient, .ambientList,
    .repeatAmbient, .seqenceAmbient, and .killOldAmbient.
.initBGAmbient
    Initiates background ambient sounds for self.  See .hasBGAmbient,
    .bgambientList, .repeatBGAmbient, .seqenceBGAmbient, and .killOldBGAmbient.
.initMusic
    Initiates background music for self.  See .hasMusic, .musicList,
    .repeatMusic, .seqenceMusic, and .killOldMusic.
.initSound
    Initiates all sound for self by calling .initMusic, .initBGAmbient, and
    .initAmbient.  Called from .enterRoom.
.islit
    Determines whether the room is lit or not.  Checks .lightson, and if that
    fails then checks every object in global.lampList to see if it's on and
    visible from self, and if that fails checks for a parent room and sees
    whether that room's lights are on.
.leaveRoom( actor, verbosity )
    Notification to room that an actor is leaving.  Sends .Leaving messages
    to all objects in .leavelist.  verbosity equaling nil usually means that
    this is a nested room to parent room movement.
.lookAround( verbosity )
    Displays a description of the room according to the given verbosity. By
    default, displays the tagline and then calls .nrmLookAround or
    .darkroomdesc as appropriate.
.notifyPreactors( actor, verbobject, directobject_object, prepositionobject,
  indirectobject_object)
    Sends .preactorAction messages to all objects of class Preactor visible
    within self.  Called by .roomAction.
.notifyReactors( actor, verbobject, directobject_object, prepositionobject,
  indirectobject_object)
    Sends .reactorAction messages to all objects of class Reactor visible
    within self.  Called by reactorDaemon.
.nrmLookAround( verbosity )
    Describes self with a given verbosity.  By default nil verbosity means
    to display only a standard inventory of self's contents and true verbosity
    means to display the long description (.roomdesc), list the .describealone
    objects, and then display the standard inventory.
.orderPreactorList( list )
    Allows modification and ordering of the list of Preactors for
    .notifyPreactors
.orderReactorList( list )
    Allows modification and ordering of the list of Reactors for
    .notifyReactors.
.roomAction( actor, verbobject, directobject_object, prepositionobject,
  indirectobject_object)
    Action routine for the actor's location.
.roomCheck( verbobject )
    Determines whether verbobject is a valid verb within self; called by
    the parser.  Should display a message if returning nil.

Actions
.darkTravel( actor, dir )
    Handles movement in a darkened room.  By default, replicates the .travel
    experience except that it requires that the destination be lit.
.echoNoise( type )
    Causes a noise of a certain type to be echoed within self.  The default
    procedure is to call .hearnoise in self and then call .hearnoise in all
    adjoining rooms (with no option for echo) and any existant parent room.
.hearNoise( type )
    Causes a noise of a certain type to be heard by all objects of class
    hearer within self; .hearnoise is called on all of said objects.
.jump( actor )
    Causes actor to jump within self.  The default version displays a
    "witty" response and jostles the actor's contents.
.makeNoise( type )
    Causes a noise of a certain type to be made within self.  The default
    procedure is to call .hearnoise in self, call .echonoise in an adjoining
    room if said room has .doesecho set true (otherwise, call .hearnoise),
    and then call .makenoise in any existing parent room.
.sitDown( actor )
    Causes actor to sit down within self.  The default version checks for
    a .sitloc on self and if none is found calls .Sitdown on actor.
.standUp( actor )
    Causes actor to stand up within self.  The default version calls
    .Standup on actor.
.travel( actor, direction_property )
    Causes actor to attempt travel in the given direction.  Calls .darkTravel
    if the room is not lit, verifies the movement via the .go property
    (see .goDown), checks to see that direction leads somewhere (if not,
    calls .cantexit), and then calls .travelTo on actor if all checks out. 

-- room subclasses


3.1.1.0.  nestedroom

class nestedroom: room

nestedrooms are rooms designed to be within other rooms; however, the code
their definition adds is mostly veneer.  .lookAround messages are passed
to parent locations and .statusdesc is set to show that this room is
really just a location within a location.  Followers, for the most part,
should not follow their quarries into these locations (.isfollowroom is
nil); articles dropped here should really fall into other places
(.isdroploc is nil).

Attributes
.statusPrep     Displays the preposition to be used in the status line:
            "Cellar, in the comfy chair".
.outOfPrep  Displays the preposition to be used when leaving: "You get
            out of the car.".

--- nestedroom subclasses


3.1.1.0.0.  bednested

class bednested: fixedthing, nestedroom, surface

bednesteds are gameworld objects which can either be sat upon or lied
down upon.  Objects put into the chair are instead put onto the chair.
The definition changes .standup to move the standing actor into the parent
room.

Attributes
.autoExit   Flag determining whether self should be automatically left when
            the sitting actor attempts to leave the parent room.  Defaults
            to nil.

Methods
.removePrepPosture( posture )
    Displays the preposition for removing oneself from the bed when one
    is in a given posture.


3.1.1.0.1.  chairnested

class chairnested: fixedthing, nestedroom, surface

chairnesteds are gameworld objects meant to be sat in like a chair. They
are identical to bednesteds except that they do not allow actors to lie
upon them, their exit prepositions are slightly different, and .autoExit
has a different default.  chairnesteds have the infrastructure to be lied
upon, so if a sofa or futon is desired, simply copying bednested code
into the object's definition should be enough.

Attributes
.autoExit   Flag determining whether self should be automatically left when
            the sitting actor attempts to leave the parent room.  Defaults
            to true.

Methods
.removePrepPosture( posture )
    Displays the preposition for removing oneself from the chair when one
    is in a given posture.


(the roomfloor object is found here in the Pianosa library file)


3.1.1.0.2.  vehicle

class vehicle: nestedroom

vehicles are gameworld objects which are meant to convey actors from one
place to another.  They can either be "open" or "closed"; if closed
(.isopen is nil), they are (or should be) in their own little world, with
the whole of the outside inaccessible.  Some vehicles can also be taken;
this case is provided for within the definition.  Furthermore, many actions
are forbidden to be done to the vehicle while inside it; because this is
done with .dobjGen and .iobjGen, it is possible to allow further actions
(than examine, put in/on, and leave) by making sure that the proper
verification routine is defined specifically within the object's code.

Atributes
.Error      Displays a message that the action is not possible from
            within the vehicle.
.isvehicle  Flag specifying that yes indeed, this is a vehicle.
.reachable  List of objects accessible from within vehicle.  If adding
            anything to this, make sure the list 1) includes self and
            2) takes into account openness, if that feature is being used.


3.1.2.  container, cover, mask, surface

class container: thing
class cover: thing
class mask: thing
class surface: thing

A container is an object meant to contain other objects within it.  A cover
is an object meant to contain other objects beneath it.  A mask is an
object meant to contain other objects behind it.  A surface is an object
meant to contain other objects on top of it.

These are the four default position-holders in Pianosa.  Properties dealing
with the duties of having contents will be dealt with here, including the
contents-listing methods.

There are four companion classes: qcontainer, qcover, qmask, and qsurface.
These classes simply set their respective .isq attributes true. 

Attributes
.behindcont List of all objects held directly behind self.  Set up
            automatically.
.behindcontdesc( c )    Displays an introductory message for an inventory
            listing; if this returns true a form of "to be" will be
            conjugated (according to the number of objects to be listed)
            directly after the message.  c is the number of objects
            (invCount) in the list.
.behindcontreachable    Flag determining whether objects held behind self
        are generally accessible.  Defaults to .behindcontvisible.
.behindcontvisible  Flag determining whether objects held behind self are
            generally visible.  Defaults to true.
.behinddesc     Displays a description of what's behind self.  Defaults to
            nothing.
.emptybehind    Displays a message stating that there is nothing (visible)
            behind self.
.emptyin    See .emptybehind.
.emptyon    See .emptybehind.
.emptyunder    See .emptybehind.
.excessbulk( object, position )     Displays a message stating that object
            will not fit in position because it is too large.
.excessweight( object, position )   Displays a message stating that object
            will not fit in position because it is too heavy.
.incont     See .behindcont.
.incontdesc( c )    See .behindcontdesc.
.incontreachable    See .behindcontreachable.  Also, defined to check .isopen.
.incontvisible      See .behindcontvisible.  Also, defined to check .isopen
            and .istransparent.
.indesc     See .behinddesc.
.iscontainer    Flag specifying that yes, good sir, this is a container.
.iscover    Flag specifying that indeed, this is a most verifiable cover.
.isdroploc  Flag determining whether dropping an object here should cause it
            to stay here or fall further.  Default true for rooms, nil for
            everything else.
.ismask     Flag specifying that in fact, this is a certified mask.
.isqcontainer   Flag determining whether a container will list its contents
            in room listings and inventories.  Default nil.
.isqcover   See .isqcontainer.
.isqmask    See .isqcontainer.
.isqsurface     See .isqcontainer.
.issurface  Flag specifying that this is truly a surface to have things laid
            upon.
.istransparent  Flag determining whether, when closed, the contents of self
            can be seen anyway.
.listcontoninspect  Flag determining whether .listallcontents will be called
            when an object is looked at.  Default is true.
.maxbulkbehind  Bulk limit for the Behind position.  Set nil for no limit.
            Default is 10.
.maxbulkin  See .maxbulkbehind.
.maxbulkon  See .maxbulkbehind.
.maxbulkunder   See .maxbulkbehind.
.maxweightbehind    Weight limit for the Behind position.  Set nil for no
            limit.  Default is 10.
.maxweightin    See .maxweightbehind.
.maxweighton    See .maxweightbehind.
.maxweightunder     See .maxweightbehind.
.oncont     See .behindcont.
.oncontdesc( c )    See .behindcontdesc.
.oncontreachable    See .behindcontreachable.
.oncontvisible      See .behindcontvisible.
.ondesc     See .behinddesc.
.outOfPrep  Displays the preposition for actors getting off of/out of a
            nestedroom like a chair or a bed.  Compare .removePrep.
.posdesc( position )    Displays how to refer to an object being held in a
            certain position relative to self.
            Example:    desk.posdesc( Under ) displays "under the desk"
.posPrep( position )    Displays the preposition to describe being in a
            certain position relative to self.
            Example:    desk.posPrep( Under ) displays "under"
.removePrep( position )     Displays the preposition to describe being taken
            out from a certain position relative to self.
            Example:    desk.removeProp( Under ) displays "out from under"
.statusPrep     Displays the preposition for actors within a nestedroom like
            a chair or a bed.  Compare .posPrep.
.undercont  See .behindcont.
.undercontdesc( c )     See .behindcontdesc.
.undercontreachable     See .behindcontreachable.
.undercontvisible   See .behindcontvisible.
.underdesc  See .behinddesc.

Methods
.bulkbehind
    Determines the total extra bulk added by objects within the Behind
    position.  Defaults to returning 0 regardless, because most containers
    are fixed.
.bulkin
    Determines the total extra bulk added by objects within the In position.
    If self has .isflexiblecontainer set true, it actually sums this up;
    otherwise, it simply returns 0.
.bulkon
    See .bulkbehind.
.bulkunder
    See .bulkbehind.
.contents
    An alias to .allcont.
.Drop( object, target )
    Message sent to self by .putInto to verify letting go of object being
    moved to target.  Returns true to abort movement.
.dropall( {position, {, dontDropWornObjects {, jostle }}} )
    Causes all objects in a position (default In) to be dropped from self
    (excepting objects with .isworn set true unless the first argument is nil)
    according to .dropFrom.
.dropping( object, position )
    Returns a list in the format [ object position ] specifying where an
    object, dropping from a certain position around self, should fall.
    By default, if .isdroploc is set nil then .dropping is called on self's
    location with the position On.
.endPutInto( object, position )
    Notification by .putInto that object has been successfully put into
    position around self.  By default, calls .mixCont.
.gaca( class {, property {, value {, argument }}} )
    Gets all contents of a certain class in any position around self.  Loops
    through the positions calling the appropriate gac-class property on self.
    If property exists, that property must equal value (default = true) on an
    object for it to be included in the list; if argument exists, it will be
    passed to the property.
.gacb( class {, property {, value {, argument }}} )
    Gets all contents of a certain class behind self.  Calls .gacva on every
    object behind self and adds those objects as well.  For the last three
    parameters, see .gaca.
.gaci( class {, property {, value {, argument }}} )
    See .gacb.
.gaco( class {, property {, value {, argument }}} )
    See .gacb.
.gacu( class {, property {, value {, argument }}} )
    See .gacb.
.gacva( class {, property {, value {, argument }}} )
    Gets all contents of a certain class in any visible position around self.
    See .gaca.
.Grab( object, position )
    Notification by .moveInto that object is being removed from a certain
    position around self (or from an object in a certain position around
    self); if this returns non-nil the movement is canceled.
.listallalonecontents( {depth} )
    Lists all describe-alone contents in all non-quiet, visible positions
    around self at a certain inventory depth (default = 1).  Calls
    aloneContListing , which calls .bdesc.
.listallcontcontents( {depth, {verbosity_type }} )
    Lists all non-quiet, visible contents positions of objects held in
    non-quiet, visible positions around self at a certain inventory depth
    (default = 2) and with a certain verbosity type.  Calls innerContListing,
    which in turn calls .listallcontents on the contents items.
.listallcontents( {depth, {verbosity_type}} )
    Lists all non-quiet, visible     contents positions on self at a
    certain inventory depth (default = 1) and with a certain verbosity type.
    Calls the specific contents-listing properties (see .listbehindcont) and
    then .listallcontcontents.
.listbehindcont( depth, verbosity_type )
    See .listXcont.
.listincont( depth, verbosity_type )
    See .listXcont.
.listoncont( depth, verbosity_type )
    See .listXcont.
.listundercont( depth, verbosity_type )
    See .listXcont.
.listXcont( position, depth, verbosity_type )
    Lists objects in a certain position relative to self, provided that the
    objects there are visible (see .behindcontvisible).  Passing true as
    depth forces a wide-inventory display; otherwise, depth just specifies
    indentation.  Displays the appropriate introduction message (see
    .behindcontdesc) if there are to-be-listed contents or the verbosity
    type is 0, then calls contListing.
.reachList( actor )
    Determines the list of all objects reachable by actor around self.
.routebehind( object, jostle )
    Routes where a certain object, being put behind self, should go.  To
    abort the movement, this should return nil.
.routein( object, jostle )
    See .routebehind.
.routeon( object, jostle )
    See .routebehind.
.routeunder( object, jostle )
    See .routebehind.
.speakList( actor )
    Determines the list of all objects speakable to by actor around self.
    Defaults to .visList.
.Take( object, position )
    Message sent to self by .putInto to verify accepting object being moved
    to a position around self.  Returns true to abort movement.
.verGrab( object, position )
    Verification routine checking whether object can be removed from a
    certain position around self (or from an object in a certain position
    around self).  Shows displeasure by diplaying a message, should not
    otherwise.
.visList( actor )
    Determines the list of all objects visible by actor from self.
.weightbehind
    Determines the total extra weight added by objects within the Behind
    position.  Defaults to 0.
.weightin
    Determines the total extra weight added by objects within the In position.
.weighton
    See .weightin.
.weightunder
    See .weightbehind.

Actions
.forceAccept( object {, position } )
    Causes object to be moved into a certain position (default = In) relative
    to self.  By default, does this by setting the appropriate location
    property on object to self and adding object to the appropriate contents
    list on self.
.forceRelease( object )
    Causes object to be removed from around self.  By default, does this by
    removing object from the appropriate contents list of self and then
    clearing all location properties of object (by calling .clearloc).
.mixCont( position )
    Causes contents in a certain position to be suddenly mixed.  Loops through
    the contents list, calling .mixwith on each object with every other object
    in the loop.

-- container class subclasses


3.1.2.0.  coverer

class coverer: qcover

coverers are covers which do not have a real-world Under position counterpart
per se, but instead are capable of hiding things underneath them until they
are moved.  The class defines a special .Move, so any other code there should
include or pass to the library code.  It also defines .verDoMove and .doMove
routines which enable that command to cause covered items to be revealed.


3.1.2.1.  liquidcontainer

class liquidcontainer: qcontainer

liquidcontainers are containers designed to hold liquids.  They can either
service only liquids (.liquidsonly set true) or function as general containers.
Whether they are qcontainers or not depends upon whether they hold liquids
or not, because they alter .specialdesc to include what they contain if it's
a liquid.  This class overrides .Take.

Attributes
.liquidsonly    Flag determining whether other objects can be placed in self
            beside liquids.
.oneliquidonly  Flag determining whether more than one liquid may be placed in
            self at a time.
.spillsafe  Determines what jostle level must be exceeded to cause liquids
            inside to spill; true if self is completely spillsafe.

Methods
.holdsliquid
    Determines whether self holds a liquid or not.
.liquiddesc
    Describes the liquid within self.


3.1.2.2.  openable

class openable: container

openables are containers which can be opened (if .isopenable is true) and
shut (if .iscloseable is true) at will.  If transparent (.istransparent is
true), their contents can be seen from without.

Attributes
.Close( actor )     Displays a message upon closing self.
.iscloseable    Flag determining whether self is closeable or not.
            Defaults true.
.isopen     Flag determining whether self is currently open or not.
            Defaults true.
.isopenable     Flag determining whether self is openable or not.
            Defaults  true.
.istransparent  Flag determining whether self is transparent or not.
            Defaults nil.
.Open( actor )  Displays a message upon opening self.

Actions
.close( actor )
    Closes self.
.open( actor )
    Opens self.

--- openable subclass


3.1.2.2.0.  lockable

class lockable: openable, Lockcode

lockables are openables which can be locked and unlocked as well (if
.islockable and .isunlockable are set true).  Most of their functional code
is in the Lockcode class.

Attributes
.autoUnlock     Flag determining whether attemping to open self should
            automatically unlock self if possible.
.Close( actor ) Displays a message upon closing self.
.iscloseable    Flag determining whether self is closeable or not.
            Defaults true.
.islockable     Flag determining whether self is lockable or not.
            Defaults nil.
.isopen     Flag determining whether self is currently open or not.
            Defaults true.
.isopenable     Flag determining whether self is openable or not.
            Defaults true.
.istransparent  Flag determining whether self is transparent or not.
            Defaults nil.
.isunlockable   Flag determining whether self is unlockable or not.
            Defaults true.
.Lock( actor, key )    Displays a message upon locking self.
.mykey      Object or object list of valid keys for self.  nil means no key
            is necessary.
.mykeyKnown     Flag determining whether a correct key for self is known
            to the player.
.Open( actor )  Displays a message upon opening self.
.Unlock( actor, key )   Displays a message upon unlocking self.

Methods
.keyHeldBy( object )
    Checks whether a defaultable key is being held by object.
.keyIsValid( object )
    Checks whether object is a valid key for self.


Actions
.close( actor )
    Closes self.
.lock( actor, key )
    Locks self.
.open( actor )
    Opens self.
.unlock( actor, key )
    Unlocks self.


3.1.2.3.  qcontainer, qcover, qmask, qsurface

class qcontainer: container
class qcover: cover
class qmask: mask
class qsurface: surface

These four classes are enabler classes, merely setting their respective
q-properties true.

--- qcontainer subclass


3.1.2.3.0.  movableActor

class movableActor: qcontainer

movableActors are NPCs which can be picked up and taken with the player.
All characters in the game inherit from movableActor.

Attributes
.actorname  The name of the actor.  Referenced by sdesc.

.bdesc      Message briefly describing self to everything else in the room.
.disavow    Message saying that self knows nothing about what was asked of
            self.
.Hungerwarning  Message notifying self that if self doesn't eat almost
            immediately, self is going to die.
.Hungerwatch    Message notifying self that if self doesn't eat "soon", self
            is going to die.
.hasfollower    Flag determining whether self can be followed.
.hashunger  Flag determining whether self must eat to survive.
.hassleep   Flag determining whether self must occaisionally sleep.
.hungerTime     Number determining how long self can live without dying.
.hungryTime     Number determining how long self has gone without eating.
.inEveryone     Flag determining whether self is included in Everyone.
            Defaults true.
.iPos       Determines the inventory position for self.
.isactor    Flag specifying the fact that self is an actor, and thus can be
            given commands.
.isasleep   Flag determining whether self is asleep or not.
.possessive     Displays the possessive, e.g. "your" or "<object>'s".
.posture    Determines the current posture of self (Stand, Sit, or Lie).
.preferredActor     Flag specifying that not only is self an actor, but is a
            preferred actor.
.primaryIPos    Displays the primay inventory position, i.e. that which taken
            objects are sent to.
.sayArriving    Message displaying that self is entering the room that
            parserGetMe() is in.
.sayLeaving     Message displaying that self is leaving the room that
            parserGetMe() is in.
.sleepTime  Number determining how long self can go without passing out and
            sleeping.
.sleepDuration  Number determining for how long self will sleep.
.Sleepwarning   Displays a message that if self doesn't get to sleep almost
            immediately, self is going to pass out on the floor.
.Sleepwatch     Message displaying that if self doesn't sleep relatively soon,
            self is going to pass out on the floor.
.sleepyTime     Number determining how long self has gone without sleeping. 

Methods
.askobject( object )
    Asks self about a specific object (called before .askword).  Should
    return true if a response is forthcoming.
.allheld
    List of all objects held by self.
.askword( word, wordlist )
    Asks self about a specific word in a list.  Should return true if an
    answer is displayed.
.followedFrom( room )
    Causes self's follower, if it exists, to move into the room just vacated
    by self.
.Hungry( time_left )
    Message sent to self every turn with the argument
    (.hungerTime - .hungryTime), i.e. the time left until self should die of
    starvation.  Any actual consequences of not eating are left up to this
    method.
.inventory( {inventory_depth {, verbosity_type}} )
    Displays a full inventory for self at a given inventory depth and
    verbosity type.
.isCarrying( object/list )
    Determines whether self is visibly carrying an object or any one of a
    set of objects.
.isCarryingAll( object/list )
    Determines whether self is visibly carrying a certain object or every
    object in a list.
.isHolding( object )
    Determines whether self is holding an object -- i.e. the object's
    location is exactly self, not some other object that self is holding.
.Sleepy( time_left )
    Message sent to self every turn with the argument
    (.sleepTime - .sleepyTime), or the time left until self should die of
    starvation.  Any actual consequences of not eating are left up to this
    method.
.travelTo( destination {, position {, verbosity}} )
    Causes self to travel to a certain position (default = On) in
    destination. If destination is an obstacle, instead travels to
    room.destination. Calls .leaveRoom on the old location (if it exists),
    calls .sayLeaving on self if self is in sight of but is not
    parserGetMe(), moves self into destination, calls .enterRoom on
    destination, and calls .sayArriving (again, if visible to
    parserGetMe()).  Finally calls .followedFrom on self if destination
    isn't .notfollowroom.

Actions
.Awaken
    Causes self to awaken.  Sets .isasleep to nil and displays a message.
.hungerdeath
    Self dies! from hunger.  Calls .perish.
.perish
    Calls die() if is parserGetMe(), otherwise fades away like a
    Jedi master (.forceInto( nil )).
.sleep
    Causes self to fall asleep.  If self is parserGetMe(), this just
    displays a cute message and wakes up again (calls .Awaken).  Otherwise,
    sets .isasleep true and sets .Awaken as a notifier until .sleepDuration
    passes.
.sleepeasy
    Causes self to fall asleep comfortably.  Calls .sleep.
.sleephard
    Causes self to fall asleep uncomfortably.  Calls .sleep.
.Sitdown
    Causes self to sit down by setting posture to Sit and displaying an
    approriate message.
.Speak( sound )
    Displays a message on how self would cause sound to be emitted.
    Calls .Say on the sound.  Returns true to abort.
.Standup
    Causes self to stand up by setting posture to Stand and displaying
    an appropriate message.

---- movableActor subclasses


3.1.2.3.0.0.  NPC

class NPC: fixedthing, movableActor

NPCs are actors which cannot be picked up.

----- NPC subclasses


3.1.2.3.0.0.0.  Actor

class Actor: NPC

An Actor is a male actor.


3.1.2.3.0.0.1.  Actors

class Actors: NPC

Actors are groups of actors, not necessarily all male.


3.1.2.3.0.0.2.  Actress

class Actress: NPC

An Actress is a female actor.


3.1.2.3.0.0.3.  basicMe

class basicMe: NPC

basicMe is the basic class for player characters; however, the definition
also easily allows for switching out of one character into another. 

Attribute
.actorname  The name of the actor.  Referenced by sdesc when self is not
            the PC.
.actorperson    The grammatical person of the actor, used for conjugation;
            can be FIRST_PERSON, SECOND_PERSON, or THIRD_PERSON, and with
            .isplural any of the 5 English persons can be used.  Referenced by
            grammarperson when self is the PC.
.grammarperson  See thing.grammarperson.  Redefined as a method.  When
            self is not the PC, returns THIRD_PERSON;  otherwise, returns
            .actorperson.
.ispasttense    Flag determining whether verbs using this object as subject
            should be conjugated in the present or the past tense.
            thing.ispasttense by default returns parserGetMe().ispasttense.

Method
.becomeMe
    Turns self into the active player character by removing the special
    words `me' and `myself' from the old PC object's noun list, adding them
    to self's vocabulary list, and calling parserSetMe().


(the Everyone object is found here in the Pianosa library file)


3.1.2.3.0.0.4.  Follower

class Follower: NPC

A Follower is a library-handled logical character which follows one room
behind its actor so that the player can type "follow her" and she will
be followed.  It is possible to declare an object of this class in the
gamefile if desired, although the .remove method should be overwritten.

Attribute
.myactor    Determines the actor that self is following.

Action
.remove     Removes self from the game.  By default, deletes it, because
            Followers are typically dynamic objects.

-- container subclasses continued


3.1.2.4.  transparentcontainer

class transparentcontainer: container

transparentcontainers are containers which can be seen through (if
.istransparent is true).  This is an enabler class, simply setting the
attribute true.

3.1.3.  Other gameworld classes
3.1.3.0.  concept

class concept: object

concepts are logical objects which can be asked about but which do not
necessarily correspond to an object present in the gameworld.  The class
is an enabler class with simple verb routines.


3.1.3.1.  Direction

class Direction: object

Direction is a programmatical structure allowing movement directions to be
defined easily without the need for editing Pianosa.  Unlike Positions,
there are no Directions defined within Pianosa, although one is required
(see 3.3. External Objects).  The standard twelve included in ts_std.t
are listed under room.   Further unlike Positions, the Direction access
functions (travelProp() and sayDirection()) are not indexed by number but
rather by the .dirTravel property value.

Attributes
.dirGoDirProp   Property pointer for the verification travel property.
.dirNames   List of single-quoted names for this direction, including
            abbreviations.
.dirTravel  Property pointer for the general travel property. 


3.1.3.2.  floatingobject

class floatingobject: object

floatingobjects are objects which are not tied to one location in the
gameworld.  Because defining .locate (and .position) as methods works in
only one direction -- up the object tree -- and the valid-object routines
work in the opposite direction, floatingobject is provided as a way to
bring these objects into consideration as objects of actions (since
.validDo moves up the object tree, they stand the same chance as any
other object). floatingobject is a marker class, all objects of which
class are assembled into global.floatingList in preinit().


3.1.3.3.  hearer

class hearer: object

hearers are gameworld objects which receive .hearnoise messages.
hearer is a marker class.


3.1.3.4.  Lockcode

class Lockcode: object

Lockcode is a programmatical convenience which brings the repetitive and
complex key-lock system into one class used by doorway and lockable and
available for use by others.  The attributes of Lockcode are discussed
in the doorway and lockable classes.  Lockcode provides mechanisms for
opening, closing, locking, and unlocking objects, with or without a key. 


3.1.3.5.  multiobject

class multiobject: object

multiobject is a programmatical device for easily creating multiple
instances of an object in multiple locations through the use of dynamic
objects. 

The .ismultiobject flag is important, unlike in other classes; since
multiobjects almost invariably create objects of their own class, it is
important that these new objects not be included in the initMultiobject()
loop; therefore, only multiobjects with this flag set true will have
.create called on them.

Attributes
.ismultiobject  Flag stating with all strength of purpose that this is,
            indeed, a multiobject (and thus .create will be called on
            this object). .locatelist    List of locations, each optionally
            followed by a position (default = In), in which the multiobject
            should go.
.multiobjectlist    List of dynamic objects, one for every object in
            .locatelist. 

Method
.create
    Spawns the multiobjects from .locatelist.  Called by initMultiobject().

3.1.3.5.0.  multilocatefixed

class multilocatefixed: fixedthing, multiobject

A multilocatefixed is the best way to implement a large number of unchanging,
identical objects in multiple locations.  Essentially, the object places
itself in the contents lists of multiple locations.

Attribute
.locatelist     List of locations in format [ location1 {position1} ... ].
            The default position is In.  Example: [ cabinet sink dormitory
            bunkbed On ] places the object inside the cabinet, the sink,
            and the dormitory, and on the surface of the bunk bed.

3.1.3.6.  notified

class notified: object

A notified object receives notification at the end of each turn.  This
is a marker class by class-loop.

Method
.notification
    Called by notifiedDaemon every turn.


3.1.3.7.  obstacle

class obstacle: object

obstacles are programmatical conveniences which allow exits to be reliant
upon, for example, whether or not a door is open as to whether or not
the player may pass.  obstacle is a marker class which sets the
.isobstacle attribute.

Attribute
.isobstacle     Flag define an obstacle self is.

Method
.destination( actor )
    Determines whether or not actor may pass.  Returns the destination object or nil.

- notified subclasses


5.1.3.7.0.  doorway

class doorway: fixedthing, obstacle, Lockcode

doorways are gameworld objects which may be open and shut, locked and
unlocked as the player desires.  They are also obstacles, so whether they
are open or not can decide whether the player can move through an exit or
not.  By default, doorways also pass .hearnoise messages on to their
destinations.

Attributes
.autoOpen   Flag determining whether self will be automatically opened
            when an actor attempts to pass through it shut.  Defaults to
            true.
.autoUnlock     Flag determining whether self will be automatically
            unlocked when an actor attempts to open it when locked.
.Close( actor )     Displays a message upon closing self.
.doordest   Object for what lies on the other side of the door.
.doordir    Property pointer for which direction should be traveled in
            when self is entered.
.iscloseable    Flag determining whether self can be closed or not.
            Defaults to true.
.isdoorway  Flag postulating that self's existence may, indeed, be determined
            to be that of a doorway.
.islockable     Flag determining whether self can be locked or not.
            Defaults to nil.
.islocked   Flag determining whether self is locked or unlocked.  Defaults
            to nil.
.isopen     Flag determining whether self is open or shut.  Defaults to true.
.isopenable     Flag determining whether self can be opened or not.
            Defaults to true.
.isunlockable   Flag determining whether self can be unlocked or not.
            Defaults to true.
.Lock( actor, key )     Displays a message upon locking self.
.mykey      List of valid keys for self.
.mykeyKnown     Flag determining whether a valid key for self is known or not.
.Open( actor )  Displays a message upon opening self.
.otherside  Object for the other side of this door (the side facing
            .doordest), which can thus be kept in harmony with this side.
.Unlock( actor, key )   Displays a message upon unlocking self.

Methods
.destination( actor )
    Determines whether actor may pass through self; if so, returns .doordest.
.keyHeldBy( object )
    Determines whether a valid key for self is known and is held by object.
.keyIsValid( object )
    Determines whether a given object is valid as a key for self. 

Actions
.close( actor )
    Closes self.
.lock( actor, key )
    Locks self.
.open( actor )
    Opens self.
.unlock( actor, key )
    Unlocks self.

-- doorway subclass


3.1.3.7.0.0.  matchdoorway

class matchdoorway: doorway, multiobject

matchdoorways are doorways which are automatically generated by the library.
The class defines its own .create, so the only reason it inherits from
multiobject is to hook initMultiobject(). .locatelist is also in a wildly
different format.

    locatelist = [ source1 destination1_1 {destination1_2 ... } is_bidirectional
                 { source2 destination2_1 {destination2_2 ... } is_bidirectional ... } ]


A door is created at the direction properties (see room.exitList) on source1
which equal destination1_1 (or destination1_2, etc.).  If is_bidirectional
is true, then the same process is repeated for the destination rooms, this
time looking for the source room.  All source/destination/is_bidirectional
sets are independent.

Attributes
.locatelist     List from which the doorways are generated.  See class description. 

Methods
.create
    Spawns the matchdoorways from .locatelist.  Called by initMultiobject().
.getdoor( source {, destination } )
    Returns the door object of class self leading from source (to
    destination, if given).  If some number other than one such door is
    found, returns nil.
.initdoor( source, destination )
    Initiates self, a door leading from source to destination.
.setupdoor( source, destination, is_bidirectional )
    Creates an instance of the matchdoorway, sets .doordest, places it,
    calls .initdoor, changes any direction properties on source which lead
    to destination so that they pass through the instance, adds vocabulary
    to the instance, and sets .doordir.  If is_bidirectional, spawns another
    door, sets .otherside on each, and repeats the process.

--- matchdoorway subclass


3.1.3.7.0.0.0.  doorwayframe

class doorwayframe: matchdoorway, openable

doorwayframes are doorways with built-in frames which accept objects.  Like
any matchdoorway, doorwayframes can be placed in multiple locations, but
beware -- in the current implementation, the frame will be shared between
all of the doorways.


3.1.3.8.  Position

class Position: object

Position is a programmatical structure allowing relative positions to be
defined as painlessly as it can get.  Four Positions are defined within
Pianosa.  On and In are used specifically by the movableActor and room
classes, while Under and Behind are simply fully declared.

The Position objects are set by preinitAdaptables(), which goes through
every object of class Position and adds it to global.positionList
in order of .position attribute.  In the case of duplicated .position
values, one of the positions will not be included.

Attributes
.position   Number of position's order in line.
.bulkProp   Property for the amount of additional bulk of contents in self.
.contProp   Property for the contents-list of self.
.contdescProp   Property for the inventory listing introduction of self.
.descProp   Property for the position description of self.
.emptyProp  Property for the empty message for self.
.gacProp    Property pointer for the "contents held of class" method for self.
.listcontProp   Property for the contents-listing method for self.
.locProp    Property for the object location attribute for self.
.maxbulkProp    Property for the maximum bulk allowed in self.
.maxweightProp  Property for the maximum weight allowed in self.
.outofPrepobject    Preposition object/object list for removing objects from
            self.
.posPrepobject  Preposition object/object list for removing objects from self.
.qProp    Property for the quiet-container attribute for self.
.reachProp  Property for the contents-reachable attribute for self.
.removePrep Double-quoted string for the preposition for removing objects
            from self.
.routeProp  Property for routing objects being placed into this position.
.showactiveposition     Double-quoted string for the preposition for putting
            objects into self.
.showposition   Double-quoted string for the preposition for objects being
            held in self.
.visProp    Property for the contents-visible attribute for self.
.weightProp Property for the amount of additional weight of contents
            in self.

Method
.initposition
    Called by preinitAdaptables, adds .posPrepobject and .outofPrepobjects
    values to takeVerb.pospreplist, which that verbs uses internally. 


(the In object is found here in the Pianosa library file)
(the On object is found here in the Pianosa library file)
(the Under object is found here in the Pianosa library file)
(the Behind object is found here in the Pianosa library file)


3.1.3.9.  Preactor

class Preactor: object

Preactors are game objects which, when visible to the actor, are notified
of an actor's intended actions before he/she completes them.  The
notification is performed by .roomAction, which calls .notifyPreactors on
the room, which in turn calls .preactorAction on all Preactors in visible
scope. Preactor is a marker class.

Method
.preactorAction( actor, verb, direct_object, preposition, indirect_object )
    Notifies self that actor is performing a certain action.  Can exit or
    abort the command if so desired.


3.1.3.10.  Prep

class Prep: object

Preps are programmatical conveniences which define preposition grammar.
Preps are used to differentiate between prepositions for the purposes of
verb .ioActions.  Two-word verbs must also have the second word defined
somewhere as a preposition.


(the Prep objects are found here in the Pianosa library file)


3.1.3.11.  Reactor

class Reactor: object

Reactors are game objects which, when visible to the actor, are notified
of an actor's intended actions after he/she has completed them.  The
notification is performed by reactorDaemon, which calls .notifyReactors
on the room, which in turn calls .reactorAction on all Reactors in
visible scope.  Reactor is a marker class.

Method
.reactorAction( actor, verb, direct_object, preposition, indirect_object )
    Notifies self that actor has performed a certain action.


3.1.3.12.  Verb

class Verb: object

Verbs are logical constructs detailing how actions are to be carried out.
The special Pianosa attributes deal mainly with general object selection;
other verb properties can be found in a general TADS reference. 

Attributes
.doIsSeen( preposition )    Determines whether the direct object for an
            action on self should be visible.
.doIsSpokenTo( preposition )    Determines whether the direct object for
            an action on self should be speakable to.
.doIsTouched( preposition )     Determines whether the direct object for
            an actionon self should be touchable.
.ioIsSeen( preposition )    Determines whether the indirect object for
            an action on self should be visible.
.ioIsSpokenTo( preposition )    Determines whether the indirect object for
            an action on self should be speakable to.
.ioIsTouched( preposition )     Determines whether the indirect object for
            an action on self should be touchable.

- Verb subclasses


3.1.3.12.0.  darkVerb

class darkVerb: Verb

darkVerbs are Verbs which are at least potentially valid in the dark.

Attribute
.isDarkVerb     Flag definitively declaring that self is a darkVerb (and
            thus passes .roomCheck).

Method
.validInDark( actor, direct_object, preposition, indirect_object )
            Determines whether a certain command is valid in the dark;
            called by .roomAction.  Does not need to display a message.
            Defaults to .isDarkVerb, which defaults to true.

-- darkVerb subclasses


3.1.3.12.0.0.  sysVerb

class sysVerb: darkVerb

sysVerbs are system-oriented actions which have nothing to do with gameplay
and everything to do with performing interface tasks such as saving and
quitting.

Attributes
.Help       Message displaying the help text for self.  All sysVerbs
            are listed.
.isSysVerb  Flag defining the absolute truth of self's identity as a sysVerb.
.ldesc      (some) Message displaying important text or prompt.
.value      Position in which the sysVerb will be listed by help.  Higher
            signifies later.  By convention, all debug verbs are value 0.
            The library already orders its collection alphabetically, so it
            simply assigns values of (5 * (order)), thus leaving plenty of
            space for additional sysVerbs. Multiple values at a certain index
            are okay.

Method
.verbtask( actor )
    Performs the verb's action.


3.1.3.12.0.1.  TravelVerb

class travelVerb: darkVerb, Direction

travelVerbs are player-movement actions which can occur in the dark. There
are no travelVerbs defined in Pianosa, but the twelve standard directions
can be found in ts_std.t.

Attributes
.isTravelVerb   Flag ajudging the probability of self's being a travelVerb.
.verbdir    Property-pointer for the direction of movement for this verb
            as passed to .travel.


3.1.3.13.  versionInfo

class versionInfo: object

versionInfos are programmatical conveniences which contain information
about library versions, including helper libraries.

Attributes
.bdesc        Brief description of the library and its version.


3.2.  Pianosa defined objects
3.2.0.  articles

articles: object

articles defines the articles allowed in the game.  There are three:
'a', 'and', and 'the'.


3.2.1.  In, On, Under, Behind

In: Position
On: Position
Under: Position
Behind: Position

These four objects define the standard four positions for the Pianosa
libraries.  In and On are required.


3.2.2.  numObj

numObj: object

numObj is a TADS-required programmatical convenience which allows plain
numbers to be used as objects in commands.  The number is assigned to
the .value property upon command entry.


3.2.3.  Pianosa

Pianosa: versionInfo

Pianosa contains version information about the Pianosa libraries.  No
auxiliary Pianosa file defines such version information.


3.2.4.  strObj

strObj: object

strObj is a TADS-required programmatical convenience which allows plain
text to be used as an object in a command.  The text is assigned to the
.value property upon command entry.


3.3.  External Classes and Objects 

There are several objects and classes not included in the Pianosa libraries
which are required for usage.


3.3.0.  required directions

At least one Direction should be defined, .dirTravel equaling &out.  This
is used for departing from chairnesteds and bednesteds.  Its presence is
not verified, and is not technically required, but the chairnested and
bednested code reference it.


3.3.1.  global

global: object

global is the official options and defaults object for Pianosa.  An
attributes list, for now, can be found in ts_std.t.


3.2.2.  menus

All menus are classes, referenced by a call to writeMenu with one argument,
the menu class name.  See the section on ts_menu.t (6.1) for more
information. These menus, with sub-menus where applicable, are included
in ts_std.t. 


3.2.2.0.  optionsMenu

class optionsMenu: Menu

Entered via the "options" verb.


3.2.2.1.  quitMenu

class quitMenu: Menu

Entered via the "quit" verb.


3.2.2.2.  restartMenu

class restartMenu: Menu

Entered via the "restart" verb.


3.2.3.  version

version: object

version is the official information object for the work; despite its name,
it is not a versionInfo object.

Attributes
.sdesc      The title of the work, underlined or quoted or whatever.
.bdesc      A brief description of the work.  Used not by Pianosa, but
            by ts_std.t.
.ldesc      The about text of the work.


3.3.  Inheritance hierarchy

Objects are listed in parentheses; only non-instance objects are listed.
Core classes are listed in bold.  For those classes with multiple
inheritance, multiple listings are made with cross-referencing;
asterisks signify that the class's definition can be found by the
marked superclass's definition, rather than the current category.



    (Pianosa)
object
    thing
        container
            openable
                doorwayframe (also *matchdoorway)
                lockable (also Lockcode)
            qcontainer
                liquidcontainer
                movableActor
                    NPC
                        Actor
                        Actors
                        Actress
                        basicMe
                        (Everyone)
                        Follower
            transparentcontainer
        cover
            qcover
                coverer
        dialthing
        fixedthing
            bednested (also *nestedroom, surface)
            buttonthing
            chairnested (also *nestedroom, surface)
            decoration
            distantthing
            doorway (also Lockcode, *obstacle)
                matchdoorway (also multiobject)
                    doorwayframe (also openable)
            multilocatefixed (also *multiobject)
        foodthing
        item
            clothingitem
            keyitem
        lightsource
        liquid
        mask
            qmask
        readable
        room
            nestedroom
                bednested (also fixedthing, surface)
                    (roomfloor) (also floatingobject)
                chairnested (also surface)
                vehicle
        surface
            bednested (also fixedthing, *nestedroom)
            chairnested (also fixedthing, *nestedroom)
            qsurface
        switchablething
    (articles)
    concept
    Direction
        travelVerb (also *darkVerb)
    floatingobject
        (Everyone) (also *NPC)
        (roomfloor) (also *bednested)
    hearer
    Lockcode
        doorway (also fixedthing, *obstacle)
            matchdoorway (also multiobject)
        lockable (also *openable)
    multiobject
        multilocatefixed (also fixedthing)
        matchdoorway (also *doorway)
            doorwayframe (also openable)
    notified
    (numObj)
    obstacle
        doorway (also fixedthing, Lockcode)
            matchdoorway (also multiobject)
                doorwayframe (also openable)
    Position
        (Behind)
        (In)
        (On)
        (Under)
    Preactor
    Prep
    Reactor
    (strObj)
    versionInfo
        (Pianosa) (found in front of library)
    Verb
        darkVerb
            sysVerb
            travelVerb (also Direction)



    Chapter 4
    The Pianosa Functions


The role of functions in an object-oriented system is frequently
questioned.  The response is that there are some tasks of universal
importance which are best left in universal domain.  If there is a
possibility that an argument object might want to modify the procedure,
then it belongs in a method.  Yet again, however, if the code is repetitive
it may be best left in a function but only accessed through methods.
Such is the debate over functions.

Although many functions are defined within Pianosa, some are left to the
writer to develop -- or at least to a standard interface file such as
ts_std.t.  Others have been exported to the (automatically included)
support file ts_funcs.t; these are, however, classified in the included
set.


4.1.  Pianosa Defined Functions

addScore( amt )
    Increments the score by amt (possibly negative).  Calls global.Score.
aloneContListing( object {, position {, inventory_depth }} )
    Lists the describe-alone contents of object in a certain position
    (default = In).  Returns the total number of spaces listed (see
    invSpaces).  By default, ignores inventory_depth.
checkReach( location, actor, verb, object )
    Verification routine which calls object.cantReach if object cannot be
    reached by actor.
conj( verb_string {, {tense,} rule_object} )
conj( verb_string {, tense} )
    Returns a single-quoted string conjugating verb_string according to
    the rules set by rule_object (defaults to the current actor).
    Optionally, the tense can be set one tense back from the norm by
    setting tense to PAST_TENSE.  See the library for more information.
    Uses the functions getPastParticiple() and getPastTense().
contListing( object {, position {, inventory_depth {, empty_verbosity }}} )
    Lists the contents in position (default = In) around object at a
    certain inventory depth (default = 1) and verbosity.  Each content is
    listed with .idesc (or .pluralidesc if multiple).  If the inventory is
    empty, then either "nothing" will be displayed (e_v = 0), nothing will
    be displayed (e_v = nil), or the emptyposition property will be called
    (e_v = true).
currentActor()
    Returns the current actor.
currentDobj()
    Returns the direct object of the current command.
currentIobj()
    Returns the indirect object of the current command.
currentPrep()
    Returns the indirect-object preposition of the current command.
currentVerb()
    Returns the verb of the current command.
daemonDaemon( parm )
    Daemon organizing the other daemons.  Don't use setdaemon and remdaemon;
    instead, use setDaemon and remDaemon, which interface with this daemon.
    The daemon list is kept in global.daemonlist.
getPastParticiple( verb_string )
    Returns the past participle of the given verb.
getPastTense( verb_string )
    Returns the past tense of the given verb (does not work for 'be').
hungerDaemon( parm )
    Actor hunger, not set in Pianosa.
initLibrary()
    Initiates library routines by setting daemons and calling
    initMultiobject().
initMultiobject()
    Initiates multiobjects.
innerContListing( object {, position {, inventory_depth {, verbosity}}} )
    Lists the visible contents of objects held in positions around object.
    See contListing().
invCount( list )
    Retrieves the gameworld number of to-be-listed objects in a list.
    Three quarters, a dime, and a pair of geese make six objects.
invSpaces( list )
    Retrieves the number of slots for to-be-listed objects in a list.
    Three quarters, a dime, and a pair of geese make three slots.
isIndistinguishable( object_1, object_2 )
    Determines whether the two objects are indistinguishable.  A general
    routine called by .distinguish.
nextTurn( parm )
    Handles the passage of time, set in initLibrary().
notifiedDaemon( parm )
    Notifies all objects of class notified by calling object.notification.
parseErrorParam( error_number, default_message, ... )
    Returns an error message;  see standard TADS documentation.  Pianosa
    defines this function, but calls modifyParseError with the same
    configuration as that received.
preinit()
    Initiates at compile time object.uberlocate, global.floatingList,
    global.lampList; calls preinitAdaptables() first.
preinitAdaptables()
    Initiates at compile time both Positions and Directions.
reactorDaemon( parm )
    Handles Reactors, set in initLibrary().
remDaemon( pointer, parameter {, object } {, clear_all_instances } )
    Removes a daemon from global.daemonlist.  pointer can be either
    a function or a method;  if a method, object must be included.
    clear_all_instances will remove all instances of that function-
    parameter pair; otherwise, only one will go.
sayDirection( direction_property )
    Returns a list of direction words for the given direction.
setDaemon( pointer, parameter {, object } {, place } )
    Places the daemon in global.daemonlist with the given parameter
    at the given place (by default, just past the middle of the list).
    Can be either a function or a method pointer.
showScore( points, turns )
    Updates the score readout in non-HTML interpretations.
sleepDaemon( parm )
    Actor sleep, not set in Pianosa.
sumBulk( list )
    Sums the .totalbulk properties of all objects in list.
sumWeight( list )
    Sums the .totalweight properties of all objects in list.
travelProp( direction_property )
    Returns the ".go" property for the given direction.


4.2.  General Functions

These functions are found in ts_funcs.t

execute( actor, verb {, direct_object {, preposition, indirect_object {, time_passes }}} )
    Executes a command with execCommand, also allowing the current command
    to finish with grace.  If time passes, runs daemons and fuses.
gac( class {, property {, value {, argument }}} )
    Gets all objects of a certain class in the entire gameworld.  If property
    exists, checks it on the object to see if it matches with value
    (default = true) before including the object; if argument exists,
    supplies it to the property.
gacal( class, list {, property {, value {, argument}}} )
    Gets all objects of a certain class in a list, including visible contents
    of the objects.
gacil( class, list {, property {, value {, argument}}} )
    Gets all objects of a certain class in a list.
getIndexList( list, value )
    Returns a list of all indeces in the list with the given value, or
    returns nil for none such.
getOutput( function_pointer )
    Returns the outcapture() for a function.
getOutput( object, property_pointer )
    Returns the outcapture() for a method.
imperative( a, b )
    IMP operation.  Returns nil only if a is true and b is nil.
inputLine()
    Retrieves a line of input, setting the input font.
listListing( list )
    Lists the contents of a list, using .thedesc.
listWithout( list, index )
    Removes a given index from a list.
pac()
    Prompt for a keypress, then clear the screen.
_rand( number )
    Adjusted random-number algorithm.
redirect( actor, verb {, direct_object {, preposition, indirect_object}} )
    Executes a command with execCommand, aborting the current command.
resource( resource_string {, options_string } )
    Attempts to display the given resource;  if cannot, returns true.
    options_string is passed directly into the HTML code.
sayDate( date_string )
    Displays the date from the string, which has the format "Mth dd yyyy",
    in the format "Month d, yyyy".  This former format is that used by
    __DATE__.
sayNumber( number )
    Displays the number (-100 <= number <= 100) in words; outside of this
    spectrum, just displays the number.
sayValue( value )
    Displays the given value, like so:
        Double:     "(double-quoted string)"
        Function:   "(function pointer)"
        List:       "[" value1 value2 "]"
        Nil:        "nil"
        Number:     value
        Object:     "(object: " value.sdesc ")"
        Property:   "(property pointer)"
        Single:     "'" value "'"
        True:       "true"
setHer( object )
    Sets the "her" pronoun to object.
setHim( object )
    Sets the "him" pronoun to object.
setThem( object|list )
    Sets the "them" pronoun to an object or a list.
sublist( list, start {, end} )
    Returns part of a list.
tabs( number {, string } )
    Displays number instances of string (default = "\t").


4.3.  External Functions

All functions here are supplied by ts_std.t.

conclude()
    Ends the work.
die()
    Kills off the player character.
init()
    Initiates when the work is loaded.
initRestart( parameter )
    Initiates when the work is restarted.
modifyParseError( error_number, default_message, ... )
    Allows modifications to parserErrorParam without having to overwrite
    what's in Pianosa.  Returning a list causes parserErrorParam
    to return the first content of that list.  ts_std.t defines
    this emptily, ready to be replaced.
pardon()
    Message called by the parser when the player types a blank line.
rank()
    Function displaying a complete rank report.
specialPreinit()
    Special compile-time initiation routines go here.
stumble()
    Message called by .cantexit when travel occurs in the dark.
terminate()
    Message called by ts_std.t's conclude() when quitting.



    Chapter 6
    Supplemental Files


There are six supplemental files: ts_codes.t, ts_funcs.t, ts_menu.t,
ts_sense.t, ts_std.t, and ts_grid.t.  The first two are included
within Pianosa and provide core functionality.  ts_std.t includes
Pianosa and ts_menu.t, and provides standard functionality.  ts_grid.t
is an optional file which implements a randomly generated
three-dimensional dynamically-constructed grid.  ts_sense.t is a
sense-passing library extension.

6.1.  ts_codes.t

These are the precompiler codes as defined by Michael J. Roberts
in adv.t. The file is up to date with adv.t v2.5.1.  This file may be
harmlessly included in any programming endeavor without risk of code
bloat, as it defines nothing which will be retained in a non-debugging
version of the gamefile.

6.2.  ts_funcs.t

These functions are of general programming use, and so are drawn into
their own file; those functions left in Pianosa are related directly
to IF programming.  For descriptions of the functions, see 4.2.

6.3.  ts_grid.t

There's a loophole in Pianosa.  The .travel() routine allows direction
properties to return a list of two elements: the first element must be
an object, on which the .create routine will be called with three
arguments: the second element, the source object, and the direction.

Example:

  GreatHall: room
    east = [ MirrorHall 5 ]
  ;

Going east will result in the call MirrorHall.create( 5, GreatHall, &east )

ts_grid.t brings in a simple application of this, dynamically generated
pathways, which it accomplishes through the dynamicgrid object and the
grid class.


class dynamicgridclass: room

Attributes
.xposProp   Property pointer which will contain the location information
            for the x coordinate.
.yposProp   Property pointer which will contain the location information
            for the y coordinate.
.zposProp   Property pointer which will contain the location information
            for the z coordinate.

Methods
.approve( x, y, z, source_object, direction_pointer )
    Determines whether or not a room at coordinates (x,y,z), being reached
    from source_object via the given direction, is valid.
.create( x, y, z, source_object, direction_pointer )
    Creates an object for the room at (x,y,z) and calls .initiate upon it.
.dynamicLinkTo( target_object, direction_pointer, deltax, deltay, deltaz, gridclass )
    Links self to target_object and returns true if the action should be
    reciprocated (all linking is done beginning at the new object;
    back-links are only done when .dynamicLinkTo returns true)
.dynamicLookup( x, y, z )
    Returns the object for the room at (x,y,z) or nil if none exists or
    has been created yet.
.initiate
    Initiates the dynamic object.
.translateProp( deltax, deltay, deltaz )
    Returns the property corresponding to the given changes in x, y, and z,
    or nil if none exists.  Setup for the standard directions; x is west-
    east, y is south-north, and z is altitude.
.xconvert( direction_pointer )
    Converts the given property into its corresponding change in x.
.yconvert( direction_pointer )
    Converts the given property into its corresponding change in y.
.zconvert( direction_pointer )
    Converts the given property into its corresponding change in z. 

Only .approve, .initiate, and the three location properties are necessary
in a class definition.

To use a grid system, define an object of the grid class, give it location
attributes, and assign one or more direction properties the value:

    [ dynamicgrid {grid class name} ]

An excellent example of grids in action is the gridskeleton.t file. 

6.4.  ts_menu.t

The following is excerpted and modified from a letter to Chad Schultz, to
whom I owe a debt of gratitude -- you see, he forced me to write this. 


>And how do I use ts_menu.t?

It's a supplemental library which establishes object-oriented menus. You
don't have to do anything;  it's automatically included [by ts_std.t].

Now, if you mean "How do I use it to write menus?", that's a harder question. 

The first thing you need is a menu class.  A complete definition:

class askMenu: menuclass
   menuCaseSensitive = nil         // default
   menuTitle = "Ask about what?"    // displayed above the menu    menuKeyed = nil            // keypress (true) or line input
   menuPrompt = ">"            // displayed below the menu, where the                         //  player types input
   orderMenu( lst, lvl, parm ) = {
       local i, newlist := [], len := length( lst );
       for (i := 1; i <= len; ++i)
           if (lst[i].isKnownAbout) newlist += lst[i];
       return newlist;
   }
// order/modify the menu, where lst is a list of every object of this menu
//  class and lvl is how deep this menu is embedded.  Should return a list of
//  objects, which do not necessarily have to be of the menu class. ;

You then define menu items by declaring them as being of the menu class.
Menu items can be gameworld objects.

Momma: Actress, askMenu
   isKnownAbout = true
   noun = 'momma' 'mother' 'mom' 'mommy' 'mommie' 'ma'
   on = mommabed
   posture = Lie
   menuDesc = "Momma"        // a description of the menu item
   menuKeys = [ 'momma' ]    // a list of all inputs which should
                             //  be taken to mean this object
   menuAction( cls, lvl, dobj ) = {
       self.ioAskAbout( Me, dobj );
       return true;
   }
;


In order to display a menu, call writeMenu( menuclass ).  writeMenu takes two
optional arguments:  the first being the depth (i.e. is this menu being
displayed within another menu or not) and the second being parm, a
completely unrestricted parameter which is passed to .menuAction, .orderMenu,
.dispMenu, and .dispMenuItem.

writeMenu() gets all the menu class objects with a specialized gac() that
verifies that .disallowMenu( parm ) is nil for each object.  It then passes
the whole thing through .orderMenu and calls .dispMenu.  From this point on,
handling is divided as to whether the menu has .menuKeyed or not.

.menuKeyed = true.  writeMenu() compiles a list of all the valid keys for
this object (in debug mode, there's a special key '$' which aborts the
menu and returns true), prints .menuPrompt and then retrieves valid input.
It finds the first object in the list with a .menuKeys entry matching the
input and calls .menuAction on that object.

.menuKeyed = nil.  writeMenu() prints .menuPrompt, gets input and (in debug
mode) tests to see if it's the special escape sequence '$'.  Otherwise, it
cycles through the menu items and calls .checkKey on each, making a list of
those returning true.  If only one returns true, .menuAction is called on it;
if none return true but one returns 1, .menuAction is called on that;
otherwise, it repeats this process.


On menu items:
.checkKey( key, class, level, parameter )
    By default, just checks to see if the key is in self's .menuKeys list.
    True for absolutely approved, 1 for conditionally approved.
.dispMenuItem( class, level, index, parm )
    By default, goes to the next line, tabs once, and calls .menuDesc.
.menuAction( class, level, parm )
    Can do anything it wants.  It should return one of three things, though:
        true        to tell writeMenu to abort the entire menu system
        a number    to move up a certain number of menus (1 goes back one
                    menu)
        nil         to just return to the same menu from which it was called
                    By default, if self.menuList <> [], then it cycles to the
                    next value (the current is stored in self.value) in
                    .menuList and returns nil.

On class:
.menuClear
    If true, the screen is cleared by the default .dispMenu.
.menuPrompt
    Defaults to ">".
.dispMenu( level, parm, list )
    Prints .menuTitle and then cycles through list, calling .dispMenuItem
    on each object.
.orderMenu( list, depth, parm )
    By default, does special behavior.  If the depth is only, it only adds
    menuQuit (a simple "abort menu" item);  if the depth is more than 1,
    it adds menuBack ("go to previous menu") too.


6.5.  ts_sense.t

ts_sense.t is a sense-passing system which is not integrated in the rest of
Pianosa for performance concerns.  It's all fairly simple: each sense is
given its own sensory object -- although only three `senses' are defined
in ts_sense.t -- and the whole thing revolves around one method, .cansense. 


class Sense: object

Attributes
.blocksenseProp     Property for the specific sense-blocking method for
                    this sense.
.issensibleProp     Property for the method determining whether an object
                    is sensible.
.positionProp       Property for the "contents sensible" property on a
                    Position object (or nil).
.quicksensibleProp  Property for a list of objects automatically sensible
                    to the player.


modify thing

Attributes
.audiblelist    List of objects automatically audible to the player.
.reachable      List of objects automatically reachable by the player.
.visiblelist    List of objects automatically visible to the player. 

Methods
.blockhearing( from_object, to_object, stepcount )
    See .blocksense.  The default version of .blockhearing defaults to
    .blockvision.
.blockreach( from_object, to_object, stepcount )
    See .blocksense.
.blocksense( sense, from_object, to_object, stepcount )
    Determines whether a sense can pass from from_object to to_object
    at a certain number of steps.  Calls the appropriate sense-blocking
    method, e.g. .blockreach.
.blockvision( from_object, to_object, stepcount )
    See .blocksense.
.cansense( sense, object {, stepcount } )
    Determines whether self can sense object using sense at a given
    number of steps away from each other (default is 1).  stepcount is
    not taken into account by .cansense, but is instead passed on to
    individual .blocksense routines which can then do as they will.
    .cansense will be discussed in a moment.
.isreachable( obj )
    Re-routed through .cansense.
.isvisible( obj ) 
    Re-routed through .cansense.
.locatetree( object )
    Returns a location-list from self up to object.  If the pipe is in
    the bowl is on the table is on the floor in the car in the driveway,
    then pipe.locatetree( carfloor ) returns:
        [ pipe In bowl On table On carfloor ]
    If the argument is not in the full location-list, the full location
    list will be returned.

The .cansense mechanism takes the following steps:

1.  If object is inside and sensible to any object in self's quicksensible
    list, self can sense object.
2.  The relationship between the two objects must be determined.
    a.  If self is inside object, .cansense is simply called up the
        location list.
    b.  If object is inside self, .cansense is not-so-simply called down
        the location list.
    c.  If self and object have a common parent (determined using location
        lists), .blocksense is checked on the intersection, and then
        .cansense is called up to that parent and then down to object.

The three senses provided for in ts_sense.t are Vision, Reach, and Hearing. 


6.6.  ts_std.t

The standard definitions file.  Included are such diverse elements as: 

6.6.0.  Functions
addfootnote( message )
    Adds a footnote with a given message.  Footnotes are accessible via
    the footnote verb.
conclude()
    Ends the game; calls terminate() and quit().
die( { message } )
    Displays a message (default = `You have died.') and calls endMenu.
init()
    Begins the game; sets Me as the player object, calls initCommon(),
    commence(), and then parserGetMe().startAt().
initCommon()
    Calls initLibrary(), sets hunger and sleep daemons, and sets up
    the title and about box.
initRestart()
    Begins the game after a restart.  Calls initCommon() and sets
    global.restarting true.
pardon()
    Called by the parser when a blank line is typed.
rank()
    Gives the score readout.
stumble()
    Called by Pianosa when traveling in the dark.
terminate()
    Prints a message when quitting; called by conclude().

6.6.1.  global


global is the options object in Pianosa.  There is an enormous amount of
information stored on this single object.  Behold.

Attributes
.directionlist  List of all the direction objects in the game.
.exitlist       List of all proerty pointers of possible exits from a room.
.floatinglist   List of floating objects.
.footnotelist   List of footnote texts.
.hungerTime     Number determining default time between necessary meals.
.hungryTime     Number determining default time elapsed since the last meal
                for all actors.
.initRestartParam   Parameter passed to initRestart.
.inventall      Flag determining whether inventories should be given in
                tall or wide forms.
.jostleJump     Amount of default jostle passed to objects when a player
                jumps up and down.
.jostlePutInto  Amount of default jostle passed to objects by putInto.
.jostleThrow    Amount of default jostle passed to thrown objects.
.lamplist       List of all lamp objects in the game.
.maxScore       Number determining the maximum score.
.minScore       Number determining the minimum score.
.Misunderstand  A message stating that whatever was done is not understood.
.positionlist   List of all position objects in the game.
.restarting     Flag determining whether the game has been restarted this
                session.
.score          Number determining the current score.
.sleepTime      Number determining default time between necessary naps.
.sleepyTime     Number determining default time elapsed since the last nap
                for all actors.
.sleepDuration  Number determining how long an NPC sleeps for.
.thisturn       Number determining which turn this is right now.
.verbose        Flag determining whether the game is in verbose or terse
                mode (ts_std.t: true).
.verboseLook    Flag determining whether switching to verbose mode should
                automatically look around (ts_std.t: nil).
.verboseScore   Flag determining whether the player should be notified of
                score changes (ts_std.t: true).

Methods
.hasHTML
    Determines whether the game is in HTML mode or not.
.hasAmbient
    Determines whether the game has ambient noises turned on or not.
.hasBGAmbient
    Determines whether the game has background ambient noises
    turned on or not.
.hasMusic
    Determines whether the game has music turned on or not.

6.6.2.  directions

ts_std.t defines the twelve standard directions: north, south, east,
west, northeast, southeast, northwest, southwest, in, out, up, and down.

6.6.3.  menus

ts_std.t includes four sets of menus:

endMenu         Called after death/conclusion.
optionsMenu     Called after an options command.
quitMenu        Called after a quit command.
restartMenu     Called after a restart command.

optionsMenu, in turn, defines two submenus:  soundMenu and displayMenu.

6.6.4.  miscellaneous

Me: basicMe, notified startAt = (self.travelTo( startroom ));
