PlayerInteractEvent throws error

Discussion in 'Plugin Development' started by SuperTerminator, Sep 19, 2013.

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

    SuperTerminator

    Hey guys, I'm writing a plugin, and whenever I break certain items, like glass, it throws this error:

    2013-09-19 22:24:25 [SEVERE] Could not pass event PlayerInteractEvent to DeceptionInfection v1.0
    org.bukkit.event.EventException
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:427)
    at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62)
    at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:477)
    at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:462)
    at org.bukkit.craftbukkit.v1_6_R2.event.CraftEventFactory.callPlayerInteractEvent(CraftEventFactory.java:190)
    at org.bukkit.craftbukkit.v1_6_R2.event.CraftEventFactory.callPlayerInteractEvent(CraftEventFactory.java:160)
    at net.minecraft.server.v1_6_R2.PlayerConnection.a(PlayerConnection.java:993)
    at net.minecraft.server.v1_6_R2.Packet18ArmAnimation.handle(SourceFile:41)
    at net.minecraft.server.v1_6_R2.NetworkManager.b(NetworkManager.java:296)
    at net.minecraft.server.v1_6_R2.PlayerConnection.e(PlayerConnection.java:116)
    at net.minecraft.server.v1_6_R2.ServerConnection.b(SourceFile:37)
    at net.minecraft.server.v1_6_R2.DedicatedServerConnection.b(SourceFile:30)
    at net.minecraft.server.v1_6_R2.MinecraftServer.t(MinecraftServer.java:590)
    at net.minecraft.server.v1_6_R2.DedicatedServer.t(DedicatedServer.java:226)
    at net.minecraft.server.v1_6_R2.MinecraftServer.s(MinecraftServer.java:486)
    at net.minecraft.server.v1_6_R2.MinecraftServer.run(MinecraftServer.java:419)
    at net.minecraft.server.v1_6_R2.ThreadServerApplication.run(SourceFile:582)
    Caused by: java.lang.NullPointerException
    at minecraft.deception_infection.SuperDigger9000.DeceptionInfection.onPlayerInteract(DeceptionInfection.java:161)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:425)
    ... 16 more

    Here's my code:

    Code:java
    1. @EventHandler
    2. public void onPlayerInteract(PlayerInteractEvent event){
    3.  
    4. if(Action.PHYSICAL != null && event.getClickedBlock().getTypeId() == Material.STONE_PLATE.getId()){
    5. Player player = event.getPlayer();
    6. if(decepInfectHashMap.get(player) == false){
    7. shoutOut(ChatColor.GREEN, player, "is not infected.");
    8. }
    9. else if(decepInfectHashMap.get(player) == true){
    10. shoutOut(ChatColor.RED, player, "is infected! KILL IT QUICKLY!");
    11. }
    12. }
    13. }


    My events are registered properly, and otherwise the plugin works perfectly fine. I really don't know what to do. If anyone needs to look at the full source code, let me know! Thanks guys!
     
  2. Offline

    WauloK

    Which line is 161?
     
  3. Offline

    SuperTerminator

    Edit: Line 148 now. Code:
    Code:java
    1. if(Action.PHYSICAL != null && event.getClickedBlock().getTypeId() == Material.STONE_PLATE.getId()){


    Does it not like it when you punch blocks?
     
  4. Offline

    WauloK

    Maybe use this way of comparing clicked blocks:
    Code:java
    1. clickedBlock.getType()==Material.SIGN

    I'd separate the check for null and the clicked block event to two lines as well.

    Usually clicks are checked like this. I don't know what PHYSICAL is about:
    Code:java
    1. if (action == Action.LEFT_CLICK_BLOCK) {


    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 4, 2016
  5. Offline

    SuperTerminator

    Physical is when you stomp on a pressure plate.

    The pressure plate code works just fine, i'm just trying to eliminate this irritating error.

    Ah well, your change doesnt work. Luckily, it's not fatal to my plugin, so I'll just live with it. Thanks anyway!

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 4, 2016
  6. use: .getType().equals(Material.SIGN)
     
  7. Offline

    kiwhen

    Actually, Action.PHYSICAL is any kind of action that does not involve clicking on things. Pressure plates, destroying farmland and things like that.

    Not quite sure what the problem is, but right off the bat, I can tell you that this:
    Code:java
    1. if(Action.PHYSICAL != null && event.getClickedBlock().getTypeId() == Material.STONE_PLATE.getId()){

    ... probably doesn't do what you think it does.

    What you're doing here, is checking if the enum Action.PHYSICAL is not null and if the clicked block has the ID of a stone plate.

    Obviously, Action.PHYSICAL will never ever be null, it will always be Action.PHYSICAL. This statement is pretty much the same as saying "if this apple is not a banana, then...". Apples will never be bananas, they are apples.

    What you probably want to do is compare the action that has taken place in the PlayerInteractEvent. You can grab that by using event.getAction(). This will return one of five (?) enums, one of which is Action.PHYSICAL. The other four are click events for left and right mouse button, clicks that involves blocks and clicks that don't (four possible combinations).

    Now, to check if the player has done something "physical", type in "if(event.getAction != Action.PHYSICAL) {". This will compare the event's action to the enum Action.PHYSICAL, which would be like saying "if this fruit is an apple, then...". Makes a whole lot more sense.

    Finally, to the NullPointerException-error. In the same statement where you are comparing apples and bananas, you have the ID-check for the clicked block. Now, like I said, there are two events that do not involve blocks. Specifically, Action.LEFT_CLICK_AIR and Action.RIGHT_CLICK_AIR. The error probably occurs because you are trying to access the ID of the clicked block. If there isn't a clicked block, there won't be an ID to access. This will get Java confused. Therefore, always check if the event involves a block before trying to access it.

    PlayerInteractEvent does come with a handy method for checking this sort of thing, called event.hasBlock(). It returns a boolean based on a null check for the clicked block, which means that if getClickedBlock() returns null, hasBlock() will return false. Use it like this: "if(event.hasBlock) {". This must be used by itself, you can't type it out in one statement, like "if(event.hasBlock() && event.getClickedBlock().getType() == Material.GRASS) {". The second condition will run no matter what hasBlock() returns, which will produce the same error. Do it in two separate if-statements. :)
     
    mollekake likes this.
  8. how can Action.PHYSICAL ever be null?
    Because if you check for Action.PHYSICAL, it returns true or false, but never null.
     
    SuperTerminator likes this.
  9. Offline

    SuperTerminator

    Thanks guys!

    kiwhen
    Thank you so much! You fixed my problem!

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 4, 2016
  10. Offline

    codename_B

    kiwhen I like your metaphors :D
     
Thread Status:
Not open for further replies.

Share This Page