/* Copyright (c) 1999, 2000 by Kevin Forchione. All Rights Reserved. */ /* * TADS ADV.T/STD.T LIBRARY EXTENSION * DOORS.T * version 1.0 * * This module implements a floatingItem object that behaves like * two TADS doorways. This implementation is easier to work with * and modify than the earlier doorItem class. * *---------------------------------------------------------------------- * REQUIREMENTS * * + HTML TADS 2.5.0 or later * + Requires ADV.T and STD.T * + Should be #included after ADV.T and STD.T. * *---------------------------------------------------------------------- * IMPORTANT LIBRARY INTERFACE AND MODIFICATION * * None. * *---------------------------------------------------------------------- * 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 * * 23-Oct-99: Creation. */ #define __DOORS_MODULE_ #pragma C+ /* * door: floatingItem, fixeditem, obstacle * * A door is an obstacle that impedes progress when it is closed. * Unlike the doorway, a door is a floatingItem and should not have its * location attribute coded. Instead, use the foundin list to indicate * the rooms in which the door is to be found. * * To make a simple two-sided door you need only code both room * objects in the foundin list of the door: * * foundin = [ hallway, kitchen ] * * To make a one-sided door, code the foundin list with the room * object in which the door is to be found, and the doorto list * with the room object to which the door leads: * * foundin = hallway * doorto = kitchen * * If you want a door that returns rooms different from those it is * found in, simply code both the foundin list and doorto list * accordingly, each element of the doorto list must have a * corresponding foundin element: * * foundin = [ hallway, kitchen ] * doorto = [ foyer, hallway ] * * From the hallway the door leads to the foyer, but from the kitchen * it leads to the hallway. */ class door: doorway, floatingItem foundin = [] doorto = nil location = { local f, actor, loc, dloc, foundList; if (self.foundin == nil) return nil; actor = parserGetObj(PO_ACTOR); if (actor == nil) actor = parserGetMe(); loc = actor; while(loc) { dloc = loc; loc = loc.location; } // // convert self.foundin into a list // switch(proptype(self, &foundin)) { case DTY_NIL: foundList = []; break; case DTY_OBJECT: foundList = [ self.foundin ]; break; case DTY_LIST: foundList = self.foundin; break; default: return nil; } if (find(foundList, dloc)) return dloc; else return nil; } findDest(actor) = { local f, loc, foundList, destList; loc = self.location; // // convert self.foundin into a list // switch(proptype(self, &foundin)) { case DTY_NIL: foundList = []; break; case DTY_OBJECT: foundList = [ self.foundin ]; break; case DTY_LIST: foundList = self.foundin; break; default: return nil; } // // convert self.doorto into a list // switch(proptype(self, &doorto)) { case DTY_NIL: destList = []; break; case DTY_OBJECT: destList = [ self.doorto ]; break; case DTY_LIST: destList = self.doorto; break; default: return nil; } // // door is linked to room directions, but no foundin // list exists. Simply return the noexit message. // if (length(foundList) == 0) { return self.noexit; } // // We don't have a doorto list. Use the foundin list, // which must have 2 elements. // if (length(destList) == 0) { if (length(foundList) != 2) { "\n[TADS-DOORS-001] When omitting the doorto list, the foundin list should contain 2 elements.\n"; return nil; } if (loc == foundList[1]) return foundList[2]; else return foundList[1]; } // // We have a doorto list, each element should correspond to // an element in the foundin list. // if (length(foundList) != length(destList)) { "\n[TADS-DOORS-002] <> requires a corresponding doorto element for each foundin element.\n"; return nil; } // // Search for the actor location in the foundin list. // f = find(foundList, loc); // // Door isn't in the actor location. return noexit. // if (f == nil) { return self.noexit; } // // return the corresponding doorto element // return destList[f]; } destination = { local actor = parserGetObj(PO_ACTOR); if (actor == nil) actor = parserGetMe(); // // The door location is nil or the actor's location doesn't // match any object in the foundin list // if (self.location == nil) return self.noexit; if (self.isopen) return self.findDest(actor); else if (!self.islocked && !self.noAutoOpen) { self.setIsopen(true); "(Opening << self.thedesc >>)\n"; return self.findDest(actor); } else { "%You%'ll have to open << self.thedesc >> first. "; setit(self); return nil; } } setIsopen(setting) = { /* update my status */ self.isopen = setting; } setIslocked(setting) = { /* update my status */ self.islocked = setting; } noexit = { "%You% can't go that way. "; return nil; } ; /* * lockableDoor: door * * This is just a normal door with the islockable and * islocked properties set to true. Fill in the other * properties (foundin and doorto) as usual. If * the door has a key, set property mykey to the key object. */ class lockableDoor: door islockable = true islocked = true ; #pragma C-