shrink_glob while away from level

If the hero left a level that had globs on the floor or in floor
containers or being carried by monsters and stayed away for a
while, returning to the level only shrunk them by one unit of
weight.  Account for all the time away.  The complexity of this
has steadily grown; I hope its peak has been reached.
This commit is contained in:
PatR
2021-11-12 23:05:55 -08:00
parent 41ede41b8b
commit 05a843826d
2 changed files with 36 additions and 4 deletions

View File

@@ -1331,12 +1331,14 @@ start_glob_timeout(
part of the program destroys it, the timer will be cancelled) */
void
shrink_glob(
anything *arg, /* glob (in arg->a_obj) */
long expire_time UNUSED) /* timer callback data, not referenced here */
anything *arg, /* glob (in arg->a_obj) */
long expire_time) /* turn the timer should have gone off; if less than
* current 'moves', we're making up for lost time
* after leaving and then returning to this level */
{
char globnambuf[BUFSZ];
int globloc;
struct obj *obj = arg->a_obj;
int globloc = item_on_ice(obj);
boolean ininv = (obj->where == OBJ_INVENT),
shrink = FALSE, gone = FALSE, updinv = FALSE;
struct obj *contnr = (obj->where == OBJ_CONTAINED) ? obj->ocontainer : 0,
@@ -1352,6 +1354,35 @@ shrink_glob(
will be replaced in the feedback with info about this glob */
check_glob(obj, "shrink obj ");
/*
* If shrinkage occurred while we were on another level, catch up now.
*/
if (expire_time < g.moves && globloc != BURIED_UNDER_ICE) {
/* number of units of weight to remove */
long delta = (g.moves - expire_time + 24L) / 25L,
/* leftover amount to use for new timer */
moddelta = 25L - (delta % 25L);
if (globloc == SET_ON_ICE)
delta = (delta + 2L) / 3L;
if (delta >= (long) obj->owt) {
/* no newsym() or message here; forthcoming map update for
level arrival is all that's needed */
obj_extract_self(obj);
obfree(obj, (struct obj *) 0);
/* won't be a container carried by hero but might be a floor
one or one carried by a monster */
if (contnr)
container_weight(contnr);
} else {
obj->owt -= (unsigned) delta;
start_glob_timeout(obj, moddelta);
}
return;
}
/*
* When on ice, only shrink every third try. If buried under ice,
* don't shrink at all, similar to being contained in an ice box
@@ -1363,7 +1394,7 @@ shrink_glob(
* monster, timer won't have a chance to run before meal is finished).
*/
if (eating_glob(obj)
|| (globloc = item_on_ice(obj)) == BURIED_UNDER_ICE
|| globloc == BURIED_UNDER_ICE
|| (globloc == SET_ON_ICE && (g.moves % 3L) == 1L)) {
/* schedule next shrink attempt; for the being eaten case, the
glob and its timer might be deleted before this kicks in */