How to make an ironblock work as a chest?

Discussion in 'Plugin Development' started by ice374, May 16, 2013.

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

    ice374

    how do i make iron blocks serve as chests?
     
  2. Offline

    JoTyler

    Umm give me a minute ill bring the code
     
  3. Offline

    chasechocolate

    I would create a HashMap<Block, Inventory> to save inventories and then listen for PlayerInteractEvent and check if they clicked on a block, then check if the HashMap contains the block, then open the inventory from the HashMap, otherwise (if it doesn't contain the inventory) create a new inventory and save it in the HashMap. Opening inventories can be done with player.openInventory(...).
     
  4. Offline

    ZeusAllMighty11

    I would create a HashMap like Chase said, but instead of Block being stored, store the location (serialized)
     
  5. Offline

    ice374

    chasechocolate & TheGreenGamerHD

    YES!
    This is the kind of stuff i want! Can you Please give me an example of how it would be saved and then loaded again when a player opens it
     
  6. Offline

    Deleted user

    I wouldn't use the Location to store it.. what happens when you pick up that block and move it?

    I would use MetaData.
     
  7. Offline

    Technius

    Eballer48 I'm pretty sure that movable blocks isn't what he wants. In vanilla, breaking a chest makes all the items pop out anyways.

    ice374
    You will need an "open chest" list:
    Code:
    ArrayList<InventoryView> open = new ArrayList<InventoryView>(); //A list of all currently open iron block chests
    
    To open chests, you can listen to PlayerInteractEvents. Check if the player clicks on a block, check if the block is a chest, and then open it for the player if the previous two conditions were met. After the chest is opened, add the InventoryView (returned from player.openInventory) to the open chest list.

    To save chests, listen to InventoryCloseEvents. Check if the event's InventoryView is on the open chest list. If it is, remove the InventoryView from the open chest list and save the chest's contents to whatever you're using.
     
  8. Offline

    ice374

    Technius
    O_O that all went in some side of my head and out the other
    I am afraid i am a bit of a retard and find it hard to understand stuff like that, i find commented code alot easier, its just the way i learn :)

    Technius chasechocolate TheGreenGamerHD

    this code produces an error but could it be addapted to make ironblocks server as chests like i want?

    Code:
    @EventHandler
    public void ChestSaves(PlayerInteractEvent event){
            Block b = event.getClickedBlock();
            Player p = event.getPlayer();
            if(b.getType()== Material.CHEST && p.getItemInHand().getType()== Material.BLAZE_ROD){
                ItemStack[] chest = ((Chest) b).getBlockInventory().getContents();
                config.addDefault("Chest", b.getLocation() + "," + chest);
                p.sendMessage(ChatColor.GREEN + "Chest stored!");9.        }10.    }
    
    that would be soo good if you could,ill follow you

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

    Technius

    ice374
    Something like this:
    Code:
    //Untested
     
    //List of open chests
    ArrayList<InventoryView> open = new ArrayList<InventoryView>();
    //Listen on the "highest" priority and ignore cancelled events
    [USER=90830436]EventHandler[/USER](priority = EventPriority.MONITOR, ignoreCancelled = true)
    public void chestOpen(PlayerInteractEvent event)
    {
        //Ignore the event is no block was clicked
        if(event.getAction() != Action.RIGHT_CLICK_BLOCK)return;
        Block b = event.getClickedBlock(); //Get the clicked block
     
        //Check if this block is a registered chest
        //Sorry, I can't provide anything here because I don't know how you do this
     
        //Create a new inventory
        Inventory inv = event.getPlayer().getServer().createInventory(null, InventoryType.CHEST);
     
        //List of items in the inventory
        //Sorry, you'll have to retrieve these yourself
        ItemStack[] items;
        for(ItemStack i:items)
        {
              //Ignore the item if it doesn't exist
              if(i == null || i.getType() == Material.AIR)continue;
              inv.addItem(i);
        }
        //Open the inventory for the player, and then add that InventoryView to the open list
        open.add(event.getPlayer().openInventory(inv));
    }
    //No need to listen to high priority here
    [USER=90830436]EventHandler[/USER]
    public void saveChest(InventoryCloseEvent event)
    {
        InventoryView view = event.getView();
        //Ignore the event if the InventoryView is not on the list
        if(!open.contains(view))return;
        //Get the inventory of the event
        Inventory inv = event.getInventory();
     
        //Save the inventory contents
        //Again, I can't do this for you as I am not sure how you will do this
    }
    
    That's as much as I can help you. I'm sure you can fill out the rest. :) One flaw with this is that multiple players opening the chests may duplicate items. You can fix this by only creating inventories when your plugin loads files and then adding those inventories to a list. You can then use those inventories instead of creating new ones on the open event.

    Edit: I can't type "@EventHandler" without something changing it :(
     
  10. Offline

    Comphenix

    An alternative solution (albeit crazy) solution is to instead place a normal chest, and then modify the block ID when it's transmitted to the client. That way, you get the appearance of a iron block, but the correct behavior of a chest - no duplications possible, and all the Bukkit events are invoked properly.

    Of course, this is not exactly an easy feat, and you will have to depend on ProtocolLib. After adding it to your project and setting "depend: [ProtocolLib]" in your plugin, you have to add these files to your project:
    https://gist.github.com/aadnk/5596971

    Then it's a very simple matter of initializing the block disguise when the plugin is enabled:
    Code:java
    1. public class ExampleMod extends JavaPlugin implements Listener {
    2. private BlockDisguiser disguiser;
    3.  
    4. [USER=90830440]Override[/USER]
    5. public void onEnable() {
    6. disguiser = new BlockDisguiser(this);
    7. }
    8.  
    9. [USER=90830440]Override[/USER]
    10. public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    11. Player player = (Player) sender;
    12.  
    13. // Create our "iron" chest
    14. disguiser.setTranslatedBlock(player.getLocation().add(0, 0, 1), Material.CHEST.getId(), Material.IRON_BLOCK.getId());
    15. return true;
    16. }
    17. }

    The disguise will be lost when the server or plugin reloads, but you can preserve them by calling disguiser,saveState(file) in onDisable() and disguiser.loadSave(file) in onEnable().
     
    TigerHix likes this.
  11. Offline

    JoTyler

    Nvm just follow everyone else.
     
  12. Offline

    topisani

    if i use this will bukkit see it as a chest or an ironblock? if i check what block a player right clicks will it return chest or iron block?

    thanks in advance
     
  13. Offline

    Comphenix

    Bukkit, and every installed plugin, will see it as a chest. The player will see it as an iron block that acts like a chest.
     
  14. Offline

    topisani

    so there is no way i can check if the player is opening a chest or an iron block?(besides giving it a name like "§I§r§o§n§c§h§e§s§t" and checking for that?)

    also if i used the world save somewhere else that didnt have the plugin would it be a chest? meaning that if i changed my server to vanilla for some reason the iron chests would be saved?

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

    Comphenix

    Of course there is! You know which blocks are iron "chests" because you are the one who create them. Just save their location somehow, or retrieve them from BlockDisguiser directly.

    It would show as a chest, yes, because the iron block is just a client side trick.

    They could be, but for them to survive a restart, you have to use saveState and loadState, and save them to a file.

    Basically, you have to try and read the source code and understand some of it. Especially the HashBasedTable bit. It's a workable example, but if you need more features you have to write them yourself.
     
  16. Offline

    topisani

    ok i think i understood it now thanks a lot :D
     
Thread Status:
Not open for further replies.

Share This Page