Elevator and stairs (TADS 3 example)
From IFWiki
#charset "us-ascii" #include <adv3.h> #include <en_us.h> versionInfo: GameID name = 'TADS 3 Elevator and Stairs Example' byline = 'by David Turpin' htmlByline = 'by <a href="mailto:dturpin@mainstreettech.com"> David Turpin</a>' version = '1.0' authorEmail = 'David Turpin <dturpin@mainstreettech.com>' desc = 'This is the TADS3 version of the Elevator and Stairs example from the IFWiki.' htmlDesc = 'This is the TADS3 version of the Elevator and Stairs example from the <a href="http://www.ifwiki.org">IFWiki</a>.' showCredit() { "Elevator and Stairs example from the <a href='http://www.ifwiki.org'>IFWiki</a>. <.p>TADS3 version by David Turpin. "; "\b"; } showAbout() { "This is the TADS3 version of the Elevator and Stairs example on the IFWiki. It is a three story building with a set of stairs and an elevator."; } ; me: Actor location = startRoom ; gameMain: GameMainDef initialPlayerChar = me showIntro() { "An example of Stairs and Elevators\n Version 1.0\n by David Turpin\b"; } showGoodbye() { "<.p>Thanks for playing!\b"; } ; /* Modified Library objects */ modify VerbRule(ClimbUp) ('climb' | 'take') singleDobj 'up' | ('climb' | 'take') 'up' singleDobj : ; modify VerbRule(ClimbDown) ('climb' | 'take') singleDobj 'down' | ('climb' | 'take') 'down' singleDobj : ; modify Stairway Stairstaken = nil dobjFor(TravelVia) { action() { gAction.actionTime = 3; "<<!Stairway.Stairstaken ? 'It took longer to take the stairs than you expected. ' : nil>>"; Stairway.Stairstaken = true; inherited; } } ; modify OneWayRoomConnector dobjFor(TravelVia) { action() { gAction.actionTime = 3; "<<!Stairway.Stairstaken ? 'It took longer to take the stairs than you expected. ' : nil>>"; Stairway.Stairstaken = true; inherited; } } ; /* Classes for the Example */ class elevatorDoor: Door 'elevator door/elevator' 'elevator door' "The elevator door is <<isOpen ? "open" : "closed">>, and there's a call button beside it" openStatus {} // This stops the door from displaying It's open or It's closed at the end of the description destination = Elevator dobjFor(Open) { check() { if (isOpen) { "{The dobj/he} is already open"; exit; } else { "Try pushing the call button."; exit; } } } dobjFor(Close) { check() { if (!isOpen) { "{The dobj/he} is already closed. "; exit; } else { "{The dobj/he} will close automatically when it needs to. "; exit; } } } ; class elevatorButton: Button, Fixture '(elevator) button*buttons' 'panel button' "The panel has three buttons: G, 2, and 3. There is also a LED display that reads '<<Elevator.floor == 1 ? "G" : Elevator.floor>>'." isLit = nil dobjFor(Push) { action() { if (elevatorButton.daemonID != nil) { elevatorButton.daemonID.removeEvent(); elevatorButton.daemonID = nil; } if (callButton.daemonID != nil) { callButton.daemonID.removeEvent(); callButton.daemonID = nil; } elevatorButton.daemonID = new Daemon(self, &daemon, 1); } } daemonID = nil floor = 0 startoff = nil daemon { switch(floor) { case 1: { if (EDoor.isOpen) { "\n The elevator door closes. "; isLit = true; EDoor.makeOpen(nil); break; } if (floor > Elevator.floor) { "<<!startoff ? '\n You feel the elevator start going up.' : nil>>"; isLit = true; startoff = true; Elevator.floor = Elevator.floor + 1; } if (floor < Elevator.floor) { "<<!startoff ? '\n You feel the elevator start going down.' : nil>>"; isLit = true;startoff = true; Elevator.floor = Elevator.floor - 1; } if (!EDoor.isOpen && floor == Elevator.floor && !startoff) { "\n The elevator door opens. The elevator button goes dark."; isLit = nil; elevatorButton.daemonID.removeEvent();elevatorButton.daemonID = nil; EDoor.makeOpen(true);GEDoor.makeOpen(true); callButton.daemonID = new Fuse(GCButton,&doorClose,2);break; } if (!EDoor.isOpen && floor == Elevator.floor && startoff) { "\n You feel the elevator come to a stop. "; startoff = nil; break; } break; } case 2: { if (EDoor.isOpen) { "\n The elevator door closes. "; isLit = true; EDoor.makeOpen(nil); break; } if (floor > Elevator.floor) { "<<!startoff ? '\n You feel the elevator start going up.' : nil>>"; isLit = true; startoff = true; Elevator.floor = Elevator.floor + 1; } if (floor < Elevator.floor) { "<<!startoff ? '\n You feel the elevator start going down.' : nil>>"; isLit = true; startoff = true; Elevator.floor = Elevator.floor - 1; } if (!EDoor.isOpen && floor == Elevator.floor && !startoff) { "\n The elevator door opens. The elevator button goes dark."; isLit = nil; elevatorButton.daemonID.removeEvent();elevatorButton.daemonID = nil; EDoor.makeOpen(true);SEDoor.makeOpen(true); callButton.daemonID = new Fuse(SCButton,&doorClose,2); break; } if (!EDoor.isOpen && floor == Elevator.floor && startoff) { "\n You feel the elevator come to a stop. "; startoff = nil; break; } break; } case 3: { if (EDoor.isOpen) { "\n The elevator door closes. "; isLit = true; EDoor.makeOpen(nil); break; } if (floor > Elevator.floor) { "<<!startoff ? '\n You feel the elevator start going up.' : nil>>"; isLit = true; startoff = true; Elevator.floor = Elevator.floor + 1; } if (floor < Elevator.floor) { "<<!startoff ? '\n You feel the elevator start going down.' : nil>>"; isLit = true; startoff = true; Elevator.floor = Elevator.floor - 1; } if (!EDoor.isOpen && floor == Elevator.floor && !startoff) { "\n The elevator door opens. The elevator button goes dark."; isLit = nil; elevatorButton.daemonID.removeEvent();elevatorButton.daemonID = nil; EDoor.makeOpen(true);TEDoor.makeOpen(true); callButton.daemonID = new Fuse(TCButton,&doorClose,2); break; } if (!EDoor.isOpen && floor == Elevator.floor && startoff) { "\n You feel the elevator come to a stop. "; startoff = nil; break; } break; } } } ; class callButton: Button, Fixture '(elevator) call button*buttons' 'call button' "Pushing this button summons the elevator to this floor. It's currently <<isLit ? 'lit' : 'dark'>>. " isLit = nil wasSaid = nil startoff = nil floor = 0 dobjFor(Push) { action() { if (callButton.daemonID != nil) { callButton.daemonID.removeEvent(); callButton.daemonID = nil; } callButton.daemonID = new SenseDaemon(self, &daemon, 1,self,sight); } } daemonID = nil daemon { switch(floor) { case 1: { if (!GEDoor.isOpen && GCButton.floor == Elevator.floor) { isLit = nil; GEDoor.makeOpen(true); "\n<<startoff ? 'The elevator door opens. The call button blinks off' : 'The elevator door opens.'>> "; startoff = nil; callButton.daemonID.removeEvent();callButton.daemonID = nil; EDoor.makeOpen(true); callButton.daemonID = new Fuse(self,&doorClose,2); break; } if (GEDoor.isOpen && GCButton.floor != Elevator.floor) { GEDoor.makeOpen(nil); break; } if (GEDoor.isOpen && GCButton.floor == Elevator.floor) { "Nothing happens. "; callButton.daemonID.removeEvent();callButton.daemonID = nil; callButton.daemonID = new Fuse(self,&doorClose,2); break; } startoff = true; isLit = true; "<<wasSaid ? nil : 'The call button lights up.'>>"; wasSaid = true; if (SEDoor.isOpen || TEDoor.isOpen) { SEDoor.makeOpen(nil); TEDoor.makeOpen(nil); break; } if (GCButton.floor > Elevator.floor) { Elevator.floor = Elevator.floor + 1; } if (GCButton.floor < Elevator.floor) { Elevator.floor = Elevator.floor - 1; } break; } case 2: { if (!SEDoor.isOpen && SCButton.floor == Elevator.floor) { isLit = nil; SEDoor.makeOpen(true); "\n<<startoff ? 'The elevator door opens. The call button blinks off' : 'The elevator door opens.'>> "; startoff = nil; callButton.daemonID.removeEvent();callButton.daemonID = nil; EDoor.makeOpen(true); callButton.daemonID = new Fuse(self,&doorClose,2); break; } if (SEDoor.isOpen && SCButton.floor != Elevator.floor) { SEDoor.makeOpen(nil); break; } if (SEDoor.isOpen && SCButton.floor == Elevator.floor) { "Nothing happens. "; callButton.daemonID.removeEvent();callButton.daemonID = nil; callButton.daemonID = new Fuse(self,&doorClose,2); break; } startoff = true; isLit = true; "<<wasSaid ? nil : 'The call button lights up.'>>"; wasSaid = true; if (GEDoor.isOpen || TEDoor.isOpen) { GEDoor.makeOpen(nil); TEDoor.makeOpen(nil); break; } if (SCButton.floor > Elevator.floor) { Elevator.floor = Elevator.floor + 1; } if (SCButton.floor < Elevator.floor) { Elevator.floor = Elevator.floor - 1; } break; } case 3: { if (!TEDoor.isOpen && TCButton.floor == Elevator.floor) { isLit = nil; TEDoor.makeOpen(true); "\n<<startoff ? 'The elevator door opens. The call button blinks off' : 'The elevator door opens.'>> "; startoff = nil; callButton.daemonID.removeEvent();callButton.daemonID = nil; EDoor.makeOpen(true); callButton.daemonID = new Fuse(self,&doorClose,2); break; } if (TEDoor.isOpen && TCButton.floor != Elevator.floor) { TEDoor.makeOpen(nil); break; } if (TEDoor.isOpen && TCButton.floor == Elevator.floor) { "Nothing happens. "; callButton.daemonID.removeEvent();callButton.daemonID = nil; callButton.daemonID = new Fuse(self,&doorClose,2); break; } startoff = true; isLit = true; "<<wasSaid ? nil : 'The call button lights up.'>>"; wasSaid = true; if (GEDoor.isOpen || SEDoor.isOpen) { GEDoor.makeOpen(nil); SEDoor.makeOpen(nil); break; } if (TCButton.floor > Elevator.floor) { Elevator.floor = Elevator.floor + 1; } if (TCButton.floor < Elevator.floor) { Elevator.floor = Elevator.floor - 1; } break; } } } doorClose { for(local obj = firstObj(elevatorDoor); obj; obj = nextObj(obj, elevatorDoor)) { obj.makeOpen(nil); } "<<me.canSee(self) || me.isIn(Elevator) ? '\n The elevator door closes. ' : nil>>"; } ; /* Example objects */ startRoom: Room 'Ground Floor' "You are on the ground floor. The <<GEDoor.isOpen ? "open" : "closed">> door to the elevator is north, and the stairs are up. " north = GEDoor up = GUpStair in asExit(north) ; +GEDoor: elevatorDoor; +GCButton: callButton {floor = 1}; +GUpStair: StairwayUp ->SStair 'up stairway/stairs' 'stairs' "They go up. " dobjFor(Take) asDobjFor(Climb) ; SecondFloor: Room 'Second Floor' "You are on the second floor. The <<SEDoor.isOpen ? "open" : "closed">> door to the elevator is north, and stairs go both up and down from here. " north = SEDoor down : OneWayRoomConnector {destination = startRoom} up : OneWayRoomConnector {destination = ThirdFloor} in asExit(north) ; +FromThird: ExitOnlyPassage, SecretFixture; //SecretFixture makes this object invisible to the player. +SEDoor: elevatorDoor; +SCButton: callButton {floor = 2}; +SStair: Stairway 'stairway/stairs' 'stairs' "They go up and down. " dobjFor(Take) { verify() {} check() {} action() { gAction.actionTime = 0; "Do you want to take the stairs up, or take the stairs down? "; exit; } } dobjFor(Climb) asDobjFor(Take) dobjFor(ClimbUp) remapTo(Up) dobjFor(ClimbDown) remapTo(Down) ; ThirdFloor: Room 'Third Floor' "You are on the third floor. The <<TEDoor.isOpen ? "open" : "closed">> door to the elevator is north, or you can take the stairs down. " north = TEDoor down = TDownStair in asExit(north) ; +TEDoor: elevatorDoor; +TCButton: callButton {floor = 3}; +TDownStair: StairwayDown ->FromThird 'down stairway/stairs' 'stairs' "They go Down. " dobjFor(Take) asDobjFor(Climb) ; Elevator: Room 'Elevator' "You are inside the elevator. The door to the south is <<EDoor.isOpen ? "open" : "closed">>, and there's the usual panel of buttons beside it. " south = EDoor out asExit(south) floor = 1 ; +EDoor: elevatorDoor destination { switch(Elevator.floor) { case 1: {return startRoom;} case 2: {return SecondFloor;} case 3: {return ThirdFloor;} default: {return startRoom;} //to prevent the annoying droping off end warning while compiling. } } dobjFor(Open) { check() { if (isOpen) { "{The dobj/he} is already open"; exit; } else { "{The dobj/he} will open automatically when it needs to. "; exit; } } } ; +GEButton: elevatorButton '(elevator) G button G' 'button G' {floor = 1}; +SEButton: elevatorButton '(elevator) 2 button 2/two' 'button 2' {floor = 2}; +TEButton: elevatorButton '(elevator) 3 button 3/three' 'button 3' {floor = 3}; +Fixture '(elevator) panel' 'elevator panel' "The panel has three buttons: G, 2, and 3. There is also a LED display that reads '<<Elevator.floor == 1 ? "G" : Elevator.floor>>'." ; +Fixture '(Elevator) LED display' 'LED display' "The LED Display is showing a large red '<<Elevator.floor == 1? 'G' : Elevator.floor>>'." ;