com.yyon.grapplinghook.entities.grappleArrow.java Source code

Java tutorial

Introduction

Here is the source code for com.yyon.grapplinghook.entities.grappleArrow.java

Source

package com.yyon.grapplinghook.entities;

import io.netty.buffer.ByteBuf;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

import com.yyon.grapplinghook.grapplemod;
import com.yyon.grapplinghook.vec;
import com.yyon.grapplinghook.network.GrappleAttachMessage;
import com.yyon.grapplinghook.network.GrappleAttachPosMessage;

/*
 * This file is part of GrappleMod.
    
GrappleMod is free software: 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.
    
GrappleMod 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 GrappleMod.  If not, see <http://www.gnu.org/licenses/>.
 */

public class grappleArrow extends EntityThrowable implements IEntityAdditionalSpawnData {
    public Entity shootingEntity = null;
    public int shootingEntityID;

    private boolean firstattach = false;
    public vec thispos;

    public boolean righthand = true;

    public boolean attached = false;

    public double taut = 1;

    public boolean ignoreFrustumCheck = true;

    public grappleArrow(World worldIn) {
        super(worldIn);
    }

    public grappleArrow(World worldIn, EntityLivingBase shooter, boolean righthand) {
        super(worldIn, shooter);

        this.shootingEntity = shooter;
        this.shootingEntityID = this.shootingEntity.getEntityId();

        /*
        double x = 0.36;
        if (righthand) {x = -0.36;}
          vec pos = vec.positionvec(this);
          pos.add_ip(new vec(x, -0.175, 0.45).rotate_yaw(Math.toRadians(shooter.rotationYaw)));
          this.setPosition(pos.x, pos.y, pos.z);
          */

        grapplemod.updateMaxLen(worldIn);
        grapplemod.updateGrapplingBlocks(worldIn);

        this.righthand = righthand;
    }

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

        if (this.shootingEntityID == 0) { // removes ghost grappling hooks
            this.kill();
        }

        if (this.firstattach) {
            this.motionX = 0;
            this.motionY = 0;
            this.motionZ = 0;
            this.firstattach = false;
            super.setPosition(this.thispos.x, this.thispos.y, this.thispos.z);
        }

        if (this.toofaraway()) {
            this.removeServer();
        }
    }

    @Override
    @SideOnly(Side.CLIENT)
    public boolean isInRangeToRender3d(double x, double y, double z) {
        return true;
    }

    @Override
    @SideOnly(Side.CLIENT)
    public boolean isInRangeToRenderDist(double distance) {
        return true;
    }

    public final int RenderBoundingBoxSize = 999;

    @Override
    @SideOnly(Side.CLIENT)
    public AxisAlignedBB getRenderBoundingBox() {
        return new AxisAlignedBB(-RenderBoundingBoxSize, -RenderBoundingBoxSize, -RenderBoundingBoxSize,
                RenderBoundingBoxSize, RenderBoundingBoxSize, RenderBoundingBoxSize);
    }

    public boolean toofaraway() {
        if (this.shootingEntity == null) {
            return false;
        }
        if (!this.worldObj.isRemote) {
            if (!grapplemod.attached.contains(this.shootingEntityID)) {
                if (grapplemod.grapplingLength != 0) {
                    double d = vec.positionvec(this).sub(vec.positionvec(this.shootingEntity)).length();
                    if (d > grapplemod.grapplingLength) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public void setPosition(double x, double y, double z) {
        if (this.thispos != null) {
            x = this.thispos.x;
            y = this.thispos.y;
            z = this.thispos.z;
        }
        super.setPosition(x, y, z);
    }

    @Override
    public void writeSpawnData(ByteBuf data) {
        data.writeInt(this.shootingEntity != null ? this.shootingEntity.getEntityId() : 0);
        data.writeBoolean(this.righthand);
    }

    @Override
    public void readSpawnData(ByteBuf data) {
        this.shootingEntityID = data.readInt();
        this.shootingEntity = this.worldObj.getEntityByID(this.shootingEntityID);
        this.righthand = data.readBoolean();
    }

    public void remove() {
        this.kill();
    }

    @Override
    public String toString() {
        return super.toString() + String.valueOf(System.identityHashCode(this)) + "]";
    }

    @Override
    protected void onImpact(RayTraceResult movingobjectposition) {
        if (!this.worldObj.isRemote) {
            if (this.shootingEntityID != 0) {
                if (movingobjectposition.typeOfHit == RayTraceResult.Type.ENTITY) {
                    // hit entity
                    Entity entityhit = movingobjectposition.entityHit;
                    if (entityhit == this.shootingEntity) {
                        return;
                    }

                    vec playerpos = vec.positionvec(this.shootingEntity);
                    vec entitypos = vec.positionvec(entityhit);
                    vec yank = playerpos.sub(entitypos).mult(0.4);
                    entityhit.addVelocity(yank.x, Math.min(yank.y, 2), yank.z);

                    this.removeServer();
                    return;
                }

                BlockPos blockpos = null;

                if (movingobjectposition.typeOfHit == RayTraceResult.Type.BLOCK) {
                    blockpos = movingobjectposition.getBlockPos();
                }
                vec vec3 = null;

                if (movingobjectposition != null) {
                    vec3 = new vec(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord,
                            movingobjectposition.hitVec.zCoord);
                }

                this.serverAttach(blockpos, vec3, movingobjectposition.sideHit);
            }
        }
    }

    public void serverAttach(BlockPos blockpos, vec pos, EnumFacing sideHit) {
        if (this.attached) {
            return;
        }
        this.attached = true;

        if (blockpos != null) {
            if (!grapplemod.anyblocks) {
                Block block = this.worldObj.getBlockState(blockpos).getBlock();

                if ((!grapplemod.removeblocks && !grapplemod.grapplingblocks.contains(block))
                        || (grapplemod.removeblocks && grapplemod.grapplingblocks.contains(block))) {
                    this.removeServer();
                    return;
                }
            }
        }

        vec vec3 = vec.positionvec(this);
        vec3.add_ip(vec.motionvec(this));
        if (pos != null) {
            vec3 = pos;

            this.setPositionAndUpdate(vec3.x, vec3.y, vec3.z);
        }

        //west -x
        //north -z
        if (sideHit == EnumFacing.DOWN) {
            this.posY -= 0.3;
        } else if (sideHit == EnumFacing.WEST) {
            this.posX -= 0.05;
        } else if (sideHit == EnumFacing.NORTH) {
            this.posZ -= 0.05;
        }

        if (this.toofaraway()) {
            System.out.println("TOOFAR");
            return;
        }

        this.motionX = 0;
        this.motionY = 0;
        this.motionZ = 0;

        this.thispos = vec.positionvec(this);
        this.firstattach = true;
        grapplemod.attached.add(this.shootingEntityID);

        grapplemod.sendtocorrectclient(
                new GrappleAttachMessage(this.getEntityId(), this.posX, this.posY, this.posZ, this.getControlId(),
                        this.shootingEntityID, grapplemod.grapplingLength, blockpos),
                this.shootingEntityID, this.worldObj);
        if (this.shootingEntity instanceof EntityPlayerMP) { // fixes strange bug in LAN
            EntityPlayerMP sender = (EntityPlayerMP) this.shootingEntity;
            int dimension = sender.dimension;
            MinecraftServer minecraftServer = sender.mcServer;
            for (EntityPlayerMP player : minecraftServer.getPlayerList().getPlayerList()) {
                GrappleAttachPosMessage msg = new GrappleAttachPosMessage(this.getEntityId(), this.posX, this.posY,
                        this.posZ); // must generate a fresh message for every player!
                if (dimension == player.dimension) {
                    grapplemod.sendtocorrectclient(msg, player.getEntityId(), player.worldObj);
                }
            }
        }
    }

    public void clientAttach(double x, double y, double z) {
        this.setAttachPos(x, y, z);

        if (this.shootingEntity instanceof EntityPlayer) {
            grapplemod.proxy.resetlaunchertime(this.shootingEntityID);
        }
    }

    @Override
    protected float getGravityVelocity() {
        return 0F;
    }

    public float getVelocity() {
        return 5F;
    }

    public void removeServer() {
        this.kill();
        this.shootingEntityID = 0;

    }

    public int getControlId() {
        return grapplemod.GRAPPLEID;
    }

    public void setAttachPos(double x, double y, double z) {
        this.setPositionAndUpdate(x, y, z);

        this.motionX = 0;
        this.motionY = 0;
        this.motionZ = 0;
        this.firstattach = true;
        this.attached = true;
        this.thispos = new vec(x, y, z);
    }
}