*WIP:* Adapted TagAPI to new TagKey's

This commit is contained in:
Frank 2022-03-08 11:47:32 +01:00
parent 48db196c7b
commit 2dbbfe04d8
4 changed files with 95 additions and 148 deletions

View file

@ -1,23 +1,23 @@
package ru.bclib.api.tag; package ru.bclib.api.tag;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import ru.bclib.api.tag.TagAPI.TagNamed;
public class CommonBlockTags { public class CommonBlockTags {
public static final TagNamed<Block> BARREL = TagAPI.makeCommonBlockTag("barrel"); public static final TagKey<Block> BARREL = TagAPI.makeCommonBlockTag("barrel");
public static final TagNamed<Block> BOOKSHELVES = TagAPI.makeCommonBlockTag("bookshelves"); public static final TagKey<Block> BOOKSHELVES = TagAPI.makeCommonBlockTag("bookshelves");
public static final TagNamed<Block> CHEST = TagAPI.makeCommonBlockTag("chest"); public static final TagKey<Block> CHEST = TagAPI.makeCommonBlockTag("chest");
public static final TagNamed<Block> END_STONES = TagAPI.makeCommonBlockTag("end_stones"); public static final TagKey<Block> END_STONES = TagAPI.makeCommonBlockTag("end_stones");
public static final TagNamed<Block> GEN_END_STONES = END_STONES; public static final TagKey<Block> GEN_END_STONES = END_STONES;
public static final TagNamed<Block> IMMOBILE = TagAPI.makeCommonBlockTag("immobile"); public static final TagKey<Block> IMMOBILE = TagAPI.makeCommonBlockTag("immobile");
public static final TagNamed<Block> LEAVES = TagAPI.makeCommonBlockTag("leaves"); public static final TagKey<Block> LEAVES = TagAPI.makeCommonBlockTag("leaves");
public static final TagNamed<Block> NETHERRACK = TagAPI.makeCommonBlockTag("netherrack"); public static final TagKey<Block> NETHERRACK = TagAPI.makeCommonBlockTag("netherrack");
public static final TagNamed<Block> NETHER_MYCELIUM = TagAPI.makeCommonBlockTag("nether_mycelium"); public static final TagKey<Block> NETHER_MYCELIUM = TagAPI.makeCommonBlockTag("nether_mycelium");
public static final TagNamed<Block> NETHER_PORTAL_FRAME = TagAPI.makeCommonBlockTag("nether_pframe"); public static final TagKey<Block> NETHER_PORTAL_FRAME = TagAPI.makeCommonBlockTag("nether_pframe");
public static final TagNamed<Block> NETHER_STONES = TagAPI.makeCommonBlockTag("nether_stones"); public static final TagKey<Block> NETHER_STONES = TagAPI.makeCommonBlockTag("nether_stones");
public static final TagNamed<Block> SAPLINGS = TagAPI.makeCommonBlockTag("saplings"); public static final TagKey<Block> SAPLINGS = TagAPI.makeCommonBlockTag("saplings");
public static final TagNamed<Block> SOUL_GROUND = TagAPI.makeCommonBlockTag("soul_ground"); public static final TagKey<Block> SOUL_GROUND = TagAPI.makeCommonBlockTag("soul_ground");
public static final TagNamed<Block> WOODEN_BARREL = TagAPI.makeCommonBlockTag("wooden_barrels"); public static final TagKey<Block> WOODEN_BARREL = TagAPI.makeCommonBlockTag("wooden_barrels");
public static final TagNamed<Block> WOODEN_CHEST = TagAPI.makeCommonBlockTag("wooden_chests"); public static final TagKey<Block> WOODEN_CHEST = TagAPI.makeCommonBlockTag("wooden_chests");
public static final TagNamed<Block> WORKBENCHES = TagAPI.makeCommonBlockTag("workbench"); public static final TagKey<Block> WORKBENCHES = TagAPI.makeCommonBlockTag("workbench");
} }

View file

@ -1,19 +1,19 @@
package ru.bclib.api.tag; package ru.bclib.api.tag;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import ru.bclib.api.tag.TagAPI.TagNamed;
public class CommonItemTags { public class CommonItemTags {
public final static TagNamed<Item> HAMMERS = TagAPI.makeCommonItemTag("hammers"); public final static TagKey<Item> HAMMERS = TagAPI.makeCommonItemTag("hammers");
public static final TagNamed<Item> BARREL = TagAPI.makeCommonItemTag("barrel"); public static final TagKey<Item> BARREL = TagAPI.makeCommonItemTag("barrel");
public static final TagNamed<Item> CHEST = TagAPI.makeCommonItemTag("chest"); public static final TagKey<Item> CHEST = TagAPI.makeCommonItemTag("chest");
public static final TagNamed<Item> SHEARS = TagAPI.makeCommonItemTag("shears"); public static final TagKey<Item> SHEARS = TagAPI.makeCommonItemTag("shears");
public static final TagNamed<Item> FURNACES = TagAPI.makeCommonItemTag("furnaces"); public static final TagKey<Item> FURNACES = TagAPI.makeCommonItemTag("furnaces");
public static final TagNamed<Item> IRON_INGOTS = TagAPI.makeCommonItemTag("iron_ingots"); public static final TagKey<Item> IRON_INGOTS = TagAPI.makeCommonItemTag("iron_ingots");
public static final TagNamed<Item> LEAVES = TagAPI.makeCommonItemTag("leaves"); public static final TagKey<Item> LEAVES = TagAPI.makeCommonItemTag("leaves");
public static final TagNamed<Item> SAPLINGS = TagAPI.makeCommonItemTag("saplings"); public static final TagKey<Item> SAPLINGS = TagAPI.makeCommonItemTag("saplings");
public static final TagNamed<Item> SOUL_GROUND = TagAPI.makeCommonItemTag("soul_ground"); public static final TagKey<Item> SOUL_GROUND = TagAPI.makeCommonItemTag("soul_ground");
public static final TagNamed<Item> WOODEN_BARREL = TagAPI.makeCommonItemTag("wooden_barrels"); public static final TagKey<Item> WOODEN_BARREL = TagAPI.makeCommonItemTag("wooden_barrels");
public static final TagNamed<Item> WOODEN_CHEST = TagAPI.makeCommonItemTag("wooden_chests"); public static final TagKey<Item> WOODEN_CHEST = TagAPI.makeCommonItemTag("wooden_chests");
public static final TagNamed<Item> WORKBENCHES = TagAPI.makeCommonItemTag("workbench"); public static final TagKey<Item> WORKBENCHES = TagAPI.makeCommonItemTag("workbench");
} }

View file

@ -5,10 +5,8 @@ import com.google.common.collect.Sets;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.ItemTags;
import net.minecraft.tags.TagKey;
import net.minecraft.tags.Tag; import net.minecraft.tags.Tag;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
@ -17,94 +15,83 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import ru.bclib.mixin.common.DiggerItemAccessor; import ru.bclib.mixin.common.DiggerItemAccessor;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.function.Supplier; import java.util.function.BiConsumer;
public class TagAPI { public class TagAPI {
private static final Map<ResourceLocation, Set<ResourceLocation>> TAGS_BLOCK = Maps.newConcurrentMap(); private static final Map<ResourceLocation, Set<ResourceLocation>> TAGS_BLOCK = Maps.newConcurrentMap();
private static final Map<ResourceLocation, Set<ResourceLocation>> TAGS_ITEM = Maps.newConcurrentMap(); private static final Map<ResourceLocation, Set<ResourceLocation>> TAGS_ITEM = Maps.newConcurrentMap();
/** /**
* Get or create {@link TagNamed}. * Get or create {@link TagKey}.
* *
* @param containerSupplier - {@link TagCollection} {@link Supplier} tag collection; * @param registry - {@link Registry<T>} tag collection;
* @param id - {@link ResourceLocation} tag id. * @param id - {@link ResourceLocation} tag id.
* @return {@link TagNamed}. * @return {@link TagKey}.
*/ */
public static <T> TagNamed<T> makeTag(Supplier<TagCollection<T>> containerSupplier, TagLocation<T> id) { public static <T> TagKey<T> makeTag(Registry<T> registry, TagLocation<T> id) {
Tag<T> tag = containerSupplier.get().getTag(id); //TODO: 1.18.2 check if registry.key() gets the correct result
return tag == null ? new Delegate<>(id, containerSupplier) : CommonDelegate.proxy((TagKey<T>) tag); return registry
.getTagNames()
.filter(tagKey -> tagKey.location().equals(id))
.findAny()
.orElse(TagKey.create(registry.key(), id));
} }
/** /**
* Get or create {@link Block} {@link TagNamed} with mod namespace. * Get or create {@link Block} {@link TagKey} with mod namespace.
* *
* @param modID - {@link String} mod namespace (mod id); * @param modID - {@link String} mod namespace (mod id);
* @param name - {@link String} tag name. * @param name - {@link String} tag name.
* @return {@link Block} {@link TagNamed}. * @return {@link Block} {@link TagKey}.
*/ */
public static TagNamed<Block> makeBlockTag(String modID, String name) { public static TagKey<Block> makeBlockTag(String modID, String name) {
return makeTag(BlockTags::getAllTags, new TagLocation<>(modID, name)); return makeTag(Registry.BLOCK, new TagLocation<>(modID, name));
} }
/** /**
* Get or create {@link Item} {@link TagNamed} with mod namespace. * Get or create {@link Item} {@link TagKey} with mod namespace.
* *
* @param modID - {@link String} mod namespace (mod id); * @param modID - {@link String} mod namespace (mod id);
* @param name - {@link String} tag name. * @param name - {@link String} tag name.
* @return {@link Item} {@link TagNamed}. * @return {@link Item} {@link TagKey}.
*/ */
public static TagNamed<Item> makeItemTag(String modID, String name) { public static TagKey<Item> makeItemTag(String modID, String name) {
return makeTag(ItemTags::getAllTags, new TagLocation<>(modID, name)); return makeTag(Registry.ITEM, new TagLocation<>(modID, name));
} }
/** /**
* Get or create {@link Block} {@link TagNamed}. * Get or create {@link Block} {@link TagKey}.
* *
* @param name - {@link String} tag name. * @param name - {@link String} tag name.
* @return {@link Block} {@link TagNamed}. * @return {@link Block} {@link TagKey}.
* @see <a href="https://fabricmc.net/wiki/tutorial:tags">Fabric Wiki (Tags)</a> * @see <a href="https://fabricmc.net/wiki/tutorial:tags">Fabric Wiki (Tags)</a>
*/ */
public static TagNamed<Block> makeCommonBlockTag(String name) { public static TagKey<Block> makeCommonBlockTag(String name) {
return makeTag(BlockTags::getAllTags, new TagLocation<>("c", name)); return makeTag(Registry.BLOCK, new TagLocation<>("c", name));
} }
/** /**
* Get or create {@link Item} {@link TagNamed}. * Get or create {@link Item} {@link TagKey}.
* *
* @param name - {@link String} tag name. * @param name - {@link String} tag name.
* @return {@link Item} {@link TagNamed}. * @return {@link Item} {@link TagKey}.
* @see <a href="https://fabricmc.net/wiki/tutorial:tags">Fabric Wiki (Tags)</a> * @see <a href="https://fabricmc.net/wiki/tutorial:tags">Fabric Wiki (Tags)</a>
*/ */
public static TagNamed<Item> makeCommonItemTag(String name) { public static TagKey<Item> makeCommonItemTag(String name) {
return makeTag(ItemTags::getAllTags, new TagLocation<>("c", name)); return makeTag(Registry.ITEM, new TagLocation<>("c", name));
}
/**
* Get or create Minecraft {@link Block} {@link TagNamed}.
*
* @param name - {@link String} tag name.
* @return {@link Block} {@link TagNamed}.
*/
@Deprecated(forRemoval = true)
public static TagNamed<Block> getMCBlockTag(String name) {
ResourceLocation id = new ResourceLocation(name);
Tag<Block> tag = BlockTags.getAllTags().getTag(id);
return CommonDelegate.proxy(tag == null ? (TagKey<Block>) TagFactory.BLOCK.create(id): (TagKey<Block>) tag);
} }
/** /**
* Initializes basic tags. Should be called only in BCLib main class. * Initializes basic tags. Should be called only in BCLib main class.
*/ */
public static void init() { public static void init() {
addBlockTag(CommonBlockTags.BOOKSHELVES.getName(), Blocks.BOOKSHELF); addBlockTag(CommonBlockTags.BOOKSHELVES, Blocks.BOOKSHELF);
addBlockTag(CommonBlockTags.CHEST.getName(), Blocks.CHEST); addBlockTag(CommonBlockTags.CHEST, Blocks.CHEST);
addItemTag(CommonItemTags.CHEST.getName(), Items.CHEST); addItemTag(CommonItemTags.CHEST, Items.CHEST);
addItemTag(CommonItemTags.IRON_INGOTS.getName(), Items.IRON_INGOT); addItemTag(CommonItemTags.IRON_INGOTS, Items.IRON_INGOT);
addItemTag(CommonItemTags.FURNACES.getName(), Blocks.FURNACE); addItemTag(CommonItemTags.FURNACES, Blocks.FURNACE);
} }
/** /**
@ -127,6 +114,15 @@ public class TagAPI {
public static void addBlockTag(TagLocation<Block> tagID, Block... blocks) { public static void addBlockTag(TagLocation<Block> tagID, Block... blocks) {
addBlockTagUntyped(tagID, blocks); addBlockTagUntyped(tagID, blocks);
} }
/**
* Adds one Tag to multiple Blocks.
* @param tagID {@link TagKey<Block>} tag ID.
* @param blocks array of {@link Block} to add into tag.
*/
public static void addBlockTag(TagKey<Block> tagID, Block... blocks) {
addBlockTagUntyped(tagID.location(), blocks);
}
/** /**
* Adds one Tag to multiple Blocks. * Adds one Tag to multiple Blocks.
@ -163,6 +159,15 @@ public class TagAPI {
public static void addItemTag(TagLocation<Item> tagID, ItemLike... items) { public static void addItemTag(TagLocation<Item> tagID, ItemLike... items) {
addItemTagUntyped(tagID, items); addItemTagUntyped(tagID, items);
} }
/**
* Adds one Tag to multiple Items.
* @param tagID {@link TagKey<Item>} tag ID.
* @param items array of {@link ItemLike} to add into tag.
*/
public static void addItemTag(TagKey<Item> tagID, ItemLike... items) {
addItemTagUntyped(tagID.location(), items);
}
/** /**
* Adds one Tag to multiple Items. * Adds one Tag to multiple Items.
@ -189,16 +194,14 @@ public class TagAPI {
* @param tagsMap The map that will hold the registered Tags * @param tagsMap The map that will hold the registered Tags
* @return The {@code tagsMap} Parameter. * @return The {@code tagsMap} Parameter.
*/ */
public static Map<ResourceLocation, Tag.Builder> apply(String directory, Map<ResourceLocation, Tag.Builder> tagsMap) { public static <T> Map<ResourceLocation, Tag.Builder> apply(String directory, Map<ResourceLocation, Tag.Builder> tagsMap) {
Map<ResourceLocation, Set<ResourceLocation>> tagMap = null; final BiConsumer<ResourceLocation, Set<ResourceLocation>> consumer;
consumer = (id, ids) -> apply(tagsMap.computeIfAbsent(id, key -> Tag.Builder.tag()), ids);
if ("tags/blocks".equals(directory)) { if ("tags/blocks".equals(directory)) {
tagMap = TAGS_BLOCK; TAGS_BLOCK.forEach(consumer);
} }
else if ("tags/items".equals(directory)) { else if ("tags/items".equals(directory)) {
tagMap = TAGS_ITEM; TAGS_ITEM.forEach(consumer);
}
if (tagMap != null) {
tagMap.forEach((id, ids) -> apply(tagsMap.computeIfAbsent(id, key -> Tag.Builder.tag()), ids));
} }
return tagsMap; return tagsMap;
} }
@ -214,16 +217,8 @@ public class TagAPI {
ids.forEach(value -> builder.addElement(value, "BCLib Code")); ids.forEach(value -> builder.addElement(value, "BCLib Code"));
return builder; return builder;
} }
/**
* Extends {@link TagNamed} to return a type safe {@link TagLocation}. This Type was introduced to
* allow type-safe definition of Tags using their ResourceLocation.
* @param <T> The Type of the underlying {@link Tag}
*/
public interface TagNamed<T> extends TagKey<T>{
TagLocation<T> getName();
}
/** /**
* Extends (without changing) {@link ResourceLocation}. This Type was introduced to allow type-safe definition af * Extends (without changing) {@link ResourceLocation}. This Type was introduced to allow type-safe definition af
* Tags using their ResourceLocation. * Tags using their ResourceLocation.
@ -233,68 +228,17 @@ public class TagAPI {
public TagLocation(String string) { public TagLocation(String string) {
super(string); super(string);
} }
public TagLocation(String string, String string2) { public TagLocation(String string, String string2) {
super(string, string2); super(string, string2);
} }
public TagLocation(ResourceLocation location) { public TagLocation(ResourceLocation location) {
super(location.getNamespace(), location.getPath()); super(location.getNamespace(), location.getPath());
} }
public static<R> TagLocation<R> of(TagKey<R> tag){ public static<R> TagLocation<R> of(TagKey<R> tag){
return new TagLocation<R>(tag.getName()); return new TagLocation<R>(tag.location());
}
}
private abstract static class CommonDelegate<T> implements TagNamed<T> {
protected final TagKey<T> delegate;
protected CommonDelegate(TagKey<T> source){
this.delegate = source;
}
public static<T> TagNamed<T> proxy(TagKey<T> source){
if (source instanceof TagNamed typed) return typed;
return new ProxyDelegate<>(source);
}
@Override
public boolean contains(T object) {
return delegate.contains(object);
}
@Override
public List<T> getValues() {
return delegate.getValues();
}
@Override
public T getRandomElement(Random random) {
return delegate.getRandomElement(random);
}
}
private static final class ProxyDelegate<T> extends CommonDelegate<T>{
private final TagLocation<T> id;
private ProxyDelegate(Tag.Named<T> source) {
super( source);
id = new TagLocation<>(source.getName()
.getNamespace(), source.getName()
.getPath());
}
@Override
public TagLocation<T> getName(){
return id;
}
}
private static final class Delegate<T> extends CommonDelegate<T>{
public Delegate(TagLocation<T> id, Supplier<TagCollection<T>> containerSupplier) {
super( new TagDelegate<>(id, containerSupplier));
}
@Override
public TagLocation<T> getName(){
return (TagLocation<T>)delegate.getName();
} }
} }

View file

@ -3,6 +3,7 @@ package ru.bclib.mixin.common;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.Tag; import net.minecraft.tags.Tag;
import net.minecraft.tags.TagLoader; import net.minecraft.tags.TagLoader;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -13,11 +14,13 @@ import java.util.Map;
@Mixin(TagLoader.class) @Mixin(TagLoader.class)
public class TagLoaderMixin { public class TagLoaderMixin {
@Final
@Shadow @Shadow
private String directory; private String directory;
@ModifyArg(method = "loadAndBuild", at = @At(value = "INVOKE", target = "Lnet/minecraft/tags/TagLoader;build(Ljava/util/Map;)Lnet/minecraft/tags/TagCollection;")) @ModifyArg(method = "loadAndBuild", at = @At(value = "INVOKE", target = "Lnet/minecraft/tags/TagLoader;build(Ljava/util/Map;)Ljava/util/Map;"))
public Map<ResourceLocation, Tag.Builder> be_modifyTags(Map<ResourceLocation, Tag.Builder> tagsMap) { public Map<ResourceLocation, Tag.Builder> be_modifyTags(Map<ResourceLocation, Tag.Builder> tagsMap) {
//TODO: 1.18.2 Check if this still works as expected
return TagAPI.apply(directory, tagsMap); return TagAPI.apply(directory, tagsMap);
} }
} }