So I've recently started working on a plugin regarding farming, but I have found it to be a pain to determine if a block is a type of crop or not. Is there a method built into the API that characterizes a block as a crop? EDIT: Since it is apparently really difficult to understand this concept. I'm going to try to make it a little more apparent. I am trying to figure out what Material a crop uses as a seed and what it produces. So, wheat would produce wheat and the seeds would be seeds. Carrots, produce carrots, seed carrots I'm trying to do this without writing a utility class to define them myself. Such as: https://gist.github.com/Crypnotic/787e1abd191a96c36d822a2a551eb239 Why don't I do this myself? I don't have the time to make sure it is on par with what the Spigot code base needs
ItemStack crop = new ItemStack(Material.CROPS); if(crop.getData() == 7) // do your stuff It could be that the number is different
So from that, how can you determine the product and seeds that crop drops without expressly defining them?
So say on BlockGrowEvent when a piece of wheat grows, all it provides is the new BlockState. How would I use a BlockState and get the seeds and wheat that it would produce without expressly checking for wheat
I'm not entirely sure. But what you could do is predefine this in your plugin in a HashMap. Other then that, I don't see a clean way. If anyone else has a better solution, please tell
Currently I have to do something like this, which breaks with the 1.12-1.13 update. Code (Text): @RequiredArgsConstructor public static enum CropSpec { BEETROOT(Material.BEETROOTS, Material.BEETROOT, Material.BEETROOT_SEEDS), CARROT(Material.CARROTS, Material.CARROT, Material.CARROT), NETHER_WARTS(Material.NETHER_WART_BLOCK, Material.NETHER_WART, Material.NETHER_WART), POTATO(Material.POTATOES, Material.POTATO, Material.POTATO), WHEAT(Material.WHEAT, Material.WHEAT, Material.WHEAT_SEEDS); @Getter private final Material block; @Getter private final Material product; @Getter private final Material seed; public static boolean isCrop(Material material) { for (CropSpec type : values()) { if (type.getBlock() == material) { return true; } } return false; } public static CropSpec getCropSpec(Material material) { for (CropSpec type : values()) { if (type.getBlock() == material) { return type; } } return null; } }
Update: I'm not sure if I'll be able to help you out. I need more and clear information in order to help you out. Most likely it's just me not understanding it, I hope you find a solution and I hope that I'll be the one able to help you out
If you're working with Materials, you either use the 1.13 API or you don't. There's no in-between. Build two separate versions, one for 1.12 and below, another for 1.13
My goal isn't to make build that supports both versions. My goal is to find a better way to determine if a Block is a crop and then get the drops from it
Take a look at XMaterial. https://www.spigotmc.org/threads/1-8-to-1-13-itemstack-material-version-support.329630/ It's honestly so good that I'm actually using it in AntiAura's upcoming 1.13 update (with the author's permission, of course). Basically, XMaterial allows you to check if a block is a certain material, no matter if it's a 1.13 or 1.12 material (it does a bunch of other stuff too but it looks like that's what you're looking for).
Block#getDrops then get one of the items and get the material and check if it is edible Material#isEdible shouldn't break in 1.13 Edit: I guess this wouldn't work with every crop, like wheat nvm
You can also take a look at the CompMaterial class inside CompatBridge, an open source library aimed to make plugins compatible with both 1.12 and 1.13.1: https://github.com/kangarko/CompatB...kangarko/compatbridge/model/CompMaterial.java
I'm trying to avoid anything predefined outside of Bukkit/Spigot. My best case scenario would be something like. Code (Text): BlockState state = event.getNewState(); Block block = state.getBlock(); if (state.isCrop()) { // Maybe even #isGrowable CropData crop = (CropData) state.getData(); if (crop.getState() == CropState.RIPE) { block.getWorld().dropItem(block.getLocation(), new ItemStack(crop.getProduct(), 1)); block.getWorld().dropItem(block.getLocation(), new ItemStack(crop.getSeed(), random.nextInt(3) + 1)); crop.setState(CropState.SEEDED); state.setData(crop); state.update(); } } If you'll notice, the code above never references any specific crop. Just a generic data type If anyone has the time and know-how to PR this for API, I would be very thankful. I just don't have the time
getBlock returns the block that grew from. To get the block that was produced, use getNewState().getBlock()
I know. That was not the point of the post. I typed that out in the reply box. Maybe stick to trying to help with the real issue at hand
You are asking us to make you an API when you don't need one. You know what the block is, right? Well you now check the block material and compare it to an arraylist that stores all materials of crops. If the arraylist contains the material it is a crop. Get the drops via getBlock#getDrops. Code (Text): List<Material> cropMaterials = new ArrayList<Material>(); public void addCrops() { cropMaterials.add(Material.WHEAT); cropMaterials.add(Material.MELON); cropMaterials.add(Material.PUMPKIN); cropMaterials.add(Material.SUGAR_CANE); cropMaterials.add(Material.POTATOES); cropMaterials.add(Material.CARROTS); cropMaterials.add(Material.BEETROOTS); cropMaterials.add(Material.NETHER_WART); }
Maybe read the post in its entirety. You'll then notice that I'm trying to interact with crops without expressly defining them. Which, if you look, is exactly what you just did. You're replying saying I don't need it and you don't understand my use case at all. Please refrain from responding when you don't know what you're replying to. Thanks.
Because I'm trying to get what a crop yields without expressly defining the Material myself in some helper class like I'm doing now. There is no API, that I am aware of, that allows you to figure out what a crop yields without knowing what specific crop it is and defining them yourself
I want to know what items a crop drops when you break it, without having to map them myself. EDIT: The problem is that I'm not using the BlockBreakEvent, so I can't just check getDrops() EDIT 2: So the Block class has getDrops(), but I need to modify the seed amount. There's still no way to modify the seeds without defining what the seeds are myself