zeldaswordskills.entity.projectile.EntityMobThrowable.java Source code

Java tutorial

Introduction

Here is the source code for zeldaswordskills.entity.projectile.EntityMobThrowable.java

Source

/**
Copyright (C) <2015> <coolAlias>
    
This file is part of coolAlias' Zelda Sword Skills Minecraft Mod; as such,
you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package zeldaswordskills.entity.projectile;

import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;

/**
 * 
 * Abstract class that provides constructor for throwing entity as a mob
 *
 */
public abstract class EntityMobThrowable extends EntityThrowable implements IEntityAdditionalSpawnData {
    /** The throwing entity's ID, in case it is not a player. Only used after loading from NBT */
    private int throwerId;

    /** Usually the damage this entity will cause upon impact */
    private float damage;

    /** Projectile gravity velocity */
    private float gravity = 0.03F;

    public EntityMobThrowable(World world) {
        super(world);
    }

    public EntityMobThrowable(World world, EntityLivingBase entity) {
        super(world, entity);
    }

    public EntityMobThrowable(World world, double x, double y, double z) {
        super(world, x, y, z);
    }

    /**
     * Constructs a throwable entity heading towards target's initial position with given velocity, with possible abnormal trajectory;
     * @param inaccuracy amount of deviation from base trajectory, used by Skeletons and the like; set to 0.0F for no x/z deviation
     */
    public EntityMobThrowable(World world, EntityLivingBase shooter, EntityLivingBase target, float velocity,
            float inaccuracy) {
        super(world, shooter);
        this.posY = shooter.posY + (double) shooter.getEyeHeight() - 0.10000000149011612D;
        double d0 = target.posX - shooter.posX;
        double d1 = target.getEntityBoundingBox().minY + (double) (target.height / 3.0F) - this.posY;
        double d2 = target.posZ - shooter.posZ;
        double d3 = (double) MathHelper.sqrt_double(d0 * d0 + d2 * d2);
        if (d3 >= 1.0E-7D) {
            float f2 = (float) (Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
            float f3 = (float) (-(Math.atan2(d1, d3) * 180.0D / Math.PI));
            double d4 = d0 / d3;
            double d5 = d2 / d3;
            setLocationAndAngles(shooter.posX + d4, this.posY, shooter.posZ + d5, f2, f3);
            float f4 = (float) d3 * 0.2F;
            setThrowableHeading(d0, d1 + (double) f4, d2, velocity, inaccuracy);
        }
    }

    @Override
    public EntityLivingBase getThrower() {
        EntityLivingBase thrower = super.getThrower();
        if (thrower == null) {
            Entity entity = worldObj.getEntityByID(throwerId);
            return (entity instanceof EntityLivingBase ? (EntityLivingBase) entity : null);
        }
        return thrower;
    }

    /** Returns the amount of damage this entity will cause upon impact */
    public float getDamage() {
        return damage;
    }

    /**
     * Sets the damage this entity will cause upon impact
     */
    public EntityMobThrowable setDamage(float amount) {
        this.damage = amount;
        return this;
    }

    /**
     * Re-sets the projectile's heading on the exact same trajectory but using the given velocity
     */
    public EntityMobThrowable setProjectileVelocity(float velocity) {
        this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, velocity, 0.0F);
        return this;
    }

    @Override
    protected float getGravityVelocity() {
        return gravity;
    }

    /**
     * Sets the projectile's gravity velocity
     */
    public EntityMobThrowable setGravityVelocity(float amount) {
        this.gravity = amount;
        return this;
    }

    @Override
    public void onUpdate() {
        super.onUpdate();
        if ((!gravityCheck() || posY > 255.0F) && !worldObj.isRemote) {
            setDead();
        }
    }

    /**
     * Sanity check for gravity - return true if the entity can stay alive.
     * Note that it will be killed anyway once it surpasses y=255.
     */
    protected boolean gravityCheck() {
        return getGravityVelocity() > 0.0F || ticksExisted < 60;
    }

    @Override
    public void writeEntityToNBT(NBTTagCompound compound) {
        super.writeEntityToNBT(compound);
        compound.setInteger("throwerId", (getThrower() == null ? -1 : getThrower().getEntityId()));
        compound.setFloat("damage", damage);
        compound.setFloat("gravity", gravity);
    }

    @Override
    public void readEntityFromNBT(NBTTagCompound compound) {
        super.readEntityFromNBT(compound);
        throwerId = compound.getInteger("throwerId");
        damage = compound.getFloat("damage");
        gravity = compound.getFloat("gravity");
    }

    @Override
    public void writeSpawnData(ByteBuf buffer) {
        buffer.writeFloat(gravity);
    }

    @Override
    public void readSpawnData(ByteBuf buffer) {
        gravity = buffer.readFloat();
    }
}