Solved Sign Commands

Discussion in 'Plugin Development' started by billman555555, Sep 25, 2013.

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

    billman555555

    I am trying to make a sign that when you click it it will send the player a message.
    Inside my PlayerInteractEvent i have:
    Code:java
    1. if (event.getClickedBlock().getState() instanceof Sign) {
    2. Sign sign = (Sign) event.getClickedBlock();
    3. if (sign.getLine(0) == "[Join]") {
    4. player.sendMessage("Signs are not yet working!");
    5. return;
    6. }
    7. }

    But it gives me a NPE when ever i click anything!
     
  2. Offline

    ZeusAllMighty11

    If you didn't check if the clicked block was null, then assuming it is a block and grabbing it's state will throw an NPE.

    Code:
    if(event.getBlock() == null) return;
    
    Make this above your current code.
     
  3. Offline

    desht

    1. Don't use getState() to check the type of a block. http://forums.bukkit.org/threads/common-mistakes.100544/page-4#post-1709082. Use getType() and check for Material.SIGN_POST or Material.WALL_SIGN.
    2. Don't assume event.getClickedBlock() doesn't return null. An interaction with air with have null return, so either check the clicked block isn't null, or only act if event.getAction() is LEFT_CLICK_BLOCK/RIGHT_CLICK_BLOCK.
    3. You can't cast event.getClickedBlock() to Sign. Cast event.getClickedBlock().getState() to Sign, after having checked the block type.
    4. You can't compare Java strings with '=='. Use .equals().
    5. Not made clear from your post, but ensure you're importing org.bukkit.block.Sign, and not org.bukkit.material.Sign.
     
  4. Offline

    billman555555

  5. Offline

    desht

    Post your code.
     
  6. Offline

    billman555555

    desht
    Code:java
    1. @EventHandler
    2. public void onClick(PlayerInteractEvent event) {
    3. Player player = event.getPlayer();
    4. if (player.getItemInHand().getType() == Material.DIAMOND) {
    5. player.openInventory(Kit);
    6. }
    7. if (event.getClickedBlock().getType() == Material.WALL_SIGN) {
    8. Sign sign = (Sign) event.getClickedBlock().getState();
    9. if (sign.getLine(0).equals("[Join]")) {
    10. player.sendMessage("Can not connect to the match!(Yea right)");
    11. }
    12. }
    13. }
     
  7. Offline

    remremrem

    as desht described, try changing line 7 to this:
    Code:java
    1. if (event.getAction()==Action.RIGHT_CLICK_BLOCK &&
    2. event.getClickedBlock().getType() == Material.WALL_SIGN)
     
  8. Offline

    billman555555

    remremrem
    I added that,
    the message now displays but whenever i click somthing it throws a NPE.
     
  9. Offline

    hanahouhanah

    NPE's are annoying.
    You'll need to null check the player and iteminhand and you should be good.
    Something like this:
    Code:java
    1. @EventHandler
    2. public void onClick(PlayerInteractEvent event) {
    3. Player player = event.getPlayer();
    4. if(player != null){
    5. if(player.getItemInHand() != null){
    6. if (player.getItemInHand().getType() == Material.DIAMOND) {
    7. player.openInventory(Kit);
    8. }
    9. if (event.getClickedBlock().getType() == Material.WALL_SIGN) {
    10. Sign sign = (Sign) event.getClickedBlock().getState();
    11. if (sign.getLine(0).equals("[Join]")) {
    12. player.sendMessage("Can not connect to the match!(Yea right)");
    13. }
    14. }
    15. }
    16. }
    17. }


    Didn't test it, but you get the idea. Also, add debug messages through each line you suspect. If you read the stacktrace, you'll also be able to tell exactly which line is giving you the NPE.
    To add a debug message, it's something like:
    Code:
    //something to test
    System.out.println("this works 1");
    //next thing
    System.out.println("this works 2");
    Before your stacktrace, you'll see the last working thing.
     
  10. Offline

    billman555555

    hanahouhanah
    Thanks for the advice BUT the NPE is not with the top bit of code. (Works fine)
    The bit that tests for the Sign being clicked gives the NPE.
     
  11. Offline

    hanahouhanah

    Code:java
    1. if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
    2. Block b = e.getClickedBlock();
    3. if ((b.getType() == Material.SIGN_POST) || (b.getType() == Material.WALL_SIGN)) {
    4. Sign s = (Sign)b.getState();
    5. if (s.getLine(0).equals("[Join]")){

    Try that. This is what I used in one of my older plugins.
    Can you read your stacktrace and show us the exact line you're getting the NPE on?
     
  12. Offline

    billman555555

    hanahouhanah
    Here is my current code:
    Code:java
    1. @EventHandler
    2. public void onClick(PlayerInteractEvent event) {
    3. Player player = event.getPlayer();
    4. if (player.getItemInHand().getType() == Material.DIAMOND) {
    5. player.openInventory(Kit);
    6. }
    7. if (event.getClickedBlock().getType() == Material.WALL_SIGN && event.getAction() == Action.RIGHT_CLICK_BLOCK) {
    8. Sign sign = (Sign) event.getClickedBlock().getState();
    9. if (sign.getLine(0).equals("[Join]")) {
    10. player.sendMessage("Can not connect to the match!(Yea right)");
    11. }
    12. }
    13. }

    It returns a NPE when i Action.LEFT_CLICK_BLOCK on somthing that is not a sign.
     
  13. Offline

    GummyBearKing

    Please paste the entire error
     
  14. Offline

    desht

    Of course it does - you're checking event.getClickedBlock().getType() before you check that the action is actually a block click and not an air click.
     
  15. Offline

    Retherz_

    Sign s = (Sign) e.getClickedBlock().getState();
     
  16. Offline

    billman555555

    MercilessPvP No need.
    desht So i have to check:
    Code:java
    1. if (event.getAction == Action.RIGHT_CLICK_BLOCK) {
    2. //other code
    3. }


    EDIT: I did it, thanks Guys!
     
Thread Status:
Not open for further replies.

Share This Page