[CODE SNIPPET] Advanced item loading limits

From: Andrey Fidrya (andrey@ALEX-UA.COM)
Date: 10/09/97


Hi, All!

Stock CircleMUD checks EQ limits according on objects which are currently
in game at the moment of EQ load. After applying this patch, objects
inside playerbase will be counted too.

Example:
  Sword's maximum is 5. There is currently 2 swords in the game and
  rented player has 2 swords (stored in playerbase).
Stock Circle:
  Swords will be loaded until 5 swords in the game is reached. So, 3 swords
  will load. After this, if player with 2 swords logs into the game, current
  number of swords will be 7 (with max of 5 allowed!).
After applying this patch:
  Swords will be loaded until 5 swords in (game+playerbase) is reached.
  So, only 1 sword will load.

This patch was tested on stock Circle30bpl11 under WIN'95 but should work
on *NIX too.

Warning: This patch is a hack on some CircleMUD functions.


In "objsave.c" in:
---------------------------------------------------------------
struct obj_data *Obj_from_store(struct obj_file_elem object)
{
---------------------------------------------------------------
after:
---------------------------------------------------------------
  if (real_object(object.item_number) > -1) {
    obj = read_object(object.item_number, VIRTUAL);
---------------------------------------------------------------
add:
---------------------------------------------------------------
    /* AF/103: decrement number, because read_object just incremented it */
    if (GET_OBJ_RNUM(obj) >= 0)
      --obj_index[GET_OBJ_RNUM(obj)].number;
---------------------------------------------------------------
In:
---------------------------------------------------------------
void Crash_extract_objs(struct obj_data * obj)
{
---------------------------------------------------------------
after:
---------------------------------------------------------------
  if (obj) {
    Crash_extract_objs(obj->contains);
    Crash_extract_objs(obj->next_content);
---------------------------------------------------------------
add:
---------------------------------------------------------------
    /* AF/103: increment number because extract_obj will decrement it */
    if (GET_OBJ_RNUM(obj) >= 0)
      ++obj_index[GET_OBJ_RNUM(obj)].number;
---------------------------------------------------------------
Ok, now renting system will no longer change total number of items.

In "db.c" in:

---------------------------------------------------------------
/* body of the booting system */
void boot_db(void)
{
---------------------------------------------------------------
after:
---------------------------------------------------------------
  if (!no_specials) {
    log("   Mobiles.");
    assign_mobiles();
    log("   Shopkeepers.");
    assign_the_shopkeepers();
    log("   Objects.");
    assign_objects();
    log("   Rooms.");
    assign_rooms();
  }
---------------------------------------------------------------
add (and prototype it if needed):
---------------------------------------------------------------
  log("Reading num objects loaded...");
  read_obj_num();
---------------------------------------------------------------
Somewhere in db.c, insert these functions:
---------------------------------------------------------------
/* used by read_obj_num - scans through all objects of current player and
   increments total number of each type of object                         */
int count_objects(char *name)
{
  FILE *fl;
  char fname[MAX_STRING_LENGTH];
  struct obj_file_elem object;
  struct rent_info rent;
  int i, total_objects = 0;

  if (!get_filename(name, fname, CRASH_FILE))
    return 0;
  if (!(fl = fopen(fname, "r+b"))) {
    if (errno != ENOENT) {      /* if it fails, NOT because of no file */
      sprintf(buf1, "SYSERR: count_objects: READING OBJECT FILE %s (5)", fname);
      perror(buf1);
    }
    return 0;
  }
  if (!feof(fl))
    fread(&rent, sizeof(struct rent_info), 1, fl);

  while (!feof(fl)) {
    fread(&object, sizeof(struct obj_file_elem), 1, fl);
    if (ferror(fl)) {
      perror("count_objects: Reading crash file: Crash_load.");
      fclose(fl);
      return total_objects;
    }
    if (!feof(fl)) {
      i = real_object(object.item_number);
      if (i > -1) {
        ++obj_index[i].number;
        ++total_objects;
      } else {
        sprintf(buf, "count_objects: Object (V) %d does not exist in database.",
                object.item_number);
        log(buf);
      }
    }
  }

  fclose(fl);

  return total_objects;
}

/* Reads and sets total number of objects of same type in game */
void read_obj_num(void)
{
  FILE *player_fl;
  struct char_file_u dummy;
  int nr = -1, total_objects = 0;
  long size, recs;

  if (!(player_fl = fopen(PLAYER_FILE, "r+b"))) {
    if (errno != ENOENT) {
      perror("read_obj_num was unable to open playerfile");
      exit(1);
    } else {
      log("No playerfile.  Read_obj_num disabled.");
      return;
    }
  }

  fseek(player_fl, 0L, SEEK_END);
  size = ftell(player_fl);
  rewind(player_fl);
  if (size % sizeof(struct char_file_u))
    fprintf(stderr, "\aWARNING:  PLAYERFILE IS PROBABLY CORRUPT!\n");
  recs = size / sizeof(struct char_file_u);
  if (recs) {
    sprintf(buf, "   found %ld players, now counting objects:", recs);
    log(buf);
  } else
    return;

  for (; !feof(player_fl);) {
    fread(&dummy, sizeof(struct char_file_u), 1, player_fl);
    if (!feof(player_fl))
      total_objects += count_objects(dummy.name);
  }

  sprintf(buf, "   %d objects total.", total_objects);
  log(buf);

  fclose(player_fl);
}
---------------------------------------------------------------

Thats all.

Feel free to mail me any bugs you find.

  Andrey (andrey@alex-ua.com)      Kiev, Ukraine
    aka Zmey//RMUD (Russian MUD Project)


     +------------------------------------------------------------+
     | 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/08/00 PST