Combat plugin

Discussion in 'Plugin Development' started by KarimAKL, Apr 8, 2018.

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

    KarimAKL

    Hey, i wanna create a combat plugin where players can't log out of combat and commands are blocked etc. (i know alot of plugins are made for this already but there are just some things in the plugins i would like to change but is not configurable) So to start off i want to ask if i should use HashMap or Lists? Like to add players to the combat and then check if they are in combat before i stop them from certain things? And how would i make it so that if you don't attack anyone or anyone attacks you within a certain time you get out of combat?
     
  2. Offline

    DutchJellyV2

    Use bukkitrunnable with HashMap
     
  3. Offline

    KarimAKL

    @DutchJellyV2 I don't know what bukkitrunnable is. :/ And with HashMap should i do this?:
    Code:
    public HashMap<UUID, String> whatever = new HashMap<UUID, String>();
    
     
  4. Offline

    timtower Administrator Administrator Moderator

  5. Offline

    KarimAKL

    @timtower Is this how i should do it?
    Code:
    public class OnDamageEvent extends BukkitRunnable implements Listener {
        
        public HashMap<UUID, String> combat = new HashMap<UUID, String>();
       
        private Main plugin;
       
        public OnDamageEvent(Main plugin) {
            this.plugin = plugin;
           
            Bukkit.getPluginManager().registerEvents(this, plugin);
        }
       
        @EventHandler
        public void onDamage(EntityDamageByEntityEvent e) {
            if (e.getDamager() instanceof Player && e.getEntity() instanceof Player) {
                Player victim = (Player) e.getEntity();
                Player attacker = (Player) e.getDamager();
               
                @Override
                public void run() {
                    //Something
                }
            }
        }
    
    }
    
    
     
  6. Offline

    CommonSenze

    @DutchJellyV2
    Why use a hashmap? He only needs to save the players who are in combat. Just save the Player's UUID and check if their UUID is saved in the list. Or am I misinterpreting what's going on?
     
  7. Offline

    KarimAKL

    @CommonSenze If i'm not supposed to use a HashMap then what? A list?
     
  8. Offline

    DutchJellyV2

    Personally I'd use the LocalDateTime object to check what players are in combat every second so you don't have to have a 100 bukkitrunnable when a 100 players are in combat. But yes you could also just start a bukkitrunnable for each individual player in combat and remove/add them to a list.
     
  9. Offline

    KarimAKL

    @DutchJellyV2 What is the LocalDateTime object(what does it do?) and why would you rather use that?
     
  10. Offline

    DutchJellyV2

    The object stores a date and time. So when a player should be in combat for 5 seconds you can set their expired time to 5 seconds in the future. With 1 bukkitrunnable you can check that Map of combattimes of players instead of having to have one for each player in combat. It's better memorywise and processorwise and is way more generic.
     
  11. Offline

    KarimAKL

    @DutchJellyV2 Okay, then it would be possible to make the time go up to 10 seconds everytime they get hit/hits someone if the time of combat is set to 10 seconds, right? If so then could you tell me how to make the LocalDateTime object?
     
    Last edited by a moderator: Apr 10, 2018
  12. Offline

    RcExtract

    1. You cannot block players from logging out. (Ik what u mean, u want the player to be dead the next time he logins if he logouts while being tagged)
    2. Yeah you should use hashmap, but "HashMap<Player, Integer>" instead of "HashMap<UUID, String>", because:
      1. You are working with players, but not uuids. I explained it here.
      2. You want to start a repeating task where every second it minus all integers inside the hashmap by one.
      3. What i am doing is to make a hashmap to store all tagged players. Then, the value (Integer) represents how many seconds they need to keep not to be hitted in order to log out correctly.
    3. Handle EntityDamageByEntityEvent. If the damaged entity is Player, put the player and the default waiting seconds into the hashmap, which sets the integer of the player in the hashmap to default waiting seconds, or put a new entry if the player was not originally added into it.
    4. LocalDateTime is unecessary.
    5. Handle PlayerLeaveEvent. If the player is in the hashmap, add him to a list.
    6. Handler PlayerJoinEvent, kill the player if he is in the list. Then, remove him from the list. (You dont need to manually remove him from the hashmap, becuase the task does it)
    7. To start a repeating task, do Bukkit.getScheduler().runRepeatingTask(Plugin, Runnable, 20, DEFAULT_WAITING_SECONDS * 20) where the third argument indicates the delay of the first run of this task, and the fourth argument indicates the interval between executions of this task. Both are IN TICKS. (1 second = 20 ticks)
     
    Last edited: Apr 10, 2018
  13. Offline

    timtower Administrator Administrator Moderator

    @RcExtract Players tend to cause memory leaks, certainly when they log off.
    UUID's don't, and you can get the Player object with them.
     
    Banjer_HD likes this.
  14. Offline

    RcExtract

    Remove the entry of the player in the PlayerLeaveEvent handler after determining whether adding player to the list or not. (this will be helpful when the task interval is long)
     
  15. Offline

    timtower Administrator Administrator Moderator

    Or just use UUID's and never have the issue.

    Why not have a task that checks the current time with the time stored in the map?
    Then you don't need to decrease all values every time it runs.
    Or just have a runnable per player with a runTaskLater
    In point 5 you are talking about a list, what list?
    Point 8: Why is this relevant? Multithreading this will cause a bunch of different issues.
     
  16. Offline

    RcExtract

    @timtower Point 8 deleted.
    As @DutchJellyV2 said we don't want to start many tasks. (Because it uses more memory?)
     
  17. Offline

    timtower Administrator Administrator Moderator

    @RcExtract Player objects take more memory in that regard.
     
  18. Offline

    RcExtract

    We are just referring Players from the hashmap. No extra memory should be required to refer to Players.
     
  19. What is a hashmap?
    Answer: A HashMap is a list with 2 values, wich means that you can for example store a <String, Integer>.
    You for example use the String to define the playername and the Integer for the amount of kills someone has. You know thier name but not the kills, you can now use the hashmap.get("Playername") and it wil return a number.

    You can use a:
    HashMap<UUID, Boolean> map = new HashMap<UUID, Boolean>();

    and when the player damage's an other player do this:
    Code:java
    1.  
    2. map.put(p.getUniqueId(), true);
    3.  
    4. Bukkit.getScheduler().runTaskLater(this, new BukkitRunnable() {
    5. @Override
    6. public void run() {
    7. map.put(p.getUniqueId(), false);
    8. }
    9. }, amount of seconds * 20);
    10.  


    EDIT:
    A better way to do this is make a ArrayList called isTagged:
    List<UUID> isTagged = new ArrayList<UUID>();
    And add the player when he is atacking and then remove the player in your runable.
     
  20. Offline

    KarimAKL

    @RcExtract @timtower @Banjer_HD I'm a little confused right now so should i use UUID or Player? Also i want the player to die when he logs out so that the items of the player is gonna drop on the ground, how would i do that? EDIT: Also should i use HashMap or ArrayList?
     
  21. Offline

    RcExtract

    Why do u keep thinking of List or ArrayList? You don't need to arrange tagged players in order.

    Sorry, you do not need the list then. simply set the player health to 0 in PlayerLeaveEvent handler. (Don't forget to remove the player from hashmap to prevent memory leaks)

    Use HashMap, because you want to countdown the tagged time for each player, and you dont want to start multiple tasks for each player.

    EDIT:

    Sorry, List idea was actually from Banjer.

    Why do u use List?

    Don't put BukkitRunnable inside runTaskLater method. Put Runnable instead.

    I don't suggest starting so task for each player. Also, what if the player hits someone else again? (Start another task? Then there will be so much tasks.)

    In ur example, you don't need Boolean as value of UUID. Use Set<UUID> instead. When tagging time is up, remove the UUID from the set. When a player hits someone, add his UUID into the set.

    EDIT 2: we are confusing Karim much.
     
    Last edited: Apr 11, 2018
  22. Offline

    KarimAKL

    @RcExtract Okay thanks for the information and yes you are confusing me much. :p So i should do this then?:
    Code:
    public static HashMap<UUID, Integer> combat = new HashMap<UUID, Integer>();
    
    If that's right then how would i set a time and reset the time everytime someone gets hit/hits another player? And i would like to be able to change the time in the config.yml like "combat-time: 10" in the config, so how would i do that?
     
  23. Offline

    DutchJellyV2

    You could use the bukkit runnable as an actual timer but I'm not sure if it'd be accurate. When the server is lagging it would slow down and extend the time period. I therefore strongly recommend you to look into the LocalDateTime object of Java.util (could be some other java import). Use the addminutes method to set a datetime in the future and keep checking if this is reached.
     
  24. Offline

    timtower Administrator Administrator Moderator

    @DutchJellyV2 Or use System.currentMillis() (or similar) and just add 1000*60*60*minutes.
     
  25. Offline

    KarimAKL

    @timtower Would that slow down when the server is lagging like @DutchJellyV2 said? Also if it doesn't then how would i do it?
     
  26. Offline

    timtower Administrator Administrator Moderator

    Nope, it is using the system time, not some internal counter that can get inaccurate.
     
  27. Offline

    KarimAKL

    @timtower Okay, nice. But then how would i do it? What's the name for it? That way i can try looking it up.
     
  28. Offline

    KarimAKL

  29. Offline

    KarimAKL

    @timtower bump, you think you could tell me a little more about it?
     
  30. Offline

    timtower Administrator Administrator Moderator

    @KarimAKL No, I won't.
    I gave the actual method already.
     
Thread Status:
Not open for further replies.

Share This Page