Search code examples
javapluginsminecraftbukkit

Cannot spawn falling blocks in minecraft


So I'm trying to make SEA_LANTERN drop multiple sand underneath of itself when it's placed so I can keep my cannon filled with sand as it's firing here is my code

Main

package me.zavage.sandbot;

import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;

import me.zavage.sandbot.commands.SandBotCommand;
import me.zavage.sandbot.listeners.SandBotListener;

public class Main extends JavaPlugin {
    
    @Override
    public void onEnable() {
        new SandBotListener(this);
        new SandBotCommand(this);
        
    }

    public static Plugin getInstance() {
        return null;
    }

}

package me.zavage.sandbot.listeners;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.FallingBlock;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;

import me.zavage.sandbot.Main;

public class SandBotListener implements Listener {
    
    private BukkitTask task;
    private int keepToSpawn = 0;
    public SandBotListener(Main main) {

    }

    @EventHandler
    public void onPlaceSandbot(BlockPlaceEvent e) {
        Material spawnType = e.getBlockPlaced().getType(); // get placed block
        if(!spawnType.equals(Material.SEA_LANTERN)) // in your case, be sure it's sea lantern
            return;
        keepToSpawn = 5; // amount of spawned item
        Location loc = e.getBlock().getLocation(); // location where entity will spawn
        task = Bukkit.getScheduler().runTaskTimer(Main.getInstance(), () -> {
            // each 0.5s, we made spawn a falling block of given type
            run(loc, spawnType);
            if(keepToSpawn == 0)
                task.cancel();
            keepToSpawn--;
        }, 10, 10); // 10 ticks = 0.5 seconds
    }

    @SuppressWarnings("deprecation")
    private void run(Location loc, Material type) {
        FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, Material.SAND, (byte) 0);
        falling.setDropItem(true);
        falling.setVelocity(new Vector(0, -0.5, 0)); // set the velicoty of the block
    }
}

Edit: I updated the code including the main class as well Theres gotta be something I'm missing, but ive tried so many different things at this point


Solution

  • This is an example code that will make spawn 5 times a falling block to below :

    private BukkitTask task;
    private int keepToSpawn = 0;
    
    @EventHandler
    public void onPlaceSandbot(BlockPlaceEvent e) {
        Material spawnType = e.getBlockPlaced().getType(); // get placed block
        if(!spawnType.equals(Material.SEA_LANTERN)) // in your case, be sure it's sea lantern
            return;
        keepToSpawn = 5; // amount of spawned item
        Location loc = e.getBlock().getLocation(); // location where entity will spawn
        task = Bukkit.getScheduler().runTaskTimer(Main.getInstance(), () -> {
            // each 0.5s, we made spawn a falling block of given type
            run(loc, spawnType);
            if(keepToSpawn == 0)
                task.cancel();
            keepToSpawn--;
        }, 10, 10); // 10 ticks = 0.5 seconds
    }
    
    @SuppressWarnings("deprecation")
    private void run(Location loc, Material type) {
        FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, type, (byte) 0);
        falling.setDropItem(true);
        falling.setVelocity(new Vector(0, -0.5, 0)); // set the velicoty of the block
    }
    

    Don't use Bukkit.getWorld(e.getBlockPlaced().getLocation().getWorld().getUID()), you already have the world instance with e.getBlockPlaced().getWorld().

    For the Vector used as velocity, you should set the direction of the block. I set negative Y to make it fall (and not x/z to make it keep at his block).

    PS: Don't forget to register the listener with this code in your onEnable:

    getServer().getPluginManager().registerEvents(new SandBotListener(this), this);
    

    For the instance of your plugin, you have to have an instance of the object "Main" which is represented by "this".

    To use it, in your Main.java :

    private static Main instance; // create variable that is "static".
    // It means it not depend to an object to get it
    public static Main getInstance() { // get the object instance, so the plugin instance
       return instance;
    }
    
    @Override
    public void onEnable() {
       instance = this; // here set the instance of this, so as the current object
     // it will make this object available for everyone
       getServer().getPluginManager().registerEvents(new SandBotListener(), this);
    }
    

    Then, you can remove the constructor of the SandBotListener.java.

    Now, you able to use Main.getInstance().