From 00cb2ea0a71a6a7dec27ad2e931f3ae5884e3b4d Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 19 Jun 2023 22:33:14 +0200 Subject: [PATCH] [Change] Support for optional Tags --- .../bclib/api/v3/datagen/TagDataProvider.java | 22 ++++-- .../worlds/together/tag/v3/TagRegistry.java | 70 +++++++++++++++++-- 2 files changed, 83 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/betterx/bclib/api/v3/datagen/TagDataProvider.java b/src/main/java/org/betterx/bclib/api/v3/datagen/TagDataProvider.java index dacfe8fd..73e23456 100644 --- a/src/main/java/org/betterx/bclib/api/v3/datagen/TagDataProvider.java +++ b/src/main/java/org/betterx/bclib/api/v3/datagen/TagDataProvider.java @@ -4,6 +4,7 @@ import org.betterx.worlds.together.tag.v3.TagRegistry; import net.minecraft.core.HolderLookup; import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagEntry; import net.minecraft.tags.TagKey; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; @@ -74,18 +75,29 @@ public class TagDataProvider extends FabricTagProvider { return modIDs == null || modIDs.contains(loc.getNamespace()); } + protected boolean isOptional(TagEntry e) { + return (e.verifyIfPresent(id -> false, id -> false)); + } + @Override protected void addTags(HolderLookup.Provider arg) { - tagRegistry.forEachTag((tag, locs, tags) -> { + tagRegistry.forEachEntry((tag, locs, tags) -> { if (!forceWrite.contains(tag) && locs.isEmpty() && tags.isEmpty()) return; final FabricTagProvider.FabricTagBuilder builder = getOrCreateTagBuilder(tag); - locs.sort(Comparator.comparing(ResourceLocation::toString)); - tags.sort(Comparator.comparing(a -> a.location().toString())); + locs.sort(Comparator.comparing(a -> a.first.toString())); + tags.sort(Comparator.comparing(a -> a.first.location().toString())); - locs.forEach(builder::add); - tags.forEach(builder::forceAddTag); + locs.forEach(pair -> { + if (isOptional(pair.second)) builder.addOptional(pair.first); + else builder.add(pair.first); + }); + + tags.forEach(pair -> { + if (isOptional(pair.second)) builder.addOptionalTag(pair.first); + else builder.forceAddTag(pair.first); + }); }, (tag, loc) -> forceWrite.contains(tag) || shouldAdd(tag.location()) || this.shouldAdd(loc)); } } diff --git a/src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java b/src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java index 08597bf9..8faea98a 100644 --- a/src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java +++ b/src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java @@ -2,6 +2,7 @@ package org.betterx.worlds.together.tag.v3; import org.betterx.bclib.BCLib; import org.betterx.bclib.interfaces.TriConsumer; +import org.betterx.bclib.util.Pair; import org.betterx.worlds.together.WorldsTogether; import net.minecraft.core.DefaultedRegistry; @@ -75,6 +76,11 @@ public class TagRegistry { super.add(tagID, elements); } + @SafeVarargs + public final void addOptional(TagKey tagID, T... elements) { + super.addOptional(tagID, elements); + } + @SafeVarargs public final void add(T element, TagKey... tagIDs) { super.add(element, tagIDs); @@ -97,6 +103,14 @@ public class TagRegistry { * @param elements array of Elements to add into tag. */ public void add(TagKey tagID, ResourceKey... elements) { + add(tagID, false, elements); + } + + public void addOptional(TagKey tagID, ResourceKey... elements) { + add(tagID, true, elements); + } + + void add(TagKey tagID, boolean optional, ResourceKey... elements) { if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); synchronized (this) { Set set = getSetForTag(tagID); @@ -110,8 +124,9 @@ public class TagRegistry { break; } } + if (id != null) { - set.add(TagEntry.element(id)); + set.add(optional ? TagEntry.optionalElement(id) : TagEntry.element(id)); } } } @@ -139,6 +154,13 @@ public class TagRegistry { } } + @SafeVarargs + public final void addOptional(TagKey tagID, ItemLike... elements) { + for (ItemLike element : elements) { + addOptional(tagID, element.asItem()); + } + } + @SafeVarargs public final void add(ItemLike element, TagKey... tagIDs) { super.add(element.asItem(), tagIDs); @@ -242,12 +264,20 @@ public class TagRegistry { } public void addOtherTags(TagKey tagID, TagKey... tags) { + addOtherTags(tagID, false, tags); + } + + public void addOptionalOtherTags(TagKey tagID, TagKey... tags) { + addOtherTags(tagID, true, tags); + } + + void addOtherTags(TagKey tagID, boolean optional, TagKey... tags) { if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); Set set = getSetForTag(tagID); for (TagKey tag : tags) { ResourceLocation id = tag.location(); if (id != null) { - set.add(TagEntry.tag(id)); + set.add(optional ? TagEntry.optionalTag(id) : TagEntry.tag(id)); } } } @@ -259,11 +289,19 @@ public class TagRegistry { * @param elements array of Elements to add into tag. */ protected void add(TagKey tagID, T... elements) { + add(tagID, false, elements); + } + + protected void addOptional(TagKey tagID, T... elements) { + add(tagID, true, elements); + } + + protected void add(TagKey tagID, boolean optional, T... elements) { if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen."); Set set = getSetForTag(tagID); for (T element : elements) { ResourceLocation id = locationProvider.apply(element); - + //only add if the set doesn't already contain the element for (TagEntry tagEntry : set) { if (!tagEntry.elementOrTag().tag() && tagEntry.elementOrTag().id().equals(id)) { @@ -273,7 +311,7 @@ public class TagRegistry { } if (id != null) { - set.add(TagEntry.element(id)); + set.add(optional ? TagEntry.optionalElement(id) : TagEntry.element(id)); } } } @@ -328,6 +366,30 @@ public class TagRegistry { }); } + public void forEachEntry( + TriConsumer, List>, List, TagEntry>>> consumer, + BiPredicate, ResourceLocation> allow + ) { + tags.forEach((tag, set) -> { + List> locations = new LinkedList<>(); + List, TagEntry>> tags = new LinkedList<>(); + + + set.forEach(e -> { + ExtraCodecs.TagOrElementLocation t = e.elementOrTag(); + if (allow == null || allow.test(tag, t.id())) { + if (t.tag()) { + tags.add(new Pair<>(TagKey.create(registryKey, t.id()), e)); + } else { + locations.add(new Pair<>(t.id(), e)); + } + } + }); + + consumer.accept(tag, locations, tags); + }); + } + public void apply(Map> tagsMap) { //this.isFrozen = true; if (BCLib.isDatagen()) {