417 lines
12 KiB
Java
Executable file
417 lines
12 KiB
Java
Executable file
/*******************************************************************************
|
|
* Copyright (c) 2012-2013 Yancarlo Ramsey and CJ Bowman
|
|
* Licensed as open source with restrictions. Please see attached LICENSE.txt.
|
|
******************************************************************************/
|
|
package com.kaijin.AdvPowerMan.tileentities;
|
|
|
|
import java.io.DataInputStream;
|
|
import java.io.DataOutputStream;
|
|
import java.io.IOException;
|
|
|
|
import com.kaijin.AdvPowerMan.AdvancedPowerManagement;
|
|
import com.kaijin.AdvPowerMan.Info;
|
|
import com.kaijin.AdvPowerMan.MovingAverage;
|
|
|
|
import ic2.api.Direction;
|
|
import ic2.api.energy.EnergyNet;
|
|
import ic2.api.energy.event.EnergyTileLoadEvent;
|
|
//import ic2.api.energy.event.EnergyTileSourceEvent;
|
|
import ic2.api.energy.event.EnergyTileUnloadEvent;
|
|
import ic2.api.energy.tile.IEnergySink;
|
|
import ic2.api.energy.tile.IEnergySource;
|
|
import io.netty.buffer.ByteBuf;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.nbt.NBTTagList;
|
|
import net.minecraft.network.Packet;
|
|
import net.minecraft.network.PacketBuffer;
|
|
import net.minecraft.tileentity.TileEntity;
|
|
import net.minecraftforge.common.MinecraftForge;
|
|
import net.minecraftforge.common.util.Constants;
|
|
import net.minecraftforge.common.util.ForgeDirection;
|
|
import cpw.mods.fml.common.FMLLog;
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
|
|
public class TEAdjustableTransformer extends TECommon implements IEnergySource, IEnergySink{
|
|
protected boolean initialized = false;
|
|
|
|
public MovingAverage outputTracker = new MovingAverage(12);
|
|
public MovingAverage inputTracker = new MovingAverage(12);
|
|
|
|
protected int maxInput = 8192;
|
|
public int energyBuffer = 0;
|
|
public int energyReceived = 0;
|
|
|
|
public int outputRate = 32;
|
|
public int packetSize = 32;
|
|
public int energyCap = 32;
|
|
|
|
public byte[] sideSettings = {0, 0, 0, 0, 0, 0}; // DOWN, UP, NORTH, SOUTH,
|
|
// WEST, EAST
|
|
|
|
public TEAdjustableTransformer() // Constructor used when placing a new tile
|
|
// entity, to set up correct parameters
|
|
{
|
|
super();
|
|
}
|
|
|
|
/**
|
|
* Reads a tile entity from NBT.
|
|
*/
|
|
@Override
|
|
public void readFromNBT(NBTTagCompound nbttagcompound){
|
|
super.readFromNBT(nbttagcompound);
|
|
|
|
outputRate = nbttagcompound.getInteger("outputRate");
|
|
packetSize = nbttagcompound.getInteger("packetSize");
|
|
energyBuffer = nbttagcompound.getInteger("energyBuffer");
|
|
if(packetSize > Info.AE_MAX_PACKET)
|
|
packetSize = Info.AE_MAX_PACKET;
|
|
if(packetSize < Info.AE_MIN_PACKET)
|
|
packetSize = Info.AE_MIN_PACKET;
|
|
if(outputRate > packetSize * Info.AE_PACKETS_TICK)
|
|
outputRate = packetSize * Info.AE_PACKETS_TICK;
|
|
if(outputRate > Info.AE_MAX_OUTPUT)
|
|
outputRate = Info.AE_MAX_OUTPUT;
|
|
if(outputRate < Info.AE_MIN_OUTPUT)
|
|
outputRate = Info.AE_MIN_OUTPUT;
|
|
if(energyBuffer > packetSize * Info.AE_PACKETS_TICK)
|
|
energyBuffer = packetSize * Info.AE_PACKETS_TICK;
|
|
energyCap = Math.max(packetSize, outputRate);
|
|
|
|
NBTTagList nbttaglist = nbttagcompound.getTagList("SideSettings", Constants.NBT.TAG_COMPOUND);
|
|
for(int i = 0; i < nbttaglist.tagCount(); ++i){
|
|
NBTTagCompound entry = (NBTTagCompound) nbttaglist.getCompoundTagAt(i);
|
|
if(i >= 0 && i < sideSettings.length){
|
|
sideSettings[i] = (byte) (entry.getByte("Flags") & 255);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Writes a tile entity to NBT.
|
|
*/
|
|
@Override
|
|
public void writeToNBT(NBTTagCompound nbttagcompound){
|
|
super.writeToNBT(nbttagcompound);
|
|
nbttagcompound.setInteger("outputRate", outputRate);
|
|
nbttagcompound.setInteger("packetSize", packetSize);
|
|
nbttagcompound.setInteger("energyBuffer", energyBuffer);
|
|
|
|
NBTTagList nbttaglist = new NBTTagList();
|
|
for(int i = 0; i < sideSettings.length; ++i){
|
|
NBTTagCompound entry = new NBTTagCompound();
|
|
entry.setByte("Flags", sideSettings[i]);
|
|
nbttaglist.appendTag(entry);
|
|
}
|
|
nbttagcompound.setTag("SideSettings", nbttaglist);
|
|
}
|
|
|
|
@Override
|
|
public void invalidate(){
|
|
if(worldObj != null && initialized){
|
|
EnergyTileUnloadEvent unloadEvent = new EnergyTileUnloadEvent(this);
|
|
MinecraftForge.EVENT_BUS.post(unloadEvent);
|
|
}
|
|
super.invalidate();
|
|
}
|
|
|
|
@Override
|
|
public int getGuiID(){
|
|
return Info.GUI_ID_ADJUSTABLE_TRANSFORMER;
|
|
}
|
|
|
|
@Override
|
|
public void updateEntity(){
|
|
if(AdvancedPowerManagement.proxy.isClient())
|
|
return;
|
|
|
|
if(!initialized){
|
|
if(worldObj == null)
|
|
return;
|
|
|
|
MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
|
|
initialized = true;
|
|
}
|
|
}
|
|
|
|
protected boolean receivingRedstoneSignal(){
|
|
return worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
|
|
}
|
|
|
|
public String getInvName(){
|
|
return Info.KEY_BLOCK_NAMES[6] + Info.KEY_NAME_SUFFIX;
|
|
}
|
|
|
|
public boolean isUseableByPlayer(EntityPlayer entityplayer){
|
|
if(worldObj.getTileEntity(xCoord, yCoord, zCoord) != this){
|
|
return false;
|
|
}
|
|
|
|
return entityplayer.getDistanceSq((double) xCoord + 0.5D, (double) yCoord + 0.5D, (double) zCoord + 0.5D) <= 64D;
|
|
}
|
|
|
|
protected void selfDestroy(){
|
|
// dropContents();
|
|
ItemStack stack = new ItemStack(AdvancedPowerManagement.blockAdvPwrMan, 1, Info.AT_META);
|
|
worldObj.setBlockToAir(xCoord, yCoord, zCoord);
|
|
this.invalidate();
|
|
}
|
|
|
|
// IC2 API stuff
|
|
|
|
// @Override - this method doesn't exist anymore
|
|
public boolean isAddedToEnergyNet(){
|
|
return initialized;
|
|
}
|
|
|
|
@Override
|
|
public boolean emitsEnergyTo(TileEntity receiver, ForgeDirection direction){
|
|
// TODO Side I/O
|
|
// System.out.println("emit - direction.toSideValue() = " +
|
|
// direction.toSideValue() + " setting = " +
|
|
// ((sideSettings[direction.toSideValue()] & 1) == 1));
|
|
return (sideSettings[direction.ordinal()] & 1) == 1;
|
|
}
|
|
|
|
@Override
|
|
public double getOfferedEnergy(){
|
|
return (!receivingRedstoneSignal()) ? Math.min(energyBuffer, outputRate) : 0;
|
|
}
|
|
|
|
@Override
|
|
public void drawEnergy(double amount){
|
|
if(!receivingRedstoneSignal()){
|
|
// Reset input limiter
|
|
if(energyReceived > outputRate)
|
|
energyReceived -= outputRate;
|
|
else
|
|
energyReceived = 0;
|
|
|
|
energyBuffer -= amount;
|
|
|
|
outputTracker.tick((int) amount);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getSinkTier(){
|
|
return maxInput;
|
|
}
|
|
|
|
@Override
|
|
public int getSourceTier(){
|
|
return maxInput;
|
|
}
|
|
|
|
@Override
|
|
public boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction){
|
|
// TODO Side I/O
|
|
// System.out.println("accept - direction.toSideValue() = " +
|
|
// direction.toSideValue() + " setting = " +
|
|
// ((sideSettings[direction.toSideValue()] & 1) == 0));
|
|
return (sideSettings[direction.ordinal()] & 1) == 0;
|
|
}
|
|
|
|
@Override
|
|
public double getDemandedEnergy(){
|
|
if(!receivingRedstoneSignal()){
|
|
final int tickAmt = Math.max(outputRate - energyReceived, 0);
|
|
final int capAmt = Math.max(energyCap - energyBuffer, 0);
|
|
// System.out.println("demandsEnergy: " + amt);
|
|
return Math.min(tickAmt, capAmt);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public double injectEnergy(ForgeDirection directionFrom, double amount, double voltage){
|
|
// System.out.println("energyBuffer: " + energyBuffer);
|
|
if(AdvancedPowerManagement.proxy.isServer()){
|
|
// if supply is greater than the max we can take per tick
|
|
if(amount > maxInput){
|
|
// If the supplied EU is over the baseMaxInput, we're getting
|
|
// supplied higher than acceptable current. Pop ourselves off
|
|
// into the world and return all but 1 EU, or if the supply
|
|
// somehow was 1EU, return zero to keep IC2 from spitting out
|
|
// massive errors in the log
|
|
selfDestroy();
|
|
if(amount <= 1)
|
|
return 0;
|
|
else
|
|
return amount - 1;
|
|
}else{
|
|
energyReceived += amount;
|
|
energyBuffer += amount;
|
|
inputTracker.tick((int) amount);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Networking stuff
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
@Override
|
|
public void receiveDescriptionData(int packetID, ByteBuf stream){
|
|
// try
|
|
// {
|
|
for(int i = 0; i < 6; i++){
|
|
sideSettings[i] = stream.readByte();
|
|
}
|
|
/*
|
|
* } catch (IOException e) { logDescPacketError(e); return; }
|
|
*/
|
|
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
|
|
}
|
|
|
|
@Override
|
|
public Packet getDescriptionPacket(){
|
|
createDescPacket();
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
protected void addUniqueDescriptionData(ByteBuf data) throws IOException{
|
|
for(int i = 0; i < 6; i++){
|
|
data.writeByte(sideSettings[i]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Packet reception by server of what button was clicked on the client's
|
|
* GUI.
|
|
*
|
|
* @param id
|
|
* = the button ID
|
|
*/
|
|
@Override
|
|
public void receiveGuiButton(int id){
|
|
switch(id){
|
|
case 0:
|
|
packetSize += 1;
|
|
if(packetSize > Info.AE_MAX_PACKET)
|
|
packetSize = Info.AE_MAX_PACKET;
|
|
break;
|
|
case 1:
|
|
packetSize += 10;
|
|
if(packetSize > Info.AE_MAX_PACKET)
|
|
packetSize = Info.AE_MAX_PACKET;
|
|
break;
|
|
case 2:
|
|
packetSize += 64;
|
|
if(packetSize == 68)
|
|
packetSize = 64;
|
|
if(packetSize > Info.AE_MAX_PACKET)
|
|
packetSize = Info.AE_MAX_PACKET;
|
|
break;
|
|
case 3:
|
|
packetSize *= 2;
|
|
if(packetSize > Info.AE_MAX_PACKET)
|
|
packetSize = Info.AE_MAX_PACKET;
|
|
break;
|
|
case 4:
|
|
packetSize -= 1;
|
|
if(packetSize < Info.AE_MIN_PACKET)
|
|
packetSize = Info.AE_MIN_PACKET;
|
|
if(outputRate > packetSize * Info.AE_PACKETS_TICK)
|
|
outputRate = packetSize * Info.AE_PACKETS_TICK;
|
|
break;
|
|
case 5:
|
|
packetSize -= 10;
|
|
if(packetSize < Info.AE_MIN_PACKET)
|
|
packetSize = Info.AE_MIN_PACKET;
|
|
if(outputRate > packetSize * Info.AE_PACKETS_TICK)
|
|
outputRate = packetSize * Info.AE_PACKETS_TICK;
|
|
break;
|
|
case 6:
|
|
packetSize -= 64;
|
|
if(packetSize < Info.AE_MIN_PACKET)
|
|
packetSize = Info.AE_MIN_PACKET;
|
|
if(outputRate > packetSize * Info.AE_PACKETS_TICK)
|
|
outputRate = packetSize * Info.AE_PACKETS_TICK;
|
|
break;
|
|
case 7:
|
|
packetSize /= 2;
|
|
if(packetSize < Info.AE_MIN_PACKET)
|
|
packetSize = Info.AE_MIN_PACKET;
|
|
if(outputRate > packetSize * Info.AE_PACKETS_TICK)
|
|
outputRate = packetSize * Info.AE_PACKETS_TICK;
|
|
break;
|
|
case 8:
|
|
outputRate += 1;
|
|
if(outputRate > packetSize * Info.AE_PACKETS_TICK)
|
|
outputRate = packetSize * Info.AE_PACKETS_TICK;
|
|
if(outputRate > Info.AE_MAX_OUTPUT)
|
|
outputRate = Info.AE_MAX_OUTPUT;
|
|
break;
|
|
case 9:
|
|
outputRate += 10;
|
|
if(outputRate > packetSize * Info.AE_PACKETS_TICK)
|
|
outputRate = packetSize * Info.AE_PACKETS_TICK;
|
|
if(outputRate > Info.AE_MAX_OUTPUT)
|
|
outputRate = Info.AE_MAX_OUTPUT;
|
|
break;
|
|
case 10:
|
|
outputRate += 64;
|
|
if(outputRate == 65)
|
|
outputRate = 64;
|
|
if(outputRate > packetSize * Info.AE_PACKETS_TICK)
|
|
outputRate = packetSize * Info.AE_PACKETS_TICK;
|
|
if(outputRate > Info.AE_MAX_OUTPUT)
|
|
outputRate = Info.AE_MAX_OUTPUT;
|
|
break;
|
|
case 11:
|
|
outputRate *= 2;
|
|
if(outputRate > packetSize * Info.AE_PACKETS_TICK)
|
|
outputRate = packetSize * Info.AE_PACKETS_TICK;
|
|
if(outputRate > Info.AE_MAX_OUTPUT)
|
|
outputRate = Info.AE_MAX_OUTPUT;
|
|
break;
|
|
case 12:
|
|
outputRate -= 1;
|
|
if(outputRate < Info.AE_MIN_OUTPUT)
|
|
outputRate = Info.AE_MIN_OUTPUT;
|
|
break;
|
|
case 13:
|
|
outputRate -= 10;
|
|
if(outputRate < Info.AE_MIN_OUTPUT)
|
|
outputRate = Info.AE_MIN_OUTPUT;
|
|
break;
|
|
case 14:
|
|
outputRate -= 64;
|
|
if(outputRate < Info.AE_MIN_OUTPUT)
|
|
outputRate = Info.AE_MIN_OUTPUT;
|
|
break;
|
|
case 15:
|
|
outputRate /= 2;
|
|
if(outputRate < Info.AE_MIN_OUTPUT)
|
|
outputRate = Info.AE_MIN_OUTPUT;
|
|
break;
|
|
case 16:
|
|
case 17:
|
|
case 18:
|
|
case 19:
|
|
case 20:
|
|
case 21:
|
|
// TODO How can we make IC2 check the new emit/accept values without
|
|
// doing a reload?
|
|
if(initialized)
|
|
MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
|
|
initialized = false;
|
|
sideSettings[id - 16] ^= 1;
|
|
MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
|
|
initialized = true;
|
|
// worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
|
|
break;
|
|
}
|
|
energyCap = Math.max(packetSize, outputRate);
|
|
final byte voltLevel = (byte) (packetSize <= 32 ? 0 : packetSize <= 128 ? 2 : packetSize <= 512 ? 4 : 6);
|
|
for(int i = 0; i < 6; i++)
|
|
sideSettings[i] = (byte) (sideSettings[i] & 249 | voltLevel);
|
|
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
|
|
}
|
|
}
|