Question

Ok so, I have a method here that when the Entity hits the ground it saves the Location and the Block inside of a HashMap defined like so:

public static HashMap<Location, Material> blocks = new HashMap<Location, Material>();

Then a few ticks later on the server it sets the block back to original type, rather than doing this at the moment its just turning into a null block.

@EventHandler
public void onProjecitle(ProjectileHitEvent event){
    if(event.getEntity().getType() == EntityType.ENDER_PEARL){
        Block block = event.getEntity().getLocation().getBlock();
        for (int z = -1; z <= 1; z++) {
            for (int x = -1; x <= 1; x++) {
                for (int y = -1; y <= 1; y++) {
                    final Location loc = block.getRelative(x, y, z).getLocation();
                    if(loc.getBlock().getType() != Material.AIR){
                        Aure.blocks.put(loc.getBlock().getLocation(), block.getType());
                        loc.getBlock().setType(Material.WOOL);
                        Bukkit.getScheduler().runTaskLater(plugin, new Runnable(){
                            @Override
                            public void run() {
                                loc.getBlock().setType(Aure.blocks.get(loc.getBlock().getLocation()));
                            }
                        }, 40L);
                    }
                }
            }
        }
    }
}
Was it helpful?

Solution

The problem about your code is that you get the block the player's feet are in, so its Material is obviously Material.AIR. You need to get the block below the player, so you should use

Location theRealBlock = event.getEntity().getLocation().substract(0.0D, 1.0D, 0.0D);

instead of

event.getEntity().getLocation();

OTHER TIPS

Try this:

Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable(){

instead of this:

Bukkit.getScheduler().runTaskLater(plugin, new Runnable(){

runTaskLater is actually scheduling an Asynchronous task, you should try to always use Synchronous tasks.

The problem with using Asynchronous tasks with Bukkit is your task will be scheduled on another thread, not being in sync with the normal server. Making it so that any Bukkit code that you use is VERY unsafe, so, as a general rule of thumb, whenever you're dealing with Bukkit, you should always use Synchronous tasks, which will be run on the same thread as your Main file. So, here's what your scheduled task should look like:

Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable(){
    public void run(){
        loc.getBlock().setType(Aure.blocks.get(loc)); //no need to use loc.getBlock().getLocation(), same thing as just using loc
    }
}, 40L);

Same rule applies when trying to create a repeating task, you should use scheduleSyncRepeatingTask.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top