Re: [CODE] A room making function

From: John Evans (evansj@HI-LINE.NET)
Date: 02/17/98


On Tue, 17 Feb 1998, Chuck Reed wrote:

> I am not to hot in OLC type things and my knowledge barely extends to
> adding onto basic OLC functions.  I was wondering if anyone had, will, or
> would point me in the right direction of making a function in OLC that will
> create blank rooms in a zone.

Here's the function that I wrote to do something similar a couple days
ago. I pulled the code from redit.c in the save internally function. It's
all hackish and probably ugly, but the code works. I removed alot of
white space from the email in hopes that it will fall under the 200 line
limit. That'll make the code a bt harder to read.

/* Function to make a new room */
#define ZCMD zone_table[zone].cmd[cmd_no]
#define  W_EXIT(room, num) (world[(room)].dir_option[(num)])
void create_new_room(int number)
{
  extern int top_of_world;
  extern room_num r_mortal_start_room;
  extern room_num r_immort_start_room;
  extern room_num r_frozen_start_room;
  int i, j, room_num = real_room(number), found = FALSE, zone, cmd_no;
  struct room_data *new_world;
  struct char_data *temp_ch;
  struct obj_data *temp_obj;

  CREATE(new_world, struct room_data, top_of_world + 2);
  /* count thru world tables */
  for (i = 0; i <= top_of_world; i++)  {
    if (!found) {
      /*. Is this the place? .*/
      if (world[i].number > number) {
        found = 1;
        new_world[i].name = str_dup("An unfinished room");
        new_world[i].description = str_dup("You are in an "
                                           "unfinished room.\r\n");
        new_world[i].contents = NULL;
        new_world[i].people = NULL;
        new_world[i].light = 0;
        new_world[i].ex_description = NULL;
        new_world[i].number = number;
        new_world[i].zone = world[number / 100].zone;
        new_world[i].func = NULL;
        room_num  = i;
        /* copy from world to new_world + 1 */
        new_world[i + 1] = world[i];
        /* people in this room must have their numbers moved */
        for (temp_ch = world[i].people; temp_ch;
             temp_ch = temp_ch->next_in_room)
          if (temp_ch->in_room != -1)
            temp_ch->in_room = i + 1;
        /* move objects */
        for (temp_obj = world[i].contents; temp_obj; temp_obj =
             temp_obj->next_content)
          if (temp_obj->in_room != -1)
            temp_obj->in_room = i + 1;
      } else {
        new_world[i] = world[i];
      }
    } else {
      /* people in this room must have their in_rooms moved */
      for (temp_ch = world[i].people; temp_ch;
           temp_ch = temp_ch->next_in_room)
        if (temp_ch->in_room != -1)
          temp_ch->in_room = i + 1;
      /* move objects */
      for (temp_obj = world[i].contents; temp_obj; temp_obj =
           temp_obj->next_content)
        if (temp_obj->in_room != -1)
          temp_obj->in_room = i + 1;
      new_world[i + 1] = world[i];
    }
  }
  if (!found) {
    /*. Still not found, insert at top of table .*/
    new_world[i].name = str_dup("An unfinished room");
    new_world[i].description = str_dup("You are in an unfinished room.\r\n");
    new_world[i].contents = NULL;
    new_world[i].people = NULL;
    new_world[i].light = 0;
    new_world[i].ex_description = NULL;
    new_world[i].number = number;
    new_world[i].zone = world[number / 100].zone;
    new_world[i].func = NULL;
    room_num  = i;
  }
  /* copy world table over */
  free(world);
  world = new_world;
  top_of_world++;
  /*. Update zone table .*/
  for (zone = 0; zone <= top_of_zone_table; zone++)
    for (cmd_no = 0; ZCMD.command != 'S'; cmd_no++)
      switch (ZCMD.command) {
        case 'M':
        case 'O':
          if (ZCMD.arg3 >= room_num)
            ZCMD.arg3++;
        break;
        case 'D':
        case 'R':
          if (ZCMD.arg1 >= room_num)
            ZCMD.arg1++;
        case 'G':
        case 'P':
        case 'E':
        case '*':
          break;
        default:
          mudlog("SYSERR: OLC: create_new_room: Unknown comand",
                 BRF, LVL_BUILDER, TRUE);
      }
  /* update load rooms, to fix creeping load room problem */
  if (room_num <= r_mortal_start_room)
    r_mortal_start_room++;
  if (room_num <= r_immort_start_room)
    r_immort_start_room++;
  if (room_num <= r_frozen_start_room)
    r_frozen_start_room++;
  /*. Update world exits .*/
  for (i = 0; i < top_of_world + 1; i++)
    for (j = 0; j < NUM_OF_DIRS; j++)
      if (W_EXIT(i, j))
        if (W_EXIT(i, j)->to_room >= room_num)
          W_EXIT(i, j)->to_room++;
}

Hope this helps.

PS: The reason I wrote this was so that my nexit command (you probably
called it 'dig') and duperoom (you probably called it 'copyto') would not
report "Room doesn't exist", but would just make the room and go on.

Now that I've looked at it, I think that a FREE(new_world) call is needed
at the bottom to prevent a mem-leak. I don't have one at anywhere in my
redit_save_iternally. Any comments from anyone?

John Evans <evansj@hi-line.net>  --  http://www.hi-line.net/~evansj/

Any sufficiently advanced technology is indistinguishable from magic.
--Arthur C. Clarke


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/15/00 PST