micdoodle8.mods.galacticraft.mars.tile.GCMarsTileEntityTerraformer.java Source code

Java tutorial

Introduction

Here is the source code for micdoodle8.mods.galacticraft.mars.tile.GCMarsTileEntityTerraformer.java

Source

package micdoodle8.mods.galacticraft.mars.tile;

import java.util.ArrayList;

import micdoodle8.mods.galacticraft.api.block.ITerraformableBlock;
import micdoodle8.mods.galacticraft.api.tile.IDisableableMachine;
import micdoodle8.mods.galacticraft.api.transmission.core.item.IItemElectric;
import micdoodle8.mods.galacticraft.api.vector.Vector3;
import micdoodle8.mods.galacticraft.core.GalacticraftCore;
import micdoodle8.mods.galacticraft.core.network.GCCorePacketManager;
import micdoodle8.mods.galacticraft.core.tile.GCCoreTileEntityElectricBlock;
import micdoodle8.mods.galacticraft.mars.entities.GCMarsEntityTerraformBubble;
import micdoodle8.mods.galacticraft.mars.world.gen.GCMarsWorldGenTerraformTree;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.packet.Packet;
import net.minecraft.util.StatCollector;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;

import com.google.common.io.ByteArrayDataInput;

/**
 * GCMarsTileEntityTerraformer.java
 *
 * This file is part of the Galacticraft project
 *
 * @author micdoodle8
 * @license Lesser GNU Public License v3 (http://www.gnu.org/licenses/lgpl.html)
 * 
 */
public class GCMarsTileEntityTerraformer extends GCCoreTileEntityElectricBlock
        implements IInventory, ISidedInventory, IDisableableMachine {
    private final int tankCapacity = 2000;
    public FluidTank waterTank = new FluidTank(this.tankCapacity);
    public boolean active;
    public boolean lastActive;
    public static final float WATTS_PER_TICK = 0.2F;
    private ItemStack[] containingItems = new ItemStack[14];
    public GCMarsEntityTerraformBubble terraformBubble;
    private ArrayList<Vector3> terraformableBlocksList = new ArrayList<Vector3>();
    private ArrayList<Vector3> grassBlockList = new ArrayList<Vector3>();
    public int terraformableBlocksListSize = 0; // used for server->client ease
    public int grassBlocksListSize = 0; // used for server->client ease
    public boolean treesDisabled;
    public boolean grassDisabled;
    public float size;
    public final double MAX_SIZE = 15.0D;
    private int[] useCount = new int[2];

    public GCMarsTileEntityTerraformer() {
        super(GCMarsTileEntityTerraformer.WATTS_PER_TICK, 50);
    }

    public int getScaledWaterLevel(int i) {
        final double fuelLevel = this.waterTank.getFluid() == null ? 0 : this.waterTank.getFluid().amount;

        return (int) (fuelLevel * i / this.tankCapacity);
    }

    @Override
    public void invalidate() {
        super.invalidate();
    }

    public double getDistanceFromServer(double par1, double par3, double par5) {
        final double d3 = this.xCoord + 0.5D - par1;
        final double d4 = this.yCoord + 0.5D - par3;
        final double d5 = this.zCoord + 0.5D - par5;
        return d3 * d3 + d4 * d4 + d5 * d5;
    }

    @Override
    public void updateEntity() {
        super.updateEntity();

        if (this.terraformBubble == null) {
            if (!this.worldObj.isRemote) {
                this.terraformBubble = new GCMarsEntityTerraformBubble(this.worldObj, new Vector3(this), this);
                this.terraformBubble.setPosition(this.xCoord, this.yCoord, this.zCoord);
                this.worldObj.spawnEntityInWorld(this.terraformBubble);
            }
        }

        if (!this.worldObj.isRemote) {
            if (this.containingItems[0] != null) {
                final FluidStack liquid = FluidContainerRegistry.getFluidForFilledItem(this.containingItems[0]);

                if (liquid != null && liquid.getFluid().getName().equals(FluidRegistry.WATER.getName())) {
                    if (this.waterTank.getFluid() == null
                            || this.waterTank.getFluid().amount + liquid.amount <= this.waterTank.getCapacity()) {
                        this.waterTank.fill(liquid, true);

                        if (FluidContainerRegistry.isBucket(this.containingItems[0])
                                && FluidContainerRegistry.isFilledContainer(this.containingItems[0])) {
                            this.containingItems[0] = new ItemStack(Item.bucketEmpty,
                                    this.containingItems[0].stackSize);
                        } else {
                            this.containingItems[0].stackSize--;

                            if (this.containingItems[0].stackSize == 0) {
                                this.containingItems[0] = null;
                            }
                        }
                    }
                }
            }

            if (this.terraformBubble.getSize() == this.MAX_SIZE && this.getEnergyStored() > 0
                    && this.getFirstBonemealStack() != null && this.waterTank.getFluid() != null
                    && this.waterTank.getFluid().amount > 0) {
                this.active = true;
            } else {
                this.active = false;
            }
        }

        if (!this.worldObj.isRemote && (this.active != this.lastActive || this.ticks % 20 == 0)) {
            this.terraformableBlocksList.clear();
            this.grassBlockList.clear();

            if (this.active) {
                for (int x = (int) Math.floor(this.xCoord - this.terraformBubble.getSize()); x < Math
                        .ceil(this.xCoord + this.terraformBubble.getSize()); x++) {
                    for (int y = (int) Math.floor(this.yCoord - this.terraformBubble.getSize()); y < Math
                            .ceil(this.yCoord + this.terraformBubble.getSize()); y++) {
                        for (int z = (int) Math.floor(this.zCoord - this.terraformBubble.getSize()); z < Math
                                .ceil(this.zCoord + this.terraformBubble.getSize()); z++) {
                            int blockID = this.worldObj.getBlockId(x, y, z);
                            int blockIDAbove = this.worldObj.getBlockId(x, y + 1, z);

                            if (blockID > 0 && this.getDistanceFromServer(x, y, z) < this.terraformBubble.getSize()
                                    * this.terraformBubble.getSize()) {
                                Block block = Block.blocksList[blockID];

                                if (block instanceof ITerraformableBlock
                                        && ((ITerraformableBlock) block).isTerraformable(this.worldObj, x, y, z)) {
                                    if (!this.grassDisabled && this.getFirstSeedStack() != null) {
                                        this.terraformableBlocksList.add(new Vector3(x, y, z));
                                    }
                                } else if (block.blockID == Block.grass.blockID && blockIDAbove == 0) {
                                    if (!this.treesDisabled && this.getFirstSaplingStack() != null) {
                                        this.grassBlockList.add(new Vector3(x, y, z));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        if (!this.worldObj.isRemote && this.terraformableBlocksList.size() > 0 && this.ticks % 15 == 0) {
            ArrayList<Vector3> terraformableBlocks2 = new ArrayList<Vector3>(this.terraformableBlocksList);

            int randomIndex = this.worldObj.rand.nextInt(this.terraformableBlocksList.size());
            Vector3 vec = terraformableBlocks2.get(randomIndex);

            int ID = 0;

            switch (this.worldObj.rand.nextInt(40)) {
            case 0:
                if (this.worldObj.isBlockFullCube(vec.intX() - 1, vec.intY(), vec.intZ())
                        && this.worldObj.isBlockFullCube(vec.intX() + 1, vec.intY(), vec.intZ())
                        && this.worldObj.isBlockFullCube(vec.intX(), vec.intY(), vec.intZ() - 1)
                        && this.worldObj.isBlockFullCube(vec.intX(), vec.intY(), vec.intZ() + 1)) {
                    ID = Block.waterMoving.blockID;
                } else {
                    ID = Block.grass.blockID;
                }
                break;
            default:
                ID = Block.grass.blockID;
                break;
            }

            this.worldObj.setBlock(vec.intX(), vec.intY(), vec.intZ(), ID);

            if (ID == Block.grass.blockID) {
                this.useCount[0]++;
                this.waterTank.drain(1, true);
                this.checkUsage(1);
            } else if (ID == Block.waterMoving.blockID) {
                this.checkUsage(2);
            }

            this.terraformableBlocksList.remove(randomIndex);
        }

        if (!this.worldObj.isRemote && !this.treesDisabled && this.grassBlockList.size() > 0
                && this.ticks % 50 == 0) {
            ArrayList<Vector3> grassBlocks2 = new ArrayList<Vector3>(this.grassBlockList);

            int randomIndex = this.worldObj.rand.nextInt(this.grassBlockList.size());
            Vector3 vec = grassBlocks2.get(randomIndex);

            if (new GCMarsWorldGenTerraformTree(true).generate(this.worldObj, this.worldObj.rand, vec.intX(),
                    vec.intY(), vec.intZ())) {
                this.useCount[1]++;
                this.waterTank.drain(50, true);
                this.checkUsage(0);
            }

            this.grassBlockList.remove(randomIndex);
        }

        if (!this.worldObj.isRemote) {
            this.terraformableBlocksListSize = this.terraformableBlocksList.size();
            this.grassBlocksListSize = this.grassBlockList.size();
        }

        if (this.getEnergyStored() > 0.0F && (!this.grassDisabled || !this.treesDisabled)) {
            this.size = (float) Math.min(Math.max(0, this.size + 0.1F), this.MAX_SIZE);
        } else {
            this.size = (float) Math.min(Math.max(0, this.size - 0.1F), this.MAX_SIZE);
        }

        this.lastActive = this.active;
    }

    private void checkUsage(int type) {
        ItemStack stack = null;

        if ((this.useCount[0] + this.useCount[1]) % 4 == 0) {
            stack = this.getFirstBonemealStack();

            if (stack != null) {
                stack.stackSize--;

                if (stack.stackSize <= 0) {
                    this.containingItems[this.getSelectiveStack(2, 6)] = null;
                }
            }
        }

        switch (type) {
        case 0:
            stack = this.getFirstSaplingStack();

            if (stack != null) {
                stack.stackSize--;

                if (stack.stackSize <= 0) {
                    this.containingItems[this.getSelectiveStack(6, 10)] = null;
                }
            }
            break;
        case 1:
            if (this.useCount[0] % 4 == 0) {
                stack = this.getFirstSeedStack();

                if (stack != null) {
                    stack.stackSize--;

                    if (stack.stackSize <= 0) {
                        this.containingItems[this.getSelectiveStack(10, 14)] = null;
                    }
                }
            }
            break;
        case 2:
            this.waterTank.drain(50, true);
            break;
        }
    }

    private int getSelectiveStack(int start, int end) {
        for (int i = start; i < end; i++) {
            ItemStack stack = this.containingItems[i];

            if (stack != null) {
                return i;
            }
        }

        return -1;
    }

    public ItemStack getFirstBonemealStack() {
        int index = this.getSelectiveStack(2, 6);

        if (index != -1) {
            return this.containingItems[index];
        }

        return null;
    }

    public ItemStack getFirstSaplingStack() {
        int index = this.getSelectiveStack(6, 10);

        if (index != -1) {
            return this.containingItems[index];
        }

        return null;
    }

    public ItemStack getFirstSeedStack() {
        int index = this.getSelectiveStack(10, 14);

        if (index != -1) {
            return this.containingItems[index];
        }

        return null;
    }

    @Override
    public void readFromNBT(NBTTagCompound nbt) {
        super.readFromNBT(nbt);

        final NBTTagList var2 = nbt.getTagList("Items");
        this.containingItems = new ItemStack[this.getSizeInventory()];

        for (int var3 = 0; var3 < var2.tagCount(); ++var3) {
            final NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3);
            final byte var5 = var4.getByte("Slot");

            if (var5 >= 0 && var5 < this.containingItems.length) {
                this.containingItems[var5] = ItemStack.loadItemStackFromNBT(var4);
            }
        }

        this.size = nbt.getFloat("BubbleSize");
        this.useCount = nbt.getIntArray("UseCountArray");

        if (this.useCount.length == 0) {
            this.useCount = new int[2];
        }

        if (nbt.hasKey("waterTank")) {
            this.waterTank.readFromNBT(nbt.getCompoundTag("waterTank"));
        }
    }

    @Override
    public void writeToNBT(NBTTagCompound nbt) {
        super.writeToNBT(nbt);

        final NBTTagList list = new NBTTagList();

        for (int var3 = 0; var3 < this.containingItems.length; ++var3) {
            if (this.containingItems[var3] != null) {
                final NBTTagCompound var4 = new NBTTagCompound();
                var4.setByte("Slot", (byte) var3);
                this.containingItems[var3].writeToNBT(var4);
                list.appendTag(var4);
            }
        }

        nbt.setTag("Items", list);
        nbt.setFloat("BubbleSize", this.size);
        nbt.setIntArray("UseCountArray", this.useCount);

        if (this.waterTank.getFluid() != null) {
            nbt.setTag("waterTank", this.waterTank.writeToNBT(new NBTTagCompound()));
        }
    }

    @Override
    public int getSizeInventory() {
        return this.containingItems.length;
    }

    @Override
    public ItemStack getStackInSlot(int par1) {
        return this.containingItems[par1];
    }

    @Override
    public ItemStack decrStackSize(int par1, int par2) {
        if (this.containingItems[par1] != null) {
            ItemStack var3;

            if (this.containingItems[par1].stackSize <= par2) {
                var3 = this.containingItems[par1];
                this.containingItems[par1] = null;
                return var3;
            } else {
                var3 = this.containingItems[par1].splitStack(par2);

                if (this.containingItems[par1].stackSize == 0) {
                    this.containingItems[par1] = null;
                }

                return var3;
            }
        } else {
            return null;
        }
    }

    @Override
    public ItemStack getStackInSlotOnClosing(int par1) {
        if (this.containingItems[par1] != null) {
            final ItemStack var2 = this.containingItems[par1];
            this.containingItems[par1] = null;
            return var2;
        } else {
            return null;
        }
    }

    @Override
    public void setInventorySlotContents(int par1, ItemStack par2ItemStack) {
        this.containingItems[par1] = par2ItemStack;

        if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) {
            par2ItemStack.stackSize = this.getInventoryStackLimit();
        }
    }

    @Override
    public String getInvName() {
        return StatCollector.translateToLocal("container.oxygendistributor.name");
    }

    @Override
    public int getInventoryStackLimit() {
        return 64;
    }

    @Override
    public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) {
        return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false
                : par1EntityPlayer.getDistanceSq(this.xCoord + 0.5D, this.yCoord + 0.5D,
                        this.zCoord + 0.5D) <= 64.0D;
    }

    // ISidedInventory Implementation:

    @Override
    public int[] getAccessibleSlotsFromSide(int side) {
        return new int[] { 1 };
    }

    @Override
    public boolean canInsertItem(int slotID, ItemStack itemstack, int side) {
        return this.isItemValidForSlot(slotID, itemstack);
    }

    @Override
    public boolean canExtractItem(int slotID, ItemStack itemstack, int side) {
        return slotID == 1;
    }

    @Override
    public boolean isInvNameLocalized() {
        return true;
    }

    @Override
    public boolean isItemValidForSlot(int slotID, ItemStack itemstack) {
        return slotID == 1 ? itemstack.getItem() instanceof IItemElectric : false;
    }

    @Override
    public void openChest() {

    }

    @Override
    public void closeChest() {

    }

    @Override
    public boolean shouldPullEnergy() {
        return this.getEnergyStored() <= this.getMaxEnergyStored() - this.ueWattsPerTick;
    }

    @Override
    public boolean shouldUseEnergy() {
        return !this.grassDisabled || !this.treesDisabled;
    }

    @Override
    public void readPacket(ByteArrayDataInput data) {
        if (this.worldObj.isRemote) {
            this.setEnergyStored(data.readFloat());
            this.treesDisabled = data.readBoolean();
            this.grassDisabled = data.readBoolean();
            this.disableCooldown = data.readInt();
            int terraformBubbleEntityID = data.readInt();
            this.terraformBubble = (GCMarsEntityTerraformBubble) (terraformBubbleEntityID == -1 ? null
                    : this.worldObj.getEntityByID(terraformBubbleEntityID));
            this.terraformableBlocksListSize = data.readInt();
            this.grassBlocksListSize = data.readInt();
            this.size = data.readFloat();

            int firstStack = -1;
            int itemID = -1;
            int stackSize = -1;
            int stackMetadata = -1;

            for (int i = 0; i < 3; i++) {
                firstStack = data.readInt();
                itemID = data.readInt();
                stackSize = data.readInt();
                stackMetadata = data.readInt();

                if (firstStack != -1) {
                    this.containingItems[firstStack] = new ItemStack(itemID, stackSize, stackMetadata);
                }
            }

            this.waterTank.setFluid(new FluidStack(GalacticraftCore.fluidFuel, data.readInt()));
        }
    }

    @Override
    public Packet getPacket() {
        ItemStack stack1 = this.getFirstBonemealStack();
        ItemStack stack2 = this.getFirstSaplingStack();
        ItemStack stack3 = this.getFirstSeedStack();
        return GCCorePacketManager.getPacket(GalacticraftCore.CHANNELENTITIES, this, this.getEnergyStored(),
                this.treesDisabled, this.grassDisabled, this.disableCooldown,
                this.terraformBubble != null ? this.terraformBubble.entityId : -1, this.terraformableBlocksListSize,
                this.grassBlocksListSize, this.size, stack1 == null ? -1 : this.getSelectiveStack(2, 6),
                stack1 == null ? -1 : stack1.itemID, stack1 == null ? -1 : stack1.stackSize,
                stack1 == null ? -1 : stack1.getItemDamage(), stack2 == null ? -1 : this.getSelectiveStack(6, 4),
                stack2 == null ? -1 : stack2.itemID, stack2 == null ? -1 : stack2.stackSize,
                stack2 == null ? -1 : stack2.getItemDamage(), stack3 == null ? -1 : this.getSelectiveStack(10, 14),
                stack3 == null ? -1 : stack3.itemID, stack3 == null ? -1 : stack3.stackSize,
                stack3 == null ? -1 : stack3.getItemDamage(),
                this.waterTank.getFluid() == null ? 0 : this.waterTank.getFluid().amount);
    }

    @Override
    protected double getPacketRange() {
        return 320.0D;
    }

    @Override
    public ForgeDirection getElectricInputDirection() {
        return ForgeDirection.getOrientation(this.getBlockMetadata() + 2);
    }

    @Override
    public ItemStack getBatteryInSlot() {
        return this.getStackInSlot(1);
    }

    @Override
    public void setDisabled(int index, boolean disabled) {
        if (this.disableCooldown <= 0) {
            switch (index) {
            case 0:
                this.treesDisabled = !this.treesDisabled;
                break;
            case 1:
                this.grassDisabled = !this.grassDisabled;
                break;
            }

            this.disableCooldown = 10;
        }
    }

    @Override
    public boolean getDisabled(int index) {
        switch (index) {
        case 0:
            return this.treesDisabled;
        case 1:
            return this.grassDisabled;
        }

        return false;
    }
}