From 23e1970db3cea80928e354acdf5b3c63d086d92b Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Sat, 25 Nov 2006 02:29:39 +0000 Subject: [PATCH] anti-magic trap (trunk only) Make anti-magic fields do something against targets which have magic resistance, expanding the functionality of that trap type and giving a minor drawback to the most valuable intrinsic in the game. Make them work against monsters too. Heroes who lack magic resistance lose spell energy as before, except that if they drop below 0 they don't take as hard a hit against max spell energy as they used to. Monsters with spell or breath attack and lacking magic resistance get their ability-last-used field bumped up a little bit, so they can't cast or breathe for a few turns. Heroes and monsters who have magic resistance take HP damage instead. I retained the concept of feeling lethargic when being hit by something which normally drains enery, and also tried to make it be the inverse of a "magical explosion": the message refers to torpor/lethargy/sluggishness and cause of death if the damage happens to be fatal is "anti-magic implosion". The latter suggests some sort of compression, so creatures who can pass through walls (xorns and ghosts) have been given partial resistance and take reduced damage. --- doc/fixes35.0 | 1 + src/trap.c | 85 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 054331630..80e877e93 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -257,6 +257,7 @@ lembas and cram never rot unless cursed multiple squeaks for squeaky boards include time, user ID, and play mode in paniclog entries add oracle and rumor regarding priestly donations +anti-magic traps have alternate effect on targets who have magic resistance Platform- and/or Interface-Specific New Features diff --git a/src/trap.c b/src/trap.c index 87ebfc444..03fa1968e 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)trap.c 3.5 2006/09/28 */ +/* SCCS Id: @(#)trap.c 3.5 2006/11/22 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1182,10 +1182,36 @@ glovecheck: (void) rust_dmg(uarmg, "gauntlets", 1, TRUE, &youmonst); case ANTI_MAGIC: seetrap(trap); - if(Antimagic) { - shieldeff(u.ux, u.uy); - You_feel("momentarily lethargic."); - } else drain_en(rnd(u.ulevel) + 1); + /* hero without magic resistance loses spell energy, + hero with magic resistance takes damage instead; + possibly non-intuitive but useful for play balance */ + if (!Antimagic) { + drain_en(rnd(u.ulevel) + 1); + } else { + int dmgval = rnd(4), hp = Upolyd ? u.mh : u.uhp; + + /* Half_XXX_damage has opposite its usual effect (approx) + but isn't cumulative if hero has more than one */ + if (Half_physical_damage || Half_spell_damage) + dmgval += rnd(4); + /* give Magicbane wielder dose of own medicine */ + if (uwep && uwep->oartifact == ART_MAGICBANE) + dmgval += rnd(4); + /* having an artifact--other than own quest one--which + confers magic resistance simply by being carried + also increases the effect */ + for (otmp = invent; otmp; otmp = otmp->nobj) + if (otmp->oartifact && !is_quest_artifact(otmp) && + protects(AD_MAGM, otmp)) break; + if (otmp) dmgval += rnd(4); + if (Passes_walls) dmgval = (dmgval + 3) / 4; + + You_feel((dmgval >= hp) ? "unbearably torpid!" : + (dmgval >= hp / 4) ? "very lethargic." : + "sluggish."); + /* opposite of magical explosion */ + losehp(dmgval, "anti-magic implosion", KILLED_BY_AN); + } break; case POLY_TRAP: { @@ -1898,7 +1924,7 @@ register struct monst *mtmp; #endif if (!inescapable && ((mtmp->mtrapseen & (1 << (tt-1))) != 0 || - (tt == HOLE && !mindless(mtmp->data)))) { + (tt == HOLE && !mindless(mptr)))) { /* it has been in such a trap - perhaps it escapes */ if(rn2(4)) return(0); } else { @@ -2112,7 +2138,7 @@ glovecheck: target = which_armor(mtmp, W_ARMG); /* paper burns very fast, assume straw is tightly * packed and burns a bit slower */ - switch (monsndx(mtmp->data)) { + switch (monsndx(mptr)) { case PM_PAPER_GOLEM: immolate = TRUE; alt = mtmp->mhpmax; break; case PM_STRAW_GOLEM: alt = mtmp->mhpmax / 2; break; @@ -2166,7 +2192,8 @@ glovecheck: target = which_armor(mtmp, W_ARMG); pline("%s %s into %s pit!", Monnam(mtmp), fallverb, a_your[trap->madeby_u]); - if (mptr == &mons[PM_PIT_VIPER] || mptr == &mons[PM_PIT_FIEND]) + if (mptr == &mons[PM_PIT_VIPER] || + mptr == &mons[PM_PIT_FIEND]) pline("How pitiful. Isn't that the pits?"); seetrap(trap); } @@ -2317,6 +2344,36 @@ glovecheck: target = which_armor(mtmp, W_ARMG); if (!rn2(21)) goto mfiretrap; break; case ANTI_MAGIC: + /* similar to hero's case, more or less */ + if (!resists_magm(mtmp)) { /* lose spell energy */ + if (attacktype(mptr, AT_MAGC) || + attacktype(mptr, AT_BREA)) { + mtmp->mspec_used += d(2, 2); + if (in_sight) { + seetrap(trap); + pline("%s seems lethargic.", Monnam(mtmp)); + } + } + } else { /* take some damage */ + int dmgval = rnd(4); + + if ((otmp = MON_WEP(mtmp)) != 0 && + otmp->oartifact == ART_MAGICBANE) + dmgval += rnd(4); + for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) + if (otmp->oartifact && protects(AD_MAGM, otmp)) + break; + if (otmp) dmgval += rnd(4); + if (passes_walls(mptr)) dmgval = (dmgval + 3) / 4; + + if (in_sight) seetrap(trap); + if ((mtmp->mhp -= dmgval) <= 0) + monkilled(mtmp, in_sight ? + "compression from an anti-magic field" : 0, + -AD_MAGM); + if (mtmp->mhp <= 0) trapkilled = TRUE; + if (see_it) newsym(trap->tx, trap->ty); + } break; case LANDMINE: @@ -2364,8 +2421,9 @@ glovecheck: target = which_armor(mtmp, W_ARMG); if (resists_magm(mtmp)) { shieldeff(mtmp->mx, mtmp->my); } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) { - (void) newcham(mtmp, (struct permonst *)0, - FALSE, FALSE); + if (newcham(mtmp, (struct permonst *)0, FALSE, FALSE)) + /* we're done with mptr but keep it up to date */ + mptr = mtmp->data; if (in_sight) seetrap(trap); } break; @@ -3288,15 +3346,18 @@ void drain_en(n) register int n; { - if (!u.uenmax) return; + if (!u.uenmax) { + You_feel("momentarily lethargic."); + } else { You_feel("your magical energy drain away!"); u.uen -= n; if(u.uen < 0) { - u.uenmax += u.uen; + u.uenmax -= rnd(-u.uen); if(u.uenmax < 0) u.uenmax = 0; u.uen = 0; } context.botl = 1; + } } int