diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/CreateTrainPerspectiveMod.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/CreateTrainPerspectiveMod.java index ac9aaef..759d396 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/CreateTrainPerspectiveMod.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/CreateTrainPerspectiveMod.java @@ -4,10 +4,9 @@ import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; import dev.architectury.event.events.common.TickEvent; import net.minecraft.client.Minecraft; -import net.minecraft.client.player.LocalPlayer; +import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; -import org.apache.commons.lang3.mutable.MutableInt; import org.slf4j.Logger; import java.util.*; @@ -25,57 +24,26 @@ public CreateTrainPerspectiveMod() { INSTANCE = this; } - private static class RotationState { - public final CarriageContraptionEntity entity; - private float lastYaw; - public boolean standingState; - public boolean isMounted; - public boolean shouldTickState = true; - public int ticksSinceLastUpdate = 0; - - public RotationState(CarriageContraptionEntity entity, boolean standingState, boolean isMounted) { - this.entity = entity; - lastYaw = entity.yaw; - this.standingState = standingState; - this.isMounted = isMounted; - } - - public float getYawDelta() { - while (entity.yaw - lastYaw < -180.0f) { - lastYaw -= 360.0f; - } - - while (entity.yaw - lastYaw >= 180.0f) { - lastYaw += 360.0f; - } - - var rotation = entity.yaw - lastYaw; - lastYaw = entity.yaw; - return rotation; - } - } - - private final HashMap states = new HashMap<>(); - public void onEntityMount(boolean isMounting, Entity entityMounting, Entity entityBeingMounted) { if( - entityMounting instanceof LocalPlayer player && + entityMounting instanceof AbstractClientPlayer player && entityBeingMounted instanceof CarriageContraptionEntity contraption ) { var persp = (Perspective) Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(player); if(isMounting) { - if(!states.containsKey(entityMounting.getUUID())) { + if(persp.getRotationState() == null) { var state = new RotationState(contraption, false, true); - states.put(entityMounting.getUUID(), state); - persp.enable(state.entity.pitch, state.entity.yaw); + persp.setRotationState(state); + var carriage = state.getCarriageEntity(); + assert carriage != null; + persp.enable(carriage.pitch, carriage.yaw); } else { - var state = states.get(entityMounting.getUUID()); - state.isMounted = true; - state.shouldTickState = true; + var state = persp.getRotationState(); + state.onMounted(); } } else { - if(states.containsKey(entityMounting.getUUID())) { - states.remove(entityMounting.getUUID()); + if(persp.getRotationState() != null) { + persp.setRotationState(null); persp.disable(); } } @@ -85,47 +53,51 @@ public void onEntityMount(boolean isMounting, Entity entityMounting, Entity enti public void tickStandingPlayer(final CarriageContraptionEntity contraption, final Player player) { if(player.getVehicle() != null) return; - var state = states.get(player.getUUID()); + var persp = (Perspective) Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(player); + var state = persp.getRotationState(); - if (state == null || !Objects.equals(state.entity, contraption)) { - var persp = (Perspective) Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(player); + if (state == null || !Objects.equals(state.getCarriageEntity(), contraption)) { state = new RotationState(contraption, true, false); - states.put(player.getUUID(), state); - persp.enable(state.entity.pitch, state.entity.yaw); + persp.setRotationState(state); + var carriage = state.getCarriageEntity(); + assert carriage != null; + persp.enable(carriage.pitch, carriage.yaw); } else { - state.ticksSinceLastUpdate = 0; + state.update(); } } - private void tickState(LocalPlayer player) { - var state = states.get(player.getUUID()); - var persp = (Perspective) Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(player); - persp.setLean(state.entity.pitch); - persp.setYaw(state.entity.yaw); + private void tickState(Player player, Perspective persp, RotationState state) { + var carriage = state.getCarriageEntity(); + if(carriage == null) return; + persp.setLean(carriage.pitch); + persp.setYaw(carriage.yaw); player.setYRot(player.getYRot() + state.getYawDelta()); player.setYBodyRot(player.getYRot()); - if(state.standingState && !state.isMounted) { - state.ticksSinceLastUpdate += 1; + if(state.isStanding() && !state.isMounted()) { + state.tick(); - if(state.ticksSinceLastUpdate > 5) { - state.shouldTickState = false; + if(state.getTicksSinceLastUpdate() > 5) { + state.setShouldTickState(false); } } } public void onTickPlayer(final Player player) { - if(player instanceof LocalPlayer localPlayer && states.containsKey(player.getUUID())) { - var state = states.get(player.getUUID()); - - if(state.shouldTickState) { - tickState(localPlayer); + if(!(player instanceof AbstractClientPlayer)) return; + if(Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(player) instanceof Perspective persp + && persp.getRotationState() != null) { + var state = persp.getRotationState(); + assert state != null; + + if(state.shouldTickState()) { + tickState(player, persp, state); } else { - var persp = (Perspective) Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(player); persp.diminish(); if(persp.diminished()) { - states.remove(player.getUUID()); + persp.setRotationState(null); persp.disable(); } } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Perspective.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Perspective.java index 4636714..b9b2d3f 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Perspective.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Perspective.java @@ -1,6 +1,7 @@ package net.derfruhling.minecraft.create.trainperspective; import net.minecraft.util.Mth; +import org.jetbrains.annotations.Nullable; public interface Perspective { void enable(float initialLean, float initialYaw); @@ -10,6 +11,8 @@ public interface Perspective { void setYaw(float yaw); float getLean(float f); float getYaw(float f); + @Nullable RotationState getRotationState(); + void setRotationState(@Nullable RotationState state); default void diminish() { setLean(getLean(1.0f) * 0.9f); diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationState.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationState.java new file mode 100644 index 0000000..a91a102 --- /dev/null +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationState.java @@ -0,0 +1,91 @@ +package net.derfruhling.minecraft.create.trainperspective; + +import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; +import org.jetbrains.annotations.Nullable; + +public class RotationState implements RotationStateKeeper { + private CarriageContraptionEntity entity; + private float lastYaw; + private final boolean standingState; + private boolean isMounted; + private boolean shouldTickState = true; + private int ticksSinceLastUpdate = 0; + + public RotationState(CarriageContraptionEntity entity, boolean standingState, boolean isMounted) { + this.entity = entity; + lastYaw = entity.yaw; + this.standingState = standingState; + this.isMounted = isMounted; + } + + @Override + public float getYawDelta() { + while (entity.yaw - lastYaw < -180.0f) { + lastYaw -= 360.0f; + } + + while (entity.yaw - lastYaw >= 180.0f) { + lastYaw += 360.0f; + } + + var rotation = entity.yaw - lastYaw; + lastYaw = entity.yaw; + return rotation; + } + + @Override + public @Nullable CarriageContraptionEntity getCarriageEntity() { + return entity; + } + + @Override + public void setCarriageEntity(@Nullable CarriageContraptionEntity entity) { + this.entity = entity; + } + + @Override + public boolean isStanding() { + return standingState; + } + + @Override + public boolean isMounted() { + return isMounted; + } + + @Override + public boolean shouldTickState() { + return shouldTickState; + } + + @Override + public void onMounted() { + this.isMounted = true; + this.shouldTickState = true; + } + + @Override + public void onDismount() { + this.isMounted = false; + } + + @Override + public void setShouldTickState(boolean shouldTickState) { + this.shouldTickState = shouldTickState; + } + + @Override + public int getTicksSinceLastUpdate() { + return ticksSinceLastUpdate; + } + + @Override + public void update() { + ticksSinceLastUpdate = 0; + } + + @Override + public void tick() { + ticksSinceLastUpdate += 1; + } +} diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationStateKeeper.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationStateKeeper.java new file mode 100644 index 0000000..8be5110 --- /dev/null +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationStateKeeper.java @@ -0,0 +1,19 @@ +package net.derfruhling.minecraft.create.trainperspective; + +import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; +import org.jetbrains.annotations.Nullable; + +public interface RotationStateKeeper { + @Nullable CarriageContraptionEntity getCarriageEntity(); + void setCarriageEntity(@Nullable CarriageContraptionEntity entity); + boolean isStanding(); + boolean isMounted(); + boolean shouldTickState(); + void onMounted(); + void onDismount(); + void setShouldTickState(boolean value); + int getTicksSinceLastUpdate(); + void update(); + void tick(); + float getYawDelta(); +} \ No newline at end of file diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/CameraMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/CameraMixin.java index 6bb219e..025b314 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/CameraMixin.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/CameraMixin.java @@ -8,7 +8,7 @@ import net.fabricmc.api.Environment; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; -import net.minecraft.client.player.LocalPlayer; +import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import org.joml.Quaternionf; @@ -57,7 +57,7 @@ public void modifyRotationsPrimary(Camera instance, float x, @Local(argsOnly = true, ordinal = 0) boolean isThirdPerson, @Local(argsOnly = true) float f) { - if(entity instanceof LocalPlayer player && !isThirdPerson) { + if(entity instanceof AbstractClientPlayer player && !isThirdPerson) { var persp = (Perspective) Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(player); ctp$zRot = persp.getLean(f) * Mth.cos((persp.getYaw(f) - y) * Mth.DEG_TO_RAD); ctp$extraYRot = MixinUtil.getExtraYRot(persp, x, y, f); 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 index 9cb1351..c1a60c3 100644 --- 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 @@ -4,11 +4,13 @@ import com.mojang.math.Axis; 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; @@ -23,6 +25,7 @@ public class PlayerRendererMixin { @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; @@ -74,6 +77,14 @@ public class PlayerRendererMixin { 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; + } + @Inject( method = "setupRotations(Lnet/minecraft/client/player/AbstractClientPlayer;Lcom/mojang/blaze3d/vertex/PoseStack;FFF)V", at = @At(