mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2024-11-25 13:57:59 +01:00
Improve bucket fix accuracy and correct head pitch when receiving a look update from the server. Fixes #201
This commit is contained in:
parent
cd29726076
commit
f145c59726
3 changed files with 69 additions and 9 deletions
|
@ -1,15 +1,28 @@
|
|||
package com.minelittlepony.client;
|
||||
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
|
||||
public class HorseCam {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the client pony's pitch to the corresponding angle for a human character.
|
||||
*/
|
||||
|
@ -19,12 +32,28 @@ public class HorseCam {
|
|||
return pitch;
|
||||
}
|
||||
|
||||
if (pitch != 0) {
|
||||
lastOriginalPitch = pitch;
|
||||
lastComputedPitch = pitch;
|
||||
}
|
||||
|
||||
PlayerEntity player = MinecraftClient.getInstance().player;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
IPony pony = MineLittlePony.getInstance().getManager().getPony(player);
|
||||
|
||||
if (!pony.getRace(false).isHuman()) {
|
||||
float factor = pony.getMetadata().getSize().getEyeHeightFactor();
|
||||
return rescaleCameraPitch(player.getStandingEyeHeight() / factor, pitch);
|
||||
pitch = rescaleCameraPitch(player.getStandingEyeHeight() / factor, pitch);
|
||||
}
|
||||
|
||||
if (lastOriginalPitch != 0) {
|
||||
lastComputedPitch = pitch;
|
||||
}
|
||||
|
||||
return pitch;
|
||||
|
@ -78,19 +107,19 @@ public class HorseCam {
|
|||
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
PlayerEntity player = client.player;
|
||||
client.gameRenderer.updateTargetedEntity(1);
|
||||
client.gameRenderer.updateTargetedEntity(client.getTickDelta());
|
||||
HitResult hit = client.crosshairTarget;
|
||||
|
||||
if (client.targetedEntity != null) {
|
||||
return originalPitch;
|
||||
}
|
||||
|
||||
// noop
|
||||
// Ignore misses, helps with bows, arrows, and projectiles
|
||||
if (hit == null || hit.getType() != HitResult.Type.BLOCK || player == null) {
|
||||
return originalPitch;
|
||||
}
|
||||
|
||||
if (hit instanceof BlockHitResult && player.world.getBlockState(((BlockHitResult)hit).getBlockPos()).getMaterial() == Material.PORTAL) {
|
||||
return originalPitch;
|
||||
}
|
||||
|
||||
Vec3d hitPos = hit.getPos();
|
||||
Vec3d pos = player.getPos();
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package com.minelittlepony.client.mixin;
|
||||
|
||||
import com.minelittlepony.client.HorseCam;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.network.*;
|
||||
import net.minecraft.network.listener.ClientPlayPacketListener;
|
||||
import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket.Flag;
|
||||
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(PlayerPositionLookS2CPacket.class)
|
||||
abstract class MixinPlayerPositionLookS2CPacket implements Packet<ClientPlayPacketListener> {
|
||||
@Shadow @Mutable
|
||||
private @Final float pitch;
|
||||
private @Final Set<Flag> flags;
|
||||
|
||||
@Inject(method = "apply(Lnet/minecraft/network/listener/ClientPlayPacketListener;)V",
|
||||
at = @At("HEAD"))
|
||||
private void onApply(ClientPlayPacketListener clientPlayPacketListener, CallbackInfo info) {
|
||||
if (!flags.contains(PlayerPositionLookS2CPacket.Flag.Y_ROT)) {
|
||||
pitch = HorseCam.transformIncomingServerCameraAngle(pitch);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
"MixinTexturedRenderLayers",
|
||||
"MixinSpriteIdentifier",
|
||||
"MixinClientPlayerEntity",
|
||||
"MixinPlayerMoveC2SPacket"
|
||||
"MixinPlayerMoveC2SPacket",
|
||||
"MixinPlayerPositionLookS2CPacket"
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue