! ---------------------------------------------------------------------------- ! 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 ! mbraun@compuserve.com ! ! ---------------------------------------------------------------------------- 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 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;