diff options
Diffstat (limited to 'patch-remap/mache-vineflower/net/minecraft/world/entity/projectile/FishingHook.java.patch')
-rw-r--r-- | patch-remap/mache-vineflower/net/minecraft/world/entity/projectile/FishingHook.java.patch | 854 |
1 files changed, 854 insertions, 0 deletions
diff --git a/patch-remap/mache-vineflower/net/minecraft/world/entity/projectile/FishingHook.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/entity/projectile/FishingHook.java.patch new file mode 100644 index 0000000000..80a95da104 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/entity/projectile/FishingHook.java.patch @@ -0,0 +1,854 @@ +--- a/net/minecraft/world/entity/projectile/FishingHook.java ++++ b/net/minecraft/world/entity/projectile/FishingHook.java +@@ -2,6 +2,7 @@ + + import com.mojang.logging.LogUtils; + import java.util.Collections; ++import java.util.Iterator; + import java.util.List; + import javax.annotation.Nullable; + import net.minecraft.advancements.CriteriaTriggers; +@@ -24,15 +25,14 @@ + import net.minecraft.util.RandomSource; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.EntityType; ++import net.minecraft.world.entity.EnumMoveType; + import net.minecraft.world.entity.ExperienceOrb; +-import net.minecraft.world.entity.MoverType; + import net.minecraft.world.entity.item.ItemEntity; +-import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.item.Items; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.Blocks; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.material.FluidState; + import net.minecraft.world.level.storage.loot.BuiltInLootTables; + import net.minecraft.world.level.storage.loot.LootParams; +@@ -45,28 +45,50 @@ + import net.minecraft.world.phys.Vec3; + import org.slf4j.Logger; + ++// CraftBukkit start ++import org.bukkit.entity.Player; ++import org.bukkit.entity.FishHook; ++import org.bukkit.event.player.PlayerFishEvent; ++// CraftBukkit end ++ + public class FishingHook extends Projectile { ++ + private static final Logger LOGGER = LogUtils.getLogger(); +- private final RandomSource syncronizedRandom = RandomSource.create(); ++ private final RandomSource syncronizedRandom; + private boolean biting; + private int outOfWaterTime; + private static final int MAX_OUT_OF_WATER_TIME = 10; +- private static final EntityDataAccessor<Integer> DATA_HOOKED_ENTITY = SynchedEntityData.defineId(FishingHook.class, EntityDataSerializers.INT); ++ public static final EntityDataAccessor<Integer> DATA_HOOKED_ENTITY = SynchedEntityData.defineId(FishingHook.class, EntityDataSerializers.INT); + private static final EntityDataAccessor<Boolean> DATA_BITING = SynchedEntityData.defineId(FishingHook.class, EntityDataSerializers.BOOLEAN); + private int life; + private int nibble; + private int timeUntilLured; + private int timeUntilHooked; + private float fishAngle; +- private boolean openWater = true; ++ private boolean openWater; + @Nullable +- private Entity hookedIn; +- private FishingHook.FishHookState currentState = FishingHook.FishHookState.FLYING; ++ public Entity hookedIn; ++ public FishingHook.HookState currentState; + private final int luck; + private final int lureSpeed; + ++ // CraftBukkit start - Extra variables to enable modification of fishing wait time, values are minecraft defaults ++ public int minWaitTime = 100; ++ public int maxWaitTime = 600; ++ public int minLureTime = 20; ++ public int maxLureTime = 80; ++ public float minLureAngle = 0.0F; ++ public float maxLureAngle = 360.0F; ++ public boolean applyLure = true; ++ public boolean rainInfluenced = true; ++ public boolean skyInfluenced = true; ++ // CraftBukkit end ++ + private FishingHook(EntityType<? extends FishingHook> entityType, Level level, int luck, int lureSpeed) { + super(entityType, level); ++ this.syncronizedRandom = RandomSource.create(); ++ this.openWater = true; ++ this.currentState = FishingHook.HookState.FLYING; + this.noCulling = true; + this.luck = Math.max(0, luck); + this.lureSpeed = Math.max(0, lureSpeed); +@@ -76,50 +98,49 @@ + this(entityType, level, 0, 0); + } + +- public FishingHook(Player player, Level level, int luck, int lureSpeed) { ++ public FishingHook(net.minecraft.world.entity.player.Player player, Level level, int luck, int lureSpeed) { + this(EntityType.FISHING_BOBBER, level, luck, lureSpeed); + this.setOwner(player); +- float xRot = player.getXRot(); +- float yRot = player.getYRot(); +- float cos = Mth.cos(-yRot * (float) (Math.PI / 180.0) - (float) Math.PI); +- float sin = Mth.sin(-yRot * (float) (Math.PI / 180.0) - (float) Math.PI); +- float f = -Mth.cos(-xRot * (float) (Math.PI / 180.0)); +- float sin1 = Mth.sin(-xRot * (float) (Math.PI / 180.0)); +- double d = player.getX() - (double)sin * 0.3; +- double eyeY = player.getEyeY(); +- double d1 = player.getZ() - (double)cos * 0.3; +- this.moveTo(d, eyeY, d1, yRot, xRot); +- Vec3 vec3 = new Vec3((double)(-sin), (double)Mth.clamp(-(sin1 / f), -5.0F, 5.0F), (double)(-cos)); +- double len = vec3.length(); +- vec3 = vec3.multiply( +- 0.6 / len + this.random.triangle(0.5, 0.0103365), +- 0.6 / len + this.random.triangle(0.5, 0.0103365), +- 0.6 / len + this.random.triangle(0.5, 0.0103365) +- ); +- this.setDeltaMovement(vec3); +- this.setYRot((float)(Mth.atan2(vec3.x, vec3.z) * 180.0F / (float)Math.PI)); +- this.setXRot((float)(Mth.atan2(vec3.y, vec3.horizontalDistance()) * 180.0F / (float)Math.PI)); ++ float f = player.getXRot(); ++ float f1 = player.getYRot(); ++ float f2 = Mth.cos(-f1 * 0.017453292F - 3.1415927F); ++ float f3 = Mth.sin(-f1 * 0.017453292F - 3.1415927F); ++ float f4 = -Mth.cos(-f * 0.017453292F); ++ float f5 = Mth.sin(-f * 0.017453292F); ++ double d0 = player.getX() - (double) f3 * 0.3D; ++ double d1 = player.getEyeY(); ++ double d2 = player.getZ() - (double) f2 * 0.3D; ++ ++ this.moveTo(d0, d1, d2, f1, f); ++ Vec3 vec3d = new Vec3((double) (-f3), (double) Mth.clamp(-(f5 / f4), -5.0F, 5.0F), (double) (-f2)); ++ double d3 = vec3d.length(); ++ ++ vec3d = vec3d.multiply(0.6D / d3 + this.random.triangle(0.5D, 0.0103365D), 0.6D / d3 + this.random.triangle(0.5D, 0.0103365D), 0.6D / d3 + this.random.triangle(0.5D, 0.0103365D)); ++ this.setDeltaMovement(vec3d); ++ this.setYRot((float) (Mth.atan2(vec3d.x, vec3d.z) * 57.2957763671875D)); ++ this.setXRot((float) (Mth.atan2(vec3d.y, vec3d.horizontalDistance()) * 57.2957763671875D)); + this.yRotO = this.getYRot(); + this.xRotO = this.getXRot(); + } + + @Override + protected void defineSynchedData() { +- this.getEntityData().define(DATA_HOOKED_ENTITY, 0); +- this.getEntityData().define(DATA_BITING, false); ++ this.getEntityData().define(FishingHook.DATA_HOOKED_ENTITY, 0); ++ this.getEntityData().define(FishingHook.DATA_BITING, false); + } + + @Override + public void onSyncedDataUpdated(EntityDataAccessor<?> key) { +- if (DATA_HOOKED_ENTITY.equals(key)) { +- int i = this.getEntityData().get(DATA_HOOKED_ENTITY); ++ if (FishingHook.DATA_HOOKED_ENTITY.equals(key)) { ++ int i = (Integer) this.getEntityData().get(FishingHook.DATA_HOOKED_ENTITY); ++ + this.hookedIn = i > 0 ? this.level().getEntity(i - 1) : null; + } + +- if (DATA_BITING.equals(key)) { +- this.biting = this.getEntityData().get(DATA_BITING); ++ if (FishingHook.DATA_BITING.equals(key)) { ++ this.biting = (Boolean) this.getEntityData().get(FishingHook.DATA_BITING); + if (this.biting) { +- this.setDeltaMovement(this.getDeltaMovement().x, (double)(-0.4F * Mth.nextFloat(this.syncronizedRandom, 0.6F, 1.0F)), this.getDeltaMovement().z); ++ this.setDeltaMovement(this.getDeltaMovement().x, (double) (-0.4F * Mth.nextFloat(this.syncronizedRandom, 0.6F, 1.0F)), this.getDeltaMovement().z); + } + } + +@@ -128,24 +149,25 @@ + + @Override + public boolean shouldRenderAtSqrDistance(double distance) { +- double d = 64.0; +- return distance < 4096.0; ++ double d1 = 64.0D; ++ ++ return distance < 4096.0D; + } + + @Override +- public void lerpTo(double d, double d1, double d2, float f, float f1, int i) { +- } ++ public void lerpTo(double d0, double d1, double d2, float f, float f1, int i) {} + + @Override + public void tick() { + this.syncronizedRandom.setSeed(this.getUUID().getLeastSignificantBits() ^ this.level().getGameTime()); + super.tick(); +- Player playerOwner = this.getPlayerOwner(); +- if (playerOwner == null) { ++ net.minecraft.world.entity.player.Player entityhuman = this.getPlayerOwner(); ++ ++ if (entityhuman == null) { + this.discard(); +- } else if (this.level().isClientSide || !this.shouldStopFishing(playerOwner)) { ++ } else if (this.level().isClientSide || !this.shouldStopFishing(entityhuman)) { + if (this.onGround()) { +- this.life++; ++ ++this.life; + if (this.life >= 1200) { + this.discard(); + return; +@@ -155,66 +177,66 @@ + } + + float f = 0.0F; +- BlockPos blockPos = this.blockPosition(); +- FluidState fluidState = this.level().getFluidState(blockPos); +- if (fluidState.is(FluidTags.WATER)) { +- f = fluidState.getHeight(this.level(), blockPos); ++ BlockPos blockposition = this.blockPosition(); ++ FluidState fluid = this.level().getFluidState(blockposition); ++ ++ if (fluid.is(FluidTags.WATER)) { ++ f = fluid.getHeight(this.level(), blockposition); + } + + boolean flag = f > 0.0F; +- if (this.currentState == FishingHook.FishHookState.FLYING) { ++ ++ if (this.currentState == FishingHook.HookState.FLYING) { + if (this.hookedIn != null) { + this.setDeltaMovement(Vec3.ZERO); +- this.currentState = FishingHook.FishHookState.HOOKED_IN_ENTITY; ++ this.currentState = FishingHook.HookState.HOOKED_IN_ENTITY; + return; + } + + if (flag) { +- this.setDeltaMovement(this.getDeltaMovement().multiply(0.3, 0.2, 0.3)); +- this.currentState = FishingHook.FishHookState.BOBBING; ++ this.setDeltaMovement(this.getDeltaMovement().multiply(0.3D, 0.2D, 0.3D)); ++ this.currentState = FishingHook.HookState.BOBBING; + return; + } + + this.checkCollision(); + } else { +- if (this.currentState == FishingHook.FishHookState.HOOKED_IN_ENTITY) { ++ if (this.currentState == FishingHook.HookState.HOOKED_IN_ENTITY) { + if (this.hookedIn != null) { + if (!this.hookedIn.isRemoved() && this.hookedIn.level().dimension() == this.level().dimension()) { +- this.setPos(this.hookedIn.getX(), this.hookedIn.getY(0.8), this.hookedIn.getZ()); ++ this.setPos(this.hookedIn.getX(), this.hookedIn.getY(0.8D), this.hookedIn.getZ()); + } else { +- this.setHookedEntity(null); +- this.currentState = FishingHook.FishHookState.FLYING; ++ this.setHookedEntity((Entity) null); ++ this.currentState = FishingHook.HookState.FLYING; + } + } + + return; + } + +- if (this.currentState == FishingHook.FishHookState.BOBBING) { +- Vec3 deltaMovement = this.getDeltaMovement(); +- double d = this.getY() + deltaMovement.y - (double)blockPos.getY() - (double)f; +- if (Math.abs(d) < 0.01) { +- d += Math.signum(d) * 0.1; ++ if (this.currentState == FishingHook.HookState.BOBBING) { ++ Vec3 vec3d = this.getDeltaMovement(); ++ double d0 = this.getY() + vec3d.y - (double) blockposition.getY() - (double) f; ++ ++ if (Math.abs(d0) < 0.01D) { ++ d0 += Math.signum(d0) * 0.1D; + } + +- this.setDeltaMovement(deltaMovement.x * 0.9, deltaMovement.y - d * (double)this.random.nextFloat() * 0.2, deltaMovement.z * 0.9); ++ this.setDeltaMovement(vec3d.x * 0.9D, vec3d.y - d0 * (double) this.random.nextFloat() * 0.2D, vec3d.z * 0.9D); + if (this.nibble <= 0 && this.timeUntilHooked <= 0) { + this.openWater = true; + } else { +- this.openWater = this.openWater && this.outOfWaterTime < 10 && this.calculateOpenWater(blockPos); ++ this.openWater = this.openWater && this.outOfWaterTime < 10 && this.calculateOpenWater(blockposition); + } + + if (flag) { + this.outOfWaterTime = Math.max(0, this.outOfWaterTime - 1); + if (this.biting) { +- this.setDeltaMovement( +- this.getDeltaMovement() +- .add(0.0, -0.1 * (double)this.syncronizedRandom.nextFloat() * (double)this.syncronizedRandom.nextFloat(), 0.0) +- ); ++ this.setDeltaMovement(this.getDeltaMovement().add(0.0D, -0.1D * (double) this.syncronizedRandom.nextFloat() * (double) this.syncronizedRandom.nextFloat(), 0.0D)); + } + + if (!this.level().isClientSide) { +- this.catchingFish(blockPos); ++ this.catchingFish(blockposition); + } + } else { + this.outOfWaterTime = Math.min(10, this.outOfWaterTime + 1); +@@ -222,28 +244,30 @@ + } + } + +- if (!fluidState.is(FluidTags.WATER)) { +- this.setDeltaMovement(this.getDeltaMovement().add(0.0, -0.03, 0.0)); ++ if (!fluid.is(FluidTags.WATER)) { ++ this.setDeltaMovement(this.getDeltaMovement().add(0.0D, -0.03D, 0.0D)); + } + +- this.move(MoverType.SELF, this.getDeltaMovement()); ++ this.move(EnumMoveType.SELF, this.getDeltaMovement()); + this.updateRotation(); +- if (this.currentState == FishingHook.FishHookState.FLYING && (this.onGround() || this.horizontalCollision)) { ++ if (this.currentState == FishingHook.HookState.FLYING && (this.onGround() || this.horizontalCollision)) { + this.setDeltaMovement(Vec3.ZERO); + } + +- double d1 = 0.92; +- this.setDeltaMovement(this.getDeltaMovement().scale(0.92)); ++ double d1 = 0.92D; ++ ++ this.setDeltaMovement(this.getDeltaMovement().scale(0.92D)); + this.reapplyPosition(); + } + } + +- private boolean shouldStopFishing(Player player) { +- ItemStack mainHandItem = player.getMainHandItem(); +- ItemStack offhandItem = player.getOffhandItem(); +- boolean isFishingRod = mainHandItem.is(Items.FISHING_ROD); +- boolean isFishingRod1 = offhandItem.is(Items.FISHING_ROD); +- if (!player.isRemoved() && player.isAlive() && (isFishingRod || isFishingRod1) && !(this.distanceToSqr(player) > 1024.0)) { ++ private boolean shouldStopFishing(net.minecraft.world.entity.player.Player player) { ++ ItemStack itemstack = player.getMainHandItem(); ++ ItemStack itemstack1 = player.getOffhandItem(); ++ boolean flag = itemstack.is(Items.FISHING_ROD); ++ boolean flag1 = itemstack1.is(Items.FISHING_ROD); ++ ++ if (!player.isRemoved() && player.isAlive() && (flag || flag1) && this.distanceToSqr((Entity) player) <= 1024.0D) { + return false; + } else { + this.discard(); +@@ -252,8 +276,9 @@ + } + + private void checkCollision() { +- HitResult hitResultOnMoveVector = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); +- this.onHit(hitResultOnMoveVector); ++ HitResult movingobjectposition = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); ++ ++ this.preOnHit(movingobjectposition); // CraftBukkit - projectile hit event + } + + @Override +@@ -267,6 +292,7 @@ + if (!this.level().isClientSide) { + this.setHookedEntity(result.getEntity()); + } ++ + } + + @Override +@@ -275,153 +301,162 @@ + this.setDeltaMovement(this.getDeltaMovement().normalize().scale(result.distanceTo(this))); + } + +- private void setHookedEntity(@Nullable Entity hookedEntity) { ++ public void setHookedEntity(@Nullable Entity hookedEntity) { + this.hookedIn = hookedEntity; +- this.getEntityData().set(DATA_HOOKED_ENTITY, hookedEntity == null ? 0 : hookedEntity.getId() + 1); ++ this.getEntityData().set(FishingHook.DATA_HOOKED_ENTITY, hookedEntity == null ? 0 : hookedEntity.getId() + 1); + } + + private void catchingFish(BlockPos pos) { +- ServerLevel serverLevel = (ServerLevel)this.level(); ++ ServerLevel worldserver = (ServerLevel) this.level(); + int i = 1; +- BlockPos blockPos = pos.above(); +- if (this.random.nextFloat() < 0.25F && this.level().isRainingAt(blockPos)) { +- i++; ++ BlockPos blockposition1 = pos.above(); ++ ++ if (this.rainInfluenced && this.random.nextFloat() < 0.25F && this.level().isRainingAt(blockposition1)) { // CraftBukkit ++ ++i; + } + +- if (this.random.nextFloat() < 0.5F && !this.level().canSeeSky(blockPos)) { +- i--; ++ if (this.skyInfluenced && this.random.nextFloat() < 0.5F && !this.level().canSeeSky(blockposition1)) { // CraftBukkit ++ --i; + } + + if (this.nibble > 0) { +- this.nibble--; ++ --this.nibble; + if (this.nibble <= 0) { + this.timeUntilLured = 0; + this.timeUntilHooked = 0; +- this.getEntityData().set(DATA_BITING, false); ++ this.getEntityData().set(FishingHook.DATA_BITING, false); ++ // CraftBukkit start ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.getPlayerOwner().getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.FAILED_ATTEMPT); ++ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent); ++ // CraftBukkit end + } +- } else if (this.timeUntilHooked > 0) { +- this.timeUntilHooked -= i; ++ } else { ++ float f; ++ float f1; ++ float f2; ++ double d0; ++ double d1; ++ double d2; ++ IBlockData iblockdata; ++ + if (this.timeUntilHooked > 0) { +- this.fishAngle = this.fishAngle + (float)this.random.triangle(0.0, 9.188); +- float f = this.fishAngle * (float) (Math.PI / 180.0); +- float sin = Mth.sin(f); +- float cos = Mth.cos(f); +- double d = this.getX() + (double)(sin * (float)this.timeUntilHooked * 0.1F); +- double d1 = (double)((float)Mth.floor(this.getY()) + 1.0F); +- double d2 = this.getZ() + (double)(cos * (float)this.timeUntilHooked * 0.1F); +- BlockState blockState = serverLevel.getBlockState(BlockPos.containing(d, d1 - 1.0, d2)); +- if (blockState.is(Blocks.WATER)) { +- if (this.random.nextFloat() < 0.15F) { +- serverLevel.sendParticles(ParticleTypes.BUBBLE, d, d1 - 0.1F, d2, 1, (double)sin, 0.1, (double)cos, 0.0); ++ this.timeUntilHooked -= i; ++ if (this.timeUntilHooked > 0) { ++ this.fishAngle += (float) this.random.triangle(0.0D, 9.188D); ++ f = this.fishAngle * 0.017453292F; ++ f1 = Mth.sin(f); ++ f2 = Mth.cos(f); ++ d0 = this.getX() + (double) (f1 * (float) this.timeUntilHooked * 0.1F); ++ d1 = (double) ((float) Mth.floor(this.getY()) + 1.0F); ++ d2 = this.getZ() + (double) (f2 * (float) this.timeUntilHooked * 0.1F); ++ iblockdata = worldserver.getBlockState(BlockPos.containing(d0, d1 - 1.0D, d2)); ++ if (iblockdata.is(Blocks.WATER)) { ++ if (this.random.nextFloat() < 0.15F) { ++ worldserver.sendParticles(ParticleTypes.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.sendParticles(ParticleTypes.FISHING, d0, d1, d2, 0, (double) f4, 0.01D, (double) (-f3), 1.0D); ++ worldserver.sendParticles(ParticleTypes.FISHING, d0, d1, d2, 0, (double) (-f4), 0.01D, (double) f3, 1.0D); + } ++ } else { ++ // CraftBukkit start ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.getPlayerOwner().getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.BITE); ++ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent); ++ if (playerFishEvent.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end ++ this.playSound(SoundEvents.FISHING_BOBBER_SPLASH, 0.25F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); ++ double d3 = this.getY() + 0.5D; + +- float f1 = sin * 0.04F; +- float f2 = cos * 0.04F; +- serverLevel.sendParticles(ParticleTypes.FISHING, d, d1, d2, 0, (double)f2, 0.01, (double)(-f1), 1.0); +- serverLevel.sendParticles(ParticleTypes.FISHING, d, d1, d2, 0, (double)(-f2), 0.01, (double)f1, 1.0); ++ worldserver.sendParticles(ParticleTypes.BUBBLE, this.getX(), d3, this.getZ(), (int) (1.0F + this.getBbWidth() * 20.0F), (double) this.getBbWidth(), 0.0D, (double) this.getBbWidth(), 0.20000000298023224D); ++ worldserver.sendParticles(ParticleTypes.FISHING, this.getX(), d3, this.getZ(), (int) (1.0F + this.getBbWidth() * 20.0F), (double) this.getBbWidth(), 0.0D, (double) this.getBbWidth(), 0.20000000298023224D); ++ this.nibble = Mth.nextInt(this.random, 20, 40); ++ this.getEntityData().set(FishingHook.DATA_BITING, true); + } +- } else { +- this.playSound(SoundEvents.FISHING_BOBBER_SPLASH, 0.25F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); +- double d3 = this.getY() + 0.5; +- serverLevel.sendParticles( +- ParticleTypes.BUBBLE, +- this.getX(), +- d3, +- this.getZ(), +- (int)(1.0F + this.getBbWidth() * 20.0F), +- (double)this.getBbWidth(), +- 0.0, +- (double)this.getBbWidth(), +- 0.2F +- ); +- serverLevel.sendParticles( +- ParticleTypes.FISHING, +- this.getX(), +- d3, +- this.getZ(), +- (int)(1.0F + this.getBbWidth() * 20.0F), +- (double)this.getBbWidth(), +- 0.0, +- (double)this.getBbWidth(), +- 0.2F +- ); +- this.nibble = Mth.nextInt(this.random, 20, 40); +- this.getEntityData().set(DATA_BITING, true); +- } +- } else if (this.timeUntilLured > 0) { +- this.timeUntilLured -= i; +- float f = 0.15F; +- if (this.timeUntilLured < 20) { +- f += (float)(20 - this.timeUntilLured) * 0.05F; +- } else if (this.timeUntilLured < 40) { +- f += (float)(40 - this.timeUntilLured) * 0.02F; +- } else if (this.timeUntilLured < 60) { +- f += (float)(60 - this.timeUntilLured) * 0.01F; +- } ++ } else if (this.timeUntilLured > 0) { ++ this.timeUntilLured -= i; ++ f = 0.15F; ++ if (this.timeUntilLured < 20) { ++ f += (float) (20 - this.timeUntilLured) * 0.05F; ++ } else if (this.timeUntilLured < 40) { ++ f += (float) (40 - this.timeUntilLured) * 0.02F; ++ } else if (this.timeUntilLured < 60) { ++ f += (float) (60 - this.timeUntilLured) * 0.01F; ++ } + +- if (this.random.nextFloat() < f) { +- float sin = Mth.nextFloat(this.random, 0.0F, 360.0F) * (float) (Math.PI / 180.0); +- float cos = Mth.nextFloat(this.random, 25.0F, 60.0F); +- double d = this.getX() + (double)(Mth.sin(sin) * cos) * 0.1; +- double d1 = (double)((float)Mth.floor(this.getY()) + 1.0F); +- double d2 = this.getZ() + (double)(Mth.cos(sin) * cos) * 0.1; +- BlockState blockState = serverLevel.getBlockState(BlockPos.containing(d, d1 - 1.0, d2)); +- if (blockState.is(Blocks.WATER)) { +- serverLevel.sendParticles(ParticleTypes.SPLASH, d, d1, d2, 2 + this.random.nextInt(2), 0.1F, 0.0, 0.1F, 0.0); ++ if (this.random.nextFloat() < f) { ++ f1 = Mth.nextFloat(this.random, 0.0F, 360.0F) * 0.017453292F; ++ f2 = Mth.nextFloat(this.random, 25.0F, 60.0F); ++ d0 = this.getX() + (double) (Mth.sin(f1) * f2) * 0.1D; ++ d1 = (double) ((float) Mth.floor(this.getY()) + 1.0F); ++ d2 = this.getZ() + (double) (Mth.cos(f1) * f2) * 0.1D; ++ iblockdata = worldserver.getBlockState(BlockPos.containing(d0, d1 - 1.0D, d2)); ++ if (iblockdata.is(Blocks.WATER)) { ++ worldserver.sendParticles(ParticleTypes.SPLASH, d0, d1, d2, 2 + this.random.nextInt(2), 0.10000000149011612D, 0.0D, 0.10000000149011612D, 0.0D); ++ } + } +- } + +- if (this.timeUntilLured <= 0) { +- this.fishAngle = Mth.nextFloat(this.random, 0.0F, 360.0F); +- this.timeUntilHooked = Mth.nextInt(this.random, 20, 80); ++ if (this.timeUntilLured <= 0) { ++ // CraftBukkit start - logic to modify fishing wait time, lure time, and lure angle ++ this.fishAngle = Mth.nextFloat(this.random, this.minLureAngle, this.maxLureAngle); ++ this.timeUntilHooked = Mth.nextInt(this.random, this.minLureTime, this.maxLureTime); ++ // CraftBukkit end ++ } ++ } else { ++ // CraftBukkit start - logic to modify fishing wait time ++ this.timeUntilLured = Mth.nextInt(this.random, this.minWaitTime, this.maxWaitTime); ++ this.timeUntilLured -= (this.applyLure) ? this.lureSpeed * 20 * 5 : 0; ++ // CraftBukkit end + } +- } else { +- this.timeUntilLured = Mth.nextInt(this.random, 100, 600); +- this.timeUntilLured = this.timeUntilLured - this.lureSpeed * 20 * 5; + } ++ + } + + private boolean calculateOpenWater(BlockPos pos) { +- FishingHook.OpenWaterType openWaterType = FishingHook.OpenWaterType.INVALID; ++ FishingHook.WaterPosition entityfishinghook_waterposition = FishingHook.WaterPosition.INVALID; + +- for (int i = -1; i <= 2; i++) { +- FishingHook.OpenWaterType openWaterTypeForArea = this.getOpenWaterTypeForArea(pos.offset(-2, i, -2), pos.offset(2, i, 2)); +- switch (openWaterTypeForArea) { ++ for (int i = -1; i <= 2; ++i) { ++ FishingHook.WaterPosition entityfishinghook_waterposition1 = this.getOpenWaterTypeForArea(pos.offset(-2, i, -2), pos.offset(2, i, 2)); ++ ++ switch (entityfishinghook_waterposition1) { + case INVALID: + return false; + case ABOVE_WATER: +- if (openWaterType == FishingHook.OpenWaterType.INVALID) { ++ if (entityfishinghook_waterposition == FishingHook.WaterPosition.INVALID) { + return false; + } + break; + case INSIDE_WATER: +- if (openWaterType == FishingHook.OpenWaterType.ABOVE_WATER) { ++ if (entityfishinghook_waterposition == FishingHook.WaterPosition.ABOVE_WATER) { + return false; + } + } + +- openWaterType = openWaterTypeForArea; ++ entityfishinghook_waterposition = entityfishinghook_waterposition1; + } + + return true; + } + +- private FishingHook.OpenWaterType getOpenWaterTypeForArea(BlockPos firstPos, BlockPos secondPos) { +- return BlockPos.betweenClosedStream(firstPos, secondPos) +- .map(this::getOpenWaterTypeForBlock) +- .reduce((firstType, secondType) -> firstType == secondType ? firstType : FishingHook.OpenWaterType.INVALID) +- .orElse(FishingHook.OpenWaterType.INVALID); ++ private FishingHook.WaterPosition getOpenWaterTypeForArea(BlockPos firstPos, BlockPos secondPos) { ++ return (FishingHook.WaterPosition) BlockPos.betweenClosedStream(firstPos, secondPos).map(this::getOpenWaterTypeForBlock).reduce((entityfishinghook_waterposition, entityfishinghook_waterposition1) -> { ++ return entityfishinghook_waterposition == entityfishinghook_waterposition1 ? entityfishinghook_waterposition : FishingHook.WaterPosition.INVALID; ++ }).orElse(FishingHook.WaterPosition.INVALID); + } + +- private FishingHook.OpenWaterType getOpenWaterTypeForBlock(BlockPos pos) { +- BlockState blockState = this.level().getBlockState(pos); +- if (!blockState.isAir() && !blockState.is(Blocks.LILY_PAD)) { +- FluidState fluidState = blockState.getFluidState(); +- return fluidState.is(FluidTags.WATER) && fluidState.isSource() && blockState.getCollisionShape(this.level(), pos).isEmpty() +- ? FishingHook.OpenWaterType.INSIDE_WATER +- : FishingHook.OpenWaterType.INVALID; ++ private FishingHook.WaterPosition getOpenWaterTypeForBlock(BlockPos pos) { ++ IBlockData iblockdata = this.level().getBlockState(pos); ++ ++ if (!iblockdata.isAir() && !iblockdata.is(Blocks.LILY_PAD)) { ++ FluidState fluid = iblockdata.getFluidState(); ++ ++ return fluid.is(FluidTags.WATER) && fluid.isSource() && iblockdata.getCollisionShape(this.level(), pos).isEmpty() ? FishingHook.WaterPosition.INSIDE_WATER : FishingHook.WaterPosition.INVALID; + } else { +- return FishingHook.OpenWaterType.ABOVE_WATER; ++ return FishingHook.WaterPosition.ABOVE_WATER; + } + } + +@@ -430,58 +465,90 @@ + } + + @Override +- public void addAdditionalSaveData(CompoundTag compound) { +- } ++ public void addAdditionalSaveData(CompoundTag compound) {} + + @Override +- public void readAdditionalSaveData(CompoundTag compound) { +- } ++ public void readAdditionalSaveData(CompoundTag compound) {} + + public int retrieve(ItemStack stack) { +- Player playerOwner = this.getPlayerOwner(); +- if (!this.level().isClientSide && playerOwner != null && !this.shouldStopFishing(playerOwner)) { ++ net.minecraft.world.entity.player.Player entityhuman = this.getPlayerOwner(); ++ ++ if (!this.level().isClientSide && entityhuman != null && !this.shouldStopFishing(entityhuman)) { + int i = 0; ++ + if (this.hookedIn != null) { ++ // CraftBukkit start ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), this.hookedIn.getBukkitEntity(), (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_ENTITY); ++ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) { ++ return 0; ++ } ++ // CraftBukkit end + this.pullEntity(this.hookedIn); +- CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer)playerOwner, stack, this, Collections.emptyList()); +- this.level().broadcastEntityEvent(this, (byte)31); ++ CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer) entityhuman, stack, this, Collections.emptyList()); ++ this.level().broadcastEntityEvent(this, (byte) 31); + i = this.hookedIn instanceof ItemEntity ? 3 : 5; + } else if (this.nibble > 0) { +- LootParams lootParams = new LootParams.Builder((ServerLevel)this.level()) +- .withParameter(LootContextParams.ORIGIN, this.position()) +- .withParameter(LootContextParams.TOOL, stack) +- .withParameter(LootContextParams.THIS_ENTITY, this) +- .withLuck((float)this.luck + playerOwner.getLuck()) +- .create(LootContextParamSets.FISHING); +- LootTable lootTable = this.level().getServer().getLootData().getLootTable(BuiltInLootTables.FISHING); +- List<ItemStack> randomItems = lootTable.getRandomItems(lootParams); +- CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer)playerOwner, stack, this, randomItems); ++ LootParams lootparams = (new LootParams.Builder((ServerLevel) this.level())).withParameter(LootContextParams.ORIGIN, this.position()).withParameter(LootContextParams.TOOL, stack).withParameter(LootContextParams.THIS_ENTITY, this).withLuck((float) this.luck + entityhuman.getLuck()).create(LootContextParamSets.FISHING); ++ LootTable loottable = this.level().getServer().getLootData().getLootTable(BuiltInLootTables.FISHING); ++ List<ItemStack> list = loottable.getRandomItems(lootparams); + +- for (ItemStack itemStack : randomItems) { +- ItemEntity itemEntity = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemStack); +- double d = playerOwner.getX() - this.getX(); +- double d1 = playerOwner.getY() - this.getY(); +- double d2 = playerOwner.getZ() - this.getZ(); +- double d3 = 0.1; +- itemEntity.setDeltaMovement(d * 0.1, d1 * 0.1 + Math.sqrt(Math.sqrt(d * d + d1 * d1 + d2 * d2)) * 0.08, d2 * 0.1); +- this.level().addFreshEntity(itemEntity); +- playerOwner.level() +- .addFreshEntity( +- new ExperienceOrb( +- playerOwner.level(), playerOwner.getX(), playerOwner.getY() + 0.5, playerOwner.getZ() + 0.5, this.random.nextInt(6) + 1 +- ) +- ); +- if (itemStack.is(ItemTags.FISHES)) { +- playerOwner.awardStat(Stats.FISH_CAUGHT, 1); ++ CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer) entityhuman, stack, this, list); ++ Iterator iterator = list.iterator(); ++ ++ while (iterator.hasNext()) { ++ ItemStack itemstack1 = (ItemStack) iterator.next(); ++ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemstack1); ++ // CraftBukkit start ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), entityitem.getBukkitEntity(), (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_FISH); ++ playerFishEvent.setExpToDrop(this.random.nextInt(6) + 1); ++ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) { ++ return 0; + } ++ // CraftBukkit end ++ double d0 = entityhuman.getX() - this.getX(); ++ double d1 = entityhuman.getY() - this.getY(); ++ double d2 = entityhuman.getZ() - this.getZ(); ++ double d3 = 0.1D; ++ ++ entityitem.setDeltaMovement(d0 * 0.1D, d1 * 0.1D + Math.sqrt(Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2)) * 0.08D, d2 * 0.1D); ++ this.level().addFreshEntity(entityitem); ++ // CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop() ++ if (playerFishEvent.getExpToDrop() > 0) { ++ entityhuman.level().addFreshEntity(new ExperienceOrb(entityhuman.level(), entityhuman.getX(), entityhuman.getY() + 0.5D, entityhuman.getZ() + 0.5D, playerFishEvent.getExpToDrop())); ++ } ++ // CraftBukkit end ++ if (itemstack1.is(ItemTags.FISHES)) { ++ entityhuman.awardStat(Stats.FISH_CAUGHT, 1); ++ } + } + + i = 1; + } + + if (this.onGround()) { ++ // CraftBukkit start ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.IN_GROUND); ++ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) { ++ return 0; ++ } ++ // CraftBukkit end + i = 2; + } ++ // CraftBukkit start ++ if (i == 0) { ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.REEL_IN); ++ this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent); ++ if (playerFishEvent.isCancelled()) { ++ return 0; ++ } ++ } ++ // CraftBukkit end + + this.discard(); + return i; +@@ -492,18 +559,20 @@ + + @Override + public void handleEntityEvent(byte id) { +- if (id == 31 && this.level().isClientSide && this.hookedIn instanceof Player && ((Player)this.hookedIn).isLocalPlayer()) { ++ if (id == 31 && this.level().isClientSide && this.hookedIn instanceof net.minecraft.world.entity.player.Player && ((net.minecraft.world.entity.player.Player) this.hookedIn).isLocalPlayer()) { + this.pullEntity(this.hookedIn); + } + + super.handleEntityEvent(id); + } + +- protected void pullEntity(Entity entity) { +- Entity owner = this.getOwner(); +- if (owner != null) { +- Vec3 vec3 = new Vec3(owner.getX() - this.getX(), owner.getY() - this.getY(), owner.getZ() - this.getZ()).scale(0.1); +- entity.setDeltaMovement(entity.getDeltaMovement().add(vec3)); ++ public void pullEntity(Entity entity) { ++ Entity entity1 = this.getOwner(); ++ ++ if (entity1 != null) { ++ Vec3 vec3d = (new Vec3(entity1.getX() - this.getX(), entity1.getY() - this.getY(), entity1.getZ() - this.getZ())).scale(0.1D); ++ ++ entity.setDeltaMovement(entity.getDeltaMovement().add(vec3d)); + } + } + +@@ -514,13 +583,13 @@ + + @Override + public void remove(Entity.RemovalReason reason) { +- this.updateOwnerInfo(null); ++ this.updateOwnerInfo((FishingHook) null); + super.remove(reason); + } + + @Override + public void onClientRemoval() { +- this.updateOwnerInfo(null); ++ this.updateOwnerInfo((FishingHook) null); + } + + @Override +@@ -530,16 +599,19 @@ + } + + private void updateOwnerInfo(@Nullable FishingHook fishingHook) { +- Player playerOwner = this.getPlayerOwner(); +- if (playerOwner != null) { +- playerOwner.fishing = fishingHook; ++ net.minecraft.world.entity.player.Player entityhuman = this.getPlayerOwner(); ++ ++ if (entityhuman != null) { ++ entityhuman.fishing = fishingHook; + } ++ + } + + @Nullable +- public Player getPlayerOwner() { +- Entity owner = this.getOwner(); +- return owner instanceof Player ? (Player)owner : null; ++ public net.minecraft.world.entity.player.Player getPlayerOwner() { ++ Entity entity = this.getOwner(); ++ ++ return entity instanceof net.minecraft.world.entity.player.Player ? (net.minecraft.world.entity.player.Player) entity : null; + } + + @Nullable +@@ -554,29 +626,34 @@ + + @Override + public Packet<ClientGamePacketListener> getAddEntityPacket() { +- Entity owner = this.getOwner(); +- return new ClientboundAddEntityPacket(this, owner == null ? this.getId() : owner.getId()); ++ Entity entity = this.getOwner(); ++ ++ return new ClientboundAddEntityPacket(this, entity == null ? this.getId() : entity.getId()); + } + + @Override + public void recreateFromPacket(ClientboundAddEntityPacket packet) { + super.recreateFromPacket(packet); + if (this.getPlayerOwner() == null) { +- int data = packet.getData(); +- LOGGER.error("Failed to recreate fishing hook on client. {} (id: {}) is not a valid owner.", this.level().getEntity(data), data); ++ int i = packet.getData(); ++ ++ FishingHook.LOGGER.error("Failed to recreate fishing hook on client. {} (id: {}) is not a valid owner.", this.level().getEntity(i), i); + this.kill(); + } ++ + } + +- static enum FishHookState { +- FLYING, +- HOOKED_IN_ENTITY, +- BOBBING; ++ public static enum HookState { ++ ++ FLYING, HOOKED_IN_ENTITY, BOBBING; ++ ++ private HookState() {} + } + +- static enum OpenWaterType { +- ABOVE_WATER, +- INSIDE_WATER, +- INVALID; ++ private static enum WaterPosition { ++ ++ ABOVE_WATER, INSIDE_WATER, INVALID; ++ ++ private WaterPosition() {} + } + } |