diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/EntityModuleFabric.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/EntityModuleFabric.java index a920623..aa42d4f 100644 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/EntityModuleFabric.java +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/EntityModuleFabric.java @@ -7,7 +7,7 @@ import net.minecraft.util.hit.HitResult; import net.minecraft.entity.LivingEntity; import org.saturnclient.common.module.EntityModule; -import org.saturnclient.modules.HealthRenderState; + /** * Fabric implementation of {@link EntityModule}. diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/HealthRenderState.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/HealthRenderState.java new file mode 100644 index 0000000..d5a063b --- /dev/null +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/HealthRenderState.java @@ -0,0 +1,20 @@ +package org.saturnclient.impl.modules; + +import org.saturnclient.common.module.EntityModule; + +/** + * Injected interface on {@link net.minecraft.client.render.entity.state.LivingEntityRenderState}. + * + * Carries the entity's health snapshot and classification into the render + * pipeline so that {@link NametagsMixin} can read them without touching + * the live entity again. + */ +public interface HealthRenderState { + + float saturn$getHealth(); + float saturn$getMaxHealth(); + void saturn$setHealth(float health, float maxHealth); + + EntityModule.EntityType saturn$getEntityType(); + void saturn$setEntityType(EntityModule.EntityType type); +} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/GameRendererMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/GameRendererMixin.java new file mode 100644 index 0000000..3dfd659 --- /dev/null +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/GameRendererMixin.java @@ -0,0 +1,37 @@ +package org.saturnclient.impl.modules.mixins; + +import net.minecraft.client.render.GameRenderer; + +import org.saturnclient.feature.features.ZoomFeature; +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; + +/** + * Overrides the game's field-of-view when {@link ZoomFeature} is active. + * + * The old code checked both {@code Zoom.isZooming} and + * {@code Zoom.shouldZoom()} separately. The refactored + * {@link ZoomFeature#shouldZoom()} already ORs both conditions + * ({@code enabled.value && isZooming}), so only one check is needed. + * + * No {@link org.saturnclient.common.module.ModuleProvider} is required + * here because zooming is a pure render-time override with no per-tick + * engine queries. + */ +@Mixin(GameRenderer.class) +public class GameRendererMixin { + + /** + * After the vanilla FOV has been computed, divide it by the zoom + * level to produce the narrowed field-of-view. + */ + @Inject(method = "getFov", at = @At("RETURN"), cancellable = true) + private void onGetFov(CallbackInfoReturnable cir) { + if (ZoomFeature.shouldZoom()) { + float zoomedFov = cir.getReturnValue() / ZoomFeature.getZoomLevel(); + cir.setReturnValue(zoomedFov); + } + } +} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/LightmapTextureManagerMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/LightmapTextureManagerMixin.java similarity index 53% rename from versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/LightmapTextureManagerMixin.java rename to versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/LightmapTextureManagerMixin.java index cd65016..564e781 100644 --- a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/LightmapTextureManagerMixin.java +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/LightmapTextureManagerMixin.java @@ -1,5 +1,6 @@ -// code modified from Gamma utils: https://github.com/Sjouwer/gamma-utils -package org.saturnclient.modules.mixins; +package org.saturnclient.impl.modules.mixins; + +// Code approach adapted from Gamma Utils: https://github.com/Sjouwer/gamma-utils import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.minecraft.client.render.LightmapTextureManager; @@ -8,9 +9,22 @@ import org.saturnclient.feature.features.FullbrightFeature; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +/** + * Overrides the lightmap's gamma computation when + * {@link FullbrightFeature} is active, replacing the vanilla + * brightness with a user-configured value. + * + * The old import was {@code org.saturnclient.feature.features.Fullbright}; + * it is now {@link FullbrightFeature}. The injection target and + * strategy are unchanged. + */ @Mixin(LightmapTextureManager.class) public class LightmapTextureManagerMixin { + /** + * If fullbright is active, substitute the feature's brightness + * value for whatever vanilla calculated. + */ @ModifyExpressionValue(method = "update", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0)) private float modifyGamma(float original) { if (FullbrightFeature.shouldOverrideBrightness()) { diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/LivingEntityRenderStateMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/LivingEntityRenderStateMixin.java new file mode 100644 index 0000000..2cecd6d --- /dev/null +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/LivingEntityRenderStateMixin.java @@ -0,0 +1,59 @@ +package org.saturnclient.impl.modules.mixins; + +import net.minecraft.client.render.entity.state.LivingEntityRenderState; + +import org.saturnclient.common.module.EntityModule; +import org.saturnclient.impl.modules.HealthRenderState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +/** + * Implements {@link HealthRenderState} on + * {@link LivingEntityRenderState}, injecting health and entity-type + * storage into every living entity's render-state snapshot. + * + * Previously imported {@code NametagsInterface.EntityType}; the enum + * now lives in {@link EntityModule.EntityType} which is the single + * canonical definition shared by the mixin layer and the feature layer. + * + * The stored values are written by + * {@link LivingEntityRendererMixin#saturn$captureHealth} each time a + * render state is extracted from a live entity, and read by + * {@link NametagsMixin} at render time. + */ +@Mixin(LivingEntityRenderState.class) +public class LivingEntityRenderStateMixin implements HealthRenderState { + + @Unique + private float saturn$health = 0f; + @Unique + private float saturn$maxHealth = 1f; + @Unique + private EntityModule.EntityType saturn$entityType = EntityModule.EntityType.OTHER; + + @Override + public float saturn$getHealth() { + return saturn$health; + } + + @Override + public float saturn$getMaxHealth() { + return saturn$maxHealth; + } + + @Override + public void saturn$setHealth(float health, float maxHealth) { + this.saturn$health = health; + this.saturn$maxHealth = maxHealth; + } + + @Override + public EntityModule.EntityType saturn$getEntityType() { + return saturn$entityType; + } + + @Override + public void saturn$setEntityType(EntityModule.EntityType type) { + saturn$entityType = type; + } +} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/LivingEntityRendererMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/LivingEntityRendererMixin.java similarity index 70% rename from versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/LivingEntityRendererMixin.java rename to versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/LivingEntityRendererMixin.java index c86c43f..3c26f90 100644 --- a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/LivingEntityRendererMixin.java +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/LivingEntityRendererMixin.java @@ -1,4 +1,4 @@ -package org.saturnclient.modules.mixins; +package org.saturnclient.impl.modules.mixins; import net.minecraft.client.render.entity.LivingEntityRenderer; import net.minecraft.client.render.entity.state.LivingEntityRenderState; @@ -8,15 +8,22 @@ import net.minecraft.entity.passive.PassiveEntity; import net.minecraft.entity.player.PlayerEntity; import org.saturnclient.common.module.EntityModule; -import org.saturnclient.modules.HealthRenderState; +import org.saturnclient.impl.modules.HealthRenderState; 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; /** - * Captures health and entity-type into the render state each frame so - * that the nametag replacement logic never needs to touch the live entity. + * Captures each living entity's health and type into the render state + * during {@code updateRenderState}, so that nametag rendering can read + * them without touching the live entity again. + * + * Previously imported {@code NametagsInterface.EntityType}; now uses + * {@link EntityModule.EntityType} — the canonical enum shared across + * the whole module system. + * + * The injection target and strategy are unchanged from the original. */ @Mixin(LivingEntityRenderer.class) public abstract class LivingEntityRendererMixin { @@ -28,6 +35,7 @@ public abstract class LivingEntityRendererMixin + *
  • The old {@code NametagsFabric.EntityStateImpl} bridge class is + * replaced by {@link EntityModuleFabric.RenderStateEntityState}, + * which wraps the {@link HealthRenderState} already injected into + * the render state by {@link LivingEntityRenderStateMixin}.
  • + *
  • The feature import changes from {@code Nametags} to + * {@link NametagsFeature}; the two static methods + * ({@code shouldReplaceName} / {@code getNametagString}) are + * unchanged in signature.
  • + *
  • The entity's display name is extracted from the render state's + * {@code nameVisible} / text fields where available, falling back + * to the plain text string passed to this method.
  • + * + * + * The re-entrancy guard ({@code saturn$rendering}) is kept intact to + * prevent infinite recursion when we call {@code renderLabelIfPresent} + * with the replacement text. + */ +@Mixin(EntityRenderer.class) +public abstract class NametagsMixin { + + /** Guards against the recursive call we make with the replacement text. */ + @Unique + private static final ThreadLocal saturn$rendering = ThreadLocal.withInitial(() -> false); + + @Shadow + protected abstract void renderLabelIfPresent( + S state, Text text, + MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light); + + @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) + private void saturn$replaceNametag( + S state, Text text, + MatrixStack matrices, VertexConsumerProvider vertexConsumers, + int light, CallbackInfo ci) { + + // Skip our own recursive call + if (saturn$rendering.get()) + return; + + if (!NametagsFeature.shouldReplaceName()) + return; + + // Only living entities carry health data + if (!(state instanceof LivingEntityRenderState living)) + return; + if (!(living instanceof HealthRenderState hrs)) + return; + + // Build the platform-neutral EntityState from the render-state snapshot + // (health/type were written by LivingEntityRendererMixin at extract time). + String customName = text != null ? text.getString() : null; + EntityModuleFabric.RenderStateEntityState entityState = new EntityModuleFabric.RenderStateEntityState( + customName, hrs); + + // Ask the feature for the replacement string + String replacement = NametagsFeature.getNametagString(entityState); + if (replacement == null) + return; // feature decided not to replace this entity + + ci.cancel(); + saturn$rendering.set(true); + try { + renderLabelIfPresent(state, Text.literal(replacement), matrices, vertexConsumers, light); + } finally { + saturn$rendering.set(false); + } + } +} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/RenderMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/RenderMixin.java new file mode 100644 index 0000000..ec9d8eb --- /dev/null +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/RenderMixin.java @@ -0,0 +1,85 @@ +package org.saturnclient.impl.modules.mixins; + +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.hud.InGameHud; +import net.minecraft.client.render.RenderTickCounter; + +import org.saturnclient.feature.Feature; +import org.saturnclient.feature.FeatureLayout; +import org.saturnclient.feature.FeatureManager; +import org.saturnclient.feature.HudFeature; +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.saturnclient.mixin.DrawContextAccessor; +import org.saturnclient.ui.RenderScope; +import org.saturnclient.ui.RenderScopeImpl; +import org.saturnclient.ui.SaturnScreenFabric; +import org.saturnclient.ui.screens.HudEditor; +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; + +/** + * Drives per-frame rendering for all registered features. + * + * This mixin is intentionally kept thin: it creates a {@link RenderScope}, + * iterates the enabled feature list from {@link FeatureManager}, and + * dispatches either {@link HudFeature#renderHud} (for HUD elements) or + * {@link Feature#render} (for world-overlay features like Crosshair). + * + * No feature-specific logic lives here — all decisions about what to + * draw are made inside each feature class. + * + * Changes from the original: + * - Package imports updated to the refactored feature names (no + * more {@code feature.features.*}). + * - The HUD-editor screen check still uses the existing + * {@link SaturnScreenFabric} / {@link HudEditor} pair; that is + * unchanged infrastructure. + */ +@Mixin(InGameHud.class) +public class RenderMixin { + + @Inject(method = "renderChat", at = @At("TAIL")) + public void renderMods(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { + TextRenderer textRenderer = SaturnClient.client.textRenderer; + + // Skip rendering while the HUD editor is open so the editor + // can draw its own preview layout without double-drawing. + if (textRenderer == null) + return; + if (SaturnClient.client.currentScreen instanceof SaturnScreenFabric f + && f.screen instanceof HudEditor) + return; + + RenderScope scope = new RenderScopeImpl( + context.getMatrices(), + ((DrawContextAccessor) context).getVertexConsumers()); + + for (Feature feature : FeatureManager.ENABLED_MODS) { + if (!feature.isEnabled()) + continue; + + if (feature instanceof HudFeature hud) { + FeatureLayout dim = hud.getDimensions(); + + scope.getMatrixStack().push(); + scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value, 0f); + scope.getMatrixStack().scale(dim.scale.value, dim.scale.value, 1.0f); + + if (dim.renderBackground) { + scope.drawRoundedRectangle(0, 0, dim.width, dim.height, + dim.radius.value, dim.bgColor.value); + } + + hud.renderHud(scope); + scope.getMatrixStack().pop(); + + } else { + // Non-HUD features (e.g. CrosshairFeature) use the plain render hook. + feature.render(scope); + } + } + } +} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/TpsMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/TpsMixin.java similarity index 56% rename from versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/TpsMixin.java rename to versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/TpsMixin.java index 8bcd93a..0c5d010 100644 --- a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/TpsMixin.java +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/modules/mixins/TpsMixin.java @@ -1,4 +1,4 @@ -package org.saturnclient.modules.mixins; +package org.saturnclient.impl.modules.mixins; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; @@ -9,6 +9,17 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +/** + * Feeds world-time packets into {@link TpsFeature}'s TPS estimator. + * + * This is the only place in the entire codebase that reads a network + * packet and passes data to a feature. The feature's + * {@link TpsFeature#onTimePacket(long)} method handles all averaging + * logic; the mixin is intentionally reduced to a single forwarding call. + * + * The only change from the original is renaming the import from + * {@code feature.features.Tps} to {@link TpsFeature}. + */ @Mixin(ClientPlayNetworkHandler.class) public class TpsMixin { diff --git a/versions/1.21.4/src/main/java/org/saturnclient/modules/CameraOverriddenEntity.java b/versions/1.21.4/src/main/java/org/saturnclient/modules/CameraOverriddenEntity.java deleted file mode 100644 index cefd982..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/modules/CameraOverriddenEntity.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.modules; - -public interface CameraOverriddenEntity { - float freelook$getCameraPitch(); - float freelook$getCameraYaw(); - - void freelook$setCameraPitch(float pitch); - void freelook$setCameraYaw(float yaw); -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/modules/HealthRenderState.java b/versions/1.21.4/src/main/java/org/saturnclient/modules/HealthRenderState.java deleted file mode 100644 index 64f1c4c..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/modules/HealthRenderState.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.saturnclient.modules; - -import org.saturnclient.common.module.EntityModule; - -/** - * Mixed into {@link net.minecraft.client.render.entity.state.LivingEntityRenderState} - * by {@link org.saturnclient.modules.mixins.LivingEntityRenderStateMixin}. - * - * Carries the health snapshot and entity classification that - * {@link org.saturnclient.modules.mixins.NametagsMixin} needs without - * accessing the live entity during rendering. - */ -public interface HealthRenderState { - - float saturn$getHealth(); - float saturn$getMaxHealth(); - - void saturn$setHealth(float health, float maxHealth); - - EntityModule.EntityType saturn$getEntityType(); - void saturn$setEntityType(EntityModule.EntityType type); -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/BackgroundRendererMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/BackgroundRendererMixin.java deleted file mode 100644 index 1caea0c..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/BackgroundRendererMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.modules.mixins; - -import net.minecraft.client.render.BackgroundRenderer; -import net.minecraft.entity.Entity; - -import org.saturnclient.feature.features.NoFogFeature; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(BackgroundRenderer.class) -public class BackgroundRendererMixin { - - @ModifyVariable(method = "applyFog", at = @At("HEAD"), ordinal = 0, argsOnly = true) - private static float modifyFogStart(float viewDistance) { - if (NoFogFeature.isActive()) { - return Float.MAX_VALUE; - } - return viewDistance; - } - - @Redirect(method = "applyFog", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;isSpectator()Z")) - private static boolean redirectIsSpectator(Entity entity) { - if (NoFogFeature.isActive() && NoFogFeature.liquids()) { - return true; // pretend to be spectator to bypass liquid fog - } - return entity.isSpectator(); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/CameraMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/CameraMixin.java deleted file mode 100644 index f2309f1..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/CameraMixin.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.saturnclient.modules.mixins; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.Camera; -import net.minecraft.entity.Entity; -import net.minecraft.world.BlockView; - -import org.saturnclient.feature.features.FreelookFeature; -import org.saturnclient.modules.CameraOverriddenEntity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -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(Camera.class) -public abstract class CameraMixin { - - @Unique - private boolean firstTime = true; - - @Shadow - protected abstract void setRotation(float yaw, float pitch); - - @Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER)) - public void lockRotation(BlockView focusedBlock, Entity cameraEntity, - boolean isThirdPerson, boolean isFrontFacing, - float tickDelta, CallbackInfo ci) { - - if (FreelookFeature.isFreeLooking && cameraEntity instanceof ClientPlayerEntity) { - CameraOverriddenEntity overridden = (CameraOverriddenEntity) cameraEntity; - - if (firstTime && MinecraftClient.getInstance().player != null) { - overridden.freelook$setCameraPitch(MinecraftClient.getInstance().player.getPitch()); - overridden.freelook$setCameraYaw(MinecraftClient.getInstance().player.getYaw()); - firstTime = false; - } - - this.setRotation(overridden.freelook$getCameraYaw(), overridden.freelook$getCameraPitch()); - } - - if (!FreelookFeature.isFreeLooking && cameraEntity instanceof ClientPlayerEntity) { - firstTime = true; - } - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/EntityMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/EntityMixin.java deleted file mode 100644 index 934ce78..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/EntityMixin.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.saturnclient.modules.mixins; - -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; - -import org.saturnclient.feature.features.FreelookFeature; -import org.saturnclient.modules.CameraOverriddenEntity; -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(Entity.class) -public class EntityMixin implements CameraOverriddenEntity { - - @Unique - private float cameraPitch; - @Unique - private float cameraYaw; - - @Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true) - public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) { - // noinspection ConstantValue — reachable at runtime despite IDE warning - if (FreelookFeature.isFreeLooking && (Object) this instanceof ClientPlayerEntity) { - this.cameraPitch = MathHelper.clamp( - this.cameraPitch + (float) (yDelta * 0.15), - -90.0f, 90.0f); - this.cameraYaw += (float) (xDelta * 0.15); - ci.cancel(); - } - } - - @Override - @Unique - public float freelook$getCameraPitch() { - return cameraPitch; - } - - @Override - @Unique - public float freelook$getCameraYaw() { - return cameraYaw; - } - - @Override - @Unique - public void freelook$setCameraPitch(float p) { - cameraPitch = p; - } - - @Override - @Unique - public void freelook$setCameraYaw(float y) { - cameraYaw = y; - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/GameRendererMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/GameRendererMixin.java deleted file mode 100644 index b8de0ea..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/GameRendererMixin.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.saturnclient.modules.mixins; - -import net.minecraft.client.render.GameRenderer; - -import org.saturnclient.feature.features.ZoomFeature; -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; - -@Mixin(GameRenderer.class) -public class GameRendererMixin { - - @Inject(method = "getFov", at = @At("RETURN"), cancellable = true) - private void onGetFov(CallbackInfoReturnable cir) { - if (ZoomFeature.shouldZoom()) { - cir.setReturnValue(cir.getReturnValue() / ZoomFeature.getZoomLevel()); - } - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/LivingEntityRenderStateMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/LivingEntityRenderStateMixin.java deleted file mode 100644 index db799b0..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/LivingEntityRenderStateMixin.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.saturnclient.modules.mixins; - -import net.minecraft.client.render.entity.state.LivingEntityRenderState; - -import org.saturnclient.common.module.EntityModule; -import org.saturnclient.modules.HealthRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -/** - * Adds health / entity-type fields to {@link LivingEntityRenderState} so - * that {@link NametagsMixin} can read them without touching the live entity. - * - * The fields are populated each frame by {@link LivingEntityRendererMixin}. - */ -@Mixin(LivingEntityRenderState.class) -public class LivingEntityRenderStateMixin implements HealthRenderState { - - @Unique private float saturn$health = 0f; - @Unique private float saturn$maxHealth = 1f; - @Unique private EntityModule.EntityType saturn$entityType = EntityModule.EntityType.OTHER; - - @Override public float saturn$getHealth() { return saturn$health; } - @Override public float saturn$getMaxHealth() { return saturn$maxHealth; } - - @Override - public void saturn$setHealth(float health, float maxHealth) { - this.saturn$health = health; - this.saturn$maxHealth = maxHealth; - } - - @Override public EntityModule.EntityType saturn$getEntityType() { return saturn$entityType; } - @Override public void saturn$setEntityType(EntityModule.EntityType type) { saturn$entityType = type; } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/NametagsMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/NametagsMixin.java deleted file mode 100644 index e92f0ae..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/NametagsMixin.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.saturnclient.modules.mixins; - -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.Text; - -import org.saturnclient.common.module.EntityModule; -import org.saturnclient.feature.features.NametagsFeature; -import org.saturnclient.modules.HealthRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -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(EntityRenderer.class) -public abstract class NametagsMixin { - - /** - * Guards against infinite recursion: our inject calls - * {@code renderLabelIfPresent} again with the replacement text, so we - * use a thread-local flag to skip re-entry on that second call. - */ - @Unique - private static final ThreadLocal saturn$rendering = ThreadLocal.withInitial(() -> false); - - @Shadow - protected abstract void renderLabelIfPresent( - S state, Text text, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light); - - @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) - private void saturn$replaceNametag( - S state, Text text, - MatrixStack matrices, VertexConsumerProvider vertexConsumers, - int light, CallbackInfo ci) { - - if (saturn$rendering.get()) - return; - if (!NametagsFeature.shouldReplaceName()) - return; - if (!(state instanceof LivingEntityRenderState liv)) - return; - - String replacement = NametagsFeature.getNametagString( - new RenderStateEntityState(liv)); - if (replacement == null) - return; - - ci.cancel(); - saturn$rendering.set(true); - try { - renderLabelIfPresent(state, Text.literal(replacement), - matrices, vertexConsumers, light); - } finally { - saturn$rendering.set(false); - } - } - - // ------------------------------------------------------------------ - // Inner adapter — bridges LivingEntityRenderState → EntityModule.EntityState - // Kept here so the mixin package is self-contained; no separate Fabric - // impl class is needed for this thin adapter. - // ------------------------------------------------------------------ - - @Unique - private static final class RenderStateEntityState implements EntityModule.EntityState { - - private final LivingEntityRenderState state; - private final HealthRenderState hrs; - - RenderStateEntityState(LivingEntityRenderState state) { - this.state = state; - // LivingEntityRenderStateMixin implements HealthRenderState - this.hrs = (state instanceof HealthRenderState h) ? h : null; - } - - @Override - public String getCustomName() { - // The vanilla render state stores the display name as a Text; - // we expose it as a plain string for feature logic. - return state.customName != null ? state.customName.getString() : null; - } - - @Override - public float getHealth() { - return hrs != null ? hrs.saturn$getHealth() : 0f; - } - - @Override - public float getMaxHealth() { - return hrs != null ? hrs.saturn$getMaxHealth() : 1f; - } - - @Override - public EntityModule.EntityType getEntityType() { - return hrs != null ? hrs.saturn$getEntityType() : EntityModule.EntityType.OTHER; - } - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/RenderMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/RenderMixin.java deleted file mode 100644 index b98c6ce..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/modules/mixins/RenderMixin.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.saturnclient.modules.mixins; - -import org.saturnclient.feature.FeatureLayout; -import org.saturnclient.feature.FeatureManager; -import org.saturnclient.feature.HudFeature; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.RenderScopeImpl; -import org.saturnclient.ui.SaturnScreenFabric; -import org.saturnclient.ui.screens.HudEditor; -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; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.render.RenderTickCounter; - -@Mixin(InGameHud.class) -public class RenderMixin { - @Inject(method = "renderChat", at = @At("TAIL")) - public void renderMods(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { - TextRenderer textRenderer = SaturnClient.client.textRenderer; - - if (textRenderer != null && - !(SaturnClient.client.currentScreen instanceof SaturnScreenFabric f && f.screen instanceof HudEditor)) { - RenderScope renderScope = new RenderScopeImpl(context.getMatrices(), - ((DrawContextAccessor) context).getVertexConsumers()); - - for (org.saturnclient.feature.Feature m : FeatureManager.ENABLED_MODS) { - if (m instanceof HudFeature && m.isEnabled()) { - FeatureLayout dim = ((HudFeature) m).getDimensions(); - - renderScope.getMatrixStack().push(); - - renderScope.getMatrixStack().translate(dim.x.value, (float) dim.y.value, 0); - - renderScope.getMatrixStack().scale(dim.scale.value, dim.scale.value, 1.0f); - - if (dim.renderBackground) { - renderScope.drawRoundedRectangle(0, 0, dim.width, dim.height, dim.radius.value, - dim.bgColor.value); - } - - ((HudFeature) m).renderHud(renderScope); - - renderScope.getMatrixStack().pop(); - } else { - m.render(renderScope); - } - } - } - } -} diff --git a/versions/1.21.4/src/main/resources/mods.mixins.json b/versions/1.21.4/src/main/resources/mods.mixins.json index 1b1b619..d8dcade 100644 --- a/versions/1.21.4/src/main/resources/mods.mixins.json +++ b/versions/1.21.4/src/main/resources/mods.mixins.json @@ -4,15 +4,12 @@ "package": "org.saturnclient.modules.mixins", "compatibilityLevel": "JAVA_21", "client": [ - "CameraMixin", - "EntityMixin", - "RenderMixin", - "LightmapTextureManagerMixin", - "BackgroundRendererMixin", "GameRendererMixin", - "NametagsMixin", - "LivingEntityRenderStateMixin", + "LightmapTextureManagerMixin", "LivingEntityRendererMixin", + "LivingEntityRenderStateMixin", + "NametagsMixin", + "RenderMixin", "TpsMixin" ], "injectors": {