Shaped and themed rooms
Allows creating shaped or themed rooms for the Dungeons of Doom via lua script. Invalidates bones and saves. Makefiles updated for unix/linux by adding themerms.lua, but other OSes need to have that added.
This commit is contained in:
@@ -638,6 +638,8 @@ const struct instance_globals g_init = {
|
||||
UNDEFINED_VALUE, /* ystart */
|
||||
UNDEFINED_VALUE, /* xsize */
|
||||
UNDEFINED_VALUE, /* ysize */
|
||||
FALSE, /* in_mk_themerooms */
|
||||
FALSE, /* themeroom_failed */
|
||||
|
||||
/* spells.c */
|
||||
0, /* spl_sortmode */
|
||||
|
||||
@@ -842,6 +842,7 @@ init_dungeons()
|
||||
i = 0;
|
||||
while (lua_next(L, tidx) != 0) {
|
||||
char *dgn_name, *dgn_bonetag, *dgn_protoname, *dgn_fill;
|
||||
char *dgn_themerms;
|
||||
int dgn_base, dgn_range, dgn_align, dgn_entry, dgn_chance, dgn_flags;
|
||||
|
||||
if (!lua_istable(L, -1))
|
||||
@@ -858,6 +859,7 @@ init_dungeons()
|
||||
dgn_chance = get_table_int_opt(L, "chance", 100);
|
||||
dgn_flags = get_dgn_flags(L);
|
||||
dgn_fill = get_table_str_opt(L, "lvlfill", emptystr);
|
||||
dgn_themerms = get_table_str_opt(L, "themerooms", emptystr);
|
||||
|
||||
debugpline4("DUNGEON[%i]: %s, base=(%i,%i)",
|
||||
i, dgn_name, dgn_base, dgn_range);
|
||||
@@ -870,6 +872,7 @@ init_dungeons()
|
||||
free((genericptr_t) dgn_bonetag);
|
||||
free((genericptr_t) dgn_protoname);
|
||||
free((genericptr_t) dgn_fill);
|
||||
free((genericptr_t) dgn_themerms);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1023,10 +1026,13 @@ init_dungeons()
|
||||
Strcpy(g.dungeons[i].fill_lvl, dgn_fill); /* FIXME: fill_lvl len */
|
||||
Strcpy(g.dungeons[i].dname, dgn_name); /* FIXME: dname length */
|
||||
Strcpy(g.dungeons[i].proto, dgn_protoname); /* FIXME: proto length */
|
||||
Strcpy(g.dungeons[i].themerms, dgn_themerms); /* FIXME: length */
|
||||
g.dungeons[i].themelua = (lua_State *) 0;
|
||||
g.dungeons[i].boneid = *dgn_bonetag ? *dgn_bonetag : 0;
|
||||
free((genericptr) dgn_fill);
|
||||
/* free((genericptr) dgn_protoname); -- stored in pd.tmpdungeon[] */
|
||||
free((genericptr) dgn_bonetag);
|
||||
free((genericptr) dgn_themerms);
|
||||
|
||||
if (dgn_range)
|
||||
g.dungeons[i].num_dunlevs = (xchar) rn1(dgn_range, dgn_base);
|
||||
|
||||
213
src/mklev.c
213
src/mklev.c
@@ -9,6 +9,9 @@
|
||||
/* croom->lx etc are schar (width <= int), so % arith ensures that */
|
||||
/* conversion of result to int is reasonable */
|
||||
|
||||
static boolean FDECL(generate_stairs_room_good, (struct mkroom *, int));
|
||||
static struct mkroom *NDECL(generate_stairs_find_room);
|
||||
static void NDECL(generate_stairs);
|
||||
static void FDECL(mkfount, (int, struct mkroom *));
|
||||
static boolean FDECL(find_okay_roompos, (struct mkroom *, coord *));
|
||||
static void FDECL(mksink, (struct mkroom *));
|
||||
@@ -94,9 +97,14 @@ xchar xl, yl, xh, yh;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Sort rooms on the level so they're ordered from left to right on the map.
|
||||
makecorridors() by default links rooms N and N+1 */
|
||||
void
|
||||
sort_rooms()
|
||||
{
|
||||
int i, x, y;
|
||||
int ri[MAXNROFROOMS+1];
|
||||
|
||||
#if defined(SYSV) || defined(DGUX)
|
||||
#define CAST_nroom (unsigned) g.nroom
|
||||
#else
|
||||
@@ -104,6 +112,17 @@ sort_rooms()
|
||||
#endif
|
||||
qsort((genericptr_t) g.rooms, CAST_nroom, sizeof (struct mkroom), do_comp);
|
||||
#undef CAST_nroom
|
||||
|
||||
/* Update the roomnos on the map */
|
||||
for (i = 0; i < g.nroom; i++)
|
||||
ri[g.rooms[i].roomnoidx] = i;
|
||||
|
||||
for (x = 1; x < COLNO; x++)
|
||||
for (y = 0; y < ROWNO; y++) {
|
||||
int rno = levl[x][y].roomno;
|
||||
if (rno >= ROOMOFFSET && rno < MAXNROFROOMS+1)
|
||||
levl[x][y].roomno = ri[rno - ROOMOFFSET] + ROOMOFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -140,6 +159,7 @@ boolean is_room;
|
||||
} else
|
||||
croom->rlit = 0;
|
||||
|
||||
croom->roomnoidx = (croom - g.rooms);
|
||||
croom->lx = lowx;
|
||||
croom->hx = hix;
|
||||
croom->ly = lowy;
|
||||
@@ -156,6 +176,7 @@ boolean is_room;
|
||||
croom->nsubrooms = 0;
|
||||
croom->sbrooms[0] = (struct mkroom *) 0;
|
||||
if (!special) {
|
||||
croom->needjoining = TRUE;
|
||||
for (x = lowx - 1; x <= hix + 1; x++)
|
||||
for (y = lowy - 1; y <= hiy + 1; y += (hiy - lowy + 2)) {
|
||||
levl[x][y].typ = HWALL;
|
||||
@@ -222,6 +243,27 @@ static void
|
||||
makerooms()
|
||||
{
|
||||
boolean tried_vault = FALSE;
|
||||
int themeroom_tries = 0;
|
||||
boolean dothemes = (g.dungeons[u.uz.dnum].themelua != NULL);
|
||||
char *fname = g.dungeons[u.uz.dnum].themerms;
|
||||
|
||||
if (*fname && !g.dungeons[u.uz.dnum].themelua) {
|
||||
g.dungeons[u.uz.dnum].themelua = nhl_init();
|
||||
if (g.dungeons[u.uz.dnum].themelua) {
|
||||
if (!nhl_loadlua(g.dungeons[u.uz.dnum].themelua, fname)) {
|
||||
/* loading lua failed, don't use themed rooms */
|
||||
g.dungeons[u.uz.dnum].themerms[0] = '\0';
|
||||
lua_close(g.dungeons[u.uz.dnum].themelua);
|
||||
g.dungeons[u.uz.dnum].themelua = NULL;
|
||||
} else {
|
||||
dothemes = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dothemes) {
|
||||
create_des_coder();
|
||||
}
|
||||
|
||||
/* make rooms until satisfied */
|
||||
/* rnd_rect() will returns 0 if no more rects are available... */
|
||||
@@ -233,10 +275,26 @@ makerooms()
|
||||
g.vault_y = g.rooms[g.nroom].ly;
|
||||
g.rooms[g.nroom].hx = -1;
|
||||
}
|
||||
} else if (!create_room(-1, -1, -1, -1, -1, -1, OROOM, -1))
|
||||
return;
|
||||
} else {
|
||||
if (dothemes) {
|
||||
g.in_mk_themerooms = TRUE;
|
||||
g.themeroom_failed = FALSE;
|
||||
lua_getglobal(g.dungeons[u.uz.dnum].themelua, "themerooms_generate");
|
||||
lua_call(g.dungeons[u.uz.dnum].themelua, 0, 0);
|
||||
g.in_mk_themerooms = FALSE;
|
||||
if (g.themeroom_failed && ((themeroom_tries++ > 10) || (g.nroom >= (MAXNROFROOMS / 6))))
|
||||
break;
|
||||
} else {
|
||||
if (!create_room(-1, -1, -1, -1, -1, -1, OROOM, -1))
|
||||
break;;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dothemes) {
|
||||
wallification(1, 0, COLNO - 1, ROWNO - 1);
|
||||
free(g.coder);
|
||||
g.coder = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -252,6 +310,9 @@ boolean nxcor;
|
||||
croom = &g.rooms[a];
|
||||
troom = &g.rooms[b];
|
||||
|
||||
if (!croom->needjoining || !troom->needjoining)
|
||||
return;
|
||||
|
||||
/* find positions cc and tt for doors in croom and troom
|
||||
and direction for a corridor between them */
|
||||
|
||||
@@ -711,25 +772,7 @@ makelevel()
|
||||
makerooms();
|
||||
sort_rooms();
|
||||
|
||||
/* construct stairs (up and down in different rooms if possible) */
|
||||
croom = &g.rooms[rn2(g.nroom)];
|
||||
if (!Is_botlevel(&u.uz))
|
||||
mkstairs(somex(croom), somey(croom), 0, croom); /* down */
|
||||
if (g.nroom > 1) {
|
||||
troom = croom;
|
||||
croom = &g.rooms[rn2(g.nroom - 1)];
|
||||
if (croom == troom)
|
||||
croom++;
|
||||
}
|
||||
|
||||
if (u.uz.dlevel != 1) {
|
||||
xchar sx, sy;
|
||||
do {
|
||||
sx = somex(croom);
|
||||
sy = somey(croom);
|
||||
} while (occupied(sx, sy));
|
||||
mkstairs(sx, sy, 1, croom); /* up */
|
||||
}
|
||||
generate_stairs(); /* up and down stairs */
|
||||
|
||||
branchp = Is_branchlev(&u.uz); /* possible dungeon branch */
|
||||
room_threshold = branchp ? 4 : 3; /* minimum number of rooms needed
|
||||
@@ -807,7 +850,10 @@ makelevel()
|
||||
/* for each room: put things inside */
|
||||
for (croom = g.rooms; croom->hx > 0; croom++) {
|
||||
int trycnt = 0;
|
||||
if (croom->rtype != OROOM)
|
||||
coord pos;
|
||||
if (croom->rtype != OROOM && croom->rtype != THEMEROOM)
|
||||
continue;
|
||||
if (!croom->needfill)
|
||||
continue;
|
||||
|
||||
/* put a sleeping monster inside */
|
||||
@@ -816,13 +862,11 @@ makelevel()
|
||||
while a monster was on the stairs. Conclusion:
|
||||
we have to check for monsters on the stairs anyway. */
|
||||
|
||||
if (u.uhave.amulet || !rn2(3)) {
|
||||
x = somex(croom);
|
||||
y = somey(croom);
|
||||
tmonst = makemon((struct permonst *) 0, x, y, MM_NOGRP);
|
||||
if ((u.uhave.amulet || !rn2(3)) && somexyspace(croom, &pos)) {
|
||||
tmonst = makemon((struct permonst *) 0, pos.x, pos.y, MM_NOGRP);
|
||||
if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER]
|
||||
&& !occupied(x, y))
|
||||
(void) maketrap(x, y, WEB);
|
||||
&& !occupied(pos.x, pos.y))
|
||||
(void) maketrap(pos.x, pos.y, WEB);
|
||||
}
|
||||
/* put traps and mimics inside */
|
||||
x = 8 - (level_difficulty() / 6);
|
||||
@@ -830,8 +874,8 @@ makelevel()
|
||||
x = 2;
|
||||
while (!rn2(x) && (++trycnt < 1000))
|
||||
mktrap(0, 0, croom, (coord *) 0);
|
||||
if (!rn2(3))
|
||||
(void) mkgold(0L, somex(croom), somey(croom));
|
||||
if (!rn2(3) && somexyspace(croom, &pos))
|
||||
(void) mkgold(0L, pos.x, pos.y);
|
||||
if (Is_rogue_level(&u.uz))
|
||||
goto skip_nonrogue;
|
||||
if (!rn2(10))
|
||||
@@ -847,18 +891,18 @@ makelevel()
|
||||
mkgrave(croom);
|
||||
|
||||
/* put statues inside */
|
||||
if (!rn2(20))
|
||||
if (!rn2(20) && somexyspace(croom, &pos))
|
||||
(void) mkcorpstat(STATUE, (struct monst *) 0,
|
||||
(struct permonst *) 0, somex(croom),
|
||||
somey(croom), CORPSTAT_INIT);
|
||||
(struct permonst *) 0, pos.x,
|
||||
pos.y, CORPSTAT_INIT);
|
||||
/* put box/chest inside;
|
||||
* 40% chance for at least 1 box, regardless of number
|
||||
* of rooms; about 5 - 7.5% for 2 boxes, least likely
|
||||
* when few rooms; chance for 3 or more is negligible.
|
||||
*/
|
||||
if (!rn2(g.nroom * 5 / 2))
|
||||
(void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, somex(croom),
|
||||
somey(croom), TRUE, FALSE);
|
||||
if (!rn2(g.nroom * 5 / 2) && somexyspace(croom, &pos))
|
||||
(void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
|
||||
pos.x, pos.y, TRUE, FALSE);
|
||||
|
||||
/* maybe make some graffiti */
|
||||
if (!rn2(27 + 3 * abs(depth(&u.uz)))) {
|
||||
@@ -867,8 +911,9 @@ makelevel()
|
||||
|
||||
if (mesg) {
|
||||
do {
|
||||
x = somex(croom);
|
||||
y = somey(croom);
|
||||
somexyspace(croom, &pos);
|
||||
x = pos.x;
|
||||
y = pos.y;
|
||||
} while (levl[x][y].typ != ROOM && !rn2(40));
|
||||
if (!(IS_POOL(levl[x][y].typ)
|
||||
|| IS_FURNITURE(levl[x][y].typ)))
|
||||
@@ -877,15 +922,15 @@ makelevel()
|
||||
}
|
||||
|
||||
skip_nonrogue:
|
||||
if (!rn2(3)) {
|
||||
(void) mkobj_at(0, somex(croom), somey(croom), TRUE);
|
||||
if (!rn2(3) && somexyspace(croom, &pos)) {
|
||||
(void) mkobj_at(0, pos.x, pos.y, TRUE);
|
||||
tryct = 0;
|
||||
while (!rn2(5)) {
|
||||
if (++tryct > 100) {
|
||||
impossible("tryct overflow4");
|
||||
break;
|
||||
}
|
||||
(void) mkobj_at(0, somex(croom), somey(croom), TRUE);
|
||||
(void) mkobj_at(0, pos.x, pos.y, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1124,7 +1169,7 @@ coord *mp;
|
||||
do
|
||||
croom = &g.rooms[rn2(g.nroom)];
|
||||
while ((croom == g.dnstairs_room || croom == g.upstairs_room
|
||||
|| croom->rtype != OROOM) && (++tryct < 100));
|
||||
|| (croom->rtype != OROOM && croom->rtype != THEMEROOM)) && (++tryct < 100));
|
||||
} else
|
||||
croom = &g.rooms[rn2(g.nroom)];
|
||||
|
||||
@@ -1133,6 +1178,7 @@ coord *mp;
|
||||
impossible("Can't place branch!");
|
||||
} while ((occupied(mp->x, mp->y)
|
||||
|| (levl[mp->x][mp->y].typ != CORR
|
||||
&& levl[mp->x][mp->y].typ != ICE
|
||||
&& levl[mp->x][mp->y].typ != ROOM)) && (++cnt < 1000));
|
||||
}
|
||||
return croom;
|
||||
@@ -1250,6 +1296,10 @@ xchar x, y;
|
||||
boolean near_door = bydoor(x, y);
|
||||
|
||||
return ((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL)
|
||||
&& (isok(x-1,y) && !IS_ROCK(levl[x-1][y].typ)
|
||||
|| 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);
|
||||
}
|
||||
|
||||
@@ -1574,6 +1624,83 @@ struct mkroom *croom;
|
||||
levl[x][y].ladder = up ? LA_UP : LA_DOWN;
|
||||
}
|
||||
|
||||
/* is room a good one to generate up or down stairs in? */
|
||||
/* phase values, smaller allows for more relaxed criteria:
|
||||
2 == no relaxed criteria
|
||||
1 == allow a themed room
|
||||
0 == allow same room as existing up/downstairs
|
||||
-1 == allow an unjoined room
|
||||
*/
|
||||
static boolean
|
||||
generate_stairs_room_good(croom, phase)
|
||||
struct mkroom *croom;
|
||||
int phase;
|
||||
{
|
||||
return (croom && (croom->needjoining || (phase < 0))
|
||||
&& ((croom != g.dnstairs_room && croom != g.upstairs_room)
|
||||
|| phase < 1)
|
||||
&& (croom->rtype == OROOM
|
||||
|| ((phase < 2) || croom->rtype == THEMEROOM)));
|
||||
}
|
||||
|
||||
/* find a good room to generate an up or down stairs in */
|
||||
static struct mkroom *
|
||||
generate_stairs_find_room()
|
||||
{
|
||||
struct mkroom *croom;
|
||||
int i, phase, tryct = 0;
|
||||
|
||||
if (!g.nroom)
|
||||
return (struct mkroom *) 0;
|
||||
|
||||
for (phase = 2; phase > -1; phase--) {
|
||||
do {
|
||||
croom = &g.rooms[rn2(g.nroom)];
|
||||
} while (!generate_stairs_room_good(croom, phase) && (tryct++ < 50));
|
||||
if (tryct < 50)
|
||||
return croom;
|
||||
}
|
||||
|
||||
for (phase = 2; phase > -2; phase--) {
|
||||
for (i = 0; i < g.nroom; i++) {
|
||||
croom = &g.rooms[i];
|
||||
if (generate_stairs_room_good(croom, phase))
|
||||
return croom;
|
||||
}
|
||||
}
|
||||
|
||||
croom = &g.rooms[rn2(g.nroom)];
|
||||
return croom;
|
||||
}
|
||||
|
||||
/* construct stairs up and down within the same branch,
|
||||
up and down in different rooms if possible */
|
||||
static void
|
||||
generate_stairs()
|
||||
{
|
||||
struct mkroom *croom = generate_stairs_find_room();
|
||||
coord pos;
|
||||
|
||||
if (!Is_botlevel(&u.uz)) {
|
||||
if (!somexyspace(croom, &pos)) {
|
||||
pos.x = somex(croom);
|
||||
pos.y = somey(croom);
|
||||
}
|
||||
mkstairs(pos.x, pos.y, 0, croom); /* down */
|
||||
}
|
||||
|
||||
if (g.nroom > 1)
|
||||
croom = generate_stairs_find_room();
|
||||
|
||||
if (u.uz.dlevel != 1) {
|
||||
if (!somexyspace(croom, &pos)) {
|
||||
pos.x = somex(croom);
|
||||
pos.y = somey(croom);
|
||||
}
|
||||
mkstairs(pos.x, pos.y, 1, croom); /* up */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mkfount(mazeflag, croom)
|
||||
int mazeflag;
|
||||
|
||||
@@ -996,6 +996,7 @@ const char *s;
|
||||
if (*protofile) {
|
||||
check_ransacked(protofile);
|
||||
Strcat(protofile, LEV_EXT);
|
||||
g.in_mk_themerooms = FALSE;
|
||||
if (load_special(protofile)) {
|
||||
/* some levels can end up with monsters
|
||||
on dead mon list, including light source monsters */
|
||||
|
||||
17
src/mkroom.c
17
src/mkroom.c
@@ -713,6 +713,23 @@ coord *c;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean
|
||||
somexyspace(croom, c)
|
||||
struct mkroom *croom;
|
||||
coord *c;
|
||||
{
|
||||
int trycnt = 0;
|
||||
boolean okay;
|
||||
|
||||
do {
|
||||
okay = somexy(croom, c) && isok(c->x, c->y) && !occupied(c->x, c->y)
|
||||
&& (levl[c->x][c->y].typ == ROOM
|
||||
|| levl[c->x][c->y].typ == CORR
|
||||
|| levl[c->x][c->y].typ == ICE);
|
||||
} while (trycnt++ < 100 && !okay);
|
||||
return okay;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for a special room given its type (zoo, court, etc...)
|
||||
* Special values :
|
||||
|
||||
@@ -1079,11 +1079,17 @@ free_dungeons()
|
||||
{
|
||||
#ifdef FREE_ALL_MEMORY
|
||||
NHFILE tnhfp;
|
||||
int i;
|
||||
|
||||
zero_nhfile(&tnhfp); /* also sets fd to -1 */
|
||||
tnhfp.mode = FREEING;
|
||||
savelevchn(&tnhfp);
|
||||
save_dungeon(&tnhfp, FALSE, TRUE);
|
||||
for (i = 0; i < g.n_dgns; i++)
|
||||
if (g.dungeons[i].themelua) {
|
||||
lua_close(g.dungeons[i].themelua);
|
||||
g.dungeons[i].themelua = (lua_State *) 0;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
107
src/sp_lev.c
107
src/sp_lev.c
@@ -23,7 +23,6 @@ typedef void FDECL((*select_iter_func), (int, int, genericptr));
|
||||
|
||||
extern void FDECL(mkmap, (lev_init *));
|
||||
|
||||
static void NDECL(create_des_coder);
|
||||
static void NDECL(solidify_map);
|
||||
static void FDECL(lvlfill_maze_grid, (int, int, int, int, SCHAR_P));
|
||||
static void FDECL(lvlfill_solid, (SCHAR_P, SCHAR_P));
|
||||
@@ -1311,6 +1310,10 @@ boolean vault;
|
||||
register int x, y, hix = *lowx + *ddx, hiy = *lowy + *ddy;
|
||||
register struct rm *lev;
|
||||
int xlim, ylim, ymax;
|
||||
xchar s_lowx, s_ddx, s_lowy, s_ddy;
|
||||
|
||||
s_lowx = *lowx; s_ddx = *ddx;
|
||||
s_lowy = *lowy; s_ddy = *ddy;
|
||||
|
||||
xlim = XLIM + (vault ? 1 : 0);
|
||||
ylim = YLIM + (vault ? 1 : 0);
|
||||
@@ -1327,6 +1330,10 @@ boolean vault;
|
||||
if (hix <= *lowx || hiy <= *lowy)
|
||||
return FALSE;
|
||||
|
||||
if (g.in_mk_themerooms && (s_lowx != *lowx) && (s_ddx != *ddx)
|
||||
&& (s_lowy != *lowy) && (s_ddy != *ddy))
|
||||
return FALSE;
|
||||
|
||||
/* check area around room (and make room smaller if necessary) */
|
||||
for (x = *lowx - xlim; x <= hix + xlim; x++) {
|
||||
if (x <= 0 || x >= COLNO)
|
||||
@@ -1345,6 +1352,8 @@ boolean vault;
|
||||
}
|
||||
if (!rn2(3))
|
||||
return FALSE;
|
||||
if (g.in_mk_themerooms)
|
||||
return FALSE;
|
||||
if (x < *lowx)
|
||||
*lowx = x + xlim + 1;
|
||||
else
|
||||
@@ -1359,6 +1368,11 @@ boolean vault;
|
||||
}
|
||||
*ddx = hix - *lowx;
|
||||
*ddy = hiy - *lowy;
|
||||
|
||||
if (g.in_mk_themerooms && (s_lowx != *lowx) && (s_ddx != *ddx)
|
||||
&& (s_lowy != *lowy) && (s_ddy != *ddy))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1462,6 +1476,7 @@ xchar rtype, rlit;
|
||||
r2.hy = yabs + htmp;
|
||||
} else { /* Only some parameters are random */
|
||||
int rndpos = 0;
|
||||
xchar dx, dy;
|
||||
|
||||
if (xtmp < 0 && ytmp < 0) { /* Position is RANDOM */
|
||||
xtmp = rnd(5);
|
||||
@@ -1518,6 +1533,12 @@ xchar rtype, rlit;
|
||||
r2.hx = xabs + wtmp + rndpos;
|
||||
r2.hy = yabs + htmp + rndpos;
|
||||
r1 = get_rect(&r2);
|
||||
dx = wtmp;
|
||||
dy = htmp;
|
||||
|
||||
if (r1 && !check_room(&xabs, &dx, &yabs, &dy, vault)) {
|
||||
r1 = 0;
|
||||
}
|
||||
}
|
||||
} while (++trycnt <= 100 && !r1);
|
||||
if (!r1) { /* creation of room failed ? */
|
||||
@@ -3703,9 +3724,8 @@ static const struct {
|
||||
const char *name;
|
||||
int type;
|
||||
} room_types[] = {
|
||||
/* for historical reasons, room types are not contiguous numbers */
|
||||
/* (type 1 is skipped) */
|
||||
{ "ordinary", OROOM },
|
||||
{ "themed", THEMEROOM },
|
||||
{ "throne", COURT },
|
||||
{ "swamp", SWAMP },
|
||||
{ "vault", VAULT },
|
||||
@@ -3764,6 +3784,9 @@ lua_State *L;
|
||||
{
|
||||
create_des_coder();
|
||||
|
||||
if (g.in_mk_themerooms && g.themeroom_failed)
|
||||
return 0;
|
||||
|
||||
lcheck_param_table(L);
|
||||
|
||||
if (g.coder->n_subroom > MAX_NESTED_ROOMS) {
|
||||
@@ -3802,7 +3825,7 @@ lua_State *L;
|
||||
tmproom.rtype = get_table_roomtype_opt(L, "type", OROOM);
|
||||
tmproom.chance = get_table_int_opt(L, "chance", 100);
|
||||
tmproom.rlit = get_table_int_opt(L, "lit", -1);
|
||||
tmproom.filled = get_table_int_opt(L, "filled", 1);
|
||||
tmproom.filled = get_table_int_opt(L, "filled", g.in_mk_themerooms ? 0 : 1);
|
||||
tmproom.joined = get_table_int_opt(L, "joined", 1);
|
||||
|
||||
if (!g.coder->failed_room[g.coder->n_subroom - 1]) {
|
||||
@@ -3822,6 +3845,8 @@ lua_State *L;
|
||||
spo_endroom(g.coder);
|
||||
return 0;
|
||||
}
|
||||
if (g.in_mk_themerooms)
|
||||
g.themeroom_failed = TRUE;
|
||||
} /* failed to create parent room, so fail this too */
|
||||
}
|
||||
g.coder->tmproomlist[g.coder->n_subroom] = (struct mkroom *) 0;
|
||||
@@ -3829,6 +3854,8 @@ lua_State *L;
|
||||
g.coder->n_subroom++;
|
||||
update_croom();
|
||||
spo_endroom(g.coder);
|
||||
if (g.in_mk_themerooms)
|
||||
g.themeroom_failed = TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -5628,7 +5655,7 @@ lua_State *L;
|
||||
/* for an ordinary room, `prefilled' is a flag to force
|
||||
an actual room to be created (such rooms are used to
|
||||
control placement of migrating monster arrivals) */
|
||||
room_not_needed = (rtype == OROOM && !irregular && !prefilled);
|
||||
room_not_needed = (rtype == OROOM && !irregular && !prefilled && !g.in_mk_themerooms);
|
||||
if (room_not_needed || g.nroom >= MAXNROFROOMS) {
|
||||
region tmpregion;
|
||||
if (!room_not_needed)
|
||||
@@ -5668,6 +5695,9 @@ lua_State *L;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (g.in_mk_themerooms && prefilled)
|
||||
troom->needfill = 1;
|
||||
|
||||
if (!room_not_needed) {
|
||||
if (g.coder->n_subroom > 1)
|
||||
impossible("region as subroom");
|
||||
@@ -6009,9 +6039,14 @@ TODO: g.coder->croom needs to be updated
|
||||
struct mapfragment *mf;
|
||||
int argc = lua_gettop(L);
|
||||
boolean has_contents = FALSE;
|
||||
int tryct = 0;
|
||||
int ox, oy;
|
||||
|
||||
create_des_coder();
|
||||
|
||||
if (g.in_mk_themerooms && g.themeroom_failed)
|
||||
return 0;
|
||||
|
||||
if (argc == 1 && lua_type(L, 1) == LUA_TSTRING) {
|
||||
char *tmpstr = dupstr(luaL_checkstring(L, 1));
|
||||
lr = tb = CENTER;
|
||||
@@ -6040,10 +6075,34 @@ TODO: g.coder->croom needs to be updated
|
||||
return 0;
|
||||
}
|
||||
|
||||
ox = x;
|
||||
oy = y;
|
||||
redo_maploc:
|
||||
|
||||
g.xsize = mf->wid;
|
||||
g.ysize = mf->hei;
|
||||
|
||||
if (lr == -1 && tb == -1) {
|
||||
if (g.in_mk_themerooms && (ox == -1 || oy == -1)) {
|
||||
if (ox == -1) {
|
||||
if (g.coder->croom) {
|
||||
x = somex(g.coder->croom) - mf->wid;
|
||||
if (x < 1) x = 1;
|
||||
} else {
|
||||
x = 1 + rn2(COLNO - 1 - mf->wid);
|
||||
}
|
||||
}
|
||||
|
||||
if (oy == -1) {
|
||||
if (g.coder->croom) {
|
||||
y = somey(g.coder->croom) - mf->hei;
|
||||
if (y < 1) y = 1;
|
||||
} else {
|
||||
y = rn2(ROWNO - mf->wid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isok(x,y)) {
|
||||
/* x,y is given, place map starting at x,y */
|
||||
if (g.coder->croom) {
|
||||
@@ -6102,6 +6161,10 @@ TODO: g.coder->croom needs to be updated
|
||||
}
|
||||
|
||||
if (g.ystart < 0 || g.ystart + g.ysize > ROWNO) {
|
||||
if (g.in_mk_themerooms) {
|
||||
g.themeroom_failed = TRUE;
|
||||
goto skipmap;
|
||||
}
|
||||
/* try to move the start a bit */
|
||||
g.ystart += (g.ystart > 0) ? -2 : 2;
|
||||
if (g.ysize == ROWNO)
|
||||
@@ -6117,6 +6180,32 @@ TODO: g.coder->croom needs to be updated
|
||||
} else {
|
||||
xchar mptyp;
|
||||
|
||||
/* Themed rooms should never overwrite anything */
|
||||
if (g.in_mk_themerooms) {
|
||||
boolean isokp = TRUE;
|
||||
for (y = g.ystart - 1; y < min(ROWNO, g.ystart + g.ysize) + 1; y++)
|
||||
for (x = g.xstart - 1; x < min(COLNO, g.xstart + g.xsize) + 1; x++) {
|
||||
if (!isok(x, y)) {
|
||||
isokp = FALSE;
|
||||
} else if (y < g.ystart || y >= (g.ystart + g.ysize)
|
||||
|| x < g.xstart || x >= (g.xstart + g.xsize)) {
|
||||
if (levl[x][y].typ != STONE) isokp = FALSE;
|
||||
if (levl[x][y].roomno != NO_ROOM) isokp = FALSE;
|
||||
} else {
|
||||
mptyp = mapfrag_get(mf, (x - g.xstart), (y - g.ystart));
|
||||
if (mptyp >= MAX_TYPE) continue;
|
||||
if (levl[x][y].typ != STONE && levl[x][y].typ != mptyp) isokp = FALSE;
|
||||
if (levl[x][y].roomno != NO_ROOM) isokp = FALSE;
|
||||
}
|
||||
if (!isokp) {
|
||||
if ((tryct++ < 100) && ((lr == -1) || (tb == -1)))
|
||||
goto redo_maploc;
|
||||
g.themeroom_failed = TRUE;
|
||||
goto skipmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Load the map */
|
||||
for (y = g.ystart; y < min(ROWNO, g.ystart + g.ysize); y++)
|
||||
for (x = g.xstart; x < min(COLNO, g.xstart + g.xsize); x++) {
|
||||
@@ -6158,14 +6247,16 @@ TODO: g.coder->croom needs to be updated
|
||||
else if (splev_init_present && levl[x][y].typ == ICE)
|
||||
levl[x][y].icedpool = icedpools ? ICED_POOL : ICED_MOAT;
|
||||
}
|
||||
if (g.coder->lvl_is_joined)
|
||||
if (g.coder->lvl_is_joined && !g.in_mk_themerooms)
|
||||
remove_rooms(g.xstart, g.ystart,
|
||||
g.xstart + g.xsize, g.ystart + g.ysize);
|
||||
}
|
||||
|
||||
skipmap:
|
||||
|
||||
mapfrag_free(&mf);
|
||||
|
||||
if (has_contents) {
|
||||
if (has_contents && !(g.in_mk_themerooms && g.themeroom_failed)) {
|
||||
l_push_wid_hei_table(L, g.xsize, g.ysize);
|
||||
lua_call(L, 1, 0);
|
||||
}
|
||||
@@ -6290,7 +6381,7 @@ lua_State *L;
|
||||
lua_setglobal(L, "des");
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
create_des_coder()
|
||||
{
|
||||
if (!g.coder)
|
||||
|
||||
Reference in New Issue
Block a user