diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index 0505ee2a..5edbad0f 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -4,6 +4,7 @@ import com.minelittlepony.unicopia.UEntities; import com.minelittlepony.unicopia.client.particle.ChangelingMagicParticle; import com.minelittlepony.unicopia.client.particle.DiskParticle; import com.minelittlepony.unicopia.client.particle.MagicParticle; +import com.minelittlepony.unicopia.client.particle.RainboomParticle; import com.minelittlepony.unicopia.client.particle.RaindropsParticle; import com.minelittlepony.unicopia.client.particle.SphereParticle; import com.minelittlepony.unicopia.particle.UParticles; @@ -22,6 +23,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.RAINBOOM_RING, RainboomParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.SPHERE, SphereParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.DISK, DiskParticle::new); diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/RainboomParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/RainboomParticle.java new file mode 100644 index 00000000..1902da88 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/RainboomParticle.java @@ -0,0 +1,123 @@ +package com.minelittlepony.unicopia.client.particle; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleTextureSheet; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.Camera; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.math.Vector3f; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.particle.DefaultParticleType; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Quaternion; +import net.minecraft.util.math.Vec3d; + +public class RainboomParticle extends Particle { + + private static final Identifier TEXTURE = new Identifier("unicopia", "textures/particles/rainboom_ring.png"); + + protected float prevBaseSize = 0; + protected float baseSize = 0; + protected float scale = 1; + + protected Quaternion rotation; + + public RainboomParticle(DefaultParticleType effect, ClientWorld world, double x, double y, double z, double angleX, double angleY, double angleZ) { + super(world, x, y, z); + + rotation = Vector3f.POSITIVE_X.getRadialQuaternion((float)angleX); + rotation.hamiltonProduct(Vector3f.POSITIVE_Y.getRadialQuaternion((float)angleY)); + rotation.hamiltonProduct(Vector3f.POSITIVE_Z.getRadialQuaternion((float)angleZ)); + setMaxAge(40); + } + + @Override + public ParticleTextureSheet getType() { + return ParticleTextureSheet.CUSTOM; + } + + @Override + public void buildGeometry(VertexConsumer drawer, Camera camera, float tickDelta) { + Vec3d cam = camera.getPos(); + + float renderX = (float)(MathHelper.lerp(tickDelta, prevPosX, x) - cam.getX()); + float renderY = (float)(MathHelper.lerp(tickDelta, prevPosY, y) - cam.getY()); + float renderZ = (float)(MathHelper.lerp(tickDelta, prevPosZ, z) - cam.getZ()); + + Vector3f[] corners = new Vector3f[]{ + new Vector3f(-1.0F, -1.0F, 0.0F), + new Vector3f(-1.0F, 1.0F, 0.0F), + new Vector3f(1.0F, 1.0F, 0.0F), + new Vector3f(1.0F, -1.0F, 0.0F) + }; + float scale = getSize(tickDelta); + + for(int k = 0; k < 4; ++k) { + Vector3f corner = corners[k]; + corner.rotate(rotation); + corner.scale(scale); + corner.add(renderX, renderY, renderZ); + } + + float alpha = colorAlpha * (1 - ((float)age / maxAge)); + + int light = getColorMultiplier(tickDelta); + + Tessellator te = Tessellator.getInstance(); + BufferBuilder buffer = te.getBuffer(); + + MinecraftClient.getInstance().getTextureManager().bindTexture(TEXTURE); + + RenderSystem.disableCull(); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate( + GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA, + GlStateManager.SrcFactor.ONE, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA + ); + RenderSystem.alphaFunc(516, 0.003921569F); + + buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT); + buffer.vertex(corners[0].getX(), corners[0].getY(), corners[0].getZ()).texture(0, 0).color(colorRed, colorGreen, colorBlue, alpha).light(light).next(); + buffer.vertex(corners[1].getX(), corners[1].getY(), corners[1].getZ()).texture(1, 0).color(colorRed, colorGreen, colorBlue, alpha).light(light).next(); + buffer.vertex(corners[2].getX(), corners[2].getY(), corners[2].getZ()).texture(0, 0).color(colorRed, colorGreen, colorBlue, alpha).light(light).next(); + buffer.vertex(corners[3].getX(), corners[3].getY(), corners[3].getZ()).texture(0, 1).color(colorRed, colorGreen, colorBlue, alpha).light(light).next(); + + te.draw(); + + RenderSystem.enableCull(); + RenderSystem.defaultAlphaFunc(); + RenderSystem.defaultBlendFunc(); + } + + public float getSize(float tickDelta) { + return MathHelper.lerp(tickDelta, prevBaseSize, baseSize) * scale; + } + + @Override + public Particle scale(float scale) { + this.scale = scale; + return super.scale(scale); + } + + @Override + public void tick() { + super.tick(); + + prevBaseSize = baseSize; + baseSize++; + + if (this.age == 1) { + this.world.playSound(x, y, z, SoundEvents.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.AMBIENT, 5, 0.3F, true); + this.world.playSound(x, y, z, SoundEvents.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.AMBIENT, 10, 1.3F, true); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java b/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java index 62411bd4..fb0633d2 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java @@ -11,6 +11,8 @@ public interface UParticles { ParticleType UNICORN_MAGIC = register("unicorn_magic", FabricParticleTypes.complex(MagicParticleEffect.UNICORN_FACTORY)); DefaultParticleType CHANGELING_MAGIC = register("changeling_magic", FabricParticleTypes.simple()); + DefaultParticleType RAINBOOM_RING = register("rainboom_ring", FabricParticleTypes.simple()); + DefaultParticleType RAIN_DROPS = register("rain_drops", FabricParticleTypes.simple()); ParticleType SPHERE = register("sphere", FabricParticleTypes.complex(true, SphereParticleEffect.FACTORY)); diff --git a/src/main/resources/assets/unicopia/particles/rainboom_ring.json b/src/main/resources/assets/unicopia/particles/rainboom_ring.json new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/src/main/resources/assets/unicopia/particles/rainboom_ring.json @@ -0,0 +1,2 @@ +{ +} diff --git a/src/main/resources/assets/unicopia/textures/particles/rainboom_ring.png b/src/main/resources/assets/unicopia/textures/particles/rainboom_ring.png new file mode 100644 index 00000000..874d6bca Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/particles/rainboom_ring.png differ