Add Builder class for MerchantRecipe - #14127
Conversation
| * @param result The ItemStack to use as the result for the MerchantRecipe. | ||
| * @param maxUses Number of max uses for this MerchantRecipe | ||
| */ | ||
| public Builder(ItemStack result, int maxUses) { |
There was a problem hiding this comment.
Is there a reason we are exposing these constructors in favor of static API methods? I actually think the normal builder method on MerchantRecipe that isn't static is also okay, but this feels like a loose end that could be tied up pretty easily.
There was a problem hiding this comment.
I can make the constructor private and expose a static builder method.
Would it be good to have a builder(ItemStack, int) and a builder(MerchantRecipe) or should we only allow builder(ItemStack, int) and have a builder from a MerchantRecipe through its builder method?
There was a problem hiding this comment.
I think the latter would be best
There was a problem hiding this comment.
I would rename the builder method to #toBuilder to match the data component builder and probably obsolete a bunch of constructors on MerchantRecipe (the builder being preferred).
There was a problem hiding this comment.
I would rename the builder method to #toBuilder to match the data component builder and probably obsolete a bunch of constructors on MerchantRecipe (the builder being preferred).
If by obsolete you mean mark them as deprecated, as I don't think a breaking change in the form of removing constructors should be considered here. Unless Paper team would be fine with such a change.
There was a problem hiding this comment.
If by obsolete you mean mark them as deprecated
Obselete is a jetbrains annotation namely ApiStatus.Obselete. I agree with Lulu here that's probably a smart addition.
There was a problem hiding this comment.
Which constructors would be best to obsolete?
The ones with fewest, or most arguments?
| * @return New MerchantRecipe class. | ||
| */ | ||
| public MerchantRecipe build() { | ||
| return new MerchantRecipe(result, uses, maxUses, experienceReward, |
There was a problem hiding this comment.
this is more of a genuine question rather than a review point. Are there "required" entries for a MerchantRecipe? Also would it do any good to enforce those here?
There was a problem hiding this comment.
Result and max uses are required given the Constructor with fewest parameters for MerchantRecipe has those set.
This Pull request adds a Builder class to the
MerchantRecipeclass.Motivation
The result item in the MerchantRecipe class is unmodifiable and the only way to change it, is by creating a new instance of the class.
This is okay for situations where you want to modify the values like experience gain, multiplier, etc. but for situations where you just want to change the result item of an existing MerchantRecipe, this situation becomes tedious, as you now need to apply every single value from the original MerchantRecipe, to the new one through the constructor.
This Builder class should help, as there is now a method in MerchantRecipe called
builder()that returns a new Builder class using the MerchantRecipe's settings and allowing you to modify them.Notes
I'm currently debugging an issue where the MerchantRecipe modification in a VillagerAcquireTradeEvent results in a villager not getting any trades to share.
The event is fired regularely, but interacting with the villager ends up in them shaking the head as if they have no trades.
I'm unsure of the cause here, but it may be an oversight on my end.
Here's the code used to test through the test-plugin: