A "complex" container is an object that can have multiple kinds of contents simultaneously. For example, a complex container could act as both a surface, so that some objects are sitting on top of it, and simultaneously as a container, with objects inside.

The standard containment model only allows one kind of containment per container, because the nature of the containment is a feature of the container itself. The complex container handles multiple simultaneous containment types by using one or more sub-containers: for example, if we want to be able to act as both a surface and a regular container, we use two sub-containers, one of class Surface and one of class Container, to hold the different types of contents. When we need to perform an operation specific to a certain containment type, we delegate the operation to the sub-container of the appropriate type.

Note that the complex container itself treats its direct contents as components, so any component parts can be made direct contents of the complex container object.

If you want to include objects in your source code that are initially located within the component sub-containers, define them as directly within the ComplexContainer object, but give each one a 'subLocation' property set to the property of the component sub-container that will initially contain it. For example, here's how you'd place a blanket inside a washing machine, and a laundry basket on top of it:

+ washingMachine: ComplexContainer 'washing machine' 'washing machine'
subContainer: ComplexComponent, Container { etc }
subSurface: ComplexComponent, Surface { etc }
; *.
++ Thing 'big cotton blanket' 'blanket'
subLocation = &subContainer
; *.
++ Container 'laundry basket' 'laundry basket'
subLocation = &subSurface

The subLocation setting is only used for initialization, and we automatically set it to nil right after we use it to set up the initial location. If you want to move something into one of the sub-containers on the fly, simply refer to the desired component directly:


class ComplexContainer :   Thing

Superclass Tree   (in declaration order)


Subclass Tree  


Global Objects  


Summary of Properties  

allSubLocations  isLocked  isOpen  subContainer  subRear  subSurface  subUnderside 

Inherited from Thing :
actorInAName  actorInName  actorInPrep  actorIntoName  actorOutOfName  actorOutOfPrep  aDisambigName  allStates  aName  brightness  bulk  canBeHeard  canBeSeen  canBeSmelled  canBeTouched  canMatchHer  canMatchHim  canMatchIt  canMatchThem  circularlyInMessage  collectiveGroup  collectiveGroups  contents  contentsListed  contentsListedInExamine  contentsListedSeparately  contentsLister  descContentsLister  described  disambigEquivName  disambigName  distantDesc  distantInitSpecialDesc  distantSpecialDesc  distinguishers  dummyName  effectiveFollowLocation  equivalenceKey  equivalentGrouper  equivalentGrouperClass  equivalentGrouperTable  esEndingPat  explicitVisualSenseInfo  getState  globalParamName  holdingIndex  iesEndingPat  initDesc  initNominalRoomPartLocation  initSpecialDesc  inlineContentsLister  isEquivalent  isHer  isHim  isInInitState  isKnown  isLikelyCommandTarget  isListedAboardVehicle  isMassNoun  isPlural  isProperName  isQualifiedName  isThingConstructed  isTopLevel  listName  listWith  location  lookInLister  moved  name  nameDoes  nameSays  nameSees  notTravelReadyMsg  objectNotifyList  objInPrep  obscuredInitSpecialDesc  obscuredSpecialDesc  owner  patElevenEighteen  patIsAlpha  patLeadingTagOrQuote  patOfPhrase  patOneLetterAnWord  patOneLetterWord  patSingleApostropheS  patTagOrQuoteChar  patUpperOrDigit  patVowelY  pluralDisambigName  pluralName  pronounSelector  roomDarkName  roomLocation  roomName  seen  sightPresence  sightSize  smellPresence  smellSize  soundPresence  soundSize  specialContentsLister  specialDesc  specialDescBeforeContents  specialDescListWith  specialDescOrder  specialNominalRoomPartLocation  suppressAutoSeen  takeFromNotInMessage  theDisambigName  theName  theNamePossNoun  tmpAmbient_  tmpAmbientFill_  tmpAmbientWithin_  tmpFillMedium_  tmpObstructor_  tmpObstructorWithin_  tmpPathIsIn_  tmpTrans_  tmpTransWithin_  touchPresence  touchSize  verbCan  verbCannot  verbCant  verbEndingSD  verbEndingSEd  verbEndingSMessageBuilder_  verbMust  verbToCome  verbToDo  verbToGo  verbToLeave  verbToSay  verbToSee  verbWill  verbWont  weight 

Inherited from VocabObject :
canResolvePossessive  disambigPromptOrder  pluralOrder  vocabLikelihood  vocabWords  weakTokens 

Summary of Methods  

addToContents  beforeMovePushable  dobjFor(Board)  dobjFor(Close)  dobjFor(Enter)  dobjFor(GetOffOf)  dobjFor(GetOutOf)  dobjFor(LieOn)  dobjFor(Lock)  dobjFor(LockWith)  dobjFor(LookBehind)  dobjFor(LookIn)  dobjFor(LookUnder)  dobjFor(Open)  dobjFor(SitOn)  dobjFor(StandOn)  dobjFor(Unlock)  dobjFor(UnlockWith)  examineStatus  getAllForTakeFrom  getNestedRoomDest  getNestedRoomSource  iobjFor(PutBehind)  iobjFor(PutIn)  iobjFor(PutOn)  iobjFor(PutUnder)  mainMoveInto  makeLocked  makeOpen  notifyComponentOfMove  tryMovingObjInto  tryPuttingObjInBag 

Inherited from Thing :
acceptCommand  addAllContents  addDirectConnections  addObjectNotifyItem  addToSenseInfoTable  adjustLookAroundTable  adjustThrowDestination  afterAction  afterTravel  allContents  aNameFrom  aNameObj  aNameOwnerLoc  announceDefaultObject  appendHeldContents  atmosphereList  baseMoveInto  basicExamine  basicExamineFeel  basicExamineListen  basicExamineSmell  basicExamineTaste  beforeAction  beforeTravel  buildContainmentPaths  cacheAmbientInfo  cacheSenseInfo  cacheSensePath  canBeHeardBy  canBeSeenBy  canBeSensed  canBeSmelledBy  canBeTouchedBy  canDetailsBeSensed  canHear  canMatchPronounType  canMoveViaPath  cannotGoShowExits  cannotReachObject  cannotSeeSmellSource  cannotSeeSoundSource  canOwn  canSee  canSmell  canThrowViaPath  canTouch  canTouchViaPath  checkActorOutOfNested  checkBulkChange  checkBulkChangeWithin  checkMoveViaPath  checkStagingLocation  checkThrowViaPath  checkTouchViaPath  checkTravelerDirectlyInRoom  childInName  childInNameGen  childInNameWithOwner  childInRemoteName  clearSenseInfo  cloneForMultiInstanceContents  cloneMultiInstanceContents  conjugateRegularVerb  connectionTable  construct  contentsInFixedIn  countDisambigName  countListName  countName  countNameFrom  countNameOwnerLoc  darkRoomContentsLister  defaultDistantDesc  defaultObscuredDesc  desc  directionForConnector  distantSmellDesc  distantSoundDesc  dobjFor(AskAbout)  dobjFor(AskFor)  dobjFor(AskVague)  dobjFor(AttachTo)  dobjFor(Attack)  dobjFor(AttackWith)  dobjFor(Break)  dobjFor(Burn)  dobjFor(BurnWith)  dobjFor(Clean)  dobjFor(CleanWith)  dobjFor(Climb)  dobjFor(ClimbDown)  dobjFor(ClimbUp)  dobjFor(Consult)  dobjFor(ConsultAbout)  dobjFor(CutWith)  dobjFor(Detach)  dobjFor(DetachFrom)  dobjFor(Dig)  dobjFor(DigWith)  dobjFor(Doff)  dobjFor(Drink)  dobjFor(Drop)  dobjFor(Eat)  dobjFor(EnterOn)  dobjFor(Examine)  dobjFor(Extinguish)  dobjFor(Fasten)  dobjFor(FastenTo)  dobjFor(Feel)  dobjFor(Flip)  dobjFor(Follow)  dobjFor(GiveTo)  dobjFor(GoThrough)  dobjFor(JumpOff)  dobjFor(JumpOver)  dobjFor(Kiss)  dobjFor(Light)  dobjFor(ListenTo)  dobjFor(LookThrough)  dobjFor(Move)  dobjFor(MoveTo)  dobjFor(MoveWith)  dobjFor(PlugIn)  dobjFor(PlugInto)  dobjFor(Pour)  dobjFor(PourInto)  dobjFor(PourOnto)  dobjFor(Pull)  dobjFor(Push)  dobjFor(PushTravel)  dobjFor(PutBehind)  dobjFor(PutIn)  dobjFor(PutOn)  dobjFor(PutUnder)  dobjFor(Read)  dobjFor(Remove)  dobjFor(Screw)  dobjFor(ScrewWith)  dobjFor(Search)  dobjFor(Set)  dobjFor(SetTo)  dobjFor(ShowTo)  dobjFor(Smell)  dobjFor(Strike)  dobjFor(Switch)  dobjFor(Take)  dobjFor(TakeFrom)  dobjFor(TalkTo)  dobjFor(Taste)  dobjFor(TellAbout)  dobjFor(TellVague)  dobjFor(Throw)  dobjFor(ThrowAt)  dobjFor(ThrowDir)  dobjFor(ThrowTo)  dobjFor(Turn)  dobjFor(TurnOff)  dobjFor(TurnOn)  dobjFor(TurnTo)  dobjFor(TurnWith)  dobjFor(TypeLiteralOn)  dobjFor(TypeOn)  dobjFor(Unfasten)  dobjFor(UnfastenFrom)  dobjFor(Unplug)  dobjFor(UnplugFrom)  dobjFor(Unscrew)  dobjFor(UnscrewWith)  dobjFor(Wear)  examineListContents  examineListContentsWith  examineSpecialContents  failCheck  feelDesc  fillMedium  findOpaqueObstructor  findTouchObstructor  forEachConnectedContainer  forEachContainer  fromPOV  getAllPathsTo  getAnnouncementDistinguisher  getBagAffinities  getBagsOfHolding  getBestDistinguisher  getBulk  getBulkWithin  getCarryingActor  getCommonContainer  getCommonDirectContainer  getConnectedContainers  getConnectorTo  getContentsForExamine  getDestName  getDropDestination  getEncumberingBulk  getEncumberingWeight  getExtraScopeItems  getHitFallDestination  getIdentityObject  getInScopeDistinguisher  getListedContents  getLocPushTraveler  getLocTraveler  getMovePathTo  getNoise  getNominalDropDestination  getNominalOwner  getObjectNotifyList  getOdor  getOutermostRoom  getOutermostVisibleRoom  getRoomNotifyList  getRoomPartLocation  getStateWithInfo  getStatuslineExitsHeight  getThrowPathTo  getTouchPathTo  getTravelConnector  getVisualSenseInfo  getWeight  hasCollectiveGroup  hideFromAll  hideFromDefault  initializeEquivalent  initializeLocation  initializeThing  inRoomName  iobjFor(AttachTo)  iobjFor(AttackWith)  iobjFor(BurnWith)  iobjFor(CleanWith)  iobjFor(CutWith)  iobjFor(DetachFrom)  iobjFor(DigWith)  iobjFor(FastenTo)  iobjFor(GiveTo)  iobjFor(LockWith)  iobjFor(MoveWith)  iobjFor(PlugInto)  iobjFor(PourInto)  iobjFor(PourOnto)  iobjFor(ScrewWith)  iobjFor(ShowTo)  iobjFor(TakeFrom)  iobjFor(ThrowAt)  iobjFor(ThrowTo)  iobjFor(TurnWith)  iobjFor(UnfastenFrom)  iobjFor(UnlockWith)  iobjFor(UnplugFrom)  iobjFor(UnscrewWith)  isActorTravelReady  isComponentOf  isDirectlyIn  isHeldBy  isIn  isInFixedIn  isListed  isListedInContents  isListedInInventory  isListedInRoomPart  isLookAroundCeiling  isNominallyIn  isNominallyInRoomPart  isOccludedBy  isOrIsIn  isOwnedBy  isShipboard  isVocabEquivalent  itIs  itNom  itObj  itPossAdj  itPossNoun  itVerb  listCardinality  localDirectionLinkForConnector  lookAround  lookAroundPov  lookAroundWithin  lookAroundWithinContents  lookAroundWithinDesc  lookAroundWithinName  lookAroundWithinSense  lookAroundWithinShowExits  lookInDesc  mainExamine  mapPushTravelHandlers  mapPushTravelHandlers  mapPushTravelHandlers  mapPushTravelHandlers  mapPushTravelHandlers  meetsObjHeld  mergeSenseInfo  mergeSenseInfoTable  moveInto  moveIntoForTravel  moveIntoNotifyPath  mustMoveObjInto  nameIs  nameIsnt  nameVerb  normalizePath  notePromptByOwnerLoc  notePromptByPossAdj  noteSeenBy  notifyInsert  notifyMoveInto  notifyMoveViaPath  notifyRemove  obscuredDesc  obscuredSmellDesc  obscuredSoundDesc  pluralNameFrom  processThrow  propHidesProp  propWithPresent  putInName  receiveDrop  remoteDesc  remoteInitSpecialDesc  remoteRoomContentsLister  remoteSpecialDesc  removeFromContents  removeObjectNotifyItem  restoreLocation  roomActorThereDesc  roomContentsLister  roomDaemon  roomDarkDesc  roomDesc  roomFirstDesc  roomRemoteDesc  roomTravelPreCond  saveLocation  selectPathTo  sendNotifyInsert  sendNotifyRemove  senseAmbientMax  senseInfoTable  senseObj  sensePathFromWithin  sensePathFromWithout  sensePathToContents  sensePathToLoc  sensePresenceList  setAllSeenBy  setContentsSeenBy  setGlobalParamName  setVisualSenseInfo  shineFromWithin  shineFromWithout  shineOnContents  shineOnLoc  showDistantSpecialDesc  showDistantSpecialDescInContents  showInventoryContents  showInventoryItem  showInventoryItemCounted  showListItem  showListItemCounted  showListItemCountedGen  showListItemGen  showObjectContents  showObscuredSpecialDesc  showObscuredSpecialDescInContents  showRemoteSpecialDesc  showRemoteSpecialDescInContents  showSpecialDesc  showSpecialDescInContents  showSpecialDescInContentsWithInfo  showSpecialDescWithInfo  showStatuslineExits  showWornItem  showWornItemCounted  smellDesc  smellHereDesc  soundDesc  soundHereDesc  specialDescList  specialPathFrom  statusName  stopThrowViaPath  superHidesSuper  tasteDesc  thatNom  thatObj  theNameFrom  theNameObj  theNameOwnerLoc  theNameWithOwner  throwTargetCatch  throwTargetHitWith  throwViaPath  transmitAmbient  transSensingIn  transSensingOut  traversePath  tryHolding  tryImplicitRemoveObstructor  useInitDesc  useInitSpecialDesc  useSpecialDesc  useSpecialDescInContents  useSpecialDescInRoom  useSpecialDescInRoomPart  verbEndingEs  verbEndingIes  verbEndingS  verbToHave  verbWas  verifyFollowable  verifyInsert  verifyMoveTo  verifyRemove  whatIf  whatIfHeldBy  withVisualSenseInfo 

Inherited from VocabObject :
addToDictionary  expandPronounList  filterResolveList  getFacets  inheritVocab  initializeVocab  initializeVocabWith  matchName  matchNameCommon  matchNameDisambig  throwNoMatchForLocation  throwNoMatchForPossessive  throwNothingInLocation 



a list of all of our component objects

no description available

In most cases, the open/closed and locked/unlocked status of a complex container refer to the status of the sub-container.

Our inner container, if any. This is a "secret" object (in other words, it doesn't appear to players as a separate named object) that we use to store the contents that are meant to be within the complex container. If this is to be used, it should be set to a Container object - the most convenient way to do this is by using the nested object syntax to define a ComplexComponent Container instance, like so:

washingMachine: ComplexContainer
subContainer: ComplexComponent, Container { etc }

Note that we use the ComplexComponent class (as well as Container) for the sub-container object. This makes the sub-container automatically use the name of its enclosing object in messages (in this case, the sub-container will use the same name as the washing machine).

Note that the sub-containers don't have to be of class ComplexComponent, but using that class makes your job a little easier because the class sets the location and naming automatically. If you prefer to define your sub-containers as separate objects, not nested in the ComplexContainer's definition, there's no need to make them ComplexComponents; just make them ordinary Component objects.

If this property is left as nil, then we don't have an inner container.

Our rear surface or container, if any. This is a secret internal object like the inner container; this object can act as our back surface, or as the space just behind us.

Our inner surface, if any. This is a secret object like the inner container; this object acts as our surface.

Our underside, if any. This is a secret object like the inner container; this object can act as the space underneath us, or as our bottom surface.


addToContents (obj)OVERRIDDENextras.t[324]

Add an object to my contents. If the object has a subLocation setting, take it as indicating which of my subcontainers is to contain the object.

beforeMovePushable (traveler, connector, dest)extras.t[389]
if we're being pushed into a new location (as a PushTraveler), abandon the contents of any SpaceOverlay components

no description available

no description available

no description available

no description available

map GET OUT/OFF to whichever complex component we're currently in

no description available

no description available

no description available

no description available

no description available

no description available

route all commands that treat us as a container to our sub-container object

no description available

route commands relevant to nested rooms to our components

no description available

no description available

examineStatus ( )OVERRIDDENextras.t[128]
Show our status. We'll show the status for each of our sub-objects, so that we list any contents of our sub-container or sub-surface along with our description.

getAllForTakeFrom (scopeList)OVERRIDDENextras.t[284]
Get a list of objects suitable for matching ALL in TAKE ALL FROM <self>. By default, if we have a sub-surface and/or sub-container, we return everything in scope that's inside either one of those. Otherwise, if we have a sub-rear-surface and/or an underside, we'll return everything from those.

getNestedRoomDest (action)extras.t[243]
Get the destination for nested travel into this object. By default, we'll look at the sub-container and sub-surface components to see if either is a nested room, and if so, we'll return that. The surface takes priority if both are nested rooms.

You can override this to differentiate by verb, if desired; for example, you could have SIT ON and LIE ON refer to the sub-surface component, while ENTER and BOARD refer to the sub-container component.

Note that if you do need to override this method to distinguish between a sub-container ("IN") and a sub-surface ("ON") for nested room purposes, there's a subtlety to watch out for. The English library maps "sit on" and "sit in" to the single Action SitOn; likewise with "lie in/on" for LieOn and "stand in/on" for StandOn. If you're distinguishing the sub-container from the sub-surface, you'll probably want to distinguish SIT IN from SIT ON (and likewise for LIE and STAND). Fortunately, even though the action class is the same for both phrasings, you can still find out exactly which preposition the player typed using action.getEnteredVerbPhrase().

getNestedRoomSource (actor)extras.t[264]
Get the source for nested travel out of this object. This is used for GET OUT OF <self> - we figure out which nested room component the actor is in, so that we can remap the command to GET OUT OF <that component>.

route commands that affect our rear to our sub-rear-side

no description available

route commands that treat us as a surface to our sub-surface

route commands that affect our underside to our sub-underside

mainMoveInto (newCont)OVERRIDDENextras.t[370]
If we have any SpaceOverlay children, abandon the contents of the overlaid spaces as needed.

makeLocked (stat)extras.t[162]
no description available

makeOpen (stat)extras.t[154]
no description available

notifyComponentOfMove (sub)extras.t[410]
if the given component is a SpaceOverlay, notify it that we're moving, so that it can abandon its contents as needed

tryMovingObjInto (obj)OVERRIDDENextras.t[427]
pass implicit PUT x IN self operations to our subcontainer

tryPuttingObjInBag (target)extras.t[418]
pass bag-of-holding operations to our sub-container

TADS 3 Library Manual
Generated on 5/16/2013 from TADS version 3.1.3