Implement a renderer for the back hole

This commit is contained in:
Sollace 2024-01-21 18:06:53 +00:00
parent e09ade57b1
commit 9510b83c72
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
9 changed files with 133 additions and 35 deletions

View file

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

View file

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

View file

@ -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

View file

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

View file

@ -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<PlaceableSpell> {
@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();

View file

@ -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<ShieldSpell> {
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;

View file

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

View file

@ -37,6 +37,7 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster<CastS
public CastSpellEntity(EntityType<?> type, World world) {
super(type, world);
ignoreCameraFrustum = true;
}
@Override

View file

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