add ToolManager

This commit is contained in:
Adrian Siekierka 2018-11-30 11:57:58 +01:00
parent 73c6a2a9c2
commit baccad6a95
23 changed files with 396 additions and 35 deletions

View file

@ -17,7 +17,7 @@
package net.fabricmc.fabric.client.render;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.render.block.entity.BlockEntityRenderManager;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import java.util.Map;
@ -41,6 +41,6 @@ public class BlockEntityRendererRegistry {
public void register(Class<? extends BlockEntity> blockEntityClass, BlockEntityRenderer<? extends BlockEntity> blockEntityRenderer) {
// TODO: warn on duplicate
blockEntityRenderers.put(blockEntityClass, blockEntityRenderer);
blockEntityRenderer.setRenderManager(BlockEntityRenderManager.instance);
blockEntityRenderer.setRenderManager(BlockEntityRenderDispatcher.INSTANCE);
}
}

View file

@ -16,7 +16,7 @@
package net.fabricmc.fabric.client.render;
import net.minecraft.client.render.entity.EntityRenderManager;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.texture.TextureManager;
@ -30,7 +30,7 @@ import java.util.function.Function;
public class EntityRendererRegistry {
@FunctionalInterface
public interface Factory {
EntityRenderer<? extends Entity> create(EntityRenderManager manager, EntityRendererRegistry.Context context);
EntityRenderer<? extends Entity> create(EntityRenderDispatcher manager, EntityRendererRegistry.Context context);
}
public static final class Context {
@ -54,14 +54,14 @@ public class EntityRendererRegistry {
}
public static final EntityRendererRegistry INSTANCE = new EntityRendererRegistry();
private final Map<EntityRenderManager, Context> renderManagerMap = new WeakHashMap<>();
private final Map<EntityRenderDispatcher, Context> renderManagerMap = new WeakHashMap<>();
private final Map<Class<? extends Entity>, EntityRendererRegistry.Factory> renderSupplierMap = new HashMap<>();
private EntityRendererRegistry() {
}
public void initialize(EntityRenderManager manager, TextureManager textureManager, ItemRenderer itemRenderer, Map<Class<? extends Entity>, EntityRenderer<? extends Entity>> map) {
public void initialize(EntityRenderDispatcher manager, TextureManager textureManager, ItemRenderer itemRenderer, Map<Class<? extends Entity>, EntityRenderer<? extends Entity>> map) {
synchronized (renderSupplierMap) {
if (renderManagerMap.containsKey(manager)) {
return;
@ -79,7 +79,7 @@ public class EntityRendererRegistry {
synchronized (renderSupplierMap) {
// TODO: warn on duplicate
renderSupplierMap.put(entityClass, factory);
for (EntityRenderManager manager : renderManagerMap.keySet()) {
for (EntityRenderDispatcher manager : renderManagerMap.keySet()) {
renderManagerMap.get(manager).rendererMap.put(entityClass, factory.create(manager, renderManagerMap.get(manager)));
}
}

View file

@ -16,6 +16,7 @@
package net.fabricmc.fabric.helpers;
import net.fabricmc.fabric.tools.ToolManager;
import net.minecraft.block.Block;
import net.minecraft.block.Material;
import net.minecraft.sound.BlockSoundGroup;

View file

@ -18,8 +18,8 @@ package net.fabricmc.fabric.mixin.registry;
import net.fabricmc.fabric.registry.RegistrySyncManager;
import net.fabricmc.fabric.registry.RemapException;
import net.minecraft.nbt.TagCompound;
import net.minecraft.nbt.TagStorageHelper;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.world.OldWorldSaveHandler;
import net.minecraft.world.level.LevelProperties;
import org.apache.logging.log4j.Logger;
@ -42,13 +42,13 @@ public class MixinWorldSaveHandler {
private static Logger LOGGER;
@Shadow
public File worldDir;
private TagCompound lastSavedIdMap = null;
private CompoundTag lastSavedIdMap = null;
private boolean readWorldIdMap(File file) {
try {
if (file.exists()) {
FileInputStream fileInputStream = new FileInputStream(file);
TagCompound tag = TagStorageHelper.readCompoundTagCompressed(fileInputStream);
CompoundTag tag = NbtIo.readCompressed(fileInputStream);
fileInputStream.close();
if (tag != null) {
RegistrySyncManager.apply(tag, true);
@ -80,7 +80,7 @@ public class MixinWorldSaveHandler {
}
}
TagCompound newIdMap = RegistrySyncManager.toTag(false);
CompoundTag newIdMap = RegistrySyncManager.toTag(false);
if (!newIdMap.equals(lastSavedIdMap)) {
for (int i = ID_REGISTRY_BACKUPS - 1; i >= 0; i--) {
File file = getWorldIdMapFile(i);
@ -96,7 +96,7 @@ public class MixinWorldSaveHandler {
try {
FileOutputStream fileOutputStream = new FileOutputStream(getWorldIdMapFile(0));
TagStorageHelper.writeCompoundTagCompressed(newIdMap, fileOutputStream);
NbtIo.writeCompressed(newIdMap, fileOutputStream);
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();

View file

@ -18,7 +18,7 @@ package net.fabricmc.fabric.mixin.render;
import net.fabricmc.fabric.client.render.BlockEntityRendererRegistry;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.render.block.entity.BlockEntityRenderManager;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -28,13 +28,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Map;
@Mixin(BlockEntityRenderManager.class)
@Mixin(BlockEntityRenderDispatcher.class)
public class MixinBlockEntityRenderManager {
@Shadow
private Map<Class<? extends BlockEntity>, BlockEntityRenderer<? extends BlockEntity>> blockEntityRenderers;
private Map<Class<? extends BlockEntity>, BlockEntityRenderer<? extends BlockEntity>> renderers;
@Inject(method = "<init>()V", at = @At("RETURN"))
public void init(CallbackInfo info) {
BlockEntityRendererRegistry.INSTANCE.initialize(blockEntityRenderers);
BlockEntityRendererRegistry.INSTANCE.initialize(renderers);
}
}

View file

@ -17,7 +17,7 @@
package net.fabricmc.fabric.mixin.render;
import net.fabricmc.fabric.client.render.EntityRendererRegistry;
import net.minecraft.client.render.entity.EntityRenderManager;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.texture.TextureManager;
@ -30,13 +30,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Map;
@Mixin(EntityRenderManager.class)
@Mixin(EntityRenderDispatcher.class)
public class MixinEntityRenderManager {
@Shadow
private Map<Class<? extends Entity>, EntityRenderer<? extends Entity>> RENDER_MAP;
private Map<Class<? extends Entity>, EntityRenderer<? extends Entity>> renderers;
@Inject(method = "<init>(Lnet/minecraft/client/texture/TextureManager;Lnet/minecraft/client/render/item/ItemRenderer;)V", at = @At("RETURN"))
public void init(TextureManager textureManager, ItemRenderer itemRenderer, CallbackInfo info) {
EntityRendererRegistry.INSTANCE.initialize((EntityRenderManager) (Object) this, textureManager, itemRenderer, RENDER_MAP);
EntityRendererRegistry.INSTANCE.initialize((EntityRenderDispatcher) (Object) this, textureManager, itemRenderer, renderers);
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.tools;
import net.fabricmc.fabric.tools.MiningToolDelegate;
import net.fabricmc.fabric.tools.ToolManager;
import net.fabricmc.fabric.util.TriState;
import net.minecraft.block.BlockState;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ItemStack.class)
public abstract class MixinItemStack {
@Shadow
public abstract Item getItem();
@Inject(at = @At("HEAD"), method = "isEffectiveOn", cancellable = true)
public void isEffectiveOn(BlockState state, CallbackInfoReturnable<Boolean> info) {
TriState triState = ToolManager.handleIsEffectiveOn((ItemStack) (Object) this, state);
if (triState != TriState.DEFAULT) {
info.setReturnValue(triState.get());
info.cancel();
}
}
@Inject(at = @At("HEAD"), method = "getBlockBreakingSpeed", cancellable = true)
public void getBlockBreakingSpeed(BlockState state, CallbackInfoReturnable<Float> info) {
if (this.getItem() instanceof MiningToolDelegate) {
TriState triState = ToolManager.handleIsEffectiveOn((ItemStack) (Object) this, state);
if (triState != TriState.DEFAULT) {
info.setReturnValue(triState.get() ? ((MiningToolDelegate) this.getItem()).getMiningToolEfficiency() : 1.0F);
info.cancel();
}
}
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.tools;
import net.fabricmc.fabric.tools.MiningToolDelegate;
import net.minecraft.item.MiningToolItem;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(MiningToolItem.class)
public class MixinMiningToolItem implements MiningToolDelegate {
@Shadow
protected float efficiency;
@Override
public float getMiningToolEfficiency() {
return efficiency;
}
}

View file

@ -23,7 +23,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.fabricmc.fabric.networking.CustomPayloadHandlerRegistry;
import net.fabricmc.fabric.networking.PacketContext;
import net.minecraft.client.network.packet.CustomPayloadClientPacket;
import net.minecraft.nbt.TagCompound;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Identifier;
import net.minecraft.util.PacketByteBuf;
import net.minecraft.util.registry.IdRegistry;
@ -52,7 +52,7 @@ public final class RegistrySyncManager {
}
public static void receivePacket(PacketContext context, PacketByteBuf buf) {
TagCompound compound = buf.readTagCompound();
CompoundTag compound = buf.readTagCompound();
try {
apply(compound, false);
@ -62,8 +62,8 @@ public final class RegistrySyncManager {
}
}
public static TagCompound toTag(boolean isClientSync) {
TagCompound mainTag = new TagCompound();
public static CompoundTag toTag(boolean isClientSync) {
CompoundTag mainTag = new CompoundTag();
for (Identifier registryId : Registry.REGISTRIES.keys()) {
if (REGISTRY_BLACKLIST.contains(registryId)) {
@ -74,7 +74,7 @@ public final class RegistrySyncManager {
ModifiableRegistry registry = Registry.REGISTRIES.get(registryId);
if (registry instanceof IdRegistry && registry instanceof RemappableRegistry) {
TagCompound registryTag = new TagCompound();
CompoundTag registryTag = new CompoundTag();
//noinspection unchecked
for (Identifier identifier : (Set<Identifier>) registry.keys()) {
registryTag.setInt(identifier.toString(), registry.getRawId(registry.get(identifier)));
@ -83,22 +83,22 @@ public final class RegistrySyncManager {
}
}
TagCompound tag = new TagCompound();
CompoundTag tag = new CompoundTag();
tag.setInt("version", 1);
tag.setTag("registries", mainTag);
return tag;
}
public static void apply(TagCompound tag, boolean reallocateMissingEntries) throws RemapException {
TagCompound mainTag = tag.getTagCompound("registries");
public static void apply(CompoundTag tag, boolean reallocateMissingEntries) throws RemapException {
CompoundTag mainTag = tag.getTagCompound("registries");
for (Identifier registryId : Registry.REGISTRIES.keys()) {
if (!mainTag.containsKey(registryId.toString())) {
continue;
}
TagCompound registryTag = mainTag.getTagCompound(registryId.toString());
CompoundTag registryTag = mainTag.getTagCompound(registryId.toString());
ModifiableRegistry registry = Registry.REGISTRIES.get(registryId);
if (registry instanceof IdRegistry && registry instanceof RemappableRegistry) {
Object2IntMap<Identifier> idMap = new Object2IntOpenHashMap<>();

View file

@ -41,7 +41,6 @@ public class BootstrapBlockRegistryListener implements RegistryListener<Block> {
@Override
public void afterRegistryRegistration(Registry<Block> registry, int id, Identifier identifier, Block object) {
System.out.println(identifier);
// refer net.minecraft.block.Blocks
object.getDropTableId();
}

View file

@ -20,8 +20,11 @@ import net.fabricmc.loader.ModInfo;
import net.minecraft.resource.DirectoryResourcePack;
import net.minecraft.resource.ResourceNotFoundException;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;
import java.io.*;
import java.util.Collection;
import java.util.function.Predicate;
public class ModDirectoryResourcePack extends DirectoryResourcePack implements ModResourcePack {
private final ModInfo info;
@ -49,6 +52,16 @@ public class ModDirectoryResourcePack extends DirectoryResourcePack implements M
}
}
@Override
public Collection<Identifier> findResources(ResourceType var1, String var2, int var3, Predicate<String> var4) {
System.out.println("called " + var1 + " " + var2 + " " + var3);
Collection<Identifier> test = super.findResources(var1, var2, var3, var4);
for (Identifier id : test) {
System.out.println("- " + id);
}
return test;
}
@Override
protected boolean containsFilename(String filename) {
return super.containsFilename(filename) || ModResourcePackUtil.containsDefault(info, filename);

View file

@ -42,14 +42,20 @@ public final class ModResourcePackUtil {
public static void appendModResourcePacks(List<ResourcePack> packList, ResourceType type) {
for (ModContainer container : FabricLoader.INSTANCE.getMods()) {
File file = container.getOriginFile();
ResourcePack pack = null;
if (file.isDirectory()) {
packList.add(new ModDirectoryResourcePack(container.getInfo(), file));
pack = new ModDirectoryResourcePack(container.getInfo(), file);
} else {
String name = file.getName().toLowerCase(Locale.ROOT);
if (name.endsWith(".zip") || name.endsWith(".jar")) {
packList.add(new ModZipResourcePack(container.getInfo(), file));
pack = new ModZipResourcePack(container.getInfo(), file);
}
}
if (pack != null && !pack.getNamespaces(type).isEmpty()) {
packList.add(pack);
}
}
}

View file

@ -16,16 +16,18 @@
package net.fabricmc.fabric.resources;
import com.google.common.io.ByteStreams;
import net.fabricmc.loader.ModInfo;
import net.minecraft.resource.ResourceNotFoundException;
import net.minecraft.resource.ResourceType;
import net.minecraft.resource.ZipResourcePack;
import net.minecraft.util.Identifier;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.function.Predicate;
public class ModZipResourcePack extends ZipResourcePack implements ModResourcePack {
private final ModInfo info;
@ -53,6 +55,16 @@ public class ModZipResourcePack extends ZipResourcePack implements ModResourcePa
}
}
@Override
public Collection<Identifier> findResources(ResourceType var1, String var2, int var3, Predicate<String> var4) {
System.out.println("called " + var1 + " " + var2 + " " + var3);
Collection<Identifier> test = super.findResources(var1, var2, var3, var4);
for (Identifier id : test) {
System.out.println("- " + id);
}
return test;
}
@Override
public boolean containsFilename(String filename) {
return super.containsFilename(filename) || ModResourcePackUtil.containsDefault(info, filename);

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.tags;
import net.minecraft.item.Item;
import net.minecraft.tag.ItemTags;
import net.minecraft.tag.Tag;
import net.minecraft.util.Identifier;
public class FabricItemTags {
public static final Tag<Item> AXES = register("axes");
public static final Tag<Item> HOES = register("hoes");
public static final Tag<Item> PICKAXES = register("pickaxes");
public static final Tag<Item> SHOVELS = register("shovels");
public static final Tag<Item> SWORDS = register("swords");
private static Tag<Item> register(String id) {
return new ItemTags.class_3490(new Identifier("fabric", id));
}
}

View file

@ -0,0 +1,21 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.tools;
public interface MiningToolDelegate {
float getMiningToolEfficiency();
}

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.tools;
import net.fabricmc.fabric.util.TriState;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ToolItem;
import net.minecraft.tag.Tag;
import java.util.HashMap;
import java.util.Map;
public final class ToolManager {
private static class Entry {
@SuppressWarnings("unchecked")
private Tag<Item>[] tags = (Tag<Item>[]) new Tag[0];
private int[] tagLevels = new int[0];
private TriState defaultValue = TriState.DEFAULT;
public void setDefaultValue(TriState defaultValue) {
this.defaultValue = defaultValue;
}
public void addTag(Tag<Item> tag, int miningLevel) {
for (int i = 0; i < tags.length; i++) {
if (tags[i] == tag) {
tagLevels[i] = miningLevel;
return;
}
}
//noinspection unchecked
Tag<Item>[] newTags = (Tag<Item>[]) new Tag[tags.length + 1];
int[] newTagLevels = new int[tagLevels.length + 1];
System.arraycopy(tags, 0, newTags, 0, tags.length);
System.arraycopy(tagLevels, 0, newTagLevels, 0, tagLevels.length);
newTags[tags.length] = tag;
newTagLevels[tagLevels.length] = miningLevel;
tags = newTags;
tagLevels = newTagLevels;
}
}
private static final Map<Block, Entry> entries = new HashMap<>();
private ToolManager() {
}
private static Entry computeEntry(Block b) {
return entries.computeIfAbsent(b, (bb) -> new Entry());
}
public static void registerBreakByHand(Block block, boolean value) {
computeEntry(block).defaultValue = TriState.of(value);
}
public static void registerBreakByTool(Block block, Tag<Item> tag, int miningLevel) {
computeEntry(block).defaultValue = TriState.FALSE;
computeEntry(block).addTag(tag, miningLevel);
}
public static int getMiningLevel(ItemStack stack) {
if (stack.getItem() instanceof ToolItem) {
return ((ToolItem) stack.getItem()).getType().getMiningLevel();
} else {
return 0;
}
}
public static TriState handleIsEffectiveOn(ItemStack stack, BlockState state) {
Entry entry = entries.get(state.getBlock());
if (entry != null) {
Item item = stack.getItem();
for (int i = 0; i < entry.tags.length; i++) {
if (item.matches(entry.tags[i])) {
return TriState.of(getMiningLevel(stack) >= entry.tagLevels[i]);
}
}
return entry.defaultValue;
} else {
return TriState.DEFAULT;
}
}
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.util;
public enum TriState {
FALSE,
DEFAULT,
TRUE;
public static TriState of(boolean b) {
return b ? TRUE : FALSE;
}
public boolean get() {
return this == TRUE;
}
}

View file

@ -0,0 +1,10 @@
{
"replace": false,
"values": [
"minecraft:wooden_axe",
"minecraft:stone_axe",
"minecraft:iron_axe",
"minecraft:golden_axe",
"minecraft:diamond_axe"
]
}

View file

@ -0,0 +1,10 @@
{
"replace": false,
"values": [
"minecraft:wooden_hoe",
"minecraft:stone_hoe",
"minecraft:iron_hoe",
"minecraft:golden_hoe",
"minecraft:diamond_hoe"
]
}

View file

@ -0,0 +1,10 @@
{
"replace": false,
"values": [
"minecraft:wooden_pickaxe",
"minecraft:stone_pickaxe",
"minecraft:iron_pickaxe",
"minecraft:golden_pickaxe",
"minecraft:diamond_pickaxe"
]
}

View file

@ -0,0 +1,10 @@
{
"replace": false,
"values": [
"minecraft:wooden_shovel",
"minecraft:stone_shovel",
"minecraft:iron_shovel",
"minecraft:golden_shovel",
"minecraft:diamond_shovel"
]
}

View file

@ -0,0 +1,10 @@
{
"replace": false,
"values": [
"minecraft:wooden_sword",
"minecraft:stone_sword",
"minecraft:iron_sword",
"minecraft:golden_sword",
"minecraft:diamond_sword"
]
}

View file

@ -12,7 +12,9 @@
"registry.MixinIdRegistry",
"registry.MixinServerPlayNetworkHandler",
"registry.MixinWorldSaveHandler",
"resources.MixinMinecraftServer"
"resources.MixinMinecraftServer",
"tools.MixinItemStack",
"tools.MixinMiningToolItem"
],
"injectors": {
"defaultRequire": 1