Mercurial > hg > early-roguelike
comparison urogue/state.c @ 296:000b1c5b8d63
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.
author | John "Elwin" Edwards |
---|---|
date | Mon, 15 Jan 2018 20:20:35 -0500 |
parents | ebf49a933e51 |
children | 0250220d8cdd |
comparison
equal
deleted
inserted
replaced
295:1e1c81fbb533 | 296:000b1c5b8d63 |
---|---|
413 ur_write_bag(savef,o->o_bag); | 413 ur_write_bag(savef,o->o_bag); |
414 if (o->next_obj && (o->next_obj->l_prev == NULL) ) | 414 if (o->next_obj && (o->next_obj->l_prev == NULL) ) |
415 ur_write_object_stack(savef, o->next_obj); | 415 ur_write_object_stack(savef, o->next_obj); |
416 } | 416 } |
417 | 417 |
418 /* | |
419 * Puts objects with identifiers into the global ident_list, keeping it sorted | |
420 * by type and identifier. | |
421 */ | |
422 void | |
423 add_to_ident(struct object *o) | |
424 { | |
425 extern linked_list *ident_list; | |
426 linked_list *obj_ll; | |
427 linked_list *list_p, *prev_p = NULL; | |
428 struct object *list_o; | |
429 | |
430 obj_ll = new_list(); | |
431 obj_ll->data.obj = o; | |
432 | |
433 for (list_p = ident_list; list_p != NULL; list_p = next(list_p)) | |
434 { | |
435 list_o = list_p->data.obj; | |
436 if (list_o->o_type == o->o_type) | |
437 { | |
438 if (list_o->o_ident > o->o_ident) | |
439 { | |
440 prev_p = list_p->l_prev; | |
441 break; | |
442 } | |
443 else if (next(list_p) && | |
444 next(list_p)->data.obj->o_type != o->o_type) | |
445 { | |
446 prev_p = list_p; | |
447 break; | |
448 } | |
449 } | |
450 if (!next(list_p)) | |
451 prev_p = list_p; | |
452 } | |
453 _attach_after(&ident_list, prev_p, obj_ll); | |
454 return; | |
455 } | |
456 | |
418 struct object * | 457 struct object * |
419 ur_read_object(FILE *savef) | 458 ur_read_object(FILE *savef) |
420 { | 459 { |
421 struct object *o; | 460 struct object *o; |
422 long id; | 461 long id; |
451 o->o_launch = ur_read_char(savef); | 490 o->o_launch = ur_read_char(savef); |
452 ur_read(savef, &o->o_mark[0], MARKLEN); | 491 ur_read(savef, &o->o_mark[0], MARKLEN); |
453 o->o_worth = ur_read_long(savef); | 492 o->o_worth = ur_read_long(savef); |
454 | 493 |
455 other = ur_read_int(savef); | 494 other = ur_read_int(savef); |
495 | |
496 if (o->o_ident != 0) { | |
497 /* The object needs to be placed in the identifiers list. */ | |
498 add_to_ident(o); | |
499 } | |
456 | 500 |
457 if (other & 1) | 501 if (other & 1) |
458 o->o_bag = ur_read_bag(savef); | 502 o->o_bag = ur_read_bag(savef); |
459 if (other & 2) | 503 if (other & 2) |
460 o->next_obj = ur_read_object_stack(savef); | 504 o->next_obj = ur_read_object_stack(savef); |