diff --git a/include/extern.h b/include/extern.h index dd67363b5..7397abfa8 100644 --- a/include/extern.h +++ b/include/extern.h @@ -85,11 +85,13 @@ E long FDECL(arti_cost, (struct obj *)); /* ### attrib.c ### */ E boolean FDECL(adjattrib, (int,int,int)); +E void FDECL(gainstr, (struct obj *,int)); +E void FDECL(losestr, (int)); +E void FDECL(poisontell, (int,BOOLEAN_P)); +E void FDECL(poisoned, (const char *,int,const char *,int,BOOLEAN_P)); E void FDECL(change_luck, (SCHAR_P)); E int FDECL(stone_luck, (BOOLEAN_P)); E void NDECL(set_moreluck); -E void FDECL(gainstr, (struct obj *,int)); -E void FDECL(losestr, (int)); E void NDECL(restore_attrib); E void FDECL(exercise, (int,BOOLEAN_P)); E void NDECL(exerchk); @@ -1161,8 +1163,6 @@ E void FDECL(xkilled, (struct monst *,int)); E void FDECL(mon_to_stone, (struct monst*)); E void FDECL(mnexto, (struct monst *)); E boolean FDECL(mnearto, (struct monst *,XCHAR_P,XCHAR_P,BOOLEAN_P)); -E void FDECL(poisontell, (int)); -E void FDECL(poisoned, (const char *,int,const char *,int)); E void FDECL(m_respond, (struct monst *)); E void FDECL(setmangry, (struct monst *)); E void FDECL(wakeup, (struct monst *)); diff --git a/src/attrib.c b/src/attrib.c index 1ceaf8e04..0477b1196 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)attrib.c 3.4 2002/10/07 */ +/* SCCS Id: @(#)attrib.c 3.4 2003/11/26 */ /* Copyright 1988, 1989, 1990, 1992, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ @@ -193,6 +193,90 @@ losestr(num) /* may kill you; cause may be poison or monster like 'a' */ (void) adjattrib(A_STR, -num, TRUE); } +static const struct poison_effect_message { + void VDECL((*delivery_func), (const char *,...)); + const char *effect_msg; +} poiseff[] = { + { You_feel, "weaker" }, /* A_STR */ + { Your, "brain is on fire" }, /* A_INT */ + { Your, "judgement is impaired" }, /* A_WIS */ + { Your, "muscles won't obey you" }, /* A_DEX */ + { You_feel, "very sick" }, /* A_CON */ + { You, "break out in hives" } /* A_CHA */ +}; + +/* feedback for attribute loss due to poisoning */ +void +poisontell(typ, exclaim) +int typ; /* which attribute */ +boolean exclaim; /* emphasis */ +{ + void VDECL((*func), (const char *,...)) = poiseff[typ].delivery_func; + + (*func)("%s%c", poiseff[typ].effect_msg, exclaim ? '!' : '.'); +} + +/* called when an attack or trap has poisoned the hero (used to be in mon.c) */ +void +poisoned(reason, typ, pkiller, fatal, thrown_weapon) +const char *reason, /* controls what messages we display */ + *pkiller; /* for score+log file if fatal */ +int typ, fatal; +boolean thrown_weapon; /* thrown weapons are less deadly */ +{ + int i, kprefix = KILLED_BY_AN; + + /* inform player about being poisoned unless that's already been done; + "blast" has given a "blast of poison gas" message; "poison arrow", + "poison dart", etc have implicitly given poison messages too... */ + if (strcmp(reason, "blast") && !strstri(reason, "poison")) { + boolean plural = (reason[strlen(reason) - 1] == 's') ? 1 : 0; + + /* avoid "The" Orcus's sting was poisoned... */ + pline("%s%s %s poisoned!", + isupper(*reason) ? "" : "The ", reason, + plural ? "were" : "was"); + } + if (Poison_resistance) { + if (!strcmp(reason, "blast")) shieldeff(u.ux, u.uy); + pline_The("poison doesn't seem to affect you."); + return; + } + + /* suppress killer prefix if it already has one */ + i = name_to_mon(pkiller); + if (i >= LOW_PM && (mons[i].geno & G_UNIQ)) { + kprefix = KILLED_BY; + if (!type_is_pname(&mons[i])) pkiller = the(pkiller); + } else if (!strncmpi(pkiller, "the ", 4) || + !strncmpi(pkiller, "an ", 3) || + !strncmpi(pkiller, "a ", 2)) { + /*[ does this need a plural check too? ]*/ + kprefix = KILLED_BY; + } + + i = rn2(fatal + (thrown_weapon ? 20 : 0)); + if (i == 0 && typ != A_CHA) { + u.uhp = -1; + pline_The("poison was deadly..."); + } else if (i <= 5) { + /* check that a stat change was made */ + if (adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), 1)) + poisontell(typ, TRUE); + } else { + i = thrown_weapon ? rnd(6) : rn1(10,6); + losehp(i, pkiller, kprefix); /* poison damage */ + } + + if (u.uhp < 1) { + killer.format = kprefix; + Strcpy(killer.name, pkiller); + /* "Poisoned by a poisoned ___" is redundant */ + done(strstri(pkiller, "poison") ? DIED : POISONING); + } + (void) encumber_msg(); +} + void change_luck(n) register schar n; diff --git a/src/mhitu.c b/src/mhitu.c index 01077338e..9d01adc7f 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)mhitu.c 3.4 2003/09/09 */ +/* SCCS Id: @(#)mhitu.c 3.4 2003/11/26 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1032,7 +1032,7 @@ dopois: if (uncancelled && !rn2(8)) { Sprintf(buf, "%s %s", s_suffix(Monnam(mtmp)), mpoisons_subj(mtmp, mattk)); - poisoned(buf, ptmp, mdat->mname, 30); + poisoned(buf, ptmp, mdat->mname, 30, FALSE); } break; case AD_DRIN: diff --git a/src/mon.c b/src/mon.c index e509d7cf6..e3b2f4563 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)mon.c 3.4 2003/08/24 */ +/* SCCS Id: @(#)mon.c 3.4 2003/11/26 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1988,76 +1988,6 @@ boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */ return(FALSE); } - -static const char *poiseff[] = { - - " feel weaker", "r brain is on fire", - "r judgement is impaired", "r muscles won't obey you", - " feel very sick", " break out in hives" -}; - -void -poisontell(typ) - - int typ; -{ - pline("You%s.", poiseff[typ]); -} - -void -poisoned(string, typ, pname, fatal) -const char *string, *pname; -int typ, fatal; -{ - int i, plural, kprefix = KILLED_BY_AN; - boolean thrown_weapon = (fatal < 0); - - if (thrown_weapon) fatal = -fatal; - if(strcmp(string, "blast") && !thrown_weapon) { - /* 'blast' has already given a 'poison gas' message */ - /* so have "poison arrow", "poison dart", etc... */ - plural = (string[strlen(string) - 1] == 's')? 1 : 0; - /* avoid "The" Orcus's sting was poisoned... */ - pline("%s%s %s poisoned!", isupper(*string) ? "" : "The ", - string, plural ? "were" : "was"); - } - - if(Poison_resistance) { - if(!strcmp(string, "blast")) shieldeff(u.ux, u.uy); - pline_The("poison doesn't seem to affect you."); - return; - } - /* suppress killer prefix if it already has one */ - if ((i = name_to_mon(pname)) >= LOW_PM && mons[i].geno & G_UNIQ) { - kprefix = KILLED_BY; - if (!type_is_pname(&mons[i])) pname = the(pname); - } else if (!strncmpi(pname, "the ", 4) || - !strncmpi(pname, "an ", 3) || - !strncmpi(pname, "a ", 2)) { - /*[ does this need a plural check too? ]*/ - kprefix = KILLED_BY; - } - i = rn2(fatal + 20*thrown_weapon); - if(i == 0 && typ != A_CHA) { - u.uhp = -1; - pline_The("poison was deadly..."); - } else if(i <= 5) { - /* Check that a stat change was made */ - if (adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), 1)) - pline("You%s!", poiseff[typ]); - } else { - i = thrown_weapon ? rnd(6) : rn1(10,6); - losehp(i, pname, kprefix); /* poison damage */ - } - if(u.uhp < 1) { - killer.format = kprefix; - Strcpy(killer.name, pname); - /* "Poisoned by a poisoned ___" is redundant */ - done(strstri(pname, "poison") ? DIED : POISONING); - } - (void) encumber_msg(); -} - /* monster responds to player action; not the same as a passive attack */ /* assumes reason for response has been tested, and response _must_ be made */ void diff --git a/src/mthrowu.c b/src/mthrowu.c index 0c0af1dfe..f965df824 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)mthrowu.c 3.4 2003/05/09 */ +/* SCCS Id: @(#)mthrowu.c 3.4 2003/11/26 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -376,7 +376,7 @@ m_throw(mon, x, y, dx, dy, range, obj) Strcpy(onmbuf, xname(singleobj)); Strcpy(knmbuf, killer_xname(singleobj)); - poisoned(onmbuf, A_STR, knmbuf, -10); + poisoned(onmbuf, A_STR, knmbuf, 10, TRUE); } if(hitu && can_blnd((struct monst*)0, &youmonst, diff --git a/src/potion.c b/src/potion.c index 33e40190d..ea6acea79 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)potion.c 3.4 2003/10/21 */ +/* SCCS Id: @(#)potion.c 3.4 2003/11/26 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -683,10 +683,10 @@ peffects(otmp) int typ = rn2(A_MAX); if (!Fixed_abil) { - poisontell(typ); + poisontell(typ, FALSE); (void) adjattrib(typ, - Poison_resistance ? -1 : -rn1(4,3), - TRUE); + Poison_resistance ? -1 : -rn1(4,3), + 1); } if(!Poison_resistance) { if (otmp->fromsink) diff --git a/src/trap.c b/src/trap.c index 17d0c5a4f..909ebebee 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)trap.c 3.4 2003/10/20 */ +/* SCCS Id: @(#)trap.c 3.4 2003/11/26 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -664,7 +664,7 @@ unsigned trflags; #endif if (thitu(7, dmgval(otmp, &youmonst), otmp, "little dart")) { if (otmp->opoisoned) - poisoned("dart", A_CON, "little dart", -10); + poisoned("dart", A_CON, "little dart", 10, TRUE); obfree(otmp, (struct obj *)0); } else { place_object(otmp, u.ux, u.uy); @@ -909,7 +909,8 @@ glovecheck: (void) rust_dmg(uarmg, "gauntlets", 1, TRUE, &youmonst); "fell into a pit of iron spikes", NO_KILLER_PREFIX); if (!rn2(6)) - poisoned("spikes", A_STR, "fall onto poison spikes", 8); + poisoned("spikes", A_STR, "fall onto poison spikes", + 8, FALSE); } else losehp(Maybe_Half_Phys(rnd(6)),"fell into a pit", NO_KILLER_PREFIX); @@ -3672,16 +3673,19 @@ boolean disarm; case 18: case 17: pline("A cloud of noxious gas billows from %s.", - the(xname(obj))); - poisoned("gas cloud", A_STR, "cloud of poison gas",15); + the(xname(obj))); + poisoned("gas cloud", A_STR, "cloud of poison gas", + 15, FALSE); exercise(A_CON, FALSE); break; case 16: case 15: case 14: case 13: - You_feel("a needle prick your %s.",body_part(bodypart)); - poisoned("needle", A_CON, "poisoned needle",10); + You_feel("a needle prick your %s.", + body_part(bodypart)); + poisoned("needle", A_CON, "poisoned needle", + 10, FALSE); exercise(A_CON, FALSE); break; case 12: diff --git a/src/zap.c b/src/zap.c index 751973560..85b82ef8d 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)zap.c 3.4 2003/08/24 */ +/* SCCS Id: @(#)zap.c 3.4 2003/11/26 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3152,7 +3152,7 @@ xchar sx, sy; if (!rn2(3)) destroy_item(RING_CLASS, AD_ELEC); break; case ZT_POISON_GAS: - poisoned("blast", A_DEX, "poisoned blast", 15); + poisoned("blast", A_DEX, "poisoned blast", 15, FALSE); break; case ZT_ACID: if (Acid_resistance) {