diff options
| author | Linnea Gräf <nea@nea.moe> | 2025-06-20 15:49:15 +0200 |
|---|---|---|
| committer | Linnea Gräf <nea@nea.moe> | 2025-06-20 15:49:15 +0200 |
| commit | 286691c54c87b5e2e70eef7b51469b4ade5a75f6 (patch) | |
| tree | a4812f2afe10d836b5682c5c957abcff674db676 /src/texturePacks/java/moe/nea/firmament/features | |
| parent | 54a76553a7ebda48f223b7a005466345e3c4774d (diff) | |
| download | Firmament-286691c54c87b5e2e70eef7b51469b4ade5a75f6.tar.gz Firmament-286691c54c87b5e2e70eef7b51469b4ade5a75f6.tar.bz2 Firmament-286691c54c87b5e2e70eef7b51469b4ade5a75f6.zip | |
feat: Add screen layout replacement feature for texture packs
Diffstat (limited to 'src/texturePacks/java/moe/nea/firmament/features')
3 files changed, 156 insertions, 1 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 new file mode 100644 index 0000000..ec696ec --- /dev/null +++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomScreenLayouts.kt @@ -0,0 +1,142 @@ +package moe.nea.firmament.features.texturepack + +import kotlinx.serialization.Serializable +import net.minecraft.client.gui.DrawContext +import net.minecraft.client.gui.screen.Screen +import net.minecraft.client.gui.screen.ingame.HandledScreen +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.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.mixins.accessor.AccessorHandledScreen +import moe.nea.firmament.util.ErrorUtil.intoCatch +import moe.nea.firmament.util.IdentifierSerializer + +object CustomScreenLayouts : SinglePreparationResourceReloader<List<CustomScreenLayouts.CustomScreenLayout>>() { + + @Serializable + data class CustomScreenLayout( + val predicates: Preds, + val background: BackgroundReplacer? = null, + val slots: List<SlotReplacer> = listOf(), + ) + + @Serializable + data class Preds( + val label: StringMatcher, + ) { + fun matches(screen: Screen): Boolean { + // TODO: does this deserve the restriction to handled screen + val s = screen as? HandledScreen<*>? ?: return false + return label.matches(s.title) + } + } + + @Serializable + data class BackgroundReplacer( + @Serializable(with = IdentifierSerializer::class) + val texture: Identifier, + // TODO: allow selectively still rendering some components (recipe button, trade backgrounds, furnace flame progress, arrows) + val x: Int, + val y: Int, + val width: Int, + val height: Int, + ) { + fun renderGeneric(context: DrawContext, screen: HandledScreen<*>) { + screen as AccessorHandledScreen + val originalX: Int = (screen.width - screen.backgroundWidth_Firmament) / 2 + val originalY: Int = (screen.height - screen.backgroundHeight_Firmament) / 2 + val modifiedX = originalX + this.x + val modifiedY = originalY + this.y + val textureWidth = this.width + val textureHeight = this.height + context.drawTexture( + RenderLayer::getGuiTextured, + this.texture, + modifiedX, + modifiedY, + 0.0f, + 0.0f, + textureWidth, + textureHeight, + textureWidth, + textureHeight + ) + + } + } + + @Serializable + data class SlotReplacer( + // TODO: override getRecipeBookButtonPos as well + // TODO: is this index or id (i always forget which one is duplicated per inventory) + val index: Int, + val x: Int, + val y: Int, + ) { + fun move(slots: List<Slot>) { + val slot = slots.getOrNull(index) ?: return + slot.x = x + slot.y = y + } + } + + + @Subscribe + fun onStart(event: FinalizeResourceManagerEvent) { + event.resourceManager.registerReloader(CustomScreenLayouts) + } + + override fun prepare( + manager: ResourceManager, + profiler: Profiler + ): List<CustomScreenLayout> { + val allScreenLayouts = manager.findResources( + "overrides/screen_layout", + { it.path.endsWith(".json") && it.namespace == "firmskyblock" }) + val allParsedLayouts = allScreenLayouts.mapNotNull { (path, stream) -> + Firmament.tryDecodeJsonFromStream<CustomScreenLayout>(stream.inputStream) + .intoCatch("Could not read custom screen layout from $path").orNull() + } + return allParsedLayouts + } + + var customScreenLayouts = listOf<CustomScreenLayout>() + + override fun apply( + prepared: List<CustomScreenLayout>, + manager: ResourceManager?, + profiler: Profiler? + ) { + this.customScreenLayouts = prepared + } + + @get:JvmStatic + var activeScreenOverride = null as CustomScreenLayout? + + @Subscribe + fun onScreenOpen(event: ScreenChangeEvent) { + if (!CustomSkyBlockTextures.TConfig.allowLayoutChanges) { + activeScreenOverride = null + return + } + activeScreenOverride = event.new?.let { screen -> + customScreenLayouts.find { it.predicates.matches(screen) } + } + + val screen = event.new as? HandledScreen<*> ?: return + val handler = screen.screenHandler + activeScreenOverride?.let { override -> + override.slots.forEach { slotReplacer -> + slotReplacer.move(handler.slots) + } + } + } + +} diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt index cf2a232..18949ff 100644 --- a/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt +++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt @@ -36,6 +36,7 @@ object CustomSkyBlockTextures : FirmamentFeature { val enableLegacyMinecraftCompat by toggle("legacy-minecraft-path-support") { true } val enableLegacyCIT by toggle("legacy-cit") { true } val allowRecoloringUiText by toggle("recolor-text") { true } + val allowLayoutChanges by toggle("screen-layouts") { true } } override val config: ManagedConfig diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomTextColors.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomTextColors.kt index 4ca1796..1fcee48 100644 --- a/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomTextColors.kt +++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomTextColors.kt @@ -2,6 +2,7 @@ package moe.nea.firmament.features.texturepack import java.util.Optional import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient import kotlin.jvm.optionals.getOrNull import net.minecraft.resource.ResourceManager import net.minecraft.resource.SinglePreparationResourceReloader @@ -18,12 +19,23 @@ object CustomTextColors : SinglePreparationResourceReloader<CustomTextColors.Tex data class TextOverrides( val defaultColor: Int, val overrides: List<TextOverride> = listOf() - ) + ) { + /** + * Stub custom text color to allow always returning a text override + */ + @Transient + val baseOverride = TextOverride( + StringMatcher.Equals("", false), + defaultColor, + false + ) + } @Serializable data class TextOverride( val predicate: StringMatcher, val override: Int, + val hidden: Boolean = false, ) @Subscribe |
