diff --git a/patches/minecraft/net/minecraft/data/LootTableProvider.java.patch b/patches/minecraft/net/minecraft/data/LootTableProvider.java.patch new file mode 100644 index 0000000000..8f73df0106 --- /dev/null +++ b/patches/minecraft/net/minecraft/data/LootTableProvider.java.patch @@ -0,0 +1,47 @@ +--- a/net/minecraft/data/LootTableProvider.java ++++ b/net/minecraft/data/LootTableProvider.java +@@ -42,7 +42,7 @@ + public void func_200398_a(DirectoryCache p_200398_1_) { + Path path = this.field_218443_d.func_200391_b(); + Map map = Maps.newHashMap(); +- this.field_218444_e.forEach((p_218438_1_) -> { ++ this.getTables().forEach((p_218438_1_) -> { + p_218438_1_.getFirst().get().accept((p_218437_2_, p_218437_3_) -> { + if (map.put(p_218437_2_, p_218437_3_.func_216039_a(p_218438_1_.getSecond()).func_216038_b()) != null) { + throw new IllegalStateException("Duplicate loot table " + p_218437_2_); +@@ -51,13 +51,8 @@ + }); + ValidationResults validationresults = new ValidationResults(); + +- for(ResourceLocation resourcelocation : Sets.difference(LootTables.func_215796_a(), map.keySet())) { +- validationresults.func_216105_a("Missing built-in table: " + resourcelocation); +- } ++ validate(map, validationresults); + +- map.forEach((p_218436_2_, p_218436_3_) -> { +- LootTableManager.func_215302_a(validationresults, p_218436_2_, p_218436_3_, map::get); +- }); + Multimap multimap = validationresults.func_216106_a(); + if (!multimap.isEmpty()) { + multimap.forEach((p_218435_0_, p_218435_1_) -> { +@@ -78,6 +73,20 @@ + } + } + ++ protected List>>, LootParameterSet>> getTables() { ++ return field_218444_e; ++ } ++ ++ protected void validate(Map map, ValidationResults validationresults) { ++ for(ResourceLocation resourcelocation : Sets.difference(LootTables.func_215796_a(), map.keySet())) { ++ validationresults.func_216105_a("Missing built-in table: " + resourcelocation); ++ } ++ ++ map.forEach((p_218436_2_, p_218436_3_) -> { ++ LootTableManager.func_215302_a(validationresults, p_218436_2_, p_218436_3_, map::get); ++ }); ++ } ++ + private static Path func_218439_a(Path p_218439_0_, ResourceLocation p_218439_1_) { + return p_218439_0_.resolve("data/" + p_218439_1_.func_110624_b() + "/loot_tables/" + p_218439_1_.func_110623_a() + ".json"); + } diff --git a/patches/minecraft/net/minecraft/data/loot/BlockLootTables.java.patch b/patches/minecraft/net/minecraft/data/loot/BlockLootTables.java.patch new file mode 100644 index 0000000000..98f1133217 --- /dev/null +++ b/patches/minecraft/net/minecraft/data/loot/BlockLootTables.java.patch @@ -0,0 +1,37 @@ +--- a/net/minecraft/data/loot/BlockLootTables.java ++++ b/net/minecraft/data/loot/BlockLootTables.java +@@ -188,7 +188,7 @@ + return LootTable.func_216119_b(); + } + +- public void accept(BiConsumer p_accept_1_) { ++ protected void addTables() { + this.func_218492_c(Blocks.field_196650_c); + this.func_218492_c(Blocks.field_196652_d); + this.func_218492_c(Blocks.field_196654_e); +@@ -962,9 +962,13 @@ + this.func_218507_a(Blocks.field_196713_dt, func_218482_a()); + this.func_218507_a(Blocks.field_185778_de, func_218482_a()); + this.func_218507_a(Blocks.field_150474_ac, func_218482_a()); ++ } ++ ++ public void accept(BiConsumer p_accept_1_) { ++ this.addTables(); + Set set = Sets.newHashSet(); + +- for(Block block : Registry.field_212618_g) { ++ for(Block block : getKnownBlocks()) { + ResourceLocation resourcelocation = block.func_220068_i(); + if (resourcelocation != LootTables.field_186419_a && set.add(resourcelocation)) { + LootTable.Builder loottable$builder = this.field_218581_i.remove(resourcelocation); +@@ -981,6 +985,10 @@ + } + } + ++ protected Iterable getKnownBlocks() { ++ return Registry.field_212618_g; ++ } ++ + public void func_218547_a(Block p_218547_1_) { + this.func_218522_a(p_218547_1_, (p_218524_0_) -> { + return func_218523_c(((FlowerPotBlock)p_218524_0_).func_220276_d()); diff --git a/src/main/java/net/minecraftforge/common/data/LanguageProvider.java b/src/main/java/net/minecraftforge/common/data/LanguageProvider.java new file mode 100644 index 0000000000..51411a5931 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/data/LanguageProvider.java @@ -0,0 +1,145 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package net.minecraftforge.common.data; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import java.util.Objects; +import java.util.TreeMap; +import java.util.function.Supplier; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import net.minecraft.block.Block; +import net.minecraft.data.DataGenerator; +import net.minecraft.data.DirectoryCache; +import net.minecraft.data.IDataProvider; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.EntityType; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.potion.Effect; +import net.minecraft.world.biome.Biome; + +public abstract class LanguageProvider implements IDataProvider { + private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().disableHtmlEscaping().create(); + private final Map data = new TreeMap<>(); + private final DataGenerator gen; + private final String modid; + private final String locale; + + public LanguageProvider(DataGenerator gen, String modid, String locale) { + this.gen = gen; + this.modid = modid; + this.locale = locale; + } + + protected abstract void addTranslations(); + + @Override + public void act(DirectoryCache cache) throws IOException { + addTranslations(); + if (!data.isEmpty()) + save(cache, data, this.gen.getOutputFolder().resolve("assets/" + modid + "/lang/" + locale + ".json")); + } + + @Override + public String getName() { + return "Languages: " + locale; + } + + private void save(DirectoryCache cache, Object object, Path target) throws IOException { + String data = GSON.toJson(object); + String hash = IDataProvider.HASH_FUNCTION.hashUnencodedChars(data).toString(); + if (!Objects.equals(cache.getPreviousHash(target), hash) || !Files.exists(target)) { + Files.createDirectories(target.getParent()); + + try (BufferedWriter bufferedwriter = Files.newBufferedWriter(target)) { + bufferedwriter.write(data); + } + } + + cache.func_208316_a(target, hash); + } + + protected void addBlock(Supplier key, String name) { + add(key.get(), name); + } + + protected void add(Block key, String name) { + add(key.getTranslationKey(), name); + } + + protected void addItem(Supplier key, String name) { + add(key.get(), name); + } + + protected void add(Item key, String name) { + add(key.getTranslationKey(), name); + } + + protected void addItemStack(Supplier key, String name) { + add(key.get(), name); + } + + protected void add(ItemStack key, String name) { + add(key.getTranslationKey(), name); + } + + protected void addEnchantment(Supplier key, String name) { + add(key.get(), name); + } + + protected void add(Enchantment key, String name) { + add(key.getName(), name); + } + + protected void addBiome(Supplier key, String name) { + add(key.get(), name); + } + + protected void add(Biome key, String name) { + add(key.getTranslationKey(), name); + } + + protected void addEffect(Supplier key, String name) { + add(key.get(), name); + } + + protected void add(Effect key, String name) { + add(key.getName(), name); + } + + protected void addEntityType(Supplier> key, String name) { + add(key.get(), name); + } + + protected void add(EntityType key, String name) { + add(key.getTranslationKey(), name); + } + + protected void add(String key, String value) { + if (data.put(key, value) != null) + throw new IllegalStateException("Duplicate translation key " + key); + } +} diff --git a/src/main/java/net/minecraftforge/registries/DeferredRegister.java b/src/main/java/net/minecraftforge/registries/DeferredRegister.java index fc57887b20..0405fb4021 100644 --- a/src/main/java/net/minecraftforge/registries/DeferredRegister.java +++ b/src/main/java/net/minecraftforge/registries/DeferredRegister.java @@ -24,10 +24,13 @@ import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.RegistryObject; +import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; +import java.util.Set; import java.util.function.Supplier; /** @@ -55,7 +58,8 @@ public class DeferredRegister> { private final IForgeRegistry type; private final String modid; - private Map, Supplier> entries = new LinkedHashMap<>(); + private final Map, Supplier> entries = new LinkedHashMap<>(); + private final Set> entriesView = Collections.unmodifiableSet(entries.keySet()); public DeferredRegister(IForgeRegistry reg, String modid) { @@ -94,6 +98,14 @@ public class DeferredRegister> bus.addListener(this::addEntries); } + /** + * @return The unmodifiable view of registered entries. Useful for bulk operations on all values. + */ + public Collection> getEntries() + { + return entriesView; + } + private void addEntries(RegistryEvent.Register event) { if (event.getGenericType() == this.type.getRegistrySuperType())