Added a runes particle

This commit is contained in:
Sollace 2021-03-03 20:03:16 +02:00
parent 269db7bdc9
commit 3bb4d36a7e
16 changed files with 2516 additions and 25 deletions

2330
runes.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 180 KiB

View file

@ -10,6 +10,7 @@ import com.minelittlepony.unicopia.client.particle.MagicParticle;
import com.minelittlepony.unicopia.client.particle.RainboomParticle; import com.minelittlepony.unicopia.client.particle.RainboomParticle;
import com.minelittlepony.unicopia.client.particle.RainbowTrailParticle; import com.minelittlepony.unicopia.client.particle.RainbowTrailParticle;
import com.minelittlepony.unicopia.client.particle.RaindropsParticle; 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.particle.SphereParticle;
import com.minelittlepony.unicopia.client.render.AccessoryFeatureRenderer; import com.minelittlepony.unicopia.client.render.AccessoryFeatureRenderer;
import com.minelittlepony.unicopia.client.render.AmuletFeatureRenderer; 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.HEALTH_DRAIN, createFactory(HealthDrainParticle::new));
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.SPHERE, SphereParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.SPHERE, SphereParticle::new);
ParticleFactoryRegistry.getInstance().register(UParticles.DISK, DiskParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.DISK, DiskParticle::new);
ParticleFactoryRegistry.getInstance().register(UParticles.GROUND_POUND, GroundPoundParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.GROUND_POUND, GroundPoundParticle::new);

View file

@ -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) { public AbstractBillboardParticle(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);
} }
@Override @Override
@ -36,7 +35,7 @@ public abstract class AbstractBillboardParticle extends Particle {
Tessellator te = Tessellator.getInstance(); Tessellator te = Tessellator.getInstance();
BufferBuilder buffer = te.getBuffer(); BufferBuilder buffer = te.getBuffer();
MinecraftClient.getInstance().getTextureManager().bindTexture(getTexture()); bindTexture(getTexture());
RenderSystem.disableCull(); RenderSystem.disableCull();
RenderSystem.enableBlend(); 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 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) { protected void renderQuad(Tessellator te, BufferBuilder buffer, Vector3f[] corners, float alpha, float tickDelta) {
int light = getColorMultiplier(tickDelta); int light = getColorMultiplier(tickDelta);

View file

@ -28,7 +28,7 @@ public class DiskParticle extends SphereParticle {
@Override @Override
public void buildGeometry(VertexConsumer vertexConsumer, Camera camera, float tickDelta) { public void buildGeometry(VertexConsumer vertexConsumer, Camera camera, float tickDelta) {
if (alpha <= 0) { if (colorAlpha <= 0) {
return; return;
} }
@ -36,7 +36,7 @@ public class DiskParticle extends SphereParticle {
VertexConsumerProvider.Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers(); VertexConsumerProvider.Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers();
model.setPosition(x, y, z); model.setPosition(x, y, z);
model.setRotation(rotX, rotY, rotZ); 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(); immediate.draw();
} }
} }

View file

@ -19,7 +19,7 @@ public abstract class OrientedBillboardParticle extends AbstractBillboardParticl
super(world, x, y, z, velocityX, velocityY, velocityZ); super(world, x, y, z, velocityX, velocityY, velocityZ);
fixed = effect.isAngleFixed(); fixed = effect.isAngleFixed();
if (!fixed) { if (fixed) {
rotation.hamiltonProduct(Vector3f.POSITIVE_X.getDegreesQuaternion(180 - effect.getYaw())); rotation.hamiltonProduct(Vector3f.POSITIVE_X.getDegreesQuaternion(180 - effect.getYaw()));
rotation.hamiltonProduct(Vector3f.POSITIVE_Y.getDegreesQuaternion(effect.getPitch())); rotation.hamiltonProduct(Vector3f.POSITIVE_Y.getDegreesQuaternion(effect.getPitch()));
} }
@ -27,7 +27,7 @@ public abstract class OrientedBillboardParticle extends AbstractBillboardParticl
@Override @Override
public void buildGeometry(VertexConsumer drawer, Camera camera, float tickDelta) { public void buildGeometry(VertexConsumer drawer, Camera camera, float tickDelta) {
if (fixed) { if (!fixed) {
rotation = camera.getRotation(); rotation = camera.getRotation();
} }
super.buildGeometry(drawer, camera, tickDelta); super.buildGeometry(drawer, camera, tickDelta);

View file

@ -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);
}
}

View file

@ -19,11 +19,6 @@ import com.minelittlepony.common.util.Color;
public class SphereParticle extends Particle implements Attachment { public class SphereParticle extends Particle implements Attachment {
protected float red;
protected float green;
protected float blue;
protected float alpha;
protected float prevRadius; protected float prevRadius;
protected float radius; protected float radius;
@ -47,10 +42,10 @@ public class SphereParticle extends Particle implements Attachment {
super(w, x, y, z); super(w, x, y, z);
this.radius = effect.getRadius(); this.radius = effect.getRadius();
this.red = effect.getRed()/255F; this.colorRed = effect.getRed()/255F;
this.green = effect.getGreen()/255F; this.colorGreen = effect.getGreen()/255F;
this.blue = effect.getBlue()/255F; this.colorBlue = effect.getBlue()/255F;
this.alpha = effect.getAlpha(); this.colorAlpha = effect.getAlpha();
setMaxAge(10); setMaxAge(10);
} }
@ -63,7 +58,7 @@ public class SphereParticle extends Particle implements Attachment {
@Override @Override
public void attach(Caster<?> caster) { public void attach(Caster<?> caster) {
setMaxAge(50000); setMaxAge(50000);
this.link.attach(caster); link.attach(caster);
} }
@Override @Override
@ -80,9 +75,9 @@ public class SphereParticle extends Particle implements Attachment {
} }
if (key == 1) { if (key == 1) {
int tint = (int)value; int tint = (int)value;
red = Color.r(tint); colorRed = Color.r(tint);
green = Color.g(tint); colorGreen = Color.g(tint);
blue = Color.b(tint); colorBlue = Color.b(tint);
} }
} }
@ -115,7 +110,7 @@ public class SphereParticle extends Particle implements Attachment {
@Override @Override
public void buildGeometry(VertexConsumer vertexConsumer, Camera camera, float tickDelta) { public void buildGeometry(VertexConsumer vertexConsumer, Camera camera, float tickDelta) {
if (alpha <= 0 || radius <= 0) { if (colorAlpha <= 0 || radius <= 0) {
return; return;
} }
@ -132,10 +127,10 @@ public class SphereParticle extends Particle implements Attachment {
float lerpedRad = MathHelper.lerp(tickDelta, prevRadius, radius); float lerpedRad = MathHelper.lerp(tickDelta, prevRadius, radius);
VertexConsumer buffer; VertexConsumer buffer;
buffer = immediate.getBuffer(RenderLayers.getTintedTexturedLayer(red, green, blue, alpha)); buffer = immediate.getBuffer(RenderLayers.getTintedTexturedLayer(colorRed, colorGreen, colorBlue, colorAlpha));
model.render(matrices, lerpedRad + 0.1F, buffer, 1, 1, red, green, blue, alpha); model.render(matrices, lerpedRad + 0.1F, buffer, 1, 1, colorRed, colorGreen, colorBlue, colorAlpha);
buffer = immediate.getBuffer(RenderLayers.getTintedTexturedLayer(red * 0.9F, green * 0.9F, blue * 0.9F, Math.min(1, alpha + 0.2F))); 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, red * 0.9F, green * 0.9F, blue * 0.9F, Math.min(1, alpha + 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(); immediate.draw();

View file

@ -30,13 +30,16 @@ public interface ParticleSource extends ParticleSpawner {
} }
default void spawnParticles(Shape area, int count, Consumer<Vec3d> particleSpawner) { default void spawnParticles(Shape area, int count, Consumer<Vec3d> particleSpawner) {
Vec3d pos = getOriginVector(); spawnParticles(getOriginVector(), area, count, particleSpawner);
}
default void spawnParticles(Vec3d pos, Shape area, int count, Consumer<Vec3d> particleSpawner) {
area.randomPoints(count, getWorld().random) area.randomPoints(count, getWorld().random)
.map(point -> point.add(pos)) .map(point -> point.add(pos))
.forEach(particleSpawner); .forEach(particleSpawner);
} }
@Override @Override
default void addParticle(ParticleEffect effect, Vec3d position, Vec3d velocity) { default void addParticle(ParticleEffect effect, Vec3d position, Vec3d velocity) {
getWorld().addParticle(effect, position.x, position.y, position.z, velocity.x, velocity.y, velocity.z); getWorld().addParticle(effect, position.x, position.y, position.z, velocity.x, velocity.y, velocity.z);

View file

@ -14,6 +14,8 @@ public interface UParticles {
ParticleType<OrientedBillboardParticleEffect> RAINBOOM_RING = register("rainboom_ring", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY)); ParticleType<OrientedBillboardParticleEffect> RAINBOOM_RING = register("rainboom_ring", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY));
DefaultParticleType RAINBOOM_TRAIL = register("rainboom_trail", FabricParticleTypes.simple()); DefaultParticleType RAINBOOM_TRAIL = register("rainboom_trail", FabricParticleTypes.simple());
ParticleType<OrientedBillboardParticleEffect> MAGIC_RUNES = register("magic_runes", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY));
DefaultParticleType RAIN_DROPS = register("rain_drops", FabricParticleTypes.simple()); DefaultParticleType RAIN_DROPS = register("rain_drops", FabricParticleTypes.simple());
ParticleType<SphereParticleEffect> SPHERE = register("sphere", FabricParticleTypes.complex(true, SphereParticleEffect.FACTORY)); ParticleType<SphereParticleEffect> SPHERE = register("sphere", FabricParticleTypes.complex(true, SphereParticleEffect.FACTORY));

View file

@ -0,0 +1,2 @@
{
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 785 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB