-
Notifications
You must be signed in to change notification settings - Fork 306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for anvil recipes #732
Conversation
…nvil enchanting or repair, yet.
|
||
public class AnvilRecipeCategory extends BlankRecipeCategory<AnvilRecipeWrapper> | ||
{ | ||
@Nonnull |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just use @MethodsNonnullByDefault
and @ParametersAreNonnullByDefault
in package info file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I copied from the wrong example. ;P
import javax.annotation.Nonnull; | ||
|
||
public class AnvilRecipeCategory extends BlankRecipeCategory<AnvilRecipeWrapper> | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code style...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I noticed that JEI uses the wrong brace location after I clicked to create the PR.
Looks good!
|
Looks basically the same as our anvil recipes. I think I could adapt them to use this instead in about 5 minutes. 👍 |
JER just tests if an enchantment can be applied to an ItemStack (see entry point), I don't know if it is the most efficient way tho. (actual checking). I guess I could look into it again and see if I can find some thing. |
"codacy"? Ok, I'll remember that as "junk to avoid"... |
I'm thinking of adding a 5th parameter to the anvil recipes, so that the recipe can show like, "required: 2+", for cases where the levels cost is variable. Opinions? |
@gigaherz I think that is not defined in a recipe; it is determined by inputs and are calculatable. |
Yes, I think subclassing is the better way here. Maybe split drawInfo(), e.g. in line 40, to make subclassing easier. |
…aked the formatting settings so that my code is even closer to the existing.
The repair recipes are now implemented. So far as I can tell, I added all the repairable items and their materials, but if there's something I missed, I'd like to know. ;P As for enchanting, iterating through all items and testing each one against all enchants seems a bit overkill. It's not hard to implement, but I imagine it would take a rather long time on a big modpack? Are there any numbers from JER regarding that, @way2muchnoise? |
I did a quick test, for vanilla recipes (786 ingredients, 30 enchantments with varying number of levels):
So it's not too bad. Event with 10x the items, and 2x the enchantments, it would still be less than half a second. |
Right now, the enchantment recipes show one by one, including separate entries for each book level. Is there some way to show all book levels as different (rotating) alternatives of the same recipe? |
@HenryLoenwind I tested out codacy to see if it would be usable for style-checking Forge, but I haven't had much time to configure it properly so it's really strict. It may still be useful. @gigaherz looks good, that doesn't take as long as I thought. |
…s rotation. Make repair show an almost-broken item on the left, so that the output represents the repair amount.
Be careful with the enchantments, Ender IO has one that can be applied to any item (soulbound). (semi OT) @mezz, I wasn't commenting on it's strictness, but on its dumbness. Rules that check the signature of a |
@HenryLoenwind This has changed in 1.11, it seems. ALL means "all of the above" now, instead of literally "all the items". |
Edit: I looked at the call stack, it is still routed through the enchantment. So still full control for the enchantment by returning true from canApply(). Thx, for the heads-up. |
I added a custom enchantment, set to apply to all items.
in contrast, without that one enchant, I get
So it it takes about as long to register one "all items" enchantment, as it takes to register all the other ones. On the upside, it's in the milliseconds, so even with 10x the items, and 2x the enchants, that's still within a second. :) |
Try one that returns true from canApply() instead. |
@HenryLoenwind Oh I was talking about EnumEnchantmentType.ALL and how it doesn't mean "ALL" anymore. |
Yeah, I know. I skipped a step and looked up what to do to make an enchantment that is applicable to all items again. There are 2 ways: (a)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. There are a few things I want changed before I test and pull it, but it's pretty much ready.
void addAnvilRecipe(ItemStack leftInput, ItemStack rightInput, ItemStack output, int levelsCost); | ||
void addAnvilRecipe(ItemStack leftInput, ItemStack rightInput, ItemStack output); | ||
void addAnvilRecipe(ItemStack leftInput, List<ItemStack> rightInput, List<ItemStack> output, int levelsCost); | ||
void addAnvilRecipe(ItemStack leftInput, List<ItemStack> rightInput, List<ItemStack> output); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be one method only, not four. Just keep
void addAnvilRecipe(ItemStack leftInput, List<ItemStack> rightInput, List<ItemStack> output, int levelsCost);
I don't think hiding the level cost is valid, if there is no cost they can put 0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that makes the use of the API unnecessarily ugly, but your choice.
However, for context, the option to not have a cost shown wasn't about the recipe not having a cost, it was about the recipe's cost not being known beforehand, such as for enchanted item repair, where the cost depends on how many times the item has been repaired, and how many enchants it has.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to automatically determine the cost, maybe using a fake ContainerRepair
?
Pair.of(new ItemStack(Items.WOODEN_SWORD), repairWood), | ||
Pair.of(new ItemStack(Items.WOODEN_PICKAXE), repairWood), | ||
Pair.of(new ItemStack(Items.WOODEN_AXE), repairWood), | ||
Pair.of(new ItemStack(Items.WOODEN_SHOVEL), repairWood), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would be cleaner as a Map
:
Map<ItemStack, List<ItemStack>> items = new HashMap<>();
items.put(repairWood, Arrays.asList(
new ItemStack(Items.WOODEN_SWORD),
new ItemStack(Items.WOODEN_PICKAXE),
...
));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree, but it's your code so I'll fix it to your preference.
@@ -133,17 +141,21 @@ public void register(IModRegistry registry) { | |||
recipeTransferRegistry.addRecipeTransferHandler(ContainerFurnace.class, VanillaRecipeCategoryUid.SMELTING, 0, 1, 3, 36); | |||
recipeTransferRegistry.addRecipeTransferHandler(ContainerFurnace.class, VanillaRecipeCategoryUid.FUEL, 1, 1, 3, 36); | |||
recipeTransferRegistry.addRecipeTransferHandler(ContainerBrewingStand.class, VanillaRecipeCategoryUid.BREWING, 0, 4, 5, 36); | |||
recipeTransferRegistry.addRecipeTransferHandler(ContainerRepair.class, VanillaRecipeCategoryUid.ANVIL, 0, 2, 3, 4 * 9); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4 * 9
should be 36
like the other lines above it
this(leftInput, Collections.singletonList(rightInput), Collections.singletonList(output), levelsCost); | ||
} | ||
|
||
public AnvilRecipeWrapper(ItemStack leftInput, List<ItemStack> rightInputs, List<ItemStack> outputs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the API, this class should only need one constructor.
this(leftInput, rightInputs, outputs, -1); | ||
} | ||
|
||
@SuppressWarnings("unchecked") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SuppressWarnings("unchecked")
should not be needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it isn't, I don't know how. I tried both Lists.newArrayList
and Arrays.asList
. So far as I can tell, Java is stupid and doesn't know how to handle generics in arrays, so it panics when it sees the varargs parameter type as List<ItemStack>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's possible to use Arrays.asList
with genetics this way, you're right.
Try creating a new arraylist and then adding the inputs to it after creation.
* Reduced number of overloads * Changed the list of pairs to a map of lists * Computed the result of a multiplication. * Unsilenced an unchecked operation.
I think this makes all the comments addressed. |
Is it possible to automatically determine the level cost, maybe using a fake |
Yes, but that would be the cost for a fresh item, at best misleading ...
…Sent from my iPhone
On 15 Feb 2017, at 10:26, James Mitchell ***@***.***> wrote:
Warning: This message has had one or more attachments removed
Warning: (msg-20509-39.html).
Warning: Please read the "j-e-b-Attachment-Warning.txt" attachment(s) for more information.
mezz commented on this pull request.
> @@ -92,6 +92,19 @@
void addDescription(List<ItemStack> itemStacks, String... descriptionKeys);
/**
+ * Adds an anvil recipe for the given inputs and output.
+ * @param leftInput The itemStack placed on the left slot.
+ * @param rightInput The itemStack placed on the right slot.
+ * @param output The resulting itemStack.
+ * @param levelsCost The cost, in experience levels, that will be required in order to pick up the item.
+ * Optional: If not specified, the cost text will not display on the recipe.
+ */
+ void addAnvilRecipe(ItemStack leftInput, ItemStack rightInput, ItemStack output, int levelsCost);
+ void addAnvilRecipe(ItemStack leftInput, ItemStack rightInput, ItemStack output);
+ void addAnvilRecipe(ItemStack leftInput, List<ItemStack> rightInput, List<ItemStack> output, int levelsCost);
+ void addAnvilRecipe(ItemStack leftInput, List<ItemStack> rightInput, List<ItemStack> output);
Is it possible to automatically determine the cost, maybe using a fake `ContainerRepair`?
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#732
This is a message from the MailScanner E-Mail Virus Protection Service
----------------------------------------------------------------------
The original e-mail message contained potentially dangerous content,
which has been removed for your safety.
The content is dangerous as it is often used to spread viruses or to gain
personal or confidential information from you, such as passwords or credit
card numbers.
Due to limitations placed on us by the Regulation of Investigatory Powers
Act 2000, we were unable to keep a copy of the original attachment.
The content filters found this:
MailScanner: Found a script in HTML message
--
Postmaster
MailScanner thanks transtec Computers for their support
|
It's better than no information, and means that nobody has to specify the level with the API. |
So here it is.
I decided not to attempt generating recipe wrapper instances for the vanilla book enchanting and repair, due to how those are hardcoded:
Item#getIsRepairable(ItemStack,ItemStack)
, with the contents of the anvil slots, and returns true if the material matches the tool. There is no way to figure out the right combinations besides a a nested loop and matching all items against all items.I'm open to suggestions.