git issue #994 - killed by a touch of death
Issue reported by vultur-cadens: cause of death reason for touch of death and death due to loss of strength only showed the cause, not the monster spellcaster who was responsible. This changes |Killed by a touch of death. to |Killed by the touch of death inflicted by the Wizard of Yendor. and |Killed by terminal fraility. to |Killed by strength loss inflicted by a chameleon imitating an arch-lich. (The 'imitating' part doesn't fit on the tombstone but will be present in logfile/xlogfile.) Noticed while implemented this: touch of death was modifying u.uhpmax and basing death vs damage on that even when hero was polymorphed. It now rehumanizes the hero in that situation. Closes #994
This commit is contained in:
@@ -1320,7 +1320,7 @@ extern boolean usmellmon(struct permonst *);
|
||||
/* ### mcastu.c ### */
|
||||
|
||||
extern int castmu(struct monst *, struct attack *, boolean, boolean);
|
||||
extern void touch_of_death(void);
|
||||
extern void touch_of_death(struct monst *);
|
||||
extern int buzzmu(struct monst *, struct attack *);
|
||||
|
||||
/* ### mdlib.c ### */
|
||||
|
||||
@@ -2228,10 +2228,10 @@ Amonnam(struct monst *mtmp)
|
||||
/* used for monster ID by the '/', ';', and 'C' commands to block remote
|
||||
identification of the endgame altars via their attending priests */
|
||||
char *
|
||||
distant_monnam(struct monst *mon,
|
||||
int article, /* only ARTICLE_NONE and ARTICLE_THE
|
||||
are handled here */
|
||||
char *outbuf)
|
||||
distant_monnam(
|
||||
struct monst *mon,
|
||||
int article, /* only ARTICLE_NONE and ARTICLE_THE are handled here */
|
||||
char *outbuf)
|
||||
{
|
||||
/* high priest(ess)'s identity is concealed on the Astral Plane,
|
||||
unless you're adjacent (overridden for hallucination which does
|
||||
|
||||
10
src/end.c
10
src/end.c
@@ -409,9 +409,8 @@ done_in_by(struct monst *mtmp, int how)
|
||||
{
|
||||
char buf[BUFSZ];
|
||||
struct permonst *mptr = mtmp->data,
|
||||
*champtr = ((mtmp->cham >= LOW_PM)
|
||||
? &mons[mtmp->cham]
|
||||
: mptr);
|
||||
*champtr = (mtmp->cham >= LOW_PM) ? &mons[mtmp->cham]
|
||||
: mptr;
|
||||
boolean distorted = (boolean) (Hallucination && canspotmon(mtmp)),
|
||||
mimicker = (M_AP_TYPE(mtmp) == M_AP_MONSTER),
|
||||
imitator = (mptr != champtr || mimicker);
|
||||
@@ -442,7 +441,7 @@ done_in_by(struct monst *mtmp, int how)
|
||||
if (imitator) {
|
||||
char shape[BUFSZ];
|
||||
const char *realnm = pmname(champtr, Mgender(mtmp)),
|
||||
*fakenm = pmname(mptr, Mgender(mtmp));
|
||||
*fakenm = pmname(mptr, Mgender(mtmp));
|
||||
boolean alt = is_vampshifter(mtmp);
|
||||
|
||||
if (mimicker) {
|
||||
@@ -498,7 +497,8 @@ done_in_by(struct monst *mtmp, int how)
|
||||
/* might need to fix up multi_reason if 'mtmp' caused the reason */
|
||||
if (gm.multi_reason
|
||||
&& gm.multi_reason > gm.multireasonbuf
|
||||
&& gm.multi_reason < gm.multireasonbuf + sizeof gm.multireasonbuf - 1) {
|
||||
&& gm.multi_reason
|
||||
< gm.multireasonbuf + sizeof gm.multireasonbuf - 1) {
|
||||
char reasondummy, *p;
|
||||
unsigned reasonmid = 0;
|
||||
|
||||
|
||||
59
src/mcastu.c
59
src/mcastu.c
@@ -39,6 +39,7 @@ static void cursetxt(struct monst *, boolean);
|
||||
static int choose_magic_spell(int);
|
||||
static int choose_clerical_spell(int);
|
||||
static int m_cure_self(struct monst *, int);
|
||||
static char *death_inflicted_by(char *, const char *, struct monst *);
|
||||
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);
|
||||
@@ -345,23 +346,60 @@ m_cure_self(struct monst *mtmp, int dmg)
|
||||
return dmg;
|
||||
}
|
||||
|
||||
/* unlike the finger of death spell which behaves like a wand of death,
|
||||
this monster spell only attacks the hero */
|
||||
void
|
||||
touch_of_death(void)
|
||||
touch_of_death(struct monst *mtmp)
|
||||
{
|
||||
static const char touchodeath[] = "touch of death";
|
||||
char kbuf[BUFSZ];
|
||||
int dmg = 50 + d(8, 6);
|
||||
int drain = dmg / 2;
|
||||
|
||||
/* if we get here, we know that hero isn't magic resistant and isn't
|
||||
poly'd into an undead or demon */
|
||||
You_feel("drained...");
|
||||
(void) death_inflicted_by(kbuf, "the touch of death", mtmp);
|
||||
|
||||
if (drain >= u.uhpmax) {
|
||||
gk.killer.format = KILLED_BY_AN;
|
||||
Strcpy(gk.killer.name, touchodeath);
|
||||
if (Upolyd) {
|
||||
u.mh = 0;
|
||||
rehumanize(); /* fatal iff Unchanging */
|
||||
} else if (drain >= u.uhpmax) {
|
||||
gk.killer.format = KILLED_BY;
|
||||
Strcpy(gk.killer.name, kbuf);
|
||||
done(DIED);
|
||||
} else {
|
||||
u.uhpmax -= drain;
|
||||
losehp(dmg, touchodeath, KILLED_BY_AN);
|
||||
losehp(dmg, kbuf, KILLED_BY);
|
||||
}
|
||||
gk.killer.name[0] = '\0'; /* not killed if we get here... */
|
||||
}
|
||||
|
||||
/* give a reason for death by some monster spells */
|
||||
static char *
|
||||
death_inflicted_by(
|
||||
char *outbuf, /* assumed big enough; pm_names are short */
|
||||
const char *deathreason, /* cause of death */
|
||||
struct monst *mtmp) /* monster who caused it */
|
||||
{
|
||||
Strcpy(outbuf, deathreason);
|
||||
if (mtmp) {
|
||||
struct permonst *mptr = mtmp->data,
|
||||
*champtr = (mtmp->cham >= LOW_PM) ? &mons[mtmp->cham] : mptr;
|
||||
const char *realnm = pmname(champtr, Mgender(mtmp)),
|
||||
*fakenm = pmname(mptr, Mgender(mtmp));
|
||||
|
||||
/* greatly simplfied extract from done_in_by(), primarily for
|
||||
reason for death due to 'touch of death' spell; if mtmp is
|
||||
shape changed, it won't be a vampshifter or mimic since they
|
||||
can't cast spells */
|
||||
if (!type_is_pname(champtr) && !the_unique_pm(mptr))
|
||||
realnm = an(realnm);
|
||||
Sprintf(eos(outbuf), " inflicted by %s%s",
|
||||
the_unique_pm(mptr) ? "the " : "", realnm);
|
||||
if (champtr != mptr)
|
||||
Sprintf(eos(outbuf), " imitating %s", an(fakenm));
|
||||
}
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -394,7 +432,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
|
||||
if (Hallucination) {
|
||||
You("have an out of body experience.");
|
||||
} else {
|
||||
touch_of_death();
|
||||
touch_of_death(mtmp);
|
||||
}
|
||||
} else {
|
||||
if (Antimagic) {
|
||||
@@ -467,13 +505,18 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
|
||||
monstseesu(M_SEEN_MAGR);
|
||||
You_feel("momentarily weakened.");
|
||||
} else {
|
||||
char kbuf[BUFSZ];
|
||||
|
||||
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);
|
||||
losestr(rnd(dmg),
|
||||
death_inflicted_by(kbuf, "strength loss", mtmp),
|
||||
KILLED_BY);
|
||||
gk.killer.name[0] = '\0'; /* not killed if we get here... */
|
||||
}
|
||||
dmg = 0;
|
||||
break;
|
||||
|
||||
@@ -1254,6 +1254,10 @@ rehumanize(void)
|
||||
gk.killer.format = NO_KILLER_PREFIX;
|
||||
Strcpy(gk.killer.name, "killed while stuck in creature form");
|
||||
done(DIED);
|
||||
/* can get to here if declining to die in explore or wizard
|
||||
mode; since we're wearing an amulet of unchanging we can't
|
||||
be wearing an amulet of life-saving */
|
||||
return; /* don't rehumanize after all */
|
||||
} else if (uamul && uamul->otyp == AMULET_OF_UNCHANGING) {
|
||||
Your("%s %s!", simpleonames(uamul), otense(uamul, "fail"));
|
||||
uamul->dknown = 1;
|
||||
@@ -1274,7 +1278,8 @@ rehumanize(void)
|
||||
/* can only happen if some bit of code reduces u.uhp
|
||||
instead of u.mh while poly'd */
|
||||
Your("old form was not healthy enough to survive.");
|
||||
Sprintf(gk.killer.name, "reverting to unhealthy %s form", gu.urace.adj);
|
||||
Sprintf(gk.killer.name, "reverting to unhealthy %s form",
|
||||
gu.urace.adj);
|
||||
gk.killer.format = KILLED_BY;
|
||||
done(DIED);
|
||||
}
|
||||
|
||||
@@ -3477,8 +3477,10 @@ mhitm_ad_pest(struct monst *magr, struct attack *mattk,
|
||||
}
|
||||
|
||||
void
|
||||
mhitm_ad_deth(struct monst *magr, struct attack *mattk UNUSED,
|
||||
struct monst *mdef, struct mhitm_data *mhm)
|
||||
mhitm_ad_deth(
|
||||
struct monst *magr,
|
||||
struct attack *mattk UNUSED,
|
||||
struct monst *mdef, struct mhitm_data *mhm)
|
||||
{
|
||||
struct permonst *pd = mdef->data;
|
||||
|
||||
@@ -3501,7 +3503,7 @@ mhitm_ad_deth(struct monst *magr, struct attack *mattk UNUSED,
|
||||
case 18:
|
||||
case 17:
|
||||
if (!Antimagic) {
|
||||
touch_of_death();
|
||||
touch_of_death(magr);
|
||||
mhm->damage = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user