package blusunrize.immersiveengineering.common.util; import blusunrize.immersiveengineering.api.IEEnums.SideConfig; import blusunrize.immersiveengineering.api.energy.immersiveflux.*; import cofh.api.energy.IEnergyConnection; import cofh.api.energy.IEnergyContainerItem; import cofh.api.energy.IEnergyProvider; import cofh.api.energy.IEnergyReceiver; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraftforge.energy.CapabilityEnergy; import net.minecraftforge.energy.IEnergyStorage; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.HashMap; /** * @author BluSunrize - 29.11.2016 */ public class EnergyHelper { public static boolean isFluxItem(ItemStack stack) { if(stack==null || stack.getItem()==null) return false; if(stack.getItem() instanceof IFluxContainerItem) return true; if(stack.getItem() instanceof IEnergyContainerItem) return true; return stack.hasCapability(CapabilityEnergy.ENERGY, null); } public static int getEnergyStored(ItemStack stack) { if(stack==null || stack.getItem()==null) return 0; if(stack.getItem() instanceof IFluxContainerItem) return ((IFluxContainerItem)stack.getItem()).getEnergyStored(stack); if(stack.getItem() instanceof IEnergyContainerItem) return ((IEnergyContainerItem)stack.getItem()).getEnergyStored(stack); if(stack.hasCapability(CapabilityEnergy.ENERGY, null)) return stack.getCapability(CapabilityEnergy.ENERGY, null).getEnergyStored(); return 0; } public static int getMaxEnergyStored(ItemStack stack) { if(stack==null || stack.getItem()==null) return 0; if(stack.getItem() instanceof IFluxContainerItem) return ((IFluxContainerItem)stack.getItem()).getMaxEnergyStored(stack); if(stack.getItem() instanceof IEnergyContainerItem) return ((IEnergyContainerItem)stack.getItem()).getMaxEnergyStored(stack); if(stack.hasCapability(CapabilityEnergy.ENERGY, null)) return stack.getCapability(CapabilityEnergy.ENERGY, null).getMaxEnergyStored(); return 0; } public static int insertFlux(ItemStack stack, int energy, boolean simulate) { if(stack==null || stack.getItem()==null) return 0; if(stack.getItem() instanceof IFluxContainerItem) return ((IFluxContainerItem)stack.getItem()).receiveEnergy(stack, energy, simulate); if(stack.getItem() instanceof IEnergyContainerItem) return ((IEnergyContainerItem)stack.getItem()).receiveEnergy(stack, energy, simulate); if(stack.hasCapability(CapabilityEnergy.ENERGY, null)) return stack.getCapability(CapabilityEnergy.ENERGY, null).receiveEnergy(energy, simulate); return 0; } public static int extractFlux(ItemStack stack, int energy, boolean simulate) { if(stack==null || stack.getItem()==null) return 0; if(stack.getItem() instanceof IFluxContainerItem) return ((IFluxContainerItem)stack.getItem()).extractEnergy(stack, energy, simulate); if(stack.getItem() instanceof IEnergyContainerItem) return ((IEnergyContainerItem)stack.getItem()).extractEnergy(stack, energy, simulate); if(stack.hasCapability(CapabilityEnergy.ENERGY, null)) return stack.getCapability(CapabilityEnergy.ENERGY, null).extractEnergy(energy, simulate); return 0; } static HashMap<Item,Boolean> reverseInsertion = new HashMap<Item,Boolean>(); public static int forceExtractFlux(ItemStack stack, int energy, boolean simulate) { if(stack==null || stack.getItem()==null) return 0; Boolean b = reverseInsertion.get(stack.getItem()); if(b==Boolean.TRUE) { int stored = getEnergyStored(stack); insertFlux(stack, -energy, simulate); return stored-getEnergyStored(stack); } else { int drawn = extractFlux(stack, energy, simulate); if(b==null) { int stored = getEnergyStored(stack); insertFlux(stack, -energy, simulate); drawn = stored-getEnergyStored(stack); //if reverse insertion was succesful, it'll be the default approach in future reverseInsertion.put(stack.getItem(),drawn>0?Boolean.TRUE:Boolean.FALSE); } return drawn; } } public static boolean isFluxReceiver(TileEntity tile, EnumFacing facing) { if(tile == null) return false; if(tile instanceof IFluxReceiver && ((IFluxReceiver)tile).canConnectEnergy(facing)) return true; if(tile instanceof IEnergyReceiver && ((IEnergyReceiver)tile).canConnectEnergy(facing)) return true; if(tile.hasCapability(CapabilityEnergy.ENERGY, facing)) return tile.getCapability(CapabilityEnergy.ENERGY, facing).canReceive(); return false; } public static int insertFlux(TileEntity tile, EnumFacing facing, int energy, boolean simulate) { if(tile == null) return 0; if(tile instanceof IFluxReceiver && ((IFluxReceiver)tile).canConnectEnergy(facing)) return ((IFluxReceiver)tile).receiveEnergy(facing, energy, simulate); if(tile instanceof IEnergyReceiver && ((IEnergyReceiver)tile).canConnectEnergy(facing)) return ((IEnergyReceiver)tile).receiveEnergy(facing, energy, simulate); if(tile.hasCapability(CapabilityEnergy.ENERGY, facing)) return tile.getCapability(CapabilityEnergy.ENERGY, facing).receiveEnergy(energy, simulate); return 0; } public interface IIEInternalFluxHandler extends IIEInternalFluxConnector, IFluxReceiver, IEnergyReceiver, IFluxProvider, IEnergyProvider { @Nonnull FluxStorage getFluxStorage(); default void postEnergyTransferUpdate(int energy, boolean simulate) { } @Override default int extractEnergy(@Nullable EnumFacing fd, int amount, boolean simulate) { if(((TileEntity)this).getWorld().isRemote || getEnergySideConfig(fd) != SideConfig.OUTPUT) return 0; int r = getFluxStorage().extractEnergy(amount, simulate); postEnergyTransferUpdate(-r, simulate); return r; } @Override default int getEnergyStored(@Nullable EnumFacing fd) { return getFluxStorage().getEnergyStored(); } @Override default int getMaxEnergyStored(@Nullable EnumFacing fd) { return getFluxStorage().getMaxEnergyStored(); } @Override default int receiveEnergy(@Nullable EnumFacing fd, int amount, boolean simulate) { if(((TileEntity)this).getWorld().isRemote || getEnergySideConfig(fd) != SideConfig.INPUT) return 0; int r = getFluxStorage().receiveEnergy(amount, simulate); postEnergyTransferUpdate(r, simulate); return r; } } public interface IIEInternalFluxConnector extends IFluxConnection, IEnergyConnection { @Nonnull SideConfig getEnergySideConfig(@Nullable EnumFacing facing); @Override default boolean canConnectEnergy(@Nullable EnumFacing fd) { return getEnergySideConfig(fd) != SideConfig.NONE; } IEForgeEnergyWrapper getCapabilityWrapper(EnumFacing facing); } public static class IEForgeEnergyWrapper implements IEnergyStorage { final IIEInternalFluxConnector fluxHandler; public final EnumFacing side; public IEForgeEnergyWrapper(IIEInternalFluxConnector fluxHandler, EnumFacing side) { this.fluxHandler = fluxHandler; this.side = side; } @Override public int receiveEnergy(int maxReceive, boolean simulate) { if(fluxHandler instanceof IIEInternalFluxHandler) return ((IIEInternalFluxHandler)fluxHandler).receiveEnergy(side, maxReceive, simulate); return 0; } @Override public int extractEnergy(int maxExtract, boolean simulate) { if(fluxHandler instanceof IIEInternalFluxHandler) return ((IIEInternalFluxHandler)fluxHandler).extractEnergy(side, maxExtract, simulate); return 0; } @Override public int getEnergyStored() { if(fluxHandler instanceof IIEInternalFluxHandler) return ((IIEInternalFluxHandler)fluxHandler).getEnergyStored(side); return 0; } @Override public int getMaxEnergyStored() { if(fluxHandler instanceof IIEInternalFluxHandler) return ((IIEInternalFluxHandler)fluxHandler).getMaxEnergyStored(side); return 0; } @Override public boolean canExtract() { if(fluxHandler instanceof IIEInternalFluxHandler) return ((IIEInternalFluxHandler)fluxHandler).getFluxStorage().getLimitExtract() > 0; return false; } @Override public boolean canReceive() { if(fluxHandler instanceof IIEInternalFluxHandler) return ((IIEInternalFluxHandler)fluxHandler).getFluxStorage().getLimitReceive() > 0; return false; } public static IEForgeEnergyWrapper[] getDefaultWrapperArray(IIEInternalFluxConnector handler) { return new IEForgeEnergyWrapper[]{ new IEForgeEnergyWrapper(handler, EnumFacing.DOWN), new IEForgeEnergyWrapper(handler, EnumFacing.UP), new IEForgeEnergyWrapper(handler, EnumFacing.NORTH), new IEForgeEnergyWrapper(handler, EnumFacing.SOUTH), new IEForgeEnergyWrapper(handler, EnumFacing.WEST), new IEForgeEnergyWrapper(handler, EnumFacing.EAST) }; } } }