diff --git a/dat/quest.txt b/dat/quest.txt index 75face8f0..5f5aeeed2 100644 --- a/dat/quest.txt +++ b/dat/quest.txt @@ -2919,7 +2919,7 @@ But it is now likely that you can defeat %n, and recover "A short time ago, %n and his minions attacked this place. They opened the huge volcanic vents you %x about the hill, and attacked. I knew that this was to come to pass, and had asked %d for a group of %gP -to help defend this place. The few you %x here are the mightiest of +to help defend this place. The few you %x here are the mightiest of Valhalla's own, and are all that are left of one hundred %d sent. "Despite the great and glorious battle we fought, %n managed at diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 55cde42ad..ab3ee4870 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -81,6 +81,12 @@ succubus/incubus seduction might result in loss of levitation which in turn seduction was proceeding as if nothing unusual had happened #turn command which aggravated monsters did so without using a turn (not a pun) fix hole/trapdoor passage inconsistency when polymorphed into a giant +making a wide-open special level with FLAGS:inaccessibles could trigger a + "floodfill stack overrun" panic (no 3.6.x levels were affected) +wallifying a special level might go out of map bounds (not with 3.6.x levels) + and corrupt other level data +if a random grave produced during level creation included some gold, that gold + was left on the ground instead of being buried with other treasure Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/mklev.c b/src/mklev.c index 46d19ec66..dce0aa789 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1629,12 +1629,23 @@ struct mkroom *croom; return; } while (occupied(m.x, m.y) || bydoor(m.x, m.y)); - /* Put a grave at m.x, m.y */ + /* Put a grave at */ make_grave(m.x, m.y, dobell ? "Saved by the bell!" : (char *) 0); /* Possibly fill it with objects */ - if (!rn2(3)) - (void) mkgold(0L, m.x, m.y); + if (!rn2(3)) { + /* this used to use mkgold(), which puts a stack of gold on + the ground (or merges it with an existing one there if + present), and didn't bother burying it; now we create a + loose, easily buriable, stack but we make no attempt to + replicate mkgold()'s level-based formula for the amount */ + struct obj *gold = mksobj(GOLD_PIECE, TRUE, FALSE); + + gold->quan = (long) (rnd(20) + level_difficulty() * rnd(5)); + gold->owt = weight(gold); + gold->ox = m.x, gold->oy = m.y; + add_to_buried(gold); + } for (tryct = rn2(5); tryct; tryct--) { otmp = mkobj(RANDOM_CLASS, TRUE); if (!otmp) diff --git a/src/sp_lev.c b/src/sp_lev.c index 8db321709..d58743c53 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -126,6 +126,8 @@ STATIC_DCL int FDECL(selection_rndcoord, (struct opvar *, schar *, schar *, STATIC_DCL void FDECL(selection_do_grow, (struct opvar *, int)); STATIC_DCL int FDECL(floodfillchk_match_under, (int, int)); STATIC_DCL int FDECL(floodfillchk_match_accessible, (int, int)); +STATIC_DCL boolean FDECL(sel_flood_havepoint, (int, int, + xchar *, xchar *, int)); STATIC_DCL void FDECL(selection_do_ellipse, (struct opvar *, int, int, int, int, int)); STATIC_DCL long FDECL(line_dist_coord, (long, long, long, long, long, long)); @@ -2550,21 +2552,29 @@ region *tmpregion; } } +<<<<<<< HEAD /* initialization common to all special levels */ /* XXX dup name in mkmap.c */ void +======= +STATIC_OVL void +>>>>>>> NetHack-3.6.2 wallify_map(x1, y1, x2, y2) int x1, y1, x2, y2; { int x, y, xx, yy, lo_xx, lo_yy, hi_xx, hi_yy; + y1 = max(y1, 0); + x1 = max(x1, 1); + y2 = min(y2, ROWNO - 1); + x2 = min(x2, COLNO - 1); for (y = y1; y <= y2; y++) { lo_yy = (y > 0) ? y - 1 : 0; hi_yy = (y < y2) ? y + 1 : y2; for (x = x1; x <= x2; x++) { if (levl[x][y].typ != STONE) continue; - lo_xx = (x > 0) ? x - 1 : 0; + lo_xx = (x > 1) ? x - 1 : 1; hi_xx = (x < x2) ? x + 1 : x2; for (yy = lo_yy; yy <= hi_yy; yy++) for (xx = lo_xx; xx <= hi_xx; xx++) @@ -3901,6 +3911,23 @@ int x, y; || levl[x][y].typ == SCORR); } +/* check whethere is already in xs[],ys[] */ +STATIC_OVL boolean +sel_flood_havepoint(x, y, xs, ys, n) +int x, y; +xchar xs[], ys[]; +int n; +{ + xchar xx = (xchar) x, yy = (xchar) y; + + while (n > 0) { + if (xs[n] == xx && ys[n] == yy) + return TRUE; + --n; + } + return FALSE; +} + void selection_floodfill(ov, x, y, diagonals) struct opvar *ov; @@ -3910,7 +3937,7 @@ boolean diagonals; static const char nhFunc[] = "selection_floodfill"; struct opvar *tmp = selection_opvar((char *) 0); #define SEL_FLOOD_STACK (COLNO * ROWNO) -#define SEL_FLOOD(nx, ny) \ +#define SEL_FLOOD(nx, ny) \ do { \ if (idx < SEL_FLOOD_STACK) { \ dx[idx] = (nx); \ @@ -3919,17 +3946,20 @@ boolean diagonals; } else \ panic(floodfill_stack_overrun); \ } while (0) -#define SEL_FLOOD_CHKDIR(mx,my,sel) \ - if (isok((mx), (my)) \ - && (*selection_flood_check_func)((mx), (my)) \ - && !selection_getpoint((mx), (my), (sel))) \ - SEL_FLOOD((mx), (my)) +#define SEL_FLOOD_CHKDIR(mx, my, sel) \ + do { \ + if (isok((mx), (my)) \ + && (*selection_flood_check_func)((mx), (my)) \ + && !selection_getpoint((mx), (my), (sel)) \ + && !sel_flood_havepoint((mx), (my), dx, dy, idx)) \ + SEL_FLOOD((mx), (my)); \ + } while (0) static const char floodfill_stack_overrun[] = "floodfill stack overrun"; int idx = 0; xchar dx[SEL_FLOOD_STACK]; xchar dy[SEL_FLOOD_STACK]; - if (selection_flood_check_func == NULL) { + if (selection_flood_check_func == (int FDECL((*), (int, int))) 0) { opvar_free(tmp); return; } diff --git a/sys/mac/Install.mw b/sys/mac/Install.mw index ad8e95017..f6cc4eab7 100644 --- a/sys/mac/Install.mw +++ b/sys/mac/Install.mw @@ -1,7 +1,7 @@ Building a PPC NetHack 3.6 with the Metrowerks compilers Note: If you are building using any compiler for OS X, use the instructions - in sys/unix. These are old instructions for 68k builds. + in sys/unix. This file contains old instructions that predated OS X. You must be familiar with the Metrowerks compiler and know how to construct projects. The NetHack source may come with the four pre-made projects that