package net.minecraft.client.particle; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Camera; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.EntityRenderDispatcher; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.phys.Vec3; @Environment(EnvType.CLIENT) public class ItemPickupParticle extends Particle { private static final int LIFE_TIME = 3; private final Entity itemEntity; private final Entity target; private int life; private final EntityRenderDispatcher entityRenderDispatcher; private double targetX; private double targetY; private double targetZ; private double targetXOld; private double targetYOld; private double targetZOld; public ItemPickupParticle(EntityRenderDispatcher entityRenderDispatcher, ClientLevel level, Entity itemEntity, Entity target) { this(entityRenderDispatcher, level, itemEntity, target, itemEntity.getDeltaMovement()); } private ItemPickupParticle(EntityRenderDispatcher entityRenderDispatcher, ClientLevel level, Entity itemEntity, Entity target, Vec3 speed) { super(level, itemEntity.getX(), itemEntity.getY(), itemEntity.getZ(), speed.x, speed.y, speed.z); this.itemEntity = this.getSafeCopy(itemEntity); this.target = target; this.entityRenderDispatcher = entityRenderDispatcher; this.updatePosition(); this.saveOldPosition(); } private Entity getSafeCopy(Entity entity) { return (Entity)(!(entity instanceof ItemEntity) ? entity : ((ItemEntity)entity).copy()); } @Override public ParticleRenderType getRenderType() { return ParticleRenderType.CUSTOM; } @Override public void renderCustom(PoseStack poseStack, MultiBufferSource bufferSource, Camera camera, float partialTick) { float f = (this.life + partialTick) / 3.0F; f *= f; double d = Mth.lerp((double)partialTick, this.targetXOld, this.targetX); double e = Mth.lerp((double)partialTick, this.targetYOld, this.targetY); double g = Mth.lerp((double)partialTick, this.targetZOld, this.targetZ); double h = Mth.lerp((double)f, this.itemEntity.getX(), d); double i = Mth.lerp((double)f, this.itemEntity.getY(), e); double j = Mth.lerp((double)f, this.itemEntity.getZ(), g); Vec3 vec3 = camera.getPosition(); this.entityRenderDispatcher .render( this.itemEntity, h - vec3.x(), i - vec3.y(), j - vec3.z(), partialTick, new PoseStack(), bufferSource, this.entityRenderDispatcher.getPackedLightCoords(this.itemEntity, partialTick) ); } @Override public void render(VertexConsumer buffer, Camera camera, float partialTick) { } @Override public void tick() { this.life++; if (this.life == 3) { this.remove(); } this.saveOldPosition(); this.updatePosition(); } private void updatePosition() { this.targetX = this.target.getX(); this.targetY = (this.target.getY() + this.target.getEyeY()) / 2.0; this.targetZ = this.target.getZ(); } private void saveOldPosition() { this.targetXOld = this.targetX; this.targetYOld = this.targetY; this.targetZOld = this.targetZ; } }