!--------------------------------------------------------------------------
! 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.
!--------------------------------------------------------------------------
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, ")^";
<<Unlock noun 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) <<Lock Chest1 self>>;
],
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";