Mercurial > hg > early-roguelike
changeset 115:1cf517d5d2a8
arogue5: make alchemy jugs survive a save and restore.
Alchemy jugs are refilled by the alchemy() fuse, which takes a pointer
to the jug object as an argument. When written to a save file and read
back out, the pointer is unlikely to point anywhere useful.
Instead, rs_write_daemons() now stores an index into the player's pack
or the list of objects on the floor. rs_read_daemons() uses this
number to locate the object when restoring.
This change should not cause any new issues with old savefiles, but it
is unable to make a broken alchemy jug work again.
author | John "Elwin" Edwards |
---|---|
date | Fri, 28 Mar 2014 15:51:43 -0700 |
parents | a5433ba4cabf |
children | 97f8fdf9595c |
files | arogue5/state.c |
diffstat | 1 files changed, 73 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/arogue5/state.c Fri Mar 28 10:57:03 2014 -0700 +++ b/arogue5/state.c Fri Mar 28 15:51:43 2014 -0700 @@ -1341,6 +1341,69 @@ return(READSTAT); } +/* Assigns a number to an alchemy jug associated with a fuse, so it can be + * found and reassociated when restoring. + * 1 - 31: slot in pack + * 32+ : on floor + * Hopefully monsters do not pick them up. + */ +int number_alchemy_jug(struct object *obj) { + struct object *tobj = NULL; + struct linked_list *item; + int i = 1; + for (item = player.t_pack; item != NULL; item = next(item), i++) { + tobj = OBJPTR(item); + if (tobj == obj && + tobj->o_type == MM && + tobj->o_which== MM_JUG) + break; + } + if (item == NULL) { + for (item = lvl_obj, i = 32; item != NULL; item = next(item), i++) { + tobj = OBJPTR(item); + if (tobj == obj && + tobj->o_type == MM && + tobj->o_which== MM_JUG) + break; + } + } + if (item == NULL) + return 0; + return i; +} + +/* Takes an alchemy jug number and tracks down the object. */ +struct object *find_alchemy_jug(int n) { + struct object *tobj; + struct linked_list *item; + + if (n <= 0) { + return NULL; + } + else if (n < 32) { + item = player.t_pack; + n -= 1; + } + else if (n < 1024) { + item = lvl_obj; + n -= 32; + } + else { + /* This is likely a bug, not 1024 actual items on the floor. */ + return NULL; + } + while (item != NULL && n > 0) { + item = next(item); + n--; + } + if (item == NULL) + return NULL; + tobj = OBJPTR(item); + if (tobj->o_type != MM || tobj->o_which != MM_JUG) + return NULL; + return tobj; +} + int rs_write_daemons(FILE *savef, struct delayed_action *d_list, int count) { @@ -1421,7 +1484,10 @@ rs_write_int(savef, d_list[i].d_type); rs_write_int(savef, func); /* d_arg is a pointer and can't actually be saved and restored. */ - rs_write_int(savef, 0); + if (func == 19) + rs_write_int(savef, number_alchemy_jug(d_list[i].d_arg)); + else + rs_write_int(savef, 0); rs_write_int(savef, d_list[i].d_time); } @@ -1518,10 +1584,15 @@ break; } + /* Most functions don't use the argument. */ rs_read_int(inf, &dummy); - d_list[i].d_arg = NULL; if (func == 2) d_list[i].d_arg = &player; + else if (func == 19) + d_list[i].d_arg = find_alchemy_jug(dummy); + else + d_list[i].d_arg = NULL; + rs_read_int(inf, &d_list[i].d_time); if (d_list[i].d_func == NULL)