* Start a corpse decay or revive timer. * This takes the age of the corpse into consideration as of 3.4.0. */
| 1386 | * This takes the age of the corpse into consideration as of 3.4.0. |
| 1387 | */ |
| 1388 | void |
| 1389 | start_corpse_timeout(struct obj *body) |
| 1390 | { |
| 1391 | long when; /* rot away when this old */ |
| 1392 | long age; /* age of corpse */ |
| 1393 | int rot_adjust; |
| 1394 | short action; |
| 1395 | |
| 1396 | /* |
| 1397 | * Note: |
| 1398 | * if body->norevive is set, the corpse will rot away instead |
| 1399 | * of revive when its REVIVE_MON timer finishes. |
| 1400 | */ |
| 1401 | |
| 1402 | /* lizards and lichen don't rot or revive */ |
| 1403 | if (body->corpsenm == PM_LIZARD || body->corpsenm == PM_LICHEN) |
| 1404 | return; |
| 1405 | |
| 1406 | action = ROT_CORPSE; /* default action: rot away */ |
| 1407 | rot_adjust = gi.in_mklev ? 25 : 10; /* give some variation */ |
| 1408 | age = max(svm.moves, 1) - body->age; |
| 1409 | if (age > ROT_AGE) |
| 1410 | when = rot_adjust; |
| 1411 | else |
| 1412 | when = ROT_AGE - age; |
| 1413 | when += (long) (rnz(rot_adjust) - rot_adjust); |
| 1414 | |
| 1415 | if (is_rider(&mons[body->corpsenm])) { |
| 1416 | action = REVIVE_MON; |
| 1417 | when = rider_revival_time(body, FALSE); |
| 1418 | } else if (mons[body->corpsenm].mlet == S_TROLL) { |
| 1419 | for (age = 2; age <= TAINT_AGE; age++) |
| 1420 | if (!rn2(TROLL_REVIVE_CHANCE)) { /* troll revives */ |
| 1421 | action = REVIVE_MON; |
| 1422 | when = age; |
| 1423 | break; |
| 1424 | } |
| 1425 | } else if (gz.zombify && zombie_form(&mons[body->corpsenm]) != NON_PM |
| 1426 | && !body->norevive) { |
| 1427 | action = ZOMBIFY_MON; |
| 1428 | when = rn1(15, 5); /* 5..19 */ |
| 1429 | } |
| 1430 | |
| 1431 | (void) start_timer(when, TIMER_OBJECT, action, obj_to_any(body)); |
| 1432 | } |
| 1433 | |
| 1434 | /* used by item_on_ice() and shrink_glob() */ |
| 1435 | enum obj_on_ice { |
no test coverage detected