Solved Issue With EntityDamageEvent

Discussion in 'Spigot Plugin Development' started by Joshkugath, May 16, 2016.

Thread Status:
Not open for further replies.
  1. So i'm coding a Bomb Lobbers plugin, and I have everything working almost perfectly. The one problem I'm running into is my test for if a TNT is exploding on the players own side doesn't always work. The way the maps are designed, both spawn points are directly opposite of each other across the X axis. My plugin finds the middle of these two points and from that defines which side is which. The only time my code doesn't work is the first time a player throws a TNT. Every other time it successfully recognizes the EntityDamageEvent, defines which side the TNT is on, checks what team the player is on, and then cancels the event if the TNT was thrown by someone on the same side. (This is to prevent team griefing.) The other weird thing is the EntityExplodeEvent to cancel the block damage, that is based off of the exact same concept, is lower in the code, and has a lower priority, but it always works. (Yes I am aware that a lot of my code needs additional if statements to prevent from throwing stack traces, I have removed them in an attempt to fine tune a solution to my problem, and once I find the cause they will be re-added)
    Any help would be greatly appreciated!

    Code (Text):
    public static Boolean shouldNotExplode(Player p, Entity e){
            Team t = Teams.getTeam(p);
            if (t == ScoreBoard.getTeam("red") && SpawnPoints.onRedSide(e.getLocation().getX())){
                return true;
            } else if(t == ScoreBoard.getTeam("blue") && !SpawnPoints.onRedSide(e.getLocation().getX())){
                return true;
            } else{
                return false;
            }
        }
           
        @EventHandler(priority = EventPriority.HIGHEST)
        public void onBlastDamage(EntityDamageEvent e) {
            if (e.getCause() == DamageCause.ENTITY_EXPLOSION || e.getCause() == DamageCause.BLOCK_EXPLOSION) {
                if (e.getEntity().getLastDamageCause() instanceof EntityDamageByEntityEvent) {
                    EntityDamageByEntityEvent edbe = (EntityDamageByEntityEvent) e.getEntity().getLastDamageCause();
                    Entity damager = edbe.getDamager();
                    Player p = Bukkit.getPlayer(damager.getMetadata("spawner").get(0).asString());
                    if (shouldNotExplode(p, damager)){
                        e.setCancelled(true);
                    }
                }
            }
        }
           
        @EventHandler(priority = EventPriority.HIGH)
        public void onExplosion(EntityExplodeEvent e) {
            Entity damager = e.getEntity();
                Player p = Bukkit.getPlayer(damager.getMetadata("spawner").get(0).asString());
                if (shouldNotExplode(p, damager)){
                    e.setCancelled(true);
                }else{
                    Object[] blocks1 = e.blockList().toArray();
                    Block[] blocks = Arrays.copyOf(blocks1, blocks1.length, Block[].class);
                    for (Block b : blocks) {
                        b.setType(Material.AIR);
                }
            }
        }
     
  2. Fixed. If anyone has the same problem, I just changed EntityDamageEvent to EntityDamageByEntityEvent, instead of checking for it, then casting it. Yes, its less efficient because this calls an event from every block effected by the TNT, but it gets rid of the glitch. If anyone can think of a more efficient way, let me know. (Its really not that big of a deal unless you have 10,000 TNT exploding.)
    Code (Text):
    public static Boolean shouldNotExplode(Player p, Entity e){
            Team t = Teams.getTeam(p);
            if (t == ScoreBoard.getTeam("red") && SpawnPoints.onRedSide(e.getLocation().getX())){
                return true;
            } else if(t == ScoreBoard.getTeam("blue") && !SpawnPoints.onRedSide(e.getLocation().getX())){
                return true;
            } else{
                return false;
            }
        }
       
        @EventHandler(priority = EventPriority.HIGHEST)
        public void onBlastDamage(EntityDamageByEntityEvent e) {
            if (e.getCause() == DamageCause.ENTITY_EXPLOSION || e.getCause() == DamageCause.BLOCK_EXPLOSION) {
                    Entity damager = e.getDamager();
                    Player p = Bukkit.getPlayer(damager.getMetadata("spawner").get(0).asString());
                    if (shouldNotExplode(p, damager)){
                        e.setCancelled(true);
                    }
            }
        }
       
           
        @EventHandler(priority = EventPriority.HIGH)
        public void onExplosion(EntityExplodeEvent e) {
            Entity damager = e.getEntity();
                Player p = Bukkit.getPlayer(damager.getMetadata("spawner").get(0).asString());
                if (shouldNotExplode(p, damager)){
                    e.setCancelled(true);
                }else{
                    Object[] blocks1 = e.blockList().toArray();
                    Block[] blocks = Arrays.copyOf(blocks1, blocks1.length, Block[].class);
                    for (Block b : blocks) {
                        b.setType(Material.AIR);
                }
            }
        }
     
Thread Status:
Not open for further replies.