diff --git a/Source/automap.cpp b/Source/automap.cpp index d0a1afa51..9f6468d8f 100644 --- a/Source/automap.cpp +++ b/Source/automap.cpp @@ -537,17 +537,17 @@ std::unique_ptr LoadAutomapData(size_t &tileCount) { switch (leveltype) { case DTYPE_CATHEDRAL: - if (currlevel < 21) - return LoadFileInMem("Levels\\L1Data\\L1.AMP", &tileCount); - return LoadFileInMem("NLevels\\L5Data\\L5.AMP", &tileCount); + return LoadFileInMem("Levels\\L1Data\\L1.AMP", &tileCount); case DTYPE_CATACOMBS: return LoadFileInMem("Levels\\L2Data\\L2.AMP", &tileCount); case DTYPE_CAVES: - if (currlevel < 17) - return LoadFileInMem("Levels\\L3Data\\L3.AMP", &tileCount); - return LoadFileInMem("NLevels\\L6Data\\L6.AMP", &tileCount); + return LoadFileInMem("Levels\\L3Data\\L3.AMP", &tileCount); case DTYPE_HELL: return LoadFileInMem("Levels\\L4Data\\L4.AMP", &tileCount); + case DTYPE_NEST: + return LoadFileInMem("NLevels\\L6Data\\L6.AMP", &tileCount); + case DTYPE_CRYPT: + return LoadFileInMem("NLevels\\L5Data\\L5.AMP", &tileCount); default: return nullptr; } diff --git a/Source/diablo.cpp b/Source/diablo.cpp index be05adb9f..06712851e 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -1079,17 +1079,10 @@ void LoadLvlGFX() pSpecialCels = LoadCel("Levels\\TownData\\TownS.CEL", SpecialCelWidth); break; case DTYPE_CATHEDRAL: - if (currlevel < 21) { - pDungeonCels = LoadFileInMem("Levels\\L1Data\\L1.CEL"); - pMegaTiles = LoadFileInMem("Levels\\L1Data\\L1.TIL"); - pLevelPieces = LoadFileInMem("Levels\\L1Data\\L1.MIN"); - pSpecialCels = LoadCel("Levels\\L1Data\\L1S.CEL", SpecialCelWidth); - } else { - pDungeonCels = LoadFileInMem("NLevels\\L5Data\\L5.CEL"); - pMegaTiles = LoadFileInMem("NLevels\\L5Data\\L5.TIL"); - pLevelPieces = LoadFileInMem("NLevels\\L5Data\\L5.MIN"); - pSpecialCels = LoadCel("NLevels\\L5Data\\L5S.CEL", SpecialCelWidth); - } + pDungeonCels = LoadFileInMem("Levels\\L1Data\\L1.CEL"); + pMegaTiles = LoadFileInMem("Levels\\L1Data\\L1.TIL"); + pLevelPieces = LoadFileInMem("Levels\\L1Data\\L1.MIN"); + pSpecialCels = LoadCel("Levels\\L1Data\\L1S.CEL", SpecialCelWidth); break; case DTYPE_CATACOMBS: pDungeonCels = LoadFileInMem("Levels\\L2Data\\L2.CEL"); @@ -1098,15 +1091,9 @@ void LoadLvlGFX() pSpecialCels = LoadCel("Levels\\L2Data\\L2S.CEL", SpecialCelWidth); break; case DTYPE_CAVES: - if (currlevel < 17) { - pDungeonCels = LoadFileInMem("Levels\\L3Data\\L3.CEL"); - pMegaTiles = LoadFileInMem("Levels\\L3Data\\L3.TIL"); - pLevelPieces = LoadFileInMem("Levels\\L3Data\\L3.MIN"); - } else { - pDungeonCels = LoadFileInMem("NLevels\\L6Data\\L6.CEL"); - pMegaTiles = LoadFileInMem("NLevels\\L6Data\\L6.TIL"); - pLevelPieces = LoadFileInMem("NLevels\\L6Data\\L6.MIN"); - } + pDungeonCels = LoadFileInMem("Levels\\L3Data\\L3.CEL"); + pMegaTiles = LoadFileInMem("Levels\\L3Data\\L3.TIL"); + pLevelPieces = LoadFileInMem("Levels\\L3Data\\L3.MIN"); pSpecialCels = LoadCel("Levels\\L1Data\\L1S.CEL", SpecialCelWidth); break; case DTYPE_HELL: @@ -1115,6 +1102,18 @@ void LoadLvlGFX() pLevelPieces = LoadFileInMem("Levels\\L4Data\\L4.MIN"); pSpecialCels = LoadCel("Levels\\L2Data\\L2S.CEL", SpecialCelWidth); break; + case DTYPE_NEST: + pDungeonCels = LoadFileInMem("NLevels\\L6Data\\L6.CEL"); + pMegaTiles = LoadFileInMem("NLevels\\L6Data\\L6.TIL"); + pLevelPieces = LoadFileInMem("NLevels\\L6Data\\L6.MIN"); + pSpecialCels = LoadCel("Levels\\L1Data\\L1S.CEL", SpecialCelWidth); + break; + case DTYPE_CRYPT: + pDungeonCels = LoadFileInMem("NLevels\\L5Data\\L5.CEL"); + pMegaTiles = LoadFileInMem("NLevels\\L5Data\\L5.TIL"); + pLevelPieces = LoadFileInMem("NLevels\\L5Data\\L5.MIN"); + pSpecialCels = LoadCel("NLevels\\L5Data\\L5S.CEL", SpecialCelWidth); + break; default: app_fatal("LoadLvlGFX"); } @@ -1142,43 +1141,34 @@ void CreateLevel(lvl_entry lvldir) case DTYPE_TOWN: CreateTown(lvldir); InitTownTriggers(); - LoadRndLvlPal(DTYPE_TOWN); break; case DTYPE_CATHEDRAL: + case DTYPE_CRYPT: CreateL5Dungeon(glSeedTbl[currlevel], lvldir); InitL1Triggers(); Freeupstairs(); - if (currlevel < 21) { - LoadRndLvlPal(DTYPE_CATHEDRAL); - } else { - LoadRndLvlPal(DTYPE_CRYPT); - } break; case DTYPE_CATACOMBS: CreateL2Dungeon(glSeedTbl[currlevel], lvldir); InitL2Triggers(); Freeupstairs(); - LoadRndLvlPal(DTYPE_CATACOMBS); break; case DTYPE_CAVES: + case DTYPE_NEST: CreateL3Dungeon(glSeedTbl[currlevel], lvldir); InitL3Triggers(); Freeupstairs(); - if (currlevel < 17) { - LoadRndLvlPal(DTYPE_CAVES); - } else { - LoadRndLvlPal(DTYPE_NEST); - } break; case DTYPE_HELL: CreateL4Dungeon(glSeedTbl[currlevel], lvldir); InitL4Triggers(); Freeupstairs(); - LoadRndLvlPal(DTYPE_HELL); break; default: app_fatal("CreateLevel"); } + + LoadRndLvlPal(leveltype); } void UnstuckChargers() @@ -2054,11 +2044,7 @@ void DisableInputWndProc(uint32_t uMsg, int32_t /*wParam*/, int32_t lParam) void LoadGameLevel(bool firstflag, lvl_entry lvldir) { - _music_id neededTrack; - if (currlevel >= 17) - neededTrack = currlevel > 20 ? TMUSIC_L5 : TMUSIC_L6; - else - neededTrack = static_cast<_music_id>(leveltype); + _music_id neededTrack = static_cast<_music_id>(leveltype); if (neededTrack != sgnMusicTrack) music_stop(); @@ -2167,8 +2153,7 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir) IncProgress(); InitMonsters(); InitItems(); - if (currlevel < 17) - CreateThemeRooms(); + CreateThemeRooms(); IncProgress(); [[maybe_unused]] uint32_t mid3Seed = GetLCGEngineState(); InitMissiles(); @@ -2352,16 +2337,18 @@ void diablo_color_cyc_logic() if (PauseMode != 0) return; - if (leveltype == DTYPE_HELL) { + if (leveltype == DTYPE_CAVES) { + if (setlevel && setlvlnum == Quests[Q_PWATER]._qslvl) { + UpdatePWaterPalette(); + } else { + palette_update_caves(); + } + } else if (leveltype == DTYPE_HELL) { lighting_color_cycling(); - } else if (currlevel >= 21) { - palette_update_crypt(); - } else if (currlevel >= 17) { + } else if (leveltype == DTYPE_NEST) { palette_update_hive(); - } else if (setlevel && setlvlnum == Quests[Q_PWATER]._qslvl) { - UpdatePWaterPalette(); - } else if (leveltype == DTYPE_CAVES) { - palette_update_caves(); + } else if (leveltype == DTYPE_CRYPT) { + palette_update_crypt(); } } diff --git a/Source/gamemenu.cpp b/Source/gamemenu.cpp index 04e0ea978..441db66ef 100644 --- a/Source/gamemenu.cpp +++ b/Source/gamemenu.cpp @@ -193,15 +193,7 @@ void GamemenuMusicVolume(bool bActivate) } else { gbMusicOn = true; sound_get_or_set_music_volume(VOLUME_MAX); - int lt; - if (currlevel >= 17) { - if (currlevel > 20) - lt = TMUSIC_L5; - else - lt = TMUSIC_L6; - } else - lt = leveltype; - music_start(lt); + music_start((_music_id)leveltype); } } else { int volume = GamemenuSliderMusicSound(&sgOptionsMenu[0]); @@ -213,15 +205,7 @@ void GamemenuMusicVolume(bool bActivate) } } else if (!gbMusicOn) { gbMusicOn = true; - int lt; - if (currlevel >= 17) { - if (currlevel > 20) - lt = TMUSIC_L5; - else - lt = TMUSIC_L6; - } else - lt = leveltype; - music_start(lt); + music_start((_music_id)leveltype); } } diff --git a/Source/gendung.cpp b/Source/gendung.cpp index 015ee295d..8362340ca 100644 --- a/Source/gendung.cpp +++ b/Source/gendung.cpp @@ -70,17 +70,17 @@ std::unique_ptr LoadLevelSOLData(size_t &tileCount) return LoadFileInMem("NLevels\\TownData\\Town.SOL", &tileCount); return LoadFileInMem("Levels\\TownData\\Town.SOL", &tileCount); case DTYPE_CATHEDRAL: - if (currlevel < 17) - return LoadFileInMem("Levels\\L1Data\\L1.SOL", &tileCount); - return LoadFileInMem("NLevels\\L5Data\\L5.SOL", &tileCount); + return LoadFileInMem("Levels\\L1Data\\L1.SOL", &tileCount); case DTYPE_CATACOMBS: return LoadFileInMem("Levels\\L2Data\\L2.SOL", &tileCount); case DTYPE_CAVES: - if (currlevel < 17) - return LoadFileInMem("Levels\\L3Data\\L3.SOL", &tileCount); - return LoadFileInMem("NLevels\\L6Data\\L6.SOL", &tileCount); + return LoadFileInMem("Levels\\L3Data\\L3.SOL", &tileCount); case DTYPE_HELL: return LoadFileInMem("Levels\\L4Data\\L4.SOL", &tileCount); + case DTYPE_NEST: + return LoadFileInMem("NLevels\\L6Data\\L6.SOL", &tileCount); + case DTYPE_CRYPT: + return LoadFileInMem("NLevels\\L5Data\\L5.SOL", &tileCount); default: app_fatal("FillSolidBlockTbls"); } @@ -185,7 +185,7 @@ void CreateThemeRoom(int themeIndex) dungeon[xx][yy] = 3; } } - if (leveltype == DTYPE_CAVES) { + if (IsAnyOf(leveltype, DTYPE_CAVES, DTYPE_NEST)) { if (yy == ly || yy == hy - 1) { dungeon[xx][yy] = 134; } else if (xx == lx || xx == hx - 1) { @@ -212,7 +212,7 @@ void CreateThemeRoom(int themeIndex) dungeon[lx][hy - 1] = 9; dungeon[hx - 1][hy - 1] = 6; } - if (leveltype == DTYPE_CAVES) { + if (IsAnyOf(leveltype, DTYPE_CAVES, DTYPE_NEST)) { dungeon[lx][ly] = 150; dungeon[hx - 1][ly] = 151; dungeon[lx][hy - 1] = 152; @@ -235,7 +235,7 @@ void CreateThemeRoom(int themeIndex) break; } } - if (leveltype == DTYPE_CAVES) { + if (IsAnyOf(leveltype, DTYPE_CAVES, DTYPE_NEST)) { switch (GenerateRnd(2)) { case 0: dungeon[hx - 1][(ly + hy) / 2] = 147; @@ -540,7 +540,7 @@ void DRLG_PlaceThemeRooms(int minSize, int maxSize, int floor, int freq, bool rn themeLoc[themeCount].y = j + 1; themeLoc[themeCount].width = themeW; themeLoc[themeCount].height = themeH; - if (leveltype == DTYPE_CAVES) + 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); diff --git a/Source/interfac.cpp b/Source/interfac.cpp index be3046a53..939492346 100644 --- a/Source/interfac.cpp +++ b/Source/interfac.cpp @@ -66,17 +66,17 @@ Cutscenes PickCutscene(interface_mode uMsg) case DTYPE_TOWN: return CutTown; case DTYPE_CATHEDRAL: - if (lvl > 16) - return CutLevel5; return CutLevel1; case DTYPE_CATACOMBS: return CutLevel2; case DTYPE_CAVES: - if (lvl > 16) - return CutLevel6; return CutLevel3; case DTYPE_HELL: return CutLevel4; + case DTYPE_NEST: + return CutLevel6; + case DTYPE_CRYPT: + return CutLevel5; default: return CutLevel1; } diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index 3bcbf4c97..389bc7c75 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -729,9 +729,48 @@ void LoadMissile(LoadHelper *file) } } +_object_id ConvertFromHellfireObject(_object_id type) +{ + if (leveltype == DTYPE_NEST) { + switch (type) { + case OBJ_BARREL: + return OBJ_POD; + case OBJ_BARRELEX: + return OBJ_PODEX; + default: + break; + } + } + + if (leveltype == DTYPE_CRYPT) { + switch (type) { + case OBJ_BARREL: + return OBJ_URN; + case OBJ_BARRELEX: + return OBJ_URNEX; + case OBJ_STORYBOOK: + return OBJ_L5BOOKS; + case OBJ_STORYCANDLE: + return OBJ_L5CANDLE; + case OBJ_L1LDOOR: + return OBJ_L5LDOOR; + case OBJ_L1RDOOR: + return OBJ_L5RDOOR; + case OBJ_LEVER: + return OBJ_L5LEVER; + case OBJ_SARC: + return OBJ_L5SARC; + default: + break; + } + } + + return type; +} + void LoadObject(LoadHelper &file, Object &object) { - object._otype = static_cast<_object_id>(file.NextLE()); + object._otype = ConvertFromHellfireObject(static_cast<_object_id>(file.NextLE())); object.position.x = file.NextLE(); object.position.y = file.NextLE(); object._oLight = file.NextBool32(); @@ -931,6 +970,17 @@ void LoadDroppedItems(LoadHelper &file, size_t savedItemCount) } } +int getHellfireLevelType(int type) +{ + if (type == DTYPE_CRYPT) + return DTYPE_CATHEDRAL; + + if (type == DTYPE_NEST) + return DTYPE_CAVES; + + return type; +} + void SaveItem(SaveHelper &file, const Item &item) { auto idx = item.IDidx; @@ -1401,9 +1451,48 @@ void SaveMissile(SaveHelper *file, const Missile &missile) file->WriteLE(missile.limitReached ? 1 : 0); } +_object_id ConvertToHellfireObject(_object_id type) +{ + if (leveltype == DTYPE_NEST) { + switch (type) { + case OBJ_POD: + return OBJ_BARREL; + case OBJ_PODEX: + return OBJ_BARRELEX; + default: + break; + } + } + + if (leveltype == DTYPE_CRYPT) { + switch (type) { + case OBJ_URN: + return OBJ_BARREL; + case OBJ_URNEX: + return OBJ_BARRELEX; + case OBJ_L5BOOKS: + return OBJ_STORYBOOK; + case OBJ_L5CANDLE: + return OBJ_STORYCANDLE; + case OBJ_L5LDOOR: + return OBJ_L1LDOOR; + case OBJ_L5RDOOR: + return OBJ_L1RDOOR; + case OBJ_L5LEVER: + return OBJ_LEVER; + case OBJ_L5SARC: + return OBJ_SARC; + default: + break; + } + } + + return type; +} + void SaveObject(SaveHelper &file, const Object &object) { - file.WriteLE(object._otype); + file.WriteLE(ConvertToHellfireObject(object._otype)); file.WriteLE(object.position.x); file.WriteLE(object.position.y); file.WriteLE(object._oLight ? 1 : 0); @@ -2162,7 +2251,7 @@ void SaveGameData() file.WriteLE(setlevel ? 1 : 0); file.WriteBE(setlvlnum); file.WriteBE(currlevel); - file.WriteBE(leveltype); + file.WriteBE(getHellfireLevelType(leveltype)); file.WriteBE(ViewPosition.x); file.WriteBE(ViewPosition.y); file.WriteLE(invflag ? 1 : 0); @@ -2177,7 +2266,7 @@ void SaveGameData() for (uint8_t i = 0; i < giNumberOfLevels; i++) { file.WriteBE(glSeedTbl[i]); - file.WriteBE(gnLevelTypeTbl[i]); + file.WriteBE(getHellfireLevelType(gnLevelTypeTbl[i])); } auto &myPlayer = Players[MyPlayerId]; diff --git a/Source/menu.cpp b/Source/menu.cpp index 29218d89a..fda304bdf 100644 --- a/Source/menu.cpp +++ b/Source/menu.cpp @@ -21,7 +21,7 @@ uint32_t gSaveNumber; namespace { /** The active music track id for the main menu. */ -uint8_t menu_music_track_id = TMUSIC_INTRO; +_music_id menu_music_track_id = TMUSIC_INTRO; void RefreshMusic() { @@ -31,13 +31,16 @@ void RefreshMusic() return; } + int nextTrack = (int)menu_music_track_id; do { - menu_music_track_id++; - if (menu_music_track_id == NUM_MUSIC || (!gbIsHellfire && menu_music_track_id > TMUSIC_L4)) - menu_music_track_id = TMUSIC_L2; - if (gbIsSpawn && menu_music_track_id > TMUSIC_L1) - menu_music_track_id = TMUSIC_L5; - } while (menu_music_track_id == TMUSIC_TOWN || menu_music_track_id == TMUSIC_L1); + nextTrack++; + if (nextTrack == NUM_MUSIC || (!gbIsHellfire && nextTrack > TMUSIC_HELL)) + nextTrack = TMUSIC_CATACOMBS; + if (gbIsSpawn && nextTrack > TMUSIC_CATHEDRAL) + nextTrack = TMUSIC_NEST; + } while (nextTrack == TMUSIC_TOWN || nextTrack == TMUSIC_CATHEDRAL); + + menu_music_track_id = (_music_id)nextTrack; } bool InitMenu(_selhero_selections type) diff --git a/Source/monster.cpp b/Source/monster.cpp index 3a46e86b7..bd8f1a5eb 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -4139,7 +4139,7 @@ void DoEnding() int musicVolume = sound_get_or_set_music_volume(1); sound_get_or_set_music_volume(0); - music_start(TMUSIC_L2); + music_start(TMUSIC_CATACOMBS); loop_movie = true; play_movie("gendata\\loopdend.smk", true); loop_movie = false; diff --git a/Source/multi.cpp b/Source/multi.cpp index dfd197007..5125794d1 100644 --- a/Source/multi.cpp +++ b/Source/multi.cpp @@ -351,10 +351,10 @@ dungeon_type InitLevelType(int l) return DTYPE_CAVES; if (l >= 13 && l <= 16) return DTYPE_HELL; - if (l >= 21 && l <= 24) - return DTYPE_CATHEDRAL; // Crypt if (l >= 17 && l <= 20) - return DTYPE_CAVES; // Hive + return DTYPE_NEST; + if (l >= 21 && l <= 24) + return DTYPE_CRYPT; return DTYPE_CATHEDRAL; } diff --git a/Source/objdat.cpp b/Source/objdat.cpp index 093e5bbf1..6ce2199cc 100644 --- a/Source/objdat.cpp +++ b/Source/objdat.cpp @@ -148,115 +148,131 @@ const _object_id ObjTypeConv[] = { OBJ_LAZSTAND, OBJ_BOOKSTAND, OBJ_BOOKSHELFR, + OBJ_POD, + OBJ_PODEX, + OBJ_URN, + OBJ_URNEX, + OBJ_L5BOOKS, + OBJ_L5CANDLE, + OBJ_L5LEVER, + OBJ_L5SARC, }; /** Contains the data related to each object ID. */ -const ObjectData AllObjects[] = { +const ObjectData AllObjects[109] = { // clang-format off - // oload, ofindex, ominlvl, omaxlvl, olvltype, otheme, oquest, oAnimFlag, oAnimDelay, oAnimLen, oAnimWidth, oSolidFlag, oMissFlag, oLightFlag, oBreak, oSelFlag, oTrapFlag - { 1, OFILE_L1BRAZ, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 1, 1, 26, 64, true, true, false, 0, 0, false }, - { 1, OFILE_L1DOORS, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 0, 1, 0, 64, false, false, true, 0, 3, true }, - { 1, OFILE_L1DOORS, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 0, 2, 0, 64, false, false, true, 0, 3, true }, - { 3, OFILE_SKULFIRE, 0, 0, DTYPE_NONE, THEME_SKELROOM, Q_INVALID, 1, 2, 11, 96, true, true, false, 0, 0, false }, - { 1, OFILE_LEVER, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 0, 1, 1, 96, true, true, true, 0, 1, true }, - { 1, OFILE_CHEST1, 1, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, - { 1, OFILE_CHEST2, 1, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, - { 1, OFILE_CHEST3, 1, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, - { 2, OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, - { 3, OFILE_CANDLE2, 0, 0, DTYPE_NONE, THEME_SHRINE, Q_INVALID, 1, 2, 4, 96, true, true, true, 0, 0, false }, - { 2, OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, - { 3, OFILE_BANNER, 0, 0, DTYPE_NONE, THEME_SKELROOM, Q_INVALID, 0, 2, 0, 96, true, true, true, 0, 0, false }, - { 3, OFILE_BANNER, 0, 0, DTYPE_NONE, THEME_SKELROOM, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 0, false }, - { 3, OFILE_BANNER, 0, 0, DTYPE_NONE, THEME_SKELROOM, Q_INVALID, 0, 3, 0, 96, true, true, true, 0, 0, false }, - { 2, OFILE_SKULPILE, 1, 4, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 1, 96, true, true, true, 0, 0, false }, - { 2, OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, - { 2, OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, - { 2, OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, - { 2, OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, - { 2, OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, - { 2, OFILE_CRUXSK1, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 15, 96, true, false, true, 1, 3, false }, - { 2, OFILE_CRUXSK2, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 15, 96, true, false, true, 1, 3, false }, - { 2, OFILE_CRUXSK3, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 15, 96, true, false, true, 1, 3, false }, - { 1, OFILE_ROCKSTAN, 5, 5, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 0, false }, - { 2, OFILE_ANGEL, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, false, true, 0, 0, false }, - { 2, OFILE_BOOK2, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 3, false }, - { 2, OFILE_BURNCROS, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 1, 0, 10, 160, true, false, false, 0, 0, false }, - { 2, OFILE_NUDE2, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 1, 3, 6, 128, true, false, true, 0, 0, false }, - { 1, OFILE_SWITCH4, 16, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, - { 1, OFILE_TNUDEM, 13, 16, DTYPE_NONE, THEME_NONE, Q_BUTCHER, 0, 1, 0, 128, true, false, true, 0, 0, false }, - { 1, OFILE_TNUDEM, 13, 16, DTYPE_NONE, THEME_TORTURE, Q_BUTCHER, 0, 2, 0, 128, true, false, true, 0, 0, false }, - { 1, OFILE_TNUDEM, 13, 16, DTYPE_NONE, THEME_TORTURE, Q_BUTCHER, 0, 3, 0, 128, true, false, true, 0, 0, false }, - { 1, OFILE_TNUDEM, 13, 16, DTYPE_NONE, THEME_TORTURE, Q_BUTCHER, 0, 4, 0, 128, true, false, true, 0, 0, false }, - { 1, OFILE_TNUDEW, 13, 16, DTYPE_NONE, THEME_TORTURE, Q_BUTCHER, 0, 1, 0, 128, true, false, true, 0, 0, false }, - { 1, OFILE_TNUDEW, 13, 16, DTYPE_NONE, THEME_TORTURE, Q_BUTCHER, 0, 2, 0, 128, true, false, true, 0, 0, false }, - { 1, OFILE_TNUDEW, 13, 16, DTYPE_NONE, THEME_TORTURE, Q_BUTCHER, 0, 3, 0, 128, true, false, true, 0, 0, false }, - { 1, OFILE_TSOUL, 13, 16, DTYPE_NONE, THEME_NONE, Q_BUTCHER, 0, 1, 0, 128, false, true, true, 0, 0, false }, - { 1, OFILE_TSOUL, 13, 16, DTYPE_NONE, THEME_NONE, Q_BUTCHER, 0, 2, 0, 128, false, true, true, 0, 0, false }, - { 1, OFILE_TSOUL, 13, 16, DTYPE_NONE, THEME_NONE, Q_BUTCHER, 0, 3, 0, 128, false, true, true, 0, 0, false }, - { 1, OFILE_TSOUL, 13, 16, DTYPE_NONE, THEME_NONE, Q_BUTCHER, 0, 4, 0, 128, false, true, true, 0, 0, false }, - { 1, OFILE_TSOUL, 13, 16, DTYPE_NONE, THEME_NONE, Q_BUTCHER, 0, 5, 0, 128, false, true, true, 0, 0, false }, - { 1, OFILE_BOOK2, 6, 6, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 4, 0, 96, true, true, true, 0, 3, false }, - { 1, OFILE_L2DOORS, 5, 8, DTYPE_CATACOMBS, THEME_NONE, Q_INVALID, 0, 1, 0, 64, false, false, true, 0, 3, true }, - { 1, OFILE_L2DOORS, 5, 8, DTYPE_CATACOMBS, THEME_NONE, Q_INVALID, 0, 2, 0, 64, false, false, true, 0, 3, true }, - { 1, OFILE_WTORCH4, 5, 8, DTYPE_CATACOMBS, THEME_NONE, Q_INVALID, 1, 1, 9, 96, false, true, false, 0, 0, false }, - { 1, OFILE_WTORCH3, 5, 8, DTYPE_CATACOMBS, THEME_NONE, Q_INVALID, 1, 1, 9, 96, false, true, false, 0, 0, false }, - { 1, OFILE_WTORCH1, 5, 8, DTYPE_CATACOMBS, THEME_NONE, Q_INVALID, 1, 1, 9, 96, false, true, false, 0, 0, false }, - { 1, OFILE_WTORCH2, 5, 8, DTYPE_CATACOMBS, THEME_NONE, Q_INVALID, 1, 1, 9, 96, false, true, false, 0, 0, false }, - { 1, OFILE_SARC, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 0, 1, 5, 128, true, true, true, 0, 3, true }, - { 2, OFILE_FLAME1, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 0, 1, 20, 96, false, true, true, 0, 0, false }, - { 2, OFILE_LEVER, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 0, 1, 2, 96, true, true, true, 0, 1, true }, - { 2, OFILE_MINIWATR, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 1, 1, 10, 64, true, false, true, 0, 0, false }, - { 1, OFILE_BOOK1, 3, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 3, false }, - { 1, OFILE_TRAPHOLE, 1, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 64, false, true, true, 0, 0, false }, - { 1, OFILE_TRAPHOLE, 1, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 2, 0, 64, false, true, true, 0, 0, false }, - { 2, OFILE_BCASE, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, false, true, 0, 0, false }, - { 2, OFILE_WEAPSTND, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, false, true, 0, 0, false }, - { 1, OFILE_BARREL, 1, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 9, 96, true, true, true, 1, 3, false }, - { 1, OFILE_BARRELEX, 1, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 10, 96, true, true, true, 1, 3, false }, - { 3, OFILE_LSHRINEG, 0, 0, DTYPE_NONE, THEME_SHRINE, Q_INVALID, 0, 1, 11, 128, false, false, true, 0, 3, false }, - { 3, OFILE_RSHRINEG, 0, 0, DTYPE_NONE, THEME_SHRINE, Q_INVALID, 0, 1, 11, 128, false, false, true, 0, 3, false }, - { 3, OFILE_BOOK2, 0, 0, DTYPE_NONE, THEME_SKELROOM, Q_INVALID, 0, 4, 0, 96, true, true, true, 0, 3, false }, - { 3, OFILE_BCASE, 0, 0, DTYPE_NONE, THEME_LIBRARY, Q_INVALID, 0, 3, 0, 96, false, false, true, 0, 3, false }, - { 3, OFILE_BCASE, 0, 0, DTYPE_NONE, THEME_LIBRARY, Q_INVALID, 0, 4, 0, 96, false, false, true, 0, 3, false }, - { 3, OFILE_BOOK2, 0, 0, DTYPE_NONE, THEME_LIBRARY, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 3, false }, - { 3, OFILE_CANDLE2, 0, 0, DTYPE_NONE, THEME_LIBRARY, Q_INVALID, 1, 2, 4, 96, true, true, true, 0, 0, false }, - { 3, OFILE_BLOODFNT, 0, 0, DTYPE_NONE, THEME_BLOODFOUNTAIN, Q_INVALID, 1, 2, 10, 96, true, true, true, 0, 3, false }, - { 1, OFILE_DECAP, 13, 16, DTYPE_NONE, THEME_DECAPITATED, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, false }, - { 1, OFILE_CHEST1, 1, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, - { 1, OFILE_CHEST2, 1, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, - { 1, OFILE_CHEST3, 1, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, - { 1, OFILE_BOOK1, 7, 7, DTYPE_CATACOMBS, THEME_NONE, Q_BLIND, 0, 1, 0, 96, true, true, true, 0, 3, false }, - { 1, OFILE_BOOK1, 5, 5, DTYPE_CATACOMBS, THEME_NONE, Q_BLOOD, 0, 4, 0, 96, true, true, true, 0, 3, false }, - { 1, OFILE_PEDISTL, 5, 5, DTYPE_CATACOMBS, THEME_NONE, Q_BLOOD, 0, 1, 0, 96, true, true, true, 0, 3, false }, - { 1, OFILE_L3DOORS, 9, 12, DTYPE_CAVES, THEME_NONE, Q_INVALID, 0, 1, 0, 64, false, false, true, 0, 3, true }, - { 1, OFILE_L3DOORS, 9, 12, DTYPE_CAVES, THEME_NONE, Q_INVALID, 0, 2, 0, 64, false, false, true, 0, 3, true }, - { 3, OFILE_PFOUNTN, 0, 0, DTYPE_NONE, THEME_PURIFYINGFOUNTAIN, Q_INVALID, 1, 2, 10, 128, true, true, true, 0, 3, false }, - { 3, OFILE_ARMSTAND, 0, 0, DTYPE_NONE, THEME_ARMORSTAND, Q_INVALID, 0, 1, 0, 96, true, false, true, 0, 3, false }, - { 3, OFILE_ARMSTAND, 0, 0, DTYPE_NONE, THEME_ARMORSTAND, Q_INVALID, 0, 2, 0, 96, true, false, true, 0, 0, false }, - { 3, OFILE_GOATSHRN, 0, 0, DTYPE_NONE, THEME_GOATSHRINE, Q_INVALID, 1, 2, 10, 96, true, true, true, 0, 3, false }, - { 1, OFILE_CAULDREN, 13, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, false, true, 0, 3, false }, - { 3, OFILE_MFOUNTN, 0, 0, DTYPE_NONE, THEME_MURKYFOUNTAIN, Q_INVALID, 1, 2, 10, 128, true, true, true, 0, 3, false }, - { 3, OFILE_TFOUNTN, 0, 0, DTYPE_NONE, THEME_TEARFOUNTAIN, Q_INVALID, 1, 2, 4, 128, true, true, true, 0, 3, false }, - { 1, OFILE_ALTBOY, 0, 0, DTYPE_CATHEDRAL, THEME_NONE, Q_BETRAYER, 0, 1, 0, 128, true, true, true, 0, 0, false }, - { 1, OFILE_MCIRL, 0, 0, DTYPE_CATHEDRAL, THEME_NONE, Q_BETRAYER, 0, 1, 0, 96, false, true, true, 0, 0, false }, - { 1, OFILE_MCIRL, 0, 0, DTYPE_CATHEDRAL, THEME_NONE, Q_BETRAYER, 0, 1, 0, 96, false, true, true, 0, 0, false }, - { 1, OFILE_BKSLBRNT, 1, 12, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 3, false }, // BUGFIX should only be loaded on level 1-12 (crypt masks as 1-4) (fixed) - { 1, OFILE_CANDLE2, 1, 12, DTYPE_NONE, THEME_NONE, Q_BETRAYER, 1, 2, 4, 96, true, true, true, 0, 0, false }, - { 1, OFILE_BOOK1, 13, 13, DTYPE_HELL, THEME_NONE, Q_WARLORD, 0, 4, 0, 96, true, true, true, 0, 3, false }, - { 1, OFILE_ARMSTAND, 13, 13, DTYPE_NONE, THEME_NONE, Q_WARLORD, 0, 1, 0, 96, true, false, true, 0, 3, false }, - { 2, OFILE_WEAPSTND, 13, 13, DTYPE_NONE, THEME_NONE, Q_WARLORD, 0, 1, 0, 96, true, false, true, 0, 3, false }, - { 2, OFILE_BURNCROS, 0, 0, DTYPE_NONE, THEME_BRNCROSS, Q_INVALID, 1, 0, 10, 160, true, false, false, 0, 0, false }, - { 2, OFILE_WEAPSTND, 0, 0, DTYPE_NONE, THEME_WEAPONRACK, Q_INVALID, 0, 1, 0, 96, true, false, true, 0, 3, false }, - { 2, OFILE_WEAPSTND, 0, 0, DTYPE_NONE, THEME_WEAPONRACK, Q_INVALID, 0, 2, 0, 96, true, false, true, 0, 0, false }, - { 2, OFILE_MUSHPTCH, 0, 0, DTYPE_NONE, THEME_NONE, Q_MUSHROOM, 0, 1, 0, 96, true, true, true, 0, 3, true }, - { 2, OFILE_LZSTAND, 0, 0, DTYPE_NONE, THEME_NONE, Q_BETRAYER, 0, 1, 0, 128, true, false, true, 0, 3, false }, - { 1, OFILE_DECAP, 9, 9, DTYPE_CAVES, THEME_NONE, Q_INVALID, 0, 2, 0, 96, true, true, true, 0, 1, false }, - { 2, OFILE_CHEST3, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, - { 2, OFILE_BCASE, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 2, 0, 96, true, false, true, 0, 0, false }, - { -1, OFILE_NULL, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, + // ofindex, ominlvl, omaxlvl, olvltype, otheme, oquest, oAnimFlag, oAnimDelay, oAnimLen, oAnimWidth, oSolidFlag, oMissFlag, oLightFlag, oBreak, oSelFlag, oTrapFlag + { OFILE_L1BRAZ, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 1, 1, 26, 64, true, true, false, 0, 0, false }, + { OFILE_L1DOORS, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 0, 1, 0, 64, false, false, true, 0, 3, true }, + { OFILE_L1DOORS, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 0, 2, 0, 64, false, false, true, 0, 3, true }, + { OFILE_SKULFIRE, 0, 0, DTYPE_NONE, THEME_SKELROOM, Q_INVALID, 1, 2, 11, 96, true, true, false, 0, 0, false }, + { OFILE_LEVER, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 0, 1, 1, 96, true, true, true, 0, 1, true }, + { OFILE_CHEST1, 1, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, + { OFILE_CHEST2, 1, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, + { OFILE_CHEST3, 1, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, + { OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, + { OFILE_CANDLE2, 0, 0, DTYPE_NONE, THEME_SHRINE, Q_INVALID, 1, 2, 4, 96, true, true, true, 0, 0, false }, + { OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, + { OFILE_BANNER, 0, 0, DTYPE_NONE, THEME_SKELROOM, Q_INVALID, 0, 2, 0, 96, true, true, true, 0, 0, false }, + { OFILE_BANNER, 0, 0, DTYPE_NONE, THEME_SKELROOM, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 0, false }, + { OFILE_BANNER, 0, 0, DTYPE_NONE, THEME_SKELROOM, Q_INVALID, 0, 3, 0, 96, true, true, true, 0, 0, false }, + { OFILE_SKULPILE, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 1, 96, true, true, true, 0, 0, false }, + { OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, + { OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, + { OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, + { OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, + { OFILE_L1BRAZ, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 0, 0, 0, false, false, false, 0, 0, false }, + { OFILE_CRUXSK1, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 15, 96, true, false, true, 1, 3, false }, + { OFILE_CRUXSK2, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 15, 96, true, false, true, 1, 3, false }, + { OFILE_CRUXSK3, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 15, 96, true, false, true, 1, 3, false }, + { OFILE_ROCKSTAN, 5, 5, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 0, false }, + { OFILE_ANGEL, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, false, true, 0, 0, false }, + { OFILE_BOOK2, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 3, false }, + { OFILE_BURNCROS, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 1, 0, 10, 160, true, false, false, 0, 0, false }, + { OFILE_NUDE2, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 1, 3, 6, 128, true, false, true, 0, 0, false }, + { OFILE_SWITCH4, 16, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, + { OFILE_TNUDEM, 13, 16, DTYPE_NONE, THEME_NONE, Q_BUTCHER, 0, 1, 0, 128, true, false, true, 0, 0, false }, + { OFILE_TNUDEM, 13, 16, DTYPE_NONE, THEME_TORTURE, Q_BUTCHER, 0, 2, 0, 128, true, false, true, 0, 0, false }, + { OFILE_TNUDEM, 13, 16, DTYPE_NONE, THEME_TORTURE, Q_BUTCHER, 0, 3, 0, 128, true, false, true, 0, 0, false }, + { OFILE_TNUDEM, 13, 16, DTYPE_NONE, THEME_TORTURE, Q_BUTCHER, 0, 4, 0, 128, true, false, true, 0, 0, false }, + { OFILE_TNUDEW, 13, 16, DTYPE_NONE, THEME_TORTURE, Q_BUTCHER, 0, 1, 0, 128, true, false, true, 0, 0, false }, + { OFILE_TNUDEW, 13, 16, DTYPE_NONE, THEME_TORTURE, Q_BUTCHER, 0, 2, 0, 128, true, false, true, 0, 0, false }, + { OFILE_TNUDEW, 13, 16, DTYPE_NONE, THEME_TORTURE, Q_BUTCHER, 0, 3, 0, 128, true, false, true, 0, 0, false }, + { OFILE_TSOUL, 13, 16, DTYPE_NONE, THEME_NONE, Q_BUTCHER, 0, 1, 0, 128, false, true, true, 0, 0, false }, + { OFILE_TSOUL, 13, 16, DTYPE_NONE, THEME_NONE, Q_BUTCHER, 0, 2, 0, 128, false, true, true, 0, 0, false }, + { OFILE_TSOUL, 13, 16, DTYPE_NONE, THEME_NONE, Q_BUTCHER, 0, 3, 0, 128, false, true, true, 0, 0, false }, + { OFILE_TSOUL, 13, 16, DTYPE_NONE, THEME_NONE, Q_BUTCHER, 0, 4, 0, 128, false, true, true, 0, 0, false }, + { OFILE_TSOUL, 13, 16, DTYPE_NONE, THEME_NONE, Q_BUTCHER, 0, 5, 0, 128, false, true, true, 0, 0, false }, + { OFILE_BOOK2, 6, 6, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 4, 0, 96, true, true, true, 0, 3, false }, + { OFILE_L2DOORS, 5, 8, DTYPE_CATACOMBS, THEME_NONE, Q_INVALID, 0, 1, 0, 64, false, false, true, 0, 3, true }, + { OFILE_L2DOORS, 5, 8, DTYPE_CATACOMBS, THEME_NONE, Q_INVALID, 0, 2, 0, 64, false, false, true, 0, 3, true }, + { OFILE_WTORCH4, 5, 8, DTYPE_CATACOMBS, THEME_NONE, Q_INVALID, 1, 1, 9, 96, false, true, false, 0, 0, false }, + { OFILE_WTORCH3, 5, 8, DTYPE_CATACOMBS, THEME_NONE, Q_INVALID, 1, 1, 9, 96, false, true, false, 0, 0, false }, + { OFILE_WTORCH1, 5, 8, DTYPE_CATACOMBS, THEME_NONE, Q_INVALID, 1, 1, 9, 96, false, true, false, 0, 0, false }, + { OFILE_WTORCH2, 5, 8, DTYPE_CATACOMBS, THEME_NONE, Q_INVALID, 1, 1, 9, 96, false, true, false, 0, 0, false }, + { OFILE_SARC, 1, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 0, 1, 5, 128, true, true, true, 0, 3, true }, + { OFILE_FLAME1, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 20, 96, false, true, true, 0, 0, false }, + { OFILE_LEVER, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 2, 96, true, true, true, 0, 1, true }, + { OFILE_MINIWATR, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 1, 1, 10, 64, true, false, true, 0, 0, false }, + { OFILE_BOOK1, 3, 4, DTYPE_CATHEDRAL, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 3, false }, + { OFILE_TRAPHOLE, 1, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 64, false, true, true, 0, 0, false }, + { OFILE_TRAPHOLE, 1, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 2, 0, 64, false, true, true, 0, 0, false }, + { OFILE_BCASE, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, false, true, 0, 0, false }, + { OFILE_WEAPSTND, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, false, true, 0, 0, false }, + { OFILE_BARREL, 1, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 9, 96, true, true, true, 1, 3, false }, + { OFILE_BARRELEX, 1, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 10, 96, true, true, true, 1, 3, false }, + { OFILE_LSHRINEG, 0, 0, DTYPE_NONE, THEME_SHRINE, Q_INVALID, 0, 1, 11, 128, false, false, true, 0, 3, false }, + { OFILE_RSHRINEG, 0, 0, DTYPE_NONE, THEME_SHRINE, Q_INVALID, 0, 1, 11, 128, false, false, true, 0, 3, false }, + { OFILE_BOOK2, 0, 0, DTYPE_NONE, THEME_SKELROOM, Q_INVALID, 0, 4, 0, 96, true, true, true, 0, 3, false }, + { OFILE_BCASE, 0, 0, DTYPE_NONE, THEME_LIBRARY, Q_INVALID, 0, 3, 0, 96, false, false, true, 0, 3, false }, + { OFILE_BCASE, 0, 0, DTYPE_NONE, THEME_LIBRARY, Q_INVALID, 0, 4, 0, 96, false, false, true, 0, 3, false }, + { OFILE_BOOK2, 0, 0, DTYPE_NONE, THEME_LIBRARY, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 3, false }, + { OFILE_CANDLE2, 0, 0, DTYPE_NONE, THEME_LIBRARY, Q_INVALID, 1, 2, 4, 96, true, true, true, 0, 0, false }, + { OFILE_BLOODFNT, 0, 0, DTYPE_NONE, THEME_BLOODFOUNTAIN, Q_INVALID, 1, 2, 10, 96, true, true, true, 0, 3, false }, + { OFILE_DECAP, 13, 16, DTYPE_NONE, THEME_DECAPITATED, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, false }, + { OFILE_CHEST1, 1, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, + { OFILE_CHEST2, 1, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, + { OFILE_CHEST3, 1, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, + { OFILE_BOOK1, 7, 7, DTYPE_CATACOMBS, THEME_NONE, Q_BLIND, 0, 1, 0, 96, true, true, true, 0, 3, false }, + { OFILE_BOOK1, 5, 5, DTYPE_CATACOMBS, THEME_NONE, Q_BLOOD, 0, 4, 0, 96, true, true, true, 0, 3, false }, + { OFILE_PEDISTL, 5, 5, DTYPE_CATACOMBS, THEME_NONE, Q_BLOOD, 0, 1, 0, 96, true, true, true, 0, 3, false }, + { OFILE_L3DOORS, 9, 12, DTYPE_CAVES, THEME_NONE, Q_INVALID, 0, 1, 0, 64, false, false, true, 0, 3, true }, + { OFILE_L3DOORS, 9, 12, DTYPE_CAVES, THEME_NONE, Q_INVALID, 0, 2, 0, 64, false, false, true, 0, 3, true }, + { OFILE_PFOUNTN, 0, 0, DTYPE_NONE, THEME_PURIFYINGFOUNTAIN, Q_INVALID, 1, 2, 10, 128, true, true, true, 0, 3, false }, + { OFILE_ARMSTAND, 0, 0, DTYPE_NONE, THEME_ARMORSTAND, Q_INVALID, 0, 1, 0, 96, true, false, true, 0, 3, false }, + { OFILE_ARMSTAND, 0, 0, DTYPE_NONE, THEME_ARMORSTAND, Q_INVALID, 0, 2, 0, 96, true, false, true, 0, 0, false }, + { OFILE_GOATSHRN, 0, 0, DTYPE_NONE, THEME_GOATSHRINE, Q_INVALID, 1, 2, 10, 96, true, true, true, 0, 3, false }, + { OFILE_CAULDREN, 13, 16, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, false, true, 0, 3, false }, + { OFILE_MFOUNTN, 0, 0, DTYPE_NONE, THEME_MURKYFOUNTAIN, Q_INVALID, 1, 2, 10, 128, true, true, true, 0, 3, false }, + { OFILE_TFOUNTN, 0, 0, DTYPE_NONE, THEME_TEARFOUNTAIN, Q_INVALID, 1, 2, 4, 128, true, true, true, 0, 3, false }, + { OFILE_ALTBOY, 0, 0, DTYPE_CATHEDRAL, THEME_NONE, Q_BETRAYER, 0, 1, 0, 128, true, true, true, 0, 0, false }, + { OFILE_MCIRL, 0, 0, DTYPE_CATHEDRAL, THEME_NONE, Q_BETRAYER, 0, 1, 0, 96, false, true, true, 0, 0, false }, + { OFILE_MCIRL, 0, 0, DTYPE_CATHEDRAL, THEME_NONE, Q_BETRAYER, 0, 1, 0, 96, false, true, true, 0, 0, false }, + { OFILE_BKSLBRNT, 1, 12, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 3, false }, + { OFILE_CANDLE2, 1, 12, DTYPE_NONE, THEME_NONE, Q_BETRAYER, 1, 2, 4, 96, true, true, true, 0, 0, false }, + { OFILE_BOOK1, 13, 13, DTYPE_HELL, THEME_NONE, Q_WARLORD, 0, 4, 0, 96, true, true, true, 0, 3, false }, + { OFILE_ARMSTAND, 13, 13, DTYPE_NONE, THEME_NONE, Q_WARLORD, 0, 1, 0, 96, true, false, true, 0, 3, false }, + { OFILE_WEAPSTND, 0, 0, DTYPE_NONE, THEME_NONE, Q_WARLORD, 0, 1, 0, 96, true, false, true, 0, 3, false }, + { OFILE_BURNCROS, 0, 0, DTYPE_NONE, THEME_BRNCROSS, Q_INVALID, 1, 0, 10, 160, true, false, false, 0, 0, false }, + { OFILE_WEAPSTND, 0, 0, DTYPE_NONE, THEME_WEAPONRACK, Q_INVALID, 0, 1, 0, 96, true, false, true, 0, 3, false }, + { OFILE_WEAPSTND, 0, 0, DTYPE_NONE, THEME_WEAPONRACK, Q_INVALID, 0, 2, 0, 96, true, false, true, 0, 0, false }, + { OFILE_MUSHPTCH, 0, 0, DTYPE_NONE, THEME_NONE, Q_MUSHROOM, 0, 1, 0, 96, true, true, true, 0, 3, true }, + { OFILE_LZSTAND, 0, 0, DTYPE_NONE, THEME_NONE, Q_BETRAYER, 0, 1, 0, 128, true, false, true, 0, 3, false }, + { OFILE_DECAP, 9, 9, DTYPE_CAVES, THEME_NONE, Q_INVALID, 0, 2, 0, 96, true, true, true, 0, 1, false }, + { OFILE_CHEST3, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 1, true }, + { OFILE_BCASE, 0, 0, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 2, 0, 96, true, false, true, 0, 0, false }, + { OFILE_POD, 17, 20, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 9, 96, true, true, true, 1, 3, false }, + { OFILE_PODEX, 17, 20, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 10, 96, true, true, true, 1, 3, false }, + { OFILE_URN, 21, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 9, 96, true, true, true, 1, 3, false }, + { OFILE_URNEX, 21, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 10, 96, true, true, true, 1, 3, false }, + { OFILE_L5BOOKS, 21, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 0, 96, true, true, true, 0, 3, false }, + { OFILE_L5CANDLE, 21, 23, DTYPE_NONE, THEME_NONE, Q_INVALID, 1, 2, 4, 96, true, true, true, 0, 0, false }, + { OFILE_L5DOORS, 21, 24, DTYPE_CRYPT, THEME_NONE, Q_INVALID, 0, 1, 0, 64, false, false, true, 0, 3, true }, + { OFILE_L5DOORS, 21, 24, DTYPE_CRYPT, THEME_NONE, Q_INVALID, 0, 2, 0, 64, false, false, true, 0, 3, true }, + { OFILE_L5LEVER, 21, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 1, 96, true, true, true, 0, 1, true }, + { OFILE_L5SARC, 21, 24, DTYPE_NONE, THEME_NONE, Q_INVALID, 0, 1, 5, 128, true, true, true, 0, 3, true }, // clang-format on }; - /** Maps from object_graphic_id to object CEL name. */ const char *const ObjMasterLoadList[] = { "L1Braz", @@ -314,125 +330,16 @@ const char *const ObjMasterLoadList[] = { "Mcirl", "Bkslbrnt", "Mushptch", - "LzStand" -}; -/** Maps from object_graphic_id to object CEL name (Hellfire Crypt overwrite). */ -const char *ObjCryptLoadList[] = { - "L1Braz", + "LzStand", + "L6Pod1", + "L6Pod2", "L5Door", "L5Lever", - "Chest1", - "Chest2", - "Banner", - "SkulPile", - "SkulFire", - "SkulStik", - "CruxSk1", - "CruxSk2", - "CruxSk3", - "Book1", - "Book2", - "Rockstan", - "Angel", - "Chest3", - "Burncros", "L5Light", - "Nude2", - "Switch4", - "TNudeM", - "TNudeW", - "TSoul", - "L2Doors", - "WTorch4", - "WTorch3", "L5Sarco", - "Flame1", - "Prsrplt1", - "Traphole", - "MiniWatr", - "WTorch2", - "WTorch1", - "BCase", - "BShelf", - "WeapStnd", "Urn", "Urnexpld", - "LShrineG", - "RShrineG", - "Bloodfnt", - "Decap", - "Pedistl", - "L3Doors", - "PFountn", - "Armstand", - "Goatshrn", - "Cauldren", - "MFountn", - "TFountn", - "Altboy", - "Mcirl", "L5Books", - "Mushptch", - "LzStand", -}; -/** Maps from object_graphic_id to object CEL name (Hellfire Hive overwrite). */ -const char *ObjHiveLoadList[] = { - "L1Braz", - "L1Doors", - "Lever", - "Chest1", - "Chest2", - "Banner", - "SkulPile", - "SkulFire", - "SkulStik", - "CruxSk1", - "CruxSk2", - "CruxSk3", - "Book1", - "Book2", - "Rockstan", - "Angel", - "Chest3", - "Burncros", - "Candle2", - "Nude2", - "Switch4", - "TNudeM", - "TNudeW", - "TSoul", - "L2Doors", - "WTorch4", - "WTorch3", - "Sarc", - "Flame1", - "Prsrplt1", - "Traphole", - "MiniWatr", - "WTorch2", - "WTorch1", - "BCase", - "BShelf", - "WeapStnd", - "L6Pod1", - "L6Pod2", - "LShrineG", - "RShrineG", - "Bloodfnt", - "Decap", - "Pedistl", - "L3Doors", - "PFountn", - "Armstand", - "Goatshrn", - "Cauldren", - "MFountn", - "TFountn", - "Altboy", - "Mcirl", - "Bkslbrnt", - "Mushptch", - "LzStand", }; } // namespace devilution diff --git a/Source/objdat.h b/Source/objdat.h index 38b60a47a..ab4786bd1 100644 --- a/Source/objdat.h +++ b/Source/objdat.h @@ -89,6 +89,15 @@ enum object_graphic_id : int8_t { OFILE_BKSLBRNT, OFILE_MUSHPTCH, OFILE_LZSTAND, + OFILE_POD, + OFILE_PODEX, + OFILE_L5DOORS, + OFILE_L5LEVER, + OFILE_L5CANDLE, + OFILE_L5SARC, + OFILE_URN, + OFILE_URNEX, + OFILE_L5BOOKS, OFILE_NULL = -1, }; @@ -192,6 +201,16 @@ enum _object_id : int8_t { OBJ_SLAINHERO, OBJ_SIGNCHEST, OBJ_BOOKSHELFR, + OBJ_POD, + OBJ_PODEX, + OBJ_URN, + OBJ_URNEX, + OBJ_L5BOOKS, + OBJ_L5CANDLE, + OBJ_L5LDOOR, + OBJ_L5RDOOR, + OBJ_L5LEVER, + OBJ_L5SARC, OBJ_NULL = -1, }; @@ -224,7 +243,6 @@ enum quest_id : int8_t { }; struct ObjectData { - int oload; // Todo create enum object_graphic_id ofindex; int8_t ominlvl; int8_t omaxlvl; @@ -244,9 +262,7 @@ struct ObjectData { }; extern const _object_id ObjTypeConv[]; -extern const ObjectData AllObjects[]; +extern const ObjectData AllObjects[109]; extern const char *const ObjMasterLoadList[]; -extern const char *ObjCryptLoadList[]; -extern const char *ObjHiveLoadList[]; } // namespace devilution diff --git a/Source/objects.cpp b/Source/objects.cpp index 52fc3e85d..16eb2d9a2 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -303,7 +303,7 @@ bool RndLocOk(int xp, int yp) return false; if (nSolidTable[dPiece[xp][yp]]) return false; - return leveltype != DTYPE_CATHEDRAL || dPiece[xp][yp] <= 126 || dPiece[xp][yp] >= 144; + return IsNoneOf(leveltype, DTYPE_CATHEDRAL, DTYPE_CRYPT) || dPiece[xp][yp] <= 126 || dPiece[xp][yp] >= 144; } bool CanPlaceWallTrap(int xp, int yp) @@ -486,6 +486,16 @@ void AddBookLever(Rectangle affectedArea, _speech_id msg) void InitRndBarrels() { + _object_id barrelId = OBJ_BARREL; + _object_id explosiveBarrelId = OBJ_BARRELEX; + if (leveltype == DTYPE_NEST) { + barrelId = OBJ_POD; + explosiveBarrelId = OBJ_PODEX; + } else if (leveltype == DTYPE_CRYPT) { + barrelId = OBJ_URN; + explosiveBarrelId = OBJ_URNEX; + } + /** number of groups of barrels to generate */ int numobjs = GenerateRnd(5) + 3; for (int i = 0; i < numobjs; i++) { @@ -495,7 +505,7 @@ void InitRndBarrels() xp = GenerateRnd(80) + 16; yp = GenerateRnd(80) + 16; } while (!RndLocOk(xp, yp)); - _object_id o = (GenerateRnd(4) != 0) ? OBJ_BARREL : OBJ_BARRELEX; + _object_id o = (GenerateRnd(4) != 0) ? barrelId : explosiveBarrelId; AddObject(o, { xp, yp }); bool found = true; /** regulates chance to stop placing barrels in current group */ @@ -518,7 +528,7 @@ void InitRndBarrels() break; } if (found) { - o = (GenerateRnd(5) != 0) ? OBJ_BARREL : OBJ_BARRELEX; + o = (GenerateRnd(5) != 0) ? barrelId : explosiveBarrelId; AddObject(o, { xp, yp }); c++; } @@ -533,9 +543,9 @@ void AddCryptObjects(int x1, int y1, int x2, int y2) for (int i = x1; i < x2; i++) { int pn = dPiece[i][j]; if (pn == 77) - AddObject(OBJ_L1LDOOR, { i, j }); + AddObject(OBJ_L5LDOOR, { i, j }); if (pn == 80) - AddObject(OBJ_L1RDOOR, { i, j }); + AddObject(OBJ_L5RDOOR, { i, j }); } } } @@ -892,18 +902,18 @@ void AddCryptStoryBook(int s) return; } } - AddCryptBook(OBJ_STORYBOOK, s, xp, yp); - AddObject(OBJ_STORYCANDLE, { xp - 2, yp + 1 }); - AddObject(OBJ_STORYCANDLE, { xp - 2, yp }); - AddObject(OBJ_STORYCANDLE, { xp - 1, yp - 1 }); - AddObject(OBJ_STORYCANDLE, { xp + 1, yp - 1 }); - AddObject(OBJ_STORYCANDLE, { xp + 2, yp }); - AddObject(OBJ_STORYCANDLE, { xp + 2, yp + 1 }); + AddCryptBook(OBJ_L5BOOKS, s, xp, yp); + AddObject(OBJ_L5CANDLE, { xp - 2, yp + 1 }); + AddObject(OBJ_L5CANDLE, { xp - 2, yp }); + AddObject(OBJ_L5CANDLE, { xp - 1, yp - 1 }); + AddObject(OBJ_L5CANDLE, { xp + 1, yp - 1 }); + AddObject(OBJ_L5CANDLE, { xp + 2, yp }); + AddObject(OBJ_L5CANDLE, { xp + 2, yp + 1 }); } void AddNakrulBook(int a1, int a2, int a3) { - AddCryptBook(OBJ_STORYBOOK, a1, a2, a3); + AddCryptBook(OBJ_L5BOOKS, a1, a2, a3); } void AddNakrulGate() @@ -1137,6 +1147,17 @@ void InitializeL1Door(Object &door) } } +void InitializeL5Door(Object &door) +{ + door.InitializeDoor(); + door._oVar1 = dPiece[door.position.x][door.position.y]; + if (door._otype == _object_id::OBJ_L5LDOOR) { + door._oVar2 = dPiece[door.position.x][door.position.y - 1]; + } else { // _object_id::OBJ_L5RDOOR + door._oVar2 = dPiece[door.position.x - 1][door.position.y]; + } +} + void InitializeMicroDoor(Object &door) { door.InitializeDoor(); @@ -1186,10 +1207,9 @@ void AddFlameLvr(int i) void AddTrap(int i) { int mt = currlevel / 3 + 1; - if (currlevel > 16) { + if (leveltype == DTYPE_NEST) { mt = (currlevel - 4) / 3 + 1; - } - if (currlevel > 20) { + } else if (leveltype == DTYPE_CRYPT) { mt = (currlevel - 8) / 3 + 1; } mt = GenerateRnd(mt); @@ -1212,15 +1232,15 @@ void AddObjectLight(int i, int r) } } -void AddBarrel(int i, int t) +void AddBarrel(Object barrel) { - Objects[i]._oVar1 = 0; - Objects[i]._oRndSeed = AdvanceRndSeed(); - Objects[i]._oVar2 = (t == OBJ_BARRELEX) ? 0 : GenerateRnd(10); - Objects[i]._oVar3 = GenerateRnd(3); + barrel._oVar1 = 0; + barrel._oRndSeed = AdvanceRndSeed(); + barrel._oVar2 = barrel.isExplosive() ? 0 : GenerateRnd(10); + barrel._oVar3 = GenerateRnd(3); - if (Objects[i]._oVar2 >= 8) - Objects[i]._oVar4 = PreSpawnSkeleton(); + if (barrel._oVar2 >= 8) + barrel._oVar4 = PreSpawnSkeleton(); } void AddShrine(int i) @@ -1570,7 +1590,7 @@ void UpdateFlameTrap(int i) if (Objects[i]._oVar4 != 0) ActivateTrapLine(Objects[i]._otype, Objects[i]._oVar1); } else { - int damage[4] = { 6, 8, 10, 12 }; + int damage[6] = { 6, 8, 10, 12, 10, 12 }; int mindam = damage[leveltype - 1]; int maxdam = mindam * 2; @@ -1593,7 +1613,7 @@ void UpdateFlameTrap(int i) void UpdateBurningCrossDamage(int i) { - int damage[4] = { 6, 8, 10, 12 }; + int damage[6] = { 6, 8, 10, 12, 10, 12 }; auto &myPlayer = Players[MyPlayerId]; @@ -1710,95 +1730,97 @@ void SetDoorPiece(Point position) void DoorSet(Point position, bool isLeftDoor) { int pn = dPiece[position.x][position.y]; - if (currlevel < 17) { - switch (pn) { - case 43: - ObjSetMicro(position, 392); - break; - case 45: - ObjSetMicro(position, 394); - break; - case 50: - ObjSetMicro(position, isLeftDoor ? 411 : 412); - break; - case 54: - ObjSetMicro(position, 397); - break; - case 55: - ObjSetMicro(position, 398); - break; - case 61: - ObjSetMicro(position, 399); - break; - case 67: - ObjSetMicro(position, 400); - break; - case 68: - ObjSetMicro(position, 401); - break; - case 69: - ObjSetMicro(position, 403); - break; - case 70: - ObjSetMicro(position, 404); - break; - case 72: - ObjSetMicro(position, 406); - break; - case 212: - ObjSetMicro(position, 407); - break; - case 354: - ObjSetMicro(position, 409); - break; - case 355: - ObjSetMicro(position, 410); - break; - case 411: - case 412: - ObjSetMicro(position, 396); - break; - } - } else { - switch (pn) { - case 75: - ObjSetMicro(position, 204); - break; - case 79: - ObjSetMicro(position, 208); - break; - case 86: - ObjSetMicro(position, isLeftDoor ? 232 : 234); - break; - case 91: - ObjSetMicro(position, 215); - break; - case 93: - ObjSetMicro(position, 218); - break; - case 99: - ObjSetMicro(position, 220); - break; - case 111: - ObjSetMicro(position, 222); - break; - case 113: - ObjSetMicro(position, 224); - break; - case 115: - ObjSetMicro(position, 226); - break; - case 117: - ObjSetMicro(position, 228); - break; - case 119: - ObjSetMicro(position, 230); - break; - case 232: - case 234: - ObjSetMicro(position, 212); - break; - } + switch (pn) { + case 43: + ObjSetMicro(position, 392); + break; + case 45: + ObjSetMicro(position, 394); + break; + case 50: + ObjSetMicro(position, isLeftDoor ? 411 : 412); + break; + case 54: + ObjSetMicro(position, 397); + break; + case 55: + ObjSetMicro(position, 398); + break; + case 61: + ObjSetMicro(position, 399); + break; + case 67: + ObjSetMicro(position, 400); + break; + case 68: + ObjSetMicro(position, 401); + break; + case 69: + ObjSetMicro(position, 403); + break; + case 70: + ObjSetMicro(position, 404); + break; + case 72: + ObjSetMicro(position, 406); + break; + case 212: + ObjSetMicro(position, 407); + break; + case 354: + ObjSetMicro(position, 409); + break; + case 355: + ObjSetMicro(position, 410); + break; + case 411: + case 412: + ObjSetMicro(position, 396); + break; + } +} + +void CryptDoorSet(Point position, bool isLeftDoor) +{ + int pn = dPiece[position.x][position.y]; + switch (pn) { + case 75: + ObjSetMicro(position, 204); + break; + case 79: + ObjSetMicro(position, 208); + break; + case 86: + ObjSetMicro(position, isLeftDoor ? 232 : 234); + break; + case 91: + ObjSetMicro(position, 215); + break; + case 93: + ObjSetMicro(position, 218); + break; + case 99: + ObjSetMicro(position, 220); + break; + case 111: + ObjSetMicro(position, 222); + break; + case 113: + ObjSetMicro(position, 224); + break; + case 115: + ObjSetMicro(position, 226); + break; + case 117: + ObjSetMicro(position, 228); + break; + case 119: + ObjSetMicro(position, 230); + break; + case 232: + case 234: + ObjSetMicro(position, 212); + break; } } @@ -1830,20 +1852,10 @@ void OperateL1RDoor(int pnum, int oi, bool sendflag) if (door._oVar4 == 0) { if (pnum == MyPlayerId && sendflag) NetSendCmdParam1(true, CMD_OPENDOOR, oi); - if (currlevel < 21) { - if (!deltaload) - PlaySfxLoc(IS_DOOROPEN, door.position); - ObjSetMicro(door.position, 395); - } else { - if (!deltaload) - PlaySfxLoc(IS_CROPEN, door.position); - ObjSetMicro(door.position, 209); - } - if (currlevel < 17) { - dSpecial[door.position.x][door.position.y] = 8; - } else { - dSpecial[door.position.x][door.position.y] = 2; - } + if (!deltaload) + PlaySfxLoc(IS_DOOROPEN, door.position); + ObjSetMicro(door.position, 395); + dSpecial[door.position.x][door.position.y] = 8; SetDoorPiece(door.position + Direction::NorthEast); door._oAnimFrame += 2; door._oPreFlag = true; @@ -1854,13 +1866,8 @@ void OperateL1RDoor(int pnum, int oi, bool sendflag) return; } - if (currlevel < 21) { - if (!deltaload) - PlaySfxLoc(IS_DOORCLOS, door.position); - } else { - if (!deltaload) - PlaySfxLoc(IS_CRCLOS, door.position); - } + if (!deltaload) + PlaySfxLoc(IS_DOORCLOS, door.position); if (!deltaload && IsDoorClear(door.position)) { if (pnum == MyPlayerId && sendflag) NetSendCmdParam1(true, CMD_CLOSEDOOR, oi); @@ -1870,17 +1877,10 @@ void OperateL1RDoor(int pnum, int oi, bool sendflag) // Restore the normal tile where the open door used to be auto openPosition = door.position + Direction::NorthWest; - if (currlevel < 17) { - if (door._oVar2 == 50 && dPiece[openPosition.x][openPosition.y] == 396) - ObjSetMicro(openPosition, 411); - else - ObjSetMicro(openPosition, door._oVar2); - } else { - if (door._oVar2 == 86 && dPiece[openPosition.x][openPosition.y] == 210) - ObjSetMicro(openPosition, 232); - else - ObjSetMicro(openPosition, door._oVar2); - } + if (door._oVar2 == 50 && dPiece[openPosition.x][openPosition.y] == 396) + ObjSetMicro(openPosition, 411); + else + ObjSetMicro(openPosition, door._oVar2); dSpecial[door.position.x][door.position.y] = 0; door._oAnimFrame -= 2; @@ -1904,23 +1904,13 @@ void OperateL1LDoor(int pnum, int oi, bool sendflag) if (door._oVar4 == 0) { if (pnum == MyPlayerId && sendflag) NetSendCmdParam1(true, CMD_OPENDOOR, oi); - if (currlevel < 21) { - if (!deltaload) - PlaySfxLoc(IS_DOOROPEN, door.position); - if (door._oVar1 == 214) - ObjSetMicro(door.position, 408); - else - ObjSetMicro(door.position, 393); - } else { - if (!deltaload) - PlaySfxLoc(IS_CROPEN, door.position); - ObjSetMicro(door.position, 206); - } - if (currlevel < 17) { - dSpecial[door.position.x][door.position.y] = 7; - } else { - dSpecial[door.position.x][door.position.y] = 1; - } + if (!deltaload) + PlaySfxLoc(IS_DOOROPEN, door.position); + if (door._oVar1 == 214) + ObjSetMicro(door.position, 408); + else + ObjSetMicro(door.position, 393); + dSpecial[door.position.x][door.position.y] = 7; SetDoorPiece(door.position + Direction::NorthWest); door._oAnimFrame += 2; door._oPreFlag = true; @@ -1931,13 +1921,8 @@ void OperateL1LDoor(int pnum, int oi, bool sendflag) return; } - if (currlevel < 21) { - if (!deltaload) - PlaySfxLoc(IS_DOORCLOS, door.position); - } else { - if (!deltaload) - PlaySfxLoc(IS_CRCLOS, door.position); - } + if (!deltaload) + PlaySfxLoc(IS_DOORCLOS, door.position); if (IsDoorClear(door.position)) { if (pnum == MyPlayerId && sendflag) NetSendCmdParam1(true, CMD_CLOSEDOOR, oi); @@ -1947,17 +1932,10 @@ void OperateL1LDoor(int pnum, int oi, bool sendflag) // Restore the normal tile where the open door used to be auto openPosition = door.position + Direction::NorthEast; - if (currlevel < 17) { - if (door._oVar2 == 50 && dPiece[openPosition.x][openPosition.y] == 396) - ObjSetMicro(openPosition, 412); - else - ObjSetMicro(openPosition, door._oVar2); - } else { - if (door._oVar2 == 86 && dPiece[openPosition.x][openPosition.y] == 210) - ObjSetMicro(openPosition, 234); - else - ObjSetMicro(openPosition, door._oVar2); - } + if (door._oVar2 == 50 && dPiece[openPosition.x][openPosition.y] == 396) + ObjSetMicro(openPosition, 412); + else + ObjSetMicro(openPosition, door._oVar2); dSpecial[door.position.x][door.position.y] = 0; door._oAnimFrame -= 2; @@ -2136,6 +2114,110 @@ void OperateL3LDoor(int pnum, int oi, bool sendflag) } } +void OperateL5RDoor(int pnum, int oi, bool sendflag) +{ + Object &door = Objects[oi]; + + if (door._oVar4 == 2) { + if (!deltaload) + PlaySfxLoc(IS_DOORCLOS, door.position); + return; + } + + if (door._oVar4 == 0) { + if (pnum == MyPlayerId && sendflag) + NetSendCmdParam1(true, CMD_OPENDOOR, oi); + if (!deltaload) + PlaySfxLoc(IS_CROPEN, door.position); + ObjSetMicro(door.position, 209); + dSpecial[door.position.x][door.position.y] = 2; + SetDoorPiece(door.position + Direction::NorthEast); + door._oAnimFrame += 2; + door._oPreFlag = true; + CryptDoorSet(door.position + Direction::NorthWest, false); + door._oVar4 = 1; + door._oSelFlag = 2; + RedoPlayerVision(); + return; + } + + if (!deltaload) + PlaySfxLoc(IS_CRCLOS, door.position); + if (!deltaload && IsDoorClear(door.position)) { + if (pnum == MyPlayerId && sendflag) + NetSendCmdParam1(true, CMD_CLOSEDOOR, oi); + door._oVar4 = 0; + door._oSelFlag = 3; + ObjSetMicro(door.position, door._oVar1); + + // Restore the normal tile where the open door used to be + auto openPosition = door.position + Direction::NorthWest; + if (door._oVar2 == 86 && dPiece[openPosition.x][openPosition.y] == 210) + ObjSetMicro(openPosition, 232); + else + ObjSetMicro(openPosition, door._oVar2); + + dSpecial[door.position.x][door.position.y] = 0; + door._oAnimFrame -= 2; + door._oPreFlag = false; + RedoPlayerVision(); + } else { + door._oVar4 = 2; + } +} + +void OperateL5LDoor(int pnum, int oi, bool sendflag) +{ + Object &door = Objects[oi]; + + if (door._oVar4 == 2) { + if (!deltaload) + PlaySfxLoc(IS_DOORCLOS, door.position); + return; + } + + if (door._oVar4 == 0) { + if (pnum == MyPlayerId && sendflag) + NetSendCmdParam1(true, CMD_OPENDOOR, oi); + if (!deltaload) + PlaySfxLoc(IS_CROPEN, door.position); + ObjSetMicro(door.position, 206); + dSpecial[door.position.x][door.position.y] = 1; + SetDoorPiece(door.position + Direction::NorthWest); + door._oAnimFrame += 2; + door._oPreFlag = true; + CryptDoorSet(door.position + Direction::NorthEast, true); + door._oVar4 = 1; + door._oSelFlag = 2; + RedoPlayerVision(); + return; + } + + if (!deltaload) + PlaySfxLoc(IS_CRCLOS, door.position); + if (IsDoorClear(door.position)) { + if (pnum == MyPlayerId && sendflag) + NetSendCmdParam1(true, CMD_CLOSEDOOR, oi); + door._oVar4 = 0; + door._oSelFlag = 3; + ObjSetMicro(door.position, door._oVar1); + + // Restore the normal tile where the open door used to be + auto openPosition = door.position + Direction::NorthEast; + if (door._oVar2 == 86 && dPiece[openPosition.x][openPosition.y] == 210) + ObjSetMicro(openPosition, 234); + else + ObjSetMicro(openPosition, door._oVar2); + + dSpecial[door.position.x][door.position.y] = 0; + door._oAnimFrame -= 2; + door._oPreFlag = false; + RedoPlayerVision(); + } else { + door._oVar4 = 2; + } +} + void OperateL1Door(int pnum, int i, bool sendflag) { int dpx = abs(Objects[i].position.x - Players[pnum].position.tile.x); @@ -2146,6 +2228,16 @@ void OperateL1Door(int pnum, int i, bool sendflag) OperateL1RDoor(pnum, i, sendflag); } +void OperateL5Door(int pnum, int i, bool sendflag) +{ + int dpx = abs(Objects[i].position.x - Players[pnum].position.tile.x); + int dpy = abs(Objects[i].position.y - Players[pnum].position.tile.y); + if (dpx == 1 && dpy <= 1 && Objects[i]._otype == OBJ_L5LDOOR) + OperateL5LDoor(pnum, i, sendflag); + if (dpx <= 1 && dpy == 1 && Objects[i]._otype == OBJ_L5RDOOR) + OperateL5RDoor(pnum, i, sendflag); +} + bool AreAllLeversActivated(int leverId) { for (int j = 0; j < ActiveObjectCount; j++) { @@ -3949,7 +4041,7 @@ void OperateWeaponRack(int pnum, int i, bool sendmsg) if (deltaload) return; - CreateTypeItem(Objects[i].position, leveltype > 1, weaponType, IMISC_NONE, sendmsg, false); + CreateTypeItem(Objects[i].position, leveltype != DTYPE_CATHEDRAL, weaponType, IMISC_NONE, sendmsg, false); if (pnum == MyPlayerId) NetSendCmdParam1(false, CMD_OPERATEOBJ, i); @@ -4001,7 +4093,7 @@ void OperateStoryBook(int pnum, int i) NetSendCmd(false, CMD_NAKRUL); return; } - } else if (currlevel >= 21) { + } else if (leveltype == DTYPE_CRYPT) { Quests[Q_NAKRUL]._qactive = QUEST_ACTIVE; Quests[Q_NAKRUL]._qlog = true; Quests[Q_NAKRUL]._qmsg = msg; @@ -4083,6 +4175,25 @@ void SyncOpL3Door(int pnum, int cmd, int i) OperateL3RDoor(-1, i, false); } +void SyncOpL5Door(int pnum, int cmd, int i) +{ + if (pnum == MyPlayerId) + return; + + bool doSync = false; + if (cmd == CMD_OPENDOOR && Objects[i]._oVar4 == 0) + doSync = true; + if (cmd == CMD_CLOSEDOOR && Objects[i]._oVar4 == 1) + doSync = true; + if (!doSync) + return; + + if (Objects[i]._otype == OBJ_L5LDOOR) + OperateL5LDoor(-1, i, false); + if (Objects[i]._otype == OBJ_L5RDOOR) + OperateL5RDoor(-1, i, false); +} + /** * @brief Checks if all active crux objects of the given type have been broken. * @@ -4160,10 +4271,10 @@ void BreakBarrel(int pnum, Object &barrel, int dam, bool forcebreak, bool sendms return; } - if (barrel._otype == OBJ_BARRELEX) { - if (currlevel >= 21 && currlevel <= 24) + if (barrel.isExplosive()) { + if (barrel._otype == _object_id::OBJ_URNEX) PlaySfxLoc(IS_POPPOP3, barrel.position); - else if (currlevel >= 17 && currlevel <= 20) + else if (barrel._otype == _object_id::OBJ_PODEX) PlaySfxLoc(IS_POPPOP8, barrel.position); else PlaySfxLoc(IS_BARLFIRE, barrel.position); @@ -4178,15 +4289,15 @@ void BreakBarrel(int pnum, Object &barrel, int dam, bool forcebreak, bool sendms } // don't really need to exclude large objects as explosive barrels are single tile objects, but using considerLargeObjects == false as this matches the old logic. Object *adjacentObject = ObjectAtPosition({ xp, yp }, false); - if (adjacentObject != nullptr && adjacentObject->_otype == _object_id::OBJ_BARRELEX && !adjacentObject->IsBroken()) { + if (adjacentObject != nullptr && adjacentObject->isExplosive() && !adjacentObject->IsBroken()) { BreakBarrel(pnum, *adjacentObject, dam, true, sendmsg); } } } } else { - if (currlevel >= 21 && currlevel <= 24) + if (barrel._otype == _object_id::OBJ_URN) PlaySfxLoc(IS_POPPOP2, barrel.position); - else if (currlevel >= 17 && currlevel <= 20) + else if (barrel._otype == _object_id::OBJ_POD) PlaySfxLoc(IS_POPPOP5, barrel.position); else PlaySfxLoc(IS_BARREL, barrel.position); @@ -4261,30 +4372,16 @@ void SyncL1Doors(Object &door) bool isLeftDoor = door._otype == _object_id::OBJ_L1LDOOR; // otherwise the door is type OBJ_L1RDOOR - if (currlevel < 17) { - if (isLeftDoor) { - ObjSetMicro(door.position, door._oVar1 == 214 ? 408 : 393); - dSpecial[door.position.x][door.position.y] = 7; - SetDoorPiece(door.position + Direction::NorthWest); - DoorSet(door.position + Direction::NorthEast, isLeftDoor); - } else { - ObjSetMicro(door.position, 395); - dSpecial[door.position.x][door.position.y] = 8; - SetDoorPiece(door.position + Direction::NorthEast); - DoorSet(door.position + Direction::NorthWest, isLeftDoor); - } + if (isLeftDoor) { + ObjSetMicro(door.position, door._oVar1 == 214 ? 408 : 393); + dSpecial[door.position.x][door.position.y] = 7; + SetDoorPiece(door.position + Direction::NorthWest); + DoorSet(door.position + Direction::NorthEast, isLeftDoor); } else { - if (isLeftDoor) { - ObjSetMicro(door.position, 206); - dSpecial[door.position.x][door.position.y] = 1; - SetDoorPiece(door.position + Direction::NorthWest); - DoorSet(door.position + Direction::NorthEast, isLeftDoor); - } else { - ObjSetMicro(door.position, 209); - dSpecial[door.position.x][door.position.y] = 2; - SetDoorPiece(door.position + Direction::NorthEast); - DoorSet(door.position + Direction::NorthWest, isLeftDoor); - } + ObjSetMicro(door.position, 395); + dSpecial[door.position.x][door.position.y] = 8; + SetDoorPiece(door.position + Direction::NorthEast); + DoorSet(door.position + Direction::NorthWest, isLeftDoor); } } @@ -4326,6 +4423,31 @@ void SyncL3Doors(Object &door) } } +void SyncL5Doors(Object &door) +{ + if (door._oVar4 == 0) { + door._oMissFlag = false; + return; + } + + door._oMissFlag = true; + door._oSelFlag = 2; + + bool isLeftDoor = door._otype == _object_id::OBJ_L5LDOOR; // otherwise the door is type OBJ_L5RDOOR + + if (isLeftDoor) { + ObjSetMicro(door.position, 206); + dSpecial[door.position.x][door.position.y] = 1; + SetDoorPiece(door.position + Direction::NorthWest); + CryptDoorSet(door.position + Direction::NorthEast, isLeftDoor); + } else { + ObjSetMicro(door.position, 209); + dSpecial[door.position.x][door.position.y] = 2; + SetDoorPiece(door.position + Direction::NorthEast); + CryptDoorSet(door.position + Direction::NorthWest, isLeftDoor); + } +} + } // namespace unsigned int Object::GetId() const @@ -4391,44 +4513,35 @@ bool IsItemBlockingObjectAtPosition(Point position) void InitObjectGFX() { - bool fileload[56] = {}; - - int lvl = currlevel; - if (currlevel >= 21 && currlevel <= 24) - lvl -= 20; - else if (currlevel >= 17 && currlevel <= 20) - lvl -= 8; - for (int i = 0; AllObjects[i].oload != -1; i++) { - if (AllObjects[i].oload == 1 - && lvl >= AllObjects[i].ominlvl - && lvl <= AllObjects[i].omaxlvl) { - fileload[AllObjects[i].ofindex] = true; + bool filesLoaded[65] = {}; + + for (const ObjectData objectData : AllObjects) { + if (objectData.ominlvl != 0 && currlevel >= objectData.ominlvl && currlevel <= objectData.omaxlvl) { + filesLoaded[objectData.ofindex] = true; } - if (AllObjects[i].otheme != THEME_NONE) { + if (objectData.otheme != THEME_NONE) { for (int j = 0; j < numthemes; j++) { - if (themes[j].ttype == AllObjects[i].otheme) - fileload[AllObjects[i].ofindex] = true; + if (themes[j].ttype == objectData.otheme) + filesLoaded[objectData.ofindex] = true; } } - if (AllObjects[i].oquest != -1) { - if (Quests[AllObjects[i].oquest].IsAvailable()) - fileload[AllObjects[i].ofindex] = true; + if (objectData.oquest != Q_INVALID) { + if (Quests[objectData.oquest].IsAvailable()) + filesLoaded[objectData.ofindex] = true; } } - for (int i = OFILE_L1BRAZ; i <= OFILE_LZSTAND; i++) { - if (fileload[i]) { - ObjFileList[numobjfiles] = static_cast(i); - char filestr[32]; - sprintf(filestr, "Objects\\%s.CEL", ObjMasterLoadList[i]); - if (currlevel >= 17 && currlevel < 21) - sprintf(filestr, "Objects\\%s.CEL", ObjHiveLoadList[i]); - else if (currlevel >= 21) - sprintf(filestr, "Objects\\%s.CEL", ObjCryptLoadList[i]); - pObjCels[numobjfiles] = LoadFileInMem(filestr); - numobjfiles++; + for (int i = OFILE_L1BRAZ; i <= OFILE_L5BOOKS; i++) { + if (!filesLoaded[i]) { + continue; } + + ObjFileList[numobjfiles] = static_cast(i); + char filestr[32]; + sprintf(filestr, "Objects\\%s.CEL", ObjMasterLoadList[i]); + pObjCels[numobjfiles] = LoadFileInMem(filestr); + numobjfiles++; } } @@ -4468,6 +4581,21 @@ void AddL2Objs(int x1, int y1, int x2, int y2) } } +void AddL5Objs(int x1, int y1, int x2, int y2) +{ + for (int j = y1; j < y2; j++) { + for (int i = x1; i < x2; i++) { + int pn = dPiece[i][j]; + if (pn == 270) + AddObject(OBJ_L1LIGHT, { i, j }); + if (pn == 44 || pn == 51 || pn == 214) + AddObject(OBJ_L5LDOOR, { i, j }); + if (pn == 46 || pn == 56) + AddObject(OBJ_L5RDOOR, { i, j }); + } + } +} + void AddSlainHero() { int x; @@ -4513,10 +4641,7 @@ void InitObjects() if (Quests[Q_LTBANNER].IsAvailable()) AddObject(OBJ_SIGNCHEST, { 2 * setpc_x + 26, 2 * setpc_y + 19 }); InitRndLocBigObj(10, 15, OBJ_SARC); - if (currlevel >= 21) - AddCryptObjects(0, 0, MAXDUNX, MAXDUNY); - else - AddL1Objs(0, 0, MAXDUNX, MAXDUNY); + AddL1Objs(0, 0, MAXDUNX, MAXDUNY); InitRndBarrels(); } if (leveltype == DTYPE_CATACOMBS) { @@ -4580,7 +4705,7 @@ void InitObjects() } InitRndBarrels(); } - if (leveltype == DTYPE_CAVES) { + if (IsAnyOf(leveltype, DTYPE_CAVES, DTYPE_NEST)) { AddL3Objs(0, 0, MAXDUNX, MAXDUNY); InitRndBarrels(); } @@ -4616,12 +4741,17 @@ void InitObjects() InitRndBarrels(); AddL4Goodies(); } + if (leveltype == DTYPE_CRYPT) { + InitRndLocBigObj(10, 15, OBJ_L5SARC); + AddCryptObjects(0, 0, MAXDUNX, MAXDUNY); + InitRndBarrels(); + } InitRndLocObj(5, 10, OBJ_CHEST1); InitRndLocObj(3, 6, OBJ_CHEST2); InitRndLocObj(1, 5, OBJ_CHEST3); if (leveltype != DTYPE_HELL) AddObjTraps(); - if (leveltype > DTYPE_CATHEDRAL) + if (IsAnyOf(leveltype, DTYPE_CATACOMBS, DTYPE_CAVES, DTYPE_HELL, DTYPE_NEST)) AddChestTraps(); ApplyObjectLighting = false; } @@ -4629,17 +4759,15 @@ void InitObjects() void SetMapObjects(const uint16_t *dunData, int startx, int starty) { - bool filesLoaded[56]; - char filestr[32]; + bool filesLoaded[65] = {}; ClrAllObjects(); - for (auto &fileLoaded : filesLoaded) - fileLoaded = false; ApplyObjectLighting = true; - for (int i = 0; AllObjects[i].oload != -1; i++) { - if (AllObjects[i].oload == 1 && leveltype == AllObjects[i].olvltype) - filesLoaded[AllObjects[i].ofindex] = true; + for (const ObjectData objectData : AllObjects) { + if (leveltype == objectData.olvltype) { + filesLoaded[objectData.ofindex] = true; + } } int width = SDL_SwapLE16(dunData[0]); @@ -4662,11 +4790,13 @@ void SetMapObjects(const uint16_t *dunData, int startx, int starty) } } - for (int i = OFILE_L1BRAZ; i <= OFILE_LZSTAND; i++) { - if (!filesLoaded[i]) + for (int i = OFILE_L1BRAZ; i <= OFILE_L5BOOKS; i++) { + if (!filesLoaded[i]) { continue; + } - ObjFileList[numobjfiles] = (object_graphic_id)i; + ObjFileList[numobjfiles] = static_cast(i); + char filestr[32]; sprintf(filestr, "Objects\\%s.CEL", ObjMasterLoadList[i]); pObjCels[numobjfiles] = LoadFileInMem(filestr); numobjfiles++; @@ -4704,6 +4834,7 @@ void AddObject(_object_id objType, Point objPos) AddObjectLight(oi, 5); break; case OBJ_STORYCANDLE: + case OBJ_L5CANDLE: AddObjectLight(oi, 3); break; case OBJ_TORCHL: @@ -4725,6 +4856,10 @@ void AddObject(_object_id objType, Point objPos) case OBJ_L3RDOOR: InitializeMicroDoor(object); break; + case OBJ_L5LDOOR: + case OBJ_L5RDOOR: + InitializeL5Door(object); + break; case OBJ_BOOK2R: object.InitializeBook({ { setpc_x, setpc_y }, { setpc_w + 1, setpc_h + 1 } }); break; @@ -4745,6 +4880,7 @@ void AddObject(_object_id objType, Point objPos) } break; case OBJ_SARC: + case OBJ_L5SARC: AddSarc(oi); break; case OBJ_FLAMEHOLE: @@ -4762,7 +4898,11 @@ void AddObject(_object_id objType, Point objPos) break; case OBJ_BARREL: case OBJ_BARRELEX: - AddBarrel(oi, objType); + case OBJ_POD: + case OBJ_PODEX: + case OBJ_URN: + case OBJ_URNEX: + AddBarrel(object); break; case OBJ_SHRINEL: case OBJ_SHRINER: @@ -4809,6 +4949,7 @@ void AddObject(_object_id objType, Point objPos) AddMagicCircle(oi); break; case OBJ_STORYBOOK: + case OBJ_L5BOOKS: AddStoryBook(oi); break; case OBJ_BCROSS: @@ -4845,6 +4986,8 @@ void OperateTrap(Object &trap) case OBJ_L2RDOOR: case OBJ_L3LDOOR: case OBJ_L3RDOOR: + case OBJ_L5LDOOR: + case OBJ_L5RDOOR: if (trigger._oVar4 == 0) return; break; @@ -4854,6 +4997,8 @@ void OperateTrap(Object &trap) case OBJ_CHEST3: case OBJ_SWITCHSKL: case OBJ_SARC: + case OBJ_L5LEVER: + case OBJ_L5SARC: if (trigger._oSelFlag != 0) return; break; @@ -4896,6 +5041,7 @@ void ProcessObjects() UpdateObjectLight(oi, 5); break; case OBJ_STORYCANDLE: + case OBJ_L5CANDLE: UpdateObjectLight(oi, 3); break; case OBJ_CRUX1: @@ -4903,6 +5049,10 @@ void ProcessObjects() case OBJ_CRUX3: case OBJ_BARREL: case OBJ_BARRELEX: + case OBJ_POD: + case OBJ_PODEX: + case OBJ_URN: + case OBJ_URNEX: case OBJ_SHRINEL: case OBJ_SHRINER: ObjectStopAnim(oi); @@ -4913,6 +5063,8 @@ void ProcessObjects() case OBJ_L2RDOOR: case OBJ_L3LDOOR: case OBJ_L3RDOOR: + case OBJ_L5LDOOR: + case OBJ_L5RDOOR: UpdateDoor(oi); break; case OBJ_TORCHL: @@ -4922,6 +5074,7 @@ void ProcessObjects() UpdateObjectLight(oi, 8); break; case OBJ_SARC: + case OBJ_L5SARC: UpdateSarcoffagus(oi); break; case OBJ_FLAMEHOLE: @@ -5014,6 +5167,14 @@ void MonstCheckDoors(Monster &monster) if (dpx <= 1 && dpy == 1 && Objects[oi]._otype == OBJ_L3LDOOR) OperateL3LDoor(MyPlayerId, oi, true); } + if ((Objects[oi]._otype == OBJ_L5LDOOR || Objects[oi]._otype == OBJ_L5RDOOR) && Objects[oi]._oVar4 == 0) { + int dpx = abs(Objects[oi].position.x - mx); + int dpy = abs(Objects[oi].position.y - my); + if (dpx == 1 && dpy <= 1 && Objects[oi]._otype == OBJ_L5LDOOR) + OperateL5LDoor(MyPlayerId, oi, true); + if (dpx <= 1 && dpy == 1 && Objects[oi]._otype == OBJ_L5RDOOR) + OperateL5RDoor(MyPlayerId, oi, true); + } } } } @@ -5026,7 +5187,7 @@ void ObjChangeMap(int x1, int y1, int x2, int y2) dungeon[i][j] = pdungeon[i][j]; } } - if (leveltype == DTYPE_CATHEDRAL && currlevel < 17) { + if (leveltype == DTYPE_CATHEDRAL) { ObjL1Special(2 * x1 + 16, 2 * y1 + 16, 2 * x2 + 17, 2 * y2 + 17); AddL1Objs(2 * x1 + 16, 2 * y1 + 16, 2 * x2 + 17, 2 * y2 + 17); } @@ -5034,6 +5195,9 @@ void ObjChangeMap(int x1, int y1, int x2, int y2) ObjL2Special(2 * x1 + 16, 2 * y1 + 16, 2 * x2 + 17, 2 * y2 + 17); AddL2Objs(2 * x1 + 16, 2 * y1 + 16, 2 * x2 + 17, 2 * y2 + 17); } + if (leveltype == DTYPE_CRYPT) { + AddL5Objs(2 * x1 + 16, 2 * y1 + 16, 2 * x2 + 17, 2 * y2 + 17); + } } void ObjChangeMapResync(int x1, int y1, int x2, int y2) @@ -5044,7 +5208,7 @@ void ObjChangeMapResync(int x1, int y1, int x2, int y2) dungeon[i][j] = pdungeon[i][j]; } } - if (leveltype == DTYPE_CATHEDRAL && currlevel < 17) { + if (leveltype == DTYPE_CATHEDRAL) { ObjL1Special(2 * x1 + 16, 2 * y1 + 16, 2 * x2 + 17, 2 * y2 + 17); } if (leveltype == DTYPE_CATACOMBS) { @@ -5125,7 +5289,20 @@ void OperateObject(int pnum, int i, bool teleFlag) if (pnum == MyPlayerId) OperateL3Door(pnum, i, true); break; + case OBJ_L5LDOOR: + case OBJ_L5RDOOR: + if (teleFlag) { + if (Objects[i]._otype == OBJ_L5LDOOR) + OperateL5LDoor(pnum, i, true); + if (Objects[i]._otype == OBJ_L5RDOOR) + OperateL5RDoor(pnum, i, true); + break; + } + if (pnum == MyPlayerId) + OperateL5Door(pnum, i, true); + break; case OBJ_LEVER: + case OBJ_L5LEVER: case OBJ_SWITCHSKL: OperateLever(pnum, i); break; @@ -5144,6 +5321,7 @@ void OperateObject(int pnum, int i, bool teleFlag) OperateChest(pnum, i, sendmsg); break; case OBJ_SARC: + case OBJ_L5SARC: OperateSarc(pnum, i, sendmsg); break; case OBJ_FLAMELVR: @@ -5186,6 +5364,7 @@ void OperateObject(int pnum, int i, bool teleFlag) OperateFountains(pnum, i); break; case OBJ_STORYBOOK: + case OBJ_L5BOOKS: OperateStoryBook(pnum, i); break; case OBJ_PEDISTAL: @@ -5227,7 +5406,12 @@ void SyncOpObject(int pnum, int cmd, int i) case OBJ_L3RDOOR: SyncOpL3Door(pnum, cmd, i); break; + case OBJ_L5LDOOR: + case OBJ_L5RDOOR: + SyncOpL5Door(pnum, cmd, i); + break; case OBJ_LEVER: + case OBJ_L5LEVER: case OBJ_SWITCHSKL: OperateLever(pnum, i); break; @@ -5240,6 +5424,7 @@ void SyncOpObject(int pnum, int cmd, int i) OperateChest(pnum, i, false); break; case OBJ_SARC: + case OBJ_L5SARC: OperateSarc(pnum, i, false); break; case OBJ_BLINDBOOK: @@ -5277,6 +5462,7 @@ void SyncOpObject(int pnum, int cmd, int i) OperateFountains(pnum, i); break; case OBJ_STORYBOOK: + case OBJ_L5BOOKS: OperateStoryBook(pnum, i); break; case OBJ_PEDISTAL: @@ -5351,12 +5537,17 @@ void SyncObjectAnim(Object &object) case OBJ_L3RDOOR: SyncL3Doors(object); break; + case OBJ_L5LDOOR: + case OBJ_L5RDOOR: + SyncL5Doors(object); + break; case OBJ_CRUX1: case OBJ_CRUX2: case OBJ_CRUX3: SyncCrux(object); break; case OBJ_LEVER: + case OBJ_L5LEVER: case OBJ_BOOK2L: case OBJ_SWITCHSKL: SyncLever(object); @@ -5383,6 +5574,7 @@ void GetObjectStr(const Object &object) InfoString = _("Crucified Skeleton"); break; case OBJ_LEVER: + case OBJ_L5LEVER: case OBJ_FLAMELVR: InfoString = _("Lever"); break; @@ -5392,6 +5584,8 @@ void GetObjectStr(const Object &object) case OBJ_L2RDOOR: case OBJ_L3LDOOR: case OBJ_L3RDOOR: + case OBJ_L5LDOOR: + case OBJ_L5RDOOR: if (object._oVar4 == 1) InfoString = _("Open Door"); if (object._oVar4 == 0) @@ -5428,6 +5622,7 @@ void GetObjectStr(const Object &object) InfoString = _("Large Chest"); break; case OBJ_SARC: + case OBJ_L5SARC: InfoString = _("Sarcophagus"); break; case OBJ_BOOKSHELF: @@ -5439,12 +5634,15 @@ void GetObjectStr(const Object &object) break; case OBJ_BARREL: case OBJ_BARRELEX: - if (currlevel >= 17 && currlevel <= 20) // for hive levels - InfoString = _("Pod"); // Then a barrel is called a pod - else if (currlevel >= 21 && currlevel <= 24) // for crypt levels - InfoString = _("Urn"); // Then a barrel is called an urn - else - InfoString = _("Barrel"); + InfoString = _("Barrel"); + break; + case OBJ_POD: + case OBJ_PODEX: + InfoString = _("Pod"); + break; + case OBJ_URN: + case OBJ_URNEX: + InfoString = _("Urn"); break; case OBJ_SHRINEL: case OBJ_SHRINER: @@ -5497,6 +5695,7 @@ void GetObjectStr(const Object &object) InfoString = _("Pedestal of Blood"); break; case OBJ_STORYBOOK: + case OBJ_L5BOOKS: InfoString = _(StoryBookName[object._oVar3]); break; case OBJ_WEAPONRACK: @@ -5561,7 +5760,7 @@ void AddNakrulLeaver() break; } } - AddObject(OBJ_LEVER, { UberRow + 3, UberCol - 1 }); + AddObject(OBJ_L5LEVER, { UberRow + 3, UberCol - 1 }); } } // namespace devilution diff --git a/Source/objects.h b/Source/objects.h index b181b685f..6b892b3d1 100644 --- a/Source/objects.h +++ b/Source/objects.h @@ -170,7 +170,15 @@ struct Object { */ [[nodiscard]] constexpr bool IsBarrel() const { - return IsAnyOf(_otype, _object_id::OBJ_BARREL, _object_id::OBJ_BARRELEX); + return IsAnyOf(_otype, _object_id::OBJ_BARREL, _object_id::OBJ_BARRELEX, _object_id::OBJ_POD, _object_id::OBJ_PODEX, _object_id::OBJ_URN, _object_id::OBJ_URNEX); + } + + /** + * @brief Check if this object contains explosives or caustic material + */ + [[nodiscard]] constexpr bool isExplosive() const + { + return IsAnyOf(_otype, _object_id::OBJ_BARRELEX, _object_id::OBJ_PODEX, _object_id::OBJ_URNEX); } /** @@ -220,7 +228,7 @@ struct Object { */ [[nodiscard]] constexpr bool IsDoor() const { - return IsAnyOf(_otype, _object_id::OBJ_L1LDOOR, _object_id::OBJ_L1RDOOR, _object_id::OBJ_L2LDOOR, _object_id::OBJ_L2RDOOR, _object_id::OBJ_L3LDOOR, _object_id::OBJ_L3RDOOR); + return IsAnyOf(_otype, _object_id::OBJ_L1LDOOR, _object_id::OBJ_L1RDOOR, _object_id::OBJ_L2LDOOR, _object_id::OBJ_L2RDOOR, _object_id::OBJ_L3LDOOR, _object_id::OBJ_L3RDOOR, _object_id::OBJ_L5LDOOR, _object_id::OBJ_L5RDOOR); } /** @@ -280,6 +288,7 @@ void InitObjectGFX(); void FreeObjectGFX(); void AddL1Objs(int x1, int y1, int x2, int y2); void AddL2Objs(int x1, int y1, int x2, int y2); +void AddL5Objs(int x1, int y1, int x2, int y2); void InitObjects(); void SetMapObjects(const uint16_t *dunData, int startx, int starty); /** diff --git a/Source/player.cpp b/Source/player.cpp index d990129b0..2ca438c86 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -2917,7 +2917,7 @@ void PlrClrTrans(Point position) void PlrDoTrans(Point position) { - if (leveltype != DTYPE_CATHEDRAL && leveltype != DTYPE_CATACOMBS) { + if (IsNoneOf(leveltype, DTYPE_CATHEDRAL, DTYPE_CATACOMBS, DTYPE_CRYPT)) { TransList[1] = true; return; } diff --git a/Source/sound.cpp b/Source/sound.cpp index 06994a5e5..fc7b5f075 100644 --- a/Source/sound.cpp +++ b/Source/sound.cpp @@ -121,8 +121,8 @@ const char *const SpawnMusicTracks[NUM_MUSIC] = { "Music\\sLvlA.wav", "Music\\sLvlA.wav", "Music\\sLvlA.wav", - "Music\\DLvlE.wav", "Music\\DLvlF.wav", + "Music\\DLvlE.wav", "Music\\sintro.wav", }; /** Maps from track ID to track name. */ @@ -132,8 +132,8 @@ const char *const MusicTracks[NUM_MUSIC] = { "Music\\DLvlB.wav", "Music\\DLvlC.wav", "Music\\DLvlD.wav", - "Music\\DLvlE.wav", "Music\\DLvlF.wav", + "Music\\DLvlE.wav", "Music\\Dintro.wav", }; @@ -228,7 +228,7 @@ void music_stop() sgnMusicTrack = NUM_MUSIC; } -void music_start(uint8_t nTrack) +void music_start(_music_id nTrack) { const char *trackPath; diff --git a/Source/sound.h b/Source/sound.h index 22bdf3841..cdec5e544 100644 --- a/Source/sound.h +++ b/Source/sound.h @@ -19,12 +19,12 @@ namespace devilution { enum _music_id : uint8_t { TMUSIC_TOWN, - TMUSIC_L1, - TMUSIC_L2, - TMUSIC_L3, - TMUSIC_L4, - TMUSIC_L5, - TMUSIC_L6, + TMUSIC_CATHEDRAL, + TMUSIC_CATACOMBS, + TMUSIC_CAVES, + TMUSIC_HELL, + TMUSIC_NEST, + TMUSIC_CRYPT, TMUSIC_INTRO, NUM_MUSIC, }; @@ -59,7 +59,7 @@ std::unique_ptr sound_file_load(const char *path, bool stream = false); void snd_init(); void snd_deinit(); void music_stop(); -void music_start(uint8_t nTrack); +void music_start(_music_id nTrack); void sound_disable_music(bool disable); int sound_get_or_set_music_volume(int volume); int sound_get_or_set_sound_volume(int volume); diff --git a/Source/themes.cpp b/Source/themes.cpp index 0f68e4ae9..2818f7edf 100644 --- a/Source/themes.cpp +++ b/Source/themes.cpp @@ -141,7 +141,7 @@ bool TFit_Obj5(int t) bool TFit_SkelRoom(int t) { - if (leveltype != DTYPE_CATHEDRAL && leveltype != DTYPE_CATACOMBS) { + if (IsNoneOf(leveltype, DTYPE_CATHEDRAL, DTYPE_CATACOMBS, DTYPE_CRYPT)) { return false; } @@ -193,7 +193,7 @@ bool CheckThemeObj3(Point origin, int8_t regionId, int frequency) bool TFit_Obj3(int8_t regionId) { - char objrnd[4] = { 4, 4, 3, 5 }; + int objrnd[6] = { 4, 4, 3, 5, 3, 4 }; for (int yp = 1; yp < MAXDUNY - 1; yp++) { for (int xp = 1; xp < MAXDUNX - 1; xp++) { @@ -229,7 +229,7 @@ bool CheckThemeReqs(theme_id t) } break; case THEME_ARMORSTAND: - if (leveltype == DTYPE_CATHEDRAL) { + if (leveltype == DTYPE_CATHEDRAL || leveltype == DTYPE_CRYPT) { return false; } break; @@ -249,7 +249,7 @@ bool CheckThemeReqs(theme_id t) } break; case THEME_WEAPONRACK: - if (leveltype == DTYPE_CATHEDRAL) { + if (leveltype == DTYPE_CATHEDRAL || leveltype == DTYPE_CRYPT) { return false; } break; @@ -363,7 +363,7 @@ bool CheckThemeRoom(int tv) } } - if (leveltype == DTYPE_CATHEDRAL && (tarea < 9 || tarea > 100)) + if (IsAnyOf(leveltype, DTYPE_CATHEDRAL, DTYPE_CRYPT) && (tarea < 9 || tarea > 100)) return false; for (int j = 0; j < MAXDUNY; j++) { @@ -400,7 +400,7 @@ void InitThemes() if (currlevel == 16) return; - if (leveltype == DTYPE_CATHEDRAL) { + if (IsAnyOf(leveltype, DTYPE_CATHEDRAL, DTYPE_CRYPT)) { for (size_t i = 0; i < 256 && numthemes < MAXTHEMES; i++) { if (CheckThemeRoom(i)) { themes[numthemes].ttval = i; @@ -412,32 +412,34 @@ void InitThemes() numthemes++; } } + return; } - if (leveltype == DTYPE_CATACOMBS || leveltype == DTYPE_CAVES || leveltype == DTYPE_HELL) { - for (int i = 0; i < themeCount; i++) - themes[i].ttype = THEME_NONE; - if (Quests[Q_ZHAR].IsAvailable()) { - for (int j = 0; j < themeCount; j++) { - themes[j].ttval = themeLoc[j].ttval; - if (SpecialThemeFit(j, THEME_LIBRARY)) { - themes[j].ttype = THEME_LIBRARY; - zharlib = j; - break; - } + + for (int i = 0; i < themeCount; i++) { + themes[i].ttype = THEME_NONE; + } + + if (Quests[Q_ZHAR].IsAvailable()) { + for (int j = 0; j < themeCount; j++) { + themes[j].ttval = themeLoc[j].ttval; + if (SpecialThemeFit(j, THEME_LIBRARY)) { + themes[j].ttype = THEME_LIBRARY; + zharlib = j; + break; } } - for (int i = 0; i < themeCount; i++) { - if (themes[i].ttype == THEME_NONE) { - themes[i].ttval = themeLoc[i].ttval; - theme_id j = ThemeGood[GenerateRnd(4)]; - while (!SpecialThemeFit(i, j)) { - j = (theme_id)GenerateRnd(17); - } - themes[i].ttype = j; + } + for (int i = 0; i < themeCount; i++) { + if (themes[i].ttype == THEME_NONE) { + themes[i].ttval = themeLoc[i].ttval; + theme_id j = ThemeGood[GenerateRnd(4)]; + while (!SpecialThemeFit(i, j)) { + j = (theme_id)GenerateRnd(17); } + themes[i].ttype = j; } - numthemes += themeCount; } + numthemes += themeCount; } void HoldThemeRooms() @@ -445,7 +447,7 @@ void HoldThemeRooms() if (currlevel == 16) return; - if (leveltype != DTYPE_CATHEDRAL) { + if (leveltype != DTYPE_CATHEDRAL && leveltype != DTYPE_CRYPT) { DRLG_HoldThemeRooms(); return; } @@ -498,8 +500,8 @@ void PlaceThemeMonsts(int t, int f) */ void Theme_Barrel(int t) { - char barrnd[4] = { 2, 6, 4, 8 }; - char monstrnd[4] = { 5, 7, 3, 9 }; + int barrnd[6] = { 2, 6, 4, 8, 4, 2 }; + int monstrnd[6] = { 5, 7, 3, 9, 3, 5 }; for (int yp = 0; yp < MAXDUNY; yp++) { for (int xp = 0; xp < MAXDUNX; xp++) { @@ -524,7 +526,7 @@ void Theme_Barrel(int t) */ void Theme_Shrine(int t) { - char monstrnd[4] = { 6, 6, 3, 9 }; + int monstrnd[6] = { 6, 6, 3, 9, 3, 6 }; TFit_Shrine(t); if (themeVar1 == 1) { @@ -546,7 +548,7 @@ void Theme_Shrine(int t) */ void Theme_MonstPit(int t) { - uint8_t monstrnd[4] = { 6, 7, 3, 9 }; + int monstrnd[6] = { 6, 7, 3, 9, 3, 6 }; int r = GenerateRnd(100) + 1; int ixp = 0; @@ -578,7 +580,7 @@ void Theme_MonstPit(int t) */ void Theme_SkelRoom(int t) { - char monstrnd[4] = { 6, 7, 3, 9 }; + int monstrnd[6] = { 6, 7, 3, 9, 3, 6 }; TFit_SkelRoom(t); @@ -651,8 +653,8 @@ void Theme_SkelRoom(int t) */ void Theme_Treasure(int t) { - int8_t treasrnd[4] = { 4, 9, 7, 10 }; - int8_t monstrnd[4] = { 6, 8, 3, 7 }; + int treasrnd[6] = { 4, 9, 7, 10, 7, 4 }; + int monstrnd[6] = { 6, 8, 3, 7, 3, 6 }; AdvanceRndSeed(); for (int yp = 0; yp < MAXDUNY; yp++) { @@ -669,7 +671,7 @@ void Theme_Treasure(int t) CreateRndItem({ xp, yp }, false, false, true); ItemNoFlippy(); } - if (rv >= treasureType - 2 && leveltype != DTYPE_CATHEDRAL) { + if (rv >= treasureType - 2 && IsNoneOf(leveltype, DTYPE_CATHEDRAL, DTYPE_CRYPT)) { Item &item = Items[ActiveItems[ActiveItemCount - 1]]; if (item.IDidx == IDI_GOLD) { item._ivalue = std::max(item._ivalue / 2, 1); @@ -688,8 +690,8 @@ void Theme_Treasure(int t) */ void Theme_Library(int t) { - char librnd[4] = { 1, 2, 2, 5 }; - char monstrnd[4] = { 5, 7, 3, 9 }; + int librnd[6] = { 1, 2, 2, 5, 2, 1 }; + int monstrnd[6] = { 5, 7, 3, 9, 3, 5 }; TFit_Shrine(t); @@ -735,8 +737,8 @@ void Theme_Library(int t) */ void Theme_Torture(int t) { - char tortrnd[4] = { 6, 8, 3, 8 }; - char monstrnd[4] = { 6, 8, 3, 9 }; + int tortrnd[6] = { 6, 8, 3, 8, 3, 6 }; + int monstrnd[6] = { 6, 8, 3, 9, 3, 6 }; for (int yp = 1; yp < MAXDUNY - 1; yp++) { for (int xp = 1; xp < MAXDUNX - 1; xp++) { @@ -758,7 +760,7 @@ void Theme_Torture(int t) */ void Theme_BloodFountain(int t) { - char monstrnd[4] = { 6, 8, 3, 9 }; + int monstrnd[6] = { 6, 8, 3, 9, 3, 6 }; TFit_Obj5(t); AddObject(OBJ_BLOODFTN, { themex, themey }); @@ -772,8 +774,8 @@ void Theme_BloodFountain(int t) */ void Theme_Decap(int t) { - char decaprnd[4] = { 6, 8, 3, 8 }; - char monstrnd[4] = { 6, 8, 3, 9 }; + int decaprnd[6] = { 6, 8, 3, 8, 3, 6 }; + int monstrnd[6] = { 6, 8, 3, 9, 3, 6 }; for (int yp = 1; yp < MAXDUNY - 1; yp++) { for (int xp = 1; xp < MAXDUNX - 1; xp++) { @@ -796,7 +798,7 @@ void Theme_Decap(int t) */ void Theme_PurifyingFountain(int t) { - char monstrnd[4] = { 6, 7, 3, 9 }; + int monstrnd[6] = { 6, 7, 3, 9, 3, 6 }; TFit_Obj5(t); AddObject(OBJ_PURIFYINGFTN, { themex, themey }); @@ -810,8 +812,8 @@ void Theme_PurifyingFountain(int t) */ void Theme_ArmorStand(int t) { - char armorrnd[4] = { 6, 8, 3, 8 }; - char monstrnd[4] = { 6, 7, 3, 9 }; + int armorrnd[6] = { 6, 8, 3, 8, 3, 6 }; + int monstrnd[6] = { 6, 7, 3, 9, 3, 6 }; if (armorFlag) { TFit_Obj3(themes[t].ttval); @@ -857,7 +859,7 @@ void Theme_GoatShrine(int t) */ void Theme_Cauldron(int t) { - char monstrnd[4] = { 6, 7, 3, 9 }; + int monstrnd[6] = { 6, 7, 3, 9, 3, 6 }; TFit_Obj5(t); AddObject(OBJ_CAULDRON, { themex, themey }); @@ -871,7 +873,7 @@ void Theme_Cauldron(int t) */ void Theme_MurkyFountain(int t) { - char monstrnd[4] = { 6, 7, 3, 9 }; + int monstrnd[6] = { 6, 7, 3, 9, 3, 6 }; TFit_Obj5(t); AddObject(OBJ_MURKYFTN, { themex, themey }); @@ -885,7 +887,7 @@ void Theme_MurkyFountain(int t) */ void Theme_TearFountain(int t) { - char monstrnd[4] = { 6, 7, 3, 9 }; + int monstrnd[6] = { 6, 7, 3, 9, 3, 6 }; TFit_Obj5(t); AddObject(OBJ_TEARFTN, { themex, themey }); @@ -900,8 +902,8 @@ void Theme_TearFountain(int t) void Theme_BrnCross(int t) { int8_t regionId = themes[t].ttval; - char monstrnd[4] = { 6, 8, 3, 9 }; - char bcrossrnd[4] = { 5, 7, 3, 8 }; + int monstrnd[6] = { 6, 8, 3, 9, 3, 6 }; + int bcrossrnd[6] = { 5, 7, 3, 8, 3, 5 }; for (int yp = 0; yp < MAXDUNY; yp++) { for (int xp = 0; xp < MAXDUNX; xp++) { @@ -925,8 +927,8 @@ void Theme_BrnCross(int t) void Theme_WeaponRack(int t) { int8_t regionId = themes[t].ttval; - char weaponrnd[4] = { 6, 8, 5, 8 }; - char monstrnd[4] = { 6, 7, 3, 9 }; + int weaponrnd[6] = { 6, 8, 5, 8, 5, 6 }; + int monstrnd[6] = { 6, 7, 3, 9, 3, 6 }; if (weaponFlag) { TFit_Obj3(regionId); @@ -963,7 +965,7 @@ void UpdateL4Trans() void CreateThemeRooms() { - if (currlevel == 16) { + if (currlevel == 16 || IsAnyOf(leveltype, DTYPE_NEST, DTYPE_CRYPT)) { return; } ApplyObjectLighting = true; diff --git a/Source/trigs.cpp b/Source/trigs.cpp index 7c23dc02c..4ce610394 100644 --- a/Source/trigs.cpp +++ b/Source/trigs.cpp @@ -761,12 +761,14 @@ void CheckTrigForce() trigflag = ForceTownTrig(); break; case DTYPE_CATHEDRAL: + case DTYPE_CRYPT: trigflag = ForceL1Trig(); break; case DTYPE_CATACOMBS: trigflag = ForceL2Trig(); break; case DTYPE_CAVES: + case DTYPE_NEST: trigflag = ForceL3Trig(); break; case DTYPE_HELL: