package net.minecraft.client.particle; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.particles.ItemParticleOption; import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.SimpleParticleType; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; @Environment(EnvType.CLIENT) public class BreakingItemParticle extends TextureSheetParticle { private final float uo; private final float vo; BreakingItemParticle(ClientLevel level, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed, ItemStackRenderState renderState) { this(level, x, y, z, renderState); this.xd *= 0.1F; this.yd *= 0.1F; this.zd *= 0.1F; this.xd += xSpeed; this.yd += ySpeed; this.zd += zSpeed; } @Override public ParticleRenderType getRenderType() { return ParticleRenderType.TERRAIN_SHEET; } protected BreakingItemParticle(ClientLevel level, double x, double y, double z, ItemStackRenderState renderState) { super(level, x, y, z, 0.0, 0.0, 0.0); TextureAtlasSprite textureAtlasSprite = renderState.pickParticleIcon(this.random); if (textureAtlasSprite != null) { this.setSprite(textureAtlasSprite); } else { this.setSprite((TextureAtlasSprite)Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(MissingTextureAtlasSprite.getLocation())); } this.gravity = 1.0F; this.quadSize /= 2.0F; this.uo = this.random.nextFloat() * 3.0F; this.vo = this.random.nextFloat() * 3.0F; } @Override protected float getU0() { return this.sprite.getU((this.uo + 1.0F) / 4.0F); } @Override protected float getU1() { return this.sprite.getU(this.uo / 4.0F); } @Override protected float getV0() { return this.sprite.getV(this.vo / 4.0F); } @Override protected float getV1() { return this.sprite.getV((this.vo + 1.0F) / 4.0F); } @Environment(EnvType.CLIENT) public static class CobwebProvider extends BreakingItemParticle.ItemParticleProvider { public Particle createParticle(SimpleParticleType simpleParticleType, ClientLevel clientLevel, double d, double e, double f, double g, double h, double i) { return new BreakingItemParticle(clientLevel, d, e, f, this.calculateState(new ItemStack(Items.COBWEB), clientLevel)); } } @Environment(EnvType.CLIENT) public abstract static class ItemParticleProvider implements ParticleProvider { private final ItemStackRenderState scratchRenderState = new ItemStackRenderState(); protected ItemStackRenderState calculateState(ItemStack stack, ClientLevel level) { Minecraft.getInstance().getItemModelResolver().updateForTopItem(this.scratchRenderState, stack, ItemDisplayContext.GROUND, level, null, 0); return this.scratchRenderState; } } @Environment(EnvType.CLIENT) public static class Provider extends BreakingItemParticle.ItemParticleProvider { public Particle createParticle(ItemParticleOption type, ClientLevel level, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { return new BreakingItemParticle(level, x, y, z, xSpeed, ySpeed, zSpeed, this.calculateState(type.getItem(), level)); } } @Environment(EnvType.CLIENT) public static class SlimeProvider extends BreakingItemParticle.ItemParticleProvider { public Particle createParticle(SimpleParticleType type, ClientLevel level, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { return new BreakingItemParticle(level, x, y, z, this.calculateState(new ItemStack(Items.SLIME_BALL), level)); } } @Environment(EnvType.CLIENT) public static class SnowballProvider extends BreakingItemParticle.ItemParticleProvider { public Particle createParticle(SimpleParticleType type, ClientLevel level, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { return new BreakingItemParticle(level, x, y, z, this.calculateState(new ItemStack(Items.SNOWBALL), level)); } } }