diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Conditional.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Conditional.java index 58c296a..00abec2 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Conditional.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Conditional.java @@ -9,7 +9,8 @@ private Conditional() {} public static boolean shouldApplyPerspectiveTo(Entity player) { if(ModConfig.INSTANCE.enabled) { - return (ModConfig.INSTANCE.applyToOthers && player instanceof RemotePlayer) + return ModConfig.INSTANCE.applyToNonPlayerEntities || + (ModConfig.INSTANCE.applyToOthers && player instanceof RemotePlayer) || player instanceof LocalPlayer; } else { return false; diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/ModConfig.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/ModConfig.java index b944260..30e61c6 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/ModConfig.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/ModConfig.java @@ -20,6 +20,7 @@ private ModConfig() {} public boolean rollEnabled = true; public float rollMagnitude = 1.0f; public boolean applyToOthers = true; + public boolean applyToNonPlayerEntities = false; public boolean dbgShowStandingTransforms = false; private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); @@ -156,6 +157,15 @@ public static Screen createConfigScreen(Screen parent) { .setSaveConsumer(value -> INSTANCE.rollMagnitude = value) .setDefaultValue(1.0f) .build()); + + advanced.add(entryBuilder + .startBooleanToggle( + Component.translatable("option.create_train_perspective.multiplayer.apply_to_entities"), + INSTANCE.applyToNonPlayerEntities) + .setTooltip(Component.translatable("option.create_train_perspective.multiplayer.apply_to_entities.tooltip")) + .setSaveConsumer(value -> INSTANCE.applyToNonPlayerEntities = value) + .setDefaultValue(true) + .build()); var debug = entryBuilder.startSubCategory(Component.translatable("category.create_train_perspective.debug")); diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/AbstractClientPlayerMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/AbstractClientPlayerMixin.java deleted file mode 100644 index bc6459e..0000000 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/AbstractClientPlayerMixin.java +++ /dev/null @@ -1,81 +0,0 @@ -package net.derfruhling.minecraft.create.trainperspective.mixin; - -import net.derfruhling.minecraft.create.trainperspective.Perspective; -import net.derfruhling.minecraft.create.trainperspective.RotationState; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.util.Mth; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Implements; -import org.spongepowered.asm.mixin.Interface; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -@Mixin(AbstractClientPlayer.class) -@Implements({@Interface(iface = Perspective.class, prefix = "ctp$")}) -@Environment(EnvType.CLIENT) -public class AbstractClientPlayerMixin { - @Unique - private boolean ctp$perspectiveActive = false; - @Unique private float ctp$lean = 0.0f, ctp$yaw = 0.0f, ctp$oldLean = 0.0f, ctp$oldYaw = 0.0f; - @Unique private @Nullable RotationState ctp$currentState = null; - - public void ctp$enable(float initialLean, float initialYaw) { - ctp$perspectiveActive = true; - ctp$lean = initialLean; - ctp$yaw = initialYaw; - ctp$oldLean = initialLean; - ctp$oldYaw = initialYaw; - } - - public void ctp$disable() { - ctp$perspectiveActive = false; - ctp$lean = 0.0f; - ctp$yaw = 0.0f; - ctp$oldLean = 0.0f; - ctp$oldYaw = 0.0f; - } - - public boolean ctp$isEnabled() { - return ctp$perspectiveActive; - } - - public void ctp$setLean(float lean) { - ctp$oldLean = ctp$lean; - ctp$lean = lean; - } - - public void ctp$setYaw(float yaw) { - // some configurations flip between 0 and 360 constantly - // adjust accordingly - ctp$oldYaw = ctp$yaw; - ctp$yaw = yaw; - - while (ctp$yaw - ctp$oldYaw < -180.0f) { - ctp$oldYaw -= 360.0f; - } - - while (ctp$yaw - ctp$oldYaw >= 180.0f) { - ctp$oldYaw += 360.0f; - } - } - - public float ctp$getLean(float f) { - if(f == 1.0f) return ctp$lean; - return Mth.lerp(f, ctp$oldLean, ctp$lean); - } - - public float ctp$getYaw(float f) { - if(f == 1.0f) return ctp$yaw; - return Mth.lerp(f, ctp$oldYaw, ctp$yaw); - } - - public @Nullable RotationState ctp$getRotationState() { - return ctp$currentState; - } - - public void ctp$setRotationState(@Nullable RotationState state) { - ctp$currentState = state; - } -} diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/EntityMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/EntityMixin.java index 69d13cf..d14f73d 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/EntityMixin.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/EntityMixin.java @@ -1,28 +1,30 @@ package net.derfruhling.minecraft.create.trainperspective.mixin; import com.llamalad7.mixinextras.sugar.Local; -import net.derfruhling.minecraft.create.trainperspective.Conditional; -import net.derfruhling.minecraft.create.trainperspective.CreateTrainPerspectiveMod; -import net.derfruhling.minecraft.create.trainperspective.MixinUtil; -import net.derfruhling.minecraft.create.trainperspective.Perspective; +import net.derfruhling.minecraft.create.trainperspective.*; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; +import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.*; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(Entity.class) +@Implements({@Interface(iface = Perspective.class, prefix = "ctp$")}) @Environment(EnvType.CLIENT) public abstract class EntityMixin { @Shadow @Nullable private Entity vehicle; @Shadow private Level level; + @Unique private boolean ctp$perspectiveActive = false; + @Unique private float ctp$lean = 0.0f, ctp$yaw = 0.0f, ctp$oldLean = 0.0f, ctp$oldYaw = 0.0f; + @Unique private @Nullable RotationState ctp$currentState = null; + @Inject(method = "startRiding(Lnet/minecraft/world/entity/Entity;Z)Z", at = @At(value = "RETURN", ordinal = 4)) public void onMount(Entity entity, boolean bl, CallbackInfoReturnable cir) { var self = (Entity)(Object)this; @@ -64,4 +66,62 @@ public float modifyYaw(float yaw, @Local(argsOnly = true, index = 1) float pitch } else return yaw; } else return yaw; } + + public void ctp$enable(float initialLean, float initialYaw) { + ctp$perspectiveActive = true; + ctp$lean = initialLean; + ctp$yaw = initialYaw; + ctp$oldLean = initialLean; + ctp$oldYaw = initialYaw; + } + + public void ctp$disable() { + ctp$perspectiveActive = false; + ctp$lean = 0.0f; + ctp$yaw = 0.0f; + ctp$oldLean = 0.0f; + ctp$oldYaw = 0.0f; + } + + public boolean ctp$isEnabled() { + return ctp$perspectiveActive; + } + + public void ctp$setLean(float lean) { + ctp$oldLean = ctp$lean; + ctp$lean = lean; + } + + public void ctp$setYaw(float yaw) { + // some configurations flip between 0 and 360 constantly + // adjust accordingly + ctp$oldYaw = ctp$yaw; + ctp$yaw = yaw; + + while (ctp$yaw - ctp$oldYaw < -180.0f) { + ctp$oldYaw -= 360.0f; + } + + while (ctp$yaw - ctp$oldYaw >= 180.0f) { + ctp$oldYaw += 360.0f; + } + } + + public float ctp$getLean(float f) { + if(f == 1.0f) return ctp$lean; + return Mth.lerp(f, ctp$oldLean, ctp$lean); + } + + public float ctp$getYaw(float f) { + if(f == 1.0f) return ctp$yaw; + return Mth.lerp(f, ctp$oldYaw, ctp$yaw); + } + + public @Nullable RotationState ctp$getRotationState() { + return ctp$currentState; + } + + public void ctp$setRotationState(@Nullable RotationState state) { + ctp$currentState = state; + } } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/LivingEntityRendererMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/LivingEntityRendererMixin.java new file mode 100644 index 0000000..b4d1ac9 --- /dev/null +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/LivingEntityRendererMixin.java @@ -0,0 +1,40 @@ +package net.derfruhling.minecraft.create.trainperspective.mixin; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; +import net.derfruhling.minecraft.create.trainperspective.Conditional; +import net.derfruhling.minecraft.create.trainperspective.Perspective; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.player.AbstractClientPlayer; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.client.renderer.entity.player.PlayerRenderer; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.LivingEntity; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +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.CallbackInfo; + +@Mixin(LivingEntityRenderer.class) +@Environment(EnvType.CLIENT) +public class LivingEntityRendererMixin { + @Inject(method = "setupRotations", at = @At("HEAD")) + protected void setupRotations(LivingEntity livingEntity, PoseStack poseStack, float f, float g, float h, CallbackInfo ci) { + if(Conditional.shouldApplyPerspectiveTo(livingEntity)) { + Perspective persp = (Perspective) livingEntity; + float height = 0; + + if(livingEntity.getVehicle() != null) { + height = livingEntity.getEyeHeight(); + } + + var lean = persp.getLean(f); + var yaw = persp.getYaw(f); + poseStack.rotateAround(Axis.ZP.rotationDegrees(Mth.cos(Mth.DEG_TO_RAD * yaw) * lean), 0, height, 0); + poseStack.rotateAround(Axis.XP.rotationDegrees(Mth.sin(Mth.DEG_TO_RAD * yaw) * -lean), 0, height, 0); + } + } +} diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/PlayerRendererMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/PlayerRendererMixin.java deleted file mode 100644 index 90846cc..0000000 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/PlayerRendererMixin.java +++ /dev/null @@ -1,48 +0,0 @@ -package net.derfruhling.minecraft.create.trainperspective.mixin; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Axis; -import net.derfruhling.minecraft.create.trainperspective.Conditional; -import net.derfruhling.minecraft.create.trainperspective.CreateTrainPerspectiveMod; -import net.derfruhling.minecraft.create.trainperspective.Perspective; -import net.derfruhling.minecraft.create.trainperspective.RotationState; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.renderer.entity.player.PlayerRenderer; -import net.minecraft.util.Mth; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Implements; -import org.spongepowered.asm.mixin.Interface; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(PlayerRenderer.class) -@Implements({@Interface(iface = Perspective.class, prefix = "ctp$")}) -@Environment(EnvType.CLIENT) -public class PlayerRendererMixin { - @Inject( - method = "setupRotations(Lnet/minecraft/client/player/AbstractClientPlayer;Lcom/mojang/blaze3d/vertex/PoseStack;FFF)V", - at = @At( - value = "HEAD" - ) - ) - protected void setupRotations(AbstractClientPlayer clientPlayer, PoseStack p_117803_, float p_117804_, float p_117805_, float f, CallbackInfo ci) { - if(Conditional.shouldApplyPerspectiveTo(clientPlayer)) { - Perspective persp = (Perspective) clientPlayer; - float height = 0; - - if(clientPlayer.getVehicle() != null) { - height = clientPlayer.getEyeHeight(); - } - - var lean = persp.getLean(f); - var yaw = persp.getYaw(f); - p_117803_.rotateAround(Axis.ZP.rotationDegrees(Mth.cos(Mth.DEG_TO_RAD * yaw) * lean), 0, height, 0); - p_117803_.rotateAround(Axis.XP.rotationDegrees(Mth.sin(Mth.DEG_TO_RAD * yaw) * -lean), 0, height, 0); - } - } -} diff --git a/common/src/main/resources/assets/minecraft/lang/en_us.json b/common/src/main/resources/assets/minecraft/lang/en_us.json index c238e8b..08ba245 100644 --- a/common/src/main/resources/assets/minecraft/lang/en_us.json +++ b/common/src/main/resources/assets/minecraft/lang/en_us.json @@ -20,6 +20,8 @@ "option.create_train_perspective.advanced.lean_magnitude.tooltip": "The magnitude to which the player will lean. Higher = more intense.", "option.create_train_perspective.advanced.roll_magnitude": "Rolling Magnitude", "option.create_train_perspective.advanced.roll_magnitude.tooltip": "The magnitude to which the player will roll. Higher = more intense.", + "option.create_train_perspective.multiplayer.apply_to_entities": "Apply mod to non-player entities", + "option.create_train_perspective.multiplayer.apply_to_entities.tooltip": "Applies the mod to non-player entities as well (may be broken with some entities)", "option.create_train_perspective.debug.standing_transforms": "Show Standing Translations", "option.create_train_perspective.debug.standing_transforms.tooltip": "Shows translations used to transform the player while standing on a train. (X, Y, Z)" } \ No newline at end of file diff --git a/common/src/main/resources/create_train_perspective.mixins.json b/common/src/main/resources/create_train_perspective.mixins.json index 37c3db2..b27b486 100644 --- a/common/src/main/resources/create_train_perspective.mixins.json +++ b/common/src/main/resources/create_train_perspective.mixins.json @@ -4,7 +4,6 @@ "package": "net.derfruhling.minecraft.create.trainperspective.mixin", "compatibilityLevel": "JAVA_8", "client": [ - "AbstractClientPlayerMixin", "AbstractContraptionEntityMixin", "CameraMixin", "ClientLevelMixin", @@ -12,7 +11,7 @@ "EntityMixin", "GameRendererMixin", "LocalPlayerMixin", - "PlayerRendererMixin" + "LivingEntityRendererMixin" ], "overwrites": { "requireAnnotations": true,