comparison arogue5/state.c @ 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 56e748983fa8
comparison
equal deleted inserted replaced
114:a5433ba4cabf 115:1cf517d5d2a8
1337 rs_read_boolean(inf, &ws_know[i]); 1337 rs_read_boolean(inf, &ws_know[i]);
1338 rs_read_new_string(inf, &ws_guess[i]); 1338 rs_read_new_string(inf, &ws_guess[i]);
1339 } 1339 }
1340 1340
1341 return(READSTAT); 1341 return(READSTAT);
1342 }
1343
1344 /* Assigns a number to an alchemy jug associated with a fuse, so it can be
1345 * found and reassociated when restoring.
1346 * 1 - 31: slot in pack
1347 * 32+ : on floor
1348 * Hopefully monsters do not pick them up.
1349 */
1350 int number_alchemy_jug(struct object *obj) {
1351 struct object *tobj = NULL;
1352 struct linked_list *item;
1353 int i = 1;
1354 for (item = player.t_pack; item != NULL; item = next(item), i++) {
1355 tobj = OBJPTR(item);
1356 if (tobj == obj &&
1357 tobj->o_type == MM &&
1358 tobj->o_which== MM_JUG)
1359 break;
1360 }
1361 if (item == NULL) {
1362 for (item = lvl_obj, i = 32; item != NULL; item = next(item), i++) {
1363 tobj = OBJPTR(item);
1364 if (tobj == obj &&
1365 tobj->o_type == MM &&
1366 tobj->o_which== MM_JUG)
1367 break;
1368 }
1369 }
1370 if (item == NULL)
1371 return 0;
1372 return i;
1373 }
1374
1375 /* Takes an alchemy jug number and tracks down the object. */
1376 struct object *find_alchemy_jug(int n) {
1377 struct object *tobj;
1378 struct linked_list *item;
1379
1380 if (n <= 0) {
1381 return NULL;
1382 }
1383 else if (n < 32) {
1384 item = player.t_pack;
1385 n -= 1;
1386 }
1387 else if (n < 1024) {
1388 item = lvl_obj;
1389 n -= 32;
1390 }
1391 else {
1392 /* This is likely a bug, not 1024 actual items on the floor. */
1393 return NULL;
1394 }
1395 while (item != NULL && n > 0) {
1396 item = next(item);
1397 n--;
1398 }
1399 if (item == NULL)
1400 return NULL;
1401 tobj = OBJPTR(item);
1402 if (tobj->o_type != MM || tobj->o_which != MM_JUG)
1403 return NULL;
1404 return tobj;
1342 } 1405 }
1343 1406
1344 int 1407 int
1345 rs_write_daemons(FILE *savef, struct delayed_action *d_list, int count) 1408 rs_write_daemons(FILE *savef, struct delayed_action *d_list, int count)
1346 { 1409 {
1419 func = -1; 1482 func = -1;
1420 1483
1421 rs_write_int(savef, d_list[i].d_type); 1484 rs_write_int(savef, d_list[i].d_type);
1422 rs_write_int(savef, func); 1485 rs_write_int(savef, func);
1423 /* d_arg is a pointer and can't actually be saved and restored. */ 1486 /* d_arg is a pointer and can't actually be saved and restored. */
1424 rs_write_int(savef, 0); 1487 if (func == 19)
1488 rs_write_int(savef, number_alchemy_jug(d_list[i].d_arg));
1489 else
1490 rs_write_int(savef, 0);
1425 rs_write_int(savef, d_list[i].d_time); 1491 rs_write_int(savef, d_list[i].d_time);
1426 } 1492 }
1427 1493
1428 return(WRITESTAT); 1494 return(WRITESTAT);
1429 } 1495 }
1516 case -1: 1582 case -1:
1517 default: d_list[i].d_func = NULL; 1583 default: d_list[i].d_func = NULL;
1518 break; 1584 break;
1519 } 1585 }
1520 1586
1587 /* Most functions don't use the argument. */
1521 rs_read_int(inf, &dummy); 1588 rs_read_int(inf, &dummy);
1522 d_list[i].d_arg = NULL;
1523 if (func == 2) 1589 if (func == 2)
1524 d_list[i].d_arg = &player; 1590 d_list[i].d_arg = &player;
1591 else if (func == 19)
1592 d_list[i].d_arg = find_alchemy_jug(dummy);
1593 else
1594 d_list[i].d_arg = NULL;
1595
1525 rs_read_int(inf, &d_list[i].d_time); 1596 rs_read_int(inf, &d_list[i].d_time);
1526 1597
1527 if (d_list[i].d_func == NULL) 1598 if (d_list[i].d_func == NULL)
1528 { 1599 {
1529 d_list[i].d_time = 0; 1600 d_list[i].d_time = 0;