Chest GUI's - Development Help/Request

Discussion in 'Plugin Development' started by iPlazzy, Apr 25, 2015.

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

    iPlazzy

    NOTICE: I update the OP every other hour or so with new code at the bottom(unless it is in direct reply to someone), to keep from spamming the thread list. If you're interested, check the OP every now and then to see what's been done so far.


    Show Spoiler
    Hi. So, I've only just begun my attempts at learning to create plugins in Bukkit yesterday... But, I'm a fast learner and I hope I'll be able to get something nice done -- with a lot of help...

    Also, I don't really intend on this being a publicly available plugin, more for personal use and practice. But I'm open to it, if you are!


    Here's what I'm trying to get this plugin to do:

    1.) Make skulls act as chests. When you shift + right click them, they open a chest GUI.
    *The GUI doesn't open from a skull item when held, but instead from when it is placed and interacted with.
    *The contents whether added or removed from by players would have to be saved, so it acts like... Well, a chest, to store things in.
    That's pretty much the main desired aim, everything that follows is more of a preference.​

    2.) Spawn a skull on player death. So, when a player dies their own player head would be spawned on the block that they died on containing the contents of their inventory. They would respawn with nothing, but whatever they had previously would be stored in their player head when they died.
    *When a player shift + right clicks the players skull, from whomever died, they open the chest GUI from the skull containing any items saved within.​

    3.) Create two GUI variants for skulls, both of which have differing inventory sizes. One type of skull would have 9 available slots to use, and the other would have 56 amount of inventory slots.
    *Default Skull: This would be any mob head, but more specifically a default player head(Steve skull?). Any skull that IS NOT a unique player head when right-clicked will open an inventory GUI containing only 9 slots.
    *Unique Skull: This would only classify as UNIQUE player heads, as in any skull that is specific to a player, and would display a total of 36 slots when opened.​

    Why is this significant? Well, it's significant because the server I "operate" on uses the Conquest Resourcepack as its official resource pack. In Conquest, the Steve skull is textured to look like a small chest. The link will refer you to a screenshot I took of a normal chest and three Steve skulls beside it.

    My goal is to allow Steve skulls, which look like small chests, act like a strongbox of sorts like seen in Skyrim. Because of how small it is, it cannot store more than 9 item stacks total. But since it's small it can be "hidden" better, which makes it kind of like a strongbox for valuables.

    And the other skulls? A unique player head is meant to act sort of like a corpse. When a player dies, their head is placed as if it was their corpse, with their possessions stored in said corpse. And so it would have 36 slots to properly save a player's total inventory.

    So that is why I wish there to be two different variants of the GUI.

    I'm aware of a lot of what I have to do in order to achieve this, however I don't know HOW to start doing that and that is where I need help.

    I know I need to use a listener so plugin knows when a player has shifted and right clicked a skull that has been placed. I know I need to be using a PlayerInteractEvent to enable the GUI. I'm pretty sure I need to use hash-maps to save contents being added or removed from individual skulls. I know I have to use a Location method or whatever to spawn a skull at a players' X, Y, Z when a player dies and it is picked up by the listeners.

    I have snippets of what code I believe I should be using, but putting things together is beyond me right now... So I need some help, if not more help than I intended.

    I'm not going to beat around the bush and say I know what I'm doing and I have a lot already done when I don't. I'll be checking this thread nearly 24/7 with the best replies I can give to those interested, and will try to provide as much information on both what I know and what I have so far as I can -- but in truth, I don't know what I'm doing... That's why I need help!

    Other Details:
    - Using CraftBukkit 1.7.10
    - Using Eclipse Java EE IDE Workbench
    - Using this post, this video, this other video, and some other stuff as a reference point.
    I'll update this list regularly for those reading.

    Thanks for reading.

    _____________________________________________


    Here's what I have so far. I've reorganized everything a second time, and basically started a new package/class to work with.

    What I need to do is make the skulls inventories unique to the location that they are interacted with at, because they currently behave like EnderChests -- a player can open any skull anywhere and it will contain the same items as a skull that they used elsewhere.

    Also, contents added to a skull that have meta info/enchants are reset when a player logs out, or the server reloads/restarts. Can anyone explain to me how I may retrieve the saved contents WITH meta information, durability, etc?


    And then I need to remake a class that places a skull at the location of a player's death with that player's inventory stored in the skull(instead of dropping the items physically).

    Code:
    package com.acheronrp.main;
    
    import java.util.HashMap;
    import java.util.Map.Entry;
    import java.util.UUID;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.configuration.ConfigurationSection;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.inventory.InventoryType;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.event.player.PlayerQuitEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class AcheronMain extends JavaPlugin implements Listener {
    
        private HashMap<UUID, Inventory> strongbox = new HashMap<UUID, Inventory>();
    
        @EventHandler
        public void onPlayerJoin(PlayerJoinEvent e) {
            Inventory inv = Bukkit.getServer().createInventory(e.getPlayer(),
                    InventoryType.CHEST, ChatColor.BLACK + "Strongbox");
    
            if (getConfig().contains("Skull_Chest." + e.getPlayer().getUniqueId())) {
                for (String item : getConfig().getConfigurationSection(
                        "Skull_Chest." + e.getPlayer().getUniqueId()).getKeys(false)) {
                    inv.addItem(loadItem(getConfig()
                            .getConfigurationSection(
                                    "Skull_Chest." + e.getPlayer().getUniqueId()
                                            + "." + item)));
                }
            }
    
            strongbox.put(e.getPlayer().getUniqueId(), inv);
        }
    
        @EventHandler
        public void onPlayerLeave(PlayerQuitEvent e) {
            if (!getConfig().contains("Skull_Chest." + e.getPlayer().getUniqueId())) {
                getConfig().createSection(
                        "Skull_Chest." + e.getPlayer().getUniqueId());
            }
    
            char c = 'a';
            for (ItemStack itemStack : strongbox.get(e.getPlayer().getUniqueId())) {
                if (itemStack != null) {
                    saveItem(
                            getConfig().createSection(
                                    "Skull_Chest." + e.getPlayer().getUniqueId()
                                            + "." + c++), itemStack);
                }
            }
    
            saveConfig();
        }
    
        public void onEnable() {
            Bukkit.getServer().getPluginManager().registerEvents(this, this);
        }
    
        public void onDisable() {
            for (Entry<UUID, Inventory> entry : strongbox.entrySet()) {
                if (!getConfig().contains("Skull_Chest." + entry.getKey())) {
                    getConfig().createSection("Skull_Chest." + entry.getKey());
                }
    
                char c = 'a';
                for (ItemStack itemStack : entry.getValue()) {
                    if (itemStack != null) {
                        saveItem(
                                getConfig().createSection(
                                        "Skull_Chest." + entry.getKey() + "." + c++),
                                itemStack);
                    }
                }
    
                saveConfig();
            }
        }
    
        @Override
        public boolean onCommand(CommandSender sender, Command cmd,
                String commandLabel, String[] args) {
            if (!(sender instanceof Player)) {
                sender.sendMessage(ChatColor.RED
                        + "The console cannot have a strongbox.");
                return true;
            }
    
            Player p = (Player) sender;
    
            if (cmd.getName().equalsIgnoreCase("strongbox")) {
                p.openInventory(strongbox.get(p.getUniqueId()));
            }
    
            return true;
        }
    
        @EventHandler
        public void onRightClick(PlayerInteractEvent e) {
            Player player = e.getPlayer();
            Action a = e.getAction();
            Block block = e.getClickedBlock();
            if (a.equals(Action.RIGHT_CLICK_BLOCK))
                if (player.getItemInHand() != null)
                    if (block.getType() == Material.SKULL) {
                        player.openInventory(strongbox.get(player.getUniqueId()));
                    }
            return;
    
        }
    
        private void saveItem(ConfigurationSection section, ItemStack itemStack) {
            section.set("type", itemStack.getType().name());
            section.set("amount", itemStack.getAmount());
    
            section.set("meta", itemStack.getItemMeta());
            section.set("enchant", itemStack.getEnchantments());
            section.set("durability", itemStack.getDurability());
            // Can I even load the added information?
        }
    
        private ItemStack loadItem(ConfigurationSection section) {
            return new ItemStack(Material.valueOf(section.getString("type")),
                    section.getInt("amount"));
            // How do I load more information?
        }
    }
     
    Last edited: Apr 27, 2015
  2. Offline

    timtower Administrator Administrator Moderator

    Moved to plugin development
     
  3. player.openInventory(inv) to open the gui.
    And you can use the player MHF_CHEST which has a chest skin head
     
  4. Offline

    iPlazzy

    Edited the bottom of the OP with more information and new code on what I've done so far.
    Making solid progress, I guess, lol. I'm definitely learning though.
     
  5. @iPlazzy I can instantly see an error. You have 2 classes extending JavaPlugin. You should only have 1, the main class. That code wont work. Also you don't need messages on enable and disable, Bukkit does it for you!
     
  6. Offline

    iPlazzy

    Yeah, but they're in two separate projects right now as I was doing the chest spawn on death location part of the plugin first, separately. When I put the code from both together into a single project and package, I'll have the appropriate classes set up correctly(or at least I hope I will).


    EDIT: I reorganized all the class files like this, and they all work together currently. The Main class file generates an empty config.yml right now, but eventually I want it to save contents which are added or removed from the Skull GUI's.

    Can anyone explain to me in detail how I'm supposed to go about saving the contents of the skulls?

    In these screenshots, I'm first looking at a skull --> then I have right-clicked it, which opens this GUI --> but when I place any items into it, and then close it, and reopen the skull there's no contents in it.


    How should I create a config file which saves the locations and itemstacks of Skulls which have been interacted with, and whose contents have been edited?
     
    Last edited: Apr 26, 2015
Thread Status:
Not open for further replies.

Share This Page