Solved Trying to enable an event with Commands

Discussion in 'Spigot Plugin Development' started by NeverFlame42, Jun 25, 2021.

  1. I got a message for both, so it is changing between true and false.
     
  2. Alright, my final suggestion is to do what Strahan suggested. Beyond that I don't know.
     
  3. The only thing I can think of is that the boolean is changing back and front in the Command bit, but that changing isn't doing anything to the Event bit. Is it possible that the boolean is going back to what I set it to before its able to affect the Event?
     
  4. And also thank you for being so helpful
     
  5. I don't know of any reason why it would. Would you mind posting your class one more time, in case something changed that you forgot?
    Edit: Try printing the value of check at the beginning and at the end (first and last line) of your command method, just to make absolutely sure that it changes. Run the command a few times and report back with whether or not it is doing what you expect.
     
    • Agree Agree x 1
  6. Strahan

    Benefactor

    Ditto, post your current code so we can see where you are with it now. This is a pretty simple thing you want to do, it shouldn't be that hard to implement.

    EDIT: I tried making this just now. I grit my teeth and did it your way even though my brain screamed at me, lol, and it worked fine. What I did was:
    Code (Text):
    Main class {
      VampClass vampClass = new VampClass();

      onEnable {
        Register vampClass as a listener
        Set executor for /vamp as vampClass
      }
    }

    VampClass {
      private boolean check = false;

      onCommand {
        If sender isn't a player, yell at them and return;

        check = !check;
        if check {
          Tell them they are a vampire
        } else {
          Tell them they're human
        }
      }

      on PME {
        Is check false?  Return
        Did they not really move?  Return

        Set lightlevel var to the lightlevel of the getTo block
        Is lightlevel 15?  Set happy effects
        Is lightlevel < 8?  Set unhappy effects
      }
    }
     
    #46 Strahan, Jun 26, 2021
    Last edited: Jun 26, 2021
    • Like Like x 1
  7. Here's my code while I was testing it last night:
    Code (Java):
    package me.flame.darkness;

    import org.bukkit.ChatColor;
    import org.bukkit.block.Block;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerMoveEvent;
    import org.bukkit.potion.PotionEffect;
    import org.bukkit.potion.PotionEffectType;

    public class DarkEnable implements CommandExecutor, Listener {
        private Main main;
        public boolean check = false;

        public DarkEnable(){
            this.main = this.main;
        }


        @Override
        public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
            if(sender instanceof Player){
                Player player = (Player) sender;

                if(player.hasPermission("vampire")){

                    if (check){
                        player.sendMessage(ChatColor.GREEN + "You are now a reverse vampire!");
                    }else{
                        player.sendMessage(ChatColor.GREEN + "You are no longer a reverse vampire!");
                    }

                    if (!check){
                        check = true;
                        player.sendMessage("Set to true");            //code1
                    }else {
                        check = false;
                        player.sendMessage("Set to false");          //code2
                    }

                    return true;

                }else {
                    player.sendMessage(ChatColor.RED + "You don't have permission to use this command!");
                    return true;
                }

            }
            else {
                main.getLogger().info("You have to be a player to become a reverse vampire!");
                return true;
            }
        }


        @EventHandler
        public void onEnterDark(PlayerMoveEvent event) {
            Block block = event.getTo().getBlock();
            int lightLevel = block.getLightLevel();
            if(!check){event.getPlayer().sendMessage("False");}         //code3

            if (check) {
                if (lightLevel < 8) {
                    event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 60, 2));
                    event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 60, 1));
                    event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.WITHER, 60, 1));
                    event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, 60, 1));
                } else if (lightLevel == 15) {
                    event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SATURATION, 120, 4));
                    event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 120, 1));
                }
            }
        }

    }
    In game when I run the command, I get both code 1 and code 2 correctly. However, no matter how many times I run the command, code 3 always runs and the effects never happen.
     
  8. Yeah sorry for my weird code, in high school I learned the basics to java and didn't learn too many of the nice shortcuts
     
  9. Alright, do these things in this order:
    1. Check if the potion effects are applied when the vampire is enabled.
    2. Check if the potion effects are applied when the vampire is disabled.
    3. Replace your two if else statements in the command executor with the following if else statement (this is what Strahan suggested that I've referenced a few times). Especially for something as simple as this, putting it in one if else statement makes debugging and understanding the state of your program at a certain point in the code a lot easier.
    Code (Text):
    if (check){
        check = false;
        player.sendMessage(ChatColor.GREEN + "You are no longer a reverse vampire!");
    }else{
        check = true;
        player.sendMessage(ChatColor.GREEN + "You are now a reverse vampire!");
    }
    Assuming my hunch is correct, I think what is happening is best explained by the following:
    1. check starts as false
    2. You run /vampire
    3. you get a message that you are no longer a reverse vampire, because check is false
    4. You switch check to true (you are now a reverse vampire)
    5. You received the message that you aren't a reverse vampire, but you are a reverse vampire.
    So the main question is: Have you tested the potion effects when you got the message that "you aren't a vampire", or have you only tested it after receiving the message that "you are a vampire"? I think the check variable and the messages are reversed.
     

  10. Thats what I was thinking of at first, but even with your bit of code, the potion effects don't activate at any point after entering in the command.
     
  11. Did you test the potion effects both after the plugin told you vampire was enabled and when it told you it was disabled? If so, post your code again so I can see the modification.
    This seems like a really simple problem, I don't know why it's giving us so much trouble. The only place that the check boolean is modified is inside that single if else statement in your command handler right?
     
    #51 Sigong, Jun 26, 2021
    Last edited: Jun 26, 2021
  12. The only time I can have the potion effects working, the check boolean has to be set to true, not false. But even if it's set to true, the effects stay on regardless of the command saying it's enabled or disabled.
     
  13. Combine your two if else statements like I suggested a few posts ago, test again, then post both your DarkEnable and main class code.
     
  14. Main class -
    Code (Java):
    package me.flame.darkness;

    import org.bukkit.plugin.java.JavaPlugin;

    public final class Main extends JavaPlugin{


        @Override
        public void onEnable() {
            // Plugin startup logic


            DarkEnable turnOn = new DarkEnable();
            getCommand("vampire").setExecutor(turnOn);

            getServer().getPluginManager().registerEvents(new DarkEnable(), this);

        }
    }
     
    DarkEnable -

    package me.flame.darkness;

    import org.bukkit.ChatColor;
    import org.bukkit.block.Block;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerMoveEvent;
    import org.bukkit.potion.PotionEffect;
    import org.bukkit.potion.PotionEffectType;

    public class DarkEnable implements CommandExecutor, Listener {
    private Main main;
    public boolean check = false;
    public boolean checkagain = false;

    public DarkEnable(){
    this.main = this.main;
    }


    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    if(sender instanceof Player){
    Player player = (Player) sender;

    if(player.hasPermission("vampire")){

    if (check){
    check = false;
    player.sendMessage(ChatColor.GREEN + "You are no longer a reverse vampire!");
    }else{
    check = true;
    player.sendMessage(ChatColor.GREEN + "You are now a reverse vampire!");
    }

    return true;

    }else {
    player.sendMessage(ChatColor.RED + "You don't have permission to use this command!");
    return true;
    }

    }
    else {
    main.getLogger().info("You have to be a player to become a reverse vampire!");
    return true;
    }
    }

    public boolean isCheck() {
    return check;
    }

    @EventHandler
    public void onEnterDark(PlayerMoveEvent event) {
    Block block = event.getTo().getBlock();
    int lightLevel = block.getLightLevel();
    // if(!check){event.getPlayer().sendMessage("False");}

    if (check) {
    if (lightLevel < 8) {
    event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 60, 2));
    event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 60, 1));
    event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.WITHER, 60, 1));
    event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, 60, 1));
    } else if (lightLevel == 15) {
    event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SATURATION, 120, 4));
    event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 120, 1));
    }
    }
    }

    }
     
  15. I'm going to try and build your project on my computer, can you paste your plugin.yml as well please?
     
  16. Here ya go -

    Code (Text):
    name: Darkness
    version: ${project.version}
    main: me.flame.darkness.Main
    api-version: 1.16
    commands:
      vampire:
        description: Makes player turn in to or that from a reverse vampire! /<command>

     
    hopefully you see something that I may be overlooking
     
  17. Well I'm glad I had you post you main class, because that's where the problem was. Look at the following three lines from your onEnable() method, and I'll explain the problem:
    Code (Java):
    DarkEnable turnOn = new DarkEnable();

    getCommand("vampire").setExecutor(turnOn);

    getServer().getPluginManager().registerEvents(new DarkEnable(), this);
    Here's what the lines are doing, in order:
    1. Create a new object of type DarkEnable and save it to the variable "turnON"
    2. Set turnOn as the executor for the command "vampire"
    3. Register events to a NEW OBJECT of type DarkEnable
    The approach you went with (having the command executor and listener in the same class) needs the command executor object and listener object to be the same object in order for your plugin to work, but you created two different objects and assigned one of the two purposes to each. Your command executor and listener each have their own copy of the "check" variable, and the listener's copy is never changing.

    This can be fixed by passing the turnOn into the registerEvents function object instead of passing it a new DarkEnable object (I tested it and it worked).

    I also saw three other things worth mentioning:
    1. In your big if else statement in your command executor, you have "return true;" at the end of every branch. It would be simpler to just put "return true;" after the entire statement (if you hover over the "if", Intellij should suggest this also).
    2. In your DarkEnable constructor, you have the line "this.main = this.main". This line is meaningless, and as a result, your main variable is never initialized and remains null. This causes a nullPointerException when the vampire command is run from the console. You need to pass your main class (using the "this" keyword) to DarkEnable objects that you create if you want to use it in those objects.
    3. Since you're using the playerMoveEvent, if a player stands still, then their potion effects expire without them changing their light level. It might make more sense to add those effects with an extremely long duration, and then remove them outright (instead of waiting for the effect to expire) if the player is in the wrong light level.
    Please let me know if this works, and if you have any other questions don't hesitate to ask.
     
    #57 Sigong, Jun 27, 2021
    Last edited: Jun 27, 2021
    • Like Like x 1
  18. So how would you pass the registerEvents function into turnOn?
     
  19. The other way around, pass the turnOn function to the registerEvents function instead of a new object. (I wrote it a little ambiguously in my long post, sorry)
     
  20. May sound like an idiot, but I still don't quite understand. Anything I try gives an error. I was thinking something like this:
    Code (Java):
    DarkEnable turnOn = getServer().getPluginManager().registerEvents(new DarkEnable(), this);
            getCommand("vampire").setExecutor(turnOn);
    But that doesn't work.