magic_negation(mon)
struct monst *mon;
{
- struct obj *armor;
- int armpro = 0;
-
- armor = (mon == &youmonst) ? uarm : which_armor(mon, W_ARM);
- if (armor && armpro < objects[armor->otyp].a_can)
- armpro = objects[armor->otyp].a_can;
- armor = (mon == &youmonst) ? uarmc : which_armor(mon, W_ARMC);
- if (armor && armpro < objects[armor->otyp].a_can)
- armpro = objects[armor->otyp].a_can;
- armor = (mon == &youmonst) ? uarmh : which_armor(mon, W_ARMH);
- if (armor && armpro < objects[armor->otyp].a_can)
- armpro = objects[armor->otyp].a_can;
-
- /* armor types for shirt, gloves, shoes, and shield don't currently
- provide any magic cancellation but we might as well be complete */
-#ifdef TOURIST
- armor = (mon == &youmonst) ? uarmu : which_armor(mon, W_ARMU);
- if (armor && armpro < objects[armor->otyp].a_can)
- armpro = objects[armor->otyp].a_can;
-#endif
- armor = (mon == &youmonst) ? uarmg : which_armor(mon, W_ARMG);
- if (armor && armpro < objects[armor->otyp].a_can)
- armpro = objects[armor->otyp].a_can;
- armor = (mon == &youmonst) ? uarmf : which_armor(mon, W_ARMF);
- if (armor && armpro < objects[armor->otyp].a_can)
- armpro = objects[armor->otyp].a_can;
- armor = (mon == &youmonst) ? uarms : which_armor(mon, W_ARMS);
- if (armor && armpro < objects[armor->otyp].a_can)
- armpro = objects[armor->otyp].a_can;
+ struct obj *o;
+ long wearmask;
+ int armpro, mc = 0;
+ boolean is_you = (mon == &youmonst), gotprot = FALSE;
+
+ for (o = is_you ? invent : mon->minvent; o; o = o->nobj) {
+ /* a_can field is only applicable for armor (which must be worn) */
+ if ((o->owornmask & W_ARMOR) != 0L) {
+ armpro = objects[o->otyp].a_can;
+ if (armpro > mc) mc = armpro;
+ }
+ /* if we've already confirmed Protection, skip additional checks */
+ if (gotprot) continue;
+
+ /* omit W_SWAPWEP+W_QUIVER; W_ART+W_ARTI handled by protects() */
+ wearmask = W_ARMOR | W_RING | W_AMUL | W_TOOL;
+ if (o->oclass == WEAPON_CLASS || is_weptool(o)) wearmask |= W_WEP;
+ if (protects(o, ((o->owornmask & wearmask) != 0L) ? TRUE : FALSE))
+ gotprot = TRUE;
+ }
-#ifdef STEED
- /* this one is really a stretch... */
- armor = (mon == &youmonst) ? 0 : which_armor(mon, W_SADDLE);
- if (armor && armpro < objects[armor->otyp].a_can)
- armpro = objects[armor->otyp].a_can;
-#endif
+ /* extrinsic Protection increases mc factor */
+ if (!gotprot) {
+ /* in case hero has extrinsic protection from some other source */
+ if (is_you && EProtection) gotprot = TRUE;
+ /* high priests have innate intrinsic protection which is as
+ strong as extrinsic protection */
+ if (mon->data == &mons[PM_HIGH_PRIEST]) gotprot = TRUE;
+ }
+ /* extrinsic Protection increases mc by 1 */
+ if (gotprot && mc < 3)
+ mc += 1;
+
+ /* intrinsic Protection is weaker than Extrinsic (play balance;
+ obtaining divine protection is too easy) */
+ if (!gotprot) {
+ if (is_you && ((HProtection && u.ublessed > 0) || u.uspellprot))
+ gotprot = TRUE;
+ /* aligned priests and angels have innate intrinsic Protection */
+ if (mon->data == &mons[PM_ALIGNED_PRIEST] || is_minion(mon->data))
+ gotprot = TRUE;
+ }
+ /* intrinsic Protection confers minimum mc 1 instead of 0 */
+ if (gotprot && mc < 1)
+ mc = 1;
- return armpro;
+ return mc;
}
/*
* armor's special magic protection. Otherwise just use !mtmp->mcan.
*/
armpro = magic_negation(&youmonst);
- uncancelled = !mtmp->mcan && ((rn2(3) >= armpro) || !rn2(50));
+ uncancelled = !mtmp->mcan && (rn2(10) >= 3 * armpro);
permdmg = 0;
/* Now, adjust damages via resistances or specific attacks */
/* NetHack 3.5 objects.c $Date$ $Revision$ */
-/* SCCS Id: @(#)objects.c 3.5 2006/12/14 */
/* Copyright (c) Mike Threepoint, 1989. */
/* NetHack may be freely redistributed. See license for details. */
1, 0, 0, 0, 0, 3, 1,10, 0, CLOTH, CLR_BROWN),
HELM("cornuthaum", "conical hat",
0, 1, CLAIRVOYANT,
- 3, 1, 4, 80,10, 2, CLOTH, CLR_BLUE),
+ 3, 1, 4, 80,10, 1, CLOTH, CLR_BLUE),
HELM("dunce cap", "conical hat",
0, 1, 0, 3, 1, 4, 1,10, 0, CLOTH, CLR_BLUE),
HELM("dented pot", (char *)0,
1, 0, 1, 0, 10, 5, 450, 820, 3, 2, ARM_SUIT, GLASS, CLR_WHITE),
#ifdef TOURIST
ARMOR("bronze plate mail", (char *)0,
- 1, 0, 1, 0, 25, 5, 450, 400, 4, 0, ARM_SUIT, COPPER, HI_COPPER),
+ 1, 0, 1, 0, 25, 5, 450, 400, 4, 1, ARM_SUIT, COPPER, HI_COPPER),
#else
ARMOR("bronze plate mail", (char *)0,
- 1, 0, 1, 0, 35, 5, 450, 400, 4, 0, ARM_SUIT, COPPER, HI_COPPER),
+ 1, 0, 1, 0, 35, 5, 450, 400, 4, 1, ARM_SUIT, COPPER, HI_COPPER),
#endif
ARMOR("splint mail", (char *)0,
1, 0, 1, 0, 62, 5, 400, 80, 4, 1, ARM_SUIT, IRON, HI_METAL),
ARMOR("banded mail", (char *)0,
- 1, 0, 1, 0, 72, 5, 350, 90, 4, 0, ARM_SUIT, IRON, HI_METAL),
+ 1, 0, 1, 0, 72, 5, 350, 90, 4, 1, ARM_SUIT, IRON, HI_METAL),
ARMOR("dwarvish mithril-coat", (char *)0,
- 1, 0, 0, 0, 10, 1, 150, 240, 4, 3, ARM_SUIT, MITHRIL, HI_METAL),
+ 1, 0, 0, 0, 10, 1, 150, 240, 4, 2, ARM_SUIT, MITHRIL, HI_METAL),
ARMOR("elven mithril-coat", (char *)0,
- 1, 0, 0, 0, 15, 1, 150, 240, 5, 3, ARM_SUIT, MITHRIL, HI_METAL),
+ 1, 0, 0, 0, 15, 1, 150, 240, 5, 2, ARM_SUIT, MITHRIL, HI_METAL),
ARMOR("chain mail", (char *)0,
1, 0, 0, 0, 72, 5, 300, 75, 5, 1, ARM_SUIT, IRON, HI_METAL),
ARMOR("orcish chain mail", "crude chain mail",
0, 0, 0, 0, 20, 5, 300, 75, 6, 1, ARM_SUIT, IRON, CLR_BLACK),
ARMOR("scale mail", (char *)0,
- 1, 0, 0, 0, 72, 5, 250, 45, 6, 0, ARM_SUIT, IRON, HI_METAL),
+ 1, 0, 0, 0, 72, 5, 250, 45, 6, 1, ARM_SUIT, IRON, HI_METAL),
ARMOR("studded leather armor", (char *)0,
1, 0, 0, 0, 72, 3, 200, 15, 7, 1, ARM_SUIT, LEATHER, HI_LEATHER),
ARMOR("ring mail", (char *)0,
- 1, 0, 0, 0, 72, 5, 250, 100, 7, 0, ARM_SUIT, IRON, HI_METAL),
+ 1, 0, 0, 0, 72, 5, 250, 100, 7, 1, ARM_SUIT, IRON, HI_METAL),
ARMOR("orcish ring mail", "crude ring mail",
0, 0, 0, 0, 20, 5, 250, 80, 8, 1, ARM_SUIT, IRON, CLR_BLACK),
ARMOR("leather armor", (char *)0,
- 1, 0, 0, 0, 82, 3, 150, 5, 8, 0, ARM_SUIT, LEATHER, HI_LEATHER),
+ 1, 0, 0, 0, 82, 3, 150, 5, 8, 1, ARM_SUIT, LEATHER, HI_LEATHER),
ARMOR("leather jacket", (char *)0,
1, 0, 0, 0, 12, 0, 30, 10, 9, 0, ARM_SUIT, LEATHER, CLR_BLACK),
CLOAK("mummy wrapping", (char *)0,
1, 0, 0, 0, 0, 3, 2, 10, 1, CLOTH, CLR_GRAY),
CLOAK("elven cloak", "faded pall",
- 0, 1, STEALTH, 8, 0, 10, 60, 9, 3, CLOTH, CLR_BLACK),
+ 0, 1, STEALTH, 8, 0, 10, 60, 9, 1, CLOTH, CLR_BLACK),
CLOAK("orcish cloak", "coarse mantelet",
- 0, 0, 0, 8, 0, 10, 40, 10, 2, CLOTH, CLR_BLACK),
+ 0, 0, 0, 8, 0, 10, 40, 10, 1, CLOTH, CLR_BLACK),
CLOAK("dwarvish cloak", "hooded cloak",
- 0, 0, 0, 8, 0, 10, 50, 10, 2, CLOTH, HI_CLOTH),
+ 0, 0, 0, 8, 0, 10, 50, 10, 1, CLOTH, HI_CLOTH),
CLOAK("oilskin cloak", "slippery cloak",
- 0, 0, 0, 8, 0, 10, 50, 9, 3, CLOTH, HI_CLOTH),
+ 0, 0, 0, 8, 0, 10, 50, 9, 2, CLOTH, HI_CLOTH),
CLOAK("robe", (char *)0,
- 1, 1, 0, 3, 0, 15, 50, 8, 3, CLOTH, CLR_RED),
+ 1, 1, 0, 3, 0, 15, 50, 8, 2, CLOTH, CLR_RED),
CLOAK("alchemy smock", "apron",
0, 1, POISON_RES, 9, 0, 10, 50, 9, 1, CLOTH, CLR_WHITE),
CLOAK("leather cloak", (char *)0,
CLOAK("cloak of protection", "tattered cape",
0, 1, PROTECTION, 9, 0, 10, 50, 7, 3, CLOTH, HI_CLOTH),
CLOAK("cloak of invisibility", "opera cloak",
- 0, 1, INVIS, 10, 0, 10, 60, 9, 2, CLOTH, CLR_BRIGHT_MAGENTA),
+ 0, 1, INVIS, 10, 0, 10, 60, 9, 1, CLOTH, CLR_BRIGHT_MAGENTA),
CLOAK("cloak of magic resistance", "ornamental cope",
- 0, 1, ANTIMAGIC, 2, 0, 10, 60, 9, 3, CLOTH, CLR_WHITE),
+ 0, 1, ANTIMAGIC, 2, 0, 10, 60, 9, 1, CLOTH, CLR_WHITE),
CLOAK("cloak of displacement", "piece of cloth",
- 0, 1, DISPLACED, 10, 0, 10, 50, 9, 2, CLOTH, HI_CLOTH),
+ 0, 1, DISPLACED, 10, 0, 10, 50, 9, 1, CLOTH, HI_CLOTH),
/* shields */
SHIELD("small shield", (char *)0,