Skip to content
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

Randomize Unique Item Generation (Reverse compatible) #7060

Open
wants to merge 44 commits into
base: master
Choose a base branch
from

Conversation

kphoenix137
Copy link
Collaborator

@kphoenix137 kphoenix137 commented Apr 10, 2024

Aims to full randomize unique item generation and allow all uniques to spawn, while maintaining as much reverse compatibility as possible.

Item Creation:
Step 1. Do item generation as normal, but disregarding already obtained uniques in SP.
Step 2. If item is unique and not a quest unique, start step 3.
Step 3. Get a random uid based on the valid uids that were used to create the unique so far, but not using already dropped uniques if SP. Also get an offset used to distinguish uniques that have the same base and min lvl.
Step 4. Force generate items with the same parameters that were used to create the original unique above, but instead, we are setting the item level to the min lvl of the desired uid, and also using the offset to get the uniques that would normally be unobtainable in most circumstances. If we iterate 10000 times with no valid result, give up and take whatever item the game gives us. (Note: Through my playtesting, there hasn't been any cases where the count went up to 10000. Usually, the highest it's gone is around 20-30). There is a special case that will turn a uper15 flag into a uper1 flag in situations where uper15 is unable to generate very low qlvl unique items.
Step 5. Set the flag if SP that tells us the game had dropped this unique already, so it doesn't drop it again. Set the CF_UIDOFFSET to the offset needed to generate the correct item when multiple base and min lvl are involved.

Item Regeneration:
The item is regenerated using CF_UIDOFFSET, which is used for getting the "impossible" uniques to work without morphing. Preexisting items will have these bits read as 0, which means no offset, so they will regenerate as they always have.

@kphoenix137 kphoenix137 marked this pull request as ready for review April 10, 2024 04:20
@kphoenix137 kphoenix137 marked this pull request as draft April 10, 2024 13:58
@kphoenix137 kphoenix137 changed the title Randomize Unique Item Generation 2 Randomize Unique Item Generation (Reverse compatible) Apr 10, 2024
@kphoenix137 kphoenix137 marked this pull request as ready for review April 11, 2024 04:09
@AJenbo
Copy link
Member

AJenbo commented May 5, 2024

This breaks the time demo is that really expected?

Also there is a conflict, please resolve.

@AJenbo AJenbo added this to the 1.6.0 milestone May 5, 2024
@StephenCWills
Copy link
Member

I believe it's based on a commit where timedemo was broken. Likely, it only needs to be rebased and the conflict resolved.

@kphoenix137
Copy link
Collaborator Author

This breaks the time demo is that really expected?

Also there is a conflict, please resolve.

done

Source/items.cpp Outdated Show resolved Hide resolved
Source/items.cpp Outdated Show resolved Hide resolved
Source/items.cpp Outdated Show resolved Hide resolved
Source/items.cpp Outdated Show resolved Hide resolved
Source/items.cpp Outdated Show resolved Hide resolved
@StephenCWills
Copy link
Member

StephenCWills commented May 12, 2024

KP, I found you an item that morphs with this PR. The following save has a Composite Staff of Phasing that morphs into Thundercall. single_0.sv.zip

This item represents a case where we can't really avoid morphing for some seeds, but I think the proper thing to do would be to interpret the absence of the CF_UNIQUE flag as an indication that the item should not be recreated as a unique item.

EDIT: FYI, I was kind of hoping that if we change the behavior for this CF_UNIQUE flag, we could avoid the loop for generating a new item when there are no valid uids. All we'd have to do is clear the CF_UNIQUE flag and recreate the item. However, if we do that, there's a chance that the item would morph when moving it to vanilla so that's probably not a good idea. I still think we should change the behavior based on CF_UNIQUE, but I'm mentioning this in case you end up having the same idea.

Point itemPos = item.position;

// Force generate items until we find a uid match.
DiabloGenerator itemGenerator(GetLCGEngineState());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this gets merged after #7030, we can use xoshiro to generate item seeds instead. Doing so would help avoid RNG overlap, since the LCG engine state at this point is going to depend on the seed the item originally had.

Also, it occurs to me that it might make more sense to use the item seed directly here instead of GetLCGEngineState().

StephenCWills
StephenCWills previously approved these changes May 12, 2024
@StephenCWills StephenCWills dismissed their stale review May 12, 2024 20:25

Consider merging #7030 first

@@ -165,7 +165,8 @@ enum icreateinfo_flag {

enum icreateinfo_flag2 {
// clang-format off
CF_HELLFIRE = 1,
CF_HELLFIRE = 1 << 0,
CF_UIDOFFSET = (1 << 5) - 1 - CF_HELLFIRE,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this would make a bit more sense (4 bits shifted 1).

Suggested change
CF_UIDOFFSET = (1 << 5) - 1 - CF_HELLFIRE,
CF_UIDOFFSET = ((1 << 4) - 1) << 1,

Here's another option that doesn't match our current pattern, but I thought it was interesting.

Suggested change
CF_UIDOFFSET = (1 << 5) - 1 - CF_HELLFIRE,
CF_UIDOFFSET = ~(~0 << 4) << 1,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Issue Report]: Unique rings and amulets drop are always the same.
3 participants