package advancedsystemsmanager.compatibility.appliedenergistics; import advancedsystemsmanager.api.execution.IBufferElement; import advancedsystemsmanager.api.tileentities.IInternalInventory; import advancedsystemsmanager.api.tileentities.IInternalTank; import advancedsystemsmanager.compatibility.appliedenergistics.buffer.AEFluidBufferElement; import advancedsystemsmanager.compatibility.appliedenergistics.buffer.AEItemBufferElement; import advancedsystemsmanager.flow.execution.ConditionSettingChecker; import advancedsystemsmanager.flow.menus.MenuItem; import advancedsystemsmanager.flow.menus.MenuLiquid; import advancedsystemsmanager.flow.menus.MenuStuff; import advancedsystemsmanager.flow.setting.ItemSetting; import advancedsystemsmanager.flow.setting.Setting; import advancedsystemsmanager.reference.Mods; import advancedsystemsmanager.registry.ClusterRegistry; import advancedsystemsmanager.registry.CommandRegistry; import advancedsystemsmanager.tileentities.TileEntityElementBase; import appeng.api.AEApi; import appeng.api.networking.*; import appeng.api.networking.security.IActionHost; import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEItemStack; import appeng.api.util.AECableType; import appeng.api.util.AEColor; import appeng.api.util.DimensionalCoord; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Optional; import net.minecraft.item.ItemStack; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidHandler; import java.util.*; @Optional.Interface(iface = "advancedsystemsmanager.api.tileentities.IHiddenTank", modid = Mods.EXTRACELLS) public class TileEntityAENode extends TileEntityElementBase implements IGridHost, IActionHost, IInternalInventory, IInternalTank { public AEHelper helper; private GridBlock gridBlock; private IGridNode gridNode; private IFluidHandler tank; private boolean isReady; public TileEntityAENode() { this.gridBlock = new GridBlock(); this.tank = new AEFakeTank(); this.helper = new AEHelper(this); } @Override public void updateEntity() { super.updateEntity(); this.isReady = true; getNode(); } public IGridNode getNode() { if (this.gridNode == null && FMLCommonHandler.instance().getEffectiveSide().isServer() && this.isReady) { this.gridNode = AEApi.instance().createGridNode(this.gridBlock); this.gridNode.updateState(); } return this.gridNode; } @Override public void invalidate() { super.invalidate(); if (this.gridNode != null) { this.gridNode.destroy(); this.gridNode = null; } } @Override public boolean canUpdate() { return !this.isReady; } @Override public void onChunkUnload() { super.onChunkUnload(); if (this.gridNode != null) { this.gridNode.destroy(); this.gridNode = null; } } @Override public IGridNode getActionableNode() { return getNode(); } @Override public IGridNode getGridNode(ForgeDirection forgeDirection) { return getNode(); } @Override public AECableType getCableConnectionType(ForgeDirection forgeDirection) { return AECableType.SMART; } @Override public void securityBreak() { this.worldObj.func_147480_a(this.xCoord, this.yCoord, this.zCoord, true); } @Override public int getAmountToInsert(ItemStack stack) { ItemStack insertable = helper.getInsertable(stack); return insertable == null ? 0 : insertable.stackSize; } @Override public void insertItemStack(ItemStack stack) { helper.insert(stack, false); } @Override public List<IBufferElement<ItemStack>> getSubElements(int id, MenuItem menuItem) { List<IBufferElement<ItemStack>> elements = new ArrayList<IBufferElement<ItemStack>>(); Iterator<IAEItemStack> itr = helper.getItrItems(); if (itr == null) return elements; List<Setting<ItemStack>> settings = CommandRegistry.INPUT.getValidSettings(menuItem.getSettings()); while (itr.hasNext()) { IAEItemStack stack = itr.next(); if (stack != null) { Setting<ItemStack> setting = CommandRegistry.INPUT.isValid(settings, stack.getItemStack()); addAEItemToBuffer(id, menuItem, setting, stack, elements); } } return elements; } @Override public void isItemValid(Collection<Setting> settings, Map<Integer, ConditionSettingChecker> conditionSettingCheckerMap) { for (Setting setting : settings) { ItemStack stack = helper.find(((ItemSetting)setting).getItem()); if (stack != null) { ConditionSettingChecker conditionSettingChecker = conditionSettingCheckerMap.get(setting.getId()); if (conditionSettingChecker == null) { conditionSettingCheckerMap.put(setting.getId(), conditionSettingChecker = new ConditionSettingChecker(setting)); } conditionSettingChecker.addCount(stack.stackSize); } } } private void addAEItemToBuffer(int id, MenuStuff menuItem, Setting<ItemStack> setting, IAEItemStack stack, List<IBufferElement<ItemStack>> itemBuffer) { if (menuItem.useWhiteList() == (setting != null) || setting != null && setting.isLimitedByAmount()) { itemBuffer.add(new AEItemBufferElement(id, this, stack, setting, menuItem.useWhiteList())); } } @Override public IFluidHandler getTank() { return tank; } @Override public List<IBufferElement<Fluid>> getSubElements(int id, MenuLiquid menuLiquid) { List<IBufferElement<Fluid>> elements = new ArrayList<IBufferElement<Fluid>>(); Iterator<IAEFluidStack> itr = helper.getItrFluids(); if (itr == null) return elements; List<Setting<Fluid>> validSettings = CommandRegistry.LIQUID_INPUT.getValidSettings(menuLiquid.getSettings()); while (itr.hasNext()) { IAEFluidStack stack = itr.next(); if (stack != null) { Setting<Fluid> setting = CommandRegistry.LIQUID_INPUT.isValid(validSettings, stack.getFluidStack().getFluid()); addAEFluidToBuffer(id, menuLiquid, setting, stack, elements); } } return elements; } private void addAEFluidToBuffer(int id, MenuStuff menuLiquid, Setting<Fluid> setting, IAEFluidStack stack, List<IBufferElement<Fluid>> liquidBuffer) { if (menuLiquid.useWhiteList() == (setting != null) || setting != null && setting.isLimitedByAmount()) { liquidBuffer.add(new AEFluidBufferElement(id, this, (int)stack.getStackSize(), stack.getFluid(), setting, menuLiquid.useWhiteList())); } } private class GridBlock implements IGridBlock { @Override public double getIdlePowerUsage() { return 10; } @Override public EnumSet<GridFlags> getFlags() { return EnumSet.of(GridFlags.REQUIRE_CHANNEL); } @Override public boolean isWorldAccessible() { return true; } @Override public DimensionalCoord getLocation() { return new DimensionalCoord(TileEntityAENode.this); } @Override public AEColor getGridColor() { return AEColor.Transparent; } @Override public void onGridNotification(GridNotification gridNotification) { } @Override public void setNetworkStatus(IGrid iGrid, int i) { } @Override public EnumSet<ForgeDirection> getConnectableSides() { return EnumSet.allOf(ForgeDirection.class); } @Override public IGridHost getMachine() { return TileEntityAENode.this; } @Override public void gridChanged() { } @Override public ItemStack getMachineRepresentation() { return AECompat.AE.getItemStack(); } } private class AEFakeTank implements IFluidHandler { @Override public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { IAEFluidStack toAdd = helper.insert(resource, doFill); return toAdd == null ? resource.amount : resource.amount - (int)toAdd.getStackSize(); } @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { IAEFluidStack drain = helper.extract(resource, doDrain); return drain == null ? null : drain.getFluidStack(); } @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { Iterator<IAEFluidStack> itr = helper.getItrFluids(); if (itr != null && itr.hasNext()) { FluidStack stack = itr.next().getFluidStack(); stack.amount = Math.min(maxDrain, stack.amount); return drain(from, stack, doDrain); } return null; } @Override public boolean canFill(ForgeDirection from, Fluid fluid) { return helper.insert(new FluidStack(fluid, 1), true) != null; } @Override public boolean canDrain(ForgeDirection from, Fluid fluid) { return helper.find(new FluidStack(fluid, 1)) != null; } @Override public FluidTankInfo[] getTankInfo(ForgeDirection from) { List<FluidTankInfo> tankInfo = new ArrayList<FluidTankInfo>(); Iterator<IAEFluidStack> itr = helper.getItrFluids(); if (itr == null) return new FluidTankInfo[0]; while (itr.hasNext()) { FluidStack stack = itr.next().getFluidStack(); tankInfo.add(new FluidTankInfo(stack, stack.amount)); } return tankInfo.toArray(new FluidTankInfo[tankInfo.size()]); } } }