|  | 
| 44 | 44 | 
 | 
| 45 | 45 | import java.lang.ref.WeakReference; | 
| 46 | 46 | import java.util.List; | 
| 47 |  | -import java.util.Optional; | 
| 48 | 47 | import java.util.UUID; | 
| 49 | 48 | import java.util.function.Function; | 
| 50 | 49 | import java.util.function.Predicate; | 
| @@ -92,7 +91,6 @@ public boolean canAttack(@NotNull LivingEntity livingEntity) { | 
| 92 | 91 |     public void openTextEdit(@NotNull SignBlockEntity sign) { | 
| 93 | 92 |     } | 
| 94 | 93 | 
 | 
| 95 |  | - | 
| 96 | 94 |     @Override | 
| 97 | 95 |     public boolean isSilent() { | 
| 98 | 96 |         return true; | 
| @@ -318,46 +316,59 @@ public HitResult findHit(boolean skipEntity, boolean skipBlock, @Nullable Predic | 
| 318 | 316 |         if (skipEntity) | 
| 319 | 317 |             return blockHit; | 
| 320 | 318 | 
 | 
| 321 |  | -        List<Entity> entities = level.getEntities(this, getBoundingBox().expandTowards(look.x * range, look.y * range, look.z * range).inflate(1, 1, 1), collidablePredicate); | 
|  | 319 | +        List<Entity> entities = level.getEntities(this, getBoundingBox().expandTowards(look.x * range, look.y * range, look.z * range).inflate(1), collidablePredicate); | 
| 322 | 320 | 
 | 
| 323 | 321 |         LivingEntity closestEntity = null; | 
| 324 | 322 |         Vec3 closestVec = null; | 
| 325 |  | -        double closestDistance = range; | 
|  | 323 | +        double closestDistance = blockHit.getType() == HitResult.Type.MISS ? range * range : distanceToSqr(blockHit.getLocation()); | 
| 326 | 324 |         for (Entity entityHit : entities) { | 
| 327 |  | -            if (!(entityHit instanceof LivingEntity) || entityFilter != null && !entityFilter.test(entityHit)) | 
|  | 325 | +            if (!(entityHit instanceof LivingEntity entity)) { | 
|  | 326 | +                continue; | 
|  | 327 | +            } | 
|  | 328 | +            // TODO: maybe let entityFilter returns the priority of the entity, instead of only returns the closest one. | 
|  | 329 | +            if (entityFilter != null && !entityFilter.test(entity)) { | 
|  | 330 | +                continue; | 
|  | 331 | +            } | 
|  | 332 | + | 
|  | 333 | +            // Removed a lot logic here to make Automata cores interact like a player. | 
|  | 334 | +            // However, the results for some edge cases may change. Need more review and tests. | 
|  | 335 | + | 
|  | 336 | +            // Hit vehicle before passenger | 
|  | 337 | +            if (entity.isPassenger()) { | 
| 328 | 338 |                 continue; | 
| 329 |  | -            // Add litter bigger that just pick radius | 
| 330 |  | -            AABB box = entityHit.getBoundingBox().inflate(entityHit.getPickRadius() + 0.5); | 
| 331 |  | -            Optional<Vec3> clipResult = box.clip(origin, target); | 
|  | 339 | +            } | 
| 332 | 340 | 
 | 
|  | 341 | +            AABB box = entity.getBoundingBox(); | 
|  | 342 | +            Vec3 clipVec; | 
| 333 | 343 |             if (box.contains(origin)) { | 
| 334 |  | -                if (closestDistance >= 0.0D) { | 
| 335 |  | -                    closestEntity = (LivingEntity) entityHit; | 
| 336 |  | -                    closestVec = clipResult.orElse(origin); | 
| 337 |  | -                    closestDistance = 0.0D; | 
|  | 344 | +                clipVec = origin; | 
|  | 345 | +            } else { | 
|  | 346 | +                clipVec = box.clip(origin, target).orElse(null); | 
|  | 347 | +                if (clipVec == null) { | 
|  | 348 | +                    continue; | 
| 338 | 349 |                 } | 
| 339 |  | -            } else if (clipResult.isPresent()) { | 
| 340 |  | -                Vec3 clipVec = clipResult.get(); | 
| 341 |  | -                double distance = origin.distanceTo(clipVec); | 
| 342 |  | - | 
| 343 |  | -                if (distance < closestDistance || closestDistance == 0.0D) { | 
| 344 |  | -                    if (entityHit == entityHit.getRootVehicle() && !entityHit.canRiderInteract()) { | 
| 345 |  | -                        if (closestDistance == 0.0D) { | 
| 346 |  | -                            closestEntity = (LivingEntity) entityHit; | 
| 347 |  | -                            closestVec = clipVec; | 
| 348 |  | -                        } | 
| 349 |  | -                    } else { | 
| 350 |  | -                        closestEntity = (LivingEntity) entityHit; | 
| 351 |  | -                        closestVec = clipVec; | 
| 352 |  | -                        closestDistance = distance; | 
| 353 |  | -                    } | 
|  | 350 | +            } | 
|  | 351 | +            double distance = origin.distanceToSqr(clipVec); | 
|  | 352 | +            // Ignore small enough distance | 
|  | 353 | +            if (distance <= 1e-6) { | 
|  | 354 | +                distance = 0; | 
|  | 355 | +            } | 
|  | 356 | +            if (distance > closestDistance) { | 
|  | 357 | +                continue; | 
|  | 358 | +            } | 
|  | 359 | +            if (distance == closestDistance && closestEntity != null) { | 
|  | 360 | +                // Hit larger entity before smaller | 
|  | 361 | +                if (closestEntity.getBoundingBox().getSize() >= box.getSize()) { | 
|  | 362 | +                    continue; | 
| 354 | 363 |                 } | 
| 355 | 364 |             } | 
|  | 365 | +            closestEntity = entity; | 
|  | 366 | +            closestVec = clipVec; | 
|  | 367 | +            closestDistance = distance; | 
| 356 | 368 |         } | 
| 357 |  | -        if (closestEntity != null && closestDistance <= range && (blockHit.getType() == HitResult.Type.MISS || distanceToSqr(blockHit.getLocation()) > closestDistance * closestDistance)) { | 
|  | 369 | +        if (closestEntity != null) { | 
| 358 | 370 |             return new EntityHitResult(closestEntity, closestVec); | 
| 359 |  | -        } else { | 
| 360 |  | -            return blockHit; | 
| 361 | 371 |         } | 
|  | 372 | +        return blockHit; | 
| 362 | 373 |     } | 
| 363 | 374 | } | 
0 commit comments