Okay, what am I doing wrong here? Trying to break gravel as if dug when it falls on a torch

Discussion in 'Plugin Development' started by rooster5105, Apr 6, 2020.

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

    rooster5105

    Hey all, wow, my login still works!!!

    So here's the deal, I'm trying to unfix the gravel + torch != flint dealy jobby that Notch fixed forever ago.

    My plugin loads, but for whatever reason it's failing to snag the falling gravel block and replace/break it.

    Here's my code thus far:

    Code:
        ArrayList<Material> torches = new ArrayList<Material>(
                Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH));
        Logger logger;
        public void onEnable() {
            getServer().getPluginManager().registerEvents(this, this);
            logger = Logger.getLogger("Minecraft");
        }
    
        @SuppressWarnings("deprecation")
        @EventHandler
        public void onGravelTorch(EntityChangeBlockEvent event) {
            // return if not a falling block entity.
            if (event.getEntity().getType() != EntityType.FALLING_BLOCK) {
                return;
            }
            // k, now check if it's gravel
            FallingBlock fallingBlock = (FallingBlock) event.getEntity();
            if (fallingBlock.getMaterial() != Material.GRAVEL) {
                return;
            }
            // There now we know it's a falling block, and it's gravel.
            // check to see if there is a torch below:
            if (checkTorchBelow(fallingBlock.getLocation())) {
                // if'n there is, delete the falling block,
                // spawn a new gravel block at the current location,
                // then break it naturally.
                Location cur = fallingBlock.getLocation();
                fallingBlock.remove();
                cur.getBlock().setType(Material.GRAVEL);
                logger.info("derp");
                cur.getBlock().breakNaturally();
            }
        }
    
        private boolean checkTorchBelow(Location l) {
            Location belowLocation = new Location(l.getWorld(), l.getX(), l.getY() - 1, l.getZ());
            if (torches.contains(l.getWorld().getBlockAt(belowLocation).getType())) {
                logger.info("We didn't break it!");
                return true;
            }
            else {
                return false;
            }
        }
    }
    Could somebody point me in the right direction?
     
  2. Offline

    keyfqs

    The EntityChangeBlockEvent event is triggered only when the entity changes it, for example, endermen. Sorry if I'm wrong.
     
  3. Offline

    rooster5105

    So should I be checking on a block physics event?
     
  4. Offline

    rooster5105

    So after some trial and error, I see that the entityblockchangeevent is only called when the block starts to fall, and not when it changes back to a block. Further, it appears that the event is only called on the first tick, not after that.

    So I came up with a clever work around, I while loop down until I hit a torch or !air, or until 256 cycles have expired, as I know the maxWorldHeight() is 256. If I hit a torch I mark the location 1 block above it as the break location, now my problem is detecting entities within that one block.

    Here are the interesting bits of code:
    Checking for a torch underneath where the block is placed:
    Code:
    private boolean isTorchBeneath(World w, Location loc) {
            Location scanLoc = new Location(w, loc.getX(), loc.getBlockY(), loc.getZ());
            do {
                // decrement scanLoc's Y value at the start of every run
                scanLoc.setY(scanLoc.getY() - 1);
                sendToConsole("Scanning Block: " + scanLoc.toVector() + " For Torches");
                Material scanType = scanLoc.getBlock().getType();
                if (scanType == Material.AIR) {
                    // don't care, skip
                    continue;
                } else if (scanType == Material.TORCH) {
                    sendToConsole("Torch Found At: " + scanLoc.toVector());
                    return true;
                } else
                    sendToConsole("No Torch Found");
                return false;
            } while (scanLoc.getY() > 0);
            return false;
        }
    And Here is where I return the coordinates of the torch:
    Code:
    // THIS IS MAGIC TO CLEAN UP MY CODE! NEVER EVER EVER CALL THIS WITHOUT CALLING
        // isTorchBeneath() BEFORE HAND!!!
        private Location findTorchLocation(World w, Location loc) {
            sendToConsole("Entered into Find Torch Location");
            Location scanLoc = new Location(w, loc.getX(), loc.getBlockY(), loc.getZ());
            Material scanType = w.getBlockAt(scanLoc).getType();
            do {
                // decrement scanLoc's Y value at the start of every run.
                scanLoc.setY(scanLoc.getY() - 1);
                scanType = scanLoc.getBlock().getType();
            }
            // we only care about finding Torches, and this should never run, if
            // isTorchBeneath has not been run.
            while (scanType != Material.TORCH);
    
            Location retLoc = new Location(w, scanLoc.getX(), scanLoc.getBlockY(), scanLoc.getZ());
            sendToConsole("Sending Location: " + retLoc.toVector() + " As a Torch!");
            return retLoc;
        }
    
    And here's the snippit I am having problems with. Trying to detect the falling entity and remove it results in a server crash, if I'm unlucky and a server hang if I've very very lucky:
    Code:
    
    Collection<Entity> fblist = world.getNearbyEntities(breakLoc, 1, 1, 1);
    if (fblist.isEmpty()) {
    sendToConsole("No Entities Found in bounding Box. Returning");
    return;
    }
    for (Entity ent : fblist) {
    sendToChat(ent.getUniqueId().toString());
    sendToChat("Ent Valid? " + ent.isValid());
    if (ent.isValid() ) {
    if (ent.getLocation().getBlockY() == breakLoc.getBlockY() + 1) {
    ent.remove();
    }
    } else {
    return;
    while (runs < world.getMaxHeight()) {
    
    Could really use some help or pointers on this.

    My full code can be found: here
     
    Last edited: Apr 8, 2020
Thread Status:
Not open for further replies.

Share This Page