@Override public MovingObjectPosition collisionRayTrace(Vec3 startVec, Vec3 endVec) { Block block = new Block(Material.rock); // It's possible for the startVec to be embedded in a lump (causing it // to hit the opposite side), so we must move it farther away Vec3 d = startVec.subtract(endVec); double scale = 5.2; // Diagonal of a 3³. (Was initially using incrScale = 2) // This isn't quite right; the dVector would properly be normalized here // & rescaled to the max diameter. But we can survive without it. // Unnormalized length of dVector is 6m in surviavl mode IIRC. This'll // be way longer than it needs to be. // Why is it + instead of -? Hmm. startVec = startVec.add(SpaceUtil.scale(d, scale)); MovingObjectPosition shortest = null; for (int i = 0; i < parts.size(); i++) { ClayLump lump = parts.get(i); lump.toRotatedBlockBounds(this, block); MovingObjectPosition mop = block.collisionRayTrace(worldObj, pos, startVec, endVec); if (mop != null) { mop.subHit = i; if (shortest == null) { shortest = mop; } else { Vec3 s = shortest.hitVec; Vec3 m = mop.hitVec; s = new Vec3(s.xCoord, s.yCoord, s.zCoord); m = new Vec3(m.xCoord, m.yCoord, m.zCoord); startVec = startVec.subtract(s).subtract(m); if (m.lengthVector() < s.lengthVector()) { shortest = mop; } } } } return shortest; // return super.collisionRayTrace(w, pos, startVec, endVec); }
@Override @SideOnly(Side.CLIENT) public boolean addHitEffects( World worldObj, MovingObjectPosition target, EffectRenderer effectRenderer) { TileEntity tileEntity = worldObj.getTileEntity(target.getBlockPos()); if (tileEntity instanceof TileEntityMulti) { BlockPos mainBlockPosition = ((TileEntityMulti) tileEntity).mainBlockPosition; if (mainBlockPosition != null) { effectRenderer.addBlockHitEffects(mainBlockPosition, target); } } return super.addHitEffects(worldObj, target, effectRenderer); }
/** * Equivalent code to the creative pick block * * @param target The client target vector * @param player The player trying to pick * @return the stack expected for the creative pick button */ private static ItemStack getItemFromPointedAt(MovingObjectPosition target, EntityPlayer player) { if (target != null) { if (target.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { BlockPos pos = target.getBlockPos(); World world = player.getEntityWorld(); Block block = world.getBlockState(pos).getBlock(); if (block.isAir(world, pos)) { return null; } return block.getPickBlock(target, world, pos); } else { if (target.typeOfHit != MovingObjectPosition.MovingObjectType.ENTITY || target.entityHit == null || !player.capabilities.isCreativeMode) { return null; } return target.entityHit.getPickedResult(target); } } return null; }
@Override public void s_() { K(); BlockPosition blockposition = new BlockPosition(locX, locY, locZ); IBlockData iblockdata = world.getType(blockposition); Block block = iblockdata.getBlock(); if (!ignoredMaterials.contains(Material.getMaterial(Block.getId(block)))) { AxisAlignedBB axisalignedbb = block.a(world, blockposition, iblockdata); if ((axisalignedbb != null) && (axisalignedbb.a(new Vec3D(locX, locY, locZ)))) { float damageMultiplier = MathHelper.sqrt(motX * motX + motY * motY + motZ * motZ); CustomProjectileHitEvent event = new ItemProjectileHitEvent( this, damageMultiplier, world.getWorld().getBlockAt((int) locX, (int) locY, (int) locZ), BlockFace.UP, getItem()); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { die(); } } } age += 1; Vec3D vec3d = new Vec3D(locX, locY, locZ); Vec3D vec3d1 = new Vec3D(locX + motX, locY + motY, locZ + motZ); MovingObjectPosition movingobjectposition = world.rayTrace(vec3d, vec3d1, false, true, false); vec3d = new Vec3D(locX, locY, locZ); vec3d1 = new Vec3D(locX + motX, locY + motY, locZ + motZ); if (movingobjectposition != null) { vec3d1 = new Vec3D( movingobjectposition.pos.a, movingobjectposition.pos.b, movingobjectposition.pos.c); } Entity entity = null; List list = world.getEntities(this, getBoundingBox().a(motX, motY, motZ).grow(1.0D, 1.0D, 1.0D)); double d0 = 0.0D; for (Object aList : list) { Entity entity1 = (Entity) aList; if ((entity1.ad()) && ((entity1 != shooter) || (age >= 5))) { float f1 = 0.3F; AxisAlignedBB axisalignedbb1 = entity1.getBoundingBox().grow(f1, f1, f1); MovingObjectPosition movingobjectposition1 = axisalignedbb1.a(vec3d, vec3d1); if (movingobjectposition1 != null) { double d1 = vec3d.distanceSquared(movingobjectposition1.pos); if ((d1 < d0) || (d0 == 0.0D)) { entity = entity1; d0 = d1; } } } } if (entity != null) { movingobjectposition = new MovingObjectPosition(entity); } if ((movingobjectposition != null) && (movingobjectposition.entity != null) && ((movingobjectposition.entity instanceof EntityHuman))) { EntityHuman entityhuman = (EntityHuman) movingobjectposition.entity; if ((entityhuman.abilities.isInvulnerable) || (((shooter instanceof EntityHuman)) && (!((EntityHuman) shooter).a(entityhuman)))) { movingobjectposition = null; } } if (movingobjectposition != null) { if (movingobjectposition.entity != null && movingobjectposition.entity instanceof EntityLiving) { float damageMultiplier = MathHelper.sqrt(motX * motX + motY * motY + motZ * motZ); CustomProjectileHitEvent event = new ItemProjectileHitEvent( this, damageMultiplier, (LivingEntity) movingobjectposition.entity.getBukkitEntity(), getItem()); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { if (getKnockback() > 0) { float f4 = MathHelper.sqrt(motX * motX + motZ * motZ); if (f4 > 0.0F) { movingobjectposition.entity.g( motX * getKnockback() * 0.6000000238418579D / f4, 0.1D, motZ * getKnockback() * 0.6000000238418579D / f4); } } die(); } } else if (movingobjectposition.a() != null) { if (!ignoredMaterials.contains(Material.getMaterial(Block.getId(block)))) { motX = ((float) (movingobjectposition.pos.a - locX)); motY = ((float) (movingobjectposition.pos.b - locY)); motZ = ((float) (movingobjectposition.pos.c - locZ)); float f3 = MathHelper.sqrt(motX * motX + motY * motY + motZ * motZ); locX -= motX / f3 * 0.0500000007450581D; locY -= motY / f3 * 0.0500000007450581D; locZ -= motZ / f3 * 0.0500000007450581D; float damageMultiplier = MathHelper.sqrt(motX * motX + motY * motY + motZ * motZ); CustomProjectileHitEvent event = new ItemProjectileHitEvent( this, damageMultiplier, world .getWorld() .getBlockAt( (int) movingobjectposition.pos.a, (int) movingobjectposition.pos.b, (int) movingobjectposition.pos.c), CraftBlock.notchToBlockFace(movingobjectposition.direction), getItem()); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { die(); } } } } locX += motX; locY += motY; locZ += motZ; float f3 = 0.99F; float f1 = 0.05F; motX *= f3; motY *= f3; motZ *= f3; motY -= f1; setPosition(locX, locY, locZ); checkBlockCollisions(); if (isAlive()) { if (this.age >= 1000) { die(); } for (Runnable r : runnables) { r.run(); } for (TypedRunnable<ItemProjectile> r : typedRunnables) { r.run(this); } } }
@Override @SuppressWarnings("unchecked") public void onUpdate() { super.onUpdate(); if (this.ticksExisted > 400) { if (this.isHot) { this.isHot = false; this.setHot(this.isHot); } } else if (!this.worldObj.isRemote) { this.setHot(this.isHot); } if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) { float f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(this.motionY, f) * 180.0D / Math.PI); } BlockPos pos = new BlockPos(this.xTile, this.yTile, this.zTile); Block block = this.worldObj.getBlockState(pos).getBlock(); if (!block.isAir(this.worldObj, pos)) { block.setBlockBoundsBasedOnState(this.worldObj, pos); AxisAlignedBB axisalignedbb = block.getCollisionBoundingBox(this.worldObj, pos, this.worldObj.getBlockState(pos)); if (axisalignedbb != null && axisalignedbb.isVecInside(new Vec3(this.posX, this.posY, this.posZ))) { this.inGround = true; } } if (this.inGround) { Block j = this.worldObj.getBlockState(pos).getBlock(); int k = j.getMetaFromState(this.worldObj.getBlockState(pos)); if (j == this.inTile && k == this.inData) { ++this.ticksInGround; if (this.ticksInGround == 1200) { this.setDead(); } } else { this.inGround = false; this.motionX *= this.rand.nextFloat() * 0.2F; this.motionY *= this.rand.nextFloat() * 0.2F; this.motionZ *= this.rand.nextFloat() * 0.2F; this.ticksInGround = 0; this.ticksInAir = 0; } } else { ++this.ticksInAir; Vec3 vec3 = new Vec3(this.posX, this.posY, this.posZ); Vec3 vec31 = new Vec3(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); MovingObjectPosition movingobjectposition = this.worldObj.rayTraceBlocks(vec3, vec31, false, true, false); vec3 = new Vec3(this.posX, this.posY, this.posZ); vec31 = new Vec3(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); if (movingobjectposition != null) { vec31 = new Vec3( movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord); } this.rotationPitch += 1F; Entity entity = null; List<Entity> list = this.worldObj.getEntitiesWithinAABBExcludingEntity( this, this.getEntityBoundingBox() .addCoord(this.motionX, this.motionY, this.motionZ) .expand(1.0D, 1.0D, 1.0D)); double d0 = 0.0D; int l; float f1; for (l = 0; l < list.size(); ++l) { Entity entity1 = list.get(l); if (entity1.canBeCollidedWith() && (entity1 != this.shootingEntity || this.ticksInAir >= 5)) { f1 = 0.3F; AxisAlignedBB axisalignedbb1 = entity1.getEntityBoundingBox().expand(f1, f1, f1); MovingObjectPosition movingobjectposition1 = axisalignedbb1.calculateIntercept(vec3, vec31); if (movingobjectposition1 != null) { double d1 = vec3.distanceTo(movingobjectposition1.hitVec); if (d1 < d0 || d0 == 0.0D) { entity = entity1; d0 = d1; } } } } if (entity != null) { movingobjectposition = new MovingObjectPosition(entity); } if (movingobjectposition != null && movingobjectposition.entityHit != null && movingobjectposition.entityHit instanceof EntityPlayer) { EntityPlayer entityplayer = (EntityPlayer) movingobjectposition.entityHit; if (entityplayer.capabilities.disableDamage || this.shootingEntity instanceof EntityPlayer && !((EntityPlayer) this.shootingEntity).canAttackPlayer(entityplayer)) { movingobjectposition = null; } } float f2; float f3; double damage = ConfigManagerCore.hardMode ? 3.2D : 1.6D; if (movingobjectposition != null) { if (movingobjectposition.entityHit != null) { f2 = MathHelper.sqrt_double( this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); int i1 = MathHelper.ceiling_double_int(f2 * damage); DamageSource damagesource = null; if (this.shootingEntity == null) { damagesource = new EntityDamageSourceIndirect("meteorChunk", this, this).setProjectile(); } else { damagesource = new EntityDamageSourceIndirect("meteorChunk", this, this.shootingEntity) .setProjectile(); } if (this.isBurning() && !(movingobjectposition.entityHit instanceof EntityEnderman)) { movingobjectposition.entityHit.setFire(2); } if (movingobjectposition.entityHit.attackEntityFrom(damagesource, i1)) { if (movingobjectposition.entityHit instanceof EntityLivingBase) { EntityLivingBase entitylivingbase = (EntityLivingBase) movingobjectposition.entityHit; if (!this.worldObj.isRemote) { entitylivingbase.setArrowCountInEntity( entitylivingbase.getArrowCountInEntity() + 1); } if (this.knockbackStrength > 0) { f3 = MathHelper.sqrt_double( this.motionX * this.motionX + this.motionZ * this.motionZ); if (f3 > 0.0F) { movingobjectposition.entityHit.addVelocity( this.motionX * this.knockbackStrength * 0.6000000238418579D / f3, 0.1D, this.motionZ * this.knockbackStrength * 0.6000000238418579D / f3); } } if (this.shootingEntity != null) { EnchantmentHelper.applyThornEnchantments(entitylivingbase, this.shootingEntity); EnchantmentHelper.applyArthropodEnchantments( (EntityLivingBase) this.shootingEntity, entitylivingbase); } if (this.shootingEntity != null && movingobjectposition.entityHit != this.shootingEntity && movingobjectposition.entityHit instanceof EntityPlayer && this.shootingEntity instanceof EntityPlayerMP) { ((EntityPlayerMP) this.shootingEntity) .playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(6, 0.0F)); } } if (!(movingobjectposition.entityHit instanceof EntityEnderman)) { this.setDead(); } } else { this.motionX *= -0.10000000149011612D; this.motionY *= -0.10000000149011612D; this.motionZ *= -0.10000000149011612D; this.rotationYaw += 180.0F; this.prevRotationYaw += 180.0F; this.ticksInAir = 0; } } else { this.xTile = movingobjectposition.getBlockPos().getX(); this.yTile = movingobjectposition.getBlockPos().getY(); this.zTile = movingobjectposition.getBlockPos().getZ(); IBlockState state = this.worldObj.getBlockState(movingobjectposition.getBlockPos()); this.inTile = state.getBlock(); this.inData = this.inTile.getMetaFromState(state); this.motionX = (float) (movingobjectposition.hitVec.xCoord - this.posX); this.motionY = (float) (movingobjectposition.hitVec.yCoord - this.posY); this.motionZ = (float) (movingobjectposition.hitVec.zCoord - this.posZ); f2 = MathHelper.sqrt_double( this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); this.posX -= this.motionX / f2 * 0.05000000074505806D; this.posY -= this.motionY / f2 * 0.05000000074505806D; this.posZ -= this.motionZ / f2 * 0.05000000074505806D; this.inGround = true; if (!this.inTile.isAir(this.worldObj, movingobjectposition.getBlockPos())) { this.inTile.onEntityCollidedWithBlock( this.worldObj, movingobjectposition.getBlockPos(), this); } } } this.posX += this.motionX; this.posY += this.motionY; this.posZ += this.motionZ; f2 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); if (!this.onGround) { this.rotationPitch += 10; this.rotationYaw += 2; } float f4 = 0.99F; f1 = 0.05F; if (this.isInWater()) { for (int j1 = 0; j1 < 4; ++j1) { f3 = 0.25F; this.worldObj.spawnParticle( EnumParticleTypes.WATER_BUBBLE, this.posX - this.motionX * f3, this.posY - this.motionY * f3, this.posZ - this.motionZ * f3, this.motionX, this.motionY, this.motionZ); } f4 = 0.8F; } this.motionX *= f4; this.motionY *= f4; this.motionZ *= f4; this.motionY -= WorldUtil.getGravityForEntity(this); this.setPosition(this.posX, this.posY, this.posZ); this.doBlockCollisions(); } }