add IFacadePluggable, let mods define their own IFacadePluggables and query facades; NPE fixes on rare world corruptions

This commit is contained in:
asiekierka 2015-01-22 13:49:08 +01:00
parent 7d9892bc13
commit a14eb3b55f
9 changed files with 92 additions and 38 deletions

View file

@ -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);
}

View file

@ -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;

View file

@ -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();
}

View file

@ -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];

View file

@ -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<ItemStack> stacks = new ArrayList<ItemStack>(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 {

View file

@ -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)) {

View file

@ -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) {

View file

@ -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;

View file

@ -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);