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; |
