From 4fec146139ca8571b72ed3d430b4d3d52627209f Mon Sep 17 00:00:00 2001 From: axenodev Date: Tue, 8 Jul 2025 03:04:08 +0200 Subject: [PATCH 1/7] feat: add abstract hammer class and specific hammer implementations --- .../java/fr/openmc/core/ListenersManager.java | 3 +- .../core/items/usable/AbstractHammer.java | 109 ++++++++++++++++++ .../core/items/usable/CustomUsableItem.java | 8 ++ .../usable/CustomUsableItemRegistry.java | 7 +- .../items/usable/items/DiamondHammer.java | 17 +++ .../core/items/usable/items/IronHammer.java | 17 +++ .../items/usable/items/NetheriteHammer.java | 17 +++ .../core/listeners/BlockBreakListener.java | 28 +++++ .../fr/openmc/core/utils/HammerUtils.java | 4 + 9 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 src/main/java/fr/openmc/core/items/usable/AbstractHammer.java create mode 100644 src/main/java/fr/openmc/core/items/usable/items/DiamondHammer.java create mode 100644 src/main/java/fr/openmc/core/items/usable/items/IronHammer.java create mode 100644 src/main/java/fr/openmc/core/items/usable/items/NetheriteHammer.java create mode 100644 src/main/java/fr/openmc/core/listeners/BlockBreakListener.java create mode 100644 src/main/java/fr/openmc/core/utils/HammerUtils.java diff --git a/src/main/java/fr/openmc/core/ListenersManager.java b/src/main/java/fr/openmc/core/ListenersManager.java index 86b9fb3b4..14b3bd0a3 100644 --- a/src/main/java/fr/openmc/core/ListenersManager.java +++ b/src/main/java/fr/openmc/core/ListenersManager.java @@ -30,7 +30,8 @@ public ListenersManager() { new AsyncChatListener(OMCPlugin.getInstance()), new BossbarListener(), new PlayerSettingsManager(), - new InteractListener() + new InteractListener(), + new BlockBreakListener() ); } diff --git a/src/main/java/fr/openmc/core/items/usable/AbstractHammer.java b/src/main/java/fr/openmc/core/items/usable/AbstractHammer.java new file mode 100644 index 000000000..53807b15f --- /dev/null +++ b/src/main/java/fr/openmc/core/items/usable/AbstractHammer.java @@ -0,0 +1,109 @@ +package fr.openmc.core.items.usable; + +import fr.openmc.core.features.city.ProtectionsManager; +import org.bukkit.FluidCollisionMode; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.RayTraceResult; + +import java.util.Objects; + +public abstract class AbstractHammer extends CustomUsableItem { + + private final Material vanillaMaterial; + private final int radius; // ↔ et ↕ – demi‑largeur (1 ⇒ 3 blocs) + private final int depth; + + protected AbstractHammer(String namespacedId, + Material vanillaMaterial, + int radius, + int depth) { + super(namespacedId); + this.vanillaMaterial = vanillaMaterial; + this.radius = radius; + this.depth = depth; + } + + @Override + public ItemStack getVanilla() { + return ItemStack.of(vanillaMaterial); + } + + @Override + public void onBlockBreak(Player player, BlockBreakEvent event) { + if (player.getGameMode() != GameMode.SURVIVAL) + return; + + ItemStack tool = player.getInventory().getItemInMainHand(); + if (tool == null || tool.getType().isAir()) + return; + + Block broken = event.getBlock(); + BlockFace face = getDestroyedBlockFace(player).getOppositeFace(); + + breakArea(player, broken, face, tool, radius, depth); + } + + private static void breakArea(Player player, + Block origin, + BlockFace face, + ItemStack tool, + int radius, + int depth) { + + Material targetType = origin.getType(); + + for (int dx = -radius; dx <= radius; dx++) { + for (int dy = -radius; dy <= radius; dy++) { + for (int dz = -depth; dz <= depth; dz++) { + + int ox = 0, oy = 0, oz = 0; + switch (face) { + case NORTH: + case SOUTH: + ox = dx; oy = dy; oz = dz; + break; + case EAST: + case WEST: + ox = dz; oy = dy; oz = dx; + break; + case UP: + case DOWN: + ox = dx; oy = dz; oz = dy; + break; + default: + break; + } + + Block b = origin.getRelative(ox, oy, oz); + + if (Objects.equals(b, origin)) + continue; + if (!ProtectionsManager.canInteract(player, b.getLocation())) + continue; + if (b.getType() != targetType) + continue; + if (b.getType().getHardness() > 41) + continue; + + b.breakNaturally(tool); + } + } + } + } + + private static BlockFace getDestroyedBlockFace(Player player) { + Location eye = player.getEyeLocation(); + RayTraceResult result = eye.getWorld().rayTraceBlocks( + eye, eye.getDirection(), 10, FluidCollisionMode.NEVER); + return result != null && result.getHitBlockFace() != null + ? result.getHitBlockFace() + : BlockFace.SELF; + } +} diff --git a/src/main/java/fr/openmc/core/items/usable/CustomUsableItem.java b/src/main/java/fr/openmc/core/items/usable/CustomUsableItem.java index 6ca844875..fcba06f24 100644 --- a/src/main/java/fr/openmc/core/items/usable/CustomUsableItem.java +++ b/src/main/java/fr/openmc/core/items/usable/CustomUsableItem.java @@ -3,6 +3,7 @@ import fr.openmc.core.items.CustomItem; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.player.PlayerInteractEvent; public abstract class CustomUsableItem extends CustomItem { @@ -14,6 +15,7 @@ public abstract class CustomUsableItem extends CustomItem { */ public CustomUsableItem(String name) { super(name); + CustomUsableItemRegistry.register(this); } /** @@ -40,6 +42,8 @@ public void onLeftClick(Player player, PlayerInteractEvent event) {} */ public void onSneakClick(Player player, PlayerInteractEvent event) {} + public void onBlockBreak(Player player, BlockBreakEvent event) {} + /** * Handles the interaction with the item. * @@ -66,4 +70,8 @@ public final void handleInteraction(Player player, PlayerInteractEvent event) { } } + public final void handleBlockBreak(Player player, BlockBreakEvent event) { + onBlockBreak(player, event); + } + } diff --git a/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java b/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java index 587e28af3..5872059a5 100644 --- a/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java +++ b/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java @@ -1,6 +1,9 @@ package fr.openmc.core.items.usable; import dev.lone.itemsadder.api.CustomStack; +import fr.openmc.core.items.usable.items.DiamondHammer; +import fr.openmc.core.items.usable.items.IronHammer; +import fr.openmc.core.items.usable.items.NetheriteHammer; import org.bukkit.inventory.ItemStack; import java.util.HashMap; @@ -15,7 +18,9 @@ public class CustomUsableItemRegistry { * This constructor should be called once during server startup. */ public CustomUsableItemRegistry() { - // register here + new IronHammer(); + new DiamondHammer(); + new NetheriteHammer(); } /** diff --git a/src/main/java/fr/openmc/core/items/usable/items/DiamondHammer.java b/src/main/java/fr/openmc/core/items/usable/items/DiamondHammer.java new file mode 100644 index 000000000..2945043c2 --- /dev/null +++ b/src/main/java/fr/openmc/core/items/usable/items/DiamondHammer.java @@ -0,0 +1,17 @@ +package fr.openmc.core.items.usable.items; + +import fr.openmc.core.items.usable.AbstractHammer; +import org.bukkit.Material; + +public class DiamondHammer extends AbstractHammer { + + public DiamondHammer() { + super( + "omc_items:diamond_hammer", + Material.DIAMOND_PICKAXE, + 1, + 1 + ); + } + +} diff --git a/src/main/java/fr/openmc/core/items/usable/items/IronHammer.java b/src/main/java/fr/openmc/core/items/usable/items/IronHammer.java new file mode 100644 index 000000000..ac0c52515 --- /dev/null +++ b/src/main/java/fr/openmc/core/items/usable/items/IronHammer.java @@ -0,0 +1,17 @@ +package fr.openmc.core.items.usable.items; + +import fr.openmc.core.items.usable.AbstractHammer; +import org.bukkit.Material; + +public class IronHammer extends AbstractHammer { + + public IronHammer() { + super( + "omc_items:iron_hammer", + Material.IRON_PICKAXE, + 1, + 0 + ); + } + +} diff --git a/src/main/java/fr/openmc/core/items/usable/items/NetheriteHammer.java b/src/main/java/fr/openmc/core/items/usable/items/NetheriteHammer.java new file mode 100644 index 000000000..6c4ed7894 --- /dev/null +++ b/src/main/java/fr/openmc/core/items/usable/items/NetheriteHammer.java @@ -0,0 +1,17 @@ +package fr.openmc.core.items.usable.items; + +import fr.openmc.core.items.usable.AbstractHammer; +import org.bukkit.Material; + +public class NetheriteHammer extends AbstractHammer { + + public NetheriteHammer() { + super( + "omc_items:netherite_hammer", + Material.NETHERITE_PICKAXE, + 1, + 2 + ); + } + +} diff --git a/src/main/java/fr/openmc/core/listeners/BlockBreakListener.java b/src/main/java/fr/openmc/core/listeners/BlockBreakListener.java new file mode 100644 index 000000000..8acd5b898 --- /dev/null +++ b/src/main/java/fr/openmc/core/listeners/BlockBreakListener.java @@ -0,0 +1,28 @@ +package fr.openmc.core.listeners; + +import fr.openmc.core.features.city.ProtectionsManager; +import fr.openmc.core.items.usable.CustomUsableItem; +import fr.openmc.core.items.usable.CustomUsableItemRegistry; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.inventory.ItemStack; + +public class BlockBreakListener implements Listener { + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + if (event.isCancelled()) return; + if (event.getBlock() == null) return; + ProtectionsManager.verify(player, event, event.getBlock().getLocation()); + + ItemStack itemInHand = player.getInventory().getItemInMainHand(); + CustomUsableItem usableItem = CustomUsableItemRegistry.getByItemStack(itemInHand); + + if (usableItem != null) + usableItem.handleBlockBreak(player, event); + } + +} diff --git a/src/main/java/fr/openmc/core/utils/HammerUtils.java b/src/main/java/fr/openmc/core/utils/HammerUtils.java new file mode 100644 index 000000000..8be618882 --- /dev/null +++ b/src/main/java/fr/openmc/core/utils/HammerUtils.java @@ -0,0 +1,4 @@ +package fr.openmc.core.utils; + +public class HammerUtils { +} From 0f1f491a93a6271ab1d978446b119cba3ad1efe6 Mon Sep 17 00:00:00 2001 From: axenodev Date: Tue, 8 Jul 2025 03:05:21 +0200 Subject: [PATCH 2/7] removing unused class --- src/main/java/fr/openmc/core/utils/HammerUtils.java | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 src/main/java/fr/openmc/core/utils/HammerUtils.java diff --git a/src/main/java/fr/openmc/core/utils/HammerUtils.java b/src/main/java/fr/openmc/core/utils/HammerUtils.java deleted file mode 100644 index 8be618882..000000000 --- a/src/main/java/fr/openmc/core/utils/HammerUtils.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.openmc.core.utils; - -public class HammerUtils { -} From b2db6f10b1bb20f239a60570484e9edd260c3353 Mon Sep 17 00:00:00 2001 From: axenodev Date: Tue, 8 Jul 2025 21:21:24 +0200 Subject: [PATCH 3/7] feat: enhance AbstractHammer functionality with optimized block processing --- .../core/items/usable/AbstractHammer.java | 87 ++++++++++--------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/src/main/java/fr/openmc/core/items/usable/AbstractHammer.java b/src/main/java/fr/openmc/core/items/usable/AbstractHammer.java index 53807b15f..e42d8d6d6 100644 --- a/src/main/java/fr/openmc/core/items/usable/AbstractHammer.java +++ b/src/main/java/fr/openmc/core/items/usable/AbstractHammer.java @@ -1,10 +1,7 @@ package fr.openmc.core.items.usable; import fr.openmc.core.features.city.ProtectionsManager; -import org.bukkit.FluidCollisionMode; -import org.bukkit.GameMode; -import org.bukkit.Location; -import org.bukkit.Material; +import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; @@ -12,13 +9,12 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.util.RayTraceResult; -import java.util.Objects; - public abstract class AbstractHammer extends CustomUsableItem { private final Material vanillaMaterial; - private final int radius; // ↔ et ↕ – demi‑largeur (1 ⇒ 3 blocs) + private final int radius; private final int depth; + private static final float MAX_HARDNESS = 41.0f; protected AbstractHammer(String namespacedId, Material vanillaMaterial, @@ -58,46 +54,54 @@ private static void breakArea(Player player, int depth) { Material targetType = origin.getType(); + if (targetType.isAir()) return; + if (targetType.getHardness() > MAX_HARDNESS) return; + + World world = origin.getWorld(); + int baseX = origin.getX(); + int baseY = origin.getY(); + int baseZ = origin.getZ(); + + IntTriConsumer apply; + switch (face) { + case NORTH: + case SOUTH: + apply = (x, y, z) -> work(world, player, tool, baseX + x, baseY + y, baseZ + z, targetType); + break; + case EAST: + case WEST: + apply = (x,y,z) -> work(world, player, tool, baseX + z, baseY + y, baseZ + x, targetType); + break; + case UP: + case DOWN: + apply = (x, y, z) -> work(world, player, tool, baseX + x, baseY + z, baseZ + y, targetType); + break; + default: + return; + } for (int dx = -radius; dx <= radius; dx++) { for (int dy = -radius; dy <= radius; dy++) { - for (int dz = -depth; dz <= depth; dz++) { - - int ox = 0, oy = 0, oz = 0; - switch (face) { - case NORTH: - case SOUTH: - ox = dx; oy = dy; oz = dz; - break; - case EAST: - case WEST: - ox = dz; oy = dy; oz = dx; - break; - case UP: - case DOWN: - ox = dx; oy = dz; oz = dy; - break; - default: - break; - } - - Block b = origin.getRelative(ox, oy, oz); - - if (Objects.equals(b, origin)) - continue; - if (!ProtectionsManager.canInteract(player, b.getLocation())) - continue; - if (b.getType() != targetType) - continue; - if (b.getType().getHardness() > 41) - continue; - - b.breakNaturally(tool); + for (int dz = -depth; dz <= depth; dz++) { + if (dx == 0 && dy == 0 && dz == 0) continue; + apply.accept(dx, dy, dz); } } } } + private static void work(World world, + Player player, + ItemStack tool, + int x, int y, int z, + Material targetType) { + Block b = world.getBlockAt(x, y, z); + if (b.getType() != targetType) return; + if (b.getType().getHardness() > MAX_HARDNESS) return; + if (!ProtectionsManager.canInteract(player, b.getLocation())) return; + b.breakNaturally(tool); + } + private static BlockFace getDestroyedBlockFace(Player player) { Location eye = player.getEyeLocation(); RayTraceResult result = eye.getWorld().rayTraceBlocks( @@ -106,4 +110,9 @@ private static BlockFace getDestroyedBlockFace(Player player) { ? result.getHitBlockFace() : BlockFace.SELF; } + + @FunctionalInterface + private interface IntTriConsumer { + void accept(int x, int y, int z); + } } From d0c92cd8b1563639b1d4e3c370a88b4367731635 Mon Sep 17 00:00:00 2001 From: axenodev Date: Sun, 28 Dec 2025 18:57:47 +0100 Subject: [PATCH 4/7] feat: refactor hammer classes and update item registry initialization --- .../items/usable/CustomUsableItemRegistry.java | 12 +++++------- .../usable/{AbstractHammer.java => Hammer.java} | 6 +++--- .../core/items/usable/items/DiamondHammer.java | 17 ----------------- .../core/items/usable/items/IronHammer.java | 17 ----------------- .../items/usable/items/NetheriteHammer.java | 17 ----------------- 5 files changed, 8 insertions(+), 61 deletions(-) rename src/main/java/fr/openmc/core/items/usable/{AbstractHammer.java => Hammer.java} (95%) delete mode 100644 src/main/java/fr/openmc/core/items/usable/items/DiamondHammer.java delete mode 100644 src/main/java/fr/openmc/core/items/usable/items/IronHammer.java delete mode 100644 src/main/java/fr/openmc/core/items/usable/items/NetheriteHammer.java diff --git a/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java b/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java index 5872059a5..8a4c81209 100644 --- a/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java +++ b/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java @@ -1,9 +1,7 @@ package fr.openmc.core.items.usable; import dev.lone.itemsadder.api.CustomStack; -import fr.openmc.core.items.usable.items.DiamondHammer; -import fr.openmc.core.items.usable.items.IronHammer; -import fr.openmc.core.items.usable.items.NetheriteHammer; +import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import java.util.HashMap; @@ -17,10 +15,10 @@ public class CustomUsableItemRegistry { * Initializes the registry and registers all custom usable items. * This constructor should be called once during server startup. */ - public CustomUsableItemRegistry() { - new IronHammer(); - new DiamondHammer(); - new NetheriteHammer(); + public static void init() { + new Hammer("omc_items:iron_hammer", Material.IRON_PICKAXE, 1, 0); + new Hammer("omc_items:diamond_hammer", Material.DIAMOND_PICKAXE, 1, 1); + new Hammer("omc_items:netherite_hammer", Material.NETHERITE_PICKAXE, 1, 2); } /** diff --git a/src/main/java/fr/openmc/core/items/usable/AbstractHammer.java b/src/main/java/fr/openmc/core/items/usable/Hammer.java similarity index 95% rename from src/main/java/fr/openmc/core/items/usable/AbstractHammer.java rename to src/main/java/fr/openmc/core/items/usable/Hammer.java index e42d8d6d6..4803f7074 100644 --- a/src/main/java/fr/openmc/core/items/usable/AbstractHammer.java +++ b/src/main/java/fr/openmc/core/items/usable/Hammer.java @@ -9,14 +9,14 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.util.RayTraceResult; -public abstract class AbstractHammer extends CustomUsableItem { +public class Hammer extends CustomUsableItem { private final Material vanillaMaterial; private final int radius; private final int depth; private static final float MAX_HARDNESS = 41.0f; - protected AbstractHammer(String namespacedId, + protected Hammer(String namespacedId, Material vanillaMaterial, int radius, int depth) { @@ -37,7 +37,7 @@ public void onBlockBreak(Player player, BlockBreakEvent event) { return; ItemStack tool = player.getInventory().getItemInMainHand(); - if (tool == null || tool.getType().isAir()) + if (tool.getType().isAir()) return; Block broken = event.getBlock(); diff --git a/src/main/java/fr/openmc/core/items/usable/items/DiamondHammer.java b/src/main/java/fr/openmc/core/items/usable/items/DiamondHammer.java deleted file mode 100644 index 2945043c2..000000000 --- a/src/main/java/fr/openmc/core/items/usable/items/DiamondHammer.java +++ /dev/null @@ -1,17 +0,0 @@ -package fr.openmc.core.items.usable.items; - -import fr.openmc.core.items.usable.AbstractHammer; -import org.bukkit.Material; - -public class DiamondHammer extends AbstractHammer { - - public DiamondHammer() { - super( - "omc_items:diamond_hammer", - Material.DIAMOND_PICKAXE, - 1, - 1 - ); - } - -} diff --git a/src/main/java/fr/openmc/core/items/usable/items/IronHammer.java b/src/main/java/fr/openmc/core/items/usable/items/IronHammer.java deleted file mode 100644 index ac0c52515..000000000 --- a/src/main/java/fr/openmc/core/items/usable/items/IronHammer.java +++ /dev/null @@ -1,17 +0,0 @@ -package fr.openmc.core.items.usable.items; - -import fr.openmc.core.items.usable.AbstractHammer; -import org.bukkit.Material; - -public class IronHammer extends AbstractHammer { - - public IronHammer() { - super( - "omc_items:iron_hammer", - Material.IRON_PICKAXE, - 1, - 0 - ); - } - -} diff --git a/src/main/java/fr/openmc/core/items/usable/items/NetheriteHammer.java b/src/main/java/fr/openmc/core/items/usable/items/NetheriteHammer.java deleted file mode 100644 index 6c4ed7894..000000000 --- a/src/main/java/fr/openmc/core/items/usable/items/NetheriteHammer.java +++ /dev/null @@ -1,17 +0,0 @@ -package fr.openmc.core.items.usable.items; - -import fr.openmc.core.items.usable.AbstractHammer; -import org.bukkit.Material; - -public class NetheriteHammer extends AbstractHammer { - - public NetheriteHammer() { - super( - "omc_items:netherite_hammer", - Material.NETHERITE_PICKAXE, - 1, - 2 - ); - } - -} From 8b2da355876c5bdeeaa805d0a7ad7e7e20d8fe95 Mon Sep 17 00:00:00 2001 From: axenodev Date: Sun, 28 Dec 2025 18:58:58 +0100 Subject: [PATCH 5/7] feat: reorganize Hammer class methods and restore block breaking functionality --- .../fr/openmc/core/items/usable/Hammer.java | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/main/java/fr/openmc/core/items/usable/Hammer.java b/src/main/java/fr/openmc/core/items/usable/Hammer.java index 4803f7074..a4e84d8e8 100644 --- a/src/main/java/fr/openmc/core/items/usable/Hammer.java +++ b/src/main/java/fr/openmc/core/items/usable/Hammer.java @@ -11,39 +11,19 @@ public class Hammer extends CustomUsableItem { + private static final float MAX_HARDNESS = 41.0f; private final Material vanillaMaterial; private final int radius; private final int depth; - private static final float MAX_HARDNESS = 41.0f; protected Hammer(String namespacedId, - Material vanillaMaterial, - int radius, - int depth) { + Material vanillaMaterial, + int radius, + int depth) { super(namespacedId); this.vanillaMaterial = vanillaMaterial; this.radius = radius; - this.depth = depth; - } - - @Override - public ItemStack getVanilla() { - return ItemStack.of(vanillaMaterial); - } - - @Override - public void onBlockBreak(Player player, BlockBreakEvent event) { - if (player.getGameMode() != GameMode.SURVIVAL) - return; - - ItemStack tool = player.getInventory().getItemInMainHand(); - if (tool.getType().isAir()) - return; - - Block broken = event.getBlock(); - BlockFace face = getDestroyedBlockFace(player).getOppositeFace(); - - breakArea(player, broken, face, tool, radius, depth); + this.depth = depth; } private static void breakArea(Player player, @@ -52,7 +32,6 @@ private static void breakArea(Player player, ItemStack tool, int radius, int depth) { - Material targetType = origin.getType(); if (targetType.isAir()) return; if (targetType.getHardness() > MAX_HARDNESS) return; @@ -70,7 +49,7 @@ private static void breakArea(Player player, break; case EAST: case WEST: - apply = (x,y,z) -> work(world, player, tool, baseX + z, baseY + y, baseZ + x, targetType); + apply = (x, y, z) -> work(world, player, tool, baseX + z, baseY + y, baseZ + x, targetType); break; case UP: case DOWN: @@ -111,6 +90,26 @@ private static BlockFace getDestroyedBlockFace(Player player) { : BlockFace.SELF; } + @Override + public ItemStack getVanilla() { + return ItemStack.of(vanillaMaterial); + } + + @Override + public void onBlockBreak(Player player, BlockBreakEvent event) { + if (player.getGameMode() != GameMode.SURVIVAL) + return; + + ItemStack tool = player.getInventory().getItemInMainHand(); + if (tool.getType().isAir()) + return; + + Block broken = event.getBlock(); + BlockFace face = getDestroyedBlockFace(player).getOppositeFace(); + + breakArea(player, broken, face, tool, radius, depth); + } + @FunctionalInterface private interface IntTriConsumer { void accept(int x, int y, int z); From 9e408d3329e436cb4aa6eb9b7398bcf5b6ea03f0 Mon Sep 17 00:00:00 2001 From: axenodev Date: Mon, 29 Dec 2025 07:45:23 +0100 Subject: [PATCH 6/7] feat: improve block interaction handling and streamline method implementations --- .../java/fr/openmc/core/ListenersManager.java | 3 +- .../java/fr/openmc/core/items/CustomItem.java | 7 +- .../core/items/usable/CustomUsableItem.java | 29 +++-- .../usable/CustomUsableItemRegistry.java | 6 +- .../fr/openmc/core/items/usable/Hammer.java | 106 +++++++----------- .../core/listeners/BlockBreakListener.java | 3 +- .../core/listeners/InteractListener.java | 3 +- 7 files changed, 69 insertions(+), 88 deletions(-) diff --git a/src/main/java/fr/openmc/core/ListenersManager.java b/src/main/java/fr/openmc/core/ListenersManager.java index e5977fe91..dbed68ddb 100644 --- a/src/main/java/fr/openmc/core/ListenersManager.java +++ b/src/main/java/fr/openmc/core/ListenersManager.java @@ -40,7 +40,8 @@ public static void init() { new AywenCapListener(), new NoMoreRabbit(), new ArmorListener(), - new SpawnerExtractorListener() + new SpawnerExtractorListener(), + new BlockBreakListener() ); if (!OMCPlugin.isUnitTestVersion()) { diff --git a/src/main/java/fr/openmc/core/items/CustomItem.java b/src/main/java/fr/openmc/core/items/CustomItem.java index 49309a6b6..95fe16897 100644 --- a/src/main/java/fr/openmc/core/items/CustomItem.java +++ b/src/main/java/fr/openmc/core/items/CustomItem.java @@ -6,13 +6,15 @@ import org.bukkit.inventory.ItemStack; public abstract class CustomItem { - public abstract ItemStack getVanilla(); - @Getter private final String name; + @Getter + private final String name; public CustomItem(String name) { this.name = name; } + public abstract ItemStack getVanilla(); + public ItemStack getItemsAdder() { CustomStack stack = CustomStack.getInstance(getName()); return stack != null ? stack.getItemStack() : null; @@ -42,6 +44,7 @@ public boolean equals(Object object) { * Order: * 1. ItemsAdder * 2. Vanilla + * * @return Best ItemStack to use for the server */ public ItemStack getBest() { diff --git a/src/main/java/fr/openmc/core/items/usable/CustomUsableItem.java b/src/main/java/fr/openmc/core/items/usable/CustomUsableItem.java index ef4255174..cf19430b7 100644 --- a/src/main/java/fr/openmc/core/items/usable/CustomUsableItem.java +++ b/src/main/java/fr/openmc/core/items/usable/CustomUsableItem.java @@ -15,34 +15,37 @@ public abstract class CustomUsableItem extends CustomItem { */ protected CustomUsableItem(String name) { super(name); - CustomUsableItemRegistry.register(this); } /** * Event called when the player right-clicks with this item. * * @param player The player who performed the right-click. - * @param event The {@link PlayerInteractEvent} representing the click. + * @param event The {@link PlayerInteractEvent} representing the click. */ - public void onRightClick(Player player, PlayerInteractEvent event) {} + public void onRightClick(Player player, PlayerInteractEvent event) { + } /** * Event called when the player left-clicks with this item. * * @param player The player who performed the left-click. - * @param event The {@link PlayerInteractEvent} representing the click. + * @param event The {@link PlayerInteractEvent} representing the click. */ - public void onLeftClick(Player player, PlayerInteractEvent event) {} + public void onLeftClick(Player player, PlayerInteractEvent event) { + } /** * Event called when the player sneaks and clicks with this item. * * @param player The player who is sneaking and performed the click. - * @param event The {@link PlayerInteractEvent} representing the click. + * @param event The {@link PlayerInteractEvent} representing the click. */ - public void onSneakClick(Player player, PlayerInteractEvent event) {} + public void onSneakClick(Player player, PlayerInteractEvent event) { + } - public void onBlockBreak(Player player, BlockBreakEvent event) {} + public void onBlockBreak(Player player, BlockBreakEvent event) { + } /** * Handles the interaction with the item. @@ -53,13 +56,9 @@ public void onBlockBreak(Player player, BlockBreakEvent event) {} public final void handleInteraction(Player player, PlayerInteractEvent event) { Action action = event.getAction(); - if (player.isSneaking()) { - onSneakClick(player, event); - } else if (action.isLeftClick()) { - onLeftClick(player, event); - } else if (action.isRightClick()) { - onRightClick(player, event); - } + if (player.isSneaking()) onSneakClick(player, event); + else if (action.isLeftClick()) onLeftClick(player, event); + else if (action.isRightClick()) onRightClick(player, event); } public final void handleBlockBreak(Player player, BlockBreakEvent event) { diff --git a/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java b/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java index 8a4c81209..b21ed2180 100644 --- a/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java +++ b/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java @@ -16,9 +16,9 @@ public class CustomUsableItemRegistry { * This constructor should be called once during server startup. */ public static void init() { - new Hammer("omc_items:iron_hammer", Material.IRON_PICKAXE, 1, 0); - new Hammer("omc_items:diamond_hammer", Material.DIAMOND_PICKAXE, 1, 1); - new Hammer("omc_items:netherite_hammer", Material.NETHERITE_PICKAXE, 1, 2); + register(new Hammer("omc_items:iron_hammer", Material.IRON_PICKAXE, 1, 0)); + register(new Hammer("omc_items:diamond_hammer", Material.DIAMOND_PICKAXE, 1, 1)); + register(new Hammer("omc_items:netherite_hammer", Material.NETHERITE_PICKAXE, 1, 2)); } /** diff --git a/src/main/java/fr/openmc/core/items/usable/Hammer.java b/src/main/java/fr/openmc/core/items/usable/Hammer.java index a4e84d8e8..505148c4e 100644 --- a/src/main/java/fr/openmc/core/items/usable/Hammer.java +++ b/src/main/java/fr/openmc/core/items/usable/Hammer.java @@ -8,86 +8,70 @@ import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.util.RayTraceResult; +import org.bukkit.util.Vector; public class Hammer extends CustomUsableItem { private static final float MAX_HARDNESS = 41.0f; + private final Material vanillaMaterial; private final int radius; private final int depth; - protected Hammer(String namespacedId, - Material vanillaMaterial, - int radius, - int depth) { + protected Hammer(String namespacedId, Material vanillaMaterial, int radius, int depth) { super(namespacedId); this.vanillaMaterial = vanillaMaterial; this.radius = radius; this.depth = depth; } - private static void breakArea(Player player, - Block origin, - BlockFace face, - ItemStack tool, - int radius, - int depth) { - Material targetType = origin.getType(); - if (targetType.isAir()) return; - if (targetType.getHardness() > MAX_HARDNESS) return; + private static BlockFace getTargetFace(Player player) { + Location eye = player.getEyeLocation(); + RayTraceResult result = eye.getWorld().rayTraceBlocks(eye, eye.getDirection(), 10, FluidCollisionMode.NEVER); + + return result != null && result.getHitBlockFace() != null ? result.getHitBlockFace() : BlockFace.SELF; + } + + private static Vector rotateOffset(int x, int y, int z, BlockFace face) { + return switch (face) { + case NORTH, SOUTH -> new Vector(x, y, z); + case EAST, WEST -> new Vector(z, y, x); + case UP, DOWN -> new Vector(x, z, y); + default -> new Vector(0, 0, 0); + }; + } + private void breakArea(Player player, Block origin, BlockFace face, ItemStack tool, Material targetType) { World world = origin.getWorld(); - int baseX = origin.getX(); - int baseY = origin.getY(); - int baseZ = origin.getZ(); - - IntTriConsumer apply; - switch (face) { - case NORTH: - case SOUTH: - apply = (x, y, z) -> work(world, player, tool, baseX + x, baseY + y, baseZ + z, targetType); - break; - case EAST: - case WEST: - apply = (x, y, z) -> work(world, player, tool, baseX + z, baseY + y, baseZ + x, targetType); - break; - case UP: - case DOWN: - apply = (x, y, z) -> work(world, player, tool, baseX + x, baseY + z, baseZ + y, targetType); - break; - default: - return; - } + int ox = origin.getX(); + int oy = origin.getY(); + int oz = origin.getZ(); for (int dx = -radius; dx <= radius; dx++) { for (int dy = -radius; dy <= radius; dy++) { for (int dz = -depth; dz <= depth; dz++) { + if (dx == 0 && dy == 0 && dz == 0) continue; - apply.accept(dx, dy, dz); + + Vector offset = rotateOffset(dx, dy, dz, face); + breakBlock(world, player, tool, ox + offset.getBlockX(), oy + offset.getBlockY(), oz + offset.getBlockZ(), targetType); } } } } - private static void work(World world, - Player player, - ItemStack tool, - int x, int y, int z, - Material targetType) { - Block b = world.getBlockAt(x, y, z); - if (b.getType() != targetType) return; - if (b.getType().getHardness() > MAX_HARDNESS) return; - if (!ProtectionsManager.canInteract(player, b.getLocation())) return; - b.breakNaturally(tool); + private void breakBlock(World world, Player player, ItemStack tool, int x, int y, int z, Material targetType) { + Block block = world.getBlockAt(x, y, z); + + if (block.getType() != targetType) return; + if (!isBreakable(block.getType())) return; + if (!ProtectionsManager.canInteract(player, block.getLocation())) return; + + block.breakNaturally(tool); } - private static BlockFace getDestroyedBlockFace(Player player) { - Location eye = player.getEyeLocation(); - RayTraceResult result = eye.getWorld().rayTraceBlocks( - eye, eye.getDirection(), 10, FluidCollisionMode.NEVER); - return result != null && result.getHitBlockFace() != null - ? result.getHitBlockFace() - : BlockFace.SELF; + private boolean isBreakable(Material material) { + return !material.isAir() && material.getHardness() <= MAX_HARDNESS; } @Override @@ -97,21 +81,17 @@ public ItemStack getVanilla() { @Override public void onBlockBreak(Player player, BlockBreakEvent event) { - if (player.getGameMode() != GameMode.SURVIVAL) - return; + if (player.getGameMode() != GameMode.SURVIVAL) return; ItemStack tool = player.getInventory().getItemInMainHand(); - if (tool.getType().isAir()) - return; + if (tool.getType().isAir()) return; - Block broken = event.getBlock(); - BlockFace face = getDestroyedBlockFace(player).getOppositeFace(); + Block origin = event.getBlock(); + Material targetType = origin.getType(); - breakArea(player, broken, face, tool, radius, depth); - } + if (!isBreakable(targetType)) return; - @FunctionalInterface - private interface IntTriConsumer { - void accept(int x, int y, int z); + BlockFace face = getTargetFace(player).getOppositeFace(); + breakArea(player, origin, face, tool, targetType); } } diff --git a/src/main/java/fr/openmc/core/listeners/BlockBreakListener.java b/src/main/java/fr/openmc/core/listeners/BlockBreakListener.java index 8acd5b898..780768216 100644 --- a/src/main/java/fr/openmc/core/listeners/BlockBreakListener.java +++ b/src/main/java/fr/openmc/core/listeners/BlockBreakListener.java @@ -21,8 +21,7 @@ public void onBlockBreak(BlockBreakEvent event) { ItemStack itemInHand = player.getInventory().getItemInMainHand(); CustomUsableItem usableItem = CustomUsableItemRegistry.getByItemStack(itemInHand); - if (usableItem != null) - usableItem.handleBlockBreak(player, event); + if (usableItem != null) usableItem.handleBlockBreak(player, event); } } diff --git a/src/main/java/fr/openmc/core/listeners/InteractListener.java b/src/main/java/fr/openmc/core/listeners/InteractListener.java index fd99571d7..31df2d139 100644 --- a/src/main/java/fr/openmc/core/listeners/InteractListener.java +++ b/src/main/java/fr/openmc/core/listeners/InteractListener.java @@ -21,8 +21,7 @@ void onInteract(PlayerInteractEvent event) { ItemStack itemInHand = player.getInventory().getItemInMainHand(); CustomUsableItem usableItem = CustomUsableItemRegistry.getByItemStack(itemInHand); - if (usableItem != null) - usableItem.handleInteraction(player, event); + if (usableItem != null) usableItem.handleInteraction(player, event); } } From 37db7f52486d0bfd2a8e7617bd804185dd0e6b26 Mon Sep 17 00:00:00 2001 From: axenodev Date: Mon, 29 Dec 2025 07:49:10 +0100 Subject: [PATCH 7/7] feat: update Hammer class package structure and modify constructor visibility --- .../openmc/core/items/usable/CustomUsableItemRegistry.java | 1 + .../java/fr/openmc/core/items/usable/{ => tools}/Hammer.java | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) rename src/main/java/fr/openmc/core/items/usable/{ => tools}/Hammer.java (94%) diff --git a/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java b/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java index b21ed2180..6531d189a 100644 --- a/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java +++ b/src/main/java/fr/openmc/core/items/usable/CustomUsableItemRegistry.java @@ -1,6 +1,7 @@ package fr.openmc.core.items.usable; import dev.lone.itemsadder.api.CustomStack; +import fr.openmc.core.items.usable.tools.Hammer; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; diff --git a/src/main/java/fr/openmc/core/items/usable/Hammer.java b/src/main/java/fr/openmc/core/items/usable/tools/Hammer.java similarity index 94% rename from src/main/java/fr/openmc/core/items/usable/Hammer.java rename to src/main/java/fr/openmc/core/items/usable/tools/Hammer.java index 505148c4e..62eecbf08 100644 --- a/src/main/java/fr/openmc/core/items/usable/Hammer.java +++ b/src/main/java/fr/openmc/core/items/usable/tools/Hammer.java @@ -1,6 +1,7 @@ -package fr.openmc.core.items.usable; +package fr.openmc.core.items.usable.tools; import fr.openmc.core.features.city.ProtectionsManager; +import fr.openmc.core.items.usable.CustomUsableItem; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -18,7 +19,7 @@ public class Hammer extends CustomUsableItem { private final int radius; private final int depth; - protected Hammer(String namespacedId, Material vanillaMaterial, int radius, int depth) { + public Hammer(String namespacedId, Material vanillaMaterial, int radius, int depth) { super(namespacedId); this.vanillaMaterial = vanillaMaterial; this.radius = radius;