Player is suddenly null

Discussion in 'Plugin Development' started by Kevinzuman22, Jan 12, 2019.

Thread Status:
Not open for further replies.
  1. I'm creating a plugin that puts player in a downed state instead of dying upon either falling, or by being killed by a player.

    That whole system on it's own is working just fine. I did it with this:

    Code:
    @EventHandler
    public void onEntityDamageByEntity(EntityDamageEvent e) {
        if(e.getEntity() instanceof Player) {
            Player p = (Player) e.getEntity();
           
            if (e instanceof EntityDamageByEntityEvent) {
                if (((EntityDamageByEntityEvent) e).getDamager() instanceof Player) {
                    if (p.getHealth() <= e.getDamage()) {
                        e.setCancelled(true);
                        p.setHealth(0.5);
                    }
                }
            }
           
            if(e.getCause() == DamageCause.FALL) {
                    if (p.getHealth() <= e.getDamage()) {
                    e.setCancelled(true);
                    p.setHealth(0.5);
                }
            }
        }
    }
    That alone prevented players from dieing from those 2 things. Now, I added the 'downed state' by changing a few things:

    The new EntityDamageListener:
    Code:
    @EventHandler
    public void onEntityDamageByEntity(EntityDamageEvent e) {
        if(e.getEntity() instanceof Player) {
            Player p = (Player) e.getEntity();
           
            if(main.getDownedPlayers().isDowned(p)) {e.setCancelled(true);return;}
           
            if (e instanceof EntityDamageByEntityEvent) {
                if (((EntityDamageByEntityEvent) e).getDamager() instanceof Player) {
                    if (p.getHealth() <= e.getDamage()) {
                        e.setCancelled(true);
                        p.setHealth(0.5);
                        main.getDownedPlayers().toggleDowned(p);
                    }
                }
            }
           
            if(e.getCause() == DamageCause.FALL) {
                    if (p.getHealth() <= e.getDamage()) {
                    e.setCancelled(true);
                    p.setHealth(0.5);
                    main.getDownedPlayers().toggleDowned(p);
                }
            }
        }
    }
    And the whole Downed handler class I've made:
    Downed.java (open)

    Code:
    package me.greenadine.revival;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.UUID;
    
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.entity.ArmorStand;
    import org.bukkit.entity.EntityType;
    import org.bukkit.entity.Player;
    
    import com.connorlinfoot.titleapi.TitleAPI;
    
    public class Downed {
       
        private Main main = Main.getInstance();
       
        private List<UUID> downed;
       
        public Downed() {
            downed = new ArrayList<UUID>();
        }
       
        public boolean isDowned(Player p) {
            return downed.contains(p.getUniqueId());
        }
       
        public void toggleDowned(Player p) {
            if(downed.contains(p.getUniqueId())) {
                downed.remove(p.getUniqueId());
               
                Location normalLoc = new Location(p.getWorld(), p.getLocation().getX(), p.getLocation().getY() + 1, p.getLocation().getZ());
               
                p.teleport(normalLoc);
                createDownedTag(p.getLocation());
               
                TitleAPI.clearTitle(p);
            } else {
                downed.add(p.getUniqueId());
               
                Location downLoc = new Location(p.getWorld(), p.getLocation().getX(), p.getLocation().getY() - 1, p.getLocation().getZ());
               
                p.teleport(downLoc);
                createDownedTag(p.getLocation());
               
                TitleAPI.sendTitle(p, 20, 1728000, 20, ChatColor.translateAlternateColorCodes('&', main.getConfig().getString("downed-title")), ChatColor.translateAlternateColorCodes('&', main.getConfig().getString("downed-subtitle")));
            }
        }
       
        private void createDownedTag(Location loc) {
            ArmorStand as = (ArmorStand) loc.getWorld().spawnEntity(loc, EntityType.ARMOR_STAND);
           
            as.setInvulnerable(true);
            as.setCollidable(false);
            as.setCustomNameVisible(true);
            as.setCustomName(ChatColor.translateAlternateColorCodes('&', Main.getInstance().getConfig().getString("downed-tag")));
        }
    }

    And my Main class is here:
    Main.java (open)
    Code:
    package me.greenadine.revival;
    
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class Main extends JavaPlugin {
    
        private Downed downedHandler;
       
        public Downed getDownedPlayers() {
            return downedHandler;
        }
       
        private static Main main;
       
        public static Main getInstance() {
            return main;
        }
       
        private String name = "Revival";
        private String versionid = "0.1";
       
        public void onEnable() {
            downedHandler = new Downed();
            getServer().getPluginManager().registerEvents(new EntityDamageByEntityListener(), this);
           
            getLogger().info("Enabled " + name + " version " + versionid);
        }
       
        public void onDisable() {
           
        }
    }
    


    Making those changes caused errors. The problem is, when using either of the methods of my Downed class, such as '.isDowned(Player)', gives the error that the player is null. However, that does not occur on 'p.getHealth()' in the EntityDamageListener.

    I'm out of ideas on fixing this. Any help?
     
  2. I'm not pretty sure about this but I think the way you handle the main Object in your Main class is not good. If you use a static Main object (which I do not recommend btw) you have to initialize it in the onEnable. Otherwise it would be null, or am I wrong?
    This will probably not solve your problem but it's the thing I always get stuck with when reading the code
     
  3. Good lord, I did oversee that simple thing. Thanks for noticing.

    I assume the recommended way of getting the instance of the main class is just by having it required in the constructor of each class it's required?
     
  4. Exactly that's the best way to do it.
    But your problem isn't fixed now, isn't it?
     
  5. Offline

    TheWolfBadger

    Put 'main = this' in your onEnable() method in front of where you declare the Downed class
     
Thread Status:
Not open for further replies.

Share This Page