minetown guards outside the town proper

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.
This commit is contained in:
cohrs
2002-07-15 04:17:13 +00:00
parent b440613866
commit a21ddbb2bf
7 changed files with 34 additions and 13 deletions

View 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

View 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);

View File

@@ -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) {

View 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] ||

View 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);

View 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;

View 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) &&