Refactored a bit of the TileEntity code so that ANY block may now have a tile entity.

This is to allow modders the ability to extend blocks other then BlockContainer, and still be able to have a TileEntity.

Also added a NBTTagCompound to the base EntityClass, this allows any entity to be given arbitrary data that will persist across world saves.
This data is NOT sent over the wire in a MP situation, to have data sent over the wire automatically use the built in data watcher.
This commit is contained in:
LexManos 2012-01-01 07:42:21 +00:00
parent dda9f474af
commit e26f1ab671
9 changed files with 354 additions and 35 deletions

View file

@ -130,7 +130,16 @@
}
}
@@ -805,6 +848,200 @@
@@ -726,7 +769,7 @@
{
entityplayer.addStat(StatList.mineBlockStatArray[blockID], 1);
entityplayer.addExhaustion(0.025F);
- if(renderAsNormalBlock() && !isBlockContainer[blockID] && EnchantmentHelper.getSilkTouchModifier(entityplayer.inventory))
+ if(renderAsNormalBlock() && !hasTileEntity(l) && EnchantmentHelper.getSilkTouchModifier(entityplayer.inventory))
{
ItemStack itemstack = func_41049_c_(l);
if(itemstack != null)
@@ -805,6 +848,238 @@
return iblockaccess.isBlockNormalCube(i, j, k) ? 0.2F : 1.0F;
}
@ -327,6 +336,44 @@
+ blockFlammability[id] = flammability;
+ }
+
+ /**
+ * Called throughout the code as a replacement for block instanceof BlockContainer
+ * Moving this to the Block base class allows for mods that wish to extend vinella
+ * blocks, and also want to have a tile entity on that block, may.
+ *
+ * Return true from this function to specify this block has a tile entity.
+ *
+ * @param metadata Metadata of the current block
+ * @return True if block has a tile entity, false otherwise
+ */
+ public boolean hasTileEntity(int metadata)
+ {
+ if (isBlockContainer[blockID])
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Called throughout the code as a replacement for BlockContainer.getBlockEntity
+ * Return the same thing you would from that function.
+ * This will fall back to BlockContainer.getBlockEntity if this block is a BlockContainer.
+ *
+ * @param metadata The Metadata of the current block
+ * @return A instance of a class extending TileEntity
+ */
+ public TileEntity getTileEntity(int metadata)
+ {
+ if (this instanceof BlockContainer)
+ {
+ return ((BlockContainer)this).getBlockEntity(metadata);
+ }
+ return null;
+ }
+
static Class _mthclass$(String s)
{

View file

@ -0,0 +1,11 @@
--- ../src_base/minecraft/net/minecraft/src/BlockPistonBase.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft/net/minecraft/src/BlockPistonBase.java 0000-00-00 00:00:00.000000000 -0000
@@ -361,7 +361,7 @@
return false;
}
}
- return !(Block.blocksList[i] instanceof BlockContainer);
+ return !(Block.blocksList[i] != null && Block.blocksList[i].hasTileEntity(world.getBlockMetadata(j, k, l)));
}
private static boolean canExtend(World world, int i, int j, int k, int l)

View file

@ -8,16 +8,36 @@
import java.io.PrintStream;
import java.util.*;
@@ -390,7 +391,7 @@
@@ -351,11 +352,12 @@
blocks[i << worldObj.xShift | k << worldObj.heightShift | j] = (byte)(byte0 & 0xff);
if(l1 != 0)
{
+ int meta = getBlockMetadata(i, j, k);
if(!worldObj.multiplayerWorld)
{
Block.blocksList[l1].onBlockRemoval(worldObj, i2, j, j2);
} else
- if(Block.blocksList[l1] instanceof BlockContainer)
+ if(Block.blocksList[l1] != null && Block.blocksList[l1].hasTileEntity(meta))
{
worldObj.removeBlockTileEntity(i2, j, j2);
}
@@ -385,12 +387,12 @@
{
Block.blocksList[l].onBlockAdded(worldObj, i2, j, j2);
}
- if(Block.blocksList[l] instanceof BlockContainer)
+ if(Block.blocksList[l] != null && Block.blocksList[l].hasTileEntity(i1))
{
TileEntity tileentity = getChunkBlockTileEntity(i, j, k);
if(tileentity == null)
{
- tileentity = ((BlockContainer)Block.blocksList[l]).getBlockEntity();
+ tileentity = ((BlockContainer)Block.blocksList[l]).getBlockEntity(i1);
+ tileentity = Block.blocksList[l].getTileEntity(i1);
worldObj.setBlockTileEntity(i, j, k, tileentity);
}
if(tileentity != null)
@@ -398,15 +399,7 @@
@@ -398,15 +400,7 @@
tileentity.updateContainingBlockInfo();
}
}
@ -34,7 +54,7 @@
isModified = true;
return true;
}
@@ -430,7 +423,11 @@
@@ -430,7 +424,11 @@
blocks[i << worldObj.xShift | k << worldObj.heightShift | j] = (byte)(byte0 & 0xff);
if(k1 != 0)
{
@ -47,17 +67,25 @@
}
data.setNibble(i, j, k, 0);
if(Block.lightOpacity[byte0 & 0xff] != 0)
@@ -458,7 +455,7 @@
@@ -453,27 +451,21 @@
{
Block.blocksList[l].onBlockAdded(worldObj, l1, j, i2);
}
- if(l > 0 && (Block.blocksList[l] instanceof BlockContainer))
+ int meta = getBlockMetadata(i, j, k);
+ if(l > 0 && Block.blocksList[l] != null && Block.blocksList[l].hasTileEntity(meta))
{
TileEntity tileentity = getChunkBlockTileEntity(i, j, k);
if(tileentity == null)
{
- tileentity = ((BlockContainer)Block.blocksList[l]).getBlockEntity();
+ tileentity = ((BlockContainer)Block.blocksList[l]).getBlockEntity(0);
+ tileentity = Block.blocksList[l].getTileEntity(meta);
worldObj.setBlockTileEntity(i, j, k, tileentity);
}
if(tileentity != null)
@@ -466,14 +463,6 @@
{
tileentity.updateContainingBlockInfo();
+ tileentity.blockMetadata = meta;
}
}
- } else
@ -71,7 +99,17 @@
}
isModified = true;
return true;
@@ -609,6 +598,11 @@
@@ -494,7 +486,8 @@
}
data.setNibble(i, j, k, l);
int j1 = getBlockID(i, j, k);
- if(j1 > 0 && (Block.blocksList[j1] instanceof BlockContainer))
+
+ if(j1 > 0 && Block.blocksList[j1] != null && Block.blocksList[j1].hasTileEntity(i1))
{
TileEntity tileentity = getChunkBlockTileEntity(i, j, k);
if(tileentity != null)
@@ -609,27 +602,38 @@
{
ChunkPosition chunkposition = new ChunkPosition(i, j, k);
TileEntity tileentity = (TileEntity)chunkTileEntityMap.get(chunkposition);
@ -83,12 +121,16 @@
if(tileentity == null)
{
int l = getBlockID(i, j, k);
@@ -618,18 +612,23 @@
- if(!Block.isBlockContainer[l])
+ int meta = getBlockMetadata(i, j, k);
+ if(Block.blocksList[l] == null || !Block.blocksList[l].hasTileEntity(meta))
{
return null;
}
if(tileentity == null)
{
- tileentity = ((BlockContainer)Block.blocksList[l]).getBlockEntity();
+ tileentity = ((BlockContainer)Block.blocksList[l]).getBlockEntity(getBlockMetadata(i,j,k));
+ tileentity = Block.blocksList[l].getTileEntity(meta);
worldObj.setBlockTileEntity(xPosition * 16 + i, j, zPosition * 16 + k, tileentity);
}
tileentity = (TileEntity)chunkTileEntityMap.get(chunkposition);
@ -114,7 +156,7 @@
}
}
@@ -641,7 +640,7 @@
@@ -641,7 +645,7 @@
setChunkBlockTileEntity(i, j, k, tileentity);
if(isChunkLoaded)
{
@ -123,7 +165,15 @@
}
}
@@ -657,6 +656,8 @@
@@ -652,11 +656,15 @@
tileentity.xCoord = xPosition * 16 + i;
tileentity.yCoord = j;
tileentity.zCoord = zPosition * 16 + k;
- if(getBlockID(i, j, k) == 0 || !(Block.blocksList[getBlockID(i, j, k)] instanceof BlockContainer))
+ int id = getBlockID(i, j, k);
+ int meta = getBlockMetadata(i, j, k);
+ if(id == 0 || Block.blocksList[id] == null || !Block.blocksList[id].hasTileEntity(meta))
{
return;
} else
{
@ -132,7 +182,7 @@
tileentity.validate();
chunkTileEntityMap.put(chunkposition, tileentity);
return;
@@ -810,6 +811,15 @@
@@ -810,6 +818,15 @@
public int setChunkData(byte abyte0[], int i, int j, int k, int l, int i1, int j1,
int k1)
{
@ -148,7 +198,7 @@
for(int l1 = i; l1 < l; l1++)
{
for(int l2 = k; l2 < j1; l2++)
@@ -859,12 +869,29 @@
@@ -859,12 +876,29 @@
}

View file

@ -0,0 +1,52 @@
--- ../src_base/minecraft/net/minecraft/src/Entity.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft/net/minecraft/src/Entity.java 0000-00-00 00:00:00.000000000 -0000
@@ -83,6 +83,9 @@
public int serverPosZ;
public boolean ignoreFrustumCheck;
public boolean isAirBorne;
+
+ //Forge: Used to store custom data for each entity.
+ private NBTTagCompound customEntityData;
public Entity(World world)
{
@@ -123,6 +126,20 @@
}
protected abstract void entityInit();
+
+ /**
+ * Returns a NBTTagCompound that can be used to store custom data for this entity.
+ * It will be written, and read from disc, so it persists over world saves.
+ * @return A NBTTagCompound
+ */
+ public NBTTagCompound getEntityData()
+ {
+ if (customEntityData == null)
+ {
+ customEntityData = new NBTTagCompound();
+ }
+ return customEntityData;
+ }
public DataWatcher getDataWatcher()
{
@@ -955,6 +972,7 @@
nbttagcompound.setShort("Fire", (short)fire);
nbttagcompound.setShort("Air", (short)getAir());
nbttagcompound.setBoolean("OnGround", onGround);
+ nbttagcompound.setCompoundTag("ForgeEntityData", customEntityData);
writeEntityToNBT(nbttagcompound);
}
@@ -989,6 +1007,10 @@
onGround = nbttagcompound.getBoolean("OnGround");
setPosition(posX, posY, posZ);
setRotation(rotationYaw, rotationPitch);
+ if (nbttagcompound.hasKey("ForgeEntityData"))
+ {
+ customEntityData.getCompoundTag("ForgeEntityData");
+ }
readEntityFromNBT(nbttagcompound);
}

View file

@ -17,7 +17,7 @@
public static int chunksUpdated = 0;
public int posX;
public int posY;
@@ -160,8 +161,9 @@
@@ -160,10 +161,11 @@
GL11.glTranslatef((float)(-sizeDepth) / 2.0F, (float)(-sizeHeight) / 2.0F, (float)(-sizeDepth) / 2.0F);
GL11.glScalef(f, f, f);
GL11.glTranslatef((float)sizeDepth / 2.0F, (float)sizeHeight / 2.0F, (float)sizeDepth / 2.0F);
@ -27,8 +27,11 @@
+ Tessellator.instance.startDrawingQuads();
+ Tessellator.instance.setTranslationD(-posX, -posY, -posZ);
}
if(i2 == 0 && Block.isBlockContainer[i3])
- if(i2 == 0 && Block.isBlockContainer[i3])
+ if(i2 == 0 && Block.blocksList[i3] != null && Block.blocksList[i3].hasTileEntity(chunkcache.getBlockMetadata(l2, j2, k2)))
{
TileEntity tileentity = chunkcache.getBlockTileEntity(l2, j2, k2);
if(TileEntityRenderer.instance.hasSpecialRenderer(tileentity))
@@ -177,15 +179,13 @@
{
flag1 = true;

View file

@ -115,7 +115,16 @@
}
}
@@ -725,6 +767,197 @@
@@ -651,7 +693,7 @@
{
entityplayer.addStat(StatList.mineBlockStatArray[blockID], 1);
entityplayer.addExhaustion(0.025F);
- if(renderAsNormalBlock() && !isBlockContainer[blockID] && EnchantmentHelper.getSilkTouchModifier(entityplayer.inventory))
+ if(renderAsNormalBlock() && !hasTileEntity(l) && EnchantmentHelper.getSilkTouchModifier(entityplayer.inventory))
{
ItemStack itemstack = func_41001_e(l);
if(itemstack != null)
@@ -725,6 +767,236 @@
return blockMaterial.getMaterialMobility();
}
@ -309,6 +318,45 @@
+ blockFireSpreadSpeed[id] = encouragement;
+ blockFlammability[id] = flammability;
+ }
+
+ /**
+ * Called throughout the code as a replacement for block instanceof BlockContainer
+ * Moving this to the Block base class allows for mods that wish to extend vinella
+ * blocks, and also want to have a tile entity on that block, may.
+ *
+ * Return true from this function to specify this block has a tile entity.
+ *
+ * @param metadata Metadata of the current block
+ * @return True if block has a tile entity, false otherwise
+ */
+ public boolean hasTileEntity(int metadata)
+ {
+ if (isBlockContainer[blockID])
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Called throughout the code as a replacement for BlockContainer.getBlockEntity
+ * Return the same thing you would from that function.
+ * This will fall back to BlockContainer.getBlockEntity if this block is a BlockContainer.
+ *
+ * @param metadata The Metadata of the current block
+ * @return A instance of a class extending TileEntity
+ */
+ public TileEntity getTileEntity(int metadata)
+ {
+ if (this instanceof BlockContainer)
+ {
+ return ((BlockContainer)this).getBlockEntity(metadata);
+ }
+ return null;
+ }
+
static Class _mthclass$(String s)
{

View file

@ -0,0 +1,11 @@
--- ../src_base/minecraft_server/net/minecraft/src/BlockPistonBase.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft_server/net/minecraft/src/BlockPistonBase.java 0000-00-00 00:00:00.000000000 -0000
@@ -356,7 +356,7 @@
return false;
}
}
- return !(Block.blocksList[i] instanceof BlockContainer);
+ return !(Block.blocksList[i] != null && Block.blocksList[i].hasTileEntity(world.getBlockMetadata(j, l, l)));
}
private static boolean canExtend(World world, int i, int j, int k, int l)

View file

@ -8,16 +8,36 @@
import java.io.PrintStream;
import java.util.*;
@@ -367,7 +368,7 @@
@@ -328,11 +329,12 @@
blocks[i << worldObj.xShift | k << worldObj.worldYBits | j] = (byte)(byte0 & 0xff);
if(l1 != 0)
{
+ int meta = getBlockMetadata(i, j, k);
if(!worldObj.singleplayerWorld)
{
Block.blocksList[l1].onBlockRemoval(worldObj, i2, j, j2);
} else
- if(Block.blocksList[l1] instanceof BlockContainer)
+ if(Block.blocksList[l1] != null && Block.blocksList[l1].hasTileEntity(meta))
{
worldObj.removeBlockTileEntity(i2, j, j2);
}
@@ -362,12 +364,12 @@
{
Block.blocksList[l].onBlockAdded(worldObj, i2, j, j2);
}
- if(Block.blocksList[l] instanceof BlockContainer)
+ if(Block.blocksList[l] != null && Block.blocksList[l].hasTileEntity(i1))
{
TileEntity tileentity = getChunkBlockTileEntity(i, j, k);
if(tileentity == null)
{
- tileentity = ((BlockContainer)Block.blocksList[l]).getBlockEntity();
+ tileentity = ((BlockContainer)Block.blocksList[l]).getBlockEntity(i1);
+ tileentity = Block.blocksList[l].getTileEntity(i1);
worldObj.setBlockTileEntity(i, j, k, tileentity);
}
if(tileentity != null)
@@ -375,14 +376,6 @@
@@ -375,14 +377,6 @@
tileentity.func_35164_g();
}
}
@ -32,7 +52,7 @@
}
isModified = true;
return true;
@@ -408,6 +401,11 @@
@@ -408,6 +402,11 @@
if(k1 != 0)
{
Block.blocksList[k1].onBlockRemoval(worldObj, l1, j, i2);
@ -44,16 +64,23 @@
}
data.setNibble(i, j, k, 0);
if(Block.lightOpacity[byte0 & 0xff] != 0)
@@ -435,7 +433,7 @@
@@ -430,12 +429,13 @@
{
Block.blocksList[l].onBlockAdded(worldObj, l1, j, i2);
}
- if(l > 0 && (Block.blocksList[l] instanceof BlockContainer))
+ int meta = getBlockMetadata(i, j, k);
+ if(l > 0 && Block.blocksList[l] != null && Block.blocksList[l].hasTileEntity(meta))
{
TileEntity tileentity = getChunkBlockTileEntity(i, j, k);
if(tileentity == null)
{
- tileentity = ((BlockContainer)Block.blocksList[l]).getBlockEntity();
+ tileentity = ((BlockContainer)Block.blocksList[l]).getBlockEntity(0);
+ tileentity = Block.blocksList[l].getTileEntity(meta);
worldObj.setBlockTileEntity(i, j, k, tileentity);
}
if(tileentity != null)
@@ -443,14 +441,6 @@
@@ -443,14 +443,6 @@
tileentity.func_35164_g();
}
}
@ -68,7 +95,16 @@
}
isModified = true;
return true;
@@ -586,6 +576,11 @@
@@ -471,7 +463,7 @@
}
data.setNibble(i, j, k, l);
int j1 = getBlockID(i, j, k);
- if(j1 > 0 && (Block.blocksList[j1] instanceof BlockContainer))
+ if(j1 > 0 && Block.blocksList[j1] != null && Block.blocksList[j1].hasTileEntity(l))
{
TileEntity tileentity = getChunkBlockTileEntity(i, j, k);
if(tileentity != null)
@@ -586,27 +578,38 @@
{
ChunkPosition chunkposition = new ChunkPosition(i, j, k);
TileEntity tileentity = (TileEntity)chunkTileEntityMap.get(chunkposition);
@ -80,12 +116,16 @@
if(tileentity == null)
{
int l = getBlockID(i, j, k);
@@ -595,18 +590,23 @@
- if(!Block.isBlockContainer[l])
+ int meta = getBlockMetadata(i, j, k);
+ if(Block.blocksList[l] == null || !Block.blocksList[l].hasTileEntity(meta))
{
return null;
}
if(tileentity == null)
{
- tileentity = ((BlockContainer)Block.blocksList[l]).getBlockEntity();
+ tileentity = ((BlockContainer)Block.blocksList[l]).getBlockEntity(getBlockMetadata(i,j,k));
+ tileentity = Block.blocksList[l].getTileEntity(meta);
worldObj.setBlockTileEntity(xPosition * 16 + i, j, zPosition * 16 + k, tileentity);
}
tileentity = (TileEntity)chunkTileEntityMap.get(chunkposition);
@ -95,7 +135,7 @@
- chunkTileEntityMap.remove(chunkposition);
- return null;
- } else
+ return tileentity;
+ return tileentity;
+ }
+
+ /* FORGE: Used to remove only invalid TileEntities */
@ -111,7 +151,7 @@
}
}
@@ -618,7 +618,7 @@
@@ -618,7 +621,7 @@
setChunkBlockTileEntity(i, j, k, tileentity);
if(isChunkLoaded)
{
@ -120,12 +160,25 @@
}
}
@@ -634,6 +634,8 @@
return;
} else
@@ -629,11 +632,19 @@
tileentity.xCoord = xPosition * 16 + i;
tileentity.yCoord = j;
tileentity.zCoord = zPosition * 16 + k;
- if(getBlockID(i, j, k) == 0 || !(Block.blocksList[getBlockID(i, j, k)] instanceof BlockContainer))
+ int id = getBlockID(i, j, k);
+ int meta = getBlockMetadata(i, j, k);
+ if(id == 0 || Block.blocksList[id] == null || !Block.blocksList[id].hasTileEntity(meta))
{
+ TileEntity old=(TileEntity)chunkTileEntityMap.get(chunkposition);
+ if(old!=null) old.invalidate();
return;
- } else
+ }
+ else
{
+ TileEntity old = (TileEntity)chunkTileEntityMap.get(chunkposition);
+ if (old != null)
+ {
+ old.invalidate();
+ }
tileentity.validate();
chunkTileEntityMap.put(chunkposition, tileentity);
return;

View file

@ -0,0 +1,44 @@
--- ../src_base/minecraft_server/net/minecraft/src/Entity.java 0000-00-00 00:00:00.000000000 -0000
+++ ../src_work/minecraft_server/net/minecraft/src/Entity.java 0000-00-00 00:00:00.000000000 -0000
@@ -119,6 +119,22 @@
protected abstract void entityInit();
+ //Forge: Used to store custom data for each entity.
+ private NBTTagCompound customEntityData;
+ /**
+ * Returns a NBTTagCompound that can be used to store custom data for this entity.
+ * It will be written, and read from disc, so it persists over world saves.
+ * @return A NBTTagCompound
+ */
+ public NBTTagCompound getEntityData()
+ {
+ if (customEntityData == null)
+ {
+ customEntityData = new NBTTagCompound();
+ }
+ return customEntityData;
+ }
+
public DataWatcher getDataWatcher()
{
return dataWatcher;
@@ -873,6 +889,7 @@
nbttagcompound.setShort("Fire", (short)fire);
nbttagcompound.setShort("Air", (short)getAir());
nbttagcompound.setBoolean("OnGround", onGround);
+ nbttagcompound.setCompoundTag("ForgeEntityData", customEntityData);
writeEntityToNBT(nbttagcompound);
}
@@ -907,6 +924,10 @@
onGround = nbttagcompound.getBoolean("OnGround");
setPosition(posX, posY, posZ);
setRotation(rotationYaw, rotationPitch);
+ if (nbttagcompound.hasKey("ForgeEntityData"))
+ {
+ customEntityData.getCompoundTag("ForgeEntityData");
+ }
readEntityFromNBT(nbttagcompound);
}