]> granicus.if.org Git - nethack/commitdiff
R806 - monsters using teleportation on noteleport levels
authorcohrs <cohrs>
Sun, 21 Apr 2002 23:25:21 +0000 (23:25 +0000)
committercohrs <cohrs>
Sun, 21 Apr 2002 23:25:21 +0000 (23:25 +0000)
Bug reported was that Vlad the Impaler never figured out that a wand of
teleportation was useless.
1) Rather than change the monst struct, overload the use of the mtrapseen
TELEP_TRAP bit to be set when a monster uses teleportation on a noteleport
level.  This has the side effect of causing the monster to know about
teleport traps if they manage to leave the level.
2) reduce chance for monsters to get teleport wands on noteleport levels,
since they will otherwise simply be left mostly charged for the player.

doc/fixes34.1
src/muse.c

index fede05675ac50a0635d6727b4615c594fa71b50b..68c9f11e61089b2b3aef6433953a21a9b3654c1e 100644 (file)
@@ -87,6 +87,7 @@ don't crash when using lookat on a boulder an BOULDER sym is unique
 attaching a single candle to fill candelabrum's last slot gave message with
        poor grammar: "The candelabrum now has seven candle attached."
 vault guards won't ask who you are if you're unconscious or paralyzed
+monsters should not repeatedly try to teleport on noteleport levels
 
 
 Platform- and/or Interface-Specific Fixes
index f1e7f0df8a7f9d5ab0ef346b2aea2c92a16d1b3d..a9b082d022be556155bfe697f97e786e9d51b327 100644 (file)
@@ -445,10 +445,19 @@ struct monst *mtmp;
                nomore(MUSE_WAN_TELEPORTATION_SELF);
                nomore(MUSE_WAN_TELEPORTATION);
                if(obj->otyp == WAN_TELEPORTATION && obj->spe > 0) {
+                   /* use the TELEP_TRAP bit to determine if they know
+                    * about noteleport on this level or not.  Avoids
+                    * ineffective re-use of teleportation.  This does
+                    * mean if the monster leaves the level, they'll know
+                    * about teleport traps.
+                    */
+                   if (!level.flags.noteleport ||
+                       !(mtmp->mtrapseen & (1 << (TELEP_TRAP-1)))) {
                        m.defensive = obj;
                        m.has_defense = (mon_has_amulet(mtmp))
                                ? MUSE_WAN_TELEPORTATION
                                : MUSE_WAN_TELEPORTATION_SELF;
+                   }
                }
                nomore(MUSE_SCR_TELEPORTATION);
                if(obj->otyp == SCR_TELEPORTATION && mtmp->mcansee
@@ -456,8 +465,12 @@ struct monst *mtmp;
                   && (!obj->cursed ||
                       (!(mtmp->isshk && inhishop(mtmp))
                            && !mtmp->isgd && !mtmp->ispriest))) {
+                   /* see WAN_TELEPORTATION case above */
+                   if (!level.flags.noteleport ||
+                       !(mtmp->mtrapseen & (1 << (TELEP_TRAP-1)))) {
                        m.defensive = obj;
                        m.has_defense = MUSE_SCR_TELEPORTATION;
+                   }
                }
 
            if (mtmp->data != &mons[PM_PESTILENCE]) {
@@ -563,6 +576,9 @@ mon_tele:
                if (tele_restrict(mtmp)) {      /* mysterious force... */
                    if (vismon && how)          /* mentions 'teleport' */
                        makeknown(how);
+                   /* monster learns that teleportation isn't useful here */
+                   if (level.flags.noteleport)
+                       mtmp->mtrapseen |= (1 << (TELEP_TRAP-1));
                    return 2;
                }
                if ((
@@ -584,6 +600,9 @@ mon_tele:
                otmp->spe--;
                m_using = TRUE;
                mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp);
+               /* monster learns that teleportation isn't useful here */
+               if (level.flags.noteleport)
+                   mtmp->mtrapseen |= (1 << (TELEP_TRAP-1));
                m_using = FALSE;
                return 2;
        case MUSE_SCR_TELEPORTATION:
@@ -882,6 +901,7 @@ struct monst *mtmp;
 {
        struct permonst *pm = mtmp->data;
        int difficulty = monstr[(monsndx(pm))];
+       int try = 0;
 
        if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
                        || pm->mlet == S_GHOST
@@ -889,9 +909,12 @@ struct monst *mtmp;
                        || pm->mlet == S_KOP
 # endif
                ) return 0;
+    try_again:
        switch (rn2(8 + (difficulty > 3) + (difficulty > 6) +
                                (difficulty > 8))) {
                case 6: case 9:
+                       if (level.flags.noteleport && ++try < 2)
+                           goto try_again;
                        if (!rn2(3)) return WAN_TELEPORTATION;
                        /* else FALLTHRU */
                case 0: case 1: