Skip to content
Open
3 changes: 2 additions & 1 deletion src/main/java/fr/openmc/core/ListenersManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public static void init() {
new AywenCapListener(),
new NoMoreRabbit(),
new ArmorListener(),
new SpawnerExtractorListener()
new SpawnerExtractorListener(),
new BlockBreakListener()
);

if (!OMCPlugin.isUnitTestVersion()) {
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/fr/openmc/core/items/CustomItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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() {
Expand Down
33 changes: 20 additions & 13 deletions src/main/java/fr/openmc/core/items/usable/CustomUsableItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -20,25 +21,31 @@ protected CustomUsableItem(String name) {
* 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) {
}

/**
* Handles the interaction with the item.
Expand All @@ -49,13 +56,13 @@ public void onSneakClick(Player player, PlayerInteractEvent event) {}
public final void handleInteraction(Player player, PlayerInteractEvent event) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a verifier le comportement de la MeteoWand.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est a dire ? J'ai rien modifie dans la methode ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non mais juste pour être sûr (fin théoriquement lorsque tu testes ta feature, tu testes les choses qui ont les même fonctionnalités genre un PlayerClickEvent (jsp comment il s'appelle mais ta compris)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

t'es good?

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) {
onBlockBreak(player, event);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
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;

import java.util.HashMap;
Expand All @@ -15,7 +17,9 @@ public class CustomUsableItemRegistry {
* This constructor should be called once during server startup.
*/
public static void init() {
// register here
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));
}

/**
Expand Down
98 changes: 98 additions & 0 deletions src/main/java/fr/openmc/core/items/usable/tools/Hammer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
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;
import org.bukkit.entity.Player;
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;

public Hammer(String namespacedId, Material vanillaMaterial, int radius, int depth) {
super(namespacedId);
this.vanillaMaterial = vanillaMaterial;
this.radius = radius;
this.depth = depth;
}

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 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;

Vector offset = rotateOffset(dx, dy, dz, face);
breakBlock(world, player, tool, ox + offset.getBlockX(), oy + offset.getBlockY(), oz + offset.getBlockZ(), targetType);
}
}
}
}

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 boolean isBreakable(Material material) {
return !material.isAir() && material.getHardness() <= MAX_HARDNESS;
}

@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 origin = event.getBlock();
Material targetType = origin.getType();

if (!isBreakable(targetType)) return;

BlockFace face = getTargetFace(player).getOppositeFace();
breakArea(player, origin, face, tool, targetType);
}
}
27 changes: 27 additions & 0 deletions src/main/java/fr/openmc/core/listeners/BlockBreakListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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);
}

}
3 changes: 1 addition & 2 deletions src/main/java/fr/openmc/core/listeners/InteractListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

}
Loading