Package mods.railcraft.common.blocks.machine.beta

Source Code of mods.railcraft.common.blocks.machine.beta.TileEngine$EnergyIndicator

/*
* 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.power.IPowerEmitter;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.api.power.PowerHandler;
import buildcraft.api.power.PowerHandler.PowerReceiver;
import buildcraft.api.tools.IToolWrench;
import buildcraft.api.transport.IPipeConnection;
import buildcraft.api.transport.IPipeTile.PipeType;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
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 mods.railcraft.common.blocks.machine.TileMachineBase;
import mods.railcraft.common.gui.widgets.IIndicatorController;
import mods.railcraft.common.gui.widgets.IndicatorController;
import mods.railcraft.common.plugins.forge.PowerPlugin;
import mods.railcraft.common.plugins.forge.WorldPlugin;
import mods.railcraft.common.util.misc.Game;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityLivingBase;

/**
*
* @author CovertJaguar <http://www.railcraft.info>
*/
public abstract class TileEngine extends TileMachineBase implements IPowerReceptor, IPipeConnection, IPowerEmitter {

    private ForgeDirection direction = ForgeDirection.UP;
    private float pistonProgress = 0;
    public float currentOutput = 0;
    private int pistonStage;
    private boolean powered;
    private boolean isActive;
    private boolean needsInit = true;
    public double energy;
    public double extraEnergy;
    private EnergyStage energyStage = EnergyStage.BLUE;
    private final PowerHandler provider = new PowerHandler(this, PowerHandler.Type.ENGINE);
    private final IIndicatorController energyIndicator = new EnergyIndicator();

    private class EnergyIndicator extends IndicatorController {

        @Override
        public void refreshToolTip() {
            tip.text = String.format("%.0f MJ", energy);
        }

        @Override
        public int getScaledLevel(int size) {
            double e = Math.min(energy, maxEnergy());
            return (int) (e * size / maxEnergy());
        }

    };

    public IIndicatorController getEnergyIndicator() {
        return energyIndicator;
    }

    public float getCurrentOutput() {
        return currentOutput;
    }

    public double getEnergy() {
        return energy;
    }

    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];
        }

    }

    public TileEngine() {
        initEnergyProvider();
    }

    private void initEnergyProvider() {
        provider.configure(2, maxEnergyReceived(), 1, maxEnergy());
        provider.configurePowerPerdition(1, 100);
    }

    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--;

        provider.update();

        if (getEnergyStage() == EnergyStage.OVERHEAT)
            overheat();
        else if (pistonStage != 0) {
            pistonProgress += getPistonSpeed();

            if (pistonProgress > 0.5 && pistonStage == 1) {
                pistonStage = 2;

                TileEntity tile = WorldPlugin.getTileEntityOnSide(worldObj, xCoord, yCoord, zCoord, direction);

                if (EngineTools.isPoweredTile(tile, direction.getOpposite())) {
                    IPowerReceptor receptor = (IPowerReceptor) tile;

                    PowerReceiver recProv = receptor.getPowerReceiver(direction.getOpposite());

                    double extracted = extractEnergy(recProv.getMinEnergyReceived(), recProv.getMaxEnergyReceived(), true);

                    if (extracted > 0)
                        recProv.receiveEnergy(PowerHandler.Type.ENGINE, extracted, direction.getOpposite());
                }
            } else if (pistonProgress >= 1) {
                pistonProgress = 0;
                pistonStage = 0;
            }
        } else if (powered) {
            TileEntity tile = WorldPlugin.getTileEntityOnSide(worldObj, xCoord, yCoord, zCoord, direction);

            if (EngineTools.isPoweredTile(tile, direction.getOpposite())) {
                IPowerReceptor receptor = (IPowerReceptor) tile;

                PowerReceiver recProv = receptor.getPowerReceiver(direction.getOpposite());

                if (extractEnergy(recProv.getMinEnergyReceived(), recProv.getMaxEnergyReceived(), false) > 0) {
                    pistonStage = 1;
                    setActive(true);
                } else
                    setActive(false);
            } else
                setActive(false);

        } else
            setActive(false);

        burn();
    }

    protected void overheat() {
        subtractEnergy(5);
    }

    protected abstract void burn();

    private void setActive(boolean isActive) {
        if (this.isActive != isActive) {
            this.isActive = isActive;
            sendUpdateToClient();
        }
    }

    public boolean isActive() {
        return isActive;
    }

    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) {
        return switchOrientation();
    }

    @Override
    public void onBlockPlacedBy(EntityLivingBase entityliving) {
        super.onBlockPlacedBy(entityliving);
        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 = WorldPlugin.getTileEntityOnSide(worldObj, xCoord, yCoord, zCoord, dir);

            if (EngineTools.isPoweredTile(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;
    }

    @Override
    public PowerReceiver getPowerReceiver(ForgeDirection side) {
        return provider.getPowerReceiver();
    }

    @Override
    public void doWork(PowerHandler workProvider) {
        if (Game.isNotHost(worldObj))
            return;
        double e = provider.useEnergy(1, maxEnergyReceived(), true) * 0.95;
        extraEnergy += e;
        addEnergy(e);
    }

    public double getEnergyLevel() {
        return energy / 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(double addition) {
        energy += addition;

        if (energy > maxEnergy())
            energy = maxEnergy();
    }

    public void subtractEnergy(double subtraction) {
        energy -= subtraction;
        if (energy < 0)
            energy = 0;
    }

    public double extractEnergy(double min, double max, boolean doExtract) {
        if (energy < min)
            return 0;

        double actualMax;

        double combinedMax = maxEnergyExtracted() + extraEnergy * 0.5;
        if (max > combinedMax)
            actualMax = combinedMax;
        else
            actualMax = max;

        double 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.setFloat("energy", (float) 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.getFloat("energy");
        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 ConnectOverride overridePipeConnection(PipeType type, ForgeDirection with) {
        if (type == PipeType.POWER)
            return ConnectOverride.DEFAULT;
        if (with == direction)
            return ConnectOverride.DISCONNECT;
        return ConnectOverride.DEFAULT;
    }

    @Override
    public boolean canEmitPowerFrom(ForgeDirection side) {
        return side == direction;
    }

}
TOP

Related Classes of mods.railcraft.common.blocks.machine.beta.TileEngine$EnergyIndicator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.