# HG changeset patch # User John "Elwin" Edwards # Date 1516065635 18000 # Node ID 000b1c5b8d63e708629db68203cb205bf726f6bd # Parent 1e1c81fbb533fef8f125a85fdbfdaf3f40ae7731 UltraRogue: fix inventory collision after save and restore. Inventory letters are based on "identifiers" stored in objects' o_ident field. Identifiers are allocated by get_ident(), which keeps a list of objects that have them, to avoid giving the same identifier to multiple objects. The list is not stored in the savefile, so after restore, get_ident() was not aware of existing identifiers. This resulted in picked-up objects having the same inventory letters as objects restored from the file. The restore code now adds all objects with identifiers to the list. diff -r 1e1c81fbb533 -r 000b1c5b8d63 urogue/state.c --- a/urogue/state.c Fri Jan 12 18:02:39 2018 -0500 +++ b/urogue/state.c Mon Jan 15 20:20:35 2018 -0500 @@ -415,6 +415,45 @@ ur_write_object_stack(savef, o->next_obj); } +/* + * Puts objects with identifiers into the global ident_list, keeping it sorted + * by type and identifier. + */ +void +add_to_ident(struct object *o) +{ + extern linked_list *ident_list; + linked_list *obj_ll; + linked_list *list_p, *prev_p = NULL; + struct object *list_o; + + obj_ll = new_list(); + obj_ll->data.obj = o; + + for (list_p = ident_list; list_p != NULL; list_p = next(list_p)) + { + list_o = list_p->data.obj; + if (list_o->o_type == o->o_type) + { + if (list_o->o_ident > o->o_ident) + { + prev_p = list_p->l_prev; + break; + } + else if (next(list_p) && + next(list_p)->data.obj->o_type != o->o_type) + { + prev_p = list_p; + break; + } + } + if (!next(list_p)) + prev_p = list_p; + } + _attach_after(&ident_list, prev_p, obj_ll); + return; +} + struct object * ur_read_object(FILE *savef) { @@ -454,6 +493,11 @@ other = ur_read_int(savef); + if (o->o_ident != 0) { + /* The object needs to be placed in the identifiers list. */ + add_to_ident(o); + } + if (other & 1) o->o_bag = ur_read_bag(savef); if (other & 2)