package mhfc.net.common.entity.projectile; import java.util.ArrayList; import java.util.List; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.Vec3; import net.minecraft.world.World; public class EntityBeam extends Entity { private final double beamRadius = 20; public EntityLivingBase beamCaster; public double endPosX, endPosY, endPosZ; public double collidePosX, collidePosY, collidePosZ; public boolean on = true; public int blockSide = -1; public int appear = 60; public EntityBeam(World worldObj) { super(worldObj); setSize(0.1F,0.1F); ignoreFrustumCheck = true; } @Override public void onUpdate() { super.onUpdate(); if(ticksExisted == 1 && worldObj.isRemote){ beamCaster = (EntityLivingBase) worldObj.getEntityByID(getCasterID()); } if(!on && appear == 0){ this.setDead(); } } public EntityBeam(World worldObj, EntityLivingBase caster, double x, double y, double z, float yaw, float pitch, int duration) { this(worldObj); this.beamCaster = caster; } @Override protected void entityInit() { dataWatcher.addObject(2, 0f); dataWatcher.addObject(3, 0f); dataWatcher.addObject(4, 0); dataWatcher.addObject(5, (byte) 0); dataWatcher.addObject(6, 0); } public double getYaw() { return dataWatcher.getWatchableObjectFloat(2); } public void setYaw(float yaw) { dataWatcher.updateObject(2, yaw); } public double getPitch() { return dataWatcher.getWatchableObjectFloat(3); } public void setPitch(float pitch) { dataWatcher.updateObject(3, pitch); } public double getDuration() { return dataWatcher.getWatchableObjectInt(4); } public void setDuration(int duration) { dataWatcher.updateObject(4, duration); } public boolean getHasPlayer() { return dataWatcher.getWatchableObjectByte(5) == (byte) 1; } public void setHasPlayer(boolean player) { dataWatcher.updateObject(5, player ? (byte) 1 : (byte) 0); } public int getCasterID() { return dataWatcher.getWatchableObjectInt(6); } public void setCasterID(int id) { dataWatcher.updateObject(6, id); } @Override protected void readEntityFromNBT(NBTTagCompound nbt) { setDead(); } @Override protected void writeEntityToNBT(NBTTagCompound nbt) { } private void calculateEndPos() { endPosX = posX + beamRadius * Math.cos(getYaw()) * Math.cos(getPitch()); endPosZ = posZ + beamRadius * Math.sin(getYaw()) * Math.cos(getPitch()); endPosY = posY + beamRadius * Math.sin(getPitch()); } @Override public boolean canBeCollidedWith() { return false; } @Override public boolean canBePushed() { return false; } @Override public boolean isInRangeToRenderDist(double distance) { return distance < 1024; } private void updateWithPlayer() { this.setYaw((float) ((beamCaster.rotationYawHead + 90) * Math.PI / 180)); this.setPitch((float) (-beamCaster.rotationPitch * Math.PI / 180)); this.setPosition(beamCaster.posX, beamCaster.posY + 1.2f, beamCaster.posZ); } public TargetHit raytraceEntities(World world, Vec3 from, Vec3 to, boolean stopOnLiquid, boolean ignoreBlockWithoutBoundingBox, boolean returnLastUncollidableBlock) { TargetHit result = new TargetHit(); result.setBlockHit(world.func_147447_a(Vec3.createVectorHelper(from.xCoord, from.yCoord, from.zCoord), to, stopOnLiquid, ignoreBlockWithoutBoundingBox, returnLastUncollidableBlock)); if (result.targetBlock != null) { collidePosX = result.targetBlock.hitVec.xCoord; collidePosY = result.targetBlock.hitVec.yCoord; collidePosZ = result.targetBlock.hitVec.zCoord; blockSide = result.targetBlock.sideHit; } else { collidePosX = endPosX; collidePosY = endPosY; collidePosZ = endPosZ; blockSide = -1; } List<EntityLivingBase> entities = world.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(Math.min(posX, collidePosX), Math.min(posY, collidePosY), Math.min(posZ, collidePosZ), Math.max(posX, collidePosX), Math.max(posY, collidePosY), Math.max(posZ, collidePosZ)).expand(1, 1, 1)); for (EntityLivingBase entity : entities) { if (entity == beamCaster) { continue; } float pad = entity.getCollisionBorderSize() + 0.5f; AxisAlignedBB aabb = entity.boundingBox.expand(pad, pad, pad); MovingObjectPosition hit = aabb.calculateIntercept(from, to); if (aabb.isVecInside(from)) { result.addEntityHit(entity); } else if (hit != null) { result.addEntityHit(entity); } } return result; } public static class TargetHit { private MovingObjectPosition targetBlock; private List<EntityLivingBase> entities = new ArrayList<>(); public MovingObjectPosition getBlockHit() { return targetBlock; } public void setBlockHit(MovingObjectPosition blockHit) { this.targetBlock = blockHit; } public void addEntityHit(EntityLivingBase entity) { entities.add(entity); } } }