From 945d3887d280cd9d2d198f2b073b27bda048c44d Mon Sep 17 00:00:00 2001 From: cpw Date: Thu, 29 Oct 2015 08:46:23 -0400 Subject: [PATCH] Fix substitutions for recipes and oredict recipes. Should mean that substitutions start working properly. --- .../FMLControlledNamespacedRegistry.java | 43 ++++++++++++++++--- .../mods/fml/common/registry/GameData.java | 1 + .../minecraftforge/oredict/OreDictionary.java | 7 ++- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/fml/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java b/fml/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java index ef6a1031fa..ab5e9a5765 100644 --- a/fml/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java +++ b/fml/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java @@ -9,7 +9,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.logging.log4j.Level; + import net.minecraft.block.Block; +import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.util.ObjectIntIdentityMap; import net.minecraft.util.RegistryNamespaced; @@ -21,6 +24,7 @@ import com.google.common.collect.Iterators; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.functions.GenericIterableFactory; +import cpw.mods.fml.common.registry.RegistryDelegate.Delegate; public class FMLControlledNamespacedRegistry extends RegistryNamespaced { public static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("fml.debugRegistryEntries", "false")); @@ -51,9 +55,10 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { { int id = getId(obj); String name = getNameForObject(obj); + boolean isSubstituted = activeSubstitutions.containsKey(name); // id lookup failed -> obj is not in the obj<->id map - if (id < 0) throw new IllegalStateException(String.format("Registry entry for %s %s, name %s, doesn't yield an id.", type, obj, name)); + if (!isSubstituted && id < 0) throw new IllegalStateException(String.format("Registry entry for %s %s, name %s, doesn't yield an id.", type, obj, name)); // id is too high if (id > maxId) throw new IllegalStateException(String.format("Registry entry for %s %s, name %s uses the too large id %d.", type, obj, name)); // name lookup failed -> obj is not in the obj<->name map @@ -62,12 +67,14 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { if (name.isEmpty()) throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, yields an empty name.", type, obj, id)); // non-prefixed name if (name.indexOf(':') == -1) throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, has the non-prefixed name %s.", type, obj, id, name)); + // the rest of the tests don't really work for substituted items or blocks + if (isSubstituted) continue; // id -> obj lookup is inconsistent if (getRaw(id) != obj) throw new IllegalStateException(String.format("Registry entry for id %d, name %s, doesn't yield the expected %s %s.", id, name, type, obj)); // name -> obj lookup is inconsistent - if (!(activeSubstitutions.containsKey(name) || activeSubstitutions.containsValue(name)) && getRaw(name) != obj ) throw new IllegalStateException(String.format("Registry entry for name %s, id %d, doesn't yield the expected %s %s.", name, id, type, obj)); + if (getRaw(name) != obj) throw new IllegalStateException(String.format("Registry entry for name %s, id %d, doesn't yield the expected %s %s.", name, id, type, obj)); // name -> id lookup is inconsistent - if (!(activeSubstitutions.containsKey(name) || activeSubstitutions.containsValue(name)) && getId(name) != id) throw new IllegalStateException(String.format("Registry entry for name %s doesn't yield the expected id %d.", name, id)); + if (getId(name) != id) throw new IllegalStateException(String.format("Registry entry for name %s doesn't yield the expected id %d.", name, id)); // id isn't marked as unavailable if (!availabilityMap.get(id)) throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, name %s, marked as empty.", type, obj, id, name)); // entry is blocked, thus should be empty @@ -105,7 +112,8 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { for (I thing : registry.typeSafeIterable()) { - addObjectRaw(registry.getId(thing), registry.getNameForObject(thing), thing); + int id = registry.getId(thing); + addObjectRaw(id, registry.getNameForObject(thing), thing); } this.activeSubstitutions.putAll(registry.activeSubstitutions); } @@ -239,9 +247,9 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { * @return */ @SuppressWarnings("unchecked") - private I cast(Object obj) + private I cast(Object obj) { - return (I)(obj); + return (I)(obj); } /** * Get the object identified by the specified name. @@ -475,6 +483,19 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { { if (getPersistentSubstitutions().containsKey(nameToReplace)) { + I original = getRaw(nameToReplace); + if (superType == Item.class) { + Item sub = (Item) getPersistentSubstitutions().get(nameToReplace); + if (original == null) { + // When we're activated from the server side, we need to set the delegate on the original instance to + // point to us. Go to the "default state" registry to get it + original = (I)GameData.getItemRegistry().getRaw(nameToReplace); + } + FMLLog.log(Level.DEBUG, "Replacing %s with %s (name %s)", original, sub, nameToReplace); + Delegate delegate = (Delegate)((Item)original).delegate; + delegate.changeReference(sub); + ((Delegate)sub.delegate).setName(nameToReplace); + } activeSubstitutions.put(nameToReplace, getPersistentSubstitutions().get(nameToReplace)); } } @@ -502,6 +523,7 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { FMLLog.severe("The substitute %s for %s is registered into the game independently. This won't work", replacement.getClass().getName(), nameToReplace); throw new IllegalArgumentException("The object substitution is already registered. This won't work"); } + FMLLog.log(Level.DEBUG, "Adding substitution %s with %s (name %s)", original, replacement, nameToReplace); getPersistentSubstitutions().put(nameToReplace, replacement); } @@ -529,4 +551,13 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { { return Iterators.concat(super.iterator(),getPersistentSubstitutions().values().iterator()); } + + // ONLY CALLED ON ITEM registry + void resetSubstitutionDelegates() + { + for (I item: typeSafeIterable()) { + Delegate delegate = (Delegate)((Item)item).delegate; + delegate.changeReference((Item)item); + } + } } diff --git a/fml/src/main/java/cpw/mods/fml/common/registry/GameData.java b/fml/src/main/java/cpw/mods/fml/common/registry/GameData.java index aa7ec6c3d9..13698082ba 100644 --- a/fml/src/main/java/cpw/mods/fml/common/registry/GameData.java +++ b/fml/src/main/java/cpw/mods/fml/common/registry/GameData.java @@ -439,6 +439,7 @@ public class GameData { getMain().iBlockRegistry.dump(); getMain().iItemRegistry.dump(); + getMain().iItemRegistry.resetSubstitutionDelegates(); GameData newData = new GameData(); for (int id : blockedIds) diff --git a/src/main/java/net/minecraftforge/oredict/OreDictionary.java b/src/main/java/net/minecraftforge/oredict/OreDictionary.java index 5b50060923..e18053e0d8 100644 --- a/src/main/java/net/minecraftforge/oredict/OreDictionary.java +++ b/src/main/java/net/minecraftforge/oredict/OreDictionary.java @@ -29,6 +29,7 @@ import com.google.common.collect.Maps; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.eventhandler.Event; +import cpw.mods.fml.common.registry.GameData; public class OreDictionary { @@ -493,7 +494,8 @@ public class OreDictionary } int oreID = getOreID(name); - int hash = Item.getIdFromItem(ore.getItem()); + // HACK: use the registry name's ID. It is unique and it knows about substitutions + int hash = GameData.getItemRegistry().getId(ore.getItem().delegate.name()); if (ore.getItemDamage() != WILDCARD_VALUE) { hash |= ((ore.getItemDamage() + 1) << 16); // +1 so 0 is significant @@ -537,7 +539,8 @@ public class OreDictionary if (ores == null) continue; for (ItemStack ore : ores) { - int hash = Item.getIdFromItem(ore.getItem()); + // HACK: use the registry name's ID. It is unique and it knows about substitutions + int hash = GameData.getItemRegistry().getId(ore.getItem().delegate.name()); if (ore.getItemDamage() != WILDCARD_VALUE) { hash |= ((ore.getItemDamage() + 1) << 16); // +1 so meta 0 is significant