/* * Copyright (c) CovertJaguar, 2014 http://railcraft.info * * This code is the property of CovertJaguar * and may only be used with explicit written * permission unless otherwise specified on the * license page at http://railcraft.info/wiki/info:license. */ package mods.railcraft.common.blocks.machine.beta; import buildcraft.api.tools.IToolWrench; import cofh.api.energy.IEnergyConnection; import mods.railcraft.common.blocks.machine.TileMachineBase; import mods.railcraft.common.plugins.forge.PowerPlugin; import mods.railcraft.common.plugins.rf.RedstoneFluxPlugin; import mods.railcraft.common.util.misc.Game; import net.minecraft.block.Block; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; /** * @author CovertJaguar <http://www.railcraft.info> */ public abstract class TileEngine extends TileMachineBase implements IEnergyConnection { public float currentOutput = 0; public int energy; private ForgeDirection direction = ForgeDirection.UP; private float pistonProgress = 0; private int pistonStage; private boolean powered; private boolean isActive; private boolean needsInit = true; // public int outputDebug, genDebug, cycleTick; private EnergyStage energyStage = EnergyStage.BLUE; public TileEngine() { } public float getCurrentOutput() { return currentOutput; } public int getEnergy() { return energy; } protected void playSoundIn() { } protected void playSoundOut() { } @Override public void updateEntity() { super.updateEntity(); if (Game.isNotHost(worldObj)) { if (pistonStage != 0) { pistonProgress += getPistonSpeed(); if (pistonProgress > 0.5 && pistonStage == 1) { pistonStage = 2; playSoundOut(); } else if (pistonProgress >= 1) { pistonStage = 0; pistonProgress = 0; playSoundIn(); } } else if (this.isActive) pistonStage = 1; return; } if (needsInit) { needsInit = false; checkPower(); } if (!powered) if (energy > 1) energy--; if (getEnergyStage() == EnergyStage.OVERHEAT) overheat(); else if (pistonStage != 0) { pistonProgress += getPistonSpeed(); if (pistonProgress > 0.5 && pistonStage == 1) { pistonStage = 2; TileEntity tile = tileCache.getTileOnSide(direction); if (RedstoneFluxPlugin.canTileReceivePower(tile, direction.getOpposite())) { RedstoneFluxPlugin.pushToTile(tile, direction.getOpposite(), extractEnergy()); } } else if (pistonProgress >= 1) { pistonProgress = 0; pistonStage = 0; // ChatPlugin.sendLocalizedChatToAllFromServer(worldObj, "Ticks=%d, Gen=%d, Out=%d", clock - cycleTick, genDebug, outputDebug); // outputDebug = 0; // genDebug = 0; // cycleTick = clock; } } else if (powered) { TileEntity tile = tileCache.getTileOnSide(direction); if (RedstoneFluxPlugin.canTileReceivePower(tile, direction.getOpposite())) if (energy > 0) { pistonStage = 1; setActive(true); } else setActive(false); else setActive(false); } else setActive(false); burn(); } protected void overheat() { subtractEnergy(50); } protected abstract void burn(); public boolean isActive() { return isActive; } private void setActive(boolean isActive) { if (this.isActive != isActive) { this.isActive = isActive; sendUpdateToClient(); } } public double getPistonSpeed() { if (Game.isHost(worldObj)) return Math.max(0.16 * getEnergyLevel(), 0.01); switch (getEnergyStage()) { case BLUE: return 0.01; case GREEN: return 0.02; case YELLOW: return 0.04; case ORANGE: return 0.08; case RED: return 0.16; default: return 0.0; } } @Override public boolean blockActivated(EntityPlayer player, int side) { ItemStack current = player.inventory.getCurrentItem(); if (current != null) if (current.getItem() instanceof IToolWrench) { IToolWrench wrench = (IToolWrench) current.getItem(); if (wrench.canWrench(player, xCoord, yCoord, zCoord)) if (Game.isHost(worldObj) && getEnergyStage() == EnergyStage.OVERHEAT) { resetEnergyStage(); wrench.wrenchUsed(player, xCoord, yCoord, zCoord); return true; } } return super.blockActivated(player, side); } @Override public boolean rotateBlock(ForgeDirection axis) { if (getEnergyStage() == EnergyStage.OVERHEAT) return false; return switchOrientation(); } @Override public void onBlockPlacedBy(EntityLivingBase entityliving, ItemStack stack) { super.onBlockPlacedBy(entityliving, stack); switchOrientation(); checkPower(); } @Override public void onNeighborBlockChange(Block block) { super.onNeighborBlockChange(block); if (Game.isNotHost(getWorld())) return; checkPower(); } private void checkPower() { boolean p = PowerPlugin.isBlockBeingPowered(worldObj, xCoord, yCoord, zCoord); if (powered != p) { powered = p; sendUpdateToClient(); } } public boolean isPowered() { return powered; } @Override public boolean canConnectRedstone(int dir) { return true; } public boolean switchOrientation() { for (int i = direction.ordinal() + 1; i < direction.ordinal() + 6; ++i) { ForgeDirection dir = ForgeDirection.getOrientation(i % 6); TileEntity tile = tileCache.getTileOnSide(dir); if (RedstoneFluxPlugin.canTileReceivePower(tile, dir.getOpposite())) { direction = dir; notifyBlocksOfNeighborChange(); sendUpdateToClient(); if (Game.isNotHost(worldObj)) markBlockForUpdate(); return true; } } return false; } public ForgeDirection getOrientation() { return direction; } @Override public boolean isSideSolid(ForgeDirection side) { return direction.getOpposite() == side; } public double getEnergyLevel() { return (double) energy / (double) maxEnergy(); } protected EnergyStage computeEnergyStage() { double energyLevel = getEnergyLevel(); if (energyLevel < 0.2) return EnergyStage.BLUE; else if (energyLevel < 0.4) return EnergyStage.GREEN; else if (energyLevel < 0.6) return EnergyStage.YELLOW; else if (energyLevel < 0.8) return EnergyStage.ORANGE; else if (energyLevel < 1) return EnergyStage.RED; else return EnergyStage.OVERHEAT; } public final EnergyStage getEnergyStage() { if (Game.isHost(worldObj)) { if (energyStage == EnergyStage.OVERHEAT) return energyStage; EnergyStage newStage = computeEnergyStage(); if (energyStage != newStage) { energyStage = newStage; sendUpdateToClient(); } } return energyStage; } public final void resetEnergyStage() { EnergyStage newStage = computeEnergyStage(); if (energyStage != newStage) { energyStage = newStage; sendUpdateToClient(); } } public void addEnergy(int addition) { energy += addition; // genDebug += addition; if (energy > maxEnergy()) energy = maxEnergy(); if (energy < 0) energy = 0; } public void subtractEnergy(int subtraction) { energy -= subtraction; if (energy > maxEnergy()) energy = maxEnergy(); if (energy < 0) energy = 0; } public int extractEnergy() { int amount = maxEnergyExtracted(); if (energy >= amount) { energy -= amount; return amount; } int returnValue = energy; energy = 0; return returnValue; } // public int extractEnergy(int min, int max, boolean doExtract) { // if (energy < min) // return 0; // // int actualMax; // // int engineMax = maxEnergyExtracted();// + extraEnergy * 0.5; // if (max > engineMax) // actualMax = engineMax; // else // actualMax = max; // // int extracted; // // if (energy >= actualMax) { // extracted = actualMax; // if (doExtract) // energy -= actualMax; //extraEnergy -= Math.min(actualMax, extraEnergy); // } else { // extracted = energy; // if (doExtract) // energy = 0; //extraEnergy = 0; // } // // return extracted; // } public float getProgress() { return pistonProgress; } public abstract int maxEnergy(); public abstract int maxEnergyExtracted(); public abstract int maxEnergyReceived(); @Override public void writeToNBT(NBTTagCompound data) { super.writeToNBT(data); data.setByte("direction", (byte) direction.ordinal()); data.setBoolean("powered", powered); data.setInteger("energyRF", energy); data.setFloat("currentOutput", currentOutput); data.setByte("energyStage", (byte) energyStage.ordinal()); } @Override public void readFromNBT(NBTTagCompound data) { super.readFromNBT(data); direction = ForgeDirection.getOrientation(data.getByte("direction")); powered = data.getBoolean("powered"); energy = data.getInteger("energyRF"); currentOutput = data.getFloat("currentOutput"); energyStage = EnergyStage.fromOrdinal(data.getByte("energyStage")); } @Override public void writePacketData(DataOutputStream data) throws IOException { super.writePacketData(data); data.writeByte(direction.ordinal()); data.writeByte(getEnergyStage().ordinal()); data.writeBoolean(isActive); } @Override public void readPacketData(DataInputStream data) throws IOException { super.readPacketData(data); direction = ForgeDirection.getOrientation(data.readByte()); energyStage = EnergyStage.fromOrdinal(data.readByte()); isActive = data.readBoolean(); } @Override public boolean canConnectEnergy(ForgeDirection from) { return from == direction; } public enum EnergyStage { BLUE, GREEN, YELLOW, ORANGE, RED, OVERHEAT; public static final EnergyStage[] VALUES = values(); public static EnergyStage fromOrdinal(int ordinal) { if (ordinal < 0 || ordinal >= VALUES.length) return BLUE; return VALUES[ordinal]; } } }