buildcraft.builders.TileFiller.java Source code

Java tutorial

Introduction

Here is the source code for buildcraft.builders.TileFiller.java

Source

/**
 * Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
 * http://www.mod-buildcraft.com
 *
 * BuildCraft is distributed under the terms of the Minecraft Mod Public
 * License 1.0, or MMPL. Please check the contents of the license located in
 * http://www.mod-buildcraft.com/MMPL-1.0.txt
 */
package buildcraft.builders;

import java.io.IOException;

import io.netty.buffer.ByteBuf;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;

import buildcraft.BuildCraftCore;
import buildcraft.api.core.IAreaProvider;
import buildcraft.api.filler.FillerManager;
import buildcraft.api.gates.IAction;
import buildcraft.api.gates.IActionReceptor;
import buildcraft.builders.filler.pattern.FillerPattern;
import buildcraft.builders.filler.pattern.PatternFill;
import buildcraft.builders.triggers.ActionFiller;
import buildcraft.core.Box;
import buildcraft.core.Box.Kind;
import buildcraft.core.IMachine;
import buildcraft.core.blueprints.BptBuilderTemplate;
import buildcraft.core.blueprints.BptContext;
import buildcraft.core.inventory.SimpleInventory;
import buildcraft.core.network.PacketPayload;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCSide;
import buildcraft.core.triggers.ActionMachineControl;
import buildcraft.core.triggers.ActionMachineControl.Mode;
import buildcraft.core.utils.Utils;

public class TileFiller extends TileAbstractBuilder implements IMachine, IActionReceptor {

    private static int POWER_ACTIVATION = 50;

    public FillerPattern currentPattern = PatternFill.INSTANCE;

    private BptBuilderTemplate currentTemplate;
    private BptContext context;

    private final Box box = new Box();
    private boolean done = false;
    private ActionMachineControl.Mode lastMode = ActionMachineControl.Mode.Unknown;
    private SimpleInventory inv = new SimpleInventory(27, "Filler", 64);

    private NBTTagCompound initNBT = null;

    public TileFiller() {
        inv.addListener(this);
        box.kind = Kind.STRIPES;
    }

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

        if (worldObj.isRemote) {
            return;
        }

        IAreaProvider a = Utils.getNearbyAreaProvider(worldObj, xCoord, yCoord, zCoord);

        if (a != null) {
            box.initialize(a);

            if (a instanceof TileMarker) {
                ((TileMarker) a).removeFromWorld();
            }

            sendNetworkUpdate();
        }

        if (currentPattern != null && currentTemplate == null) {
            currentTemplate = currentPattern.getTemplateBuilder(box, getWorld());
            context = currentTemplate.getContext();
        }

        if (initNBT != null && currentTemplate != null) {
            currentTemplate.loadBuildStateToNBT(initNBT.getCompoundTag("builderState"), this);
        }

        initNBT = null;
    }

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

        if (worldObj.isRemote) {
            return;
        }

        if (lastMode == Mode.Off) {
            return;
        }

        if (!box.isInitialized()) {
            return;
        }

        if (mjStored < POWER_ACTIVATION || !buildTracker.markTimeIfDelay(worldObj)) {
            return;
        }

        boolean oldDone = done;

        if (done) {
            if (lastMode == Mode.Loop) {
                done = false;
            } else {
                return;
            }
        }

        if (currentPattern != null && currentTemplate == null) {
            currentTemplate = currentPattern.getTemplateBuilder(box, getWorld());
            context = currentTemplate.getContext();
        }

        if (currentTemplate != null) {
            currentTemplate.buildNextSlot(worldObj, this, xCoord, yCoord, zCoord);

            if (currentTemplate.isDone(this)) {
                done = true;
                currentTemplate = null;
            }
        }

        if (oldDone != done) {
            sendNetworkUpdate();
        }
    }

    @Override
    public final int getSizeInventory() {
        return inv.getSizeInventory();
    }

    @Override
    public ItemStack getStackInSlot(int slot) {
        return inv.getStackInSlot(slot);
    }

    @Override
    public ItemStack decrStackSize(int slot, int amount) {
        return inv.decrStackSize(slot, amount);
    }

    @Override
    public void setInventorySlotContents(int slot, ItemStack stack) {
        inv.setInventorySlotContents(slot, stack);
    }

    @Override
    public ItemStack getStackInSlotOnClosing(int slot) {
        return inv.getStackInSlotOnClosing(slot);
    }

    @Override
    public String getInventoryName() {
        return "Filler";
    }

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

        inv.readFromNBT(nbt);

        if (nbt.hasKey("pattern")) {
            currentPattern = (FillerPattern) FillerManager.registry.getPattern(nbt.getString("pattern"));
        }

        if (currentPattern == null) {
            currentPattern = PatternFill.INSTANCE;
        }

        if (nbt.hasKey("box")) {
            box.initialize(nbt.getCompoundTag("box"));
        }

        done = nbt.getBoolean("done");
        lastMode = Mode.values()[nbt.getByte("lastMode")];

        // The rest of load has to be done upon initialize.
        initNBT = (NBTTagCompound) nbt.getCompoundTag("bpt").copy();
    }

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

        inv.writeToNBT(nbt);

        if (currentPattern != null) {
            nbt.setString("pattern", currentPattern.getUniqueTag());
        }

        NBTTagCompound boxStore = new NBTTagCompound();
        box.writeToNBT(boxStore);
        nbt.setTag("box", boxStore);

        nbt.setBoolean("done", done);
        nbt.setByte("lastMode", (byte) lastMode.ordinal());

        NBTTagCompound bptNBT = new NBTTagCompound();

        if (currentTemplate != null) {
            NBTTagCompound builderCpt = new NBTTagCompound();
            currentTemplate.saveBuildStateToNBT(builderCpt, this);
            bptNBT.setTag("builderState", builderCpt);
        }

        nbt.setTag("bpt", bptNBT);
    }

    @Override
    public int getInventoryStackLimit() {
        return inv.getInventoryStackLimit();
    }

    @Override
    public boolean isUseableByPlayer(EntityPlayer entityplayer) {
        if (worldObj.getTileEntity(xCoord, yCoord, zCoord) != this) {
            return false;
        }

        return entityplayer.getDistanceSq(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D) <= 64D;
    }

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

    public void setPattern(FillerPattern pattern) {
        if (pattern != null && currentPattern != pattern) {
            currentPattern = pattern;
            currentTemplate = null;
            done = false;
            sendNetworkUpdate();
        }
    }

    @Override
    public PacketPayload getPacketPayload() {
        PacketPayload payload = new PacketPayload(new PacketPayload.StreamWriter() {
            @Override
            public void writeData(ByteBuf data) {
                box.writeToStream(data);
                data.writeBoolean(done);
                Utils.writeUTF(data, currentPattern.getUniqueTag());
            }
        });

        return payload;
    }

    public void handlePacketPayload(ByteBuf data) {
        boolean initialized = box.isInitialized();
        box.readFromStream(data);
        done = data.readBoolean();
        setPattern((FillerPattern) FillerManager.registry.getPattern(Utils.readUTF(data)));

        worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
    }

    @Override
    public void handleDescriptionPacket(PacketUpdate packet) throws IOException {
        handlePacketPayload(packet.payload.stream);
    }

    @Override
    public void handleUpdatePacket(PacketUpdate packet) throws IOException {
        handlePacketPayload(packet.payload.stream);
    }

    @Override
    public boolean isActive() {
        return !done && lastMode != Mode.Off;
    }

    @Override
    public boolean manageFluids() {
        return false;
    }

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

    @Override
    public void openInventory() {
    }

    @Override
    public void closeInventory() {
    }

    @Override
    public void actionActivated(IAction action) {
        if (action == BuildCraftCore.actionOn) {
            lastMode = ActionMachineControl.Mode.On;
        } else if (action == BuildCraftCore.actionOff) {
            lastMode = ActionMachineControl.Mode.Off;
        } else if (action == BuildCraftCore.actionLoop) {
            lastMode = ActionMachineControl.Mode.Loop;
        } else if (action instanceof ActionFiller) {
            ActionFiller actFill = (ActionFiller) action;
            setPattern(actFill.pattern);
        }
    }

    @Override
    public boolean allowAction(IAction action) {
        return true;
    }

    @Override
    public boolean isItemValidForSlot(int slot, ItemStack stack) {
        return true;
    }

    public void rpcSetPatternFromString(String name) {
        RPCHandler.rpcServer(this, "setPatternFromString", name);
    }

    @RPC(RPCSide.SERVER)
    public void setPatternFromString(String name) {
        setPattern((FillerPattern) FillerManager.registry.getPattern(name));
    }

    @Override
    public boolean hasCustomInventoryName() {
        return false;
    }

    @Override
    public Box getBox() {
        return box;
    }

    @Override
    public AxisAlignedBB getRenderBoundingBox() {
        return new Box(this).extendToEncompass(box).expand(50).getBoundingBox();
    }

    @Override
    public boolean isBuildingMaterialSlot(int i) {
        return true;
    }

}