package net.minecraft.world.entity.projectile; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.level.Level; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; public abstract class ThrowableProjectile extends Projectile { protected ThrowableProjectile(EntityType entityType, Level level) { super(entityType, level); } protected ThrowableProjectile(EntityType entityType, double x, double y, double z, Level level) { this(entityType, level); this.setPos(x, y, z); } protected ThrowableProjectile(EntityType entityType, LivingEntity shooter, Level level) { this(entityType, shooter.getX(), shooter.getEyeY() - 0.1F, shooter.getZ(), level); this.setOwner(shooter); } @Override public boolean shouldRenderAtSqrDistance(double distance) { double d = this.getBoundingBox().getSize() * 4.0; if (Double.isNaN(d)) { d = 4.0; } d *= 64.0; return distance < d * d; } @Override public boolean canUsePortal(boolean allowPassengers) { return true; } @Override public void tick() { super.tick(); HitResult hitResult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); if (hitResult.getType() != HitResult.Type.MISS) { this.hitTargetOrDeflectSelf(hitResult); } this.checkInsideBlocks(); Vec3 vec3 = this.getDeltaMovement(); double d = this.getX() + vec3.x; double e = this.getY() + vec3.y; double f = this.getZ() + vec3.z; this.updateRotation(); float h; if (this.isInWater()) { for (int i = 0; i < 4; i++) { float g = 0.25F; this.level().addParticle(ParticleTypes.BUBBLE, d - vec3.x * 0.25, e - vec3.y * 0.25, f - vec3.z * 0.25, vec3.x, vec3.y, vec3.z); } h = 0.8F; } else { h = 0.99F; } this.setDeltaMovement(vec3.scale(h)); this.applyGravity(); this.setPos(d, e, f); } @Override protected double getDefaultGravity() { return 0.03; } }