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 c8fb3a6d..7c05d439 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 @@ -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"); } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TargetSelecter.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TargetSelecter.java index b2482157..d1730e78 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TargetSelecter.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TargetSelecter.java @@ -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 getEntities(Caster source, double radius, BiPredicate, 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 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); } diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java index 8cde15c2..c731c559 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java @@ -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); 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 index 0389cfca..548854ae 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/spell/DarkVortexSpellRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/spell/DarkVortexSpellRenderer.java @@ -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 { - 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 { @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 { 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 { 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(); } } 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 2a2a8449..26c6d4c7 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java @@ -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; } diff --git a/src/main/resources/assets/unicopia/textures/spells/dark_vortex/accretion_disk.png b/src/main/resources/assets/unicopia/textures/spells/dark_vortex/accretion_disk.png new file mode 100644 index 00000000..d1ffe0c5 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/spells/dark_vortex/accretion_disk.png differ