2019-07-09 14:05:29 +02:00
|
|
|
package com.minelittlepony.client;
|
|
|
|
|
|
|
|
import net.minecraft.client.MinecraftClient;
|
|
|
|
import net.minecraft.entity.player.PlayerEntity;
|
|
|
|
import net.minecraft.util.hit.HitResult;
|
2022-12-08 03:09:32 +00:00
|
|
|
import net.minecraft.util.math.*;
|
2019-07-09 14:05:29 +02:00
|
|
|
|
2020-04-03 23:54:12 +02:00
|
|
|
import com.minelittlepony.api.pony.IPony;
|
2022-12-08 03:09:32 +00:00
|
|
|
import com.minelittlepony.common.util.settings.Setting;
|
2019-07-09 14:05:29 +02:00
|
|
|
|
|
|
|
public class HorseCam {
|
2022-06-10 12:12:41 +02:00
|
|
|
private static float lastOriginalPitch;
|
|
|
|
private static float lastComputedPitch;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Restores the previous camera (unadjusted) angle for the client when the server sends an update.
|
|
|
|
* This is to prevent issues caused by the server updating our pitch whenever the player leaves a portal.
|
|
|
|
*/
|
|
|
|
public static float transformIncomingServerCameraAngle(float serverPitch) {
|
|
|
|
if (MathHelper.approximatelyEquals(serverPitch, lastComputedPitch)) {
|
|
|
|
return lastOriginalPitch;
|
|
|
|
}
|
|
|
|
return serverPitch;
|
|
|
|
}
|
|
|
|
|
2019-07-09 14:05:29 +02:00
|
|
|
/**
|
|
|
|
* Transforms the client pony's pitch to the corresponding angle for a human character.
|
|
|
|
*/
|
|
|
|
public static float transformCameraAngle(float pitch) {
|
|
|
|
|
2019-07-12 17:06:03 +02:00
|
|
|
if (!MineLittlePony.getInstance().getConfig().fillycam.get()) {
|
2019-07-09 14:05:29 +02:00
|
|
|
return pitch;
|
|
|
|
}
|
|
|
|
|
2022-06-10 12:12:41 +02:00
|
|
|
if (pitch != 0) {
|
|
|
|
lastOriginalPitch = pitch;
|
|
|
|
lastComputedPitch = pitch;
|
|
|
|
}
|
|
|
|
|
2019-07-09 14:05:29 +02:00
|
|
|
PlayerEntity player = MinecraftClient.getInstance().player;
|
2022-06-10 12:12:41 +02:00
|
|
|
|
|
|
|
// noop
|
|
|
|
// Only run when the player has an item in their hands. Can't check for buckets specifically since mods exist.
|
|
|
|
if (player.getMainHandStack().isEmpty() && player.getOffHandStack().isEmpty()) {
|
|
|
|
return pitch;
|
|
|
|
}
|
|
|
|
|
2022-12-11 00:38:00 +00:00
|
|
|
IPony pony = IPony.getManager().getPony(player);
|
2019-07-09 14:05:29 +02:00
|
|
|
|
2022-12-08 20:53:30 +00:00
|
|
|
if (!pony.race().isHuman()) {
|
2022-12-08 03:09:32 +00:00
|
|
|
Setting<Boolean> fillyCam = MineLittlePony.getInstance().getConfig().fillycam;
|
|
|
|
|
|
|
|
fillyCam.set(false);
|
|
|
|
final float vanillaHeight = player.getEyeHeight(player.getPose());
|
|
|
|
fillyCam.set(true);
|
|
|
|
final float alteredHeight = player.getEyeHeight(player.getPose());
|
|
|
|
|
|
|
|
// only change the angle if required
|
|
|
|
if (!MathHelper.approximatelyEquals(vanillaHeight, alteredHeight)) {
|
|
|
|
pitch = rescaleCameraPitch(vanillaHeight, pitch);
|
|
|
|
}
|
|
|
|
|
|
|
|
//float factor = pony.getMetadata().getSize().getEyeHeightFactor();
|
|
|
|
//pitch = rescaleCameraPitch(player.getStandingEyeHeight() / factor, pitch);
|
2022-06-10 12:12:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (lastOriginalPitch != 0) {
|
|
|
|
lastComputedPitch = pitch;
|
2019-07-09 14:05:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return pitch;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculates a corresponding camera pitch for the current player at
|
|
|
|
* the specified character height.
|
|
|
|
*
|
|
|
|
* @param toHeight Target height.
|
|
|
|
* @param originalPitch Original, unchanged pitch.
|
|
|
|
*
|
|
|
|
* @return The new pitch value, otherwise the original value passed in.
|
|
|
|
*/
|
|
|
|
public static float rescaleCameraPitch(double toHeight, float originalPitch) {
|
|
|
|
/* -90
|
|
|
|
* |
|
|
|
|
* ---------------0
|
|
|
|
* |
|
|
|
|
* 90
|
|
|
|
*/
|
|
|
|
/* A A - toHeight
|
|
|
|
* |\ B - fromHeight
|
|
|
|
* |?\ y - headPitch
|
|
|
|
* | \ ? - result
|
|
|
|
* | \ C - raytrace
|
|
|
|
* B- \
|
|
|
|
* |y - \
|
|
|
|
* | - \ Tan(?) = horDist / toHeight
|
2019-07-15 10:21:15 +02:00
|
|
|
*==|-------C=== ? = arcTan(horDist / toHeight);
|
2019-07-09 14:05:29 +02:00
|
|
|
* horDist
|
2019-07-15 10:21:15 +02:00
|
|
|
*
|
|
|
|
* horDist
|
|
|
|
* |-------C
|
|
|
|
* | /.
|
|
|
|
* | /.
|
|
|
|
* | / .
|
|
|
|
* | / .
|
|
|
|
* | / .
|
|
|
|
* |?/ .
|
|
|
|
* A/ .
|
|
|
|
* | .
|
|
|
|
* | .
|
|
|
|
* | .
|
|
|
|
* | .
|
|
|
|
* B
|
|
|
|
* |
|
|
|
|
* |
|
|
|
|
*==o===========
|
2019-07-09 14:05:29 +02:00
|
|
|
*/
|
2019-07-15 10:21:15 +02:00
|
|
|
|
2019-07-09 14:05:29 +02:00
|
|
|
MinecraftClient client = MinecraftClient.getInstance();
|
|
|
|
PlayerEntity player = client.player;
|
2022-06-10 12:12:41 +02:00
|
|
|
client.gameRenderer.updateTargetedEntity(client.getTickDelta());
|
2019-11-22 19:24:22 +02:00
|
|
|
HitResult hit = client.crosshairTarget;
|
2019-07-09 14:05:29 +02:00
|
|
|
|
2022-06-10 12:12:41 +02:00
|
|
|
if (client.targetedEntity != null) {
|
2019-07-09 14:05:29 +02:00
|
|
|
return originalPitch;
|
|
|
|
}
|
|
|
|
|
2022-06-10 12:12:41 +02:00
|
|
|
// noop
|
|
|
|
// Ignore misses, helps with bows, arrows, and projectiles
|
|
|
|
if (hit == null || hit.getType() != HitResult.Type.BLOCK || player == null) {
|
2022-06-09 22:23:12 +02:00
|
|
|
return originalPitch;
|
|
|
|
}
|
|
|
|
|
2019-07-09 14:05:29 +02:00
|
|
|
Vec3d hitPos = hit.getPos();
|
|
|
|
Vec3d pos = player.getPos();
|
|
|
|
|
2022-12-08 03:09:32 +00:00
|
|
|
double diffX = hitPos.x - pos.x;
|
|
|
|
double diffZ = hitPos.z - pos.z;
|
2019-07-15 10:21:15 +02:00
|
|
|
|
2019-07-09 14:05:29 +02:00
|
|
|
double horDist = Math.sqrt(diffX * diffX + diffZ * diffZ);
|
|
|
|
|
2019-07-15 10:21:15 +02:00
|
|
|
double toEyePos = pos.y + toHeight;
|
|
|
|
|
|
|
|
double verDist = Math.abs(hitPos.y - toEyePos);
|
|
|
|
|
|
|
|
double theta = Math.atan(horDist / verDist);
|
2019-07-09 14:05:29 +02:00
|
|
|
|
|
|
|
// convert to degress
|
2019-07-15 10:21:15 +02:00
|
|
|
theta /= Math.PI / 180D;
|
2019-07-09 14:05:29 +02:00
|
|
|
|
|
|
|
// convert to vertical pitch (-90 to 90).
|
|
|
|
// Preserve up/down direction.
|
2019-07-15 10:21:15 +02:00
|
|
|
double newPitch = Math.abs(90 - theta) * Math.signum(originalPitch);
|
2019-07-09 14:05:29 +02:00
|
|
|
|
2019-07-15 10:21:15 +02:00
|
|
|
return (float)newPitch;
|
2019-07-09 14:05:29 +02:00
|
|
|
}
|
|
|
|
}
|