!-------------------------------------------------------------------------- ! A chest and a padlock. There are actually two chests. Chest1 is an ! ordinary chest - you can put objects in it, open it, shut it, etc. If ! you lock it with the padlock, it gets removed and Chest2 put in its ! place. Chest2 pretends to be a container, but is actually a supporter ! with one child - the padlock. When you unlock the padlock and remove it ! from Chest2, then Chest2 is swapped for Chest1 again. ! ! Note: the verb "lock" is extended so that "lock padlock" allows you to ! lock the padlock (without the parser asking you what you want to lock it ! with). ! ! Note: the verb "unlock" is extended so that "unlock padlock" chooses a ! default object when it is sensible to do so (i.e. when the player is ! carrying a single key). Although this may seem tempting to generalise ! this, in fact there are tricky issues involved - supposing that the keys ! are red herrings and the lock should be picked with the hairpin? Do you ! choose the hairpin as the default, or do you choose the key ! (unsuccessfully), even when the player is carrying the hairpin? ! ! Gareth Rees, 31/10/94, with thanks to Scott Harvey for the idea. !-------------------------------------------------------------------------- Constant Story "PADLOCK"; Constant Headline "^An Interactive Locked-box Mystery^by Gareth Rees^"; Include "parser"; Include "verblib"; Include "grammar"; Attribute is_key; [ Initialise; location = Dungeon1; print "^^^^^What is in the box?^^"; ]; [ PadlockTest; if (noun == Padlock) rtrue; else rfalse; ]; [ PadlockLockSub; if (noun ~= Padlock) "error!"; if (Padlock has locked) "It's already locked."; give Padlock locked; "You snap the padlock shut."; ]; [ OneKeyTest i j; objectloop (i in player) { if (i has is_key) j++; } if (j == 1) rtrue; else rfalse; ]; [ MyUnlockSub i j; objectloop (i in player) { if (i has is_key) j = i; } print "(with ", (the) j, ")^"; <>; ]; Extend "lock" first * noun=PadlockTest -> PadlockLock; Extend "unlock" first * noun=OneKeyTest -> MyUnlock; Object Chest1 "chest" nothing has container openable with name "chest", capacity 5, before [ i; Lock: if (second == Padlock) { if (Padlock has locked) "The padlock is locked shut."; if (self has open) "The chest is open."; i = parent(self); remove self; move padlock to Chest2; move Chest2 to i; give padlock locked; "You snap the padlock shut on the chest."; } "The chest has no lock."; ]; Object Dungeon1 "Cavern" has light with description "A dark and forbidding cavern.", cant_go "The only exit is a low passage to the north.", n_to Dungeon2; Nearby IronKey "iron key" has is_key with name "iron" "key"; Nearby Chest2 "chest" has supporter openable locked lockable with name "chest", before [; Unlock: "The chest has no lock. But you could try the padlock."; Open: "The chest is held shut by the padlock."; Receive: if (noun ~= Padlock) "Putting things on the chest would achieve nothing."; ]; Object Padlock "padlock" Chest2 has concealed lockable locked with name "padlock" "lock", before [; Take, Remove: if (self has locked && parent(self) == Chest2) "The padlock is securely attached to the chest."; if (parent(self) == Chest2) give self general; PutOn: if (second == Chest1) <>; ], after [ i; Take, Remove: if (self has general) { i = parent(Chest2); remove Chest2; move Chest1 to i; give self ~general; } ], with_key BrassKey; Object Steve "the head of Steve Meretsky" Chest1 with name "head" "of" "Steve" "Meretsky", article "the", description "His eyes glint brightly in the gloomy light."; Object Dungeon2 "Narrow passage" has light with description "A difficult squeeze.", cant_go "The passage is too narrow to proceed further. Better go \ back south to the cavern.", s_to Dungeon1; Nearby BrassKey "brass key" has is_key with name "brass" "key"; End;