I was trying to make a Minecraft plugin while having this problem, but I thought this would be more of a Java discussion
So I tried to make a spawner that would spawn a chicken every second (for testing, it would become every minute when I’m done), but while I was testing the event doesn’t seem to run (because TimeUnit.SECONDS.sleep()
would block the MC thread). So may I have an alternative?
The delay I’m using as for now is TimeUnit.SECONDS.sleep(*insert some number here*);
As shown here:
Note: I already tried using setTaskTimer
and scheduleSyncRepeatingTask
as shown in the answers, but they didn’t seem to work. Is this an event issue or a spawnEntity
issue?
package com.TheRealBee.Bows.Event10; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.EntityType; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockPlaceEvent; import java.util.concurrent.TimeUnit; public class EventManager10 implements Listener { @EventHandler public void onNukePlace(BlockPlaceEvent e){ // Return if it's not TNT, doesn't have ItemMeta or doesn't have a custom dispaly name if(!e.getBlock().getType().equals(Material.GOLD_BLOCK) || !e.getItemInHand().hasItemMeta() || !e.getItemInHand().getItemMeta().hasDisplayName()) return; // Return if the item display name is not correct if(!e.getItemInHand().getItemMeta().getDisplayName().equals(ChatColor.WHITE+"Spawner")) return; // Create the explosion try { for (int i = 0; i < 300000000; i++) { e.getBlock().getLocation().getWorld().spawnEntity(e.getBlock().getLocation(), EntityType.CHICKEN); TimeUnit.SECONDS.sleep(1); } } catch(InterruptedException ex) { Thread.currentThread().interrupt(); } } }
Advertisement
Answer
You should use Bukkit.getScheduler().scheduleSyncRepeatingTask(...)
in place of that for loop and TimeUnit.SECONDS.sleep
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() { @Override public void run() { e.getBlock().getLocation().getWorld().spawnEntity(e.getBlock().getLocation(), EntityType.CHICKEN); } }, 0L, 20L)
plugin
should be the instance of your plugin
0L
is the delay (in ticks) before the first task is run
20L
is the delay (in ticks) before the next task is run
scheduleSyncRepeatingTask in the Spigot JavaDoc
As this is a spawner I assume you will want to stop spawning chickens when the block is broken. You can cancel a task using its taskID. The taskID is the integer that scheduleSyncRepeatingTask
returns. You should save this taskID because you can cancel the task later (when the block breaks). To cancel the task you can use cancelTask
:
Bukkit.getServer().getScheduler().cancelTask(taskID);
cancelTask in the Spigot JavaDoc
Save this taskID using for example a HashMap. When the block is place you should save the coordinates as key and the taskID as the value in the HashMap. When the block is broken (use the block break event) you should lookup the coordinates of the broken block in that HashMap. If the coordinates exist in the HashMap you should cancel the task and remove the entry from the HashMap.