Squashed commit of the following:

commit b3b290aec9d3010a134859da6001ea28a96c2fdc
Merge: c6ce6a0 d803f7d
Author: cpw <cpw@weeksfamily.ca>
Date:   Fri Mar 25 13:28:04 2016 -0400

    Merge branch 'RegistryRework' of https://github.com/LexManos/MinecraftForge into LexManos-RegistryRework

    Implement proper registry slaves. Should help with rollback related issues.

    Missing patch

commit d803f7db76f65db9d27302c9804a643bc853dc22
Author: LexManos <LexManos@gmail.com>
Date:   Tue Mar 22 03:36:14 2016 -0700

    Update VillagerRegistry and use it. Should in theory make custom villagers work now. Using string version instead of int id for networking.

commit eb5e5b4b42fdca26d2a104e4dc1e6a3ea3051a7b
Author: LexManos <LexManos@gmail.com>
Date:   Tue Mar 22 02:14:16 2016 -0700

    More cleanup.

commit edbc56b2ff314629d0e402709f3cf29fc79c4a3d
Author: LexManos <LexManos@gmail.com>
Date:   Tue Mar 22 02:05:23 2016 -0700

    More cleanups, removed deprecated UniqueIdentifier {ResourceLocation now}

commit e2df8d1be3c97601508f83dc97b0e8853fa1e271
Author: LexManos <LexManos@gmail.com>
Date:   Tue Mar 22 01:29:19 2016 -0700

    Stupid generics....

commit 46d57dc4677fa5ff3923e64eaccfb33d7e5aad8d
Author: LexManos <LexManos@gmail.com>
Date:   Tue Mar 22 01:00:25 2016 -0700

    Some registry tweaking to provde a non-complicated API modders can use.
This commit is contained in:
cpw 2016-04-01 17:13:06 -04:00
parent b427b26583
commit 6e04a6c572
19 changed files with 659 additions and 435 deletions

View file

@ -1,7 +1,11 @@
--- ../src-base/minecraft/net/minecraft/block/Block.java --- ../src-base/minecraft/net/minecraft/block/Block.java
+++ ../src-work/minecraft/net/minecraft/block/Block.java +++ ../src-work/minecraft/net/minecraft/block/Block.java
@@ -46,8 +46,9 @@ @@ -43,11 +43,12 @@
public class Block import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
-public class Block
+public class Block extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl<Block>
{ {
private static final ResourceLocation field_176230_a = new ResourceLocation("air"); private static final ResourceLocation field_176230_a = new ResourceLocation("air");
- public static final RegistryNamespacedDefaultedByKey<ResourceLocation, Block> field_149771_c = new RegistryNamespacedDefaultedByKey(field_176230_a); - public static final RegistryNamespacedDefaultedByKey<ResourceLocation, Block> field_149771_c = new RegistryNamespacedDefaultedByKey(field_176230_a);
@ -12,17 +16,7 @@
public static final AxisAlignedBB field_185505_j = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); public static final AxisAlignedBB field_185505_j = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D);
public static final AxisAlignedBB field_185506_k = null; public static final AxisAlignedBB field_185506_k = null;
private CreativeTabs field_149772_a; private CreativeTabs field_149772_a;
@@ -70,6 +71,9 @@ @@ -83,7 +84,8 @@
private IBlockState field_176228_M;
private String field_149770_b;
+ public final net.minecraftforge.fml.common.registry.RegistryDelegate<Block> delegate =
+ ((net.minecraftforge.fml.common.registry.FMLControlledNamespacedRegistry)field_149771_c).getDelegate(this, Block.class);
+
public static int func_149682_b(Block p_149682_0_)
{
return field_149771_c.func_148757_b(p_149682_0_);
@@ -83,7 +87,8 @@
public static Block func_149729_e(int p_149729_0_) public static Block func_149729_e(int p_149729_0_)
{ {
@ -32,7 +26,7 @@
} }
public static IBlockState func_176220_d(int p_176220_0_) public static IBlockState func_176220_d(int p_176220_0_)
@@ -268,7 +273,7 @@ @@ -268,7 +270,7 @@
public boolean func_176200_f(IBlockAccess p_176200_1_, BlockPos p_176200_2_) public boolean func_176200_f(IBlockAccess p_176200_1_, BlockPos p_176200_2_)
{ {
@ -41,7 +35,7 @@
} }
public Block func_149711_c(float p_149711_1_) public Block func_149711_c(float p_149711_1_)
@@ -305,9 +310,10 @@ @@ -305,9 +307,10 @@
return this.field_149789_z; return this.field_149789_z;
} }
@ -53,7 +47,7 @@
} }
public AxisAlignedBB func_185496_a(IBlockState p_185496_1_, IBlockAccess p_185496_2_, BlockPos p_185496_3_) public AxisAlignedBB func_185496_a(IBlockState p_185496_1_, IBlockAccess p_185496_2_, BlockPos p_185496_3_)
@@ -346,13 +352,13 @@ @@ -346,13 +349,13 @@
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public int func_185484_c(IBlockState p_185484_1_, IBlockAccess p_185484_2_, BlockPos p_185484_3_) public int func_185484_c(IBlockState p_185484_1_, IBlockAccess p_185484_2_, BlockPos p_185484_3_)
{ {
@ -69,7 +63,7 @@
} }
else else
{ {
@@ -415,7 +421,7 @@ @@ -415,7 +418,7 @@
} }
} }
@ -78,7 +72,7 @@
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@@ -472,6 +478,10 @@ @@ -472,6 +475,10 @@
public void func_180663_b(World p_180663_1_, BlockPos p_180663_2_, IBlockState p_180663_3_) public void func_180663_b(World p_180663_1_, BlockPos p_180663_2_, IBlockState p_180663_3_)
{ {
@ -89,7 +83,7 @@
} }
public int func_149745_a(Random p_149745_1_) public int func_149745_a(Random p_149745_1_)
@@ -486,8 +496,7 @@ @@ -486,8 +493,7 @@
public float func_180647_a(IBlockState p_180647_1_, EntityPlayer p_180647_2_, World p_180647_3_, BlockPos p_180647_4_) public float func_180647_a(IBlockState p_180647_1_, EntityPlayer p_180647_2_, World p_180647_3_, BlockPos p_180647_4_)
{ {
@ -99,7 +93,7 @@
} }
public final void func_176226_b(World p_176226_1_, BlockPos p_176226_2_, IBlockState p_176226_3_, int p_176226_4_) public final void func_176226_b(World p_176226_1_, BlockPos p_176226_2_, IBlockState p_176226_3_, int p_176226_4_)
@@ -497,20 +506,16 @@ @@ -497,20 +503,16 @@
public void func_180653_a(World p_180653_1_, BlockPos p_180653_2_, IBlockState p_180653_3_, float p_180653_4_, int p_180653_5_) public void func_180653_a(World p_180653_1_, BlockPos p_180653_2_, IBlockState p_180653_3_, float p_180653_4_, int p_180653_5_)
{ {
@ -125,7 +119,7 @@
} }
} }
} }
@@ -518,8 +523,13 @@ @@ -518,8 +520,13 @@
public static void func_180635_a(World p_180635_0_, BlockPos p_180635_1_, ItemStack p_180635_2_) public static void func_180635_a(World p_180635_0_, BlockPos p_180635_1_, ItemStack p_180635_2_)
{ {
@ -140,7 +134,7 @@
float f = 0.5F; float f = 0.5F;
double d0 = (double)(p_180635_0_.field_73012_v.nextFloat() * f) + (double)(1.0F - f) * 0.5D; double d0 = (double)(p_180635_0_.field_73012_v.nextFloat() * f) + (double)(1.0F - f) * 0.5D;
double d1 = (double)(p_180635_0_.field_73012_v.nextFloat() * f) + (double)(1.0F - f) * 0.5D; double d1 = (double)(p_180635_0_.field_73012_v.nextFloat() * f) + (double)(1.0F - f) * 0.5D;
@@ -588,7 +598,7 @@ @@ -588,7 +595,7 @@
public boolean func_176196_c(World p_176196_1_, BlockPos p_176196_2_) public boolean func_176196_c(World p_176196_1_, BlockPos p_176196_2_)
{ {
@ -149,7 +143,7 @@
} }
public boolean func_180639_a(World p_180639_1_, BlockPos p_180639_2_, IBlockState p_180639_3_, EntityPlayer p_180639_4_, EnumHand p_180639_5_, ItemStack p_180639_6_, EnumFacing p_180639_7_, float p_180639_8_, float p_180639_9_, float p_180639_10_) public boolean func_180639_a(World p_180639_1_, BlockPos p_180639_2_, IBlockState p_180639_3_, EntityPlayer p_180639_4_, EnumHand p_180639_5_, ItemStack p_180639_6_, EnumFacing p_180639_7_, float p_180639_8_, float p_180639_9_, float p_180639_10_)
@@ -638,25 +648,35 @@ @@ -638,25 +645,35 @@
p_180657_2_.func_71029_a(StatList.func_188055_a(this)); p_180657_2_.func_71029_a(StatList.func_188055_a(this));
p_180657_2_.func_71020_j(0.025F); p_180657_2_.func_71020_j(0.025F);
@ -188,20 +182,15 @@
} }
protected ItemStack func_180643_i(IBlockState p_180643_1_) protected ItemStack func_180643_i(IBlockState p_180643_1_)
@@ -747,9 +767,11 @@ @@ -747,6 +764,7 @@
p_176216_2_.field_70181_x = 0.0D; p_176216_2_.field_70181_x = 0.0D;
} }
+ @Deprecated // Forge: Use more sensitive version below: getPickBlock + @Deprecated // Forge: Use more sensitive version below: getPickBlock
public ItemStack func_185473_a(World p_185473_1_, BlockPos p_185473_2_, IBlockState p_185473_3_) public ItemStack func_185473_a(World p_185473_1_, BlockPos p_185473_2_, IBlockState p_185473_3_)
{ {
- return new ItemStack(Item.func_150898_a(this), 1, this.func_180651_a(p_185473_3_)); return new ItemStack(Item.func_150898_a(this), 1, this.func_180651_a(p_185473_3_));
+ Item item = Item.func_150898_a(this); @@ -844,6 +862,1120 @@
+ return item == null ? null : new ItemStack(item, 1, this.func_180651_a(p_185473_3_));
}
@SideOnly(Side.CLIENT)
@@ -844,6 +866,1191 @@
return "Block{" + field_149771_c.func_177774_c(this) + "}"; return "Block{" + field_149771_c.func_177774_c(this) + "}";
} }
@ -1286,24 +1275,12 @@
+ +
+ /** + /**
+ * Queries if this block should render in a given layer. + * Queries if this block should render in a given layer.
+ * ISmartBlockModel can use {@link MinecraftForgeClient#getRenderLayer()} to alter their model based on layer. + * ISmartBlockModel can use MinecraftForgeClient.getRenderLayer to alter their model based on layer
+ *
+ * @deprecated New method with state sensitivity: {@link #canRenderInLayer(IBlockState, BlockRenderLayer)}
+ */ + */
+ @Deprecated
+ public boolean canRenderInLayer(BlockRenderLayer layer) + public boolean canRenderInLayer(BlockRenderLayer layer)
+ { + {
+ return func_180664_k() == layer; + return func_180664_k() == layer;
+ } + }
+
+ /**
+ * Queries if this block should render in a given layer.
+ * ISmartBlockModel can use {@link MinecraftForgeClient#getRenderLayer()} to alter their model based on layer.
+ */
+ public boolean canRenderInLayer(IBlockState state, BlockRenderLayer layer)
+ {
+ return canRenderInLayer(layer);
+ }
+ +
+ // For Internal use only to capture droped items inside getDrops + // For Internal use only to capture droped items inside getDrops
+ protected static ThreadLocal<Boolean> captureDrops = new ThreadLocal<Boolean>() + protected static ThreadLocal<Boolean> captureDrops = new ThreadLocal<Boolean>()
@ -1329,65 +1306,6 @@
+ } + }
+ } + }
+ +
+ 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?", oldPrefix, 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;
+ }
+
+ /**
+ * Add information to the blocks tooltip, called from the default implementation of {@link ItemBlock#addInformation(ItemStack, EntityPlayer, List, boolean)}
+ * @param stack The stack the tooltip is being retrieved for
+ * @param player The player retrieving the tooltip
+ * @param tooltip The lines to be displayed on the tooltip
+ * @param advanced If the client has advanced debug tooltips enabled
+ */
+ public void addInformation(ItemStack stack, EntityPlayer player, List<String> tooltip, boolean advanced)
+ {
+ }
+ /* ========================================= FORGE END ======================================*/ + /* ========================================= FORGE END ======================================*/
+ +
public static void func_149671_p() public static void func_149671_p()

View file

@ -5,7 +5,7 @@
return field_110906_m; return field_110906_m;
default: default:
- return field_110903_f; - return field_110903_f;
+ return net.minecraftforge.fml.common.registry.VillagerRegistry.getVillagerSkin(p_110775_1_.func_70946_n(), field_110903_f); + return p_110775_1_.getProfessionForge().getSkin();
} }
} }

File diff suppressed because one or more lines are too long

View file

@ -1,8 +1,11 @@
--- ../src-base/minecraft/net/minecraft/item/Item.java --- ../src-base/minecraft/net/minecraft/item/Item.java
+++ ../src-work/minecraft/net/minecraft/item/Item.java +++ ../src-work/minecraft/net/minecraft/item/Item.java
@@ -58,8 +58,8 @@ @@ -56,10 +56,10 @@
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class Item -public class Item
+public class Item extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl<Item>
{ {
- public static final RegistryNamespaced<ResourceLocation, Item> field_150901_e = new RegistryNamespaced(); - public static final RegistryNamespaced<ResourceLocation, Item> field_150901_e = new RegistryNamespaced();
- private static final Map<Block, Item> field_179220_a = Maps.<Block, Item>newHashMap(); - private static final Map<Block, Item> field_179220_a = Maps.<Block, Item>newHashMap();
@ -11,17 +14,7 @@
private static final IItemPropertyGetter field_185046_b = new IItemPropertyGetter() private static final IItemPropertyGetter field_185046_b = new IItemPropertyGetter()
{ {
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@@ -104,6 +104,9 @@ @@ -192,6 +192,7 @@
private Item field_77700_c;
private String field_77774_bZ;
+ public final net.minecraftforge.fml.common.registry.RegistryDelegate<Item> delegate =
+ ((net.minecraftforge.fml.common.registry.FMLControlledNamespacedRegistry)field_150901_e).getDelegate(this, Item.class);
+
public static int func_150891_b(Item p_150891_0_)
{
return p_150891_0_ == null ? 0 : field_150901_e.func_148757_b(p_150891_0_);
@@ -192,6 +195,7 @@
return p_77654_1_; return p_77654_1_;
} }
@ -29,7 +22,7 @@
public int func_77639_j() public int func_77639_j()
{ {
return this.field_77777_bU; return this.field_77777_bU;
@@ -312,6 +316,7 @@ @@ -312,6 +313,7 @@
return this.field_77700_c; return this.field_77700_c;
} }
@ -37,7 +30,7 @@
public boolean func_77634_r() public boolean func_77634_r()
{ {
return this.field_77700_c != null; return this.field_77700_c != null;
@@ -367,7 +372,7 @@ @@ -367,7 +369,7 @@
public boolean func_77616_k(ItemStack p_77616_1_) public boolean func_77616_k(ItemStack p_77616_1_)
{ {
@ -46,7 +39,7 @@
} }
protected RayTraceResult func_77621_a(World p_77621_1_, EntityPlayer p_77621_2_, boolean p_77621_3_) protected RayTraceResult func_77621_a(World p_77621_1_, EntityPlayer p_77621_2_, boolean p_77621_3_)
@@ -385,6 +390,10 @@ @@ -385,6 +387,10 @@
float f6 = f3 * f4; float f6 = f3 * f4;
float f7 = f2 * f4; float f7 = f2 * f4;
double d3 = 5.0D; double d3 = 5.0D;
@ -57,7 +50,7 @@
Vec3d vec3d1 = vec3d.func_72441_c((double)f6 * d3, (double)f5 * d3, (double)f7 * d3); Vec3d vec3d1 = vec3d.func_72441_c((double)f6 * d3, (double)f5 * d3, (double)f7 * d3);
return p_77621_1_.func_147447_a(vec3d, vec3d1, p_77621_3_, !p_77621_3_, false); return p_77621_1_.func_147447_a(vec3d, vec3d1, p_77621_3_, !p_77621_3_, false);
} }
@@ -422,11 +431,606 @@ @@ -422,11 +428,557 @@
return false; return false;
} }
@ -575,55 +568,6 @@
+ return !oldStack.equals(newStack); //!ItemStack.areItemStacksEqual(oldStack, newStack); + return !oldStack.equals(newStack); //!ItemStack.areItemStacksEqual(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?", oldPrefix, 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;
+ }
+
+ /** + /**
+ * Called from ItemStack.setItem, will hold extra data for the life of this ItemStack. + * Called from ItemStack.setItem, will hold extra data for the life of this ItemStack.
+ * Can be retrieved from stack.getCapabilities() + * Can be retrieved from stack.getCapabilities()
@ -664,7 +608,7 @@
public static void func_150900_l() 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<ItemStack, String>() func_179214_a(Blocks.field_150348_b, (new ItemMultiTexture(Blocks.field_150348_b, Blocks.field_150348_b, new Function<ItemStack, String>()
@@ -935,6 +1539,10 @@ @@ -935,6 +1487,10 @@
private final float field_78011_i; private final float field_78011_i;
private final int field_78008_j; private final int field_78008_j;
@ -675,7 +619,7 @@
private ToolMaterial(int p_i1874_3_, int p_i1874_4_, float p_i1874_5_, float p_i1874_6_, int p_i1874_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_; this.field_78001_f = p_i1874_3_;
@@ -969,9 +1577,36 @@ @@ -969,9 +1525,36 @@
return this.field_78008_j; return this.field_78008_j;
} }

View file

@ -1,8 +1,11 @@
--- ../src-base/minecraft/net/minecraft/potion/Potion.java --- ../src-base/minecraft/net/minecraft/potion/Potion.java
+++ ../src-work/minecraft/net/minecraft/potion/Potion.java +++ ../src-work/minecraft/net/minecraft/potion/Potion.java
@@ -23,7 +23,7 @@ @@ -21,9 +21,9 @@
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class Potion -public class Potion
+public class Potion extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl<Potion>
{ {
- public static final RegistryNamespaced<ResourceLocation, Potion> field_188414_b = new RegistryNamespaced(); - public static final RegistryNamespaced<ResourceLocation, Potion> field_188414_b = new RegistryNamespaced();
+ public static final RegistryNamespaced<ResourceLocation, Potion> field_188414_b = net.minecraftforge.fml.common.registry.GameData.getPotionRegistry(); + public static final RegistryNamespaced<ResourceLocation, Potion> field_188414_b = net.minecraftforge.fml.common.registry.GameData.getPotionRegistry();

View file

@ -1,5 +1,14 @@
--- ../src-base/minecraft/net/minecraft/world/biome/BiomeGenBase.java --- ../src-base/minecraft/net/minecraft/world/biome/BiomeGenBase.java
+++ ../src-work/minecraft/net/minecraft/world/biome/BiomeGenBase.java +++ ../src-work/minecraft/net/minecraft/world/biome/BiomeGenBase.java
@@ -51,7 +51,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-public abstract class BiomeGenBase
+public abstract class BiomeGenBase extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl<BiomeGenBase>
{
private static final Logger field_150586_aC = LogManager.getLogger();
protected static final IBlockState field_185365_a = Blocks.field_150348_b.func_176223_P();
@@ -70,7 +70,7 @@ @@ -70,7 +70,7 @@
protected static final WorldGenTrees field_76757_N = new WorldGenTrees(false); protected static final WorldGenTrees field_76757_N = new WorldGenTrees(false);
protected static final WorldGenBigTree field_76758_O = new WorldGenBigTree(false); protected static final WorldGenBigTree field_76758_O = new WorldGenBigTree(false);

View file

@ -192,7 +192,7 @@ public final class ModelLoader extends ModelBakery
{ {
public int compare(Block b1, Block b2) public int compare(Block b1, Block b2)
{ {
return b1.getRegistryName().compareTo(b2.getRegistryName()); return b1.getRegistryName().toString().compareTo(b2.getRegistryName().toString());
} }
}); });
ProgressBar blockBar = ProgressManager.push("ModelLoader: blocks", blocks.size()); ProgressBar blockBar = ProgressManager.push("ModelLoader: blocks", blocks.size());
@ -201,7 +201,7 @@ public final class ModelLoader extends ModelBakery
for(Block block : blocks) for(Block block : blocks)
{ {
blockBar.step(block.getRegistryName()); blockBar.step(block.getRegistryName().toString());
for(ResourceLocation location : mapper.getBlockstateLocations(block)) for(ResourceLocation location : mapper.getBlockstateLocations(block))
{ {
loadBlock(mapper, block, location); loadBlock(mapper, block, location);
@ -276,14 +276,14 @@ public final class ModelLoader extends ModelBakery
{ {
public int compare(Item i1, Item i2) public int compare(Item i1, Item i2)
{ {
return i1.getRegistryName().compareTo(i2.getRegistryName()); return i1.getRegistryName().toString().compareTo(i2.getRegistryName().toString());
} }
}); });
ProgressBar itemBar = ProgressManager.push("ModelLoader: items", items.size()); ProgressBar itemBar = ProgressManager.push("ModelLoader: items", items.size());
for(Item item : items) for(Item item : items)
{ {
itemBar.step(item.getRegistryName()); itemBar.step(item.getRegistryName().toString());
for(String s : getVariantNames(item)) for(String s : getVariantNames(item))
{ {
ResourceLocation file = getItemLocation(s); ResourceLocation file = getItemLocation(s);
@ -916,7 +916,7 @@ public final class ModelLoader extends ModelBakery
for(String s : getVariantNames(item)) for(String s : getVariantNames(item))
{ {
ModelResourceLocation memory = getInventoryVariant(s); ModelResourceLocation memory = getInventoryVariant(s);
reverseItemMap.put(memory, item.getRegistryName()); reverseItemMap.put(memory, item.getRegistryName().toString());
} }
} }
} }

View file

@ -38,7 +38,7 @@ public class BlockSnapshot implements Serializable
this.dimId = world.provider.getDimension(); this.dimId = world.provider.getDimension();
this.pos = pos; this.pos = pos;
this.setReplacedBlock(state); this.setReplacedBlock(state);
this.registryName = new ResourceLocation(state.getBlock().getRegistryName()); this.registryName = state.getBlock().getRegistryName();
this.meta = state.getBlock().getMetaFromState(state); this.meta = state.getBlock().getMetaFromState(state);
this.setFlag(3); this.setFlag(3);
TileEntity te = world.getTileEntity(pos); TileEntity te = world.getTileEntity(pos);
@ -60,7 +60,7 @@ public class BlockSnapshot implements Serializable
this.dimId = world.provider.getDimension(); this.dimId = world.provider.getDimension();
this.pos = pos.toImmutable(); this.pos = pos.toImmutable();
this.setReplacedBlock(state); this.setReplacedBlock(state);
this.registryName = new ResourceLocation(state.getBlock().getRegistryName()); this.registryName = state.getBlock().getRegistryName();
this.meta = state.getBlock().getMetaFromState(state); this.meta = state.getBlock().getMetaFromState(state);
this.setFlag(3); this.setFlag(3);
this.nbt = nbt; this.nbt = nbt;

View file

@ -433,13 +433,7 @@ public abstract class FluidRegistry
} }
@Override @Override
public String name() public ResourceLocation name() {
{
return name;
}
@Override
public ResourceLocation getResourceName() {
return new ResourceLocation(name); return new ResourceLocation(name);
} }

View file

@ -48,7 +48,7 @@ import com.google.common.eventbus.Subscribe;
* @author cpw * @author cpw
* *
*/ */
public class FMLContainer extends DummyModContainer implements WorldAccessContainer public final class FMLContainer extends DummyModContainer implements WorldAccessContainer
{ {
public FMLContainer() public FMLContainer()
{ {

View file

@ -8,31 +8,31 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import com.google.common.base.Joiner;
import com.google.common.base.Throwables;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.Validate;
import org.apache.logging.log4j.Level;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.RegistryNamespacedDefaultedByKey; import net.minecraft.util.registry.RegistryNamespacedDefaultedByKey;
import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.functions.GenericIterableFactory; import net.minecraftforge.fml.common.functions.GenericIterableFactory;
import net.minecraftforge.fml.common.registry.RegistryDelegate.Delegate; import net.minecraftforge.fml.common.registry.RegistryDelegate.Delegate;
import org.apache.commons.lang3.Validate; public class FMLControlledNamespacedRegistry<I extends IForgeRegistryEntry<I>> extends RegistryNamespacedDefaultedByKey<ResourceLocation, I> implements IForgeRegistry<I>
import org.apache.logging.log4j.Level;
import com.google.common.base.Joiner;
import com.google.common.base.Throwables;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Iterators;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaultedByKey<ResourceLocation, I>
{ {
public static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("fml.debugRegistryEntries", "false")); public static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("fml.debugRegistryEntries", "false"));
private final Class<I> superType; private final Class<I> superType;
private final boolean isDelegated; private final boolean isDelegated;
private final Field delegateAccessor;
private ResourceLocation optionalDefaultKey; private ResourceLocation optionalDefaultKey;
private I optionalDefaultObject; private I optionalDefaultObject;
private int maxId; private int maxId;
@ -59,43 +59,30 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
private final BitSet availabilityMap; private final BitSet availabilityMap;
private final Map<ResourceLocation,?> slaves = Maps.newHashMap();
private final AddCallback<I> addCallback; private final AddCallback<I> addCallback;
public interface AddCallback<T> private final ClearCallback<I> clearCallback;
{
public void onAdd(T obj, int id);
}
FMLControlledNamespacedRegistry(ResourceLocation defaultKey, int maxIdValue, int minIdValue, Class<I> type, boolean isDelegated) private final CreateCallback<I> createCallback;
{
this(defaultKey, maxIdValue, minIdValue, type, isDelegated, null);
}
FMLControlledNamespacedRegistry(ResourceLocation defaultKey, int maxIdValue, int minIdValue, Class<I> type, boolean isDelegated, AddCallback<I> callback) FMLControlledNamespacedRegistry(ResourceLocation defaultKey, int minIdValue, int maxIdValue, Class<I> type, AddCallback<I> addCallback, ClearCallback<I> clearCallback, CreateCallback<I> createCallback)
{ {
super(defaultKey); super(defaultKey);
this.superType = type; this.superType = type;
this.optionalDefaultKey = defaultKey; this.optionalDefaultKey = defaultKey;
this.maxId = maxIdValue;
this.minId = minIdValue; this.minId = minIdValue;
this.maxId = maxIdValue;
this.availabilityMap = new BitSet(maxIdValue + 1); this.availabilityMap = new BitSet(maxIdValue + 1);
this.isDelegated = isDelegated; this.isDelegated = IForgeRegistryEntry.Impl.class.isAssignableFrom(type);
if (this.isDelegated) this.addCallback = addCallback;
this.clearCallback = clearCallback;
this.createCallback = createCallback;
if (createCallback != null)
{ {
try createCallback.onCreate(slaves);
{
this.delegateAccessor = type.getField("delegate");
} catch (NoSuchFieldException e)
{
FMLLog.log(Level.ERROR, e, "Delegate class identified with missing delegate field");
throw Throwables.propagate(e);
}
} }
else
{
this.delegateAccessor = null;
}
this.addCallback = callback;
} }
void validateContent(ResourceLocation registryName) void validateContent(ResourceLocation registryName)
@ -462,7 +449,7 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
addObjectRaw(idToUse, name, thing); addObjectRaw(idToUse, name, thing);
if (isDelegated) if (isDelegated)
{ {
getExistingDelegate(thing).setResourceName(name); getExistingDelegate(thing).setName(name);
} }
if (this.dummiedLocations.remove(name) && DEBUG) if (this.dummiedLocations.remove(name) && DEBUG)
@ -561,7 +548,7 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
availabilityMap.set(id); availabilityMap.set(id);
if (addCallback != null) if (addCallback != null)
{ {
addCallback.onAdd(thing, id); addCallback.onAdd(thing, id, slaves);
} }
} }
@ -576,15 +563,15 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Delegate<I> getExistingDelegate(I thing) private Delegate<I> getExistingDelegate(I thing)
{ {
try if (isDelegated)
{ {
return (Delegate<I>)delegateAccessor.get(thing); return (Delegate<I>)((IForgeRegistryEntry.Impl<I>)thing).delegate;
} catch (IllegalAccessException e) }
else
{ {
FMLLog.log(Level.ERROR, e, "Illegal attempt to access delegate"); return null;
throw Throwables.propagate(e);
} }
} }
@ -655,7 +642,7 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
FMLControlledNamespacedRegistry<I> makeShallowCopy() FMLControlledNamespacedRegistry<I> makeShallowCopy()
{ {
return new FMLControlledNamespacedRegistry<I>(optionalDefaultKey, maxId, minId, superType, isDelegated); return new FMLControlledNamespacedRegistry<I>(optionalDefaultKey, minId, maxId, superType, addCallback, clearCallback, createCallback);
} }
void resetSubstitutionDelegates() void resetSubstitutionDelegates()
@ -672,7 +659,7 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> FMLControlledNamespacedRegistry<T> asType(Class<? extends T> type) public <T extends IForgeRegistryEntry<T>> FMLControlledNamespacedRegistry<T> asType(Class<? extends T> type)
{ {
return (FMLControlledNamespacedRegistry<T>)this; return (FMLControlledNamespacedRegistry<T>)this;
} }
@ -758,18 +745,118 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
for (I i : this.underlyingIntegerMap) for (I i : this.underlyingIntegerMap)
{ {
addCallback.onAdd(i, this.underlyingIntegerMap.add(i)); addCallback.onAdd(i, this.underlyingIntegerMap.add(i), slaves);
} }
} }
@Override @Override
public ResourceLocation getNameForObject(I p_177774_1_) public ResourceLocation getNameForObject(I p_177774_1_)
{ {
ResourceLocation rl = super.getNameForObject(p_177774_1_); ResourceLocation rl = super.getNameForObjectBypass(p_177774_1_);
if (rl == null) if (rl == null)
{ {
rl = activeSubstitutions.inverse().get(p_177774_1_); rl = activeSubstitutions.inverse().get(p_177774_1_);
} }
return rl; return rl;
} }
@Override
public Class<I> getRegistrySuperType()
{
return superType;
}
// IForgeRegistry: Modders should only interfaces with these methods
@Override
public void register(I value)
{
ResourceLocation key = value.getRegistryName();
if (key == null)
{
FMLLog.severe("Attempted to register a entry with a null name: %s", value);
throw new NullPointerException(String.format("Attempted to register a entry with a null name: %s", value));
}
add(-1, key, value);
}
@Override
public boolean containsValue(I value)
{
return getKey(value) != null;
}
@Override
public I getValue(ResourceLocation key)
{
return getObject(key);
}
@Override
public ResourceLocation getKey(I value)
{
return getNameForObject(value);
}
@Override
public List<I> getValues()
{
return Lists.newArrayList(this.iterator());
}
@Override
public Set<Entry<ResourceLocation, I>> getEntries()
{
return Sets.newHashSet(new Iterator<Entry<ResourceLocation, I>>()
{
Iterator<I> itr = FMLControlledNamespacedRegistry.this.iterator();
@Override
public boolean hasNext()
{
return itr.hasNext();
}
@Override
public Entry<ResourceLocation, I> next()
{
final I value = itr.next();
final ResourceLocation key = FMLControlledNamespacedRegistry.this.getKey(value);
return new Entry<ResourceLocation, I>()
{
@Override
public ResourceLocation getKey()
{
return key;
}
@Override
public I getValue()
{
return value;
}
@Override
public I setValue(I value)
{
throw new UnsupportedOperationException("Setting the value in an iterator is not allowed");
}
};
}
@Override
public void remove()
{
throw new UnsupportedOperationException("This is a READ ONLY view of this registry.");
}
});
}
@SuppressWarnings("unchecked")
@Override
public <T> T getSlaveMap(ResourceLocation slaveMapName, Class<T> type)
{
return (T)slaves.get(slaveMapName);
}
} }

View file

@ -14,6 +14,7 @@ package net.minecraftforge.fml.common.registry;
import java.util.Map; import java.util.Map;
import com.google.common.collect.HashBiMap;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@ -27,7 +28,6 @@ import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.ModContainer; import net.minecraftforge.fml.common.ModContainer;
import com.google.common.collect.BiMap; import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
public class GameData public class GameData
{ {
@ -35,12 +35,22 @@ public class GameData
static final int MAX_BLOCK_ID = 4095; static final int MAX_BLOCK_ID = 4095;
static final int MIN_ITEM_ID = 4096; static final int MIN_ITEM_ID = 4096;
static final int MAX_ITEM_ID = 31999; static final int MAX_ITEM_ID = 31999;
public static final int MIN_POTION_ID = 0; // 0-~31 are vanilla, forge start at 32 static final int MIN_POTION_ID = 0; // 0-~31 are vanilla, forge start at 32
public static final int MAX_POTION_ID = 255; // S1DPacketEntityEffect sends bytes, we can only use 255 static final int MAX_POTION_ID = 255; // S1DPacketEntityEffect sends bytes, we can only use 255
public static final int MIN_BIOME_ID = 0; // 0-~31 are vanilla, forge start at 32 static final int MIN_BIOME_ID = 0; // 0-~31 are vanilla, forge start at 32
public static final int MAX_BIOME_ID = 255; // S1DPacketEntityEffect sends bytes, we can only use 255 static final int MAX_BIOME_ID = 255; // S1DPacketEntityEffect sends bytes, we can only use 255
private static final ResourceLocation BLOCK_TO_ITEM = new ResourceLocation("minecraft:blocktoitemmap");
private static final ResourceLocation BLOCKSTATE_TO_ID = new ResourceLocation("minecraft:blockstatetoid");
private static final GameData mainData = new GameData(); private static final GameData mainData = new GameData();
public GameData()
{
iBlockRegistry = PersistentRegistryManager.createRegistry(PersistentRegistryManager.BLOCKS, Block.class, new ResourceLocation("minecraft:air"), MIN_BLOCK_ID, MAX_BLOCK_ID, true, BlockCallbacks.INSTANCE, BlockCallbacks.INSTANCE, BlockCallbacks.INSTANCE);
iItemRegistry = PersistentRegistryManager.createRegistry(PersistentRegistryManager.ITEMS, Item.class, null, MIN_ITEM_ID, MAX_ITEM_ID, true, ItemCallbacks.INSTANCE, ItemCallbacks.INSTANCE, ItemCallbacks.INSTANCE);
iPotionRegistry = PersistentRegistryManager.createRegistry(PersistentRegistryManager.POTIONS, Potion.class, null, MIN_POTION_ID, MAX_POTION_ID, false, PotionCallbacks.INSTANCE, PotionCallbacks.INSTANCE, PotionCallbacks.INSTANCE);
iBiomeRegistry = PersistentRegistryManager.createRegistry(PersistentRegistryManager.BIOMES, BiomeGenBase.class, null, MIN_BIOME_ID, MAX_BIOME_ID, false, BiomeCallbacks.INSTANCE, BiomeCallbacks.INSTANCE, BiomeCallbacks.INSTANCE);
}
// public api // public api
/** /**
@ -96,10 +106,10 @@ public class GameData
} }
// internal registry objects // internal registry objects
private final FMLControlledNamespacedRegistry<Block> iBlockRegistry = PersistentRegistryManager.createRegistry(PersistentRegistryManager.BLOCKS, Block.class, new ResourceLocation("minecraft:air"), MAX_BLOCK_ID, MIN_BLOCK_ID, true, BlockStateCapture.INSTANCE); private final FMLControlledNamespacedRegistry<Block> iBlockRegistry;
private final FMLControlledNamespacedRegistry<Item> iItemRegistry = PersistentRegistryManager.createRegistry(PersistentRegistryManager.ITEMS, Item.class, null, MAX_ITEM_ID, MIN_ITEM_ID, true, ItemBlockCapture.INSTANCE); private final FMLControlledNamespacedRegistry<Item> iItemRegistry;
private final FMLControlledNamespacedRegistry<Potion> iPotionRegistry = PersistentRegistryManager.createRegistry(PersistentRegistryManager.POTIONS, Potion.class, null, MAX_POTION_ID, MIN_POTION_ID, false, PotionArrayCapture.INSTANCE); private final FMLControlledNamespacedRegistry<Potion> iPotionRegistry;
private final FMLControlledNamespacedRegistry<BiomeGenBase> iBiomeRegistry = PersistentRegistryManager.createRegistry(PersistentRegistryManager.BIOMES, BiomeGenBase.class, null, MAX_BIOME_ID, MIN_BIOME_ID, false, BiomeCapture.INSTANCE); private final FMLControlledNamespacedRegistry<BiomeGenBase> iBiomeRegistry;
int registerItem(Item item, String name) // from GameRegistry int registerItem(Item item, String name) // from GameRegistry
{ {
@ -152,42 +162,45 @@ public class GameData
void registerSubstitutionAlias(String name, GameRegistry.Type type, Object toReplace) throws ExistingSubstitutionException void registerSubstitutionAlias(String name, GameRegistry.Type type, Object toReplace) throws ExistingSubstitutionException
{ {
ResourceLocation nameToSubstitute = new ResourceLocation(name); ResourceLocation nameToSubstitute = new ResourceLocation(name);
final BiMap<Block, Item> blockItemMap = getBlockItemMap();
if (type == GameRegistry.Type.BLOCK) if (type == GameRegistry.Type.BLOCK)
{ {
iBlockRegistry.addSubstitutionAlias(Loader.instance().activeModContainer().getModId(), nameToSubstitute, (Block)toReplace); iBlockRegistry.addSubstitutionAlias(Loader.instance().activeModContainer().getModId(), nameToSubstitute, (Block)toReplace);
Block orig = iBlockRegistry.activateSubstitution(nameToSubstitute); Block orig = iBlockRegistry.activateSubstitution(nameToSubstitute);
if (BLOCK_TO_ITEM.containsKey(orig)) if (blockItemMap.containsKey(orig))
{ {
Item i = BLOCK_TO_ITEM.get(orig); Item i = blockItemMap.get(orig);
BLOCK_TO_ITEM.forcePut((Block)toReplace,i); blockItemMap.forcePut((Block)toReplace,i);
} }
} }
else if (type == GameRegistry.Type.ITEM) else if (type == GameRegistry.Type.ITEM)
{ {
iItemRegistry.addSubstitutionAlias(Loader.instance().activeModContainer().getModId(), nameToSubstitute, (Item)toReplace); iItemRegistry.addSubstitutionAlias(Loader.instance().activeModContainer().getModId(), nameToSubstitute, (Item)toReplace);
Item orig = iItemRegistry.activateSubstitution(nameToSubstitute); Item orig = iItemRegistry.activateSubstitution(nameToSubstitute);
if (BLOCK_TO_ITEM.containsValue(orig)) if (blockItemMap.containsValue(orig))
{ {
Block b = BLOCK_TO_ITEM.inverse().get(orig); Block b = blockItemMap.inverse().get(orig);
BLOCK_TO_ITEM.forcePut(b, (Item)toReplace); blockItemMap.forcePut(b, (Item)toReplace);
} }
} }
} }
private static BiMap<Block, Item> BLOCK_TO_ITEM = HashBiMap.create(); @SuppressWarnings("unchecked")
public static BiMap<Block,Item> getBlockItemMap()
//Internal: DO NOT USE, will change without warning.
public static Map<Block, Item> getBlockItemMap()
{ {
return BLOCK_TO_ITEM; return (BiMap<Block,Item>)getMain().iItemRegistry.getSlaveMap(BLOCK_TO_ITEM, BiMap.class);
}
static <K extends IForgeRegistryEntry<K>> K register(K object, ResourceLocation location)
{
final IForgeRegistry<K> registry = PersistentRegistryManager.findRegistry(object);
registry.register(object);
return object;
} }
private static ClearableObjectIntIdentityMap<IBlockState> BLOCKSTATE_TO_ID = new ClearableObjectIntIdentityMap<IBlockState>(); @SuppressWarnings("unchecked")
public static ObjectIntIdentityMap<IBlockState> getBlockStateIDMap()
//Internal: DO NOT USE, will change without warning.
public static ClearableObjectIntIdentityMap<IBlockState> getBlockStateIDMap()
{ {
return BLOCKSTATE_TO_ID; return (ObjectIntIdentityMap<IBlockState>)getMain().iBlockRegistry.getSlaveMap(BLOCKSTATE_TO_ID, ObjectIntIdentityMap.class);
} }
//Lets us clear the map so we can rebuild it. //Lets us clear the map so we can rebuild it.
@ -200,56 +213,116 @@ public class GameData
} }
} }
public <T> RegistryDelegate<T> makeDelegate(T obj, Class<T> rootClass) public <T extends IForgeRegistryEntry<T>> RegistryDelegate<T> makeDelegate(T obj, Class<T> rootClass)
{ {
return PersistentRegistryManager.makeDelegate(obj, rootClass); return PersistentRegistryManager.makeDelegate(obj, rootClass);
} }
private static class BlockStateCapture implements FMLControlledNamespacedRegistry.AddCallback<Block> private static class BlockCallbacks implements IForgeRegistry.AddCallback<Block>,IForgeRegistry.ClearCallback<Block>,IForgeRegistry.CreateCallback<Block>
{ {
static final BlockStateCapture INSTANCE = new BlockStateCapture(); static final BlockCallbacks INSTANCE = new BlockCallbacks();
@SuppressWarnings("unchecked")
@Override @Override
public void onAdd(Block block, int blockId) public void onAdd(Block block, int blockId, Map<ResourceLocation,?> slaves)
{ {
ClearableObjectIntIdentityMap<IBlockState> blockstateMap = (ClearableObjectIntIdentityMap<IBlockState>)slaves.get(BLOCKSTATE_TO_ID);
for (IBlockState state : block.getBlockState().getValidStates()) for (IBlockState state : block.getBlockState().getValidStates())
{ {
GameData.BLOCKSTATE_TO_ID.put(state, blockId << 4 | block.getMetaFromState(state)); blockstateMap.put(state, blockId << 4 | block.getMetaFromState(state));
} }
} }
@SuppressWarnings("unchecked")
@Override
public void onClear(Map<ResourceLocation, ?> slaveset)
{
ClearableObjectIntIdentityMap<IBlockState> blockstateMap = (ClearableObjectIntIdentityMap<IBlockState>)slaveset.get(BLOCKSTATE_TO_ID);
blockstateMap.clear();
}
@SuppressWarnings("unchecked")
@Override
public void onCreate(Map<ResourceLocation, ?> slaveset)
{
final ClearableObjectIntIdentityMap<Block> idMap = new ClearableObjectIntIdentityMap<Block>();
((Map<ResourceLocation,Object>)slaveset).put(BLOCKSTATE_TO_ID, idMap);
}
} }
private static class ItemBlockCapture implements FMLControlledNamespacedRegistry.AddCallback<Item> private static class ItemCallbacks implements IForgeRegistry.AddCallback<Item>,IForgeRegistry.ClearCallback<Item>,IForgeRegistry.CreateCallback<Item>
{ {
static final ItemBlockCapture INSTANCE = new ItemBlockCapture(); static final ItemCallbacks INSTANCE = new ItemCallbacks();
@Override @Override
public void onAdd(Item item, int blockId) public void onAdd(Item item, int blockId, Map<ResourceLocation, ?> slaves)
{ {
if (item instanceof ItemBlock) if (item instanceof ItemBlock)
{ {
ItemBlock itemBlock = (ItemBlock)item; ItemBlock itemBlock = (ItemBlock)item;
BLOCK_TO_ITEM.forcePut(itemBlock.getBlock().delegate.get(), item); @SuppressWarnings("unchecked") BiMap<Block, Item> blockToItem = (BiMap<Block, Item>)slaves.get(BLOCK_TO_ITEM);
blockToItem.forcePut(itemBlock.getBlock().delegate.get(), item);
} }
} }
@SuppressWarnings("unchecked")
@Override
public void onClear(Map<ResourceLocation, ?> slaveset)
{
Map<Block,Item> map = (Map<Block, Item>)slaveset.get(BLOCK_TO_ITEM);
map.clear();
}
@SuppressWarnings("unchecked")
@Override
public void onCreate(Map<ResourceLocation, ?> slaveset)
{
final HashBiMap<Block, Item> map = HashBiMap.create();
((Map<ResourceLocation,Object>)slaveset).put(BLOCK_TO_ITEM, map);
}
} }
private static class PotionArrayCapture implements FMLControlledNamespacedRegistry.AddCallback<Potion> private static class PotionCallbacks implements IForgeRegistry.AddCallback<Potion>,IForgeRegistry.ClearCallback<Potion>,IForgeRegistry.CreateCallback<Potion>
{ {
static final PotionArrayCapture INSTANCE = new PotionArrayCapture(); static final PotionCallbacks INSTANCE = new PotionCallbacks();
@Override @Override
public void onAdd(Potion potion, int id) { public void onAdd(Potion potion, int id, Map<ResourceLocation, ?> slaves) {
// no op for the minute?
}
@Override
public void onClear(Map<ResourceLocation, ?> slaveset)
{
// no op for the minute?
}
@Override
public void onCreate(Map<ResourceLocation, ?> slaveset)
{
// no op for the minute? // no op for the minute?
} }
} }
private static class BiomeCapture implements FMLControlledNamespacedRegistry.AddCallback<BiomeGenBase> private static class BiomeCallbacks implements IForgeRegistry.AddCallback<BiomeGenBase>,IForgeRegistry.ClearCallback<BiomeGenBase>,IForgeRegistry.CreateCallback<BiomeGenBase>
{ {
static final BiomeCapture INSTANCE = new BiomeCapture(); static final BiomeCallbacks INSTANCE = new BiomeCallbacks();
@Override @Override
public void onAdd(BiomeGenBase potion, int id) { public void onAdd(BiomeGenBase potion, int id, Map<ResourceLocation, ?> slaves) {
// no op for the minute?
}
@Override
public void onClear(Map<ResourceLocation, ?> slaveset)
{
// no op for the minute?
}
@Override
public void onCreate(Map<ResourceLocation, ?> slaveset)
{
// no op for the minute? // no op for the minute?
} }
} }
} }

View file

@ -51,7 +51,6 @@ import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Level;
import com.google.common.base.Objects;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -128,14 +127,19 @@ public class GameRegistry
sortedGeneratorList = ImmutableList.copyOf(list); sortedGeneratorList = ImmutableList.copyOf(list);
} }
public static <K extends IForgeRegistryEntry<K>> K register(K object, ResourceLocation location)
{
return GameData.register(object, location);
}
/** /**
* Register an item with the item registry with a the name specified in Item.getRegistryName() * Register an item with the item registry with a the name specified in Item.getRegistryName()
* *
* @param item The item to register * @param item The item to register
*/ */
@Deprecated
public static void registerItem(Item item) public static void registerItem(Item item)
{ {
registerItem(item, item.getRegistryName()); registerItem(item, item.getRegistryName().toString());
} }
/** /**
@ -144,6 +148,7 @@ public class GameRegistry
* @param item The item to register * @param item The item to register
* @param name The mod-unique name of the item * @param name The mod-unique name of the item
*/ */
@Deprecated
public static void registerItem(Item item, String name) public static void registerItem(Item item, String name)
{ {
if (Strings.isNullOrEmpty(name)) if (Strings.isNullOrEmpty(name))
@ -153,20 +158,6 @@ public class GameRegistry
GameData.getMain().registerItem(item, name); GameData.getMain().registerItem(item, name);
} }
/**
* Register the specified Item with a mod specific name : overrides the standard type based name
*
* @param item The item to register
* @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)
{
registerItem(item, name);
return item;
}
/** /**
* Add a forced persistent substitution alias for the block or item to another block or item. This will have * 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 * the effect of using the substituted block or item instead of the original, where ever it is
@ -188,9 +179,10 @@ public class GameRegistry
* *
* @param block The block to register * @param block The block to register
*/ */
@Deprecated
public static Block registerBlock(Block block) public static Block registerBlock(Block block)
{ {
return registerBlock(block, block.getRegistryName()); return registerBlock(block, block.getRegistryName().toString());
} }
/** /**
@ -199,6 +191,7 @@ public class GameRegistry
* @param block The block to register * @param block The block to register
* @param name The mod-unique name to register it as, will get prefixed by your modid. * @param name The mod-unique name to register it as, will get prefixed by your modid.
*/ */
@Deprecated
public static Block registerBlock(Block block, String name) public static Block registerBlock(Block block, String name)
{ {
return registerBlock(block, ItemBlock.class, name); return registerBlock(block, ItemBlock.class, name);
@ -210,6 +203,7 @@ public class GameRegistry
* @param block The block to register * @param block The block to register
* @param itemclass The item type to register with it : null registers a block without associated item. * @param itemclass The item type to register with it : null registers a block without associated item.
*/ */
@Deprecated
public static Block registerBlock(Block block, Class<? extends ItemBlock> itemclass) public static Block registerBlock(Block block, Class<? extends ItemBlock> itemclass)
{ {
return registerBlock(block, itemclass, block.getRegistryName()); return registerBlock(block, itemclass, block.getRegistryName());
@ -222,6 +216,7 @@ public class GameRegistry
* @param itemclass The item type to register with it : null registers a block without associated item. * @param itemclass The item type to register with it : null registers a block without associated item.
* @param name The mod-unique name to register it as, will get prefixed by your modid. * @param name The mod-unique name to register it as, will get prefixed by your modid.
*/ */
@Deprecated
public static Block registerBlock(Block block, Class<? extends ItemBlock> itemclass, String name) public static Block registerBlock(Block block, Class<? extends ItemBlock> itemclass, String name)
{ {
return registerBlock(block, itemclass, name, new Object[] {}); return registerBlock(block, itemclass, name, new Object[] {});
@ -235,9 +230,10 @@ public class GameRegistry
* @param itemclass The item type to register with it : null registers a block without associated item. * @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). * @param itemCtorArgs Arguments to pass (after the required {@code Block} parameter) to the ItemBlock constructor (optional).
*/ */
@Deprecated
public static Block registerBlock(Block block, Class<? extends ItemBlock> itemclass, Object... itemCtorArgs) public static Block registerBlock(Block block, Class<? extends ItemBlock> itemclass, Object... itemCtorArgs)
{ {
return registerBlock(block, itemclass, block.getRegistryName(), itemCtorArgs); return registerBlock(block, itemclass, block.getRegistryName().toString(), itemCtorArgs);
} }
/** /**
@ -248,6 +244,7 @@ public class GameRegistry
* @param name The mod-unique name to register it as, will get prefixed by your modid. * @param name The mod-unique name to register it as, will get prefixed by your modid.
* @param itemCtorArgs Arguments to pass (after the required {@code Block} parameter) to the ItemBlock constructor (optional). * @param itemCtorArgs Arguments to pass (after the required {@code Block} parameter) to the ItemBlock constructor (optional).
*/ */
@Deprecated
public static Block registerBlock(Block block, Class<? extends ItemBlock> itemclass, String name, Object... itemCtorArgs) public static Block registerBlock(Block block, Class<? extends ItemBlock> itemclass, String name, Object... itemCtorArgs)
{ {
if (Strings.isNullOrEmpty(name)) if (Strings.isNullOrEmpty(name))
@ -371,6 +368,7 @@ public class GameRegistry
* @param name The name of the block itself * @param name The name of the block itself
* @return The block or null if not found * @return The block or null if not found
*/ */
@Deprecated
public static Block findBlock(String modId, String name) public static Block findBlock(String modId, String name)
{ {
return GameData.findBlock(modId, name); return GameData.findBlock(modId, name);
@ -383,6 +381,7 @@ public class GameRegistry
* @param name The name of the item itself * @param name The name of the item itself
* @return The item or null if not found * @return The item or null if not found
*/ */
@Deprecated
public static Item findItem(String modId, String name) public static Item findItem(String modId, String name)
{ {
return GameData.findItem(modId, name); return GameData.findItem(modId, name);

View file

@ -0,0 +1,67 @@
package net.minecraftforge.fml.common.registry;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import net.minecraft.util.ResourceLocation;
/**
* Main interface for the registry system. Use this to query the registry system.
*
* @param <V> The top level type for the registry
*/
@SuppressWarnings("WeakerAccess")
public interface IForgeRegistry<V extends IForgeRegistryEntry<V>> extends Iterable<V>
{
public Class<V> getRegistrySuperType();
void register(V value);
boolean containsKey(ResourceLocation key);
boolean containsValue(V value);
V getValue(ResourceLocation key);
ResourceLocation getKey(V value);
Set<ResourceLocation> getKeys();
List<V> getValues();
Set<Entry<ResourceLocation, V>> getEntries();
/**
* Retrieve the slave map of type T from the registry.
* Slave maps are maps which are dependent on registry content in some way.
* @param slaveMapName The name of the slavemap
* @param type The type
* @param <T> Type to return
* @return The slavemap if present
*/
<T> T getSlaveMap(ResourceLocation slaveMapName, Class<T> type);
/**
* Callback fired when objects are added to the registry. This will fire when the registry is rebuilt
* on the client side from a server side synchronization, or when a world is loaded.
*/
interface AddCallback<V>
{
void onAdd(V obj, int id, Map<ResourceLocation, ?> slaveset);
}
/**
* Callback fired when the registry is cleared. This is done before a registry is reloaded from client
* or server.
*/
interface ClearCallback<V>
{
void onClear(Map<ResourceLocation, ?> slaveset);
}
/**
* Callback fired when a registry instance is created. Populate slave maps here.
*/
interface CreateCallback<V>
{
void onCreate(Map<ResourceLocation, ?> slaveset);
}
}

View file

@ -0,0 +1,83 @@
package net.minecraftforge.fml.common.registry;
import com.google.common.reflect.TypeToken;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.FMLContainer;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.InjectedModContainer;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.ModContainer;
public interface IForgeRegistryEntry<V>
{
/**
* 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
*/
V setRegistryName(ResourceLocation name);
/**
* A unique identifier for this entry, if this entry is registered already it will return it's official registry name.
* Otherwise it will return the name set in setRegistryName().
* If neither are valid null is returned.
*
* @return Unique identifier or null.
*/
ResourceLocation getRegistryName();
Class<? super V> getRegistryType();
// Default implementation, modders who make extra items SHOULD extend this instead of Object.
// We have to do this until we get default implementations in Java 8.
@SuppressWarnings({ "serial", "unchecked" })
public static class Impl<T extends IForgeRegistryEntry<T>> implements IForgeRegistryEntry<T>
{
private TypeToken<T> token = new TypeToken<T>(getClass()){};
public final RegistryDelegate<T> delegate = PersistentRegistryManager.makeDelegate((T)this, (Class<T>)token.getRawType());
private ResourceLocation registryName = null;
public final T setRegistryName(String name)
{
if (getRegistryName() != null)
throw new IllegalStateException("Attempted to set registry name with existing 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);
ModContainer mc = Loader.instance().activeModContainer();
String prefix = mc == null || (mc instanceof InjectedModContainer && ((InjectedModContainer)mc).wrappedContainer instanceof FMLContainer) ? "minecraft" : mc.getModId();
if (!oldPrefix.equals(prefix) && oldPrefix.length() > 0)
{
FMLLog.bigWarning("Dangerous alternative prefix %s for name %s, invalid registry invocation/invalid name?", oldPrefix, name);
prefix = oldPrefix;
}
this.registryName = new ResourceLocation(prefix, name);
return (T)this;
}
//Helper functions
public final T setRegistryName(ResourceLocation name){ return setRegistryName(name.toString()); }
public final T setRegistryName(String modID, String name){ return setRegistryName(modID + ":" + name); }
public final ResourceLocation getRegistryName()
{
if (delegate.name() != null) return delegate.name();
return registryName != null ? registryName : null;
}
@Override
public final Class<? super T> getRegistryType() { return token.getRawType(); };
}
}

View file

@ -39,22 +39,29 @@ import com.google.common.collect.Sets.SetView;
* *
* @author cpw * @author cpw
*/ */
@SuppressWarnings("WeakerAccess")
public class PersistentRegistryManager public class PersistentRegistryManager
{ {
private enum PersistentRegistry private enum PersistentRegistry
{ {
ACTIVE, FROZEN, STAGING; ACTIVE, VANILLA, FROZEN, STAGING;
private final BiMap<ResourceLocation, FMLControlledNamespacedRegistry<?>> registries = HashBiMap.create(); private final BiMap<ResourceLocation, FMLControlledNamespacedRegistry<?>> registries = HashBiMap.create();
private final BiMap<Class<?>, ResourceLocation> registrySuperTypes = HashBiMap.create(); private final BiMap<Class<? extends IForgeRegistryEntry<?>>, ResourceLocation> registrySuperTypes = HashBiMap.create();
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
<T> FMLControlledNamespacedRegistry<T> getRegistry(ResourceLocation key, Class<T> regType) private <T extends IForgeRegistryEntry<T>> Class<T> getRegistrySuperType(ResourceLocation key)
{
return (Class<T>)registrySuperTypes.inverse().get(key);
}
@SuppressWarnings("unchecked")
private <T extends IForgeRegistryEntry<T>> FMLControlledNamespacedRegistry<T> getRegistry(ResourceLocation key, @SuppressWarnings("UnusedParameters") Class<T> regType)
{ {
return (FMLControlledNamespacedRegistry<T>)registries.get(key); return (FMLControlledNamespacedRegistry<T>)registries.get(key);
} }
<T> FMLControlledNamespacedRegistry<T> getOrShallowCopyRegistry(ResourceLocation key, Class<T> regType, FMLControlledNamespacedRegistry<T> other) private <T extends IForgeRegistryEntry<T>> FMLControlledNamespacedRegistry<T> getOrShallowCopyRegistry(ResourceLocation key, Class<T> regType, FMLControlledNamespacedRegistry<T> other)
{ {
if (!registries.containsKey(key)) if (!registries.containsKey(key))
{ {
@ -64,12 +71,7 @@ public class PersistentRegistryManager
return getRegistry(key, regType); return getRegistry(key, regType);
} }
private <T> FMLControlledNamespacedRegistry<T> createRegistry(ResourceLocation registryName, Class<T> registryType, ResourceLocation optionalDefaultKey, int minId, int maxId, boolean hasDelegates) private <T extends IForgeRegistryEntry<T>> FMLControlledNamespacedRegistry<T> createRegistry(ResourceLocation registryName, Class<T> type, ResourceLocation defaultObjectKey, int minId, int maxId, IForgeRegistry.AddCallback<T> addCallback, IForgeRegistry.ClearCallback<T> clearCallback, IForgeRegistry.CreateCallback<T> createCallback)
{
return this.createRegistry(registryName, registryType, optionalDefaultKey, minId, maxId, hasDelegates, null);
}
private <T> FMLControlledNamespacedRegistry<T> createRegistry(ResourceLocation registryName, Class<T> type, ResourceLocation defaultObjectKey, int minId, int maxId, boolean isDelegated, FMLControlledNamespacedRegistry.AddCallback<T> addCallback)
{ {
Set<Class<?>> parents = Sets.newHashSet(); Set<Class<?>> parents = Sets.newHashSet();
findSuperTypes(type, parents); findSuperTypes(type, parents);
@ -80,7 +82,7 @@ public class PersistentRegistryManager
FMLLog.severe("Found existing registry of type %1s named %2s, you cannot create a new registry (%3s) with type %4s, as %4s has a parent of that type", foundType, registrySuperTypes.get(foundType), registryName, type); FMLLog.severe("Found existing registry of type %1s named %2s, you cannot create a new registry (%3s) with type %4s, as %4s has a parent of that type", foundType, registrySuperTypes.get(foundType), registryName, type);
throw new IllegalArgumentException("Duplicate registry parent type found - you can only have one registry for a particular super type"); throw new IllegalArgumentException("Duplicate registry parent type found - you can only have one registry for a particular super type");
} }
FMLControlledNamespacedRegistry<T> fmlControlledNamespacedRegistry = new FMLControlledNamespacedRegistry<T>(defaultObjectKey, maxId, minId, type, isDelegated, addCallback); FMLControlledNamespacedRegistry<T> fmlControlledNamespacedRegistry = new FMLControlledNamespacedRegistry<T>(defaultObjectKey, minId, maxId, type, addCallback, clearCallback, createCallback);
registries.put(registryName, fmlControlledNamespacedRegistry); registries.put(registryName, fmlControlledNamespacedRegistry);
registrySuperTypes.put(type, registryName); registrySuperTypes.put(type, registryName);
return getRegistry(registryName, type); return getRegistry(registryName, type);
@ -117,7 +119,7 @@ public class PersistentRegistryManager
return registries.containsValue(registry); return registries.containsValue(registry);
} }
public <T> FMLControlledNamespacedRegistry<T> getRegistry(Class<T> rootClass) public <T extends IForgeRegistryEntry<T>> FMLControlledNamespacedRegistry<T> getRegistry(Class<T> rootClass)
{ {
ResourceLocation rl = registrySuperTypes.get(rootClass); ResourceLocation rl = registrySuperTypes.get(rootClass);
return getRegistry(rl, rootClass); return getRegistry(rl, rootClass);
@ -129,16 +131,25 @@ public class PersistentRegistryManager
public static final ResourceLocation POTIONS = new ResourceLocation("minecraft:potions"); public static final ResourceLocation POTIONS = new ResourceLocation("minecraft:potions");
public static final ResourceLocation BIOMES = new ResourceLocation("minecraft:biomes"); public static final ResourceLocation BIOMES = new ResourceLocation("minecraft:biomes");
public static <T> FMLControlledNamespacedRegistry<T> createRegistry(ResourceLocation registryName, Class<T> registryType, ResourceLocation optionalDefaultKey, int maxId, int minId, boolean hasDelegates, FMLControlledNamespacedRegistry.AddCallback<T> addCallback) public static <T extends IForgeRegistryEntry<T>> FMLControlledNamespacedRegistry<T> createRegistry(ResourceLocation registryName, Class<T> registryType, ResourceLocation optionalDefaultKey, int minId, int maxId, boolean hasDelegates, IForgeRegistry.AddCallback<T> addCallback, IForgeRegistry.ClearCallback<T> clearCallback, IForgeRegistry.CreateCallback<T> createCallback)
{ {
return PersistentRegistry.ACTIVE.createRegistry(registryName, registryType, optionalDefaultKey, minId, maxId, hasDelegates, addCallback); return PersistentRegistry.ACTIVE.createRegistry(registryName, registryType, optionalDefaultKey, minId, maxId, addCallback, clearCallback, createCallback);
} }
public static <T> FMLControlledNamespacedRegistry<T> createRegistry(ResourceLocation registryName, Class<T> registryType, ResourceLocation optionalDefaultKey, int maxId, int minId, boolean hasDelegates) @SuppressWarnings("unchecked")
static <V extends IForgeRegistryEntry<V>> IForgeRegistry<V> findRegistry(IForgeRegistryEntry<?> entry)
{ {
return PersistentRegistry.ACTIVE.createRegistry(registryName, registryType, optionalDefaultKey, minId, maxId, hasDelegates); final Class<V> registryType = (Class<V>)entry.getRegistryType();
final FMLControlledNamespacedRegistry<V> registry = PersistentRegistry.ACTIVE.getRegistry(registryType);
if (registry == null)
{
FMLLog.getLogger().log(Level.ERROR, "Unable to locate registry for registered object of type {}", entry.getClass().getName());
throw new IllegalArgumentException("Unable to locate registry for registered object");
}
return registry;
} }
public static List<String> injectSnapshot(GameDataSnapshot snapshot, boolean injectFrozenData, boolean isLocalWorld) public static List<String> injectSnapshot(GameDataSnapshot snapshot, boolean injectFrozenData, boolean isLocalWorld)
{ {
FMLLog.info("Injecting existing block and item data into this %s instance", FMLCommonHandler.instance().getEffectiveSide().isServer() ? "server" : "client"); FMLLog.info("Injecting existing block and item data into this %s instance", FMLCommonHandler.instance().getEffectiveSide().isServer() ? "server" : "client");
@ -149,13 +160,11 @@ public class PersistentRegistryManager
forAllRegistries(PersistentRegistry.ACTIVE, DumpRegistryFunction.OPERATION); forAllRegistries(PersistentRegistry.ACTIVE, DumpRegistryFunction.OPERATION);
forAllRegistries(PersistentRegistry.ACTIVE, ResetDelegatesFunction.OPERATION); forAllRegistries(PersistentRegistry.ACTIVE, ResetDelegatesFunction.OPERATION);
// Empty the blockstate map before loading
GameData.getBlockStateIDMap().clear();
// Load the snapshot into the "STAGING" registry // Load the snapshot into the "STAGING" registry
for (Map.Entry<ResourceLocation, GameDataSnapshot.Entry> snapshotEntry : snapshot.entries.entrySet()) for (Map.Entry<ResourceLocation, GameDataSnapshot.Entry> snapshotEntry : snapshot.entries.entrySet())
{ {
loadPersistentDataToStagingRegistry(injectFrozenData, remaps, missing, snapshotEntry, PersistentRegistry.ACTIVE.registrySuperTypes.inverse().get(snapshotEntry.getKey())); final Class<? extends IForgeRegistryEntry> registrySuperType = PersistentRegistry.ACTIVE.getRegistrySuperType(snapshotEntry.getKey());
loadPersistentDataToStagingRegistry(injectFrozenData, remaps, missing, snapshotEntry, registrySuperType);
} }
// Handle dummied blocks // Handle dummied blocks
@ -213,7 +222,8 @@ public class PersistentRegistryManager
// So we load it from the frozen persistent registry // So we load it from the frozen persistent registry
for (Map.Entry<ResourceLocation, FMLControlledNamespacedRegistry<?>> r : PersistentRegistry.ACTIVE.registries.entrySet()) for (Map.Entry<ResourceLocation, FMLControlledNamespacedRegistry<?>> r : PersistentRegistry.ACTIVE.registries.entrySet())
{ {
loadFrozenDataToStagingRegistry(remaps, r.getKey(), PersistentRegistry.ACTIVE.registrySuperTypes.inverse().get(r.getKey())); final Class<? extends IForgeRegistryEntry> registrySuperType = PersistentRegistry.ACTIVE.getRegistrySuperType(r.getKey());
loadFrozenDataToStagingRegistry(remaps, r.getKey(), registrySuperType);
} }
} }
@ -223,7 +233,8 @@ public class PersistentRegistryManager
// Load the STAGING registry into the ACTIVE registry // Load the STAGING registry into the ACTIVE registry
for (Map.Entry<ResourceLocation, FMLControlledNamespacedRegistry<?>> r : PersistentRegistry.ACTIVE.registries.entrySet()) for (Map.Entry<ResourceLocation, FMLControlledNamespacedRegistry<?>> r : PersistentRegistry.ACTIVE.registries.entrySet())
{ {
loadRegistry(r.getKey(), PersistentRegistry.STAGING, PersistentRegistry.ACTIVE, PersistentRegistry.ACTIVE.registrySuperTypes.inverse().get(r.getKey())); final Class<? extends IForgeRegistryEntry> registrySuperType = PersistentRegistry.ACTIVE.getRegistrySuperType(r.getKey());
loadRegistry(r.getKey(), PersistentRegistry.STAGING, PersistentRegistry.ACTIVE, registrySuperType);
} }
// Dump the active registry // Dump the active registry
@ -254,7 +265,7 @@ public class PersistentRegistryManager
} }
} }
private static <T> void loadRegistry(final ResourceLocation registryName, final PersistentRegistry from, final PersistentRegistry to, Class<T> regType) private static <T extends IForgeRegistryEntry<T>> void loadRegistry(final ResourceLocation registryName, final PersistentRegistry from, final PersistentRegistry to, final Class<T> regType)
{ {
FMLControlledNamespacedRegistry<T> fromRegistry = from.getRegistry(registryName, regType); FMLControlledNamespacedRegistry<T> fromRegistry = from.getRegistry(registryName, regType);
if (fromRegistry == null) if (fromRegistry == null)
@ -290,14 +301,14 @@ public class PersistentRegistryManager
} }
} }
private static <T> void loadFrozenDataToStagingRegistry(Map<ResourceLocation, Map<ResourceLocation, Integer[]>> remaps, ResourceLocation registryName, Class<T> regType) private static <T extends IForgeRegistryEntry<T>> void loadFrozenDataToStagingRegistry(Map<ResourceLocation, Map<ResourceLocation, Integer[]>> remaps, ResourceLocation registryName, Class<T> regType)
{ {
FMLControlledNamespacedRegistry<T> frozenRegistry = PersistentRegistry.FROZEN.getRegistry(registryName, regType); FMLControlledNamespacedRegistry<T> frozenRegistry = PersistentRegistry.FROZEN.getRegistry(registryName, regType);
FMLControlledNamespacedRegistry<T> newRegistry = PersistentRegistry.STAGING.getOrShallowCopyRegistry(registryName, regType, frozenRegistry); FMLControlledNamespacedRegistry<T> newRegistry = PersistentRegistry.STAGING.getOrShallowCopyRegistry(registryName, regType, frozenRegistry);
newRegistry.loadIds(frozenRegistry.getEntriesNotIn(newRegistry), Maps.<ResourceLocation, Integer>newLinkedHashMap(), remaps.get(registryName), frozenRegistry, registryName); newRegistry.loadIds(frozenRegistry.getEntriesNotIn(newRegistry), Maps.<ResourceLocation, Integer>newLinkedHashMap(), remaps.get(registryName), frozenRegistry, registryName);
} }
private static <T> void loadPersistentDataToStagingRegistry(boolean injectFrozenData, Map<ResourceLocation, Map<ResourceLocation, Integer[]>> remaps, LinkedHashMap<ResourceLocation, Map<ResourceLocation, Integer>> missing, Map.Entry<ResourceLocation, GameDataSnapshot.Entry> snapEntry, Class<T> regType) private static <T extends IForgeRegistryEntry<T>> void loadPersistentDataToStagingRegistry(boolean injectFrozenData, Map<ResourceLocation, Map<ResourceLocation, Integer[]>> remaps, LinkedHashMap<ResourceLocation, Map<ResourceLocation, Integer>> missing, Map.Entry<ResourceLocation, GameDataSnapshot.Entry> snapEntry, Class<T> regType)
{ {
ResourceLocation registryName = snapEntry.getKey(); ResourceLocation registryName = snapEntry.getKey();
@ -311,6 +322,7 @@ public class PersistentRegistryManager
{ {
FMLLog.severe("An unknown persistent registry type \"%s\" has been encountered. This Forge instance cannot understand it.", registryName); FMLLog.severe("An unknown persistent registry type \"%s\" has been encountered. This Forge instance cannot understand it.", registryName);
StartupQuery.abort(); StartupQuery.abort();
return; // fake exit to shut up null analysis
} }
FMLControlledNamespacedRegistry<T> newRegistry = PersistentRegistry.STAGING.getOrShallowCopyRegistry(registryName, regType, currentRegistry); FMLControlledNamespacedRegistry<T> newRegistry = PersistentRegistry.STAGING.getOrShallowCopyRegistry(registryName, regType, currentRegistry);
// Copy the persistent substitution set from the currently active one into the new registry // Copy the persistent substitution set from the currently active one into the new registry
@ -350,7 +362,8 @@ public class PersistentRegistryManager
} }
for (Map.Entry<ResourceLocation, FMLControlledNamespacedRegistry<?>> r : PersistentRegistry.ACTIVE.registries.entrySet()) for (Map.Entry<ResourceLocation, FMLControlledNamespacedRegistry<?>> r : PersistentRegistry.ACTIVE.registries.entrySet())
{ {
loadRegistry(r.getKey(), PersistentRegistry.FROZEN, PersistentRegistry.ACTIVE, PersistentRegistry.ACTIVE.registrySuperTypes.inverse().get(r.getKey())); final Class<? extends IForgeRegistryEntry> registrySuperType = PersistentRegistry.ACTIVE.getRegistrySuperType(r.getKey());
loadRegistry(r.getKey(), PersistentRegistry.FROZEN, PersistentRegistry.ACTIVE, registrySuperType);
} }
// the id mapping has reverted, fire remap events for those that care about id changes // the id mapping has reverted, fire remap events for those that care about id changes
Loader.instance().fireRemapEvent(ImmutableMap.<ResourceLocation, Integer[]>of(), ImmutableMap.<ResourceLocation, Integer[]>of(), true); Loader.instance().fireRemapEvent(ImmutableMap.<ResourceLocation, Integer[]>of(), ImmutableMap.<ResourceLocation, Integer[]>of(), true);
@ -365,7 +378,9 @@ public class PersistentRegistryManager
FMLLog.fine("Freezing block and item id maps"); FMLLog.fine("Freezing block and item id maps");
for (Map.Entry<ResourceLocation, FMLControlledNamespacedRegistry<?>> r : PersistentRegistry.ACTIVE.registries.entrySet()) for (Map.Entry<ResourceLocation, FMLControlledNamespacedRegistry<?>> r : PersistentRegistry.ACTIVE.registries.entrySet())
{ {
loadRegistry(r.getKey(), PersistentRegistry.ACTIVE, PersistentRegistry.FROZEN, PersistentRegistry.ACTIVE.registrySuperTypes.inverse().get(r.getKey())); // This has to be performed prior to invoking the method so the compiler can precompute the type bounds for the method
final Class<? extends IForgeRegistryEntry> registrySuperType = PersistentRegistry.ACTIVE.getRegistrySuperType(r.getKey());
loadRegistry(r.getKey(), PersistentRegistry.ACTIVE, PersistentRegistry.FROZEN, registrySuperType);
} }
forAllRegistries(PersistentRegistry.FROZEN, ValidateRegistryFunction.OPERATION); forAllRegistries(PersistentRegistry.FROZEN, ValidateRegistryFunction.OPERATION);
} }
@ -576,7 +591,7 @@ public class PersistentRegistryManager
public final Map<ResourceLocation, Entry> entries = Maps.newHashMap(); public final Map<ResourceLocation, Entry> entries = Maps.newHashMap();
} }
public static <T> RegistryDelegate<T> makeDelegate(T obj, Class<T> rootClass) public static <T extends IForgeRegistryEntry<T>> RegistryDelegate<T> makeDelegate(T obj, Class<T> rootClass)
{ {
return PersistentRegistry.ACTIVE.getRegistry(rootClass).getDelegate(obj, rootClass); return PersistentRegistry.ACTIVE.getRegistry(rootClass).getDelegate(obj, rootClass);
} }
@ -617,4 +632,5 @@ public class PersistentRegistryManager
return null; return null;
} }
} }
} }

View file

@ -23,23 +23,12 @@ public interface RegistryDelegate<T> {
*/ */
T get(); T get();
/**
* Get the name of this delegate. This is completely static after registration has completed and will never change.
*
* Deprecated in favour of the resource location.
*
* @see #getResourceName()
* @return The name
*/
@Deprecated
String name();
/** /**
* Get the unique resource location for this delegate. Completely static after registration has completed, and * Get the unique resource location for this delegate. Completely static after registration has completed, and
* will never change. * will never change.
* @return The name * @return The name
*/ */
ResourceLocation getResourceName(); ResourceLocation name();
/** /**
* Get the delegate type. It will be dependent on the registry this delegate is sourced from. * Get the delegate type. It will be dependent on the registry this delegate is sourced from.
@ -67,12 +56,7 @@ public interface RegistryDelegate<T> {
} }
@Override @Override
public String name() { public ResourceLocation name() { return name; }
return name.toString();
}
@Override
public ResourceLocation getResourceName() { return name; }
@Override @Override
public Class<T> type() public Class<T> type()
@ -85,7 +69,7 @@ public interface RegistryDelegate<T> {
this.referent = newTarget; this.referent = newTarget;
} }
void setResourceName(ResourceLocation name) { this.name = name; } void setName(ResourceLocation name) { this.name = name; }
@Override @Override
public boolean equals(Object obj) public boolean equals(Object obj)

View file

@ -12,8 +12,6 @@
package net.minecraftforge.fml.common.registry; package net.minecraftforge.fml.common.registry;
import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
@ -42,10 +40,6 @@ import net.minecraft.world.gen.structure.StructureComponent;
import net.minecraft.world.gen.structure.StructureVillagePieces; import net.minecraft.world.gen.structure.StructureVillagePieces;
import net.minecraft.world.gen.structure.StructureVillagePieces.PieceWeight; import net.minecraft.world.gen.structure.StructureVillagePieces.PieceWeight;
import net.minecraft.world.gen.structure.StructureVillagePieces.Village; import net.minecraft.world.gen.structure.StructureVillagePieces.Village;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
/** /**
* Registry for villager trading control * Registry for villager trading control
* *
@ -57,9 +51,6 @@ public class VillagerRegistry
private static final VillagerRegistry INSTANCE = new VillagerRegistry(); private static final VillagerRegistry INSTANCE = new VillagerRegistry();
private Map<Class<?>, IVillageCreationHandler> villageCreationHandlers = Maps.newHashMap(); private Map<Class<?>, IVillageCreationHandler> villageCreationHandlers = Maps.newHashMap();
private List<Integer> newVillagerIds = Lists.newArrayList();
@SideOnly(Side.CLIENT)
private Map<Integer, ResourceLocation> newVillagers;
private VillagerRegistry() private VillagerRegistry()
{ {
@ -110,39 +101,6 @@ public class VillagerRegistry
return INSTANCE; return INSTANCE;
} }
/**
* Register your villager id
*
* @param id
*/
@Deprecated // Doesn't work at all.
public void registerVillagerId(int id)
{
if (newVillagerIds.contains(id))
{
FMLLog.severe("Attempt to register duplicate villager id %d", id);
throw new RuntimeException();
}
newVillagerIds.add(id);
}
/**
* Register a new skin for a villager type
*
* @param villagerId
* @param villagerSkin
*/
@SideOnly(Side.CLIENT)
@Deprecated // Doesn't work at all.
public void registerVillagerSkin(int villagerId, ResourceLocation villagerSkin)
{
if (newVillagers == null)
{
newVillagers = Maps.newHashMap();
}
newVillagers.put(villagerId, villagerSkin);
}
/** /**
* Register a new village creation handler * Register a new village creation handler
* *
@ -153,34 +111,6 @@ public class VillagerRegistry
villageCreationHandlers.put(handler.getComponentClass(), handler); villageCreationHandlers.put(handler.getComponentClass(), handler);
} }
/**
* Callback to setup new villager types
*
* @param villagerType
* @param defaultSkin
*/
@SideOnly(Side.CLIENT)
@Deprecated // Doesn't work at all.
public static ResourceLocation getVillagerSkin(int villagerType, ResourceLocation defaultSkin)
{
if (instance().newVillagers != null && instance().newVillagers.containsKey(villagerType))
{
return instance().newVillagers.get(villagerType);
}
return defaultSkin;
}
/**
* Returns a list of all added villager types
*
* @return newVillagerIds
*/
@Deprecated // Doesn't work at all.
public static Collection<Integer> getRegisteredVillagers()
{
return Collections.unmodifiableCollection(instance().newVillagerIds);
}
public static void addExtraVillageComponents(List<PieceWeight> list, Random random, int i) public static void addExtraVillageComponents(List<PieceWeight> list, Random random, int i)
{ {
List<StructureVillagePieces.PieceWeight> parts = list; List<StructureVillagePieces.PieceWeight> parts = list;
@ -207,7 +137,8 @@ public class VillagerRegistry
} }
private boolean hasInit = false; private boolean hasInit = false;
private FMLControlledNamespacedRegistry<VillagerProfession> professions = PersistentRegistryManager.createRegistry(PROFESSIONS, VillagerProfession.class, null, 1024, 0, true, null); private FMLControlledNamespacedRegistry<VillagerProfession> professions = PersistentRegistryManager.createRegistry(PROFESSIONS, VillagerProfession.class, null, 0, 1024, true, null, null, null);
public IForgeRegistry<VillagerProfession> getRegistry() { return this.professions; }
private void init() private void init()
@ -250,18 +181,17 @@ public class VillagerRegistry
} }
} }
public static class VillagerProfession public static class VillagerProfession extends IForgeRegistryEntry.Impl<VillagerProfession>
{ {
private ResourceLocation name; private ResourceLocation name;
private ResourceLocation texture; private ResourceLocation texture;
private List<VillagerCareer> careers = Lists.newArrayList(); private List<VillagerCareer> careers = Lists.newArrayList();
public final RegistryDelegate<VillagerProfession> delegate = PersistentRegistryManager.makeDelegate(this, VillagerProfession.class);
public VillagerProfession(String name, String texture) public VillagerProfession(String name, String texture)
{ {
this.name = new ResourceLocation(name); this.name = new ResourceLocation(name);
this.texture = new ResourceLocation(texture); this.texture = new ResourceLocation(texture);
((RegistryDelegate.Delegate<VillagerProfession>)delegate).setResourceName(this.name); this.setRegistryName(this.name);
} }
private void register(VillagerCareer career) private void register(VillagerCareer career)
@ -271,6 +201,22 @@ public class VillagerRegistry
career.id = careers.size(); career.id = careers.size();
careers.add(career); careers.add(career);
} }
public ResourceLocation getSkin() { return this.texture; }
public VillagerCareer getCareer(int id)
{
for (VillagerCareer car : this.careers)
{
if (car.id == id)
return car;
}
return this.careers.get(0);
}
public int getRandomCareer(Random rand)
{
return this.careers.get(rand.nextInt(this.careers.size())).id;
}
} }
public static class VillagerCareer public static class VillagerCareer
@ -278,6 +224,7 @@ public class VillagerRegistry
private VillagerProfession profession; private VillagerProfession profession;
private String name; private String name;
private int id; private int id;
private ITradeList[][] trades;
public VillagerCareer(VillagerProfession parent, String name) public VillagerCareer(VillagerProfession parent, String name)
{ {
@ -286,8 +233,19 @@ public class VillagerRegistry
parent.register(this); parent.register(this);
} }
private VillagerCareer init(EntityVillager.ITradeList[][] traids) public String getName()
{ {
return this.name;
}
public ITradeList[][] getTrades()
{
return this.trades;
}
private VillagerCareer init(EntityVillager.ITradeList[][] trades)
{
this.trades = trades;
return this; return this;
} }
@ -316,9 +274,7 @@ public class VillagerRegistry
public static void setRandomProfession(EntityVillager entity, Random rand) public static void setRandomProfession(EntityVillager entity, Random rand)
{ {
Set<ResourceLocation> entries = INSTANCE.professions.getKeys(); Set<ResourceLocation> entries = INSTANCE.professions.getKeys();
int prof = rand.nextInt(entries.size()); entity.setProfession(rand.nextInt(entries.size()));
//TODO: Grab id range from internal registry
entity.setProfession(rand.nextInt(5));
} }
//TODO: Figure out a good generic system for this. Put on hold for Patches. //TODO: Figure out a good generic system for this. Put on hold for Patches.

View file

@ -326,7 +326,7 @@ public class OreDictionary
// HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not aware of the item yet // HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not aware of the item yet
// IT should be noted that -1 will fail the gate further down, if an entry already exists with value -1 for this name. This is what is broken and being warned about. // IT should be noted that -1 will fail the gate further down, if an entry already exists with value -1 for this name. This is what is broken and being warned about.
// APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes - you can't make them properly until you've registered with the game. // APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes - you can't make them properly until you've registered with the game.
ResourceLocation registryName = stack.getItem().delegate.getResourceName(); ResourceLocation registryName = stack.getItem().delegate.name();
int id; int id;
if (registryName == null) if (registryName == null)
{ {
@ -488,7 +488,7 @@ public class OreDictionary
// HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not aware of the item yet // HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not aware of the item yet
// IT should be noted that -1 will fail the gate further down, if an entry already exists with value -1 for this name. This is what is broken and being warned about. // IT should be noted that -1 will fail the gate further down, if an entry already exists with value -1 for this name. This is what is broken and being warned about.
// APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes - you can't make them properly until you've registered with the game. // APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes - you can't make them properly until you've registered with the game.
ResourceLocation registryName = ore.getItem().delegate.getResourceName(); ResourceLocation registryName = ore.getItem().delegate.name();
int hash; int hash;
if (registryName == null) if (registryName == null)
{ {
@ -555,7 +555,7 @@ public class OreDictionary
for (ItemStack ore : ores) for (ItemStack ore : ores)
{ {
// HACK: use the registry name's ID. It is unique and it knows about substitutions // HACK: use the registry name's ID. It is unique and it knows about substitutions
ResourceLocation name = ore.getItem().delegate.getResourceName(); ResourceLocation name = ore.getItem().delegate.name();
int hash; int hash;
if (name == null) if (name == null)
{ {