Skip to content

Conversation

@kami-tsuki
Copy link

@kami-tsuki kami-tsuki commented Nov 15, 2025

  • Brew Time can optionally be shown on Action Bar (default disabled)

  • Brew Time can optionally be shown in Chat (default enabled)

  • Brew time can update on Look at the cauldron when using a clock in main or offhand (default disabled)

  • Implemented Removal of Latest added Items

  • Configurable Amount (0 to disable)

  • Configurable Limit Time (0 to disable)

  • When removed all Ingredients Cauldron Brewing is resetted

  • Message in Action bar when removing, item drops at Player pos and a small sound effect appears

Need to Test Recipe accuracy if the Recipe is truly without the Ingredient when removed
Need to proper Test with Permission and Claim Plugins!
tested on paper 1.21.10 without any other plugins

Copy link
Contributor

@Thorinwasher Thorinwasher left a comment

Choose a reason for hiding this comment

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

I will test this as well. Don't worry, I'm not a clean code guy. I mostly care if it's flexible / adaptable to unforeseen changes in required behavior and so on, it seem modular enough, the logic looks solid as well.

Might be an issue on plugin reloads / server restarts; This behavior will not be persistently stored, but I think that's fine, as it's an utility kind of thing.

Comment on lines +60 to +70
private static class IngredientAddition {
final Ingredient ingredient;
final long timestamp;
final ItemStack originalItem;

IngredientAddition(Ingredient ingredient, long timestamp, ItemStack originalItem) {
this.ingredient = ingredient;
this.timestamp = timestamp;
this.originalItem = originalItem.clone();
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Could make this a record :^)

Comment on lines +193 to +200
if (ingredientHistory.isEmpty()) {
return null;
}

// Check if brew has been extracted
if (brewExtracted) {
return null;
}
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 (ingredientHistory.isEmpty()) {
return null;
}
// Check if brew has been extracted
if (brewExtracted) {
return null;
}
if (ingredientHistory.isEmpty() || brewExtracted) {
return null;
}

Comment on lines +281 to +306
if (removed) {
// Recalculate recipe only if there are still ingredients
if (!isEmpty) {
this.recipe = brew.closestRecipe(TheBrewingProject.getInstance().getRecipeRegistry())
.orElse(null);
} else {
this.recipe = null;
}

// Play a sound effect
final boolean finalIsEmpty = isEmpty;
BukkitAdapter.toLocation(this.location)
.ifPresent(loc -> {
World world = loc.getWorld();
if (finalIsEmpty) {
// Play water splash sound when reverting to normal cauldron
world.playSound(loc, org.bukkit.Sound.ENTITY_PLAYER_SPLASH, 0.7f, 1.0f);
world.spawnParticle(Particle.SPLASH, loc.add(0.5, 0.7, 0.5), 20, 0.2, 0.1, 0.2, 0.5);
} else {
// Play item pickup sound for normal removal
world.playSound(loc, org.bukkit.Sound.ENTITY_ITEM_PICKUP, 0.5f, 1.2f);
}
});

return lastAddition.originalItem;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably make this a method instead, I don't see why not

boolean removed = false;
boolean isEmpty = false;

if (brew.lastStep() instanceof BrewingStep.Cook cook) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Try to unwrap these if possible. Use return statements, or maybe make a separate method for the cook and mix case. I think you already know this, but if you don't here's an example:

if(statment1) {
    if(statement2) {
        // Code 1
    } else {
        // Code 2
    }
} else {
    // Code 3
}

Becomes this:

if(!statement1) {
    // Code 3
    return;
}
if(!statement2) {
    // Code 2
    return;
}
// Code 1

Up to you, though. I have also written similar code in this project, for what I could guess at least. Makes life somewhat easier for me to review it though.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also the mix and cook part here are extremely similar to each other, it should be possible to remove some code duplication.

Copy link
Contributor

@Thorinwasher Thorinwasher left a comment

Choose a reason for hiding this comment

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

DUPE FOUND!!! 😛

Hehe, no worries, that's why we have testing. Also going to note that it looks like the ingredients are getting properly updated. You can find out by retrieving a brew and doing the command:

tbp info

Whilst holding the item

Ingredient ingredient = BukkitIngredientManager.INSTANCE.getIngredient(item);

// Track this ingredient addition for potential removal
ingredientHistory.add(new IngredientAddition(ingredient, time, item));
Copy link
Contributor

Choose a reason for hiding this comment

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

The item added here has to have 1 in amount, I got a dupe otherwise by adding items when holding an item stack with more than 1 items in it.

boolean removed = false;
boolean isEmpty = false;

if (brew.lastStep() instanceof BrewingStep.Cook cook) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Also the mix and cook part here are extremely similar to each other, it should be possible to remove some code duplication.

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.

2 participants