Solved Killstreak giving me an error after first kill.

Discussion in 'Spigot Plugin Development' started by Fep310, Feb 12, 2020.

  1. I've been working the past 2 days on creating a kitpvp plugin for 1.9 combat.
    Inside the plugin, there's an event class (PvPEvts) that deals with pvp related stuff. On it, i'm trying to code a killstreak system, it should work like this:

    - 1st kill: + 10 points
    - 2st kill (w/o dying): + 20 points
    - 3st kill (w/o dying): + 30 points
    and so on...

    All player's killstreaks are stored in a HashMap that can be accessed from the main class - the getter is called "getpKs()".

    PvPEvts class:
    Code (Java):
    package io.github.fep310.quickpvpplugin.Events;

    import io.github.fep310.quickpvpplugin.Files.PlayerStatsFile;
    import io.github.fep310.quickpvpplugin.QuickPvpPlugin;
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.Sound;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.PlayerDeathEvent;
    import org.bukkit.event.player.PlayerSwapHandItemsEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.Plugin;

    public class PvPEvts implements Listener {

        // Get access from the main class
        private QuickPvpPlugin plugin;
        public PvPEvts(QuickPvpPlugin plugin) {
            this.plugin = plugin;
        }

        // Method to get shortened code
        public void sendKillerMsg(Player killer, Player dead, ChatColor color, int points) {
            killer.sendMessage(color +""+ ChatColor.BOLD + ">> " + color + "You killed " + dead.getName());
            killer.sendMessage(color +""+ color + "+ " + points + " Points");
        }

        @EventHandler
        public void playerKill (PlayerDeathEvent e) {

            e.setDeathMessage(null);

            Player dead = e.getEntity();
            Player killer = dead.getKiller();

            // If killer exists and dead had a kit selected
            if (killer != null && plugin.getKitMap().get(dead.getName()) != null) {

                // If it's the killer's first kill, START killer killstreak
                if (!plugin.getpKs().containsKey(killer.getName())) plugin.getpKs().put(killer.getName(), 1);

                // If the killer already killed someone, ADD a kill to his killstreak
                else plugin.getpKs().put(killer.getName(), plugin.getpKs().get(killer.getName() + 1));

                // Getting UUIDs paths from the player_stats.yml
                String dUUID = dead.getUniqueId().toString();
                String kUUID = killer.getUniqueId().toString();
                int deaths = PlayerStatsFile.get().getInt("Players." + dUUID + ".Deaths");
                int kills = PlayerStatsFile.get().getInt("Players." + kUUID + ".Kills");
                int points = PlayerStatsFile.get().getInt("Players." + kUUID + ".Points");

                // Changing player's stats
                PlayerStatsFile.get().set("Players." + dUUID + ".Deaths", deaths + 1);
                PlayerStatsFile.get().set("Players." + kUUID + ".Kills", kills + 1);

                // Kill actions
                switch (plugin.getpKs().get(killer.getName())) { // How high is the killer's killstreak
                    case 1:
                        sendKillerMsg(killer, dead, ChatColor.GREEN, 10); // Using created method for message
                        PlayerStatsFile.get().set("Players." + kUUID + ".Points", points + 10);
                        PlayerStatsFile.save();
                        break;
                    case 2:
                        sendKillerMsg(killer, dead, ChatColor.GREEN, 20);
                        PlayerStatsFile.get().set("Players." + kUUID + ".Points", points + 20);
                        PlayerStatsFile.save();
                        break;
                    case 3:
                        sendKillerMsg(killer, dead, ChatColor.GREEN, 30);
                        PlayerStatsFile.get().set("Players." + kUUID + ".Points", points + 30);
                        PlayerStatsFile.save();
                        break;
                    case 4:
                        sendKillerMsg(killer, dead, ChatColor.GREEN, 40);
                        PlayerStatsFile.get().set("Players." + kUUID + ".Points", points + 40);
                        PlayerStatsFile.save();
                        break;
                    case 5:
                        sendKillerMsg(killer, dead, ChatColor.GOLD, 50);
                        PlayerStatsFile.get().set("Players." + kUUID + ".Points", points + 50);
                        PlayerStatsFile.save();
                        Bukkit.broadcastMessage(ChatColor.GOLD +""+ ChatColor.BOLD + ">> " + ChatColor.GOLD +
                                killer.getDisplayName() + " killed " + ChatColor.AQUA +""+ ChatColor.BOLD + "5" +
                                ChatColor.GOLD + " players without dying!");
                        killer.playSound(killer.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
                        break;
                    case 6:
                        sendKillerMsg(killer, dead, ChatColor.GREEN, 60);
                        PlayerStatsFile.get().set("Players." + kUUID + ".Points", points + 60);
                        PlayerStatsFile.save();
                        break;
                    case 7:
                        sendKillerMsg(killer, dead, ChatColor.GREEN, 70);
                        PlayerStatsFile.get().set("Players." + kUUID + ".Points", points + 70);
                        PlayerStatsFile.save();
                        break;
                    case 8:
                        sendKillerMsg(killer, dead, ChatColor.GREEN, 80);
                        PlayerStatsFile.get().set("Players." + kUUID + ".Points", points + 80);
                        PlayerStatsFile.save();
                        break;
                    case 9:
                        sendKillerMsg(killer, dead, ChatColor.GOLD, 90);
                        PlayerStatsFile.get().set("Players." + kUUID + ".Points", points + 90);
                        PlayerStatsFile.save();
                        break;
                    case 10:
                        sendKillerMsg(killer, dead, ChatColor.DARK_RED, 100);
                        PlayerStatsFile.get().set("Players." + kUUID + ".Points", points + 100);
                        PlayerStatsFile.save();
                        Bukkit.broadcastMessage(ChatColor.DARK_RED +""+ ChatColor.BOLD + ">> " + ChatColor.DARK_RED +
                                killer.getDisplayName() + " killed " + ChatColor.AQUA +""+ ChatColor.BOLD + "10" +
                                ChatColor.DARK_RED + " players without dying!");
                        for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
                            onlinePlayer.playSound(onlinePlayer.getLocation(), Sound.ENTITY_ENDER_DRAGON_GROWL, 1, 1);
                        }
                        break;
                }

                // If killstreaks exceeds 10
                if (plugin.getpKs().get(killer.getName()) > 10) {
                    sendKillerMsg(killer, dead, ChatColor.DARK_RED, 30);
                    PlayerStatsFile.get().set("Players." + kUUID + ".Points", points + 30);
                    PlayerStatsFile.save();
                }

                // Death message
                dead.sendMessage(ChatColor.RED +""+ ChatColor.BOLD + ">> " + ChatColor.RED + "You were killed by " + killer.getName());

                // Add dead player's head
                ItemStack deadHead = new ItemStack(Material.GOLDEN_APPLE);
                ItemMeta deadHeadMeta = deadHead.getItemMeta();
                deadHeadMeta.setDisplayName(dead.getDisplayName() + "'s head");
                deadHead.setItemMeta(deadHeadMeta);
                killer.getInventory().addItem(deadHead);

            }

            // Remove/end dead player's killstreak if he had one.
            plugin.getpKs().remove(dead.getName());

            // If the player died with a kit selected, remove the kit
            if (plugin.getKitMap().get(dead.getName()) != null) plugin.getKitMap().remove(dead.getName());
        }

        Plugin pl = QuickPvpPlugin.getPlugin(QuickPvpPlugin.class);
        Boolean allowBothHands = pl.getConfig().getBoolean("allow-both-hands");

        // Checking from the config if it's allowed to swap hand items
        @EventHandler
        public void onSwitch(PlayerSwapHandItemsEvent e) {
            if (!allowBothHands) e.setCancelled(true);
        }
    }
    Everything works for the first kill.
    On the second kill, I get a console error saying that there's a nullPointerException on line 61: "switch (plugin.getpKs().get(killer.getName())) {".
    I really can't figure it out what I didn't check or got it wrong.
    Just to clarify myself - the killstreak system is the only thing here that is not working. If I remove the statement, the stats works just fine.

    Thanks for the time and attention! ^^

    Extra info about code if interested:
    - Ignore the "getKitMap()" method, this only gets the player choosen kit;
    - I've got a working custom config .yml file (file name: player_stats.yml; class name: PlayerStatsFile) that holds player stats (kills, deaths, coins and other stuff);
    - My main class:
    Code (Java):
    package io.github.fep310.quickpvpplugin;[/SPOILER]

    import io.github.fep310.quickpvpplugin.Commands.*;
    import io.github.fep310.quickpvpplugin.Events.*;
    import io.github.fep310.quickpvpplugin.Files.PlayerStatsFile;
    import org.bukkit.plugin.java.JavaPlugin;

    import java.util.ArrayList;
    import java.util.HashMap;

    public final class QuickPvpPlugin extends JavaPlugin {

        @Override
        public void onEnable() {

            getConfig().options().copyDefaults();
            saveDefaultConfig();

            PlayerStatsFile.setup();
            PlayerStatsFile.get().options().copyDefaults(true);
            PlayerStatsFile.save();

            getServer().getPluginManager().registerEvents(new ApplyKitsEvt(this), this);
            getServer().getPluginManager().registerEvents(new ClickItemEvts(), this);
            getServer().getPluginManager().registerEvents(new InvItemsEvts(this), this);
            getServer().getPluginManager().registerEvents(new PassiveEvts(), this);
            getServer().getPluginManager().registerEvents(new TeleportChecksEvts(), this);
            getServer().getPluginManager().registerEvents(new PlayerResetEvt(this), this);
            getServer().getPluginManager().registerEvents(new PvPEvts(this), this);

            getCommand("slimy").setExecutor(new TestCmd());
            getCommand("setspawn").setExecutor  (new SpawnCmds(this));
            getCommand("spawn").setExecutor     (new SpawnCmds(this));
            getCommand("stats").setExecutor(new StatsCmd());
            getCommand("kit").setExecutor(new KitsCmd(this));
            getCommand("staffmode").setExecutor(new StaffmodeCmd(this));
            getCommand("qpvpdev-gethead").setExecutor(new DevCmds());
        }

        // Player's kit
        private HashMap<String, String> pKit = new HashMap<>();
        public HashMap<String, String> getKitMap() {
            return pKit;
        }

        // Staffmode players list
        private ArrayList<String> staffList = new ArrayList<>();
        public ArrayList<String> getStaffList() {
            return staffList;
        }

        // Player's killstreak
        private HashMap<String, Integer> pKs = new HashMap<>();
        public HashMap<String, Integer> getpKs() { return pKs; }
    }
     
     
  2. Hi,

    I'm sure your error is in the following line:
    Code (Java):
    else plugin.getpKs().put(killer.getName(), plugin.getpKs().get(killer.getName() + 1))
    You are trying to get a value from your Map with killer.getName() + 1 which will (probably) never yield anything other than null, because this 1 will be concatenated to killer.getName(). Basically, you just misplaced some parantheses. But this null value will then be stored to the killstreak-Map, eventually causing the exception to be thrown. An easy fix would be:
    Code (Java):
    else plugin.getpKs().put(killer.getName(), plugin.getpKs().get(killer.getName()) + 1)
    But I would also like to encourage you to take a look at these methods from Map (introduced in Java 8):
    Map#compute
    Map#computeIfAbsent
    If used correctly, these built-in methods can do a lot for you.

    Greetings,
    petomka
     
    • Like Like x 1
  3. Thank you so much! I didn't know it was that simple lol
    I sure will get involved on learning those methods :)