feat: move text in replace text colors

This commit is contained in:
Jacob
2025-06-21 19:14:16 +08:00
committed by Linnea Gräf
parent fc640a97d9
commit db0174ca8c
8 changed files with 113 additions and 28 deletions

View File

@@ -1,5 +1,3 @@
package moe.nea.firmament.mixins.accessor;
import net.minecraft.client.gui.screen.ingame.HandledScreen;

View File

@@ -1,6 +1,8 @@
package moe.nea.firmament.features.texturepack
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.gui.screen.ingame.HandledScreen
@@ -8,12 +10,14 @@ import net.minecraft.client.render.RenderLayer
import net.minecraft.resource.ResourceManager
import net.minecraft.resource.SinglePreparationResourceReloader
import net.minecraft.screen.slot.Slot
import net.minecraft.text.Text
import net.minecraft.util.Identifier
import net.minecraft.util.profiler.Profiler
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.mixins.accessor.AccessorHandledScreen
import moe.nea.firmament.util.ErrorUtil.intoCatch
import moe.nea.firmament.util.IdentifierSerializer
@@ -25,6 +29,8 @@ 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()
)
@Serializable
@@ -87,6 +93,55 @@ object CustomScreenLayouts : SinglePreparationResourceReloader<List<CustomScreen
}
}
@Serializable
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 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))
return when (align) {
Alignment.LEFT -> x
Alignment.CENTER -> x + (width - textWidth) / 2
Alignment.RIGHT -> x + (width - textWidth)
}
}
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 mapTextToX(text: Text, x: Int): Int {
return x + if (text.string == "Inventory") activeScreenOverride?.playerTitle?.x
?: 0 else activeScreenOverride?.containerTitle?.x ?: 0
}
fun mapTextToY(text: Text, y: Int): Int {
return y + if (text.string == "Inventory") activeScreenOverride?.playerTitle?.y
?: 0 else activeScreenOverride?.containerTitle?.y ?: 0
}
@Subscribe
fun onStart(event: FinalizeResourceManagerEvent) {

View File

@@ -27,7 +27,8 @@ object CustomTextColors : SinglePreparationResourceReloader<CustomTextColors.Tex
val baseOverride = TextOverride(
StringMatcher.Equals("", false),
defaultColor,
false
0,
0
)
}
@@ -35,7 +36,8 @@ object CustomTextColors : SinglePreparationResourceReloader<CustomTextColors.Tex
data class TextOverride(
val predicate: StringMatcher,
val override: Int,
val hidden: Boolean = false,
val x: Int = 0,
val y: Int = 0,
)
@Subscribe
@@ -43,14 +45,14 @@ object CustomTextColors : SinglePreparationResourceReloader<CustomTextColors.Tex
event.resourceManager.registerReloader(this)
}
val cache = WeakCache.memoize<Text, Optional<Int>>("CustomTextColor") { text ->
val cache = WeakCache.memoize<Text, Optional<TextOverride>>("CustomTextColor") { text ->
val override = textOverrides ?: return@memoize Optional.empty()
Optional.of(override.overrides.find { it.predicate.matches(text) }?.override ?: override.defaultColor)
Optional.ofNullable(override.overrides.find { it.predicate.matches(text) })
}
fun mapTextColor(text: Text, oldColor: Int): Int {
if (textOverrides == null) return oldColor
return cache(text).getOrNull() ?: oldColor
val override = cache(text).orElse(null)
return override?.override ?: textOverrides?.defaultColor ?: oldColor
}
override fun prepare(

View File

@@ -1,9 +1,10 @@
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;
@@ -31,7 +32,8 @@ public class ReplaceTextColorInHandledScreen {
expect = 0,
require = 0)
private int replaceTextColorWithVariableShadow(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, boolean shadow, Operation<Integer> original) {
return original.call(instance, textRenderer, text, x, y, CustomTextColors.INSTANCE.mapTextColor(text, color), shadow);
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(
@@ -42,7 +44,8 @@ public class ReplaceTextColorInHandledScreen {
expect = 0,
require = 0)
private int replaceTextColorWithShadow(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, Operation<Integer> original) {
return original.call(instance, textRenderer, text, x, y, CustomTextColors.INSTANCE.mapTextColor(text, color));
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));
}
}

View File

@@ -13,7 +13,6 @@ import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import java.util.function.Function;
@Mixin(AbstractFurnaceScreen.class)

View File

@@ -1,6 +1,5 @@
package moe.nea.firmament.mixins.custommodels.screenlayouts;
import moe.nea.firmament.features.texturepack.CustomScreenLayouts;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.*;

View File

@@ -1,6 +1,5 @@
package moe.nea.firmament.mixins.custommodels.screenlayouts;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import moe.nea.firmament.features.texturepack.CustomScreenLayouts;
import net.minecraft.client.gui.DrawContext;

View File

@@ -635,22 +635,52 @@ You need to specify an x and y offset relative to where the regular screen would
You can move slots around by a specific index. This is not the index in the inventory, but rather the index in the screen (so if you have a chest screen then all the player inventory slots would be a higher index since the chest slots move them down the list). The x and y are relative to where the regular screen top left would be. Set to large values to effectively "delete" a slot by moving it offscreen.
### Moving window title around
```json
{
"predicates": {
"label": {
"regex": "Hyper Furnace"
}
},
"playerTitle": {
"x": 0,
"y": 0,
"align": "left",
"replace": "a"
}
}
```
You can move the window title around. The x and y are relative to where the text normally is. Set to large values to effectively "delete" a slot by moving it offscreen. playerTitle is the Inventory text where containerTitle is the chest text at the top
### All together
| Field | Required | Description |
|----------------------|----------|--------------------------------------------------------------------------------------------|
| `predicates` | true | A list of predicates that need to match in order to change the layout of a screen |
| `predicates.label` | true | A [string matcher](#string-matcher) for the screen title |
| `background` | false | Allows replacing the background texture |
| `background.texture` | true | The texture of the background as an identifier |
| `background.x` | true | The x offset of the background relative to where the regular background would be rendered. |
| `background.y` | true | The y offset of the background relative to where the regular background would be rendered. |
| `background.width` | true | The width of the background texture. |
| `background.height` | true | The height of the background texture. |
| `slots` | false | An array of slots to move around. |
| `slots[*].index` | true | The index in the array of all slots on the screen (not inventory). |
| `slots[*].x` | true | The x coordinate of the slot relative to the top left of the screen |
| `slots[*].y` | true | The y coordinate of the slot relative to the top left of the screen |
| Field | Required | Description |
|--------------------------|----------|--------------------------------------------------------------------------------------------|
| `predicates` | true | A list of predicates that need to match in order to change the layout of a screen |
| `predicates.label` | true | A [string matcher](#string-matcher) for the screen title |
| `background` | false | Allows replacing the background texture |
| `background.texture` | true | The texture of the background as an identifier |
| `background.x` | true | The x offset of the background relative to where the regular background would be rendered. |
| `background.y` | true | The y offset of the background relative to where the regular background would be rendered. |
| `background.width` | true | The width of the background texture. |
| `background.height` | true | The height of the background texture. |
| `slots` | false | An array of slots to move around. |
| `slots[*].index` | true | The index in the array of all slots on the screen (not inventory). |
| `slots[*].x` | true | The x coordinate of the slot relative to the top left of the screen |
| `slots[*].y` | true | The y coordinate of the slot relative to the top left of the screen |
| `playerTitle` | false | The Inventory title. |
| `playerTitle.x` | false | The x coordinate of the slot relative to the text normally is |
| `playerTitle.y` | false | The y coordinate of the slot relative to the text normally is |
| `playerTitle.align` | false | How you want the text to align. "left", "center" or "right" |
| `playerTitle.replace` | false | Replace window text with your text |
| `containerTitle` | false | The container title (eg chest, ender chest, ect) |
| `containerTitle.x` | false | The x coordinate of the slot relative to the text normally is |
| `containerTitle.y` | false | The y coordinate of the slot relative to the text normally is |
| `containerTitle.align` | false | How you want the text to align. "left", "center" or "right" |
| `containerTitle.replace` | false | Replace window text with your text |
## Global Item Texture Replacement