Skip to content

Commit

Permalink
DebugSpawnItem: Ensure item uses valid monster level
Browse files Browse the repository at this point in the history
  • Loading branch information
obligaron committed Feb 10, 2024
1 parent 38e98fb commit f3e20c4
Showing 1 changed file with 31 additions and 1 deletion.
32 changes: 31 additions & 1 deletion Source/items.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4585,26 +4585,56 @@ std::string DebugSpawnItem(std::string itemName)

Item testItem;

// get all valid monster levels
std::vector<uint8_t> monsterLevels {};
for (int16_t i = 0; i < static_cast<int16_t>(NUM_MTYPES); i++) {
const auto &monsterData = MonstersData[i];
auto monsterLevel = static_cast<uint8_t>(monsterData.level);

if (i == MT_DIABLO) {
if (!gbIsHellfire) {
// Adjust The Dark Lord's mlvl if the item isn't a Hellfire item to match the Diablo mlvl
monsterLevel -= 15;
}
} else {
if (monsterData.availability == MonsterAvailability::Never) {
// Skip monsters that are unable to appear in the game
continue;
}
if (!gbIsHellfire && monsterData.minDunLvl > 16) {
// Skip hellfire monsters in diablo
continue;
}
}

if (std::find(monsterLevels.begin(), monsterLevels.end(), monsterLevel) == monsterLevels.end()) {
monsterLevels.push_back(monsterLevel);
}
}

uint32_t begin = SDL_GetTicks();
int i = 0;
for (;; i++) {
// using a better rng here to seed the item to prevent getting stuck repeating same values using old one
std::uniform_int_distribution<int32_t> dist(0, INT_MAX);
std::uniform_int_distribution<int32_t> distLevel(0, static_cast<int>(monsterLevels.size()) - 1);
SetRndSeed(dist(BetterRng));
if (SDL_GetTicks() - begin > max_time)
return StrCat("Item not found in ", max_time / 1000, " seconds!");

if (i > max_iter)
return StrCat("Item not found in ", max_iter, " tries!");

const int8_t monsterLevel = dist(BetterRng) % CF_LEVEL + 1;
const int8_t monsterLevel = monsterLevels[distLevel(BetterRng)];
_item_indexes idx = RndItemForMonsterLevel(monsterLevel);
if (IsAnyOf(idx, IDI_NONE, IDI_GOLD))
continue;

testItem = {};
SetupAllItems(*MyPlayer, testItem, idx, AdvanceRndSeed(), monsterLevel, 1, false, false, false);

assert(IsDungeonItemValid(testItem._iCreateInfo, testItem.dwBuff));

std::string tmp = AsciiStrToLower(testItem._iIName);
if (tmp.find(itemName) != std::string::npos)
break;
Expand Down

0 comments on commit f3e20c4

Please sign in to comment.