From e2dd0a12ae0ac734a5776324d0e0eec1fbbb5542 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Sun, 29 Jan 2006 04:32:04 +0000 Subject: [PATCH] fix #H30 - rn2(0) from off by 1 bug in special level door creation From a bug report, the placement of random doors by the code that loads special levels would attempt to evaluate rn2(0) and either get a divide by zero crash (normal build) or an impossible warning (DEBUG enabled when compiing rnd.c, done automatically when BETA is defined). The problem was only noticable for random door in a 1x1 room; none of our distributed levels specify such a thing so regular users won't have encountered this bug. It's a one line fix. Altar placement in temples also had a quirk of a similar nature. It wouldn't trigger rn2(0) problems but would always place the altar to left of mid-point in rooms with even width and above the center point in ones with even height. Now the placement is randomized so that sometimes it'll be to the right and/or below mid-point in such cases. This also simplifies a couple other instances of similar expressions that I spotted. --- doc/fixes34.4 | 2 ++ src/mklev.c | 6 +++--- src/mkroom.c | 20 ++++++++++++++------ src/sp_lev.c | 5 +++-- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/doc/fixes34.4 b/doc/fixes34.4 index 734a84ee1..f6844d6bd 100644 --- a/doc/fixes34.4 +++ b/doc/fixes34.4 @@ -181,6 +181,8 @@ only count successful statue creations against the monster limit in sp_lev.c unseen wand of striking zapped by unseen monster became known if it hit a door tweak knight quest messages guidebook grammar bits +special level loader wasn't able to place random door in 1x1 room; could + trigger divide-by-0 crash for user-developed custom levels Platform- and/or Interface-Specific Fixes diff --git a/src/mklev.c b/src/mklev.c index b21dae88a..dcc87a307 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)mklev.c 3.5 2001/11/29 */ +/* SCCS Id: @(#)mklev.c 3.5 2006/01/28 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -83,8 +83,8 @@ xchar xl,yl,xh,yh; { register xchar x, y; - x = (xl == xh) ? xl : (xl + rn2(xh-xl+1)); - y = (yl == yh) ? yl : (yl + rn2(yh-yl+1)); + x = rn1(xh - xl + 1, xl); + y = rn1(yh - yl + 1, yl); if(okdoor(x, y)) goto gotit; diff --git a/src/mkroom.c b/src/mkroom.c index 8683611be..1c1946bd6 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)mkroom.c 3.5 2005/03/12 */ +/* SCCS Id: @(#)mkroom.c 3.5 2006/01/28 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -483,11 +483,19 @@ shrine_pos(roomno) int roomno; { static coord buf; + int delta; struct mkroom *troom = &rooms[roomno - ROOMOFFSET]; - buf.x = troom->lx + ((troom->hx - troom->lx) / 2); - buf.y = troom->ly + ((troom->hy - troom->ly) / 2); - return(&buf); + /* if width and height are odd, placement will be the exact center; + if either or both are even, center point is a hypothetical spot + between map locations and placement will be adjacent to that */ + delta = troom->hx - troom->lx; + buf.x = troom->lx + delta / 2; + if ((delta % 2) && rn2(2)) buf.x++; + delta = troom->hy - troom->ly; + buf.y = troom->ly + delta / 2; + if ((delta % 2) && rn2(2)) buf.y++; + return &buf; } STATIC_OVL void @@ -555,14 +563,14 @@ int somex(croom) register struct mkroom *croom; { - return rn2(croom->hx-croom->lx+1) + croom->lx; + return rn1(croom->hx - croom->lx + 1, croom->lx); } int somey(croom) register struct mkroom *croom; { - return rn2(croom->hy-croom->ly+1) + croom->ly; + return rn1(croom->hy - croom->ly + 1, croom->ly); } boolean diff --git a/src/sp_lev.c b/src/sp_lev.c index 98e8a476d..34194b80e 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)sp_lev.c 3.5 2006/01/02 */ +/* SCCS Id: @(#)sp_lev.c 3.5 2006/01/28 */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -620,7 +620,8 @@ struct mkroom *broom; dpos = dd->pos; if (dpos == -1) /* The position is RANDOM */ dpos = rn2((dwall == W_WEST || dwall == W_EAST) ? - (broom->hy - broom->ly) : (broom->hx - broom->lx)); + (broom->hy - broom->ly + 1) : + (broom->hx - broom->lx + 1)); /* Convert wall and pos into an absolute coordinate! */ -- 2.40.0