globs have quantity 1 and size which varies by multiples of 20 in owt; they don't become tainted with age, but every 25 turns this timer runs and reduces owt by 1; when it hits 0, destroy the glob (if some other part of the program destroys it, the timer will be cancelled); note: timer keeps going if an object gets buried or scheduled to migrate to another level and can delete the g
| 1497 | note: timer keeps going if an object gets buried or scheduled to |
| 1498 | migrate to another level and can delete the glob in those states */ |
| 1499 | void |
| 1500 | shrink_glob( |
| 1501 | anything *arg, /* glob (in arg->a_obj) */ |
| 1502 | long expire_time) /* turn the timer should have gone off; if less than |
| 1503 | * current 'moves', we're making up for lost time |
| 1504 | * after leaving and then returning to this level */ |
| 1505 | { |
| 1506 | char globnambuf[BUFSZ]; |
| 1507 | struct obj *obj = arg->a_obj; |
| 1508 | int globloc = item_on_ice(obj); |
| 1509 | boolean ininv = (obj->where == OBJ_INVENT), |
| 1510 | shrink = FALSE, gone = FALSE, updinv = FALSE; |
| 1511 | struct obj *contnr = (obj->where == OBJ_CONTAINED) ? obj->ocontainer : 0, |
| 1512 | *topcontnr = 0; |
| 1513 | unsigned old_top_owt = 0; |
| 1514 | |
| 1515 | if (!obj->globby) { |
| 1516 | impossible("shrink_glob for non-glob [%d: %s]?", |
| 1517 | obj->otyp, simpleonames(obj)); |
| 1518 | return; /* old timer is gone, don't start a new one */ |
| 1519 | } |
| 1520 | /* note: if check_glob() complains about a problem, the " obj " here |
| 1521 | will be replaced in the feedback with info about this glob */ |
| 1522 | check_glob(obj, "shrink obj "); |
| 1523 | |
| 1524 | /* |
| 1525 | * If shrinkage occurred while we were on another level, catch up now. |
| 1526 | */ |
| 1527 | if (expire_time < svm.moves && globloc != BURIED_UNDER_ICE) { |
| 1528 | /* number of units of weight to remove */ |
| 1529 | long delta = (svm.moves - expire_time + 24L) / 25L, |
| 1530 | /* leftover amount to use for new timer */ |
| 1531 | moddelta = 25L - (delta % 25L); |
| 1532 | |
| 1533 | if (globloc == SET_ON_ICE) |
| 1534 | delta = (delta + 2L) / 3L; |
| 1535 | |
| 1536 | if (delta >= (long) obj->owt) { |
| 1537 | /* gone; no newsym() or message here--forthcoming map update for |
| 1538 | level arrival is all that's needed */ |
| 1539 | obj->owt = 0; /* not required; accurately reflects obj's state */ |
| 1540 | shrinking_glob_gone(obj); |
| 1541 | } else { |
| 1542 | /* shrank but not gone; reduce remaining weight */ |
| 1543 | obj->owt -= (unsigned) delta; |
| 1544 | /* when contained, update container's weight (recursively if |
| 1545 | nested); won't be in a container carried by hero (since |
| 1546 | catching up for lost time never applies in that situation) |
| 1547 | but might be in one on floor or one carried by a monster */ |
| 1548 | if (contnr) |
| 1549 | container_weight(contnr); |
| 1550 | /* resume regular shrinking */ |
| 1551 | start_glob_timeout(obj, moddelta); |
| 1552 | } |
| 1553 | return; |
| 1554 | } |
| 1555 | |
| 1556 | /* |
nothing calls this directly
no test coverage detected