Exemple #1
0
/*
 * return values:
 * 0 - successful load, keep char in rent room.
 * 1 - load failure or load of crash items -- put char in temple.
 * 2 - rented equipment lost (no $)
 */
int Crash_load(struct char_data * ch)
{
  FILE *fl;
  char fname[MAX_STRING_LENGTH];
  struct obj_file_elem object;
  struct rent_info rent;
  int    cost, orig_rent_code, num_objs = 0, j;
  float  num_of_days;
  struct obj_data *obj, *obj2, *cont_row[MAX_BAG_ROWS];
  int    location;

  /* Empty all of the container lists (you never know ...) */
  for (j = 0; j < MAX_BAG_ROWS; j++)
    cont_row[j] = NULL;

  if (!get_filename(GET_NAME(ch), fname, CRASH_FILE))
    return 1;

  if (!(fl = fopen(fname, "r+b"))) {
    if (errno != ENOENT) {      /* if it fails, NOT because of no file */
      sprintf(buf1, "SYSERR: READING OBJECT FILE %s (5)", fname);
      perror(buf1);
      send_to_char("\r\n********************* NOTICE *********************\r\n"
		   "There was a problem loading your objects from disk.\r\n"
		   "Contact a God for assistance.\r\n", ch);
    }
    sprintf(buf, "%s entering game with NO equipment.", GET_NAME(ch));
    mudlog(buf, NRM, MAX((int)LVL_IMMORT, (int)GET_INVIS_LEV(ch)), TRUE);
    return 1;
  }
  if (!feof(fl))
    fread(&rent, sizeof(struct rent_info), 1, fl);
  else {
    plog("SYSERR: Crash_load: %s's rent file was empty!", GET_NAME(ch));
    return 1;
  }

  if (rent.rentcode == RENT_RENTED || rent.rentcode == RENT_TIMEDOUT) {
    num_of_days = (float) (time(0) - rent.time) / SECS_PER_REAL_DAY;
    cost = (int) (rent.net_cost_per_diem * num_of_days);
    if (cost > GET_GOLD(ch) + GET_BANK_GOLD(ch)) {
      fclose(fl);
      sprintf(buf, "%s entering game, rented equipment lost (no $).",
	      GET_NAME(ch));
      mudlog(buf, BRF, MAX((int)LVL_IMMORT, (int)GET_INVIS_LEV(ch)), TRUE);
      Crash_crashsave(ch);
      return 2;
    } else {
      GET_BANK_GOLD(ch) -= MAX((long)cost - GET_GOLD(ch), 0L);
      GET_GOLD(ch) = MAX((long)GET_GOLD(ch) - cost, 0L);
      save_char(ch, NOWHERE);
    }
  }
  switch (orig_rent_code = rent.rentcode) {
  case RENT_RENTED:
    sprintf(buf, "%s un-renting and entering game.", GET_NAME(ch));
    mudlog(buf, NRM, MAX((int)LVL_IMMORT, (int)GET_INVIS_LEV(ch)), TRUE);
    break;
  case RENT_CRASH:
    sprintf(buf, "%s retrieving crash-saved items and entering game.", GET_NAME(ch));
    mudlog(buf, NRM, MAX((int)LVL_IMMORT, (int)GET_INVIS_LEV(ch)), TRUE);
    break;
  case RENT_CRYO:
    sprintf(buf, "%s un-cryo'ing and entering game.", GET_NAME(ch));
    mudlog(buf, NRM, MAX((int)LVL_IMMORT, (int)GET_INVIS_LEV(ch)), TRUE);
    break;
  case RENT_FORCED:
  case RENT_TIMEDOUT:
    sprintf(buf, "%s retrieving force-saved items and entering game.", GET_NAME(ch));
    mudlog(buf, NRM, MAX((int)LVL_IMMORT, (int)GET_INVIS_LEV(ch)), TRUE);
    break;
  default:
    sprintf(buf, "WARNING: %s entering game with undefined rent code.", GET_NAME(ch));
    mudlog(buf, BRF, MAX((int)LVL_IMMORT, (int)GET_INVIS_LEV(ch)), TRUE);
    break;
  }

  while (!feof(fl)) {
    fread(&object, sizeof(struct obj_file_elem), 1, fl);
    if (ferror(fl)) {
      perror("Reading crash file: Crash_load.");
      fclose(fl);
      return 1;
    }

    if (feof(fl))
      break;

    ++num_objs;
    if ( (obj = Obj_from_store(object, &location)) == NULL )
      continue;

    auto_equip( ch, obj, location );

    /*
     * What to do with a new loaded item:
     *
     * If there's a list with location less than 1 below this, then its
     * container has disappeared from the file so we put the list back into
     * the character's inventory. (Equipped items are 0 here.)
     *
     * If there's a list of contents with location of 1 below this, then we
     * check if it is a container:
     *   - Yes: Get it from the character, fill it, and give it back so we
     *          have the correct weight.
     *   -  No: The container is missing so we put everything back into the
     *          character's inventory.
     *
     * For items with negative location, we check if there is already a list
     * of contents with the same location.  If so, we put it there and if not,
     * we start a new list.
     *
     * Since location for contents is < 0, the list indices are switched to
     * non-negative.
     *
     * This looks ugly, but it works.
     */
    if (location > 0) {		/* Equipped */
      for (j = MAX_BAG_ROWS - 1; j > 0; j--) {
        if (cont_row[j]) {	/* No container, back to inventory. */
          for (; cont_row[j]; cont_row[j] = obj2) {
            obj2 = cont_row[j]->next_content;
            obj_to_char(cont_row[j], ch);
          }
          cont_row[j] = NULL;
        }
      }
      if (cont_row[0]) {	/* Content list existing. */
        if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER) {
	/* Remove object, fill it, equip again. */
          obj = unequip_char(ch, location - 1);
          obj->contains = NULL;	/* Should be NULL anyway, but just in case. */
          for (; cont_row[0]; cont_row[0] = obj2) {
            obj2 = cont_row[0]->next_content;
            obj_to_obj(cont_row[0], obj);
          }
          equip_char(ch, obj, location - 1);
        } else {			/* Object isn't container, empty the list. */
          for (; cont_row[0]; cont_row[0] = obj2) {
            obj2 = cont_row[0]->next_content;
            obj_to_char(cont_row[0], ch);
          }
          cont_row[0] = NULL;
        }
      }
    } else {	/* location <= 0 */
      for (j = MAX_BAG_ROWS - 1; j > -location; j--) {
        if (cont_row[j]) {	/* No container, back to inventory. */
          for (; cont_row[j]; cont_row[j] = obj2) {
            obj2 = cont_row[j]->next_content;
            obj_to_char(cont_row[j], ch);
          }
          cont_row[j] = NULL;
        }
      }
      if (j == -location && cont_row[j]) {	/* Content list exists. */
        if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER) {
		/* Take the item, fill it, and give it back. */
          obj_from_char(obj);
          obj->contains = NULL;
          for (; cont_row[j]; cont_row[j] = obj2) {
            obj2 = cont_row[j]->next_content;
            obj_to_obj(cont_row[j], obj);
          }
          obj_to_char(obj, ch);	/* Add to inventory first. */
        } else {	/* Object isn't container, empty content list. */
          for (; cont_row[j]; cont_row[j] = obj2) {
            obj2 = cont_row[j]->next_content;
            obj_to_char(cont_row[j], ch);
          }
          cont_row[j] = NULL;
        }
      }
      if (location < 0 && location >= -MAX_BAG_ROWS) {
        /*
         * Let the object be part of the content list but put it at the
         * list's end.  Thus having the items in the same order as before
         * the character rented.
         */
        obj_from_char(obj);
        if ((obj2 = cont_row[-location - 1]) != NULL) {
          while (obj2->next_content)
            obj2 = obj2->next_content;
          obj2->next_content = obj;
        } else
          cont_row[-location - 1] = obj;
      }
    }
  }

  /* Little hoarding check. -gg 3/1/98 */
  sprintf(fname, "%s (level %d) has %d object%s (max %d).",
          GET_NAME(ch), GET_LEVEL(ch), num_objs,
          num_objs != 1 ? "s" : "", max_obj_save);
  mudlog(fname, NRM, MAX(GET_INVIS_LEV(ch), LVL_GOD), TRUE);

  /* turn this into a crash file by re-writing the control block */
  rent.rentcode = RENT_CRASH;
  rent.time = time(0);
  rewind(fl);
  Crash_write_rentcode(ch, fl, &rent);

  fclose(fl);

  if ((orig_rent_code == RENT_RENTED) || (orig_rent_code == RENT_CRYO))
    return (0);
  else
    return (1);
}
Exemple #2
0
int handle_obj(struct obj_data *temp, struct char_data *ch, int locate, struct obj_data **cont_row)
{
  int j;
  struct obj_data *obj1;

  if (!temp)  /* this should never happen, but.... */
    return (0);

  auto_equip(ch, temp, locate);

  /* 
     what to do with a new loaded item:

     if there's a list with <locate> less than 1 below this:
     (equipped items are assumed to have <locate>==0 here) then its
     container has disappeared from the file   *gasp*
     -> put all the list back to ch's inventory
     if there's a list of contents with <locate> 1 below this:
     check if it's a container
     - if so: get it from ch, fill it, and give it back to ch (this way the
     container has its correct weight before modifying ch)
     - if not: the container is missing -> put all the list to ch's inventory

     for items with negative <locate>:
     if there's already a list of contents with the same <locate> put obj to it
     if not, start a new list

     Confused? Well maybe you can think of some better text to be put here ...

     since <locate> for contents is < 0 the list indices are switched to
     non-negative
  */

  if (locate > 0) { /* item equipped */

    for (j = MAX_BAG_ROWS-1;j > 0;j--)
      if (cont_row[j]) { /* no container -> back to ch's inventory */
        for (;cont_row[j];cont_row[j] = obj1) {
          obj1 = cont_row[j]->next_content;
          obj_to_char(cont_row[j], ch);
        }
        cont_row[j] = NULL;
      }
    if (cont_row[0]) { /* content list existing */
      if (GET_OBJ_TYPE(temp) == ITEM_CONTAINER) {
        /* rem item ; fill ; equip again */
        temp = unequip_char(ch, locate-1);
        temp->contains = NULL; /* should be empty - but who knows */
        for (;cont_row[0];cont_row[0] = obj1) {
          obj1 = cont_row[0]->next_content;
          obj_to_obj(cont_row[0], temp);
        }
        equip_char(ch, temp, locate-1);
      } else { /* object isn't container -> empty content list */
        for (;cont_row[0];cont_row[0] = obj1) {
          obj1 = cont_row[0]->next_content;
          obj_to_char(cont_row[0], ch);
        }
        cont_row[0] = NULL;
      }
    }
  } else { /* locate <= 0 */
    for (j = MAX_BAG_ROWS-1;j > -locate;j--)
      if (cont_row[j]) { /* no container -> back to ch's inventory */
        for (;cont_row[j];cont_row[j] = obj1) {
          obj1 = cont_row[j]->next_content;
          obj_to_char(cont_row[j], ch);
        } 
        cont_row[j] = NULL;
      }

    if (j == -locate && cont_row[j]) { /* content list existing */
      if (GET_OBJ_TYPE(temp) == ITEM_CONTAINER) {
        /* take item ; fill ; give to char again */
        obj_from_char(temp);
        temp->contains = NULL;
        for (;cont_row[j];cont_row[j] = obj1) {
          obj1 = cont_row[j]->next_content;
          obj_to_obj(cont_row[j], temp);
        }
        obj_to_char(temp, ch); /* add to inv first ... */
      } else { /* object isn't container -> empty content list */
        for (;cont_row[j];cont_row[j] = obj1) {
          obj1 = cont_row[j]->next_content;
          obj_to_char(cont_row[j], ch);
        }
        cont_row[j] = NULL;
      }
    }

    if (locate < 0 && locate >= -MAX_BAG_ROWS) {
      /* let obj be part of content list
         but put it at the list's end thus having the items
         in the same order as before renting */
      obj_from_char(temp);
      if ((obj1 = cont_row[-locate-1])) {
        while (obj1->next_content)
          obj1 = obj1->next_content;
        obj1->next_content = temp;
      } else
        cont_row[-locate-1] = temp;
    }
  } /* locate less than zero */

  return (1);
}