Skip to content

(#364) Item objective#571

Merged
immortius merged 5 commits into
mainfrom
dividesByZero/item_objective
Feb 20, 2026
Merged

(#364) Item objective#571
immortius merged 5 commits into
mainfrom
dividesByZero/item_objective

Conversation

@immortius

Copy link
Copy Markdown
Contributor

Background

This PR adds an item collection based objective to the rift.

Testing Instructions

The objective can added to a rift key by including one or more buckets in the recipe. It requires throwing away items of specific types, which are deleted when thrown away.

Implementation

  • While unnecessary for the final objective, reworks the GoalBasedObjective to track completion separately for each player before summing to get the total progress. This allows for goals that track a state for each player.
  • Adds a CollectItem goal that tracks the quantity of an item that a player has on them.
  • Adds a TossItem goal that tracks the quantity of an item that a player has dropped (and removes the dropped items)
  • For both these new goals adds a provider that will generate one the goals from a loot table, by rolling it a number of times and then picking item types from the result.
  • Adds a Collections helper class, which includes a method to iterate recursively over a player's inventory and the contents of any containers they have
  • Fixes rendering of the Objective tracker when given a custom location
  • Refactors Goals so that their event subscriptions are within the Goal type classes, rather than in a separate class.

Notes

  • I would suggest future work to add support for rewarding partial objective completion, but this depends on another unmerged PR.

Closes #364

@ImplementsLegend ImplementsLegend left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems fine.

I'll note thet there's nothing preventing you from bringing the items into the rift (atleast for the toss goal).

Also I was looking a bit into the Instant loot and I think it wouldn't be a bad idea to make an objective based on that.

Comment on lines +56 to +63
List<ItemStack> output = new ArrayList<>();
for (int i = 0; i < lootRolls.getInt(context); i++) {
table.getRandomItems(context, output::add);
}
Object2IntMap<Item> itemCounts = new Object2IntArrayMap<>(output.size());
for (ItemStack stack : output) {
itemCounts.merge(stack.getItem(), stack.getCount(), Integer::sum);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does this need two separate loops?

Suggested change
List<ItemStack> output = new ArrayList<>();
for (int i = 0; i < lootRolls.getInt(context); i++) {
table.getRandomItems(context, output::add);
}
Object2IntMap<Item> itemCounts = new Object2IntArrayMap<>(output.size());
for (ItemStack stack : output) {
itemCounts.merge(stack.getItem(), stack.getCount(), Integer::sum);
}
Object2IntMap<Item> itemCounts = new Object2IntArrayMap<>();
for (int i = 0; i < lootRolls.getInt(context); i++) {
table.getRandomItems(context, stack->itemCounts.merge(stack.getItem(), stack.getCount(), Integer::sum);
}


@SubscribeEvent
public static void onContainerClose(PlayerContainerEvent.Close event) {
GoalManager.getGoalStates(event.getEntity(), CollectItemGoal.class).forEach(goalState -> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Iterating through the entire inventory per goal seems inefficient, although I'm not sure what would be better.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I could change the logic to get the ingredients from all the CollectItem goals, loop over the inventory once checking each item against each ingredient and collecting their counts, and then progressing each goal with a second loop afterwards. It effectively is just swapping inner and outer loops. Though the recursive inventory loop is presumably a bit chunkier in terms of iteration cost so might be some value there. Might be premature optimisation though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In terms of generally iterating the entire inventory... Yeah, it is mostly a catch all. I didn't find a good hook for container interaction. Although looking now potentially could add a slot listener to every menu.

/**
* Visit for traversing containers
*/
public interface ItemVisitor {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why not use Consumer<ItemAccessor>?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point.

@immortius

Copy link
Copy Markdown
Contributor Author

I'll note thet there's nothing preventing you from bringing the items into the rift (atleast for the toss goal).

Yeah. My understanding is the plan would be to have objective-specific loot in the future, in which case we'ld presumably remove it from the player when they leave the rift. Which would solve this and other issues with the toss goal (e.g. tossing your gear on accident when it happens to be the goal and it being wiped from existence).

feat: Collections helper class
refactor: combined goal event handlers with relevant event type
@immortius

Copy link
Copy Markdown
Contributor Author

Also I was looking a bit into the Instant loot and I think it wouldn't be a bad idea to make an objective based on that.

Honestly, insta-loot with custom items would probably make a better item collection objective than the toss goal.

Also we could drop Rewards and just use instant pickup items instead.

@immortius
immortius force-pushed the dividesByZero/item_objective branch from 671f5bc to 6a7706e Compare February 20, 2026 13:01
fix: add rewards to collect_items objective
@immortius
immortius merged commit 6726f1c into main Feb 20, 2026
2 checks passed
@immortius
immortius deleted the dividesByZero/item_objective branch February 20, 2026 22:34
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.

Collect Item Objective

2 participants