mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-01 19:46:42 +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.UNICORN_MAGIC, createFactory(MagicParticle::new));
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.CHANGELING_MAGIC, createFactory(ChangelingMagicParticle::new));
|
ParticleFactoryRegistry.getInstance().register(UParticles.CHANGELING_MAGIC, createFactory(ChangelingMagicParticle::new));
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.RAIN_DROPS, createFactory(RaindropsParticle::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_RING, RainboomParticle::new);
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.RAINBOOM_TRAIL, RainbowTrailParticle::new);
|
ParticleFactoryRegistry.getInstance().register(UParticles.RAINBOOM_TRAIL, RainbowTrailParticle::new);
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.MAGIC_RUNES, RunesParticle::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 com.minelittlepony.unicopia.particle.FollowingParticleEffect;
|
||||||
|
|
||||||
|
import net.minecraft.client.particle.Particle;
|
||||||
import net.minecraft.client.particle.ParticleTextureSheet;
|
import net.minecraft.client.particle.ParticleTextureSheet;
|
||||||
import net.minecraft.client.particle.SpriteBillboardParticle;
|
import net.minecraft.client.particle.SpriteBillboardParticle;
|
||||||
import net.minecraft.client.particle.SpriteProvider;
|
import net.minecraft.client.particle.SpriteProvider;
|
||||||
|
@ -12,7 +13,14 @@ public class HealthDrainParticle extends SpriteBillboardParticle {
|
||||||
|
|
||||||
private final FollowingParticleEffect effect;
|
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);
|
super(world, x, y, z, velocityX, velocityY, velocityZ);
|
||||||
setSprite(provider);
|
setSprite(provider);
|
||||||
setMaxAge(3);
|
setMaxAge(3);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.minelittlepony.unicopia.particle;
|
package com.minelittlepony.unicopia.particle;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.mojang.brigadier.StringReader;
|
import com.mojang.brigadier.StringReader;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
@ -25,12 +26,23 @@ public class FollowingParticleEffect implements ParticleEffect {
|
||||||
|
|
||||||
private final float followSpeed;
|
private final float followSpeed;
|
||||||
|
|
||||||
|
private Optional<ParticleEffect> childEffect = Optional.empty();
|
||||||
|
|
||||||
protected FollowingParticleEffect(ParticleType<FollowingParticleEffect> type, StringReader reader) throws CommandSyntaxException {
|
protected FollowingParticleEffect(ParticleType<FollowingParticleEffect> type, StringReader reader) throws CommandSyntaxException {
|
||||||
this(type, -1, ParticleFactoryHelper.readVector(reader), ParticleFactoryHelper.readFloat(reader));
|
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) {
|
protected FollowingParticleEffect(ParticleType<FollowingParticleEffect> type, PacketByteBuf buf) {
|
||||||
this(particleType, buf.readInt(), new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()), buf.readFloat());
|
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) {
|
public FollowingParticleEffect(ParticleType<FollowingParticleEffect> type, Vec3d target, float followSpeed) {
|
||||||
|
@ -51,6 +63,22 @@ public class FollowingParticleEffect implements ParticleEffect {
|
||||||
this.followSpeed = followSpeed;
|
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) {
|
public Vec3d getTarget(World world) {
|
||||||
if (movingTarget > -1) {
|
if (movingTarget > -1) {
|
||||||
Entity e = world.getEntityById(movingTarget);
|
Entity e = world.getEntityById(movingTarget);
|
||||||
|
@ -79,10 +107,26 @@ public class FollowingParticleEffect implements ParticleEffect {
|
||||||
buf.writeDouble(fixedTarget.y);
|
buf.writeDouble(fixedTarget.y);
|
||||||
buf.writeDouble(fixedTarget.z);
|
buf.writeDouble(fixedTarget.z);
|
||||||
buf.writeFloat(followSpeed);
|
buf.writeFloat(followSpeed);
|
||||||
|
getChildEffect().ifPresentOrElse(child -> {
|
||||||
|
buf.writeBoolean(true);
|
||||||
|
buf.writeInt(Registry.PARTICLE_TYPE.getRawId(child.getType()));
|
||||||
|
child.write(buf);
|
||||||
|
}, () -> buf.writeBoolean(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String asString() {
|
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;
|
package com.minelittlepony.unicopia.particle;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.mojang.brigadier.StringReader;
|
import com.mojang.brigadier.StringReader;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
|
||||||
|
import net.minecraft.command.argument.ParticleEffectArgumentType;
|
||||||
import net.minecraft.network.PacketByteBuf;
|
import net.minecraft.network.PacketByteBuf;
|
||||||
import net.minecraft.particle.ParticleEffect;
|
import net.minecraft.particle.ParticleEffect;
|
||||||
import net.minecraft.particle.ParticleType;
|
import net.minecraft.particle.ParticleType;
|
||||||
|
@ -10,6 +13,16 @@ import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public interface ParticleFactoryHelper {
|
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 {
|
static Vec3d readVector(StringReader reader) throws CommandSyntaxException {
|
||||||
return new Vec3d(readDouble(reader), readDouble(reader), readDouble(reader));
|
return new Vec3d(readDouble(reader), readDouble(reader), readDouble(reader));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue