diff --git a/runes.svg b/runes.svg new file mode 100644 index 00000000..46af8d00 --- /dev/null +++ b/runes.svg @@ -0,0 +1,2330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index 89f8cab9..ceea0235 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -10,6 +10,7 @@ import com.minelittlepony.unicopia.client.particle.MagicParticle; import com.minelittlepony.unicopia.client.particle.RainboomParticle; import com.minelittlepony.unicopia.client.particle.RainbowTrailParticle; import com.minelittlepony.unicopia.client.particle.RaindropsParticle; +import com.minelittlepony.unicopia.client.particle.RunesParticle; import com.minelittlepony.unicopia.client.particle.SphereParticle; import com.minelittlepony.unicopia.client.render.AccessoryFeatureRenderer; import com.minelittlepony.unicopia.client.render.AmuletFeatureRenderer; @@ -48,6 +49,7 @@ public interface URenderers { ParticleFactoryRegistry.getInstance().register(UParticles.HEALTH_DRAIN, createFactory(HealthDrainParticle::new)); ParticleFactoryRegistry.getInstance().register(UParticles.RAINBOOM_RING, RainboomParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.RAINBOOM_TRAIL, RainbowTrailParticle::new); + ParticleFactoryRegistry.getInstance().register(UParticles.MAGIC_RUNES, RunesParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.SPHERE, SphereParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.DISK, DiskParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.GROUND_POUND, GroundPoundParticle::new); diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/AbstractBillboardParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/AbstractBillboardParticle.java index 070ff59c..ffee02b8 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/AbstractBillboardParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/AbstractBillboardParticle.java @@ -23,7 +23,6 @@ public abstract class AbstractBillboardParticle extends Particle { public AbstractBillboardParticle(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) { super(world, x, y, z, velocityX, velocityY, velocityZ); - } @Override @@ -36,7 +35,7 @@ public abstract class AbstractBillboardParticle extends Particle { Tessellator te = Tessellator.getInstance(); BufferBuilder buffer = te.getBuffer(); - MinecraftClient.getInstance().getTextureManager().bindTexture(getTexture()); + bindTexture(getTexture()); RenderSystem.disableCull(); RenderSystem.enableBlend(); @@ -62,6 +61,10 @@ public abstract class AbstractBillboardParticle extends Particle { protected abstract void renderQuads(Tessellator te, BufferBuilder buffer, float x, float y, float z, float tickDelta); + protected void bindTexture(Identifier texture) { + MinecraftClient.getInstance().getTextureManager().bindTexture(texture); + } + protected void renderQuad(Tessellator te, BufferBuilder buffer, Vector3f[] corners, float alpha, float tickDelta) { int light = getColorMultiplier(tickDelta); diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/DiskParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/DiskParticle.java index 516ea1b5..53711068 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/DiskParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/DiskParticle.java @@ -28,7 +28,7 @@ public class DiskParticle extends SphereParticle { @Override public void buildGeometry(VertexConsumer vertexConsumer, Camera camera, float tickDelta) { - if (alpha <= 0) { + if (colorAlpha <= 0) { return; } @@ -36,7 +36,7 @@ public class DiskParticle extends SphereParticle { VertexConsumerProvider.Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers(); model.setPosition(x, y, z); model.setRotation(rotX, rotY, rotZ); - model.render(matrices, radius, immediate.getBuffer(RenderLayer.getTranslucent()), 1, 1, red, green, blue, alpha); + model.render(matrices, radius, immediate.getBuffer(RenderLayer.getTranslucent()), 1, 1, colorRed, colorGreen, colorBlue, colorAlpha); immediate.draw(); } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/OrientedBillboardParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/OrientedBillboardParticle.java index 47df9584..1759b974 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/OrientedBillboardParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/OrientedBillboardParticle.java @@ -19,7 +19,7 @@ public abstract class OrientedBillboardParticle extends AbstractBillboardParticl super(world, x, y, z, velocityX, velocityY, velocityZ); fixed = effect.isAngleFixed(); - if (!fixed) { + if (fixed) { rotation.hamiltonProduct(Vector3f.POSITIVE_X.getDegreesQuaternion(180 - effect.getYaw())); rotation.hamiltonProduct(Vector3f.POSITIVE_Y.getDegreesQuaternion(effect.getPitch())); } @@ -27,7 +27,7 @@ public abstract class OrientedBillboardParticle extends AbstractBillboardParticl @Override public void buildGeometry(VertexConsumer drawer, Camera camera, float tickDelta) { - if (fixed) { + if (!fixed) { rotation = camera.getRotation(); } super.buildGeometry(drawer, camera, tickDelta); diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/RunesParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/RunesParticle.java new file mode 100644 index 00000000..d3e3b8a1 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/RunesParticle.java @@ -0,0 +1,154 @@ +package com.minelittlepony.unicopia.client.particle; + +import com.minelittlepony.common.util.Color; +import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect; +import com.minelittlepony.unicopia.particle.ParticleHandle.Attachment; +import com.minelittlepony.unicopia.particle.ParticleHandle.Link; +import com.mojang.blaze3d.systems.RenderSystem; + +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.util.math.Vector3f; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Quaternion; + +public class RunesParticle extends OrientedBillboardParticle implements Attachment { + + private static final Identifier[] TEXTURES = new Identifier[] { + new Identifier("unicopia", "textures/particles/runes_0.png"), + new Identifier("unicopia", "textures/particles/runes_1.png"), + new Identifier("unicopia", "textures/particles/runes_2.png"), + new Identifier("unicopia", "textures/particles/runes_3.png"), + new Identifier("unicopia", "textures/particles/runes_4.png"), + new Identifier("unicopia", "textures/particles/runes_5.png") + }; + + protected float prevBaseSize = 0; + protected float baseSize = 0; + + private float prevRotationAngle; + private float rotationAngle; + + private final Link link = new Link(); + + private int stasisAge = -1; + + public RunesParticle(OrientedBillboardParticleEffect effect, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) { + super(effect, world, x, y, z, velocityX, velocityY, velocityZ); + setMaxAge(70); + + colorRed = world.random.nextFloat(); + colorGreen = world.random.nextFloat(); + colorBlue = world.random.nextFloat(); + } + + @Override + public boolean isStillAlive() { + return age < (maxAge - 1); + } + + @Override + public void attach(Caster caster) { + link.attach(caster); + velocityX = 0; + velocityY = 0; + velocityZ = 0; + } + + @Override + public void detach() { + link.detach(); + } + + @Override + public void setAttribute(int key, Object value) { + if (key == 1) { + int tint = (int)value; + colorRed = Color.r(tint); + colorGreen = Color.g(tint); + colorBlue = Color.b(tint); + } + } + @Override + public float getScale(float tickDelta) { + return MathHelper.lerp(tickDelta, prevBaseSize, baseSize) * super.getScale(tickDelta); + } + + @Override + protected Identifier getTexture() { + return TEXTURES[0]; + } + + private float getAlphaScale() { + float transitionScale = age < maxAge / 2 ? 5 : 3; + return (float)Math.min(1, Math.sin(Math.PI * age / maxAge) * transitionScale); + } + + @Override + protected int getColorMultiplier(float tint) { + return 0xF000F0; + } + + @Override + protected void renderQuads(Tessellator te, BufferBuilder buffer, float x, float y, float z, float tickDelta) { + + float alpha = colorAlpha * getAlphaScale(); + + float angle = MathHelper.lerp(tickDelta, prevRotationAngle, rotationAngle); + + for (int i = 0; i < TEXTURES.length; i++) { + bindTexture(TEXTURES[i]); + + RenderSystem.color3f(colorRed, colorGreen, colorBlue); + + Vector3f[] corners = new Vector3f[]{ + new Vector3f(-1, -1, 0), + new Vector3f(-1, 1, 0), + new Vector3f( 1, 1, 0), + new Vector3f( 1, -1, 0) + }; + float scale = getScale(tickDelta); + + float ringSpeed = (i % 2 == 0 ? i : -1) * i; + + Quaternion ringAngle = Vector3f.POSITIVE_Z.getDegreesQuaternion(angle * ringSpeed); + + for(int k = 0; k < 4; ++k) { + Vector3f corner = corners[k]; + corner.rotate(ringAngle); + corner.rotate(rotation); + corner.scale(scale); + corner.add(x, y + 0.001F, z); + } + + renderQuad(te, buffer, corners, alpha, tickDelta); + } + } + + @Override + public void tick() { + super.tick(); + + if (link.linked()) { + link.ifAbsent(this::detach).map(Caster::getEntity).ifPresent(e -> { + if (getAlphaScale() >= 0.9F) { + if (stasisAge < 0) { + stasisAge = age; + } + age = stasisAge; + } + }); + } + + prevBaseSize = baseSize; + if (baseSize < 3) { + baseSize++; + } + + prevRotationAngle = rotationAngle; + rotationAngle = MathHelper.wrapDegrees(rotationAngle + 0.3F); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/SphereParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/SphereParticle.java index 4101c1cf..5e28746c 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/SphereParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/SphereParticle.java @@ -19,11 +19,6 @@ import com.minelittlepony.common.util.Color; public class SphereParticle extends Particle implements Attachment { - protected float red; - protected float green; - protected float blue; - protected float alpha; - protected float prevRadius; protected float radius; @@ -47,10 +42,10 @@ public class SphereParticle extends Particle implements Attachment { super(w, x, y, z); this.radius = effect.getRadius(); - this.red = effect.getRed()/255F; - this.green = effect.getGreen()/255F; - this.blue = effect.getBlue()/255F; - this.alpha = effect.getAlpha(); + this.colorRed = effect.getRed()/255F; + this.colorGreen = effect.getGreen()/255F; + this.colorBlue = effect.getBlue()/255F; + this.colorAlpha = effect.getAlpha(); setMaxAge(10); } @@ -63,7 +58,7 @@ public class SphereParticle extends Particle implements Attachment { @Override public void attach(Caster caster) { setMaxAge(50000); - this.link.attach(caster); + link.attach(caster); } @Override @@ -80,9 +75,9 @@ public class SphereParticle extends Particle implements Attachment { } if (key == 1) { int tint = (int)value; - red = Color.r(tint); - green = Color.g(tint); - blue = Color.b(tint); + colorRed = Color.r(tint); + colorGreen = Color.g(tint); + colorBlue = Color.b(tint); } } @@ -115,7 +110,7 @@ public class SphereParticle extends Particle implements Attachment { @Override public void buildGeometry(VertexConsumer vertexConsumer, Camera camera, float tickDelta) { - if (alpha <= 0 || radius <= 0) { + if (colorAlpha <= 0 || radius <= 0) { return; } @@ -132,10 +127,10 @@ public class SphereParticle extends Particle implements Attachment { float lerpedRad = MathHelper.lerp(tickDelta, prevRadius, radius); VertexConsumer buffer; - buffer = immediate.getBuffer(RenderLayers.getTintedTexturedLayer(red, green, blue, alpha)); - model.render(matrices, lerpedRad + 0.1F, buffer, 1, 1, red, green, blue, alpha); - buffer = immediate.getBuffer(RenderLayers.getTintedTexturedLayer(red * 0.9F, green * 0.9F, blue * 0.9F, Math.min(1, alpha + 0.2F))); - model.render(matrices, lerpedRad - 0.1F, buffer, 1, 1, red * 0.9F, green * 0.9F, blue * 0.9F, Math.min(1, alpha + 0.2F)); + buffer = immediate.getBuffer(RenderLayers.getTintedTexturedLayer(colorRed, colorGreen, colorBlue, colorAlpha)); + model.render(matrices, lerpedRad + 0.1F, buffer, 1, 1, colorRed, colorGreen, colorBlue, colorAlpha); + buffer = immediate.getBuffer(RenderLayers.getTintedTexturedLayer(colorRed * 0.9F, colorGreen * 0.9F, colorBlue * 0.9F, Math.min(1, colorAlpha + 0.2F))); + model.render(matrices, lerpedRad - 0.1F, buffer, 1, 1, colorRed * 0.9F, colorGreen * 0.9F, colorBlue * 0.9F, Math.min(1, colorAlpha + 0.2F)); immediate.draw(); diff --git a/src/main/java/com/minelittlepony/unicopia/particle/ParticleSource.java b/src/main/java/com/minelittlepony/unicopia/particle/ParticleSource.java index cb8e66f2..c0777fa8 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/ParticleSource.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/ParticleSource.java @@ -30,13 +30,16 @@ public interface ParticleSource extends ParticleSpawner { } default void spawnParticles(Shape area, int count, Consumer particleSpawner) { - Vec3d pos = getOriginVector(); + spawnParticles(getOriginVector(), area, count, particleSpawner); + } + default void spawnParticles(Vec3d pos, Shape area, int count, Consumer particleSpawner) { area.randomPoints(count, getWorld().random) .map(point -> point.add(pos)) .forEach(particleSpawner); } + @Override default void addParticle(ParticleEffect effect, Vec3d position, Vec3d velocity) { getWorld().addParticle(effect, position.x, position.y, position.z, velocity.x, velocity.y, velocity.z); diff --git a/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java b/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java index 36ceb97d..2af541f3 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java @@ -14,6 +14,8 @@ public interface UParticles { ParticleType RAINBOOM_RING = register("rainboom_ring", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY)); DefaultParticleType RAINBOOM_TRAIL = register("rainboom_trail", FabricParticleTypes.simple()); + ParticleType MAGIC_RUNES = register("magic_runes", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY)); + 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/magic_runes.json b/src/main/resources/assets/unicopia/particles/magic_runes.json new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/src/main/resources/assets/unicopia/particles/magic_runes.json @@ -0,0 +1,2 @@ +{ +} diff --git a/src/main/resources/assets/unicopia/textures/particles/runes_0.png b/src/main/resources/assets/unicopia/textures/particles/runes_0.png new file mode 100644 index 00000000..fb0c86bd Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/particles/runes_0.png differ diff --git a/src/main/resources/assets/unicopia/textures/particles/runes_1.png b/src/main/resources/assets/unicopia/textures/particles/runes_1.png new file mode 100644 index 00000000..a4884cb1 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/particles/runes_1.png differ diff --git a/src/main/resources/assets/unicopia/textures/particles/runes_2.png b/src/main/resources/assets/unicopia/textures/particles/runes_2.png new file mode 100644 index 00000000..5ca59885 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/particles/runes_2.png differ diff --git a/src/main/resources/assets/unicopia/textures/particles/runes_3.png b/src/main/resources/assets/unicopia/textures/particles/runes_3.png new file mode 100644 index 00000000..7eba7f67 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/particles/runes_3.png differ diff --git a/src/main/resources/assets/unicopia/textures/particles/runes_4.png b/src/main/resources/assets/unicopia/textures/particles/runes_4.png new file mode 100644 index 00000000..bfed4a45 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/particles/runes_4.png differ diff --git a/src/main/resources/assets/unicopia/textures/particles/runes_5.png b/src/main/resources/assets/unicopia/textures/particles/runes_5.png new file mode 100644 index 00000000..6cca072e Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/particles/runes_5.png differ