diff --git a/include/extern.h b/include/extern.h index 506726e99..deda4d8ec 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2907,7 +2907,7 @@ extern int water_damage(struct obj *, const char *, boolean); extern void water_damage_chain(struct obj *, boolean); extern boolean rnd_nextto_goodpos(coordxy *, coordxy *, struct monst *); extern boolean drown(void); -extern void drain_en(int); +extern void drain_en(int, boolean); extern int dountrap(void); extern int could_untrap(boolean, boolean); extern void cnv_trap_obj(int, int, struct trap *, boolean); diff --git a/src/invent.c b/src/invent.c index 38f44a078..39b716743 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1575,7 +1575,8 @@ getobj( cntgiven = TRUE; goto need_more_cq; /* now, get CMDQ_KEY */ } else { - cmdq_clear(CQ_CANNED); /* this should maybe clear the CQ_REPEAT too? */ + cmdq_clear(CQ_CANNED); + /* should maybe clear the CQ_REPEAT too? */ return NULL; } } @@ -4345,21 +4346,18 @@ look_here( There("are %s%s objects here.", (obj_cnt == 2) ? "two" : (obj_cnt < 5) ? "a few" - : (obj_cnt < 10) ? "several" - : "many", + : (obj_cnt < 10) ? "several" + : "many", picked_some ? " more" : ""); for (; otmp; otmp = otmp->nexthere) if (otmp->otyp == CORPSE && will_feel_cockatrice(otmp, FALSE)) { pline("%s %s%s.", - (obj_cnt > 1) - ? "Including" - : (otmp->quan > 1L) - ? "They're" - : "It's", + (obj_cnt > 1) ? "Including" + : (otmp->quan > 1L) ? "They're" + : "It's", corpse_xname(otmp, (const char *) 0, CXN_ARTICLE), - poly_when_stoned(gy.youmonst.data) - ? "" - : ", unfortunately"); + poly_when_stoned(gy.youmonst.data) ? "" + : ", unfortunately"); feel_cockatrice(otmp, FALSE); break; } @@ -5354,7 +5352,10 @@ worn_wield_only(struct obj *obj) * MINV_ALL - display all inventory */ struct obj * -display_minventory(struct monst *mon, int dflags, char *title) +display_minventory( + struct monst *mon, /* monster whose minvent we're showing */ + int dflags, /* control over what to display */ + char *title) /* menu title */ { struct obj *ret; char tmp[QBUFSZ]; @@ -5362,7 +5363,8 @@ display_minventory(struct monst *mon, int dflags, char *title) menu_item *selected = 0; int do_all = (dflags & MINV_ALL) != 0, incl_hero = (do_all && engulfing_u(mon)), - have_inv = (mon->minvent != 0), have_any = (have_inv || incl_hero), + have_inv = (mon->minvent != 0), + have_any = (have_inv || incl_hero), pickings = (dflags & MINV_PICKMASK); Sprintf(tmp, "%s %s:", s_suffix(noit_Monnam(mon)), @@ -5383,7 +5385,7 @@ display_minventory(struct monst *mon, int dflags, char *title) iflags.suppress_price--; /* was 'set_uasmon();' but that potentially has side-effects */ - gy.youmonst.data = &mons[u.umonnum]; /* most basic part of set_uasmon */ + gy.youmonst.data = &mons[u.umonnum]; /* basic part of set_uasmon() */ } else { invdisp_nothing(title ? title : tmp, "(none)"); n = 0; diff --git a/src/mhitu.c b/src/mhitu.c index 8f4b5c7e6..08928a9fc 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1406,7 +1406,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk) case AD_DREN: /* AC magic cancellation doesn't help when engulfed */ if (!mtmp->mcan && rn2(4)) /* 75% chance */ - drain_en(tmp); + drain_en(tmp, FALSE); tmp = 0; break; default: diff --git a/src/trap.c b/src/trap.c index af2daf329..b4dbdb076 100644 --- a/src/trap.c +++ b/src/trap.c @@ -2115,8 +2115,8 @@ trapeffect_anti_magic( unsigned int trflags UNUSED) { if (mtmp == &gy.youmonst) { - int drain = d(2, 6); /* 2d6 => 2..12 */ - int halfd = rnd((drain + 1) / 2); /* 1..drain/2 (rounded up) */ + int drain, halfd; + boolean exclaim_it = FALSE; seetrap(trap); if (Antimagic) { @@ -2149,11 +2149,24 @@ trapeffect_anti_magic( losehp(dmgval2, "anti-magic implosion", KILLED_BY_AN); } - if (u.uenmax > halfd) { + /* if the drain amount is more than hero's maximum energy then up + to half of the amount comes directly out of maximum, the rest + comes out of current energy; drain_en() lowers the current + amount and when doing so it will take even more from maximum + if the new current value would drop below zero */ + drain = d(2, 6); /* 2d6 => 2..12 */ + halfd = rnd(drain / 2); /* 1..drain/2 (round down) */ + if (u.uenmax > drain) { /* [was u.uenmax > halfd] */ + /* note: since 'halfd' is no more than half, 'drain -= halfd' + is at least as big, so drain_en() is never asked to remove + less from current than what we're removing from maximum; + however, it might do that anyway (via its throttle check) so + it needs to make sure uen doesn't end up exceeding uenmax */ u.uenmax -= halfd; /* drain_en() will set context.botl */ - drain = halfd; + drain -= halfd; + exclaim_it = TRUE; } - drain_en(drain); + drain_en(drain, exclaim_it); } else { boolean trapkilled = FALSE; boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); @@ -4598,31 +4611,48 @@ drown(void) } void -drain_en(int n) +drain_en(int n, boolean max_already_drained) { + const char *mesg; + char punct = max_already_drained ? '!' : '.'; + /* * FIXME? * u.uenmax should probably have a higher mininum than 0; * perhaps u.ulevel or (u.ulevel + 1) / 2 */ - if (!u.uenmax) { + if (u.uenmax < 1) { /* energy is completely gone */ - You_feel("momentarily lethargic."); + if (u.uen || u.uenmax) { /* paranoia */ + u.uen = u.uenmax = 0; + gc.context.botl = TRUE; + } + mesg = "momentarily lethargic"; } else { /* throttle further loss a bit when there's not much left to lose */ if (n > (u.uen + u.uenmax) / 3) n = rnd(n); - You_feel("your magical energy drain away%c", (n > u.uen) ? '!' : '.'); + mesg = "your magical energy drain away"; + if (n > u.uen) + punct = '!'; + u.uen -= n; if (u.uen < 0) { u.uenmax -= rnd(-u.uen); if (u.uenmax < 0) u.uenmax = 0; u.uen = 0; + } else if (u.uen > u.uenmax) { + /* uen might be greater than uenmax if caller reduced uenmax + and then we throttled the loss being applied to current */ + u.uen = u.uenmax; } gc.context.botl = TRUE; } + /* after manipulating u.uen,uenmax and setting context.botl, so + that You_feel() -> pline() will update status before the message */ + You_feel("%s%c", mesg, punct); } /* the #untrap command - disarm a trap */ diff --git a/src/uhitm.c b/src/uhitm.c index 66b22af0b..f10accf3d 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2224,7 +2224,7 @@ mhitm_ad_dren( /* mhitu */ hitmsg(magr, mattk); if (!negated && !rn2(4)) /* 25% chance */ - drain_en(mhm->damage); + drain_en(mhm->damage, FALSE); mhm->damage = 0; } else { /* mhitm */