diff --git a/LICENSE.md b/LICENSE.md
index a50e13c..9e84fc3 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2021 Florian Berger
+Copyright (c) 2021-2022 Florian Berger
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 05059c3..c99d3db 100644
--- a/README.md
+++ b/README.md
@@ -9,15 +9,38 @@ The 'Mending' enchantment isn't enough for me. So I created a mod that adds such
## Recipes
-The following recipes are added to the game:\
+To craft the ingot, use the following shapeless recipe:\
![Recipe_Ingot](/curseforge/images/Recipe_Ingot.png?raw=true)
+
+With these ingots, you are able to craft the known tools by using the known patterns:\
+![Recipes_Gif](/curseforge/images/tools-recipes.gif?raw=true)
+
+
+
+Recipes as static images
+
+**Axe**\
![Recipe_Axe](/curseforge/images/Recipe_Axe.png?raw=true)
+
+**Hoe**\
![Recipe_Hoe](/curseforge/images/Recipe_Hoe.png?raw=true)
+
+**Pickaxe**\
![Recipe_Pickaxe](/curseforge/images/Recipe_Pickaxe.png?raw=true)
+
+**Shovel**\
![Recipe_Shovel](/curseforge/images/Recipe_Shovel.png?raw=true)
+
+**Sword**\
![Recipe_Sword](/curseforge/images/Recipe_Sword.png?raw=true)
+
+## Multi-Tool
+From **Version 2022.1**, this modification contains a multi-tool. It combines the capabilities of the pickaxe, the shovel and the axe. You can craft it by using the following recipe:\
+![Recipe_MultiTool](/curseforge/images/Recipe_Multitool.png?raw=true)
+\
+Thanks to [Fundryi](https://github.com/Fundryi) for the [Multi-Tool suggestion](https://github.com/florian-berger/indestructible-tools/issues/4)!
-### Using in modpacks
-You can use this mod in every modpack that is available for free. You are allowed to distribute the mod file in an own ModPack launcher.
-Just add a link to this repository, [my website](https://berger-media.biz/downloads/10/minecraft/indestructible-tools) or the [CurseForge page](https://www.curseforge.com/minecraft/mc-mods/indestructible-tools) of this modification.
+## Usage in modpacks
+You can use this mod in every modpack that is available for free. You are allowed to distribute the mod file in an own ModPack launcher.\
+If the modpack is not distributed via CurseForge, you need to add a link to this repository, [my website](https://berger-media.biz/downloads/10/minecraft/indestructible-tools) or the [CurseForge page](https://www.curseforge.com/minecraft/mc-mods/indestructible-tools) of this modification.
diff --git a/build.gradle b/build.gradle
index f8c1afa..b74fdfa 100644
--- a/build.gradle
+++ b/build.gradle
@@ -13,7 +13,7 @@ apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
-version = '2021.2.1'
+version = '2022.1.0'
group = 'biz.berger_media.indestructibletools' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'indestructibletools'
@@ -27,7 +27,7 @@ minecraft {
// stable_# Stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace.
- mappings channel: 'official', version: '1.18'
+ mappings channel: 'official', version: '1.18.1'
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
@@ -113,7 +113,7 @@ dependencies {
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
- minecraft 'net.minecraftforge:forge:1.18-38.0.14'
+ minecraft 'net.minecraftforge:forge:1.18.1-39.0.59'
// Real mod deobf dependency examples - these get remapped to your current mappings
// compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency
@@ -136,7 +136,7 @@ jar {
"Specification-Vendor": "indestructibletoolssareus",
"Specification-Version": "1", // We are version 1 of ourselves
"Implementation-Title": project.name,
- "Implementation-Version": "${version}",
+ "Implementation-Version": project.jar.archiveVersion,
"Implementation-Vendor" :"indestructibletoolssareus",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
])
diff --git a/curseforge/images/Recipe_Multitool.png b/curseforge/images/Recipe_Multitool.png
new file mode 100644
index 0000000..a3d7e8e
Binary files /dev/null and b/curseforge/images/Recipe_Multitool.png differ
diff --git a/curseforge/images/tools-recipes.gif b/curseforge/images/tools-recipes.gif
new file mode 100644
index 0000000..b042510
Binary files /dev/null and b/curseforge/images/tools-recipes.gif differ
diff --git a/gimp/indestructible_multitool.xcf b/gimp/indestructible_multitool.xcf
new file mode 100644
index 0000000..6355419
Binary files /dev/null and b/gimp/indestructible_multitool.xcf differ
diff --git a/src/main/java/biz/berger_media/indestructibletools/IndestructibleTools.java b/src/main/java/biz/berger_media/indestructibletools/IndestructibleTools.java
index 6cb314c..4a1af14 100644
--- a/src/main/java/biz/berger_media/indestructibletools/IndestructibleTools.java
+++ b/src/main/java/biz/berger_media/indestructibletools/IndestructibleTools.java
@@ -1,8 +1,11 @@
package biz.berger_media.indestructibletools;
+import biz.berger_media.indestructibletools.events.RightClickBlockEventListener;
import biz.berger_media.indestructibletools.item.IndestructibleItems;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.block.Blocks;
+import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.common.Mod;
@@ -20,6 +23,8 @@ public class IndestructibleTools {
*/
public static final String MOD_ID = "indestructibletools";
+ public static final BlockState DirtPathState = Blocks.DIRT_PATH.defaultBlockState();
+
/**
* Creates an instance of the mod
*/
@@ -30,6 +35,7 @@ public IndestructibleTools() {
IndestructibleItems.ITEMS.register(bus);
MinecraftForge.EVENT_BUS.register(this);
+ MinecraftForge.EVENT_BUS.register(new RightClickBlockEventListener());
}
private void setup(final FMLCommonSetupEvent event) {
diff --git a/src/main/java/biz/berger_media/indestructibletools/events/RightClickBlockEventListener.java b/src/main/java/biz/berger_media/indestructibletools/events/RightClickBlockEventListener.java
new file mode 100644
index 0000000..741a69e
--- /dev/null
+++ b/src/main/java/biz/berger_media/indestructibletools/events/RightClickBlockEventListener.java
@@ -0,0 +1,70 @@
+package biz.berger_media.indestructibletools.events;
+
+import biz.berger_media.indestructibletools.IndestructibleTools;
+import biz.berger_media.indestructibletools.item.ItemIndestructibleMultiTool;
+import net.minecraft.core.BlockPos;
+import net.minecraft.sounds.SoundEvents;
+import net.minecraft.sounds.SoundSource;
+import net.minecraft.world.InteractionHand;
+import net.minecraft.world.entity.player.Player;
+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;
+import net.minecraft.world.level.material.Material;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+import net.minecraftforge.eventbus.api.Event;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
+
+public class RightClickBlockEventListener {
+ /**
+ * Listener for the RightClick event on a block
+ */
+ @SubscribeEvent
+ public void onRightClick(PlayerInteractEvent.RightClickBlock event) {
+ if (event.getResult() != Event.Result.DEFAULT || event.isCanceled()) {
+ return;
+ }
+
+ Player player = event.getPlayer();
+ Level world = event.getWorld();
+ InteractionHand hand = event.getHand();
+
+ if (player.getItemInHand(hand).getItem() instanceof ItemIndestructibleMultiTool) {
+ BlockPos pos = event.getPos();
+ if (world.getBlockState(pos.above()).getMaterial() == Material.AIR) {
+ BlockState state = world.getBlockState(pos);
+ if (isConvertible(state)) {
+ convertToPath(world, pos, player, hand);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks if the target block can be converted to a Dirt Path
+ */
+ private static boolean isConvertible(BlockState state) {
+ Block block = state.getBlock();
+ return block == Blocks.COARSE_DIRT || block == Blocks.DIRT ||
+ block == Blocks.MYCELIUM || block == Blocks.PODZOL ||
+ block == Blocks.GRASS_BLOCK;
+ }
+
+ /**
+ * Replaces a block at position with a dirt path and plays a sound
+ *
+ * @param world World where the block should be replaced
+ * @param pos Position that should be replaced
+ * @param player Player that is replacing the block
+ * @param hand Hand that should swing
+ */
+ private static void convertToPath(Level world, BlockPos pos, Player player, InteractionHand hand) {
+ world.playSound(player, pos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);
+ player.swing(hand);
+
+ if (!world.isClientSide) {
+ world.setBlock(pos, IndestructibleTools.DirtPathState, 11);
+ }
+ }
+}
diff --git a/src/main/java/biz/berger_media/indestructibletools/item/IndestructibleItems.java b/src/main/java/biz/berger_media/indestructibletools/item/IndestructibleItems.java
index 2cf40c5..c07c18a 100644
--- a/src/main/java/biz/berger_media/indestructibletools/item/IndestructibleItems.java
+++ b/src/main/java/biz/berger_media/indestructibletools/item/IndestructibleItems.java
@@ -28,4 +28,6 @@ public class IndestructibleItems {
public static final RegistryObject INDESTRUCTIBLE_HOE =
ITEMS.register("indestructible_hoe", ItemIndestructibleHoe::new);
+ public static final RegistryObject- INDESTRUCTIBLE_MULTITOOL =
+ ITEMS.register("indestructible_multitool", ItemIndestructibleMultiTool::new);
}
diff --git a/src/main/java/biz/berger_media/indestructibletools/item/ItemIndestructibleMultiTool.java b/src/main/java/biz/berger_media/indestructibletools/item/ItemIndestructibleMultiTool.java
new file mode 100644
index 0000000..42bb49e
--- /dev/null
+++ b/src/main/java/biz/berger_media/indestructibletools/item/ItemIndestructibleMultiTool.java
@@ -0,0 +1,78 @@
+package biz.berger_media.indestructibletools.item;
+
+import biz.berger_media.indestructibletools.helpers.EnchantmentHelper;
+import biz.berger_media.indestructibletools.helpers.ItemHelper;
+import net.minecraft.tags.BlockTags;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.PickaxeItem;
+import net.minecraft.world.item.Tiers;
+import net.minecraft.world.item.enchantment.Enchantment;
+import net.minecraft.world.level.block.state.BlockState;
+
+/**
+ * Class that represents the Multi-Tool (can be used as different tool)
+ */
+public class ItemIndestructibleMultiTool extends PickaxeItem {
+ public ItemIndestructibleMultiTool() {
+ super(Tiers.NETHERITE, 4, -1.5F, ItemHelper.getProperties());
+ }
+
+ @Override
+ public boolean isFireResistant() {
+ return true;
+ }
+
+ @Override
+ public boolean isDamageable(ItemStack stack) {
+ return false;
+ }
+
+ @Override
+ public float getDestroySpeed(ItemStack stack, BlockState state) {
+ if (state.is(BlockTags.MINEABLE_WITH_AXE)) {
+ return this.speed;
+ }
+
+ if (state.is(BlockTags.MINEABLE_WITH_SHOVEL)) {
+ return this.speed;
+ }
+
+ return super.getDestroySpeed(stack, state);
+ }
+
+ @Override
+ public boolean isCorrectToolForDrops(ItemStack stack, BlockState state) {
+ if (state.is(BlockTags.MINEABLE_WITH_AXE)) {
+ return true;
+ }
+
+ if (state.is(BlockTags.MINEABLE_WITH_SHOVEL)) {
+ return true;
+ }
+
+ return super.isCorrectToolForDrops(stack, state);
+ }
+
+ @Override
+ public boolean isEnchantable(ItemStack stack) {
+ return !stack.isEnchanted();
+ }
+
+ @Override
+ public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
+ if (EnchantmentHelper.isInvalidEnchantment(enchantment)) {
+ return false;
+ }
+
+ return super.canApplyAtEnchantingTable(stack, enchantment);
+ }
+
+ @Override
+ public boolean isBookEnchantable(ItemStack stack, ItemStack book) {
+ if (EnchantmentHelper.isBookEnchantedWithInvalidSpell(book)) {
+ return false;
+ }
+
+ return super.isBookEnchantable(stack, book);
+ }
+}
diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml
index 7c7044a..362bc49 100644
--- a/src/main/resources/META-INF/mods.toml
+++ b/src/main/resources/META-INF/mods.toml
@@ -1,6 +1,6 @@
modLoader="javafml" #mandatory
-loaderVersion="[38,)"
+loaderVersion="[39,)"
license="https://github.com/florian-berger/indestructible-tools/blob/master/LICENSE"
issueTrackerURL="https://github.com/florian-berger/indestructible-tools/issues"
@@ -8,7 +8,7 @@ issueTrackerURL="https://github.com/florian-berger/indestructible-tools/issues"
[[mods]]
modId="indestructibletools"
-version="2021.2.1"
+version="2022.1.0"
displayName="Indestructible Tools"
logoFile="indestructibletools.png"
@@ -22,7 +22,7 @@ This mod is adding some indestructible tools to Minecraft. They are crafted by u
# the modid of the dependency
modId="forge"
mandatory=true
- versionRange="[38,)"
+ versionRange="[39,)"
ordering="NONE"
side="BOTH"
diff --git a/src/main/resources/assets/indestructibletools/lang/de_de.json b/src/main/resources/assets/indestructibletools/lang/de_de.json
index e706e5a..4967426 100644
--- a/src/main/resources/assets/indestructibletools/lang/de_de.json
+++ b/src/main/resources/assets/indestructibletools/lang/de_de.json
@@ -6,5 +6,6 @@
"item.indestructibletools.indestructible_shovel": "Unzerstörbare Schaufel",
"item.indestructibletools.indestructible_sword": "Unzerstörbares Schwert",
"item.indestructibletools.indestructible_hoe": "Unzerstörbare Hacke",
+ "item.indestructibletools.indestructible_multitool": "Unzerstörbares Mehrfach-Werkzeug",
"item.indestructibletools.indestructible_ingot": "Unzerstörbarer Barren"
}
\ No newline at end of file
diff --git a/src/main/resources/assets/indestructibletools/lang/en_us.json b/src/main/resources/assets/indestructibletools/lang/en_us.json
index eaae425..9ff062c 100644
--- a/src/main/resources/assets/indestructibletools/lang/en_us.json
+++ b/src/main/resources/assets/indestructibletools/lang/en_us.json
@@ -6,5 +6,6 @@
"item.indestructibletools.indestructible_shovel": "Indestructible shovel",
"item.indestructibletools.indestructible_sword": "Indestructible sword",
"item.indestructibletools.indestructible_hoe": "Indestructible hoe",
+ "item.indestructibletools.indestructible_multitool": "Indestructible multitool",
"item.indestructibletools.indestructible_ingot": "Indestructible ingot"
}
\ No newline at end of file
diff --git a/src/main/resources/assets/indestructibletools/models/item/indestructible_multitool.json b/src/main/resources/assets/indestructibletools/models/item/indestructible_multitool.json
new file mode 100644
index 0000000..9581fa4
--- /dev/null
+++ b/src/main/resources/assets/indestructibletools/models/item/indestructible_multitool.json
@@ -0,0 +1,6 @@
+{
+ "parent": "minecraft:item/handheld",
+ "textures": {
+ "layer0": "indestructibletools:items/indestructible_multitool"
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/indestructibletools/textures/items/indestructible_multitool.png b/src/main/resources/assets/indestructibletools/textures/items/indestructible_multitool.png
new file mode 100644
index 0000000..39d6d81
Binary files /dev/null and b/src/main/resources/assets/indestructibletools/textures/items/indestructible_multitool.png differ
diff --git a/src/main/resources/data/indestructibletools/advancements/recipes/indestructible_multitool.json b/src/main/resources/data/indestructibletools/advancements/recipes/indestructible_multitool.json
new file mode 100644
index 0000000..28eb1c4
--- /dev/null
+++ b/src/main/resources/data/indestructibletools/advancements/recipes/indestructible_multitool.json
@@ -0,0 +1,34 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "indestructibletools:indestructible_multitool"
+ ]
+ },
+ "criteria": {
+ "has_ingot": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": [
+ "indestructibletools:indestructible_pickaxe"
+ ]
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "indestructibletools:indestructible_multitool"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "has_ingot",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/main/resources/data/indestructibletools/recipes/indestructible_multitool.json b/src/main/resources/data/indestructibletools/recipes/indestructible_multitool.json
new file mode 100644
index 0000000..3f7a673
--- /dev/null
+++ b/src/main/resources/data/indestructibletools/recipes/indestructible_multitool.json
@@ -0,0 +1,28 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "PSA",
+ "#I#",
+ " I "
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:string"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ },
+ "P": {
+ "item": "indestructibletools:indestructible_pickaxe"
+ },
+ "S": {
+ "item": "indestructibletools:indestructible_shovel"
+ },
+ "A": {
+ "item": "indestructibletools:indestructible_axe"
+ }
+ },
+ "result": {
+ "item": "indestructibletools:indestructible_multitool"
+ }
+}
\ No newline at end of file