[CODE] [LONG] [NEED HELP] Need help with specialize corpse looting code

From: Rob Masten (Diablo@deathwalker.net)
Date: 03/01/01


I am trying to implement code that makes it impossible to loot more than one
'trophy' item from a player's corpse, unless you are the corpse's owner OR
you
are in a list of 'allowed to loot my corpse' created by the character... and
I
am sure it's full of memory errors and it crashes ALOT... at different
stages.
I just can't get my brain around it enough to figure out where my logic
flaws
are.... anyway... here is the gdb errors and the code snippets...

from ACT.ITEM.C:
int on_corpse_list(struct obj_data * cont, struct char_data * ch)
{
  corpse_list * name;
  for (name = cont->canloot; name; name = name->next) {
     if (name->id == GET_IDNUM(ch))
       return (1);
  }
  return (0);
}

ACMD(do_corpse)
{
  bool found = FALSE;
  corpse_list * name;
  struct char_data *i;
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];

  two_arguments(argument, arg1, arg2);
  if (!*arg1) {
    send_to_char("\r\nPlayers currently online authorized\r\n"
                     "       to loot your corpse:\r\n"
                     "-----------------------------------\r\n", ch);
    for (i = character_list; i; i = i->next) {
      for (name = ch->player_specials->saved.canloot; name; name = name->next) {
        if (IS_NPC(i))
          continue;
        if (GET_IDNUM(i) == name->id) {
          sprintf(buf, "%s\r\n", GET_NAME(i));
          send_to_char(buf, ch);
          found = TRUE;
        }
      }
    }
    if (!found)
      send_to_char("Nobody.\r\n", ch);
    return;
  } else {
    if ((str_cmp(arg1, "add") && str_cmp(arg1, "remove")) || !*arg2)
      send_to_char("Who, besides you, may loot your corpse.\r\nUsage:
corpse\r\n        corpse add <name>\r\n        corpse remove <name>\r\n",
ch);
    else {
      if (!str_cmp(arg1, "add")) {
        for (i = character_list; i; i = i->next) {
          if (IS_NPC(i))
            continue;
          if (!str_cmp(i->player.name, arg2)) {
            name = ch->player_specials->saved.canloot;
            CREATE(name, corpse_list, 1);
            name->next = ch->player_specials->saved.canloot;
            name->id = GET_IDNUM(i);
            ch->player_specials->saved.canloot = name;
            sprintf(buf, "%s has been added to your corpse list.\r\n",
GET_NAME(i));
            send_to_char(buf, ch);
            found = TRUE;
          }
        }
        free (name);
        if (!found)
          send_to_char("The new person must be online to be added.\r\n",
ch);
      } else
        if (!str_cmp(arg1, "remove")) {
      }


get_from_container:
    } else {
      struct obj_data *obj_next;
      if (IS_CORPSE(cont)) {
        if ((cont->owner != ch) && (!on_corpse_list(cont, ch))) {
          if ((IS_OBJ_STAT(obj, ITEM_QUEST)) ||
              (IS_OBJ_STAT(obj, ITEM_UNIQUE))) {
            send_to_char("Quest Items and Unique Items may not be trophy
items.\r\n", ch);
            return;
          } else {
            if (GET_OBJ_VAL(cont, 8) != 0) {
              GET_OBJ_VAL(cont, 8) = 0;
              howmany = 1;
            } else {
              send_to_char("One item has already been taken as a
trophy.\r\n", ch);
              return;
            }
          }
        }
      }
      while(obj && howmany--) {
        obj_next = obj->next_content;
        perform_get_from_container(ch, obj, cont, mode);
        obj = get_obj_in_list_vis(ch, arg, obj_next);


    if (IS_CORPSE(cont) && (obj_dotmode == FIND_ALL))
      if ((cont->owner != ch) && (!on_corpse_list(cont, ch))) {
        send_to_char("You may only take one trophy item from this
corpse.\r\n", ch);
        return;
      }
    for (obj = cont->contains; obj; obj = next_obj) {
      next_obj = obj->next_content;
        if (CAN_SEE_OBJ(ch, obj) &&
          (obj_dotmode == FIND_ALL || isname_exact(arg, obj->name))) {
        found = 1;


FROM STRUCTS.H:
struct corpse_struct {
   long id;
   struct corpse_struct *next;
};
typedef struct corpse_struct corpse_list;

and in struct obj_data {
struct char_data *owner;          /* used for engrave and corpses     */
   corpse_list *canloot;        /* list of player id's that can loot */

and in struct player_special_data_saved {
corpse_list *canloot;        /* who is allowed to loot your corpse   */


FROM FIGHT.C make_corpse:
corpse->owner = ch;
corpse->canloot = ch->player_specials->saved.canloot;


Current GDB:
Program received signal SIGSEGV, Segmentation fault.
do_corpse (ch=0x8378f08, argument=0xbffff5b2 "", cmd=50, subcmd=0)
    at act.item.c:265
265             if (GET_IDNUM(i) == name->id) {
(gdb) #0  do_corpse (ch=0x8378f08, argument=0xbffff5b2 "", cmd=50, subcmd=0)
    at act.item.c:265
#1  0x808a612 in command_interpreter (ch=0x8378f08,
    argument=0xbffff5ac "corpse") at interpreter.c:709
#2  0x807284c in game_loop (mother_desc=5) at comm.c:743

--
   +---------------------------------------------------------------+
   | FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
   | Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
   +---------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/04/01 PST