User Tools

Site Tools


coding:advancedroom

TODO: cleanup layout

Document for my waste#.c rooms Boss 10/99

This is intended as a walk through help file for wizards who want to make rooms that are more than just long descriptions and exits. No, adding 4 items doesn't count ;P I am assuming that who ever reads this knows how to use ed. If you don't, read /doc/wizards/build/ed0-ed4 All real code that you can copy/paste is enclosed within the – segments

Step 1: Make a basic room. Here is sample code and comments for new wizards:

/*--------------------------------------------------------------------*/
inherit "/room/newroom" ; //For all functions to work, inherit newroom.c
reset( arg ) //Everything the room needs happens after this
{
   if( arg ) //Put stuff in when a reset occurs
      return ;
 
   set_indoor() ; //tells the room you are indoors
   make_light(1) ; //makes the light level 1 (this function is dangerous)
   short_desc = "A boring room" ; //The short desc that is seen when in brief
   long_desc = "This is a boring room, there is nothing special here.\n" ;
/* The description that is seen when one enters a room or types look/examine */
   dest_dir = /* the directions a player can leave */
   ([
      "east" : "/players/yourname/boringroom2",
      "west" : "/players/yourname/boringroom3",
   ]);
   items = /* things that can be seen by <look at nothing> */
   ([
      "nothing" : "This is more nothing.",
   ]);
    set_planet("earth") ; //the planet for the various daemon funcs...
}
/*--------------------------------------------------------------------*/

Now for the run down: If you use a text editor offline to make the rooms do NOT use tabs. To correctly space out code use 2 spaces for each indent (Sauron). This is so that when someone wants to read your code using ed, they see the correct spacing instead of the character for tab…

Ok, now that you have a boring room, here is how to make it better. If it is outdoors, make it outdoors. This allows for the planet daemons to do stuff. When I wrote this, the daemons changed the time of day, temprature, and light level for night/day. Of course, you can make your own events and here is how.

1. set_indoor() ; /* You have to do this otherwise the planet daemon sends you the other messages as well as the ones you set */

2. make_light(1) ; /* This function is dangerous because it ignores all light in the room ie torches/ixian eyes. Use set_light(1) ; if you don't understand how the light system works */

3. Make a long_desc as shown above that has no mention of time, this is basically the default. Or if you don't want to make a different long_desc for each time_event.

4. Add the new events. This comes after the final } in the reset func

/*--------------------------------------------------------------------*/
notify_time_event(int day_stat)
/* set up the different conditions for the times of day */
{
   switch((int)day_stat) 
   {
      default:
         tell_room(this_object(), "It is nearing dawn.\n") ;
         break ;
 
      case 0:
         tell_room(this_object(), "It is nearing dawn") ;
         break ;
 
      case 1:
         tell_room(this_object(), "It is mid day\n") ;
         break ;
 
      case 2:
         tell_room(this_object(), "It is evening\n") ;
         break ;
 
      case 3:
         tell_room(this_object(),"It is midnight\n") ;
         break;
   }   
}
/*--------------------------------------------------------------------*/

When the time event changes the room will tell all the players the above.

5. Ok now you have the time of day changes…time to add the long_desc:

In each case statement, write a new long_desc that says something about the time of day:

/*--------------------------------------------------------------------*/
      case 3:
         tell_room(this_object(),"It is midnight\n") ;
         long_desc = "This is a slightly less boring room. It is mid night.\n" ;
         break;
/*--------------------------------------------------------------------*/

You can take this as far as you want. You can even redefine the desc of items to include shadows. Basically the more interactive descriptive stuff you add, the cooler you are (that or REAL players will apreciate your area more). Adding items that are objects (actually there as opposed to just descs) is cool, but it takes up memory. For this reason, adding stuff like street lamps, or other items that are no_get is not encouraged.

6. Exits

Yes, a player can just type e and end up in the next room, but what fun is that? In my example of a good room, I allow the players to walk, unhindered, during the day. But at night, instead of a room all players hate (light -1), I added exit functions. The room doesn't get dark, instead the long_desc tells the player it is dark, they can't see much, and when they exit: the fun begins.

/*--------------------------------------------------------------------*/
      case 3:
         tell_room(this_object(),"It is midnight\n") ;
         long_desc = "This is a slightly less boring room. It is mid night.\n" ;
         dest_dir = 
         ([
            "east": #'east_dark,
            "west" : #'west_dark,
         ]);
         break;
/*--------------------------------------------------------------------*/

Ok to set this up you need a few thing: a. You need the prototypes for these functions b. You need to define them

A prototype is a declaration of the function which comes at the beginning of the .c file (we don't use .h, header files)

/*--------------------------------------------------------------------*/
inherit "/room/newroom";
 
/* prototypes */
east_dark() ; //move east when it is dark
west_dark() ; //move west when it is dark
/*--------------------------------------------------------------------*/

Now for a definition:

/*--------------------------------------------------------------------*/
east_dark() //do this if going east in the dark
{
   write("You stumble in the dark.\n") ;
   say(capitalize(name) + " stumbles in the dark.\n") ;
   TP->move_player("east#/players/yourname/boringroom2") ;
   return 1 ;
}
/*--------------------------------------------------------------------*/

Do the same for west_dark() This is a slightly less boring movement, but TP has to be defined.

/*--------------------------------------------------------------------*/
inherit "/room/newroom";
#define TP this_player()
 
/* prototypes */
east_dark() ; //move east when it is dark
west_dark() ; //move west when it is dark
/*--------------------------------------------------------------------*/

The movement is interesting, but to make it more realistic, add a delay to the completion of the movement. I use the call_out function for this. It is not recomended that new wizards use call_out() because if you fail to finish it or call multiple call_out()s the mud will lag. In my example room, it is impossible for the call_out() functions to add up, but if you are unsure, use remove_call_out() before all call_out()s.

/*--------------------------------------------------------------------*/
east_dark() //do this if going east in the dark
{
   write("You stumble in the dark.\n") ;
   say(capitalize(name) + " stumbles in the dark.\n") ;
   call_out("finish_move", 2) ;
   return 1 ;
}
/*--------------------------------------------------------------------*/

The call_out does the delay. Type man call_out for more info. To make the code neat, and allow for further adaptions, we need to declare and define the finish_move() function. Just add: finish_move(); to the prototype list.

Definition:

/*--------------------------------------------------------------------*/
finish_move()
{
   TP->move_player("east#/players/yourname/boringroom2") ;
}
/*--------------------------------------------------------------------*/

*Note* the “east#/blah” is required to tell the room what direction the player is leaving. It can be “nowhere#/blah”…

We now come to a slight problem. If you are delaying the player, what is to stop them from entering more direction commands while the call_out is being done? The answer is a variable that keeps track of the movement being done…it is called a flag.

In my room, I called it is_moving. It is an int that is either 0 or 1. Make it global so all functions know what it is. Add it right after the #define TP line:

/*--------------------------------------------------------------------*/
/* globals */
int is_moving ; //Keeps track of movement actions so they can't build up
/*--------------------------------------------------------------------*/

Now every function in this room can “see” the value of is_moving. To implement this flag into your code simply query it before any action, set it to 1 (true) when you start an action, and set it to 0 (false) when you have completed that action:

/*--------------------------------------------------------------------*/
east_dark() //do this if going east in the dark
{
   if(is_moving==1)
   {
      write("You are already trying to go somewhere.\n") ;
      return 1 ;
   }
   else
   {
      is_moving = 1 ; //movement is happening
 
      write("You stumble in the dark.\n") ;
      say(capitalize(name) + " stumbles in the dark.\n") ;
      call_out("finish_move", 2) ;
      return is_moving ; //need to return 1 anyway...
   }
}
/*--------------------------------------------------------------------*/

The finish_move() func must be updated as well

/*--------------------------------------------------------------------*/
finish_move()
{
   TP->move_player("east#/players/yourname/boringroom2") ;
   is_moving = 0 ; 
}
/*--------------------------------------------------------------------*/

From here you can add many more ways of exiting the room. In my example room, I give the players a chance based on a random They succeed with no delay. The are hindered but succeed with a delay. They are hindered and fail to go the right way. They are hindered and go nowhere. They are hindered, go nowhere, and have the possiblity of being attacked.

It takes a while to bang all these functions out, and it may not seem like it is worth it. Remember you should be proud of your area, and REAL players will appreciate it. I am not going to put the code for all those functions in this document, but it should be fairly obvious by now what they do and how they do it. Just a few notes are in order:

switch(random(10)) 
{}

This generates a “random” number between 0 and 9.

call_out("finish_move", 1, 2, 1,) ;

This calls the function finish_move(2,1) with a 1 second delay

I query if a player has a luckstone in the call_guards() function. If they do, they get lucky more often, duh.

Now go out and make rooms that rock the mud, etc.

coding/advancedroom.txt · Last modified: 2010/04/27 07:00 by temujin