Remove the per dungeon level door limit

Number of doors in a room-and-corridor style level was fixed
at 120; now the doors-array is dynamically allocated when needed.

Breaks saves and bones.
This commit is contained in:
Pasi Kallinen
2022-09-09 12:58:45 +03:00
parent c6a8519fec
commit a733004912
10 changed files with 85 additions and 62 deletions

View File

@@ -2107,4 +2107,5 @@ for Planes of Water and Air, save the air bubbles and clouds with the level
switch to a flags arg on newcham() in place of the pair of boolean args
replace some old 'time_t' hackery in system.h and hacklib.c with something
less obtrusive in unixconf.h
remove the per dungeon level door limit

View File

@@ -817,7 +817,8 @@ struct instance_globals {
char toplines[TBUFSZ];
coord bhitpos; /* place where throw or zap hits or stops */
boolean in_steed_dismounting;
coord doors[DOORMAX];
int doors_alloc; /* doors-array allocated size */
coord *doors; /* array of door locations */
struct menucoloring *menu_colorings;
schar lastseentyp[COLNO][ROWNO]; /* last seen/touched dungeon typ */
struct spell spl_book[MAXSPELL + 1];

View File

@@ -400,7 +400,7 @@ extern struct nomakedefs_s nomakedefs;
#define MAXNROFROOMS 40 /* max number of rooms per level */
#define MAX_SUBROOMS 24 /* max # of subrooms in a given room */
#define DOORMAX 120 /* max number of doors per level */
#define DOORINC 120 /* number of doors per level, increment */
#define BUFSZ 256 /* for getlin buffers */
#define QBUFSZ 128 /* for building question text */

View File

@@ -16,7 +16,7 @@ struct mkroom {
schar needfill; /* sp_lev: does the room need filling? */
boolean needjoining; /* sp_lev: should the room connect to others? */
schar doorct; /* door count */
schar fdoor; /* index for the first door of the room */
int fdoor; /* index for the first door of the room */
schar nsubrooms; /* number of subrooms */
boolean irregular; /* true if room is non-rectangular */
schar roomnoidx;

View File

@@ -17,7 +17,7 @@
* Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files.
*/
#define EDITLEVEL 62
#define EDITLEVEL 63
/*
* Development status possibilities.

View File

@@ -286,7 +286,8 @@ const struct instance_globals g_init = {
UNDEFINED_VALUES, /* toplines */
{ 0, 0 }, /* bhitpos */
FALSE, /* in_steed_dismounting */
{ { 0, 0 } }, /* doors */
0, /* doors_alloc */
NULL, /* doors */
UNDEFINED_PTR, /* menu_colorings */
{ { 0 } }, /* lastseentyp */
{ DUMMY }, /* spl_book */

View File

@@ -30,6 +30,7 @@ static void make_niches(void);
static int QSORTCALLBACK mkroom_cmp(const genericptr, const genericptr);
static void dosdoor(coordxy, coordxy, struct mkroom *, int);
static void join(int, int, boolean);
static void alloc_doors(void);
static void do_room_or_subroom(struct mkroom *,
coordxy, coordxy, coordxy, coordxy,
boolean, schar, boolean, boolean);
@@ -343,7 +344,7 @@ join(register int a, register int b, boolean nxcor)
/* find positions cc and tt for doors in croom and troom
and direction for a corridor between them */
if (troom->hx < 0 || croom->hx < 0 || g.doorindex >= DOORMAX)
if (troom->hx < 0 || croom->hx < 0)
return;
if (troom->lx > croom->hx) {
dx = 1;
@@ -442,6 +443,22 @@ makecorridors(void)
}
}
/* (re)allocate space for g.doors array */
static void
alloc_doors(void)
{
if (!g.doors || g.doorindex >= g.doors_alloc) {
int c = g.doors_alloc + DOORINC;
coord *doortmp = (coord *) alloc(c * sizeof(coord));
if (g.doors) {
(void) memcpy(doortmp, g.doors, g.doors_alloc * sizeof(coord));
free(g.doors);
}
g.doors = doortmp;
g.doors_alloc = c;
}
}
void
add_door(coordxy x, coordxy y, register struct mkroom *aroom)
{
@@ -449,6 +466,8 @@ add_door(coordxy x, coordxy y, register struct mkroom *aroom)
register int tmp;
int i;
alloc_doors();
if (aroom->doorct) {
for (i = 0; i < aroom->doorct; i++) {
tmp = aroom->fdoor + i;
@@ -589,58 +608,56 @@ makeniche(int trap_type)
coordxy dy, xx, yy;
struct trap *ttmp;
if (g.doorindex < DOORMAX) {
while (vct--) {
aroom = &g.rooms[rn2(g.nroom)];
if (aroom->rtype != OROOM)
continue; /* not an ordinary room */
if (aroom->doorct == 1 && rn2(5))
continue;
if (!place_niche(aroom, &dy, &xx, &yy))
continue;
while (vct--) {
aroom = &g.rooms[rn2(g.nroom)];
if (aroom->rtype != OROOM)
continue; /* not an ordinary room */
if (aroom->doorct == 1 && rn2(5))
continue;
if (!place_niche(aroom, &dy, &xx, &yy))
continue;
rm = &levl[xx][yy + dy];
if (trap_type || !rn2(4)) {
rm->typ = SCORR;
if (trap_type) {
if (is_hole(trap_type) && !Can_fall_thru(&u.uz))
trap_type = ROCKTRAP;
ttmp = maketrap(xx, yy + dy, trap_type);
if (ttmp) {
if (trap_type != ROCKTRAP)
ttmp->once = 1;
if (trap_engravings[trap_type]) {
make_engr_at(xx, yy - dy,
trap_engravings[trap_type], 0L,
DUST);
wipe_engr_at(xx, yy - dy, 5,
FALSE); /* age it a little */
}
rm = &levl[xx][yy + dy];
if (trap_type || !rn2(4)) {
rm->typ = SCORR;
if (trap_type) {
if (is_hole(trap_type) && !Can_fall_thru(&u.uz))
trap_type = ROCKTRAP;
ttmp = maketrap(xx, yy + dy, trap_type);
if (ttmp) {
if (trap_type != ROCKTRAP)
ttmp->once = 1;
if (trap_engravings[trap_type]) {
make_engr_at(xx, yy - dy,
trap_engravings[trap_type], 0L,
DUST);
wipe_engr_at(xx, yy - dy, 5,
FALSE); /* age it a little */
}
}
dosdoor(xx, yy, aroom, SDOOR);
} else {
rm->typ = CORR;
if (rn2(7))
dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
else {
/* inaccessible niches occasionally have iron bars */
if (!rn2(5) && IS_WALL(levl[xx][yy].typ)) {
(void) set_levltyp(xx, yy, IRONBARS);
if (rn2(3))
(void) mkcorpstat(CORPSE, (struct monst *) 0,
mkclass(S_HUMAN, 0), xx,
yy + dy, TRUE);
}
if (!g.level.flags.noteleport)
(void) mksobj_at(SCR_TELEPORTATION, xx, yy + dy, TRUE,
FALSE);
if (!rn2(3))
(void) mkobj_at(RANDOM_CLASS, xx, yy + dy, TRUE);
}
}
return;
dosdoor(xx, yy, aroom, SDOOR);
} else {
rm->typ = CORR;
if (rn2(7))
dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
else {
/* inaccessible niches occasionally have iron bars */
if (!rn2(5) && IS_WALL(levl[xx][yy].typ)) {
(void) set_levltyp(xx, yy, IRONBARS);
if (rn2(3))
(void) mkcorpstat(CORPSE, (struct monst *) 0,
mkclass(S_HUMAN, 0), xx,
yy + dy, TRUE);
}
if (!g.level.flags.noteleport)
(void) mksobj_at(SCR_TELEPORTATION, xx, yy + dy, TRUE,
FALSE);
if (!rn2(3))
(void) mkobj_at(RANDOM_CLASS, xx, yy + dy, TRUE);
}
}
return;
}
}
@@ -728,6 +745,9 @@ clear_level_structures(void)
g.nsubroom = 0;
g.subrooms[0].hx = -1;
g.doorindex = 0;
g.doors_alloc = 0;
free(g.doors);
g.doors = (coord *) 0;
init_rect();
init_vault();
stairway_free_all();
@@ -1334,17 +1354,12 @@ okdoor(coordxy x, coordxy y)
|| (isok(x + 1, y) && !IS_ROCK(levl[x + 1][y].typ))
|| (isok(x, y - 1) && !IS_ROCK(levl[x][y - 1].typ))
|| (isok(x, y + 1) && !IS_ROCK(levl[x][y + 1].typ)))
&& g.doorindex < DOORMAX && !near_door);
&& !near_door);
}
void
dodoor(coordxy x, coordxy y, struct mkroom *aroom)
{
if (g.doorindex >= DOORMAX) {
impossible("DOORMAX exceeded?");
return;
}
dosdoor(x, y, aroom, rn2(8) ? DOOR : SDOOR);
}

View File

@@ -1068,7 +1068,11 @@ getlev(NHFILE* nhfp, int pid, xint8 lev)
mread(nhfp->fd, (genericptr_t)&g.updest, sizeof(dest_area));
mread(nhfp->fd, (genericptr_t)&g.dndest, sizeof(dest_area));
mread(nhfp->fd, (genericptr_t)&g.level.flags, sizeof(g.level.flags));
mread(nhfp->fd, (genericptr_t)g.doors, sizeof(g.doors));
if (g.doors)
free(g.doors);
mread(nhfp->fd, (genericptr_t) &g.doors_alloc, sizeof (g.doors_alloc));
g.doors = (coord *) alloc(g.doors_alloc * sizeof (coord));
mread(nhfp->fd, (genericptr_t) g.doors, g.doors_alloc * sizeof (coord));
}
rest_rooms(nhfp); /* No joke :-) */
if (g.nroom)

View File

@@ -539,7 +539,8 @@ savelev_core(NHFILE *nhfp, xint8 lev)
bwrite(nhfp->fd, (genericptr_t) &g.updest, sizeof (dest_area));
bwrite(nhfp->fd, (genericptr_t) &g.dndest, sizeof (dest_area));
bwrite(nhfp->fd, (genericptr_t) &g.level.flags, sizeof g.level.flags);
bwrite(nhfp->fd, (genericptr_t) g.doors, sizeof g.doors);
bwrite(nhfp->fd, (genericptr_t) &g.doors_alloc, sizeof g.doors_alloc);
bwrite(nhfp->fd, (genericptr_t) g.doors, g.doors_alloc * sizeof (coord));
}
save_rooms(nhfp); /* no dynamic memory to reclaim */

View File

@@ -1071,7 +1071,7 @@ shared_with_room(int x, int y, struct mkroom *droom)
static void
maybe_add_door(int x, int y, struct mkroom* droom)
{
if (droom->hx >= 0 && g.doorindex < DOORMAX
if (droom->hx >= 0
&& ((!droom->irregular && inside_room(droom, x, y))
|| (int) levl[x][y].roomno == (droom - g.rooms) + ROOMOFFSET
|| shared_with_room(x, y, droom))) {