Skip to content

Commit

Permalink
Capture the level seed and use it to skip failed dungeon layouts
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenCWills authored and AJenbo committed Mar 6, 2024
1 parent 9e682af commit 3c5b298
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 0 deletions.
1 change: 1 addition & 0 deletions Source/diablo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
namespace devilution {

uint32_t DungeonSeeds[NUMLEVELS];
std::optional<uint32_t> LevelSeeds[NUMLEVELS];
Point MousePosition;
bool gbRunGame;
bool gbRunGameResult;
Expand Down
1 change: 1 addition & 0 deletions Source/diablo.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ enum class MouseActionType : uint8_t {
};

extern uint32_t DungeonSeeds[NUMLEVELS];
extern std::optional<uint32_t> LevelSeeds[NUMLEVELS];
extern Point MousePosition;
extern DVL_API_FOR_TEST bool gbRunGame;
extern bool gbRunGameResult;
Expand Down
4 changes: 4 additions & 0 deletions Source/levels/drlg_l1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,9 @@ bool PlaceStairs(lvl_entry entry)

void GenerateLevel(lvl_entry entry)
{
if (LevelSeeds[currlevel])
SetRndSeed(*LevelSeeds[currlevel]);

size_t minarea = 761;
switch (currlevel) {
case 1:
Expand All @@ -1181,6 +1184,7 @@ void GenerateLevel(lvl_entry entry)
DRLG_InitTrans();

do {
LevelSeeds[currlevel] = GetLCGEngineState();
FirstRoom();
} while (FindArea() < minarea);

Expand Down
4 changes: 4 additions & 0 deletions Source/levels/drlg_l2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2669,7 +2669,11 @@ bool PlaceStairs(lvl_entry entry)

void GenerateLevel(lvl_entry entry)
{
if (LevelSeeds[currlevel])
SetRndSeed(*LevelSeeds[currlevel]);

while (true) {
LevelSeeds[currlevel] = GetLCGEngineState();
nRoomCnt = 0;
InitDungeonFlags();
DRLG_InitTrans();
Expand Down
5 changes: 5 additions & 0 deletions Source/levels/drlg_l3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "monster.h"
#include "objdat.h"
#include "objects.h"
#include "player.h"
#include "quests.h"

namespace devilution {
Expand Down Expand Up @@ -1988,7 +1989,11 @@ bool PlaceStairs(lvl_entry entry)

void GenerateLevel(lvl_entry entry)
{
if (LevelSeeds[currlevel])
SetRndSeed(*LevelSeeds[currlevel]);

while (true) {
LevelSeeds[currlevel] = GetLCGEngineState();
InitDungeonFlags();
int x1 = GenerateRnd(20) + 10;
int y1 = GenerateRnd(20) + 10;
Expand Down
5 changes: 5 additions & 0 deletions Source/levels/drlg_l4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "monster.h"
#include "multi.h"
#include "objdat.h"
#include "player.h"

namespace devilution {

Expand Down Expand Up @@ -1138,11 +1139,15 @@ bool PlaceStairs(lvl_entry entry)

void GenerateLevel(lvl_entry entry)
{
if (LevelSeeds[currlevel])
SetRndSeed(*LevelSeeds[currlevel]);

while (true) {
DRLG_InitTrans();

constexpr size_t Minarea = 692;
do {
LevelSeeds[currlevel] = GetLCGEngineState();
InitDungeonFlags();
FirstRoom();
CloseOuterBorders();
Expand Down
28 changes: 28 additions & 0 deletions Source/loadsave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2027,6 +2027,21 @@ void SaveHotkeys(SaveWriter &saveWriter, const Player &player)
file.WriteLE<uint8_t>(static_cast<uint8_t>(player._pRSplType));
}

void LoadLevelSeeds()
{
LoadHelper file(OpenSaveArchive(gSaveNumber), "levelseeds");
if (!file.IsValid())
return;

for (int i = 0; i < giNumberOfLevels; i++) {
if (file.NextLE<uint8_t>() != 0) {
LevelSeeds[i] = file.NextLE<uint32_t>();
} else {
LevelSeeds[i] = std::nullopt;
}
}
}

void LoadHeroItems(Player &player)
{
LoadHelper file(OpenSaveArchive(gSaveNumber), "heroitems");
Expand Down Expand Up @@ -2137,6 +2152,7 @@ void LoadGame(bool firstflag)

for (uint8_t i = 0; i < giNumberOfLevels; i++) {
DungeonSeeds[i] = file.NextBE<uint32_t>();
LevelSeeds[i] = std::nullopt;
file.Skip(4); // Skip loading gnLevelTypeTbl
}

Expand Down Expand Up @@ -2304,6 +2320,18 @@ void LoadGame(bool firstflag)
gbIsHellfireSaveGame = gbIsHellfire;
}

void SaveLevelSeeds(SaveWriter &saveWriter)
{
SaveHelper file(saveWriter, "levelseeds", giNumberOfLevels * (sizeof(uint8_t) + sizeof(uint32_t)));

for (int i = 0; i < giNumberOfLevels; i++) {
file.WriteLE<uint8_t>(LevelSeeds[i] ? 1 : 0);
if (LevelSeeds[i]) {
file.WriteLE<uint32_t>(*LevelSeeds[i]);
}
}
}

void SaveHeroItems(SaveWriter &saveWriter, Player &player)
{
size_t itemCount = static_cast<size_t>(NUM_INVLOC) + InventoryGridCells + MaxBeltItems;
Expand Down
1 change: 1 addition & 0 deletions Source/lua/modules/dev/level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ std::string DebugCmdResetLevel(uint8_t level, std::optional<int> seed)

if (seed.has_value()) {
DungeonSeeds[level] = *seed;
LevelSeeds[level] = std::nullopt;
return StrCat("Successfully reset level ", level, " with seed ", *seed, ".");
}
return StrCat("Successfully reset level ", level, ".");
Expand Down
1 change: 1 addition & 0 deletions Source/multi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,7 @@ bool NetInit(bool bSinglePlayer)

for (int i = 0; i < NUMLEVELS; i++) {
DungeonSeeds[i] = AdvanceRndSeed();
LevelSeeds[i] = std::nullopt;
}
PublicGame = DvlNet_IsPublicGame();

Expand Down

0 comments on commit 3c5b298

Please sign in to comment.