buildcraft/common/buildcraft/robotics/DockingStationPipe.java
Adrian Siekierka cc9df443f7 fix #3429
2017-02-07 12:12:31 +01:00

316 lines
7.7 KiB
Java

package buildcraft.robotics;
import java.util.List;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.BuildCraftRobotics;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.EnumColor;
import buildcraft.api.gates.IGate;
import buildcraft.api.robots.DockingStation;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IRequestProvider;
import buildcraft.api.robots.RobotManager;
import buildcraft.api.statements.IStatement;
import buildcraft.api.statements.StatementSlot;
import buildcraft.api.transport.IInjectable;
import buildcraft.api.transport.IPipeTile;
import buildcraft.core.lib.inventory.InventoryWrapper;
import buildcraft.transport.Pipe;
import buildcraft.transport.PipeTransportItems;
import buildcraft.transport.TravelingItem;
import buildcraft.transport.gates.ActionIterator;
import buildcraft.transport.pipes.PipeFluidsWood;
import buildcraft.transport.pipes.PipeItemsWood;
public class DockingStationPipe extends DockingStation implements IRequestProvider {
private IInjectable injectablePipe = new IInjectable() {
@Override
public boolean canInjectItems(ForgeDirection from) {
return true;
}
@Override
public int injectItem(ItemStack stack, boolean doAdd, ForgeDirection from, EnumColor color) {
if (doAdd) {
float cx = x() + 0.5F + 0.2F * side().offsetX;
float cy = y() + 0.5F + 0.2F * side().offsetY;
float cz = z() + 0.5F + 0.2F * side().offsetZ;
TravelingItem item = TravelingItem.make(cx, cy, cz, stack);
if (item.isCorrupted()) {
return 0;
}
((PipeTransportItems) ((Pipe<?>) getPipe().getPipe()).transport)
.injectItem(item, from);
}
return stack.stackSize;
}
};
private IPipeTile pipe;
public DockingStationPipe() {
// Loading later from NBT - DO NOT TOUCH!
}
public DockingStationPipe(IPipeTile iPipe, ForgeDirection side) {
super(new BlockIndex(iPipe.x(), iPipe.y(), iPipe.z()), side);
pipe = iPipe;
world = iPipe.getWorld();
}
public IPipeTile getPipe() {
if (pipe == null) {
TileEntity tile = world.getTileEntity(x(), y(), z());
if (tile instanceof IPipeTile) {
pipe = (IPipeTile) tile;
}
}
if (pipe == null || ((TileEntity) pipe).isInvalid()) {
// Inconsistency - remove this pipe from the registry.
RobotManager.registryProvider.getRegistry(world).removeStation(this);
pipe = null;
}
return pipe;
}
@Override
public Iterable<StatementSlot> getActiveActions() {
return new ActionIterator(getPipe().getPipe());
}
@Override
public IInjectable getItemOutput() {
if (getPipe().getPipeType() != IPipeTile.PipeType.ITEM) {
return null;
}
return injectablePipe;
}
@Override
public ForgeDirection getItemOutputSide() {
return side().getOpposite();
}
@Override
public ISidedInventory getItemInput() {
if (getPipe().getPipeType() != IPipeTile.PipeType.ITEM) {
return null;
}
if (!(getPipe().getPipe() instanceof PipeItemsWood)) {
return null;
}
int meta = ((TileEntity) getPipe()).getBlockMetadata();
ForgeDirection dir = ForgeDirection.getOrientation(meta);
TileEntity connectedTile = getPipe().getWorld().getTileEntity(x() + dir.offsetX,
y() + dir.offsetY, z() + dir.offsetZ);
if (connectedTile instanceof IInventory) {
return InventoryWrapper.getWrappedInventory(connectedTile);
}
return null;
}
@Override
public ForgeDirection getItemInputSide() {
if (getPipe().getPipeType() != IPipeTile.PipeType.ITEM) {
return ForgeDirection.UNKNOWN;
}
if (!(getPipe().getPipe() instanceof PipeItemsWood)) {
return ForgeDirection.UNKNOWN;
}
int meta = ((TileEntity) getPipe()).getBlockMetadata();
return ForgeDirection.getOrientation(meta).getOpposite();
}
@Override
public IFluidHandler getFluidInput() {
if (getPipe().getPipeType() != IPipeTile.PipeType.FLUID) {
return null;
}
if (!(getPipe().getPipe() instanceof PipeFluidsWood)) {
return null;
}
int meta = ((TileEntity) getPipe()).getBlockMetadata();
ForgeDirection dir = ForgeDirection.getOrientation(meta);
TileEntity connectedTile = getPipe().getWorld().getTileEntity(x() + dir.offsetX,
y() + dir.offsetY, z() + dir.offsetZ);
if (connectedTile instanceof IFluidHandler) {
return (IFluidHandler) connectedTile;
}
return null;
}
@Override
public ForgeDirection getFluidInputSide() {
if (getPipe().getPipeType() != IPipeTile.PipeType.FLUID) {
return ForgeDirection.UNKNOWN;
}
if (!(getPipe().getPipe() instanceof PipeFluidsWood)) {
return ForgeDirection.UNKNOWN;
}
int meta = ((TileEntity) getPipe()).getBlockMetadata();
return ForgeDirection.getOrientation(meta).getOpposite();
}
@Override
public IFluidHandler getFluidOutput() {
if (getPipe().getPipeType() != IPipeTile.PipeType.FLUID) {
return null;
}
return (IFluidHandler) ((Pipe<?>) getPipe().getPipe()).transport;
}
@Override
public ForgeDirection getFluidOutputSide() {
return ForgeDirection.UNKNOWN;
}
@Override
public boolean providesPower() {
return getPipe().getPipeType() == IPipeTile.PipeType.POWER;
}
@Override
public IRequestProvider getRequestProvider() {
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
TileEntity nearbyTile = getPipe().getWorld().getTileEntity(x() + dir.offsetX,
y() + dir.offsetY, z() + dir.offsetZ);
if (nearbyTile instanceof IRequestProvider) {
return (IRequestProvider) nearbyTile;
}
}
return this;
}
@Override
public boolean isInitialized() {
IPipeTile pipe = getPipe();
if (pipe == null || pipe.getPipe() == null) {
return false;
}
return ((Pipe<?>) pipe.getPipe()).isInitialized();
}
@Override
public boolean take(EntityRobotBase robot) {
IPipeTile pipe = getPipe();
if (pipe == null)
return false;
boolean result = super.take(robot);
if (result) {
pipe.scheduleRenderUpdate();
}
return result;
}
@Override
public boolean takeAsMain(EntityRobotBase robot) {
IPipeTile pipe = getPipe();
if (pipe == null)
return false;
boolean result = super.takeAsMain(robot);
if (result) {
pipe.scheduleRenderUpdate();
}
return result;
}
@Override
public void unsafeRelease(EntityRobotBase robot) {
super.unsafeRelease(robot);
if (robotTaking() == null && getPipe() != null) {
getPipe().scheduleRenderUpdate();
}
}
@Override
public void onChunkUnload() {
pipe = null;
}
@Override
public int getRequestsCount() {
return 127;
}
@Override
public ItemStack getRequest(int slot) {
ForgeDirection side = ForgeDirection.getOrientation((slot & 0x70) >> 4);
int action = (slot & 0xc) >> 2;
int param = slot & 0x3;
IGate gate = getPipe().getPipe().getGate(side);
if (gate == null) {
return null;
}
List<IStatement> actions = gate.getActions();
if (actions.size() <= action) {
return null;
}
if (actions.get(action) != BuildCraftRobotics.actionStationRequestItems) {
return null;
}
List<StatementSlot> activeActions = gate.getActiveActions();
StatementSlot slotStmt = null;
for (StatementSlot stmt : activeActions) {
if (stmt.statement == actions.get(action)) {
slotStmt = stmt;
break;
}
}
if (slotStmt == null) {
return null;
}
if (slotStmt.parameters.length <= param) {
return null;
}
if (slotStmt.parameters[param] == null) {
return null;
}
return slotStmt.parameters[param].getItemStack();
}
@Override
public ItemStack offerItem(int slot, ItemStack stack) {
int consumed = injectablePipe.injectItem(stack, true, side.getOpposite(), null);
if (stack.stackSize > consumed) {
ItemStack newStack = stack.copy();
newStack.stackSize -= consumed;
return newStack;
}
return null;
}
}