From a14eb3b55fea33f1f595ff987a0c6c8054a60f37 Mon Sep 17 00:00:00 2001 From: asiekierka Date: Thu, 22 Jan 2015 13:49:08 +0100 Subject: [PATCH] add IFacadePluggable, let mods define their own IFacadePluggables and query facades; NPE fixes on rare world corruptions --- api/buildcraft/api/transport/IPipeTile.java | 6 +-- .../api/transport/package-info.java | 2 +- .../transport/pluggable/IFacadePluggable.java | 10 +++++ .../buildcraft/transport/FacadePluggable.java | 43 +++++++++++++------ common/buildcraft/transport/ItemFacade.java | 9 +++- .../transport/PipeTransportItems.java | 4 ++ .../buildcraft/transport/TileGenericPipe.java | 9 ++-- .../transport/render/FacadeBlockAccess.java | 17 ++++---- .../transport/render/FacadeRenderHelper.java | 30 +++++++++---- 9 files changed, 92 insertions(+), 38 deletions(-) create mode 100644 api/buildcraft/api/transport/pluggable/IFacadePluggable.java diff --git a/api/buildcraft/api/transport/IPipeTile.java b/api/buildcraft/api/transport/IPipeTile.java index a6e2d3a6..c8b3b4e7 100644 --- a/api/buildcraft/api/transport/IPipeTile.java +++ b/api/buildcraft/api/transport/IPipeTile.java @@ -48,8 +48,8 @@ public interface IPipeTile extends IInjectable { IPipe getPipe(); int getPipeColor(); - PipePluggable getPipePluggable(ForgeDirection direction); - boolean hasPipePluggable(ForgeDirection direction); + PipePluggable getPipePluggable(ForgeDirection direction); // Now in IPluggableProvider + boolean hasPipePluggable(ForgeDirection direction); // Now in IPluggableProvider boolean hasBlockingPluggable(ForgeDirection direction); void scheduleNeighborChange(); @@ -57,6 +57,6 @@ public interface IPipeTile extends IInjectable { // For compatibility with BC 6.2.x and below int injectItem(ItemStack stack, boolean doAdd, ForgeDirection from, EnumColor color); - @Deprecated + @Deprecated // Now in IInjectable int injectItem(ItemStack stack, boolean doAdd, ForgeDirection from); } diff --git a/api/buildcraft/api/transport/package-info.java b/api/buildcraft/api/transport/package-info.java index 77d44059..f4c84cb4 100644 --- a/api/buildcraft/api/transport/package-info.java +++ b/api/buildcraft/api/transport/package-info.java @@ -6,7 +6,7 @@ * Please check the contents of the license, which should be located * as "LICENSE.API" in the BuildCraft source code distribution. */ -@API(apiVersion = "3.0", owner = "BuildCraftAPI|core", provides = "BuildCraftAPI|transport") +@API(apiVersion = "3.1", owner = "BuildCraftAPI|core", provides = "BuildCraftAPI|transport") package buildcraft.api.transport; import cpw.mods.fml.common.API; diff --git a/api/buildcraft/api/transport/pluggable/IFacadePluggable.java b/api/buildcraft/api/transport/pluggable/IFacadePluggable.java new file mode 100644 index 00000000..08ae33f7 --- /dev/null +++ b/api/buildcraft/api/transport/pluggable/IFacadePluggable.java @@ -0,0 +1,10 @@ +package buildcraft.api.transport.pluggable; + +import net.minecraft.block.Block; + +public interface IFacadePluggable { + public Block getCurrentBlock(); + public int getCurrentMetadata(); + public boolean isTransparent(); + public boolean isHollow(); +} diff --git a/common/buildcraft/transport/FacadePluggable.java b/common/buildcraft/transport/FacadePluggable.java index 8b60fef4..091c25e1 100644 --- a/common/buildcraft/transport/FacadePluggable.java +++ b/common/buildcraft/transport/FacadePluggable.java @@ -11,11 +11,12 @@ import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.ForgeDirection; import buildcraft.api.transport.IPipeTile; +import buildcraft.api.transport.pluggable.IFacadePluggable; import buildcraft.api.transport.pluggable.IPipePluggableRenderer; import buildcraft.api.transport.pluggable.PipePluggable; import buildcraft.core.utils.MatrixTranformations; -public class FacadePluggable extends PipePluggable { +public class FacadePluggable extends PipePluggable implements IFacadePluggable { public ItemFacade.FacadeState[] states; private ItemFacade.FacadeState activeState; @@ -26,7 +27,7 @@ public class FacadePluggable extends PipePluggable { public FacadePluggable(ItemFacade.FacadeState[] states) { this.states = states; - activeState = states.length > 0 ? states[0] : null; + prepareStates(); } public FacadePluggable() { @@ -51,7 +52,7 @@ public class FacadePluggable extends PipePluggable { if (states != null) { return new ItemStack[] { ItemFacade.getFacade(states) }; } else { - return new ItemStack[] { ItemFacade.getFacade(new ItemFacade.FacadeState(getRenderingBlock(), getRenderingMeta(), null, isHollow())) }; + return new ItemStack[] { ItemFacade.getFacade(new ItemFacade.FacadeState(getCurrentBlock(), getCurrentMetadata(), null, isHollow())) }; } } @@ -60,13 +61,28 @@ public class FacadePluggable extends PipePluggable { return !isHollow(); } - public boolean isHollow() { - return states == null ? renderAsHollow : states[0].hollow; + @Override + public Block getCurrentBlock() { + prepareStates(); + return activeState == null ? block : activeState.block; } - public Block getRenderingBlock() { return block; } - public int getRenderingMeta() { return meta; } - public boolean getRenderingTransparent() { return transparent; } + @Override + public int getCurrentMetadata() { + prepareStates(); + return activeState == null ? meta : activeState.metadata; + } + + @Override + public boolean isTransparent() { + prepareStates(); + return activeState == null ? transparent : activeState.transparent; + } + + public boolean isHollow() { + prepareStates(); + return activeState == null ? renderAsHollow : activeState.hollow; + } @Override public AxisAlignedBB getBoundingBox(ForgeDirection side) { @@ -97,9 +113,7 @@ public class FacadePluggable extends PipePluggable { @Override public void writeData(ByteBuf data) { - if (activeState == null) { - activeState = states.length > 0 ? states[0] : null; - } + prepareStates(); if (activeState == null || activeState.block == null) { data.writeShort(0); @@ -114,7 +128,6 @@ public class FacadePluggable extends PipePluggable { @Override public void readData(ByteBuf data) { - int blockId = data.readUnsignedShort(); if (blockId > 0) { block = Block.getBlockById(blockId); @@ -129,6 +142,12 @@ public class FacadePluggable extends PipePluggable { renderAsHollow = (flags & 0x40) > 0; } + private void prepareStates() { + if (activeState == null) { + activeState = states != null && states.length > 0 ? states[0] : null; + } + } + protected void setActiveState(int id) { if (id >= 0 && id < states.length) { activeState = states[id]; diff --git a/common/buildcraft/transport/ItemFacade.java b/common/buildcraft/transport/ItemFacade.java index 12081c44..d64e8821 100644 --- a/common/buildcraft/transport/ItemFacade.java +++ b/common/buildcraft/transport/ItemFacade.java @@ -27,6 +27,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.world.World; +import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -244,8 +245,12 @@ public class ItemFacade extends ItemBuildCraft implements IFacadeItem, IPipePlug private void registerValidFacades(Block block, Item item) { //for (int i = 0; i < 16; i++) { ArrayList stacks = new ArrayList(16); - for (CreativeTabs tab : item.getCreativeTabs()) { - block.getSubBlocks(item, tab, stacks); + if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) { + block.getSubBlocks(item, null, stacks); + } else { + for (int i = 0; i < 16; i++) { + stacks.add(new ItemStack(item, 1, i)); + } } for (ItemStack stack : stacks) { try { diff --git a/common/buildcraft/transport/PipeTransportItems.java b/common/buildcraft/transport/PipeTransportItems.java index 34e8a590..9a7afa59 100644 --- a/common/buildcraft/transport/PipeTransportItems.java +++ b/common/buildcraft/transport/PipeTransportItems.java @@ -231,6 +231,10 @@ public class PipeTransportItems extends PipeTransport { if (entity instanceof IPipeTile) { Pipe pipe = (Pipe) ((IPipeTile) entity).getPipe(); + if (pipe == null || pipe.transport == null) { + return false; + } + //return !pipe.pipe.isClosed() && pipe.pipe.transport instanceof PipeTransportItems; return pipe.inputOpen(o.getOpposite()) && pipe.transport instanceof PipeTransportItems; } else if (entity instanceof IInventory && item.getInsertionHandler().canInsertItem(item, (IInventory) entity)) { diff --git a/common/buildcraft/transport/TileGenericPipe.java b/common/buildcraft/transport/TileGenericPipe.java index d63a8756..f129e889 100644 --- a/common/buildcraft/transport/TileGenericPipe.java +++ b/common/buildcraft/transport/TileGenericPipe.java @@ -49,6 +49,7 @@ import buildcraft.api.transport.IPipeConnection; import buildcraft.api.transport.IPipeTile; import buildcraft.api.transport.PipeManager; import buildcraft.api.transport.PipeWire; +import buildcraft.api.transport.pluggable.IFacadePluggable; import buildcraft.api.transport.pluggable.PipePluggable; import buildcraft.core.DefaultProps; import buildcraft.core.IDropControlInventory; @@ -348,7 +349,9 @@ public class TileGenericPipe extends TileEntity implements IFluidHandler, worldObj.notifyBlockOfNeighborChange(xCoord, yCoord, zCoord, getBlock()); scheduleRenderUpdate(); sendUpdateToClient(); - BlockGenericPipe.updateNeighbourSignalState(pipe); + if (pipe != null) { + BlockGenericPipe.updateNeighbourSignalState(pipe); + } } @Override @@ -896,7 +899,7 @@ public class TileGenericPipe extends TileEntity implements IFluidHandler, if (direction == null || direction == ForgeDirection.UNKNOWN) { return false; } else { - return sideProperties.pluggables[direction.ordinal()] instanceof FacadePluggable; + return sideProperties.pluggables[direction.ordinal()] instanceof IFacadePluggable; } } @@ -940,7 +943,7 @@ public class TileGenericPipe extends TileEntity implements IFluidHandler, } public boolean hasEnabledFacade(ForgeDirection direction) { - return hasFacade(direction) && !((FacadePluggable) getPipePluggable(direction)).getRenderingTransparent(); + return hasFacade(direction) && !((FacadePluggable) getPipePluggable(direction)).isTransparent(); } public DockingStation getStation(ForgeDirection direction) { diff --git a/common/buildcraft/transport/render/FacadeBlockAccess.java b/common/buildcraft/transport/render/FacadeBlockAccess.java index 1e79a7e3..af27afe7 100644 --- a/common/buildcraft/transport/render/FacadeBlockAccess.java +++ b/common/buildcraft/transport/render/FacadeBlockAccess.java @@ -6,6 +6,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.world.IBlockAccess; import net.minecraft.world.biome.BiomeGenBase; import net.minecraftforge.common.util.ForgeDirection; +import buildcraft.api.transport.pluggable.IFacadePluggable; import buildcraft.api.transport.pluggable.PipePluggable; import buildcraft.transport.BlockGenericPipe; import buildcraft.transport.FacadePluggable; @@ -22,13 +23,13 @@ public class FacadeBlockAccess implements IBlockAccess { @Override public Block getBlock(int x, int y, int z) { - System.out.println("Querying block at " + x + ", " + y + ", " + z); + //System.out.println("Querying block at " + x + ", " + y + ", " + z); TileEntity tile = world.getTileEntity(x, y, z); if (tile instanceof TileGenericPipe) { PipePluggable p = ((TileGenericPipe) tile).getPipePluggable(side); - if (p instanceof FacadePluggable) { - System.out.println("Found facade"); - return ((FacadePluggable) p).getRenderingBlock(); + if (p instanceof IFacadePluggable) { + //System.out.println("Found facade"); + return ((IFacadePluggable) p).getCurrentBlock(); } } return Blocks.air; @@ -46,13 +47,13 @@ public class FacadeBlockAccess implements IBlockAccess { @Override public int getBlockMetadata(int x, int y, int z) { - System.out.println("Querying block metadata at " + x + ", " + y + ", " + z); + //System.out.println("Querying block metadata at " + x + ", " + y + ", " + z); TileEntity tile = world.getTileEntity(x, y, z); if (tile instanceof TileGenericPipe) { PipePluggable p = ((TileGenericPipe) tile).getPipePluggable(side); - if (p instanceof FacadePluggable) { - System.out.println("Found facade " + ((FacadePluggable) p).getRenderingMeta()); - return ((FacadePluggable) p).getRenderingMeta(); + if (p instanceof IFacadePluggable) { + //System.out.println("Found facade " + ((FacadePluggable) p).getRenderingMeta()); + return ((IFacadePluggable) p).getCurrentMetadata(); } } return 0; diff --git a/common/buildcraft/transport/render/FacadeRenderHelper.java b/common/buildcraft/transport/render/FacadeRenderHelper.java index d6fe778f..253a5291 100644 --- a/common/buildcraft/transport/render/FacadeRenderHelper.java +++ b/common/buildcraft/transport/render/FacadeRenderHelper.java @@ -17,6 +17,8 @@ import net.minecraftforge.common.util.ForgeDirection; import buildcraft.BuildCraftTransport; import buildcraft.api.core.render.ITextureStates; +import buildcraft.api.transport.pluggable.IFacadePluggable; +import buildcraft.api.transport.pluggable.PipePluggable; import buildcraft.core.CoreConstants; import buildcraft.core.utils.MatrixTranformations; import buildcraft.transport.BlockGenericPipe; @@ -102,19 +104,24 @@ public final class FacadeRenderHelper { //block_statemachine.setRenderAllSides(); for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) { - if (!(tile.getPipePluggable(direction) instanceof FacadePluggable)) { + if (!(tile.getPipePluggable(direction) instanceof IFacadePluggable)) { continue; } - FacadePluggable pluggable = (FacadePluggable) tile.getPipePluggable(direction); - Block renderBlock = pluggable.getRenderingBlock(); + IFacadePluggable pluggable = (IFacadePluggable) tile.getPipePluggable(direction); + if (((PipePluggable) pluggable).getRenderer() != null) { + // This IFacadePluggable provides its own renderer. + continue; + } + + Block renderBlock = pluggable.getCurrentBlock(); if (renderBlock != null) { IBlockAccess facadeBlockAccess = new FacadeBlockAccess(tile.getWorldObj(), direction); // If the facade is meant to render in the current pass if (renderBlock.canRenderInPass(PipeRendererWorld.renderPass)) { - int renderMeta = pluggable.getRenderingMeta(); + int renderMeta = pluggable.getCurrentMetadata(); for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { textures[side.ordinal()] = renderBlock.getIcon( @@ -126,11 +133,11 @@ public final class FacadeRenderHelper { if (side == direction || side == direction.getOpposite()) { blockStateMachine.setRenderSide(side, true); } else { - if (!(tile.getPipePluggable(side) instanceof FacadePluggable)) { + if (!(tile.getPipePluggable(side) instanceof IFacadePluggable)) { blockStateMachine.setRenderSide(side, true); } else { - FacadePluggable pluggable2 = (FacadePluggable) tile.getPipePluggable(side); - blockStateMachine.setRenderSide(side, pluggable2.getRenderingBlock() == null); + IFacadePluggable pluggable2 = (IFacadePluggable) tile.getPipePluggable(side); + blockStateMachine.setRenderSide(side, pluggable2.getCurrentBlock() == null); } } } @@ -212,8 +219,13 @@ public final class FacadeRenderHelper { // Always render connectors in pass 0 if (PipeRendererWorld.renderPass == 0) { for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) { - if (tile.getPipePluggable(direction) instanceof FacadePluggable) { - FacadePluggable pluggable = (FacadePluggable) tile.getPipePluggable(direction); + if (tile.getPipePluggable(direction) instanceof IFacadePluggable) { + IFacadePluggable pluggable = (IFacadePluggable) tile.getPipePluggable(direction); + + if (((PipePluggable) pluggable).getRenderer() != null) { + // This IFacadePluggable provides its own renderer. + continue; + } if (!pluggable.isHollow()) { float[][] rotated = MatrixTranformations.deepClone(zeroStateSupport);