mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
565 lines
12 KiB
Java
565 lines
12 KiB
Java
package com.hbm.tileentity.machine;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
|
|
import com.google.common.collect.HashBiMap;
|
|
import com.hbm.handler.MultiblockHandlerXR;
|
|
import com.hbm.blocks.BlockDummyable;
|
|
import com.hbm.handler.FluidTypeHandler.FluidType;
|
|
import com.hbm.interfaces.IConsumer;
|
|
import com.hbm.interfaces.IFluidAcceptor;
|
|
import com.hbm.interfaces.ISource;
|
|
import com.hbm.inventory.FluidTank;
|
|
import com.hbm.items.ModItems;
|
|
import com.hbm.lib.Library;
|
|
import com.hbm.tileentity.TileEntityMachineBase;
|
|
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
import net.minecraft.item.Item;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.tileentity.TileEntity;
|
|
import net.minecraft.tileentity.TileEntityFurnace;
|
|
import net.minecraft.util.AxisAlignedBB;
|
|
import net.minecraftforge.common.util.ForgeDirection;
|
|
|
|
public class TileEntityMachineIGenerator extends TileEntityMachineBase implements ISource, IFluidAcceptor {
|
|
|
|
public long power;
|
|
public static final long maxPower = 1000000;
|
|
public int lastBurnTime;
|
|
public int burnTime;
|
|
public int temperature;
|
|
public static final int maxTemperature = 1000;
|
|
public int torque;
|
|
public static final int maxTorque = 10000;
|
|
public float limiter = 0.0F; /// 0 - 1 ///
|
|
|
|
public static final int animSpeed = 50;
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
public float rotation;
|
|
@SideOnly(Side.CLIENT)
|
|
public float prevRotation;
|
|
|
|
public IGenRTG[] pellets = new IGenRTG[12];
|
|
public FluidTank[] tanks;
|
|
|
|
public int age = 0;
|
|
public List<IConsumer> list = new ArrayList();
|
|
|
|
public TileEntityMachineIGenerator() {
|
|
super(15);
|
|
tanks = new FluidTank[3];
|
|
tanks[0] = new FluidTank(FluidType.WATER, 8000, 0);
|
|
tanks[1] = new FluidTank(FluidType.HEATINGOIL, 16000, 1);
|
|
tanks[2] = new FluidTank(FluidType.LUBRICANT, 2000, 2);
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return "container.iGenerator";
|
|
}
|
|
|
|
@Override
|
|
public void updateEntity() {
|
|
|
|
if(!worldObj.isRemote) {
|
|
|
|
age++;
|
|
if (age >= 20) {
|
|
age = 0;
|
|
}
|
|
|
|
if (age == 9 || age == 19)
|
|
ffgeuaInit();
|
|
|
|
tanks[0].loadTank(7, 8, slots);
|
|
tanks[1].loadTank(9, 10, slots);
|
|
tanks[1].setType(11, 12, slots);
|
|
tanks[2].loadTank(13, 14, slots);
|
|
|
|
loadFuel();
|
|
pelletAction();
|
|
|
|
if(burnTime > 0) {
|
|
burnTime --;
|
|
temperature += 100;
|
|
}
|
|
|
|
fuelAction();
|
|
|
|
if(temperature > maxTemperature)
|
|
temperature = maxTemperature;
|
|
|
|
int displayHeat = temperature;
|
|
|
|
rtgAction();
|
|
|
|
rotorAction();
|
|
generatorAction();
|
|
|
|
this.power = Library.chargeItemsFromTE(slots, 6, power, maxPower);
|
|
|
|
NBTTagCompound data = new NBTTagCompound();
|
|
int[] rtgs = new int[pellets.length];
|
|
|
|
for(int i = 0; i < pellets.length; i++) {
|
|
if(pellets[i] != null)
|
|
rtgs[i] = pellets[i].ordinal();
|
|
else
|
|
rtgs[i] = -1;
|
|
}
|
|
|
|
data.setIntArray("rtgs", rtgs);
|
|
data.setInteger("temp", displayHeat);
|
|
data.setInteger("torque", torque);
|
|
data.setInteger("power", (int)power);
|
|
data.setShort("burn", (short) burnTime);
|
|
data.setShort("lastBurn", (short) lastBurnTime);
|
|
data.setFloat("dial", limiter);
|
|
this.networkPack(data, 250);
|
|
|
|
for(int i = 0; i < 3; i++)
|
|
tanks[i].updateTank(xCoord, yCoord, zCoord, this.worldObj.provider.dimensionId);
|
|
} else {
|
|
|
|
this.prevRotation = this.rotation;
|
|
|
|
this.rotation += this.torque * animSpeed / maxTorque;
|
|
|
|
if(this.rotation >= 360) {
|
|
this.rotation -= 360;
|
|
this.prevRotation -= 360;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void networkUnpack(NBTTagCompound nbt) {
|
|
|
|
int[] rtgs = nbt.getIntArray("rtgs");
|
|
|
|
if(rtgs != null) {
|
|
for(int i = 0; i < pellets.length; i++) {
|
|
|
|
int pellet = rtgs[i];
|
|
if(pellet >= 0 && pellet < IGenRTG.values().length) {
|
|
pellets[i] = IGenRTG.values()[pellet];
|
|
} else {
|
|
pellets[i] = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.temperature = nbt.getInteger("temp");
|
|
this.torque = nbt.getInteger("torque");
|
|
this.power = nbt.getInteger("power");
|
|
this.burnTime = nbt.getShort("burn");
|
|
this.lastBurnTime = nbt.getShort("lastBurn");
|
|
|
|
if(ignoreNext <= 0) {
|
|
this.limiter = nbt.getFloat("dial");
|
|
} else {
|
|
ignoreNext--;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void handleButtonPacket(int value, int meta) {
|
|
|
|
if(meta == 0)
|
|
pushPellet();
|
|
if(meta == 1)
|
|
popPellet();
|
|
if(meta == 2)
|
|
setDialByAngle(value);
|
|
}
|
|
|
|
/**
|
|
* Checks for solid fuel and burns it
|
|
*/
|
|
private void loadFuel() {
|
|
|
|
if(this.burnTime <= 0 && slots[0] != null) {
|
|
|
|
int time = TileEntityFurnace.getItemBurnTime(slots[0]) / 2;
|
|
|
|
if(time > 0) {
|
|
|
|
if(slots[0].getItem().hasContainerItem(slots[0]) && slots[0].stackSize == 1) {
|
|
slots[0] = slots[0].getItem().getContainerItem(slots[0]);
|
|
} else {
|
|
this.decrStackSize(0, 1);
|
|
}
|
|
|
|
this.burnTime = time;
|
|
this.lastBurnTime = time;
|
|
|
|
this.markDirty();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates heat from RTG pellets
|
|
*/
|
|
private void pelletAction() {
|
|
|
|
for(int i = 0; i < pellets.length; i++) {
|
|
if(pellets[i] != null)
|
|
this.temperature += pellets[i].heat;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Burns liquid fuel
|
|
*/
|
|
private void fuelAction() {
|
|
|
|
int heat = getHeatFromFuel(tanks[1].getTankType());
|
|
|
|
int maxBurn = 2;
|
|
|
|
if(tanks[1].getFill() > 0) {
|
|
|
|
int burn = Math.min(maxBurn, tanks[1].getFill());
|
|
|
|
tanks[1].setFill(tanks[1].getFill() - burn);
|
|
temperature += heat * burn;
|
|
}
|
|
}
|
|
|
|
public int getHeatFromFuel(FluidType type) {
|
|
|
|
switch(type) {
|
|
case SMEAR: return 75;
|
|
case HEATINGOIL: return 150;
|
|
case DIESEL: return 225;
|
|
case KEROSENE: return 300;
|
|
case RECLAIMED: return 100;
|
|
case PETROIL: return 125;
|
|
case BIOFUEL: return 200;
|
|
case NITAN: return 2500;
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* does the thing with the thermo elements
|
|
*/
|
|
private void rtgAction() {
|
|
|
|
int rtg = 0;
|
|
|
|
for(int i = 3; i <= 5; i++) {
|
|
|
|
if(slots[i] != null && slots[i].getItem() == ModItems.thermo_element)
|
|
rtg += 15;
|
|
}
|
|
|
|
int pow = Math.min(this.temperature, rtg);
|
|
|
|
this.temperature -= pow;
|
|
this.power += pow;
|
|
|
|
if(power > maxPower)
|
|
power = maxPower;
|
|
}
|
|
|
|
/**
|
|
* Turns heat into rotational energy
|
|
*/
|
|
private void rotorAction() {
|
|
|
|
int conversion = getConversion();
|
|
|
|
if(temperature > 10 && tanks[0].getFill() > 0)
|
|
tanks[0].setFill(tanks[0].getFill() - 1);
|
|
|
|
if(torque > 10 && tanks[2].getFill() > 0 && worldObj.rand.nextInt(2) == 0)
|
|
tanks[2].setFill(tanks[2].getFill() - 1);
|
|
|
|
this.torque += conversion * (tanks[0].getFill() > 0 ? 1.5 : 1);
|
|
this.temperature -= conversion;
|
|
|
|
if(torque > maxTorque)
|
|
worldObj.createExplosion(null, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, 5, true);
|
|
}
|
|
|
|
/**
|
|
* Do the power stuff
|
|
*/
|
|
private void generatorAction() {
|
|
|
|
double balanceFactor = 0.025D;
|
|
|
|
this.power += this.torque * balanceFactor;
|
|
torque -= getBrake();
|
|
|
|
if(power > maxPower)
|
|
power = maxPower;
|
|
}
|
|
|
|
public int getBrake() {
|
|
return (int) Math.ceil(torque * 0.1 * (tanks[2].getFill() > 0 ? 0.5 : 1));
|
|
}
|
|
|
|
public int getConversion() {
|
|
return (int) (temperature * limiter);
|
|
}
|
|
|
|
/**
|
|
* Adds a pellet onto the pile
|
|
*/
|
|
private void pushPellet() {
|
|
|
|
if(pellets[11] != null)
|
|
return;
|
|
|
|
if(slots[1] != null) {
|
|
|
|
IGenRTG pellet = IGenRTG.getPellet(slots[1].getItem());
|
|
|
|
if(pellet != null) {
|
|
|
|
for(int i = 0; i < pellets.length; i++) {
|
|
|
|
if(pellets[i] == null) {
|
|
pellets[i] = pellet;
|
|
this.decrStackSize(1, 1);
|
|
|
|
this.markDirty();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes a pellet from the bottom of the pile
|
|
*/
|
|
private void popPellet() {
|
|
|
|
if(slots[2] != null)
|
|
return;
|
|
|
|
if(pellets[0] == null)
|
|
return;
|
|
|
|
//i don't feel like adding null checks because they won't trigger anyway
|
|
slots[2] = new ItemStack(this.rtgPellets.inverse().get(pellets[0]));
|
|
|
|
for(int i = 0; i < pellets.length - 1; i++) {
|
|
pellets[i] = pellets[i + 1];
|
|
}
|
|
|
|
pellets[pellets.length - 1] = null;
|
|
|
|
this.markDirty();
|
|
}
|
|
|
|
public double getSolidGauge() {
|
|
return (double) burnTime / (double) lastBurnTime;
|
|
}
|
|
|
|
public double getPowerGauge() {
|
|
return (double) power / (double) maxPower;
|
|
}
|
|
|
|
public double getTempGauge() {
|
|
return (double) temperature / (double) maxTemperature;
|
|
}
|
|
|
|
public double getTorqueGauge() {
|
|
return (double) torque / (double) maxTorque;
|
|
}
|
|
|
|
public float getAngleFromDial() {
|
|
return (45F + limiter * 270F) % 360F;
|
|
}
|
|
|
|
int ignoreNext = 0;
|
|
public void setDialByAngle(float angle) {
|
|
this.limiter = (angle - 45F) / 270F;
|
|
ignoreNext = 5;
|
|
}
|
|
|
|
@Override
|
|
public void ffgeuaInit() {
|
|
|
|
ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - BlockDummyable.offset);
|
|
|
|
int[] rot = MultiblockHandlerXR.rotate(new int [] {1,0,2,2,8,8}, dir);
|
|
|
|
boolean tact = this.getTact();
|
|
|
|
for(int iy = 0; iy <= 1; iy++) {
|
|
for(int ix = -rot[4]; ix <= rot[5]; ix++) {
|
|
for(int iz = -rot[2]; iz <= rot[3]; iz++) {
|
|
|
|
if(ix == -rot[4] || ix == rot[5] || iz == -rot[2] || iz == rot[3]) {
|
|
|
|
ffgeua(xCoord + dir.offsetX * 2 + ix, yCoord + iy, zCoord + dir.offsetZ * 2 + iz, tact);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void ffgeua(int x, int y, int z, boolean newTact) {
|
|
Library.ffgeua(x, y, z, newTact, this, worldObj);
|
|
}
|
|
|
|
@Override
|
|
public boolean getTact() {
|
|
if (age >= 0 && age < 10) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public long getSPower() {
|
|
return this.power;
|
|
}
|
|
|
|
@Override
|
|
public void setSPower(long i) {
|
|
this.power = i;
|
|
}
|
|
|
|
@Override
|
|
public List<IConsumer> getList() {
|
|
return this.list;
|
|
}
|
|
|
|
@Override
|
|
public void clearList() {
|
|
this.list.clear();
|
|
}
|
|
|
|
@Override
|
|
public void setFillstate(int fill, int index) {
|
|
tanks[index].setFill(fill);
|
|
}
|
|
|
|
@Override
|
|
public void setFluidFill(int fill, FluidType type) {
|
|
|
|
if(type == FluidType.WATER)
|
|
tanks[0].setFill(fill);
|
|
else if(type == FluidType.LUBRICANT)
|
|
tanks[2].setFill(fill);
|
|
else if(tanks[1].getTankType() == type)
|
|
tanks[1].setFill(fill);
|
|
}
|
|
|
|
@Override
|
|
public void setType(FluidType type, int index) {
|
|
tanks[index].setTankType(type);
|
|
}
|
|
|
|
@Override
|
|
public List<FluidTank> getTanks() {
|
|
return Arrays.asList(tanks);
|
|
}
|
|
|
|
@Override
|
|
public int getFluidFill(FluidType type) {
|
|
|
|
for(int i = 0; i < 3; i++)
|
|
if(tanks[i].getTankType() == type)
|
|
return tanks[i].getFill();
|
|
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public int getMaxFluidFill(FluidType type) {
|
|
|
|
for(int i = 0; i < 3; i++)
|
|
if(tanks[i].getTankType() == type)
|
|
return tanks[i].getMaxFill();
|
|
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void readFromNBT(NBTTagCompound nbt) {
|
|
super.readFromNBT(nbt);
|
|
|
|
for(int i = 0; i < pellets.length; i++) {
|
|
|
|
short s = nbt.getShort("pellet" + i);
|
|
|
|
if(s >= 0 && s < IGenRTG.values().length) {
|
|
pellets[i] = IGenRTG.values()[s];
|
|
} else {
|
|
pellets[i] = null;
|
|
}
|
|
}
|
|
|
|
this.burnTime = nbt.getInteger("burn");
|
|
this.lastBurnTime = nbt.getInteger("lastBurn");
|
|
this.limiter = nbt.getFloat("limiter");
|
|
}
|
|
|
|
@Override
|
|
public void writeToNBT(NBTTagCompound nbt) {
|
|
super.writeToNBT(nbt);
|
|
|
|
for(int i = 0; i < pellets.length; i++) {
|
|
|
|
if(pellets[i] != null) {
|
|
nbt.setShort("pellet" + i, (short) pellets[i].ordinal());
|
|
} else {
|
|
nbt.setShort("pellet" + i, (short)-1);
|
|
}
|
|
}
|
|
|
|
nbt.setInteger("burn", burnTime);
|
|
nbt.setInteger("lastBurn", lastBurnTime);
|
|
nbt.setFloat("limiter", limiter);
|
|
}
|
|
|
|
private static HashBiMap<Item, IGenRTG> rtgPellets = HashBiMap.create();
|
|
|
|
public static enum IGenRTG {
|
|
PLUTONIUM(ModItems.pellet_rtg, 0, 5),
|
|
URANIUM(ModItems.pellet_rtg_weak, 9, 3),
|
|
POLONIUM(ModItems.pellet_rtg_polonium, 18, 25);
|
|
|
|
public int offset;
|
|
public int heat;
|
|
|
|
private IGenRTG(Item item, int offset, int heat) {
|
|
rtgPellets.put(item, this);
|
|
this.offset = offset;
|
|
this.heat = heat;
|
|
}
|
|
|
|
public static IGenRTG getPellet(Item item) {
|
|
return rtgPellets.get(item);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public AxisAlignedBB getRenderBoundingBox() {
|
|
return TileEntity.INFINITE_EXTENT_AABB;
|
|
}
|
|
|
|
@Override
|
|
@SideOnly(Side.CLIENT)
|
|
public double getMaxRenderDistanceSquared()
|
|
{
|
|
return 65536.0D;
|
|
}
|
|
}
|