From: Pasi Kallinen Date: Wed, 26 Feb 2020 17:55:53 +0000 (+0200) Subject: Demon lords and princes suppress teleporting in Gehennom X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d86b7e8e7c687a711912e8682894a3ef34c0c7f8;p=nethack Demon lords and princes suppress teleporting in Gehennom 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. --- diff --git a/dat/asmodeus.lua b/dat/asmodeus.lua index 7191f12cd..a8b73b8a4 100644 --- a/dat/asmodeus.lua +++ b/dat/asmodeus.lua @@ -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 = [[ --------------------- diff --git a/dat/baalz.lua b/dat/baalz.lua index 04d6a4634..33eb215ee 100644 --- a/dat/baalz.lua +++ b/dat/baalz.lua @@ -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 = [[ diff --git a/dat/juiblex.lua b/dat/juiblex.lua index 68b50f327..588290cc1 100644 --- a/dat/juiblex.lua +++ b/dat/juiblex.lua @@ -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 diff --git a/dat/orcus.lua b/dat/orcus.lua index 203899959..ac5b940bf 100644 --- a/dat/orcus.lua +++ b/dat/orcus.lua @@ -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 = [[ .|....|....|....|..............|....|........ diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 9e42f5ee2..6a12e3fc0 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -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 diff --git a/include/extern.h b/include/extern.h index ec2910480..c0ce6bae8 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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, diff --git a/src/dokick.c b/src/dokick.c index 7eb52bd94..a0ffff9f4 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -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" diff --git a/src/monmove.c b/src/monmove.c index b58d29303..42f8cf288 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -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)) diff --git a/src/muse.c b/src/muse.c index 0d3847c76..266282995 100644 --- a/src/muse.c +++ b/src/muse.c @@ -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; diff --git a/src/teleport.c b/src/teleport.c index 7f330ccd9..840a6205c 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -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); diff --git a/src/trap.c b/src/trap.c index e0c2a1026..a1aeb7770 100644 --- a/src/trap.c +++ b/src/trap.c @@ -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;