Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 59 additions & 33 deletions src/main/java/io/github/pylonmc/pylon/content/tools/LumberAxe.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.pylonmc.pylon.content.tools;

import io.github.pylonmc.rebar.block.BlockStorage;
import io.github.pylonmc.rebar.config.adapter.ConfigAdapter;
import io.github.pylonmc.rebar.event.api.annotation.MultiHandler;
import io.github.pylonmc.rebar.item.RebarItem;
import io.github.pylonmc.rebar.item.interfaces.BlockBreakRebarItemHandler;
Expand Down Expand Up @@ -28,11 +29,12 @@

@SuppressWarnings("UnstableApiUsage")
public class LumberAxe extends RebarItem implements BlockBreakRebarItemHandler {

public LumberAxe( @NotNull ItemStack stack) {
public LumberAxe(@NotNull ItemStack stack) {
super(stack);
}

private final int maxBreakBlocks = getSettingOrThrow("max-break-blocks", ConfigAdapter.INTEGER);

private static final Set<Event> eventsToIgnore = Collections.newSetFromMap(new WeakHashMap<>());

@Override @MultiHandler(priorities = EventPriority.MONITOR, ignoreCancelled = true)
Expand All @@ -50,41 +52,65 @@ public void onBreakBlock(@NotNull BlockBreakEvent event, @NotNull EventPriority
event.setCancelled(true); // Stop vanilla logic
}

private void breakAttachedWood(Block block, Player player, ItemStack tool) {
// Recursive function, for every adjacent block check if it's a log, if so delete it and give the drop to the player and check all its adjacent blocks
if (!Tag.LOGS.isTagged(block.getType()) || BlockStorage.isRebarBlock(block)
|| !block.getWorld().getWorldBorder().isInside(block.getLocation())) {
return;
}
BlockBreakEvent blockBreakEvent = new BlockBreakEvent(block, player);
eventsToIgnore.add(blockBreakEvent);
if (!blockBreakEvent.callEvent()) {
return;
}
BlockState blockState = block.getState();
Collection<ItemStack> drops = block.getDrops(tool);
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getBlockData());
block.setType(Material.AIR);
if (blockBreakEvent.isDropItems()) {
List<Item> itemsDropped = new ArrayList<>();
for (ItemStack itemStack : drops) {
Item item = block.getWorld().dropItem(block.getLocation(), itemStack);
itemsDropped.add(item);
private void breakAttachedWood(Block startBlock, Player player, ItemStack tool) {
Deque<Block> queue = new ArrayDeque<>();
Set<Block> visited = new HashSet<>();

queue.offer(startBlock);
visited.add(startBlock);

int brokenBlocks = 0;
while (!queue.isEmpty()) {
Block block = queue.poll();

if (!Tag.LOGS.isTagged(block.getType()) || BlockStorage.isRebarBlock(block)
|| !block.getWorld().getWorldBorder().isInside(block.getLocation())) {
continue;
}

BlockBreakEvent blockBreakEvent = new BlockBreakEvent(block, player);
eventsToIgnore.add(blockBreakEvent);
if (!blockBreakEvent.callEvent()) {
continue;
}
if (!new BlockDropItemEvent(block, blockState, player, itemsDropped).callEvent()) {
for (Item item : itemsDropped) {
item.remove();
BlockState blockState = block.getState();
Collection<ItemStack> drops = block.getDrops(tool);
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getBlockData());
block.setType(Material.AIR);
brokenBlocks++;
if (blockBreakEvent.isDropItems()) {
List<Item> itemsDropped = new ArrayList<>();
for (ItemStack itemStack : drops) {
Item item = block.getWorld().dropItem(block.getLocation(), itemStack);
itemsDropped.add(item);
}
if (!new BlockDropItemEvent(block, blockState, player, itemsDropped).callEvent()) {
for (Item item : itemsDropped) {
item.remove();
}
}
}
}

Tool toolComponent = tool.getData(DataComponentTypes.TOOL);
if (toolComponent != null) {
RebarUtils.damageItem(tool, toolComponent.damagePerBlock(), player, EquipmentSlot.HAND);
}
Tool toolComponent = tool.getData(DataComponentTypes.TOOL);
if (toolComponent != null) {
RebarUtils.damageItem(tool, toolComponent.damagePerBlock(), player, EquipmentSlot.HAND);
}

if (tool.getData(DataComponentTypes.DAMAGE) >= tool.getData(DataComponentTypes.MAX_DAMAGE)) {
return;
}

if (brokenBlocks >= maxBreakBlocks) {
return;
}

for (BlockFace face : RebarUtils.IMMEDIATE_FACES) {
breakAttachedWood(block.getRelative(face), player, tool);
for (BlockFace face : RebarUtils.IMMEDIATE_FACES) {
Block relative = block.getRelative(face);
if (!visited.contains(relative)) {
visited.add(relative);
queue.offer(relative);
}
}
}
}
}
}
3 changes: 2 additions & 1 deletion src/main/resources/settings/lumber_axe.yml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
durability: 800
durability: 800
max-break-blocks: 128
Loading