From 1a150ed193ab9a8ed6fd32bf9fe0f80eab5cddb8 Mon Sep 17 00:00:00 2001 From: obligaron Date: Sun, 9 Apr 2023 02:32:52 +0200 Subject: [PATCH] Multiplayer: Ensure monster hitpoints are calculated reproducable in quest/set-maps (#5958) * Always use the same seed for generating set/quest maps * Use setlvltype for loading quest/set-map (instead of leveltype) * Ensure dungeon flags are reset when loading a quest/set-map --- Source/diablo.cpp | 9 ++++++++- Source/levels/drlg_l1.cpp | 8 ++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Source/diablo.cpp b/Source/diablo.cpp index dc32551f5..96e1f36ed 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -2710,7 +2710,14 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir) InitStores(); InitAutomapOnce(); } - SetRndSeed(glSeedTbl[currlevel]); + if (!setlevel) { + SetRndSeed(glSeedTbl[currlevel]); + } else { + // Maps are not randomly generated, but the monsters max hitpoints are. + // So we need to ensure that we have a stable seed when generating quest/set-maps. + // For this purpose we reuse the normal dungeon seeds. + SetRndSeed(glSeedTbl[static_cast(setlvlnum)]); + } if (leveltype == DTYPE_TOWN) { SetupTownStores(); diff --git a/Source/levels/drlg_l1.cpp b/Source/levels/drlg_l1.cpp index e3ff202bf..bf7e726d1 100644 --- a/Source/levels/drlg_l1.cpp +++ b/Source/levels/drlg_l1.cpp @@ -1304,12 +1304,12 @@ void CreateL5Dungeon(uint32_t rseed, lvl_entry entry) void LoadPreL1Dungeon(const char *path) { - memset(dungeon, Dirt, sizeof(dungeon)); + InitDungeonFlags(); auto dunData = LoadFileInMem(path); PlaceDunTiles(dunData.get(), { 0, 0 }, Floor); - if (leveltype == DTYPE_CATHEDRAL) + if (setlvltype == DTYPE_CATHEDRAL) FillFloor(); memcpy(pdungeon, dungeon, sizeof(pdungeon)); @@ -1319,12 +1319,12 @@ void LoadL1Dungeon(const char *path, Point spawn) { LoadDungeonBase(path, spawn, Floor, Dirt); - if (leveltype == DTYPE_CATHEDRAL) + if (setlvltype == DTYPE_CATHEDRAL) FillFloor(); Pass3(); - if (leveltype == DTYPE_CRYPT) + if (setlvltype == DTYPE_CRYPT) AddCryptObjects(0, 0, MAXDUNX, MAXDUNY); else AddL1Objs(0, 0, MAXDUNX, MAXDUNY);