diff --git a/pom.xml b/pom.xml index ee97bdc7..8230492e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ nl.aurorion.blockregen BlockRegen - 3.5.8-b5 + 3.5.8-b6 BlockRegen diff --git a/src/main/java/nl/aurorion/blockregen/api/BlockRegenBlockBreakEvent.java b/src/main/java/nl/aurorion/blockregen/api/BlockRegenBlockBreakEvent.java new file mode 100644 index 00000000..b17d4bcb --- /dev/null +++ b/src/main/java/nl/aurorion/blockregen/api/BlockRegenBlockBreakEvent.java @@ -0,0 +1,29 @@ +package nl.aurorion.blockregen.api; + +import lombok.Getter; +import lombok.Setter; +import nl.aurorion.blockregen.system.preset.BlockPreset; +import org.bukkit.event.Cancellable; +import org.bukkit.event.block.BlockBreakEvent; + +/** + * Fired after the original BlockBreakEvent. + * Cancelling this event causes BlockRegen not to do any action after the block is broken. It does not cancel BlockBreakEvent itself. + */ +public class BlockRegenBlockBreakEvent extends BlockRegenBlockEvent implements Cancellable { + + /** + * Original BLockBreakEvent which caused BlockRegen to take action. + */ + @Getter + private final BlockBreakEvent blockBreakEvent; + + @Getter + @Setter + private boolean cancelled = false; + + public BlockRegenBlockBreakEvent(BlockBreakEvent blockBreakEvent, BlockPreset blockPreset) { + super(blockBreakEvent.getBlock(), blockPreset); + this.blockBreakEvent = blockBreakEvent; + } +} \ No newline at end of file diff --git a/src/main/java/nl/aurorion/blockregen/api/BlockRegenBlockEvent.java b/src/main/java/nl/aurorion/blockregen/api/BlockRegenBlockEvent.java new file mode 100644 index 00000000..946271a9 --- /dev/null +++ b/src/main/java/nl/aurorion/blockregen/api/BlockRegenBlockEvent.java @@ -0,0 +1,30 @@ +package nl.aurorion.blockregen.api; + +import lombok.Getter; +import nl.aurorion.blockregen.system.preset.BlockPreset; +import org.bukkit.block.Block; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockEvent; +import org.jetbrains.annotations.NotNull; + +/** + * Base class for Events regarding BlockRegenBlock actions. + */ +public class BlockRegenBlockEvent extends BlockEvent { + + private static final HandlerList HANDLERS = new HandlerList(); + + @Override + public @NotNull HandlerList getHandlers() { + return HANDLERS; + } + + @Getter + private final BlockPreset blockPreset; + + public BlockRegenBlockEvent(Block block, BlockPreset blockPreset) { + super(block); + this.blockPreset = blockPreset; + } +} \ No newline at end of file diff --git a/src/main/java/nl/aurorion/blockregen/api/BlockRegenBlockRegenerationEvent.java b/src/main/java/nl/aurorion/blockregen/api/BlockRegenBlockRegenerationEvent.java new file mode 100644 index 00000000..28b13b36 --- /dev/null +++ b/src/main/java/nl/aurorion/blockregen/api/BlockRegenBlockRegenerationEvent.java @@ -0,0 +1,42 @@ +package nl.aurorion.blockregen.api; + +import lombok.Getter; +import lombok.Setter; +import nl.aurorion.blockregen.system.RegenerationProcess; +import org.bukkit.Material; +import org.bukkit.event.Cancellable; + +/** + * Event fired before a block is regenerated. + * Cancelling this event causes the block not to regenerate into another, also deletes the regeneration process. + */ +public class BlockRegenBlockRegenerationEvent extends BlockRegenBlockEvent implements Cancellable { + + @Getter + @Setter + private boolean cancelled = false; + + /** + * Regeneration process responsible for this block. + */ + @Getter + private final RegenerationProcess regenerationProcess; + + public BlockRegenBlockRegenerationEvent(RegenerationProcess regenerationProcess) { + super(regenerationProcess.getBlock(), regenerationProcess.getPreset()); + this.regenerationProcess = regenerationProcess; + } + + + /* + * Shortcuts. + * */ + + public Material getRegenerateInto() { + return regenerationProcess.getRegenerateInto(); + } + + public void setRegenerateInto(Material material) { + regenerationProcess.setRegenerateInto(material); + } +} \ No newline at end of file diff --git a/src/main/java/nl/aurorion/blockregen/listeners/BlockBreak.java b/src/main/java/nl/aurorion/blockregen/listeners/BlockBreak.java index 03d091c3..651b9d03 100644 --- a/src/main/java/nl/aurorion/blockregen/listeners/BlockBreak.java +++ b/src/main/java/nl/aurorion/blockregen/listeners/BlockBreak.java @@ -10,11 +10,13 @@ import nl.aurorion.blockregen.BlockRegen; import nl.aurorion.blockregen.Message; import nl.aurorion.blockregen.Utils; +import nl.aurorion.blockregen.api.BlockRegenBlockBreakEvent; import nl.aurorion.blockregen.system.Getters; import nl.aurorion.blockregen.system.RegenerationProcess; import nl.aurorion.blockregen.system.preset.BlockPreset; import nl.aurorion.blockregen.system.preset.ExperienceDrop; import nl.aurorion.blockregen.system.preset.ItemDrop; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; @@ -197,6 +199,13 @@ private void process(RegenerationProcess process, BlockBreakEvent event) { return; } + // Event API + BlockRegenBlockBreakEvent blockRegenBlockBreakEvent = new BlockRegenBlockBreakEvent(event, preset); + Bukkit.getServer().getPluginManager().callEvent(blockRegenBlockBreakEvent); + + if (blockRegenBlockBreakEvent.isCancelled()) + return; + List drops = new ArrayList<>(); // Events --------------------------------------------------------------------------------------------- diff --git a/src/main/java/nl/aurorion/blockregen/system/RegenerationManager.java b/src/main/java/nl/aurorion/blockregen/system/RegenerationManager.java index c0518743..5c28f0ab 100644 --- a/src/main/java/nl/aurorion/blockregen/system/RegenerationManager.java +++ b/src/main/java/nl/aurorion/blockregen/system/RegenerationManager.java @@ -11,7 +11,6 @@ import org.bukkit.block.Block; import org.jetbrains.annotations.Nullable; -import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -23,12 +22,6 @@ import java.util.List; public class RegenerationManager { - // Periodical saving - // Reset all - - /* - * On disable, replace all blocks with their originals, so if the plugin gets removed, it will be like before. - * */ private final BlockRegen plugin; @@ -161,7 +154,6 @@ private void afterLoad() { Location location = simpleLocation.toLocation(); process.setBlock(location.getBlock()); - process.setBlockState(location.getBlock().getState()); BlockPreset preset = plugin.getPresetManager().getPreset(process.getPresetName()); diff --git a/src/main/java/nl/aurorion/blockregen/system/RegenerationProcess.java b/src/main/java/nl/aurorion/blockregen/system/RegenerationProcess.java index 8464a82b..2e7c78f0 100644 --- a/src/main/java/nl/aurorion/blockregen/system/RegenerationProcess.java +++ b/src/main/java/nl/aurorion/blockregen/system/RegenerationProcess.java @@ -1,41 +1,56 @@ package nl.aurorion.blockregen.system; import lombok.Data; +import lombok.Getter; +import lombok.Setter; import nl.aurorion.blockregen.BlockRegen; +import nl.aurorion.blockregen.api.BlockRegenBlockRegenerationEvent; import nl.aurorion.blockregen.system.preset.BlockPreset; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; @Data public class RegenerationProcess implements Runnable { private SimpleLocation simpleLocation; + @Getter private transient Block block; - private transient BlockState blockState; - + @Getter private Material originalMaterial; + @Getter private String regionName; + @Getter private String worldName; private String presetName; + @Getter private transient BlockPreset preset; + /** + * Holds the system time when the block should regenerate. + */ + @Getter private transient long regenerationTime; + @Getter private long timeLeft = -1; + @Getter + @Setter + private transient Material regenerateInto; + + private transient BukkitTask task; + public RegenerationProcess(Block block, BlockPreset preset) { this.block = block; this.preset = preset; this.presetName = preset.getName(); - this.blockState = block.getState(); this.originalMaterial = block.getType(); this.simpleLocation = new SimpleLocation(block.getLocation()); } @@ -53,28 +68,39 @@ public void start() { Material replaceMaterial = preset.getReplaceMaterial().get(); - new BukkitRunnable() { - @Override - public void run() { - block.setType(replaceMaterial); - BlockRegen.getInstance().consoleOutput.debug("Replaced block with " + replaceMaterial.toString()); - } - }.runTaskLater(BlockRegen.getInstance(), 2L); + Bukkit.getScheduler().runTask(BlockRegen.getInstance(), () -> block.setType(replaceMaterial)); + BlockRegen.getInstance().consoleOutput.debug("Replaced block with " + replaceMaterial.toString()); - Material regenerateInto = preset.getRegenMaterial().get(); + regenerateInto = preset.getRegenMaterial().get(); - if (regenerateInto != blockState.getType()) - blockState.setType(regenerateInto); + if (task != null) task.cancel(); - Bukkit.getScheduler().runTaskLater(BlockRegen.getInstance(), this, timeLeft / 50); + task = Bukkit.getScheduler().runTaskLaterAsynchronously(BlockRegen.getInstance(), this, timeLeft / 50); BlockRegen.getInstance().getConsoleOutput().debug("Started regeneration..."); } @Override public void run() { - blockState.update(true); + + task.cancel(); + task = null; + + BlockRegenBlockRegenerationEvent blockRegenBlockRegenEvent = new BlockRegenBlockRegenerationEvent(this); + Bukkit.getServer().getPluginManager().callEvent(blockRegenBlockRegenEvent); + BlockRegen.getInstance().getRegenerationManager().removeProcess(this); + if (blockRegenBlockRegenEvent.isCancelled()) + return; + + Bukkit.getScheduler().runTask(BlockRegen.getInstance(), () -> block.setType(regenerateInto)); BlockRegen.getInstance().getConsoleOutput().debug("Regenerated block " + originalMaterial); } + + public void updateTimeLeft(long timeLeft) { + this.timeLeft = timeLeft; + if (timeLeft > 0) + start(); + else run(); + } } \ No newline at end of file