mojira.dev
MC-241081

Fishing bobber retrieving sounds and hand animations aren't played when fishing bobbers are automatically returned from long distances

The Bug:

Fishing bobber retrieving sounds and hand animations aren't played when fishing bobbers are automatically returned from long distances.

Steps to Reproduce:

  1. Obtain a fishing rod and cast it.

  2. Walk backward far enough so that the fishing bobber automatically returns and both listen and watch closely as this happens.

  3. Take note as to whether or not fishing bobber retrieving sounds and hand animations aren't played when fishing bobbers are automatically returned from long distances.

Observed Behavior:

Fishing bobber retrieving sounds and hand animations aren't played.

Expected Behavior:

Fishing bobber retrieving sounds and hand animations would be played.

Code Analysis & Fix:

Code analysis and fix by @unknown can be found in this comment.

Linked issues

Comments 1

Code Analysis:

The following is based on a decompiled version of Minecraft 1.20.1 using MCP-Reborn.

net.minecraft.world.entity.projectile.FishingHook.java // Original

public class FishingHook extends Projectile {
    ...
    public void tick() {
        this.syncronizedRandom.setSeed(this.getUUID().getLeastSignificantBits() ^ this.level().getGameTime());
        super.tick();
        Player player = this.getPlayerOwner();
        if (player == null) {
            this.discard();
        } else if (this.level().isClientSide || !this.shouldStopFishing(player)) {
            if (this.onGround()) {
                ++this.life;
                if (this.life >= 1200) {
                    this.discard();
                    return;
                }
            } else {
                this.life = 0;
            }
            ...
        }
        ...
    }    
    ...
    private boolean shouldStopFishing(Player p_37137_) {
        ItemStack itemstack = p_37137_.getMainHandItem();
        ItemStack itemstack1 = p_37137_.getOffhandItem();
        boolean flag = itemstack.is(Items.FISHING_ROD);
        boolean flag1 = itemstack1.is(Items.FISHING_ROD);
        if (!p_37137_.isRemoved() && p_37137_.isAlive() && (flag || flag1) && !(this.distanceToSqr(p_37137_) > 1024.0D)) {
            return false;
        } else {
            this.discard();
            return true;
        }
    }
    ...
}

As we can see in the code, FishingHook#shouldStopFishing is used to determine the distance from the player and the fishing rod. If the distance is too high, it will delete the fishing line, therefore no animations, sounds, and reward comes out of it.

Fix:

To fix this, we can simply remove !(this.distanceToSqr(p_37137) > 1024.0D)) from FishingHook#shouldStopFishing and move it to FishingHook#tick. Then, we can create our own additional "if" statement to check the distance and handle actually animating, rewarding, and emitting sound globally.

net.minecraft.world.entity.projectile.FishingHook.java // Updated

public class FishingHook extends Projectile {
    ...
    public void tick() {
        this.syncronizedRandom.setSeed(this.getUUID().getLeastSignificantBits() ^ this.level().getGameTime());
        super.tick();
        Player player = this.getPlayerOwner();
        if (player == null) {
            this.discard();
        } else if (this.distanceToSqr(player) > 1024.0 D && player.fishing != null) {
            ItemStack itemStack = player.getMainHandItem().isEmpty() ? player.getOffhandItem() : player.getMainHandItem();
            InteractionHand interactionHand = player.getMainHandItem().isEmpty() ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
            int i = player.fishing.retrieve(itemStack);
            itemStack.hurtAndBreak(i, player, (p_41288_) -> p_41288_.broadcastBreakEvent(interactionHand));
            player.swing(interactionHand);
            player.level().playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.FISHING_BOBBER_RETRIEVE, SoundSource.NEUTRAL, 1.0 F, 0.4 F / (player.level().getRandom().nextFloat() * 0.4 F + 0.8 F));
        } else if (this.level().isClientSide || !this.shouldStopFishing(player)) {
            if (this.onGround()) {
                ++this.life;
                if (this.life >= 1200) {
                    this.discard();
                    return;
                }
            } else {
                this.life = 0;
            }
            ...
        }
        ...
    }
    ...
    private boolean shouldStopFishing(Player p_37137_) {
        ItemStack itemstack = p_37137_.getMainHandItem();
        ItemStack itemstack1 = p_37137_.getOffhandItem();
        boolean flag = itemstack.is(Items.FISHING_ROD);
        boolean flag1 = itemstack1.is(Items.FISHING_ROD);
        if (!p_37137_.isRemoved() && p_37137_.isAlive() && (flag || flag1)) {
            return false;
        } else {
            this.discard();
            return true;
        }
    }
    ...
}

Avoma

(Unassigned)

Confirmed

Entities, Player Animation, Sound

fishing_bobber, fishing_rod

1.17.1, 21w44a, 1.18 Pre-release 1, 1.18 Pre-release 6, 1.18 Pre-release 7, ..., 1.19.1, 1.19.2, 1.19.3, 1.19.4, 1.20.1

Retrieved