199 lines
6.4 KiB
C
199 lines
6.4 KiB
C
#include <lib.h>
|
|
#include "ex.h"
|
|
|
|
inherit LIB_ROOM;
|
|
int pre_north();
|
|
int post_south();
|
|
int post_north();
|
|
|
|
void create()
|
|
{
|
|
::create();
|
|
SetAmbientLight(30);
|
|
SetShort( "pre/post exits and add/remove exits" );
|
|
SetLong(@EndText
|
|
There's a door to the north with a doorbell, and a blank
|
|
wall to the south.
|
|
-------------------------------------------------------------
|
|
This is an example room for using pre-exits and post-exits.
|
|
It also shows how to add & delete an exit from the room, and
|
|
use a temporary variable on a player.
|
|
|
|
There's a lever to pull and push, and a bell to ring.
|
|
Pull the lever out: create an exit to the south.
|
|
Push the lever in: delete an exit to the south.
|
|
Ring the bell: allows you to go north.
|
|
When you go south, the exit to the south disappears.
|
|
-------------------------------------------------------------
|
|
EndText
|
|
);
|
|
|
|
SetExits( ([
|
|
]));
|
|
|
|
AddExit( "north", EXPATH + "exroom5", (: pre_north :));
|
|
|
|
}
|
|
|
|
void init()
|
|
{
|
|
::init();
|
|
add_action("aa_pull","pull");
|
|
add_action("aa_push","push");
|
|
add_action("aa_ring","ring");
|
|
}
|
|
|
|
|
|
int aa_pull(string str)
|
|
{
|
|
if (str!="lever" && str!="lever out")
|
|
{
|
|
write( "Pull what?\n" );
|
|
return 1;
|
|
}
|
|
/* Now, we can find out if the lever has been already pulled
|
|
in one of two ways.
|
|
Method one: we test to see if the exit to the south is open.
|
|
Since pulling the lever does this, and the only way to
|
|
create that exit is pulling the lever -- this is a valid method.
|
|
|
|
Method two: we use a variable and change it's value when the lever
|
|
is pushed or pulled. Since we have a method that works without
|
|
using an additional variable, that is the method I'll pick here.
|
|
It will also show you how to query for an exit.
|
|
|
|
Note: GetExits() returns a mapping for all the exits in a room
|
|
GetExit("dir") returns the value for that specific direction.
|
|
if there is NOT an exit in that direction it will return UNDEFINED
|
|
and can be detected using the ! operator. (! means 'not')
|
|
conversely, if GetExit("dir") is true, then there IS an exit
|
|
to that direction. Got it? Good.
|
|
*/
|
|
|
|
if ( GetExit("south") )
|
|
{
|
|
write("The lever is already pulled out!\n");
|
|
return 1;
|
|
}
|
|
|
|
/* If you don't know by now, this_player() indicates the player doing the actions
|
|
So when I do this_player()->GetName() it gives me the name of the player
|
|
who is doing the actions and allows me to tell the room who it is.
|
|
*/
|
|
|
|
write( "You pull the lever and an invisible crack appears in the south wall. "+
|
|
"A door slides open and there is a previously undetected exit." );
|
|
say(this_player()->GetName() + " pulls the lever and an exit appears to the south.\n");
|
|
|
|
// AddExit() functions add an exit to the room. Here, we added an exit and
|
|
// set up a (: functional :) to do close up the exit when they leave.
|
|
|
|
AddExit( "south", EXPATH + "exroom3", (: post_south :) );
|
|
SetObviousExits("north, south");
|
|
return 1;
|
|
}
|
|
|
|
|
|
int aa_push(string str)
|
|
{
|
|
if (str!="lever" && str!="lever in")
|
|
{
|
|
write( "Push what?\n" );
|
|
return 1;
|
|
}
|
|
|
|
/* Since there's more then one way for the exit to dissappear (see the post-exit
|
|
function for south) and there may be more then one player wandering the halls
|
|
we don't want to assume that 'this' player pushed the lever. So we wouldn't
|
|
say "You've already pushed the lever."
|
|
*/
|
|
|
|
if ( ! GetExit("south") )
|
|
{
|
|
write( "The lever is pushed in as far as it will go.\n");
|
|
return 1;
|
|
}
|
|
write( "You push the lever in and an unseen door slides shut in the south wall."+
|
|
"The wall now appears solid and unpenatrable." );
|
|
say(this_player()->GetName() + " pushes the lever and the south closes tight.\n");
|
|
|
|
// Now we remove the exit that was added earlier.
|
|
|
|
RemoveExit("south");
|
|
SetObviousExits("n");
|
|
return 1;
|
|
}
|
|
|
|
|
|
int aa_ring(string str)
|
|
{
|
|
if (str!="bell" && str!="doorbell" && str!="door bell")
|
|
{
|
|
write( "Ring what?\n" );
|
|
return 1;
|
|
}
|
|
//if we only want to let them ring it once, we can check for the
|
|
//temp var here. This version will let them ring it many times.
|
|
write("DONG!\nYou ring a doorbell! You are now admitted north.\n");
|
|
say("DONG! A doorbell rings.\n");
|
|
this_player()->SetProperty("rung_bell", 1);
|
|
return 1;
|
|
}
|
|
|
|
|
|
/* CODING STYLE 101
|
|
Personally, I always put my post/pre exit functions right after create and
|
|
before the reset() or init() functions. This makes them easy to find.
|
|
Since they're MENTIONED in the create() I like to keep 'em close at hand.
|
|
For the same reason I usually follow my init() with any add_actions that
|
|
I've created. I also preface my functions with an indicator saying what
|
|
their purpose is. I've chosen aa_ for add_actions an pe_ for pre or post
|
|
exit functions. OR i use pre_ or post_ when i have both going on. This
|
|
may not seem like a big deal in a little file, but when the file gets
|
|
huge, it helps to glance at a function and go: ah ha! this is a post_exit
|
|
function. or ah ha! this is an add_action or similarly: ah ha! this is
|
|
not any specialized function so I must be calling it for some other reason.
|
|
The order you write them in is a personal decision. Just keep your
|
|
create() function first on the list.
|
|
*/
|
|
|
|
//A return 0 in a pre-exit will prevent you from going that dir.
|
|
//A return 1 will allow you to go that dir.
|
|
|
|
|
|
int pre_north()
|
|
{
|
|
if( !this_player()->GetProperty("rung_bell") )
|
|
{
|
|
write("Ring the doorbell first!\n");
|
|
return 0;
|
|
}
|
|
// Now that the pre_north() function has done what it needs to do, we
|
|
// will call the post_north() function here
|
|
post_north();
|
|
return 1;
|
|
}
|
|
|
|
|
|
int post_north()
|
|
{
|
|
//might as well delete it, it's served its purpose.
|
|
this_player()->RemoveProperty("rung_bell");
|
|
return 1;
|
|
}
|
|
|
|
|
|
//We're going to delete the exit AFTER the player walks through
|
|
// Because doing it in a pre_exit would be tatamount to slamming
|
|
// a door in their face. You wouldn't want to do that... would you? :P
|
|
|
|
|
|
int post_south()
|
|
{
|
|
write("You hear a noise and realize the wall has mysteriously closed.\n");
|
|
say("You hear a noise and realize the wall has mysteriously closed.\n");
|
|
this_player()->eventMoveLiving("/domains/examples/room/exroom3", "south", this_player()->GetName()+" enters.");
|
|
RemoveExit("south");
|
|
SetObviousExits("n");
|
|
}
|