Plugin Help Help with hashmaps

Discussion in 'Plugin Help/Development/Requests' started by McDaniel, Aug 23, 2015.

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

    McDaniel

    Hi! I'm new here and it'd be nice to say something on start. :)

    I've got a little problem with hashmap. I want to make assist-system on my Minecraft server and I'm stuck right now.

    I have one HashMap:

    public static HashMap<Entity, HashMap<UUID,Integer>> test = new HashMap<>();

    I want to save entity (e.g. zombie) into this hashmap and next add player (as UUID code) with total damage that he/she gives to enemy. And... that's a problem. I'm stucked here. At entity's death I'm going to say all players who attacked enemy how much damage they had given.

    For example:

    Fight with Zombie:
    Zombie is attacked by 3 players.

    On fight player one gave 110 damage points to enemy.
    On fight player two gave 60 damage points to enemy.
    On fight player three gave 25 damage points to enemy.

    Final attack (when zombie's dead) - player one.

    After enemy's death for players display messages about who killed zombie, how much damage gave and other informations about assists (for player who killed only assist, for other players - other players-in-fight statistics).

    I know I can't explain this very good, but I'm stuck at hashmap and I don't know what's next...

    Please, any proposes below. :)

    Thanks. :)
     
    Last edited: Aug 23, 2015
  2. Offline

    timtower Administrator Administrator Moderator

  3. Offline

    McDaniel

    I have this hashmap and EntityDamagebyEntityEvent. I tried like this:

    @EventHandler
    public void onAttack(EntityDamageByEntityEvent e){
    if(e.getDamager() instanceof Player){
    if(e.getEntity() instanceof LivingEntity){
    Player p = (Player) e.getDamager();
    UUID u = p.getUniqueId();
    LivingEntity le = (LivingEntity) e.getEntity();
    int dmg = (int) e.getDamage();

    HashMap<UUID,Integer> amount = new HashMap<>();
    amount.put(u, dmg);
    test.put(le, amount);
    }
    }
    }

    but it doesn't work, because hashmap "test" is still overwriting... :/
     
  4. Offline

    timtower Administrator Administrator Moderator

    @McDaniel Get the old content first, then add the new damage to the player, then set it.
     
  5. Offline

    McDaniel

    Nah, that's no problem. I can't set in one hashmap "test" all other hashmaps with players and integers like:

    In hashmap "test" for entity e.g. zombie:
    first slot: Player 1 : damage e.g. 20
    second slot: Player 2 : damage e.g. 30


    //OK, doesn't matter, I fixed it with config file, because it's no way to put two hashmap into another hashmap, because it's overwriting. :)
     
    Last edited: Aug 23, 2015
  6. Offline

    timtower Administrator Administrator Moderator

    @McDaniel
    Code:
    map1 = mainMap.get(zombie)
    if(map1 contains playeruuid){
    score = map1 get playeruuid + newdamage
    else
    score = newdamage
    }
    map1 put uuid, score
    mainmap.put(zombie,map1)
    It doesn't overwrite when done correctly
     
  7. Offline

    McDaniel

    Where I have to write "map1"? In Event or outside?
     
  8. Offline

    timtower Administrator Administrator Moderator

    @McDaniel It is dummy code, you can't copy paste it, you need to use your own variables
     
  9. Offline

    McDaniel

    You didn't understand me. I know about variables and it is a example code. :) I asked about map1.

    //Edit: I also know "map1" is example, but first I want to keep my code on Yours, because it is easier. :)
     
    Last edited: Aug 24, 2015
  10. Offline

    timtower Administrator Administrator Moderator

    @McDaniel Don't do that please. Just keep your own variables.
     
  11. Offline

    McDaniel

    public static HashMap<Entity, HashMap<UUID,Integer>> testMap = new HashMap<>();
    @EventHandler
    public void onAttack(EntityDamageByEntityEvent e){
    if(e.getDamager() instanceof Player){
    if(e.getEntity() instanceof LivingEntity){
    final Player p = (Player) e.getDamager();
    final UUID u = p.getUniqueId();
    final LivingEntity le = (LivingEntity) e.getEntity();
    int dmg = (int) e.getDamage();

    HashMap<UUID, Integer> map1 = testMap.get(le);
    int score;

    if(map1.containsKey(u)){
    score = map1.get(u) + dmg;
    }
    else{
    score = dmg;
    }

    map1.put(u, score);
    testMap.put(le, map1);

    }
    }
    }

    Like that? Because it doesn't work, by fighting displays this:
    http://scr.hu/11ts/fspuf

    55th line says: if(map1.containsKey(u))
     
  12. Offline

    timtower Administrator Administrator Moderator

    @McDaniel This is why you shouldn't copy blindly.
    What is in the hashmap.get(entity) when it hasn't been attacked yet?
     
  13. Offline

    McDaniel

    Yes, I thought about it, then how can I fix it? Check if testMap isn't empty?
     
  14. Offline

    timtower Administrator Administrator Moderator

  15. Offline

    McDaniel

    Code:
    @EventHandler
         public void onAttack(EntityDamageByEntityEvent e){
             if(e.getDamager() instanceof Player){
                 if(e.getEntity() instanceof LivingEntity){
                    final Player p = (Player) e.getDamager();
                    final UUID u = p.getUniqueId();
                    final LivingEntity le = (LivingEntity) e.getEntity();   
                    int dmg = (int) e.getDamage();
                   
                    int score;
                    if(testMap.get(le) != null){
                        HashMap<UUID, Integer> map1 = new HashMap<UUID, Integer>();
                        map1 = testMap.get(le);
                        if(map1.containsKey(u)){
                            score = map1.get(u) + dmg;
                            //p.sendMessage("Your map has been edited!");
                        }
                        else{
                            score = dmg;
                            p.sendMessage("Your map has been created!");
                        }
                       
                        for(UUID pu : testMap.get(le).keySet()){
                            Player pl = Bukkit.getPlayer(pu);
                            Bukkit.broadcastMessage(pl + ": " + testMap.get(le).get(u));
                        }
                       
                        map1.put(u, score);
                        testMap.put(le, map1);   
                    }
                    else{
                        HashMap<UUID, Integer> map1 = new HashMap<UUID, Integer>();
                        map1.put(u, dmg);
                        testMap.put(le, map1);
                        p.sendMessage("This mob hasn't been attacked yet!");
                        p.sendMessage("Your map has been created!");
                    }
                       
                       
                 }
             }
         }
    Not like this? I added messages to better navigate in this and loop that shows all players in hashmap and their statistics, but it's something wrong in this, because if e.g. Player1 changes his total dmg from 4 to 5, other's dmg in hashmap also change. :/
     
  16. Offline

    timtower Administrator Administrator Moderator

    @McDaniel 1. Try using other variable names, "u" isn't a very good one.
    2. Your for loop to show everything is wrong, it shows {CraftPlayer:<stuff>} instead of a player name, and it will always show the damage that the current attacker did as you are getting the value from "u" again.
     
  17. Offline

    McDaniel

    Yes, I set pl.getName() and I notice what I put in this code:
    Code:
    for(UUID pu : testMap.get(le).keySet()){
                            Player pl = Bukkit.getPlayer(pu);
                            Bukkit.broadcastMessage(pl + ": " + testMap.get(le).get(u));
                        }
    testMap.get(le).get(u) change to ----> testMap.get(le).get(pu);

    And now it's working, this loop was showing me bad informations because of wrong code. :/

    We solved that problem, because it's work very good. :) Thanks! :)

    Can I ask one more question?

    How to show all players in hashmap information about other players?

    For example:
    Three players in hashmap, on death shows message:

    For players:
    *about other total dmg, without own, e.g.:
    for 1st player only information about 2nd and 3rd player
    for 2nd player only info about 1st and 3rd player etc.?

    I know I have to make a loop, but I don't know how code it.

    EDIT by Timtower: merged posts
     
    Last edited by a moderator: Aug 24, 2015
  18. Offline

    timtower Administrator Administrator Moderator

    @McDaniel map.keySet
    Loop over it, get the current player
    Loop over it again while in the old loop, if uuid==playeruuid: do nothing, else send message
     
  19. Offline

    McDaniel

    OK, it works, thank you so much indeed for help! :)
     
Thread Status:
Not open for further replies.

Share This Page