Skip to content

fix: Match vanilla behavior on item use and release - #609

Open
NandoBF wants to merge 4 commits into
Steel-Foundation:masterfrom
NandoBF:fix/vanilla-active-item-use
Open

fix: Match vanilla behavior on item use and release#609
NandoBF wants to merge 4 commits into
Steel-Foundation:masterfrom
NandoBF:fix/vanilla-active-item-use

Conversation

@NandoBF

@NandoBF NandoBF commented Sep 5, 2026

Copy link
Copy Markdown

Type of change

  • Block implementation
  • Item implementation
  • Command implementation
  • Entity implementation
  • Bug fix
  • New feature
  • Breaking change
  • Refactor / code cleanup
  • Performance improvement
  • Chore / tooling

Description

Fixes #529 by better mimicking vanilla behaviour on functions tick_active_item_use and release_using_item.

Previously the held item would be replaced with an empty stack and the on_use_tick would be run on the local item stack. Now, the held item remains unchanged and on_use_tick is run on a clone of the held item. After that it is checked if the item still matches the item that was being held, if it does overwrite to apply item changes, if it doesn't it returns early. This check is also done after finish_using_item.

Also changed release_using_item to use the same pattern so that it matches vanilla since it had the same bug.

How this was tested

Ran cargo fmt, cargo clippy, cargo check and typos. There aren't any tests that cover this bug and I also didn't make one since the necessary behaviour to replicate this is in PR #411, which isn't merged.

Screenshots / logs

Checklist

  • Code builds w/o errors or warnings
  • Self-reviewed the diff
  • Docs updated (if applicable)
  • No leftover debug code / comments

Classes / commands modified:

Additional notes

Although the bug was present in release_using_item I don't think any vanilla item would be able to trigger it, since the only item that changes to something different than an empty hand on release would be an elytra (which isn't used on hand). However, plugins/mods could trigger that bug.

@github-actions github-actions Bot added the Bug Something isn't working label Sep 5, 2026

@kdcokenny kdcokenny 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.

also we def do need a test for this. i dont think you need #411 for this as long as you test the tick_active_item_use fn directly in player/tests.rs

Comment thread steel-core/src/player/mod.rs
Comment thread steel-core/src/player/mod.rs Outdated

if self.active_item_use_hand() != Some(hand) {
self.inventory.lock().set_item_in_hand(hand, item);
return;

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.

what happens here if on_use_tick damages the item (like a brush) and stops item use? returning early here drops those changes without writing them back to the inventory.

Comment thread steel-core/src/player/mod.rs Outdated
let mut inventory = self.inventory.lock();
let current_hand = inventory.get_item_in_hand_mut(hand);
if current_hand.item() == active.item() {
*current_hand = item.clone();

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.

this writes item back as long as the item id matches, which overwrites any changes made to the held stack during on_use_tick.

and because it writes item back here, hand_item down on line 455 is always going to equal item. so if item == hand_item will basically always be true and never hit the release_using_item branch.

vanilla checks if the hand still matches the stack from before onUseTick. if it changed during the tick, it releases instead of finishing and doesnt overwrite the hand.

Comment thread steel-core/src/player/mod.rs Outdated
let result = behavior.finish_using(&mut item, &world, self);
let mut inventory = self.inventory.lock();
let current_hand = inventory.get_item_in_hand_mut(hand);
if current_hand.item() == active.item() {

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.

in vanilla completeUsingItem, it also checks !this.useItem.isEmpty() before calling finishUsingItem.

also why check current_hand.item() == active.item() after finish_using? finish_using is supposed to change the item type for things like soup or honey bottles turning into empty bowls/bottles.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Isn't it possible for finish_using itself to modify the item? Without the check it would open up the same bug on_use_tick had, overwriting what finish_using did with the returned result.
I believe in vanilla it happens with a stack with more than 1 item of honey bottles, for example. With 2 honey bottles it would return the empty glass and modify the inventory to decrease the amount of items.
At least, I believe this can happen but there is a high chance I am wrong.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

This pull request has conflicts with the base branch "master". Please resolve those so we can test out your changes.

@NandoBF
NandoBF force-pushed the fix/vanilla-active-item-use branch from 079f9f6 to 0051b9d Compare September 5, 2026 23:51
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Conflicts have been resolved! 🎉

@NandoBF

NandoBF commented Sep 5, 2026

Copy link
Copy Markdown
Author

I believe I've fixed everything according to the reviews. Some of the tests use stand-in items because the real behavior for food/drinks still hadn't been merged. Now that #411 is merged, I'll later send a follow up commit replacing them with tests using real items.

Comment thread steel-core/src/player/mod.rs Outdated
Comment on lines +465 to +466
// TODO: Vanilla checks !useOnRelease here.
// implemented in PR #469

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.

Didn't do only quick todo check, so no review
means this should be merged after 469?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

To keep it completely in line with vanilla behavior, yes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Also, do you mean that I shouldn't leave TODO comments?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Active item use can overwrite changes to the held stack

3 participants