diff --git a/patches/minecraft/net/minecraft/tags/Tag.java.patch b/patches/minecraft/net/minecraft/tags/Tag.java.patch index 8c9026aa4..8ed2d291b 100644 --- a/patches/minecraft/net/minecraft/tags/Tag.java.patch +++ b/patches/minecraft/net/minecraft/tags/Tag.java.patch @@ -18,24 +18,39 @@ this.field_199888_a = p_i48224_1_; this.field_199889_b = (Set)(p_i48224_3_ ? Sets.newLinkedHashSet() : Sets.newHashSet()); this.field_200150_c = p_i48224_2_; -@@ -48,7 +52,7 @@ +@@ -45,11 +49,18 @@ + JsonArray jsonarray = new JsonArray(); + + for(Tag.ITagEntry itagentry : this.field_200150_c) { ++ if (!(itagentry instanceof net.minecraftforge.common.data.IOptionalTagEntry)) itagentry.func_200576_a(jsonarray, p_200571_1_); } ++ JsonArray optional = new JsonArray(); ++ for(Tag.ITagEntry itagentry : this.field_200150_c) { ++ if (itagentry instanceof net.minecraftforge.common.data.IOptionalTagEntry) ++ itagentry.func_200576_a(optional, p_200571_1_); ++ } - jsonobject.addProperty("replace", false); + jsonobject.addProperty("replace", replace); jsonobject.add("values", jsonarray); ++ jsonobject.add("optional", optional); return jsonobject; } -@@ -77,6 +81,7 @@ - public static class Builder { + +@@ -74,9 +85,10 @@ + return this.field_199888_a; + } + +- public static class Builder { ++ public static class Builder implements net.minecraftforge.common.extensions.IForgeTagBuilder { private final Set> field_200052_a = Sets.newLinkedHashSet(); private boolean field_200053_b; + private boolean replace = false; public static Tag.Builder func_200047_a() { return new Tag.Builder<>(); -@@ -103,6 +108,22 @@ +@@ -103,6 +115,22 @@ return this; } @@ -58,7 +73,7 @@ public Tag.Builder func_200045_a(boolean p_200045_1_) { this.field_200053_b = p_200045_1_; return this; -@@ -119,7 +140,7 @@ +@@ -119,7 +147,7 @@ } public Tag func_200051_a(ResourceLocation p_200051_1_) { @@ -67,7 +82,7 @@ } public Tag.Builder func_219783_a(Function> p_219783_1_, JsonObject p_219783_2_) { -@@ -143,8 +164,10 @@ +@@ -143,8 +171,26 @@ } this.field_200052_a.addAll(list); @@ -75,10 +90,26 @@ return this; } + public Tag.Builder remove(Tag.ITagEntry e) { this.field_200052_a.remove(e); return this; } ++ ++ public Tag.Builder addOptional(TagCollection collection, ResourceLocation entry) { ++ return addOptional(collection.getEntryLookup(), Collections.singleton(entry)); ++ } ++ ++ @SafeVarargs ++ public final Tag.Builder addOptional(TagCollection collection, ResourceLocation... entries) { ++ return addOptional(collection.getEntryLookup(), Lists.newArrayList(entries)); ++ } ++ ++ @SafeVarargs ++ public final Tag.Builder addOptionalTag(ResourceLocation... tags) { ++ for (ResourceLocation tag : tags) ++ addOptionalTag(tag); ++ return this; ++ } } public interface ITagEntry { -@@ -183,6 +206,8 @@ +@@ -183,6 +229,8 @@ public Collection func_200578_a() { return this.field_200165_a; } @@ -87,7 +118,7 @@ } public static class TagEntry implements Tag.ITagEntry { -@@ -229,5 +254,7 @@ +@@ -229,5 +277,7 @@ public void func_200576_a(JsonArray p_200576_1_, Function p_200576_2_) { p_200576_1_.add("#" + this.func_200577_a()); } diff --git a/patches/minecraft/net/minecraft/tags/TagCollection.java.patch b/patches/minecraft/net/minecraft/tags/TagCollection.java.patch new file mode 100644 index 000000000..8b4f68851 --- /dev/null +++ b/patches/minecraft/net/minecraft/tags/TagCollection.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/tags/TagCollection.java ++++ b/net/minecraft/tags/TagCollection.java +@@ -154,4 +154,8 @@ + public Map> func_200039_c() { + return this.field_199921_d; + } ++ ++ Function> getEntryLookup() { ++ return this.field_200040_e; ++ } + } diff --git a/src/generated_test/resources/.cache/cache b/src/generated_test/resources/.cache/cache index 5c2dec9d1..0c7be501f 100644 --- a/src/generated_test/resources/.cache/cache +++ b/src/generated_test/resources/.cache/cache @@ -24,7 +24,7 @@ c3ecb601615c300cafbdd9dc28f9fc42b6835dcd assets\data_gen_test\models\block\birch 3bcea12fba8714c7ad7c00f440f3e7546a8958ce assets\data_gen_test\models\block\birch_fence_gate_open.json 13b47687fb80334b3e51781e691f53f8073843a7 assets\data_gen_test\models\block\birch_fence_gate_wall.json dd0a89461e5f72c08ccf6f3d07bce9c290019022 assets\data_gen_test\models\block\birch_fence_gate_wall_open.json -1d0f4dceda264528ae1b1f5f971ae84202405e51 assets\data_gen_test\models\block\block.json +49948428acf0defe004ff07718afd9b50fc41326 assets\data_gen_test\models\block\block.json 42fcd2c027f204708f423808f22f6e4c0d5f586b assets\data_gen_test\models\block\cobblestone_wall_post.json 21d8ec1410152c67c4b7a06184be545ef1e1d0cf assets\data_gen_test\models\block\cobblestone_wall_side.json 26c80ee9a99336b434c9984445bfcf01b25f2cd0 assets\data_gen_test\models\block\cube.json @@ -63,3 +63,4 @@ bf2e445b48b024354a69138b20a4a4a8aa5d15d1 assets\minecraft\blockstates\oak_trapdo a012d6d92bab1c91913bd0f2dc0492a0fce916f2 assets\minecraft\blockstates\wall_torch.json 4fbaf6f4a3ea05cc071076e27f44ac81f9cc50e3 data\data_gen_test\advancements\conditional.json ed4cbf1a3a2f5d8969f6346fdc9acdbe81d0c919 data\data_gen_test\recipes\conditional.json +2c3e2073a1597baaa2970de5ae1649781f87aef8 data\data_gen_test\tags\blocks\test.json diff --git a/src/generated_test/resources/assets/data_gen_test/models/block/block.json b/src/generated_test/resources/assets/data_gen_test/models/block/block.json index 7ad9a5c7d..c69c0f6b9 100644 --- a/src/generated_test/resources/assets/data_gen_test/models/block/block.json +++ b/src/generated_test/resources/assets/data_gen_test/models/block/block.json @@ -1,4 +1,5 @@ { + "gui_light": "side", "display": { "gui": { "rotation": [ diff --git a/src/generated_test/resources/data/data_gen_test/tags/blocks/test.json b/src/generated_test/resources/data/data_gen_test/tags/blocks/test.json new file mode 100644 index 000000000..a844bba42 --- /dev/null +++ b/src/generated_test/resources/data/data_gen_test/tags/blocks/test.json @@ -0,0 +1,11 @@ +{ + "replace": false, + "values": [ + "minecraft:diamond_block", + "#minecraft:stone_bricks" + ], + "optional": [ + "chisel:marble/raw", + "#forge:storage_blocks/ruby" + ] +} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index f2e3971cd..832459af0 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -39,6 +39,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Queues; import com.google.common.collect.Sets; import com.google.gson.Gson; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; @@ -118,6 +119,7 @@ import net.minecraft.world.dimension.DimensionType; import net.minecraft.world.storage.loot.LootContext; import net.minecraft.world.storage.loot.LootTable; import net.minecraft.world.storage.loot.LootTableManager; +import net.minecraftforge.common.data.IOptionalTagEntry; import net.minecraftforge.common.loot.IGlobalLootModifier; import net.minecraftforge.common.loot.LootModifierManager; import net.minecraftforge.common.util.BlockSnapshot; @@ -1095,12 +1097,9 @@ public class ForgeHooks { String s = JSONUtils.getString(entry, "value"); if (!s.startsWith("#")) - { - T value = valueGetter.apply(new ResourceLocation(s)).orElse(null); - if (value != null) - builder.add(value); - } else - builder.add(new OptionalTagEntry<>(new ResourceLocation(s.substring(1)))); + builder.addOptional(valueGetter, Collections.singleton(new ResourceLocation(s))); + else + builder.addOptionalTag(new ResourceLocation(s.substring(1))); } } @@ -1114,7 +1113,7 @@ public class ForgeHooks T value = valueGetter.apply(new ResourceLocation(s)).orElse(null); if (value != null) { - Tag.ITagEntry dummyEntry = new Tag.ListEntry<>(Collections.singletonList(value)); + Tag.ITagEntry dummyEntry = new Tag.ListEntry<>(Collections.singleton(value)); builder.remove(dummyEntry); } } else @@ -1126,35 +1125,6 @@ public class ForgeHooks } } - private static class OptionalTagEntry extends Tag.TagEntry - { - private Tag resolvedTag = null; - - OptionalTagEntry(ResourceLocation referent) - { - super(referent); - } - - @Override - public boolean resolve(@Nonnull Function> resolver) - { - if (this.resolvedTag == null) - { - this.resolvedTag = resolver.apply(this.getSerializedId()); - } - return true; // never fail if resolver returns null - } - - @Override - public void populate(@Nonnull Collection items) - { - if (this.resolvedTag != null) - { - items.addAll(this.resolvedTag.getAllElements()); - } - } - } - private static final Map, DataSerializerEntry> serializerEntries = GameData.getSerializerMap(); //private static final ForgeRegistry serializerRegistry = (ForgeRegistry) ForgeRegistries.DATA_SERIALIZERS; // Do not reimplement this ^ it introduces a chicken-egg scenario by classloading registries during bootstrap diff --git a/src/main/java/net/minecraftforge/common/data/IOptionalTagEntry.java b/src/main/java/net/minecraftforge/common/data/IOptionalTagEntry.java new file mode 100644 index 000000000..1bb8ef85f --- /dev/null +++ b/src/main/java/net/minecraftforge/common/data/IOptionalTagEntry.java @@ -0,0 +1,8 @@ +package net.minecraftforge.common.data; + +import net.minecraft.tags.Tag.ITagEntry; + +public interface IOptionalTagEntry extends ITagEntry +{ + +} diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeTagBuilder.java b/src/main/java/net/minecraftforge/common/extensions/IForgeTagBuilder.java new file mode 100644 index 000000000..fb495d5a5 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeTagBuilder.java @@ -0,0 +1,85 @@ +package net.minecraftforge.common.extensions; + +import java.util.Collection; +import java.util.Optional; +import java.util.function.Function; + +import javax.annotation.Nonnull; + +import com.google.gson.JsonArray; + +import net.minecraft.tags.Tag; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.data.IOptionalTagEntry; + +public interface IForgeTagBuilder +{ + default Tag.Builder addOptional(Function> valueGetter, Collection locations) + { + return ((Tag.Builder)this).add(new OptionalListEntry<>(locations, valueGetter)); + } + + default Tag.Builder addOptionalTag(ResourceLocation tag) + { + return ((Tag.Builder)this).add(new OptionalTagEntry<>(tag)); + } +} + +class OptionalListEntry implements IOptionalTagEntry +{ + private final Collection names; + private final Function> valueGetter; + + OptionalListEntry(Collection names, Function> valueGetter) + { + this.names = names; + this.valueGetter = valueGetter; + } + + @Override + public void populate(Collection itemsIn) + { + for (ResourceLocation rl : names) + { + valueGetter.apply(rl).ifPresent(itemsIn::add); + } + } + + @Override + public void serialize(JsonArray array, Function getNameForObject) + { + for (ResourceLocation rl : names) + { + array.add(rl.toString()); + } + } +} + +class OptionalTagEntry extends Tag.TagEntry implements IOptionalTagEntry +{ + private Tag resolvedTag = null; + + OptionalTagEntry(ResourceLocation referent) + { + super(referent); + } + + @Override + public boolean resolve(@Nonnull Function> resolver) + { + if (this.resolvedTag == null) + { + this.resolvedTag = resolver.apply(this.getSerializedId()); + } + return true; // never fail if resolver returns null + } + + @Override + public void populate(@Nonnull Collection items) + { + if (this.resolvedTag != null) + { + items.addAll(this.resolvedTag.getAllElements()); + } + } +} diff --git a/src/main/java/net/minecraftforge/fml/client/EarlyLoaderGUI.java b/src/main/java/net/minecraftforge/fml/client/EarlyLoaderGUI.java index 83192cb60..a1ad71a05 100644 --- a/src/main/java/net/minecraftforge/fml/client/EarlyLoaderGUI.java +++ b/src/main/java/net/minecraftforge/fml/client/EarlyLoaderGUI.java @@ -24,7 +24,6 @@ import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.MainWindow; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.AbstractGui; import net.minecraft.util.math.MathHelper; import net.minecraftforge.fml.loading.progress.StartupMessageManager; import org.apache.commons.lang3.tuple.Pair; diff --git a/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java b/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java index 3deb3c80b..068d57e37 100644 --- a/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java +++ b/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java @@ -65,6 +65,8 @@ import net.minecraft.block.WallBlock; import net.minecraft.client.renderer.model.ItemCameraTransforms; import net.minecraft.client.renderer.model.ItemTransformVec3f; import net.minecraft.client.renderer.model.Variant; +import net.minecraft.client.renderer.model.BlockModel.GuiLight; +import net.minecraft.data.BlockTagsProvider; import net.minecraft.data.DataGenerator; import net.minecraft.data.DirectoryCache; import net.minecraft.data.IFinishedRecipe; @@ -76,6 +78,7 @@ import net.minecraft.item.Items; import net.minecraft.potion.Effects; import net.minecraft.resources.IResource; import net.minecraft.resources.ResourcePackType; +import net.minecraft.tags.BlockTags; import net.minecraft.util.Direction; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.StringTextComponent; @@ -126,6 +129,7 @@ public class DataGeneratorTest if (event.includeServer()) { gen.addProvider(new Recipes(gen)); + gen.addProvider(new Tags(gen)); } } @@ -183,6 +187,25 @@ public class DataGeneratorTest } } + public static class Tags extends BlockTagsProvider + { + + public Tags(DataGenerator gen) + { + super(gen); + } + + @Override + protected void registerTags() + { + getBuilder(new BlockTags.Wrapper(new ResourceLocation(MODID, "test"))) + .add(Blocks.DIAMOND_BLOCK) + .add(BlockTags.STONE_BRICKS) + .addOptional(BlockTags.getCollection(), new ResourceLocation("chisel", "marble/raw")) + .addOptionalTag(new ResourceLocation("forge", "storage_blocks/ruby")); + } + } + public static class Lang extends LanguageProvider { public Lang(DataGenerator gen) @@ -339,7 +362,9 @@ public class DataGeneratorTest ConfiguredModel.class)); // From here on, models are 1-to-1 copies of vanilla (except for model locations) and will be tested as such below - ModelFile block = models().getBuilder("block").transforms() + ModelFile block = models().getBuilder("block") + .guiLight(GuiLight.SIDE) + .transforms() .transform(Perspective.GUI) .rotation(30, 225, 0) .scale(0.625f)