Mercurial > hg > early-roguelike
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; |