mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 16:27:47 +00:00
Add support for server side only recipes, as well as detection of vanilla client recipe book filter to prevent errors.
This commit is contained in:
1 parent
ee27276ba2
commit
28e341002f
14 files changed
+168
-55
No files matched your search
@@ -30,8 +30,11 @@ import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.potion.PotionType;
|
||||
@@ -40,6 +43,7 @@ import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.registry.RegistryNamespaced;
|
||||
import net.minecraft.util.registry.RegistryNamespacedDefaultedByKey;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
@@ -128,7 +132,7 @@ public class GameData
|
||||
makeRegistry(SOUNDEVENTS, SoundEvent.class, MAX_SOUND_ID).create();
|
||||
makeRegistry(POTIONTYPES, PotionType.class, MAX_POTIONTYPE_ID, new ResourceLocation("empty")).create();
|
||||
makeRegistry(ENCHANTMENTS, Enchantment.class, MAX_ENCHANTMENT_ID).create();
|
||||
makeRegistry(RECIPES, IRecipe.class, MAX_RECIPE_ID).disableSaving().allowModification().create();
|
||||
makeRegistry(RECIPES, IRecipe.class, MAX_RECIPE_ID).disableSaving().allowModification().addCallback(RecipeCallbacks.INSTANCE).create();
|
||||
makeRegistry(PROFESSIONS, VillagerProfession.class, MAX_PROFESSION_ID).create();
|
||||
entityRegistry = (ForgeRegistry<EntityEntry>)makeRegistry(ENTITIES, EntityEntry.class, MAX_ENTITY_ID).addCallback(EntityCallbacks.INSTANCE).create();
|
||||
}
|
||||
@@ -276,7 +280,6 @@ public class GameData
|
||||
private static class BlockCallbacks implements IForgeRegistry.AddCallback<Block>, IForgeRegistry.ClearCallback<Block>, IForgeRegistry.CreateCallback<Block>, IForgeRegistry.DummyFactory<Block>
|
||||
{
|
||||
static final BlockCallbacks INSTANCE = new BlockCallbacks();
|
||||
Field regName;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
@@ -349,31 +352,8 @@ public class GameData
|
||||
@Override
|
||||
public Block createDummy(ResourceLocation key)
|
||||
{
|
||||
if (regName == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
regName = IForgeRegistryEntry.Impl.class.getDeclaredField("registryName");
|
||||
regName.setAccessible(true);
|
||||
}
|
||||
catch (NoSuchFieldException | SecurityException e)
|
||||
{
|
||||
FMLLog.log.error("Could not get `registryName` field from IForgeRegistryEntry.Impl");
|
||||
FMLLog.log.throwing(Level.ERROR, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
Block ret = new BlockDummyAir().setUnlocalizedName("air");
|
||||
try
|
||||
{
|
||||
regName.set(ret, key);
|
||||
}
|
||||
catch (IllegalArgumentException | IllegalAccessException e)
|
||||
{
|
||||
FMLLog.log.error("Could not set `registryName` field in IForgeRegistryEntry.Impl to `{}`", key.toString());
|
||||
FMLLog.log.throwing(Level.ERROR, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
GameData.forceRegistryName(ret, key);
|
||||
return ret;
|
||||
}
|
||||
private static class BlockDummyAir extends BlockAir //A named class so DummyBlockReplacementTest can detect if its a dummy
|
||||
@@ -414,6 +394,35 @@ public class GameData
|
||||
}
|
||||
}
|
||||
|
||||
private static class RecipeCallbacks implements IForgeRegistry.MissingFactory<IRecipe>
|
||||
{
|
||||
static final RecipeCallbacks INSTANCE = new RecipeCallbacks();
|
||||
|
||||
@Override
|
||||
public IRecipe createMissing(ResourceLocation key, boolean isNetwork)
|
||||
{
|
||||
return isNetwork ? new DummyRecipe().setRegistryName(key) : null;
|
||||
}
|
||||
private static class DummyRecipe implements IRecipe
|
||||
{
|
||||
private static ItemStack result = new ItemStack(Items.DIAMOND, 64);
|
||||
private ResourceLocation name;
|
||||
|
||||
@Override
|
||||
public IRecipe setRegistryName(ResourceLocation name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
@Override public ResourceLocation getRegistryName() { return name; }
|
||||
@Override public Class<IRecipe> getRegistryType() { return IRecipe.class; }
|
||||
@Override public boolean matches(InventoryCrafting inv, World worldIn) { return false; } //dirt?
|
||||
@Override public ItemStack getCraftingResult(InventoryCrafting inv) { return result; }
|
||||
@Override public boolean canFit(int width, int height) { return false; }
|
||||
@Override public ItemStack getRecipeOutput() { return result; }
|
||||
@Override public boolean isHidden() { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static ForgeRegistry<EntityEntry> entityRegistry;
|
||||
public static ForgeRegistry<EntityEntry> getEntityRegistry() { return entityRegistry; }
|
||||
@@ -559,16 +568,12 @@ public class GameData
|
||||
if (!lst.isEmpty())
|
||||
{
|
||||
FMLLog.log.error("Unidentified mapping from registry {}", name);
|
||||
lst.forEach(map -> {
|
||||
FMLLog.log.error(" {}: {}", map.key, map.id);
|
||||
if (!isLocalWorld)
|
||||
defaulted.put(name, map.key);
|
||||
});
|
||||
lst.forEach(map -> FMLLog.log.error(" {}: {}", map.key, map.id));
|
||||
}
|
||||
event.getAllMappings().stream().filter(e -> e.getAction() == MissingMappings.Action.FAIL).forEach(fail -> failed.put(name, fail.key));
|
||||
|
||||
final Class<? extends IForgeRegistryEntry> clazz = RegistryManager.ACTIVE.getSuperType(name);
|
||||
processMissing(clazz, name, STAGING, event, m.getValue(), remaps.get(name), defaulted.get(name), failed.get(name));
|
||||
processMissing(clazz, name, STAGING, event, m.getValue(), remaps.get(name), defaulted.get(name), failed.get(name), !isLocalWorld);
|
||||
});
|
||||
|
||||
if (!defaulted.isEmpty() && !isLocalWorld)
|
||||
@@ -679,12 +684,12 @@ public class GameData
|
||||
|
||||
//Another bouncer for generic reasons
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends IForgeRegistryEntry<T>> void processMissing(Class<T> clazz, ResourceLocation name, RegistryManager STAGING, MissingMappings<?> e, Map<ResourceLocation, Integer> missing, Map<ResourceLocation, Integer[]> remaps, Collection<ResourceLocation> defaulted, Collection<ResourceLocation> failed)
|
||||
private static <T extends IForgeRegistryEntry<T>> void processMissing(Class<T> clazz, ResourceLocation name, RegistryManager STAGING, MissingMappings<?> e, Map<ResourceLocation, Integer> missing, Map<ResourceLocation, Integer[]> remaps, Collection<ResourceLocation> defaulted, Collection<ResourceLocation> failed, boolean injectNetworkDummies)
|
||||
{
|
||||
List<MissingMappings.Mapping<T>> mappings = ((MissingMappings<T>)e).getAllMappings();
|
||||
ForgeRegistry<T> active = RegistryManager.ACTIVE.getRegistry(name);
|
||||
ForgeRegistry<T> staging = STAGING.getRegistry(name);
|
||||
staging.processMissingEvent(name, active, mappings, missing, remaps, defaulted, failed);
|
||||
staging.processMissingEvent(name, active, mappings, missing, remaps, defaulted, failed, injectNetworkDummies);
|
||||
}
|
||||
|
||||
private static <T extends IForgeRegistryEntry<T>> void loadFrozenDataToStagingRegistry(RegistryManager STAGING, ResourceLocation name, Map<ResourceLocation, Integer[]> remaps, Class<T> clazz)
|
||||
@@ -742,4 +747,34 @@ public class GameData
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
private static Field regName;
|
||||
private static void forceRegistryName(IForgeRegistryEntry<?> entry, ResourceLocation name)
|
||||
{
|
||||
if (regName == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
regName = IForgeRegistryEntry.Impl.class.getDeclaredField("registryName");
|
||||
regName.setAccessible(true);
|
||||
}
|
||||
catch (NoSuchFieldException | SecurityException e)
|
||||
{
|
||||
FMLLog.log.error("Could not get `registryName` field from IForgeRegistryEntry.Impl");
|
||||
FMLLog.log.throwing(Level.ERROR, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
regName.set(entry, name);
|
||||
}
|
||||
catch (IllegalArgumentException | IllegalAccessException e)
|
||||
{
|
||||
FMLLog.log.error("Could not set `registryName` field in IForgeRegistryEntry.Impl to `{}`", name.toString());
|
||||
FMLLog.log.throwing(Level.ERROR, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user