422 lines
10 KiB
Java
422 lines
10 KiB
Java
package resonantinduction.core.prefab.tile;
|
|
|
|
import java.util.EnumSet;
|
|
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.NBTBase;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.nbt.NBTTagFloat;
|
|
import net.minecraft.nbt.NBTTagLong;
|
|
import net.minecraft.tileentity.TileEntity;
|
|
import net.minecraftforge.common.ForgeDirection;
|
|
import net.minecraftforge.oredict.OreDictionary;
|
|
import universalelectricity.api.CompatibilityModule;
|
|
import universalelectricity.api.electricity.IVoltageInput;
|
|
import universalelectricity.api.electricity.IVoltageOutput;
|
|
import universalelectricity.api.energy.IEnergyContainer;
|
|
import universalelectricity.api.energy.IEnergyInterface;
|
|
import universalelectricity.api.vector.Vector3;
|
|
import universalelectricity.api.vector.VectorHelper;
|
|
import dark.lib.interfaces.IPowerLess;
|
|
|
|
/**
|
|
* Basic energy tile that can consume power
|
|
*
|
|
* Based off both UE universal electrical tile, and electrical tile prefabs
|
|
*
|
|
* @author DarkGuardsman
|
|
*/
|
|
public abstract class TileEntityEnergyMachine extends TileEntityMachine implements IEnergyInterface, IEnergyContainer, IPowerLess, IVoltageInput, IVoltageOutput
|
|
{
|
|
/** Forge Ore Directory name of the item to toggle infinite power mode */
|
|
public static String powerToggleItemID = "battery";
|
|
/** Demand per tick in watts */
|
|
protected long JOULES_PER_TICK;
|
|
/** Max limit of the internal battery/buffer of the machine */
|
|
protected long MAX_JOULES_STORED;
|
|
/** Current energy stored in the machine's battery/buffer */
|
|
protected long energyStored = 0;
|
|
/** Should we run without power */
|
|
private boolean runWithoutPower = true;
|
|
/** Point by which this machines suffers low voltage damage */
|
|
protected long brownOutVoltage = -1;
|
|
/** Point by which this machines suffers over voltage damage */
|
|
protected long shortOutVoltage = -1;
|
|
/** Voltage by which the machine was designed and rated for */
|
|
protected long ratedVoltage = 240;
|
|
|
|
public TileEntityEnergyMachine()
|
|
{
|
|
this.brownOutVoltage = this.getVoltage() / 2;
|
|
this.shortOutVoltage = (long) ((Math.sqrt(2) * this.getVoltage()) + 0.05 * this.getVoltage());
|
|
}
|
|
|
|
public TileEntityEnergyMachine(long wattsPerTick)
|
|
{
|
|
this();
|
|
this.JOULES_PER_TICK = wattsPerTick;
|
|
this.MAX_JOULES_STORED = wattsPerTick * 20;
|
|
}
|
|
|
|
public TileEntityEnergyMachine(long wattsPerTick, long maxEnergy)
|
|
{
|
|
this(wattsPerTick);
|
|
this.MAX_JOULES_STORED = maxEnergy;
|
|
}
|
|
|
|
@Override
|
|
public void updateEntity()
|
|
{
|
|
super.updateEntity();
|
|
if (!this.worldObj.isRemote && this.isFunctioning())
|
|
{
|
|
this.consumePower(this.JOULES_PER_TICK, true);
|
|
}
|
|
}
|
|
|
|
/** Does this tile have power to run and do work */
|
|
@Override
|
|
public boolean canFunction()
|
|
{
|
|
return super.canFunction() && (this.runPowerLess() || this.consumePower(this.JOULES_PER_TICK, false));
|
|
}
|
|
|
|
/** Called when a player activates the tile's block */
|
|
public boolean onPlayerActivated(EntityPlayer player)
|
|
{
|
|
if (player != null && player.capabilities.isCreativeMode)
|
|
{
|
|
ItemStack itemStack = player.getHeldItem();
|
|
if (itemStack != null)
|
|
{
|
|
for (ItemStack stack : OreDictionary.getOres(powerToggleItemID))
|
|
{
|
|
if (stack.isItemEqual(itemStack))
|
|
{
|
|
this.togglePowerMode();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void updateContainingBlockInfo()
|
|
{
|
|
super.updateContainingBlockInfo();
|
|
// TODO use this to reset any values that are based on the block as this gets called when
|
|
// the block changes
|
|
}
|
|
|
|
/* ********************************************
|
|
* Electricity logic
|
|
* *********************************************
|
|
*/
|
|
|
|
@Override
|
|
public long onReceiveEnergy(ForgeDirection from, long receive, boolean doReceive)
|
|
{
|
|
if (!this.runPowerLess() && this.getInputDirections().contains(from) && receive > 0)
|
|
{
|
|
long prevEnergyStored = Math.max(this.getEnergy(from), 0);
|
|
long newStoredEnergy = Math.min(this.getEnergy(from) + receive, this.getEnergyCapacity(from));
|
|
if (doReceive)
|
|
{
|
|
this.setEnergy(from, newStoredEnergy);
|
|
}
|
|
|
|
return Math.max(newStoredEnergy - prevEnergyStored, 0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/** Called to consume power from the internal storage */
|
|
protected boolean consumePower(long watts, boolean doDrain)
|
|
{
|
|
if (watts <= 0)
|
|
{
|
|
return true;
|
|
}
|
|
if (!this.runPowerLess() && this.getEnergy(ForgeDirection.UNKNOWN) >= watts)
|
|
{
|
|
if (doDrain)
|
|
{
|
|
this.setEnergy(ForgeDirection.UNKNOWN, this.getEnergyStored() - watts);
|
|
}
|
|
return true;
|
|
}
|
|
return this.runPowerLess();
|
|
}
|
|
|
|
@Override
|
|
public long onExtractEnergy(ForgeDirection from, long request, boolean doExtract)
|
|
{
|
|
if (this.getOutputDirections().contains(from) && request > 0)
|
|
{
|
|
long requestedEnergy = Math.min(request, this.energyStored);
|
|
if (doExtract)
|
|
{
|
|
this.setEnergy(from, this.energyStored - requestedEnergy);
|
|
}
|
|
return requestedEnergy;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/** Called to produce power using the output enumset for directions to output in */
|
|
protected void produce()
|
|
{
|
|
for (ForgeDirection direction : this.getOutputDirections())
|
|
{
|
|
if (direction != ForgeDirection.UNKNOWN)
|
|
{
|
|
TileEntity entity = VectorHelper.getTileEntityFromSide(this.worldObj, new Vector3(this), direction);
|
|
if (CompatibilityModule.canConnect(entity, direction.getOpposite()))
|
|
{
|
|
long output = this.onExtractEnergy(direction, this.JOULES_PER_TICK, false);
|
|
long input = CompatibilityModule.receiveEnergy(entity, direction.getOpposite(), output, true);
|
|
if (input > 0 && this.onExtractEnergy(direction, input, true) > 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public long getVoltageInput(ForgeDirection direction)
|
|
{
|
|
if (this.getInputDirections().contains(direction))
|
|
{
|
|
return this.ratedVoltage;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void onWrongVoltage(ForgeDirection direction, long voltage)
|
|
{
|
|
if (voltage > this.ratedVoltage)
|
|
{
|
|
if (voltage > this.shortOutVoltage)
|
|
{
|
|
// TODO damage machine
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (voltage < this.brownOutVoltage)
|
|
{
|
|
// TODO cause machine to run slow
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public long getVoltageOutput(ForgeDirection direction)
|
|
{
|
|
if (this.getOutputDirections().contains(direction))
|
|
{
|
|
return this.ratedVoltage;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* ********************************************
|
|
* Electricity connection logic
|
|
* *********************************************
|
|
*/
|
|
|
|
@Override
|
|
public boolean canConnect(ForgeDirection direction)
|
|
{
|
|
if (direction == null || direction.equals(ForgeDirection.UNKNOWN))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return this.getInputDirections().contains(direction) || this.getOutputDirections().contains(direction);
|
|
}
|
|
|
|
/**
|
|
* The electrical input direction.
|
|
*
|
|
* @return The direction that electricity is entered into the tile. Return null for no input. By
|
|
* default you can accept power from all sides.
|
|
*/
|
|
public EnumSet<ForgeDirection> getInputDirections()
|
|
{
|
|
return EnumSet.allOf(ForgeDirection.class);
|
|
}
|
|
|
|
/**
|
|
* The electrical output direction.
|
|
*
|
|
* @return The direction that electricity is output from the tile. Return null for no output. By
|
|
* default it will return an empty EnumSet.
|
|
*/
|
|
public EnumSet<ForgeDirection> getOutputDirections()
|
|
{
|
|
return EnumSet.noneOf(ForgeDirection.class);
|
|
}
|
|
|
|
/* ********************************************
|
|
* Machine energy parms
|
|
* *********************************************
|
|
*/
|
|
|
|
public long getVoltage()
|
|
{
|
|
return this.ratedVoltage;
|
|
}
|
|
|
|
public TileEntityEnergyMachine setVoltage(long volts)
|
|
{
|
|
this.ratedVoltage = volts;
|
|
return this;
|
|
}
|
|
|
|
public long getMaxEnergyStored()
|
|
{
|
|
return this.MAX_JOULES_STORED;
|
|
}
|
|
|
|
@Override
|
|
public long getEnergyCapacity(ForgeDirection from)
|
|
{
|
|
if (this.canConnect(from) || from == ForgeDirection.UNKNOWN)
|
|
{
|
|
return this.getMaxEnergyStored();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public void setMaxEnergyStored(long energy)
|
|
{
|
|
this.MAX_JOULES_STORED = energy;
|
|
}
|
|
|
|
public long getEnergyStored()
|
|
{
|
|
return this.energyStored;
|
|
}
|
|
|
|
@Override
|
|
public void setEnergy(ForgeDirection from, long energy)
|
|
{
|
|
if (this.canConnect(from) || from == ForgeDirection.UNKNOWN)
|
|
{
|
|
this.energyStored = Math.max(Math.min(energy, this.getMaxEnergyStored()), 0);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public long getEnergy(ForgeDirection from)
|
|
{
|
|
if (this.canConnect(from) || from == ForgeDirection.UNKNOWN)
|
|
{
|
|
return this.energyStored;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public boolean runPowerLess()
|
|
{
|
|
return !runWithoutPower;
|
|
}
|
|
|
|
@Override
|
|
public void setPowerLess(boolean bool)
|
|
{
|
|
runWithoutPower = !bool;
|
|
}
|
|
|
|
public void togglePowerMode()
|
|
{
|
|
this.setPowerLess(!this.runPowerLess());
|
|
}
|
|
|
|
public long getJoulesPerTick()
|
|
{
|
|
return this.JOULES_PER_TICK;
|
|
}
|
|
|
|
public long getJoulesPerSec()
|
|
{
|
|
return getJoulesPerTick() * 20;
|
|
}
|
|
|
|
public long getJoulesPerMin()
|
|
{
|
|
return getJoulesPerSec() * 60;
|
|
}
|
|
|
|
public long getJoulesPerHour()
|
|
{
|
|
return getJoulesPerMin() * 60;
|
|
}
|
|
|
|
public TileEntityEnergyMachine setJoulesPerTick(long energy)
|
|
{
|
|
this.JOULES_PER_TICK = energy;
|
|
return this;
|
|
}
|
|
|
|
public TileEntityEnergyMachine setJoulesPerSecound(long energy)
|
|
{
|
|
this.JOULES_PER_TICK = energy / 20;
|
|
return this;
|
|
}
|
|
|
|
public TileEntityEnergyMachine setJoulesPerMin(long energy)
|
|
{
|
|
this.JOULES_PER_TICK = energy / 1200;
|
|
return this;
|
|
}
|
|
|
|
public TileEntityEnergyMachine setJoulesPerHour(long energy)
|
|
{
|
|
this.JOULES_PER_TICK = energy / 72000;
|
|
return this;
|
|
}
|
|
|
|
/* ********************************************
|
|
* DATA/SAVE/LOAD
|
|
* *********************************************
|
|
*/
|
|
|
|
@Override
|
|
public void readFromNBT(NBTTagCompound nbt)
|
|
{
|
|
super.readFromNBT(nbt);
|
|
|
|
NBTBase tag = nbt.getTag("energyStored");
|
|
if (tag instanceof NBTTagFloat)
|
|
{
|
|
this.energyStored = (long) nbt.getFloat("energyStored") * 1000;
|
|
}
|
|
else if (tag instanceof NBTTagLong)
|
|
{
|
|
this.energyStored = nbt.getLong("energyStored");
|
|
}
|
|
|
|
runWithoutPower = !nbt.getBoolean("shouldPower");
|
|
this.functioning = nbt.getBoolean("isRunning");
|
|
}
|
|
|
|
@Override
|
|
public void writeToNBT(NBTTagCompound nbt)
|
|
{
|
|
super.writeToNBT(nbt);
|
|
nbt.setBoolean("shouldPower", !runWithoutPower);
|
|
nbt.setLong("energyStored", this.getEnergyStored());
|
|
nbt.setBoolean("isRunning", this.functioning);
|
|
}
|
|
|
|
}
|