1.15.2 How to assign a player variable and display it?

Discussion in 'Spigot Plugin Development' started by Bluehawk409, Sep 11, 2020.

  1. I am trying to create a plugin that tracks the number of kills a player has and displays in an inventory name. When I killed a mob it worked, but when I logged on to a different account we shared the same kill count number. How am I meant to display a variable unique to a player? Here is my code:

    Listener Class:
    Code (Text):
    package me.paynt.recipes.events;

    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    import java.util.UUID;

    import org.bukkit.entity.Entity;
    import org.bukkit.entity.Monster;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.EntityDeathEvent;

    import net.md_5.bungee.api.ChatColor;

        public class MobListener implements Listener {
           
            public static Map<String, Integer> soulsmap = new HashMap<>();
            public static int souls = 0;
           

           
           
    @EventHandler
    public void GetSoul(EntityDeathEvent event) {

       
            Entity mob = event.getEntity();

            Player player = event.getEntity().getKiller();
           
            if (player instanceof Player && mob instanceof Monster){

                    String suuid = player.getUniqueId().toString();


                   
                    souls = souls + 1;
                   
                   
                   
                    player.sendMessage(ChatColor.BLUE + "+1 Souls");
                   
                    if (soulsmap.containsKey(player)) {
                        soulsmap.replace(suuid, souls);
                    } else {
                        soulsmap.put(suuid, souls);
                    }
                   
                }
               
               
                 

               
               
               
           
        }

    }


     
    Gui Command Class:
    Code (Text):
    package me.paynt.recipes.commands;

    import java.util.HashMap;
    import java.util.Map;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;

    import me.paynt.recipes.events.MobListener;

    public class GUICommand implements CommandExecutor {
       
        public static Map<String, Float> menus = new HashMap<String, Float>();
        @Override
        public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
       
           
            if(sender instanceof Player) {
               
                Player player = (Player) sender;

               
                Integer displaysouls = MobListener.souls;
                Inventory tree = Bukkit.createInventory(player, 45, ChatColor.translateAlternateColorCodes('&', "&cSkill Tree &0|| &cSoul Number: ") + ChatColor.DARK_RED + displaysouls);
               
                player.openInventory(tree);
               
               
            }
           
           
            return true;
        }
    }
     
     
  2. Use something called a HashMap and store the players uuid and their kills. You can learn about HashMaps here.
     
  3. If you read my code I am using a hashmap, I am wondering how to display the values of that hashmap in the inventory name. I have read the documentation and have tried :
    MobListener.soulsmap.get(MobListener.souls);

    but that returns null, even after assigning souls a value in the hashmap. What am I doing wrong?
     
  4. your key isn’t a Player type....

    why is this a global variable? In addition, you don’t reset the value every time you replace the value in the map with this variable. why do you need a variable at all? Just get the number of souls from the map, add one to that, then put it to the map.

    when you want to find the number of souls for that player, get the map, and get the value using the player uuid as the key.
     
  5. How do I get the value from the map without a variable? normally I would use this:
    Code (Text):
    soulsmap.get(souls);
    But now that i no longer have a souls variable how am I supposed to pull the integer from the hashmap?
     
  6. souls is of type int. that would just give you errors.

    you have a string as the key. Hopefully, that string is the uuid of the player. Basically, each string points to certain number of souls. To get the number of souls for a player, get their uuid, convert it to a string, then call Map#get(playerUUID)
     
  7. So this would return 1?
    Code (Text):
    public static Map<String, Integer> soulsmap = new HashMap<>();

    String suuid = player.getUniqueId().toString();
    soulsmap.put(suuid, 0);
    soulsmap.get(suuid);
     
  8. that would return 0. You haven’t changed the value for that player. If you want to add one, get the value, add 1 to it, and put the new value back into the map.
     
  9. I have tried:
    Code (Text):
        public class MobListener implements Listener {
           
            public static Map<String, Integer> soulsmap = new HashMap<>();

           

           
           
    @EventHandler
    public void GetSoul(EntityDeathEvent event) {

       
            Entity mob = event.getEntity();

            Player player = event.getEntity().getKiller();
           
            if (player instanceof Player && mob instanceof Monster){

                    String suuid = player.getUniqueId().toString();
           
                   
                   
                   
                    if (soulsmap.containsKey(player)) {
                        soulsmap.replace(suuid, soulsmap.get(suuid) + 1);
                    } else {
                        soulsmap.put(suuid, soulsmap.get(suuid) + 1);
                    }
                   
                    player.sendMessage(soulsmap.get(suuid) + "Souls");
                   
                }
               
               
                 

               
               
               
           
        }

    }
     
    This sends nullSouls in chat when I kill a mob, rather than 1Souls or 0Souls like I want. I still don't understand what I am doing wrong.
     
  10.  
  11. ^
    but dont bother checking if the map has the value already, youre going to be assigning a value no matter what you do...
    Code (Java):
    soulsmap.put(suuid, soulsmap.getOrDefault(suuid, 0) + 1);
    is all you need.

    additionally, why are you changing the key to a string uuid? why not leave it as a uuid, or maybe even a player depending on what youre doing?
    since youre just storing a count reference, i would just leave it as uuid.. no point in converting it to a string
     
    • Informative Informative x 1
  12. Thanks, you all, this worked! the only other problem I am having is when I restart the server the soul value returns to 0. I know I have to save the hashmap to the config file, but can't figure out how to do that when the key is UUID and the value is Integer?
     
  13. then save it to the config as a string. no need to convert to serialization first while youre still using the objects.. just convert to string when you actually need it as a string