Solved Set Orientation for blocks?

Discussion in 'Spigot Plugin Development' started by Globdom, Jul 22, 2021 at 1:04 AM.

  1. So I am developing a tool that replaces a copper block with its oxidized version. The issue I'm having is stairs and slabs are not keeping the orientation of the block it replaced. The "dir" and "blockFace" are attempts at getting the orientation, but every time I try to put it into the actual setting of the block I get a bit stuck. Let me know if I am going about this correctly, and if not, how I could do so. The code is below. Thank you in advance!

    v
    Code (Text):

    public class Listener implements org.bukkit.event.Listener {


        public HashMap<Material,Material> mats = new HashMap<>();




        @EventHandler
        public void onClick(PlayerInteractEvent event){



            if(event.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.SPONGE))
                if (event.getPlayer().getInventory().getItemInMainHand().getItemMeta().hasLore()){




                    Player player = (Player) event.getPlayer();

                    mats.put(Material.COPPER_BLOCK,Material.OXIDIZED_COPPER);
                    mats.put(Material.CUT_COPPER,Material.OXIDIZED_CUT_COPPER);
                    mats.put(Material.WAXED_CUT_COPPER,Material.WAXED_OXIDIZED_CUT_COPPER);
                    mats.put(Material.CUT_COPPER_SLAB,Material.OXIDIZED_CUT_COPPER_SLAB);
                    mats.put(Material.CUT_COPPER_STAIRS,Material.OXIDIZED_CUT_COPPER_STAIRS);
                    mats.put(Material.WAXED_COPPER_BLOCK,Material.WAXED_OXIDIZED_COPPER);
                    mats.put(Material.WAXED_CUT_COPPER_SLAB,Material.WAXED_OXIDIZED_CUT_COPPER_SLAB);
                    mats.put(Material.WAXED_CUT_COPPER_STAIRS,Material.WAXED_OXIDIZED_CUT_COPPER_STAIRS);

                    mats.put(Material.WEATHERED_COPPER,Material.OXIDIZED_COPPER);
                    mats.put(Material.WEATHERED_CUT_COPPER,Material.OXIDIZED_CUT_COPPER);
                    mats.put(Material.WAXED_WEATHERED_CUT_COPPER,Material.WAXED_OXIDIZED_CUT_COPPER);
                    mats.put(Material.WEATHERED_CUT_COPPER_SLAB,Material.OXIDIZED_CUT_COPPER_SLAB);
                    mats.put(Material.WEATHERED_CUT_COPPER_STAIRS,Material.OXIDIZED_CUT_COPPER_STAIRS);
                    mats.put(Material.WAXED_WEATHERED_COPPER,Material.WAXED_OXIDIZED_COPPER);
                    mats.put(Material.WAXED_WEATHERED_CUT_COPPER_SLAB,Material.WAXED_OXIDIZED_CUT_COPPER_SLAB);
                    mats.put(Material.WAXED_WEATHERED_CUT_COPPER_STAIRS,Material.WAXED_OXIDIZED_CUT_COPPER_STAIRS);

                    mats.put(Material.EXPOSED_COPPER,Material.OXIDIZED_COPPER);
                    mats.put(Material.EXPOSED_CUT_COPPER,Material.OXIDIZED_CUT_COPPER);
                    mats.put(Material.WAXED_EXPOSED_CUT_COPPER,Material.WAXED_OXIDIZED_CUT_COPPER);
                    mats.put(Material.EXPOSED_CUT_COPPER_SLAB,Material.OXIDIZED_CUT_COPPER_SLAB);
                    mats.put(Material.EXPOSED_CUT_COPPER_STAIRS,Material.OXIDIZED_CUT_COPPER_STAIRS);
                    mats.put(Material.WAXED_EXPOSED_COPPER,Material.WAXED_OXIDIZED_COPPER);
                    mats.put(Material.WAXED_EXPOSED_CUT_COPPER_SLAB,Material.WAXED_OXIDIZED_CUT_COPPER_SLAB);
                    mats.put(Material.WAXED_EXPOSED_CUT_COPPER_STAIRS,Material.WAXED_OXIDIZED_CUT_COPPER_STAIRS);




                    if (event.getAction() == Action.LEFT_CLICK_BLOCK){
                        if (mats.containsKey(event.getClickedBlock().getType())){

                            Directional dir = (Directional) event.getClickedBlock().getBlockData();
                            BlockFace blockFace = dir.getFacing();

                            event.getClickedBlock().setType(mats.get(event.getClickedBlock().getType()));





                        } else{

                            player.sendMessage(ChatColor.RED + "Invalid block type");
                        }


                    }

                }

        }

        @EventHandler
        public void onPlace(BlockPlaceEvent event){
            if(event.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.SPONGE))
                if (event.getPlayer().getInventory().getItemInMainHand().getItemMeta().hasLore()){

                    event.setCancelled(true);

                }



        }
        @EventHandler
        public void onBreak(BlockBreakEvent event){
            if(event.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.SPONGE))
                if (event.getPlayer().getInventory().getItemInMainHand().getItemMeta().hasLore()){

                    event.setCancelled(true);

                }

        }



    }
     
     
    #1 Globdom, Jul 22, 2021 at 1:04 AM
    Last edited: Jul 22, 2021 at 3:59 AM
  2. Did you try getting the state of the block? And after update material, update the state.
     
  3. I have definitely tried. Just not sure how to properly do it with my Hashmap code and such
     
  4. BlockFace blockFace;
    switch (direction) {
    case 0://East
    blockFace = BlockFace.WEST;
    break;
    case 1://South
    blockFace = BlockFace.NORTH;
    break;
    case 2://West
    blockFace = BlockFace.EAST;
    break;
    case 3://North
    blockFace = BlockFace.SOUTH;
    break;
    default:
    blockFace = BlockFace.DOWN;
    break;
    }
    BlockState state = material.getState();
    state.setData(new Material(blockFace));
    state.update();

    EDIT: direction is an integer and material is a Block
     
  5. When you noted that material is a block, were you referring to the "material.getState()" portion? It's giving me an error in the Blockstate state portion. I also tried using a lower and upper case "block" and "material" but it didn't seem to work either:

    Code (Text):
    if (event.getAction() == Action.LEFT_CLICK_BLOCK){
                        if (mats.containsKey(event.getClickedBlock().getType())){

                            BlockFace blockFace;
                            int direction = 0;
                            switch (direction) {
                                case 0://East
                                    blockFace = BlockFace.WEST;
                                    break;
                                case 1://South
                                    blockFace = BlockFace.NORTH;
                                    break;
                                case 2://West
                                    blockFace = BlockFace.EAST;
                                    break;
                                case 3://North
                                    blockFace = BlockFace.SOUTH;
                                    break;
                                default:
                                    blockFace = BlockFace.DOWN;
                                    break;
                            }

                            event.getClickedBlock().setType(mats.get(event.getClickedBlock().getType()));



                            BlockState state = Block.getState();
                            state.setData(new Block(blockFace));
                            state.update();


                        } else{

                            player.sendMessage(ChatColor.RED + "Invalid block type");
                        }
     
    #5 Globdom, Jul 22, 2021 at 4:06 PM
    Last edited: Jul 22, 2021 at 6:19 PM
  6. Since all you're doing is replacing the the normal for the oxidized version, they will have identical BlockDatas in terms of properties, such as facing, water-logging, attachment, etc. You can use that to your advantage.

    A possible solution would be turning the BlockData into its string representation, replacing the type for the oxidized version, constructing the BlockData back, and setting it to the block. It will be generalized enough to work with any type of copper block, and you won't have to worry about setting properties manually. The pseudo-code would look something like the following:
    Code (Java):
    Block block = /* your block */

    Material currentType = block.type
    Material targetType = /* value from your map */

    String dataString = block.blockData.asString
    String oxidizedDataString = dataString.replace(currentType.key.toString(), targetType.key.toString())

    block.setBlockData(server.createBlockData(oxidizedDataString))
     
    • Winner Winner x 1
  7. I was able to follow along up until “server.” Is there something I should be importing to get that portion working? Otherwise there’s an error
     
  8. It's an instance of Server. You can get it with Bukkit.getServer(), or just call Bukkit.createBlockData() directly for convenience.
     
  9. So I used your method, but it doesn't seem to change the block type. Let me know if I entered it in wrong:

    Code (Text):
     Block block = event.getClickedBlock();

                    if (event.getAction() == Action.LEFT_CLICK_BLOCK){
                        if (mats.containsKey(block.getType())){

                            Material currentType = block.getType();
                            Material targetType = mats.get(block.getType());

                            String dataString = block.getBlockData().getAsString();
                            String oxidizedDataString = dataString.replace(currentType.toString(), targetType.toString());


                            block.setType(mats.get(block.getType()));
                            block.setBlockData(Bukkit.createBlockData(oxidizedDataString));


                        }
     
     
  10. You're calling toString directly on the Material, instead of its key. Also, the BlockData already encapsulates all the information about the block, so, you don't need to set its type.
     
  11. It works! Thank you so much for all the help