mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-01 11:36:43 +01:00
Added general particle effects that follow a point of entity
This commit is contained in:
parent
7ad82f0bb2
commit
56af8f80ba
5 changed files with 146 additions and 5 deletions
|
@ -51,7 +51,7 @@ public interface URenderers {
|
|||
ParticleFactoryRegistry.getInstance().register(UParticles.UNICORN_MAGIC, createFactory(MagicParticle::new));
|
||||
ParticleFactoryRegistry.getInstance().register(UParticles.CHANGELING_MAGIC, createFactory(ChangelingMagicParticle::new));
|
||||
ParticleFactoryRegistry.getInstance().register(UParticles.RAIN_DROPS, createFactory(RaindropsParticle::new));
|
||||
ParticleFactoryRegistry.getInstance().register(UParticles.HEALTH_DRAIN, createFactory(HealthDrainParticle::new));
|
||||
ParticleFactoryRegistry.getInstance().register(UParticles.HEALTH_DRAIN, createFactory(HealthDrainParticle::create));
|
||||
ParticleFactoryRegistry.getInstance().register(UParticles.RAINBOOM_RING, RainboomParticle::new);
|
||||
ParticleFactoryRegistry.getInstance().register(UParticles.RAINBOOM_TRAIL, RainbowTrailParticle::new);
|
||||
ParticleFactoryRegistry.getInstance().register(UParticles.MAGIC_RUNES, RunesParticle::new);
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package com.minelittlepony.unicopia.client.particle;
|
||||
|
||||
import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.particle.NoRenderParticle;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.SpriteProvider;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class FollowingParticle extends NoRenderParticle {
|
||||
|
||||
private final FollowingParticleEffect parameters;
|
||||
|
||||
private final Particle particle;
|
||||
|
||||
private float scale;
|
||||
|
||||
public FollowingParticle(FollowingParticleEffect parameters, SpriteProvider provider, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
|
||||
super(world, x, y, z, velocityX, velocityY, velocityZ);
|
||||
this.scale = 0.1f * (this.random.nextFloat() * 0.5f + 0.5f) * 2.0f;
|
||||
setMaxAge(3);
|
||||
scale(0.125F);
|
||||
this.parameters = parameters;
|
||||
this.collidesWithWorld = false;
|
||||
this.particle = parameters.getChildEffect().map(child -> MinecraftClient.getInstance().particleManager.addParticle(child, x, y, z, velocityX, velocityY, velocityZ)).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Particle scale(float scale) {
|
||||
this.scale *= scale;
|
||||
super.scale(scale);
|
||||
if (particle != null) {
|
||||
particle.scale(scale);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(double dx, double dy, double dz) {
|
||||
super.move(dx, dy, dz);
|
||||
if (particle != null) {
|
||||
particle.setPos(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (this.particle == null || !this.particle.isAlive()) {
|
||||
markDead();
|
||||
}
|
||||
|
||||
super.tick();
|
||||
|
||||
Vec3d target = parameters.getTarget(world);
|
||||
Vec3d pos = new Vec3d(x, y, z);
|
||||
|
||||
if (scale * 1.5F < 0.5F) {
|
||||
scale(1.5F);
|
||||
}
|
||||
|
||||
double distance = pos.distanceTo(target);
|
||||
if (distance > 1) {
|
||||
age = 0;
|
||||
}
|
||||
|
||||
Vec3d motion = target.subtract(pos).normalize().multiply(Math.min(distance, parameters.getSpeed()));
|
||||
move(motion.x, motion.y, motion.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ", Speed " + parameters.getSpeed() + ", Target (" + parameters.getTargetDescriptor() + ") Sub-Particle (" + particle + ")";
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.client.particle;
|
|||
|
||||
import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
|
||||
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.ParticleTextureSheet;
|
||||
import net.minecraft.client.particle.SpriteBillboardParticle;
|
||||
import net.minecraft.client.particle.SpriteProvider;
|
||||
|
@ -12,7 +13,14 @@ public class HealthDrainParticle extends SpriteBillboardParticle {
|
|||
|
||||
private final FollowingParticleEffect effect;
|
||||
|
||||
public HealthDrainParticle(FollowingParticleEffect effect, SpriteProvider provider, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
|
||||
public static Particle create(FollowingParticleEffect effect, SpriteProvider provider, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
|
||||
if (effect.getChildEffect().isPresent()) {
|
||||
return new FollowingParticle(effect, provider, world, x, y, z, velocityX, velocityY, velocityZ);
|
||||
}
|
||||
return new HealthDrainParticle(effect, provider, world, x, y, z, velocityX, velocityY, velocityZ);
|
||||
}
|
||||
|
||||
protected HealthDrainParticle(FollowingParticleEffect effect, SpriteProvider provider, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
|
||||
super(world, x, y, z, velocityX, velocityY, velocityZ);
|
||||
setSprite(provider);
|
||||
setMaxAge(3);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.minelittlepony.unicopia.particle;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
@ -25,12 +26,23 @@ public class FollowingParticleEffect implements ParticleEffect {
|
|||
|
||||
private final float followSpeed;
|
||||
|
||||
private Optional<ParticleEffect> childEffect = Optional.empty();
|
||||
|
||||
protected FollowingParticleEffect(ParticleType<FollowingParticleEffect> type, StringReader reader) throws CommandSyntaxException {
|
||||
this(type, -1, ParticleFactoryHelper.readVector(reader), ParticleFactoryHelper.readFloat(reader));
|
||||
|
||||
if (reader.canRead()) {
|
||||
reader.expect(' ');
|
||||
childEffect = ParticleFactoryHelper.read(reader);
|
||||
}
|
||||
}
|
||||
|
||||
protected FollowingParticleEffect(ParticleType<FollowingParticleEffect> particleType, PacketByteBuf buf) {
|
||||
this(particleType, buf.readInt(), new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()), buf.readFloat());
|
||||
protected FollowingParticleEffect(ParticleType<FollowingParticleEffect> type, PacketByteBuf buf) {
|
||||
this(type, buf.readInt(), new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()), buf.readFloat());
|
||||
|
||||
if (buf.readBoolean()) {
|
||||
childEffect = ParticleFactoryHelper.read(Registry.PARTICLE_TYPE.get(buf.readInt()), buf);
|
||||
}
|
||||
}
|
||||
|
||||
public FollowingParticleEffect(ParticleType<FollowingParticleEffect> type, Vec3d target, float followSpeed) {
|
||||
|
@ -51,6 +63,22 @@ public class FollowingParticleEffect implements ParticleEffect {
|
|||
this.followSpeed = followSpeed;
|
||||
}
|
||||
|
||||
public ParticleEffect withChild(ParticleEffect child) {
|
||||
childEffect = Optional.of(child);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Optional<ParticleEffect> getChildEffect() {
|
||||
return childEffect;
|
||||
}
|
||||
|
||||
public String getTargetDescriptor() {
|
||||
if (movingTarget > -1) {
|
||||
return "Moving(" + movingTarget + ")";
|
||||
}
|
||||
return fixedTarget.toString();
|
||||
}
|
||||
|
||||
public Vec3d getTarget(World world) {
|
||||
if (movingTarget > -1) {
|
||||
Entity e = world.getEntityById(movingTarget);
|
||||
|
@ -79,10 +107,26 @@ public class FollowingParticleEffect implements ParticleEffect {
|
|||
buf.writeDouble(fixedTarget.y);
|
||||
buf.writeDouble(fixedTarget.z);
|
||||
buf.writeFloat(followSpeed);
|
||||
getChildEffect().ifPresentOrElse(child -> {
|
||||
buf.writeBoolean(true);
|
||||
buf.writeInt(Registry.PARTICLE_TYPE.getRawId(child.getType()));
|
||||
child.write(buf);
|
||||
}, () -> buf.writeBoolean(false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asString() {
|
||||
return String.format(Locale.ROOT, "%s %.2f %.2f %.2f %.2f", Registry.PARTICLE_TYPE.getId(getType()), fixedTarget.x, fixedTarget.y, fixedTarget.z, followSpeed);
|
||||
return getChildEffect().map(child -> {
|
||||
return String.format(Locale.ROOT, "%s %.2f %.2f %.2f %.2f %s",
|
||||
Registry.PARTICLE_TYPE.getId(getType()),
|
||||
fixedTarget.x, fixedTarget.y, fixedTarget.z,
|
||||
followSpeed, child.asString());
|
||||
}).orElseGet(() -> {
|
||||
return String.format(Locale.ROOT, "%s %.2f %.2f %.2f %.2f",
|
||||
Registry.PARTICLE_TYPE.getId(getType()),
|
||||
fixedTarget.x, fixedTarget.y, fixedTarget.z,
|
||||
followSpeed);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package com.minelittlepony.unicopia.particle;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
||||
import net.minecraft.command.argument.ParticleEffectArgumentType;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.particle.ParticleEffect;
|
||||
import net.minecraft.particle.ParticleType;
|
||||
|
@ -10,6 +13,16 @@ import net.minecraft.util.math.Vec3d;
|
|||
|
||||
public interface ParticleFactoryHelper {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static <T extends ParticleEffect> Optional<T> read(StringReader reader) throws CommandSyntaxException {
|
||||
return Optional.ofNullable((T)ParticleEffectArgumentType.readParameters(reader));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
static <T extends ParticleEffect> Optional<ParticleEffect> read(ParticleType<T> type, PacketByteBuf buf) {
|
||||
return Optional.ofNullable(type.getParametersFactory().read(type, buf));
|
||||
}
|
||||
|
||||
static Vec3d readVector(StringReader reader) throws CommandSyntaxException {
|
||||
return new Vec3d(readDouble(reader), readDouble(reader), readDouble(reader));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue