CRASH: Any ideas whay this causes a crash?

From: Fionn Colvin (fcolvin@metz.une.edu.au)
Date: 10/13/96


Hiya all,
         I'm in the process of making a brew skill which allows a player
to brew together a number of ingredients and make a potion from them. They
type something like:

brew water turnip foxweed dandylion

The command creates a potion correctly, but if a player quaffs the potion
the mud crashes. Any ideas why? The code follows.
If I stat the potion it all seems fine, says its type potion, spell level
10 and has armor spell with other 2 unused.

The last line of my syslog file is:

Assertion failed: (struct header *)lblk > arena, file ../malloc.c, line 454

The mud crashed at the following line:

in db.c

void free_obj(struct obj_data * obj)

<stuff>

if ((nr = GET_OBJ_RNUM(obj)) == -1) {
  if (obj->name)
    free(obj->name)            <-------------- Just here!

<stuff>



#################
# MY ADDED CODE #
#################

##########################
# Array of legal potions #
##########################

struct potion_list {
  int items_needed[4];
  char *potion_alias;
  char *potion_short;
  char *potion_long;
  int potion_values[4];
} potions[] = {

{{ 24, 25, 26, 27},                     /* Armor Potion */
 "brown potion",
 "a brown potion",
 "A brown potion lies here.",
 { 10, 1, -1, -1}},

{{ -1, -1, -1, 1},                      /* Empty Potion */
 "empty potion",
 "an empty potion",
 "An empty potion lies here.",
 {1, -1, -1, -1}}
};


#############
# Brew Code #
#############

int items_match(int item_numbers[4], int pos)
{
  if ((item_numbers[0] == potions[pos].items_needed[0]) &&
      (item_numbers[1] == potions[pos].items_needed[1]) &&
      (item_numbers[2] == potions[pos].items_needed[2]) &&
      (item_numbers[3] == potions[pos].items_needed[3]))
    return(1);
  return(0);
}

void create_potion(struct char_data *ch, int pos)
{
  struct obj_data *potion;
  int temp = 0;

  potion = create_obj();

  potion->item_number = NOTHING;
  potion->in_room = NOWHERE;
  potion->name = potions[pos].potion_alias;
  potion->short_description = potions[pos].potion_short;
  potion->description = potions[pos].potion_long;
  GET_OBJ_TYPE(potion) = ITEM_POTION;
  GET_OBJ_WEAR(potion) = ITEM_WEAR_TAKE;
  GET_OBJ_WEIGHT(potion) = 5;
  GET_OBJ_RENT(potion) = 0;
  GET_OBJ_COST(potion) = 1;
  for (temp = 0; temp < 4; temp ++)
    GET_OBJ_VAL(potion, temp) = potions[pos].potion_values[temp];
  obj_to_char(potion, ch);
  sprintf(buf, "You mix the ingredients and create %s.\r\n", potion->short_description);
  send_to_char(buf, ch);
  act("$n mixes some ingredients and creates $p.", TRUE, ch, 0, potion, TO_ROOM);
}


ACMD(do_brew)
{
  char arg0[MAX_INPUT_LENGTH];
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  char arg3[MAX_INPUT_LENGTH];

  struct char_data *person = NULL;
  struct obj_data *item0 = NULL;
  struct obj_data *item1 = NULL;
  struct obj_data *item2 = NULL;
  struct obj_data *item3 = NULL;
  int item_numbers[4] = { -1, -1, -1, -1};
  int temp1, temp2, temp3;


  if (!*argument) {
    send_to_char("You mix nothing together, and to no ones amazement, create nothing!\r\n", ch);
    return;
  }

  argument = one_argument(argument, arg0);
  argument = one_argument(argument, arg1);
  argument = one_argument(argument, arg2);
  argument = one_argument(argument, arg3);

  if (*arg0) {
    if (!generic_find(arg0, FIND_OBJ_INV, ch, &person, &item0)) {
      sprintf(buf, "You don't seem to have %s %s.\r\n", AN(arg0), arg0);
      send_to_char(buf, ch);
      return;
    }
    item_numbers[0] = GET_OBJ_VNUM(item0);
  }

  if (*arg1) {
    if (!generic_find(arg1, FIND_OBJ_INV, ch, &person, &item1)) {
      sprintf(buf, "You don't seem to have %s %s.\r\n", AN(arg1), arg1);
      send_to_char(buf, ch);
      return;
    }
    item_numbers[1] = GET_OBJ_VNUM(item1);
  }

  if (*arg2) {
    if (!generic_find(arg2, FIND_OBJ_INV, ch, &person, &item2)) {
      sprintf(buf, "You don't seem to have %s %s.\r\n", AN(arg2), arg2);
      send_to_char(buf, ch);
      return;
    }
    item_numbers[2] = GET_OBJ_VNUM(item2);
  }

  if (*arg3) {
    if (!generic_find(arg3, FIND_OBJ_INV, ch, &person, &item3)) {
      sprintf(buf, "You don't seem to have %s %s.\r\n", AN(arg3), arg3);
      send_to_char(buf, ch);
      return;
    }
    item_numbers[3] = GET_OBJ_VNUM(item3);
  }

  if ((item0 == NULL) || (item1 == NULL)) {
    send_to_char("Every potion needs at least two ingredients!\r\n", ch);
    return;
  }

  extract_obj(item0);
  extract_obj(item1);
  if (item2 != NULL)
    extract_obj(item2);
  if (item3 != NULL)
    extract_obj(item3);

  for (temp3 = 0; temp3 < 3; temp3 ++)
    for (temp1 = 0; temp1 < 3; temp1 ++)
      if (item_numbers[temp1] > item_numbers[temp1 + 1]) {
        temp2 = item_numbers[temp1];
        item_numbers[temp1] = item_numbers[temp1 + 1];
        item_numbers[temp1 + 1] = temp2;
      }

  temp1 = 0;

  while (potions[temp1].items_needed[2] != -1) {
    if (items_match(item_numbers, temp1)) {
      create_potion(ch, temp1);
      return;
    }
    temp1 ++;
  }
  send_to_char("You mix the ingredients, but create nothing but a mess.\r\n", ch);
  act("$n mixes some ingredients, but creates nothing but a mess.", TRUE, ch, 0, 0, TO_ROOM);
  return; 
}


##############################
# Some items used by command #
##############################

#24
flask salt water~
@c12a flask of salt water@c00~
A flask of @c12salt water@c00 lies here.~
~
12 0 ml
0 0 0 0
1 0 0
#25
foxweed~
@c09some foxweed@c00~
Some @c09foxweed@c00 lies here.~
~
12 0 ml
0 0 0 0
1 0 0
#26
turnip~
@c02a green turnip@c00~
A @c02green turnip@c00 lies here.~
~
12 0 ml
0 0 0 0
1 0 0
#27
dandylion~
@c11some dandylion@c00~
Some @c11dandylion@c00 lies here.~
~
12 0 ml
0 0 0 0
1 0 0
+-----------------------------------------------------------+
| Ensure that you have read the CircleMUD Mailing List FAQ: |
|   http://cspo.queensu.ca/~fletcher/Circle/list_faq.html   |
+-----------------------------------------------------------+



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