From dd8bf650d55d7a49c7e298bc41c2deac5c815b38 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 26 Mar 2024 20:46:19 +0000 Subject: [PATCH] #168 Add speed boosts when performing stunts and add a stunt for flying at low altitude. --- .../entity/player/FlightStuntUtil.java | 19 +++++ .../unicopia/entity/player/PlayerPhysics.java | 73 ++++++++++++------- .../unicopia/util/MutableVector.java | 18 +++++ 3 files changed, 85 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/player/FlightStuntUtil.java diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/FlightStuntUtil.java b/src/main/java/com/minelittlepony/unicopia/entity/player/FlightStuntUtil.java new file mode 100644 index 00000000..c5975dbe --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/FlightStuntUtil.java @@ -0,0 +1,19 @@ +package com.minelittlepony.unicopia.entity.player; + +import com.minelittlepony.unicopia.entity.mob.StormCloudEntity; +import com.minelittlepony.unicopia.util.MutableVector; + +import net.minecraft.util.math.BlockPos; + +public class FlightStuntUtil { + public static boolean isPerformingDive(Pony pony, MutableVector velocity) { + double horizontalSpeed = velocity.horizontalLengthSquared(); + double verticalSpeed = velocity.y; + return horizontalSpeed != 0 && verticalSpeed < -0.3F && (verticalSpeed / horizontalSpeed) < -0.3F; + } + + public static boolean isFlyingLow(Pony pony, MutableVector velocity) { + BlockPos pos = pony.asEntity().getBlockPos(); + return velocity.horizontalLengthSquared() > 0.005F && (pos.getY() - StormCloudEntity.findSurfaceBelow(pony.asWorld(), pos).getY()) < 6; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java index 8ac41371..b4db56d0 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java @@ -60,6 +60,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab private int ticksInAir; private int ticksToGlide; private int ticksDiving; + private int ticksFlyingLow; private float thrustScale = 0; private float prevThrustScale; @@ -335,28 +336,9 @@ public class PlayerPhysics extends EntityPhysics implements Tickab velocity.y /= 2F; } - double horizontalSpeed = this.getHorizontalMotion(); - double verticalSpeed = velocity.y; - - if (Abilities.RAINBOOM.canUse(pony.getCompositeRace()) && horizontalSpeed != 0 && verticalSpeed < -0.3F && (verticalSpeed / horizontalSpeed) < -0.3F) { - ticksDiving++; - } else { - ticksDiving = 0; - } - - if (ticksDiving > 0 && ticksDiving % 25 == 0) { - pony.getMagicalReserves().getCharge().addPercent(12.5F); - } + tickStunts(velocity); } else { - prevStrafe = 0; - strafe = 0; - ticksInAir = 0; - wallHitCooldown = MAX_WALL_HIT_CALLDOWN; - soundPlaying = false; - descentRate = 0; - ticksDiving = 0; - updraft.update(0, 100); - windStrength.update(0, 100); + tickGrounded(); if (Abilities.RAINBOOM.canUse(pony.getCompositeRace()) && entity.isOnGround()) { pony.getMagicalReserves().getCharge().set(0); @@ -367,10 +349,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab } } } else { - descentRate = 0; - soundPlaying = false; - updraft.update(0, 100); - windStrength.update(0, 100); + tickGrounded(); } if (!entity.isOnGround()) { @@ -379,6 +358,10 @@ public class PlayerPhysics extends EntityPhysics implements Tickab velocity.z /= heavyness; } + float maximum = 1.5F; + velocity.x = MathHelper.clamp(velocity.x, -maximum, maximum); + velocity.y = MathHelper.clamp(velocity.y, -maximum, maximum); + velocity.z = MathHelper.clamp(velocity.z, -maximum, maximum); entity.setVelocity(velocity.toImmutable()); if (isFlying() && !entity.isFallFlying() && !pony.getAcrobatics().isHanging() && pony.isClient()) { @@ -397,6 +380,46 @@ public class PlayerPhysics extends EntityPhysics implements Tickab } } + private void tickGrounded() { + prevStrafe = 0; + strafe = 0; + ticksInAir = 0; + wallHitCooldown = MAX_WALL_HIT_CALLDOWN; + soundPlaying = false; + descentRate = 0; + ticksDiving = 0; + ticksFlyingLow = 0; + updraft.update(0, 0); + windStrength.update(0, 0); + } + + private void tickStunts(MutableVector velocity) { + boolean canPerformStunts = Abilities.RAINBOOM.canUse(pony.getCompositeRace()); + ticksDiving = canPerformStunts && FlightStuntUtil.isPerformingDive(pony, velocity) ? (ticksDiving + 1) : 0; + ticksFlyingLow = canPerformStunts && FlightStuntUtil.isFlyingLow(pony, velocity) ? (ticksFlyingLow + 1) : 0; + + if (ticksDiving > 0) { + float horDiveScale = MathHelper.clamp(ticksDiving / 100F, 0, 10); + float verDiveScale = MathHelper.clamp(ticksDiving / 90F, 0, 5); + velocity.multiply(1 + horDiveScale, 1 + verDiveScale, 1 + horDiveScale); + } + + if (ticksFlyingLow > 0) { + float horDiveScale = MathHelper.clamp(ticksFlyingLow / 1000F, 0, 0.9F); + float verDiveScale = MathHelper.clamp(ticksFlyingLow / 900F, 0, 0.5F); + velocity.multiply(1 + horDiveScale, 1 + verDiveScale, 1 + horDiveScale); + } + + if (pony.asEntity().age % 2 == 0) { + if (ticksDiving > 0) { + pony.getMagicalReserves().getCharge().addPercent(1F); + } + if (ticksFlyingLow > 0) { + pony.getMagicalReserves().getCharge().addPercent(ticksFlyingLow / 200F); + } + } + } + private void tickFlight(FlightType type, MutableVector velocity) { if (type.isArtifical()) { tickArtificialFlight(velocity); diff --git a/src/main/java/com/minelittlepony/unicopia/util/MutableVector.java b/src/main/java/com/minelittlepony/unicopia/util/MutableVector.java index c76e0209..8ea4aac6 100644 --- a/src/main/java/com/minelittlepony/unicopia/util/MutableVector.java +++ b/src/main/java/com/minelittlepony/unicopia/util/MutableVector.java @@ -20,6 +20,12 @@ public class MutableVector { z = vec.z; } + public void multiply(double x, double y, double z) { + this.x *= x; + this.y *= y; + this.z *= z; + } + public void add(Vec3d vector) { add(vector.x, vector.y, vector.z); } @@ -38,6 +44,18 @@ public class MutableVector { this.z += z; } + public double horizontalLengthSquared() { + return x * x + z * z; + } + + public double verticalLengthSquared() { + return y * y; + } + + public double lengthSquared() { + return verticalLengthSquared() + horizontalLengthSquared(); + } + public Vec3d toImmutable() { return new Vec3d(x, y, z); }