Package pneumaticCraft.common.tileentity

Source Code of pneumaticCraft.common.tileentity.TileEntityAirCannon

package pneumaticCraft.common.tileentity;

import java.util.List;
import java.util.Random;

import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityBoat;
import net.minecraft.entity.item.EntityExpBottle;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityMinecartChest;
import net.minecraft.entity.item.EntityMinecartEmpty;
import net.minecraft.entity.item.EntityMinecartFurnace;
import net.minecraft.entity.item.EntityMinecartHopper;
import net.minecraft.entity.item.EntityMinecartTNT;
import net.minecraft.entity.item.EntityTNTPrimed;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.entity.projectile.EntityEgg;
import net.minecraft.entity.projectile.EntityFireball;
import net.minecraft.entity.projectile.EntityPotion;
import net.minecraft.entity.projectile.EntitySnowball;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemMonsterPlacer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.ForgeDirection;

import org.apache.commons.lang3.tuple.Pair;

import pneumaticCraft.api.tileentity.IPneumaticMachine;
import pneumaticCraft.common.block.Blockss;
import pneumaticCraft.common.item.ItemMachineUpgrade;
import pneumaticCraft.common.item.Itemss;
import pneumaticCraft.common.network.NetworkHandler;
import pneumaticCraft.common.network.PacketPlaySound;
import pneumaticCraft.common.network.PacketSpawnParticle;
import pneumaticCraft.common.thirdparty.computercraft.LuaConstant;
import pneumaticCraft.common.thirdparty.computercraft.LuaMethod;
import pneumaticCraft.lib.ModIds;
import pneumaticCraft.lib.PneumaticValues;
import pneumaticCraft.lib.Sounds;
import pneumaticCraft.lib.TileEntityConstants;
import cpw.mods.fml.common.Optional;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.peripheral.IComputerAccess;

public class TileEntityAirCannon extends TileEntityPneumaticBase implements ISidedInventory, IInventory,
        IMinWorkingPressure, IRedstoneControl{

    private ItemStack[] inventory;
    private final Random rand = new Random();
    public float rotationAngle;
    public float heightAngle;
    public float targetRotationAngle;
    public float targetHeightAngle;
    public int ticks = 100;
    public boolean doneTurning = false;
    private boolean redstonePowered = false;
    public int gpsX;
    public int gpsY;
    public int gpsZ;
    public boolean coordWithinReach;
    public boolean fireOnlyOnRightAngle = true;
    private int oldRangeUpgrades;
    private boolean externalControl;//used in the CC API, to disallow the Cannon to update its angles when things like range upgrades / GPS Tool have changed.

    private final int INVENTORY_SIZE = 6;
    public final int CANNON_SLOT = 0;
    public final int GPS_SLOT = 1;
    public final int UPGRADE_SLOT_1 = 2;
    public final int UPGRADE_SLOT_2 = 3;
    public final int UPGRADE_SLOT_3 = 4;
    public final int UPGRADE_SLOT_4 = 5;

    public TileEntityAirCannon(){
        super(PneumaticValues.DANGER_PRESSURE_AIR_CANNON, PneumaticValues.MAX_PRESSURE_AIR_CANNON, PneumaticValues.VOLUME_AIR_CANNON);
        inventory = new ItemStack[INVENTORY_SIZE];
        setUpgradeSlots(new int[]{UPGRADE_SLOT_1, UPGRADE_SLOT_2, UPGRADE_SLOT_3, UPGRADE_SLOT_4});
    }

    @Override
    public void updateEntity(){
        ticks++;
        if(!worldObj.isRemote && ticks > 100) {
            sendDescriptionPacket();
            ticks = 0;
        }

        // GPS Tool read
        if(inventory[1] != null && inventory[1].getItem() == Itemss.GPSTool && !externalControl) {
            if(inventory[1].stackTagCompound != null) {

                NBTTagCompound gpsTag = inventory[1].stackTagCompound;
                int destinationX = gpsTag.getInteger("x");
                int destinationY = gpsTag.getInteger("y");
                int destinationZ = gpsTag.getInteger("z");

                if(destinationX != gpsX || destinationY != gpsY || destinationZ != gpsZ) {

                    gpsX = destinationX;
                    gpsY = destinationY;
                    gpsZ = destinationZ;
                    updateDestination();
                }
            }
        }

        int curRangeUpgrades = Math.min(8, getUpgrades(ItemMachineUpgrade.UPGRADE_RANGE, getUpgradeSlots()));
        if(curRangeUpgrades != oldRangeUpgrades) {
            oldRangeUpgrades = curRangeUpgrades;
            if(!externalControl) updateDestination();
        }

        // update angles
        doneTurning = true;
        float speedMultiplier = getSpeedMultiplierFromUpgrades(getUpgradeSlots());
        if(rotationAngle < targetRotationAngle) {
            if(rotationAngle < targetRotationAngle - TileEntityConstants.CANNON_SLOW_ANGLE) {
                rotationAngle += TileEntityConstants.CANNON_TURN_HIGH_SPEED * speedMultiplier;
            } else {
                rotationAngle += TileEntityConstants.CANNON_TURN_LOW_SPEED * speedMultiplier;
            }
            if(rotationAngle > targetRotationAngle) rotationAngle = targetRotationAngle;
            doneTurning = false;
        }
        if(rotationAngle > targetRotationAngle) {
            if(rotationAngle > targetRotationAngle + TileEntityConstants.CANNON_SLOW_ANGLE) {
                rotationAngle -= TileEntityConstants.CANNON_TURN_HIGH_SPEED * speedMultiplier;
            } else {
                rotationAngle -= TileEntityConstants.CANNON_TURN_LOW_SPEED * speedMultiplier;
            }
            if(rotationAngle < targetRotationAngle) rotationAngle = targetRotationAngle;
            doneTurning = false;
        }
        if(heightAngle < targetHeightAngle) {
            if(heightAngle < targetHeightAngle - TileEntityConstants.CANNON_SLOW_ANGLE) {
                heightAngle += TileEntityConstants.CANNON_TURN_HIGH_SPEED * speedMultiplier;
            } else {
                heightAngle += TileEntityConstants.CANNON_TURN_LOW_SPEED * speedMultiplier;
            }
            if(heightAngle > targetHeightAngle) heightAngle = targetHeightAngle;
            doneTurning = false;
        }
        if(heightAngle > targetHeightAngle) {
            if(heightAngle > targetHeightAngle + TileEntityConstants.CANNON_SLOW_ANGLE) {
                heightAngle -= TileEntityConstants.CANNON_TURN_HIGH_SPEED * speedMultiplier;
            } else {
                heightAngle -= TileEntityConstants.CANNON_TURN_LOW_SPEED * speedMultiplier;
            }
            if(heightAngle < targetHeightAngle) heightAngle = targetHeightAngle;
            doneTurning = false;
        }

        super.updateEntity();

    }

    // ANGLE METHODS -------------------------------------------------

    private void updateDestination(){
        doneTurning = false;
        // send a packet to the client to be able to show the right GPS coords
        // in the gui.
        if(!worldObj.isRemote) sendDescriptionPacket();
        // take dispenser upgrade in account
        double payloadFrictionY = 0.98D;// this value will differ when a
                                        // dispenser upgrade is inserted.
        double payloadFrictionX = 0.98D;
        double payloadGravity = 0.04D;
        if(getUpgrades(ItemMachineUpgrade.UPGRADE_DISPENSER_DAMAGE, getUpgradeSlots()) > 0 && inventory[0] != null) {// if
            // there
            // is
            // a
            // dispenser
            // upgrade
            // inserted.
            Item item = inventory[0].getItem();
            if(item == Items.potionitem || item == Items.experience_bottle || item == Items.egg || item == Items.snowball) {// EntityThrowable
                payloadFrictionY = 0.99D;
                payloadGravity = 0.03D;
            } else if(item == Items.arrow) {
                payloadFrictionY = 0.99D;
                payloadGravity = 0.05D;
            } else if(item == Items.minecart || item == Items.chest_minecart || item == Items.hopper_minecart || item == Items.tnt_minecart || item == Items.furnace_minecart) {
                payloadFrictionY = 0.95D;
            }
            // else if(itemID == Item.fireballCharge.itemID){
            // payloadGravity = 0.0D;
            // }

            // family items (throwable) which only differ in gravity.
            if(item == Items.potionitem) payloadGravity = 0.05D;
            else if(item == Items.experience_bottle) payloadGravity = 0.07D;

            payloadFrictionX = payloadFrictionY;

            // items which have different frictions for each axis.
            if(item == Items.boat) {
                payloadFrictionX = 0.99D;
                payloadFrictionY = 0.95D;
            }
            if(item == Items.spawn_egg) {
                payloadFrictionY = 0.98D;
                payloadFrictionX = 0.91D;
                payloadGravity = 0.08D;
            }
        }

        // calculate the heading.
        double deltaX = gpsX - xCoord;
        double deltaZ = gpsZ - zCoord;
        float calculatedRotationAngle;
        if(deltaX >= 0 && deltaZ < 0) {
            calculatedRotationAngle = (float)(Math.atan(Math.abs(deltaX / deltaZ)) / Math.PI * 180D);
        } else if(deltaX >= 0 && deltaZ >= 0) {
            calculatedRotationAngle = (float)(Math.atan(Math.abs(deltaZ / deltaX)) / Math.PI * 180D) + 90;
        } else if(deltaX < 0 && deltaZ >= 0) {
            calculatedRotationAngle = (float)(Math.atan(Math.abs(deltaX / deltaZ)) / Math.PI * 180D) + 180;
        } else {
            calculatedRotationAngle = (float)(Math.atan(Math.abs(deltaZ / deltaX)) / Math.PI * 180D) + 270;
        }

        // calculate the height angle.
        double distance = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ);
        double deltaY = gpsY - yCoord;
        float calculatedHeightAngle = calculateBestHeightAngle(distance, deltaY, getForce(), payloadGravity, payloadFrictionX, payloadFrictionY);

        setTargetAngles(calculatedRotationAngle, calculatedHeightAngle);
    }

    private float calculateBestHeightAngle(double distance, double deltaY, float force, double payloadGravity, double payloadFrictionX, double payloadFrictionY){
        double bestAngle = 0;
        double bestDistance = Float.MAX_VALUE;
        if(payloadGravity == 0D) {
            return 90F - (float)(Math.atan(deltaY / distance) * 180F / Math.PI);
        }
        for(double i = Math.PI * 0.25D; i < Math.PI * 0.50D; i += 0.001D) {
            double motionX = Math.cos(i) * force;// calculate the x component of
                                                 // the vector
            double motionY = Math.sin(i) * force;// calculate the y component of
                                                 // the vector
            double posX = 0;
            double posY = 0;
            while(posY > deltaY || motionY > 0) { // simulate movement, until we
                                                  // reach the y-level required
                posX += motionX;
                posY += motionY;
                motionY -= payloadGravity;// gravity
                motionX *= payloadFrictionX;// friction
                motionY *= payloadFrictionY;// friction
            }
            double distanceToTarget = Math.abs(distance - posX);// take the
                                                                // distance
            if(distanceToTarget < bestDistance) {// and return the best angle.
                bestDistance = distanceToTarget;
                bestAngle = i;
            }
        }
        coordWithinReach = bestDistance < 1.5D;
        return 90F - (float)(bestAngle * 180D / Math.PI);
    }

    public synchronized void setTargetAngles(float rotationAngle, float heightAngle){
        targetRotationAngle = rotationAngle;
        targetHeightAngle = heightAngle;
        if(!worldObj.isRemote) scheduleDescriptionPacket();
    }

    // this function calculates with the parsed in X and Z angles and the force
    // the needed, and outputs the X, Y and Z velocities.
    public double[] getVelocityVector(float angleX, float angleZ, float force){
        double[] velocities = new double[3];
        velocities[0] = Math.sin((double)angleZ / 180 * Math.PI);
        velocities[1] = Math.cos((double)angleX / 180 * Math.PI);
        velocities[2] = Math.cos((double)angleZ / 180 * Math.PI) * -1;

        velocities[0] *= Math.sin((double)angleX / 180 * Math.PI);
        velocities[2] *= Math.sin((double)angleX / 180 * Math.PI);
        // calculate the total velocity vector, in relation.
        double vectorTotal = velocities[0] * velocities[0] + velocities[1] * velocities[1] + velocities[2] * velocities[2];
        vectorTotal = force / vectorTotal; // calculate the relation between the
                                           // forces to be shot, and the
                                           // calculated vector (the scale).
        for(int i = 0; i < 3; i++) {
            velocities[i] *= vectorTotal; // scale up the velocities
            // System.out.println("velocities " + i + " = " + velocities[i]);
        }
        return velocities;
    }

    public boolean hasCoordinate(){
        return gpsX != 0 || gpsY != 0 || gpsZ != 0;
    }

    // PNEUMATIC METHODS -----------------------------------------

    @Override
    protected void disperseAir(){
        super.disperseAir();
        List<Pair<ForgeDirection, IPneumaticMachine>> teList = getConnectedPneumatics();
        if(teList.size() == 0) airLeak(ForgeDirection.getOrientation(getBlockMetadata()));
    }

    @Override
    public boolean isConnectedTo(ForgeDirection side){
        return ForgeDirection.getOrientation(worldObj.getBlockMetadata(xCoord, yCoord, zCoord)) == side;
    }

    public float getForce(){
        return 2F + oldRangeUpgrades;
    }

    // INVENTORY METHODS- && NBT
    // ------------------------------------------------------------

    /**
     * Returns the number of slots in the inventory.
     */
    @Override
    public int getSizeInventory(){

        return inventory.length;
    }

    /**
     * Returns the stack in slot i
     */
    @Override
    public ItemStack getStackInSlot(int slot){

        return inventory[slot];
    }

    @Override
    public ItemStack decrStackSize(int slot, int amount){

        ItemStack itemStack = getStackInSlot(slot);
        if(itemStack != null) {
            if(itemStack.stackSize <= amount) {
                setInventorySlotContents(slot, null);
            } else {
                itemStack = itemStack.splitStack(amount);
                if(itemStack.stackSize == 0) {
                    setInventorySlotContents(slot, null);
                }
            }
        }

        return itemStack;
    }

    @Override
    public ItemStack getStackInSlotOnClosing(int slot){

        ItemStack itemStack = getStackInSlot(slot);
        if(itemStack != null) {
            setInventorySlotContents(slot, null);
        }
        return itemStack;
    }

    @Override
    public void setInventorySlotContents(int slot, ItemStack itemStack){
        inventory[slot] = itemStack;
        if(itemStack != null && itemStack.stackSize > getInventoryStackLimit()) {
            itemStack.stackSize = getInventoryStackLimit();
        }
    }

    @Override
    public String getInventoryName(){
        return Blockss.airCannon.getUnlocalizedName();
    }

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

    @Override
    public void readFromNBT(NBTTagCompound nbtTagCompound){
        super.readFromNBT(nbtTagCompound);
        redstonePowered = nbtTagCompound.getBoolean("redstonePowered");
        targetRotationAngle = nbtTagCompound.getFloat("targetRotationAngle");
        targetHeightAngle = nbtTagCompound.getFloat("targetHeightAngle");
        rotationAngle = nbtTagCompound.getFloat("rotationAngle");
        heightAngle = nbtTagCompound.getFloat("heightAngle");
        gpsX = nbtTagCompound.getInteger("gpsX");
        gpsY = nbtTagCompound.getInteger("gpsY");
        gpsZ = nbtTagCompound.getInteger("gpsZ");
        fireOnlyOnRightAngle = nbtTagCompound.getBoolean("fireOnRightAngle");
        coordWithinReach = nbtTagCompound.getBoolean("targetWithinReach");
        // Read in the ItemStacks in the inventory from NBT
        NBTTagList tagList = nbtTagCompound.getTagList("Items", 10);
        inventory = new ItemStack[getSizeInventory()];
        for(int i = 0; i < tagList.tagCount(); ++i) {
            NBTTagCompound tagCompound = tagList.getCompoundTagAt(i);
            byte slot = tagCompound.getByte("Slot");
            if(slot >= 0 && slot < inventory.length) {
                inventory[slot] = ItemStack.loadItemStackFromNBT(tagCompound);
            }
        }
    }

    @Override
    public void writeToNBT(NBTTagCompound nbtTagCompound){
        super.writeToNBT(nbtTagCompound);
        nbtTagCompound.setBoolean("redstonePowered", redstonePowered);
        nbtTagCompound.setFloat("targetRotationAngle", targetRotationAngle);
        nbtTagCompound.setFloat("targetHeightAngle", targetHeightAngle);
        nbtTagCompound.setFloat("rotationAngle", rotationAngle);
        nbtTagCompound.setFloat("heightAngle", heightAngle);
        nbtTagCompound.setInteger("gpsX", gpsX);
        nbtTagCompound.setInteger("gpsY", gpsY);
        nbtTagCompound.setInteger("gpsZ", gpsZ);
        nbtTagCompound.setBoolean("fireOnRightAngle", fireOnlyOnRightAngle);
        nbtTagCompound.setBoolean("targetWithinReach", coordWithinReach);
        // Write the ItemStacks in the inventory to NBT
        NBTTagList tagList = new NBTTagList();
        for(int currentIndex = 0; currentIndex < inventory.length; ++currentIndex) {
            if(inventory[currentIndex] != null) {
                NBTTagCompound tagCompound = new NBTTagCompound();
                tagCompound.setByte("Slot", (byte)currentIndex);
                inventory[currentIndex].writeToNBT(tagCompound);
                tagList.appendTag(tagCompound);
            }
        }
        nbtTagCompound.setTag("Items", tagList);
    }

    @Override
    public boolean isItemValidForSlot(int i, ItemStack itemstack){
        if(i == GPS_SLOT && itemstack != null && itemstack.getItem() != Itemss.GPSTool) return false;
        if(i > GPS_SLOT && i <= UPGRADE_SLOT_4 && itemstack != null && itemstack.getItem() != Itemss.machineUpgrade) return false;
        return true;
    }

    @Override
    // upgrades and GPS can be inserted/extracted from and into the bottom,
    // other sides are cannon slots.
    public int[] getAccessibleSlotsFromSide(int var1){
        if(var1 == 0) return new int[]{1, 2, 3, 4, 5};
        return new int[]{0};
    }

    @Override
    public boolean canInsertItem(int slot, ItemStack itemstack, int side){
        return true;
    }

    @Override
    public boolean canExtractItem(int slot, ItemStack itemstack, int side){
        return true;
    }

    @Override
    public boolean isUseableByPlayer(EntityPlayer var1){
        return isGuiUseableByPlayer(var1);
    }

    // REDSTONE BEHAVIOUR
    // ------------------------------------------------------------

    @Override
    public void handleGUIButtonPress(int buttonID, EntityPlayer player){
        if(buttonID == 0) {
            fireOnlyOnRightAngle = !fireOnlyOnRightAngle;
            sendDescriptionPacket();
        }
    }

    public void onNeighbourBlockChange(int x, int y, int z, Block block){
        if(!block.isAir(worldObj, x, y, z) && worldObj.isBlockIndirectlyGettingPowered(x, y, z) && !redstonePowered && (!fireOnlyOnRightAngle || doneTurning)) {
            fire();
            redstonePowered = true;
        } else if(!worldObj.isBlockIndirectlyGettingPowered(x, y, z) && redstonePowered) {
            redstonePowered = false;
        }
    }

    private synchronized boolean fire(){
        double[] velocity = getVelocityVector(heightAngle, rotationAngle, getForce());
        if(getPressure(ForgeDirection.UNKNOWN) >= PneumaticValues.MIN_PRESSURE_AIR_CANNON && inventory[0] != null) {
            addAir((int)(-500 * getForce()), ForgeDirection.UNKNOWN);
            Entity itemShot = getPayloadEntity();
            itemShot.setPosition(xCoord + 0.5D, yCoord + 1.8D, zCoord + 0.5D);
            if(itemShot instanceof EntityFireball) {
                velocity[0] *= 0.05D;
                velocity[1] *= 0.05D;
                velocity[2] *= 0.05D;
            }

            itemShot.motionX = velocity[0];
            itemShot.motionY = velocity[1];
            itemShot.motionZ = velocity[2];
            if(!worldObj.isRemote) worldObj.spawnEntityInWorld(itemShot);

            if(itemShot instanceof EntityItem) {
                inventory[0] = null;
            } else {
                inventory[0].stackSize--;
                if(inventory[0].stackSize <= 0) inventory[0] = null;
            }
            for(int i = 0; i < 10; i++) {
                double velX = velocity[0] * 0.4D + (rand.nextGaussian() - 0.5D) * 0.05D;
                double velY = velocity[1] * 0.4D + (rand.nextGaussian() - 0.5D) * 0.05D;
                double velZ = velocity[2] * 0.4D + (rand.nextGaussian() - 0.5D) * 0.05D;
                NetworkHandler.sendToAllAround(new PacketSpawnParticle("largesmoke", xCoord + 0.5D, yCoord + 0.7D, zCoord + 0.5D, velX, velY, velZ), worldObj);
            }
            NetworkHandler.sendToAllAround(new PacketPlaySound(Sounds.CANNON_SOUND, xCoord, yCoord, zCoord, 1.0F, rand.nextFloat() / 4F + 0.75F, true), worldObj);
            return true;
        } else {
            return false;
        }
    }

    // warning: no null-check for inventory slot 0
    private Entity getPayloadEntity(){

        if(getUpgrades(ItemMachineUpgrade.UPGRADE_DISPENSER_DAMAGE, getUpgradeSlots()) > 0) {
            Item item = inventory[0].getItem();
            if(item == Item.getItemFromBlock(Blocks.tnt)) {
                EntityTNTPrimed tnt = new EntityTNTPrimed(worldObj);
                tnt.fuse = 80;
                return tnt;
            } else if(item == Items.experience_bottle) return new EntityExpBottle(worldObj);
            else if(item == Items.potionitem) {
                EntityPotion potion = new EntityPotion(worldObj);
                potion.setPotionDamage(inventory[0].getItemDamage());
                return potion;
            } else if(item == Items.arrow) return new EntityArrow(worldObj);
            else if(item == Items.egg) return new EntityEgg(worldObj);
            // else if(itemID == Item.fireballCharge) return new
            // EntitySmallFireball(worldObj);
            else if(item == Items.snowball) return new EntitySnowball(worldObj);
            else if(item == Items.spawn_egg) return ItemMonsterPlacer.spawnCreature(worldObj, inventory[0].getItemDamage(), 0, 0, 0);
            else if(item == Items.minecart) return new EntityMinecartEmpty(worldObj);
            else if(item == Items.chest_minecart) return new EntityMinecartChest(worldObj);
            else if(item == Items.furnace_minecart) return new EntityMinecartFurnace(worldObj);
            else if(item == Items.hopper_minecart) return new EntityMinecartHopper(worldObj);
            else if(item == Items.tnt_minecart) return new EntityMinecartTNT(worldObj);
            else if(item == Items.boat) return new EntityBoat(worldObj);

        }
        EntityItem item = new EntityItem(worldObj);
        item.setEntityItemStack(inventory[0].copy());
        item.age = 4800; // 1200 ticks left to live, = 60s.
        item.lifespan += Math.min(getUpgrades(ItemMachineUpgrade.UPGRADE_ITEM_LIFE, getUpgradeSlots()) * 600, 4800); // add
        // 30s
        // for
        // each
        // life
        // upgrade,
        // to
        // the
        // max
        // of
        // 5
        // min.
        return item;

    }

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

    @Override
    public void openInventory(){}

    @Override
    public void closeInventory(){}

    /*
     *  COMPUTERCRAFT API
     */

    @Override
    public String getType(){
        return "airCannon";
    }

    @Override
    @Optional.Method(modid = ModIds.COMPUTERCRAFT)
    protected void addLuaMethods(){
        super.addLuaMethods();
        luaMethods.add(new LuaConstant("getMinWorkingPressure", PneumaticValues.MIN_PRESSURE_AIR_CANNON));

        luaMethods.add(new LuaMethod("setTargetLocation"){
            @Override
            public Object[] call(IComputerAccess computer, ILuaContext context, Object[] args) throws LuaException, InterruptedException{
                if(args.length == 3) {
                    gpsX = ((Double)args[0]).intValue();
                    gpsY = ((Double)args[1]).intValue();
                    gpsZ = ((Double)args[2]).intValue();
                    updateDestination();
                    return new Object[]{coordWithinReach};
                } else {
                    throw new IllegalArgumentException("setTargetLocation requires 3 parameters (x,y,z)");
                }
            }
        });

        luaMethods.add(new LuaMethod("fire"){
            @Override
            public Object[] call(IComputerAccess computer, ILuaContext context, Object[] args) throws LuaException, InterruptedException{
                if(args.length == 0) {
                    return new Object[]{fire()};//returns true if the fire succeeded.
                } else {
                    throw new IllegalArgumentException("fire doesn't take any arguments!");
                }
            }
        });
        luaMethods.add(new LuaMethod("isDoneTurning"){
            @Override
            public Object[] call(IComputerAccess computer, ILuaContext context, Object[] args) throws LuaException, InterruptedException{
                if(args.length == 0) {
                    return new Object[]{doneTurning};
                } else {
                    throw new IllegalArgumentException("isDoneTurning doesn't take any arguments!");
                }
            }
        });

        luaMethods.add(new LuaMethod("setRotationAngle"){
            @Override
            public Object[] call(IComputerAccess computer, ILuaContext context, Object[] args) throws LuaException, InterruptedException{
                if(args.length == 1) {
                    setTargetAngles(((Double)args[0]).floatValue(), targetHeightAngle);
                    return null;
                } else {
                    throw new IllegalArgumentException("setRotationAngle does take one argument!");
                }
            }
        });

        luaMethods.add(new LuaMethod("setHeightAngle"){
            @Override
            public Object[] call(IComputerAccess computer, ILuaContext context, Object[] args) throws LuaException, InterruptedException{
                if(args.length == 1) {
                    setTargetAngles(targetRotationAngle, 90 - ((Double)args[0]).floatValue());
                    return null;
                } else {
                    throw new IllegalArgumentException("setHeightAngle does take one argument!");
                }
            }
        });

        luaMethods.add(new LuaMethod("setExternalControl"){
            @Override
            public Object[] call(IComputerAccess computer, ILuaContext context, Object[] args) throws LuaException, InterruptedException{
                if(args.length == 1) {
                    externalControl = (Boolean)args[0];
                    return null;
                } else {
                    throw new IllegalArgumentException("setExternalControl does take one argument!");
                }
            }
        });
    }

    @Override
    public float getMinWorkingPressure(){
        return PneumaticValues.MIN_PRESSURE_AIR_CANNON;
    }

    @Override
    public int getRedstoneMode(){
        return fireOnlyOnRightAngle ? 0 : 1;
    }
}
TOP

Related Classes of pneumaticCraft.common.tileentity.TileEntityAirCannon

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.