#charset "us-ascii" /* Tads-3 Container with Lid Steve Breslin, 2004 email: versim@hotmail.com ==== Licence: Everyone is free to use this, but please provide me with all improvements and modifications. ==== This extension provides a ContainerWithLid class which you can use to implement any kind of container which you want to close with a separate object (the lid). You can make bottles with caps, boxes with lids, etc. It's quite easy to use this extension: simply include it in your project, and write an object which inherits from ContainerWithLid; then include in the container's lidList any object which can "lid" the container. */ #include #include // example objects: largeBottle: ContainerWithLid 'large bottle' 'large bottle' "It's a large bottle.\n" lidList = [largeCap] location = me ; largeCap: Thing 'large cap' 'large cap' "It's a large cap.\n" location = me bulk = 2 ; smallBottle: ContainerWithLid 'small bottle' 'small bottle' "It's a small bottle.\n" lidList = [smallCap] location = me ; smallCap: Thing 'small cap' 'small cap' "It's a small cap.\n" location = me bulk = 1 ; class ContainerWithLid: ComplexContainer, PreinitObject /* A list of objects which can be used to close this object. */ lidList = [] /* We need to provide our special subContainer and subSurface for * each instance of the ContainerWithLid class. */ execute() { if (subContainer && subContainer.location != self) { subContainer = subContainer.createInstance(); subContainer.moveInto(self); subContainer.lexicalParent = self; } if (subSurface && subSurface.location != self) { subSurface = subSurface.createInstance(); subSurface.moveInto(self); subSurface.lexicalParent = self; } } /* The subSurface is where the lid goes */ subSurface : ComplexComponent, Surface { /* This handles putting a lid on the ContainerWithLid object */ iobjFor(PutOn) { check() { /* if there's already something on the surface, we * assume it's a lid. So we don't allow another lid. */ if (contents.length) { reportFailure('There\'s already a lid on it.\n'); exit; } /* If the object isn't in our list of acceptable lids, * the lid doesn't fit. */ if (!location.lidList.indexOf(gDobj)) { reportFailure('It doesn\'t fit.\n'); exit; } inherited(); } /* place the lid on the surface, and close the container */ action() { "You close <> with <>. "; gDobj.moveInto(self); location.subContainer.makeOpen(nil); } } /* if an object is removed from the surface, assume it's the * lid. with the lid removed, the object is open. */ notifyRemove(obj) { inherited(obj); location.subContainer.makeOpen(true); } } /* The subContainer is where the contents of the object go, * excepting the lid of course. */ subContainer : ComplexComponent, OpenableContainer { /* When someone tries simply to close the object, we redirect * processing, asking "what (lid) do you want to put on the * container?" */ dobjFor(Close) { action() { PutOnAction.retryWithMissingDobj(gAction, ResolveAsker); } } /* We don't actually want the lid to go on the subContainer, * but on the subSurface. */ iobjFor(PutOn) remapTo(PutOn, DirectObject, location.subSurface) /* Opening the container means taking the cap from the * container. */ dobjFor(Open) { action() { if (location.subSurface.contents) { "You remove <> from <>.\n"; replaceAction(Take, location.subSurface.contents[1]); } } } /* We're initially open if there's no lid on the subSurface. */ initiallyOpen() { return (location.subSurface.contents == []); } /* Only things smaller than the lid can fit through the * container's mouth. */ canFitObjThruOpening(obj) { return (location.lidList[1].getBulk == 0 || obj.getBulk < location.lidList[1].getBulk); } } ; /* treat "cap X with Y" and "close X with Y" the same as "put Y on X" */ VerbRule(CapWith) ('cap' | 'close') singleIobj 'with' singleDobj : PutOnAction verbPhrase = 'cap/capping (what) (with what)' ; /* treat "cap X" the same as "close X" */ VerbRule(Cap) 'cap' singleDobj : CloseAction verbPhrase = 'cap/capping (what)' ;