micdoodle8.mods.galacticraft.core.entities.GCCoreEntityLander.java Source code

Java tutorial

Introduction

Here is the source code for micdoodle8.mods.galacticraft.core.entities.GCCoreEntityLander.java

Source

package micdoodle8.mods.galacticraft.core.entities;

import java.util.ArrayList;
import java.util.List;

import micdoodle8.mods.galacticraft.api.vector.Vector3;
import micdoodle8.mods.galacticraft.core.GalacticraftCore;
import micdoodle8.mods.galacticraft.core.client.fx.GCCoreEntityLanderFlameFX;
import micdoodle8.mods.galacticraft.core.entities.player.GCCorePlayerMP;
import micdoodle8.mods.galacticraft.core.inventory.IInventorySettable;
import micdoodle8.mods.galacticraft.core.items.GCCoreItems;
import micdoodle8.mods.galacticraft.core.network.GCCorePacketHandlerClient.EnumPacketClient;
import micdoodle8.mods.galacticraft.core.network.GCCorePacketHandlerServer.EnumPacketServer;
import micdoodle8.mods.galacticraft.core.network.GCCorePacketManager;
import micdoodle8.mods.galacticraft.core.util.GCCoreUtil;
import micdoodle8.mods.galacticraft.core.util.PacketUtil;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;

import com.google.common.io.ByteArrayDataInput;

import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

/**
 * GCCoreEntityLander.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 GCCoreEntityLander extends InventoryEntity
        implements IInventorySettable, IScaleableFuelLevel, IControllableEntity {
    private final int tankCapacity = 5000;
    public FluidTank fuelTank = new FluidTank(this.tankCapacity);
    private boolean waitForPlayer;
    private boolean lastWaitForPlayer;
    public float currentDamage;
    public int timeSinceHit;
    public int rockDirection = 1;
    public boolean lastOnGround;
    private double lastMotionY;

    public GCCoreEntityLander(World par1World) {
        super(par1World);
        this.setSize(3.5F, 4.8F);
        this.ignoreFrustumCheck = true;
        this.isImmuneToFire = true;
    }

    public GCCoreEntityLander(GCCorePlayerMP player) {
        this(player.worldObj);

        this.containedItems = new ItemStack[player.getRocketStacks().length + 1];
        this.fuelTank.setFluid(new FluidStack(GalacticraftCore.fluidFuel, player.getFuelLevel()));

        for (int i = 0; i < player.getRocketStacks().length; i++) {
            this.containedItems[i] = player.getRocketStacks()[i];
        }
    }

    @Override
    protected void entityInit() {
        ;
    }

    @Override
    protected void readEntityFromNBT(NBTTagCompound nbt) {
        NBTTagList itemList = nbt.getTagList("Items");
        this.containedItems = new ItemStack[nbt.getInteger("rocketStacksLength")];

        for (int i = 0; i < itemList.tagCount(); ++i) {
            NBTTagCompound itemTag = (NBTTagCompound) itemList.tagAt(i);
            int slotID = itemTag.getByte("Slot") & 255;

            if (slotID >= 0 && slotID < this.containedItems.length) {
                this.containedItems[slotID] = ItemStack.loadItemStackFromNBT(itemTag);
            }
        }

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

        this.setWaitForPlayer(nbt.getBoolean("WaitingForPlayer"));

        this.lastOnGround = this.onGround;
        this.lastMotionY = this.motionY;
    }

    @Override
    protected void writeEntityToNBT(NBTTagCompound nbt) {
        NBTTagList itemList = new NBTTagList();

        nbt.setInteger("rocketStacksLength", this.containedItems.length);

        for (int i = 0; i < this.containedItems.length; ++i) {
            if (this.containedItems[i] != null) {
                NBTTagCompound itemTag = new NBTTagCompound();
                itemTag.setByte("Slot", (byte) i);
                this.containedItems[i].writeToNBT(itemTag);
                itemList.appendTag(itemTag);
            }
        }

        nbt.setTag("Items", itemList);

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

        nbt.setBoolean("WaitingForPlayer", this.getWaitForPlayer());
    }

    @Override
    public void onUpdate() {
        if (this.timeSinceHit > 0) {
            this.timeSinceHit--;
        }

        if (this.currentDamage > 0.0F) {
            this.currentDamage--;
        }

        if (this.getWaitForPlayer()) {
            if (this.riddenByEntity != null) {
                if (this.ticksExisted >= 40) {
                    if (!this.worldObj.isRemote) {
                        Entity e = this.riddenByEntity;
                        this.riddenByEntity.ridingEntity = null;
                        this.riddenByEntity = null;
                        e.mountEntity(this);
                    }

                    this.setWaitForPlayer(false);
                } else {
                    this.motionX = this.motionY = this.motionZ = 0.0D;
                    this.riddenByEntity.motionX = this.riddenByEntity.motionY = this.riddenByEntity.motionZ = 0;
                }
            } else {
                this.motionX = this.motionY = this.motionZ = 0.0D;
            }
        }

        if (!this.waitForPlayer && this.lastWaitForPlayer) {
            this.motionY = -3.5D;
        }

        super.onUpdate();

        if (!this.onGround && Math.abs(this.motionY) > 0.01
                && FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) {
            this.spawnParticles();
        }

        AxisAlignedBB box = this.boundingBox.expand(0.2D, 0.4D, 0.2D);

        final List<?> var15 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, box);

        if (var15 != null && !var15.isEmpty()) {
            for (int var52 = 0; var52 < var15.size(); ++var52) {
                final Entity var17 = (Entity) var15.get(var52);

                if (var17 != this.riddenByEntity) {
                    this.pushEntityAway(var17);
                }
            }
        }

        if (!this.worldObj.isRemote) {
            final FluidStack liquid = this.fuelTank.getFluid();

            if (liquid != null && this.fuelTank.getFluid() != null
                    && this.fuelTank.getFluid().getFluid().getName().equalsIgnoreCase("Fuel")) {
                if (FluidContainerRegistry.isEmptyContainer(this.containedItems[this.containedItems.length - 1])) {
                    boolean isCanister = this.containedItems[this.containedItems.length - 1].isItemEqual(
                            new ItemStack(GCCoreItems.oilCanister, 1, GCCoreItems.oilCanister.getMaxDamage()));
                    final int amountToFill = Math.min(liquid.amount,
                            isCanister ? GCCoreItems.fuelCanister.getMaxDamage() - 1
                                    : FluidContainerRegistry.BUCKET_VOLUME);

                    if (isCanister) {
                        this.containedItems[this.containedItems.length - 1] = new ItemStack(
                                GCCoreItems.fuelCanister, 1,
                                GCCoreItems.fuelCanister.getMaxDamage() - amountToFill);
                    } else {
                        this.containedItems[this.containedItems.length - 1] = FluidContainerRegistry
                                .fillFluidContainer(liquid, this.containedItems[this.containedItems.length - 1]);
                    }

                    this.fuelTank.drain(amountToFill, true);
                }
            }
        }

        this.motionY -= 0.008D;

        if (this.worldObj.isRemote && FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) {
            this.sendPacketToServer();
        }

        if (this.onGround) {
            this.motionX = this.motionY = this.motionZ = 0.0D;
        } else {
            if (this.worldObj.isRemote) {
                this.motionX = -50.0 * Math.cos(Math.toRadians(this.rotationYaw))
                        * Math.sin(Math.toRadians(this.rotationPitch * 0.01));
                this.motionZ = -50.0 * Math.sin(Math.toRadians(this.rotationYaw))
                        * Math.sin(Math.toRadians(this.rotationPitch * 0.01));
            }

            this.moveEntity(this.motionX, this.motionY, this.motionZ);
        }

        if (!this.worldObj.isRemote) {
            if (this.onGround && !this.lastOnGround) {
                if (Math.abs(this.lastMotionY) > 2.0D) {
                    if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayerMP) {
                        final Object[] toSend2 = { 0 };
                        ((EntityPlayerMP) this.riddenByEntity).playerNetServerHandler.sendPacketToPlayer(PacketUtil
                                .createPacket(GalacticraftCore.CHANNEL, EnumPacketClient.ZOOM_CAMERA, toSend2));

                        this.riddenByEntity.mountEntity(this);
                    }

                    this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, 12, true);

                    this.setDead();
                }
            }
        }

        if (this.onGround) {
            this.rotationPitch = 0.0F;
        }

        this.lastWaitForPlayer = this.waitForPlayer;
        this.lastOnGround = this.onGround;
        this.lastMotionY = this.motionY;
    }

    @SideOnly(Side.CLIENT)
    private void spawnParticles() {
        final double x1 = 2 * Math.cos(this.rotationYaw * Math.PI / 180.0D)
                * Math.sin(this.rotationPitch * Math.PI / 180.0D);
        final double z1 = 2 * Math.sin(this.rotationYaw * Math.PI / 180.0D)
                * Math.sin(this.rotationPitch * Math.PI / 180.0D);
        final double y1 = -5.0D;

        final float angle1 = (float) ((this.rotationYaw - 40.0F) * Math.PI / 180.0F);
        final float angle2 = (float) ((this.rotationYaw + 40.0F) * Math.PI / 180.0F);
        final float angle3 = (float) ((this.rotationYaw + 180 - 40.0F) * Math.PI / 180.0F);
        final float angle4 = (float) ((this.rotationYaw + 180 + 40.0F) * Math.PI / 180.0F);
        final float pitch = (float) Math.sin(this.rotationPitch * Math.PI / 180.0F);

        Vector3 vec1 = new Vector3(this).translate(new Vector3(0.4 * Math.cos(angle1) * Math.cos(pitch), 0.5,
                0.4 * Math.sin(angle1) * Math.cos(pitch)));
        Vector3 vec2 = new Vector3(this).translate(new Vector3(0.4 * Math.cos(angle2) * Math.cos(pitch), 0.5,
                0.4 * Math.sin(angle2) * Math.cos(pitch)));
        Vector3 vec3 = new Vector3(this).translate(new Vector3(0.4 * Math.cos(angle3) * Math.cos(pitch), 0.5,
                0.4 * Math.sin(angle3) * Math.cos(pitch)));
        Vector3 vec4 = new Vector3(this).translate(new Vector3(0.4 * Math.cos(angle4) * Math.cos(pitch), 0.5,
                0.4 * Math.sin(angle4) * Math.cos(pitch)));

        this.spawnParticle(new GCCoreEntityLanderFlameFX(this.worldObj, vec1.x, vec1.y, vec1.z, x1, y1, z1));
        this.spawnParticle(new GCCoreEntityLanderFlameFX(this.worldObj, vec2.x, vec2.y, vec2.z, x1, y1, z1));
        this.spawnParticle(new GCCoreEntityLanderFlameFX(this.worldObj, vec3.x, vec3.y, vec3.z, x1, y1, z1));
        this.spawnParticle(new GCCoreEntityLanderFlameFX(this.worldObj, vec4.x, vec4.y, vec4.z, x1, y1, z1));
    }

    @SideOnly(Side.CLIENT)
    private void spawnParticle(EntityFX fx) {
        final Minecraft mc = FMLClientHandler.instance().getClient();

        if (mc != null && mc.renderViewEntity != null && mc.effectRenderer != null) {
            if (fx != null) {
                mc.effectRenderer.addEffect(fx);
            }
        }
    }

    private void sendPacketToServer() {
        if (this.riddenByEntity == FMLClientHandler.instance().getClient().thePlayer) {
            PacketDispatcher.sendPacketToServer(GCCorePacketManager.getPacket(GalacticraftCore.CHANNELENTITIES,
                    this, this.getNetworkedData(new ArrayList<Object>())));
        }
    }

    public void pushEntityAway(Entity par1Entity) {
        if (this.riddenByEntity != par1Entity && this.ridingEntity != par1Entity) {
            double d0 = this.posX - par1Entity.posX;
            double d1 = this.posZ - par1Entity.posZ;
            double d2 = MathHelper.abs_max(d0, d1);

            if (d2 >= 0.009999999776482582D) {
                d2 = MathHelper.sqrt_double(d2);
                d0 /= d2;
                d1 /= d2;
                double d3 = 1.0D / d2;

                if (d3 > 1.0D) {
                    d3 = 1.0D;
                }

                d0 *= d3;
                d1 *= d3;
                d0 *= 0.05000000074505806D;
                d1 *= 0.05000000074505806D;
                d0 *= 1.0F - par1Entity.entityCollisionReduction;
                d1 *= 1.0F - par1Entity.entityCollisionReduction;
                par1Entity.addVelocity(-d0, 0.0D, -d1);
            }
        }
    }

    @Override
    public boolean pressKey(int key) {
        if (this.onGround) {
            return false;
        }

        float turnFactor = 2.0F;

        switch (key) {
        case 0:
            if (!this.onGround) {
                this.rotationPitch = Math.min(Math.max(this.rotationPitch - 0.5F * turnFactor, -35), 35);
            }

            return true;
        case 1:
            if (!this.onGround) {
                this.rotationPitch = Math.min(Math.max(this.rotationPitch + 0.5F * turnFactor, -35), 35);
            }

            return true;
        case 2:
            if (!this.onGround) {
                this.rotationYaw -= 0.5F * turnFactor;
            }

            return true;
        case 3:
            if (!this.onGround) {
                this.rotationYaw += 0.5F * turnFactor;
            }

            return true;
        case 4:
            this.motionY = Math.min(this.motionY + 0.03F, -1.0);
            return true;
        case 5:
            this.motionY = Math.min(this.motionY - 0.022F, -1.0);
            return true;
        }

        return false;
    }

    @Override
    public double getMountedYOffset() {
        return 1.0D;
    }

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

    @Override
    public String getInvName() {
        return "Lander";
    }

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

    @Override
    public boolean isItemValidForSlot(int i, ItemStack itemstack) {
        return false;
    }

    @Override
    public int getScaledFuelLevel(int scale) {
        return (int) ((double) this.fuelTank.getFluidAmount() / (double) this.tankCapacity * scale);
    }

    @Override
    public void setSizeInventory(int size) {
        this.containedItems = new ItemStack[size];
    }

    @Override
    protected boolean canTriggerWalking() {
        return false;
    }

    @Override
    public AxisAlignedBB getBoundingBox() {
        return null;
    }

    @Override
    public AxisAlignedBB getCollisionBox(Entity par1Entity) {
        return null;
    }

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

    @Override
    public boolean canBeCollidedWith() {
        return !this.isDead;
    }

    @Override
    public boolean attackEntityFrom(DamageSource var1, float var2) {
        if (this.isDead || var1.equals(DamageSource.cactus) || this.riddenByEntity != null) {
            return true;
        } else {
            this.rockDirection = -this.rockDirection;
            this.timeSinceHit = 10;
            this.currentDamage = this.currentDamage + var2 * 10;
            this.setBeenAttacked();

            if (var1.getEntity() instanceof EntityPlayer
                    && ((EntityPlayer) var1.getEntity()).capabilities.isCreativeMode) {
                this.currentDamage = 100;
            }

            if (this.currentDamage > 70) {
                if (this.riddenByEntity != null) {
                    if (this.riddenByEntity instanceof EntityPlayerMP) {
                        final Object[] toSend2 = { 0 };
                        ((EntityPlayerMP) this.riddenByEntity).playerNetServerHandler.sendPacketToPlayer(PacketUtil
                                .createPacket(GalacticraftCore.CHANNEL, EnumPacketClient.ZOOM_CAMERA, toSend2));
                    }

                    this.riddenByEntity.mountEntity(this);

                    return false;
                }

                if (!this.worldObj.isRemote) {
                    if (this.riddenByEntity != null) {
                        this.riddenByEntity.mountEntity(this);
                    }

                    this.dropItems();

                    this.setDead();
                }
            }

            return true;
        }
    }

    @Override
    public boolean interactFirst(EntityPlayer var1) {
        if (this.worldObj.isRemote) {
            return false;
        }

        if (this.riddenByEntity == null && var1 instanceof EntityPlayerMP) {
            GCCoreUtil.openParachestInv((EntityPlayerMP) var1, this);
            return true;
        } else if (var1 instanceof EntityPlayerMP) {
            ((EntityPlayerMP) var1).playerNetServerHandler.sendPacketToPlayer(PacketUtil
                    .createPacket(GalacticraftCore.CHANNEL, EnumPacketClient.ZOOM_CAMERA, new Object[] { 0 }));
            var1.mountEntity(null);
            return true;
        } else {
            return true;
        }
    }

    @Override
    public void readNetworkedData(ByteArrayDataInput dataStream) {
        if (this.worldObj.isRemote) {
            int cargoLength = dataStream.readInt();

            if (this.containedItems == null || this.containedItems.length == 0) {
                this.containedItems = new ItemStack[cargoLength];
                PacketDispatcher.sendPacketToServer(PacketUtil.createPacket(GalacticraftCore.CHANNEL,
                        EnumPacketServer.UPDATE_DYNAMIC_ENTITY_INV, new Object[] { this.entityId }));
            }

            this.fuelTank.setFluid(new FluidStack(GalacticraftCore.fluidFuel, dataStream.readInt()));

            this.setWaitForPlayer(dataStream.readBoolean());

            this.onGround = dataStream.readBoolean();
        } else {
            this.motionX = dataStream.readDouble() / 8000.0D;
            this.motionY = dataStream.readDouble() / 8000.0D;
            this.motionZ = dataStream.readDouble() / 8000.0D;

            this.rotationPitch = dataStream.readFloat();
            this.rotationYaw = dataStream.readFloat();
        }
    }

    @Override
    public ArrayList<Object> getNetworkedData(ArrayList<Object> list) {
        if (!this.worldObj.isRemote) {
            list.add(this.containedItems != null ? this.containedItems.length : 0);
            list.add(this.fuelTank.getFluidAmount());

            list.add(this.getWaitForPlayer());

            list.add(this.onGround);

            return list;
        } else {
            list.add(this.motionX * 8000.0D);
            list.add(this.motionY * 8000.0D);
            list.add(this.motionZ * 8000.0D);

            list.add(this.rotationPitch);
            list.add(this.rotationYaw);

            return list;
        }
    }

    @Override
    public double getPacketRange() {
        return 100.0D;
    }

    public boolean getWaitForPlayer() {
        return this.waitForPlayer;
    }

    public void setWaitForPlayer(boolean waitForPlayer) {
        this.waitForPlayer = waitForPlayer;
    }

    public void dropItems() {
        for (ItemStack item : this.getItemsDropped()) {
            if (item != null) {
                this.entityDropItem(item, 0);
            }
        }
    }

    public List<ItemStack> getItemsDropped() {
        final List<ItemStack> items = new ArrayList<ItemStack>();

        for (ItemStack stack : this.containedItems) {
            if (stack != null) {
                items.add(stack);
            }
        }

        return items;
    }
}