diff --git a/doc/fixes34.1 b/doc/fixes34.1 index 9da922c11..9310cbe68 100644 --- a/doc/fixes34.1 +++ b/doc/fixes34.1 @@ -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 diff --git a/include/extern.h b/include/extern.h index 1e290ae02..1b6cec7be 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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); diff --git a/src/dig.c b/src/dig.c index fc74204c3..e7659ecee 100644 --- 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) { diff --git a/src/dokick.c b/src/dokick.c index 52296f51d..969baf855 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -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] || diff --git a/src/fountain.c b/src/fountain.c index 69133de83..5bec5c4f0 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -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); diff --git a/src/hack.c b/src/hack.c index 136df1477..56a407ece 100644 --- a/src/hack.c +++ b/src/hack.c @@ -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; diff --git a/src/monmove.c b/src/monmove.c index 44595171c..3c30c64d0 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -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) &&