Registering in the Main Class

Discussion in 'Plugin Development' started by TCO_007, Apr 12, 2014.

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

    TCO_007

    I have a bit of a problem. I am trying to code a kit where you can teleport a player in a 3x2000x3 area to you and have a 5 second cooldown. I believe I have to register this in the main class though and I have no idea how. Any help?
    Kit Class:
    Code:java
    1. HashMap<String, Integer> map = new HashMap<String, Integer>();
    2.  
    3. public void addCooldown(String name, int time){
    4. map.put(name, time);
    5. }
    6.  
    7. public boolean hasCooldown(String name){
    8. return map.containsKey(name);
    9. }
    10.  
    11. public void removeOneSecond(String name){
    12. map.put(name, map.get(name) - 1);
    13. }
    14.  
    15. public int getSeconds(String name){
    16. if(map.containsKey(name)){
    17. return map.get(name);
    18. }else{
    19. return 0;
    20. }
    21. }
    22. public void startTask(){
    23. new BukkitRunnable(){
    24. public void run(){
    25. for(String entry : map.keySet()){
    26. removeOneSecond(entry);
    27. int amount = getSeconds(entry);
    28. if(amount <= 0){
    29. map.remove(entry);
    30. }
    31. }
    32. }
    33. }.runTaskTimer(Main.getInstance(), 0, 20); //Runs every second, also. Im not 100% sure but this might cause a concurrent modification exception
    34. }
    35. }
    36.  
    37.  
    38.  
    39.  
    40.  
    41.  


    Main class:
    Code:java
    1. package me.TCOB055.MultiKits;
    2.  
    3. import java.util.ArrayList;
    4.  
    5. import org.bukkit.Bukkit;
    6. import org.bukkit.entity.Player;
    7. import org.bukkit.event.Listener;
    8. import org.bukkit.plugin.PluginManager;
    9. import org.bukkit.plugin.java.JavaPlugin;
    10. import org.bukkit.scheduler.BukkitRunnable;
    11.  
    12. public class Main extends JavaPlugin {
    13. public GUIListener guilisten = new GUIListener(this);
    14. public Events Events = new Events(this);
    15. //array lists for kits
    16. ArrayList<String> PvP = new ArrayList<String>();
    17. ArrayList<String> Fisherman = new ArrayList<String>();
    18. ArrayList<String> kitused = new ArrayList<String>();
    19. ArrayList<String> venom = new ArrayList<String>();
    20. ArrayList<String> trampler = new ArrayList<String>();
    21. ArrayList<String> TearGhast = new ArrayList<String>();
    22. ArrayList<String> Archer = new ArrayList<String>();
    23. ArrayList<String> Taken = new ArrayList<String>();
    24. ArrayList<String> Ninja = new ArrayList<String>();
    25. ArrayList<String> Caveman = new ArrayList<String>();
    26. ArrayList<String> Launcher = new ArrayList<String>();
    27. ArrayList<String> Reverser = new ArrayList<String>();
    28. //end of array lists
    29.  
    30. public void onEnable() {
    31. commands();
    32. events();
    33. }
    34.  
    35. public void commands(){
    36. getCommand("Fisherman").setExecutor(new Fisherman(this));
    37. getCommand("PvP").setExecutor(new PvP(this));
    38. getCommand("kit").setExecutor(new Kit(this));
    39. getCommand("Venom").setExecutor(new Venom(this));
    40. getCommand("Trampler").setExecutor(new Trampler(this));
    41. getCommand("tearghast").setExecutor(new TearGhast(this));
    42. getCommand("Archer").setExecutor(new Archer(this));
    43. getCommand("Taken").setExecutor(new Taken(this));
    44. getCommand("Ninja").setExecutor(new Ninja(this));
    45. getCommand("Caveman").setExecutor(new Caveman(this));
    46. getCommand("Launcher").setExecutor(new Launcher(this));
    47. getCommand("Reverser").setExecutor(new Reverser(this));
    48. }
    49.  
    50. public void events(){
    51. PluginManager pm = getServer().getPluginManager();
    52. pm.registerEvents(Events, this);
    53. pm.registerEvents(guilisten, this);
    54.  
    55. }
    56. }
    57.  
    58.  
     
  2. Offline

    xTigerRebornx

    TCO_007 I'd reccomend a different approach, as what you want is a delay, not a cooldown. You can simply use either a BukkitRunnable or a repeating task that runs every second and checks if the Player has moved, and if he hasn't, it either continues counting down or teleports him, and cancels the task/runnable.
     
  3. Offline

    TCO_007

    Well, what Im trying to do is basically recreate the kit Endermage from the well-known HG server of MC-HG.
    I just want it so that the player cant teleport again for atleast 5 seconds. And where can I learn how to take your approach because this is the first time I have ever tried to make a cooldown. xTigerRebornx

    by the way, this is the kit event in that same class:
    Code:java
    1. @ EventHandler
    2. public void onTakenClick(PlayerInteractEvent event) {
    3. Player p = (Player) event.getPlayer();
    4. if (plugin.Taken.contains(p.getName())){
    5. if (event.getAction() == Action.RIGHT_CLICK_AIR && p.getItemInHand().getType() == Material.IRON_INGOT) {
    6. List<Entity> nearby = p.getNearbyEntities(3, 20000, 3);
    7. for (Entity tmp : nearby)
    8. if (tmp instanceof Player) {
    9. tmp.teleport(p.getLocation());
    10. p.teleport(p.getLocation());
    11. p.sendMessage(ChatColor.GOLD + "You have teleported " + ((Player) tmp).getName() + " to you!");
    12.  
    13. }
    14. }
    15. }
    16.  
    17. }


    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 7, 2016
  4. Offline

    xTigerRebornx

    TCO_007 Ah, my bad, I read what the problem was wrong. You are taking the correct approach to what you are doing, but I'd still reccomend using a scheduler to work with your cooldowns. You could simply add them to a List that stores who is cooling down, and use a delayed task to remove them from that List a few seconds later. Look into how to use the Bukkit Scheduler
     
  5. Offline

    TCO_007

    Can you help me with this though? It says the ".getInstance()..." at the bottom is "undefined for the type main". I figure that means I have to register that in the Main class but I have no idea how to.
     
  6. Offline

    coasterman10

    List would work but is an ordered collection, not exactly descriptive of what we truly want here. A little bit of OO theory lesson: a plain Collection (or Set) would work best, and then we could chose from HashSet, ArrayList, LinkedList, LinkedHashSet, etc.

    You should probably not be using the Singleton pattern, but since dependency injection would create a lot of objects with the same reference, you should either schedule this in the main class, or just create a singleton system with getInstance().

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 7, 2016
  7. Offline

    TCO_007

    I dont want any given code straight to me here but is there an example code I could use anywhere thats from recent? I will have to look up what the singleton system is because I have no idea what that is XD
    Now how could I schedule it in the main class? Thats what I am stuck on.
    coasterman10
     
  8. Offline

    coasterman10

    TCO_007 Singleton is a design paattern where you have just one instance of a class that is accessed by a static method such as getInstance(). It's a bit different for Bukkit plugins because they don't instantiate themselves, hence why it is a bit weird and not optimal. Here's the general pattern:
    Code:java
    1. public class Main extends JavaPlugin {
    2. private static Main instance;
    3.  
    4. public static Main getInstance() {
    5. return instance;
    6. }
    7.  
    8. public void onEnable() {
    9. instance = this;
    10. }
    11.  
    12. public void onDisable() {
    13. instance = null;
    14. }
    15. }


    Now, if you aren't creating a huge number of a class, dependency injection works well, and is generally preferable to singletons for a number of reasons, one being that not only does it eliminate temptations to bad static coding practices, but it also supports different instances of the injected class. Dependency injection is where you take the class you want to reference, and pass it into another class's constructor so it can reference it later, like so:
    Code:java
    1. public class Foo {
    2. private final Main plugin;
    3.  
    4. public Foo(Main plugin) {
    5. this.plugin = plugin;
    6. }
    7. }


    I personally prefer dependency injection. In this case, you may want to consider using it. To schedule the task in your kit class, you would use dependency injection to pass it the plugin, and then just use "plugin" instead of "Main.getInstance()".
     
  9. Offline

    TCO_007

    So the code should look like this now correct?
    Kit Taken Event:
    Code:java
    1. @ EventHandler
    2. public void onTakenClick(PlayerInteractEvent event) {
    3. Player p = (Player) event.getPlayer();
    4. if (plugin.Taken.contains(p.getName())){
    5. if (event.getAction() == Action.RIGHT_CLICK_AIR && p.getItemInHand().getType() == Material.IRON_INGOT) {
    6. List<Entity> nearby = p.getNearbyEntities(3, 20000, 3);
    7. for (Entity tmp : nearby)
    8. if (tmp instanceof Player) {
    9. tmp.teleport(p.getLocation());
    10. p.teleport(p.getLocation());
    11. p.sendMessage(ChatColor.GOLD + "You have teleported " + ((Player) tmp).getName() + " to you!");
    12.  
    13. }
    14. }
    15. }
    16.  
    17. }


    The map event:
    Code:java
    1. HashMap<String, Integer> map = new HashMap<String, Integer>();
    2.  
    3. public void addCooldown(String name, int time){
    4. map.put(name, time);
    5. }
    6.  
    7. public boolean hasCooldown(String name){
    8. return map.containsKey(name);
    9. }
    10.  
    11. public void removeOneSecond(String name){
    12. map.put(name, map.get(name) - 1);
    13. }
    14.  
    15. public int getSeconds(String name){
    16. if(map.containsKey(name)){
    17. return map.get(name);
    18. }else{
    19. return 0;
    20. }
    21. }
    22. public void startTask(){
    23. new BukkitRunnable(){
    24. public void run(){
    25. for(String entry : map.keySet()){
    26. removeOneSecond(entry);
    27. int amount = getSeconds(entry);
    28. if(amount <= 0){
    29. map.remove(entry);
    30. }
    31. }
    32. }
    33. }.runTaskTimer(plugin, 0, 20); //Runs every second, also. Im not 100% sure but this might cause a concurrent modification exception
    34. }
    35. }
    36.  
    37.  


    The main class:
    Code:java
    1. package me.TCOB055.MultiKits;
    2.  
    3. import java.util.ArrayList;
    4.  
    5. import org.bukkit.Bukkit;
    6. import org.bukkit.entity.Player;
    7. import org.bukkit.event.Listener;
    8. import org.bukkit.plugin.Plugin;
    9. import org.bukkit.plugin.PluginManager;
    10. import org.bukkit.plugin.java.JavaPlugin;
    11. import org.bukkit.scheduler.BukkitRunnable;
    12.  
    13. public class Main extends JavaPlugin {
    14. public GUIListener guilisten = new GUIListener(this);
    15. public Events Events = new Events(this);
    16. //array lists for kits
    17. ArrayList<String> PvP = new ArrayList<String>();
    18. ArrayList<String> Fisherman = new ArrayList<String>();
    19. ArrayList<String> kitused = new ArrayList<String>();
    20. ArrayList<String> venom = new ArrayList<String>();
    21. ArrayList<String> trampler = new ArrayList<String>();
    22. ArrayList<String> TearGhast = new ArrayList<String>();
    23. ArrayList<String> Archer = new ArrayList<String>();
    24. ArrayList<String> Taken = new ArrayList<String>();
    25. ArrayList<String> Ninja = new ArrayList<String>();
    26. ArrayList<String> Caveman = new ArrayList<String>();
    27. ArrayList<String> Launcher = new ArrayList<String>();
    28. ArrayList<String> Reverser = new ArrayList<String>();
    29. //end of array lists
    30. public void onDisable(){
    31. instance = null;
    32. }
    33. public void onEnable() {
    34. commands();
    35. events();
    36. instance = this;
    37. }
    38.  
    39. public void commands(){
    40. getCommand("Fisherman").setExecutor(new Fisherman(this));
    41. getCommand("PvP").setExecutor(new PvP(this));
    42. getCommand("kit").setExecutor(new Kit(this));
    43. getCommand("Venom").setExecutor(new Venom(this));
    44. getCommand("Trampler").setExecutor(new Trampler(this));
    45. getCommand("tearghast").setExecutor(new TearGhast(this));
    46. getCommand("Archer").setExecutor(new Archer(this));
    47. getCommand("Taken").setExecutor(new Taken(this));
    48. getCommand("Ninja").setExecutor(new Ninja(this));
    49. getCommand("Caveman").setExecutor(new Caveman(this));
    50. getCommand("Launcher").setExecutor(new Launcher(this));
    51. getCommand("Reverser").setExecutor(new Reverser(this));
    52. }
    53.  
    54. public void events(){
    55. PluginManager pm = getServer().getPluginManager();
    56. pm.registerEvents(Events, this);
    57. pm.registerEvents(guilisten, this);
    58.  
    59. }
    60.  
    61. private static Main instance;
    62.  
    63. public static Main getInstance() {
    64. return instance;
    65. }
    66. }
    67.  
    68.  

    coasterman10
     
  10. Offline

    xTigerRebornx

    coasterman10 When I used the term "List", was referring to any sort of List or Collection, not just a List.
     
  11. Offline

    TCO_007

    I am still not seeing though where the code actually puts the player into the cooldown because its not with the code of the Taken kit and that EventHandler doesnt have anything in it that references to it. Does the kit (after teleporting them) even add them to the cooldown?
     
  12. Offline

    coasterman10

    Well it seems you have managed to mix up dependency injection and the singleton. Seeing as you have implemented the singleton correctly in your main class, replace "plugin" with "Main.getInstance()" in your event class.

    As for making the cooldown actually happen, that is up to you to determine the logic. If the code isn't there, add it.
     
  13. Offline

    TCO_007

    Well, Im just confused now because I thought that Hashmap was all I needed but seeing as Its not, would I just add the player to the Hashmap "map"?
    Like map.add(p.getName())?
    Thats how I have done it with ArrayLists but they are not quite the same thing so Im a little stuck on that part. So this code should be correct now though correct? I changed the plugin to Main.getInstance();
    Code:java
    1. HashMap<String, Integer> map = new HashMap<String, Integer>();
    2.  
    3. public void addCooldown(String name, int time){
    4. map.put(name, time);
    5. }
    6.  
    7. public boolean hasCooldown(String name){
    8. return map.containsKey(name);
    9. }
    10.  
    11. public void removeOneSecond(String name){
    12. map.put(name, map.get(name) - 1);
    13. }
    14.  
    15. public int getSeconds(String name){
    16. if(map.containsKey(name)){
    17. return map.get(name);
    18. }else{
    19. return 0;
    20. }
    21. }
    22. public void startTask(){
    23. new BukkitRunnable(){
    24. public void run(){
    25. for(String entry : map.keySet()){
    26. removeOneSecond(entry);
    27. int amount = getSeconds(entry);
    28. if(amount <= 0){
    29. map.remove(entry);
    30. }
    31. }
    32. }
    33. }.runTaskTimer(Main.getInstance(), 0, 20); //Runs every second, also. Im not 100% sure but this might cause a concurrent modification exception
    34. }
    35. }

    coasterman10
     
  14. Offline

    coasterman10

    TCO_007 Maps use key/value pairs, so you would use map.add(key, value), like you have in your code.
     
Thread Status:
Not open for further replies.

Share This Page