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.
This commit is contained in:
John "Elwin" Edwards 2014-03-28 15:51:43 -07:00
parent 7b0ec1230e
commit a8b96bbc3e

View file

@ -1341,6 +1341,69 @@ rs_read_sticks(int inf)
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_daemons(FILE *savef, struct delayed_action *d_list, int count)
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 @@ rs_read_daemons(int inf, struct delayed_action *d_list, int count)
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)