Solved Getting chest direction

Discussion in 'Plugin Help/Development/Requests' started by oceantheskatr, Apr 15, 2015.

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

    oceantheskatr

    Hi, today I need to get the direction of a chest. I'm making a plugin that stores the location of placed chests, and when the server starts up it will place them. This is because they are loot chests, and when a player closes one it will break (for now until the server restarts). I've gotten every part working and it places the chests, however I do not know how to get a chests metadata which handles the direction the chest faces so by default any placed chest will have the buckle thingy on it pointing north.

    I'm hoping that someone will be able to help me out! :)

    Thanks in advance.

    Here is my code in case it is needed:

    Code:
    package me.themineshack;
    
    import java.util.ArrayList;
    import java.util.List;
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockPlaceEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class MainClass extends JavaPlugin implements Listener {
    
        ArrayList<String> chests = new ArrayList<String>();
    
        @Override
        public void onEnable() {
            Bukkit.getServer().getPluginManager().registerEvents(this, this);
            List<String> chests = getConfig().getStringList("chests");
            for (String str : chests) {
                String[] words = str.split(",");
                //World wor;
                String aWorld = words[0];
                //World cWorld = wor.getWorld(aWorld);
                String aX = words[1];
                double aX1 = Double.parseDouble(aX);
                String aY = words[2];
                double aY1 = Double.parseDouble(aY);
                String aZ = words[3];
                double aZ1 = Double.parseDouble(aZ);
                Location chestLoc = new Location (Bukkit.getWorld(aWorld), aX1, aY1, aZ1);
                chestLoc.getBlock().setType(Material.CHEST);
            }
        }
    
        @Override
        public void onDisable() {
        }
    
        @EventHandler
        public void onBlockPlace(BlockPlaceEvent e) {
            Player player = e.getPlayer();
            ItemStack bih = e.getItemInHand();
            Block b = e.getBlock();
            String bLoc = b.getLocation().getWorld().getName() + "," + b.getType() /* I would put the metadata here */ + "," + b.getLocation().getBlockX() + "," + b.getLocation().getBlockY() + "," + b.getLocation().getBlockZ();
            if (b.getType() == Material.CHEST) {
                if (bih.getItemMeta().getDisplayName().contains("Loot Chest")) {
                    player.sendMessage("Loot Chest placed!");
                    chests.add(bLoc);
                    getConfig().set("chests", chests);
                    saveConfig();
                }
            }
        }
    
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        
            if (cmd.getName().equalsIgnoreCase("inv") && sender instanceof Player) {
                Player player = (Player) sender;
                if (args.length == 0) {
                    player.sendMessage(ChatColor.GOLD + "------ " + ChatColor.GREEN + "" + ChatColor.BOLD + "Item List" + ChatColor.GOLD + " ------");
                    player.sendMessage(ChatColor.GOLD + "- " + ChatColor.WHITE + "lootchest");
                }
            
                if (args.length == 1) {
                    if (args[0].equalsIgnoreCase("lootchest")) {
                        ItemStack item = new ItemStack(Material.CHEST);
                        ItemMeta meta = item.getItemMeta();
                        String color = "&6&lLoot Chest";
                        color = ChatColor.translateAlternateColorCodes('&', color);
                        meta.setDisplayName(color);
                        item.setItemMeta(meta);
                    
                        player.getInventory().addItem(item);
                        return true;
                    }
                }
                return true;
            }
            return false;
        }
    }
    @I Al Istannen Maybe you can shed some light?
     
    Last edited: Apr 15, 2015
  2. Offline

    I Al Istannen

    @oceantheskatr Sorry for late reply ;(
    Ok, you can cast the block, after checking if it is a chest to a Chest:
    Code:
    Chest chest = (Chest) block.getState();
    
    //then you can use:
    chest.getData()
    
    //example Output if you use .toString():
    CHEST<5> facing EAST
    
    So you can see, that 4 is WEST, 3 is SOUTH, 5 is EAST and 2 is NORTH

    You should be able to get the number with "chest.getData().getData()". It's deprecated, but i don't know any other method which does this.
     
    Last edited: Apr 15, 2015
  3. Offline

    oceantheskatr

    @I Al Istannen Awesome! Thanks for the reply! :) I was indeed able to grab the direction of the chest, however I have a few more questions that shouldn't be too hard for you.

    What format would I use to set that block as setType requires a Material.
    Currently it's chestLoc.getBlock().setType(Material.CHEST); and I'm not sure what to change it to.

    Am I supposed to store it as "CHEST<5>"? (5 being of course the getdata getdata)
     
  4. Offline

    I Al Istannen

    @oceantheskatr To place it use Material.CHEST. Then cast the State to Chest, as done above. And then set the data:
    Code:
    chest.setData(new MaterialData(Material.CHEST,(byte) yourData));
    To save it: it depends on how you save your chests. You can store it as what you want, as long as you know how to retrieve it.

    EDIT: Maybe a ConfigurationSection would be nice. That way you could save the location as key and the data as Value.
     
    Last edited: Apr 15, 2015
  5. Offline

    oceantheskatr

    I feel that I am quite close now, however just can't seem to get it. I've implemented getting the data and parsing the string that holds the direction to a byte.

    Here is my updated code:

    Code:
    package me.themineshack;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.block.Chest;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockPlaceEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.material.MaterialData;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.fusesource.jansi.Ansi;
    
    public class MainClass extends JavaPlugin implements Listener {
       
        ArrayList<String> chests = new ArrayList<String>();
       
        @Override
        public void onEnable() {
            Bukkit.getServer().getPluginManager().registerEvents(this, this);
            List<String> chests = getConfig().getStringList("chests");
            for (String str : chests) {
                String[] words = str.split(",");
                String aWorld = words[0];
                byte dir = Byte.parseByte(words[2]);
                String aX = words[3];
                double aX1 = Double.parseDouble(aX);
                String aY = words[4];
                double aY1 = Double.parseDouble(aY);
                String aZ = words[5];
                double aZ1 = Double.parseDouble(aZ);
                Location chestLoc = new Location (Bukkit.getWorld(aWorld), aX1, aY1, aZ1);
               
                if (chestLoc.getBlock().getType() != Material.CHEST) {
                    //Not sure what exactly to use here
                    //chestLoc.getBlock().setType(Material.CHEST);
                   
                } else {
                    getLogger().info(Ansi.ansi().fg(Ansi.Color.YELLOW) + "A chest was already at " + aX + "," + aY + "," + aZ + "!" + Ansi.ansi().fg(Ansi.Color.DEFAULT));
                }
            }
        }
       
        @Override
        public void onDisable() {
        }
       
        @EventHandler
        public void onBlockPlace(BlockPlaceEvent e) {
            Player player = e.getPlayer();
            ItemStack bih = e.getItemInHand();
            Block b = e.getBlock();
            Chest chest = (Chest) b.getState();
            String bLoc = b.getLocation().getWorld().getName() + "," + b.getType() + "," + chest.getData().getData() + "," + b.getLocation().getBlockX() + "," + b.getLocation().getBlockY() + "," + b.getLocation().getBlockZ();
            if (b.getType() == Material.CHEST) {
                if (bih.getItemMeta().getDisplayName().contains("Loot Chest")) {
                    player.sendMessage("Loot Chest placed!");
                    chests.add(bLoc);
                    getConfig().set("chests", chests);
                    saveConfig();
                }
            }
        }
    }
     
  6. Offline

    I Al Istannen

    @oceantheskatr That should do the trick. But more important is that you need to know why that works :)
    Code:
    if (chestLoc.getBlock().getType() != Material.CHEST) {
                    //set to chest
                    chestLoc.getBlock().setType(Material.CHEST);
                    //getting chest object from BlockState
                    Chest chest = (Chest) chestLoc.getBlock().getState();
                    //and now apply the byte        
                    chest.setData(new MaterialData(Material.CHEST,dir));
    
     
  7. Offline

    oceantheskatr

    @I Al Istannen Ahh I see! I haven't used BlockState things before. I'll definitely have to learn more about them, though I can understand what is going on in what you posted.
     
  8. Offline

    I Al Istannen

  9. Offline

    oceantheskatr

    Sadly it doesn't seem to be working properly, it still places the block facing north even though the number is set to 5 which is east.

    I also do not get any console errors.
     
  10. Offline

    I Al Istannen

    @oceantheskatr I will try it out, wait a sec ;)
    I did some more testing:
    Code:
    loc.getBlock().setData((byte) direction);
    
    seems to be enaugh
     
    Last edited: Apr 15, 2015
    oceantheskatr likes this.
  11. Offline

    oceantheskatr

    Alright! :D
     
  12. Offline

    I Al Istannen

    @oceantheskatr Blockstate seems to capture the state of the block and let you modify, for example its inventory (chest) but not the rotation of the block. That seems unlogical to me, but it looks like it isnt needed.
    (the more you know... xD)

    I edited my previous post.
     
    oceantheskatr likes this.
  13. Offline

    oceantheskatr

    IT DID IT! WOO!

    Thank you again, so much! :)
     
  14. Offline

    I Al Istannen

    @oceantheskatr No problem. Though i need to do some better testing before posting things here *cough* :D
     
  15. Offline

    oceantheskatr

Thread Status:
Not open for further replies.

Share This Page