Welcome to the Builder Academy

Question oedit saves over player objects

More
24 Jul 2025 12:50 #10827 by Errigour
Is there an easy way to make oedit not save over player objects? Like I have leggings in my inventory but I don't want oedit to save the ac value for the change I make to the object in my inventory.

Please Log in or Create an account to join the conversation.

More
24 Jul 2025 13:56 #10828 by Errigour
Like I got this far but I think it frees the keywords and name of the object because I had a weird object in my inventory after that. Is there like a function that will make a copy of the object so I can replace it easily? Like I want to make it unique here but will there be data leaks if I start allocating data for the object here or will it be freed when the mud shutsdown or player logs out?
Code:
static int update_all_objects(struct obj_data *refobj) {   struct obj_data *obj, swap;   int count = 0;   for (obj = object_list; obj; obj = obj->next) {     if (obj->item_number != refobj->item_number)       continue;     if ((obj->carried_by && !IS_NPC(obj->carried_by)) ||         (obj->worn_by && !IS_NPC(obj->worn_by)) ||         (obj->in_obj && obj->in_obj->carried_by && !IS_NPC(obj->in_obj->carried_by)) ||         (obj->in_obj && obj->in_obj->worn_by && !IS_NPC(obj->in_obj->worn_by))) {       //I think I should make a new object here idk.       continue;     }     count++;     /* Update the existing object but save a copy for private information. */     swap = *obj;     *obj = *refobj;     /* Copy game-time dependent variables over. */     obj->script_id = swap.script_id;     IN_ROOM(obj) = swap.in_room;     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;     obj->sitting_here = swap.sitting_here;   }   return count; }

Please Log in or Create an account to join the conversation.

More
24 Jul 2025 18:39 - 25 Jul 2025 11:02 #10829 by Errigour
Like will this be a memory leak because the obj strings are allocated independently of the object proto?

Also please let me know some insight of what I am doing. I think I am trying to make this item unique if I use oedit to change it while the player is online.

Also if you do use this you need to modify add_object to:
Code:
obj_rnum add_object(struct obj_data *newobj, obj_vnum ovnum) {   int found = NOTHING;   zone_rnum rznum = real_zone_by_thing(ovnum);   /* Write object to internal tables. */   if ((newobj->item_number = real_object(ovnum)) != NOTHING) {     update_all_objects(newobj);     add_to_save_list(zone_table[rznum].number, SL_OBJ);     return newobj->item_number;   }   found = insert_object(newobj, ovnum);   adjust_objects(found);   add_to_save_list(zone_table[rznum].number, SL_OBJ);   return found; }
Code:
static int update_all_objects(struct obj_data *refobj) {   struct obj_data *obj, swap, strings, *op;   int count = 0;   strings.name = obj_proto[refobj->item_number].name;   strings.description = obj_proto[refobj->item_number].description;   strings.short_description = obj_proto[refobj->item_number].short_description;   strings.action_description = obj_proto[refobj->item_number].action_description;   strings.ex_description = obj_proto[refobj->item_number].ex_description;   copy_object(&obj_proto[refobj->item_number], refobj);   op = &obj_proto[refobj->item_number];   for (obj = object_list; obj; obj = obj->next) {     if (obj->item_number != refobj->item_number)       continue;     count++;     if (obj->carried_by ||         obj->worn_by ||         obj->in_obj ||         IN_ROOM(obj)) {         obj->item_number = NOTHING;         if (obj->name == strings.name)             obj->name = op->name ? strdup(op->name) : NULL;         if (obj->description == strings.description)             obj->description = op->description ? strdup(op->description) : NULL;         if (obj->short_description == strings.short_description)             obj->short_description = op->short_description ? strdup(op->short_description) : NULL;         if (obj->action_description == strings.action_description)             obj->action_description = op->action_description ? strdup(op->action_description) : NULL;         if (obj->ex_description == strings.ex_description) {             if (op->ex_description)                 copy_ex_descriptions(&obj->ex_description, op->ex_description);             else                 obj->ex_description = NULL;         }         continue;     }     /* Update the existing object but save a copy for private information. */     swap = *obj;     *obj = *op;     /* Copy game-time dependent variables over. */     obj->script_id = swap.script_id;     IN_ROOM(obj) = swap.in_room;     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;     obj->sitting_here = swap.sitting_here;   }   return count; }
Last edit: 25 Jul 2025 11:02 by Errigour.

Please Log in or Create an account to join the conversation.

More
24 Jul 2025 22:46 - 24 Jul 2025 22:52 #10830 by Errigour
While I am here I want to ask another question about this line in objsave_parse_objects, Is there anything I can make this equal that will not be ommitted from Crash_is_unrentable?
Code:
temp->item_number = NOTHING;
It seems when you deal with unique items that is what is defined but this function won't let me save the item after it is unique is there an easy work around?
Code:
static int Crash_is_unrentable(struct obj_data *obj) {   if (!obj)     return FALSE;   if (OBJ_FLAGGED(obj, ITEM_NORENT) ||       GET_OBJ_RENT(obj) < 0 ||       GET_OBJ_RNUM(obj) == NOTHING || <-- I think this is the line that says do not save item.       GET_OBJ_TYPE(obj) == ITEM_KEY) { log("Crash_is_unrentable: removing object %s", obj->short_description);     return TRUE;   }   return FALSE; }
All my items are now saved with this line now because I want all items to be unique.
Code:
fprintf(fp, "#%d\n", NOTHING);
Last edit: 24 Jul 2025 22:52 by Errigour.

Please Log in or Create an account to join the conversation.

More
24 Jul 2025 22:58 - 24 Jul 2025 22:59 #10831 by Errigour
This is now my objsave_save_obj_record, thanks to whoever did most of the work I just deleted all the checks so every item saves all of it's data. The reason I deleted the checks is so the items won't change if it doesn't have a tag and there is a new item in proto. IDK what I am doing here heh. 
Code:
int objsave_save_obj_record(struct obj_data *obj, FILE *fp, int locate) {   int counter2;   struct extra_descr_data *ex_desc;   char buf1[MAX_STRING_LENGTH +1];   struct obj_data *temp = NULL;   if (GET_OBJ_VNUM(obj) != NOTHING)     temp=read_object(GET_OBJ_VNUM(obj), VIRTUAL);   else {     temp = create_obj();     temp->item_number = NOWHERE;   }   if (obj->action_description) {     strcpy(buf1, obj->action_description);     strip_cr(buf1);   } else     *buf1 = 0;   fprintf(fp, "#%d\n", NOTHING);// GET_OBJ_VNUM(obj));   if (locate)     fprintf(fp, "Loc : %d\n", locate);   fprintf(fp,           "Vals: %d %d %d %d\n",           GET_OBJ_VAL(obj, 0),           GET_OBJ_VAL(obj, 1),           GET_OBJ_VAL(obj, 2),           GET_OBJ_VAL(obj, 3)           );   fprintf(fp, "Flag: %d %d %d %d\n", GET_OBJ_EXTRA(obj)[0], GET_OBJ_EXTRA(obj)[1], GET_OBJ_EXTRA(obj)[2], GET_OBJ_EXTRA(obj)[3]);   fprintf(fp, "Name: %s\n", obj->name ? obj->name : "Undefined");   fprintf(fp, "Shrt: %s\n", obj->short_description ? obj->short_description : "Undefined");   /* These two could be a pain on the read... we'll see... */   fprintf(fp, "Desc: %s\n", obj->description ? obj->description : "Undefined");   /* Only even try to process this if an action desc exists */   if (obj->action_description)     fprintf(fp, "ADes:\n%s~\n", buf1);   fprintf(fp, "Type: %d\n", GET_OBJ_TYPE(obj));   fprintf(fp, "Wght: %d\n", GET_OBJ_WEIGHT(obj));   fprintf(fp, "Cost: %d\n", GET_OBJ_COST(obj));   fprintf(fp, "Rent: %d\n", GET_OBJ_RENT(obj));   fprintf(fp, "Perm: %d %d %d %d\n", GET_OBJ_AFFECT(obj)[0], GET_OBJ_AFFECT(obj)[1], GET_OBJ_AFFECT(obj)[2], GET_OBJ_AFFECT(obj)[3]);   fprintf(fp, "Wear: %d %d %d %d\n", GET_OBJ_WEAR(obj)[0], GET_OBJ_WEAR(obj)[1], GET_OBJ_WEAR(obj)[2], GET_OBJ_WEAR(obj)[3]);   /* Do we have affects? */   for (counter2 = 0; counter2 < MAX_OBJ_AFFECT; counter2++)     fprintf(fp, "Aff : %d %d %d\n",             counter2,             obj->affected[counter2].location,             obj->affected[counter2].modifier             );   /* Do we have extra descriptions? */   if (obj->ex_description) {     /* To be reimplemented.  Need to handle this case in loading as       well */     for (ex_desc = obj->ex_description; ex_desc; ex_desc = ex_desc->next) {       /*. Sanity check to prevent nasty protection faults . */       if (!*ex_desc->keyword || !*ex_desc->description) {         continue;       }       strcpy(buf1, ex_desc->description);       strip_cr(buf1);       fprintf(fp, "EDes:\n"               "%s~\n"               "%s~\n",               ex_desc->keyword,               buf1               );     }   }   fprintf(fp, "\n");   extract_obj(temp);   return 1; }
Last edit: 24 Jul 2025 22:59 by Errigour.

Please Log in or Create an account to join the conversation.

More
25 Jul 2025 11:15 #10832 by Errigour
If I wanted to save the scripts also how would I do that in objsave_save_obj_record?

Please Log in or Create an account to join the conversation.

Time to create page: 0.243 seconds