diff --git a/src/attrib.c b/src/attrib.c index 5b20419af..23747bf59 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -216,7 +216,12 @@ losestr(int num, const char *knam, schar k_format) { int uhpmin = minuhpmax(1), olduhpmax = u.uhpmax; int ustr = ABASE(A_STR) - num, amt, dmg; + boolean waspolyd = Upolyd; + if (num <= 0 || ABASE(A_STR) < ATTRMIN(A_STR)) { + impossible("losestr: %d - %d", ABASE(A_STR), num); + return; + } dmg = 0; while (ustr < ATTRMIN(A_STR)) { ++ustr; @@ -225,8 +230,6 @@ losestr(int num, const char *knam, schar k_format) dmg += amt; } if (dmg) { - boolean waspolyd = Upolyd; - /* in case damage is fatal and caller didn't supply killer reason */ if (!knam || !*knam) { knam = "terminal frailty"; @@ -237,10 +240,9 @@ losestr(int num, const char *knam, schar k_format) if (Upolyd) { /* if still polymorhed, reduce you-as-monst maxHP; never below 1 */ u.mhmax -= min(dmg, u.mhmax - 1); - } else if (waspolyd) { - ; /* rehumanization was triggered; don't reduce no-polyd HP */ - } else { - /* not polymorphed; reduce max HP, but not below below uhpmin */ + } else if (!waspolyd) { + /* not polymorphed now and didn't rehumanize when taking damage; + reduce max HP, but not below below uhpmin */ if (u.uhpmax > uhpmin) setuhpmax(max(u.uhpmax - dmg, uhpmin)); } @@ -255,7 +257,10 @@ losestr(int num, const char *knam, schar k_format) #else nhUse(olduhpmax); #endif - (void) adjattrib(A_STR, -num, 1); + /* 'num' chould have been reduced to 0 in the minimum strength loop; + '(Upolyd || !waspolyd)' is True unless damage caused rehumanization */ + if (num > 0 && (Upolyd || !waspolyd)) + (void) adjattrib(A_STR, -num, 1); } /* combined strength loss and damage from some poisons */ diff --git a/src/mcastu.c b/src/mcastu.c index d8dc1c9e4..fa8097484 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -42,8 +42,7 @@ static int m_cure_self(struct monst *, int); static void cast_wizard_spell(struct monst *, int, int); static void cast_cleric_spell(struct monst *, int, int); static boolean is_undirected_spell(unsigned int, int); -static boolean -spell_would_be_useless(struct monst *, unsigned int, int); +static boolean spell_would_be_useless(struct monst *, unsigned int, int); /* feedback when frustrated monster couldn't cast a spell */ static void @@ -173,10 +172,11 @@ choose_clerical_spell(int spellnum) * 0: unsuccessful spell */ int -castmu(register struct monst *mtmp, - register struct attack *mattk, - boolean thinks_it_foundyou, - boolean foundyou) +castmu( + register struct monst *mtmp, /* caster */ + register struct attack *mattk, /* caster's current attack */ + boolean thinks_it_foundyou, /* might be mistaken if displaced */ + boolean foundyou) /* knows hero's precise location */ { int dmg, ml = mtmp->m_lev; int ret; @@ -347,6 +347,7 @@ m_cure_self(struct monst *mtmp, int dmg) void touch_of_death(void) { + static const char touchodeath[] = "touch of death"; int dmg = 50 + d(8, 6); int drain = dmg / 2; @@ -354,15 +355,18 @@ touch_of_death(void) if (drain >= u.uhpmax) { g.killer.format = KILLED_BY_AN; - Strcpy(g.killer.name, "touch of death"); + Strcpy(g.killer.name, touchodeath); done(DIED); } else { u.uhpmax -= drain; - losehp(dmg, "touch of death", KILLED_BY_AN); + losehp(dmg, touchodeath, KILLED_BY_AN); } } -/* monster wizard and cleric spellcasting functions */ +/* + * Monster wizard and cleric spellcasting functions. + */ + /* If dmg is zero, then the monster is not casting at you. If the monster is intentionally not casting at you, we have previously @@ -463,6 +467,8 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum) } else { You("suddenly feel weaker!"); dmg = mtmp->m_lev - 6; + if (dmg < 1) /* paranoia since only chosen when m_lev is high */ + dmg = 1; if (Half_spell_damage) dmg = (dmg + 1) / 2; losestr(rnd(dmg), (const char *) 0, 0); @@ -615,7 +621,8 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum) if (!enexto(&bypos, mtmp->mux, mtmp->muy, mtmp->data)) break; if ((pm = mkclass(let, 0)) != 0 - && (mtmp2 = makemon(pm, bypos.x, bypos.y, MM_ANGRY|MM_NOMSG)) != 0) { + && (mtmp2 = makemon(pm, bypos.x, bypos.y, MM_ANGRY | MM_NOMSG)) + != 0) { success = TRUE; mtmp2->msleeping = mtmp2->mpeaceful = mtmp2->mtame = 0; set_malign(mtmp2); @@ -678,6 +685,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum) /* note: resists_blnd() doesn't apply here */ if (!Blinded) { int num_eyes = eyecount(g.youmonst.data); + pline("Scales cover your %s!", (num_eyes == 1) ? body_part(EYE) : makeplural(body_part(EYE))); @@ -694,17 +702,16 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum) monstseesu(M_SEEN_MAGR); if (g.multi >= 0) You("stiffen briefly."); - nomul(-1); - g.multi_reason = "paralyzed by a monster"; + dmg = 1; /* to produce nomul(-1), not actual damage */ } else { if (g.multi >= 0) You("are frozen in place!"); dmg = 4 + (int) mtmp->m_lev; if (Half_spell_damage) dmg = (dmg + 1) / 2; - nomul(-dmg); - g.multi_reason = "paralyzed by a monster"; } + nomul(-dmg); + g.multi_reason = "paralyzed by a monster"; g.nomovemsg = 0; dmg = 0; break;