feat: finished HUD pos conf system

Signed-off-by: moonleay <contact@moonleay.net>
This commit is contained in:
moonleay 2024-05-05 20:03:29 +02:00
parent 5c77165d17
commit 89dee6841a
Signed by: moonleay
GPG key ID: 82667543CCD715FB
7 changed files with 136 additions and 47 deletions

View file

@ -23,6 +23,7 @@ import kotlinx.serialization.Serializable
@Serializable @Serializable
data class GimbalGuiSettings( data class GimbalGuiSettings(
val showHud: Boolean = true, val showHud: Boolean = true,
val scaledRes: ScaledRes = ScaledRes(4.0, 4.0), val offset: ScaledRes = ScaledRes(4.0, 4.0),
val anchorPoint: AnchorPoint = AnchorPoint.TOP_LEFT, val horizontalAnchor: HorizontalAnchor = HorizontalAnchor.LEFT,
val verticalAnchor: VerticalAnchor = VerticalAnchor.TOP,
) )

View file

@ -21,10 +21,8 @@ package net.moonleay.gimbal.client.config
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
enum class AnchorPoint { enum class HorizontalAnchor {
TOP_LEFT, LEFT,
TOP_RIGHT, CENTER,
BOTTOM_RIGHT, RIGHT,
BOTTOM_LEFT,
CENTER
} }

View file

@ -0,0 +1,28 @@
/*
* Gimbal
* Copyright (C) 2024 moonleay
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.moonleay.gimbal.client.config
import kotlinx.serialization.Serializable
@Serializable
enum class VerticalAnchor {
TOP,
CENTER,
BOTTOM,
}

View file

@ -24,7 +24,10 @@ import net.minecraft.client.util.math.MatrixStack
import net.minecraft.screen.ScreenTexts import net.minecraft.screen.ScreenTexts
import net.minecraft.text.Text import net.minecraft.text.Text
import net.moonleay.gimbal.build.BuildConstants import net.moonleay.gimbal.build.BuildConstants
import net.moonleay.gimbal.client.config.* import net.moonleay.gimbal.client.config.ClientConfigHolder
import net.moonleay.gimbal.client.config.GimbalClientConfig
import net.moonleay.gimbal.client.config.GimbalGuiSettings
import net.moonleay.gimbal.client.config.ScaledRes
import net.moonleay.gimbal.client.util.screen.ScreenUtil import net.moonleay.gimbal.client.util.screen.ScreenUtil
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
@ -37,8 +40,8 @@ class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfig
private var shouldFollow = false private var shouldFollow = false
init { init {
this.tempXOffset = cfg.config.guiSettings.scaledRes.scaledX this.tempXOffset = cfg.config.guiSettings.offset.scaledX
this.tempYOffset = cfg.config.guiSettings.scaledRes.scaledY this.tempYOffset = cfg.config.guiSettings.offset.scaledY
} }
override fun init() { override fun init() {
@ -69,14 +72,18 @@ class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfig
} }
LOGGER.info("Saving Pos...") LOGGER.info("Saving Pos...")
val anchor = ScreenUtil.getAnchor(this.tempXOffset, this.tempYOffset)
val newConf = GimbalClientConfig( val newConf = GimbalClientConfig(
showToasts = oldConf.showToasts, showToasts = oldConf.showToasts,
guiSettings = GimbalGuiSettings( guiSettings = GimbalGuiSettings(
showHud = oldConf.guiSettings.showHud, showHud = oldConf.guiSettings.showHud,
scaledRes = ScaledRes( offset = ScaledRes(
scaledX = this.tempXOffset, scaledX = this.tempXOffset,
scaledY = this.tempYOffset, scaledY = this.tempYOffset,
) ),
horizontalAnchor = anchor.first,
verticalAnchor = anchor.second
) )
) )
@ -92,12 +99,14 @@ class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfig
super.tick() super.tick()
if (this.shouldFollow) { if (this.shouldFollow) {
val mouse = this.client?.mouse!! val mouse = this.client?.mouse!!
val scaleFactor = this.client!!.window.calculateScaleFactor( val wantedX = ScreenUtil.getScaled(this.client!!.window.width, mouse.x.toFloat())
this.client!!.options.guiScale.value, val wantedY = ScreenUtil.getScaled(this.client!!.window.height, mouse.y.toFloat())
this.client!!.forcesUnicodeFont() if (!ScreenUtil.isPositionOutOfBounds(wantedX, wantedY)) {
) this.tempXOffset = wantedX
this.tempXOffset = ScreenUtil.getScaled(this.width, mouse.x.toFloat() / scaleFactor) this.tempYOffset = wantedY
this.tempYOffset = ScreenUtil.getScaled(this.height, mouse.y.toFloat() / scaleFactor) } else {
LOGGER.info("Text is oob. wantedX: ${wantedX}, wantedY: ${wantedY}, width: ${this.client!!.window.width}, height: ${this.client!!.window.height}")
}
} }
} }
@ -114,22 +123,30 @@ class GimbalEditHudGui(private val parent: Screen, private val cfg: ClientConfig
override fun render(matrices: MatrixStack?, mouseX: Int, mouseY: Int, delta: Float) { override fun render(matrices: MatrixStack?, mouseX: Int, mouseY: Int, delta: Float) {
this.renderBackground(matrices) this.renderBackground(matrices)
drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 15, 16777215) drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 15, 16777215)
val scaleFactor = this.client!!.window.calculateScaleFactor(
this.client!!.options.guiScale.value,
this.client!!.forcesUnicodeFont()
)
val anchor = ScreenUtil.getAnchor(this.tempXOffset, this.tempYOffset)
this.textRenderer.drawWithShadow( this.textRenderer.drawWithShadow(
matrices, matrices,
Text.translatable("gimbal.gui.examplehud"), Text.translatable("gimbal.gui.examplehud"),
ScreenUtil.getXForRender( ScreenUtil.getXForAnchor(
ScreenUtil.getReal(this.width, this.tempXOffset), ScreenUtil.getReal(this.client!!.window.width, this.tempXOffset) / scaleFactor,
AnchorPoint.CENTER, anchor.first,
this.textRenderer.getWidth(Text.translatable("gimbal.gui.examplehud")) this.textRenderer.getWidth(Text.translatable("gimbal.gui.examplehud"))
), ),
ScreenUtil.getYForRender( ScreenUtil.getYForAnchor(
ScreenUtil.getReal(this.height, this.tempYOffset), ScreenUtil.getReal(this.client!!.window.height, this.tempYOffset) / scaleFactor,
AnchorPoint.CENTER, anchor.second,
this.textRenderer.fontHeight this.textRenderer.fontHeight
), ),
0xFFFFFF 0xFFFFFF
) // TODO: improve placement when changing the scaling ) // TODO: improve placement when changing the scaling
// LOGGER.info("width: ${this.width}, height: ${this.height}, posX: ${ScreenUtil.getReal(this.width, this.tempXOffset)}, posY: ${ScreenUtil.getReal(this.height, this.tempYOffset)}, scaleX: ${this.tempXOffset}, scaleY: ${this.tempYOffset}") // LOGGER.info("width: ${this.width}, height: ${this.height}," +
// " posX: ${ScreenUtil.getReal(this.width, this.tempXOffset)}," +
// " posY: ${ScreenUtil.getReal(this.height, this.tempYOffset)}," +
// " scaleX: ${this.tempXOffset}, scaleY: ${this.tempYOffset}")
super.render(matrices, mouseX, mouseY, delta) super.render(matrices, mouseX, mouseY, delta)
} }
} }

View file

@ -46,8 +46,9 @@ class GimbalSettingsGui(private val parent: Screen, private val cfg: ClientConfi
val oldGui = cfg.config.guiSettings val oldGui = cfg.config.guiSettings
val newGui = GimbalGuiSettings( val newGui = GimbalGuiSettings(
showHud = isEnabled ?: true, showHud = isEnabled ?: true,
scaledRes = oldGui.scaledRes, offset = oldGui.offset,
anchorPoint = oldGui.anchorPoint horizontalAnchor = oldGui.horizontalAnchor,
verticalAnchor = oldGui.verticalAnchor,
) )
val newConf = GimbalClientConfig( val newConf = GimbalClientConfig(
guiSettings = newGui, guiSettings = newGui,

View file

@ -18,27 +18,37 @@
package net.moonleay.gimbal.client.util.screen package net.moonleay.gimbal.client.util.screen
import net.moonleay.gimbal.client.config.AnchorPoint import net.moonleay.gimbal.client.config.HorizontalAnchor
import net.moonleay.gimbal.client.config.VerticalAnchor
object ScreenUtil { object ScreenUtil {
fun getXForRender(x: Float, anchor: AnchorPoint, textWidth: Int): Float { fun getAnchor(x: Double, y: Double): Pair<HorizontalAnchor, VerticalAnchor> {
return when (anchor) { return when (x) {
AnchorPoint.TOP_LEFT -> x in 0.0..<34.0 -> HorizontalAnchor.LEFT
AnchorPoint.BOTTOM_LEFT -> x in 34.0..<67.0 -> HorizontalAnchor.CENTER
AnchorPoint.TOP_RIGHT -> x - textWidth else -> HorizontalAnchor.RIGHT
AnchorPoint.BOTTOM_RIGHT -> x - textWidth } to when (y) {
AnchorPoint.CENTER -> x - textWidth / 2 in 0.0..<34.0 -> VerticalAnchor.TOP
in 34.0..<67.0 -> VerticalAnchor.CENTER
else -> VerticalAnchor.BOTTOM
} }
} }
fun getYForRender(y: Float, anchor: AnchorPoint, textHeight: Int): Float { fun getXForAnchor(x: Float, anchor: HorizontalAnchor, textWidth: Int): Float {
return when (anchor) { return when (anchor) {
AnchorPoint.TOP_LEFT -> y HorizontalAnchor.LEFT -> x
AnchorPoint.TOP_RIGHT -> y HorizontalAnchor.CENTER -> x - (textWidth / 2)
AnchorPoint.BOTTOM_RIGHT -> y - textHeight HorizontalAnchor.RIGHT -> x - textWidth
AnchorPoint.BOTTOM_LEFT -> y - textHeight }
AnchorPoint.CENTER -> y - textHeight / 2 }
fun getYForAnchor(y: Float, anchor: VerticalAnchor, textHeight: Int): Float {
return when (anchor) {
VerticalAnchor.TOP -> y
VerticalAnchor.CENTER -> y - (textHeight / 2)
VerticalAnchor.BOTTOM -> y - textHeight
} }
} }

View file

@ -22,7 +22,11 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.hud.InGameHud; import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
import net.moonleay.gimbal.client.ClientMain;
import net.moonleay.gimbal.client.config.GimbalGuiSettings;
import net.moonleay.gimbal.client.editor.ClientEditor; import net.moonleay.gimbal.client.editor.ClientEditor;
import net.moonleay.gimbal.client.util.screen.ScreenUtil;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@ -31,16 +35,46 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(InGameHud.class) @Mixin(InGameHud.class)
public class HudMixin { public abstract class HudMixin {
@Shadow @Final private MinecraftClient client; @Shadow @Final private MinecraftClient client;
@Shadow
private int scaledHeight;
@Shadow
public abstract void clear();
@Inject(method = "renderStatusEffectOverlay", at = @At("HEAD")) @Inject(method = "renderStatusEffectOverlay", at = @At("HEAD"))
private void render(MatrixStack matrices, CallbackInfo ci) { private void render(MatrixStack matrices, CallbackInfo ci) {
TextRenderer tr = this.client.textRenderer; TextRenderer tr = this.client.textRenderer;
tr.drawWithShadow(matrices, GimbalGuiSettings conf = ClientMain.CONFIG.getConfig().getGuiSettings();
ClientEditor.INSTANCE.getModeDisplayText(), if (!conf.getShowHud())
4, 4, return;
ClientEditor.INSTANCE.getCurrentColor()); int scaleFactor = this.client.getWindow()
.calculateScaleFactor(
this.client.options.getGuiScale().getValue(),
this.client.forcesUnicodeFont()
);
Text displayText = ClientEditor.INSTANCE.getModeDisplayText();
tr.drawWithShadow(
matrices,
displayText,
ScreenUtil.INSTANCE.getXForAnchor(
ScreenUtil.INSTANCE.getReal(
this.client.getWindow().getWidth(),
conf.getOffset().getScaledX() / scaleFactor),
conf.getHorizontalAnchor(),
this.client.textRenderer.getWidth(displayText)
),
ScreenUtil.INSTANCE.getYForAnchor(
ScreenUtil.INSTANCE.getReal(
this.client.getWindow().getHeight(),
conf.getOffset().getScaledY() / scaleFactor),
conf.getVerticalAnchor(),
this.client.textRenderer.fontHeight
),
ClientEditor.INSTANCE.getCurrentColor()
);
} }
} }