-/* NetHack 3.6 timeout.c $NHDT-Date: 1446861771 2015/11/07 02:02:51 $ $NHDT-Branch: master $:$NHDT-Revision: 1.63 $ */
+/* NetHack 3.6 timeout.c $NHDT-Date: 1505214876 2017/09/12 11:14:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.75 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/*-Copyright (c) Robert Patrick Rankin, 2018. */
/* NetHack may be freely redistributed. See license for details. */
/* JNetHack Copyright */
/* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
-/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2018 */
/* JNetHack may be freely redistributed. See license for details. */
#include "hack.h"
STATIC_DCL void NDECL(stoned_dialogue);
STATIC_DCL void NDECL(vomiting_dialogue);
STATIC_DCL void NDECL(choke_dialogue);
+STATIC_DCL void NDECL(levitation_dialogue);
STATIC_DCL void NDECL(slime_dialogue);
STATIC_DCL void NDECL(slip_or_trip);
STATIC_DCL void FDECL(see_lamp_flicker, (struct obj *, const char *));
STATIC_DCL void FDECL(lantern_message, (struct obj *));
STATIC_DCL void FDECL(cleanup_burn, (ANY_P *, long));
+/* used by wizard mode #timeout and #wizintrinsic; order by 'interest'
+ for timeout countdown, where most won't occur in normal play */
+/*JP \83E\83B\83U\81[\83h\83\82\81[\83h\82Å\82µ\82©\8eg\82í\82ê\82È\82¢\82æ\82¤\82È\82Ì\82Å\96|\96ó\82µ\82È\82¢ */
+const struct propname {
+ int prop_num;
+ const char *prop_name;
+} propertynames[] = {
+ { INVULNERABLE, "invulnerable" },
+ { STONED, "petrifying" },
+ { SLIMED, "becoming slime" },
+ { STRANGLED, "strangling" },
+ { SICK, "fatally sick" },
+ { STUNNED, "stunned" },
+ { CONFUSION, "confused" },
+ { HALLUC, "hallucinating" },
+ { BLINDED, "blinded" },
+ { DEAF, "deafness" },
+ { VOMITING, "vomiting" },
+ { GLIB, "slippery fingers" },
+ { WOUNDED_LEGS, "wounded legs" },
+ { SLEEPY, "sleepy" },
+ { TELEPORT, "teleporting" },
+ { POLYMORPH, "polymorphing" },
+ { LEVITATION, "levitating" },
+ { FAST, "very fast" }, /* timed 'FAST' is very fast */
+ { CLAIRVOYANT, "clairvoyant" },
+ { DETECT_MONSTERS, "monster detection" },
+ { SEE_INVIS, "see invisible" },
+ { INVIS, "invisible" },
+ /* properties beyond here don't have timed values during normal play,
+ so there's no much point in trying to order them sensibly;
+ they're either on or off based on equipment, role, actions, &c */
+ { FIRE_RES, "fire resistance" },
+ { COLD_RES, "cold resistance" },
+ { SLEEP_RES, "sleep resistance" },
+ { DISINT_RES, "disintegration resistance" },
+ { SHOCK_RES, "shock resistance" },
+ { POISON_RES, "poison resistance" },
+ { ACID_RES, "acid resistance" },
+ { STONE_RES, "stoning resistance" },
+ { DRAIN_RES, "drain resistance" },
+ { SICK_RES, "sickness resistance" },
+ { ANTIMAGIC, "magic resistance" },
+ { HALLUC_RES, "hallucination resistance" },
+ { FUMBLING, "fumbling" },
+ { HUNGER, "voracious hunger" },
+ { TELEPAT, "telepathic" },
+ { WARNING, "warning" },
+ { WARN_OF_MON, "warn: monster type or class" },
+ { WARN_UNDEAD, "warn: undead" },
+ { SEARCHING, "searching" },
+ { INFRAVISION, "infravision" },
+ { ADORNED, "adorned (+/- Cha)" },
+ { DISPLACED, "displaced" },
+ { STEALTH, "stealthy" },
+ { AGGRAVATE_MONSTER, "monster aggravation" },
+ { CONFLICT, "conflict" },
+ { JUMPING, "jumping" },
+ { TELEPORT_CONTROL, "teleport control" },
+ { FLYING, "flying" },
+ { WWALKING, "water walking" },
+ { SWIMMING, "swimming" },
+ { MAGICAL_BREATHING, "magical breathing" },
+ { PASSES_WALLS, "pass thru walls" },
+ { SLOW_DIGESTION, "slow digestion" },
+ { HALF_SPDAM, "half spell damage" },
+ { HALF_PHDAM, "half physical damage" },
+ { REGENERATION, "HP regeneration" },
+ { ENERGY_REGENERATION, "energy regeneration" },
+ { PROTECTION, "extra protection" },
+ { PROT_FROM_SHAPE_CHANGERS, "protection from shape changers" },
+ { POLYMORPH_CONTROL, "polymorph control" },
+ { UNCHANGING, "unchanging" },
+ { REFLECTING, "reflecting" },
+ { FREE_ACTION, "free action" },
+ { FIXED_ABIL, "fixed abilites" },
+ { LIFESAVED, "life will be saved" },
+ { 0, 0 },
+};
+
/* He is being petrified - dialogue by inmet!tower */
static NEARDATA const char *const stoned_texts[] = {
#if 0 /*JP*/
multi_reason = "\90Î\89»\82µ\82Â\82Â\82 \82é\8e\9e\82É";
nomovemsg = You_can_move_again; /* not unconscious */
break;
+ case 2:
+ if ((HDeaf & TIMEOUT) > 0L && (HDeaf & TIMEOUT) < 5L)
+ set_itimeout(&HDeaf, 5L); /* avoid Hear_again at tail end */
default:
break;
}
exercise(A_DEX, FALSE);
}
-/* He is getting sicker and sicker prior to vomiting */
+/* hero is getting sicker and sicker prior to vomiting */
static NEARDATA const char *const vomiting_texts[] = {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
"are feeling mildly nauseated.", /* 14 */
"feel slightly confused.", /* 11 */
"can't seem to think straight.", /* 8 */
"feel incredibly sick.", /* 5 */
- "suddenly vomit!" /* 2 */
+ "are about to vomit." /* 2 */
#else
"\82¿\82å\82Á\82Æ\93f\82«\8bC\82ª\82µ\82½\81D", /* 14 */
"\8f\82µ\8d¬\97\90\82µ\82½\81D", /* 11 */
"\82Ü\82Æ\82à\82É\8ev\8dl\82Å\82«\82È\82\82È\82Á\82½\81D", /* 8 */
"\82Æ\82Ä\82à\8bC\95ª\82ª\88«\82\82È\82Á\82½\81D", /* 5 */
- "\93Ë\91R\9aq\93f\82µ\82½\81I" /* 2 */
+ "\93Ë\91R\9aq\93f\82µ\82½\81D" /* 2 */
#endif
};
txt = vomiting_texts[4];
if (cantvomit(youmonst.data))
/*JP
- txt = "gag uncontrolably.";
+ txt = "gag uncontrollably.";
*/
txt = "\8bC\95ª\82Ì\88«\82³\82ª\97}\82¦\82ç\82ê\82È\82\82È\82Á\82½\81D";
+ else if (Hallucination)
+ /* "hurl" is short for "hurl chunks" which is slang for
+ relatively violent vomiting... */
+/*JP
+ txt = "are about to hurl!";
+*/
+ txt = "\83\8a\83o\81[\83X\90¡\91O\82¾\81I";
break;
case 0:
stop_occupation();
- if (!cantvomit(youmonst.data))
+ if (!cantvomit(youmonst.data)) {
morehungry(20);
+ /* case 2 used to be "You suddenly vomit!" but it wasn't sudden
+ since you've just been through the earlier messages of the
+ countdown, and it was still possible to move around between
+ that message and "You can move again." (from vomit()'s
+ nomul(-2)) with no intervening message; give one here to
+ have more specific point at which hero became unable to move
+ [vomit() issues its own message for the cantvomit() case
+ and for the FAINTING-or-worse case where stomach is empty] */
+ if (u.uhs < FAINTING)
+/*JP
+ You("%s!", !Hallucination ? "vomit" : "hurl chunks");
+*/
+ You("%s\81I", !Hallucination ? "\93f\82¢\82½" : "\83\8a\83o\81[\83X\82µ\82½");
+ }
vomit();
break;
default:
}
static NEARDATA const char *const choke_texts[] = {
-#if 0 /*JP*/
- "You find it hard to breathe.", "You're gasping for air.",
- "You can no longer breathe.", "You're turning %s.", "You suffocate."
+#if 0 /*JP:T*/
+ "You find it hard to breathe.",
+ "You're gasping for air.",
+ "You can no longer breathe.",
+ "You're turning %s.",
+ "You suffocate."
#else
"\82 \82È\82½\82Í\8cÄ\8bz\82ª\8d¢\93ï\82É\82È\82Á\82½\81D",
"\82 \82È\82½\82Í\8bê\82µ\82\82Ä\82 \82¦\82¢\82¾\81D",
#if 0 /*JP*/
"Your %s is becoming constricted.",
"Your blood is having trouble reaching your brain.",
- "The pressure on your %s increases.", "Your consciousness is fading.",
+ "The pressure on your %s increases.",
+ "Your consciousness is fading.",
"You suffocate."
#else
"\82 \82È\82½\82Ì%s\82Í\8di\82ß\82Â\82¯\82ç\82ê\82½\81D",
exercise(A_STR, FALSE);
}
+static NEARDATA const char *const levi_texts[] = {
+#if 0 /*JP*//* %s\82Í\8eg\82í\82È\82¢ */
+ "You float slightly lower.",
+ "You wobble unsteadily %s the %s."
+#else
+ "\82 \82È\82½\82Ì\95\82\82«\8bï\8d\87\82Í\8f\82µ\92á\82\82È\82Á\82½\81D",
+ "\82 \82È\82½\82Í\82®\82ç\82®\82ç\97h\82ê\82Í\82¶\82ß\82½\81D"
+#endif
+};
+
+STATIC_OVL void
+levitation_dialogue()
+{
+ /* -1 because the last message comes via float_down() */
+ long i = (((HLevitation & TIMEOUT) - 1L) / 2L);
+
+ if (ELevitation)
+ return;
+
+ if (!ACCESSIBLE(levl[u.ux][u.uy].typ)
+ && !is_pool_or_lava(u.ux,u.uy))
+ return;
+
+ if (((HLevitation & TIMEOUT) % 2L) && i > 0L && i <= SIZE(levi_texts)) {
+ const char *s = levi_texts[SIZE(levi_texts) - i];
+
+#if 0 /*JP*//* %s \82Í\8eg\82Á\82Ä\82¢\82È\82¢\82Ì\82Å\92P\8f\83\89» */
+ if (index(s, '%')) {
+ boolean danger = (is_pool_or_lava(u.ux, u.uy)
+ && !Is_waterlevel(&u.uz));
+
+ pline(s, danger ? "over" : "in",
+ danger ? surface(u.ux, u.uy) : "air");
+ } else
+#endif
+ pline1(s);
+ }
+}
+
static NEARDATA const char *const slime_texts[] = {
#if 0 /*JP*/
"You are turning a little %s.", /* 5 */
if (multi > 0)
nomul(0);
}
+ if (i == 2L && (HDeaf & TIMEOUT) > 0L && (HDeaf & TIMEOUT) < 5L)
+ set_itimeout(&HDeaf, 5L); /* avoid Hear_again at tail end */
exercise(A_DEX, FALSE);
}
/*JP
make_slimed(0L, "The slime that covers you is burned away!");
*/
- pline("\82 \82È\82½\82ð\95¢\82Á\82Ä\82¢\82½\83X\83\89\83C\83\80\82Í\8fÄ\82¯\97\8e\82¿\82½\81I");
+ make_slimed(0L, "\82 \82È\82½\82ð\95¢\82Á\82Ä\82¢\82½\83X\83\89\83C\83\80\82Í\8fÄ\82¯\97\8e\82¿\82½\81I");
}
}
+/* Intrinsic Passes_walls is temporary when your god is trying to fix
+ all troubles and then TROUBLE_STUCK_IN_WALL calls safe_teleds() but
+ it can't find anywhere to place you. If that happens you get a small
+ value for (HPasses_walls & TIMEOUT) to move somewhere yourself.
+ Message given is "you feel much slimmer" as a joke hint that you can
+ move between things which are closely packed--like the substance of
+ solid rock! */
+static NEARDATA const char *const phaze_texts[] = {
+#if 0 /*JP*/
+ "You start to feel bloated.",
+ "You are feeling rather flabby.",
+#else
+ "\82 \82È\82½\82Í\96c\82ç\82Ý\82Í\82¶\82ß\82½\8bC\82ª\82·\82é\81D",
+ "\82 \82È\82½\82Í\8f\82µ\82½\82é\82ñ\82¾\8bC\82ª\82·\82é\81D",
+#endif
+};
+
+STATIC_OVL void
+phaze_dialogue()
+{
+ long i = ((HPasses_walls & TIMEOUT) / 2L);
+
+ if (EPasses_walls || (HPasses_walls & ~TIMEOUT))
+ return;
+
+ if (((HPasses_walls & TIMEOUT) % 2L) && i > 0L && i <= SIZE(phaze_texts))
+ pline1(phaze_texts[SIZE(phaze_texts) - i]);
+}
+
void
nh_timeout()
{
baseluck -= 1;
if (u.uluck != baseluck
- && moves % (u.uhave.amulet || u.ugangr ? 300 : 600) == 0) {
+ && moves % ((u.uhave.amulet || u.ugangr) ? 300 : 600) == 0) {
/* Cursed luckstones stop bad luck from timing out; blessed luckstones
* stop good luck from timing out; normal luckstones stop both;
* neither is stopped if you don't have a luckstone.
vomiting_dialogue();
if (Strangled)
choke_dialogue();
+ if (HLevitation & TIMEOUT)
+ levitation_dialogue();
+ if (HPasses_walls & TIMEOUT)
+ phaze_dialogue();
if (u.mtimedone && !--u.mtimedone) {
if (Unchanging)
u.mtimedone = rnd(100 * youmonst.data->mlevel + 1);
+ else if (is_were(youmonst.data))
+ you_unwere(FALSE); /* if polycontrl, asks whether to rehumanize */
else
rehumanize();
}
case DEAF:
set_itimeout(&HDeaf, 1L);
make_deaf(0L, TRUE);
+ context.botl = TRUE;
if (!Deaf)
stop_occupation();
break;
case LEVITATION:
(void) float_down(I_SPECIAL | TIMEOUT, 0L);
break;
+ case PASSES_WALLS:
+ if (!Passes_walls) {
+ if (stuck_in_wall())
+/*JP
+ You_feel("hemmed in again.");
+*/
+ You_feel("\82Ü\82½\95Â\82¶\8d\9e\82ß\82ç\82ê\82½\82æ\82¤\82¾\81D");
+ else
+#if 0 /*JP*/
+ pline("You're back to your %s self again.",
+ !Upolyd ? "normal" : "unusual");
+#else
+ pline("\82 \82È\82½\82Í\8dÄ\82Ñ\92Ê\8fí%s\82Ì\8fó\91Ô\82É\82È\82Á\82½\81D",
+ !Upolyd ? "" : "\82Å\82Í\82È\82¢");
+#endif
+ }
+ break;
case STRANGLED:
killer.format = KILLED_BY;
#if 0 /*JP*/
/* caller can follow with a direct call to Hear_again() if
there's a need to override this when wakeup_msg is true */
incr_itimeout(&HDeaf, how_long);
+ context.botl = TRUE;
afternmv = Hear_again; /* this won't give any messages */
}
/* early wakeup from combat won't be possible until next monster turn */
boolean siblings = (hatchcount > 1), redraw = FALSE;
if (cansee_hatchspot) {
+ /* [bug? m_monnam() yields accurate monster type
+ regardless of hallucination] */
#if 0 /*JP*/
Sprintf(monnambuf, "%s%s", siblings ? "some " : "",
siblings ? makeplural(m_monnam(mon)) : an(m_monnam(mon)));
case OBJ_MINVENT:
if (cansee_hatchspot) {
/* egg carrying monster might be invisible */
- if (canseemon(egg->ocarry)) {
-/*JP
+ mon2 = egg->ocarry;
+ if (canseemon(mon2)
+ && (!mon2->wormno || cansee(mon2->mx, mon2->my))) {
+#if 0 /*JP:T*/
Sprintf(carriedby, "%s pack",
-*/
+ s_suffix(a_monnam(mon2)));
+#else
Sprintf(carriedby, "%s\82Ì\94w\95\89\82¢\91Ü\82©\82ç",
- s_suffix(a_monnam(egg->ocarry)));
+ a_monnam(mon2));
+#endif
knows_egg = TRUE;
- } else if (is_pool(mon->mx, mon->my))
+ } else if (is_pool(mon->mx, mon->my)) {
/*JP
Strcpy(carriedby, "empty water");
*/
Strcpy(carriedby, "\89½\82à\82È\82¢\90\85\92\86\82©\82ç");
- else
+ } else {
/*JP
Strcpy(carriedby, "thin air");
*/
Strcpy(carriedby, "\89½\82à\82È\82¢\8bó\8aÔ\82©\82ç");
-#if 0 /*JP*/
+ }
+#if 0 /*JP:T*/
You_see("%s %s out of %s!", monnambuf,
locomotion(mon->data, "drop"), carriedby);
#else
long timeout;
{
struct obj *obj = arg->a_obj;
- boolean canseeit, many, menorah, need_newsym;
+#if 0 /*JP*/
+ boolean canseeit, many, menorah, need_newsym, need_invupdate;
+#else
+ boolean canseeit, menorah, need_newsym, need_invupdate;
+#endif
xchar x, y;
char whose[BUFSZ];
menorah = obj->otyp == CANDELABRUM_OF_INVOCATION;
+#if 0 /*JP*/
many = menorah ? obj->spe > 1 : obj->quan > 1L;
+#endif
/* timeout while away */
if (timeout != monstermoves) {
if (menorah) {
obj->spe = 0; /* no more candles */
+ obj->owt = weight(obj);
} else if (Is_candle(obj) || obj->otyp == POT_OIL) {
/* get rid of candles and burning oil potions;
we know this object isn't carried by hero,
} else {
canseeit = FALSE;
}
- need_newsym = FALSE;
+ need_newsym = need_invupdate = FALSE;
/* obj->age is the age remaining at this point. */
switch (obj->otyp) {
if (canseeit) {
switch (obj->where) {
case OBJ_INVENT:
+ need_invupdate = TRUE;
+ /*FALLTHRU*/
case OBJ_MINVENT:
/*JP
pline("%spotion of oil has burnt away.", whose);
if (canseeit || obj->where == OBJ_INVENT) {
switch (obj->where) {
case OBJ_INVENT:
+ need_invupdate = TRUE;
+ /*FALLTHRU*/
case OBJ_MINVENT:
if (obj->otyp == BRASS_LANTERN)
/*JP
if (menorah) {
switch (obj->where) {
case OBJ_INVENT:
+ need_invupdate = TRUE;
+ /*FALLTHRU*/
case OBJ_MINVENT:
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%scandelabrum's flame%s.", whose,
many ? "s die" : " dies");
#else
} else {
switch (obj->where) {
case OBJ_INVENT:
+ /* no need_invupdate for update_inventory() necessary;
+ useupall() -> freeinv() handles it */
+ /*FALLTHRU*/
case OBJ_MINVENT:
#if 0 /*JP*/
pline("%s %s consumed!", Yname2(obj),
break;
case OBJ_FLOOR:
/*
- You see some wax candles consumed!
- You see a wax candle consumed!
- */
+ You see some wax candles consumed!
+ You see a wax candle consumed!
+ */
#if 0 /*JP*/
You_see("%s%s consumed!", many ? "some " : "",
many ? xname(obj) : an(xname(obj)));
: Blind ? "" : (many ? "Their flames die."
: "Its flame dies."));
#else
- pline(Hallucination ? "\82»\82ê\82Í\90k\82¦\82½\81D"
- : Blind ? ""
- : "\89\8a\82Í\8fÁ\82¦\82½\81D");
+ pline(Hallucination ? "\82»\82ê\82Í\8bà\90Ø\82è\90º\82ð\82 \82°\82½\81I"
+ : Blind ? ""
+ : "\89\8a\82Í\8fÁ\82¦\82½\81D");
#endif
}
}
if (menorah) {
obj->spe = 0;
+ obj->owt = weight(obj);
} else {
if (carried(obj)) {
useupall(obj);
}
obj = (struct obj *) 0;
}
- break;
+ break; /* case [age ==] 0 */
default:
/*
if (obj && obj->age)
begin_burn(obj, TRUE);
-
- break;
+ break; /* case [otyp ==] candelabrum|tallow_candle|wax_candle */
default:
impossible("burn_object: unexpeced obj %s", xname(obj));
}
if (need_newsym)
newsym(x, y);
+ if (need_invupdate)
+ update_inventory();
}
/*
*/
pline("\83s\83J\83b\81I\81I\83S\83\8d\83S\83\8d\83S\83\8d\83S\83\8d\81I\81I\83h\81[\83\93\81I");
incr_itimeout(&HDeaf, rn1(20, 30));
+ context.botl = TRUE;
if (!u.uinvulnerable) {
stop_occupation();
nomul(-3);
char buf[BUFSZ];
if (!base) {
- putstr(win, 0, "<empty>");
+ putstr(win, 0, " <empty>");
} else {
putstr(win, 0, "timeout id kind call");
for (curr = base; curr; curr = curr->next) {
{
winid win;
char buf[BUFSZ];
+ const char *propname;
+ long intrinsic;
+ int i, p, count, longestlen, ln, specindx = 0;
win = create_nhwindow(NHW_MENU); /* corner text window */
if (win == WIN_ERR)
putstr(win, 0, "");
print_queue(win, timer_base);
+ /* Timed properies:
+ * check every one; the majority can't obtain temporary timeouts in
+ * normal play but those can be forced via the #wizintrinsic command.
+ */
+ count = longestlen = 0;
+ for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
+ p = propertynames[i].prop_num;
+ intrinsic = u.uprops[p].intrinsic;
+ if (intrinsic & TIMEOUT) {
+ ++count;
+ if ((ln = (int) strlen(propname)) > longestlen)
+ longestlen = ln;
+ }
+ if (specindx == 0 && p == FIRE_RES)
+ specindx = i;
+ }
+ putstr(win, 0, "");
+ if (!count) {
+ putstr(win, 0, "No timed properties.");
+ } else {
+ putstr(win, 0, "Timed properties:");
+ putstr(win, 0, "");
+ for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
+ p = propertynames[i].prop_num;
+ intrinsic = u.uprops[p].intrinsic;
+ if (intrinsic & TIMEOUT) {
+ if (specindx > 0 && i >= specindx) {
+ putstr(win, 0, " -- settable via #wizinstrinc only --");
+ specindx = 0;
+ }
+ /* timeout value can be up to 16777215 (0x00ffffff) but
+ width of 4 digits should result in values lining up
+ almost all the time (if/when they don't, it won't
+ look nice but the information will still be accurate) */
+ Sprintf(buf, " %*s %4ld", -longestlen, propname,
+ (intrinsic & TIMEOUT));
+ putstr(win, 0, buf);
+ }
+ }
+ }
display_nhwindow(win, FALSE);
destroy_nhwindow(win);
for (curr = timer_base; curr; curr = curr->next)
if (curr->kind == TIMER_OBJECT) {
struct obj *obj = curr->arg.a_obj;
+
if (obj->timed == 0) {
pline("timer sanity: untimed obj %s, timer %ld",
fmt_ptr((genericptr_t) obj), curr->tid);
panic("start_timer");
gnu = (timer_element *) alloc(sizeof(timer_element));
+ (void) memset((genericptr_t)gnu, 0, sizeof(timer_element));
gnu->next = 0;
gnu->tid = timer_id++;
gnu->timeout = monstermoves + when;
}
}
+/* to support '#stats' wizard-mode command */
+void
+timer_stats(hdrfmt, hdrbuf, count, size)
+const char *hdrfmt;
+char *hdrbuf;
+long *count, *size;
+{
+ timer_element *te;
+
+ Sprintf(hdrbuf, hdrfmt, (long) sizeof (timer_element));
+ *count = *size = 0L;
+ for (te = timer_base; te; te = te->next) {
+ ++*count;
+ *size += (long) sizeof *te;
+ }
+}
+
/* reset all timers that are marked for reseting */
void
relink_timers(ghostly)