From d0a7d150230b48c604f86aa39e18e6cdfe389675 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Thu, 20 Dec 2007 23:02:47 +0000 Subject: [PATCH] drain energy attack (trunk only) During some recent newsgroup discussion, posted an entry from his personal bug list: energy draining damage from ordinary attacks is implemented even though there are no monsters with that capability and it was not implemented for engulf attacks even though energy vortices have the capability. This implements energy drain engulf attacks against the hero and also both modes of energy drain attacks for monsters and poly'd hero against spellcasting monsters. Since monsters don't have energy, they lose access to their special abilities (their spells, that is) for a few turns, same as a post-3.4.3 change done for anti-magic traps. --- doc/fixes35.0 | 1 + include/extern.h | 1 + src/mhitm.c | 20 +++++++++++++++++++- src/mhitu.c | 8 +++++++- src/monst.c | 4 ++-- src/trap.c | 9 +++++++-- src/uhitm.c | 12 +++++++++++- 7 files changed, 48 insertions(+), 7 deletions(-) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index c385d5aa7..2b2d7914e 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -275,6 +275,7 @@ secret door detection's trap finding is no longer blocked by water or clouds on the Planes of Water and Air potion thrown by monster which hit a long worm's tail gave feedback about hitting its head +implement energy vortex's previously unused energy drain attack Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index 5ae8f2eda..b83e45fb2 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1099,6 +1099,7 @@ E int FDECL(mdisplacem, (struct monst *,struct monst *,BOOLEAN_P)); E void FDECL(paralyze_monst, (struct monst *,int)); E int FDECL(sleep_monst, (struct monst *,int,int)); E void FDECL(slept_monst, (struct monst *)); +E void FDECL(xdrainenergym, (struct monst *,BOOLEAN_P)); E long FDECL(attk_protection, (int)); /* ### mhitu.c ### */ diff --git a/src/mhitm.c b/src/mhitm.c index 31ae58c25..860859966 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)mhitm.c 3.5 2007/04/02 */ +/* SCCS Id: @(#)mhitm.c 3.5 2007/12/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1121,6 +1121,11 @@ mdamagem(magr, mdef, mattk) } tmp = 0; break; + case AD_DREN: + if (!cancelled && !rn2(4)) + xdrainenergym(mdef, vis && mattk->aatyp != AT_ENGL); + tmp = 0; + break; case AD_DRST: case AD_DRDX: case AD_DRCO: @@ -1449,6 +1454,19 @@ int mdead; return (mdead | mhit); } +/* hero or monster has successfully hit target mon with drain energy attack */ +void +xdrainenergym(mon, givemsg) +struct monst *mon; +boolean givemsg; +{ + if (mon->mspec_used < 20 && /* limit draining */ + (attacktype(mon->data, AT_MAGC) || attacktype(mon->data, AT_BREA))) { + mon->mspec_used += d(2, 2); + if (givemsg) pline("%s seems lethargic.", Monnam(mon)); + } +} + /* "aggressive defense"; what type of armor prevents specified attack from touching its target? */ long diff --git a/src/mhitu.c b/src/mhitu.c index 141eecee4..9b38755de 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)mhitu.c 3.5 2007/06/02 */ +/* SCCS Id: @(#)mhitu.c 3.5 2007/12/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1802,6 +1802,12 @@ gulpmu(mtmp, mattk) /* monster swallows you, or damage if u.uswallow */ case AD_DISE: if (!diseasemu(mtmp->data)) tmp = 0; break; + case AD_DREN: + /* AC magic cancellation doesn't help when engulfed */ + if (!mtmp->mcan && rn2(4)) + drain_en(tmp); + tmp = 0; + break; default: physical_damage = TRUE; tmp = 0; diff --git a/src/monst.c b/src/monst.c index 0e7bef1fe..b42cdbec5 100644 --- a/src/monst.c +++ b/src/monst.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)monst.c 3.5 2007/04/02 */ +/* SCCS Id: @(#)monst.c 3.5 2007/12/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -955,7 +955,7 @@ NEARDATA struct permonst mons[] = { M2_HOSTILE|M2_NEUTER, M3_INFRAVISIBLE, CLR_CYAN), MON("energy vortex", S_VORTEX, LVL(6, 20, 2, 30, 0), (G_GENO|G_NOCORPSE|1), - A(ATTK(AT_ENGL, AD_ELEC, 1, 6), ATTK(AT_ENGL, AD_DREN, 0, 0), + A(ATTK(AT_ENGL, AD_ELEC, 1, 6), ATTK(AT_ENGL, AD_DREN, 4, 6), ATTK(AT_NONE, AD_ELEC, 0, 4), NO_ATTK, NO_ATTK, NO_ATTK), SIZ(0, 0, MS_SILENT, MZ_HUGE), MR_ELEC|MR_SLEEP|MR_DISINT|MR_POISON|MR_STONE, 0, diff --git a/src/trap.c b/src/trap.c index e22f15a32..a366d8989 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)trap.c 3.5 2007/08/24 */ +/* SCCS Id: @(#)trap.c 3.5 2007/12/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3389,9 +3389,14 @@ drain_en(n) register int n; { if (!u.uenmax) { + /* energy is completely gone */ You_feel("momentarily lethargic."); } else { - You_feel("your magical energy drain away!"); + /* throttle further loss a bit when there's not much left to lose */ + if (n > u.uenmax || n > u.ulevel) n = rnd(n); + + You_feel("your magical energy drain away%c", + (n > u.uen) ? '!' : '.'); u.uen -= n; if(u.uen < 0) { u.uenmax -= rnd(-u.uen); diff --git a/src/uhitm.c b/src/uhitm.c index e969e1a81..1bcab9479 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)uhitm.c 3.5 2007/05/16 */ +/* SCCS Id: @(#)uhitm.c 3.5 2007/12/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1566,6 +1566,11 @@ register struct attack *mattk; hurtmarmor(mdef, AD_DCAY); tmp = 0; break; + case AD_DREN: + if (!negated && !rn2(4)) + xdrainenergym(mdef, TRUE); + tmp = 0; + break; case AD_DRST: case AD_DRDX: case AD_DRCO: @@ -1958,6 +1963,11 @@ register struct attack *mattk; golemeffects(mdef,(int)mattk->adtyp,dam); } else dam = 0; break; + case AD_DREN: + if (!rn2(4)) + xdrainenergym(mdef, TRUE); + dam = 0; + break; } end_engulf(); if ((mdef->mhp -= dam) <= 0) {