InventoryClickEvent problem!

Discussion in 'Plugin Development' started by IRRIDVX, Aug 31, 2015.

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

    IRRIDVX

    So I have this custom inventory that opens when someone left click with a bow, the inventory shows a tnt and a sapling, I don't know what to put in paranthesis when I call the onProjectile event when someone clicks on the tnt!

    Here is the code:

    Code:
    package me.eldarm.plugin;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.entity.Arrow;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.entity.ProjectileHitEvent;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class Main extends JavaPlugin implements Listener {
    
        public void onEnable() {
            Bukkit.getServer().getPluginManager().registerEvents(this, this);
        }
    
        public void onDisable() {
    
        }
       
        public Map<Player,Boolean> tag = new HashMap<Player,Boolean>();
       
        @EventHandler
        private void onProjectile(ProjectileHitEvent event) {
            Player player = (Player) event.getEntity().getShooter();
            if(event.getEntity() instanceof Arrow && player instanceof Player) {
                event.getEntity().getWorld().createExplosion(event.getEntity().getLocation(), 1.5f, true);
                event.getEntity().remove();
               
            }
           
        }
    
        @EventHandler
        public void onInventoryClick(InventoryClickEvent event) {
            if(!ChatColor.stripColor(event.getInventory().getName().equalsIgnoreCase("Magic Arrow Selector"))) {
                return;
            }
            Player player = (Player) event.getWhoClicked();
            event.setCancelled(true);
    
            if(event.getCurrentItem() == null || event.getCurrentItem().getType() == Material.AIR || !event.getCurrentItem().hasItemMeta()) {
                player.closeInventory();
                return;
            }
            switch(event.getCurrentItem().getType()) {
            case TNT:
                onProjectile(player);
               
           
           
            }
           
           
           
    
        }
    
        private void openGUI(Player player) {
            Inventory inv = Bukkit.createInventory(null, 27, ChatColor.GREEN + "Magic Arrow Selector");
    
            ItemStack explosive = new ItemStack(Material.TNT);
            ItemMeta explosiveMeta = explosive.getItemMeta();
            ItemStack sapling = new ItemStack(Material.SAPLING);
            ItemMeta saplingMeta = sapling.getItemMeta();
    
            explosiveMeta.setDisplayName(ChatColor.RED + "Explosive Arrows!");
            explosive.setItemMeta(explosiveMeta);
            saplingMeta.setDisplayName(ChatColor.GREEN + "Tree arrows!");
            sapling.setItemMeta(saplingMeta);
    
            inv.setItem(3, explosive);
            inv.setItem(5, sapling);
    
            player.openInventory(inv);
    
        }
    
        @EventHandler
        public void onPlayerJoin(PlayerJoinEvent event) {
            event.getPlayer().getInventory().addItem(new ItemStack(Material.BOW));
        }
    
        @EventHandler
        public void onPlayerClick(PlayerInteractEvent event) {
            Action a = event.getAction();
            ItemStack is = event.getItem();
            if(a == Action.PHYSICAL || is == null || is.getType() == Material.AIR) {
                return;
            }
            if(a.equals(Action.LEFT_CLICK_BLOCK) && is.getType() == Material.BOW) {
                openGUI(event.getPlayer());
    
            }
    
        }
    
    }
    
    And also could someone explain me how to use properly hashmaps? I mean how to disable explosive arrows if the event is enabled? Thanks :D
     
  2. Offline

    au2001

    @IRRIDVX You cast the shooter to a player before checking if he's a player, that will throw an error if not.

    You call the onProjectile method with the argument player, not ProjectileHitEvent this won't work.
    What are you trying to do here?

    For your map, don't save players: it's a memory leak. Just save their UUID.
    And if you just save a boolean, use an ArrayList instead.

    To add someone to the list:
    Code:
    ArrayList.add(player.getUniqueId());
    to remove him:
    Code:
    ArrayList.remove(player.getUniqueId());
    and to check if he is in it:
    Code:
    ArrayList.contains(player.getUniqueId());
     
    IRRIDVX likes this.
  3. Offline

    IRRIDVX

    If I change that to onProjectile(ProjectileHitEvent) eclipse gives me an error...
    Btw thanks for the hashmap explaining :p
     
  4. Offline

    au2001

    @IRRIDVX
    You would have to use new ProjectileHitEvent(...) but that's not the good way to do it.
    If you want an explosion where the player is:
    Code:
    player.getWorld().createExplosion(player.getLocation(), 1.5f, true);
    And if you want the player to shoot an arrow:
    Code:
    player.launchProjectile(Arrow.class);
     
    IRRIDVX likes this.
  5. Offline

    IRRIDVX

    @au2001

    Code:
    package me.eldarm.plugin;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.entity.ProjectileHitEvent;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class Main extends JavaPlugin implements Listener {
        String invname = "Magic Arrows Selector";
    
        public void onEnable() {
            Bukkit.getServer().getPluginManager().registerEvents(this, this);
        }
    
        public void onDisable() {
    
        }
    
        public boolean explosiveEnabled = false;
        public boolean treeEnabled = false;
    
        @EventHandler
        public void onPlayerJoin(PlayerJoinEvent event) {
            event.getPlayer().getInventory().addItem(new ItemStack(Material.BOW));
        }
    
        private void openGUI(Player player) {
            Inventory inv = Bukkit.createInventory(null, 27, invname);
    
            ItemStack explosive = new ItemStack(Material.TNT);
            ItemMeta explosiveMeta = explosive.getItemMeta();
            ItemStack sapling = new ItemStack(Material.SAPLING);
            ItemMeta saplingMeta = sapling.getItemMeta();
    
            explosiveMeta.setDisplayName(ChatColor.RED + "Explosive Arrows!");
            explosive.setItemMeta(explosiveMeta);
            saplingMeta.setDisplayName(ChatColor.RED + "Tree arrows!");
            sapling.setItemMeta(saplingMeta);
    
            inv.setItem(12, explosive);
            inv.setItem(14, sapling);
    
            player.openInventory(inv);
    
        }
    
        @EventHandler
        public void onPlayerClick(PlayerInteractEvent event) {
            Action a = event.getAction();
            ItemStack is = event.getItem();
            if(a == Action.PHYSICAL || is == null) {
                return;
            }
            if((a == Action.LEFT_CLICK_BLOCK || a == Action.LEFT_CLICK_AIR) && is.getType() == Material.BOW) {
                openGUI(event.getPlayer());
    
            }
    
        }
    
        @EventHandler
        public void onIventoryClick(InventoryClickEvent event) {
            if(!(event.getInventory().getName().equalsIgnoreCase(invname))) {
                return;
            }
            Player player = (Player) event.getWhoClicked();
            if(event.getCurrentItem().getType() == Material.TNT) {
                event.setCancelled(true);
                if(explosiveEnabled == true) {
                    explosiveEnabled = false;
                    player.sendMessage(ChatColor.RED + "Explosive arrows: OFF");
                    ProjectileHitEvent.getHandlerList().unregister(new ExplosiveArrow());
                    player.closeInventory();
                    return;
                }
                explosiveEnabled = true;
                if(explosiveEnabled == true) {
                    player.closeInventory();
                    Bukkit.getServer().getPluginManager().registerEvents(new ExplosiveArrow(), this);
                    player.sendMessage(ChatColor.RED + "Explosive arrows: " + ChatColor.GREEN + "ON");
                    explosiveEnabled = true;
                    return;
                }
    
            }
            if(event.getCurrentItem().getType() == Material.SAPLING) {
                event.setCancelled(true);
                if(treeEnabled == true) {
                    treeEnabled = false;
                    player.sendMessage(ChatColor.RED + "Tree arrows: OFF");
                    ProjectileHitEvent.getHandlerList().unregister(new TreeArrow());
                    player.closeInventory();
                    return;
                }
                treeEnabled = true;
                if(treeEnabled == true) {
                    player.closeInventory();
                    Bukkit.getServer().getPluginManager().registerEvents(new TreeArrow(), this);
                    player.sendMessage(ChatColor.RED + "Tree arrows: " + ChatColor.GREEN + "ON");
                    treeEnabled = true;
                    return;
                }
    
            }
    
        }
    
    
    }
    
    Ok, I worked like alot on this but I have 1 problem... I don't know why the code doesn't unregister the events (The lines on what I am referring start both with "ProjectileHitEvent")
    Can you help me on this? And is there a faster way to do what I wrote? xD
     
  6. Offline

    au2001

    @IRRIDVX You shouldn't register/unregister events each time.
    Make a HashMap<UUID, ArrowEffect> (ArrowEffect is an enum you create with all your effects)
    Then in each event handler, check if the player's effect is the one you want (or use a switch).
     
  7. Offline

    IRRIDVX

    Alright, so I don't need even all those explosiveEnable = true/false? Thanks
    @au2001

    @au2001
    After making the hasmap with HasMap<UUID, ArrowEffect> = new HashMap<UUID, ArrowEffetc>;
    How I disable the event if I registered it after the user clicked on the TNT or Sapling?

    <Edited by bwfcwalshy: Merged posts, please use the edit button rather than double posting.>
     
    Last edited by a moderator: Sep 1, 2015
  8. Offline

    mine-care

    You dont have to override something you are not using.

    Dont store player objects long term unless you handle them properly which aparently you are not.
    First check, then cast.

    Dont compare booleans with == :/ if(boolean) for true, and if(!boolean) to check for false.

    What is the point of those two?
    Also keep in mind that those are public booleans so the same between event calls so it will mess it up if the event is called at the same time twice.

    Have you gone through the basics of java?
     
  9. Offline

    IRRIDVX

    Hello thanks for the reponse, I have gone through the basics, but like 2 years ago and I learned nothing so I am trying to practice, maybe it works :p

    Code:
    if(event.getCurrentItem().getType() == Material.SAPLING) {
                event.setCancelled(true);
                if(treeEnabled == true) {
                    treeEnabled = false;
                    player.sendMessage(ChatColor.RED + "Tree arrows: OFF");
                    ProjectileHitEvent.getHandlerList().unregister(new TreeArrow());
                    player.closeInventory();
                    return;
                }
                treeEnabled = true;
                if(treeEnabled == true) {
                    player.closeInventory();
                    Bukkit.getServer().getPluginManager().registerEvents(new TreeArrow(), this);
                    player.sendMessage(ChatColor.RED + "Tree arrows: " + ChatColor.GREEN + "ON");
                    treeEnabled = true;
                    return;
    with that first I check if treeEnabled is true, if it is Im changing value to false and disabling the event cause the player clicked the tnt and the event was already enabled! Then if it's false (by default is false) Im changing value to True and activate the event... Is that wrong??
    If I use maps, how can I check if an event is currently enabled and how I can disable it?
    Thanks again for asnwering :p
     
  10. @IRRIDVX

    Code:
    if(treeEnabled){
        //If it is true
    }else{
        //If it is false
    You can also do

    Code:
    if(!treeEnabled){
         //If it is false
    }else{
        //If it is true
     
    mine-care and IRRIDVX like this.
  11. Offline

    au2001

    @IRRIDVX
    Register all your events once on your onEnable.
    Then you can either make an array list for each power, if you want to have several active at the same time.
    Or create an enum, and store the UUID/enum for each player.

    It seems like you understood how to create
    But don't forget to do:
    Object name = new Object<...>();

    Now for the rest, use this:
    - To change the arrow power of a player:
    Code:
    hashmap.put(player.getUniqueId(), Enum.VALUE);
    - To reset his power:
    Code:
    hashmap.remove(player.getUniqueId());
    - To check if he has a power:
    Code:
    hashmap.containsKey(player.getUniqueId());
    - To get the player's power:
    Code:
    if (hashmap.get(player.getUniqueId()).equals(Enum.VALUE)) { ... }
    - And use a switch for each power in your ProjectileHitEvent:
    Code:
    switch (players_power) {
    case VALUE:
        // Do the code for your explosive or whatever power.
        break; // Don't forget this or it will do the explosive, ice, tree... power for this arrow, which you don't want
    case VALUE2:
        // Do the code for your ice or whatever power.
        break;
    case VALUE3:
    case VALUE4: // If you want two powers to have the same effect, just put two "cases" without a break.
        // Do the code for your tree or whatever power.
        break;
    case [...]:
        // Do the code for your other power.
        break;
    default: // This is optional, it's if you want to do something when he doesn't have any power
        // Do something else.
        // You don't need a break in the last one since there isn't any code below.
    }
    You could call a separate method in each case if you want to make it clearer.
    Or register one class per power and check (with the 4th code I gave you) if it's the right power for this class.
    If you do this last option (which I don't recommend), it would be clearer if you would have one array for each power, located in the correct class.
    Note that you would have to remove the player's uuid from each other array before adding him to another (unless you want him to be able to use several power at the same time).
     
Thread Status:
Not open for further replies.

Share This Page