Add a PotionRegistry to handle dynamic distribution and remapping of Potion IDs

This commit is contained in:
Bernhard Bonigl 2015-11-29 22:02:55 +01:00
parent a13ed35031
commit 57d1a657a0
6 changed files with 176 additions and 1 deletions

View file

@ -1,6 +1,47 @@
--- ../src-base/minecraft/net/minecraft/potion/Potion.java
+++ ../src-work/minecraft/net/minecraft/potion/Potion.java
@@ -310,4 +310,27 @@
@@ -21,7 +21,7 @@
public class Potion
{
- public static final Potion[] field_76425_a = new Potion[32];
+ public static final Potion[] field_76425_a = new Potion[256];
private static final Map<ResourceLocation, Potion> field_180150_I = Maps.<ResourceLocation, Potion>newHashMap();
public static final Potion field_180151_b = null;
public static final Potion field_76424_c = (new Potion(1, new ResourceLocation("speed"), false, 8171462)).func_76390_b("potion.moveSpeed").func_76399_b(0, 0).func_111184_a(SharedMonsterAttributes.field_111263_d, "91AEAA56-376B-4498-935B-2F7F68070635", 0.20000000298023224D, 2);
@@ -64,8 +64,10 @@
private double field_76412_L;
private boolean field_76413_M;
+ @Deprecated // use the Constructor without potion ID or everything will explode.
protected Potion(int p_i45897_1_, ResourceLocation p_i45897_2_, boolean p_i45897_3_, int p_i45897_4_)
{
+ p_i45897_1_ = net.minecraftforge.fml.common.registry.GameRegistry.registerPotion(this, p_i45897_2_, p_i45897_1_);
this.field_76415_H = p_i45897_1_;
field_76425_a[p_i45897_1_] = this;
field_180150_I.put(p_i45897_2_, this);
@@ -83,14 +85,18 @@
this.field_76414_N = p_i45897_4_;
}
+ protected Potion(ResourceLocation location, boolean badEffect, int potionColor) {
+ this(-1, location, badEffect, potionColor);
+ }
+
public static Potion func_180142_b(String p_180142_0_)
{
- return (Potion)field_180150_I.get(new ResourceLocation(p_180142_0_));
+ return net.minecraftforge.fml.common.registry.GameData.getPotionRegistry().func_82594_a(new ResourceLocation(p_180142_0_));
}
public static Set<ResourceLocation> func_181168_c()
{
- return field_180150_I.keySet();
+ return net.minecraftforge.fml.common.registry.GameData.getPotionRegistry().func_148742_b();
}
protected Potion func_76399_b(int p_76399_1_, int p_76399_2_)
@@ -310,4 +316,27 @@
{
return p_111183_2_.func_111164_d() * (double)(p_111183_1_ + 1);
}

View file

@ -19,6 +19,7 @@ import com.google.common.collect.Maps;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.Item;
import net.minecraft.potion.Potion;
import net.minecraft.util.ObjectIntIdentityMap;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.FMLLog;
@ -31,6 +32,8 @@ public class GameData
static final int MAX_BLOCK_ID = 4095;
static final int MIN_ITEM_ID = 4096;
static final int MAX_ITEM_ID = 31999;
public static final int MIN_POTION_ID = 32; // 0-31 are vanilla, forge start at 32
public static final int MAX_POTION_ID = 255; // S1DPacketEntityEffect sends bytes, we can only use 255
private static final GameData mainData = new GameData();
// public api
@ -55,6 +58,16 @@ public class GameData
return getMain().iItemRegistry;
}
/**
* Get the currently active potion registry.
*
* @return Potion Registry.
*/
public static FMLControlledNamespacedRegistry<Potion> getPotionRegistry() {
return getMain().iPotionRegistry;
}
/***************************************************
* INTERNAL CODE FROM HERE ON DO NOT USE!
***************************************************/
@ -98,6 +111,7 @@ public class GameData
// 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<Item> iItemRegistry = PersistentRegistryManager.createRegistry(PersistentRegistryManager.ITEMS, Item.class, null, MAX_ITEM_ID, MIN_ITEM_ID, true);
private final FMLControlledNamespacedRegistry<Potion> iPotionRegistry = PersistentRegistryManager.createRegistry(PersistentRegistryManager.POTIONS, Potion.class, null, MAX_POTION_ID, MIN_POTION_ID, false, PotionArrayCapture.INSTANCE);
int registerItem(Item item, String name) // from GameRegistry
{
@ -133,6 +147,13 @@ public class GameData
return iBlockRegistry.add(idHint, name, block);
}
/**
* Called from GameRegistry, which is called from Potion-Constructor
*/
int registerPotion(Potion potion, ResourceLocation name, int id) {
return iPotionRegistry.add(id, name, potion);
}
/**
* Prefix the supplied name with the current mod id.
* <p/>
@ -228,4 +249,16 @@ public class GameData
}
}
}
private static class PotionArrayCapture implements FMLControlledNamespacedRegistry.AddCallback<Potion>
{
static final PotionArrayCapture INSTANCE = new PotionArrayCapture();
@Override
public void onAdd(Potion potion, int id) {
// fix the data in the potion and the potions-array
potion.id = id;
Potion.potionTypes[id] = potion;
}
}
}

View file

@ -47,6 +47,7 @@ import net.minecraft.nbt.JsonToNBT;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTException;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.Potion;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
@ -235,6 +236,11 @@ public class GameRegistry
}
}
/** Called from Potion Constructor */
public static int registerPotion(Potion potion, ResourceLocation name, int potionID) {
return GameData.getMain().registerPotion(potion, name, potionID);
}
public static void addRecipe(ItemStack output, Object... params)
{
addShapedRecipe(output, params);

View file

@ -1,6 +1,7 @@
package net.minecraftforge.fml.common.registry;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@ -20,6 +21,7 @@ import com.google.common.collect.Sets.SetView;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.potion.Potion;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.FMLLog;
@ -122,6 +124,7 @@ public class PersistentRegistryManager
public static final ResourceLocation BLOCKS = new ResourceLocation("minecraft:blocks");
public static final ResourceLocation ITEMS = new ResourceLocation("minecraft:items");
public static final ResourceLocation POTIONS = new ResourceLocation("minecraft:potions");
public static <T> FMLControlledNamespacedRegistry<T> createRegistry(ResourceLocation registryName, Class<T> registryType, ResourceLocation optionalDefaultKey, int maxId, int minId, boolean hasDelegates, FMLControlledNamespacedRegistry.AddCallback<T> addCallback)
{
@ -145,6 +148,8 @@ public class PersistentRegistryManager
// Empty the blockstate map before loading
GameData.getBlockStateIDMap().clear();
// Clean up potion array before reloading it from the snapshot
Arrays.fill(Potion.potionTypes, null);
// Load the snapshot into the "STAGING" registry
for (Map.Entry<ResourceLocation, GameDataSnapshot.Entry> snapshotEntry : snapshot.entries.entrySet())

View file

@ -25,6 +25,8 @@ public net.minecraft.block.BlockFire func_176534_d(Lnet/minecraft/block/Block;)I
public net.minecraft.item.Item func_77656_e(I)Lnet.minecraft.item.Item; #setMaxDamage
public net.minecraft.item.Item func_77627_a(Z)Lnet.minecraft.item.Item; #setHasSubtypes
public net.minecraft.item.Item func_77631_c(Ljava.lang.String;)Lnet.minecraft.item.Item; #setPotionEffect
# Potion
public-f net.minecraft.potion.Potion field_76415_H #id
# EntityPlayer
public net.minecraft.entity.player.EntityPlayer func_71012_a(Lnet/minecraft/entity/item/EntityItem;)V #joinEntityItemWithWorld
public net.minecraft.client.entity.EntityPlayerSP func_71012_a(Lnet/minecraft/entity/item/EntityItem;)V #joinEntityItemWithWorld

View file

@ -0,0 +1,88 @@
package net.minecraftforge.debug;
import gnu.trove.set.TIntSet;
import gnu.trove.set.hash.TIntHashSet;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import java.util.Random;
@Mod(modid=PotionRegistryDebug.MODID)
public class PotionRegistryDebug {
public static final String MODID = "ForgePotionRegistry";
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
new PotionForge(new ResourceLocation("forge", "forge"), false, 0xff00ff); // test automatic id distribution
new PotionForge(200, new ResourceLocation("forge", "forgy"), true, 0x00ff00); // test that ids above 127 work
Random rand = new Random();
TIntSet taken = new TIntHashSet(100);
int ra = rand.nextInt(100) + 100;
taken.add(ra);
// a new potion with a random id so that forge has to remap it
new PotionForge(ra, new ResourceLocation("forge", "realRandomPotion"), false, 0x0000ff);
for(int i = 0; i < 20; i++) {
int r = rand.nextInt(200) + 35;
while(taken.contains(r))
r = rand.nextInt(200) + 35;
//r = 32+i;
taken.add(r);
// this potions will most likely not have the same IDs between server and client.
// The forge handshake on connect should fix this.
new PotionForge(r, new ResourceLocation("forge", "randomPotion" + r), false, 0xff00ff);
}
}
protected class PotionForge extends Potion {
public PotionForge(int potionID, ResourceLocation location, boolean badEffect, int potionColor) {
super(potionID, location, badEffect, potionColor);
setPotionName("potion." + location.getResourcePath());
}
protected PotionForge(ResourceLocation location, boolean badEffect, int potionColor) {
super(location, badEffect, potionColor);
setPotionName("potion." + location.getResourcePath());
}
@Override
public void renderInventoryEffect(int x, int y, PotionEffect effect, Minecraft mc) {
Potion potion = Potion.potionTypes[effect.getPotionID()];
mc.getTextureManager().bindTexture(TextureMap.locationBlocksTexture);
TextureAtlasSprite sprite = mc.getTextureMapBlocks().getAtlasSprite("minecraft:blocks/fire_layer_0");
x += 6;
y += 7;
int width = 18;
int height = width;
/*
Tessellator tessellator = Tessellator.getInstance();
WorldRenderer worldrenderer = tessellator.getWorldRenderer();
worldrenderer.startDrawingQuads();
worldrenderer.setColorOpaque_I(potion.getLiquidColor());
worldrenderer.addVertexWithUV((double) x, (double) (y + height), 0.0D, sprite.getMinU(), sprite.getMaxV());
worldrenderer.addVertexWithUV((double)(x + width), (double)(y + height), 0.0D, sprite.getMaxU(), sprite.getMaxV());
worldrenderer.addVertexWithUV((double)(x + width), (double)y, 0.0D, sprite.getMaxU(), sprite.getMinV());
worldrenderer.addVertexWithUV((double)x, (double)y, 0.0D, sprite.getMinU(), sprite.getMinV());
tessellator.draw();*/
}
}
}