fix(chunkloader): deliver anchor directly to inventory on break and protect against accidental interaction

This commit is contained in:
Marcos Paulo
2026-08-20 10:01:59 -03:00
parent 24ab63b9be
commit d93711e5c1
@@ -1,7 +1,8 @@
package dev.marcospaulo.canalhandia; package dev.marcospaulo.canalhandia;
import net.kyori.adventure.text.Component; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle; import org.bukkit.Particle;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@@ -9,14 +10,18 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockExplodeEvent; import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map;
/** /**
* Protects and handles block placement, removal, and explosions for Chunk Anchors. * Protects and handles block placement, removal, and explosions for Chunk Anchors.
@@ -92,7 +97,7 @@ final class ChunkLoaderListener implements Listener {
+ (current + 1) + "/" + limitStr + ")."); + (current + 1) + "/" + limitStr + ").");
} }
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event) { public void onBlockBreak(BlockBreakEvent event) {
Block block = event.getBlock(); Block block = event.getBlock();
ChunkLoader loader = plugin.chunkLoaders().byLocation( ChunkLoader loader = plugin.chunkLoaders().byLocation(
@@ -118,16 +123,46 @@ final class ChunkLoaderListener implements Listener {
plugin.chunkLoaders().remove(loader.id()); plugin.chunkLoaders().remove(loader.id());
event.setDropItems(false); event.setDropItems(false);
event.setExpToDrop(0);
if (player.getGameMode() != GameMode.CREATIVE) {
Map<Integer, ItemStack> overflow = player.getInventory().addItem(ChunkAnchorItem.create(plugin, 1));
for (ItemStack drop : overflow.values()) {
player.getWorld().dropItemNaturally(player.getLocation(), drop);
}
}
Location loc = block.getLocation();
try { try {
loc.getWorld().dropItemNaturally(loc, ChunkAnchorItem.create(plugin, 1)); var loc = block.getLocation().add(0.5, 0.5, 0.5);
loc.getWorld().playSound(loc, Sound.BLOCK_RESPAWN_ANCHOR_DEPLETE, 1.0f, 0.8f); loc.getWorld().playSound(loc, Sound.BLOCK_RESPAWN_ANCHOR_DEPLETE, 1.0f, 0.8f);
} catch (Exception ignored) { } catch (Exception ignored) {
} }
plugin.blueMap().syncChunkLoaders(); plugin.blueMap().syncChunkLoaders();
Msg.ok(player, "Âncora de Chunk #" + loader.id() + " desativada e recolhida."); Msg.ok(player, "Âncora de Chunk #" + loader.id() + " desativada e recolhida para o seu inventário.");
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
}
Block block = event.getClickedBlock();
if (block == null || block.getType() != Material.RESPAWN_ANCHOR) {
return;
}
ChunkLoader loader = plugin.chunkLoaders().byLocation(
block.getWorld().getName(),
block.getX(),
block.getY(),
block.getZ()
);
if (loader != null) {
// Prevent respawn anchor exploding or depleting charges when used as chunk loader
event.setCancelled(true);
Player player = event.getPlayer();
Msg.ok(player, "Âncora de Chunk #" + loader.id() + " (" + loader.ownerName() + ") está ativa.");
}
} }
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)