Tweak dark vortex rendering and fix its behaviour

This commit is contained in:
Sollace 2024-01-22 15:47:58 +00:00
parent 34aa3b8ced
commit 225c67d558
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
6 changed files with 76 additions and 36 deletions

View file

@ -10,6 +10,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.Situation;
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.Living;
import com.minelittlepony.unicopia.entity.damage.UDamageTypes;
import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
@ -47,7 +48,6 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
private static final Vec3d SPHERE_OFFSET = new Vec3d(0, 2, 0);
private int age = 0;
private float accumulatedMass = 0;
protected DarkVortexSpell(CustomisedSpellType<?> type) {
@ -79,7 +79,7 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
return true;
}
if (++age % 20 == 0) {
if (source.asEntity().age % 20 == 0) {
source.asWorld().playSound(null, source.getOrigin(), USounds.AMBIENT_DARK_VORTEX_ADDITIONS, SoundCategory.AMBIENT, 1, 1);
}
@ -112,16 +112,18 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
public void generateParticles(Caster<?> source) {
super.generateParticles(source);
if (getEventHorizonRadius() > 3) {
if (getEventHorizonRadius() > 0.3) {
double range = getDrawDropOffRange(source);
Vec3d origin = getOrigin(source);
source.spawnParticles(origin, new Sphere(false, range), 17, p -> {
source.addParticle(
new FollowingParticleEffect(UParticles.HEALTH_DRAIN, origin, 0.4F)
.withChild(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE),
p,
Vec3d.ZERO
);
source.spawnParticles(origin, new Sphere(false, range), 1, p -> {
if (!source.asWorld().isAir(BlockPos.ofFloored(p))) {
source.addParticle(
new FollowingParticleEffect(UParticles.HEALTH_DRAIN, origin, 0.4F)
.withChild(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE),
p,
Vec3d.ZERO
);
}
});
}
}
@ -181,8 +183,7 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
}
private double getMass() {
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;
return Math.min(15, 0.1F + accumulatedMass / 10F);
}
@Override
@ -194,6 +195,11 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
if (distance <= getEventHorizonRadius() + 0.5) {
target.setVelocity(target.getVelocity().multiply(distance / (2 * radius)));
if (distance < 1) {
target.setVelocity(target.getVelocity().multiply(distance));
}
Living.updateVelocity(target);
@Nullable
Entity master = source.getMaster();
@ -213,7 +219,7 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
double massOfTarget = AttractionUtils.getMass(target);
if (massOfTarget != 0) {
if (!source.isClient() && massOfTarget != 0) {
accumulatedMass += massOfTarget;
setDirty();
}
@ -223,6 +229,9 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
target.discard();
source.asWorld().playSound(null, source.getOrigin(), USounds.ENCHANTMENT_CONSUMPTION_CONSUME, SoundCategory.AMBIENT, 2, 0.02F);
}
if (target.isAlive()) {
target.damage(source.asEntity().getDamageSources().outOfWorld(), Integer.MAX_VALUE);
}
source.subtractEnergyCost(-massOfTarget * 10);
source.asWorld().playSound(null, source.getOrigin(), USounds.AMBIENT_DARK_VORTEX_MOOD, SoundCategory.AMBIENT, 2, 0.02F);
@ -238,14 +247,12 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
@Override
public void toNBT(NbtCompound compound) {
super.toNBT(compound);
compound.putInt("age", age);
compound.putFloat("accumulatedMass", accumulatedMass);
}
@Override
public void fromNBT(NbtCompound compound) {
super.fromNBT(compound);
age = compound.getInt("age");
accumulatedMass = compound.getFloat("accumulatedMass");
}
}

View file

@ -10,7 +10,6 @@ import java.util.stream.Stream;
import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.ability.magic.Affine;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
@ -29,7 +28,7 @@ public class TargetSelecter {
public Stream<Entity> getEntities(Caster<?> source, double radius, BiPredicate<Caster<?>, Entity> filter) {
targets.values().removeIf(Target::tick);
return source.findAllEntitiesInRange(radius)
.filter(entity -> entity.isAlive() && !entity.isRemoved() && notOwnerOrFriend(spell, source, entity) && !SpellPredicate.IS_SHIELD_LIKE.isOn(entity))
.filter(entity -> entity.isAlive() && !entity.isRemoved() && notOwnerOrFriend(spell, source, entity))
.filter(EquinePredicates.EXCEPT_MAGIC_IMMUNE)
.filter(e -> filter.test(source, e))
.map(i -> {
@ -57,6 +56,11 @@ public class TargetSelecter {
public static <T extends Entity> boolean isOwnerOrFriend(Affine affine, Caster<?> source, Entity target) {
Entity owner = source.getMaster();
var equine = Pony.of(target);
if (equine.isPresent() && !affine.isFriendlyTogether(equine.get())) {
return false;
}
if (affine.isEnemy(source)) {
return FriendshipBraceletItem.isComrade(source, target);
}

View file

@ -7,6 +7,8 @@ import com.minelittlepony.unicopia.*;
import com.minelittlepony.unicopia.ability.*;
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.client.render.RenderLayers;
import com.minelittlepony.unicopia.client.render.spell.DarkVortexSpellRenderer;
import com.minelittlepony.unicopia.client.sound.*;
import com.minelittlepony.unicopia.entity.ItemTracker;
import com.minelittlepony.unicopia.entity.effect.EffectUtils;
@ -193,6 +195,19 @@ public class UHud {
protected void renderViewEffects(Pony pony, DrawContext context, int scaledWidth, int scaledHeight, float tickDelta) {
float vortexDistortion = DarkVortexSpellRenderer.getCameraDistortion();
if (vortexDistortion > 20) {
context.fill(RenderLayers.getEndPortal(), 0, 0, scaledWidth, scaledHeight, 0);
context.getMatrices().push();
context.getMatrices().translate(scaledWidth / 2, scaledHeight / 2, 0);
DrawableUtil.drawArc(context.getMatrices(), 0, 20, 0, MathHelper.TAU, 0x000000FF, false);
context.getMatrices().pop();
return;
} else if (vortexDistortion > 0) {
context.fill(0, 0, scaledWidth, scaledHeight, (int)((vortexDistortion / 20F) * 255) << 24);
}
boolean hasEffect = client.player.hasStatusEffect(UEffects.SUN_BLINDNESS);
ItemStack glasses = GlassesItem.getForEntity(client.player);

View file

@ -1,5 +1,6 @@
package com.minelittlepony.unicopia.client.render.spell;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.spell.effect.DarkVortexSpell;
import com.minelittlepony.unicopia.client.render.RenderLayers;
@ -17,7 +18,7 @@ import net.minecraft.util.math.RotationAxis;
public class DarkVortexSpellRenderer implements SpellRenderer<DarkVortexSpell> {
private static final Identifier ECRETION_RING_TEXTURE = new Identifier("textures/misc/forcefield.png");
private static final Identifier ACCRETION_DISK_TEXTURE = Unicopia.id("textures/spells/dark_vortex/accretion_disk.png");
private static float cameraDistortion;
@ -29,16 +30,17 @@ public class DarkVortexSpellRenderer implements SpellRenderer<DarkVortexSpell> {
@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.translate(0, 2 + radius, 0);
SphereModel.SPHERE.render(matrices, vertices.getBuffer(RenderLayers.getSolid()), light, 1, Math.min(radius * 0.6F, absDistance * 0.1F), 0, 0, 0, 1);
matrices.push();
@ -46,6 +48,7 @@ public class DarkVortexSpellRenderer implements SpellRenderer<DarkVortexSpell> {
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);
@ -57,30 +60,41 @@ public class DarkVortexSpellRenderer implements SpellRenderer<DarkVortexSpell> {
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);
if (absDistance > radius) {
matrices.push();
matrices.translate(0, -0.1F, 0);
for (int i = 0; i < 10; i++) {
matrices.scale(1, 1, 0.796F);
float brightness = i / 10F;
SphereModel.DISK.render(matrices, vertices.getBuffer(RenderLayers.getMagicNoColor()), light, 1, radius * (1 + (0.25F * i)) * 0.7F, brightness, brightness, brightness, 0.2F);
}
matrices.pop();
}
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;
if (radius > 0.3F && absDistance > radius) {
radius *= 3 + radius;
matrices.scale(radius, radius, radius);
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(animationProgress));
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(45));
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90));
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(animationProgress * 168));
VertexConsumer buffer = vertices.getBuffer(RenderLayer.getEntityTranslucent(ECRETION_RING_TEXTURE));
VertexConsumer buffer = vertices.getBuffer(RenderLayer.getEntityTranslucent(ACCRETION_DISK_TEXTURE));
PlaneModel.INSTANCE.render(matrices, buffer, light, 0, 1, 1, 1, 1, 1);
matrices.push();
matrices.scale(0.5F, 0.5F, 0.5F);
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(33));
PlaneModel.INSTANCE.render(matrices, buffer, light, 0, 1, 1, 1, 1, 1);
matrices.pop();
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(45));
PlaneModel.INSTANCE.render(matrices, buffer, light, 0, 1, 1, 1, 1, 1);
}
matrices.pop();
matrices.pop();
}
}

View file

@ -63,7 +63,7 @@ public class PlayerCamera extends MotionCompositor {
public double calculateFieldOfView(double fov) {
fov += player.getMagicalReserves().getExertion().get() / 5F;
fov += getEnergyAddition();
fov += DarkVortexSpellRenderer.getCameraDistortion();
fov += DarkVortexSpellRenderer.getCameraDistortion() * 2.5F;
return fov;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB