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:[email protected]">
David Turpin</a>'
version = '1.0'
authorEmail = 'David Turpin <[email protected]>'
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>>'."
;