diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DarkVortexSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DarkVortexSpell.java index 4e50d13e..740a2a21 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DarkVortexSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DarkVortexSpell.java @@ -13,6 +13,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; import com.minelittlepony.unicopia.entity.damage.UDamageTypes; import com.minelittlepony.unicopia.particle.ParticleHandle.Attachment; import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; +import com.minelittlepony.unicopia.particle.ParticleHandle; import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.particle.SphereParticleEffect; import com.minelittlepony.unicopia.particle.UParticles; @@ -51,6 +52,9 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega private int age = 0; private float accumulatedMass = 0; + @Deprecated + protected final ParticleHandle particlEffect = new ParticleHandle(); + protected DarkVortexSpell(CustomisedSpellType<?> type) { super(type); } @@ -109,6 +113,11 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega return EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.test(entity) && getAttractiveForce(source, entity) > 0; } + @Override + protected void onDestroyed(Caster<?> caster) { + particlEffect.destroy(); + } + @Override public void generateParticles(Caster<?> source) { super.generateParticles(source); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java index 71f5cede..023da1c7 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java @@ -1,5 +1,7 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect; +import java.util.Optional; + import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.Unicopia; @@ -10,11 +12,9 @@ import com.minelittlepony.unicopia.ability.magic.spell.Spell; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.minelittlepony.unicopia.particle.MagicParticleEffect; -import com.minelittlepony.unicopia.particle.ParticleHandle; -import com.minelittlepony.unicopia.particle.SphereParticleEffect; -import com.minelittlepony.unicopia.particle.UParticles; -import com.minelittlepony.unicopia.particle.ParticleHandle.Attachment; +import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.projectile.ProjectileUtil; import com.minelittlepony.unicopia.util.shape.Sphere; @@ -30,6 +30,7 @@ import net.minecraft.entity.passive.PassiveEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.vehicle.AbstractMinecartEntity; import net.minecraft.entity.vehicle.BoatEntity; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; public class ShieldSpell extends AbstractSpell { @@ -40,10 +41,14 @@ public class ShieldSpell extends AbstractSpell { .with(Trait.AIR, 9) .build(); - protected final ParticleHandle particlEffect = new ParticleHandle(); - private final TargetSelecter targetSelecter = new TargetSelecter(this); + private float prevRadius; + private float radius; + + private float rangeMultiplier; + private float targetRangeMultiplier; + protected ShieldSpell(CustomisedSpellType<?> type) { super(type); } @@ -53,33 +58,27 @@ public class ShieldSpell extends AbstractSpell { return method == CastingMethod.STAFF || getTraits().get(Trait.GENEROSITY) > 0 ? toPlaceable() : this; } - @Override - protected void onDestroyed(Caster<?> caster) { - particlEffect.destroy(); - } - @Override public Affinity getAffinity() { return getTraits().get(Trait.DARKNESS) > 0 ? Affinity.BAD : Affinity.GOOD; } protected void generateParticles(Caster<?> source) { - float radius = (float)getDrawDropOffRange(source); Vec3d origin = getOrigin(source); source.spawnParticles(origin, new Sphere(true, radius), (int)(radius * 6), pos -> { source.addParticle(new MagicParticleEffect(getType().getColor()), pos, Vec3d.ZERO); - }); - particlEffect.update(getUuid(), source, spawner -> { - spawner.addParticle(new SphereParticleEffect(UParticles.SPHERE, getType().getColor(), 0.3F, radius), origin, Vec3d.ZERO); - }).ifPresent(p -> { - p.setAttribute(Attachment.ATTR_RADIUS, radius); + if (source.asWorld().random.nextInt(10) == 0 && source.asWorld().random.nextFloat() < source.getCorruption().getScaled(1)) { + ParticleUtils.spawnParticle(source.asWorld(), new LightningBoltParticleEffect(true, 3, 2, 0.1F, Optional.empty()), pos, Vec3d.ZERO); + } }); } @Override public boolean tick(Caster<?> source, Situation situation) { + prevRadius = radius; + radius = (float)getDrawDropOffRange(source); if (source.isClient()) { generateParticles(source); @@ -108,20 +107,32 @@ public class ShieldSpell extends AbstractSpell { cost *= costMultiplier / ((1 + source.getLevel().get()) * 3F); cost /= knowledge; - cost += getDrawDropOffRange(source) / 10F; + cost += radius / 10F; if (!source.subtractEnergyCost(cost)) { setDead(); } } + public float getRadius(float tickDelta) { + return MathHelper.lerp(tickDelta, prevRadius, radius); + } + /** * Calculates the maximum radius of the shield. aka The area of effect. */ public double getDrawDropOffRange(Caster<?> source) { - float multiplier = source instanceof Pony pony && pony.asEntity().isSneaking() ? 1 : 2; + targetRangeMultiplier = source instanceof Pony pony && pony.asEntity().isSneaking() ? 1 : 2; + if (rangeMultiplier < targetRangeMultiplier - 0.1F) { + rangeMultiplier += 0.1F; + } else if (rangeMultiplier > targetRangeMultiplier + 0.1) { + rangeMultiplier -= 0.1F; + } else { + rangeMultiplier = targetRangeMultiplier; + } + float min = (source instanceof Pony ? 4 : 6) + getTraits().get(Trait.POWER); - double range = (min + (source.getLevel().getScaled(source instanceof Pony ? 4 : 40) * (source instanceof Pony ? 2 : 10))) / multiplier; + double range = (min + (source.getLevel().getScaled(source instanceof Pony ? 4 : 40) * (source instanceof Pony ? 2 : 10))) / rangeMultiplier; return range; } @@ -150,7 +161,7 @@ public class ShieldSpell extends AbstractSpell { } protected long applyEntities(Caster<?> source) { - double radius = getDrawDropOffRange(source); + double radius = this.radius; Vec3d origin = getOrigin(source); diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/MagicParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/MagicParticle.java index 700963a6..fd40922f 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/MagicParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/MagicParticle.java @@ -22,9 +22,9 @@ public class MagicParticle extends SpriteBillboardParticle { velocityX = vX; velocityY = vY; velocityZ = vZ; - startX = x + random.nextGaussian()/3; - startY = y + random.nextGaussian()/3; - startZ = z + random.nextGaussian()/3; + startX = x;// + random.nextGaussian()/3; + startY = y;// + random.nextGaussian()/3; + startZ = z;// + random.nextGaussian()/3; scale = random.nextFloat() * 0.12F; maxAge = (int)(Math.random() * 10) + 20; diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/RenderLayers.java b/src/main/java/com/minelittlepony/unicopia/client/render/RenderLayers.java index 80eeefd4..5f58b7b1 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/RenderLayers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/RenderLayers.java @@ -72,7 +72,15 @@ public final class RenderLayers extends RenderLayer { } public static RenderLayer getMagicNoColor() { - return MAGIC_NO_COLOR; + //return MAGIC_NO_COLOR; + return of("magic_no_color", VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL, + VertexFormat.DrawMode.QUADS, 256, true, true, MultiPhaseParameters.builder() + .program(COLOR_PROGRAM) + .transparency(TRANSLUCENT_TRANSPARENCY) + .target(TRANSLUCENT_TARGET) + .cull(DISABLE_CULLING) + .writeMaskState(COLOR_MASK) + .build(false)); } public static RenderLayer getMagicColored() { diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/model/BakedModel.java b/src/main/java/com/minelittlepony/unicopia/client/render/model/BakedModel.java index f868ff04..694571c3 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/model/BakedModel.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/model/BakedModel.java @@ -3,38 +3,37 @@ package com.minelittlepony.unicopia.client.render.model; import java.util.ArrayList; import java.util.List; -import org.joml.Matrix4f; +import org.joml.Vector3f; import org.joml.Vector4f; +import com.minelittlepony.unicopia.client.render.RenderUtil; + import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.util.math.MatrixStack; public class BakedModel { - private static final Vector4f drawVert = new Vector4f(); - - protected final List<Vertex> vertices = new ArrayList<>(); + protected final List<RenderUtil.Vertex> vertices = new ArrayList<>(); protected void addVertex(Vector4f vertex) { addVertex(vertex.x, vertex.y, vertex.z, 0, 0); } protected void addVertex(float x, float y, float z, float u, float v) { - vertices.add(new Vertex(x, y, z, u, v)); + vertices.add(new RenderUtil.Vertex(new Vector3f(x, y, z), u, v)); } - public final void render(MatrixStack matrices, VertexConsumer vertexWriter, int light, int overlay, float scale, float r, float g, float b, float a) { + public final void render(MatrixStack matrices, VertexConsumer buffer, int light, int overlay, float scale, float r, float g, float b, float a) { scale = Math.abs(scale); if (scale < 0.001F) { return; } - Matrix4f model = matrices.peek().getPositionMatrix(); - for (Vertex vertex : vertices) { - drawVert.set(vertex.x() * scale, vertex.y() * scale, vertex.z() * scale, 1); - drawVert.mul(model); - vertexWriter.vertex(drawVert.x, drawVert.y, drawVert.z, r, g, b, a, vertex.u(), vertex.v(), overlay, light, 0, 0, 0); + matrices.push(); + matrices.scale(scale, scale, scale); + for (RenderUtil.Vertex vertex : vertices) { + Vector4f pos = vertex.position(matrices); + buffer.vertex(pos.x, pos.y, pos.z, r, g, b, a, vertex.u(), vertex.v(), overlay, light, 0, 0, 0); } + matrices.pop(); } - - record Vertex(float x, float y, float z, float u, float v) {} } diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/spell/ShieldSpellRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/spell/ShieldSpellRenderer.java new file mode 100644 index 00000000..45731fd0 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/render/spell/ShieldSpellRenderer.java @@ -0,0 +1,41 @@ +package com.minelittlepony.unicopia.client.render.spell; + +import com.minelittlepony.common.util.Color; +import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.spell.effect.ShieldSpell; +import com.minelittlepony.unicopia.client.render.RenderLayers; +import com.minelittlepony.unicopia.client.render.model.SphereModel; +import com.minelittlepony.unicopia.util.ColorHelper; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.VertexConsumerProvider.Immediate; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.MathHelper; + +public class ShieldSpellRenderer implements SpellRenderer<ShieldSpell> { + @Override + public void render(MatrixStack matrices, VertexConsumerProvider vertices, ShieldSpell spell, Caster<?> caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { + matrices.push(); + double height = caster.asEntity().getEyeY() - caster.getOriginVector().y; + matrices.translate(0, height, 0); + + Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers(); + immediate.draw(); + + int color = ColorHelper.lerp(caster.getCorruption().getScaled(1) * (tickDelta / (1 + caster.asWorld().random.nextFloat())), spell.getType().getColor(), 0xFF000); + float[] colors = ColorHelper.changeSaturation(Color.r(color), Color.g(color), Color.b(color), 4); + float radius = 0.35F + spell.getRadius(tickDelta) + MathHelper.sin(animationProgress / 30F) * 0.01F; + + VertexConsumer buffer = vertices.getBuffer(RenderLayers.getMagicNoColor()); + + float thickness = 0.02F * MathHelper.sin(animationProgress / 30F); + float alpha = 1 - Math.abs(MathHelper.sin(animationProgress / 20F)) * 0.2F; + SphereModel.SPHERE.render(matrices, buffer, light, 1, radius + thickness, colors[0], colors[1], colors[2], alpha * 0.08F); + SphereModel.SPHERE.render(matrices, buffer, light, 1, radius - thickness, colors[0], colors[1], colors[2], alpha * 0.05F); + SphereModel.SPHERE.render(matrices, buffer, light, 1, radius + thickness * 2, colors[0], colors[1], colors[2], alpha * 0.05F); + + matrices.pop(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/spell/SpellEffectsRenderDispatcher.java b/src/main/java/com/minelittlepony/unicopia/client/render/spell/SpellEffectsRenderDispatcher.java index f44aad5f..692a8e89 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/spell/SpellEffectsRenderDispatcher.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/spell/SpellEffectsRenderDispatcher.java @@ -45,6 +45,7 @@ public class SpellEffectsRenderDispatcher implements SynchronousResourceReloader static { register(SpellType.PLACED_SPELL, PlacedSpellRenderer::new); + register(SpellType.SHIELD, ShieldSpellRenderer::new); } @Nullable