/* Copyright (c) 2000 by Kevin Forchione. All Rights Reserved. */
/*
* TADS ADV.T/STD.T LIBRARY EXTENSION
* WALLS.T
* version 1.1
*
* walls.t implements walls, celings, and floors for actor
* locations. Simply #include the module after sense.t and your
* rooms will have walls, etc. Rooms with the attribute isOutside
* set to true will not have walls or ceilings.
*
*----------------------------------------------------------------------
* REQUIREMENTS
*
* + HTML TADS 2.5.1 or later
* + Requires ADV.T and STD.T
* + Requires SENSE.T 3.1
* + Should be #included after SENSE.T
*
*----------------------------------------------------------------------
* IMPORTANT LIBRARY INTERFACE AND MODIFICATION
*
* This module modifies the functioning of the following ADV.T
* listing functions:
*
* Module performs the following process:
*
* 1. Define the abstract class
* a. Setup instance
* b. Check requiresInstance
* c. Check for cleanup
* d. Clean up
* 2. Define walls, ceiling, and floor classes
* 3. Put abstract objects in scope
* 4. Disambiguate abstract / non-abstract objects
* 5. Redirect command from abstract to instance
* 6. Delete the instance
*
* In addition this module modifies the following in Sense.t:
*
* + deepverb validXo()
* + deepverb disambigXobj()
* + deepverb cantReach()
*
*----------------------------------------------------------------------
* COPYRIGHT NOTICE
*
* You may modify and use this file in any way you want, provided that
* if you redistribute modified copies of this file in source form, the
* copies must include the original copyright notice (including this
* paragraph), and must be clearly marked as modified from the original
* version.
*
*------------------------------------------------------------------------------
* REVISION HISTORY
*
* 26-Jan-2000 Creation.
* 30-Jan-2000 Modified creation location of instances.
* Modified floor to move objects to the room instead
* of the floor contents, except for actors sitting or
* lying on the floor.
*/
#define __WALLS_MODULE_
#ifndef __SENSE_MODULE_
#error THIS MODULE REQUIRES THAT YOU #INCLUDE SENSE.T
#endif
#pragma C+
/*======================================================================
* A B S T R A C T C L A S S
*====================================================================*/
class abstract: object
isabstract = true
/*
* Setup an instance of our abstract object. This object is not
* considered abstract. It is moved into the actor's location and
* the clean-up daemon is started.
*/
newAbstract(actor) = {
local obj, loc;
if (self.requiresInstance(actor))
{
obj = new self;
loc = scopeCeiling(actor, nil, &access_reachable);
obj.moveInto(loc);
obj.isabstract = nil;
notify(obj, &checkForCleanup, 0);
}
else
obj = self;
return obj;
}
/*
* Used to check if the actor's location requires an instance of
* the abstract. If not then the "You don't see any foo..." message
* is displayed.
*/
requiresInstance(actor) = { return true; }
/*
* Don't delete the object if it is holding things or the actor
* location == this object or the object is being referenced by a
* command. Because daemons run before endCommand we do not delete
* the object if either it or its class is referenced by a command
* to allow for endCommand() each_turn style processing.
*/
checkForCleanup = {
if (length(self.contents) > 0
|| command.actorPtr.location == self
|| (command.dobjPtr && isclass(self, command.dobjPtr))
|| (command.dobjPtr && self == command.dobjPtr)
|| (command.iobjPtr && isclass(self, command.iobjPtr))
|| (command.iobjPtr && self == command.iobjPtr))
return;
else self.cleanup;
}
/*
* unnotify the daemon for this object, move it into nil (to clean
* up the object tree) and then delete it.
*/
cleanup = {
unnotify(self, &checkForCleanup);
self.moveInto(nil);
delete self;
}
;
/*======================================================================
* W A L L S A N D C E I L I N G
*====================================================================*/
/*
* class wall: abstract, decoration
*
* The wall class has been defined as an abstract decoration, which
* means that most actions will be regarded as unimportant.
*
* This class defines requires instance to check the actor.location
* isOutside attribute. If the attribute is true then we don't require
* an instance of wall; otherwise one is dynamically created.
*/
class wall: abstract, decoration
requiresInstance(actor) = {
if (actor.location.isOutside) return nil;
return true;
}
;
/*======================================================================
* T H E F L O O R
*====================================================================*/
/*
* floor: abstract, fixeditem, surface
*
* The floor is treated slightly differently because we can sit on it
* and put things on it. The actor doesn't actually walk on the floor,
* and it will behave like a nestedroom when they enter it.
*/
floor: abstract, fixeditem, surface
noun = 'floor' 'ground'
sdesc = "floor"
adesc = "the floor"
isenterable = true
isFloor = true
ldesc = {
"It lies beneath you. ";
if (itemcnt(self.location.contents))
{
"%You% see%s% <<listcont(self.location)>> here. ";
listcontcont(self.location);
}
}
ioPutOn(actor, dobj) =
{
dobj.doDrop(actor);
}
ioPutIn(actor, dobj) =
{
dobj.doDrop(actor);
}
ioThrowAt(actor, dobj) =
{
"Thrown. ";
dobj.moveInto(actor.location);
}
;
/*======================================================================
* D E E P V E R B M O D I F I C A T I O N S
*====================================================================*/
modify deepverb
/* put abstract direct objects into scope */
replace validDo(actor, obj, seqno) = {
command.dobjPtr = obj;
if (obj.isabstract) return true;
if (testScope(actor, obj))
return true;
else
return (testScope(actor, obj, self.dorequires));
}
/* put abstract indirect objects into scope */
replace validIo(actor, obj, seqno) = {
command.iobjPtr = obj;
if (obj.isabstract) return true;
if (testScope(actor, obj))
return true;
else
return (testScope(actor, obj, self.iorequires));
}
/* if abstract has same vocab remove it */
disambigDobj(actor, prep, dobj, verprop, wordlist, objlist, flaglist,
numberWanted, isAmbiguous, silent) = {
local i, j, len, cnt = 0, abslist = [], newlist = [];
local vi = [], vj = [];
if (!isAmbiguous) return objlist;
len = length(objlist);
for (i = 1; i <= len; ++i)
{
for (j = i+1; j <= len; ++j)
{
vi = [], vj = [];
if (objlist[i] == objlist[j]) continue;
vi += getwords(objlist[i], &adjective);
vi += getwords(objlist[i], &noun);
vi += getwords(objlist[i], &plural);