! ----------------------------------------------------------------------------
! The Elevator 28/01/98
!
! An elevator object, implemented with Inform 6.14 Library 6/7. Most
! descriptions are ripped off the immortal game Lurking Horror. (I
! sincerely hope that such quotes are covered by the fair use clause.)
! The code is copyleft.
!
! The elevator uses the following strategy: it moves in any given
! direction, servicing each floor which has been called from within
! itself or from a call button corresponding to the current direction.
! At the end of each journey, the elevator reverses directions and
! services the remaining calls, if any.
!
! V2: Oops, the command "push u" (short for "push up-arrow button")
! triggered the question "what do you mean, the ceiling or the button",
! which of course is plainly annoying. I fixed it, sort of, via the
! ChooseObjects routine (see p. 165 in the manual).
!
! - Martin Braun
!
[email protected]
!
! ----------------------------------------------------------------------------
Switches scd;
Constant DEBUG;
Include "Parser";
Include "VerbLib";
! ----------------------------------------------------------------------------
! Global variables and arrays
! ----------------------------------------------------------------------------
Global elevDest = 0; ! current destination, 0 = no active task
Global elevMoveCounter = 4;
Global elevDirection = 0; ! 1 when moving up, 2 when moving down
Array ElevButtons -> 9;
Array UpButtons -> 9;
Array DownButtons -> 9;
! ----------------------------------------------------------------------------
! The ChooseObjects routine
! ----------------------------------------------------------------------------
[ ChooseObjects obj code;
if (code < 2 || action_to_be == ##Go) rfalse;
if (obj == UpButton or DownButton) return 3;
rfalse;
];
! ----------------------------------------------------------------------------
! Class definition: some locations outside the elevator
! ----------------------------------------------------------------------------
Class Stairs
with description
[; print "This is the ";
switch(self.number)
{ 1: print "basement";
2: print "lobby";
3: print "second floor";
4: print "third floor";
5: print "fourth floor";
6: print "fifth floor";
7: print "sixth floor";
8: print "seventh floor";
}
print " of the Computer Center. An elevator and call button";
if (self.u_to ~= 0 && self.d_to ~= 0) print "s are";
else print " is";
print " on the south side of the hallway. Stairs also lead ";
if (self.u_to ~= 0)
{ print "up"; if (self.d_to ~= 0) print " and "; }
if (self.d_to ~= 0) print "down";
", for the energetic.";
],
before
[; Go: if (noun == in_obj) << Go s_obj >>;
if (noun == s_obj)
{ if (lift.number ~= self.number) "The lift isn't here."; }
],
s_to liftdoor,
has light;
! ----------------------------------------------------------------------------
! The map
! ----------------------------------------------------------------------------
Stairs Seventh_Floor "Seventh Floor"
with number 8,
d_to Sixth_Floor;
Stairs Sixth_Floor "Sixth Floor"
with number 7,
u_to Seventh_Floor, d_to Fifth_Floor;
Stairs Fifth_Floor "Fifth Floor"
with number 6,
u_to Sixth_Floor, d_to Fourth_Floor;
Stairs Fourth_Floor "Fourth Floor"
with number 5,
u_to Fifth_Floor, d_to Third_Floor;
Stairs Third_Floor "Third Floor"
with number 4,
u_to Fourth_Floor, d_to Second_Floor;
Stairs Second_Floor "Second Floor"
with number 3,
u_to Third_Floor, d_to Computer_Center;
Stairs Computer_Center "Computer Center"
with number 2,
u_to Second_Floor, d_to Basement;
Stairs Basement "Basement"
with number 1,
u_to Computer_Center;
! ----------------------------------------------------------------------------
! The call buttons
! ----------------------------------------------------------------------------
Object UpButton "up-arrow button"
with name "u" 'call' 'button' 'buttons' 'arrow' 'up' 'up-arrow',
description
[; if (UpButtons -> parent(self).number == 0)
"You see nothing special about ", (the) self, ".";
print_ret (The) self, " is glowing.";
],
before
[; Push:
if (UpButtons -> parent(self).number == 1)
{ print_ret (The) self, " is already activated."; }
if (lift.number==parent(self).number && lift hasnt general)
{ OpenElevDoor(); return; }
UpButtons -> parent(self).number = 1;
if (elevDest==0) elevDest=parent(self).number;
print_ret (The) self, " begins to glow.";
],
found_in Sixth_Floor Fifth_Floor Fourth_Floor Third_Floor Second_Floor
Computer_Center Basement,
has static concealed;
Object DownButton "down-arrow button"
with name "d" 'call' 'button' 'buttons' 'arrow' 'down' 'down-arrow',
description
[; if (DownButtons -> parent(self).number == 0)
"You see nothing special about ", (the) self, ".";
print_ret (The) self, " is glowing.";
],
before
[; Push:
if (DownButtons -> parent(self).number == 1)
{ print_ret (The) self, " is already activated."; }
if (lift.number==parent(self).number && lift hasnt general)
{ OpenElevDoor(); return; }
DownButtons -> parent(self).number = 1;
if (elevDest==0) elevDest=parent(self).number;
print_ret (The) self, " begins to glow.";
],
found_in Seventh_Floor Sixth_Floor Fifth_Floor Fourth_Floor
Third_Floor Second_Floor Computer_Center,
has static concealed;
! ----------------------------------------------------------------------------
! The elevator doors
! ----------------------------------------------------------------------------
Object liftdoor "elevator doors"
with name 'lift' 'elevator' 'door' 'doors' 'liftdoor',
description
[; print (The) self, " are ";
if (self has open) "opened.";
"closed.";
],
number 0,
door_dir
[; if (parent(self) ~= lift)
return s_to;
return n_to;
],
door_to
[; if (parent(self) ~= lift) return lift;
switch(lift.number)
{ 1: return Basement;
2: return Computer_Center;
3: return Second_Floor;
4: return Third_Floor;
5: return Fourth_Floor;
6: return Fifth_Floor;
7: return Sixth_Floor;
8: return Seventh_Floor;
}
],
before
[; Open, Push, Pull:
if (self has open) "But the doors are already open!";
if (self in lift)
{ if (lift has general)
"You should wait until the elevator reaches
its destination.";
"Just press the 'open' button.";
}
if (lift.number == parent(self).number)
"The elevator is here, so the doors will open when you
press a call button.";
"You better call the elevator first.";
Close:
if (self hasnt open) "But the doors are already closed!";
if (self in lift)
"Just press the 'close' button.";
if (lift.number == parent(self).number)
"Don't worry, the doors will be closed automatically.";
],
found_in Seventh_Floor Sixth_Floor Fifth_Floor Fourth_Floor
Third_Floor Second_Floor Computer_Center Basement lift,
! Since the doors are implemented as one single floating object
! we have to make sure that they don't open all at once. Thus:
react_before
[; if (self has general && (parent(self) == lift ||
parent(self).number == lift.number))
give self open;
else give self ~open;
rfalse;
],
daemon
[; self.number--;
if (self.number == 0) CloseElevDoor(1);
],
has door static scenery pluralname; ! general when open
[ OpenElevDoor i;
liftdoor.number = 3;
startdaemon(liftdoor);
give liftdoor general;
if (location == lift || location.number == lift.number)
{ if (i == 1) print "^";
print "The elevator doors slide open.^";
}
return;
];
[ CloseElevDoor i;
stopdaemon(liftdoor);
give liftdoor ~general;
if (location == lift || location.number == lift.number)
{ if (i == 1) print "^";
print "The elevator doors slide closed.^";
}
return;
];
! ----------------------------------------------------------------------------
! The elevator itself
! ----------------------------------------------------------------------------
Object lift "Elevator"
with number 3, ! start at 2nd floor
name 'fake' 'wood' 'wooden' 'walls' 'graffiti' 'graffito',
description
[; print "A battered, rather dirty elevator. The fake wood walls are
scratched and marred with graffiti. A digital sign reads ";
if (self.number==1) print "B";
else print self.number-1;
print ". The elevator doors are ";
if (liftdoor has open) print "open";
else print "closed";
print ". To the right of the doors is an area with floor buttons
(B and 1 through 7), an open button, a close button, a stop
switch and an alarm button. ";
<< Examine allElevButtons >>;
],
before
[; Exit: << Go n_obj >>;
],
n_to liftdoor,
cant_go "The only exit leads north.",
daemon
[ i;
if (elevDest == 0) return; ! no task defined
if (liftdoor has general || stopSwitch has on) return;
elevMoveCounter--;
switch(elevMoveCounter)
{ 0: OpenElevDoor(1);
elevDest = ChooseElevDest();
elevMoveCounter = 4;
1: if (elevDirection == 1) lift.number++;
else lift.number--;
i = CheckElevDest();
if (i ~= 0) elevDest = i;
PrintElevMessage();
if (lift.number ~= elevDest) ! task not finished
{ elevMoveCounter = 3; return; }
ElevButtons -> lift.number = 0;
UpButtons -> lift.number = 0; DownButtons -> lift.number = 0;
give self ~general;
2: PrintElevMessage();
3: give self general;
if (self.number < elevDest)
elevDirection = 1;
else
elevDirection = 2;
PrintElevMessage();
}
],
has light;
[ CheckElevDest i;
i = lift.number;
if (elevDirection == 1)
{ if (UpButtons -> i == 1 || ElevButtons -> i == 1 )
return i;
}
else
{ if (DownButtons -> i == 1 || ElevButtons -> i == 1)
return i;
}
return 0;
];
[ ChooseElevDest i;
if (elevDirection == 1)
{ i = SearchUp();
if (i ~= 0) return i;
return SearchDown();
}
else
{ i = SearchDown();
if (i ~= 0) return i;
return SearchUp();
}
];
[ SearchUp i;
for (i=lift.number+1:i<=8:i++)
{ if (ElevButtons -> i == 1 || UpButtons -> i == 1)
return i;
}
for (i=8:i>lift.number:i--)
{ if (DownButtons -> i == 1)
return i;
}
return 0;
];
[ SearchDown i;
for (i=lift.number-1:i>0:i--)
{ if (ElevButtons -> i == 1 || DownButtons -> i == 1)
return i;
}
for (i=1:i<lift.number:i++)
{ if (UpButtons -> i == 1)
return i;
}
return 0;
];
[ PrintElevMessage;
if (location == lift)
{ switch(elevMoveCounter)
{ 1: print "^The sign flashes briefly. It now displays the ";
if (lift.number == 1) print "letter B";
else print "number ", lift.number-1;
print ".^";
if (lift.number == elevDest) ! task finished
{ print "^The elevator slows and comes to a stop. The
button for the ";
switch(self.number)
{ 1: print "basement";
2: print "lobby";
3: print "second floor";
4: print "third floor";
5: print "fourth floor";
6: print "fifth floor";
7: print "sixth floor";
8: print "seventh floor";
}
print " blinks off.^";
}
2: print "^The elevator continues to move ";
if (elevDirection == 1) print "up";
else print "down";
print "wards.^";
3: print "^The elevator begins to move ";
if (elevDirection == 1) print "up";
else print "down";
print "wards.^";
}
}
if (location ofclass Stairs)
{ switch(elevMoveCounter)
{ 1: if (lift.number ~= elevDest)
print "^You hear the elevator moving.^";
else
{ print "^You no longer hear the elevator moving.^";
if (location.number == lift.number)
{ if (UpButtons -> lift.number == 1 ||
DownButtons -> lift.number == 1)
{ print "^The call button";
if (UpButtons -> lift.number == 1 &&
DownButtons -> lift.number == 1)
print "s blink";
else print " blinks";
print " off.^";
}
}
}
2: print "^You hear the elevator moving.^";
3: print "^You hear the elevator begin moving.^";
}
}
];
Object -> sign "sign"
with name 'digital' 'sign' 'display',
description
[; print "The sign reads ";
if (lift.number==1) print "B";
else print lift.number-1;
print_ret ".";
],
has static concealed;
! ----------------------------------------------------------------------------
! Class definition: floor buttons in the elevator
! ----------------------------------------------------------------------------
Class ElevButton
has static concealed
with name 'button',
number 0,
description
[; if (ElevButtons -> self.number == 0)
"You see nothing special about ", (the) self, ".";
print_ret (The) self, " is glowing."; ],
before
[; Push:
if (ElevButtons -> self.number == 1)
{ print_ret (The) self, " is already activated."; }
if (self.number == lift.number && lift hasnt general)
<< Push openButton >>;
ElevButtons -> self.number = 1;
if (elevDest == 0) elevDest = self.number;
print "The button for the ";
switch(self.number)
{ 1: print "basement";
2: print "lobby";
3: print "second floor";
4: print "third floor";
5: print "fourth floor";
6: print "fifth floor";
7: print "sixth floor";
8: print "seventh floor";
}
" begins to glow.";
];
! ----------------------------------------------------------------------------
! A meta object and the floor buttons
! ----------------------------------------------------------------------------
Object -> allElevButtons "buttons"
with name 'buttons' 'controls' 'area',
description
[ i j temp;
for (i=1:i<=8:i++) {
if (ElevButtons -> i==1) j++;
}
if (j==0) "None of the buttons is activated.";
print "You notice that ", (number) j, " floor button";
if (j>1) print "s";
print " (namely ";
temp=j;
for (i=1:i<=8:i++)
{ if (ElevButtons -> i==1)
{ if (i==1) print "B";
else print i-1;
temp--;
if (temp>0)
{ if (temp==1) print " and ";
else print ", ";
}
}
}
print ") ";
if (j>1) print "are";
else print "is";
" currently activated.";
],
before [; Push: "Only one at a time."; ],
has static concealed pluralname;
ElevButton -> elevButton1 "basement button"
with name "b" 'basement' 'cellar',
number 1;
ElevButton -> elevButton2 "1 button"
with name "1" 'one' 'lobby' 'first',
number 2;
ElevButton -> elevButton3 "2 button"
with name "2" 'two' 'second',
number 3;
ElevButton -> elevButton4 "3 button"
with name "3" 'three' 'third',
number 4;
ElevButton -> elevButton5 "4 button"
with name "4" 'four' 'fourth',
number 5;
ElevButton -> elevButton6 "5 button"
with name "5" 'five' 'fifth',
number 6;
ElevButton -> elevButton7 "6 button"
with name "6" 'six' 'sixth',
number 7;
ElevButton -> elevButton8 "7 button"
with name "7" 'seven' 'seventh',
number 8;
! ----------------------------------------------------------------------------
! and more elevator controls
! ----------------------------------------------------------------------------
Object -> openButton "open button"
with name 'button' 'open',
before
[; Push:
if (liftdoor has general) "Nothing happens.";
if (lift has general) "Not between floors.";
OpenElevDoor(); return;
],
has static concealed;
Object -> closeButton "close button"
with name 'button' 'close',
before
[; Push:
if (liftdoor hasnt general) "Nothing happens.";
CloseElevDoor(); return;
],
has static concealed;
Object -> alarmButton "alarm button"
with name 'button' 'alarm' 'bell',
before
[; Push: "For as long as you hold the button down, an
ear-splitting alarm bell rings.";
],
has static concealed;
Object -> stopSwitch "stop switch"
with name 'stop' 'switch',
before
[; Push, Turn: if (self has on) << SwitchOff self >>;
else << SwitchOn self >>;
],
after
[; SwitchOn:
print "You turn the switch";
if (lift has general) " and the elevator comes to a halt.";
print_ret ".";
SwitchOff:
print "You release the switch";
if (lift has general) " and the elevator starts moving.";
print_ret ".";
],
has static concealed switchable;
[ Initialise;
location = Second_Floor; startdaemon(lift); startdaemon(Fred);
print "^^^^Welcome to the...^^";
return 2; ! don't print headlines pp.
];
[ CallSub;
if (noun has animate)
print_ret "You'll have to address ", (the) noun, " directly.";
print_ret "You can't talk to ", (the) noun, ".";
];
[ CallElevSub i;
if (location == lift) "You're in it!";
if (location ofclass Stairs)
{ if (liftdoor has open) "It's right here!";
if (location == Seventh_Floor or Basement) i = 1;
print "You'll have to press ";
if (i ~= 1) print "one of ";
print "the call button";
if (i ~= 1) print "s (up or down)";
print_ret ".";
}
"You can't see any elevator here.";
];
Include "Grammar";
Verb 'call'
* 'elevator'/'lift' -> CallElev
* noun -> Call;
end;