Solved Make an Inventory with a skull per player

Discussion in 'Plugin Development' started by Robin Bi, May 27, 2014.

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

    Robin Bi

    Hey there!


    Currently i'm working on a reportmenu-plugin. By rightclicking on an item, an inventory shall open with a playerskull per player. By clicking on a player, he'll be reported but this is yet to come.
    So atm i've just made two classes.

    In this class i define the inventory and i have some methods to use it:
    Code:java
    1. public class Inv {
    2.  
    3.  
    4. public static Inventory reportMenu;
    5.  
    6. public static void createInventory() {
    7. double online = Bukkit.getServer().getOnlinePlayers().length;
    8. int felder = (int) Math.ceil(online / 9);
    9. reportMenu = Bukkit.createInventory(null, felder);
    10.  
    11. int counter = 0;
    12. for (Player op : Bukkit.getServer().getOnlinePlayers()) {
    13. ItemStack item = makeItem(op.getName());
    14. reportMenu.setItem(counter, item);
    15. counter++;
    16. }
    17. counter = 0;
    18.  
    19. }
    20.  
    21. public static ItemStack makeItem(String playerName) {
    22. ItemStack item = new ItemStack(Material.SKULL);
    23. ItemMeta im = item.getItemMeta();
    24. im.setDisplayName(playerName);
    25. item.setItemMeta(im);
    26. return item;
    27. }
    28.  
    29. public static void openInventory(Player player) {
    30. player.openInventory(reportMenu);
    31. }
    32. }



    And in the second one here i've just made a little command to try the inventory out:
    Code:java
    1. public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    2. if (label.equalsIgnoreCase("report")) {
    3. if (!(sender instanceof Player)) {
    4. sender.sendMessage(ChatColor.RED + "This command cannot be enetered in console.");
    5. return true;
    6. }
    7.  
    8. Player p = (Player) sender;
    9. Inv.openInventory(p);
    10. }
    11. return true;
    12. }



    But unfortunately i get this error when perfoming the command. Ingame i just get this nice lil "internal error occured" message.

    Main:53 is this:
    Code:java
    1. Inv.openInventory(p);

    And Inv:39 this:
    Code:java
    1. player.openInventory(reportMenu);


    So the bothes refer to an other method but i don't quite know where my mistake is at...



    Thanks for your help :3
     
  2. Offline

    HeadGam3z

    Just to be sure, is there a line 185 by any chance?
     
  3. Offline

    Robin Bi

    No, the longest class (the one with the command) is 60 lines long. HeadGam3z
     
  4. Offline

    HeadGam3z

    Where are you getting "Inv" from on line 53/9? Only place where I see that is the class name, but then again, I am on my phone lol
     
  5. Offline

    Robin Bi

    openInventory() is a method in the class called Inv, and it's static. ;) HeadGam3z
     
  6. Offline

    MCForger

    Robin Bi
    Make an object called ReportMenu and inside that have an open function where it fetches the inventory and such. I would not recommend using static calls like this.
    An example:
    Code:java
    1. ReportMenu menu = new ReportMenu(plugin);
    2. menu.open(player);
     
  7. Offline

    Robin Bi

    MCForger Well, i appreciate your advice, but it hasn't solved my problem.... Any ideas left?
     
  8. Offline

    MCForger

    Robin Bi
    Do you ever call the createInventory function??
     
    Robin Bi likes this.
  9. Offline

    mythbusterma

    The one problem I notice with this Is in the way Java does math, in your felder variable specifically. Try ciel ((double) online/9.0) for the correct result, because right now it can be zero if its less than 9 players online.
     
    Robin Bi likes this.
  10. Offline

    Robin Bi

    mythbusterma It should never be 0 because it ceils the value and doesn't floor it, should it?

    MCForger Yes, i didn't, nice point ^^

    I've now made this in my Inv-class:
    Code:java
    1. public class Inv {
    2.  
    3.  
    4. public Inventory reportMenu;
    5.  
    6. public void createInventory() {
    7. int felder = calcPlayers();
    8. reportMenu = Bukkit.createInventory(null, felder);
    9.  
    10. int counter = 0;
    11. for (Player op : Bukkit.getServer().getOnlinePlayers()) {
    12. ItemStack item = makeItem(op.getName());
    13. reportMenu.setItem(counter, item);
    14. counter++;
    15. }
    16. counter = 0;
    17.  
    18. }
    19.  
    20. public ItemStack makeItem(String playerName) {
    21. ItemStack item = new ItemStack(Material.SKULL);
    22. ItemMeta im = item.getItemMeta();
    23. im.setDisplayName(playerName);
    24. item.setItemMeta(im);
    25. return item;
    26. }
    27.  
    28. public void openInventory(Player player) {
    29. player.openInventory(reportMenu);
    30. }
    31.  
    32. public int calcPlayers() {
    33. double online = Bukkit.getServer().getOnlinePlayers().length;
    34. int felder = (int) (Math.ceil(online / 9) * 9);
    35.  
    36. if (felder < 9) felder = 9;
    37. return felder;
    38. }
    39. }


    So i've added something to prevent the inventory to be less than 9, as you said, mythbusterma.



    Thanks quite a bunch!

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

    mythbusterma

    Due to the way Java does math, an integer divided by an integer will give you a rounded (or floored maybe?) Integer. So lets say online players is 4, 4/9 is less than .5 and as such will evaluate to 0, which in your code, is then cast to a double, and then ceilinged, ceil (0) is still 0.

    TL;DR change to ciel((double)online / 9.0)
     
Thread Status:
Not open for further replies.

Share This Page