Lots of feature upgrades.

This commit is contained in:
Justin Marshall
2026-05-30 02:50:21 -07:00
parent 7806bb8ef8
commit ea74cd9921
13 changed files with 2433 additions and 153 deletions
+217 -48
View File
@@ -1599,6 +1599,109 @@ static int DRLG_PlaceMiniSet(const byte miniset[], int tmin, int tmax, int cx, i
return(3);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static BOOL L5MiniSetFits(const byte miniset[], int sx, int sy)
{
int sw, sh;
int xx, yy;
int ii;
sw = miniset[0];
sh = miniset[1];
if (sx < 0 || sy < 0 || sx + sw >= MDMAXX || sy + sh >= MDMAXY)
return FALSE;
ii = 2;
for (yy = 0; yy < sh; yy++) {
for (xx = 0; xx < sw; xx++) {
if ((miniset[ii] != 0) && (dungeon[sx + xx][sy + yy] != miniset[ii]))
return FALSE;
if (dflags[sx + xx][sy + yy] != 0)
return FALSE;
ii++;
}
}
return TRUE;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void L5PlaceMiniSetAt(const byte miniset[], int sx, int sy)
{
int sw, sh;
int xx, yy;
int ii;
sw = miniset[0];
sh = miniset[1];
ii = (sw * sh) + 2;
for (yy = 0; yy < sh; yy++) {
for (xx = 0; xx < sw; xx++) {
if (miniset[ii] != 0)
dungeon[sx + xx][sy + yy] = miniset[ii];
ii++;
}
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static BOOL L5TryPlaceLamp(int sx, int sy)
{
if (!L5MiniSetFits(LAMPS, sx, sy))
return FALSE;
L5PlaceMiniSetAt(LAMPS, sx, sy);
return TRUE;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int L5PlaceLampNear(int cx, int cy, int max)
{
static const int offsets[][2] = {
{ -3, -2 }, { 2, -2 }, { -3, 2 }, { 2, 2 },
{ -4, 0 }, { 3, 0 }, { 0, -4 }, { 0, 3 },
{ -5, -1 }, { 4, -1 }, { -1, 4 }, { -1, -5 },
};
int i, n, start;
int placed;
placed = 0;
n = sizeof(offsets) / sizeof(offsets[0]);
start = random(0, n);
for (i = 0; i < n && placed < max; i++) {
if (L5TryPlaceLamp(cx + offsets[(start + i) % n][0], cy + offsets[(start + i) % n][1]))
placed++;
}
return placed;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void L5PlaceLevel1Lamps()
{
int i, j;
if (currlevel != 1)
return;
for (j = 1; j < MDMAXY - 1; j++) {
for (i = 1; i < MDMAXX - 1; i++) {
if (dungeon[i][j] == 64)
L5PlaceLampNear(i, j, 2);
if (dungeon[i][j] == 59)
L5PlaceLampNear(i, j, 1);
}
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
/*
@@ -1972,12 +2075,54 @@ void LoadPreL1Dungeon(char sFileName[], int vx, int vy)
byte L5dungeon[L5DX][L5DY];
byte L5ConvTbl[16] = { 22, 13, 1, 13, 2, 13, 13, 13, 4, 13, 1, 13, 2, 13, 16, 13 };
typedef struct {
int minArea;
int roomMin;
int roomMax;
int wallChance;
int archWallChance;
int grateWallChance;
int archDoorChance;
int loopChance;
int lampMin;
int lampMax;
} L5CathedralProfile;
static L5CathedralProfile L5Profile;
/*------------------------------------------------------------------------*
** Global variables
**------------------------------------------------------------------------*/
static BOOL HR1, HR2, HR3;
static BOOL VR1, VR2, VR3;
/*------------------------------------------------------------------------*
**------------------------------------------------------------------------*/
static const L5CathedralProfile *GetL5CathedralProfile()
{
static const L5CathedralProfile profiles[4] = {
{ 533, 2, 6, 92, 20, 10, 14, 0, 4, 7 },
{ 693, 2, 7, 96, 23, 13, 16, 3, 6, 10 },
{ 761, 4, 7, 100, 25, 16, 18, 5, 4, 8 },
{ 805, 4, 8, 100, 28, 20, 20, 7, 3, 6 },
};
static const L5CathedralProfile oldProfile = {
761, L5ROOM_MIN, L5ROOM_MAX, 100, 25, 25, 16, 0, 5, 10
};
if (currlevel >= 1 && currlevel <= 4)
return &profiles[currlevel - 1];
return &oldProfile;
}
/*------------------------------------------------------------------------*
**------------------------------------------------------------------------*/
static void InitL5CathedralProfile()
{
L5Profile = *GetL5CathedralProfile();
}
/*------------------------------------------------------------------------*
**------------------------------------------------------------------------*/
static void InitL5Dungeon()
@@ -2060,8 +2205,8 @@ static void L5roomGen(int x, int y, int w, int h, int dir)
// left room
num = 0;
do {
width = ((random(0, L5ROOM_MAX - L5ROOM_MIN + 1) + L5ROOM_MIN) >> 1) << 1;
height = ((random(0, L5ROOM_MAX - L5ROOM_MIN + 1) + L5ROOM_MIN) >> 1) << 1;
width = ((random(0, L5Profile.roomMax - L5Profile.roomMin + 1) + L5Profile.roomMin) >> 1) << 1;
height = ((random(0, L5Profile.roomMax - L5Profile.roomMin + 1) + L5Profile.roomMin) >> 1) << 1;
ry = y + (h / 2) - (height / 2);
rx = x - width;
cx1 = rx - 1;
@@ -2089,8 +2234,8 @@ static void L5roomGen(int x, int y, int w, int h, int dir)
// top room
num = 0;
do {
width = ((random(0, L5ROOM_MAX - L5ROOM_MIN + 1) + L5ROOM_MIN) >> 1) << 1;
height = ((random(0, L5ROOM_MAX - L5ROOM_MIN + 1) + L5ROOM_MIN) >> 1) << 1;
width = ((random(0, L5Profile.roomMax - L5Profile.roomMin + 1) + L5Profile.roomMin) >> 1) << 1;
height = ((random(0, L5Profile.roomMax - L5Profile.roomMin + 1) + L5Profile.roomMin) >> 1) << 1;
rx = x + (w / 2) - (width / 2);
ry = y - height;
cx1 = rx - 1;
@@ -2287,26 +2432,23 @@ static int L5VWallOk(int i, int j)
static void L5HorizWall(int i, int j, char p, int dx)
{
int xx;
int rv;
char wt, dt;
switch (random(0, 4)) {
case 0:
case 1:
wt = 2; // Normal solid wall
break;
case 2:
rv = random(0, 100);
if (rv < L5Profile.archWallChance) {
wt = 12; // Arch wall
if (p == 2) p = 12;
if (p == 4) p = 10;
break;
case 3:
} else if (rv < L5Profile.archWallChance + L5Profile.grateWallChance) {
wt = 36; // Grate wall
if (p == 2) p = 36;
if (p == 4) p = 27;
break;
} else {
wt = 2; // Normal solid wall
}
if (random(0, 6) == 5) dt = 12; // Arch
if (random(0, 100) < L5Profile.archDoorChance) dt = 12; // Arch
else dt = 26; // Door
if (wt == 12) dt = 12; // If arch wall, force arch door
@@ -2326,26 +2468,23 @@ static void L5HorizWall(int i, int j, char p, int dx)
static void L5VertWall(int i, int j, char p, int dy)
{
int yy;
int rv;
char wt, dt;
switch (random(0, 4)) {
case 0:
case 1:
wt = 1; // Normal solid wall
break;
case 2:
rv = random(0, 100);
if (rv < L5Profile.archWallChance) {
wt = 11; // Arch wall
if (p == 1) p = 11;
if (p == 4) p = 14;
break;
case 3:
} else if (rv < L5Profile.archWallChance + L5Profile.grateWallChance) {
wt = 35; // Grate wall
if (p == 1) p = 35;
if (p == 4) p = 37;
break;
} else {
wt = 1; // Normal solid wall
}
if (random(0, 6) == 5) dt = 11; // Arch
if (random(0, 100) < L5Profile.archDoorChance) dt = 11; // Arch
else dt = 25; // Door
if (wt == 11) dt = 11; // If arch wall, force arch door
@@ -2362,7 +2501,6 @@ static void L5VertWall(int i, int j, char p, int dy)
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
#define WALLRND 100
static void L5AddWall()
{
int i, j;
@@ -2371,27 +2509,27 @@ static void L5AddWall()
for (j = 0; j < MDMAXY; j++) {
for (i = 0; i < MDMAXX; i++) {
if (dflags[i][j] == 0) {
if ((dungeon[i][j] == 3) && (random(0, 100) < WALLRND)) {
if ((dungeon[i][j] == 3) && (random(0, 100) < L5Profile.wallChance)) {
x = L5HWallOk(i, j);
if (x != -1) L5HorizWall(i, j, 2, x);
}
if ((dungeon[i][j] == 3) && (random(0, 100) < WALLRND)) {
if ((dungeon[i][j] == 3) && (random(0, 100) < L5Profile.wallChance)) {
y = L5VWallOk(i, j);
if (y != -1) L5VertWall(i, j, 1, y);
}
if ((dungeon[i][j] == 6) && (random(0, 100) < WALLRND)) {
if ((dungeon[i][j] == 6) && (random(0, 100) < L5Profile.wallChance)) {
x = L5HWallOk(i, j);
if (x != -1) L5HorizWall(i, j, 4, x);
}
if ((dungeon[i][j] == 7) && (random(0, 100) < WALLRND)) {
if ((dungeon[i][j] == 7) && (random(0, 100) < L5Profile.wallChance)) {
y = L5VWallOk(i, j);
if (y != -1) L5VertWall(i, j, 4, y);
}
if ((dungeon[i][j] == 2) && (random(0, 100) < WALLRND)) {
if ((dungeon[i][j] == 2) && (random(0, 100) < L5Profile.wallChance)) {
x = L5HWallOk(i, j);
if (x != -1) L5HorizWall(i, j, 2, x);
}
if ((dungeon[i][j] == 1) && (random(0, 100) < WALLRND)) {
if ((dungeon[i][j] == 1) && (random(0, 100) < L5Profile.wallChance)) {
y = L5VWallOk(i, j);
if (y != -1) L5VertWall(i, j, 1, y);
}
@@ -2400,6 +2538,41 @@ static void L5AddWall()
}
}
/*------------------------------------------------------------------------*
**------------------------------------------------------------------------*/
static BOOL L5OpenFloor(int x, int y)
{
return dungeon[x][y] == D_FLOOR && dflags[x][y] == NODOOR;
}
/*------------------------------------------------------------------------*
**------------------------------------------------------------------------*/
static void L5AddLoops()
{
int i, j;
if (L5Profile.loopChance <= 0) return;
for (j = 2; j < MDMAXY - 2; j++) {
for (i = 2; i < MDMAXX - 2; i++) {
if (dflags[i][j] != NODOOR) continue;
if (random(0, 100) >= L5Profile.loopChance) continue;
if (dungeon[i][j] == D_VWALL && L5OpenFloor(i - 1, j) && L5OpenFloor(i + 1, j)) {
if (random(0, 100) < L5Profile.archDoorChance)
dungeon[i][j] = D_AVW;
else
dflags[i][j] |= VDOOR;
} else if (dungeon[i][j] == D_HWALL && L5OpenFloor(i, j - 1) && L5OpenFloor(i, j + 1)) {
if (random(0, 100) < L5Profile.archDoorChance)
dungeon[i][j] = D_AHW;
else
dflags[i][j] |= HDOOR;
}
}
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void DRLG_L5GChamber(int sx, int sy, int topflag, int bottomflag, int leftflag, int rightflag)
@@ -3252,6 +3425,7 @@ static void NormalGrate(int chance)
DRLG_L5PlaceRndSet(FLOOR3, chance);
DRLG_L5PlaceRndSet(FLOOR4, chance);
}
/*-----------------------------------------------------------------------*
**-----------------------------------------------------------------------*/
static void DRLG_L5(int entry)
@@ -3262,21 +3436,9 @@ static void DRLG_L5(int entry)
int xx, yy;
doneflag = FALSE;
InitL5CathedralProfile();
minarea = L5Profile.minArea;
switch (currlevel) {
case 1:
minarea = 533; //(L5DUNX*L5DUNY)/3;
break;
case 2:
minarea = 693; //((L5DUNX*L5DUNY)/3) + ((L5DUNX*L5DUNY)/10);
break;
case 3:
case 4:
minarea = 761; //((L5DUNX*L5DUNY)/3) + ((L5DUNX*L5DUNY)/7);
break;
default:
minarea = 761; // Crypt levels
}
while (!doneflag) {
DRLG_InitTrans();
do {
@@ -3292,6 +3454,7 @@ static void DRLG_L5(int entry)
L5tileFix();
L5AddWall();
if (currlevel < CRYPTSTART) L5AddLoops();
L5ClearFlags();
DRLG_L5FloodTVal();
@@ -3435,7 +3598,11 @@ static void DRLG_L5(int entry)
// Random subs
if (currlevel < CRYPTSTART) // These are to turn off stuff in the crypt JKE
{
// Keep Cathedral levels on the L1-safe substitution table. The broken
// wall, grate, statue, and rubble minisets below belong to the Crypt art.
DRLG_L5Subs();
}
else
{
@@ -3498,9 +3665,11 @@ static void DRLG_L5(int entry)
// else
// DRLG_L5Shadows();
// Create mini set pieces
if (currlevel < CRYPTSTART)
DRLG_PlaceMiniSet(LAMPS, 5, 10, 0, 0, 0, -1, LVL_NODIR);
// Create mini set pieces
if (currlevel < CRYPTSTART) {
L5PlaceLevel1Lamps();
DRLG_PlaceMiniSet(LAMPS, L5Profile.lampMin, L5Profile.lampMax, 0, 0, 0, -1, LVL_NODIR);
}
// Floor subs
if (currlevel < CRYPTSTART)