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:
parent
7b0ec1230e
commit
a8b96bbc3e
1 changed files with 73 additions and 2 deletions
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue