385 lines
10 KiB
Java
385 lines
10 KiB
Java
package universalelectricity.compatibility;
|
|
|
|
import ic2.api.energy.event.EnergyTileLoadEvent;
|
|
import ic2.api.energy.event.EnergyTileUnloadEvent;
|
|
import ic2.api.energy.tile.IEnergySink;
|
|
import ic2.api.energy.tile.IEnergySource;
|
|
import ic2.api.energy.tile.IEnergyTile;
|
|
import ic2.api.item.IElectricItemManager;
|
|
import ic2.api.item.ISpecialElectricItem;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.tileentity.TileEntity;
|
|
import net.minecraft.world.World;
|
|
import net.minecraftforge.common.ForgeDirection;
|
|
import net.minecraftforge.common.MinecraftForge;
|
|
import universalelectricity.core.electricity.ElectricityPack;
|
|
import universalelectricity.core.item.IItemElectric;
|
|
import universalelectricity.core.vector.Vector3;
|
|
import universalelectricity.prefab.tile.TileEntityElectrical;
|
|
import buildcraft.api.power.IPowerReceptor;
|
|
import buildcraft.api.power.PowerHandler;
|
|
import buildcraft.api.power.PowerHandler.PowerReceiver;
|
|
import buildcraft.api.power.PowerHandler.Type;
|
|
import cofh.api.energy.IEnergyContainerItem;
|
|
import cofh.api.energy.IEnergyHandler;
|
|
|
|
/**
|
|
* A universal electricity tile used for tiles that consume or produce electricity.
|
|
*
|
|
* Extend this class or use as a reference for your own implementation of compatible electrical
|
|
* tiles.
|
|
*
|
|
* @author micdoodle8, Calclavia
|
|
*
|
|
*/
|
|
public abstract class TileEntityUniversalElectrical extends TileEntityElectrical implements IEnergySink, IEnergySource, IPowerReceptor, IEnergyHandler
|
|
{
|
|
protected boolean isAddedToEnergyNet;
|
|
public PowerHandler bcPowerHandler;
|
|
public Type bcBlockType = Type.MACHINE;
|
|
public float maxInputEnergy = 100;
|
|
|
|
/**
|
|
* Recharges electric item.
|
|
*/
|
|
@Override
|
|
public void recharge(ItemStack itemStack)
|
|
{
|
|
if (itemStack != null)
|
|
{
|
|
if (itemStack.getItem() instanceof IItemElectric)
|
|
{
|
|
super.recharge(itemStack);
|
|
}
|
|
else if (itemStack.getItem() instanceof ISpecialElectricItem)
|
|
{
|
|
ISpecialElectricItem electricItem = (ISpecialElectricItem) itemStack.getItem();
|
|
IElectricItemManager manager = electricItem.getManager(itemStack);
|
|
float energy = Math.max(this.getProvide(ForgeDirection.UNKNOWN) * Compatibility.IC2_RATIO, 0);
|
|
energy = manager.charge(itemStack, (int) (energy * Compatibility.TO_IC2_RATIO), 0, false, false) * Compatibility.IC2_RATIO;
|
|
this.provideElectricity(energy, true);
|
|
}
|
|
else if (itemStack.getItem() instanceof IEnergyContainerItem)
|
|
{
|
|
float forgienEnergyAccepted = ((IEnergyContainerItem) itemStack.getItem()).receiveEnergy(itemStack, (int) (this.getProvide(ForgeDirection.UNKNOWN) * Compatibility.TO_TE_RATIO), false);
|
|
this.provideElectricity(forgienEnergyAccepted * Compatibility.TE_RATIO, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Discharges electric item.
|
|
*/
|
|
@Override
|
|
public void discharge(ItemStack itemStack)
|
|
{
|
|
if (itemStack != null)
|
|
{
|
|
if (itemStack.getItem() instanceof IItemElectric)
|
|
{
|
|
super.discharge(itemStack);
|
|
}
|
|
else if (itemStack.getItem() instanceof ISpecialElectricItem)
|
|
{
|
|
ISpecialElectricItem electricItem = (ISpecialElectricItem) itemStack.getItem();
|
|
|
|
if (electricItem.canProvideEnergy(itemStack))
|
|
{
|
|
IElectricItemManager manager = electricItem.getManager(itemStack);
|
|
float energy = Math.max(this.getRequest(ForgeDirection.UNKNOWN) * Compatibility.IC2_RATIO, 0);
|
|
energy = manager.discharge(itemStack, (int) (energy * Compatibility.TO_IC2_RATIO), 0, false, false);
|
|
this.receiveElectricity(energy, true);
|
|
}
|
|
}
|
|
else if (itemStack.getItem() instanceof IEnergyContainerItem)
|
|
{
|
|
float forgienEnergy = ((IEnergyContainerItem) itemStack.getItem()).extractEnergy(itemStack, (int) (this.getRequest(ForgeDirection.UNKNOWN) * Compatibility.TO_TE_RATIO), false);
|
|
this.receiveElectricity(forgienEnergy * Compatibility.TE_RATIO, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void initiate()
|
|
{
|
|
super.initiate();
|
|
this.initBuildCraft();
|
|
}
|
|
|
|
@Override
|
|
public void updateEntity()
|
|
{
|
|
super.updateEntity();
|
|
|
|
// Register to the IC2 Network
|
|
if (!this.worldObj.isRemote)
|
|
{
|
|
if (!this.isAddedToEnergyNet)
|
|
{
|
|
this.initIC();
|
|
}
|
|
|
|
if (this.bcPowerHandler == null)
|
|
{
|
|
this.initBuildCraft();
|
|
}
|
|
|
|
if (Compatibility.isBuildcraftLoaded())
|
|
{
|
|
if (this.bcPowerHandler.getEnergyStored() > 0)
|
|
{
|
|
/**
|
|
* Cheat BuildCraft powerHandler and always empty energy inside of it.
|
|
*/
|
|
this.receiveElectricity(this.bcPowerHandler.getEnergyStored() * Compatibility.BC3_RATIO, true);
|
|
this.bcPowerHandler.setEnergy(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void produce()
|
|
{
|
|
if (!this.worldObj.isRemote)
|
|
{
|
|
for (ForgeDirection outputDirection : this.getOutputDirections())
|
|
{
|
|
if (outputDirection != ForgeDirection.UNKNOWN)
|
|
{
|
|
if (!this.produceUE(outputDirection))
|
|
{
|
|
if (!this.produceThermalExpansion(outputDirection))
|
|
{
|
|
this.produceBuildCraft(outputDirection);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean produceThermalExpansion(ForgeDirection outputDirection)
|
|
{
|
|
if (!this.worldObj.isRemote && outputDirection != null && outputDirection != ForgeDirection.UNKNOWN)
|
|
{
|
|
float provide = this.getProvide(outputDirection);
|
|
|
|
if (this.getEnergyStored() >= provide && provide > 0)
|
|
{
|
|
if (Compatibility.isThermalExpansionLoaded())
|
|
{
|
|
TileEntity tileEntity = new Vector3(this).modifyPositionFromSide(outputDirection).getTileEntity(this.worldObj);
|
|
|
|
if (tileEntity instanceof IEnergyHandler)
|
|
{
|
|
IEnergyHandler receiver = (IEnergyHandler) tileEntity;
|
|
int convertedProvide = (int) (provide * Compatibility.TO_TE_RATIO);
|
|
|
|
if (receiver.canInterface(outputDirection.getOpposite()) && receiver.receiveEnergy(outputDirection.getOpposite(), convertedProvide, true) > 0)
|
|
{
|
|
int forgienEnergyUsed = receiver.receiveEnergy(outputDirection.getOpposite(), convertedProvide, false);
|
|
this.provideElectricity(forgienEnergyUsed * Compatibility.TE_RATIO, true);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public boolean produceBuildCraft(ForgeDirection outputDirection)
|
|
{
|
|
if (!this.worldObj.isRemote && outputDirection != null && outputDirection != ForgeDirection.UNKNOWN)
|
|
{
|
|
float provide = this.getProvide(outputDirection);
|
|
|
|
if (this.getEnergyStored() >= provide && provide > 0)
|
|
{
|
|
if (Compatibility.isBuildcraftLoaded())
|
|
{
|
|
TileEntity tileEntity = new Vector3(this).modifyPositionFromSide(outputDirection).getTileEntity(this.worldObj);
|
|
|
|
if (tileEntity instanceof IPowerReceptor)
|
|
{
|
|
PowerReceiver receiver = ((IPowerReceptor) tileEntity).getPowerReceiver(outputDirection.getOpposite());
|
|
|
|
if (receiver != null)
|
|
{
|
|
if (receiver.powerRequest() > 0)
|
|
{
|
|
float convertedProvide = provide * Compatibility.TO_BC_RATIO;
|
|
float forgienEnergyUsed = receiver.receiveEnergy(this.bcBlockType, convertedProvide, outputDirection.getOpposite());
|
|
this.provideElectricity(forgienEnergyUsed * Compatibility.BC3_RATIO, true);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* TE Methods
|
|
*/
|
|
public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate)
|
|
{
|
|
return (int) (this.receiveElectricity(from, ElectricityPack.getFromWatts(maxReceive * Compatibility.TE_RATIO, this.getVoltage()), !simulate) * Compatibility.TO_TE_RATIO);
|
|
}
|
|
|
|
public int extractEnergy(ForgeDirection from, int maxExtract, boolean simulate)
|
|
{
|
|
return (int) (this.provideElectricity(from, ElectricityPack.getFromWatts(maxExtract * Compatibility.TE_RATIO, this.getVoltage()), !simulate).getWatts() * Compatibility.TO_TE_RATIO);
|
|
}
|
|
|
|
public boolean canInterface(ForgeDirection from)
|
|
{
|
|
return this.canConnect(from);
|
|
}
|
|
|
|
/**
|
|
* Returns the amount of energy currently stored.
|
|
*/
|
|
public int getEnergyStored(ForgeDirection from)
|
|
{
|
|
return (int) (this.getEnergyStored() * Compatibility.TO_TE_RATIO);
|
|
}
|
|
|
|
/**
|
|
* Returns the maximum amount of energy that can be stored.
|
|
*/
|
|
public int getMaxEnergyStored(ForgeDirection from)
|
|
{
|
|
return (int) (this.getMaxEnergyStored() * Compatibility.TO_TE_RATIO);
|
|
}
|
|
|
|
/**
|
|
* IC2 Methods
|
|
*/
|
|
@Override
|
|
public boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction)
|
|
{
|
|
return this.getInputDirections().contains(direction);
|
|
}
|
|
|
|
@Override
|
|
public double getOfferedEnergy()
|
|
{
|
|
return this.getProvide(ForgeDirection.UNKNOWN) * Compatibility.TO_IC2_RATIO;
|
|
}
|
|
|
|
@Override
|
|
public void drawEnergy(double amount)
|
|
{
|
|
this.provideElectricity((float) amount * Compatibility.IC2_RATIO, true);
|
|
}
|
|
|
|
@Override
|
|
public void invalidate()
|
|
{
|
|
this.unloadTileIC2();
|
|
super.invalidate();
|
|
}
|
|
|
|
@Override
|
|
public void onChunkUnload()
|
|
{
|
|
this.unloadTileIC2();
|
|
super.onChunkUnload();
|
|
}
|
|
|
|
protected void initIC()
|
|
{
|
|
if (Compatibility.isIndustrialCraft2Loaded())
|
|
{
|
|
MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
|
|
}
|
|
|
|
this.isAddedToEnergyNet = true;
|
|
}
|
|
|
|
private void unloadTileIC2()
|
|
{
|
|
if (this.isAddedToEnergyNet && this.worldObj != null)
|
|
{
|
|
if (Compatibility.isIndustrialCraft2Loaded())
|
|
{
|
|
MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
|
|
}
|
|
|
|
this.isAddedToEnergyNet = false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public double demandedEnergyUnits()
|
|
{
|
|
return this.getRequest(ForgeDirection.UNKNOWN) * Compatibility.TO_IC2_RATIO;
|
|
}
|
|
|
|
@Override
|
|
public double injectEnergyUnits(ForgeDirection direction, double amount)
|
|
{
|
|
if (this.getInputDirections().contains(direction))
|
|
{
|
|
float convertedEnergy = (float) (amount * Compatibility.IC2_RATIO);
|
|
ElectricityPack toSend = ElectricityPack.getFromWatts(convertedEnergy, this.getVoltage());
|
|
float receive = this.receiveElectricity(direction, toSend, true);
|
|
|
|
// Return the difference, since injectEnergy returns left over energy, and
|
|
// receiveElectricity returns energy used.
|
|
return Math.round(amount - (receive * Compatibility.TO_IC2_RATIO));
|
|
}
|
|
|
|
return amount;
|
|
}
|
|
|
|
@Override
|
|
public boolean emitsEnergyTo(TileEntity receiver, ForgeDirection direction)
|
|
{
|
|
return receiver instanceof IEnergyTile && this.getOutputDirections().contains(direction);
|
|
}
|
|
|
|
@Override
|
|
public int getMaxSafeInput()
|
|
{
|
|
return Integer.MAX_VALUE;
|
|
}
|
|
|
|
/**
|
|
* BuildCraft power support
|
|
*/
|
|
public void initBuildCraft()
|
|
{
|
|
if (this.bcPowerHandler == null)
|
|
{
|
|
this.bcPowerHandler = new PowerHandler(this, this.bcBlockType);
|
|
}
|
|
this.bcPowerHandler.configure(0, this.maxInputEnergy, 0, (int) Math.ceil(this.getMaxEnergyStored() * Compatibility.BC3_RATIO));
|
|
}
|
|
|
|
@Override
|
|
public PowerReceiver getPowerReceiver(ForgeDirection side)
|
|
{
|
|
this.initBuildCraft();
|
|
return this.bcPowerHandler.getPowerReceiver();
|
|
}
|
|
|
|
@Override
|
|
public void doWork(PowerHandler workProvider)
|
|
{
|
|
|
|
}
|
|
|
|
@Override
|
|
public World getWorld()
|
|
{
|
|
return this.getWorldObj();
|
|
}
|
|
}
|