Replace crops 1.15.2

Discussion in 'Plugin Development' started by AlpacaKyle, Mar 12, 2020.

Thread Status:
Not open for further replies.
  1. Offline

    AlpacaKyle

    hello! I am trying to make a plugin for my server to replace crops whenever they are broken. preferably as baby form so that they can grow back eventually. I have found multiple solutions, but all of them have been for older versions of Minecraft.
     
  2. Online

    timtower Administrator Administrator Moderator

    @AlpacaKyle And did you try the older solutions or did you just ignore them?
     
  3. Offline

    Kars

    @AlpacaKyle so what do you want from us? Please elaborate on what you have tried and what specifically does not work.
     
  4. Offline

    wand555

    Listen to BlockBreakEvent -> check if Material matches -> is instance of Ageable (or CraftCrops, CraftPotatoes, etc...) -> cast it -> setAge(0) -> setBlockData
    Or just place the "baby form" of the crop in that location.
     
  5. Offline

    AlpacaKyle

    I did try the older versions, but they either do not work, or are depreciated to the point of not working.

    I have gotten somewhere... I use this code:
    Code:
    package main;
    
    import org.bukkit.Material;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class MainClassFarm extends JavaPlugin implements Listener {
        @Override
        public void onEnable() {
            PluginManager manager = this.getServer().getPluginManager();
        }
        @Override
        public void onDisable() {
        }
        @EventHandler
        public void onBlockBreak(BlockBreakEvent event){
            float x,y,z;
            org.bukkit.block.Block b = event.getBlock();
            org.bukkit.block.Block b1 = event.getBlock();
            x = b.getX();
            y = b.getY();
            z = b.getZ();
            if (b1.getType() == Material.WHEAT){
               b1.setType(Material.WHEAT, true);
            }
          
        }
    
    }
    And the plugin loads with no errors, but it doesn't actually replace the wheat. no errors in console or anything.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Mar 13, 2020
  6. Offline

    Kars

    @AlpacaKyle i'm not sure if extending JavaPlugin and implementing Listener in the same class will work.
     
  7. Offline

    AlpacaKyle

    That didn't fix it, I removed Listener and it did nothing.
     
  8. Offline

    Machine Maker

    You definitely can do this. You can have events handlers inside your main class


    @AlpacaKyle I think you do still have to register the event using the plugin manager. I don't see that in your code.
     
  9. Offline

    AlpacaKyle

    This is my new code but it STILL doesn't work.
    Code:
    package main;
    
    import org.bukkit.Material;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class MainClassFarm extends JavaPlugin implements Listener {
        @Override
        public void onEnable() {
            this.getServer().getPluginManager().registerEvents(this, this);
        }
        @Override
        public void onDisable() {
        }
        @EventHandler
        public void onBlockBreak(BlockBreakEvent event){
            float x,y,z;
            org.bukkit.block.Block b = event.getBlock();
            org.bukkit.block.Block b1 = event.getBlock();
            x = b.getX();
            y = b.getY();
            z = b.getZ();
            if (b1.getType() == Material.WHEAT){
               b1.setType(Material.WHEAT, true);
            }
        }
    }
     
  10. Offline

    wand555

    @AlpacaKyle don't set the block to wheat, set it to "Material.WHEAT_SEEDS" instead.
     
  11. Offline

    Machine Maker

  12. Offline

    wand555

    Yeah youre right, got confused. mb
     
  13. Offline

    Kars

    Obviously, because then you don't implement listener where your EventHandler is...
     
  14. Offline

    Machine Maker

    Start doing some debugging. Is the event firing when a block breaks? To find out just have it print something to the console every time the event is fired. If that works, then check to see if your conditional expression in the IF statement is returning true when it should be by printing it out to the console. Debug in small steps
     
  15. Offline

    Kars

    This is your problem.
    Make a seperate class that implements Listener, put your EventHandler in it and registerEvents with an instance of the new class.
     
  16. Offline

    Machine Maker

    @Kars you can't have event listeners in your main class? I don't think that is true. I'm pretty sure you can have that.
     
  17. Offline

    vildaberper

    So you basically have two options. Simply cancelling the event, grabbing block.getDrops() and drop it manually, get the block data, cast it to ageable, set age to 0 and update.
    What I recommend however is a bit simpler: Schedule a task to run 0 ticks later (after the event) and set the type to WHEAT.

    Both solutions will technically guarantee one extra seed drop, which can be "nerfed" but I'll let you figure that out yourself.
     
  18. Offline

    AlpacaKyle

    Can you please elaborate? im fairly new to Java.
     
  19. Offline

    vildaberper

    This is not your problem. There is no need to create a separate Listener class.
    The reason your plugin is not working right now is that you set the block type before the event is internally handled, which overrides the state. Try this:
    Code:
    new BukkitRunnable(){
        @Override
        public void run(){
            b1.setType(Material.WHEAT, true);
        }
    }.runTaskLater(this,  0L);
    
     
    Kars likes this.
  20. Offline

    AlpacaKyle

    K, i'm getting somewhere. At least its giving me an error now.
    Here it is:
    Code:
    [21:56:23] [Server thread/ERROR]: Fatal error trying to convert Farm v1:main/MainClassFarm$1.class
    org.bukkit.plugin.AuthorNagException: No legacy enum constant for LEGACY_WHEAT. Did you forget to define api-version: 1.13 in your plugin.yml?
            at org.bukkit.craftbukkit.v1_15_R1.util.Commodore$1$1.visitFieldInsn(Commodore.java:176) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.craftbukkit.libs.org.objectweb.asm.ClassReader.readCode(ClassReader.java:2419) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.craftbukkit.libs.org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1492) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.craftbukkit.libs.org.objectweb.asm.ClassReader.accept(ClassReader.java:717) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.craftbukkit.libs.org.objectweb.asm.ClassReader.accept(ClassReader.java:401) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.craftbukkit.v1_15_R1.util.Commodore.convert(Commodore.java:130) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.craftbukkit.v1_15_R1.util.CraftMagicNumbers.processClass(CraftMagicNumbers.java:283) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:119) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.plugin.java.JavaPluginLoader.getClassByName(JavaPluginLoader.java:200) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:103) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:92) ~[server.jar:git-Bukkit-8160e29]
            at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_241]
            at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_241]
            at main.MainClassFarm.onBlockBreak(MainClassFarm.java:26) ~[?:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_241]
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_241]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_241]
            at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_241]
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:310) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:528) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:513) ~[server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.PlayerInteractManager.breakBlock(PlayerInteractManager.java:306) ~[server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.PlayerInteractManager.a(PlayerInteractManager.java:265) ~[server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.PlayerInteractManager.a(PlayerInteractManager.java:152) ~[server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.PlayerConnection.a(PlayerConnection.java:1182) ~[server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.PacketPlayInBlockDig.a(SourceFile:40) ~[server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.PacketPlayInBlockDig.a(SourceFile:10) ~[server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:19) ~[server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.TickTask.run(SourceFile:18) [server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.executeTask(SourceFile:144) [server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.IAsyncTaskHandlerReentrant.executeTask(SourceFile:23) [server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.executeNext(SourceFile:118) [server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.MinecraftServer.ba(MinecraftServer.java:876) [server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.MinecraftServer.executeNext(MinecraftServer.java:869) [server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.awaitTasks(SourceFile:127) [server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.MinecraftServer.sleepForTick(MinecraftServer.java:853) [server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.MinecraftServer.run(MinecraftServer.java:793) [server.jar:git-Bukkit-8160e29]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_241]
    [21:56:23] [Server thread/WARN]: [Farm] Task #37 for Farm v1 generated an exception
    java.lang.IllegalArgumentException: Cannot get data for not block LEGACY_WHEAT
            at com.google.common.base.Preconditions.checkArgument(Preconditions.java:191) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.craftbukkit.v1_15_R1.block.data.CraftBlockData.newData(CraftBlockData.java:520) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.craftbukkit.v1_15_R1.CraftServer.createBlockData(CraftServer.java:1821) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.craftbukkit.v1_15_R1.CraftServer.createBlockData(CraftServer.java:1796) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.Bukkit.createBlockData(Bukkit.java:1345) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.Material.createBlockData(Material.java:3363) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock.setType(CraftBlock.java:164) ~[server.jar:git-Bukkit-8160e29]
            at main.MainClassFarm$1.run(MainClassFarm.java:29) ~[?:?]
            at org.bukkit.craftbukkit.v1_15_R1.scheduler.CraftTask.run(CraftTask.java:77) ~[server.jar:git-Bukkit-8160e29]
            at org.bukkit.craftbukkit.v1_15_R1.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:393) [server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.MinecraftServer.b(MinecraftServer.java:985) [server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.DedicatedServer.b(DedicatedServer.java:386) [server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.MinecraftServer.a(MinecraftServer.java:940) [server.jar:git-Bukkit-8160e29]
            at net.minecraft.server.v1_15_R1.MinecraftServer.run(MinecraftServer.java:789) [server.jar:git-Bukkit-8160e29]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_241]
     
  21. Online

    timtower Administrator Administrator Moderator

    @AlpacaKyle Did you define an API-version in the plugin.yml?
     
  22. Offline

    AlpacaKyle

    No, I haven't figured out how.

    Ok, I figured it out using a document page. I have followed the errors myself and I have gotten it to work.
     
    Last edited: Mar 15, 2020
  23. Online

    timtower Administrator Administrator Moderator

    You don't.
     
  24. Offline

    AlpacaKyle

    One question though, how do I disable item drops for the wheat when its broken? I would not like the seeds to drop, so I am planning on disabling its drops then giving the player 1 wheat, so, how can I disable the wheat drops? I have a little bit of code, from a different thread, but it doesn't give errors, but it doesn't work. Here it is:
    Code:
     public void run(){
                    b1.setType(Material.WHEAT, true);
                    p.getInventory().addItem(new ItemStack(Material.WHEAT));
                    event.setDropItems(false);
                }
     
  25. Offline

    vildaberper

    Well, it's basically your first problem in reverse. You are clearing the drops after the event is handled internally. This should not happen in your scheduler.
     
  26. Offline

    AlpacaKyle

    How do I fix it then?
     
  27. Offline

    vildaberper

    Move the call outside your Runnable.
     
  28. Offline

    AlpacaKyle

    Ok, I got that to work. Is there a way that I can make it so that the wheat has to be fully grown before you can get anything from it? Like create an age variable and check it before giving the player the wheat.
     
  29. Offline

    vildaberper

    Yes, cast the BlockData to Ageable and compare getAge() with getMaxAge().
    Try finding what you are looking for here next time.
     
  30. Offline

    AlpacaKyle

    Thanks. I got it to work. But I'm going to be in adventure mode for the use of this plugin that i'm making, so I need a hoe to be able to break it. The hoe needs to be unbreakable and can only break wheat. I have achieved this through in-game commands, but that would be inefficient. So, I need to give the player an iron_hoe that's unbreakable and can only break wheat.
     
Thread Status:
Not open for further replies.

Share This Page