package net.minecraft.server; import java.util.Collections; import java.util.Iterator; import java.util.List; import javax.annotation.Nullable; public class EntityFishingHook extends Entity { private static final DataWatcherObject<Integer> c = DataWatcher.a(EntityFishingHook.class, DataWatcherRegistry.b); private boolean isInGround; private int e; public EntityHuman owner; private int g; private int ao; private int ap; private int aq; private float ar; public Entity hooked; private EntityFishingHook.HookState as; private final int at; private final int au; private EntityFishingHook(World world, EntityHuman entityhuman, int i, int j) { super(EntityTypes.FISHING_BOBBER, world); this.as = EntityFishingHook.HookState.FLYING; this.ac = true; this.owner = entityhuman; this.owner.hookedFish = this; this.at = Math.max(0, i); this.au = Math.max(0, j); } public EntityFishingHook(EntityHuman entityhuman, World world, int i, int j) { this(world, entityhuman, i, j); float f = this.owner.pitch; float f1 = this.owner.yaw; float f2 = MathHelper.cos(-f1 * 0.017453292F - 3.1415927F); float f3 = MathHelper.sin(-f1 * 0.017453292F - 3.1415927F); float f4 = -MathHelper.cos(-f * 0.017453292F); float f5 = MathHelper.sin(-f * 0.017453292F); double d0 = this.owner.locX() - (double) f3 * 0.3D; double d1 = this.owner.getHeadY(); double d2 = this.owner.locZ() - (double) f2 * 0.3D; this.setPositionRotation(d0, d1, d2, f1, f); Vec3D vec3d = new Vec3D((double) (-f3), (double) MathHelper.a(-(f5 / f4), -5.0F, 5.0F), (double) (-f2)); double d3 = vec3d.f(); vec3d = vec3d.d(0.6D / d3 + 0.5D + this.random.nextGaussian() * 0.0045D, 0.6D / d3 + 0.5D + this.random.nextGaussian() * 0.0045D, 0.6D / d3 + 0.5D + this.random.nextGaussian() * 0.0045D); this.setMot(vec3d); this.yaw = (float) (MathHelper.d(vec3d.x, vec3d.z) * 57.2957763671875D); this.pitch = (float) (MathHelper.d(vec3d.y, (double) MathHelper.sqrt(b(vec3d))) * 57.2957763671875D); this.lastYaw = this.yaw; this.lastPitch = this.pitch; } @Override protected void initDatawatcher() { this.getDataWatcher().register(EntityFishingHook.c, 0); } @Override public void a(DataWatcherObject<?> datawatcherobject) { if (EntityFishingHook.c.equals(datawatcherobject)) { int i = (Integer) this.getDataWatcher().get(EntityFishingHook.c); this.hooked = i > 0 ? this.world.getEntity(i - 1) : null; } super.a(datawatcherobject); } @Override public void tick() { super.tick(); if (this.owner == null) { this.die(); } else if (this.world.isClientSide || !this.k()) { if (this.isInGround) { ++this.e; if (this.e >= 1200) { this.die(); return; } } float f = 0.0F; BlockPosition blockposition = new BlockPosition(this); Fluid fluid = this.world.getFluid(blockposition); if (fluid.a(TagsFluid.WATER)) { f = fluid.getHeight(this.world, blockposition); } if (this.as == EntityFishingHook.HookState.FLYING) { if (this.hooked != null) { this.setMot(Vec3D.a); this.as = EntityFishingHook.HookState.HOOKED_IN_ENTITY; return; } if (f > 0.0F) { this.setMot(this.getMot().d(0.3D, 0.2D, 0.3D)); this.as = EntityFishingHook.HookState.BOBBING; return; } if (!this.world.isClientSide) { this.m(); } if (!this.isInGround && !this.onGround && !this.positionChanged) { ++this.g; } else { this.g = 0; this.setMot(Vec3D.a); } } else { if (this.as == EntityFishingHook.HookState.HOOKED_IN_ENTITY) { if (this.hooked != null) { if (this.hooked.dead) { this.hooked = null; this.as = EntityFishingHook.HookState.FLYING; } else { this.setPosition(this.hooked.locX(), this.hooked.e(0.8D), this.hooked.locZ()); } } return; } if (this.as == EntityFishingHook.HookState.BOBBING) { Vec3D vec3d = this.getMot(); double d0 = this.locY() + vec3d.y - (double) blockposition.getY() - (double) f; if (Math.abs(d0) < 0.01D) { d0 += Math.signum(d0) * 0.1D; } this.setMot(vec3d.x * 0.9D, vec3d.y - d0 * (double) this.random.nextFloat() * 0.2D, vec3d.z * 0.9D); if (!this.world.isClientSide && f > 0.0F) { this.a(blockposition); } } } if (!fluid.a(TagsFluid.WATER)) { this.setMot(this.getMot().add(0.0D, -0.03D, 0.0D)); } this.move(EnumMoveType.SELF, this.getMot()); this.l(); double d1 = 0.92D; this.setMot(this.getMot().a(0.92D)); this.Z(); } } private boolean k() { ItemStack itemstack = this.owner.getItemInMainHand(); ItemStack itemstack1 = this.owner.getItemInOffHand(); boolean flag = itemstack.getItem() == Items.FISHING_ROD; boolean flag1 = itemstack1.getItem() == Items.FISHING_ROD; if (!this.owner.dead && this.owner.isAlive() && (flag || flag1) && this.h(this.owner) <= 1024.0D) { return false; } else { this.die(); return true; } } private void l() { Vec3D vec3d = this.getMot(); float f = MathHelper.sqrt(b(vec3d)); this.yaw = (float) (MathHelper.d(vec3d.x, vec3d.z) * 57.2957763671875D); for (this.pitch = (float) (MathHelper.d(vec3d.y, (double) f) * 57.2957763671875D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { ; } while (this.pitch - this.lastPitch >= 180.0F) { this.lastPitch += 360.0F; } while (this.yaw - this.lastYaw < -180.0F) { this.lastYaw -= 360.0F; } while (this.yaw - this.lastYaw >= 180.0F) { this.lastYaw += 360.0F; } this.pitch = MathHelper.g(0.2F, this.lastPitch, this.pitch); this.yaw = MathHelper.g(0.2F, this.lastYaw, this.yaw); } private void m() { MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, this.getBoundingBox().a(this.getMot()).g(1.0D), (entity) -> { return !entity.isSpectator() && (entity.isInteractable() || entity instanceof EntityItem) && (entity != this.owner || this.g >= 5); }, RayTrace.BlockCollisionOption.COLLIDER, true); if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) { this.hooked = ((MovingObjectPositionEntity) movingobjectposition).getEntity(); this.n(); } else { this.isInGround = true; } } } private void n() { this.getDataWatcher().set(EntityFishingHook.c, this.hooked.getId() + 1); } private void a(BlockPosition blockposition) { WorldServer worldserver = (WorldServer) this.world; int i = 1; BlockPosition blockposition1 = blockposition.up(); if (this.random.nextFloat() < 0.25F && this.world.isRainingAt(blockposition1)) { ++i; } if (this.random.nextFloat() < 0.5F && !this.world.f(blockposition1)) { --i; } if (this.ao > 0) { --this.ao; if (this.ao <= 0) { this.ap = 0; this.aq = 0; } else { this.setMot(this.getMot().add(0.0D, -0.2D * (double) this.random.nextFloat() * (double) this.random.nextFloat(), 0.0D)); } } else { float f; float f1; float f2; double d0; double d1; double d2; Block block; if (this.aq > 0) { this.aq -= i; if (this.aq > 0) { this.ar = (float) ((double) this.ar + this.random.nextGaussian() * 4.0D); f = this.ar * 0.017453292F; f1 = MathHelper.sin(f); f2 = MathHelper.cos(f); d0 = this.locX() + (double) (f1 * (float) this.aq * 0.1F); d1 = (double) ((float) MathHelper.floor(this.locY()) + 1.0F); d2 = this.locZ() + (double) (f2 * (float) this.aq * 0.1F); block = worldserver.getType(new BlockPosition(d0, d1 - 1.0D, d2)).getBlock(); if (block == Blocks.WATER) { if (this.random.nextFloat() < 0.15F) { worldserver.a(Particles.BUBBLE, d0, d1 - 0.10000000149011612D, d2, 1, (double) f1, 0.1D, (double) f2, 0.0D); } float f3 = f1 * 0.04F; float f4 = f2 * 0.04F; worldserver.a(Particles.FISHING, d0, d1, d2, 0, (double) f4, 0.01D, (double) (-f3), 1.0D); worldserver.a(Particles.FISHING, d0, d1, d2, 0, (double) (-f4), 0.01D, (double) f3, 1.0D); } } else { Vec3D vec3d = this.getMot(); this.setMot(vec3d.x, (double) (-0.4F * MathHelper.a(this.random, 0.6F, 1.0F)), vec3d.z); this.a(SoundEffects.ENTITY_FISHING_BOBBER_SPLASH, 0.25F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); double d3 = this.locY() + 0.5D; worldserver.a(Particles.BUBBLE, this.locX(), d3, this.locZ(), (int) (1.0F + this.getWidth() * 20.0F), (double) this.getWidth(), 0.0D, (double) this.getWidth(), 0.20000000298023224D); worldserver.a(Particles.FISHING, this.locX(), d3, this.locZ(), (int) (1.0F + this.getWidth() * 20.0F), (double) this.getWidth(), 0.0D, (double) this.getWidth(), 0.20000000298023224D); this.ao = MathHelper.nextInt(this.random, 20, 40); } } else if (this.ap > 0) { this.ap -= i; f = 0.15F; if (this.ap < 20) { f = (float) ((double) f + (double) (20 - this.ap) * 0.05D); } else if (this.ap < 40) { f = (float) ((double) f + (double) (40 - this.ap) * 0.02D); } else if (this.ap < 60) { f = (float) ((double) f + (double) (60 - this.ap) * 0.01D); } if (this.random.nextFloat() < f) { f1 = MathHelper.a(this.random, 0.0F, 360.0F) * 0.017453292F; f2 = MathHelper.a(this.random, 25.0F, 60.0F); d0 = this.locX() + (double) (MathHelper.sin(f1) * f2 * 0.1F); d1 = (double) ((float) MathHelper.floor(this.locY()) + 1.0F); d2 = this.locZ() + (double) (MathHelper.cos(f1) * f2 * 0.1F); block = worldserver.getType(new BlockPosition(d0, d1 - 1.0D, d2)).getBlock(); if (block == Blocks.WATER) { worldserver.a(Particles.SPLASH, d0, d1, d2, 2 + this.random.nextInt(2), 0.10000000149011612D, 0.0D, 0.10000000149011612D, 0.0D); } } if (this.ap <= 0) { this.ar = MathHelper.a(this.random, 0.0F, 360.0F); this.aq = MathHelper.nextInt(this.random, 20, 80); } } else { this.ap = MathHelper.nextInt(this.random, 100, 600); this.ap -= this.au * 20 * 5; } } } @Override public void b(NBTTagCompound nbttagcompound) {} @Override public void a(NBTTagCompound nbttagcompound) {} public int b(ItemStack itemstack) { if (!this.world.isClientSide && this.owner != null) { int i = 0; if (this.hooked != null) { this.reel(); CriterionTriggers.D.a((EntityPlayer) this.owner, itemstack, this, Collections.emptyList()); this.world.broadcastEntityEffect(this, (byte) 31); i = this.hooked instanceof EntityItem ? 3 : 5; } else if (this.ao > 0) { LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).set(LootContextParameters.POSITION, new BlockPosition(this)).set(LootContextParameters.TOOL, itemstack).a(this.random).a((float) this.at + this.owner.eA()); LootTable loottable = this.world.getMinecraftServer().getLootTableRegistry().getLootTable(LootTables.ab); List<ItemStack> list = loottable.populateLoot(loottableinfo_builder.build(LootContextParameterSets.FISHING)); CriterionTriggers.D.a((EntityPlayer) this.owner, itemstack, this, list); Iterator iterator = list.iterator(); while (iterator.hasNext()) { ItemStack itemstack1 = (ItemStack) iterator.next(); EntityItem entityitem = new EntityItem(this.world, this.locX(), this.locY(), this.locZ(), itemstack1); double d0 = this.owner.locX() - this.locX(); double d1 = this.owner.locY() - this.locY(); double d2 = this.owner.locZ() - this.locZ(); double d3 = 0.1D; entityitem.setMot(d0 * 0.1D, d1 * 0.1D + Math.sqrt(Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2)) * 0.08D, d2 * 0.1D); this.world.addEntity(entityitem); this.owner.world.addEntity(new EntityExperienceOrb(this.owner.world, this.owner.locX(), this.owner.locY() + 0.5D, this.owner.locZ() + 0.5D, this.random.nextInt(6) + 1)); if (itemstack1.getItem().a(TagsItem.FISHES)) { this.owner.a(StatisticList.FISH_CAUGHT, 1); } } i = 1; } if (this.isInGround) { i = 2; } this.die(); return i; } else { return 0; } } protected void reel() { if (this.owner != null) { Vec3D vec3d = (new Vec3D(this.owner.locX() - this.locX(), this.owner.locY() - this.locY(), this.owner.locZ() - this.locZ())).a(0.1D); this.hooked.setMot(this.hooked.getMot().e(vec3d)); } } @Override protected boolean playStepSound() { return false; } @Override public void die() { super.die(); if (this.owner != null) { this.owner.hookedFish = null; } } @Nullable public EntityHuman i() { return this.owner; } @Override public boolean canPortal() { return false; } @Override public Packet<?> L() { EntityHuman entityhuman = this.i(); return new PacketPlayOutSpawnEntity(this, entityhuman == null ? this.getId() : entityhuman.getId()); } static enum HookState { FLYING, HOOKED_IN_ENTITY, BOBBING; private HookState() {} } }