buildcraft.core.builders.BuildingItem.java Source code

Java tutorial

Introduction

Here is the source code for buildcraft.core.builders.BuildingItem.java

Source

/**
 * Copyright (c) 2011-2015, 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.core.builders;

import java.util.Date;
import java.util.LinkedList;

import io.netty.buffer.ByteBuf;

import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;

import net.minecraftforge.common.util.Constants;

import buildcraft.BuildCraftBuilders;
import buildcraft.api.blueprints.IBuilderContext;
import buildcraft.api.blueprints.MappingNotFoundException;
import buildcraft.api.blueprints.MappingRegistry;
import buildcraft.api.core.ISerializable;
import buildcraft.api.core.Position;
import buildcraft.core.StackAtPosition;

public class BuildingItem implements IBuildingItem, ISerializable {

    public static int ITEMS_SPACE = 2;

    public Position origin, destination;
    public LinkedList<StackAtPosition> stacksToDisplay = new LinkedList<StackAtPosition>();

    public Position posDisplay = new Position();
    public boolean isDone = false;

    public BuildingSlot slotToBuild;
    public IBuilderContext context;

    public double receivedProgress = 0;

    private long previousUpdate;
    private double lifetimeDisplay = 0;
    private double maxLifetime = 0;
    private boolean initialized = false;
    private double vx, vy, vz;
    private double maxHeight;
    private double lifetime = 0;

    public void initialize() {
        if (!initialized) {
            double dx = destination.x - origin.x;
            double dy = destination.y - origin.y;
            double dz = destination.z - origin.z;

            double size = Math.sqrt(dx * dx + dy * dy + dz * dz);

            maxLifetime = size * 4;

            // maxHeight = 5.0 + (destination.y - origin.y) / 2.0;

            maxHeight = size / 2;

            // the below computation is an approximation of the distance to
            // travel for the object. It really follows a sinus, but we compute
            // the size of a triangle for simplification.

            Position middle = new Position();
            middle.x = (destination.x + origin.x) / 2;
            middle.y = (destination.y + origin.y) / 2;
            middle.z = (destination.z + origin.z) / 2;

            Position top = new Position();
            top.x = middle.x;
            top.y = middle.y + maxHeight;
            top.z = middle.z;

            Position originToTop = new Position();
            originToTop.x = top.x - origin.x;
            originToTop.y = top.y - origin.y;
            originToTop.z = top.z - origin.z;

            Position destinationToTop = new Position();
            destinationToTop.x = destination.x - origin.x;
            destinationToTop.y = destination.y - origin.y;
            destinationToTop.z = destination.z - origin.z;

            Position distance = new Position();

            double d1 = Math.sqrt(
                    originToTop.x * originToTop.x + originToTop.y * originToTop.y + originToTop.z * originToTop.z);

            double d2 = Math.sqrt(destinationToTop.x * destinationToTop.x + destinationToTop.y * destinationToTop.y
                    + destinationToTop.z * destinationToTop.z);

            d1 = d1 / size * maxLifetime;
            d2 = d2 / size * maxLifetime;

            maxLifetime = d1 + d2;

            vx = dx / maxLifetime;
            vy = dy / maxLifetime;
            vz = dz / maxLifetime;

            if (stacksToDisplay.size() == 0) {
                StackAtPosition sPos = new StackAtPosition();
                sPos.stack = new ItemStack(BuildCraftBuilders.buildToolBlock);
                stacksToDisplay.add(sPos);
            }

            initialized = true;
        }
    }

    public Position getDisplayPosition(double time) {
        Position result = new Position();

        result.x = origin.x + vx * time;
        result.y = origin.y + vy * time + Math.sin(time / maxLifetime * Math.PI) * maxHeight;
        result.z = origin.z + vz * time;

        return result;
    }

    public void update() {
        if (isDone) {
            return;
        }

        initialize();

        lifetime++;

        if (lifetime > maxLifetime + stacksToDisplay.size() * ITEMS_SPACE - 1) {
            isDone = true;
            build();
        }

        lifetimeDisplay = lifetime;
        previousUpdate = new Date().getTime();

        if (slotToBuild != null && lifetime > maxLifetime) {
            slotToBuild.writeCompleted(context, (lifetime - maxLifetime) / (stacksToDisplay.size() * ITEMS_SPACE));
        }
    }

    public void displayUpdate() {
        initialize();

        double tickDuration = 1000.0 / 20.0;
        long currentUpdate = new Date().getTime();
        double timeSpan = currentUpdate - previousUpdate;
        previousUpdate = currentUpdate;

        double displayPortion = timeSpan / tickDuration;

        if (lifetimeDisplay - lifetime <= 1.0) {
            lifetimeDisplay += 1.0 * displayPortion;
        }
    }

    private void build() {
        if (slotToBuild != null) {
            int destX = (int) Math.floor(destination.x);
            int destY = (int) Math.floor(destination.y);
            int destZ = (int) Math.floor(destination.z);
            Block block = context.world().getBlock(destX, destY, destZ);
            int meta = context.world().getBlockMetadata(destX, destY, destZ);

            context.world().playAuxSFXAtEntity(null, 2001, destX, destY, destZ,
                    Block.getIdFromBlock(block) + (meta << 12));

            /*if (BlockUtil.isToughBlock(context.world(), destX, destY, destZ)) {
               BlockUtil.breakBlock(context.world(), destX, destY, destZ, BuildCraftBuilders.fillerLifespanTough);
            } else {
               BlockUtil.breakBlock(context.world(), destX, destY, destZ, BuildCraftBuilders.fillerLifespanNormal);
            }*/

            slotToBuild.writeToWorld(context);
        }
    }

    public LinkedList<StackAtPosition> getStacks() {
        int d = 0;

        for (StackAtPosition s : stacksToDisplay) {
            double stackLife = lifetimeDisplay - d;

            if (stackLife <= maxLifetime && stackLife > 0) {
                s.pos = getDisplayPosition(stackLife);
                s.display = true;
            } else {
                s.display = false;
            }

            d += ITEMS_SPACE;
        }

        return stacksToDisplay;
    }

    @Override
    public boolean isDone() {
        return isDone;
    }

    public void writeToNBT(NBTTagCompound nbt) {
        NBTTagCompound originNBT = new NBTTagCompound();
        origin.writeToNBT(originNBT);
        nbt.setTag("origin", originNBT);

        NBTTagCompound destinationNBT = new NBTTagCompound();
        destination.writeToNBT(destinationNBT);
        nbt.setTag("destination", destinationNBT);

        nbt.setDouble("lifetime", lifetime);

        NBTTagList items = new NBTTagList();

        for (StackAtPosition s : stacksToDisplay) {
            NBTTagCompound cpt = new NBTTagCompound();
            s.stack.writeToNBT(cpt);
            items.appendTag(cpt);
        }

        nbt.setTag("items", items);

        MappingRegistry registry = new MappingRegistry();

        NBTTagCompound slotNBT = new NBTTagCompound();
        NBTTagCompound registryNBT = new NBTTagCompound();

        slotToBuild.writeToNBT(slotNBT, registry);
        registry.write(registryNBT);

        nbt.setTag("registry", registryNBT);

        if (slotToBuild instanceof BuildingSlotBlock) {
            nbt.setByte("slotKind", (byte) 0);
        } else {
            nbt.setByte("slotKind", (byte) 1);
        }

        nbt.setTag("slotToBuild", slotNBT);
    }

    public void readFromNBT(NBTTagCompound nbt) throws MappingNotFoundException {
        origin = new Position(nbt.getCompoundTag("origin"));
        destination = new Position(nbt.getCompoundTag("destination"));
        lifetime = nbt.getDouble("lifetime");

        NBTTagList items = nbt.getTagList("items", Constants.NBT.TAG_COMPOUND);

        for (int i = 0; i < items.tagCount(); ++i) {
            StackAtPosition sPos = new StackAtPosition();
            sPos.stack = ItemStack.loadItemStackFromNBT(items.getCompoundTagAt(i));
            stacksToDisplay.add(sPos);
        }

        MappingRegistry registry = new MappingRegistry();
        registry.read(nbt.getCompoundTag("registry"));

        if (nbt.getByte("slotKind") == 0) {
            slotToBuild = new BuildingSlotBlock();
        } else {
            slotToBuild = new BuildingSlotEntity();
        }

        slotToBuild.readFromNBT(nbt.getCompoundTag("slotToBuild"), registry);
    }

    public void setStacksToDisplay(LinkedList<ItemStack> stacks) {
        if (stacks != null) {
            for (ItemStack s : stacks) {
                for (int i = 0; i < s.stackSize; ++i) {
                    StackAtPosition sPos = new StackAtPosition();
                    sPos.stack = s.copy();
                    sPos.stack.stackSize = 1;
                    stacksToDisplay.add(sPos);
                }
            }
        }
    }

    @Override
    public void readData(ByteBuf stream) {
        origin = new Position();
        destination = new Position();
        origin.readData(stream);
        destination.readData(stream);
        lifetime = stream.readDouble();
        stacksToDisplay.clear();
        int size = stream.readUnsignedShort();
        for (int i = 0; i < size; i++) {
            StackAtPosition e = new StackAtPosition();
            e.readData(stream);
            stacksToDisplay.add(e);
        }
    }

    @Override
    public void writeData(ByteBuf stream) {
        origin.writeData(stream);
        destination.writeData(stream);
        stream.writeDouble(lifetime);
        stream.writeShort(stacksToDisplay.size());
        for (StackAtPosition s : stacksToDisplay) {
            s.writeData(stream);
        }
    }
}