Problems with copying objects

From: John Evans (evansj@DATAWEST.NET)
Date: 06/14/98


Greetings,
        I am trying to copy one obj vnum to another with a 'simple'
command-line process like: ocopy <orig vnum> <target vnum>
If the target does not exist, then it is created. I have the creation of
an object work perfefctly. It's the copying of the original to the target
that messes things up. I used oedit_save_internally() as a basis for my
command's copy code, but things just are quite right. If you do something
like:
ocopy 100 101
ocopy 100 101
(yes, do the same command twice)

Then obj 100 and 101 get very messed up. The numeric data remains intact,
but the string data is really trashed out. Mostly random characters for
alias, s-desc, l-desc and d-desc. It seems to me that memory is not being
(de)allocated properly and I can't manage to track down where. Here is the
code along with some /* NOTES */ that are included here to clarify my
non-stock code.

----------
ACMD(do_ocopy)
{
  /* NOTE: obj_num has been typedef'd to long in structs.h */
  obj_num vorig, rorig, vdest, rdest;
  struct extra_descr_data *this, *next_one;
  struct obj_data *obj, *swap;

  /* NOTE: is_order is a parameter passed as ACMD and is TRUE if someone
     charms the acting character and orders him to take action */
  if (is_order && ch->master) {
    send_to_char("You cannot order others to use immortal powers.\r\n",
                 ch->master);
    return;
  }

  two_arguments(argument, buf, buf2);

  if (!*buf2) {
    send_to_char("Usage: ocopy <original vnum> <target vnum>\r\n", ch);
    return;
  }
  if (!(isdigit(*buf) && isdigit(*buf2))) {
    send_to_char("Both arguments must be numbers.\r\n", ch);
    return;
  }

  vorig = atol(buf);
  rorig = real_object(vorig);
  if (rorig == -1) {
    send_to_charf(ch, "Object #%ld does not exist!\r\n", vorig);
    return;
  }

  vdest = atol(buf2);
  rdest = real_object(vdest);
  if (vdest == vorig) {
    send_to_char("The original and target objects are the same!\r\n", ch);
    return;
  }

  /* NOTE: Creators can edit up to four zones. This returns TRUE if the
     target vnum is in one of the four zones they have access to. */
  if (!can_alter_vnum(ch, vdest)) {
    send_to_charf(ch, "You do not have permission alter object #%ld.\r\n",
                  vdest);
    return;
  }

  /* NOTE: This creates the new object and all works well with it. */
  if (rdest == -1) {  /* Obj doesn't exist. Have to make it. */
    send_to_charf(ch, "\\c08Creating object #%d.\\c00\r\n", vdest);
    create_new_obj(vdest);
    rdest = real_object(vdest);
    rorig = real_object(vorig);
  }

  /* NOTE: This is pretty much straight from oedit.c */
  /* Overwrite existing objects with new prototype */
  CREATE(swap, struct obj_data, 1);
  for (obj = object_list; obj; obj = obj->next) {
    if (obj->item_number == rdest) {
      *swap = *obj;
      *obj = *(obj_proto + rorig);
      obj->in_room = swap->in_room;
      obj->item_number = rdest;
      obj->carried_by = swap->carried_by;
      obj->worn_by = swap->worn_by;
      obj->worn_on = swap->worn_on;
      obj->in_obj = swap->in_obj;
      obj->contains = swap->contains;
      obj->next_content = swap->next_content;
      obj->next = swap->next;
    }
  }
  free(swap);

  /* NOTE: The following lines actually copy the object, but I feel
           that something is missing from how the code is acting, but not
           sure what. The code is VERY similar to oedit_save_internally,
           and I compared it to bpl12 w/ Oasis 1.6b and found that the
           code was the same as what I am currently using. */
  if (obj_proto[rdest].name)
    free(obj_proto[rdest].name);
  if (obj_proto[rdest].description)
    free(obj_proto[rdest].description);
  if (obj_proto[rdest].short_description)
    free(obj_proto[rdest].short_description);
  if (obj_proto[rdest].detail_description)
    free(obj_proto[rdest].detail_description);
  if (obj_proto[rdest].ex_description)
    for (this = obj_proto[rdest].ex_description; this; this = next_one) {
      next_one = this->next;
      if (this->keyword)
        free(this->keyword);
      if (this->description)
        free(this->description);
      free(this);
    }

  /* NOTE: I'm really suspiscious of the next line, but not sure what to
           do with it. */
  obj_proto[rdest] = *(obj_proto + rorig);
  obj_proto[rdest].item_number = rdest;

  olc_add_to_save_list((vdest/100), OLC_SAVE_OBJ);
  send_to_charf(ch, "You copy object #%ld to #%ld.\r\n", vorig, vdest);
}
----------

Any clues as to what is going wrong would be appreciated.

John Evans <evansj@datawest.net>
http://www.hi-line.net/~evansj/              telnet://spear.gator.net:1066

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