diff --git a/patches/minecraft/net/minecraft/block/Block.java.patch b/patches/minecraft/net/minecraft/block/Block.java.patch index 0f8b38ce33..a7439368d6 100644 --- a/patches/minecraft/net/minecraft/block/Block.java.patch +++ b/patches/minecraft/net/minecraft/block/Block.java.patch @@ -188,7 +188,7 @@ } protected ItemStack func_180643_i(IBlockState p_180643_1_) -@@ -1010,6 +1030,1065 @@ +@@ -1010,6 +1030,1114 @@ return "Block{" + field_149771_c.func_177774_c(this) + "}"; } @@ -1249,6 +1249,55 @@ + return capturedDrops.get(); + } + } ++ ++ private ResourceLocation registryName = null; ++ /** ++ * Sets a unique name for this Block. This should be used for uniquely identify the instance of the Block. ++ * This is the valid replacement for the atrocious 'getUnlocalizedName().substring(6)' stuff that everyone does. ++ * Unlocalized names have NOTHING to do with unique identifiers. As demonstrated by vanilla blocks and items. ++ * ++ * The supplied name will be prefixed with the currently active mod's modId. ++ * If the supplied name already has a prefix that is different, it will be used and a warning will be logged. ++ * ++ * If a name already exists, or this Block is already registered in a registry, then an IllegalStateException is thrown. ++ * ++ * Returns 'this' to allow for chaining. ++ * ++ * @param name Unique registry name ++ * @return This instance ++ */ ++ public final Block setRegistryName(String name) ++ { ++ if (getRegistryName() != null) ++ throw new IllegalStateException("Attempted to set registry name on block with exisiting registry name! New: " + name + " Old: " + getRegistryName()); ++ int index = name.lastIndexOf(':'); ++ String oldPrefix = index == -1 ? "" : name.substring(0, index); ++ name = index == -1 ? name : name.substring(index + 1); ++ net.minecraftforge.fml.common.ModContainer mc = net.minecraftforge.fml.common.Loader.instance().activeModContainer(); ++ String prefix = mc == null ? "minecraft" : mc.getModId(); ++ if (!oldPrefix.equals(prefix) && oldPrefix.length() > 0) ++ { ++ net.minecraftforge.fml.common.FMLLog.bigWarning("Dangerous alternative prefix %s for name %s, invalid registry invocation/invalid name?", name.substring(0, index), name); ++ prefix = oldPrefix; ++ } ++ this.registryName = new ResourceLocation(prefix, name); ++ return this; ++ } ++ public final Block setRegistryName(ResourceLocation name){ return setRegistryName(name.toString()); } ++ public final Block setRegistryName(String modID, String name){ return setRegistryName(modID + ":" + name); } ++ ++ /** ++ * A unique identifier for this block, if this block is registered in the game registry it will return that name. ++ * Otherwise it will return the name set in setRegistryName(). ++ * If neither are valid null is returned. ++ * ++ * @return Unique identifier or null. ++ */ ++ public final String getRegistryName() ++ { ++ if (delegate.getResourceName() != null) return delegate.getResourceName().toString(); ++ return registryName != null ? registryName.toString() : null; ++ } + /* ========================================= FORGE END ======================================*/ + public static void func_149671_p() diff --git a/patches/minecraft/net/minecraft/item/Item.java.patch b/patches/minecraft/net/minecraft/item/Item.java.patch index e79d76addc..e6490c861a 100644 --- a/patches/minecraft/net/minecraft/item/Item.java.patch +++ b/patches/minecraft/net/minecraft/item/Item.java.patch @@ -57,7 +57,7 @@ Vec3 vec31 = vec3.func_72441_c((double)f6 * d3, (double)f5 * d3, (double)f7 * d3); return p_77621_1_.func_147447_a(vec3, vec31, p_77621_3_, !p_77621_3_, false); } -@@ -371,11 +380,591 @@ +@@ -371,11 +380,641 @@ return false; } @@ -91,16 +91,16 @@ + } + + /** -+ * Allow the item one last chance to modify its name used for the ++ * Allow the item one last chance to modify its name used for the + * tool highlight useful for adding something extra that can't be removed + * by a user in the displayed name, such as a mode of operation. -+ * ++ * + * @param item the ItemStack for the item. + * @param the name that will be displayed unless it is changed in this method. + */ + public String getHighlightTip( ItemStack item, String displayName ) + { -+ return displayName; ++ return displayName; + } + + /** @@ -644,12 +644,62 @@ + { + return !ItemStack.func_77989_b(oldStack, newStack); + } ++ ++ ++ private ResourceLocation registryName = null; ++ /** ++ * Sets a unique name for this Item. This should be used for uniquely identify the instance of the Item. ++ * This is the valid replacement for the atrocious 'getUnlocalizedName().substring(6)' stuff that everyone does. ++ * Unlocalized names have NOTHING to do with unique identifiers. As demonstrated by vanilla blocks and items. ++ * ++ * The supplied name will be prefixed with the currently active mod's modId. ++ * If the supplied name already has a prefix that is different, it will be used and a warning will be logged. ++ * ++ * If a name already exists, or this Item is already registered in a registry, then an IllegalStateException is thrown. ++ * ++ * Returns 'this' to allow for chaining. ++ * ++ * @param name Unique registry name ++ * @return This instance ++ */ ++ public final Item setRegistryName(String name) ++ { ++ if (getRegistryName() != null) ++ throw new IllegalStateException("Attempted to set registry name on block with exisiting registry name! New: " + name + " Old: " + getRegistryName()); ++ int index = name.lastIndexOf(':'); ++ String oldPrefix = index == -1 ? "" : name.substring(0, index); ++ name = index == -1 ? name : name.substring(index + 1); ++ net.minecraftforge.fml.common.ModContainer mc = net.minecraftforge.fml.common.Loader.instance().activeModContainer(); ++ String prefix = mc == null ? "minecraft" : mc.getModId(); ++ if (!oldPrefix.equals(prefix) && oldPrefix.length() > 0) ++ { ++ net.minecraftforge.fml.common.FMLLog.bigWarning("Dangerous alternative prefix %s for name %s, invalid registry invocation/invalid name?", name.substring(0, index), name); ++ prefix = oldPrefix; ++ } ++ this.registryName = new ResourceLocation(prefix, name); ++ return this; ++ } ++ public final Item setRegistryName(ResourceLocation name){ return setRegistryName(name.toString()); } ++ public final Item setRegistryName(String modID, String name){ return setRegistryName(modID + ":" + name); } ++ ++ /** ++ * A unique identifier for this block, if this block is registered in the game registry it will return that name. ++ * Otherwise it will return the name set in setRegistryName(). ++ * If neither are valid null is returned. ++ * ++ * @return Unique identifier or null. ++ */ ++ public final String getRegistryName() ++ { ++ if (delegate.getResourceName() != null) return delegate.getResourceName().toString(); ++ return registryName != null ? registryName.toString() : null; ++ } + /* ======================================== FORGE END =====================================*/ + public static void func_150900_l() { func_179214_a(Blocks.field_150348_b, (new ItemMultiTexture(Blocks.field_150348_b, Blocks.field_150348_b, new Function() -@@ -855,6 +1444,10 @@ +@@ -855,6 +1494,10 @@ private final float field_78011_i; private final int field_78008_j; @@ -660,7 +710,7 @@ private ToolMaterial(int p_i1874_3_, int p_i1874_4_, float p_i1874_5_, float p_i1874_6_, int p_i1874_7_) { this.field_78001_f = p_i1874_3_; -@@ -889,9 +1482,36 @@ +@@ -889,9 +1532,36 @@ return this.field_78008_j; } diff --git a/src/main/java/net/minecraftforge/fml/common/registry/GameData.java b/src/main/java/net/minecraftforge/fml/common/registry/GameData.java index 1e696e8a16..80e94566c5 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/GameData.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/GameData.java @@ -117,36 +117,12 @@ public class GameData int registerItem(Item item, String name) // from GameRegistry { - int index = name.indexOf(':'); - if (index != -1) - { - FMLLog.bigWarning("Dangerous extra prefix %s for name %s, invalid registry invocation/invalid name?", name.substring(0, index), name); - } - - ResourceLocation rl = addPrefix(name); - return registerItem(item, rl, -1); - } - - private int registerItem(Item item, ResourceLocation name, int idHint) - { - return iItemRegistry.add(idHint, name, item); + return iItemRegistry.add(-1, addPrefix(name), item); } int registerBlock(Block block, String name) // from GameRegistry { - int index = name.indexOf(':'); - if (index != -1) - { - FMLLog.bigWarning("Dangerous alternative prefix %s for name %s, invalid registry invocation/invalid name?", name.substring(0, index), name); - } - - ResourceLocation rl = addPrefix(name); - return registerBlock(block, rl, -1); - } - - private int registerBlock(Block block, ResourceLocation name, int idHint) - { - return iBlockRegistry.add(idHint, name, block); + return iBlockRegistry.add(-1, addPrefix(name), block); } /** @@ -165,12 +141,13 @@ public class GameData { int index = name.lastIndexOf(':'); String oldPrefix = index == -1 ? "" : name.substring(0, index); + name = index == -1 ? name : name.substring(index + 1); String prefix; ModContainer mc = Loader.instance().activeModContainer(); if (mc != null) { - prefix = mc.getModId(); + prefix = mc.getModId().toLowerCase(); } else // no mod container, assume minecraft { @@ -179,6 +156,7 @@ public class GameData if (!oldPrefix.equals(prefix) && oldPrefix.length() > 0) { + FMLLog.bigWarning("Dangerous alternative prefix %s for name %s, invalid registry invocation/invalid name?", prefix, name); prefix = oldPrefix; } diff --git a/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java b/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java index 56089e9b74..a27b6bc78a 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java @@ -127,15 +127,29 @@ public class GameRegistry sortedGeneratorList = ImmutableList.copyOf(list); } + /** + * Register an item with the item registry with a the name specified in Item.getRegistryName() + * + * @param item The item to register + */ + public static void registerItem(Item item) + { + registerItem(item, item.getRegistryName()); + } + /** * Register an item with the item registry with a custom name : this allows for easier server->client resolution * * @param item The item to register * @param name The mod-unique name of the item */ - public static void registerItem(net.minecraft.item.Item item, String name) + public static void registerItem(Item item, String name) { - registerItem(item, name, null); + if (Strings.isNullOrEmpty(name)) + { + throw new IllegalArgumentException("Attempted to register a block with no name: " + item); + } + GameData.getMain().registerItem(item, name); } /** @@ -145,13 +159,13 @@ public class GameRegistry * @param name The mod-unique name to register it as - null will remove a custom name * @param modId deprecated, unused */ + @Deprecated // See version without modID remove in 1.9 public static Item registerItem(Item item, String name, String modId) { - GameData.getMain().registerItem(item, name); + registerItem(item, name); return item; } - /** * Add a forced persistent substitution alias for the block or item to another block or item. This will have * the effect of using the substituted block or item instead of the original, where ever it is @@ -168,6 +182,16 @@ public class GameRegistry GameData.getMain().registerSubstitutionAlias(nameToSubstitute, type, object); } + /** + * Register a block with the name that Block.getRegistryName returns. + * + * @param block The block to register + */ + public static Block registerBlock(Block block) + { + return registerBlock(block, block.getRegistryName()); + } + /** * Register a block with the specified mod specific name * @@ -179,6 +203,17 @@ public class GameRegistry return registerBlock(block, ItemBlock.class, name); } + /** + * Register a block with the world, with the specified item class using Block.getRegistryName's name + * + * @param block The block to register + * @param itemclass The item type to register with it : null registers a block without associated item. + */ + public static Block registerBlock(Block block, Class itemclass) + { + return registerBlock(block, itemclass, block.getRegistryName()); + } + /** * Register a block with the world, with the specified item class and block name * @@ -191,6 +226,19 @@ public class GameRegistry return registerBlock(block, itemclass, name, new Object[] {}); } + + /** + * Register a block with the world, with the specified item class using Block.getRegistryName's name + * + * @param block The block to register + * @param itemclass The item type to register with it : null registers a block without associated item. + * @param itemCtorArgs Arguments to pass (after the required {@code Block} parameter) to the ItemBlock constructor (optional). + */ + public static Block registerBlock(Block block, Class itemclass, Object... itemCtorArgs) + { + return registerBlock(block, itemclass, block.getRegistryName(), itemCtorArgs); + } + /** * Register a block with the world, with the specified item class, block name and owning modId * @@ -201,6 +249,10 @@ public class GameRegistry */ public static Block registerBlock(Block block, Class itemclass, String name, Object... itemCtorArgs) { + if (Strings.isNullOrEmpty(name)) + { + throw new IllegalArgumentException("Attempted to register a block with no name: " + block); + } if (Loader.instance().isInState(LoaderState.CONSTRUCTING)) { FMLLog.warning("The mod %s is attempting to register a block whilst it it being constructed. This is bad modding practice - please use a proper mod lifecycle event.", Loader.instance().activeModContainer()); diff --git a/src/test/java/net/minecraftforge/debug/ForgeBlockStatesLoaderDebug.java b/src/test/java/net/minecraftforge/debug/ForgeBlockStatesLoaderDebug.java index 6a5009b94b..6fe7468fb7 100644 --- a/src/test/java/net/minecraftforge/debug/ForgeBlockStatesLoaderDebug.java +++ b/src/test/java/net/minecraftforge/debug/ForgeBlockStatesLoaderDebug.java @@ -14,6 +14,7 @@ import net.minecraft.client.renderer.block.statemap.StateMap; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.init.Blocks; import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemMultiTexture; import net.minecraft.item.ItemStack; import net.minecraft.util.IStringSerializable; @@ -37,24 +38,24 @@ public class ForgeBlockStatesLoaderDebug { public static final Block blockCustom = new CustomMappedBlock(); public static final String nameCustomWall = "custom_wall"; public static final BlockWall blockCustomWall = new BlockWall(Blocks.cobblestone); - public static final ItemMultiTexture itemCustomWall = new ItemMultiTexture(blockCustomWall, blockCustomWall, new Function() + public static final ItemMultiTexture itemCustomWall = (ItemMultiTexture)new ItemMultiTexture(blockCustomWall, blockCustomWall, new Function() { @Override public String apply(ItemStack stack) { return BlockWall.EnumType.byMetadata(stack.getMetadata()).getUnlocalizedName(); } - }); + }).setRegistryName(nameCustomWall); @EventHandler public void preInit(FMLPreInitializationEvent event) { - blockCustom.setUnlocalizedName(MODID + ".customBlock"); - GameRegistry.registerBlock(blockCustom, "customBlock"); + blockCustom.setUnlocalizedName(MODID + ".customBlock").setRegistryName("customBlock"); + GameRegistry.registerBlock(blockCustom); - blockCustomWall.setUnlocalizedName(MODID + ".customWall"); - GameRegistry.registerBlock(blockCustomWall, null, nameCustomWall); - GameRegistry.registerItem(itemCustomWall, nameCustomWall); + blockCustomWall.setUnlocalizedName(MODID + ".customWall").setRegistryName(nameCustomWall); + GameRegistry.registerBlock(blockCustomWall, (Class)null); + GameRegistry.registerItem(itemCustomWall); GameData.getBlockItemMap().put(blockCustomWall, itemCustomWall); if (event.getSide() == Side.CLIENT) @@ -96,34 +97,34 @@ public class ForgeBlockStatesLoaderDebug { protected CustomMappedBlock() { super(Material.rock); - + this.setUnlocalizedName(MODID + ".customMappedBlock"); } - + @Override protected BlockState createBlockState() { return new BlockState(this, VARIANT); } - + @Override public int getMetaFromState(IBlockState state) { return ((CustomVariant)state.getValue(VARIANT)).ordinal(); } - + @Override public IBlockState getStateFromMeta(int meta) { if(meta > CustomVariant.values().length || meta < 0) meta = 0; - + return this.getDefaultState().withProperty(VARIANT, CustomVariant.values()[meta]); } - + public static enum CustomVariant implements IStringSerializable { TypeA, TypeB; - + public String getName() { return this.toString(); }; } }