Skip to content

Conversation

@Caladius
Copy link
Contributor

@Caladius Caladius commented Nov 6, 2025

This adds 3 modes to RI_JUNK items:

  • Default: The default cyclical behavior except you can now select which items appear in the cycle.
  • Weighted: Items appear by chance, chance is set by the Item Weights that can be customized per item.
  • Supply: This uses customizable thresholds to determine which item is the current Junk item.

TODO:

  • Testing
  • Weighted needs some review and maybe some improvements, I'm not happy with it but its functional.
  • Remove Rupees from Threshold and Weighted as they are the fallback.

Build Artifacts

@Eblo Eblo mentioned this pull request Nov 11, 2025
31 tasks
if (Rando::IsItemObtainable(randJunkItem)) {
lastJunkItem = randJunkItem;
}
if (failOver >= FAIL_OVER_MAX) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (failOver >= FAIL_OVER_MAX) {
// Reached max number of attempts, default to nothing
if (failOver >= FAIL_OVER_MAX) {


switch (CVarGetInteger("gRando.Junk.ItemType", (uint32_t)RO_JUNK_TYPE_DEFAULT)) {
case RO_JUNK_TYPE_DEFAULT:
if (gPlayState != NULL && ABS(gPlayState->gameplayFrames - lastChosenAt) > 20) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it even possible for gPlayState to be null in a function that relies on an Actor* argument?


totalWeight += weight;
}
if (totalWeight == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (totalWeight == 0) {
// No obtainable items have weight, default to nothing
if (totalWeight == 0) {

break;
case RI_MAGIC_JAR_SMALL:
if (Rando::IsItemObtainable(itemId)) {
if (gSaveContext.save.saveInfo.playerData.magic <= threshold) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Magic never seems to drop even if I have an empty magic bar and nothing else has reached its threshold. Looking through this code, I'm not certain why that is.

if (weight == 0) {
continue;
}
if (!Rando::IsItemObtainable(itemId)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

While this does exclude the item from the weight calculation, it is still possible to get items that should not be obtainable. For example, I can still get arrows from the weighted option even if I don't have a bow.

break;
}

weightedValue = rand() % totalWeight;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you implement lastChosenAt for weighted as well? Depending on what configuration you have, the resulting item can rapidly change every frame.

Threshold is more or less deterministic and does not share this problem.

}
break;
case RI_MAGIC_JAR_SMALL:
if (Rando::IsItemObtainable(itemId)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

You may be able to just wrap the entire switch block with Rando::IsItemObtainable(itemId). Hearts, nuts, and sticks should already just return true.

}
if (lastJunkItem == RI_UNKNOWN) {
if (lastRupee != gSaveContext.save.saveInfo.playerData.rupees) {
selectedRupee = rupeeList[rand() % rupeeList.size()];
Copy link
Contributor

@Eblo Eblo Nov 23, 2025

Choose a reason for hiding this comment

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

Maybe lastChosenAt should be implemented for threshold after all, at least for this particular case. If you have multiple Rupee junk items in view and acquire a larger Rupee, the remaining junk Rupees will rapidly flash through the different types as the Rupee counter increments.

Edit: Upon further thought, maybe just always do lastChosenAt at the start of CurrentJunkItem. No need to implement it three separate times.

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.

3 participants