mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-13 00:37:52 +00:00
Fix duplicate WorldEvent.Unload call in client key handler.
Add recipe generator to replace vanilla recipes with Forge tags.
This commit is contained in:
1 parent
ac8b196b8c
commit
13ae8e41ee
132 files changed
+2591
-15
No files matched your search
@@ -47,6 +47,7 @@ import net.minecraft.world.storage.SaveHandler;
|
||||
import net.minecraft.world.storage.WorldInfo;
|
||||
import net.minecraftforge.common.data.ForgeBlockTagsProvider;
|
||||
import net.minecraftforge.common.data.ForgeItemTagsProvider;
|
||||
import net.minecraftforge.common.data.ForgeRecipeProvider;
|
||||
import net.minecraftforge.common.model.animation.CapabilityAnimation;
|
||||
import net.minecraftforge.energy.CapabilityEnergy;
|
||||
import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
|
||||
@@ -228,6 +229,7 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook
|
||||
{
|
||||
gen.addProvider(new ForgeBlockTagsProvider(gen));
|
||||
gen.addProvider(new ForgeItemTagsProvider(gen));
|
||||
gen.addProvider(new ForgeRecipeProvider(gen));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,13 +20,20 @@
|
||||
package net.minecraftforge.common.data;
|
||||
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.data.BlockTagsProvider;
|
||||
|
||||
import static net.minecraftforge.common.Tags.Blocks.*;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ForgeBlockTagsProvider extends BlockTagsProvider
|
||||
{
|
||||
private Set<ResourceLocation> filter = null;
|
||||
|
||||
public ForgeBlockTagsProvider(DataGenerator gen)
|
||||
{
|
||||
super(gen);
|
||||
@@ -35,6 +42,9 @@ public class ForgeBlockTagsProvider extends BlockTagsProvider
|
||||
@Override
|
||||
public void registerTags()
|
||||
{
|
||||
super.registerTags();
|
||||
filter = this.tagToBuilder.entrySet().stream().map(e -> e.getKey().getId()).collect(Collectors.toSet());
|
||||
|
||||
getBuilder(CHESTS).add(CHESTS_ENDER, CHESTS_TRAPPED, CHESTS_WOODEN);
|
||||
getBuilder(CHESTS_ENDER).add(Blocks.ENDER_CHEST);
|
||||
getBuilder(CHESTS_TRAPPED).add(Blocks.TRAPPED_CHEST);
|
||||
@@ -67,6 +77,12 @@ public class ForgeBlockTagsProvider extends BlockTagsProvider
|
||||
getBuilder(STORAGE_BLOCKS_REDSTONE).add(Blocks.REDSTONE_BLOCK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Path makePath(ResourceLocation id)
|
||||
{
|
||||
return filter != null && filter.contains(id) ? null : super.makePath(id); //We don't want to save vanilla tags.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
|
||||
@@ -19,13 +19,20 @@
|
||||
|
||||
package net.minecraftforge.common.data;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.ItemTagsProvider;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.Tags;
|
||||
|
||||
public class ForgeItemTagsProvider extends ItemTagsProvider
|
||||
{
|
||||
private Set<ResourceLocation> filter = null;
|
||||
|
||||
public ForgeItemTagsProvider(DataGenerator gen)
|
||||
{
|
||||
super(gen);
|
||||
@@ -34,6 +41,9 @@ public class ForgeItemTagsProvider extends ItemTagsProvider
|
||||
@Override
|
||||
public void registerTags()
|
||||
{
|
||||
super.registerTags();
|
||||
filter = this.tagToBuilder.entrySet().stream().map(e -> e.getKey().getId()).collect(Collectors.toSet());
|
||||
|
||||
copy(Tags.Blocks.CHESTS, Tags.Items.CHESTS);
|
||||
copy(Tags.Blocks.CHESTS_ENDER, Tags.Items.CHESTS_ENDER);
|
||||
copy(Tags.Blocks.CHESTS_TRAPPED, Tags.Items.CHESTS_TRAPPED);
|
||||
@@ -104,6 +114,12 @@ public class ForgeItemTagsProvider extends ItemTagsProvider
|
||||
copy(Tags.Blocks.STORAGE_BLOCKS_REDSTONE, Tags.Items.STORAGE_BLOCKS_REDSTONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Path makePath(ResourceLocation id)
|
||||
{
|
||||
return filter != null && filter.contains(id) ? null : super.makePath(id); //We don't want to save vanilla tags.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* 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.lang.reflect.Field;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.DirectoryCache;
|
||||
import net.minecraft.data.IFinishedRecipe;
|
||||
import net.minecraft.data.RecipeProvider;
|
||||
import net.minecraft.data.ShapedRecipeBuilder;
|
||||
import net.minecraft.data.ShapelessRecipeBuilder;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.item.crafting.Ingredient.IItemList;
|
||||
import net.minecraft.item.crafting.Ingredient.TagList;
|
||||
import net.minecraft.item.crafting.Ingredient.SingleItemList;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.util.IItemProvider;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.Tags;
|
||||
|
||||
public class ForgeRecipeProvider extends RecipeProvider
|
||||
{
|
||||
private final DataGenerator generator;
|
||||
private final Path ADV_ROOT;
|
||||
private Map<Item, Tag<Item>> replacements = new HashMap<>();
|
||||
private Set<ResourceLocation> excludes = new HashSet<>();
|
||||
|
||||
public ForgeRecipeProvider(DataGenerator generatorIn)
|
||||
{
|
||||
super(generatorIn);
|
||||
this.generator = generatorIn;
|
||||
ADV_ROOT = this.generator.getOutputFolder().resolve("data/minecraft/advancements/recipes/root.json");
|
||||
}
|
||||
|
||||
private void exclude(IItemProvider item)
|
||||
{
|
||||
excludes.add(item.asItem().getRegistryName());
|
||||
}
|
||||
|
||||
private void replace(IItemProvider item, Tag<Item> tag)
|
||||
{
|
||||
replacements.put(item.asItem(), tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerRecipes(Consumer<IFinishedRecipe> consumer)
|
||||
{
|
||||
replace(Items.STICK, Tags.Items.RODS_WOODEN);
|
||||
replace(Items.GOLD_INGOT, Tags.Items.INGOTS_GOLD);
|
||||
replace(Items.IRON_INGOT, Tags.Items.INGOTS_IRON);
|
||||
replace(Items.DIAMOND, Tags.Items.GEMS_DIAMOND);
|
||||
replace(Items.EMERALD, Tags.Items.GEMS_EMERALD);
|
||||
replace(Items.CHEST, Tags.Items.CHESTS_WOODEN);
|
||||
replace(Blocks.COBBLESTONE, Tags.Items.COBBLESTONE);
|
||||
|
||||
exclude(Blocks.GOLD_BLOCK);
|
||||
exclude(Items.GOLD_NUGGET);
|
||||
exclude(Blocks.IRON_BLOCK);
|
||||
exclude(Items.IRON_NUGGET);
|
||||
exclude(Blocks.DIAMOND_BLOCK);
|
||||
exclude(Blocks.EMERALD_BLOCK);
|
||||
|
||||
super.registerRecipes(vanilla -> {
|
||||
IFinishedRecipe modified = enhance(vanilla);
|
||||
if (modified != null)
|
||||
consumer.accept(modified);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveRecipeAdvancement(DirectoryCache cache, JsonObject advancementJson, Path pathIn) {
|
||||
if (pathIn.equals(ADV_ROOT)) return; //We NEVER care about this.
|
||||
//NOOP - We dont replace any of the advancement things yet...
|
||||
}
|
||||
|
||||
private IFinishedRecipe enhance(IFinishedRecipe vanilla)
|
||||
{
|
||||
if (vanilla instanceof ShapelessRecipeBuilder.Result)
|
||||
return enhance((ShapelessRecipeBuilder.Result)vanilla);
|
||||
if (vanilla instanceof ShapedRecipeBuilder.Result)
|
||||
return enhance((ShapedRecipeBuilder.Result)vanilla);
|
||||
return null;
|
||||
}
|
||||
|
||||
private IFinishedRecipe enhance(ShapelessRecipeBuilder.Result vanilla)
|
||||
{
|
||||
List<Ingredient> ingredients = getField(ShapelessRecipeBuilder.Result.class, vanilla, 4);
|
||||
boolean modified = false;
|
||||
for (int x = 0; x < ingredients.size(); x++)
|
||||
{
|
||||
Ingredient ing = enhance(vanilla.getID(), ingredients.get(x));
|
||||
if (ing != null)
|
||||
{
|
||||
ingredients.set(x, ing);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
return modified ? vanilla : null;
|
||||
}
|
||||
|
||||
private IFinishedRecipe enhance(ShapedRecipeBuilder.Result vanilla)
|
||||
{
|
||||
Map<Character, Ingredient> ingredients = getField(ShapedRecipeBuilder.Result.class, vanilla, 5);
|
||||
boolean modified = false;
|
||||
for (Character x : ingredients.keySet())
|
||||
{
|
||||
Ingredient ing = enhance(vanilla.getID(), ingredients.get(x));
|
||||
if (ing != null)
|
||||
{
|
||||
ingredients.put(x, ing);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
return modified ? vanilla : null;
|
||||
}
|
||||
|
||||
private Ingredient enhance(ResourceLocation name, Ingredient vanilla)
|
||||
{
|
||||
if (excludes.contains(name))
|
||||
return null;
|
||||
|
||||
boolean modified = false;
|
||||
List<IItemList> items = new ArrayList<>();
|
||||
IItemList[] vanillaItems = getField(Ingredient.class, vanilla, 3);
|
||||
for (IItemList entry : vanillaItems)
|
||||
{
|
||||
if (entry instanceof SingleItemList)
|
||||
{
|
||||
ItemStack stack = entry.getStacks().stream().findFirst().orElse(ItemStack.EMPTY);
|
||||
Tag<Item> replacement = replacements.get(stack.getItem());
|
||||
if (replacement != null)
|
||||
{
|
||||
items.add(new TagList(replacement));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
items.add(entry);
|
||||
}
|
||||
else
|
||||
items.add(entry);
|
||||
}
|
||||
return modified ? Ingredient.fromItemListStream(items.stream()) : null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T, R> R getField(Class<T> clz, T inst, int index)
|
||||
{
|
||||
Field fld = clz.getDeclaredFields()[index];
|
||||
fld.setAccessible(true);
|
||||
try
|
||||
{
|
||||
return (R)fld.get(inst);
|
||||
}
|
||||
catch (IllegalArgumentException | IllegalAccessException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user