]> granicus.if.org Git - nethack/commitdiff
Demon lords and princes suppress teleporting in Gehennom
authorPasi Kallinen <paxed@alt.org>
Wed, 26 Feb 2020 17:55:53 +0000 (19:55 +0200)
committerPasi Kallinen <paxed@alt.org>
Wed, 26 Feb 2020 18:03:00 +0000 (20:03 +0200)
Instead of having the demon lair levels unconditionally no-teleport,
grant demon lords and princes the ability to suppress teleportation
in Gehennom on the level they are on.

dat/asmodeus.lua
dat/baalz.lua
dat/juiblex.lua
dat/orcus.lua
doc/fixes37.0
include/extern.h
src/dokick.c
src/monmove.c
src/muse.c
src/teleport.c
src/trap.c

index 7191f12cd81328ed7644f29e91e859218d5c410c..a8b73b8a4a771f4f7f9fe151a6a8254f0a66de62 100644 (file)
@@ -5,7 +5,7 @@
 --
 des.level_init({ style="mazegrid", bg ="-" });
 
-des.level_flags("mazelevel", "noteleport")
+des.level_flags("mazelevel")
 -- First part
 des.map({ halign = "half-left", valign = "center", map = [[
 ---------------------
index 04d6a4634391d650803e31421967b0efabbf731e..33eb215ee5d3655cd95822c35a47b87130eb1c69 100644 (file)
@@ -7,7 +7,7 @@ des.level_init({ style = "solidfill", fg = " " });
 
 -- TODO FIXME: see baalz_fixup - the legs get removed currently.
 
-des.level_flags("mazelevel", "noteleport", "corrmaze")
+des.level_flags("mazelevel", "corrmaze")
 -- the two pools are fakes used to mark spots which need special wall fixups
 -- the two iron bars are eyes and spots to their left will be made diggable
 des.map({ halign = "right", valign = "center", map = [[
index 68b50f327136db1df1bab2e73071f128d172d3ce..588290cc1fe969a6650e3ac32bef17c281fd4a74 100644 (file)
@@ -4,7 +4,7 @@
 -- NetHack may be freely redistributed.  See license for details.
 --
 
-des.level_flags("mazelevel", "noteleport", "shortsighted", "noflip")
+des.level_flags("mazelevel", "shortsighted", "noflip")
 -- des.level_init(mines,'.','}',true,true,unlit,false)
 des.level_init({ style = "swamp", lit = 0 });
 -- guarantee at least one open spot to ensure successful stair placement
index 203899959deaf07b77afbcb392a71463fe99ba08..ac5b940bf4cc21f02e9fe8a64f87da3102850094 100644 (file)
@@ -5,7 +5,7 @@
 --
 des.level_init({ style="mazegrid", bg ="-" });
 
-des.level_flags("mazelevel", "noteleport", "shortsighted")
+des.level_flags("mazelevel", "shortsighted")
 -- A ghost town
 des.map({ halign = "right", valign = "center", map = [[
 .|....|....|....|..............|....|........
index 9e42f5ee2eeda1b9b58eaa390e9c9c1ecda74d67..6a12e3fc05fed7868dcb18bb935834560289234f 100644 (file)
@@ -165,6 +165,7 @@ added several new status conditions all of which are opt-in except
 tipping your cap might get a response
 special levels can be flipped horizontally and/or vertically
 new special level initialization routine, "swamp"
+demon lords and princes suppress teleporting in Gehennom
 
 
 Platform- and/or Interface-Specific New Features
index ec291048078ad9342645c7d4429020fdeddb21ca..c0ce6bae8112e0d778cd5113a6b7ce75879fa29b 100644 (file)
@@ -2555,6 +2555,7 @@ E boolean FDECL(stucksteed, (BOOLEAN_P));
 
 /* ### teleport.c ### */
 
+E boolean FDECL(noteleport_level, (struct monst *));
 E boolean FDECL(goodpos, (int, int, struct monst *, unsigned));
 E boolean FDECL(enexto, (coord *, XCHAR_P, XCHAR_P, struct permonst *));
 E boolean FDECL(enexto_core, (coord *, XCHAR_P, XCHAR_P,
index 7eb52bd94f73ed4f0a3d122937ad062d64515afb..a0ffff9f4d3515629fd9e1d1b4f9d819c4ceb7eb 100644 (file)
@@ -258,7 +258,7 @@ xchar x, y;
             if (mon->mx != x || mon->my != y) {
                 (void) unmap_invisible(x, y);
                 pline("%s %s, %s evading your %skick.", Monnam(mon),
-                      (!g.level.flags.noteleport && can_teleport(mon->data))
+                      (can_teleport(mon->data) && !noteleport_level(mon))
                           ? "teleports"
                           : is_floater(mon->data)
                                 ? "floats"
index b58d293035fd47540ae5ae3bea6ff1bc79061753..42f8cf288417b6f8a9956df0d773d7870c59cef0 100644 (file)
@@ -470,7 +470,7 @@ register struct monst *mtmp;
 
     /* some monsters teleport */
     if (mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz
-        && !g.level.flags.noteleport) {
+        && !noteleport_level(mtmp)) {
         (void) rloc(mtmp, TRUE);
         return 0;
     }
@@ -1149,7 +1149,7 @@ register int after;
     if (is_minion(ptr) || is_rider(ptr))
         flag |= ALLOW_SANCT;
     /* unicorn may not be able to avoid hero on a noteleport level */
-    if (is_unicorn(ptr) && !g.level.flags.noteleport)
+    if (is_unicorn(ptr) && !noteleport_level(mtmp))
         flag |= NOTONL;
     if (passes_walls(ptr))
         flag |= (ALLOW_WALL | ALLOW_ROCK);
@@ -1185,7 +1185,7 @@ register int after;
         if (!mtmp->mpeaceful && g.level.flags.shortsighted
             && nidist > (couldsee(nix, niy) ? 144 : 36) && appr == 1)
             appr = 0;
-        if (is_unicorn(ptr) && g.level.flags.noteleport) {
+        if (is_unicorn(ptr) && noteleport_level(mtmp)) {
             /* on noteleport levels, perhaps we cannot avoid hero */
             for (i = 0; i < cnt; i++)
                 if (!(info[i] & NOTONL))
index 0d3847c76a5b09a746143138b9fd9e846cdd5466..2662829957fad0e4be570cc6ae37f163f196c042 100644 (file)
@@ -546,7 +546,7 @@ struct monst *mtmp;
              * mean if the monster leaves the level, they'll know
              * about teleport traps.
              */
-            if (!g.level.flags.noteleport
+            if (!noteleport_level(mtmp)
                 || !(mtmp->mtrapseen & (1 << (TELEP_TRAP - 1)))) {
                 g.m.defensive = obj;
                 g.m.has_defense = (mon_has_amulet(mtmp))
@@ -560,7 +560,7 @@ struct monst *mtmp;
             && (!obj->cursed || (!(mtmp->isshk && inhishop(mtmp))
                                  && !mtmp->isgd && !mtmp->ispriest))) {
             /* see WAN_TELEPORTATION case above */
-            if (!g.level.flags.noteleport
+            if (!noteleport_level(mtmp)
                 || !(mtmp->mtrapseen & (1 << (TELEP_TRAP - 1)))) {
                 g.m.defensive = obj;
                 g.m.has_defense = MUSE_SCR_TELEPORTATION;
@@ -673,7 +673,7 @@ struct monst *mtmp;
             if (vismon && how)     /* mentions 'teleport' */
                 makeknown(how);
             /* monster learns that teleportation isn't useful here */
-            if (g.level.flags.noteleport)
+            if (noteleport_level(mtmp))
                 mtmp->mtrapseen |= (1 << (TELEP_TRAP - 1));
             return 2;
         }
@@ -692,7 +692,7 @@ struct monst *mtmp;
         g.m_using = TRUE;
         mbhit(mtmp, rn1(8, 6), mbhitm, bhito, otmp);
         /* monster learns that teleportation isn't useful here */
-        if (g.level.flags.noteleport)
+        if (noteleport_level(mtmp))
             mtmp->mtrapseen |= (1 << (TELEP_TRAP - 1));
         g.m_using = FALSE;
         return 2;
@@ -1016,7 +1016,7 @@ struct monst *mtmp;
     switch (rn2(8 + (difficulty > 3) + (difficulty > 6) + (difficulty > 8))) {
     case 6:
     case 9:
-        if (g.level.flags.noteleport && ++trycnt < 2)
+        if (noteleport_level(mtmp) && ++trycnt < 2)
             goto try_again;
         if (!rn2(3))
             return WAN_TELEPORTATION;
index 7f330ccd92679242c50aa09a7c1f3e91494bc5d6..840a6205c3520d9ec3887645dd2ea1995797fc4a 100644 (file)
@@ -11,6 +11,26 @@ static void NDECL(vault_tele);
 static boolean FDECL(rloc_pos_ok, (int, int, struct monst *));
 static void FDECL(mvault_tele, (struct monst *));
 
+/* teleporting is prevented on this level for this monster? */
+boolean
+noteleport_level(mon)
+struct monst *mon;
+{
+    struct monst *mtmp;
+
+    /* demon court in Gehennom prevent others from teleporting */
+    if (In_hell(&u.uz) && !(is_dlord(mon->data) || is_dprince(mon->data)))
+        for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+            if (is_dlord(mtmp->data) || is_dprince(mtmp->data))
+                return TRUE;
+
+    /* natural no-teleport level */
+    if (g.level.flags.noteleport)
+        return TRUE;
+
+    return FALSE;
+}
+
 /*
  * Is (x,y) a good position of mtmp?  If mtmp is NULL, then is (x,y) good
  * for an object?
@@ -495,7 +515,7 @@ struct obj *scroll;
     boolean result = FALSE; /* don't learn scroll */
 
     /* Disable teleportation in stronghold && Vlad's Tower */
-    if (g.level.flags.noteleport) {
+    if (noteleport_level(&g.youmonst)) {
         if (!wizard) {
             pline("A mysterious force prevents you from teleporting!");
             return TRUE;
@@ -1316,7 +1336,7 @@ boolean
 tele_restrict(mon)
 struct monst *mon;
 {
-    if (g.level.flags.noteleport) {
+    if (noteleport_level(mon)) {
         if (canseemon(mon))
             pline("A mysterious force prevents %s from teleporting!",
                   mon_nam(mon));
@@ -1591,7 +1611,7 @@ boolean give_feedback;
         if (give_feedback)
             pline("%s resists your magic!", Monnam(mtmp));
         return FALSE;
-    } else if (g.level.flags.noteleport && u.uswallow && mtmp == u.ustuck) {
+    } else if (u.uswallow && mtmp == u.ustuck && noteleport_level(mtmp)) {
         if (give_feedback)
             You("are no longer inside %s!", mon_nam(mtmp));
         unstuck(mtmp);
index e0c2a1026dc526bdab93a976afc5961e45ce2a98..a1aeb7770f2e02959c8e1929ee214e25fadea05a 100644 (file)
@@ -3806,7 +3806,7 @@ drown()
     if ((Teleportation || can_teleport(g.youmonst.data)) && !Unaware
         && (Teleport_control || rn2(3) < Luck + 2)) {
         You("attempt a teleport spell."); /* utcsri!carroll */
-        if (!g.level.flags.noteleport) {
+        if (!noteleport_level(&g.youmonst)) {
             (void) dotele(FALSE);
             if (!is_pool(u.ux, u.uy))
                 return TRUE;