mojira.dev

Nickid2018

Assigned

No issues.

Reported

MC-301531 Server Management Protocol returns wrong response for invalid method IDs Plausible MC-216150 Bounding Box disappears randomly in the water Duplicate MC-213973 Wrong state of the fishing rod in the hotbar Duplicate

Comments

Code analysis:

Mob attacking turtle behavior uses NearestAttackableTargetGoal and its subclasses. The behavior can only keep active when the method canContinueToUse returns true.

For untamable mobs, they use NearestAttackableTargetGoal. They use following method:

// TargetGoal::canContinueToUse
@Override
public boolean canContinueToUse() {
    LivingEntity livingEntity = this.mob.getTarget();
    if (livingEntity == null) {
        livingEntity = this.targetMob;
    }
    if (livingEntity == null) {
        return false;
    }
    if (!this.mob.canAttack(livingEntity)) {
        return false;
    }
    PlayerTeam playerTeam = this.mob.getTeam();
    PlayerTeam playerTeam2 = livingEntity.getTeam();
    if (playerTeam != null && playerTeam2 == playerTeam) {
        return false;
    }
    double d = this.getFollowDistance();
    if (this.mob.distanceToSqr(livingEntity) > d * d) {
        return false;
    }
    if (this.mustSee) {
        if (this.mob.getSensing().hasLineOfSight(livingEntity)) {
            this.unseenTicks = 0;
        } else if (++this.unseenTicks > TargetGoal.reducedTickDelay(this.unseenMemoryTicks)) {
            return false;
        }
    }
    this.mob.setTarget(livingEntity);
    return true;
}

Untamable mobs don't check the target condition in canContinueToUse, so they can't stop attacking immediately when the turtle grows up.

For tamable animals, they use NonTameRandomTargetGoal. They use following method:

// NonTameRandomTargetGoal::canContinueToUse
@Override
public boolean canContinueToUse() {
    if (this.targetConditions != null) {
        return this.targetConditions.test(NonTameRandomTargetGoal.getServerLevel(this.mob), this.mob, this.target);
    }
    return super.canContinueToUse(); // TargetGoal::canContinueToUse
}

Tamable mobs check the target condition in canContinueToUse, so they can stop attacking immediately when the turtle grows up.

Fix:

Override canContinueToUse in NearestAttackableTargetGoal

@Override
public boolean canContinueToUse() {
    if (this.targetConditions != null) {
        return this.targetConditions.test(getServerLevel(this.mob), this.mob, this.target);
    }
    return super.canContinueToUse();
}

 

Remove canContinueToUse in NonTameRandomTargetGoal

This is because player avoids to fall from block edge, but the checking method is wrong.

@Override
protected Vec3 maybeBackOffFromEdge(Vec3 var0, MoverType var1) {
    if (!this.abilities.flying && var0.y <= 0.0 && (var1 == MoverType.SELF || var1 == MoverType.PLAYER) && this.isStayingOnGroundSurface() && this.isAboveGround()) {
        double var2 = var0.x;
        double var3 = var0.z;
        double var4 = 0.05;
        while (var2 != 0.0 && this.level().noCollision(this, this.getBoundingBox().move(var2, -this.maxUpStep(), 0.0))) {
            if (var2 < 0.05 && var2 >= -0.05) {
                var2 = 0.0;
                continue;
            }
            if (var2 > 0.0) {
                var2 -= 0.05;
                continue;
            }
            var2 += 0.05;
        }
        while (var3 != 0.0 && this.level().noCollision(this, this.getBoundingBox().move(0.0, -this.maxUpStep(), var3))) {
            if (var3 < 0.05 && var3 >= -0.05) {
                var3 = 0.0;
                continue;
            }
            if (var3 > 0.0) {
                var3 -= 0.05;
                continue;
            }
            var3 += 0.05;
        }
        while (var2 != 0.0 && var3 != 0.0 && this.level().noCollision(this, this.getBoundingBox().move(var2, -this.maxUpStep(), var3))) {
            var2 = var2 < 0.05 && var2 >= -0.05 ? 0.0 : (var2 > 0.0 ? (var2 -= 0.05) : (var2 += 0.05));
            if (var3 < 0.05 && var3 >= -0.05) {
                var3 = 0.0;
                continue;
            }
            if (var3 > 0.0) {
                var3 -= 0.05;
                continue;
            }
            var3 += 0.05;
        }
        var0 = new Vec3(var2, var0.y, var3);
    }
    return var0;
}

It should search the collision from player's feet to its max step height, not just move the collision box to the max step height and check whether it collides.

This may be due to gamma.

This is because the player's own movement is calculated by the client, while the server is only responsible for checking and moving entities.

I can confirm that all versions after fixing MC-183786 in 20w21a parse "0" into 48, while all previous versions parse it into a random seed

Can confirmed in 20w51a and 1.16.4

This should be because the seed text box parses "0" into a string instead of a number. Because the hash code value of the string "0" is 48.