Browse Source

Use common function for loading .dun tile data

pull/4699/head
Anders Jenbo 4 years ago
parent
commit
43311ad375
  1. 108
      Source/drlg_l1.cpp
  2. 66
      Source/drlg_l2.cpp
  3. 75
      Source/drlg_l3.cpp
  4. 110
      Source/drlg_l4.cpp
  5. 12
      Source/drlg_l4.h
  6. 158
      Source/gendung.cpp
  7. 27
      Source/gendung.h
  8. 2
      Source/items.cpp
  9. 120
      Source/monster.cpp
  10. 113
      Source/objects.cpp
  11. 116
      Source/quests.cpp

108
Source/drlg_l1.cpp

@ -1457,10 +1457,7 @@ void FixTilesPatterns()
void SetCornerRoom(int rx1, int ry1)
{
setpc_x = rx1;
setpc_y = ry1;
setpc_w = CornerstoneRoomPattern.size.width;
setpc_h = CornerstoneRoomPattern.size.height;
SetPiece = { { rx1, ry1 }, CornerstoneRoomPattern.size };
CornerstoneRoomPattern.place({ rx1, ry1 }, true);
}
@ -1505,39 +1502,11 @@ void Substitution()
}
}
void SetRoom(int rx1, int ry1)
{
int width = SDL_SwapLE16(L5pSetPiece[0]);
int height = SDL_SwapLE16(L5pSetPiece[1]);
setpc_x = rx1;
setpc_y = ry1;
setpc_w = width;
setpc_h = height;
uint16_t *tileLayer = &L5pSetPiece[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(tileLayer[j * width + i]));
if (tileId != 0) {
dungeon[rx1 + i][ry1 + j] = tileId;
Protected[rx1 + i][ry1 + j] = true;
} else {
dungeon[rx1 + i][ry1 + j] = Tile::Floor;
}
}
}
}
void SetCryptRoom(int rx1, int ry1)
{
UberRow = 2 * rx1 + 6;
UberCol = 2 * ry1 + 8;
setpc_x = rx1;
setpc_y = ry1;
setpc_w = UberRoomPattern.size.width;
setpc_h = UberRoomPattern.size.height;
SetPiece = { { rx1, ry1 }, UberRoomPattern.size };
IsUberRoomOpened = false;
IsUberLeverActivated = false;
@ -1704,6 +1673,7 @@ void FillChambers()
}
}
if (L5setloadflag) {
Point position;
if (VR1 || VR2 || VR3) {
int c = 1;
if (!VR1 && VR2 && VR3 && GenerateRnd(2) != 0)
@ -1723,13 +1693,13 @@ void FillChambers()
switch (c) {
case 0:
SetRoom(16, 2);
position = { 16, 2 };
break;
case 1:
SetRoom(16, 16);
position = { 16, 16 };
break;
case 2:
SetRoom(16, 30);
position = { 16, 30 };
break;
}
} else {
@ -1751,16 +1721,18 @@ void FillChambers()
switch (c) {
case 0:
SetRoom(2, 16);
position = { 2, 16 };
break;
case 1:
SetRoom(16, 16);
position = { 16, 16 };
break;
case 2:
SetRoom(30, 16);
position = { 30, 16 };
break;
}
}
PlaceDunTiles(L5pSetPiece.get(), position, Tile::Floor);
SetPiece = { position, { SDL_SwapLE16(L5pSetPiece[0]), SDL_SwapLE16(L5pSetPiece[1]) } };
}
}
@ -1994,14 +1966,14 @@ bool PlaceCathedralStairs(lvl_entry entry)
// Place poison water entrance
if (Quests[Q_PWATER].IsAvailable()) {
position = PlaceMiniSet(PWATERIN, 4000, true);
position = PlaceMiniSet(PWATERIN, DMAXX * DMAXY, true);
if (!position) {
success = false;
} else {
int8_t t = TransVal;
TransVal = 0;
Point miniPosition = *position;
DRLG_MRectTrans(miniPosition.x, miniPosition.y + 2, miniPosition.x + 5, miniPosition.y + 4);
DRLG_MRectTrans({ miniPosition + Displacement { 0, 2 }, { 5, 2 } });
TransVal = t;
Quests[Q_PWATER].position = miniPosition.megaToWorld() + Displacement { 5, 7 };
if (entry == ENTRY_RTNLVL)
@ -2010,7 +1982,7 @@ bool PlaceCathedralStairs(lvl_entry entry)
}
// Place stairs up
position = PlaceMiniSet(MyPlayer->pOriginalCathedral ? L5STAIRSUP : STAIRSUP, 4000, true);
position = PlaceMiniSet(MyPlayer->pOriginalCathedral ? L5STAIRSUP : STAIRSUP, DMAXX * DMAXY, true);
if (!position) {
if (MyPlayer->pOriginalCathedral)
return false;
@ -2022,9 +1994,9 @@ bool PlaceCathedralStairs(lvl_entry entry)
// Place stairs down
if (Quests[Q_LTBANNER].IsAvailable()) {
if (entry == ENTRY_PREV)
ViewPosition = Point(setpc_x, setpc_y).megaToWorld() + Displacement { 4, 12 };
ViewPosition = SetPiece.position.megaToWorld() + Displacement { 4, 12 };
} else {
position = PlaceMiniSet(STAIRSDOWN, 4000, true);
position = PlaceMiniSet(STAIRSDOWN, DMAXX * DMAXY, true);
if (!position) {
success = false;
} else if (entry == ENTRY_PREV) {
@ -2041,7 +2013,7 @@ bool PlaceCryptStairs(lvl_entry entry)
std::optional<Point> position;
// Place stairs up
position = PlaceMiniSet(currlevel != 21 ? L5STAIRSUPHF : L5STAIRSTOWN, 4000, true);
position = PlaceMiniSet(currlevel != 21 ? L5STAIRSUPHF : L5STAIRSTOWN, DMAXX * DMAXY, true);
if (!position) {
success = false;
} else if (entry == ENTRY_MAIN || entry == ENTRY_TWARPDN) {
@ -2050,7 +2022,7 @@ bool PlaceCryptStairs(lvl_entry entry)
// Place stairs down
if (currlevel != 24) {
position = PlaceMiniSet(L5STAIRSDOWN, 4000, true);
position = PlaceMiniSet(L5STAIRSDOWN, DMAXX * DMAXY, true);
if (!position)
success = false;
else if (entry == ENTRY_PREV)
@ -2172,7 +2144,7 @@ void GenerateLevel(lvl_entry entry)
int numt = GenerateRnd(5) + 5;
for (int i = 0; i < numt; i++) {
PlaceMiniSet(LAMPS, 4000, true);
PlaceMiniSet(LAMPS, DMAXX * DMAXY, true);
}
FillFloor();
@ -2185,7 +2157,7 @@ void GenerateLevel(lvl_entry entry)
}
DRLG_Init_Globals();
DRLG_CheckQuests({ setpc_x, setpc_y });
DRLG_CheckQuests(SetPiece.position);
}
void Pass3()
@ -2210,24 +2182,7 @@ void LoadL1Dungeon(const char *path, int vx, int vy)
}
auto dunData = LoadFileInMem<uint16_t>(path);
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
const uint16_t *tileLayer = &dunData[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(*tileLayer));
tileLayer++;
if (tileId != 0) {
dungeon[i][j] = tileId;
Protected[i][j] = true;
} else {
dungeon[i][j] = Tile::Floor;
}
}
}
PlaceDunTiles(dunData.get(), { 0, 0 }, Tile::Floor);
FillFloor();
@ -2239,7 +2194,7 @@ void LoadL1Dungeon(const char *path, int vx, int vy)
if (leveltype != DTYPE_CRYPT)
InitDungeonPieces();
SetMapMonsters(dunData.get(), { 0, 0 });
SetMapMonsters(dunData.get(), Point(0, 0).megaToWorld());
SetMapObjects(dunData.get(), 0, 0);
}
@ -2256,24 +2211,7 @@ void LoadPreL1Dungeon(const char *path)
dmaxPosition = { 96, 96 };
auto dunData = LoadFileInMem<uint16_t>(path);
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
const uint16_t *tileLayer = &dunData[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(*tileLayer));
tileLayer++;
if (tileId != 0) {
dungeon[i][j] = tileId;
Protected[i][j] = true;
} else {
dungeon[i][j] = Tile::Floor;
}
}
}
PlaceDunTiles(dunData.get(), { 0, 0 }, Tile::Floor);
FillFloor();

66
Source/drlg_l2.cpp

@ -1578,7 +1578,7 @@ void PlaceMiniSetRandom(const Miniset &miniset, int rndper)
for (int sy = 0; sy < DMAXY - sh; sy++) {
for (int sx = 0; sx < DMAXX - sw; sx++) {
if (SetPiecesRoom.Contains({ sx, sy }))
if (SetPieceRoom.Contains({ sx, sy }))
continue;
if (!miniset.matches({ sx, sy }))
continue;
@ -1611,8 +1611,6 @@ void LoadQuestSetPieces()
if (Quests[Q_BLIND].IsAvailable()) {
pSetPiece = LoadFileInMem<uint16_t>("Levels\\L2Data\\Blind1.DUN");
pSetPiece[13] = SDL_SwapLE16(154); // Close outer wall
pSetPiece[100] = SDL_SwapLE16(154); // Close outer wall
setloadflag = true;
} else if (Quests[Q_BLOOD].IsAvailable()) {
pSetPiece = LoadFileInMem<uint16_t>("Levels\\L2Data\\Blood1.DUN");
@ -1829,7 +1827,7 @@ void CreateRoom(int nX1, int nY1, int nX2, int nY2, int nRDest, int nHDir, bool
DefineRoom(nRx1, nRy1, nRx2, nRy2, forceHW);
if (forceHW) {
SetPiecesRoom = { { nRx1 + 2, nRy1 + 2 }, { nRx2 - nRx1 - 1, nRy2 - nRy1 - 1 } };
SetPieceRoom = { { nRx1 + 2, nRy1 + 2 }, { nRx2 - nRx1 - 1, nRy2 - nRy1 - 1 } };
}
int nRid = nRoomCnt;
@ -2133,7 +2131,7 @@ void Substitution()
{
for (int y = 0; y < DMAXY; y++) {
for (int x = 0; x < DMAXX; x++) {
if (SetPiecesRoom.Contains({ x, y }))
if (SetPieceRoom.Contains({ x, y }))
continue;
if (GenerateRnd(4) != 0)
continue;
@ -2169,31 +2167,6 @@ void Substitution()
}
}
void SetRoom(Point position)
{
int width = SDL_SwapLE16(pSetPiece[0]);
int height = SDL_SwapLE16(pSetPiece[1]);
setpc_x = position.x;
setpc_y = position.y;
setpc_w = width;
setpc_h = height;
uint16_t *tileLayer = &pSetPiece[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(tileLayer[j * width + i]));
if (tileId != 0) {
dungeon[position.x + i][position.y + j] = tileId;
Protected[position.x + i][position.y + j] = true;
} else {
dungeon[position.x + i][position.y + j] = 3;
}
}
}
}
int CountEmptyTiles()
{
int t = 0;
@ -2776,7 +2749,8 @@ void GenerateLevel(lvl_entry entry)
}
FixTilesPatterns();
if (setloadflag) {
SetRoom(SetPiecesRoom.position);
PlaceDunTiles(pSetPiece.get(), SetPieceRoom.position, 3);
SetPiece = { SetPieceRoom.position, { SDL_SwapLE16(pSetPiece[0]), SDL_SwapLE16(pSetPiece[1]) } };
}
FloodTransparencyValues(3);
FixTransparency();
@ -2907,7 +2881,7 @@ void GenerateLevel(lvl_entry entry)
}
DRLG_Init_Globals();
DRLG_CheckQuests(SetPiecesRoom.position);
DRLG_CheckQuests(SetPieceRoom.position);
}
void LoadDungeonData(const uint16_t *dunData)
@ -2918,27 +2892,10 @@ void LoadDungeonData(const uint16_t *dunData)
for (int j = 0; j < DMAXY; j++) {
for (int i = 0; i < DMAXX; i++) {
dungeon[i][j] = 12;
Protected[i][j] = false;
}
}
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
const uint16_t *tileLayer = &dunData[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(*tileLayer));
tileLayer++;
if (tileId != 0) {
dungeon[i][j] = tileId;
Protected[i][j] = true;
} else {
dungeon[i][j] = 3;
}
}
}
PlaceDunTiles(dunData, { 0, 0 }, 3);
for (int j = 0; j < DMAXY; j++) {
for (int i = 0; i < DMAXX; i++) { // NOLINT(modernize-loop-convert)
@ -2959,7 +2916,6 @@ void Pass3()
void LoadL2Dungeon(const char *path, int vx, int vy)
{
auto dunData = LoadFileInMem<uint16_t>(path);
LoadDungeonData(dunData.get());
Pass3();
@ -2969,16 +2925,14 @@ void LoadL2Dungeon(const char *path, int vx, int vy)
ViewPosition = { vx, vy };
SetMapMonsters(dunData.get(), { 0, 0 });
SetMapMonsters(dunData.get(), Point(0, 0).megaToWorld());
SetMapObjects(dunData.get(), 0, 0);
}
void LoadPreL2Dungeon(const char *path)
{
{
auto dunData = LoadFileInMem<uint16_t>(path);
LoadDungeonData(dunData.get());
}
auto dunData = LoadFileInMem<uint16_t>(path);
LoadDungeonData(dunData.get());
for (int j = 0; j < DMAXY; j++) {
for (int i = 0; i < DMAXX; i++) {

75
Source/drlg_l3.cpp

@ -1407,8 +1407,8 @@ bool PlaceMiniSetRandom(const Miniset &miniset, int rndper)
int sh = miniset.size.height;
bool placed = false;
for (int sy = 0; sy < DMAXX - sh; sy++) {
for (int sx = 0; sx < DMAXY - sw; sx++) {
for (int sy = 0; sy < DMAXY - sh; sy++) {
for (int sx = 0; sx < DMAXX - sw; sx++) {
if (!miniset.matches({ sx, sy }))
continue;
if (!CanReplaceTile(miniset.replace[0][0], { sx, sy }))
@ -1836,14 +1836,13 @@ bool PlaceAnvil()
auto dunData = LoadFileInMem<uint16_t>("Levels\\L3Data\\Anvil.DUN");
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
int sx = GenerateRnd(DMAXX - width - 2) - 1;
int sx = GenerateRnd(DMAXX - width - 2);
int sy = GenerateRnd(DMAXY - height - 2);
for (int trys = 0;; trys++) {
for (int trys = 0;; trys++, sx++) {
if (trys > 198)
return false;
sx++;
if (sx == DMAXX - width - 2) {
sx = 0;
sy++;
@ -1867,34 +1866,20 @@ bool PlaceAnvil()
break;
}
setpc_x = sx;
setpc_y = sy;
setpc_w = width + 2;
setpc_h = height + 2;
SetPiece = { { sx, sy }, { width + 2, height + 2 } };
for (int yy = 0; yy < setpc_h; yy++) {
for (int xx = 0; xx < setpc_w; xx++) {
for (int yy = 0; yy < SetPiece.size.width; yy++) {
for (int xx = 0; xx < SetPiece.size.height; xx++) {
Protected[xx + sx][yy + sy] = true;
}
}
sx++;
sy++;
const uint16_t *tileLayer = &dunData[2];
for (int yy = 0; yy < height; yy++) {
for (int xx = 0; xx < width; xx++) {
int tileId = tileLayer[xx + yy * width];
if (tileId != 0) {
dungeon[xx + sx][yy + sy] = tileId;
}
}
}
PlaceDunTiles(dunData.get(), { sx + 1, sy + 1 }, 7);
// Hack to avoid rivers entering the island, reversed later
dungeon[setpc_x + 7][setpc_y + 5] = 2;
dungeon[setpc_x + 8][setpc_y + 5] = 2;
dungeon[setpc_x + 9][setpc_y + 5] = 2;
dungeon[SetPiece.position.x + 7][SetPiece.position.y + 5] = 2;
dungeon[SetPiece.position.x + 8][SetPiece.position.y + 5] = 2;
dungeon[SetPiece.position.x + 9][SetPiece.position.y + 5] = 2;
return true;
}
@ -2151,11 +2136,11 @@ void GenerateLevel(lvl_entry entry)
River();
if (Quests[Q_ANVIL].IsAvailable()) {
dungeon[setpc_x + 7][setpc_y + 5] = 7;
dungeon[setpc_x + 8][setpc_y + 5] = 7;
dungeon[setpc_x + 9][setpc_y + 5] = 7;
if (dungeon[setpc_x + 10][setpc_y + 5] == 17 || dungeon[setpc_x + 10][setpc_y + 5] == 18) {
dungeon[setpc_x + 10][setpc_y + 5] = 45;
dungeon[SetPiece.position.x + 7][SetPiece.position.y + 5] = 7;
dungeon[SetPiece.position.x + 8][SetPiece.position.y + 5] = 7;
dungeon[SetPiece.position.x + 9][SetPiece.position.y + 5] = 7;
if (dungeon[SetPiece.position.x + 10][SetPiece.position.y + 5] == 17 || dungeon[SetPiece.position.x + 10][SetPiece.position.y + 5] == 18) {
dungeon[SetPiece.position.x + 10][SetPiece.position.y + 5] = 45;
}
}
@ -2267,18 +2252,7 @@ void LoadL3Dungeon(const char *path, int vx, int vy)
DRLG_InitTrans();
auto dunData = LoadFileInMem<uint16_t>(path);
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
const uint16_t *tileLayer = &dunData[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(tileLayer[j * width + i]));
dungeon[i][j] = (tileId != 0) ? tileId : 7;
}
}
PlaceDunTiles(dunData.get(), { 0, 0 }, 7);
for (int j = 0; j < DMAXY; j++) {
for (int i = 0; i < DMAXX; i++) { // NOLINT(modernize-loop-convert)
@ -2293,7 +2267,7 @@ void LoadL3Dungeon(const char *path, int vx, int vy)
ViewPosition = { vx, vy };
SetMapMonsters(dunData.get(), { 0, 0 });
SetMapMonsters(dunData.get(), Point(0, 0).megaToWorld());
SetMapObjects(dunData.get(), 0, 0);
for (int j = 0; j < MAXDUNY; j++) {
@ -2315,18 +2289,7 @@ void LoadPreL3Dungeon(const char *path)
DRLG_InitTrans();
auto dunData = LoadFileInMem<uint16_t>(path);
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
const uint16_t *tileLayer = &dunData[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(tileLayer[j * width + i]));
dungeon[i][j] = (tileId != 0) ? tileId : 7;
}
}
PlaceDunTiles(dunData.get(), { 0, 0 }, 7);
for (int j = 0; j < DMAXY; j++) {
for (int i = 0; i < DMAXX; i++) { // NOLINT(modernize-loop-convert)

110
Source/drlg_l4.cpp

@ -14,20 +14,15 @@
namespace devilution {
int diabquad1x;
int diabquad1y;
int diabquad2x;
int diabquad2y;
int diabquad3x;
int diabquad3y;
int diabquad4x;
int diabquad4y;
Point DiabloQuad1;
Point DiabloQuad2;
Point DiabloQuad3;
Point DiabloQuad4;
namespace {
bool hallok[20];
int l4holdx;
int l4holdy;
Point L4Hold;
BYTE L4dungeon[80][80];
BYTE dung[20][20];
// int dword_52A4DC;
@ -195,26 +190,6 @@ void InitDungeonFlags()
}
}
void SetRoom(const uint16_t *dunData, Point position)
{
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
const uint16_t *tileLayer = &dunData[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(tileLayer[j * width + i]));
if (tileId != 0) {
dungeon[position.x + i][position.y + j] = tileId;
Protected[position.x + i][position.y + j] = true;
} else {
dungeon[position.x + i][position.y + j] = 6;
}
}
}
}
void MapRoom(int x, int y, int width, int height)
{
for (int j = 0; j < height && j + y < 20; j++) {
@ -329,27 +304,23 @@ void FirstRoom()
int y = GenerateRnd(ymax - ymin + 1) + ymin;
if (currlevel == 16) {
l4holdx = x;
l4holdy = y;
L4Hold = { x, y };
}
if (Quests[Q_WARLORD].IsAvailable() || (currlevel == Quests[Q_BETRAYER]._qlevel && gbIsMultiplayer)) {
SetPiecesRoom = { { x + 1, y + 1 }, { w + 1, h + 1 } };
SetPieceRoom = { { x + 1, y + 1 }, { w + 1, h + 1 } };
} else {
SetPiecesRoom = {};
SetPieceRoom = {};
}
MapRoom(x, y, w, h);
GenerateRoom(x, y, w, h, GenerateRnd(2));
}
void SetSetPiecesRoom(Point position)
void SetSetPieceRoom(Point position)
{
setpc_x = position.x;
setpc_y = position.y;
setpc_w = SDL_SwapLE16(pSetPiece[0]);
setpc_h = SDL_SwapLE16(pSetPiece[1]);
SetPiece = { position, { SDL_SwapLE16(pSetPiece[0]), SDL_SwapLE16(pSetPiece[1]) } };
SetRoom(pSetPiece.get(), position);
PlaceDunTiles(pSetPiece.get(), position, 6);
}
void MakeDungeon()
@ -1049,17 +1020,14 @@ int GetArea()
return rv;
}
void SaveQuads()
void ProtectQuads()
{
int x = l4holdx;
int y = l4holdy;
for (int j = 0; j < 14; j++) {
for (int i = 0; i < 14; i++) {
Protected[i + x][j + y] = true;
Protected[DMAXX - 1 - i - x][j + y] = true;
Protected[i + x][DMAXY - 1 - j - y] = true;
Protected[DMAXX - 1 - i - x][DMAXY - 1 - j - y] = true;
for (int y = 0; y < 14; y++) {
for (int x = 0; x < 14; x++) {
Protected[L4Hold.x + x][L4Hold.y + y] = true;
Protected[DMAXX - 1 - x - L4Hold.x][L4Hold.y + y] = true;
Protected[L4Hold.x + x][DMAXY - 1 - y - L4Hold.y] = true;
Protected[DMAXX - 1 - x - L4Hold.x][DMAXY - 1 - y - L4Hold.y] = true;
}
}
}
@ -1068,27 +1036,23 @@ void LoadDiabQuads(bool preflag)
{
{
auto dunData = LoadFileInMem<uint16_t>("Levels\\L4Data\\diab1.DUN");
diabquad1x = 4 + l4holdx;
diabquad1y = 4 + l4holdy;
SetRoom(dunData.get(), { diabquad1x, diabquad1y });
DiabloQuad1 = L4Hold + Displacement { 4, 4 };
PlaceDunTiles(dunData.get(), DiabloQuad1, 6);
}
{
auto dunData = LoadFileInMem<uint16_t>(preflag ? "Levels\\L4Data\\diab2b.DUN" : "Levels\\L4Data\\diab2a.DUN");
diabquad2x = 27 - l4holdx;
diabquad2y = 1 + l4holdy;
SetRoom(dunData.get(), { diabquad2x, diabquad2y });
DiabloQuad2 = { 27 - L4Hold.x, 1 + L4Hold.y };
PlaceDunTiles(dunData.get(), DiabloQuad2, 6);
}
{
auto dunData = LoadFileInMem<uint16_t>(preflag ? "Levels\\L4Data\\diab3b.DUN" : "Levels\\L4Data\\diab3a.DUN");
diabquad3x = 1 + l4holdx;
diabquad3y = 27 - l4holdy;
SetRoom(dunData.get(), { diabquad3x, diabquad3y });
DiabloQuad3 = { 1 + L4Hold.x, 27 - L4Hold.y };
PlaceDunTiles(dunData.get(), DiabloQuad3, 6);
}
{
auto dunData = LoadFileInMem<uint16_t>(preflag ? "Levels\\L4Data\\diab4b.DUN" : "Levels\\L4Data\\diab4a.DUN");
diabquad4x = 28 - l4holdx;
diabquad4y = 28 - l4holdy;
SetRoom(dunData.get(), { diabquad4x, diabquad4y });
DiabloQuad4 = { 28 - L4Hold.x, 28 - L4Hold.y };
PlaceDunTiles(dunData.get(), DiabloQuad4, 6);
}
}
@ -1215,7 +1179,7 @@ bool PlaceStairs(lvl_entry entry)
if (currlevel != 16) {
if (Quests[Q_WARLORD].IsAvailable()) {
if (entry == ENTRY_PREV)
ViewPosition = Point(setpc_x, setpc_y).megaToWorld() + Displacement { 6, 6 };
ViewPosition = SetPiece.position.megaToWorld() + Displacement { 6, 6 };
} else {
position = PlaceMiniSet(L4DSTAIRS);
if (!position)
@ -1263,11 +1227,11 @@ void GenerateLevel(lvl_entry entry)
MakeDmt();
FixTilesPatterns();
if (currlevel == 16) {
SaveQuads();
ProtectQuads();
}
if (Quests[Q_WARLORD].IsAvailable() || (currlevel == Quests[Q_BETRAYER]._qlevel && gbIsMultiplayer)) {
for (int spi = SetPiecesRoom.position.x; spi < SetPiecesRoom.position.x + SetPiecesRoom.size.width - 1; spi++) {
for (int spj = SetPiecesRoom.position.y; spj < SetPiecesRoom.position.y + SetPiecesRoom.size.height - 1; spj++) {
for (int spi = SetPieceRoom.position.x; spi < SetPieceRoom.position.x + SetPieceRoom.size.width - 1; spi++) {
for (int spj = SetPieceRoom.position.y; spj < SetPieceRoom.position.y + SetPieceRoom.size.height - 1; spj++) {
Protected[spi][spj] = true;
}
}
@ -1276,7 +1240,7 @@ void GenerateLevel(lvl_entry entry)
FloodTransparencyValues(6);
FixTransparency();
if (setloadflag) {
SetSetPiecesRoom(SetPiecesRoom.position);
SetSetPieceRoom(SetPieceRoom.position);
}
if (currlevel == 16) {
LoadDiabQuads(true);
@ -1304,13 +1268,13 @@ void GenerateLevel(lvl_entry entry)
}
}
DRLG_CheckQuests(SetPiecesRoom.position);
DRLG_CheckQuests(SetPieceRoom.position);
if (currlevel == 15) {
for (int j = 0; j < DMAXY; j++) {
for (int i = 0; i < DMAXX; i++) {
if (IsAnyOf(dungeon[i][j], 98, 107)) {
Make_SetPC(i - 1, j - 1, 5, 5);
Make_SetPC({ { i - 1, j - 1 }, { 5, 5 } });
if (Quests[Q_BETRAYER]._qactive >= QUEST_ACTIVE) { /// Lazarus staff skip bug fixed
// Set the portal position to the location of the northmost pentagram tile.
Quests[Q_BETRAYER].position = { i, j };
@ -1362,15 +1326,14 @@ void LoadL4Dungeon(const char *path, int vx, int vy)
InitDungeonFlags();
auto dunData = LoadFileInMem<uint16_t>(path);
SetRoom(dunData.get(), { 0, 0 });
PlaceDunTiles(dunData.get(), { 0, 0 }, 6);
ViewPosition = { vx, vy };
Pass3();
DRLG_Init_Globals();
SetMapMonsters(dunData.get(), { 0, 0 });
SetMapMonsters(dunData.get(), Point(0, 0).megaToWorld());
SetMapObjects(dunData.get(), 0, 0);
}
@ -1382,8 +1345,7 @@ void LoadPreL4Dungeon(const char *path)
InitDungeonFlags();
auto dunData = LoadFileInMem<uint16_t>(path);
SetRoom(dunData.get(), { 0, 0 });
PlaceDunTiles(dunData.get(), { 0, 0 }, 6);
}
} // namespace devilution

12
Source/drlg_l4.h

@ -9,14 +9,10 @@
namespace devilution {
extern int diabquad1x;
extern int diabquad1y;
extern int diabquad2x;
extern int diabquad2y;
extern int diabquad3x;
extern int diabquad3y;
extern int diabquad4x;
extern int diabquad4y;
extern Point DiabloQuad1;
extern Point DiabloQuad2;
extern Point DiabloQuad3;
extern Point DiabloQuad4;
void CreateL4Dungeon(uint32_t rseed, lvl_entry entry);
void LoadL4Dungeon(const char *path, int vx, int vy);
void LoadPreL4Dungeon(const char *path);

158
Source/gendung.cpp

@ -23,11 +23,8 @@ namespace devilution {
uint8_t dungeon[DMAXX][DMAXY];
uint8_t pdungeon[DMAXX][DMAXY];
bool Protected[DMAXX][DMAXY];
Rectangle SetPiecesRoom;
int setpc_x;
int setpc_y;
int setpc_w;
int setpc_h;
Rectangle SetPieceRoom;
Rectangle SetPiece;
std::unique_ptr<uint16_t[]> pSetPiece;
bool setloadflag;
std::optional<OwnedCelSprite> pSpecialCels;
@ -175,10 +172,10 @@ bool WillThemeRoomFit(int floor, int x, int y, int minSize, int maxSize, int *wi
void CreateThemeRoom(int themeIndex)
{
const int lx = themeLoc[themeIndex].x;
const int ly = themeLoc[themeIndex].y;
const int hx = lx + themeLoc[themeIndex].width;
const int hy = ly + themeLoc[themeIndex].height;
const int lx = themeLoc[themeIndex].room.position.x;
const int ly = themeLoc[themeIndex].room.position.y;
const int hx = lx + themeLoc[themeIndex].room.size.width;
const int hy = ly + themeLoc[themeIndex].room.size.height;
for (int yy = ly; yy < hy; yy++) {
for (int xx = lx; xx < hx; xx++) {
@ -477,24 +474,31 @@ void DRLG_InitTrans()
TransVal = 1;
}
void DRLG_RectTrans(int x1, int y1, int x2, int y2)
void DRLG_RectTrans(Rectangle area)
{
for (int j = y1; j <= y2; j++) {
for (int i = x1; i <= x2; i++) {
Point position = area.position;
Size size = area.size;
for (int j = position.y; j <= position.y + size.height; j++) {
for (int i = position.x; i <= position.x + size.width; i++) {
dTransVal[i][j] = TransVal;
}
}
TransVal++;
}
void DRLG_MRectTrans(int x1, int y1, int x2, int y2)
void DRLG_MRectTrans(Rectangle area)
{
x1 = 2 * x1 + 16 + 1;
y1 = 2 * y1 + 16 + 1;
x2 = 2 * x2 + 16;
y2 = 2 * y2 + 16;
Point position = area.position.megaToWorld();
Size size = area.size * 2;
DRLG_RectTrans({ position + Displacement { 1, 1 }, { size.width - 1, size.height - 1 } });
}
DRLG_RectTrans(x1, y1, x2, y2);
void DRLG_MRectTrans(Point origin, Point extent)
{
DRLG_MRectTrans({ origin, { extent.x - origin.x, extent.y - origin.y } });
}
void DRLG_CopyTrans(int sx, int sy, int dx, int dy)
@ -504,37 +508,23 @@ void DRLG_CopyTrans(int sx, int sy, int dx, int dy)
void DRLG_InitSetPC()
{
SetPiecesRoom = { { -1, -1 }, { -1, -1 } };
setpc_x = 0;
setpc_y = 0;
setpc_w = 0;
setpc_h = 0;
SetPieceRoom = { { -1, -1 }, { -1, -1 } };
SetPiece = { { 0, 0 }, { 0, 0 } };
}
void DRLG_SetPC()
{
int w = 2 * setpc_w;
int h = 2 * setpc_h;
int x = 2 * setpc_x + 16;
int y = 2 * setpc_y + 16;
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
dFlags[i + x][j + y] |= DungeonFlag::Populated;
}
}
Make_SetPC(SetPiece);
}
void Make_SetPC(int x, int y, int w, int h)
void Make_SetPC(Rectangle area)
{
int dw = 2 * w;
int dh = 2 * h;
int dx = 2 * x + 16;
int dy = 2 * y + 16;
for (int j = 0; j < dh; j++) {
for (int i = 0; i < dw; i++) {
dFlags[i + dx][j + dy] |= DungeonFlag::Populated;
Point position = area.position.megaToWorld();
Size size = area.size * 2;
for (int j = 0; j < size.height; j++) {
for (int i = 0; i < size.width; i++) {
dFlags[position.x + i][position.y + j] |= DungeonFlag::Populated;
}
}
}
@ -543,30 +533,26 @@ std::optional<Point> PlaceMiniSet(const Miniset &miniset, int tries, bool drlg1Q
{
int sw = miniset.size.width;
int sh = miniset.size.height;
int sx = GenerateRnd(DMAXX - sw);
int sy = GenerateRnd(DMAXY - sh);
for (int bailcnt = 0;; bailcnt++, sx++) {
if (bailcnt > tries)
return {};
if (sx == DMAXX - sw) {
sx = 0;
sy++;
if (sy == DMAXY - sh) {
sy = 0;
Point position { GenerateRnd(DMAXX - sw), GenerateRnd(DMAXY - sh) };
for (int i = 0; i < tries; i++, position.x++) {
if (position.x == DMAXX - sw) {
position.x = 0;
position.y++;
if (position.y == DMAXY - sh) {
position.y = 0;
}
}
// Limit the position of SetPieces for compatibility with Diablo bug
if (drlg1Quirk) {
bool valid = true;
if (sx <= 12) {
sx++;
if (position.x <= 12) {
position.x++;
valid = false;
}
if (sy <= 12) {
sy++;
if (position.y <= 12) {
position.y++;
valid = false;
}
if (!valid) {
@ -574,15 +560,37 @@ std::optional<Point> PlaceMiniSet(const Miniset &miniset, int tries, bool drlg1Q
}
}
if (SetPiecesRoom.Contains({ sx, sy }))
if (SetPieceRoom.Contains(position))
continue;
if (miniset.matches({ sx, sy }))
break;
if (!miniset.matches(position))
continue;
miniset.place(position);
return position;
}
miniset.place({ sx, sy });
return {};
}
return Point(sx, sy);
void PlaceDunTiles(const uint16_t *dunData, Point position, int floorId)
{
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
const uint16_t *tileLayer = &dunData[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(tileLayer[j * width + i]));
if (tileId != 0) {
dungeon[position.x + i][position.y + j] = tileId;
Protected[position.x + i][position.y + j] = true;
} else if (floorId != 0) {
dungeon[position.x + i][position.y + j] = floorId;
}
}
}
}
void DRLG_PlaceThemeRooms(int minSize, int maxSize, int floor, int freq, bool rndSize)
@ -604,27 +612,25 @@ void DRLG_PlaceThemeRooms(int minSize, int maxSize, int floor, int freq, bool rn
if (themeH < min || themeH > max)
themeH = min;
}
themeLoc[themeCount].x = i + 1;
themeLoc[themeCount].y = j + 1;
themeLoc[themeCount].width = themeW;
themeLoc[themeCount].height = themeH;
if (IsAnyOf(leveltype, DTYPE_CAVES, DTYPE_NEST))
DRLG_RectTrans(2 * i + 20, 2 * j + 20, 2 * (i + themeW) + 15, 2 * (j + themeH) + 15);
else
DRLG_MRectTrans(i + 1, j + 1, i + themeW, j + themeH);
themeLoc[themeCount].room = { { i + 1, j + 1 }, { themeW, themeH } };
if (IsAnyOf(leveltype, DTYPE_CAVES, DTYPE_NEST)) {
DRLG_RectTrans({ Point(i + 2, j + 2).megaToWorld(), { themeW * 2 - 5, themeH * 2 - 5 } });
} else {
DRLG_MRectTrans({ { i + 1, j + 1 }, { themeW - 1, themeH - 1 } });
}
themeLoc[themeCount].ttval = TransVal - 1;
CreateThemeRoom(themeCount);
themeCount++;
}
}
}
}
} // namespace
void DRLG_HoldThemeRooms()
{
for (int i = 0; i < themeCount; i++) {
for (int y = themeLoc[i].y; y < themeLoc[i].y + themeLoc[i].height - 1; y++) {
for (int x = themeLoc[i].x; x < themeLoc[i].x + themeLoc[i].width - 1; x++) {
for (int y = themeLoc[i].room.position.y; y < themeLoc[i].room.position.y + themeLoc[i].room.size.height - 1; y++) {
for (int x = themeLoc[i].room.position.x; x < themeLoc[i].room.position.x + themeLoc[i].room.size.width - 1; x++) {
int xx = 2 * x + 16;
int yy = 2 * y + 16;
dFlags[xx][yy] |= DungeonFlag::Populated;
@ -697,8 +703,8 @@ void DRLG_Init_Globals()
bool SkipThemeRoom(int x, int y)
{
for (int i = 0; i < themeCount; i++) {
if (x >= themeLoc[i].x - 2 && x <= themeLoc[i].x + themeLoc[i].width + 2
&& y >= themeLoc[i].y - 2 && y <= themeLoc[i].y + themeLoc[i].height + 2)
if (x >= themeLoc[i].room.position.x - 2 && x <= themeLoc[i].room.position.x + themeLoc[i].room.size.width + 2
&& y >= themeLoc[i].room.position.y - 2 && y <= themeLoc[i].room.position.y + themeLoc[i].room.size.height + 2)
return false;
}

27
Source/gendung.h

@ -97,11 +97,8 @@ struct ScrollStruct {
};
struct THEME_LOC {
int16_t x;
int16_t y;
Rectangle room;
int16_t ttval;
int16_t width;
int16_t height;
};
struct MegaTile {
@ -131,15 +128,9 @@ extern DVL_API_FOR_TEST uint8_t dungeon[DMAXX][DMAXY];
extern uint8_t pdungeon[DMAXX][DMAXY];
/** Tile that may not be overwritten by the level generator */
extern bool Protected[DMAXX][DMAXY];
extern Rectangle SetPiecesRoom;
/** Specifies the active set level X-coordinate of the map. */
extern int setpc_x;
/** Specifies the active set level Y-coordinate of the map. */
extern int setpc_y;
/** Specifies the width of the active set level of the map. */
extern int setpc_w;
/** Specifies the height of the active set level of the map. */
extern int setpc_h;
extern Rectangle SetPieceRoom;
/** Specifies the active set quest piece in coordinate. */
extern Rectangle SetPiece;
/** Contains the contents of the single player quest DUN file. */
extern std::unique_ptr<uint16_t[]> pSetPiece;
/** Specifies whether a single player quest DUN has been loaded. */
@ -330,17 +321,19 @@ struct Miniset {
void FillSolidBlockTbls();
void SetDungeonMicros();
void DRLG_InitTrans();
void DRLG_MRectTrans(int x1, int y1, int x2, int y2);
void DRLG_RectTrans(int x1, int y1, int x2, int y2);
void DRLG_MRectTrans(Point origin, Point extent);
void DRLG_MRectTrans(Rectangle area);
void DRLG_RectTrans(Rectangle area);
void DRLG_CopyTrans(int sx, int sy, int dx, int dy);
void DRLG_InitSetPC();
void DRLG_SetPC();
void Make_SetPC(int x, int y, int w, int h);
void Make_SetPC(Rectangle area);
/**
* @param tries Tiles to try, 1600 will scan the full map
* @param drlg1Quirk Match buggy behaviour of Diablo's Cathedral
*/
std::optional<Point> PlaceMiniSet(const Miniset &miniset, int tries = 198, bool drlg1Quirk = false);
std::optional<Point> PlaceMiniSet(const Miniset &miniset, int tries = 199, bool drlg1Quirk = false);
void PlaceDunTiles(const uint16_t *dunData, Point position, int floorId = 0);
void DRLG_PlaceThemeRooms(int minSize, int maxSize, int floor, int freq, bool rndSize);
void DRLG_HoldThemeRooms();
void DRLG_LPass3(int lv);

2
Source/items.cpp

@ -2318,7 +2318,7 @@ void InitItems()
if (Quests[Q_ROCK].IsAvailable())
SpawnRock();
if (Quests[Q_ANVIL].IsAvailable())
SpawnQuestItem(IDI_ANVIL, { 2 * setpc_x + 27, 2 * setpc_y + 27 }, 0, 1);
SpawnQuestItem(IDI_ANVIL, SetPiece.position.megaToWorld() + Displacement { 11, 11 }, 0, 1);
if (sgGameInitInfo.bCowQuest != 0 && currlevel == 20)
SpawnQuestItem(IDI_BROWNSUIT, { 25, 25 }, 3, 1);
if (sgGameInitInfo.bCowQuest != 0 && currlevel == 19)

120
Source/monster.cpp

@ -18,6 +18,7 @@
#include "drlg_l4.h"
#include "engine/cel_header.hpp"
#include "engine/load_file.hpp"
#include "engine/points_in_rectangle_range.hpp"
#include "engine/random.hpp"
#include "engine/render/cl2_render.hpp"
#include "init.h"
@ -284,26 +285,17 @@ void InitMonster(Monster &monster, Direction rd, int mtype, Point position)
}
}
bool CanPlaceMonster(int xp, int yp)
bool CanPlaceMonster(Point position)
{
if (!InDungeonBounds({ xp, yp })
|| dMonster[xp][yp] != 0
|| dPlayer[xp][yp] != 0) {
return false;
}
if (IsTileVisible({ xp, yp })) {
return false;
}
if (TileContainsSetPiece({ xp, yp })) {
return false;
}
return !IsTileOccupied({ xp, yp });
return InDungeonBounds(position)
&& dMonster[position.x][position.y] == 0
&& dPlayer[position.x][position.y] == 0
&& !IsTileVisible(position)
&& !TileContainsSetPiece(position)
&& !IsTileOccupied(position);
}
void PlaceMonster(int i, int mtype, int x, int y)
void PlaceMonster(int i, int mtype, Point position)
{
if (LevelMonsterTypes[mtype].mtype == MT_NAKRUL) {
for (int j = 0; j < ActiveMonsterCount; j++) {
@ -315,10 +307,10 @@ void PlaceMonster(int i, int mtype, int x, int y)
}
}
}
dMonster[x][y] = i + 1;
dMonster[position.x][position.y] = i + 1;
auto rd = static_cast<Direction>(GenerateRnd(8));
InitMonster(Monsters[i], rd, mtype, { x, y });
InitMonster(Monsters[i], rd, mtype, position);
}
void PlaceGroup(int mtype, int num, UniqueMonsterPack uniqueMonsterPack, int leaderId)
@ -346,7 +338,7 @@ void PlaceGroup(int mtype, int num, UniqueMonsterPack uniqueMonsterPack, int lea
do {
xp = GenerateRnd(80) + 16;
yp = GenerateRnd(80) + 16;
} while (!CanPlaceMonster(xp, yp));
} while (!CanPlaceMonster({ xp, yp }));
}
int x1 = xp;
int y1 = yp;
@ -357,14 +349,14 @@ void PlaceGroup(int mtype, int num, UniqueMonsterPack uniqueMonsterPack, int lea
int j = 0;
for (int try2 = 0; j < num && try2 < 100; xp += Displacement(static_cast<Direction>(GenerateRnd(8))).deltaX, yp += Displacement(static_cast<Direction>(GenerateRnd(8))).deltaX) { /// BUGFIX: `yp += Point.y`
if (!CanPlaceMonster(xp, yp)
if (!CanPlaceMonster({ xp, yp })
|| (dTransVal[xp][yp] != dTransVal[x1][y1])
|| (uniqueMonsterPack == UniqueMonsterPack::Leashed && (abs(xp - x1) >= 4 || abs(yp - y1) >= 4))) {
try2++;
continue;
}
PlaceMonster(ActiveMonsterCount, mtype, xp, yp);
PlaceMonster(ActiveMonsterCount, mtype, { xp, yp });
if (uniqueMonsterPack != UniqueMonsterPack::None) {
auto &minion = Monsters[ActiveMonsterCount];
minion._mmaxhp *= 2;
@ -412,15 +404,13 @@ void PlaceUniqueMonst(int uniqindex, int miniontype, int bosspacksize)
}
int count = 0;
int xp;
int yp;
Point position;
while (true) {
xp = GenerateRnd(80) + 16;
yp = GenerateRnd(80) + 16;
position = Point { GenerateRnd(80), GenerateRnd(80) } + Displacement { 16, 16 };
int count2 = 0;
for (int x = xp - 3; x < xp + 3; x++) {
for (int y = yp - 3; y < yp + 3; y++) {
if (InDungeonBounds({ x, y }) && CanPlaceMonster(x, y)) {
for (int x = position.x - 3; x < position.x + 3; x++) {
for (int y = position.y - 3; y < position.y + 3; y++) {
if (InDungeonBounds({ x, y }) && CanPlaceMonster({ x, y })) {
count2++;
}
}
@ -433,66 +423,51 @@ void PlaceUniqueMonst(int uniqindex, int miniontype, int bosspacksize)
}
}
if (CanPlaceMonster(xp, yp)) {
if (CanPlaceMonster(position)) {
break;
}
}
if (uniqindex == UMT_SNOTSPIL) {
xp = 2 * setpc_x + 24;
yp = 2 * setpc_y + 28;
position = SetPiece.position.megaToWorld() + Displacement { 8, 12 };
}
if (uniqindex == UMT_WARLORD) {
xp = 2 * setpc_x + 22;
yp = 2 * setpc_y + 23;
position = SetPiece.position.megaToWorld() + Displacement { 6, 7 };
}
if (uniqindex == UMT_ZHAR) {
for (int i = 0; i < themeCount; i++) {
if (i == zharlib) {
xp = 2 * themeLoc[i].x + 20;
yp = 2 * themeLoc[i].y + 20;
position = themeLoc[i].room.position.megaToWorld() + Displacement { 4, 4 };
break;
}
}
}
if (!gbIsMultiplayer) {
if (uniqindex == UMT_LAZARUS) {
xp = 32;
yp = 46;
position = { 32, 46 };
}
if (uniqindex == UMT_RED_VEX) {
xp = 40;
yp = 45;
position = { 40, 45 };
}
if (uniqindex == UMT_BLACKJADE) {
xp = 38;
yp = 49;
position = { 38, 49 };
}
if (uniqindex == UMT_SKELKING) {
xp = 35;
yp = 47;
position = { 35, 47 };
}
} else {
if (uniqindex == UMT_LAZARUS) {
xp = 2 * setpc_x + 19;
yp = 2 * setpc_y + 22;
position = SetPiece.position.megaToWorld() + Displacement { 3, 6 };
}
if (uniqindex == UMT_RED_VEX) {
xp = 2 * setpc_x + 21;
yp = 2 * setpc_y + 19;
position = SetPiece.position.megaToWorld() + Displacement { 5, 3 };
}
if (uniqindex == UMT_BLACKJADE) {
xp = 2 * setpc_x + 21;
yp = 2 * setpc_y + 25;
position = SetPiece.position.megaToWorld() + Displacement { 5, 9 };
}
}
if (uniqindex == UMT_BUTCHER) {
bool done = false;
for (yp = 0; yp < MAXDUNY && !done; yp++) {
for (xp = 0; xp < MAXDUNX && !done; xp++) {
done = dPiece[xp][yp] == 367;
}
}
position = SetPiece.position.megaToWorld() + Displacement { 4, 4 };
}
if (uniqindex == UMT_NAKRUL) {
@ -500,11 +475,10 @@ void PlaceUniqueMonst(int uniqindex, int miniontype, int bosspacksize)
UberDiabloMonsterIndex = -1;
return;
}
xp = UberRow - 2;
yp = UberCol;
position = { UberRow - 2, UberCol };
UberDiabloMonsterIndex = ActiveMonsterCount;
}
PlaceMonster(ActiveMonsterCount, uniqtype, xp, yp);
PlaceMonster(ActiveMonsterCount, uniqtype, position);
PrepareUniqueMonst(monster, uniqindex, miniontype, bosspacksize, uniqueMonsterData);
}
@ -608,23 +582,23 @@ void PlaceQuestMonsters()
if (Quests[Q_LTBANNER].IsAvailable()) {
auto dunData = LoadFileInMem<uint16_t>("Levels\\L1Data\\Banner1.DUN");
SetMapMonsters(dunData.get(), Point { setpc_x, setpc_y } * 2);
SetMapMonsters(dunData.get(), SetPiece.position.megaToWorld());
}
if (Quests[Q_BLOOD].IsAvailable()) {
auto dunData = LoadFileInMem<uint16_t>("Levels\\L2Data\\Blood2.DUN");
SetMapMonsters(dunData.get(), Point { setpc_x, setpc_y } * 2);
SetMapMonsters(dunData.get(), SetPiece.position.megaToWorld());
}
if (Quests[Q_BLIND].IsAvailable()) {
auto dunData = LoadFileInMem<uint16_t>("Levels\\L2Data\\Blind2.DUN");
SetMapMonsters(dunData.get(), Point { setpc_x, setpc_y } * 2);
SetMapMonsters(dunData.get(), SetPiece.position.megaToWorld());
}
if (Quests[Q_ANVIL].IsAvailable()) {
auto dunData = LoadFileInMem<uint16_t>("Levels\\L3Data\\Anvil.DUN");
SetMapMonsters(dunData.get(), Point { setpc_x + 1, setpc_y + 1 } * 2);
SetMapMonsters(dunData.get(), SetPiece.position.megaToWorld() + Displacement { 2, 2 });
}
if (Quests[Q_WARLORD].IsAvailable()) {
auto dunData = LoadFileInMem<uint16_t>("Levels\\L4Data\\Warlord.DUN");
SetMapMonsters(dunData.get(), Point { setpc_x, setpc_y } * 2);
SetMapMonsters(dunData.get(), SetPiece.position.megaToWorld());
AddMonsterType(UniqueMonstersData[UMT_WARLORD].mtype, PLACE_SCATTER);
}
if (Quests[Q_VEIL].IsAvailable()) {
@ -641,7 +615,7 @@ void PlaceQuestMonsters()
PlaceUniqueMonst(UMT_RED_VEX, 0, 0);
PlaceUniqueMonst(UMT_BLACKJADE, 0, 0);
auto dunData = LoadFileInMem<uint16_t>("Levels\\L4Data\\Vile1.DUN");
SetMapMonsters(dunData.get(), Point { setpc_x, setpc_y } * 2);
SetMapMonsters(dunData.get(), SetPiece.position.megaToWorld());
}
if (currlevel == 24) {
@ -673,19 +647,19 @@ void LoadDiabMonsts()
{
{
auto dunData = LoadFileInMem<uint16_t>("Levels\\L4Data\\diab1.DUN");
SetMapMonsters(dunData.get(), Point { diabquad1x, diabquad1y } * 2);
SetMapMonsters(dunData.get(), DiabloQuad1.megaToWorld());
}
{
auto dunData = LoadFileInMem<uint16_t>("Levels\\L4Data\\diab2a.DUN");
SetMapMonsters(dunData.get(), Point { diabquad2x, diabquad2y } * 2);
SetMapMonsters(dunData.get(), DiabloQuad2.megaToWorld());
}
{
auto dunData = LoadFileInMem<uint16_t>("Levels\\L4Data\\diab3a.DUN");
SetMapMonsters(dunData.get(), Point { diabquad3x, diabquad3y } * 2);
SetMapMonsters(dunData.get(), DiabloQuad3.megaToWorld());
}
{
auto dunData = LoadFileInMem<uint16_t>("Levels\\L4Data\\diab4a.DUN");
SetMapMonsters(dunData.get(), Point { diabquad4x, diabquad4y } * 2);
SetMapMonsters(dunData.get(), DiabloQuad4.megaToWorld());
}
}
@ -1645,10 +1619,10 @@ bool MonsterTalk(Monster &monster)
}
if (monster._uniqtype - 1 == UMT_SNOTSPIL) {
if (monster.mtalkmsg == TEXT_BANNER10 && (monster._mFlags & MFLAG_QUEST_COMPLETE) == 0) {
ObjChangeMap(setpc_x, setpc_y, (setpc_w / 2) + setpc_x + 2, (setpc_h / 2) + setpc_y - 2);
ObjChangeMap(SetPiece.position.x, SetPiece.position.y, SetPiece.position.x + (SetPiece.size.width / 2) + 2, SetPiece.position.y + (SetPiece.size.height / 2) - 2);
auto tren = TransVal;
TransVal = 9;
DRLG_MRectTrans(setpc_x, setpc_y, (setpc_w / 2) + setpc_x + 4, setpc_y + (setpc_h / 2));
DRLG_MRectTrans({ SetPiece.position, { SetPiece.size.width / 2 + 4, SetPiece.size.height / 2 } });
TransVal = tren;
Quests[Q_LTBANNER]._qvar1 = 2;
if (Quests[Q_LTBANNER]._qactive == QUEST_INIT)
@ -2896,7 +2870,7 @@ void SnotSpilAi(int i)
if (IsTileVisible(monster.position.tile)) {
if (monster.mtalkmsg == TEXT_BANNER12) {
if (!effect_is_playing(USFX_SNOT3) && monster._mgoal == MGOAL_TALKING) {
ObjChangeMap(setpc_x, setpc_y, setpc_x + setpc_w + 1, setpc_y + setpc_h + 1);
ObjChangeMap(SetPiece.position.x, SetPiece.position.y, SetPiece.position.x + SetPiece.size.width + 1, SetPiece.position.y + SetPiece.size.height + 1);
Quests[Q_LTBANNER]._qvar1 = 3;
RedoPlayerVision();
monster._msquelch = UINT8_MAX;
@ -3899,7 +3873,7 @@ void SetMapMonsters(const uint16_t *dunData, Point startPosition)
auto monsterId = static_cast<uint8_t>(SDL_SwapLE16(monsterLayer[j * width + i]));
if (monsterId != 0) {
int mtype = AddMonsterType(MonstConvTbl[monsterId - 1], PLACE_SPECIAL);
PlaceMonster(ActiveMonsterCount++, mtype, i + startPosition.x + 16, j + startPosition.y + 16);
PlaceMonster(ActiveMonsterCount++, mtype, startPosition + Displacement { i, j });
}
}
}

113
Source/objects.cpp

@ -451,16 +451,14 @@ void AddCandles()
void AddBookLever(Rectangle affectedArea, _speech_id msg)
{
int cnt = 0;
int xp;
int yp;
Point position;
bool exit = false;
while (!exit) {
exit = true;
xp = GenerateRnd(80) + 16;
yp = GenerateRnd(80) + 16;
position = Point { GenerateRnd(80), GenerateRnd(80) } + Displacement { 16, 16 };
for (int n = -2; n <= 2; n++) {
for (int m = -2; m <= 2; m++) {
if (!RndLocOk(xp + m, yp + n))
if (!RndLocOk(position.x + m, position.y + n))
exit = false;
}
}
@ -472,15 +470,14 @@ void AddBookLever(Rectangle affectedArea, _speech_id msg)
}
if (Quests[Q_BLIND].IsAvailable())
AddObject(OBJ_BLINDBOOK, { xp, yp });
AddObject(OBJ_BLINDBOOK, position);
if (Quests[Q_WARLORD].IsAvailable())
AddObject(OBJ_STEELTOME, { xp, yp });
AddObject(OBJ_STEELTOME, position);
if (Quests[Q_BLOOD].IsAvailable()) {
xp = 2 * setpc_x + 25;
yp = 2 * setpc_y + 40;
AddObject(OBJ_BLOODBOOK, { xp, yp });
position = SetPiece.position.megaToWorld() + Displacement { 9, 24 };
AddObject(OBJ_BLOODBOOK, position);
}
ObjectAtPosition({ xp, yp })->InitializeQuestBook(affectedArea, leverid, msg);
ObjectAtPosition(position)->InitializeQuestBook(affectedArea, leverid, msg);
leverid++;
}
@ -648,7 +645,7 @@ void AddChestTraps()
}
}
void LoadMapObjects(const char *path, Point start, Rectangle mapRange, int leveridx)
void LoadMapObjects(const char *path, Point start, Rectangle mapRange = {}, int leveridx = 0)
{
LoadingMapObjects = true;
ApplyObjectLighting = true;
@ -666,46 +663,14 @@ void LoadMapObjects(const char *path, Point start, Rectangle mapRange, int lever
const uint16_t *objectLayer = &dunData[layer2Offset + width * height * 2];
start += Displacement { 16, 16 };
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto objectId = static_cast<uint8_t>(SDL_SwapLE16(objectLayer[j * width + i]));
if (objectId != 0) {
Point mapPos = start + Displacement { i, j };
AddObject(ObjTypeConv[objectId], mapPos);
ObjectAtPosition(mapPos)->InitializeLoadedObject(mapRange, leveridx);
}
}
}
ApplyObjectLighting = false;
LoadingMapObjects = false;
}
void LoadMapObjs(const char *path, Point start)
{
LoadingMapObjects = true;
ApplyObjectLighting = true;
auto dunData = LoadFileInMem<uint16_t>(path);
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
int layer2Offset = 2 + width * height;
// The rest of the layers are at dPiece scale
width *= 2;
height *= 2;
const uint16_t *objectLayer = &dunData[layer2Offset + width * height * 2];
start += Displacement { 16, 16 };
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto objectId = static_cast<uint8_t>(SDL_SwapLE16(objectLayer[j * width + i]));
if (objectId != 0) {
AddObject(ObjTypeConv[objectId], start + Displacement { i, j });
if (leveridx > 0)
ObjectAtPosition(mapPos)->InitializeLoadedObject(mapRange, leveridx);
}
}
}
@ -716,9 +681,9 @@ void LoadMapObjs(const char *path, Point start)
void AddDiabObjs()
{
LoadMapObjects("Levels\\L4Data\\diab1.DUN", { 2 * diabquad1x, 2 * diabquad1y }, { { diabquad2x, diabquad2y }, { 11, 12 } }, 1);
LoadMapObjects("Levels\\L4Data\\diab2a.DUN", { 2 * diabquad2x, 2 * diabquad2y }, { { diabquad3x, diabquad3y }, { 11, 11 } }, 2);
LoadMapObjects("Levels\\L4Data\\diab3a.DUN", { 2 * diabquad3x, 2 * diabquad3y }, { { diabquad4x, diabquad4y }, { 9, 9 } }, 3);
LoadMapObjects("Levels\\L4Data\\diab1.DUN", DiabloQuad1.megaToWorld(), { DiabloQuad2, { 11, 12 } }, 1);
LoadMapObjects("Levels\\L4Data\\diab2a.DUN", DiabloQuad2.megaToWorld(), { DiabloQuad3, { 11, 11 } }, 2);
LoadMapObjects("Levels\\L4Data\\diab3a.DUN", DiabloQuad3.megaToWorld(), { DiabloQuad4, { 9, 9 } }, 3);
}
void AddCryptObject(Object &object, int a2)
@ -1337,10 +1302,10 @@ void AddBrnCross(int i)
void AddPedistal(int i)
{
Objects[i]._oVar1 = setpc_x;
Objects[i]._oVar2 = setpc_y;
Objects[i]._oVar3 = setpc_x + setpc_w;
Objects[i]._oVar4 = setpc_y + setpc_h;
Objects[i]._oVar1 = SetPiece.position.x;
Objects[i]._oVar2 = SetPiece.position.y;
Objects[i]._oVar3 = SetPiece.position.x + SetPiece.size.width;
Objects[i]._oVar4 = SetPiece.position.y + SetPiece.size.height;
Objects[i]._oVar6 = 0;
}
@ -2327,8 +2292,6 @@ void OperateBook(int pnum, Object &book)
void OperateBookLever(int pnum, int i)
{
int x = 2 * setpc_x + 16;
int y = 2 * setpc_y + 16;
if (ActiveItemCount >= MAXITEMS) {
return;
}
@ -2342,7 +2305,7 @@ void OperateBookLever(int pnum, int i)
Quests[Q_BLOOD]._qactive = QUEST_ACTIVE;
Quests[Q_BLOOD]._qlog = true;
Quests[Q_BLOOD]._qvar1 = 1;
SpawnQuestItem(IDI_BLDSTONE, { 2 * setpc_x + 25, 2 * setpc_y + 33 }, 0, 1);
SpawnQuestItem(IDI_BLDSTONE, SetPiece.position.megaToWorld() + Displacement { 9, 17 }, 0, 1);
}
if (Objects[i]._otype == OBJ_STEELTOME && Quests[Q_WARLORD]._qvar1 == 0) {
Quests[Q_WARLORD]._qactive = QUEST_ACTIVE;
@ -2353,10 +2316,10 @@ void OperateBookLever(int pnum, int i)
if (Objects[i]._otype != OBJ_BLOODBOOK)
ObjChangeMap(Objects[i]._oVar1, Objects[i]._oVar2, Objects[i]._oVar3, Objects[i]._oVar4);
if (Objects[i]._otype == OBJ_BLINDBOOK) {
SpawnUnique(UITEM_OPTAMULET, Point { x, y } + Displacement { 5, 5 });
SpawnUnique(UITEM_OPTAMULET, SetPiece.position.megaToWorld() + Displacement { 5, 5 });
auto tren = TransVal;
TransVal = 9;
DRLG_MRectTrans(Objects[i]._oVar1, Objects[i]._oVar2, Objects[i]._oVar3, Objects[i]._oVar4);
DRLG_MRectTrans({ Objects[i]._oVar1, Objects[i]._oVar2 }, { Objects[i]._oVar3, Objects[i]._oVar4 });
TransVal = tren;
}
}
@ -2643,21 +2606,21 @@ void OperatePedistal(int pnum, int i)
if (Objects[i]._oVar6 == 1) {
if (!deltaload)
PlaySfxLoc(LS_PUDDLE, Objects[i].position);
ObjChangeMap(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7);
SpawnQuestItem(IDI_BLDSTONE, { 2 * setpc_x + 19, 2 * setpc_y + 26 }, 0, 1);
ObjChangeMap(SetPiece.position.x, SetPiece.position.y + 3, SetPiece.position.x + 2, SetPiece.position.y + 7);
SpawnQuestItem(IDI_BLDSTONE, SetPiece.position.megaToWorld() + Displacement { 3, 10 }, 0, 1);
}
if (Objects[i]._oVar6 == 2) {
if (!deltaload)
PlaySfxLoc(LS_PUDDLE, Objects[i].position);
ObjChangeMap(setpc_x + 6, setpc_y + 3, setpc_x + setpc_w, setpc_y + 7);
SpawnQuestItem(IDI_BLDSTONE, { 2 * setpc_x + 31, 2 * setpc_y + 26 }, 0, 1);
ObjChangeMap(SetPiece.position.x + 6, SetPiece.position.y + 3, SetPiece.position.x + SetPiece.size.width, SetPiece.position.y + 7);
SpawnQuestItem(IDI_BLDSTONE, SetPiece.position.megaToWorld() + Displacement { 15, 10 }, 0, 1);
}
if (Objects[i]._oVar6 == 3) {
if (!deltaload)
PlaySfxLoc(LS_BLODSTAR, Objects[i].position);
ObjChangeMap(Objects[i]._oVar1, Objects[i]._oVar2, Objects[i]._oVar3, Objects[i]._oVar4);
LoadMapObjs("Levels\\L2Data\\Blood2.DUN", { 2 * setpc_x, 2 * setpc_y });
SpawnUnique(UITEM_ARMOFVAL, Point { setpc_x, setpc_y } * 2 + Displacement { 25, 19 });
LoadMapObjects("Levels\\L2Data\\Blood2.DUN", SetPiece.position.megaToWorld());
SpawnUnique(UITEM_ARMOFVAL, SetPiece.position.megaToWorld() + Displacement { 9, 3 });
Objects[i]._oSelFlag = 0;
}
}
@ -4240,7 +4203,7 @@ void SyncQSTLever(const Object &qstLever)
if (qstLever._otype == OBJ_BLINDBOOK) {
auto tren = TransVal;
TransVal = 9;
DRLG_MRectTrans(qstLever._oVar1, qstLever._oVar2, qstLever._oVar3, qstLever._oVar4);
DRLG_MRectTrans({ qstLever._oVar1, qstLever._oVar2 }, { qstLever._oVar3, qstLever._oVar4 });
TransVal = tren;
}
}
@ -4256,7 +4219,7 @@ void SyncPedestal(const Object &pedestal, Point origin, int width)
}
if (pedestal._oVar6 == 3) {
ObjChangeMapResync(pedestal._oVar1, pedestal._oVar2, pedestal._oVar3, pedestal._oVar4);
LoadMapObjs("Levels\\L2Data\\Blood2.DUN", origin * 2);
LoadMapObjects("Levels\\L2Data\\Blood2.DUN", origin.megaToWorld());
}
}
@ -4570,7 +4533,7 @@ void InitObjects()
if (Quests[Q_PWATER].IsAvailable())
AddCandles();
if (Quests[Q_LTBANNER].IsAvailable())
AddObject(OBJ_SIGNCHEST, { 2 * setpc_x + 26, 2 * setpc_y + 19 });
AddObject(OBJ_SIGNCHEST, SetPiece.position.megaToWorld() + Displacement { 10, 3 });
InitRndLocBigObj(10, 15, OBJ_SARC);
AddL1Objs(0, 0, MAXDUNX, MAXDUNY);
InitRndBarrels();
@ -4605,8 +4568,8 @@ void InitObjects()
break;
}
Quests[Q_BLIND]._qmsg = spId;
AddBookLever({ { setpc_x, setpc_y }, { setpc_w + 1, setpc_h + 1 } }, spId);
LoadMapObjs("Levels\\L2Data\\Blind2.DUN", { 2 * setpc_x, 2 * setpc_y });
AddBookLever({ SetPiece.position, { SetPiece.size.width + 1, SetPiece.size.height + 1 } }, spId);
LoadMapObjects("Levels\\L2Data\\Blind2.DUN", SetPiece.position.megaToWorld());
}
if (Quests[Q_BLOOD].IsAvailable()) {
_speech_id spId;
@ -4631,8 +4594,8 @@ void InitObjects()
break;
}
Quests[Q_BLOOD]._qmsg = spId;
AddBookLever({ { setpc_x, setpc_y + 3 }, { 2, 4 } }, spId);
AddObject(OBJ_PEDISTAL, { 2 * setpc_x + 25, 2 * setpc_y + 32 });
AddBookLever({ { SetPiece.position + Displacement { 0, 3 } }, { 2, 4 } }, spId);
AddObject(OBJ_PEDISTAL, SetPiece.position.megaToWorld() + Displacement { 9, 16 });
}
InitRndBarrels();
}
@ -4664,8 +4627,8 @@ void InitObjects()
break;
}
Quests[Q_WARLORD]._qmsg = spId;
AddBookLever({ { setpc_x, setpc_y }, { setpc_w, setpc_h } }, spId);
LoadMapObjs("Levels\\L4Data\\Warlord.DUN", { 2 * setpc_x, 2 * setpc_y });
AddBookLever(SetPiece, spId);
LoadMapObjects("Levels\\L4Data\\Warlord.DUN", SetPiece.position.megaToWorld());
}
if (Quests[Q_BETRAYER].IsAvailable() && !gbIsMultiplayer)
AddLazStand();
@ -4779,7 +4742,7 @@ void AddObject(_object_id objType, Point objPos)
InitializeL5Door(object);
break;
case OBJ_BOOK2R:
object.InitializeBook({ { setpc_x, setpc_y }, { setpc_w + 1, setpc_h + 1 } });
object.InitializeBook({ SetPiece.position, { SetPiece.size.width + 1, SetPiece.size.height + 1 } });
break;
case OBJ_CHEST1:
case OBJ_CHEST2:
@ -5479,7 +5442,7 @@ void SyncObjectAnim(Object &object)
SyncQSTLever(object);
break;
case OBJ_PEDISTAL:
SyncPedestal(object, { setpc_x, setpc_y }, setpc_w);
SyncPedestal(object, SetPiece.position, SetPiece.size.width);
break;
default:
break;

116
Source/quests.cpp

@ -126,9 +126,8 @@ int QuestGroup4[2] = { Q_VEIL, Q_WARLORD };
*/
void DrawButcher()
{
int x = 2 * setpc_x + 16;
int y = 2 * setpc_y + 16;
DRLG_RectTrans(x + 3, y + 3, x + 10, y + 10);
Point position = SetPiece.position.megaToWorld() + Displacement { 3, 3 };
DRLG_RectTrans({ position, { 7, 7 } });
}
void DrawSkelKing(quest_id q, Point position)
@ -140,44 +139,18 @@ void DrawWarLord(Point position)
{
auto dunData = LoadFileInMem<uint16_t>("Levels\\L4Data\\Warlord2.DUN");
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
SetPiece = { position, { SDL_SwapLE16(dunData[0]), SDL_SwapLE16(dunData[1]) } };
setpc_x = position.x;
setpc_y = position.y;
setpc_w = width;
setpc_h = height;
const uint16_t *tileLayer = &dunData[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(tileLayer[j * width + i]));
dungeon[position.x + i][position.y + j] = (tileId != 0) ? tileId : 6;
}
}
PlaceDunTiles(dunData.get(), position, 6);
}
void DrawSChamber(quest_id q, Point position)
{
auto dunData = LoadFileInMem<uint16_t>("Levels\\L2Data\\Bonestr1.DUN");
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
SetPiece = { position, { SDL_SwapLE16(dunData[0]), SDL_SwapLE16(dunData[1]) } };
setpc_x = position.x;
setpc_y = position.y;
setpc_w = width;
setpc_h = height;
const uint16_t *tileLayer = &dunData[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(tileLayer[j * width + i]));
dungeon[position.x + i][position.y + j] = (tileId != 0) ? tileId : 3;
}
}
PlaceDunTiles(dunData.get(), position, 3);
Quests[q].position = position.megaToWorld() + Displacement { 6, 7 };
}
@ -189,10 +162,7 @@ void DrawLTBanner(Point position)
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
setpc_x = position.x;
setpc_y = position.y;
setpc_w = width;
setpc_h = height;
SetPiece = { position, { SDL_SwapLE16(dunData[0]), SDL_SwapLE16(dunData[1]) } };
const uint16_t *tileLayer = &dunData[2];
@ -206,52 +176,22 @@ void DrawLTBanner(Point position)
}
}
/**
* Close outer wall
*/
void DrawBlind(Point position)
{
auto dunData = LoadFileInMem<uint16_t>("Levels\\L2Data\\Blind1.DUN");
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
setpc_x = position.x;
setpc_y = position.y;
setpc_w = width;
setpc_h = height;
const uint16_t *tileLayer = &dunData[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(tileLayer[j * width + i]));
if (tileId != 0) {
pdungeon[position.x + i][position.y + j] = tileId;
}
}
}
dungeon[position.x][position.y + 1] = 154;
dungeon[position.x + 10][position.y + 8] = 154;
}
void DrawBlood(Point position)
{
auto dunData = LoadFileInMem<uint16_t>("Levels\\L2Data\\Blood2.DUN");
int width = SDL_SwapLE16(dunData[0]);
int height = SDL_SwapLE16(dunData[1]);
setpc_x = position.x;
setpc_y = position.y;
setpc_w = width;
setpc_h = height;
SetPiece = { position, { SDL_SwapLE16(dunData[0]), SDL_SwapLE16(dunData[1]) } };
const uint16_t *tileLayer = &dunData[2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
auto tileId = static_cast<uint8_t>(SDL_SwapLE16(tileLayer[j * width + i]));
if (tileId != 0) {
dungeon[position.x + i][position.y + j] = tileId;
}
}
}
PlaceDunTiles(dunData.get(), position, 0);
}
int QuestLogMouseToEntry()
@ -375,7 +315,7 @@ void CheckQuests()
auto &quest = Quests[Q_BETRAYER];
if (quest.IsAvailable() && gbIsMultiplayer && quest._qvar1 == 2) {
AddObject(OBJ_ALTBOY, Point(setpc_x, setpc_y).megaToWorld() + Displacement { 4, 6 });
AddObject(OBJ_ALTBOY, SetPiece.position.megaToWorld() + Displacement { 4, 6 });
quest._qvar1 = 3;
NetSendCmdQuest(true, quest);
}
@ -636,7 +576,7 @@ void ResyncMPQuests()
NetSendCmdQuest(true, betrayerQuest);
}
if (betrayerQuest.IsAvailable())
AddObject(OBJ_ALTBOY, Point(setpc_x, setpc_y).megaToWorld() + Displacement { 4, 6 });
AddObject(OBJ_ALTBOY, SetPiece.position.megaToWorld() + Displacement { 4, 6 });
auto &cryptQuest = Quests[Q_GRAVE];
if (cryptQuest._qactive == QUEST_INIT && currlevel == cryptQuest._qlevel - 1) {
@ -665,32 +605,32 @@ void ResyncQuests()
if (Quests[Q_LTBANNER].IsAvailable()) {
if (Quests[Q_LTBANNER]._qvar1 == 1) {
ObjChangeMapResync(
setpc_w + setpc_x - 2,
setpc_h + setpc_y - 2,
setpc_w + setpc_x + 1,
setpc_h + setpc_y + 1);
SetPiece.position.x + SetPiece.size.width - 2,
SetPiece.position.y + SetPiece.size.height - 2,
SetPiece.position.x + SetPiece.size.width + 1,
SetPiece.position.y + SetPiece.size.height + 1);
}
if (Quests[Q_LTBANNER]._qvar1 == 2) {
ObjChangeMapResync(
setpc_w + setpc_x - 2,
setpc_h + setpc_y - 2,
setpc_w + setpc_x + 1,
setpc_h + setpc_y + 1);
ObjChangeMapResync(setpc_x, setpc_y, (setpc_w / 2) + setpc_x + 2, (setpc_h / 2) + setpc_y - 2);
SetPiece.position.x + SetPiece.size.width - 2,
SetPiece.position.y + SetPiece.size.height - 2,
SetPiece.position.x + SetPiece.size.width + 1,
SetPiece.position.y + SetPiece.size.height + 1);
ObjChangeMapResync(SetPiece.position.x, SetPiece.position.y, SetPiece.position.x + (SetPiece.size.width / 2) + 2, SetPiece.position.y + (SetPiece.size.height / 2) - 2);
for (int i = 0; i < ActiveObjectCount; i++)
SyncObjectAnim(Objects[ActiveObjects[i]]);
auto tren = TransVal;
TransVal = 9;
DRLG_MRectTrans(setpc_x, setpc_y, (setpc_w / 2) + setpc_x + 4, setpc_y + (setpc_h / 2));
DRLG_MRectTrans({ SetPiece.position, { SetPiece.size.width / 2 + 4, SetPiece.size.height / 2 } });
TransVal = tren;
}
if (Quests[Q_LTBANNER]._qvar1 == 3) {
ObjChangeMapResync(setpc_x, setpc_y, setpc_x + setpc_w + 1, setpc_y + setpc_h + 1);
ObjChangeMapResync(SetPiece.position.x, SetPiece.position.y, SetPiece.position.x + SetPiece.size.width + 1, SetPiece.position.y + SetPiece.size.height + 1);
for (int i = 0; i < ActiveObjectCount; i++)
SyncObjectAnim(Objects[ActiveObjects[i]]);
auto tren = TransVal;
TransVal = 9;
DRLG_MRectTrans(setpc_x, setpc_y, (setpc_w / 2) + setpc_x + 4, setpc_y + (setpc_h / 2));
DRLG_MRectTrans({ SetPiece.position, { SetPiece.size.width / 2 + 4, SetPiece.size.height / 2 } });
TransVal = tren;
}
}

Loading…
Cancel
Save