From 9510b83c72f7e2ff21ad025ad0547739f7d3f6af Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 21 Jan 2024 18:06:53 +0000 Subject: [PATCH] Implement a renderer for the back hole --- .../ability/magic/spell/PlaceableSpell.java | 10 +- .../magic/spell/effect/AttractiveSpell.java | 6 +- .../magic/spell/effect/DarkVortexSpell.java | 38 +++---- .../render/spell/DarkVortexSpellRenderer.java | 99 +++++++++++++++++++ .../render/spell/PlacedSpellRenderer.java | 5 + .../render/spell/ShieldSpellRenderer.java | 5 - .../spell/SpellEffectsRenderDispatcher.java | 2 + .../unicopia/entity/mob/CastSpellEntity.java | 1 + .../unicopia/entity/player/PlayerCamera.java | 2 + 9 files changed, 133 insertions(+), 35 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/client/render/spell/DarkVortexSpellRenderer.java diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java index 98095393..bba345b4 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java @@ -106,11 +106,11 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS setDead(); return false; } - } else { - prevAge = age; - if (age < 25) { - age++; - } + } + + prevAge = age; + if (age < 25) { + age++; } return super.tick(source, Situation.GROUND); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractiveSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractiveSpell.java index d91970b2..a28dc8ee 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractiveSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractiveSpell.java @@ -7,7 +7,6 @@ import com.minelittlepony.unicopia.entity.EntityReference; import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.damage.UDamageTypes; import com.minelittlepony.unicopia.particle.FollowingParticleEffect; -import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; import com.minelittlepony.unicopia.projectile.ProjectileDelegate; @@ -16,6 +15,7 @@ import com.minelittlepony.unicopia.util.shape.Sphere; import net.minecraft.entity.Entity; import net.minecraft.entity.ItemEntity; import net.minecraft.nbt.NbtCompound; +import net.minecraft.particle.ParticleTypes; import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -60,12 +60,12 @@ public class AttractiveSpell extends ShieldSpell implements HomingSpell, TimedSp @Override public void generateParticles(Caster source) { - double range = getDrawDropOffRange(source) + 10; + double range = getDrawDropOffRange(source); source.spawnParticles(getOrigin(source), new Sphere(false, range), 7, p -> { source.addParticle( new FollowingParticleEffect(UParticles.HEALTH_DRAIN, source.asEntity(), 0.4F) - .withChild(new MagicParticleEffect(getType().getColor())), + .withChild(ParticleTypes.AMBIENT_ENTITY_EFFECT), p, Vec3d.ZERO ); 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 0cea87e2..edf3b732 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 @@ -11,9 +11,10 @@ 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.damage.UDamageTypes; +import com.minelittlepony.unicopia.particle.FollowingParticleEffect; import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; -import com.minelittlepony.unicopia.particle.ParticleHandle; import com.minelittlepony.unicopia.particle.ParticleUtils; +import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; import com.minelittlepony.unicopia.projectile.ProjectileDelegate; import com.minelittlepony.unicopia.util.shape.Sphere; @@ -49,9 +50,6 @@ 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); } @@ -114,21 +112,17 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega public void generateParticles(Caster source) { super.generateParticles(source); - /*float radius = (float)getEventHorizonRadius(); - - particlEffect.update(getUuid(), source, spawner -> { - spawner.addParticle(new SphereParticleEffect(UParticles.SPHERE, 0x000000, 0.99F, radius, SPHERE_OFFSET), source.getOriginVector(), Vec3d.ZERO); - }).ifPresent(p -> { - p.setAttribute(Attachment.ATTR_RADIUS, radius); - p.setAttribute(Attachment.ATTR_OPACITY, 2F); - }); - particlEffect.update(getUuid(), "_ring", source, spawner -> { - spawner.addParticle(new SphereParticleEffect(UParticles.DISK, 0xAAAAAA, 0.4F, radius + 1, SPHERE_OFFSET), getOrigin(source), Vec3d.ZERO); - }).ifPresent(p -> { - p.setAttribute(Attachment.ATTR_RADIUS, radius * 0F); - });*/ - - source.spawnParticles(ParticleTypes.SMOKE, 3); + if (getEventHorizonRadius() > 3) { + double range = getDrawDropOffRange(source); + source.spawnParticles(getOrigin(source), new Sphere(false, range), 17, p -> { + source.addParticle( + new FollowingParticleEffect(UParticles.HEALTH_DRAIN, source.asEntity(), 0.4F) + .withChild(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE), + p, + Vec3d.ZERO + ); + }); + } } @Override @@ -178,7 +172,7 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega // 3. force reaches 0 at distance of drawDropOffRange public double getEventHorizonRadius() { - return Math.sqrt(Math.max(0.001, getMass() - 12)); + return Math.sqrt(Math.max(0.001, getMass() / 3F)); } private double getAttractiveForce(Caster source, Entity target) { @@ -186,8 +180,8 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega } private double getMass() { - float pulse = (float)Math.sin(age * 8) / 1F; - return 10 + Math.min(15, Math.min(0.5F + pulse, (float)Math.exp(age) / 8F - 90) + accumulatedMass / 10F) + pulse; + float pulse = (float)Math.sin(age * 8) / 160F; + return Math.min(15, Math.min(0.5F, (float)Math.exp(age) / 8F - 90) + accumulatedMass / 10F) + pulse; } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/spell/DarkVortexSpellRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/spell/DarkVortexSpellRenderer.java new file mode 100644 index 00000000..98b32575 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/render/spell/DarkVortexSpellRenderer.java @@ -0,0 +1,99 @@ +package com.minelittlepony.unicopia.client.render.spell; + +import org.joml.Vector3f; +import org.joml.Vector4f; + +import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.spell.effect.DarkVortexSpell; +import com.minelittlepony.unicopia.client.render.RenderLayers; +import com.minelittlepony.unicopia.client.render.RenderUtil; +import com.minelittlepony.unicopia.client.render.model.SphereModel; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.Entity; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RotationAxis; + +public class DarkVortexSpellRenderer implements SpellRenderer { + + private static float cameraDistortion; + + public static float getCameraDistortion() { + cameraDistortion *= 0.9F; + cameraDistortion = MathHelper.clamp(cameraDistortion, 0, 80); + System.out.println(cameraDistortion); + return cameraDistortion; + } + + @Override + public void render(MatrixStack matrices, VertexConsumerProvider vertices, DarkVortexSpell 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 + 2, 0); + + Entity cameraEntity = MinecraftClient.getInstance().getCameraEntity(); + + float radius = (float)spell.getEventHorizonRadius(); + float absDistance = (float)cameraEntity.getEyePos().distanceTo(caster.getOriginVector().add(0, 2, 0)); + + SphereModel.SPHERE.render(matrices, vertices.getBuffer(RenderLayers.getSolid()), light, 1, Math.min(radius, absDistance / 2F), 0, 0, 0, 1); + + matrices.push(); + + + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(90)); + matrices.multiply(RotationAxis.NEGATIVE_X.rotationDegrees(90 + cameraEntity.getYaw(tickDelta))); + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-cameraEntity.getPitch(tickDelta))); + matrices.scale(0.7F, 1, 1); + + + float distance = 1F / MathHelper.clamp((absDistance / (radius * 4)), 0.0000001F, 1); + distance *= distance; + if (absDistance < radius * 4) { + cameraDistortion += distance; + } + + matrices.scale(distance, distance, distance); + + matrices.push(); + for (int i = 0; i < 10; i++) { + matrices.scale(0.96F, 1, 1); + float brightness = i / 10F; + SphereModel.DISK.render(matrices, vertices.getBuffer(RenderLayers.getMagicNoColor()), light, 1, radius * (1 + (0.25F * i)), brightness, brightness, brightness, 0.2F); + } + matrices.pop(); + + SphereModel.DISK.render(matrices, vertices.getBuffer(RenderLayers.getEndPortal()), light, 1, radius * 0.5F, 1, 0.5F, 0, 1); + + matrices.pop(); + + if (radius > 1 && absDistance > radius) { + radius *= 1.1F; + + matrices.scale(radius, radius, radius); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(animationProgress)); + matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(45)); + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(animationProgress * 168)); + + + RenderUtil.Vertex[] CORNERS = new RenderUtil.Vertex[]{ + new RenderUtil.Vertex(new Vector3f(-1, -1, 0), 0, 0), + new RenderUtil.Vertex(new Vector3f(-1, 1, 0), 1, 0), + new RenderUtil.Vertex(new Vector3f( 1, 1, 0), 1, 1), + new RenderUtil.Vertex(new Vector3f( 1, -1, 0), 0, 1) + }; + + VertexConsumer buffer = vertices.getBuffer(RenderLayer.getEntityTranslucent(new Identifier("textures/misc/forcefield.png"))); + + for (var corner : CORNERS) { + Vector4f pos = corner.position(matrices); + buffer.vertex(pos.x, pos.y, pos.z, 1, 1, 1, 1, corner.u(), corner.v(), 0, light, 1, 1, 1); + } + } + matrices.pop(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/spell/PlacedSpellRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/spell/PlacedSpellRenderer.java index 78789761..142b11ac 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/spell/PlacedSpellRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/spell/PlacedSpellRenderer.java @@ -9,6 +9,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.spell.PlaceableSpell; import com.minelittlepony.unicopia.ability.magic.spell.Spell; import com.minelittlepony.unicopia.client.render.RenderUtil; +import com.minelittlepony.unicopia.entity.mob.CastSpellEntity; import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumer; @@ -36,6 +37,10 @@ public class PlacedSpellRenderer implements SpellRenderer { @Override public void render(MatrixStack matrices, VertexConsumerProvider vertices, PlaceableSpell spell, Caster caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { + if (!(caster.asEntity() instanceof CastSpellEntity)) { + return; + } + for (Spell delegate : spell.getDelegates()) { matrices.push(); 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 index 347a66ba..55844dd9 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/spell/ShieldSpellRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/spell/ShieldSpellRenderer.java @@ -7,10 +7,8 @@ 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; @@ -21,9 +19,6 @@ public class ShieldSpellRenderer implements SpellRenderer { 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; 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 e911a81a..9de95849 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 @@ -46,6 +46,7 @@ public class SpellEffectsRenderDispatcher implements SynchronousResourceReloader static { register(SpellType.PLACED_SPELL, PlacedSpellRenderer::new); register(SpellType.SHIELD, ShieldSpellRenderer::new); + register(SpellType.DARK_VORTEX, DarkVortexSpellRenderer::new); } @Nullable @@ -67,6 +68,7 @@ public class SpellEffectsRenderDispatcher implements SynchronousResourceReloader public void render(MatrixStack matrices, VertexConsumerProvider vertices, Spell spell, Caster caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { var renderer = getRenderer(spell); if (renderer != null) { + MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers().draw(); renderer.render(matrices, vertices, spell, caster, light, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch); } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/CastSpellEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/CastSpellEntity.java index df9c7e37..16a4100b 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/CastSpellEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/CastSpellEntity.java @@ -37,6 +37,7 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster type, World world) { super(type, world); + ignoreCameraFrustum = true; } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java index 11b71c2e..2a2a8449 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java @@ -5,6 +5,7 @@ import java.util.Optional; import com.minelittlepony.common.util.animation.MotionCompositor; import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell; +import com.minelittlepony.unicopia.client.render.spell.DarkVortexSpellRenderer; import net.minecraft.util.math.Vec3d; @@ -62,6 +63,7 @@ public class PlayerCamera extends MotionCompositor { public double calculateFieldOfView(double fov) { fov += player.getMagicalReserves().getExertion().get() / 5F; fov += getEnergyAddition(); + fov += DarkVortexSpellRenderer.getCameraDistortion(); return fov; }