Reputation: 37
I'm new to plugin development in Spigot and recently i had the idea to create an ambicious project (at least for me). I want to store all placed blocks into an ArrayList, the same with broken blocks, and when the player executes the command resetblocks, all broken blocks turn into their original material and the placed blocks turn into air, but for some reason it's not working. I'm almost sure that this is a scope problem and i'm not realizing it.
public class ResetBlocksCommand implements CommandExecutor, Listener {
List<Block> placedBlocks = new ArrayList<>();
List<Block> brokenBlocks = new ArrayList<>();
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (cmd.getName().equalsIgnoreCase("resetblocks")) {
for (Block block : placedBlocks) {
Material blockMaterial = block.getType();
blockMaterial = Material.AIR;
sleep(500);
}
for (Block block : brokenBlocks) {
Material blockMaterial = block.getType();
blockMaterial = blockMaterial;
sleep(500);
}
return true;
}
return true;
}
@EventHandler
public void blockPlaceEvent (BlockPlaceEvent event) {
Block block = event.getBlock();
Bukkit.getConsoleSender().sendMessage(block.getType().name());
placedBlocks.add(block);
}
@EventHandler
public void blockBrakeEvent (BlockBreakEvent event) {
Block block = event.getBlock();
Bukkit.getConsoleSender().sendMessage(block.getType().name());
brokenBlocks.add(block);
}
private void sleep(long milli) {
try {
Thread.sleep(milli);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
PS: The console is printing the broken and placed blocks.
Upvotes: 1
Views: 932
Reputation: 6307
It's been a long time since I have used spigot/bukkit, but I believe to change a block you need to use Block.setType(Material type);
rather than just changing the returned material blockMaterial = Material.AIR;
This should do the trick to change the type:
for (Block block : placedBlocks) {
block.setType(Material.AIR);
sleep(500);
}
To restore broken blocks you will have a different issue. When you use Block block = event.getBlock();
in your blockBrakeEvent
it is getting a reference to the current block which will get the current material before the block was broken, but once the event is passed through your plugin the server will then cause the break event to happen and the block material will become Material.AIR
. What you need to do to solve this is save both the block and the original material, for example:
//Create a list for the Block and the Material
List<Block> brokenBlocks = new ArrayList<>();
List<Material> brokenBlockMaterial = new ArrayList<>();
@EventHandler
public void blockBrakeEvent (BlockBreakEvent event) {
Block block = event.getBlock();
//Save both the block and the material to to the array
brokenBlocks.add(block);
brokenBlockMaterial.add(block.getType());
}
Then in your restore loop you need to reference to both the block and the material that have been saved:
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (cmd.getName().equalsIgnoreCase("resetblocks")) {
for (Block block : placedBlocks) {
block.setType(Material.AIR);
sleep(500);
}
//use a loop that iterates through both lists using an index
for (int i = 0; i < brokenBlocks.size(); i++)
{
//Reference to the brokenBlocks list to get the block
Block block = brokenBlocks.get(i);
//Then use the brokenBlockMaterial list to restore/set the material type
block.setType(brokenBlockMaterial.get(i));
sleep(500);
}
return true;
}
return true;
}
Note: What will happen when a player breaks a block and then places a block in the same spot more than once? You need to work out how your will process everything in the correct order. Just something to think about going forward.
Upvotes: 2