com.kaijin.AdvPowerMan.tileentities.TEAdjustableTransformer.java Source code

Java tutorial

Introduction

Here is the source code for com.kaijin.AdvPowerMan.tileentities.TEAdjustableTransformer.java

Source

/*******************************************************************************
 * 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);
    }
}