From ec10e5c285e6769ec9bb4200c55697cd5e97304c Mon Sep 17 00:00:00 2001 From: Jottyfan Date: Fri, 2 Jan 2026 00:16:03 +0100 Subject: [PATCH] added tools --- .../java/de/jottyfan/minecraft/Quickly.java | 2 + .../minecraft/event/EventBlockBreak.java | 215 ++++++++++++++++++ .../minecraft/event/QuicklyEvents.java | 20 ++ .../jottyfan/minecraft/item/HarvestRange.java | 110 +++++++++ .../jottyfan/minecraft/item/QuicklyItems.java | 40 +++- .../minecraft/item/ToolQuickiepowderAxe.java | 26 +++ .../minecraft/item/ToolQuickiepowderHoe.java | 20 ++ .../item/ToolQuickiepowderPickaxe.java | 55 +++++ .../item/ToolQuickiepowderShears.java | 100 ++++++++ .../item/ToolQuickiepowderShovel.java | 97 ++++++++ .../item/ToolQuickiepowderWaterHoe.java | 47 ++++ .../minecraft/item/ToolRangeable.java | 39 ++++ .../minecraft/item/ToolRangeableAxe.java | 63 +++++ .../minecraft/item/ToolRangeableHoe.java | 96 ++++++++ .../minecraft/item/ToolSpeedpowderAxe.java | 26 +++ .../minecraft/item/ToolSpeedpowderHoe.java | 20 ++ .../item/ToolSpeedpowderPickaxe.java | 55 +++++ .../minecraft/item/ToolSpeedpowderShears.java | 105 +++++++++ .../minecraft/item/ToolSpeedpowderShovel.java | 96 ++++++++ .../item/ToolSpeedpowderWaterHoe.java | 47 ++++ .../quickly/items/quickiepowderaxe.json | 6 + .../quickly/items/quickiepowderhoe.json | 6 + .../quickly/items/quickiepowderpickaxe.json | 6 + .../quickly/items/quickiepowdershears.json | 6 + .../quickly/items/quickiepowdershovel.json | 6 + .../quickly/items/quickiepowderwaterhoe.json | 6 + .../assets/quickly/items/speedpowderaxe.json | 6 + .../assets/quickly/items/speedpowderhoe.json | 6 + .../quickly/items/speedpowderpickaxe.json | 6 + .../quickly/items/speedpowdershears.json | 6 + .../quickly/items/speedpowdershovel.json | 6 + .../quickly/items/speedpowderwaterhoe.json | 6 + .../resources/assets/quickly/lang/de_de.json | 13 ++ .../resources/assets/quickly/lang/en_us.json | 13 ++ .../quickly/models/item/quickiepowderaxe.json | 6 + .../quickly/models/item/quickiepowderhoe.json | 6 + .../models/item/quickiepowderpickaxe.json | 6 + .../models/item/quickiepowdershears.json | 6 + .../models/item/quickiepowdershovel.json | 6 + .../models/item/quickiepowderwaterhoe.json | 6 + .../quickly/models/item/speedpowderaxe.json | 6 + .../quickly/models/item/speedpowderhoe.json | 6 + .../models/item/speedpowderpickaxe.json | 6 + .../models/item/speedpowdershears.json | 6 + .../models/item/speedpowdershovel.json | 6 + .../models/item/speedpowderwaterhoe.json | 6 + .../textures/item/quickiepowderaxe.png | Bin 0 -> 4650 bytes .../textures/item/quickiepowderhoe.png | Bin 0 -> 4632 bytes .../textures/item/quickiepowderpickaxe.png | Bin 0 -> 4662 bytes .../textures/item/quickiepowdershears.png | Bin 0 -> 4790 bytes .../textures/item/quickiepowdershovel.png | Bin 0 -> 4642 bytes .../textures/item/quickiepowderwaterhoe.png | Bin 0 -> 4676 bytes .../quickly/textures/item/speedpowderaxe.png | Bin 0 -> 4399 bytes .../quickly/textures/item/speedpowderhoe.png | Bin 0 -> 6016 bytes .../textures/item/speedpowderpickaxe.png | Bin 0 -> 4409 bytes .../textures/item/speedpowdershears.png | Bin 0 -> 4790 bytes .../textures/item/speedpowdershovel.png | Bin 0 -> 4417 bytes .../textures/item/speedpowderwaterhoe.png | Bin 0 -> 6140 bytes src/main/resources/data/c/tags/item/axes.json | 7 + src/main/resources/data/c/tags/item/hoes.json | 9 + .../resources/data/c/tags/item/pickaxes.json | 7 + .../resources/data/c/tags/item/shovels.json | 7 + .../recipe/shaped_quickiepowder_shears.json | 14 ++ .../recipe/shaped_quickiepowderaxe.json | 17 ++ .../recipe/shaped_quickiepowderhoe.json | 17 ++ .../recipe/shaped_quickiepowderpickaxe.json | 17 ++ .../recipe/shaped_quickiepowdershovel.json | 17 ++ .../recipe/shaped_speedpowder_shears.json | 14 ++ .../quickly/recipe/shaped_speedpowderaxe.json | 17 ++ .../quickly/recipe/shaped_speedpowderhoe.json | 17 ++ .../recipe/shaped_speedpowderpickaxe.json | 17 ++ .../recipe/shaped_speedpowdershovel.json | 17 ++ .../shapeless_quickiepowderwaterhoe.json | 11 + .../recipe/shapeless_speedpowderwaterhoe.json | 11 + 74 files changed, 1664 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/jottyfan/minecraft/event/EventBlockBreak.java create mode 100644 src/main/java/de/jottyfan/minecraft/event/QuicklyEvents.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/HarvestRange.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderAxe.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderHoe.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderPickaxe.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderShears.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderShovel.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderWaterHoe.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolRangeable.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolRangeableAxe.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolRangeableHoe.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderAxe.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderHoe.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderPickaxe.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderShears.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderShovel.java create mode 100644 src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderWaterHoe.java create mode 100644 src/main/resources/assets/quickly/items/quickiepowderaxe.json create mode 100644 src/main/resources/assets/quickly/items/quickiepowderhoe.json create mode 100644 src/main/resources/assets/quickly/items/quickiepowderpickaxe.json create mode 100644 src/main/resources/assets/quickly/items/quickiepowdershears.json create mode 100644 src/main/resources/assets/quickly/items/quickiepowdershovel.json create mode 100644 src/main/resources/assets/quickly/items/quickiepowderwaterhoe.json create mode 100644 src/main/resources/assets/quickly/items/speedpowderaxe.json create mode 100644 src/main/resources/assets/quickly/items/speedpowderhoe.json create mode 100644 src/main/resources/assets/quickly/items/speedpowderpickaxe.json create mode 100644 src/main/resources/assets/quickly/items/speedpowdershears.json create mode 100644 src/main/resources/assets/quickly/items/speedpowdershovel.json create mode 100644 src/main/resources/assets/quickly/items/speedpowderwaterhoe.json create mode 100644 src/main/resources/assets/quickly/models/item/quickiepowderaxe.json create mode 100644 src/main/resources/assets/quickly/models/item/quickiepowderhoe.json create mode 100644 src/main/resources/assets/quickly/models/item/quickiepowderpickaxe.json create mode 100644 src/main/resources/assets/quickly/models/item/quickiepowdershears.json create mode 100644 src/main/resources/assets/quickly/models/item/quickiepowdershovel.json create mode 100644 src/main/resources/assets/quickly/models/item/quickiepowderwaterhoe.json create mode 100644 src/main/resources/assets/quickly/models/item/speedpowderaxe.json create mode 100644 src/main/resources/assets/quickly/models/item/speedpowderhoe.json create mode 100644 src/main/resources/assets/quickly/models/item/speedpowderpickaxe.json create mode 100644 src/main/resources/assets/quickly/models/item/speedpowdershears.json create mode 100644 src/main/resources/assets/quickly/models/item/speedpowdershovel.json create mode 100644 src/main/resources/assets/quickly/models/item/speedpowderwaterhoe.json create mode 100644 src/main/resources/assets/quickly/textures/item/quickiepowderaxe.png create mode 100644 src/main/resources/assets/quickly/textures/item/quickiepowderhoe.png create mode 100644 src/main/resources/assets/quickly/textures/item/quickiepowderpickaxe.png create mode 100644 src/main/resources/assets/quickly/textures/item/quickiepowdershears.png create mode 100644 src/main/resources/assets/quickly/textures/item/quickiepowdershovel.png create mode 100644 src/main/resources/assets/quickly/textures/item/quickiepowderwaterhoe.png create mode 100644 src/main/resources/assets/quickly/textures/item/speedpowderaxe.png create mode 100644 src/main/resources/assets/quickly/textures/item/speedpowderhoe.png create mode 100644 src/main/resources/assets/quickly/textures/item/speedpowderpickaxe.png create mode 100644 src/main/resources/assets/quickly/textures/item/speedpowdershears.png create mode 100644 src/main/resources/assets/quickly/textures/item/speedpowdershovel.png create mode 100644 src/main/resources/assets/quickly/textures/item/speedpowderwaterhoe.png create mode 100644 src/main/resources/data/c/tags/item/axes.json create mode 100644 src/main/resources/data/c/tags/item/hoes.json create mode 100644 src/main/resources/data/c/tags/item/pickaxes.json create mode 100644 src/main/resources/data/c/tags/item/shovels.json create mode 100644 src/main/resources/data/quickly/recipe/shaped_quickiepowder_shears.json create mode 100644 src/main/resources/data/quickly/recipe/shaped_quickiepowderaxe.json create mode 100644 src/main/resources/data/quickly/recipe/shaped_quickiepowderhoe.json create mode 100644 src/main/resources/data/quickly/recipe/shaped_quickiepowderpickaxe.json create mode 100644 src/main/resources/data/quickly/recipe/shaped_quickiepowdershovel.json create mode 100644 src/main/resources/data/quickly/recipe/shaped_speedpowder_shears.json create mode 100644 src/main/resources/data/quickly/recipe/shaped_speedpowderaxe.json create mode 100644 src/main/resources/data/quickly/recipe/shaped_speedpowderhoe.json create mode 100644 src/main/resources/data/quickly/recipe/shaped_speedpowderpickaxe.json create mode 100644 src/main/resources/data/quickly/recipe/shaped_speedpowdershovel.json create mode 100644 src/main/resources/data/quickly/recipe/shapeless_quickiepowderwaterhoe.json create mode 100644 src/main/resources/data/quickly/recipe/shapeless_speedpowderwaterhoe.json diff --git a/src/main/java/de/jottyfan/minecraft/Quickly.java b/src/main/java/de/jottyfan/minecraft/Quickly.java index 7714249..f786a90 100644 --- a/src/main/java/de/jottyfan/minecraft/Quickly.java +++ b/src/main/java/de/jottyfan/minecraft/Quickly.java @@ -6,6 +6,7 @@ import org.apache.logging.log4j.Logger; import de.jottyfan.minecraft.block.QuicklyBlocks; import de.jottyfan.minecraft.blockentity.QuicklyBlockEntity; import de.jottyfan.minecraft.composter.QuicklyComposter; +import de.jottyfan.minecraft.event.QuicklyEvents; import de.jottyfan.minecraft.feature.QuicklyFeatures; import de.jottyfan.minecraft.item.QuicklyItems; import de.jottyfan.minecraft.loot.QuicklyLootTables; @@ -32,5 +33,6 @@ public class Quickly implements ModInitializer { QuicklyFeatures.registerFeatures(); QuicklyComposter.registerComposterItems(); QuicklyLootTables.registerChanges(); + QuicklyEvents.registerBlockBreak(); } } \ No newline at end of file diff --git a/src/main/java/de/jottyfan/minecraft/event/EventBlockBreak.java b/src/main/java/de/jottyfan/minecraft/event/EventBlockBreak.java new file mode 100644 index 0000000..2a66774 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/event/EventBlockBreak.java @@ -0,0 +1,215 @@ +package de.jottyfan.minecraft.event; + +import java.util.ArrayList; +import java.util.List; + +import de.jottyfan.minecraft.Quickly; +import de.jottyfan.minecraft.item.HarvestRange; +import de.jottyfan.minecraft.item.QuicklyItems; +import de.jottyfan.minecraft.item.ToolRangeable; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.ExperienceOrb; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +/** + * + * @author jotty + * + */ +public class EventBlockBreak { + private enum BlockBreakDirection { + UPWARDS, ALL; + } + + /** + * break surrounding block if item is of ToolRangeable + * + * @param level + * @param blockPos + * @param blockState + * @param player + * @param oldBlock + * @return true if this range breaking routine has been used, false otherwise + */ + public boolean doBreakBlock(Level level, BlockPos blockPos, BlockState blockState, Player player, Block oldBlock) { + ItemStack mainHandItemStack = player.getMainHandItem(); + if (mainHandItemStack != null) { + Item item = mainHandItemStack.getItem(); + if (item instanceof ToolRangeable) { + ToolRangeable tool = (ToolRangeable) item; + // not needed when added to before block break +// if (!world.getBlockState(blockPos).getBlock().equals(oldBlock)) { +// // recreate old block to make it breakable; otherwise, the recursive algorithm stops directly +// // this leads to the BUG that blocks with no neighbour will respawn and drop -> unlimited items. +// world.setBlockState(blockPos, oldBlock.getDefaultState()); +// } + int handled = handleRangeableTools(tool, mainHandItemStack, level, oldBlock, blockPos, player); + if (handled >= 255) { + // reward for using rangeable tool very successful + level.addFreshEntity( + new ExperienceOrb(level, blockPos.getX(), blockPos.getY(), blockPos.getZ(), handled / 255)); + } + return handled > 0; // this way, a rangeable pickaxe can break a dirt block + } else { + return false; + } + } else { + return false; + } + } + + /** + * handle the rangeable tools break event + * + * @param tool the tool that has been used + * @param itemStack the item stack + * @param level the world + * @param block the block to break + * @param pos the position of the current block + * @param player the current player + * @return number of affected blocks + */ + private int handleRangeableTools(ToolRangeable tool, ItemStack itemStack, Level level, Block currentBlock, + BlockPos pos, Player player) { + List validBlocks = tool.getBlockList(currentBlock); + HarvestRange range = tool.getRange(itemStack); + if (tool instanceof Item) { + Item toolItem = (Item) tool; // a rangeable tool should always be an item + List visitedBlocks = new ArrayList<>(); + if (QuicklyItems.TOOL_SPEEDPOWDERAXE.getName().equals(toolItem.getName())) { + return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.UPWARDS, + player, true); + } else if (QuicklyItems.TOOL_SPEEDPOWDERPICKAXE.getName().equals(toolItem.getName())) { + return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.ALL, + player, false); + } else if (QuicklyItems.TOOL_SPEEDPOWDERSHOVEL.getName().equals(toolItem.getName())) { + return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.ALL, + player, false); + } else if (QuicklyItems.TOOL_SPEEDPOWDERHOE.getName().equals(toolItem.getName())) { + return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.ALL, + player, false); + } else if (QuicklyItems.TOOL_QUICKIEPOWDERAXE.getName().equals(toolItem.getName())) { + return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.UPWARDS, + player, true); + } else if (QuicklyItems.TOOL_QUICKIEPOWDERPICKAXE.getName().equals(toolItem.getName())) { + return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.ALL, + player, false); + } else if (QuicklyItems.TOOL_QUICKIEPOWDERSHOVEL.getName().equals(toolItem.getName())) { + return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.ALL, + player, false); + } else if (QuicklyItems.TOOL_QUICKIEPOWDERHOE.getName().equals(toolItem.getName())) { + return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.ALL, + player, false); + } else { + return 0; + } + } else { + Quickly.LOGGER.warn("using a tool that is not an item - no rangeable operations are possible."); + return 0; + } + } + + /** + * break block recursively; + * + * @param visitedBlocks the positions of visited blocks + * @param level the world + * @param validBlocks the blocks to break + * @param tool the tool used + * @param range the range left over + * @param pos the position + * @param blockBreakDirection the direction for the recursive call + * @param player the player + * @return number of affected blocks + */ + private int breakBlockRecursive(List visitedBlocks, Level level, List validBlocks, BlockPos pos, + ToolRangeable tool, HarvestRange range, BlockBreakDirection blockBreakDirection, Player player, + boolean breakLeaves) { +// boolean ignoreSpawn = visitedBlocks.size() < 1; // with this, the already broken block can be omitted to spawn + if (visitedBlocks.contains(pos.toString())) { + return 0; + } else if (validBlocks == null) { + return 0; + } else { + visitedBlocks.add(pos.toString()); + } + Integer affected = 0; + BlockState blockState = level.getBlockState(pos); + if (tool.canBreakNeighbors(blockState)) { + Block currentBlock = blockState.getBlock(); + if (validBlocks.contains(currentBlock)) { +// if (!ignoreSpawn) { + Block.dropResources(blockState, level, pos); // includes xorbs +// } + affected += 1; + level.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState()); + if (range == null || range.getxRange() > 1 || range.getyRange() > 1 || range.getzRange() > 1) { + HarvestRange nextRadius = range == null ? null : range.addXYZ(-1); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.north(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.north().east(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.north().west(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.south(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.south().east(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.south().west(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.east(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.west(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().north(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().north().east(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().north().west(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().east(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().west(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().south().east(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().south().west(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().south(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + + if (BlockBreakDirection.ALL.equals(blockBreakDirection)) { + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().north(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().south(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().east(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().west(), tool, nextRadius, + blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().north().east(), tool, + nextRadius, blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().north().west(), tool, + nextRadius, blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().south().east(), tool, + nextRadius, blockBreakDirection, player, breakLeaves); + affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().south().west(), tool, + nextRadius, blockBreakDirection, player, breakLeaves); + } + } + } + } + return affected; + } +} diff --git a/src/main/java/de/jottyfan/minecraft/event/QuicklyEvents.java b/src/main/java/de/jottyfan/minecraft/event/QuicklyEvents.java new file mode 100644 index 0000000..db09e12 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/event/QuicklyEvents.java @@ -0,0 +1,20 @@ +package de.jottyfan.minecraft.event; + +import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents; + +/** + * + * @author jotty + * + */ +public class QuicklyEvents { + public static final void registerBlockBreak() { + PlayerBlockBreakEvents.BEFORE.register((world, player, pos, state, blockEntity) -> { + if (new EventBlockBreak().doBreakBlock(world, pos, state, player, state.getBlock())) { + return false; + } else { + return true; + } + }); + } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/HarvestRange.java b/src/main/java/de/jottyfan/minecraft/item/HarvestRange.java new file mode 100644 index 0000000..69468cc --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/HarvestRange.java @@ -0,0 +1,110 @@ +package de.jottyfan.minecraft.item; + +import java.io.Serializable; + +/** + * + * @author jotty + * + */ +public class HarvestRange implements Serializable { + private static final long serialVersionUID = 1L; + private int xRange; + private int yRange; + private int zRange; + + public HarvestRange(int xyzRange) { + super(); + this.xRange = xyzRange; + this.yRange = xyzRange; + this.zRange = xyzRange; + } + + public HarvestRange(int[] xyzRange) { + super(); + this.xRange = xyzRange[0]; + this.yRange = xyzRange[1]; + this.zRange = xyzRange[2]; + } + + public HarvestRange(int xRange, int yRange, int zRange) { + super(); + this.xRange = xRange; + this.yRange = yRange; + this.zRange = zRange; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(xRange).append(":"); + buf.append(yRange).append(":"); + buf.append(zRange).append(":"); + return buf.toString(); + } + + /** + * add i to x, y and z and return the resulting class as a new one + * + * @param i + * the summand + * @return the new class + */ + public HarvestRange addXYZ(int i) { + return new HarvestRange(xRange + i, yRange + i, zRange + i); + } + + /** + * get range as int array + * + * @return the int array + */ + public int[] getRangeAsArray() { + return new int[] {xRange, yRange, zRange}; + } + + /** + * @return the xRange + */ + public int getxRange() { + return xRange; + } + + /** + * @param xRange + * the xRange to set + */ + public void setxRange(int xRange) { + this.xRange = xRange; + } + + /** + * @return the yRange + */ + public int getyRange() { + return yRange; + } + + /** + * @param yRange + * the yRange to set + */ + public void setyRange(int yRange) { + this.yRange = yRange; + } + + /** + * @return the zRange + */ + public int getzRange() { + return zRange; + } + + /** + * @param zRange + * the zRange to set + */ + public void setzRange(int zRange) { + this.zRange = zRange; + } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/QuicklyItems.java b/src/main/java/de/jottyfan/minecraft/item/QuicklyItems.java index e971191..b7e2650 100644 --- a/src/main/java/de/jottyfan/minecraft/item/QuicklyItems.java +++ b/src/main/java/de/jottyfan/minecraft/item/QuicklyItems.java @@ -48,7 +48,33 @@ public class QuicklyItems { public static final Item SULFOR = registerItem("sulfor"); public static final Item CARROTSTACK = registerItem("carrotstack"); - // TODO: tools + // TODO: normalize classes and try to summarize tools (such as ToolShovel for both speed and quickie) + // TODO: rename tools to speedaxe and quickaxe instead of the powder version + + public static final Item TOOL_SPEEDPOWDERAXE = registerItem("speedpowderaxe", + properties -> new ToolSpeedpowderAxe(properties)); + public static final Item TOOL_SPEEDPOWDERHOE = registerItem("speedpowderhoe", + properties -> new ToolSpeedpowderHoe(properties)); + public static final Item TOOL_SPEEDPOWDERPICKAXE = registerItem("speedpowderpickaxe", + properties -> new ToolSpeedpowderPickaxe(properties)); + public static final Item TOOL_SPEEDPOWDERSHEARS = registerItem("speedpowdershears", + properties -> new ToolSpeedpowderShears(properties)); + public static final Item TOOL_SPEEDPOWDERSHOVEL = registerItem("speedpowdershovel", + properties -> new ToolSpeedpowderShovel(properties)); + public static final Item TOOL_SPEEDPOWDERWATERHOE = registerItem("speedpowderwaterhoe", + properties -> new ToolSpeedpowderWaterHoe(properties, QuicklyItems.TOOL_SPEEDPOWDERHOE)); + public static final Item TOOL_QUICKIEPOWDERAXE = registerItem("quickiepowderaxe", + properties -> new ToolQuickiepowderAxe(properties)); + public static final Item TOOL_QUICKIEPOWDERHOE = registerItem("quickiepowderhoe", + properties -> new ToolQuickiepowderHoe(properties)); + public static final Item TOOL_QUICKIEPOWDERPICKAXE = registerItem("quickiepowderpickaxe", + properties -> new ToolQuickiepowderPickaxe(properties)); + public static final Item TOOL_QUICKIEPOWDERSHOVEL = registerItem("quickiepowdershovel", + properties -> new ToolQuickiepowderShovel(properties)); + public static final Item TOOL_QUICKIEPOWDERWATERHOE = registerItem("quickiepowderwaterhoe", + properties -> new ToolQuickiepowderWaterHoe(properties, QuicklyItems.TOOL_QUICKIEPOWDERHOE)); + public static final Item TOOL_QUICKIEPOWDERSHEARS = registerItem("quickiepowdershears", + properties -> new ToolSpeedpowderShears(properties)); public static final Item ARMOR_TURQUOISE_BOOTS = registerItem("turquoise_boots", ArmorType.BOOTS); public static final Item ARMOR_TURQUOISE_HELMET = registerItem("turquoise_helmet", ArmorType.HELMET); @@ -108,6 +134,18 @@ public class QuicklyItems { item.accept(ARMOR_TURQUOISE_CHESTPLATE); item.accept(ARMOR_TURQUOISE_LEGGINGS); item.accept(ARMOR_TURQUOISE_BOOTS); + item.accept(TOOL_QUICKIEPOWDERPICKAXE); + item.accept(TOOL_QUICKIEPOWDERAXE); + item.accept(TOOL_QUICKIEPOWDERSHOVEL); + item.accept(TOOL_QUICKIEPOWDERSHEARS); + item.accept(TOOL_QUICKIEPOWDERHOE); + item.accept(TOOL_QUICKIEPOWDERWATERHOE); + item.accept(TOOL_SPEEDPOWDERPICKAXE); + item.accept(TOOL_SPEEDPOWDERAXE); + item.accept(TOOL_SPEEDPOWDERSHOVEL); + item.accept(TOOL_SPEEDPOWDERSHEARS); + item.accept(TOOL_SPEEDPOWDERHOE); + item.accept(TOOL_SPEEDPOWDERWATERHOE); }); } } diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderAxe.java b/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderAxe.java new file mode 100644 index 0000000..00a4463 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderAxe.java @@ -0,0 +1,26 @@ +package de.jottyfan.minecraft.item; + +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ToolMaterial; + +/** + * + * @author jotty + * + */ +public class ToolQuickiepowderAxe extends ToolRangeableAxe { + + private final static ToolMaterial MATERIAL = new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, 2400, 7f, 1f, 15, ItemTags.DIAMOND_TOOL_MATERIALS); + + public ToolQuickiepowderAxe(Properties properties) { + super(MATERIAL, 7F, -3.1F, properties); + } + + @Override + public HarvestRange getRange(ItemStack stack) { + // TODO: get the range from the stack + return new HarvestRange(64, 128, 64); // trees bigger than that are too heavy for one small axe... + } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderHoe.java b/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderHoe.java new file mode 100644 index 0000000..09adf75 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderHoe.java @@ -0,0 +1,20 @@ +package de.jottyfan.minecraft.item; + +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.item.ToolMaterial; + +/** + * + * @author jotty + * + */ +public class ToolQuickiepowderHoe extends ToolRangeableHoe { + + public static final Integer DEFAULT_PLOW_RANGE = 4; + private final static ToolMaterial MATERIAL = new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, 2400, 7f, 1f, 15, ItemTags.DIAMOND_TOOL_MATERIALS); + + public ToolQuickiepowderHoe(Properties properties) { + super(MATERIAL, 7F, -3.1f, properties, new HarvestRange(DEFAULT_PLOW_RANGE)); + } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderPickaxe.java b/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderPickaxe.java new file mode 100644 index 0000000..da52ad4 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderPickaxe.java @@ -0,0 +1,55 @@ +package de.jottyfan.minecraft.item; + +import java.util.List; + +import com.google.common.collect.Lists; + +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ToolMaterial; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +/** + * + * @author jotty + * + */ +public class ToolQuickiepowderPickaxe extends Item implements ToolRangeable { + + public static final int[] DEFAULT_HARVEST_RANGE = new int[] { 6, 6, 6 }; + private final static ToolMaterial MATERIAL = new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, 2400, 7f, 1f, 15, ItemTags.DIAMOND_TOOL_MATERIALS); + + public ToolQuickiepowderPickaxe(Properties properties) { + super(properties.pickaxe(MATERIAL, 7F, -3.1F)); + } + + @Override + public HarvestRange getRange(ItemStack stack) { + return new HarvestRange(DEFAULT_HARVEST_RANGE); + } + + @Override + public boolean canBreakNeighbors(BlockState blockIn) { + return new ItemStack(this).isCorrectToolForDrops(blockIn); + } + + @Override + public List getBlockList(Block block) { + return Lists.newArrayList(block); + } + +// @Override +// public ActionResult onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { +// CommonToolCode.onItemRightClick(worldIn, playerIn, handIn); +// return super.onItemRightClick(worldIn, playerIn, handIn); +// } +// +// @Override +// public void addInformation(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn) { +// CommonToolCode.addInformation(stack, worldIn, tooltip, flagIn); +// super.addInformation(stack, worldIn, tooltip, flagIn); +// } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderShears.java b/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderShears.java new file mode 100644 index 0000000..085ac04 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderShears.java @@ -0,0 +1,100 @@ +package de.jottyfan.minecraft.item; + +import java.util.Random; + +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.animal.chicken.Chicken; +import net.minecraft.world.entity.animal.cow.Cow; +import net.minecraft.world.entity.animal.equine.Horse; +import net.minecraft.world.entity.animal.sheep.Sheep; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.ShearsItem; +import net.minecraft.world.phys.Vec3; + + +/** + * + * @author jotty + * + */ +public class ToolQuickiepowderShears extends ShearsItem { + + public ToolQuickiepowderShears(Properties properties) { + super(properties.component(DataComponents.TOOL, ShearsItem.createToolProperties())); + } + + @Override + public InteractionResult interactLivingEntity(ItemStack stack, Player user, LivingEntity entity, + InteractionHand hand) { + Vec3 pos = entity.position(); + Integer amount = 3 + new Random().nextInt(4); + if (entity instanceof Sheep sheep) { + if (!sheep.isSheared()) { + sheep.setSheared(true); + sheep.playAmbientSound(); + DyeColor color = sheep.getColor(); + Item item = Items.WHITE_WOOL; + if (color.equals(DyeColor.BLACK)) { + item = Items.BLACK_WOOL; + } else if (color.equals(DyeColor.GRAY)) { + item = Items.GRAY_WOOL; + } else if (color.equals(DyeColor.LIGHT_GRAY)) { + item = Items.LIGHT_GRAY_WOOL; + } else if (color.equals(DyeColor.BROWN)) { + item = Items.BROWN_WOOL; + } else if (color.equals(DyeColor.BLUE)) { + item = Items.BLUE_WOOL; + } else if (color.equals(DyeColor.LIGHT_BLUE)) { + item = Items.LIGHT_BLUE_WOOL; + } else if (color.equals(DyeColor.GREEN)) { + item = Items.GREEN_WOOL; + } else if (color.equals(DyeColor.LIME)) { + item = Items.LIME_WOOL; + } else if (color.equals(DyeColor.CYAN)) { + item = Items.CYAN_WOOL; + } else if (color.equals(DyeColor.MAGENTA)) { + item = Items.MAGENTA_WOOL; + } else if (color.equals(DyeColor.ORANGE)) { + item = Items.ORANGE_WOOL; + } else if (color.equals(DyeColor.PINK)) { + item = Items.PINK_WOOL; + } else if (color.equals(DyeColor.PURPLE)) { + item = Items.PURPLE_WOOL; + } else if (color.equals(DyeColor.RED)) { + item = Items.RED_WOOL; + } else if (color.equals(DyeColor.YELLOW)) { + item = Items.YELLOW_WOOL; + } + user.level().addFreshEntity(new ItemEntity(user.level(), pos.x, pos.y, pos.z, new ItemStack(item, amount))); + return InteractionResult.SUCCESS; + } + } else if (entity instanceof Horse horse) { + horse.playAmbientSound(); + horse.setBaby(true); + user.level() + .addFreshEntity(new ItemEntity(user.level(), pos.x, pos.y, pos.z, new ItemStack(Items.LEATHER, amount))); + return InteractionResult.SUCCESS; + } else if (entity instanceof Cow cow) { + cow.playAmbientSound(); + cow.setBaby(true); + user.level() + .addFreshEntity(new ItemEntity(user.level(), pos.x, pos.y, pos.z, new ItemStack(Items.LEATHER, amount))); + return InteractionResult.SUCCESS; + } else if (entity instanceof Chicken chicken) { + chicken.playAmbientSound(); + chicken.setBaby(true); + user.level() + .addFreshEntity(new ItemEntity(user.level(), pos.x, pos.y, pos.z, new ItemStack(Items.FEATHER, amount))); + return InteractionResult.SUCCESS; + } + return InteractionResult.PASS; + } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderShovel.java b/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderShovel.java new file mode 100644 index 0000000..0df3be6 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderShovel.java @@ -0,0 +1,97 @@ +package de.jottyfan.minecraft.item; + +import java.util.List; + +import com.google.common.collect.Lists; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ShovelItem; +import net.minecraft.world.item.ToolMaterial; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +/** + * + * @author jotty + * + */ +public class ToolQuickiepowderShovel extends ShovelItem implements ToolRangeable { + public static final Integer DEFAULT_HARVEST_RANGE = 6; + private final static ToolMaterial MATERIAL = new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, 2400, 7f, 1f, 15, ItemTags.DIAMOND_TOOL_MATERIALS); + public HarvestRange range; + + public ToolQuickiepowderShovel(Properties properties) { + super(MATERIAL, 7F, -3.1F, properties); + this.range = new HarvestRange(DEFAULT_HARVEST_RANGE); + } + + private void createPathOnGrass(Level level, BlockPos pos, Direction side) { + BlockState blockState = level.getBlockState(pos); + if (blockState.isAir()) { + // try to find one underneath + pos = pos.below(); + blockState = level.getBlockState(pos); + } else if (!level.getBlockState(pos.above()).isAir()) { + pos = pos.above(); + blockState = level.getBlockState(pos); + } + if (side != Direction.DOWN) { + if (blockState != null && level.getBlockState(pos.above()).isAir()) { + if (!level.isClientSide()) { + level.setBlock(pos, blockState, 11); + } + } + } + } + + @Override + public InteractionResult useOn(UseOnContext context) { + Level level = context.getLevel(); + BlockPos pos = context.getClickedPos(); + BlockPos[] positions = new BlockPos[] { pos.north().north().west().west(), pos.north().north().west(), + pos.north().north(), pos.north().north().east(), pos.north().north().east().east(), pos.north().west().west(), + pos.north().west(), pos.north(), pos.north().east(), pos.north().east().east(), pos.west().west(), pos.west(), + pos, pos.east(), pos.east().east(), pos.south().west().west(), pos.south().west(), pos.south(), + pos.south().east(), pos.south().east().east(), pos.south().south().west().west(), pos.south().south().west(), + pos.south().south(), pos.south().south().east(), pos.south().south().east().east() }; + for (BlockPos p : positions) { + createPathOnGrass(level, p, context.getClickedFace()); + } + return super.useOn(context); + } + + @Override + public HarvestRange getRange(ItemStack stack) { + // TODO: get range from stack + return range; + } + + @Override + public boolean canBreakNeighbors(BlockState blockState) { + return new ItemStack(this).isCorrectToolForDrops(blockState); + } + + @Override + public List getBlockList(Block block) { + return Lists.newArrayList(block); + } + +// @Override +// public ActionResult onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { +// CommonToolCode.onItemRightClick(worldIn, playerIn, handIn); +// return super.onItemRightClick(worldIn, playerIn, handIn); +// } +// +// @Override +// public void addInformation(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn) { +// CommonToolCode.addInformation(stack, worldIn, tooltip, flagIn); +// super.addInformation(stack, worldIn, tooltip, flagIn); +// } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderWaterHoe.java b/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderWaterHoe.java new file mode 100644 index 0000000..794279f --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolQuickiepowderWaterHoe.java @@ -0,0 +1,47 @@ +package de.jottyfan.minecraft.item; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +/** + * + * @author jotty + * + */ +public class ToolQuickiepowderWaterHoe extends ToolQuickiepowderHoe { + private Item fallbackHoe; + + public ToolQuickiepowderWaterHoe(Properties properties, Item fallbackHoe) { + super(properties); + this.fallbackHoe = fallbackHoe; + } + + @Override + public InteractionResult useOn(UseOnContext context) { + InteractionResult res = super.useOn(context); + if (!InteractionResult.PASS.equals(res)) { + BlockPos pos = context.getClickedPos(); + Level level = context.getLevel(); + BlockState oldBlockState = level.getBlockState(pos); + level.setBlockAndUpdate(pos, Blocks.WATER.defaultBlockState()); + InteractionHand hand = context.getHand(); + Player player = context.getPlayer(); + ItemStack oldTool = player.getItemInHand(hand); + ItemStack newTool = new ItemStack(fallbackHoe); + newTool.setDamageValue(oldTool.getDamageValue()); + level.addFreshEntity( + new ItemEntity(level, pos.getX(), pos.getY(), pos.getZ(), new ItemStack(oldBlockState.getBlock()))); + player.setItemInHand(hand, newTool); + } + return res; + } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolRangeable.java b/src/main/java/de/jottyfan/minecraft/item/ToolRangeable.java new file mode 100644 index 0000000..57b48ed --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolRangeable.java @@ -0,0 +1,39 @@ +package de.jottyfan.minecraft.item; + +import java.util.List; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + + +/** + * + * @author jotty + * + */ +public interface ToolRangeable { + + /** + * @param stack the item stack that keeps the range + * @return range of blocks to be harvested + */ + public HarvestRange getRange(ItemStack stack); + + /** + * check if this block state is one that affects the neighbor blocks to break + * also if they are from the same type + * + * @param blockState the block state of the current block + * @return true or false + */ + public boolean canBreakNeighbors(BlockState blockState); + + /** + * get list of blocks that belong together (could be useful for stripped logs) + * + * @param block of the set + * @return the list of blocks or null if not found + */ + public List getBlockList(Block block); +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolRangeableAxe.java b/src/main/java/de/jottyfan/minecraft/item/ToolRangeableAxe.java new file mode 100644 index 0000000..353c748 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolRangeableAxe.java @@ -0,0 +1,63 @@ +package de.jottyfan.minecraft.item; + +import java.util.List; + +import com.google.common.collect.Lists; + +import net.minecraft.tags.BlockTags; +import net.minecraft.world.item.AxeItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ToolMaterial; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; + +/** + * + * @author jotty + * + */ +public abstract class ToolRangeableAxe extends AxeItem implements ToolRangeable { + + protected ToolRangeableAxe(ToolMaterial material, float attackDamage, float attackSpeed, Properties properties) { + super(material, attackDamage, attackSpeed, properties); + } + + @Override + public HarvestRange getRange(ItemStack stack) { + // TODO: get the range from the stack + return new HarvestRange(16, 32, 16); + } + + /** + * check if the block is a leaves block + * + * @param blockIn the block + * @return true or false + */ + private boolean isLeavesBlock(BlockState blockIn) { + boolean vanillaLeaves = blockIn.getBlock() instanceof LeavesBlock; + boolean terrestriaLeaves = false; + try { + Class extendedLeavesBlock = Class.forName("com.terraformersmc.terraform.leaves.block.ExtendedLeavesBlock"); + terrestriaLeaves = extendedLeavesBlock.isInstance(blockIn.getBlock()); + } catch (ClassNotFoundException e) { + // no terrestria mod available, so ignore this + // using this approach instead of the instanceof functionality, we don't need to refer to terrestria + // and omit a crash on installations that do not have or want terrestria available + } + boolean blockTagLeaves = blockIn.is(BlockTags.LEAVES); + return vanillaLeaves || terrestriaLeaves || blockTagLeaves; + } + + @Override + public boolean canBreakNeighbors(BlockState blockIn) { + return new ItemStack((ItemLike) this).isCorrectToolForDrops(blockIn) || isLeavesBlock(blockIn) || blockIn.is(BlockTags.LOGS); + } + + @Override + public List getBlockList(Block block) { + return Lists.newArrayList(block); + } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolRangeableHoe.java b/src/main/java/de/jottyfan/minecraft/item/ToolRangeableHoe.java new file mode 100644 index 0000000..24c33a5 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolRangeableHoe.java @@ -0,0 +1,96 @@ +package de.jottyfan.minecraft.item; + +import java.util.List; + +import com.google.common.collect.Lists; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.HoeItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ToolMaterial; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.CropBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; + +/** + * + * @author jotty + * + */ +public abstract class ToolRangeableHoe extends HoeItem implements ToolRangeable { + + public HarvestRange range; + + public ToolRangeableHoe(ToolMaterial material, float attackDamage, float attackSpeed, Properties properties, HarvestRange range) { + super(material, attackDamage, attackSpeed, properties); + this.range = range; + } + + @Override + public InteractionResult useOn(UseOnContext context) { + InteractionResult res = super.useOn(context); + boolean isCrop = context.getLevel().getBlockState(context.getClickedPos()).getBlock() instanceof CropBlock; + if (!InteractionResult.PASS.equals(res) || isCrop) { + for (int x = -this.range.getxRange(); x <= this.range.getxRange(); x++) { + for (int y = -this.range.getyRange(); y <= this.range.getyRange(); y++) { + for (int z = -this.range.getzRange(); z <= this.range.getzRange(); z++) { + if (!isCrop) { + removePossibleGrass(context.getLevel(), new BlockPos(x, y, z)); + BlockHitResult bhr = new BlockHitResult(context.getClickedPos().getCenter(), Direction.UP, + context.getClickedPos().offset(x, y, z), false); + UseOnContext ctx = new UseOnContext(context.getPlayer(), context.getHand(), bhr); + super.useOn(ctx); + } else { + harvestIfPossible(context.getClickedPos().offset(x, y, z), context.getLevel()); + } + } + } + } + } + return res; + } + + private void removePossibleGrass(Level level, BlockPos pos) { + Block block = level.getBlockState(pos).getBlock(); + Boolean grassFound = Blocks.FERN.equals(block) || Blocks.LARGE_FERN.equals(block) + || Blocks.SHORT_GRASS.equals(block) || Blocks.TALL_GRASS.equals(block); + if (grassFound) { + level.destroyBlock(pos, true); + } + } + + private void harvestIfPossible(BlockPos pos, Level level) { + BlockState blockState = level.getBlockState(pos); + Block block = blockState.getBlock(); + if (block instanceof CropBlock) { + CropBlock cBlock = (CropBlock) block; + if (cBlock.isMaxAge(blockState)) { + Block.dropResources(blockState, level, pos); + level.setBlockAndUpdate(pos, cBlock.defaultBlockState().setValue(CropBlock.AGE, 0)); + } + } + } + + @Override + public HarvestRange getRange(ItemStack stack) { + // TODO: get range from stack + return range; + } + + @Override + public boolean canBreakNeighbors(BlockState blockState) { + return new ItemStack(this).isCorrectToolForDrops(blockState) || Blocks.TALL_GRASS.equals(blockState.getBlock()) + || Blocks.FERN.equals(blockState.getBlock()) || Blocks.LARGE_FERN.equals(blockState.getBlock()); + } + + @Override + public List getBlockList(Block block) { + return Lists.newArrayList(block); + } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderAxe.java b/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderAxe.java new file mode 100644 index 0000000..d32db79 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderAxe.java @@ -0,0 +1,26 @@ +package de.jottyfan.minecraft.item; + +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ToolMaterial; + +/** + * + * @author jotty + * + */ +public class ToolSpeedpowderAxe extends ToolRangeableAxe { + + private final static ToolMaterial MATERIAL = new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, 800, 7f, 1f, 15, ItemTags.DIAMOND_TOOL_MATERIALS); + + public ToolSpeedpowderAxe(Properties properties) { + super(MATERIAL, 7f, -3.1f, properties); + } + + @Override + public HarvestRange getRange(ItemStack stack) { + // TODO: get the range from the stack + return new HarvestRange(32, 64, 32); + } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderHoe.java b/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderHoe.java new file mode 100644 index 0000000..383443d --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderHoe.java @@ -0,0 +1,20 @@ +package de.jottyfan.minecraft.item; + +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.item.ToolMaterial; + +/** + * + * @author jotty + * + */ +public class ToolSpeedpowderHoe extends ToolRangeableHoe { + + public static final Integer DEFAULT_PLOW_RANGE = 2; + private final static ToolMaterial MATERIAL = new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, 800, 7f, 1f, 15, ItemTags.DIAMOND_TOOL_MATERIALS); + + public ToolSpeedpowderHoe(Properties properties) { + super(MATERIAL, 7F, -3.1F, properties, new HarvestRange(DEFAULT_PLOW_RANGE)); + } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderPickaxe.java b/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderPickaxe.java new file mode 100644 index 0000000..8073ed5 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderPickaxe.java @@ -0,0 +1,55 @@ +package de.jottyfan.minecraft.item; + +import java.util.List; + +import com.google.common.collect.Lists; + +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ToolMaterial; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +/** + * + * @author jotty + * + */ +public class ToolSpeedpowderPickaxe extends Item implements ToolRangeable { + + public static final int[] DEFAULT_HARVEST_RANGE = new int[] { 3, 3, 3 }; + private final static ToolMaterial MATERIAL = new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, 800, 7.0F, 1.0F, 15, ItemTags.DIAMOND_TOOL_MATERIALS); + + public ToolSpeedpowderPickaxe(Properties properties) { + super(properties.pickaxe(MATERIAL, 7F, -3.1F)); + } + + @Override + public HarvestRange getRange(ItemStack stack) { + return new HarvestRange(DEFAULT_HARVEST_RANGE); + } + + @Override + public boolean canBreakNeighbors(BlockState blockIn) { + return new ItemStack(this).isCorrectToolForDrops(blockIn); + } + + @Override + public List getBlockList(Block block) { + return Lists.newArrayList(block); + } + +// @Override +// public ActionResult onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { +// CommonToolCode.onItemRightClick(worldIn, playerIn, handIn); +// return super.onItemRightClick(worldIn, playerIn, handIn); +// } +// +// @Override +// public void addInformation(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn) { +// CommonToolCode.addInformation(stack, worldIn, tooltip, flagIn); +// super.addInformation(stack, worldIn, tooltip, flagIn); +// } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderShears.java b/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderShears.java new file mode 100644 index 0000000..2e002d9 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderShears.java @@ -0,0 +1,105 @@ +package de.jottyfan.minecraft.item; + +import java.util.Random; + +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.animal.chicken.Chicken; +import net.minecraft.world.entity.animal.cow.Cow; +import net.minecraft.world.entity.animal.equine.Horse; +import net.minecraft.world.entity.animal.sheep.Sheep; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.ShearsItem; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.phys.Vec3; + +/** + * + * @author jotty + * + */ +public class ToolSpeedpowderShears extends ShearsItem { + + public ToolSpeedpowderShears(Properties properties) { + super(properties.component(DataComponents.TOOL, ShearsItem.createToolProperties())); + } + + @Override + public InteractionResult useOn(UseOnContext context) { + return super.useOn(context); + } + + @Override + public InteractionResult interactLivingEntity(ItemStack stack, Player user, LivingEntity entity, + InteractionHand hand) { + Vec3 pos = entity.position(); + Integer amount = 1 + new Random().nextInt(4); + if (entity instanceof Sheep sheep) { + if (!sheep.isSheared()) { + sheep.setSheared(true); + sheep.playAmbientSound(); + DyeColor color = sheep.getColor(); + Item item = Items.WHITE_WOOL; + if (color.equals(DyeColor.BLACK)) { + item = Items.BLACK_WOOL; + } else if (color.equals(DyeColor.GRAY)) { + item = Items.GRAY_WOOL; + } else if (color.equals(DyeColor.LIGHT_GRAY)) { + item = Items.LIGHT_GRAY_WOOL; + } else if (color.equals(DyeColor.BROWN)) { + item = Items.BROWN_WOOL; + } else if (color.equals(DyeColor.BLUE)) { + item = Items.BLUE_WOOL; + } else if (color.equals(DyeColor.LIGHT_BLUE)) { + item = Items.LIGHT_BLUE_WOOL; + } else if (color.equals(DyeColor.GREEN)) { + item = Items.GREEN_WOOL; + } else if (color.equals(DyeColor.LIME)) { + item = Items.LIME_WOOL; + } else if (color.equals(DyeColor.CYAN)) { + item = Items.CYAN_WOOL; + } else if (color.equals(DyeColor.MAGENTA)) { + item = Items.MAGENTA_WOOL; + } else if (color.equals(DyeColor.ORANGE)) { + item = Items.ORANGE_WOOL; + } else if (color.equals(DyeColor.PINK)) { + item = Items.PINK_WOOL; + } else if (color.equals(DyeColor.PURPLE)) { + item = Items.PURPLE_WOOL; + } else if (color.equals(DyeColor.RED)) { + item = Items.RED_WOOL; + } else if (color.equals(DyeColor.YELLOW)) { + item = Items.YELLOW_WOOL; + } + user.level().addFreshEntity(new ItemEntity(user.level(), pos.x, pos.y, pos.z, new ItemStack(item, amount))); + return InteractionResult.SUCCESS; + } + } else if (entity instanceof Horse horse) { + horse.playAmbientSound(); + horse.setBaby(true); + user.level() + .addFreshEntity(new ItemEntity(user.level(), pos.x, pos.y, pos.z, new ItemStack(Items.LEATHER, amount))); + return InteractionResult.SUCCESS; + } else if (entity instanceof Cow cow) { + cow.playAmbientSound(); + cow.setBaby(true); + user.level() + .addFreshEntity(new ItemEntity(user.level(), pos.x, pos.y, pos.z, new ItemStack(Items.LEATHER, amount))); + return InteractionResult.SUCCESS; + } else if (entity instanceof Chicken chicken) { + chicken.playAmbientSound(); + chicken.setBaby(true); + user.level() + .addFreshEntity(new ItemEntity(user.level(), pos.x, pos.y, pos.z, new ItemStack(Items.FEATHER, amount))); + return InteractionResult.SUCCESS; + } + return InteractionResult.PASS; + } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderShovel.java b/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderShovel.java new file mode 100644 index 0000000..ecb4868 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderShovel.java @@ -0,0 +1,96 @@ +package de.jottyfan.minecraft.item; + +import java.util.List; + +import com.google.common.collect.Lists; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ShovelItem; +import net.minecraft.world.item.ToolMaterial; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +/** + * + * @author jotty + * + */ +public class ToolSpeedpowderShovel extends ShovelItem implements ToolRangeable { + public static final Integer DEFAULT_HARVEST_RANGE = 3; + private final static ToolMaterial MATERIAL = new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, 800, 7f, 1f, 15, ItemTags.DIAMOND_TOOL_MATERIALS); + public HarvestRange range; + + public ToolSpeedpowderShovel(Properties properties) { + super(MATERIAL, 7F, -3.1F, properties); + this.range = new HarvestRange(DEFAULT_HARVEST_RANGE); + } + + private void createPathOnGrass(Level level, BlockPos pos, Direction side) { + BlockState blockState = level.getBlockState(pos); + if (blockState.isAir()) { + // try to find one underneath + pos = pos.below(); + blockState = level.getBlockState(pos); + } else if (!level.getBlockState(pos.above()).isAir()) { + pos = pos.above(); + blockState = level.getBlockState(pos); + } + if (side != Direction.DOWN) { + if (blockState != null && level.getBlockState(pos.above()).isAir()) { + if (!level.isClientSide()) { + level.setBlock(pos, blockState, 11); + } + } + } + } + + @Override + public InteractionResult useOn(UseOnContext context) { + Level level = context.getLevel(); + BlockPos pos = context.getClickedPos(); + createPathOnGrass(level, pos.north(), context.getClickedFace()); + createPathOnGrass(level, pos.north().east(), context.getClickedFace()); + createPathOnGrass(level, pos.north().west(), context.getClickedFace()); + createPathOnGrass(level, pos.east(), context.getClickedFace()); + createPathOnGrass(level, pos.west(), context.getClickedFace()); + createPathOnGrass(level, pos.south(), context.getClickedFace()); + createPathOnGrass(level, pos.south().east(), context.getClickedFace()); + createPathOnGrass(level, pos.south().west(), context.getClickedFace()); + return super.useOn(context); + } + + @Override + public HarvestRange getRange(ItemStack stack) { + // TODO: get range from stack + return range; + } + + @Override + public boolean canBreakNeighbors(BlockState blockState) { + return new ItemStack(this).isCorrectToolForDrops(blockState); + } + + @Override + public List getBlockList(Block block) { + return Lists.newArrayList(block); + } + +// @Override +// public ActionResult onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { +// CommonToolCode.onItemRightClick(worldIn, playerIn, handIn); +// return super.onItemRightClick(worldIn, playerIn, handIn); +// } +// +// @Override +// public void addInformation(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn) { +// CommonToolCode.addInformation(stack, worldIn, tooltip, flagIn); +// super.addInformation(stack, worldIn, tooltip, flagIn); +// } +} diff --git a/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderWaterHoe.java b/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderWaterHoe.java new file mode 100644 index 0000000..17c0065 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/item/ToolSpeedpowderWaterHoe.java @@ -0,0 +1,47 @@ +package de.jottyfan.minecraft.item; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +/** + * + * @author jotty + * + */ +public class ToolSpeedpowderWaterHoe extends ToolSpeedpowderHoe { + private Item fallbackHoe; + + public ToolSpeedpowderWaterHoe(Properties properties, Item fallbackHoe) { + super(properties); + this.fallbackHoe = fallbackHoe; + } + + @Override + public InteractionResult useOn(UseOnContext context) { + InteractionResult res = super.useOn(context); + if (!InteractionResult.PASS.equals(res)) { + BlockPos pos = context.getClickedPos(); + Level level = context.getLevel(); + BlockState oldBlockState = level.getBlockState(pos); + level.setBlockAndUpdate(pos, Blocks.WATER.defaultBlockState()); + InteractionHand hand = context.getHand(); + Player player = context.getPlayer(); + ItemStack oldTool = player.getItemInHand(hand); + ItemStack newTool = new ItemStack(fallbackHoe); + newTool.setDamageValue(oldTool.getDamageValue()); + level.addFreshEntity( + new ItemEntity(level, pos.getX(), pos.getY(), pos.getZ(), new ItemStack(oldBlockState.getBlock()))); + player.setItemInHand(hand, newTool); + } + return res; + } +} diff --git a/src/main/resources/assets/quickly/items/quickiepowderaxe.json b/src/main/resources/assets/quickly/items/quickiepowderaxe.json new file mode 100644 index 0000000..106004d --- /dev/null +++ b/src/main/resources/assets/quickly/items/quickiepowderaxe.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "quickly:item/quickiepowderaxe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/quickiepowderhoe.json b/src/main/resources/assets/quickly/items/quickiepowderhoe.json new file mode 100644 index 0000000..be9c7fc --- /dev/null +++ b/src/main/resources/assets/quickly/items/quickiepowderhoe.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "quickly:item/quickiepowderhoe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/quickiepowderpickaxe.json b/src/main/resources/assets/quickly/items/quickiepowderpickaxe.json new file mode 100644 index 0000000..74bd4bc --- /dev/null +++ b/src/main/resources/assets/quickly/items/quickiepowderpickaxe.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "quickly:item/quickiepowderpickaxe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/quickiepowdershears.json b/src/main/resources/assets/quickly/items/quickiepowdershears.json new file mode 100644 index 0000000..51a2b9f --- /dev/null +++ b/src/main/resources/assets/quickly/items/quickiepowdershears.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "quickly:item/quickiepowdershears" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/quickiepowdershovel.json b/src/main/resources/assets/quickly/items/quickiepowdershovel.json new file mode 100644 index 0000000..1bf2ab6 --- /dev/null +++ b/src/main/resources/assets/quickly/items/quickiepowdershovel.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "quickly:item/quickiepowdershovel" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/quickiepowderwaterhoe.json b/src/main/resources/assets/quickly/items/quickiepowderwaterhoe.json new file mode 100644 index 0000000..b56c3b9 --- /dev/null +++ b/src/main/resources/assets/quickly/items/quickiepowderwaterhoe.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "quickly:item/quickiepowderwaterhoe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/speedpowderaxe.json b/src/main/resources/assets/quickly/items/speedpowderaxe.json new file mode 100644 index 0000000..b17572e --- /dev/null +++ b/src/main/resources/assets/quickly/items/speedpowderaxe.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "quickly:item/speedpowderaxe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/speedpowderhoe.json b/src/main/resources/assets/quickly/items/speedpowderhoe.json new file mode 100644 index 0000000..ff1de1c --- /dev/null +++ b/src/main/resources/assets/quickly/items/speedpowderhoe.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "quickly:item/speedpowderhoe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/speedpowderpickaxe.json b/src/main/resources/assets/quickly/items/speedpowderpickaxe.json new file mode 100644 index 0000000..6e8b992 --- /dev/null +++ b/src/main/resources/assets/quickly/items/speedpowderpickaxe.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "quickly:item/speedpowderpickaxe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/speedpowdershears.json b/src/main/resources/assets/quickly/items/speedpowdershears.json new file mode 100644 index 0000000..eecb506 --- /dev/null +++ b/src/main/resources/assets/quickly/items/speedpowdershears.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "quickly:item/speedpowdershears" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/speedpowdershovel.json b/src/main/resources/assets/quickly/items/speedpowdershovel.json new file mode 100644 index 0000000..7898517 --- /dev/null +++ b/src/main/resources/assets/quickly/items/speedpowdershovel.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "quickly:item/speedpowdershovel" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/speedpowderwaterhoe.json b/src/main/resources/assets/quickly/items/speedpowderwaterhoe.json new file mode 100644 index 0000000..6d94c4b --- /dev/null +++ b/src/main/resources/assets/quickly/items/speedpowderwaterhoe.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "quickly:item/speedpowderwaterhoe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/lang/de_de.json b/src/main/resources/assets/quickly/lang/de_de.json index b15d0b6..58467e4 100644 --- a/src/main/resources/assets/quickly/lang/de_de.json +++ b/src/main/resources/assets/quickly/lang/de_de.json @@ -1,4 +1,17 @@ { + "item.quickly.speedpowderaxe": "Fluchtpulveraxt", + "item.quickly.speedpowderpickaxe": "Fluchtpulverspitzhacke", + "item.quickly.speedpowdershovel": "Fluchtpulverschaufel", + "item.quickly.speedpowderhoe": "Fluchtpulverfeldhacke", + "item.quickly.speedpowderwaterhoe": "bewässerte Fluchtpulverfeldhacke", + "item.quickly.speedpowdershears": "Fluchtpulverschere", + "item.quickly.quickiepowderaxe": "Eilpulveraxt", + "item.quickly.quickiepowderpickaxe": "Eilpulverspitzhacke", + "item.quickly.quickiepowdershovel": "Eilpulverschaufel", + "item.quickly.quickiepowderhoe": "Eilpulverfeldhacke", + "item.quickly.quickiepowderwaterhoe": "bewässerte Eilpulverfeldhacke", + "item.quickly.quickiepowdershears": "Eilpulverschere", + "info.block.drillfuel": "Ladung: %s Bohrungen", "info.block.itemhoarder": "enthält: %s", "info.block.monsterhoarder": "Radius: %s, Brenndauer: %s Ticks", diff --git a/src/main/resources/assets/quickly/lang/en_us.json b/src/main/resources/assets/quickly/lang/en_us.json index fe3bbdf..fcb62bb 100644 --- a/src/main/resources/assets/quickly/lang/en_us.json +++ b/src/main/resources/assets/quickly/lang/en_us.json @@ -1,4 +1,17 @@ { + "item.quickly.speedpowderaxe": "speedpowder axe", + "item.quickly.speedpowderpickaxe": "speedpowder pickaxe", + "item.quickly.speedpowdershovel": "speedpowder shovel", + "item.quickly.speedpowderhoe": "speedpowder hoe", + "item.quickly.speedpowderwaterhoe": "watered speedpowder hoe", + "item.quickly.speedpowdershears": "speedpowder shears", + "item.quickly.quickiepowderaxe": "hurrypowder axe", + "item.quickly.quickiepowderpickaxe": "hurrypowder pickaxe", + "item.quickly.quickiepowdershovel": "hurrypowder shovel", + "item.quickly.quickiepowderhoe": "hurrypowder hoe", + "item.quickly.quickiepowderwaterhoe": "watered hurrypowder hoe", + "item.quickly.quickiepowdershears": "hurrypowder shears", + "info.block.drillfuel": "Load: %s drills", "info.block.itemhoarder": "contains: %s", "info.block.monsterhoarder": "radius: %s, burn ticks: %s", diff --git a/src/main/resources/assets/quickly/models/item/quickiepowderaxe.json b/src/main/resources/assets/quickly/models/item/quickiepowderaxe.json new file mode 100644 index 0000000..ce29cb7 --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/quickiepowderaxe.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "quickly:item/quickiepowderaxe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/item/quickiepowderhoe.json b/src/main/resources/assets/quickly/models/item/quickiepowderhoe.json new file mode 100644 index 0000000..41c8884 --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/quickiepowderhoe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "quickly:item/quickiepowderhoe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/item/quickiepowderpickaxe.json b/src/main/resources/assets/quickly/models/item/quickiepowderpickaxe.json new file mode 100644 index 0000000..0aa1f69 --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/quickiepowderpickaxe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "quickly:item/quickiepowderpickaxe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/item/quickiepowdershears.json b/src/main/resources/assets/quickly/models/item/quickiepowdershears.json new file mode 100644 index 0000000..9259e8f --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/quickiepowdershears.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "quickly:item/quickiepowdershears" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/item/quickiepowdershovel.json b/src/main/resources/assets/quickly/models/item/quickiepowdershovel.json new file mode 100644 index 0000000..7a5e5d5 --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/quickiepowdershovel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "quickly:item/quickiepowdershovel" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/item/quickiepowderwaterhoe.json b/src/main/resources/assets/quickly/models/item/quickiepowderwaterhoe.json new file mode 100644 index 0000000..baf865e --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/quickiepowderwaterhoe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "quickly:item/quickiepowderwaterhoe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/item/speedpowderaxe.json b/src/main/resources/assets/quickly/models/item/speedpowderaxe.json new file mode 100644 index 0000000..f36839f --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/speedpowderaxe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "quickly:item/speedpowderaxe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/item/speedpowderhoe.json b/src/main/resources/assets/quickly/models/item/speedpowderhoe.json new file mode 100644 index 0000000..af2019d --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/speedpowderhoe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "quickly:item/speedpowderhoe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/item/speedpowderpickaxe.json b/src/main/resources/assets/quickly/models/item/speedpowderpickaxe.json new file mode 100644 index 0000000..34015fd --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/speedpowderpickaxe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "quickly:item/speedpowderpickaxe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/item/speedpowdershears.json b/src/main/resources/assets/quickly/models/item/speedpowdershears.json new file mode 100644 index 0000000..28126cb --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/speedpowdershears.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "quickly:item/speedpowdershears" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/item/speedpowdershovel.json b/src/main/resources/assets/quickly/models/item/speedpowdershovel.json new file mode 100644 index 0000000..e76e6de --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/speedpowdershovel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "quickly:item/speedpowdershovel" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/item/speedpowderwaterhoe.json b/src/main/resources/assets/quickly/models/item/speedpowderwaterhoe.json new file mode 100644 index 0000000..f10b42e --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/speedpowderwaterhoe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "quickly:item/speedpowderwaterhoe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/textures/item/quickiepowderaxe.png b/src/main/resources/assets/quickly/textures/item/quickiepowderaxe.png new file mode 100644 index 0000000000000000000000000000000000000000..0aa56aab8a33c74799ca9cb3358ad858fb4efaa6 GIT binary patch literal 4650 zcmeHKeNYo;9$v0(P{h_wb%0jRZM;K0-DG#On`HNrpe8732~dcrwLRTzHen^nhGda| z)uL@dv{TW$w#cB+a^rD_wzbvsv&tRPa#DdgPl|e?hTcazUWunIy#tPWH{o;IPKTN6 z{Y7T>*ax6Mv^{eA!rK{Y;j4PFB6p`u>h4!@4+D zYv_&B(Ur4_Ijy8q%)NZ!;(bl!>dMUMmD`=~{M|dJ>&JK2IW|)N&e-qGfAgcgmicIsew$S~U0W+RBDk`ycu3eXF~49p($6vuRuX$l3Sx zCl`KHR#E%jj<%>@*4+O`T}#`N&c_Dxx~*mDSh@0(8wb)G+Jr-IUws&YqF&&Q z#!R!(IMNU3qI%07eQMLvxy|ddkICmmt9FPjnfq_QDSzcyOiKN%jW6XSrYQ!uCn4sY zyXtN}?G3Rqi5clT6p-P>s}!SdK;OpZJKwd_#h`o3wQFBBiVH_$#v$&Q_AE-5k1b&{8oy5R#? zj^{BrC5>hUw}P5?y#d$1c zmnR!ybO9OwxH*x518$ecPY3k!FfI+=C9_fvheO0Xy?l)&6E+Gy4ki?Y0!2~+{3cv( zh=FxJyMxX$tr&&?BfUIV6uq=kSy))8C{!r~pHqoZ6s1IQC5|H?0`V7lL?(cE{PQJ< z2!@ICvp(J{@`4AJFd3UrAnN6E;D<-*b9*h8QFxDkm<7OxGQfD1m;zP0-OBM9elcYe z02wam8#DY?uuGL$oL?yLv0Ta~&Lhqr4`F9V^SuQ=SGXNJtK?jq8-)77tk{GpSDG!E zqZtwfPTuVeX92P&M2fs)jI0T@NuF>!;|l@lqqq~IM|uwjgD8uIHVJHjRG!(SmrL{0 zc7f&XboiAa8J56E7O}A^4MI4y8ic}d@P^?kR%_$5I7*F!GJE_Y<6$`o3V+l*9S_K#3A2hALD<*dr|q4VnSOGLlXK zK-dm?p^ZL{5e1)B5L|k>R1z#@j=C*iJJ}hLF)<q5Uqd1L@ zix=#?qv*S$rOgBDB1@ji`@#H0VN+yBWpnwFQDo@i!&?c4!<&L;*hmY0W)o)**9ov9 zE;g6(I5}{749j)I&VPdxR1|8nF&Y&@;iL^AG-@27Y<3RO*jccQHj>mjv=h<&fJHUjINlmPe#rI{^=Eh55g6<4L<`PlQP?rD@_mq?Sz(Us*8t!Wx6+YtsjDB zJR)6DP*rt2Fh+}JOG@;ovbnPtM0F2}I536Gre#)bE4!gK8tv%p7itgp)wnJ;4`mFt z7axyncs%Vz;-}Bn-VCTu-3 zbUxJ6w4k*8?w6`(P865#*$`iS`nhd)3~|X#TX?cmfAZ4fvNQc@&&5uwx;FIsuAh9> zzUc71d8?-h>fe*sFKa< g+qJDs{cIHU*6yOD;L&Y0pm)fel5Toy`G)QP1#DBBN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/item/quickiepowderhoe.png b/src/main/resources/assets/quickly/textures/item/quickiepowderhoe.png new file mode 100644 index 0000000000000000000000000000000000000000..f8f9f0be5612398c2a55b3e45f62ba35e3135868 GIT binary patch literal 4632 zcmeHKeNYtV9bQR20r6uJGea9CJ4b5k;NI=-?Q(Z3$LF2gAqNa!A?l3oC#>Gx9=D4e zN0o~x@oS<;)k-kN(ot$mjYebCG!hk!^^4j@6BTrz#@JMgEg79CrSIM$;3S=vnff0) zv$ya5KA!jYd*0`L=XP~oPUeK@pF~3tG{IrF=7Z;C^^Vkl--JUWl-5#-`yZvCplGEXkDG_VG_6K_#mJ_RDgngZ>_U@SRdc(Q;_czp3H%2bFF1C3q=1dXW`GcxiV z85vLd0bMjLt+&`uq)u&HP;gND;yA-9<+HqPfBUue&4balmdT4&7EjC8^(~){IM%Ff zzB$+1!|wa*&8|J~*1iizE(?A%K4*+jzmYW$fEC8n^Z)?X%B(@o33irWmj261!Sj)|HMB|EGgICs{KzqriNarLX=z>;?K)XT+V^eP*|%bS&7Z$L`=l4x89nF{-dxUyKU2QVrBXme@e6ThcPD(wYD~1nOFVtu1TqN zN3uGgac{Kx>-S$-+SzfV|Gx##m9`Nx6ft*4%u$VP-+LYwz zBtHcJ+`K}=ez(gbQ+|s!giC?3YSwGvP>8bFqAhXe!5NZ|hY1~_LlK)_T!L$pqv0eU zCs6s;*#i*Z&7v(+6fdRMS5{W)Dh)cxSE|R%X0sl}^*D}z2t=;(D6}8($nh#f7{kiT ztWWeRqU3>9Oq!7@6pL01{P2_d++L@15Z)sXumJeb`)RKp)1i8|TR%KQR%}ZE$Us3q zm?0N}U8>LLWvRl)^0p9)DFk$c^B^np)!~iduqx|hcj<5L#3cp zbbCWtfb6Ft6;T)>>#5pQPpF;Yg@E)y+^3?S^d1TZQBEgimDmckJcreyRp+NTi4{32 zG{gimiwY!xkPM3<1ZiRrCeg?viDr|TGx0P_)66g^heuXu56i1i09+>m9F}KD9%o2| zW&|D~IE+LXmLm|8fEvvVZo&wH9R`u>6M-se*YK)TC=Nj3W`l`0Vj!0`Bq9WsXaLpl zG$P;}&6*Plj3)396vtAtC7+uH%PG3)QeN-%l!hEC;Z$0l!=lA?=#VAPMJobGuxPVI zPlbQTQ7F3k0)pmd7liFsA6KM&On4b>atLv89*$p>J$Kk z?4TDa!^hK# zmeHP49-JNna(!YKe?SVHnK3auFCZjKk_chMQG{X4CImIICXT^Kp25OW7(|yPL8+vD zd|D~s5pV_M8R825xszt$+=3ZT7gJfrtIL4m1_Z+p+)#+&6k(tUV*-k)jOm|!k49D? zXqq-7EK3Rq!4g2Ngc*!5#$aG*BSQ-RbB`f0{-+j61WiP~FN%Q{ll1Dj_+(X+^xs?e zaKNyG6i^ekfdd+x_xiyDe}FTvCeQL3(A%?|0)|H?84~`UF z|E?b|TiSQ3=kBdp8qKZN{x4!a{U*ZPGXCQng!4bRJL`n|jhMRIUws(!I7<^_+>$H2 zQU>i$`!L~Z?6Rc~&-L`&A77Wd_Eqe)=`)`&=A`qWA9H__XJ{E0P9Wbr;uv z^8D?wu^Z4seHZs~tv&KZZC%aY6g(;YQf51pCO_(Tb?uMYej$#1_^;l$y1?}G#;Q#d z$`_sbCL%qtn+%qmFZq4yx(~{a1gE@(%}?EZJ~s8b{;QN-2QJlU0?$GDCl=*q*Dvh` Pok9*JD8G)G literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/item/quickiepowderpickaxe.png b/src/main/resources/assets/quickly/textures/item/quickiepowderpickaxe.png new file mode 100644 index 0000000000000000000000000000000000000000..3b8146b5761c02ee9c06cded00511599a7ce6f72 GIT binary patch literal 4662 zcmeHKeNYtV8DDHY0l{c7GuWuv9Iesf-tO(~-p7^$g*&-Z4k=$T>V&+vw|i{7yFKp~ zI56l9pjEUXLSiDtq?VM>#56^560{8zL?yJ5*2b6^)L_zRrZJ>yNk_=_-Qz=;B-3%G z{>RPi?Y_^)?|q)%`#jI=?#jwckB$CeG=d2J zpkANI3oZ_oO1&J)1q2>J0w1`uHq7ZlV{U&s|EH;z8C6&Mj@A`dF51>q^-6|+`{uepIfIJ|h9U=VsZJglJ~Lua9Q{LgFlbunq|Yw7h`#WC z>!yaGUFQ63YQR4bRj0BHpDud$itZirb2DF9R=@vdQj2Bz{m0jRZqFx+284m;rU#zE z9maEdar3#vqH}LOybb8ZL(BaK`0rbn+oQ-IH8(fziFTbRq%AE^H;q))Z2SAI-jB0; z@)QZDX1vmO@Xf7*DPQ%!miK)9&DzeWUk!C{PCgmzQ}sQee`l!WN^55Dvc}6v!|yI3 zZd=P58_hMrgYL@%#~OdTrQ?%1#J_TLGP<9wpth$*1X3EswAcD-cmcbKlTbV76g)=d7suO`sNgUvAE9l8&6~y*3YIb-ms6IR%a(0o4Gv{W za&%IFfdFn!0%*YP^7xs6Q5nW%;Ik~om1x*R+GJF&vt^-aqK`u<6{R9Db3iC2mC4a) zlFz|2*``%v5O8Hw7D|$r!SRxk5><&tCHkDW+F&r?1c{R*1}!jusYe0<%;QgxAx1Gw zoS*dxUP%x=sEi5hVv%H2Dxn@7kI(J3*(TsU{xKFHA9w(GakYxT-EMrchhH)mLy)n6 zzSYB@3%eB0=KNxjkLAq8oJUHS4B=oW{Jlj!S2!I9i*qi{4Nd)USM`)F)2+6w2@jb9 zr{MO6y&&0BEG2=zL)MhoWKB4o$$>!k3EU~xbD&_qdhsX*J zCj7`#oW{VCT8z{J4x@Cm8Us8DFdeTWDZQH4XlV5$D67XW0T0W`P!L=tKpdL2(>e!D zVGa(cF-q;wVE|ARrXdVk7U&7u4#-ImYkdN&O5mCtl?>&8P&y4w=(PqK(;IXwj7ATm z(NH9&bBvr&6NtO#pJajNB zGXzgj;Ep0!aC12lkl9qjpZ!~(fa zAwXCTb79ha9FRm`t|+>UN;xD{_MA}LU^_X01WZ8UASgl7454L6eJ)8d8a+ePi3G_I zlk7!@z?c3nYq@#Qq|qa{2!6PKX;?JcQ90b^(beeEC4^fEMZ-jAy=?G!(5?DZGc7B<}90PUQ)=($3T!8Os&R9O|BX;W?3 z!oP9uqXv@(DWqmp1_v~p_xQxXALC3Ot@rRZR&V!k2M9gA$zAa~P1iJCcg4V68BbT& zG+lSaz+D+nSJ(fIuIM|TjGPC)>6O3_!g^(FEBu&L*w>_+5DKYAR_GeaLQoRrwLI!a zklAta6@k<@#6#gM$!astx~5n-e~B(~W8Y^`G;B4k%+>d@kH;5w>|B$&I{)7($Ic%) zRkL6hxdJZQGa3@VSM$u$%3w8B89clkUNK$KZK$HSxLEO6oNmXO#3ps^$1_xL*?ysS zL4J>deDbR^Zx4QQt$bDO@J~FRp@N*88{7UGIvd&>>r}2fQq}hPwum2>?>P11R>GD2 z3&+kt>zwPU6^h9E3!xCMIx~2+FMkKV_6yC{+yANisQ2t6F{ZW^eII_E^7`S2x?VnV zD*mmMKh7Gu@#({+c(l+HdeOFV-$%FpWLsLlAU-}m`NQ&xOUU!Q^vijwz^+U0`+hbv zWcbaqU&qCD?|JF`o>*dDG%*lYT@dq_^K1-)B<$xKwVe?pjoGflrseZ1no#F&&k literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/item/quickiepowdershears.png b/src/main/resources/assets/quickly/textures/item/quickiepowdershears.png new file mode 100644 index 0000000000000000000000000000000000000000..cf0a275e0c85983e5898e5656d2dc36c77eb5b10 GIT binary patch literal 4790 zcmeHLYj6|S6<#L++v4Gb3B?m^v&b!vz)GuqNxQXVV@n``rFd-FJesMw+K0SB(h6yf zg_#5mhG0wrffgrWLfYVzxP@khBovBicsLlR%n;KM69T3lle9x8A#R3@+r%!tEBQIi zOvjVbU)IcOckeytyXX7PIeWF*QQ}!PP4}1%L6B)Kr@a)OAJ&ev2jTYuETasbT5G+l z)KXA`h9in32Sile7#2}6CQAqs`y^O$eOfCzwcp>ct9#bkwz=-dtLt`E)*X1ffJ|Il1c>lYS-t!3KW3cH1|eI$hy3^4>px zu;SS5FRonz2kZ8neQEWn?H4ZXXxZT_KGJl#^GaLZ^Bt*QDW3U%nssy8>N(1n=8FiD zQYRM`mAHzEhUh>NuROiS>TE5@I$v3KOg}S~tXJDh4t#!4zw4OJ(fsgJ+bXh)4Fg-| zVXlUqP2Fq4z5LO?b@v=OTz42vdnSHjil@O)+H-Gj;m*vAUEluw&dpnQvQcVL@$uT8 zc<5t^d-;X8eqX-uZiCH^>ZdLN6+us9S#Ne_Us~_ihPJo+KNw&qA3JqE9=B)t=?~}K zL|?u3&bn9nb~q|Zsh((0`p*o`{`TsRZkaDRUYzvm!u>Db%{%H`JhNrh7rqLjx<~G5 zJ~aF1M#0)?QPy`Zs_uMu{$^lNjx3HIkREa^_N5a)Y;JCPP8WEuigq4-;n2X=-J7p` zeeu)M_sb{eUU=X)9j~2urZ@i|UB4}VY5(25=hA=KcYeLCE#6`1c*=6A@93>}Jn?Qa zEUNt<&BMQS)iyObcE?`}cK4iY`t_zWpH0WV@|G2!-?xR@R+tjYZ&Lo4(t7;Nnf+IP zvT4p683oUtT;7GGZa)*-^VZd;Z+88;>-uT`Cj$e>@+$ln z>v&es=i797F%AL*MHQg2U?3FbVpe?umxI^Zuu+dDOw@H&{VI0}TBJlolrm5T9CO6v z4TRpNL-Qhn#Fg5Y4nn{?tG-HA!<^ArQ&VH8Aq`5zZ#1ziYs3j7L154Vi*5|5Aclpa zxf(ev851_Sy|kEjR0Sbk)Sw`^L54UK zC75y2OklK+H)9kf0nBHnc}x^YoTV6xg$MK~h$kX4tV$3V9hC+pKqwPMo6HgqFh(Fu z7$pD;=EHFl#+X@>WoXet(I5dO@Z3@*5(F@vauE1MV>skbOlX30OG;c;Jz>B{MoI!e zm7s%FUo3~JV0=BVet|K{N_kv z5l(RUD0@YarH%j1T5BFOFPUXrd`Nz$Yn0!3I%C z#0jyIQ+yQ&`9=8j7%bPJarrw+frbep%%p%Z1Ocmw#VO1pQX=L9r08QTKA(?GvKmH@ zDw0|QBH|K1)Ddb0%QK-Bx*(CLg=1r>sS>p;-~@%?3}zy|CYGZZjJD1iO|e;nPA&w!rtzBCTa{r0mJD6!VPQlYgjg^Njyd*-3*@TLsL1atv-ka7Qx^ zZ)t;N0pq=&pTUm0pG%i3<*mz!Xs^p;NwL>afFS9!_32r;>2v4JFj*fl=g)GKXF6BT@;sU24b1Tda#n_N z)`W9@8r8j_PCdJI`i;YL`Lt zKc^ijGZ!q6!@*S5<#wdro}Be)*4%4zTi_hxb=jAAGe6vS@%oH7n)XnKBlqo{z4t0- zU#YisPS41aQf%8D<&wGYMEH^8&mO<}*qe7xobKHR8XGsAebLc*V@gZ#$yVp>wYH0R iK^xvK9jr{-9C@(i&I2bem-XdBe8lDO*xxK%yXD`XotIYt literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/item/quickiepowdershovel.png b/src/main/resources/assets/quickly/textures/item/quickiepowdershovel.png new file mode 100644 index 0000000000000000000000000000000000000000..56d2b5d39a3e6af4ddafabe39d3278aa08f3b874 GIT binary patch literal 4642 zcmeHKdr%bj9bat1OHq@eV$`@f9RiWP+t)pIbB73r+!+ojFEKimef$nq?#0~#C((d_ zHlhv!L?8>$z`Ui|jF8-dcO3 zf3S8{SXxwLU2h{5@^qWG27jdJ$+RQ|LK_>6aRZ`(c$ZZX^CepN6*VS5_9gt z)Dvr)ul>7>`g)=DmFFJI)4%0fY>fOg>b!q;@A}?<)q$W#_ zJ?-feTCa6=w;ZfFh=xB~_1@HsI(1fe;DzMvF*BYY_{YtQJvSGi^pf;8N0Ll7Od+J@B2pm(K~lf4Kkr^zv-x|GS4s6{w4Mzy6@cK z;ywM_QuDItZeMrAF16+E@zT$F^q-{u^1*%ajW69cwptQqeUN{H&m&8_rS9ef^M0-o zO=k`6lCw)n&;IW5O3vVJN$~BpKVVJZBgni2L$F_2Ln6iP0W>hB*MRiTn-QmxY3aGNIu6iJo}FUYRQ$Pp@v1x8dY zO^h`9SqR_+GKcz|4wsMhn^Zwu7LFCOMui4LOq04Hf`43yR7lR1|F6etL;mLLwp@f>Z? z@tA=$Xfaw4ag3w&1jg7!LST3X@U(sm#7eIORmnNVR;56R5Xw%7I0f_uI6V(Anipt{ zr|l$$3xZZl<9c3XgdmhCu*=vP`QpOQwU9?J&Wl zN|#)v{!vGc-4=Pc?BycrF2R+KNu&^0OET`xc z0tD@_7dFKUIN9yZal0KRl~NL_WRAFPa65^d%$YeEKv102vbc^V4LKyqQU;dREx}0^ z9~18uCHsc|6|HO@)Ht-{7Rd+a-w-qn?Wk-}GW0g|>X3q42}OgOg5`vv7JOV85QB9> ztRa_B#JLIqJUxcxde1I>j}#1AonF*aI?OQcF&uy2> zIWJgN2zi8DL3swbLgQ?lfUeArA74y)5m1%^Cn<~|Fp|n4NS4M~3Nl70jA`zFkGwzu zlF`u^AZQ&%7=NfmEr#o`?}}o$MWaSJ7w@gA zQS+U39|{<_B1b-APLj6u0U(nOTbwxiUc16!BFzls59u0k9^Zxe- zD@%^P7%-lx3oNO8bfA8IgIU_W{fRrL;@`f#&@?-Id6N>ND_OmDWnn$Bv9h9m=j(D( zi@jxYT#+mA%Bph>aet0eH#E!)1hRixvpN4|Vr`!?h<>?sN`~}C;Nge616Ld8g$!(5 W+qmZA{5h~?#G0C6{&jLe^?v{eHjC~6 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/item/quickiepowderwaterhoe.png b/src/main/resources/assets/quickly/textures/item/quickiepowderwaterhoe.png new file mode 100644 index 0000000000000000000000000000000000000000..52cc760ec1390589db954bac7a4bfd3807ff9bc9 GIT binary patch literal 4676 zcmeHLeNYtV8DGGje5q*6j0)Dxk&sy2yS@Fmk1Yoxhu$fNe2I`+!`|-RvC7>Zw+oyw zC}OnVm4)gYm|J3D!}ieZ-!}bX)n*old|YC z*zFPQd=Upro7^1Cd3ieod9OM%GH15Kp@Uz}{b_LUPk!8W?B~tVcluL08nl(aTJ7Dl zHfYxueIait!h`3WXxKYv!5iiy8@BqE-i^tiDys23Ngu(^>G>$O`_^FgtQP(D4VkCs z-R_C#dHy-yP&s~oQE|oW{6Ds47RNSZhPpDk@($Ge?W@q9t?^P!;kkDz4#)MaYjz5| zwk9}qb5%=3dW|Z}H@tV*&Uv$TJ^bg_*KdBk5GLZ&PL=zrT%Xyg zgL|6aS+n>-O`-`_Mkdp_&h-7+y$fIH3+??@)p=szlR<;xi`#O>AEl8svv0QIv%Ji&zeRtf>TAaf{jyo zoo*mI2ueuux@l%3C&4z(!Mlvgd#z`bFwYv5Ye_3=b*FHJyt&-NWtXStFy$K=1FK9* z3{UV<0KmyfH0*U2xkSoqRQho#a4(zHO4#orZ8R$LtQl~M;Nf6GMW|3D)ytP+%EWLu z!Nc0AEYtE42=HW77D|$vQmf0#%2Z{zO7J+;8iT>0Mlm&pA;1F>H@PI*i@3yC86tpT z;zY*7yCq(5!7?Uo6G|kbQVGW4(fpilt91bGq4Cl;+Rd(YEhk5HxA0;5+&Nja55ACSMdPHt~F>` zTF)RDN#F>B zFe=k{SBdx0Ko0NZvL#w(Q==m_8UjZ#oWL-W43zE1%jG;GP@;^fK~*^650~3Qfnor$ zw5(GA;J1TXs1y%JOM)jy5Q>aS83L9g$A+z7IkB`vn`nsxpeROCsFuR?IT%LaIts<( zQH(;z`3o#>-}Jw{<;4Rh1X^z9MKJ#+zbUYyvbo~GQ{b_P_b(+F_Ad&GW&$OMbScOB z^8{FdA*PUaIXJL;jL3D=&VP>-7>$8obc`O+>1=w0Ffca6z|cB`)@w+dAxK~dNMQ_J z6zozN?ctIgfJeX;kf)z3_&F=hz^k(tPfVt)kdxa0dW2{+2!`iqFp3~4jEqM$GGpq; zUn7U%s0L#V2us>Ygs|IbL{E|!!WwXrWDEqx>TDB}{^1(^V*H^JNd(m*-xbA3i3w_X zUmWdfg8Dms4>*k5NC7ng8`z-1ey<+e@JBcUJ$anRh~6IO6fitB$)xz5qHBt-Nii@f z=P7kf(KRUsCgnV(uKycd;g3EUITv`-D+3>dUtUN$13o4dwpA-k5CPRdOLcYS!@v^e zHs^~F6!C<720^uT^MG->WU;1BzpaRw`%Fl1M_C>C!yv+9O3u+=UasFp5hWV!90j_`G z@A1X!tAfJBp5cL&ipZqCCAR*)|HQV(K3zF&Mig;s_>(x*h2GnDG&}CCzDGAYly4kd z`+3w+`)L)-;_E|R?0&gB;+#JEt-~FIwjpt4{Mmizw!yu_k^fpX)O0JMYUfiY@-I3! zSGu2g-~RBKVT0EM^MCm;v8D6bKB3_1E*cLB3E4*vZkemSL`Ghk1`S2JdrHkcnSd$C MlA3NhwydD~zu+pBIRF3v literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/item/speedpowderaxe.png b/src/main/resources/assets/quickly/textures/item/speedpowderaxe.png new file mode 100644 index 0000000000000000000000000000000000000000..c933955880433ce6f4b98483166fb18fea72cde3 GIT binary patch literal 4399 zcmeHKeNYtV8DByR7Q{lZ6IzI_M-oKcyWPFxZg0bZ2M2P>!Filj3=;Qt--8X@2YU;5 zkf4czMvR|S6B$rUq6r;iI^t)sVj>^bV#GR0YaBJ|R7NEwgK0~(hQ51zPcqYCrumPX z+1uUc`R(s{p5Obt&+Kk8XDtc~`BeylAYsM~g9V<$rDIwU{Ga`Bkb$SR3hN5d!gx`) z;Ii|@02RyK00lnYjv&4-9cKNEz&X=SKdwm%h_Sx5_1g6pp6K_zoLADUZm5cgQp#=( zoPPP%<%ryM@4tKMZe~!Eg>5$QjSXGT#l5Om=03Xh^t;Da$E7!2?Yoq8<#yY}Bck%p zAB0|;XDwO#gy`Sc9apov*J-^ztz=qnkmI$@!so)^r)AwC&qmPu>uiv&6zH4&|;l zH}C2F?O*>{)mN>Xw|MTk^xu><%nXgEw>=)%xT@74 zug-fO7Zx-=6?Wu7@ZkEJ&Byw4YV$2~XNYI0&pM;JkA!yek*>T?G&OYlSJ3W?c?B!?|og z?sK?d;~_|5vd_)1ML?N=a+Ms%(tLawDN71L z69vvrTMX&L6!1Z z01qqhZjpC6QHhhWxk^QyOa}evNPZ5t$uvsu^bD&2^-%a2w}O!43Wq~6{t1tmRt8Ci z6Z*j?JXW|(6&B!el?p6KD+5k3c09!*qsctVAeB_WJKX-Fpm-C4aqKA0T`Cm&F&wJ^ z#lQhcJup9F0$$|pV`5FnP4f858J`FYH_AT&JyN?L3{fT%ZE&%rQc$BoCzJA}ITy=w zwEt2|YVCkilbBYmAu$z0DlrDI1ZGodNJ_;ekaiV0j>_oth>Vj35)~wu^N`2R5eaG) ztHJD~l7keu4bxIeEv8lhl^Up^L8}@^kuC7BE1BZ)SxHnJq|$0QwML6`7)w$x8#Qag zC;)62sa9$z%7#;9g56Igtplw$8+9^Lj*nT)#f)fo2@aji#IR^~&X~u_J3x-eNU9MU z9M`CDLWyfAT!|-)fqo4H59~OJl)&Xmwco?BbULJDVCV1-rT{41&H}$fS{E8t1C?c@ zMup6NJ1mAy6#yf;1gpzctdmK}q7vn(+XVL$$B2x95dn;blS-N(Xi{km?hf44;Wq|YN z3Au(`Y$4+;0C0Q^_v?tA|AAg0aW$Sm*#Ybyih{kMW-*4LG#JMyH8`aNS{rMd$nJ63 zMK2=&eF4-FY6bh#uN69XXbIyd!o7t+S|6wwMiAKd6;ljXtdOS0NXdzc?}?J=2aFpt z@VOxy9A9u6Dn`fQuxQfY`4NA^i}52yfYeh#CZ+F`TvKvQN`Xm%r@CuOu1P5{DezQx z{omvY8T+6DPWT$+g`Z36hQX`wQ!B`}WRU^+7zsv#x6j6BLCeqF8Mz(=35}GF0Hm%y z3L1k&qbV)8C-j+6oU~^zPll#1j0U}x`cwOkOCbSEXLhtI@9jQB9O&3tmswlAC2rxx zKwrS#voHDr@;f8n+0?c&{y=Vh)2ral%B7!{zBh2Z=W%7v>~BJ=*EFUkcVBu%8%=Gk zFn1LO(z)1q`m2y7_PO@(%j-LdbJwE}y)&okEZ%=~84{rvHpD8e9aMaElc!@rR$t}8 zU({_e2fiNuRAjxY_N~S8!zbLC0S`gS-~Ka$0o%S~!gdi{$3OcX9IdHH{P5oImv?`B z!}!9<`*(>Ymg3|62ezGgagSc=2@Z?x^9)3bh!zruR F{TIY6I#d7v literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/item/speedpowderhoe.png b/src/main/resources/assets/quickly/textures/item/speedpowderhoe.png new file mode 100644 index 0000000000000000000000000000000000000000..87e0627d1d1625b2f73d4c1c240f0ca1a019b02a GIT binary patch literal 6016 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/item/speedpowderpickaxe.png b/src/main/resources/assets/quickly/textures/item/speedpowderpickaxe.png new file mode 100644 index 0000000000000000000000000000000000000000..6a7a71d3824a395f895272c4c69cad135787c6cb GIT binary patch literal 4409 zcmeHKeNYtV9bRe*5l%~mPM{#JheS~J_T#=+P6Y0Nlbj%66oU+VyL-om`&jQ5?qG^E zh(?GO0x=n=ALtmSNo`Ct8BtO+A|bV?ajcDvwpgpRModyo{DN|Q_YM#zndvao{Kw7Q z?Y_VF+2{TJp5ODnbK8)&B5PLY&qE;ynq|z^=Ywmw_GZ$vIhuPcb_-&4NucJPwX=ZwE4PS1I^AwFWx zy|cqVi<`R=x!98PcG67h!izRZqvZXKtAB?@{Ac7 z;{|~-cGSG8%kIsK+>~2jIM=xG$A;Lt!iC+x*+Ty={iloS*X~&r()z||TI=QoeSIr= zMDyU#nhJjXpD%p0D*UP1WyR}uM6TO+a=0b^m8f~ef9tRMD)!6npM-zGb{5UWmz}rE zw{Ll+ZRqWb-!_&=^0%cox3L4p{5d_hZp8)l3>vCl_x(O~_3rjVQQ_eY^Z;hRI_qki z>C%-Cb7L)rqJ*UjcVTa(UCnxDaon->vaaN>2i|R4aXRAVhQ9Qe#rA>5&dd~3>`LX% zJDaxlFS>!8S$pJEd(E9^HoG33B0hU7v-!C6bvUiQZqf3@-pto3cSeRKkxj!7US4-h zFWXd{fVq-8el+Xgtq|YF!9yS1DQGRpPn<3EXwLLUefmL|;>BOxtr^m6i+~?Uifd^P87{a^t1@@<*M?7$5e{{wjC*u77+J zlzo1Gi~9IS^RbeSp^Due&*8JT2bY|F_#enJ!?maT-1Z`1ylM^@Y>nwTl6Kl<6yr3r zGOwKn&V!(oR4-4_<*WdkSu5wzNx$koCWSdhCta;HVJ1F%}G3^91QN2r9qus|fF7uq;!#|Np>{hu`3bjRs01Wq z34QMq?n1Cn(R|kJtZ>n+p^|k7@slaCjHbK^2C*b7XXpJz0r8$#jG-rRe1*&A$1pU? z+E_avb%XryC-4Gic`ViwxrsCWawaDNmYd*z0zF>49}G|?6RCI772={sy-q6TOEONH zV@UrkO=uKyB|{;&T1g`c6|O=kv&w?d7Beo_GK5;q$|q479d3bg(5y%W$YmVhF)J;s zg3!>2Mx_N58r+OfYApd68M7KwQYwOACQ;Qlr9^N|p98=y}%V296U+aZDyx`DYlK%mkDaa1LjutSrhqto{kHFC?f2 zC`*Y(1VatY7611-4WHyFM@q3~ii$FTt>XSCAAPD8Wrt zvVm>^uD}#sMmel3I6lVwIv(e~#|v^f!78DLNQ474!GFWLm$Q^tz@0g53wj(k@!bgW`jJT=BkPC>sT zN{Sya>6ih}1!Ca%0;eH5aU70`1~T{|KV!}KA(w#R=|!fb@3dUga!pBrDS@ZmH7(ba z6qpit+Fk!Qxk4YmP_Yj1H^>8Cm*~jPZQxZa*qoE4hYmm?P)PGUEDl6w^4Udh2nvf3 zzd=y@jwlce5sW57$c?aP!q8{mJG<>N2n`zbX@#0U(xp*l$G7C9FMs}C>d}jb`kSH~ zh-F~l`_t+JQTprGqMk}v;J=FZ``$>VO08Ba|JkEHj6NTq*;0JG@5~u~iQ=`i%72@K z<2vt4)NwWJft2#k#`UwwxO( zO+3k8Iq|~gn5G_L!|=n_zkl1CCD9*&EO$q4=jM%!j9z!22=2JFHTnK%U(QJIm4ng2 zC8^c*gMZn1^9!HyT9+>(qHpU(+sFU3?cLkheA=6~d3Wr?_M{-_%Wk&Gw$saiQX!*Z Lh5nuN(z^cw@uoqj literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/item/speedpowdershears.png b/src/main/resources/assets/quickly/textures/item/speedpowdershears.png new file mode 100644 index 0000000000000000000000000000000000000000..11ecda367f2787ed53234438f962552c4d50678d GIT binary patch literal 4790 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/item/speedpowdershovel.png b/src/main/resources/assets/quickly/textures/item/speedpowdershovel.png new file mode 100644 index 0000000000000000000000000000000000000000..b1a4458264578ea7fe276033cb32a05af8124869 GIT binary patch literal 4417 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