Help Needed-Remembering inventory position

Discussion in 'Plugin Development' started by benthomas7777, Mar 22, 2014.

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

    benthomas7777

    In a my plugin i wish to add a block that when clicked will display a custom inventory. For example you place the block (in this case sponge), you click on the first piece of sponge and it opens an inventory that you put a diamond in. After that you can close it and walk to another sponge and click it, this will open another inventory that is blank (every time block the block is place, each one needs to have own inventory, like chest) you can the put a coal block in this one. If you go back to the first sponge it will have a diamond, if you then restart the server and click the second sponge it will have a coal block.

    I have no idea how to go about it as I have no experience with this sort of coding, so a lot of help is needed thanks.
     
  2. Offline

    benthomas7777

    Help Please
     
  3. Offline

    TwoPointDuck

    Inventory inv = Bukkit.createInventory(null, 27, "name");
    make the inventory you want with that.

    I dont quite know what you mean by what block they clicked.
    So, you gotta store all the blocks that you want in a HashMap<Block <- includes location, Inventory>>

    The code:

    Code:
    HashMap<Block, Inventory> inventories = new HashMap<Block, Inventory>();
        @EventHandler
        public void onEntityInteract(PlayerInteractEvent event){
            if(event.getAction() == Action.RIGHT_CLICK_BLOCK){
                for(Block b:inventories.keySet()){
                    if(b == event.getClickedBlock())event.getPlayer().openInventory(inventories.get(b));
                }
            }
        }
    Inventory always has to have multiple of 9 slots. So 9, 18, 27
     
    benthomas7777 likes this.
  4. Offline

    benthomas7777

    Basically every block of sponge on the map will have its on separate inventory
     
  5. Offline

    TwoPointDuck

    benthomas7777

    I get it. Do you need to save the inventory they have each time you wanna restart your server (stop, reload, restart)?.

    To add new inventories if there is none in the sponge yet do:

    Code:
    HashMap<Block, Inventory> inventories = new HashMap<Block, Inventory>();
        @EventHandler
        public void onEntityInteract(PlayerInteractEvent event){
            if(event.getAction() == Action.RIGHT_CLICK_BLOCK){
                for(Block b:inventories.keySet()){
                    if(b == event.getClickedBlock())event.getPlayer().openInventory(inventories.get(b));
                    else{Inventory i = Bukkit.createInventory(null, 27, "name of inventory");inventories.put(b, i);}
                }
            }
        }
     
  6. Offline

    benthomas7777

    Yes, I need it to save. It's basically like a normal chest, except with another block so later on I can edit it
     
  7. Offline

    TwoPointDuck

    Ugh, I don't know an efficient way to tell you how to do this. You should look up bukkit tutorials on files first, it's quite alot. Too much to cram into a forum reply, sorry.
     
    benthomas7777 likes this.
  8. Offline

    benthomas7777

    I've tried making your code into a basic plugin to test, but when I right click a block nothing happens, I believe I have found how to do the saving though, just need to get this sorted

    package me.benthomas7777.ic2;
    import java.util.HashMap;
    import java.util.logging.Logger;
    import org.bukkit.Bukkit;
    import org.bukkit.block.Block;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.plugin.java.JavaPlugin;
    public class Main extends JavaPlugin implements Listener {
    public final Logger logger = Logger.getLogger("Minecraft");

    public void onEnable() {
    getServer().getPluginManager().registerEvents(this, this);
    this.logger.info("This is Beta Version");
    }

    HashMap<Block, Inventory> inventories = new HashMap<Block, Inventory>();
    @EventHandler
    public void onEntityInteract(PlayerInteractEvent event){
    if(event.getAction() == Action.RIGHT_CLICK_BLOCK){
    for(Block b:inventories.keySet()){
    if(b == event.getClickedBlock())event.getPlayer().openInventory(inventories.get(b));
    else{Inventory i = Bukkit.createInventory(null, 27, "Custom Inv");inventories.put(b, i);}
    }
    }
    }


    }
     
  9. Offline

    TwoPointDuck

    benthomas7777

    Since this is your Main class, you gotta put the: = new HashMap<Block, Inventory>(); into the on enable

    it should look like this:

    HashMap<Block, Inventory> inventories;

    @Override
    public void onEnable(){
    getServer().getPluginManager().registerevents(this, this);
    this.logger.info("This is actually more like an Alpha Version");
    }

    @EventHandler
    public void onEntityInteract(PlayerInteractEvent event{
    if(event.getAction() == Action.RIGHT_CLICK_BLOCK{
    for(Block b:inventories.keySet()){
    if(b ==event.getClickedBlock())event.getPlayer().openInventory(inventories.get(b));
    else{Inventory i = Bukkit.createInventory(null, 27, "Custom Inv");inventories.put(b, i);
    event.getPlayer().openInventory(i); <<<< you forgot to open the inventory too.
    }
     
  10. Offline

    Maurdekye

    benthomas7777 TwoPointDuck I recently made a very similar plugin; you can get around this by psuedo-saving the inventories to a config file. To help explain my method, I'll define two variables necessary for saving a psuedo-inventory; an Inventory, and the location of that inventory;
    Code:java
    1. Block block = /*Block with inventory associated with it*/;
    2. Inventory inv = /*Inventory associated with the above block*/;

    You end up having to save the location of the block as the key and the inventory itself as a value. This becomes interesting when you realize that Locations can't be keys for values in config files; only Strings can. So you have to make them strings. You can do this by stringing out the minimal information, by using only the xyz and worldname, as such;
    Code:java
    1. String keystring = block.getBlockX() + "|" + block.getBlockY() + "|" + block.getBlockZ() + "|" + block.getWorld().getName();

    This has all the necessary information for the block's location in it, while being a string. This allows us to save it as a key. Now, we need to save the inventory as the value.

    Inventories aren't serializeable, which means they can't be saved directly to a config file like some other objects. Fortunately for us, ItemStacks are serializeable. And Inventories are basically just Arrays of ItemStacks, which you can also save to config files. So, we'll save our inventory as a list of ItemStacks. Fortunately for us, there's an easy convenience function for just this purpose;
    Code:java
    1. ItemStack[] value = inv.getContents();

    Now, we can save it to our config file;
    Code:java
    1. getConfig().set("sponges." + keystring, value);
    2. saveConfig();

    This process needs to be repeated for each inventory you want to save; say, looped over through a HashMap.

    If you want to get the information back out of the config file and into your program, you first need to store all the information from the config to a variable. You can start by fetching every key, and sorting out all the ones that reference inventories, like so;
    Code:java
    1. ArrayList<String> keys = new ArrayList<>();
    2. for (String key : getConfig().getKeys(true))
    3. if (key.beginsWith("sponges.")) keys.add(key.substring(0, 8));

    Then, we turn them into actual blocks by extracting the information from them, like so;
    Code:java
    1. ArrayList<Block> blocks = new ArrayList<>();
    2. for (String key : keys) {
    3. int[] vect = new int[3];
    4. String[] info = key.split("\\|");
    5. for (int i=0;i<3;i++)
    6. vect[i] = Integer.parseInt(info[i]);
    7. Location l = new Location(Bukkit.getWorld(info[3], vect[0], vect[1], vect[2]));
    8. blocks.add(l.getBlock());
    9. }[/i][/i]

    We then use their values to get their associated inventories;
    Code:java
    1. ArrayList<Inventory> invs = new ArrayList<>();
    2. for (String key : keys) {
    3. List<?> list = getConfig().getList("sponges." + key);
    4. Inventory inv = Bukkit.createInventory(null, list.size());
    5. inv.setContents(list.toArray(new ItemStack[list.size()]));
    6. invs.add(inv);
    7. }

    And that should be about it.
     
Thread Status:
Not open for further replies.

Share This Page