aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2025-06-22 14:51:38 +0200
committerLinnea Gräf <nea@nea.moe>2025-06-22 14:54:02 +0200
commit4cfba87783a7280678312ac42373eb639c86a62a (patch)
treeb721e53fb8de4826c2f46ac98b75210d0e081af3 /src
parentdb0174ca8c391e0b46cd013c53602679f99af398 (diff)
downloadFirmament-4cfba87783a7280678312ac42373eb639c86a62a.tar.gz
Firmament-4cfba87783a7280678312ac42373eb639c86a62a.tar.bz2
Firmament-4cfba87783a7280678312ac42373eb639c86a62a.zip
feat: Add interactive component movers + fix: move coordinates
Diffstat (limited to 'src')
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomScreenLayouts.kt86
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceTextColorInHandledScreen.java51
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplaceAnvilScreen.java55
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplaceForgingScreen.java9
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplacePlayerBackgrounds.java17
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplaceTextColorInHandledScreen.java65
6 files changed, 200 insertions, 83 deletions
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomScreenLayouts.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomScreenLayouts.kt
index 76047b4..a68fb2a 100644
--- a/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomScreenLayouts.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomScreenLayouts.kt
@@ -2,7 +2,8 @@ package moe.nea.firmament.features.texturepack
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
-import net.minecraft.client.MinecraftClient
+import kotlinx.serialization.Transient
+import net.minecraft.client.font.TextRenderer
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.gui.screen.ingame.HandledScreen
@@ -17,7 +18,9 @@ import moe.nea.firmament.Firmament
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.FinalizeResourceManagerEvent
import moe.nea.firmament.events.ScreenChangeEvent
-import moe.nea.firmament.features.texturepack.CustomTextColors.cache
+import moe.nea.firmament.features.texturepack.CustomScreenLayouts.Alignment.CENTER
+import moe.nea.firmament.features.texturepack.CustomScreenLayouts.Alignment.LEFT
+import moe.nea.firmament.features.texturepack.CustomScreenLayouts.Alignment.RIGHT
import moe.nea.firmament.mixins.accessor.AccessorHandledScreen
import moe.nea.firmament.util.ErrorUtil.intoCatch
import moe.nea.firmament.util.IdentifierSerializer
@@ -29,8 +32,18 @@ object CustomScreenLayouts : SinglePreparationResourceReloader<List<CustomScreen
val predicates: Preds,
val background: BackgroundReplacer? = null,
val slots: List<SlotReplacer> = listOf(),
- val playerTitle: TitleReplacer = TitleReplacer(),
- val containerTitle: TitleReplacer = TitleReplacer()
+ val playerTitle: TitleReplacer? = null,
+ val containerTitle: TitleReplacer? = null,
+ val repairCostTitle: TitleReplacer? = null,
+ val nameField: ComponentMover? = null,
+ )
+
+ @Serializable
+ data class ComponentMover(
+ val x: Int,
+ val y: Int,
+ val width: Int? = null,
+ val height: Int? = null,
)
@Serializable
@@ -97,49 +110,48 @@ object CustomScreenLayouts : SinglePreparationResourceReloader<List<CustomScreen
enum class Alignment {
@SerialName("left")
LEFT,
+
@SerialName("center")
CENTER,
+
@SerialName("right")
RIGHT
}
@Serializable
data class TitleReplacer(
- val x: Int = 0,
- val y: Int = 0,
+ val x: Int? = null,
+ val y: Int? = null,
val align: Alignment = Alignment.LEFT,
val replace: String? = null
- )
-
- fun alignText(text: Text, x: Int, width: Int): Int {
- var currentText = mapReplaceText(text)
- val align = if (currentText.string == "Inventory") activeScreenOverride?.playerTitle?.align ?: Alignment.LEFT
- else activeScreenOverride?.containerTitle?.align ?: Alignment.LEFT
-
- val textWidth = MinecraftClient.getInstance().textRenderer.getWidth(Text.literal(currentText.string))
-
+ ) {
+ @Transient
+ val replacedText: Text? = replace?.let(Text::literal)
- return when (align) {
- Alignment.LEFT -> x
- Alignment.CENTER -> x + (width - textWidth) / 2
- Alignment.RIGHT -> x + (width - textWidth)
+ fun replaceText(text: Text): Text {
+ if (replacedText != null) return replacedText
+ return text
}
- }
- fun mapReplaceText(text: Text): Text {
- val replaceText = if (text.string == "Inventory") activeScreenOverride?.playerTitle?.replace ?: null else activeScreenOverride?.containerTitle?.replace ?: null
- if (replaceText == null) return text
- return Text.literal(replaceText)
- }
+ fun replaceY(y: Int): Int {
+ return this.y ?: y
+ }
- fun mapTextToX(text: Text, x: Int): Int {
- return x + if (text.string == "Inventory") activeScreenOverride?.playerTitle?.x
- ?: 0 else activeScreenOverride?.containerTitle?.x ?: 0
- }
+ fun replaceX(font: TextRenderer, text: Text, x: Int): Int {
+ val baseX = this.x ?: x
+ return baseX + when (this.align) {
+ LEFT -> 0
+ CENTER -> -font.getWidth(text) / 2
+ RIGHT -> -font.getWidth(text)
+ }
+ }
- fun mapTextToY(text: Text, y: Int): Int {
- return y + if (text.string == "Inventory") activeScreenOverride?.playerTitle?.y
- ?: 0 else activeScreenOverride?.containerTitle?.y ?: 0
+ /**
+ * Not technically part of the package, but it does allow for us to later on seamlessly integrate a color option into this class as well
+ */
+ fun replaceColor(text: Text, color: Int): Int {
+ return CustomTextColors.mapTextColor(text, color)
+ }
}
@@ -175,6 +187,16 @@ object CustomScreenLayouts : SinglePreparationResourceReloader<List<CustomScreen
@get:JvmStatic
var activeScreenOverride = null as CustomScreenLayout?
+ val DO_NOTHING_TEXT_REPLACER = TitleReplacer()
+
+ @JvmStatic
+ fun <T>getMover(selector: (CustomScreenLayout)-> (T?)) =
+ activeScreenOverride?.let(selector)
+
+ @JvmStatic
+ fun getTextMover(selector: (CustomScreenLayout) -> (TitleReplacer?)) =
+ getMover(selector) ?: DO_NOTHING_TEXT_REPLACER
+
@Subscribe
fun onScreenOpen(event: ScreenChangeEvent) {
if (!CustomSkyBlockTextures.TConfig.allowLayoutChanges) {
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceTextColorInHandledScreen.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceTextColorInHandledScreen.java
deleted file mode 100644
index 3cdc7d8..0000000
--- a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceTextColorInHandledScreen.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import moe.nea.firmament.features.texturepack.CustomScreenLayouts;
-import moe.nea.firmament.features.texturepack.CustomTextColors;
-import moe.nea.firmament.mixins.accessor.AccessorHandledScreen;
-import net.minecraft.client.font.TextRenderer;
-import net.minecraft.client.gui.DrawContext;
-import net.minecraft.client.gui.screen.ingame.AnvilScreen;
-import net.minecraft.client.gui.screen.ingame.BeaconScreen;
-import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
-import net.minecraft.client.gui.screen.ingame.HandledScreen;
-import net.minecraft.client.gui.screen.ingame.InventoryScreen;
-import net.minecraft.client.gui.screen.ingame.MerchantScreen;
-import net.minecraft.text.Text;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-@Mixin({HandledScreen.class, InventoryScreen.class, CreativeInventoryScreen.class, MerchantScreen.class,
- AnvilScreen.class, BeaconScreen.class})
-public class ReplaceTextColorInHandledScreen {
-
- // To my future self: double check those mixins, but don't be too concerned about errors. Some of the wrapopertions
- // only apply in some of the specified subclasses.
-
- @WrapOperation(
- method = "drawForeground",
- at = @At(
- value = "INVOKE",
- target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;IIIZ)I"),
- expect = 0,
- require = 0)
- private int replaceTextColorWithVariableShadow(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, boolean shadow, Operation<Integer> original) {
- int width = ((AccessorHandledScreen) this).getBackgroundWidth_Firmament();
- return original.call(instance, textRenderer, CustomScreenLayouts.INSTANCE.mapReplaceText(text), CustomScreenLayouts.INSTANCE.alignText(text, CustomScreenLayouts.INSTANCE.mapTextToX(text, x), width), CustomScreenLayouts.INSTANCE.mapTextToY(text, y), CustomTextColors.INSTANCE.mapTextColor(text, color), shadow);
- }
-
- @WrapOperation(
- method = "drawForeground",
- at = @At(
- value = "INVOKE",
- target = "Lnet/minecraft/client/gui/DrawContext;drawTextWithShadow(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;III)I"),
- expect = 0,
- require = 0)
- private int replaceTextColorWithShadow(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, Operation<Integer> original) {
- int width = ((AccessorHandledScreen) this).getBackgroundWidth_Firmament();
- return original.call(instance, textRenderer, CustomScreenLayouts.INSTANCE.mapReplaceText(text), CustomScreenLayouts.INSTANCE.alignText(text, CustomScreenLayouts.INSTANCE.mapTextToX(text, x), width), CustomScreenLayouts.INSTANCE.mapTextToY(text, y), CustomTextColors.INSTANCE.mapTextColor(text, color));
- }
-
-}
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplaceAnvilScreen.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplaceAnvilScreen.java
new file mode 100644
index 0000000..7c5dc45
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplaceAnvilScreen.java
@@ -0,0 +1,55 @@
+package moe.nea.firmament.mixins.custommodels.screenlayouts;
+
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import moe.nea.firmament.features.texturepack.CustomScreenLayouts;
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.ingame.AnvilScreen;
+import net.minecraft.client.gui.screen.ingame.ForgingScreen;
+import net.minecraft.client.gui.widget.TextFieldWidget;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.screen.AnvilScreenHandler;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(AnvilScreen.class)
+public abstract class ReplaceAnvilScreen extends ForgingScreen<AnvilScreenHandler> {
+ @Shadow
+ private TextFieldWidget nameField;
+
+ public ReplaceAnvilScreen(AnvilScreenHandler handler, PlayerInventory playerInventory, Text title, Identifier texture) {
+ super(handler, playerInventory, title, texture);
+ }
+
+ @Inject(method = "setup", at = @At("TAIL"))
+ private void moveNameField(CallbackInfo ci) {
+ var override = CustomScreenLayouts.getMover(CustomScreenLayouts.CustomScreenLayout::getNameField);
+ if (override == null) return;
+ int baseX = (this.width - this.backgroundWidth) / 2;
+ int baseY = (this.height - this.backgroundHeight) / 2;
+ nameField.setX(baseX + override.getX());
+ nameField.setY(baseY + override.getY());
+ if (override.getWidth() != null)
+ nameField.setWidth(override.getWidth());
+ if (override.getHeight() != null)
+ nameField.setHeight(override.getHeight());
+ }
+
+ @WrapOperation(method = "drawForeground",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawTextWithShadow(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;III)I"),
+ allow = 1)
+ private int onDrawRepairCost(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, Operation<Integer> original) {
+ var textOverride = CustomScreenLayouts.getTextMover(CustomScreenLayouts.CustomScreenLayout::getRepairCostTitle);
+ return original.call(instance, textRenderer,
+ textOverride.replaceText(text),
+ textOverride.replaceX(textRenderer, text, x),
+ textOverride.replaceY(y),
+ textOverride.replaceColor(text, color));
+ }
+}
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplaceForgingScreen.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplaceForgingScreen.java
new file mode 100644
index 0000000..6e9023d
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplaceForgingScreen.java
@@ -0,0 +1,9 @@
+package moe.nea.firmament.mixins.custommodels.screenlayouts;
+
+import net.minecraft.client.gui.screen.ingame.ForgingScreen;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.Inject;
+
+@Mixin(ForgingScreen.class)
+public class ReplaceForgingScreen {
+}
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplacePlayerBackgrounds.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplacePlayerBackgrounds.java
index b631dbd..e02a821 100644
--- a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplacePlayerBackgrounds.java
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplacePlayerBackgrounds.java
@@ -1,7 +1,10 @@
package moe.nea.firmament.mixins.custommodels.screenlayouts;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import moe.nea.firmament.features.texturepack.CustomScreenLayouts;
+import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.InventoryScreen;
import net.minecraft.client.gui.screen.ingame.RecipeBookScreen;
@@ -22,6 +25,20 @@ public abstract class ReplacePlayerBackgrounds extends RecipeBookScreen<PlayerSc
super(handler, recipeBook, inventory, title);
}
+
+ @WrapOperation(method = "drawForeground",
+ allow = 1,
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;IIIZ)I"))
+ private int onDrawForegroundText(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, boolean shadow, Operation<Integer> original) {
+ var textOverride = CustomScreenLayouts.getTextMover(CustomScreenLayouts.CustomScreenLayout::getContainerTitle);
+ return original.call(instance, textRenderer,
+ textOverride.replaceText(text),
+ textOverride.replaceX(textRenderer, text, x),
+ textOverride.replaceY(y),
+ textOverride.replaceColor(text, color),
+ shadow);
+ }
+
@WrapWithCondition(method = "drawBackground", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawTexture(Ljava/util/function/Function;Lnet/minecraft/util/Identifier;IIFFIIII)V"))
private boolean onDrawBackground(DrawContext instance, Function<Identifier, RenderLayer> renderLayers, Identifier sprite, int x, int y, float u, float v, int width, int height, int textureWidth, int textureHeight) {
final var override = CustomScreenLayouts.getActiveScreenOverride();
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplaceTextColorInHandledScreen.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplaceTextColorInHandledScreen.java
new file mode 100644
index 0000000..8f6f7a5
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/screenlayouts/ReplaceTextColorInHandledScreen.java
@@ -0,0 +1,65 @@
+package moe.nea.firmament.mixins.custommodels.screenlayouts;
+
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import moe.nea.firmament.features.texturepack.CustomScreenLayouts;
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.ingame.AnvilScreen;
+import net.minecraft.client.gui.screen.ingame.BeaconScreen;
+import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
+import net.minecraft.client.gui.screen.ingame.InventoryScreen;
+import net.minecraft.client.gui.screen.ingame.MerchantScreen;
+import net.minecraft.text.Text;
+import org.objectweb.asm.Opcodes;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Slice;
+
+@Mixin(HandledScreen.class)
+// TODO: MerchantScreen.class, BeaconScreen.class
+public class ReplaceTextColorInHandledScreen {
+
+ @WrapOperation(
+ method = "drawForeground",
+ at = @At(
+ value = "INVOKE",
+ target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;IIIZ)I"),
+ slice = @Slice(
+ from = @At(value = "FIELD", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;title:Lnet/minecraft/text/Text;", opcode = Opcodes.GETFIELD),
+ to = @At(value = "FIELD", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;playerInventoryTitle:Lnet/minecraft/text/Text;", opcode = Opcodes.GETFIELD)
+ ),
+ allow = 1,
+ require = 1)
+ private int replaceContainerTitle(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, boolean shadow, Operation<Integer> original) {
+ var textOverride = CustomScreenLayouts.getTextMover(CustomScreenLayouts.CustomScreenLayout::getContainerTitle);
+ return original.call(instance, textRenderer,
+ textOverride.replaceText(text),
+ textOverride.replaceX(textRenderer, text, x),
+ textOverride.replaceY(y),
+ textOverride.replaceColor(text, color),
+ shadow);
+ }
+
+ @WrapOperation(
+ method = "drawForeground",
+ at = @At(
+ value = "INVOKE",
+ target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;IIIZ)I"),
+ slice = @Slice(
+ from = @At(value = "FIELD", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;playerInventoryTitle:Lnet/minecraft/text/Text;", opcode = Opcodes.GETFIELD),
+ to = @At(value = "TAIL")
+ ),
+ allow = 1,
+ require = 1)
+ private int replacePlayerShadow(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, boolean shadow, Operation<Integer> original) {
+ var textOverride = CustomScreenLayouts.getTextMover(CustomScreenLayouts.CustomScreenLayout::getContainerTitle);
+ return original.call(instance, textRenderer,
+ textOverride.replaceText(text),
+ textOverride.replaceX(textRenderer, text, x),
+ textOverride.replaceY(y),
+ textOverride.replaceColor(text, color),
+ shadow);
+ }
+}