diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java index 8665ed5c..e426f14b 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java @@ -204,6 +204,10 @@ public class Disguise implements NbtSerialisable { return -1; } + public Optional getDistance(Pony player) { + return EntityBehaviour.forEntity(entity).getCameraDistance(entity, player); + } + public Optional getDimensions() { return dimensions = EntityBehaviour.forEntity(entity).getDimensions(entity, dimensions); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java index d7bc986e..d2c76ff5 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java @@ -57,6 +57,17 @@ public class EntityBehaviour { entity.remove(); } + public Optional getCameraDistance(Entity entity, Pony player) { + if (entity == null) { + return Optional.empty(); + } + + double normalHeight = PlayerEntity.STANDING_DIMENSIONS.height; + double entityHeight = entity.getDimensions(entity.getPose()).height; + + return Optional.of(entityHeight / normalHeight); + } + public Optional getDimensions(T entity, Optional current) { if (entity == null) { return Optional.empty(); 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 1355a266..c2030dc7 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java @@ -1,27 +1,27 @@ package com.minelittlepony.unicopia.entity.player; -import com.minelittlepony.common.util.animation.MotionCompositor; +import java.util.Optional; +import com.minelittlepony.common.util.animation.MotionCompositor; +import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import net.minecraft.util.math.Vec3d; public class PlayerCamera extends MotionCompositor { private final Pony player; - private double baseRoll = 0; - public PlayerCamera(Pony player) { this.player = player; } public float calculateRoll() { - double roll = baseRoll; + double roll = 0; if (player.getMotion().isFlying()) { Vec3d vel = player.getOwner().getVelocity(); - roll -= super.calculateRoll(player.getOwner(), vel.x, vel.y, vel.z); + roll -= calculateRoll(player.getOwner(), vel.x, vel.y, vel.z); } if (player.getPhysics().isGravityNegative()) { @@ -44,6 +44,13 @@ public class PlayerCamera extends MotionCompositor { return yaw + getEnergyAddition(); } + public Optional calculateDistance(double distance) { + return player.getSpellOrEmpty(DisguiseSpell.class, false) + .map(DisguiseSpell::getDisguise) + .flatMap(d -> d.getDistance(player)) + .map(d -> distance * d); + } + public double calculateFieldOfView(double fov) { fov += player.getMagicalReserves().getExertion().get() / 5F; fov += getEnergyAddition(); @@ -66,12 +73,4 @@ public class PlayerCamera extends MotionCompositor { return energyAddition; } - - public double getBaseRoll() { - return baseRoll; - } - - public void setBaseRoll(double roll) { - baseRoll = roll; - } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinCamera.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinCamera.java index f3192d5b..81f9f5da 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinCamera.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinCamera.java @@ -2,13 +2,12 @@ package com.minelittlepony.unicopia.mixin.client; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import com.minelittlepony.unicopia.entity.player.Pony; - -import net.minecraft.client.MinecraftClient; +import com.minelittlepony.unicopia.client.UnicopiaClient; import net.minecraft.client.render.Camera; -import net.minecraft.entity.player.PlayerEntity; @Mixin(Camera.class) abstract class MixinCamera { @@ -17,13 +16,7 @@ abstract class MixinCamera { ordinal = 0, argsOnly = true) private float modifyYaw(float yaw) { - PlayerEntity player = MinecraftClient.getInstance().player; - - if (player != null && MinecraftClient.getInstance().cameraEntity == player) { - return Pony.of(player).getCamera().calculateYaw(yaw); - } - - return yaw; + return UnicopiaClient.getCamera().map(c -> c.calculateYaw(yaw)).orElse(yaw); } @ModifyVariable(method = "setRotation(FF)V", @@ -31,12 +24,13 @@ abstract class MixinCamera { ordinal = 1, argsOnly = true) private float modifyPitch(float pitch) { - PlayerEntity player = MinecraftClient.getInstance().player; + return UnicopiaClient.getCamera().map(c -> c.calculatePitch(pitch)).orElse(pitch); + } - if (player != null && MinecraftClient.getInstance().cameraEntity == player) { - return Pony.of(player).getCamera().calculatePitch(pitch); - } - - return pitch; + @Inject(method = "clipToSpace(D)D", + at = @At("RETURN"), + cancellable = true) + private void redirectCameraDistance(double initial, CallbackInfoReturnable info) { + UnicopiaClient.getCamera().flatMap(c -> c.calculateDistance(info.getReturnValueD())).ifPresent(info::setReturnValue); } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinClientPlayerInteractionManager.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinClientPlayerInteractionManager.java new file mode 100644 index 00000000..429bfce2 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinClientPlayerInteractionManager.java @@ -0,0 +1,23 @@ +package com.minelittlepony.unicopia.mixin.client; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import com.minelittlepony.unicopia.entity.player.Pony; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayerInteractionManager; + +@Mixin(ClientPlayerInteractionManager.class) +abstract class MixinClientPlayerInteractionManager { + @Inject(method = "getReachDistance()F", at = @At("RETURN"), cancellable = true) + private void onGetReachDistance(CallbackInfoReturnable info) { + Pony player = Pony.of(MinecraftClient.getInstance().player); + + if (player != null) { + info.setReturnValue(player.getExtendedReach() + info.getReturnValueF()); + } + } +} diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 1a29e3da..6ac39693 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -20,6 +20,7 @@ ], "client": [ "client.MixinCamera", + "client.MixinClientPlayerInteractionManager", "client.MixinEntityRenderDispatcher", "client.MixinGameRenderer", "client.MixinInGameHud",