nerovapes/src/main/java/ru/neroduckale/particles/Particles.java
2024-06-24 23:09:09 +05:00

120 lines
4.4 KiB
Java

package ru.neroduckale.particles;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.*;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.particle.DefaultParticleType;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import java.util.List;
@Environment(EnvType.CLIENT)
public class Particles extends SpriteBillboardParticle {
private final SpriteProvider spriteProvider;
private static final double MAX_SQUARED_COLLISION_CHECK_DISTANCE = MathHelper.square((double)100.0);
private boolean stopped;
float randomX = -0.03f + random.nextFloat() * (0.03f - -0.03f);
float randomZ = -0.03f + random.nextFloat() * (0.03f - -0.03f);
protected Particles(ClientWorld clientWorld, double x, double y, double z, double velX, double velY, double velZ, SpriteProvider spriteProvider) {
super(clientWorld, x, y, z);
this.spriteProvider = spriteProvider; //Sets the sprite provider from above to the sprite provider in the constructor parameters
this.maxAge = 50; //50 ticks = 2.5 seconds
this.scale = 0.5f;
this.velocityX = velX; //The velX from the constructor parameters
this.velocityY = velY;
this.velocityZ = velZ;
this.x = x; //The x from the constructor parameters
this.y = y;
this.z = z;
this.collidesWithWorld = true;
this.alpha = 1.0f; //Setting the alpha to 1.0f means there will be no opacity change until the alpha value is changed
this.setSpriteForAge(spriteProvider); //Required
}
@Override
public ParticleTextureSheet getType() {
return ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT;
}
public void tick() {
this.prevPosX = this.x;
this.prevPosY = this.y;
this.prevPosZ = this.z;
if (this.age++ >= this.maxAge || this.scale <= 0 || this.alpha <= 0) { //Despawns the particle if the age has reached the max age, or if the scale is 0, or if the alpha is 0
this.markDead();
return;
}
this.move(this.velocityX, this.velocityY, this.velocityZ);
if (this.age >= (this.maxAge / 3)) {
this.alpha -= 0.02f;
this.velocityX = randomX;
this.velocityZ = randomZ;
this.velocityY += 0.005f;
}
if (this.age >= (this.maxAge / 3) * 2) {
this.scale -= 0.02f;
}
if (this.onGround) {
this.velocityZ = 0;
this.velocityX = 0;
this.velocityY = 0.1f;
}
}
@Override
public void move(double dx, double dy, double dz) {
if (this.stopped) {
return;
}
double d = dx;
double e = dy;
double f = dz;
if (this.collidesWithWorld && (dx != 0.0 || dy != 0.0 || dz != 0.0) && dx * dx + dy * dy + dz * dz < MAX_SQUARED_COLLISION_CHECK_DISTANCE) {
Vec3d vec3d = Entity.adjustMovementForCollisions(null, new Vec3d(dx, dy, dz), this.getBoundingBox(), this.world, List.of());
dx = vec3d.x;
dy = vec3d.y;
dz = vec3d.z;
}
if (dx != 0.0 || dy != 0.0 || dz != 0.0) {
this.setBoundingBox(this.getBoundingBox().offset(dx, dy, dz));
this.repositionFromBoundingBox();
}
if (Math.abs(e) >= (double)1.0E-5f && Math.abs(dy) < (double)1.0E-5f) {
this.stopped = true;
}
boolean bl = this.onGround = e != dy && e < 0.0;
if (d != dx) {
this.velocityX = 0.0;
this.velocityY = 0.1f;
this.velocityZ = 0.0;
}
if (f != dz) {
this.velocityY = 0.1f;
this.velocityZ = 0.0;
this.velocityX = 0.0;
}
}
@Environment(EnvType.CLIENT)
public static class Factory implements ParticleFactory<DefaultParticleType> {
//The factory used in a particle's registry
private final SpriteProvider spriteProvider;
public Factory(SpriteProvider spriteProvider) {
this.spriteProvider = spriteProvider;
}
public Particle createParticle(DefaultParticleType defaultParticleType, ClientWorld clientWorld, double x, double y, double z, double velX, double velY, double velZ) {
return new Particles(clientWorld, x, y, z, velX, velY, velZ, this.spriteProvider);
}
}
}