WIP 0.1.0 cleanup

This commit is contained in:
Adrian Siekierka 2018-12-09 13:29:59 +01:00
parent 75b640e987
commit 0594469b69
28 changed files with 278 additions and 82 deletions

View file

@ -23,7 +23,7 @@ sourceCompatibility = 1.8
targetCompatibility = 1.8
archivesBaseName = "fabric"
version = "0.0.3-SNAPSHOT"
version = "0.1.0-SNAPSHOT"
minecraft {
refmapName = "net.fabricmc.fabric.refmap.json"
@ -31,7 +31,7 @@ minecraft {
dependencies {
minecraft "com.mojang:minecraft:18w49a"
mappings "net.fabricmc:pomf:18w49a.2"
mappings "net.fabricmc:pomf:18w49a.16"
modCompile "net.fabricmc:fabric-loader:0.1.0.52"
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package net.fabricmc.fabric.helpers;
package net.fabricmc.fabric.events;
import net.fabricmc.fabric.util.HandlerList;
import net.fabricmc.fabric.util.HandlerRegistry;
@ -23,11 +23,16 @@ import net.minecraft.item.Item;
import java.util.function.BiConsumer;
public final class FabricBuilderEvent {
/**
* This is a class for events emitted when a Block.Builder/Item.Builder is
* turned into a Block or Item. You can use these to extend these builders with
* your own methods and transparently add the resulting information to a Map.
*/
public final class ObjectBuilderEvent {
public static final HandlerRegistry<BiConsumer<Block.Builder, Block>> BLOCK = new HandlerList<>();
public static final HandlerRegistry<BiConsumer<Item.Builder, Item>> ITEM = new HandlerList<>();
private FabricBuilderEvent() {
private ObjectBuilderEvent() {
}
}

View file

@ -55,7 +55,7 @@ public final class PlayerInteractionEvent {
@FunctionalInterface
public interface EntityPositioned {
ActionResult interact(PlayerEntity player, World world, Hand hand, net.minecraft.entity.Entity entity, Vec3d hitPos);
ActionResult interact(PlayerEntity player, World world, Hand hand, net.minecraft.entity.Entity entity, Vec3d hitPosition);
}
@FunctionalInterface
@ -63,14 +63,38 @@ public final class PlayerInteractionEvent {
ActionResult interact(PlayerEntity player, World world, Hand hand);
}
/**
* Event emitted when a player "attacks" a block.
*/
public static final HandlerRegistry<Block> ATTACK_BLOCK = new HandlerList<>();
/**
* Event emitted when a player "attacks" an entity.
*/
public static final HandlerRegistry<Entity> ATTACK_ENTITY = new HandlerList<>();
// TODO: For completeness' sake, but requires us to add a custom packet. Is it worth the complexity?
/* public static final HandlerRegistry<Item> ATTACK_ITEM = new HandlerList<>(); */
/**
* Event emitted when a player interacts with a block.
*/
public static final HandlerRegistry<BlockPositioned> INTERACT_BLOCK = new HandlerList<>();
/**
* Event emitted when a player interacts with an entity.
*
* Developer note: Minecraft provides two methods to interact with
* Entities - one takes in a hit position, the other does not. However,
* all vanilla interaction cases seem to use one, then the other - as such,
* only one event is currently provided, but it is accordingly named in
* the case of a second event being necessary.
*/
public static final HandlerRegistry<EntityPositioned> INTERACT_ENTITY_POSITIONED = new HandlerList<>();
/**
* Event emitted when a player interacts with an item.
*/
public static final HandlerRegistry<Item> INTERACT_ITEM = new HandlerList<>();
/**

View file

@ -24,6 +24,10 @@ import net.minecraft.world.World;
import java.util.function.Consumer;
/**
* Events emitted during the ticking process for global Minecraft objects.
* You can use them as endpoints to tick your own, related logic "globally".
*/
public final class TickEvent {
public static final HandlerRegistry<Consumer<MinecraftServer>> SERVER = new HandlerList<>();
public static final HandlerRegistry<Consumer<World>> WORLD = new HandlerList<>();

View file

@ -16,12 +16,18 @@
package net.fabricmc.fabric.events.client;
import net.fabricmc.fabric.events.TickEvent;
import net.fabricmc.fabric.util.HandlerList;
import net.fabricmc.fabric.util.HandlerRegistry;
import net.minecraft.client.MinecraftClient;
import java.util.function.Consumer;
/**
* Events emitted during the ticking process for Minecraft client objects.
*
* @see TickEvent
*/
public final class ClientTickEvent {
public static final HandlerRegistry<Consumer<MinecraftClient>> CLIENT = new HandlerList<>();

View file

@ -29,6 +29,14 @@ import net.minecraft.world.loot.LootTables;
import java.util.function.Function;
/**
* Fabric's version of Block.Builder. Adds additional methods and hooks
* not found in the original class.
*
* To use it, simply replace Block.Builder.create() with
* FabricBlockBuilder.create() and add .build() at the end to return the
* vanilla Block.Builder instance beneath.
*/
public class FabricBlockBuilder {
public interface Delegate {
void fabric_setMapColor(MaterialColor color);

View file

@ -16,7 +16,7 @@
package net.fabricmc.fabric.mixin.helpers;
import net.fabricmc.fabric.helpers.FabricBuilderEvent;
import net.fabricmc.fabric.events.ObjectBuilderEvent;
import net.fabricmc.fabric.util.HandlerList;
import net.minecraft.block.Block;
import org.spongepowered.asm.mixin.Mixin;
@ -30,7 +30,7 @@ import java.util.function.BiConsumer;
public class MixinBlock {
@Inject(method = "<init>(Lnet/minecraft/block/Block$Builder;)V", at = @At("RETURN"))
public void init(Block.Builder builder, CallbackInfo info) {
for (Object o : ((HandlerList<BiConsumer<Block.Builder, Block>>) FabricBuilderEvent.BLOCK).getBackingArray()) {
for (Object o : ((HandlerList<BiConsumer<Block.Builder, Block>>) ObjectBuilderEvent.BLOCK).getBackingArray()) {
((BiConsumer<Block.Builder, Block>) o).accept(builder, (Block) (Object) this);
}
}

View file

@ -16,7 +16,7 @@
package net.fabricmc.fabric.mixin.helpers;
import net.fabricmc.fabric.helpers.FabricBuilderEvent;
import net.fabricmc.fabric.events.ObjectBuilderEvent;
import net.fabricmc.fabric.util.HandlerList;
import net.minecraft.item.Item;
import org.spongepowered.asm.mixin.Mixin;
@ -30,7 +30,7 @@ import java.util.function.BiConsumer;
public class MixinItem {
@Inject(method = "<init>(Lnet/minecraft/item/Item$Builder;)V", at = @At("RETURN"))
public void init(Item.Builder builder, CallbackInfo info) {
for (Object o : ((HandlerList<BiConsumer<Item.Builder, Item>>) FabricBuilderEvent.ITEM).getBackingArray()) {
for (Object o : ((HandlerList<BiConsumer<Item.Builder, Item>>) ObjectBuilderEvent.ITEM).getBackingArray()) {
((BiConsumer<Item.Builder, Item>) o).accept(builder, (Item) (Object) this);
}
}

View file

@ -16,15 +16,14 @@
package net.fabricmc.fabric.mixin.networking;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Side;
import net.fabricmc.fabric.networking.CustomPayloadHandlerRegistry;
import net.fabricmc.fabric.networking.CustomPayloadPacketRegistry;
import net.fabricmc.fabric.networking.PacketContext;
import net.fabricmc.fabric.networking.SPacketCustomPayloadAccessor;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.packet.CustomPayloadClientPacket;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ThreadTaskQueue;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -39,14 +38,14 @@ public class MixinClientPlayNetworkHandler implements PacketContext {
@Inject(method = "onCustomPayload", at = @At("HEAD"), cancellable = true)
public void onCustomPayload(CustomPayloadClientPacket packet, CallbackInfo info) {
if (CustomPayloadHandlerRegistry.CLIENT.accept(packet.getChannel(), this, packet.getData())) {
if (CustomPayloadPacketRegistry.CLIENT.accept(packet.getChannel(), this, packet.getData())) {
info.cancel();
}
}
@Override
public Side getNetworkSide() {
return Side.CLIENT;
public EnvType getPacketEnvironment() {
return EnvType.CLIENT;
}
@Override

View file

@ -16,8 +16,9 @@
package net.fabricmc.fabric.mixin.networking;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Side;
import net.fabricmc.fabric.networking.CustomPayloadHandlerRegistry;
import net.fabricmc.fabric.networking.CustomPayloadPacketRegistry;
import net.fabricmc.fabric.networking.PacketContext;
import net.fabricmc.fabric.networking.SPacketCustomPayloadAccessor;
import net.minecraft.entity.player.PlayerEntity;
@ -43,14 +44,14 @@ public class MixinServerPlayNetworkHandler implements PacketContext {
public void onCustomPayload(CustomPayloadServerPacket packet, CallbackInfo info) {
SPacketCustomPayloadAccessor accessor = ((SPacketCustomPayloadAccessor) packet);
if (CustomPayloadHandlerRegistry.SERVER.accept(accessor.getChannel(), this, accessor.getData())) {
if (CustomPayloadPacketRegistry.SERVER.accept(accessor.getChannel(), this, accessor.getData())) {
info.cancel();
}
}
@Override
public Side getNetworkSide() {
return Side.SERVER;
public EnvType getPacketEnvironment() {
return EnvType.SERVER;
}
@Override

View file

@ -16,7 +16,7 @@
package net.fabricmc.fabric.mixin.registry;
import net.fabricmc.fabric.networking.CustomPayloadHandlerRegistry;
import net.fabricmc.fabric.networking.CustomPayloadPacketRegistry;
import net.fabricmc.fabric.registry.ListenableRegistry;
import net.fabricmc.fabric.registry.RegistrySyncManager;
import net.fabricmc.fabric.registry.listeners.BootstrapBiomeRegistryListener;
@ -54,6 +54,6 @@ public class MixinBootstrap {
((ListenableRegistry<Item>) Registry.ITEMS).registerListener(new BootstrapItemRegistryListener());
// The packet code is not side-specific, so this is fine!
CustomPayloadHandlerRegistry.CLIENT.register(RegistrySyncManager.ID, RegistrySyncManager::receivePacket);
CustomPayloadPacketRegistry.CLIENT.register(RegistrySyncManager.ID, RegistrySyncManager::receivePacket);
}
}

View file

@ -16,17 +16,12 @@
package net.fabricmc.fabric.mixin.registry;
import net.fabricmc.api.Side;
import net.fabricmc.fabric.networking.CustomPayloadHandlerRegistry;
import net.fabricmc.fabric.networking.PacketContext;
import net.fabricmc.fabric.networking.SPacketCustomPayloadAccessor;
import net.fabricmc.fabric.registry.RegistrySyncManager;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.Packet;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ThreadTaskQueue;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;

View file

@ -17,15 +17,13 @@
package net.fabricmc.fabric.mixin.registry.client;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.fabricmc.fabric.registry.ListenableRegistry;
import net.fabricmc.fabric.registry.RegistryListener;
import net.minecraft.client.render.item.ItemModelMap;
import net.minecraft.client.render.item.ItemModels;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedModelManager;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.item.Item;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import org.spongepowered.asm.mixin.Mixin;
@ -35,15 +33,14 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
@Mixin(ItemModelMap.class)
@Mixin(ItemModels.class)
public class MixinItemModelMap implements RegistryListener<Item> {
@Shadow
public Int2ObjectMap<ModelIdentifier> field_4129;
public Int2ObjectMap<ModelIdentifier> modelIds;
@Shadow
private Int2ObjectMap<BakedModel> field_4130;
private Int2ObjectMap<BakedModel> models;
private Map<Identifier, ModelIdentifier> fabricModelIdMap;
private Map<Identifier, BakedModel> fabricModelMap;
@ -63,8 +60,8 @@ public class MixinItemModelMap implements RegistryListener<Item> {
for (Identifier id : registry.keys()) {
Item object = registry.get(id);
int rawId = registry.getRawId(object);
ModelIdentifier modelId = field_4129.get(rawId);
BakedModel bakedModel = field_4130.get(rawId);
ModelIdentifier modelId = modelIds.get(rawId);
BakedModel bakedModel = models.get(rawId);
if (modelId != null) {
fabricModelIdMap.put(id, modelId);
@ -75,18 +72,18 @@ public class MixinItemModelMap implements RegistryListener<Item> {
}
}
field_4129.clear();
field_4130.clear();
modelIds.clear();
models.clear();
}
@Override
public void beforeRegistryRegistration(Registry<Item> registry, int id, Identifier identifier, Item object, boolean isNew) {
if (fabricModelIdMap != null && fabricModelIdMap.containsKey(identifier)) {
field_4129.put(id, fabricModelIdMap.get(identifier));
modelIds.put(id, fabricModelIdMap.get(identifier));
}
if (fabricModelMap != null && fabricModelMap.containsKey(identifier)) {
field_4130.put(id, fabricModelMap.get(identifier));
models.put(id, fabricModelMap.get(identifier));
}
}

View file

@ -16,7 +16,7 @@
package net.fabricmc.fabric.mixin.resources;
import net.fabricmc.fabric.resources.ModResourcePackUtil;
import net.fabricmc.fabric.resources.impl.ModResourcePackUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.resource.ReloadableResourceManager;
import net.minecraft.resource.ResourcePack;

View file

@ -16,14 +16,9 @@
package net.fabricmc.fabric.mixin.resources;
import net.fabricmc.fabric.resources.ModDataPackSupplier;
import net.fabricmc.fabric.resources.ModResourcePack;
import net.fabricmc.fabric.resources.ModResourcePackUtil;
import net.fabricmc.fabric.resources.impl.ModDataPackSupplier;
import net.minecraft.class_3283;
import net.minecraft.class_3288;
import net.minecraft.resource.ReloadableResourceManager;
import net.minecraft.resource.ResourcePack;
import net.minecraft.resource.ResourceType;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.LevelProperties;
import org.spongepowered.asm.mixin.Mixin;
@ -31,11 +26,8 @@ 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.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@Mixin(MinecraftServer.class)
public class MixinMinecraftServer {

View file

@ -23,16 +23,26 @@ import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
public class CustomPayloadHandlerRegistry {
public static final CustomPayloadHandlerRegistry CLIENT = new CustomPayloadHandlerRegistry();
public static final CustomPayloadHandlerRegistry SERVER = new CustomPayloadHandlerRegistry();
/**
* Registry for CustomPayload-based packet handling. You can use this
* to register your own CustomPayload packet handlers.
*/
public class CustomPayloadPacketRegistry {
public static final CustomPayloadPacketRegistry CLIENT = new CustomPayloadPacketRegistry();
public static final CustomPayloadPacketRegistry SERVER = new CustomPayloadPacketRegistry();
protected final Map<Identifier, BiConsumer<PacketContext, PacketByteBuf>> consumerMap;
protected CustomPayloadHandlerRegistry() {
protected CustomPayloadPacketRegistry() {
consumerMap = new HashMap<>();
}
/**
* Register a packet.
*
* @param id The packet Identifier.
* @param consumer The method used for handling the packet.
*/
public void register(Identifier id, BiConsumer<PacketContext, PacketByteBuf> consumer) {
if (consumerMap.containsKey(id)) {
// TODO: log warning
@ -41,8 +51,16 @@ public class CustomPayloadHandlerRegistry {
consumerMap.put(id, consumer);
}
public boolean accept(Identifier identifier, PacketContext context, PacketByteBuf buf) {
BiConsumer<PacketContext, PacketByteBuf> consumer = consumerMap.get(identifier);
/**
* Hook for accepting packets used in Fabric mixins.
*
* @param id The packet Identifier received.
* @param context The packet context provided.
* @param buf The packet data buffer received.
* @return Whether or not the packet was handled by this packet registry.
*/
public boolean accept(Identifier id, PacketContext context, PacketByteBuf buf) {
BiConsumer<PacketContext, PacketByteBuf> consumer = consumerMap.get(id);
if (consumer != null) {
try {
consumer.accept(context, buf);

View file

@ -16,6 +16,7 @@
package net.fabricmc.fabric.networking;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Side;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ThreadTaskQueue;
@ -26,7 +27,38 @@ import net.minecraft.util.ThreadTaskQueue;
* the correct task queue to enqueue synchronization-requiring code on.
*/
public interface PacketContext {
Side getNetworkSide();
/**
* Get the environment associated with the packet.
*
* @return EnvType.CLIENT if processing packet on the client side,
* EnvType.SERVER otherwise.
*/
EnvType getPacketEnvironment();
/**
* Get the player associated with the packet.
*
* On the client side, this always returns the client-side player instance.
* On the server side, it returns the player belonging to the client this
* packet was sent by.
*
* @return The player associated with the packet.
*/
PlayerEntity getPlayer();
/**
* Get the task queue for a given side.
*
* As Minecraft networking I/O is asynchronous, but a lot of its logic is
* not thread-safe, it is recommended to do the following:
*
* - read and parse the PacketByteBuf,
* - run the packet response logic through the main thread task queue via
* ThreadTaskQueue.execute(). The method will check if it's not already
* on the main thread in order to avoid unnecessary delays, so don't
* worry about that!
*
* @return The thread task queue.
*/
ThreadTaskQueue getTaskQueue();
}

View file

@ -20,7 +20,6 @@ import com.google.common.collect.ImmutableSet;
import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
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.CompoundTag;
@ -30,8 +29,6 @@ import net.minecraft.util.registry.IdRegistry;
import net.minecraft.util.registry.ModifiableRegistry;
import net.minecraft.util.registry.Registry;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public final class RegistrySyncManager {

View file

@ -20,9 +20,13 @@ import net.fabricmc.loader.ModInfo;
import net.minecraft.resource.ResourcePack;
import net.minecraft.resource.ResourceType;
/**
* Interface implemented by mod-provided resource packs.
*/
public interface ModResourcePack extends ResourcePack {
ModInfo getModInfo();
default boolean provides(ResourceType type) {
return true;
}
/**
* @return The ModInfo object associated with the mod providing this
* resource pack.
*/
ModInfo getFabricModInfo();
}

View file

@ -14,8 +14,9 @@
* limitations under the License.
*/
package net.fabricmc.fabric.resources;
package net.fabricmc.fabric.resources.impl;
import net.fabricmc.fabric.resources.ModResourcePack;
import net.minecraft.class_3285;
import net.minecraft.class_3288;
import net.minecraft.resource.ResourcePack;
@ -36,7 +37,7 @@ public class ModDataPackSupplier implements class_3285 {
throw new RuntimeException("Not a ModResourcePack!");
}
T var3 = class_3288.method_14456("fabric/" + ((ModResourcePack) pack).getModInfo().getId(),
T var3 = class_3288.method_14456("fabric/" + ((ModResourcePack) pack).getFabricModInfo().getId(),
false, () -> pack, class_3290, class_3288.class_3289.BOTTOM);
if (var3 != null) {

View file

@ -14,17 +14,14 @@
* limitations under the License.
*/
package net.fabricmc.fabric.resources;
package net.fabricmc.fabric.resources.impl;
import net.fabricmc.fabric.resources.ModResourcePack;
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;
@ -58,7 +55,7 @@ public class ModDirectoryResourcePack extends DirectoryResourcePack implements M
}
@Override
public ModInfo getModInfo() {
public ModInfo getFabricModInfo() {
return info;
}
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package net.fabricmc.fabric.resources;
package net.fabricmc.fabric.resources.impl;
import com.google.common.base.Charsets;
import net.fabricmc.loader.FabricLoader;

View file

@ -14,20 +14,17 @@
* limitations under the License.
*/
package net.fabricmc.fabric.resources;
package net.fabricmc.fabric.resources.impl;
import net.fabricmc.fabric.resources.ModResourcePack;
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;
@ -61,7 +58,7 @@ public class ModZipResourcePack extends ZipResourcePack implements ModResourcePa
}
@Override
public ModInfo getModInfo() {
public ModInfo getFabricModInfo() {
return info;
}
}

View file

@ -0,0 +1,37 @@
/*
* 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.block.Block;
import net.minecraft.item.Item;
import net.minecraft.tag.BlockTags;
import net.minecraft.tag.ItemTags;
import net.minecraft.tag.Tag;
import net.minecraft.util.Identifier;
/**
* Block tags provided by Fabric.
*/
public class FabricBlockTags {
private FabricBlockTags() {
}
private static Tag<Block> register(String id) {
return TagRegistry.block(new Identifier("fabric", id));
}
}

View file

@ -21,6 +21,9 @@ import net.minecraft.tag.ItemTags;
import net.minecraft.tag.Tag;
import net.minecraft.util.Identifier;
/**
* Item tags provdied by Fabric.
*/
public class FabricItemTags {
public static final Tag<Item> AXES = register("axes");
public static final Tag<Item> HOES = register("hoes");
@ -28,7 +31,11 @@ public class FabricItemTags {
public static final Tag<Item> SHOVELS = register("shovels");
public static final Tag<Item> SWORDS = register("swords");
private FabricItemTags() {
}
private static Tag<Item> register(String id) {
return new ItemTags.class_3490(new Identifier("fabric", id));
return TagRegistry.item(new Identifier("fabric", id));
}
}

View file

@ -0,0 +1,39 @@
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;
import java.util.Collection;
public class TagDelegate<T> extends Tag<T> {
protected Tag<T> delegate;
public TagDelegate(Identifier id, Tag<T> delegate) {
super(id);
this.delegate = delegate;
}
protected void onAccess() {
}
@Override
public boolean contains(T var1) {
onAccess();
return delegate.contains(var1);
}
@Override
public Collection<T> values() {
onAccess();
return delegate.values();
}
@Override
public Collection<Tag.Entry<T>> entries() {
onAccess();
return delegate.entries();
}
}

View file

@ -0,0 +1,36 @@
package net.fabricmc.fabric.tags;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.tag.BlockTags;
import net.minecraft.tag.ItemTags;
import net.minecraft.tag.Tag;
import net.minecraft.tag.TagContainer;
import net.minecraft.util.Identifier;
/**
* Helper methods for registering Tags.
*/
public final class TagRegistry {
private TagRegistry() {
}
public static Tag<Block> block(Identifier id) {
return new TagDelegate<Block>(id, null) {
private TagContainer<Block> container;
@Override
protected void onAccess() {
if (container != BlockTags.getContainer()) {
container = BlockTags.getContainer();
delegate = container.getOrCreate(this.getId());
}
}
};
}
public static Tag<Item> item(Identifier id) {
return new ItemTags.class_3490(id);
}
}

View file

@ -16,7 +16,7 @@
package net.fabricmc.fabric.tools;
import net.fabricmc.fabric.helpers.FabricBuilderEvent;
import net.fabricmc.fabric.events.ObjectBuilderEvent;
import net.fabricmc.fabric.util.TriState;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@ -74,7 +74,7 @@ public final class ToolManager {
}
static {
FabricBuilderEvent.BLOCK.register(ToolManager::onBlockRegistered);
ObjectBuilderEvent.BLOCK.register(ToolManager::onBlockRegistered);
}
private static void onBlockRegistered(Block.Builder builder, Block block) {