]> granicus.if.org Git - nethack/commitdiff
minetown guards outside the town proper
authorcohrs <cohrs>
Mon, 15 Jul 2002 04:17:13 +0000 (04:17 +0000)
committercohrs <cohrs>
Mon, 15 Jul 2002 04:17:13 +0000 (04:17 +0000)
Pat forwarded a message from the newsgroup in March that the town guards
enforce rules even outside the town proper.  Fix: On room-based town levels,
check if the location is in a room containing subrooms (roomno will often
have a subroom id instead).  On the other levels (e.g. minetn-5), there are
no subrooms, so the whole level is fair game.  Currently, this is valid.
If fancier towns are added in the future, more flags or use of regions may
be required to tell where the town border actually is.  These checks are done
in a new in_town function.

doc/fixes34.1
include/extern.h
src/dig.c
src/dokick.c
src/fountain.c
src/hack.c
src/monmove.c

index 9da922c11ba2a21fb0a9fba9b5f8bb3a27145891..9310cbe68a38db63e731f7f4aa4a6d1fd348dde1 100644 (file)
@@ -166,6 +166,7 @@ in some situations, if hero stood still, a hostile dwarf would switch back
 uncontrolled teleports did not handle leashed pets
 minetown fountain warnings shouldn't prevent finding gems/coins in fountain
 order of container and objects was different for mazelike and roomfilled levels
+minetown guards only enforce town rules inside the town proper
 
 
 Platform- and/or Interface-Specific Fixes
index 1e290ae028b745106b667130b6087addbd440341..1b6cec7be93d82d576ca8626963d454a90c5f680 100644 (file)
@@ -669,6 +669,7 @@ E void NDECL(domove);
 E void NDECL(invocation_message);
 E void FDECL(spoteffects, (BOOLEAN_P));
 E char *FDECL(in_rooms, (XCHAR_P,XCHAR_P,int));
+E boolean FDECL(in_town, (int,int));
 E void FDECL(check_special_room, (BOOLEAN_P));
 E int NDECL(dopickup);
 E void NDECL(lookaround);
index fc74204c31823e3f8848b58d5f761ab3df8cb483..e7659ecee409852036b0bcf8b03c47b7f1ecd00b 100644 (file)
--- a/src/dig.c
+++ b/src/dig.c
@@ -1006,10 +1006,9 @@ watch_dig(mtmp, x, y, zap)
     xchar x, y;
     boolean zap;
 {
-       s_level *slev = Is_special(&u.uz);
        struct rm *lev = &levl[x][y];
 
-       if (slev && slev->flags.town &&
+       if (in_town(x, y) &&
            (closed_door(x, y) || lev->typ == SDOOR ||
             IS_WALL(lev->typ) || IS_FOUNTAIN(lev->typ))) {
            if (!mtmp) {
index 52296f51db33960a5dfa176cb5909fcef1c92d44..969baf855f4ae4758b281288d696da175fec175c 100644 (file)
@@ -591,7 +591,6 @@ dokick()
        register int x, y;
        int avrg_attrib;
        register struct monst *mtmp;
-       s_level *slev;
        boolean no_kick = FALSE;
        char buf[BUFSZ];
 
@@ -1016,7 +1015,7 @@ dumb:
                    add_damage(x, y, 400L);
                    pay_for_damage("break");
                }
-               if ((slev = Is_special(&u.uz)) && slev->flags.town)
+               if (in_town(x, y))
                  for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
                    if (DEADMONSTER(mtmp)) continue;
                    if((mtmp->data == &mons[PM_WATCHMAN] ||
@@ -1036,7 +1035,7 @@ dumb:
            if (Blind) feel_location(x,y);      /* we know we hit it */
            exercise(A_STR, TRUE);
            pline("WHAMMM!!!");
-           if ((slev = Is_special(&u.uz)) && slev->flags.town)
+           if (in_town(x, y))
                for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
                    if (DEADMONSTER(mtmp)) continue;
                    if ((mtmp->data == &mons[PM_WATCHMAN] ||
index 69133de835e8095b3e5515cc6818abc4f489178e..5bec5c4f0a4e8f5b64d33ae5c1dc6fb417148db1 100644 (file)
@@ -152,9 +152,7 @@ boolean isyou;
 {
        if (IS_FOUNTAIN(levl[x][y].typ) &&
            (!rn2(3) || FOUNTAIN_IS_WARNED(x,y))) {
-               s_level *slev = Is_special(&u.uz);
-               if(isyou && slev && slev->flags.town &&
-                  !FOUNTAIN_IS_WARNED(x,y)) {
+               if(isyou && in_town(x, y) && !FOUNTAIN_IS_WARNED(x,y)) {
                        struct monst *mtmp;
                        SET_FOUNTAIN_WARNED(x,y);
                        /* Warn about future fountain use. */
@@ -188,7 +186,7 @@ boolean isyou;
                /* or felt if the hero is blind.                         */
                newsym(x, y);
                level.flags.nfountains--;
-               if(isyou && slev && slev->flags.town)
+               if(isyou && in_town(x, y))
                    (void) angry_guards(FALSE);
        }
 }
@@ -362,7 +360,6 @@ register struct obj *obj;
            && u.ulevel >= 5 && !rn2(6)
            && !obj->oartifact
            && !exist_artifact(LONG_SWORD, artiname(ART_EXCALIBUR))) {
-               s_level *slev = Is_special(&u.uz);
 
                if (u.ualign.type != A_LAWFUL) {
                        /* Ha!  Trying to cheat her. */
@@ -389,7 +386,7 @@ register struct obj *obj;
                levl[u.ux][u.uy].looted = 0;
                if(Invisible) newsym(u.ux, u.uy);
                level.flags.nfountains--;
-               if(slev && slev->flags.town)
+               if(in_town(u.ux, u.uy))
                    (void) angry_guards(FALSE);
                return;
        } else (void) get_wet(obj);
index 136df14779eb81a3d5951483e480cb8d58676402..56a407eceb7f9375a514630c82c6c4bf87b3d7b4 100644 (file)
@@ -1576,6 +1576,31 @@ register int typewanted;
        return(ptr);
 }
 
+/* is (x,y) in a town? */
+boolean
+in_town(x, y)
+register int x, y;
+{
+       s_level *slev = Is_special(&u.uz);
+       register struct mkroom *sroom;
+       boolean has_subrooms = FALSE;
+
+       if (!slev || !slev->flags.town) return FALSE;
+
+       /*
+        * See if (x,y) is in a room with subrooms, if so, assume it's the
+        * town.  If there are no subrooms, the whole level is in town.
+        */
+       for (sroom = &rooms[0]; sroom->hx > 0; sroom++) {
+           if (sroom->nsubrooms > 0) {
+               has_subrooms = TRUE;
+               if (inside_room(sroom, x, y)) return TRUE;
+           }
+       }
+
+       return !has_subrooms;
+}
+
 STATIC_OVL void
 move_update(newlev)
 register boolean newlev;
index 44595171cfd2f459d098aebe2ca07536ce672232..3c30c64d0474dbda2d37e4d0971879457e4709d8 100644 (file)
@@ -48,10 +48,9 @@ STATIC_OVL void
 watch_on_duty(mtmp)
 register struct monst *mtmp;
 {
-       register s_level *slev = Is_special(&u.uz);
        int     x, y;
 
-       if(slev && slev->flags.town && mtmp->mpeaceful &&
+       if(mtmp->mpeaceful && in_town(u.ux+u.dx, u.uy+u.dy) &&
           mtmp->mcansee && m_canseeu(mtmp) && !rn2(3)) {
 
            if(picking_lock(&x, &y) && IS_DOOR(levl[x][y].typ) &&