-
Notifications
You must be signed in to change notification settings - Fork 795
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix infinite loop in unique item randomization #7370
Conversation
Hold that thought. I seem to have some uniques vanishing before I can reach them. Also it appears to be generating like vanilla. Let me test further. |
Okay, so I was able to get some item drops, but the vanished from the ground before I could pick them up:
(Note: All the other uniques I've encountered so far have not vanished) This was played in Nightmare, so some of these could legally drop even in vanilla. What it looks like to me is that the |
How do you generate the uniques? |
I'm forcing all monsters to take on unique monster status, then spamming chain lightning around the dungeon. I personally don't trust the debug command |
With this PR logic: Desktop.2024.08.25.-.16.18.33.03.mp4Current master logic: Desktop.2024.08.25.-.16.21.18.04.mp4Debug modifications: } else if (true || monster.isUnique() || dropsSpecialTreasure) { L3415 int uper = 15; L3237 item._iIdentified = true; |
Thanks @kphoenix137 🙂 This didn't matter in the debug commands, because the position was set after the |
Thats funny. I remember having the same exact problem when coding this in the first place. I just forgot what the problem was until you mentioned that |
You left your debug code in. |
Bad news, nearly all the uniques I picked up morph in vanilla (Specifically most of the ones I was picking up were previously on the "vanish" list, so those are the ones being recreated). Are you utilizing The code for selecting a target level was introduced in order to create reverse compatible uniques, as we would first select the uid we want, and then brute force search using target item data to find that unique, that doesn't exactly match the source of the drop, but it successfully allows us to create stable uniques that won't morph in vanilla. The idea was to take advantage of the fact vanilla always selects the last applicable uid, so we'd select a target level that makes sure that the desired uid is the last in the list. |
I just tested forcing all monsters as unique monsters and forced the War Hammer as the selected idx for every drop, and I was able to successfully get Schaefer's Hammer to drop in the latest master. Maybe there's something wrong with the debug command for generating these uniques? Edit: Back again, I got an infinite loop in Single Player Hellfire. I'll see what happens in Single Player Diablo Edit: No infinite loop in SP Diablo Edit: Infinite loop in SP and MP Hellfire. Looking into it. |
Here, the vanilla algorithm picked Thunderclap, and then
Vanilla algorithm decides again that it's a Thunderclap.
At this point,
This repeats for a bit as it's selecting non-uniques.
We finally roll a unique, but
As expected, it continues on and on like this. I truly didn't anticipate this happening as I was testing in Diablo. Maybe you already explained this, but the original post seems overly technical for my understanding. :( |
eee54c3
to
57974a8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found a new typo
57974a8
to
2695ead
Compare
Nice work, infinite loops are terrible |
I tried to create some debug items for testing (with
dev.items.spawn
) and sometimes I encountered an infinite loop inTryRandomUniqueItem
.After some debugging I found out that it is trying to generate one of the following unqiues
The problem can be reproduced with debug lua commands
dev.items.spawnUnique
command and one of the above uniques.The cause was that the
uid
offset was not always calculated correctly. There are two reasons why this can happenCheckUnique
andTryRandomUniqueItem
can be different because the check againstUIMinLvl
is different (CheckUnique
calculates it withGetItemBLevel
andTryRandomUniqueItem
has a custom implementation). So the calculated offset can be different or the desired unique can't be generated byCheckUnique
.UIMinLvl
is == and not >= as inCheckUnique
.All this can only happen for some specific uniques or item levels, so the problem is not so easy to get in normal gameplay.
This PR
SetupAllItems
doesCheckUnique
CheckUnique
remains the same