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); |
