A timer for every player

Discussion in 'Plugin Development' started by jumbledProgram, Aug 24, 2020.

Thread Status:
Not open for further replies.
  1. Im trying to make it so that when you kill a mob, a 1 minute timer resets and you start taking damage unless you kill another mob. I've got the command "/bloodthirst <add/remove> <name>" but i dont know how to give them a seperate timer. I need the timer to be displayed in the actionbar in seconds.
     
  2. Offline

    KarimAKL

    @jumbledProgram Make a BukkitRunnable that runs every 20 ticks (1 second), then create a Map<UUID, Long> that contains the player's UUID as the key and the milliseconds for when the timer started.
     
    Last edited by a moderator: Aug 24, 2020
  3. Would that just be a standard hashmap?
     
  4. Offline

    KarimAKL

  5. Could i use a variable of type UUID? "import java.util.UUID;"
     
  6. Offline

    KarimAKL

  7. i used "HashMap<UUID, Integer> bloodTimer = new HashMap();" to create a hashmap that stores uuid and times, but i think i got confused with minecraft uuids and java uuids, i think i should store it as a string instead. EDIT : "UUID uuid = e.getPlayer().getUniqueId();" can only hold UUID values. so i guess i gotta use that
     
  8. Offline

    KarimAKL

    @jumbledProgram
    1. I said Map<UUID, Long>, not Map<UUID, Integer>.
    2. The UUID used by Minecraft is java.util.UUID, it's the same.

    What do you mean? Why won't you use a Map?
     
  9. I am using a map, thats just what im using to make a variable uuid on the playerjoinevent, it checks if that player has a score on the map, if they dont it gives them one, if they do it resets it.
     
  10. Offline

    KarimAKL

  11. okay well, ive gotten a lot further, i have a hashmap with UUIDs and time left in ticks, im trying to make this code run for every player, but im stuck. it should get their uuid, and check a hashmap to get their score.
    Code:
    Player p;
           bloodTimer.replace(p.getUniqueId(), bloodTimer.get(p.getUniqueId())-1);
           p.sendMessage("Blood Timer >>>" + bloodTimer.get(p.getUniqueId()));
    Edit: also every player gets added to the hashmap when they join using this code :
    Code:
    @EventHandler
            public void onPlayerJoin(PlayerJoinEvent e) {
                Player player = e.getPlayer();
                UUID uuid = e.getPlayer().getUniqueId();
                if(!(bloodTimer.containsKey(uuid))) {
                    bloodTimer.put(uuid, 1200);
                } else {
                    bloodTimer.replace(uuid, 1200);
                }
            }
     
  12. Offline

    Strahan

    You definitely don't need to store it as a String. Also Map is an interface, HashMap is the implementation of said interface. It is properly instantiated as Map<whatever, whatever> variable = new HashMap<>(); You can specify the types again in the right side, but it's not necessary. Anyway, per SOLID design it's best to declare the interface on the left and implementation on the right.

    That's not how you really should do it. I'd be storing the time until penalty in the map, not seconds left. Then you evaluate current time against the deadline to get your display.

    Also is literally every player supposed to get this effect? Usually when I see things like this, it's only if a certain status is in effect. Like if they are a vampire, or have a curse or whatever.

    Also also you don't need to check if they are in the map and alternate between put and replace. You can put a key in the map that is already there, that won't be a prob. It will overwrite the prior value.
     
  13. Not really, i'm trying to make it access an arraylist that contains the players UUIDs of everyone who's been /bloodthirsty add <name>

    1200 ticks is the time until penelty, on the display i want it to say "14 seconds left"

    Thank you for letting me know! :)
     
  14. Offline

    Strahan

    Then you're gonna want to put some logic in the player join event. You'll also want to put logic in the onEnable to implement it after a reload.

    Yea, I got that. But the way you are doing it is more work than you need to be doing. Just store the time when the penalty gets applied, and calculate from that. No need to increment a counter every loop.

    No prob.
     
  15. Not to be rude, but i dont really see what this can do, i the hashmap i have the players uuid as the key, and their time left as the value, i dont really know what you mean by store the time when the penalty gets applied and calculate from that
     
  16. Offline

    Strahan

    Assuming I have a Map<UUID, Long> penalties holding the player and I'm adding like:
    Code:
    penalties.put(uuidObject, System.currentTimeMillis() + penaltyDelay * 1000);
    I'd do the task like:
    Code:
    private void bloodthirstWorkerTask() {
      new BukkitRunnable() {
        @Override
        public void run() {
          for (Map.Entry<UUID, Long> data : penalties.entrySet()) {
            Player p = getServer().getPlayer(data.getKey());
            if (p == null) {
              penalties.remove(data.getKey());
              continue;
            }
          
            long secondsRemain = (data.getValue() - System.currentTimeMillis()) / 1000;
            if (secondsRemain > 0) {
              p.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(secondsRemain + " second(s) remain until penalty"));
              continue;
            }
          
            if (p.isDead()) {
              penalties.remove(data.getKey());
              continue;
            }
          
            p.setHealth(p.getHealth()-1);
            p.playSound(p.getLocation(), Sound.ENTITY_PLAYER_HURT, 1, 1);
          }
        }
      }.runTaskTimer(this, 0, 20L);
    }
     
  17. Hey, sorry that this isnt too related to this issue, but do you have any java tutorials / courses i could use?
     
  18. Offline

    KarimAKL

Thread Status:
Not open for further replies.

Share This Page