Solved Make sand/gravel not fall

Discussion in 'Plugin Development' started by Leviticalpixel10, Jan 13, 2017.

Thread Status:
Not open for further replies.
  1. I have a block and a material of another block and if its sand, I want it to NOT fall, in case there isn't a block beneath it. I want to be able to stop it from falling, WITHOUT using a whole new event class. I've tried calling a BlockPhysicsEvent and setting it to cancelled with my block as the block, but it doesn't work. Heres what I have:
    Code:
    Block block = blocklist.get(t);
                    block.setType(matlist.get(t), false);
                    block.setData(datalist.get(t));
                    if (block.getType() == Material.SAND | block.getType() == Material.GRAVEL) {
                        //Idk what to do here
                    }
                    if (block instanceof Leaves)
                        ((Leaves) block).setDecayable(false);
    If you can do tell me / lead me to do this without making a new event class or registering new events that would be great.
     
  2. Offline

    ipodtouch0218

    Code:
    if block.getType() == Material.SAND
    e.setCancelled(true)
    Also, blocks store their Data and Material inside of them already. No need to save them separately.
     
  3. @ipodtouch0218 I'm dealing with explosions, which I think have the material changed to air. Here's exactly what I have (don't judge on my methods I'm not great at making things efficient):
    Code:
    public void onExplosion(EntityExplodeEvent event) {
            List<Block> blocklist = event.blockList();
            List<Material> matlist = new ArrayList<Material>();
            List<Byte> datalist = new ArrayList<Byte>();
            event.setYield(0);
            for (Block b : blocklist) {
                if (b.getType() != Material.TNT) {
                    matlist.add(b.getType());
                    datalist.add(b.getData());
                } else {
                    matlist.add(Material.AIR);
                    datalist.add((byte) 0);
                }
            }
            if (blocklist.size() == 0)
                return;
            new BukkitRunnable() {
                int t = 0;
    
                public void run() {
                    if (t >= matlist.size() - 1) {
                        for (Item item : event.getLocation().getWorld().getEntitiesByClass(Item.class)) {
                            if (item.getLocation().distance(event.getLocation()) >= 10)
                                continue;
                            item.teleport(new Location(item.getWorld(), 0, 0, 0));
                        }
                        this.cancel();
                    }
                    if (blocklist.get(t) == null)
                        return;
                    Block block = blocklist.get(t);
                    block.setType(matlist.get(t), false);
                    block.setData(datalist.get(t));
                    if (block.getType() == Material.SAND | block.getType() == Material.GRAVEL) {
                      //IDK
                    }
                    if (block instanceof Leaves)
                        ((Leaves) block).setDecayable(false);
                    t += 1;
                }
            }.runTaskTimer(ldsessions.plugin, 100, 5);
        }
     
  4. Offline

    TheEnderman

    If your making blocks regenerate add a tick to the method which respawns the blocks


    Sent from my iPhone using Tapatalk
     
  5. @TheEnderman what do you mean? It's in a bukkitrunnable with a 5 second delay and it runs every .25 seconds/5 ticks
     
  6. Offline

    TheEnderman

    Yes, but if the block is a block with physics have it wait extra time. Nest another scheduler or similar.
     
  7. Offline

    MrGriefer_

    Try using EntityChangeBlockEvent check the entity type, if its sand or gravel then cancel the event.
     
  8. @MrGriefer_ I said I'm trying to avoid using events/making new classes please read before you respond
    @TheEnderman I now have this:
    Code:
    public void onExplosion(EntityExplodeEvent event) {
            List<Block> blocklist = event.blockList();
            List<Material> matlist = new ArrayList<Material>();
            List<Byte> datalist = new ArrayList<Byte>();
            event.setYield(0);
            for (Block b : blocklist) {
                if (b.getType() != Material.TNT) {
                    matlist.add(b.getType());
                    datalist.add(b.getData());
                } else {
                    matlist.add(Material.AIR);
                    datalist.add((byte) 0);
                }
            }
            if (blocklist.size() == 0)
                return;
            new BukkitRunnable() {
                int t = 0;
    
                public void run() {
                    if (t >= matlist.size() - 1) {
                        for (Item item : event.getLocation().getWorld().getEntitiesByClass(Item.class)) {
                            if (item.getLocation().distance(event.getLocation()) >= 10)
                                continue;
                            item.teleport(new Location(item.getWorld(), 0, 0, 0));
                        }
                        this.cancel();
                    }
                    if (blocklist.get(t) == null)
                        return;
                    Block block = blocklist.get(t);
                    if (matlist.get(t) == Material.SAND | matlist.get(t) == Material.GRAVEL) {
                        if (block.getLocation().subtract(0, 1, 0).getBlock().getType() == Material.AIR) {
                            Bukkit.getScheduler().scheduleSyncDelayedTask(ldsessions.plugin, new BukkitRunnable() {
                                public void run() {
                                    block.setType(matlist.get(t), false);
                                    block.setData(datalist.get(t));
                                }
                            }, 100);
                        }
                    } else {
                        block.setType(matlist.get(t), false);
                        block.setData(datalist.get(t));
                        if (block instanceof Leaves)
                            ((Leaves) block).setDecayable(false);
                    }
                    t += 1;
                }
            }.runTaskTimer(ldsessions.plugin, 100, 2);
        }
    but it's just pauses everything before the sand is set as the material
     
  9. Offline

    TheEnderman

    What do you mean by pauses?

    This tutorial should help:
     
  10. @TheEnderman that doesn't really help because I'm trying to do one block at a time, and he's doing it all at once, so even if there is sand there will be a block under it :/
     
  11. Offline

    Zombie_Striker

    @Leviticalpixel10
    To regenerate blocks slowly, do as pogo did in the video and then add a Delayed Task around the regenerating block. Every time you create a delayed task, increase the delay.
     
  12. Offline

    TheEnderman

    Pick a random number between 1 and 100 and add it to each block respawn timer, if it has gravity/physics then add another 100 , so in 1-5 seconds (from start) non physics blocks will spawn and then from 5-10 secs from start physics blocks will spawn. So in 1-10 secs the blocks will regenerate.

    Put the whole method in a scheduler for a delay from explosion to regenerate sequence
     
Thread Status:
Not open for further replies.

Share This Page