120 lines
4.4 KiB
Java
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);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|