diff options
Diffstat (limited to 'src/main/kotlin')
61 files changed, 1014 insertions, 492 deletions
diff --git a/src/main/kotlin/Firmament.kt b/src/main/kotlin/Firmament.kt index b00546a..83cc259 100644 --- a/src/main/kotlin/Firmament.kt +++ b/src/main/kotlin/Firmament.kt @@ -74,6 +74,7 @@ object Firmament { prettyPrint = DEBUG isLenient = true allowTrailingComma = true + allowComments = true ignoreUnknownKeys = true encodeDefaults = true prettyPrintIndent = if (prettyPrint) "\t" else DEFAULT_JSON_INDENT @@ -91,7 +92,6 @@ object Firmament { prettyPrint = false // Reset pretty print indent back to default to prevent getting yelled at by json prettyPrintIndent = DEFAULT_JSON_INDENT - encodeDefaults = false explicitNulls = false } diff --git a/src/main/kotlin/features/chat/ChatLinks.kt b/src/main/kotlin/features/chat/ChatLinks.kt index 1fb12e1..28c526f 100644 --- a/src/main/kotlin/features/chat/ChatLinks.kt +++ b/src/main/kotlin/features/chat/ChatLinks.kt @@ -8,6 +8,7 @@ import java.net.URL import java.util.Collections import java.util.concurrent.atomic.AtomicInteger import moe.nea.jarvis.api.Point +import org.joml.Vector2i import kotlinx.coroutines.Deferred import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.async @@ -27,6 +28,7 @@ import moe.nea.firmament.events.ModifyChatEvent import moe.nea.firmament.events.ScreenRenderPostEvent import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.gui.config.ManagedConfig +import moe.nea.firmament.jarvis.JarvisIntegration import moe.nea.firmament.util.MC import moe.nea.firmament.util.render.drawTexture import moe.nea.firmament.util.transformEachRecursively @@ -42,7 +44,7 @@ object ChatLinks : FirmamentFeature { val allowAllHosts by toggle("allow-all-hosts") { false } val allowedHosts by string("allowed-hosts") { "cdn.discordapp.com,media.discordapp.com,media.discordapp.net,i.imgur.com" } val actualAllowedHosts get() = allowedHosts.split(",").map { it.trim() } - val position by position("position", 16 * 20, 9 * 20) { Point(0.0, 0.0) } + val position by position("position", 16 * 20, 9 * 20) { Vector2i(0, 0) } } private fun isHostAllowed(host: String) = @@ -110,11 +112,11 @@ object ChatLinks : FirmamentFeature { val imageFuture = imageCache[url] ?: return if (!imageFuture.isCompleted) return val image = imageFuture.getCompleted() ?: return - it.drawContext.matrices.push() + it.drawContext.matrices.pushMatrix() val pos = TConfig.position - pos.applyTransformations(it.drawContext.matrices) + pos.applyTransformations(JarvisIntegration.jarvis, it.drawContext.matrices) val scale = min(1F, min((9 * 20F) / image.height, (16 * 20F) / image.width)) - it.drawContext.matrices.scale(scale, scale, 1F) + it.drawContext.matrices.scale(scale, scale) it.drawContext.drawTexture( image.texture, 0, @@ -126,7 +128,7 @@ object ChatLinks : FirmamentFeature { image.width, image.height, ) - it.drawContext.matrices.pop() + it.drawContext.matrices.popMatrix() } @Subscribe diff --git a/src/main/kotlin/features/debug/ExportedTestConstantMeta.kt b/src/main/kotlin/features/debug/ExportedTestConstantMeta.kt index f0250dc..bdc1f9a 100644 --- a/src/main/kotlin/features/debug/ExportedTestConstantMeta.kt +++ b/src/main/kotlin/features/debug/ExportedTestConstantMeta.kt @@ -12,7 +12,7 @@ data class ExportedTestConstantMeta( ) { companion object { val current = ExportedTestConstantMeta( - SharedConstants.getGameVersion().saveVersion.id, + SharedConstants.getGameVersion().dataVersion().id, Optional.of("Firmament ${Firmament.version.friendlyString}") ) diff --git a/src/main/kotlin/features/debug/itemeditor/ItemExporter.kt b/src/main/kotlin/features/debug/itemeditor/ItemExporter.kt index 2a56204..386a741 100644 --- a/src/main/kotlin/features/debug/itemeditor/ItemExporter.kt +++ b/src/main/kotlin/features/debug/itemeditor/ItemExporter.kt @@ -51,7 +51,10 @@ object ItemExporter { nonOverlayCache.clear() val exporter = LegacyItemExporter.createExporter(itemStack) var json = exporter.exportJson() - val fileName = json.jsonObject["internalname"]!!.jsonPrimitive.content + val fileName = json.jsonObject["internalname"]?.jsonPrimitive?.takeIf { it.isString }?.content + if (fileName == null) { + return tr("firmament.repoexport.nointernalname", "Could not find internal name to export for this item (null.json)") + } val itemFile = RepoDownloadManager.repoSavedLocation.resolve("items").resolve("${fileName}.json") itemFile.createParentDirectories() if (itemFile.exists()) { diff --git a/src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt b/src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt index bc8c618..4b647c7 100644 --- a/src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt +++ b/src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt @@ -1,15 +1,13 @@ package moe.nea.firmament.features.debug.itemeditor import kotlinx.serialization.Serializable -import kotlin.jvm.optionals.getOrNull -import net.minecraft.item.ItemStack import net.minecraft.nbt.NbtCompound import net.minecraft.util.Identifier import moe.nea.firmament.Firmament import moe.nea.firmament.repo.ExpensiveItemCacheApi import moe.nea.firmament.repo.ItemCache -import moe.nea.firmament.util.MC import moe.nea.firmament.util.StringUtil.camelWords +import moe.nea.firmament.util.mc.loadItemFromNbt /** * Load data based on [prismarine.js' 1.8 item data](https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/items.json) @@ -68,8 +66,8 @@ object LegacyItemData { putByte("Count", 1) putShort("Damage", legacyItemType.metadata) })!! - val stack = ItemStack.fromNbt(MC.defaultRegistries, nbt).getOrNull() - ?: error("Could not transform ${legacyItemType}") + nbt.remove("components") + val stack = loadItemFromNbt(nbt) ?: error("Could not transform $legacyItemType: $nbt") stack.item to legacyItemType } }.toMap() diff --git a/src/main/kotlin/features/debug/itemeditor/LegacyItemExporter.kt b/src/main/kotlin/features/debug/itemeditor/LegacyItemExporter.kt index ecf3d2c..20ab2c3 100644 --- a/src/main/kotlin/features/debug/itemeditor/LegacyItemExporter.kt +++ b/src/main/kotlin/features/debug/itemeditor/LegacyItemExporter.kt @@ -33,6 +33,7 @@ import moe.nea.firmament.util.json.toJsonArray import moe.nea.firmament.util.mc.displayNameAccordingToNbt import moe.nea.firmament.util.mc.loreAccordingToNbt import moe.nea.firmament.util.mc.toNbtList +import moe.nea.firmament.util.modifyExtraAttributes import moe.nea.firmament.util.skyBlockId import moe.nea.firmament.util.skyblock.Rarity import moe.nea.firmament.util.transformEachRecursively @@ -45,6 +46,7 @@ class LegacyItemExporter private constructor(var itemStack: ItemStack) { } var lore = itemStack.loreAccordingToNbt + val originalId = itemStack.extraAttributes.getString("id") var name = itemStack.displayNameAccordingToNbt val extraAttribs = itemStack.extraAttributes.copy() val legacyNbt = NbtCompound() @@ -195,8 +197,12 @@ class LegacyItemExporter private constructor(var itemStack: ItemStack) { } fun exportModernSnbt(): NbtElement { - val overlay = ItemStack.CODEC.encodeStart(NbtOps.INSTANCE, itemStack) - .orThrow + val overlay = ItemStack.CODEC.encodeStart(NbtOps.INSTANCE, itemStack.copy().also { + it.modifyExtraAttributes { attribs -> + originalId.ifPresent { attribs.putString("id", it) } + attribs + } + }).orThrow val overlayWithVersion = ExportedTestConstantMeta.SOURCE_CODEC.encode(ExportedTestConstantMeta.current, NbtOps.INSTANCE, overlay) .orThrow @@ -284,7 +290,7 @@ class LegacyItemExporter private constructor(var itemStack: ItemStack) { fun copyLegacySkullNbt() { val profile = itemStack.get(DataComponentTypes.PROFILE) ?: return legacyNbt.put("SkullOwner", NbtCompound().apply { - profile.id.ifPresent { + profile.uuid.ifPresent { putString("Id", it.toString()) } putBoolean("hypixelPopulated", true) diff --git a/src/main/kotlin/features/debug/itemeditor/PromptScreen.kt b/src/main/kotlin/features/debug/itemeditor/PromptScreen.kt deleted file mode 100644 index 187b70b..0000000 --- a/src/main/kotlin/features/debug/itemeditor/PromptScreen.kt +++ /dev/null @@ -1,15 +0,0 @@ -package moe.nea.firmament.features.debug.itemeditor - -import io.github.notenoughupdates.moulconfig.gui.CloseEventListener -import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper -import io.github.notenoughupdates.moulconfig.gui.GuiContext -import io.github.notenoughupdates.moulconfig.gui.component.CenterComponent -import io.github.notenoughupdates.moulconfig.gui.component.ColumnComponent -import io.github.notenoughupdates.moulconfig.gui.component.PanelComponent -import io.github.notenoughupdates.moulconfig.gui.component.TextComponent -import io.github.notenoughupdates.moulconfig.gui.component.TextFieldComponent -import io.github.notenoughupdates.moulconfig.observer.GetSetter -import kotlin.reflect.KMutableProperty0 -import moe.nea.firmament.gui.FirmButtonComponent -import moe.nea.firmament.util.MoulConfigUtils - diff --git a/src/main/kotlin/features/diana/AncestralSpadeSolver.kt b/src/main/kotlin/features/diana/AncestralSpadeSolver.kt index ff85c00..48004e8 100644 --- a/src/main/kotlin/features/diana/AncestralSpadeSolver.kt +++ b/src/main/kotlin/features/diana/AncestralSpadeSolver.kt @@ -106,13 +106,11 @@ object AncestralSpadeSolver : SubscriptionOwner { nextGuess?.let { tinyBlock(it, 1f, 0x80FFFFFF.toInt()) // TODO: replace this - color(1f, 1f, 0f, 1f) - tracer(it, lineWidth = 3f) + tracer(it, lineWidth = 3f, color = 0x80FFFFFF.toInt()) } if (particlePositions.size > 2 && lastDing.passedTime() < 10.seconds && nextGuess != null) { // TODO: replace this // TODO: add toggle - color(0f, 1f, 0f, 0.7f) - line(particlePositions) + line(particlePositions, color = 0x80FFFFFF.toInt()) } } } diff --git a/src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt b/src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt index 0cfaeba..0f0316a 100644 --- a/src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt +++ b/src/main/kotlin/features/events/anniversity/AnniversaryFeatures.kt @@ -4,6 +4,7 @@ package moe.nea.firmament.features.events.anniversity import io.github.notenoughupdates.moulconfig.observer.ObservableList import io.github.notenoughupdates.moulconfig.xml.Bind import moe.nea.jarvis.api.Point +import org.joml.Vector2i import kotlin.time.Duration.Companion.seconds import net.minecraft.entity.passive.PigEntity import net.minecraft.util.math.BlockPos @@ -31,7 +32,7 @@ object AnniversaryFeatures : FirmamentFeature { object TConfig : ManagedConfig(identifier, Category.EVENTS) { val enableShinyPigTracker by toggle("shiny-pigs") {true} - val trackPigCooldown by position("pig-hud", 200, 300) { Point(0.1, 0.2) } + val trackPigCooldown by position("pig-hud", 200, 300) { Vector2i(100, 200) } } override val config: ManagedConfig? diff --git a/src/main/kotlin/features/events/carnival/MinesweeperHelper.kt b/src/main/kotlin/features/events/carnival/MinesweeperHelper.kt index cfc05cc..3baf5a5 100644 --- a/src/main/kotlin/features/events/carnival/MinesweeperHelper.kt +++ b/src/main/kotlin/features/events/carnival/MinesweeperHelper.kt @@ -2,7 +2,7 @@ package moe.nea.firmament.features.events.carnival import io.github.notenoughupdates.moulconfig.observer.ObservableList -import io.github.notenoughupdates.moulconfig.platform.ModernItemStack +import io.github.notenoughupdates.moulconfig.platform.MoulConfigPlatform import io.github.notenoughupdates.moulconfig.xml.Bind import java.util.UUID import net.minecraft.block.Blocks @@ -120,7 +120,7 @@ object MinesweeperHelper { .setSkyBlockFirmamentUiId("MINESWEEPER_$name") @Bind - fun getIcon() = ModernItemStack.of(itemStack) + fun getIcon() = MoulConfigPlatform.wrap(itemStack) @Bind fun pieceLabel() = fruitColor.formattingCode + fruitName @@ -158,7 +158,7 @@ object MinesweeperHelper { ; @Bind("itemType") - fun getItemStack() = ModernItemStack.of(ItemStack(itemType)) + fun getItemStack() = MoulConfigPlatform.wrap(ItemStack(itemType)) companion object { val id = SkyblockId("CARNIVAL_SHOVEL") diff --git a/src/main/kotlin/features/fixes/Fixes.kt b/src/main/kotlin/features/fixes/Fixes.kt index 0105624..b002dbd 100644 --- a/src/main/kotlin/features/fixes/Fixes.kt +++ b/src/main/kotlin/features/fixes/Fixes.kt @@ -1,6 +1,7 @@ package moe.nea.firmament.features.fixes import moe.nea.jarvis.api.Point +import org.joml.Vector2i import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable import net.minecraft.client.MinecraftClient import net.minecraft.client.option.KeyBinding @@ -22,7 +23,7 @@ object Fixes : FirmamentFeature { var autoSprint by toggle("auto-sprint") { false } val autoSprintKeyBinding by keyBindingWithDefaultUnbound("auto-sprint-keybinding") val autoSprintUnderWater by toggle("auto-sprint-underwater") { true } - val autoSprintHud by position("auto-sprint-hud", 80, 10) { Point(0.0, 1.0) } + val autoSprintHud by position("auto-sprint-hud", 80, 10) { Vector2i() } val peekChat by keyBindingWithDefaultUnbound("peek-chat") val hidePotionEffects by toggle("hide-mob-effects") { false } val hidePotionEffectsHud by toggle("hide-potion-effects-hud") { false } @@ -50,7 +51,7 @@ object Fixes : FirmamentFeature { @Subscribe fun onRenderHud(it: HudRenderEvent) { if (!TConfig.autoSprintKeyBinding.isBound) return - it.context.matrices.push() + it.context.matrices.pushMatrix() TConfig.autoSprintHud.applyTransformations(it.context.matrices) it.context.drawText( MC.font, ( @@ -66,7 +67,7 @@ object Fixes : FirmamentFeature { } ), 0, 0, -1, true ) - it.context.matrices.pop() + it.context.matrices.popMatrix() } @Subscribe diff --git a/src/main/kotlin/features/inventory/ItemRarityCosmetics.kt b/src/main/kotlin/features/inventory/ItemRarityCosmetics.kt index fdc378a..9dae118 100644 --- a/src/main/kotlin/features/inventory/ItemRarityCosmetics.kt +++ b/src/main/kotlin/features/inventory/ItemRarityCosmetics.kt @@ -1,6 +1,7 @@ package moe.nea.firmament.features.inventory import java.awt.Color +import net.minecraft.client.gl.RenderPipelines import net.minecraft.client.gui.DrawContext import net.minecraft.client.render.RenderLayer import net.minecraft.item.ItemStack @@ -38,7 +39,7 @@ object ItemRarityCosmetics : FirmamentFeature { val rarity = Rarity.fromItem(item) ?: return val rgb = rarityToColor[rarity] ?: 0xFF00FF80.toInt() drawContext.drawGuiTexture( - RenderLayer::getGuiTextured, + RenderPipelines.GUI_TEXTURED, Identifier.of("firmament:item_rarity_background"), x, y, 16, 16, diff --git a/src/main/kotlin/features/inventory/PetFeatures.kt b/src/main/kotlin/features/inventory/PetFeatures.kt index 9393b03..701d30c 100644 --- a/src/main/kotlin/features/inventory/PetFeatures.kt +++ b/src/main/kotlin/features/inventory/PetFeatures.kt @@ -1,6 +1,6 @@ package moe.nea.firmament.features.inventory -import moe.nea.jarvis.api.Point +import org.joml.Vector2i import net.minecraft.item.ItemStack import net.minecraft.text.Text import net.minecraft.util.Formatting @@ -10,6 +10,7 @@ import moe.nea.firmament.events.HudRenderEvent import moe.nea.firmament.events.SlotRenderEvents import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.gui.config.ManagedConfig +import moe.nea.firmament.jarvis.JarvisIntegration import moe.nea.firmament.util.FirmFormatters.formatPercent import moe.nea.firmament.util.FirmFormatters.shortFormat import moe.nea.firmament.util.MC @@ -31,7 +32,9 @@ object PetFeatures : FirmamentFeature { object TConfig : ManagedConfig(identifier, Category.INVENTORY) { val highlightEquippedPet by toggle("highlight-pet") { true } var petOverlay by toggle("pet-overlay") { false } - val petOverlayHud by position("pet-overlay-hud", 80, 10) { Point(0.5, 1.0) } + val petOverlayHud by position("pet-overlay-hud", 80, 10) { + Vector2i() + } } val petMenuTitle = "Pets(?: \\([0-9]+/[0-9]+\\))?".toPattern() @@ -43,12 +46,12 @@ object PetFeatures : FirmamentFeature { val stack = event.slot.stack if (stack.petData?.active == true) petMenuTitle.useMatch(MC.screenName ?: return) { - petItemStack = stack - event.context.drawGuiTexture( - Firmament.identifier("selected_pet_background"), - event.slot.x, event.slot.y, 16, 16, - ) - } + petItemStack = stack + event.context.drawGuiTexture( + Firmament.identifier("selected_pet_background"), + event.slot.x, event.slot.y, 16, 16, + ) + } } @Subscribe @@ -62,25 +65,48 @@ object PetFeatures : FirmamentFeature { val petType = titleCase(petData.type) val heldItem = petData.heldItem?.let { item -> "Held Item: ${titleCase(item)}" } - it.context.matrices.push() - TConfig.petOverlayHud.applyTransformations(it.context.matrices) + it.context.matrices.pushMatrix() + TConfig.petOverlayHud.applyTransformations(JarvisIntegration.jarvis, it.context.matrices) val lines = mutableListOf<Text>() - it.context.matrices.push() - it.context.matrices.translate(-0.5, -0.5, 0.0) - it.context.matrices.scale(2f, 2f, 1f) + it.context.matrices.pushMatrix() + it.context.matrices.translate(-0.5F, -0.5F) + it.context.matrices.scale(2f, 2f) it.context.drawItem(itemStack, 0, 0) - it.context.matrices.pop() + it.context.matrices.popMatrix() lines.add(Text.literal("[Lvl ${xp.currentLevel}] ").append(Text.literal(petType).withColor(rarityCode))) if (heldItem != null) lines.add(Text.literal(heldItem)) - if (xp.currentLevel != xp.maxLevel) lines.add(Text.literal("Required L${xp.currentLevel + 1}: ${shortFormat(xp.expInCurrentLevel.toDouble())}/${shortFormat(xp.expRequiredForNextLevel.toDouble())} (${formatPercent(xp.percentageToNextLevel.toDouble())})")) - lines.add(Text.literal("Required L100: ${shortFormat(xp.expTotal.toDouble())}/${shortFormat(xp.expRequiredForMaxLevel.toDouble())} (${formatPercent(xp.percentageToMaxLevel.toDouble())})")) + if (xp.currentLevel != xp.maxLevel) lines.add( + Text.literal( + "Required L${xp.currentLevel + 1}: ${shortFormat(xp.expInCurrentLevel.toDouble())}/${ + shortFormat( + xp.expRequiredForNextLevel.toDouble() + ) + } (${formatPercent(xp.percentageToNextLevel.toDouble())})" + ) + ) + lines.add( + Text.literal( + "Required L100: ${shortFormat(xp.expTotal.toDouble())}/${shortFormat(xp.expRequiredForMaxLevel.toDouble())} (${ + formatPercent( + xp.percentageToMaxLevel.toDouble() + ) + })" + ) + ) for ((index, line) in lines.withIndex()) { - it.context.drawText(MC.font, line.copy().withColor(Formatting.GRAY), 36, MC.font.fontHeight * index, -1, true) + it.context.drawText( + MC.font, + line.copy().withColor(Formatting.GRAY), + 36, + MC.font.fontHeight * index, + -1, + true + ) } - it.context.matrices.pop() + it.context.matrices.popMatrix() } } diff --git a/src/main/kotlin/features/inventory/REIDependencyWarner.kt b/src/main/kotlin/features/inventory/REIDependencyWarner.kt index 476759a..6bf2928 100644 --- a/src/main/kotlin/features/inventory/REIDependencyWarner.kt +++ b/src/main/kotlin/features/inventory/REIDependencyWarner.kt @@ -31,7 +31,7 @@ object REIDependencyWarner { var sentWarning = false fun modrinthLink(slug: String) = - "https://modrinth.com/mod/$slug/versions?g=${SharedConstants.getGameVersion().name}&l=fabric" + "https://modrinth.com/mod/$slug/versions?g=${SharedConstants.getGameVersion().name()}&l=fabric" fun downloadButton(modName: String, modId: String, slug: String): Text { val alreadyDownloaded = FabricLoader.getInstance().isModLoaded(modId) diff --git a/src/main/kotlin/features/inventory/SlotLocking.kt b/src/main/kotlin/features/inventory/SlotLocking.kt index 0a3f01b..eefc6d1 100644 --- a/src/main/kotlin/features/inventory/SlotLocking.kt +++ b/src/main/kotlin/features/inventory/SlotLocking.kt @@ -2,6 +2,7 @@ package moe.nea.firmament.features.inventory +import com.mojang.blaze3d.pipeline.RenderPipeline import java.util.UUID import org.lwjgl.glfw.GLFW import kotlinx.serialization.KSerializer @@ -16,6 +17,7 @@ import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.int import kotlinx.serialization.serializer +import net.minecraft.client.gl.RenderPipelines import net.minecraft.client.gui.screen.ingame.HandledScreen import net.minecraft.client.render.RenderLayer import net.minecraft.entity.player.PlayerInventory @@ -429,7 +431,7 @@ object SlotLocking : FirmamentFeature { return if (isHotbar()) { x + 9 to y } else { - x + 9 to y + 17 + x + 9 to y + 16 } } @@ -484,7 +486,7 @@ object SlotLocking : FirmamentFeature { val isUUIDLocked = (it.slot.stack?.skyblockUUID) in (lockedUUIDs ?: setOf()) if (isSlotLocked || isUUIDLocked) { it.context.drawGuiTexture( - RenderLayer::getGuiTexturedOverlay, + RenderPipelines.GUI_TEXTURED, when { isSlotLocked -> (Identifier.of("firmament:slot_locked")) diff --git a/src/main/kotlin/features/inventory/buttons/InventoryButtonEditor.kt b/src/main/kotlin/features/inventory/buttons/InventoryButtonEditor.kt index eecbd17..7334c82 100644 --- a/src/main/kotlin/features/inventory/buttons/InventoryButtonEditor.kt +++ b/src/main/kotlin/features/inventory/buttons/InventoryButtonEditor.kt @@ -2,8 +2,8 @@ package moe.nea.firmament.features.inventory.buttons import io.github.notenoughupdates.moulconfig.common.IItemStack import io.github.notenoughupdates.moulconfig.gui.component.PanelComponent -import io.github.notenoughupdates.moulconfig.platform.ModernItemStack -import io.github.notenoughupdates.moulconfig.platform.ModernRenderContext +import io.github.notenoughupdates.moulconfig.platform.MoulConfigPlatform +import io.github.notenoughupdates.moulconfig.platform.MoulConfigRenderContext import io.github.notenoughupdates.moulconfig.xml.Bind import me.shedaniel.math.Point import me.shedaniel.math.Rectangle @@ -35,7 +35,7 @@ class InventoryButtonEditor( @Bind fun getItemIcon(): IItemStack { save() - return ModernItemStack.of(InventoryButton.getItemForName(icon)) + return MoulConfigPlatform.wrap(InventoryButton.getItemForName(icon)) } @Bind @@ -122,7 +122,9 @@ class InventoryButtonEditor( ButtonWidget.builder(Text.translatable("firmament.inventory-buttons.simple-preset")) { // Preset from NEU // Credit: https://github.com/NotEnoughUpdates/NotEnoughUpdates/blob/9b1fcfebc646e9fb69f99006327faa3e734e5f51/src/main/resources/assets/notenoughupdates/invbuttons/presets.json#L900-L1348 - val newButtons = InventoryButtonTemplates.loadTemplate("TkVVQlVUVE9OUy9bIntcblx0XCJ4XCI6IDE2MCxcblx0XCJ5XCI6IC0yMCxcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogZmFsc2UsXG5cdFwiaWNvblwiOiBcImJvbmVcIixcblx0XCJjb21tYW5kXCI6IFwicGV0c1wiXG59Iiwie1xuXHRcInhcIjogMTQwLFxuXHRcInlcIjogLTIwLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiBmYWxzZSxcblx0XCJpY29uXCI6IFwiYXJtb3Jfc3RhbmRcIixcblx0XCJjb21tYW5kXCI6IFwid2FyZHJvYmVcIlxufSIsIntcblx0XCJ4XCI6IDEyMCxcblx0XCJ5XCI6IC0yMCxcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogZmFsc2UsXG5cdFwiaWNvblwiOiBcImVuZGVyX2NoZXN0XCIsXG5cdFwiY29tbWFuZFwiOiBcInN0b3JhZ2VcIlxufSIsIntcblx0XCJ4XCI6IDEwMCxcblx0XCJ5XCI6IC0yMCxcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogZmFsc2UsXG5cdFwiaWNvblwiOiBcInNrdWxsOmQ3Y2M2Njg3NDIzZDA1NzBkNTU2YWM1M2UwNjc2Y2I1NjNiYmRkOTcxN2NkODI2OWJkZWJlZDZmNmQ0ZTdiZjhcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBpc2xhbmRcIlxufSIsIntcblx0XCJ4XCI6IDgwLFxuXHRcInlcIjogLTIwLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiBmYWxzZSxcblx0XCJpY29uXCI6IFwic2t1bGw6MzVmNGI0MGNlZjllMDE3Y2Q0MTEyZDI2YjYyNTU3ZjhjMWQ1YjE4OWRhMmU5OTUzNDIyMmJjOGNlYzdkOTE5NlwiLFxuXHRcImNvbW1hbmRcIjogXCJ3YXJwIGh1YlwiXG59Il0=") + val newButtons = InventoryButtonTemplates.loadTemplate( + "TkVVQlVUVE9OUy9bIntcblx0XCJ4XCI6IDE2MCxcblx0XCJ5XCI6IC0yMCxcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogZmFsc2UsXG5cdFwiaWNvblwiOiBcImJvbmVcIixcblx0XCJjb21tYW5kXCI6IFwicGV0c1wiXG59Iiwie1xuXHRcInhcIjogMTQwLFxuXHRcInlcIjogLTIwLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiBmYWxzZSxcblx0XCJpY29uXCI6IFwiYXJtb3Jfc3RhbmRcIixcblx0XCJjb21tYW5kXCI6IFwid2FyZHJvYmVcIlxufSIsIntcblx0XCJ4XCI6IDEyMCxcblx0XCJ5XCI6IC0yMCxcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogZmFsc2UsXG5cdFwiaWNvblwiOiBcImVuZGVyX2NoZXN0XCIsXG5cdFwiY29tbWFuZFwiOiBcInN0b3JhZ2VcIlxufSIsIntcblx0XCJ4XCI6IDEwMCxcblx0XCJ5XCI6IC0yMCxcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogZmFsc2UsXG5cdFwiaWNvblwiOiBcInNrdWxsOmQ3Y2M2Njg3NDIzZDA1NzBkNTU2YWM1M2UwNjc2Y2I1NjNiYmRkOTcxN2NkODI2OWJkZWJlZDZmNmQ0ZTdiZjhcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBpc2xhbmRcIlxufSIsIntcblx0XCJ4XCI6IDgwLFxuXHRcInlcIjogLTIwLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiBmYWxzZSxcblx0XCJpY29uXCI6IFwic2t1bGw6MzVmNGI0MGNlZjllMDE3Y2Q0MTEyZDI2YjYyNTU3ZjhjMWQ1YjE4OWRhMmU5OTUzNDIyMmJjOGNlYzdkOTE5NlwiLFxuXHRcImNvbW1hbmRcIjogXCJ3YXJwIGh1YlwiXG59Il0=" + ) if (newButtons != null) buttons = moveButtons(newButtons.map { it.copy(command = it.command?.removePrefix("/")) }) } @@ -134,7 +136,9 @@ class InventoryButtonEditor( ButtonWidget.builder(Text.translatable("firmament.inventory-buttons.all-warps-preset")) { // Preset from NEU // Credit: https://github.com/NotEnoughUpdates/NotEnoughUpdates/blob/9b1fcfebc646e9fb69f99006327faa3e734e5f51/src/main/resources/assets/notenoughupdates/invbuttons/presets.json#L1817-L2276 - val newButtons = InventoryButtonTemplates.loadTemplate("TkVVQlVUVE9OUy9bIntcblx0XCJ4XCI6IDIsXG5cdFwieVwiOiAtODQsXG5cdFwiYW5jaG9yUmlnaHRcIjogdHJ1ZSxcblx0XCJhbmNob3JCb3R0b21cIjogdHJ1ZSxcblx0XCJpY29uXCI6IFwic2t1bGw6YzljODg4MWU0MjkxNWE5ZDI5YmI2MWExNmZiMjZkMDU5OTEzMjA0ZDI2NWRmNWI0MzliM2Q3OTJhY2Q1NlwiLFxuXHRcImNvbW1hbmRcIjogXCJ3YXJwIGhvbWVcIlxufSIsIntcblx0XCJ4XCI6IDIsXG5cdFwieVwiOiAtNjQsXG5cdFwiYW5jaG9yUmlnaHRcIjogdHJ1ZSxcblx0XCJhbmNob3JCb3R0b21cIjogdHJ1ZSxcblx0XCJpY29uXCI6IFwic2t1bGw6ZDdjYzY2ODc0MjNkMDU3MGQ1NTZhYzUzZTA2NzZjYjU2M2JiZGQ5NzE3Y2Q4MjY5YmRlYmVkNmY2ZDRlN2JmOFwiLFxuXHRcImNvbW1hbmRcIjogXCJ3YXJwIGh1YlwiXG59Iiwie1xuXHRcInhcIjogMixcblx0XCJ5XCI6IC00NCxcblx0XCJhbmNob3JSaWdodFwiOiB0cnVlLFxuXHRcImFuY2hvckJvdHRvbVwiOiB0cnVlLFxuXHRcImljb25cIjogXCJza3VsbDo5YjU2ODk1Yjk2NTk4OTZhZDY0N2Y1ODU5OTIzOGFmNTMyZDQ2ZGI5YzFiMDM4OWI4YmJlYjcwOTk5ZGFiMzNkXCIsXG5cdFwiY29tbWFuZFwiOiBcIndhcnAgZHVuZ2Vvbl9odWJcIlxufSIsIntcblx0XCJ4XCI6IDIsXG5cdFwieVwiOiAtMjQsXG5cdFwiYW5jaG9yUmlnaHRcIjogdHJ1ZSxcblx0XCJhbmNob3JCb3R0b21cIjogdHJ1ZSxcblx0XCJpY29uXCI6IFwic2t1bGw6Nzg0MGI4N2Q1MjI3MWQyYTc1NWRlZGM4Mjg3N2UwZWQzZGY2N2RjYzQyZWE0NzllYzE0NjE3NmIwMjc3OWE1XCIsXG5cdFwiY29tbWFuZFwiOiBcIndhcnAgZW5kXCJcbn0iLCJ7XG5cdFwieFwiOiAxMDksXG5cdFwieVwiOiAtMTksXG5cdFwiYW5jaG9yUmlnaHRcIjogZmFsc2UsXG5cdFwiYW5jaG9yQm90dG9tXCI6IGZhbHNlLFxuXHRcImljb25cIjogXCJza3VsbDo4NmYwNmVhYTMwMDRhZWVkMDliM2Q1YjQ1ZDk3NmRlNTg0ZTY5MWMwZTljYWRlMTMzNjM1ZGU5M2QyM2I5ZWRiXCIsXG5cdFwiY29tbWFuZFwiOiBcImhvdG1cIlxufSIsIntcblx0XCJ4XCI6IDEzMCxcblx0XCJ5XCI6IC0xOSxcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogZmFsc2UsXG5cdFwiaWNvblwiOiBcIkVOREVSX0NIRVNUXCIsXG5cdFwiY29tbWFuZFwiOiBcInN0b3JhZ2VcIlxufSIsIntcblx0XCJ4XCI6IDE1MSxcblx0XCJ5XCI6IC0xOSxcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogZmFsc2UsXG5cdFwiaWNvblwiOiBcIkJPTkVcIixcblx0XCJjb21tYW5kXCI6IFwicGV0c1wiXG59Iiwie1xuXHRcInhcIjogLTE5LFxuXHRcInlcIjogMixcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogZmFsc2UsXG5cdFwiaWNvblwiOiBcIkdPTERfQkxPQ0tcIixcblx0XCJjb21tYW5kXCI6IFwiYWhcIlxufSIsIntcblx0XCJ4XCI6IC0xOSxcblx0XCJ5XCI6IDIyLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiBmYWxzZSxcblx0XCJpY29uXCI6IFwiR09MRF9CQVJESU5HXCIsXG5cdFwiY29tbWFuZFwiOiBcImJ6XCJcbn0iLCJ7XG5cdFwieFwiOiAtMTksXG5cdFwieVwiOiAtODQsXG5cdFwiYW5jaG9yUmlnaHRcIjogZmFsc2UsXG5cdFwiYW5jaG9yQm90dG9tXCI6IHRydWUsXG5cdFwiaWNvblwiOiBcInNrdWxsOjQzOGNmM2Y4ZTU0YWZjM2IzZjkxZDIwYTQ5ZjMyNGRjYTE0ODYwMDdmZTU0NTM5OTA1NTUyNGMxNzk0MWY0ZGNcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBtdXNldW1cIlxufSIsIntcblx0XCJ4XCI6IC0xOSxcblx0XCJ5XCI6IC02NCxcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogdHJ1ZSxcblx0XCJpY29uXCI6IFwic2t1bGw6ZjQ4ODBkMmMxZTdiODZlODc1MjJlMjA4ODI2NTZmNDViYWZkNDJmOTQ5MzJiMmM1ZTBkNmVjYWE0OTBjYjRjXCIsXG5cdFwiY29tbWFuZFwiOiBcIndhcnAgZ2FyZGVuXCJcbn0iLCJ7XG5cdFwieFwiOiAtMTksXG5cdFwieVwiOiAtNDQsXG5cdFwiYW5jaG9yUmlnaHRcIjogZmFsc2UsXG5cdFwiYW5jaG9yQm90dG9tXCI6IHRydWUsXG5cdFwiaWNvblwiOiBcInNrdWxsOjRkM2E2YmQ5OGFjMTgzM2M2NjRjNDkwOWZmOGQyZGM2MmNlODg3YmRjZjNjYzViMzg0ODY1MWFlNWFmNmJcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBiYXJuXCJcbn0iLCJ7XG5cdFwieFwiOiAtMTksXG5cdFwieVwiOiAtMjQsXG5cdFwiYW5jaG9yUmlnaHRcIjogZmFsc2UsXG5cdFwiYW5jaG9yQm90dG9tXCI6IHRydWUsXG5cdFwiaWNvblwiOiBcInNrdWxsOjUxNTM5ZGRkZjllZDI1NWVjZTYzNDgxOTNjZDc1MDEyYzgyYzkzYWVjMzgxZjA1NTcyY2VjZjczNzk3MTFiM2JcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBkZXNlcnRcIlxufSIsIntcblx0XCJ4XCI6IDQsXG5cdFwieVwiOiAyLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiB0cnVlLFxuXHRcImljb25cIjogXCJza3VsbDo3M2JjOTY1ZDU3OWMzYzYwMzlmMGExN2ViN2MyZTZmYWY1MzhjN2E1ZGU4ZTYwZWM3YTcxOTM2MGQwYTg1N2E5XCIsXG5cdFwiY29tbWFuZFwiOiBcIndhcnAgZ29sZFwiXG59Iiwie1xuXHRcInhcIjogMjUsXG5cdFwieVwiOiAyLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiB0cnVlLFxuXHRcImljb25cIjogXCJza3VsbDo1NjlhMWYxMTQxNTFiNDUyMTM3M2YzNGJjMTRjMjk2M2E1MDExY2RjMjVhNjU1NGM0OGM3MDhjZDk2ZWJmY1wiLFxuXHRcImNvbW1hbmRcIjogXCJ3YXJwIGRlZXBcIlxufSIsIntcblx0XCJ4XCI6IDQ2LFxuXHRcInlcIjogMixcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogdHJ1ZSxcblx0XCJpY29uXCI6IFwic2t1bGw6MjFkYmUzMGIwMjdhY2JjZWI2MTI1NjNiZDg3N2NkN2ViYjcxOWVhNmVkMTM5OTAyN2RjZWU1OGJiOTA0OWQ0YVwiLFxuXHRcImNvbW1hbmRcIjogXCJ3YXJwIGNyeXN0YWxzXCJcbn0iLCJ7XG5cdFwieFwiOiA2Nyxcblx0XCJ5XCI6IDIsXG5cdFwiYW5jaG9yUmlnaHRcIjogZmFsc2UsXG5cdFwiYW5jaG9yQm90dG9tXCI6IHRydWUsXG5cdFwiaWNvblwiOiBcInNrdWxsOjVjYmQ5ZjVlYzFlZDAwNzI1OTk5NjQ5MWU2OWZmNjQ5YTMxMDZjZjkyMDIyN2IxYmIzYTcxZWU3YTg5ODYzZlwiLFxuXHRcImNvbW1hbmRcIjogXCJ3YXJwIGZvcmdlXCJcbn0iLCJ7XG5cdFwieFwiOiA4OCxcblx0XCJ5XCI6IDIsXG5cdFwiYW5jaG9yUmlnaHRcIjogZmFsc2UsXG5cdFwiYW5jaG9yQm90dG9tXCI6IHRydWUsXG5cdFwiaWNvblwiOiBcInNrdWxsOjZiMjBiMjNjMWFhMmJlMDI3MGYwMTZiNGM5MGQ2ZWU2YjgzMzBhMTdjZmVmODc4NjlkNmFkNjBiMmZmYmYzYjVcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBtaW5lc1wiXG59Iiwie1xuXHRcInhcIjogMTA5LFxuXHRcInlcIjogMixcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogdHJ1ZSxcblx0XCJpY29uXCI6IFwic2t1bGw6YTIyMWY4MTNkYWNlZTBmZWY4YzU5Zjc2ODk0ZGJiMjY0MTU0NzhkOWRkZmM0NGMyZTcwOGE2ZDNiNzU0OWJcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBwYXJrXCJcbn0iLCJ7XG5cdFwieFwiOiAxMzAsXG5cdFwieVwiOiAyLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiB0cnVlLFxuXHRcImljb25cIjogXCJza3VsbDo5ZDdlM2IxOWFjNGYzZGVlOWM1Njc3YzEzNTMzM2I5ZDM1YTdmNTY4YjYzZDFlZjRhZGE0YjA2OGI1YTI1XCIsXG5cdFwiY29tbWFuZFwiOiBcIndhcnAgc3BpZGVyXCJcbn0iLCJ7XG5cdFwieFwiOiAxNTEsXG5cdFwieVwiOiAyLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiB0cnVlLFxuXHRcImljb25cIjogXCJza3VsbDpjMzY4N2UyNWM2MzJiY2U4YWE2MWUwZDY0YzI0ZTY5NGMzZWVhNjI5ZWE5NDRmNGNmMzBkY2ZiNGZiY2UwNzFcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBuZXRoZXJcIlxufSJd") + val newButtons = InventoryButtonTemplates.loadTemplate( + "TkVVQlVUVE9OUy9bIntcblx0XCJ4XCI6IDIsXG5cdFwieVwiOiAtODQsXG5cdFwiYW5jaG9yUmlnaHRcIjogdHJ1ZSxcblx0XCJhbmNob3JCb3R0b21cIjogdHJ1ZSxcblx0XCJpY29uXCI6IFwic2t1bGw6YzljODg4MWU0MjkxNWE5ZDI5YmI2MWExNmZiMjZkMDU5OTEzMjA0ZDI2NWRmNWI0MzliM2Q3OTJhY2Q1NlwiLFxuXHRcImNvbW1hbmRcIjogXCJ3YXJwIGhvbWVcIlxufSIsIntcblx0XCJ4XCI6IDIsXG5cdFwieVwiOiAtNjQsXG5cdFwiYW5jaG9yUmlnaHRcIjogdHJ1ZSxcblx0XCJhbmNob3JCb3R0b21cIjogdHJ1ZSxcblx0XCJpY29uXCI6IFwic2t1bGw6ZDdjYzY2ODc0MjNkMDU3MGQ1NTZhYzUzZTA2NzZjYjU2M2JiZGQ5NzE3Y2Q4MjY5YmRlYmVkNmY2ZDRlN2JmOFwiLFxuXHRcImNvbW1hbmRcIjogXCJ3YXJwIGh1YlwiXG59Iiwie1xuXHRcInhcIjogMixcblx0XCJ5XCI6IC00NCxcblx0XCJhbmNob3JSaWdodFwiOiB0cnVlLFxuXHRcImFuY2hvckJvdHRvbVwiOiB0cnVlLFxuXHRcImljb25cIjogXCJza3VsbDo5YjU2ODk1Yjk2NTk4OTZhZDY0N2Y1ODU5OTIzOGFmNTMyZDQ2ZGI5YzFiMDM4OWI4YmJlYjcwOTk5ZGFiMzNkXCIsXG5cdFwiY29tbWFuZFwiOiBcIndhcnAgZHVuZ2Vvbl9odWJcIlxufSIsIntcblx0XCJ4XCI6IDIsXG5cdFwieVwiOiAtMjQsXG5cdFwiYW5jaG9yUmlnaHRcIjogdHJ1ZSxcblx0XCJhbmNob3JCb3R0b21cIjogdHJ1ZSxcblx0XCJpY29uXCI6IFwic2t1bGw6Nzg0MGI4N2Q1MjI3MWQyYTc1NWRlZGM4Mjg3N2UwZWQzZGY2N2RjYzQyZWE0NzllYzE0NjE3NmIwMjc3OWE1XCIsXG5cdFwiY29tbWFuZFwiOiBcIndhcnAgZW5kXCJcbn0iLCJ7XG5cdFwieFwiOiAxMDksXG5cdFwieVwiOiAtMTksXG5cdFwiYW5jaG9yUmlnaHRcIjogZmFsc2UsXG5cdFwiYW5jaG9yQm90dG9tXCI6IGZhbHNlLFxuXHRcImljb25cIjogXCJza3VsbDo4NmYwNmVhYTMwMDRhZWVkMDliM2Q1YjQ1ZDk3NmRlNTg0ZTY5MWMwZTljYWRlMTMzNjM1ZGU5M2QyM2I5ZWRiXCIsXG5cdFwiY29tbWFuZFwiOiBcImhvdG1cIlxufSIsIntcblx0XCJ4XCI6IDEzMCxcblx0XCJ5XCI6IC0xOSxcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogZmFsc2UsXG5cdFwiaWNvblwiOiBcIkVOREVSX0NIRVNUXCIsXG5cdFwiY29tbWFuZFwiOiBcInN0b3JhZ2VcIlxufSIsIntcblx0XCJ4XCI6IDE1MSxcblx0XCJ5XCI6IC0xOSxcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogZmFsc2UsXG5cdFwiaWNvblwiOiBcIkJPTkVcIixcblx0XCJjb21tYW5kXCI6IFwicGV0c1wiXG59Iiwie1xuXHRcInhcIjogLTE5LFxuXHRcInlcIjogMixcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogZmFsc2UsXG5cdFwiaWNvblwiOiBcIkdPTERfQkxPQ0tcIixcblx0XCJjb21tYW5kXCI6IFwiYWhcIlxufSIsIntcblx0XCJ4XCI6IC0xOSxcblx0XCJ5XCI6IDIyLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiBmYWxzZSxcblx0XCJpY29uXCI6IFwiR09MRF9CQVJESU5HXCIsXG5cdFwiY29tbWFuZFwiOiBcImJ6XCJcbn0iLCJ7XG5cdFwieFwiOiAtMTksXG5cdFwieVwiOiAtODQsXG5cdFwiYW5jaG9yUmlnaHRcIjogZmFsc2UsXG5cdFwiYW5jaG9yQm90dG9tXCI6IHRydWUsXG5cdFwiaWNvblwiOiBcInNrdWxsOjQzOGNmM2Y4ZTU0YWZjM2IzZjkxZDIwYTQ5ZjMyNGRjYTE0ODYwMDdmZTU0NTM5OTA1NTUyNGMxNzk0MWY0ZGNcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBtdXNldW1cIlxufSIsIntcblx0XCJ4XCI6IC0xOSxcblx0XCJ5XCI6IC02NCxcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogdHJ1ZSxcblx0XCJpY29uXCI6IFwic2t1bGw6ZjQ4ODBkMmMxZTdiODZlODc1MjJlMjA4ODI2NTZmNDViYWZkNDJmOTQ5MzJiMmM1ZTBkNmVjYWE0OTBjYjRjXCIsXG5cdFwiY29tbWFuZFwiOiBcIndhcnAgZ2FyZGVuXCJcbn0iLCJ7XG5cdFwieFwiOiAtMTksXG5cdFwieVwiOiAtNDQsXG5cdFwiYW5jaG9yUmlnaHRcIjogZmFsc2UsXG5cdFwiYW5jaG9yQm90dG9tXCI6IHRydWUsXG5cdFwiaWNvblwiOiBcInNrdWxsOjRkM2E2YmQ5OGFjMTgzM2M2NjRjNDkwOWZmOGQyZGM2MmNlODg3YmRjZjNjYzViMzg0ODY1MWFlNWFmNmJcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBiYXJuXCJcbn0iLCJ7XG5cdFwieFwiOiAtMTksXG5cdFwieVwiOiAtMjQsXG5cdFwiYW5jaG9yUmlnaHRcIjogZmFsc2UsXG5cdFwiYW5jaG9yQm90dG9tXCI6IHRydWUsXG5cdFwiaWNvblwiOiBcInNrdWxsOjUxNTM5ZGRkZjllZDI1NWVjZTYzNDgxOTNjZDc1MDEyYzgyYzkzYWVjMzgxZjA1NTcyY2VjZjczNzk3MTFiM2JcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBkZXNlcnRcIlxufSIsIntcblx0XCJ4XCI6IDQsXG5cdFwieVwiOiAyLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiB0cnVlLFxuXHRcImljb25cIjogXCJza3VsbDo3M2JjOTY1ZDU3OWMzYzYwMzlmMGExN2ViN2MyZTZmYWY1MzhjN2E1ZGU4ZTYwZWM3YTcxOTM2MGQwYTg1N2E5XCIsXG5cdFwiY29tbWFuZFwiOiBcIndhcnAgZ29sZFwiXG59Iiwie1xuXHRcInhcIjogMjUsXG5cdFwieVwiOiAyLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiB0cnVlLFxuXHRcImljb25cIjogXCJza3VsbDo1NjlhMWYxMTQxNTFiNDUyMTM3M2YzNGJjMTRjMjk2M2E1MDExY2RjMjVhNjU1NGM0OGM3MDhjZDk2ZWJmY1wiLFxuXHRcImNvbW1hbmRcIjogXCJ3YXJwIGRlZXBcIlxufSIsIntcblx0XCJ4XCI6IDQ2LFxuXHRcInlcIjogMixcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogdHJ1ZSxcblx0XCJpY29uXCI6IFwic2t1bGw6MjFkYmUzMGIwMjdhY2JjZWI2MTI1NjNiZDg3N2NkN2ViYjcxOWVhNmVkMTM5OTAyN2RjZWU1OGJiOTA0OWQ0YVwiLFxuXHRcImNvbW1hbmRcIjogXCJ3YXJwIGNyeXN0YWxzXCJcbn0iLCJ7XG5cdFwieFwiOiA2Nyxcblx0XCJ5XCI6IDIsXG5cdFwiYW5jaG9yUmlnaHRcIjogZmFsc2UsXG5cdFwiYW5jaG9yQm90dG9tXCI6IHRydWUsXG5cdFwiaWNvblwiOiBcInNrdWxsOjVjYmQ5ZjVlYzFlZDAwNzI1OTk5NjQ5MWU2OWZmNjQ5YTMxMDZjZjkyMDIyN2IxYmIzYTcxZWU3YTg5ODYzZlwiLFxuXHRcImNvbW1hbmRcIjogXCJ3YXJwIGZvcmdlXCJcbn0iLCJ7XG5cdFwieFwiOiA4OCxcblx0XCJ5XCI6IDIsXG5cdFwiYW5jaG9yUmlnaHRcIjogZmFsc2UsXG5cdFwiYW5jaG9yQm90dG9tXCI6IHRydWUsXG5cdFwiaWNvblwiOiBcInNrdWxsOjZiMjBiMjNjMWFhMmJlMDI3MGYwMTZiNGM5MGQ2ZWU2YjgzMzBhMTdjZmVmODc4NjlkNmFkNjBiMmZmYmYzYjVcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBtaW5lc1wiXG59Iiwie1xuXHRcInhcIjogMTA5LFxuXHRcInlcIjogMixcblx0XCJhbmNob3JSaWdodFwiOiBmYWxzZSxcblx0XCJhbmNob3JCb3R0b21cIjogdHJ1ZSxcblx0XCJpY29uXCI6IFwic2t1bGw6YTIyMWY4MTNkYWNlZTBmZWY4YzU5Zjc2ODk0ZGJiMjY0MTU0NzhkOWRkZmM0NGMyZTcwOGE2ZDNiNzU0OWJcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBwYXJrXCJcbn0iLCJ7XG5cdFwieFwiOiAxMzAsXG5cdFwieVwiOiAyLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiB0cnVlLFxuXHRcImljb25cIjogXCJza3VsbDo5ZDdlM2IxOWFjNGYzZGVlOWM1Njc3YzEzNTMzM2I5ZDM1YTdmNTY4YjYzZDFlZjRhZGE0YjA2OGI1YTI1XCIsXG5cdFwiY29tbWFuZFwiOiBcIndhcnAgc3BpZGVyXCJcbn0iLCJ7XG5cdFwieFwiOiAxNTEsXG5cdFwieVwiOiAyLFxuXHRcImFuY2hvclJpZ2h0XCI6IGZhbHNlLFxuXHRcImFuY2hvckJvdHRvbVwiOiB0cnVlLFxuXHRcImljb25cIjogXCJza3VsbDpjMzY4N2UyNWM2MzJiY2U4YWE2MWUwZDY0YzI0ZTY5NGMzZWVhNjI5ZWE5NDRmNGNmMzBkY2ZiNGZiY2UwNzFcIixcblx0XCJjb21tYW5kXCI6IFwid2FycCBuZXRoZXJcIlxufSJd" + ) if (newButtons != null) buttons = moveButtons(newButtons.map { it.copy(command = it.command?.removePrefix("/")) }) } @@ -188,31 +192,24 @@ class InventoryButtonEditor( return newButtons } - override fun renderBackground(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { - context.matrices.push() - context.matrices.translate(0F, 0F, -15F) - super.renderBackground(context, mouseX, mouseY, delta) - context.matrices.pop() - } - override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { super.render(context, mouseX, mouseY, delta) - context.matrices.push() - context.matrices.translate(0f, 0f, -10f) + context.matrices.pushMatrix() PanelComponent.DefaultBackgroundRenderer.VANILLA .render( - ModernRenderContext(context), + MoulConfigRenderContext(context), lastGuiRect.minX, lastGuiRect.minY, lastGuiRect.width, lastGuiRect.height, ) - context.matrices.pop() + context.matrices.popMatrix() for (button in buttons) { val buttonPosition = button.getBounds(lastGuiRect) - context.matrices.push() - context.matrices.translate(buttonPosition.minX.toFloat(), buttonPosition.minY.toFloat(), 0F) + context.matrices.pushMatrix() + context.matrices.translate(buttonPosition.minX.toFloat(), buttonPosition.minY.toFloat()) button.render(context) - context.matrices.pop() + context.matrices.popMatrix() } + renderPopup(context, mouseX, mouseY, delta) } override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean { @@ -228,8 +225,15 @@ class InventoryButtonEditor( if (super.mouseReleased(mouseX, mouseY, button)) return true val clickedButton = buttons.firstOrNull { it.getBounds(lastGuiRect).contains(Point(mouseX, mouseY)) } if (clickedButton != null && !justPerformedAClickAction) { - if (InputUtil.isKeyPressed(MC.window.handle, InputUtil.GLFW_KEY_LEFT_CONTROL)) Editor(clickedButton).delete() - else createPopup(MoulConfigUtils.loadGui("button_editor_fragment", Editor(clickedButton)), Point(mouseX, mouseY)) + if (InputUtil.isKeyPressed( + MC.window.handle, + InputUtil.GLFW_KEY_LEFT_CONTROL + ) + ) Editor(clickedButton).delete() + else createPopup( + MoulConfigUtils.loadGui("button_editor_fragment", Editor(clickedButton)), + Point(mouseX, mouseY) + ) return true } justPerformedAClickAction = false diff --git a/src/main/kotlin/features/inventory/buttons/InventoryButtons.kt b/src/main/kotlin/features/inventory/buttons/InventoryButtons.kt index ab80d97..46e91b2 100644 --- a/src/main/kotlin/features/inventory/buttons/InventoryButtons.kt +++ b/src/main/kotlin/features/inventory/buttons/InventoryButtons.kt @@ -76,10 +76,10 @@ object InventoryButtons { var hoveredComponent: InventoryButton? = null for (button in getValidButtons(it.screen)) { val buttonBounds = button.getBounds(bounds) - it.context.matrices.push() - it.context.matrices.translate(buttonBounds.minX.toFloat(), buttonBounds.minY.toFloat(), 0F) + it.context.matrices.pushMatrix() + it.context.matrices.translate(buttonBounds.minX.toFloat(), buttonBounds.minY.toFloat()) button.render(it.context) - it.context.matrices.pop() + it.context.matrices.popMatrix() if (buttonBounds.contains(it.mouseX, it.mouseY) && TConfig.hoverText && hoveredComponent == null) { hoveredComponent = button diff --git a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt index 267799d..a023ce6 100644 --- a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt +++ b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt @@ -20,7 +20,6 @@ import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot import net.minecraft.text.Text import net.minecraft.util.Identifier -import moe.nea.firmament.annotations.Subscribe import moe.nea.firmament.events.SlotRenderEvents import moe.nea.firmament.gui.EmptyComponent import moe.nea.firmament.gui.FirmButtonComponent @@ -182,7 +181,7 @@ class StorageOverlayScreen : Screen(Text.literal("")) { val searchField = TextFieldComponent( searchText, 100, GetSetter.constant(true), tr("firmament.storage-overlay.search.suggestion", "Search...").string, - IMinecraft.instance.defaultFontRenderer + IMinecraft.INSTANCE.defaultFontRenderer ) val controlComponent = PanelComponent( ColumnComponent( @@ -384,7 +383,7 @@ class StorageOverlayScreen : Screen(Text.literal("")) { controlComponent, measurements.controlX, measurements.controlY, CONTROL_WIDTH, CONTROL_HEIGHT, - KeyboardEvent.KeyPressed(keyCode, false) + KeyboardEvent.KeyPressed(keyCode, scanCode, false) ) ) { return true @@ -401,7 +400,7 @@ class StorageOverlayScreen : Screen(Text.literal("")) { controlComponent, measurements.controlX, measurements.controlY, CONTROL_WIDTH, CONTROL_HEIGHT, - KeyboardEvent.KeyPressed(keyCode, true) + KeyboardEvent.KeyPressed(keyCode, scanCode, true) ) ) { return true @@ -498,7 +497,7 @@ class StorageOverlayScreen : Screen(Text.literal("")) { return 18 } assertTrueOr(slots == null || slots.size == inv.stacks.size) { return 0 } - val name = page.defaultName() + val name = inventory.title val pageHeight = inv.rows * SLOT_SIZE + 8 + textRenderer.fontHeight if (slots != null && StorageOverlay.TConfig.outlineActiveStoragePage) context.drawBorder( @@ -522,8 +521,8 @@ class StorageOverlayScreen : Screen(Text.literal("")) { inv.stacks.forEachIndexed { index, stack -> val slotX = (index % 9) * SLOT_SIZE + x + 3 val slotY = (index / 9) * SLOT_SIZE + y + 5 + textRenderer.fontHeight + 1 - val fakeSlot = FakeSlot(stack, slotX, slotY) if (slots == null) { + val fakeSlot = FakeSlot(stack, slotX, slotY) SlotRenderEvents.Before.publish(SlotRenderEvents.Before(context, fakeSlot)) context.drawItem(stack, slotX, slotY) context.drawStackOverlay(textRenderer, stack, slotX, slotY) diff --git a/src/main/kotlin/features/inventory/storageoverlay/StorageOverviewScreen.kt b/src/main/kotlin/features/inventory/storageoverlay/StorageOverviewScreen.kt index 3462d3d..e383d29 100644 --- a/src/main/kotlin/features/inventory/storageoverlay/StorageOverviewScreen.kt +++ b/src/main/kotlin/features/inventory/storageoverlay/StorageOverviewScreen.kt @@ -44,10 +44,10 @@ class StorageOverviewScreen() : Screen(Text.empty()) { super.render(context, mouseX, mouseY, delta) context.fill(0, 0, width, height, 0x90000000.toInt()) layoutedForEach { (key, value), offsetX, offsetY -> - context.matrices.push() - context.matrices.translate(offsetX.toFloat(), offsetY.toFloat(), 0F) + context.matrices.pushMatrix() + context.matrices.translate(offsetX.toFloat(), offsetY.toFloat()) renderStoragePage(context, value, mouseX - offsetX, mouseY - offsetY) - context.matrices.pop() + context.matrices.popMatrix() } } diff --git a/src/main/kotlin/features/items/BonemerangOverlay.kt b/src/main/kotlin/features/items/BonemerangOverlay.kt index ffdffe3..6483b7a 100644 --- a/src/main/kotlin/features/items/BonemerangOverlay.kt +++ b/src/main/kotlin/features/items/BonemerangOverlay.kt @@ -2,6 +2,7 @@ package moe.nea.firmament.features.items import me.shedaniel.math.Color import moe.nea.jarvis.api.Point +import org.joml.Vector2i import net.minecraft.entity.LivingEntity import net.minecraft.entity.decoration.ArmorStandEntity import net.minecraft.entity.player.PlayerEntity @@ -25,7 +26,7 @@ object BonemerangOverlay : FirmamentFeature { object TConfig : ManagedConfig(identifier, Category.ITEMS) { var bonemerangOverlay by toggle("bonemerang-overlay") { false } - val bonemerangOverlayHud by position("bonemerang-overlay-hud", 80, 10) { Point(0.1, 1.0) } + val bonemerangOverlayHud by position("bonemerang-overlay-hud", 80, 10) { Vector2i() } var highlightHitEntities by toggle("highlight-hit-entities") { false } } @@ -87,7 +88,7 @@ object BonemerangOverlay : FirmamentFeature { val entities = getEntities() - it.context.matrices.push() + it.context.matrices.pushMatrix() TConfig.bonemerangOverlayHud.applyTransformations(it.context.matrices) it.context.drawText( MC.font, String.format( @@ -96,6 +97,6 @@ object BonemerangOverlay : FirmamentFeature { ).string, entities.size ), 0, 0, -1, true ) - it.context.matrices.pop() + it.context.matrices.popMatrix() } } diff --git a/src/main/kotlin/features/macros/ComboProcessor.kt b/src/main/kotlin/features/macros/ComboProcessor.kt index 5c5ac0e..1f77ff6 100644 --- a/src/main/kotlin/features/macros/ComboProcessor.kt +++ b/src/main/kotlin/features/macros/ComboProcessor.kt @@ -56,12 +56,11 @@ object ComboProcessor { fun onRender(event: HudRenderEvent) { if (!isInputting) return if (!event.isRenderingHud) return - event.context.matrices.push() + event.context.matrices.pushMatrix() val width = 120 event.context.matrices.translate( (MC.window.scaledWidth - width) / 2F, - (MC.window.scaledHeight) / 2F + 8, - 0F + (MC.window.scaledHeight) / 2F + 8 ) val breadCrumbText = breadCrumbs.joinToString(" > ") event.context.drawText( @@ -72,7 +71,7 @@ object ComboProcessor { -1, true ) - event.context.matrices.translate(0F, MC.font.fontHeight + 2F, 0F) + event.context.matrices.translate(0F, MC.font.fontHeight + 2F) for ((key, value) in activeTrie.nodes) { event.context.drawText( MC.font, @@ -82,9 +81,9 @@ object ComboProcessor { -1, true ) - event.context.matrices.translate(0F, MC.font.fontHeight + 1F, 0F) + event.context.matrices.translate(0F, MC.font.fontHeight + 1F) } - event.context.matrices.pop() + event.context.matrices.popMatrix() } @Subscribe diff --git a/src/main/kotlin/features/macros/MacroUI.kt b/src/main/kotlin/features/macros/MacroUI.kt index 8c22c5c..5a7d406 100644 --- a/src/main/kotlin/features/macros/MacroUI.kt +++ b/src/main/kotlin/features/macros/MacroUI.kt @@ -1,7 +1,9 @@ package moe.nea.firmament.features.macros +import io.github.notenoughupdates.moulconfig.common.text.StructuredText import io.github.notenoughupdates.moulconfig.gui.CloseEventListener import io.github.notenoughupdates.moulconfig.observer.ObservableList +import io.github.notenoughupdates.moulconfig.platform.MoulConfigPlatform import io.github.notenoughupdates.moulconfig.xml.Bind import moe.nea.firmament.annotations.Subscribe import moe.nea.firmament.commands.thenExecute @@ -62,6 +64,9 @@ class MacroUI { val parent: Wheel, ) { @Bind + fun textR() = StructuredText.of(text) + + @Bind fun delete() { parent.editableCommands.removeIf { it === this } parent.editableCommands.update() @@ -82,7 +87,7 @@ class MacroUI { } @Bind("keyCombo") - fun text() = binding.format().string + fun text() = MoulConfigPlatform.wrap(binding.format()) @field:Bind("commands") val commands = commands.mapTo(ObservableList(mutableListOf())) { Command(it.command, this) } @@ -246,12 +251,15 @@ class MacroUI { @field:Bind("command") var command: String = (action.action as CommandAction).command + @Bind + fun commandR() = StructuredText.of(command) + @field:Bind("combo") val combo = action.keys.map { KeyBindingEditor(it, this) }.toObservableList() @Bind fun formattedCombo() = - combo.joinToString(" > ") { it.binding.toString() } + StructuredText.of(combo.joinToString(" > ") { it.binding.toString() }) // TODO: this can be joined without .toString() @Bind fun addStep() { diff --git a/src/main/kotlin/features/macros/RadialMenu.kt b/src/main/kotlin/features/macros/RadialMenu.kt index 9e5222f..5134994 100644 --- a/src/main/kotlin/features/macros/RadialMenu.kt +++ b/src/main/kotlin/features/macros/RadialMenu.kt @@ -63,11 +63,10 @@ object RadialMenuViewer { fun onRender(event: HudRenderEvent) { val menu = activeMenu ?: return val mat = event.context.matrices - mat.push() + mat.pushMatrix() mat.translate( (MC.window.scaledWidth) / 2F, (MC.window.scaledHeight) / 2F, - 0F ) val sliceWidth = (τ / menu.options.size).toFloat() var selectedAngle = wrapAngle(atan2(delta.y, delta.x)) @@ -75,8 +74,8 @@ object RadialMenuViewer { selectedAngle = Float.NaN for ((idx, option) in menu.options.withIndex()) { val range = (sliceWidth * idx)..(sliceWidth * (idx + 1)) - mat.push() - mat.scale(64F, 64F, 1F) + mat.pushMatrix() + mat.scale(64F, 64F) val cutout = INNER_CIRCLE_RADIUS / 64F / 2 RenderCircleProgress.renderCircularSlice( event.context, @@ -86,16 +85,16 @@ object RadialMenuViewer { color = if (selectedAngle in range) 0x70A0A0A0 else 0x70FFFFFF, innerCutoutRadius = cutout ) - mat.pop() - mat.push() + mat.popMatrix() + mat.pushMatrix() val centreAngle = lerpAngle(range.start, range.endInclusive, 0.5F) val vec = Vector2f(cos(centreAngle), sin(centreAngle)).mul(40F) - mat.translate(vec.x, vec.y, 0F) + mat.translate(vec.x, vec.y) option.renderSlice(event.context) - mat.pop() + mat.popMatrix() } event.context.drawLine(1, 1, delta.x.toInt(), delta.y.toInt(), me.shedaniel.math.Color.ofOpaque(0x00FF00)) - mat.pop() + mat.popMatrix() } @Subscribe diff --git a/src/main/kotlin/features/mining/MiningBlockInfoUi.kt b/src/main/kotlin/features/mining/MiningBlockInfoUi.kt index e8ea4f4..5b58d4f 100644 --- a/src/main/kotlin/features/mining/MiningBlockInfoUi.kt +++ b/src/main/kotlin/features/mining/MiningBlockInfoUi.kt @@ -2,7 +2,7 @@ package moe.nea.firmament.features.mining import io.github.notenoughupdates.moulconfig.observer.ObservableList import io.github.notenoughupdates.moulconfig.observer.Property -import io.github.notenoughupdates.moulconfig.platform.ModernItemStack +import io.github.notenoughupdates.moulconfig.platform.MoulConfigPlatform import io.github.notenoughupdates.moulconfig.xml.Bind import net.minecraft.client.gui.screen.Screen import net.minecraft.item.ItemStack @@ -31,7 +31,7 @@ object MiningBlockInfoUi { class BlockInfo(val block: MiningRepoData.Block189, val info: MiningInfo) { @get:Bind("item") - val item = ModernItemStack.of(block.block?.let { ItemStack(it) } ?: ItemStack.EMPTY) + val item = MoulConfigPlatform.wrap(block.block?.let { ItemStack(it) } ?: ItemStack.EMPTY) @get:Bind("isSelected") val isSelected get() = info.search.let { block.isActiveIn(SkyBlockIsland.forMode(it)) } diff --git a/src/main/kotlin/features/mining/PickaxeAbility.kt b/src/main/kotlin/features/mining/PickaxeAbility.kt index a049001..df683de 100644 --- a/src/main/kotlin/features/mining/PickaxeAbility.kt +++ b/src/main/kotlin/features/mining/PickaxeAbility.kt @@ -231,14 +231,14 @@ object PickaxeAbility : FirmamentFeature { if (ao != ability.name && ao != null) { ability = PickaxeAbilityData(ao, defaultAbilityDurations[ao] ?: 120.seconds) } - event.context.matrices.push() - event.context.matrices.translate(MC.window.scaledWidth / 2F, MC.window.scaledHeight / 2F, 0F) - event.context.matrices.scale(TConfig.cooldownScale.toFloat(), TConfig.cooldownScale.toFloat(), 1F) + event.context.matrices.pushMatrix() + event.context.matrices.translate(MC.window.scaledWidth / 2F, MC.window.scaledHeight / 2F) + event.context.matrices.scale(TConfig.cooldownScale.toFloat(), TConfig.cooldownScale.toFloat()) RenderCircleProgress.renderCircle( event.context, Identifier.of("firmament", "textures/gui/circle.png"), getCooldownPercentage(ability.name, ability.cooldown).toFloat(), 0f, 1f, 0f, 1f ) - event.context.matrices.pop() + event.context.matrices.popMatrix() } } diff --git a/src/main/kotlin/features/mining/PristineProfitTracker.kt b/src/main/kotlin/features/mining/PristineProfitTracker.kt index 377a470..eb3cba6 100644 --- a/src/main/kotlin/features/mining/PristineProfitTracker.kt +++ b/src/main/kotlin/features/mining/PristineProfitTracker.kt @@ -2,6 +2,7 @@ package moe.nea.firmament.features.mining import io.github.notenoughupdates.moulconfig.xml.Bind import moe.nea.jarvis.api.Point +import org.joml.Vector2i import kotlinx.serialization.Serializable import kotlinx.serialization.serializer import kotlin.time.Duration.Companion.seconds @@ -57,7 +58,7 @@ object PristineProfitTracker : FirmamentFeature { object TConfig : ManagedConfig(identifier, Category.MINING) { val timeout by duration("timeout", 0.seconds, 120.seconds) { 30.seconds } - val gui by position("position", 100, 30) { Point(0.05, 0.2) } + val gui by position("position", 100, 30) { Vector2i() } val useFineGemstones by toggle("fine-gemstones") { false } } diff --git a/src/main/kotlin/features/misc/CustomCapes.kt b/src/main/kotlin/features/misc/CustomCapes.kt index dc5187a..77a5c2d 100644 --- a/src/main/kotlin/features/misc/CustomCapes.kt +++ b/src/main/kotlin/features/misc/CustomCapes.kt @@ -1,8 +1,13 @@ package moe.nea.firmament.features.misc +import com.mojang.blaze3d.buffers.GpuBuffer +import com.mojang.blaze3d.buffers.Std140Builder import com.mojang.blaze3d.systems.RenderSystem +import java.nio.ByteBuffer +import java.nio.ByteOrder import java.util.OptionalDouble import java.util.OptionalInt +import org.joml.Vector4f import util.render.CustomRenderPipelines import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds @@ -14,12 +19,14 @@ import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.entity.state.PlayerEntityRenderState import net.minecraft.client.util.BufferAllocator import net.minecraft.client.util.SkinTextures +import net.minecraft.client.util.math.MatrixStack import net.minecraft.util.Identifier import moe.nea.firmament.Firmament import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.gui.config.ManagedConfig import moe.nea.firmament.util.MC import moe.nea.firmament.util.TimeMark +import moe.nea.firmament.util.mc.CustomRenderPassHelper object CustomCapes : FirmamentFeature { override val identifier: String @@ -36,6 +43,7 @@ object CustomCapes : FirmamentFeature { fun replaceRender( renderLayer: RenderLayer, vertexConsumerProvider: VertexConsumerProvider, + matrixStack: MatrixStack, model: (VertexConsumer) -> Unit ) } @@ -46,6 +54,7 @@ object CustomCapes : FirmamentFeature { override fun replaceRender( renderLayer: RenderLayer, vertexConsumerProvider: VertexConsumerProvider, + matrixStack: MatrixStack, model: (VertexConsumer) -> Unit ) { model(vertexConsumerProvider.getBuffer(RenderLayer.getEntitySolid(location))) @@ -61,37 +70,27 @@ object CustomCapes : FirmamentFeature { override fun replaceRender( renderLayer: RenderLayer, vertexConsumerProvider: VertexConsumerProvider, + matrixStack: MatrixStack, model: (VertexConsumer) -> Unit ) { - BufferAllocator(2048).use { allocator -> - val bufferBuilder = BufferBuilder(allocator, renderLayer.drawMode, renderLayer.vertexFormat) - model(bufferBuilder) - bufferBuilder.end().use { buffer -> - val commandEncoder = RenderSystem.getDevice().createCommandEncoder() - val vertexBuffer = renderLayer.vertexFormat.uploadImmediateVertexBuffer(buffer.buffer) - val indexBufferConstructor = RenderSystem.getSequentialBuffer(renderLayer.drawMode) - val indexBuffer = indexBufferConstructor.getIndexBuffer(buffer.drawParameters.indexCount) - val templateTexture = MC.textureManager.getTexture(template) - val backgroundTexture = MC.textureManager.getTexture(background) - val foregroundTexture = MC.textureManager.getTexture(overlay) - commandEncoder.createRenderPass( - MC.instance.framebuffer.colorAttachment, - OptionalInt.empty(), - MC.instance.framebuffer.depthAttachment, - OptionalDouble.empty(), - ).use { renderPass -> - // TODO: account for lighting - renderPass.setPipeline(CustomRenderPipelines.PARALLAX_CAPE_SHADER) - renderPass.bindSampler("Sampler0", templateTexture.glTexture) - renderPass.bindSampler("Sampler1", backgroundTexture.glTexture) - renderPass.bindSampler("Sampler3", foregroundTexture.glTexture) - val animationValue = (startTime.passedTime() / animationSpeed).mod(1F) - renderPass.setUniform("Animation", animationValue.toFloat()) - renderPass.setIndexBuffer(indexBuffer, indexBufferConstructor.indexType) - renderPass.setVertexBuffer(0, vertexBuffer) - renderPass.drawIndexed(0, buffer.drawParameters.indexCount) - } + val animationValue = (startTime.passedTime() / animationSpeed).mod(1F) + CustomRenderPassHelper( + { "Firmament Cape Renderer" }, + renderLayer.drawMode, + renderLayer.vertexFormat, + MC.instance.framebuffer, + true, + ).use { renderPass -> + renderPass.setPipeline(CustomRenderPipelines.PARALLAX_CAPE_SHADER) + renderPass.setAllDefaultUniforms() + renderPass.setUniform("Animation", 4) { + it.putFloat(animationValue.toFloat()) } + renderPass.bindSampler("Sampler0", template) + renderPass.bindSampler("Sampler1", background) + renderPass.bindSampler("Sampler3", overlay) + renderPass.uploadVertices(2048, model) + renderPass.draw() } } } @@ -122,7 +121,10 @@ object CustomCapes : FirmamentFeature { 110.seconds ) ), - + UNPLEASANT_GRADIENT( + "unpleasant_gradient", + TexturedCapeRenderer(Firmament.identifier("textures/cape/unpleasant_gradient.png")) + ), FURFSKY_STATIC( "FurfSky", TexturedCapeRenderer(Firmament.identifier("textures/cape/fsr_static.png")) @@ -141,7 +143,7 @@ object CustomCapes : FirmamentFeature { val byUuid = listOf( listOf( - Devs.nea to AllCapes.FIRMAMENT_ANIMATED, + Devs.nea to AllCapes.UNPLEASANT_GRADIENT, Devs.kath to AllCapes.FIRMAMENT_STATIC, Devs.jani to AllCapes.FIRMAMENT_ANIMATED, ), @@ -154,12 +156,13 @@ object CustomCapes : FirmamentFeature { vertexConsumer: VertexConsumer, renderLayer: RenderLayer, vertexConsumerProvider: VertexConsumerProvider, + matrixStack: MatrixStack, model: (VertexConsumer) -> Unit ) { val capeStorage = CapeStorage.cast(playerEntityRenderState) val firmCape = capeStorage.cape_firmament if (firmCape != null) { - firmCape.render.replaceRender(renderLayer, vertexConsumerProvider, model) + firmCape.render.replaceRender(renderLayer, vertexConsumerProvider, matrixStack, model) } else { model(vertexConsumer) } diff --git a/src/main/kotlin/features/misc/Hud.kt b/src/main/kotlin/features/misc/Hud.kt index 9661fc5..8c785ab 100644 --- a/src/main/kotlin/features/misc/Hud.kt +++ b/src/main/kotlin/features/misc/Hud.kt @@ -7,6 +7,7 @@ import moe.nea.firmament.gui.config.ManagedConfig import moe.nea.firmament.util.MC import moe.nea.firmament.util.tr import moe.nea.jarvis.api.Point +import org.joml.Vector2i import net.minecraft.client.network.PlayerListEntry import net.minecraft.text.Text @@ -16,11 +17,11 @@ object Hud : FirmamentFeature { object TConfig : ManagedConfig(identifier, Category.MISC) { var dayCount by toggle("day-count") { false } - val dayCountHud by position("day-count-hud", 80, 10) { Point(0.5, 0.8) } + val dayCountHud by position("day-count-hud", 80, 10) { Vector2i() } var fpsCount by toggle("fps-count") { false } - val fpsCountHud by position("fps-count-hud", 80, 10) { Point(0.5, 0.9) } + val fpsCountHud by position("fps-count-hud", 80, 10) { Vector2i() } var pingCount by toggle("ping-count") { false } - val pingCountHud by position("ping-count-hud", 80, 10) { Point(0.5, 1.0) } + val pingCountHud by position("ping-count-hud", 80, 10) { Vector2i() } } override val config: ManagedConfig @@ -29,7 +30,7 @@ object Hud : FirmamentFeature { @Subscribe fun onRenderHud(it: HudRenderEvent) { if (TConfig.dayCount) { - it.context.matrices.push() + it.context.matrices.pushMatrix() TConfig.dayCountHud.applyTransformations(it.context.matrices) val day = (MC.world?.timeOfDay ?: 0L) / 24000 it.context.drawText( @@ -40,11 +41,11 @@ object Hud : FirmamentFeature { -1, true ) - it.context.matrices.pop() + it.context.matrices.popMatrix() } if (TConfig.fpsCount) { - it.context.matrices.push() + it.context.matrices.pushMatrix() TConfig.fpsCountHud.applyTransformations(it.context.matrices) it.context.drawText( MC.font, Text.literal( @@ -53,11 +54,11 @@ object Hud : FirmamentFeature { ) ), 36, MC.font.fontHeight, -1, true ) - it.context.matrices.pop() + it.context.matrices.popMatrix() } if (TConfig.pingCount) { - it.context.matrices.push() + it.context.matrices.pushMatrix() TConfig.pingCountHud.applyTransformations(it.context.matrices) val ping = MC.player?.let { val entry: PlayerListEntry? = MC.networkHandler?.getPlayerListEntry(it.uuid) @@ -71,7 +72,7 @@ object Hud : FirmamentFeature { ), 36, MC.font.fontHeight, -1, true ) - it.context.matrices.pop() + it.context.matrices.popMatrix() } } } diff --git a/src/main/kotlin/features/world/FairySouls.kt b/src/main/kotlin/features/world/FairySouls.kt index d4bf560..699aafc 100644 --- a/src/main/kotlin/features/world/FairySouls.kt +++ b/src/main/kotlin/features/world/FairySouls.kt @@ -103,7 +103,6 @@ object FairySouls : FirmamentFeature { currentMissingSouls.forEach { block(it.blockPos, Color.ofRGBA(176, 0, 255, 128).color) } - color(1f, 0f, 1f, 1f) currentLocationSouls.forEach { wireframeCube(it.blockPos) } diff --git a/src/main/kotlin/features/world/Waypoints.kt b/src/main/kotlin/features/world/Waypoints.kt index b4f91b0..205d5eb 100644 --- a/src/main/kotlin/features/world/Waypoints.kt +++ b/src/main/kotlin/features/world/Waypoints.kt @@ -53,8 +53,7 @@ object Waypoints : FirmamentFeature { } else { orderedIndex %= w.waypoints.size val firstColor = Color.ofRGBA(0, 200, 40, 180) - color(firstColor) - tracer(w.waypoints[orderedIndex].blockPos.toCenterPos(), lineWidth = 3f) + tracer(w.waypoints[orderedIndex].blockPos.toCenterPos(), color = firstColor.color, lineWidth = 3f) w.waypoints.withIndex().toList().wrappingWindow(orderedIndex, 3).zip(listOf( firstColor, Color.ofRGBA(180, 200, 40, 150), diff --git a/src/main/kotlin/gui/BarComponent.kt b/src/main/kotlin/gui/BarComponent.kt index da781da..751ea39 100644 --- a/src/main/kotlin/gui/BarComponent.kt +++ b/src/main/kotlin/gui/BarComponent.kt @@ -6,8 +6,10 @@ import io.github.notenoughupdates.moulconfig.common.RenderContext import io.github.notenoughupdates.moulconfig.gui.GuiComponent import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext import io.github.notenoughupdates.moulconfig.observer.GetSetter -import io.github.notenoughupdates.moulconfig.platform.ModernRenderContext +import io.github.notenoughupdates.moulconfig.platform.MoulConfigPlatform +import io.github.notenoughupdates.moulconfig.platform.MoulConfigRenderContext import me.shedaniel.math.Color +import net.minecraft.client.gl.RenderPipelines import net.minecraft.client.gui.DrawContext import net.minecraft.client.render.RenderLayer import net.minecraft.util.Identifier @@ -33,7 +35,7 @@ class BarComponent( ) { fun draw(context: DrawContext, x: Int, y: Int, width: Int, height: Int, color: Color) { context.drawTexturedQuad( - RenderLayer::getGuiTextured, + RenderPipelines.GUI_TEXTURED, identifier, x, y, x + width, x + height, u1, u2, v1, v2, @@ -81,7 +83,7 @@ class BarComponent( } override fun render(context: GuiImmediateContext) { - val renderContext = (context.renderContext as ModernRenderContext).drawContext + val renderContext = (context.renderContext as MoulConfigRenderContext).drawContext var i = 0 val x = 0 val y = 0 @@ -104,7 +106,6 @@ class BarComponent( (context.width - 4) * total.get() / context.width, total.get() ) - RenderSystem.setShaderColor(1F, 1F, 1F, 1F) } diff --git a/src/main/kotlin/gui/CheckboxComponent.kt b/src/main/kotlin/gui/CheckboxComponent.kt index fc48661..7a9f2ef 100644 --- a/src/main/kotlin/gui/CheckboxComponent.kt +++ b/src/main/kotlin/gui/CheckboxComponent.kt @@ -4,7 +4,8 @@ import io.github.notenoughupdates.moulconfig.gui.GuiComponent import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext import io.github.notenoughupdates.moulconfig.gui.MouseEvent import io.github.notenoughupdates.moulconfig.observer.GetSetter -import io.github.notenoughupdates.moulconfig.platform.ModernRenderContext +import io.github.notenoughupdates.moulconfig.platform.MoulConfigRenderContext +import net.minecraft.client.gl.RenderPipelines import net.minecraft.client.render.RenderLayer import moe.nea.firmament.Firmament @@ -25,9 +26,9 @@ class CheckboxComponent<T>( } override fun render(context: GuiImmediateContext) { - val ctx = (context.renderContext as ModernRenderContext).drawContext + val ctx = (context.renderContext as MoulConfigRenderContext).drawContext ctx.drawGuiTexture( - RenderLayer::getGuiTextured, + RenderPipelines.GUI_TEXTURED, if (isEnabled()) Firmament.identifier("widget/checkbox_checked") else Firmament.identifier("widget/checkbox_unchecked"), 0, 0, diff --git a/src/main/kotlin/gui/FirmHoverComponent.kt b/src/main/kotlin/gui/FirmHoverComponent.kt index e38582a..eed795a 100644 --- a/src/main/kotlin/gui/FirmHoverComponent.kt +++ b/src/main/kotlin/gui/FirmHoverComponent.kt @@ -1,5 +1,6 @@ package moe.nea.firmament.gui +import io.github.notenoughupdates.moulconfig.common.text.StructuredText import io.github.notenoughupdates.moulconfig.gui.GuiComponent import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext import io.github.notenoughupdates.moulconfig.gui.KeyboardEvent @@ -31,7 +32,8 @@ class FirmHoverComponent( override fun render(context: GuiImmediateContext) { if (context.isHovered && (permaHover || lastMouseMove.passedTime() > hoverDelay)) { - context.renderContext.scheduleDrawTooltip(context.mouseX, context.mouseY, hoverLines.get()) + context.renderContext.scheduleDrawTooltip(context.mouseX, context.mouseY, hoverLines.get() + .map { it -> StructuredText.of(it) }) permaHover = true } else { permaHover = false diff --git a/src/main/kotlin/gui/config/DurationHandler.kt b/src/main/kotlin/gui/config/DurationHandler.kt index 8d485b1..32bec25 100644 --- a/src/main/kotlin/gui/config/DurationHandler.kt +++ b/src/main/kotlin/gui/config/DurationHandler.kt @@ -3,6 +3,7 @@ package moe.nea.firmament.gui.config import io.github.notenoughupdates.moulconfig.common.IMinecraft +import io.github.notenoughupdates.moulconfig.common.text.StructuredText import io.github.notenoughupdates.moulconfig.gui.component.RowComponent import io.github.notenoughupdates.moulconfig.gui.component.SliderComponent import io.github.notenoughupdates.moulconfig.gui.component.TextComponent @@ -31,8 +32,8 @@ class DurationHandler(val config: ManagedConfig, val min: Duration, val max: Dur guiAppender.appendLabeledRow( opt.labelText, RowComponent( - TextComponent(IMinecraft.instance.defaultFontRenderer, - { FirmFormatters.formatTimespan(opt.value) }, + TextComponent(IMinecraft.INSTANCE.defaultFontRenderer, + { StructuredText.of(FirmFormatters.formatTimespan(opt.value)) }, 40, TextComponent.TextAlignment.CENTER, true, diff --git a/src/main/kotlin/gui/config/HudMetaHandler.kt b/src/main/kotlin/gui/config/HudMetaHandler.kt index a9659ee..0637351 100644 --- a/src/main/kotlin/gui/config/HudMetaHandler.kt +++ b/src/main/kotlin/gui/config/HudMetaHandler.kt @@ -8,18 +8,25 @@ import kotlinx.serialization.json.encodeToJsonElement import net.minecraft.client.gui.screen.Screen import net.minecraft.text.MutableText import net.minecraft.text.Text +import moe.nea.firmament.Firmament import moe.nea.firmament.gui.FirmButtonComponent import moe.nea.firmament.jarvis.JarvisIntegration import moe.nea.firmament.util.MC -class HudMetaHandler(val config: ManagedConfig, val label: MutableText, val width: Int, val height: Int) : +class HudMetaHandler( + val config: ManagedConfig, + val propertyName: String, + val label: MutableText, + val width: Int, + val height: Int +) : ManagedConfig.OptionHandler<HudMeta> { override fun toJson(element: HudMeta): JsonElement? { return Json.encodeToJsonElement(element.position) } override fun fromJson(element: JsonElement): HudMeta { - return HudMeta(Json.decodeFromJsonElement(element), label, width, height) + return HudMeta(Json.decodeFromJsonElement(element), Firmament.identifier(propertyName), label, width, height) } fun openEditor(option: ManagedOption<HudMeta>, oldScreen: Screen) { @@ -34,7 +41,8 @@ class HudMetaHandler(val config: ManagedConfig, val label: MutableText, val widt opt.labelText, FirmButtonComponent( TextComponent( - Text.stringifiedTranslatable("firmament.hud.edit", label).string), + Text.stringifiedTranslatable("firmament.hud.edit", label).string + ), ) { openEditor(opt, guiAppender.screenAccessor()) }) diff --git a/src/main/kotlin/gui/config/IntegerHandler.kt b/src/main/kotlin/gui/config/IntegerHandler.kt index 31ce90f..fd10447 100644 --- a/src/main/kotlin/gui/config/IntegerHandler.kt +++ b/src/main/kotlin/gui/config/IntegerHandler.kt @@ -3,6 +3,7 @@ package moe.nea.firmament.gui.config import io.github.notenoughupdates.moulconfig.common.IMinecraft +import io.github.notenoughupdates.moulconfig.common.text.StructuredText import io.github.notenoughupdates.moulconfig.gui.component.RowComponent import io.github.notenoughupdates.moulconfig.gui.component.SliderComponent import io.github.notenoughupdates.moulconfig.gui.component.TextComponent @@ -26,8 +27,8 @@ class IntegerHandler(val config: ManagedConfig, val min: Int, val max: Int) : Ma guiAppender.appendLabeledRow( opt.labelText, RowComponent( - TextComponent(IMinecraft.instance.defaultFontRenderer, - { FirmFormatters.formatCommas(opt.value, 0) }, + TextComponent(IMinecraft.INSTANCE.defaultFontRenderer, + { StructuredText.of(FirmFormatters.formatCommas(opt.value, 0)) }, 40, TextComponent.TextAlignment.CENTER, true, diff --git a/src/main/kotlin/gui/config/JAnyHud.kt b/src/main/kotlin/gui/config/JAnyHud.kt index 35c4eb2..1cde4f9 100644 --- a/src/main/kotlin/gui/config/JAnyHud.kt +++ b/src/main/kotlin/gui/config/JAnyHud.kt @@ -1,48 +1,67 @@ - - package moe.nea.firmament.gui.config import moe.nea.jarvis.api.JarvisHud -import moe.nea.jarvis.api.JarvisScalable +import org.joml.Matrix3x2f +import org.joml.Vector2i +import org.joml.Vector2ic import kotlinx.serialization.Serializable import net.minecraft.text.Text +import net.minecraft.util.Identifier +import moe.nea.firmament.jarvis.JarvisIntegration @Serializable data class HudPosition( - var x: Double, - var y: Double, - var scale: Float, + var x: Int, + var y: Int, + var scale: Float, ) data class HudMeta( - val position: HudPosition, - private val label: Text, - private val width: Int, - private val height: Int, -) : JarvisScalable, JarvisHud { - override fun getX(): Double = position.x + val position: HudPosition, + private val id: Identifier, + private val label: Text, + private val width: Int, + private val height: Int, +) : JarvisHud, JarvisHud.Scalable { + override fun getLabel(): Text = label + override fun getUnscaledWidth(): Int { + return width + } + + override fun getUnscaledHeight(): Int { + return height + } - override fun setX(newX: Double) { - position.x = newX - } + override fun getHudId(): Identifier { + return id + } - override fun getY(): Double = position.y + override fun getPosition(): Vector2ic { + return Vector2i(position.x, position.y) + } - override fun setY(newY: Double) { - position.y = newY - } + override fun setPosition(p0: Vector2ic) { + position.x = p0.x() + position.y = p0.y() + } - override fun getLabel(): Text = label + override fun isEnabled(): Boolean { + return true // TODO: this should be actually truthful, if possible + } - override fun getWidth(): Int = width + override fun isVisible(): Boolean { + return true // TODO: this should be actually truthful, if possible + } - override fun getHeight(): Int = height + override fun getScale(): Float = position.scale - override fun getScale(): Float = position.scale + override fun setScale(newScale: Float) { + position.scale = newScale + } - override fun setScale(newScale: Float) { - position.scale = newScale - } + fun applyTransformations(matrix4f: Matrix3x2f) { + applyTransformations(JarvisIntegration.jarvis, matrix4f) + } } diff --git a/src/main/kotlin/gui/config/KeyBindingStateManager.kt b/src/main/kotlin/gui/config/KeyBindingStateManager.kt index 1528ac4..49a4465 100644 --- a/src/main/kotlin/gui/config/KeyBindingStateManager.kt +++ b/src/main/kotlin/gui/config/KeyBindingStateManager.kt @@ -6,6 +6,7 @@ import io.github.notenoughupdates.moulconfig.deps.libninepatch.NinePatch import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext import io.github.notenoughupdates.moulconfig.gui.KeyboardEvent import io.github.notenoughupdates.moulconfig.gui.component.TextComponent +import io.github.notenoughupdates.moulconfig.platform.MoulConfigPlatform import org.lwjgl.glfw.GLFW import net.minecraft.text.Text import net.minecraft.util.Formatting @@ -116,8 +117,8 @@ class KeyBindingStateManager( fun createButton(): FirmButtonComponent { return object : FirmButtonComponent( TextComponent( - IMinecraft.instance.defaultFontRenderer, - { this@KeyBindingStateManager.label.string }, + IMinecraft.INSTANCE.defaultFontRenderer, + { MoulConfigPlatform.wrap(this@KeyBindingStateManager.label) }, 130, TextComponent.TextAlignment.LEFT, false, diff --git a/src/main/kotlin/gui/config/ManagedConfig.kt b/src/main/kotlin/gui/config/ManagedConfig.kt index 12b82d6..2f4144c 100644 --- a/src/main/kotlin/gui/config/ManagedConfig.kt +++ b/src/main/kotlin/gui/config/ManagedConfig.kt @@ -3,7 +3,6 @@ package moe.nea.firmament.gui.config import com.mojang.serialization.Codec import io.github.notenoughupdates.moulconfig.ChromaColour import io.github.notenoughupdates.moulconfig.gui.CloseEventListener -import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper import io.github.notenoughupdates.moulconfig.gui.GuiContext import io.github.notenoughupdates.moulconfig.gui.component.CenterComponent import io.github.notenoughupdates.moulconfig.gui.component.ColumnComponent @@ -11,7 +10,9 @@ import io.github.notenoughupdates.moulconfig.gui.component.PanelComponent import io.github.notenoughupdates.moulconfig.gui.component.RowComponent import io.github.notenoughupdates.moulconfig.gui.component.ScrollPanelComponent import io.github.notenoughupdates.moulconfig.gui.component.TextComponent +import io.github.notenoughupdates.moulconfig.platform.MoulConfigScreenComponent import moe.nea.jarvis.api.Point +import org.joml.Vector2i import org.lwjgl.glfw.GLFW import kotlinx.serialization.encodeToString import kotlinx.serialization.json.JsonElement @@ -119,7 +120,7 @@ abstract class ManagedConfig( return option(propertyName, default, BooleanHandler(this)) } - protected fun colour(propertyName: String, default: ()-> ChromaColour) : ManagedOption<ChromaColour> { + protected fun colour(propertyName: String, default: () -> ChromaColour): ManagedOption<ChromaColour> { return option(propertyName, default, ColourHandler(this)) } @@ -172,13 +173,13 @@ abstract class ManagedConfig( propertyName: String, width: Int, height: Int, - default: () -> Point, + default: () -> Vector2i, ): ManagedOption<HudMeta> { val label = Text.translatable("firmament.config.${name}.${propertyName}") return option(propertyName, { val p = default() - HudMeta(HudPosition(p.x, p.y, 1F), label, width, height) - }, HudMetaHandler(this, label, width, height)) + HudMeta(HudPosition(p.x(), p.y(), 1F), Firmament.identifier(propertyName), label, width, height) + }, HudMetaHandler(this, propertyName, label, width, height)) } protected fun keyBinding( @@ -228,7 +229,8 @@ abstract class ManagedConfig( var screen: Screen? = null val guiapp = GuiAppender(400) { requireNotNull(screen) { "Screen Accessor called too early" } } latestGuiAppender = guiapp - guiapp.appendFullRow(RowComponent( + guiapp.appendFullRow( + RowComponent( FirmButtonComponent(TextComponent("←")) { if (parent != null) { save() @@ -240,12 +242,16 @@ abstract class ManagedConfig( )) sortedOptions.forEach { it.appendToGui(guiapp) } guiapp.reloadables.forEach { it() } - val component = CenterComponent(PanelComponent(ScrollPanelComponent(400, 300, ColumnComponent(guiapp.panel)), - 10, - PanelComponent.DefaultBackgroundRenderer.VANILLA)) - screen = object : GuiComponentWrapper(GuiContext(component)) { + val component = CenterComponent( + PanelComponent( + ScrollPanelComponent(400, 300, ColumnComponent(guiapp.panel)), + 10, + PanelComponent.DefaultBackgroundRenderer.VANILLA + ) + ) + screen = object : MoulConfigScreenComponent(Text.empty(), GuiContext(component), parent) { override fun close() { - if (context.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) { + if (guiContext.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) { client!!.setScreen(parent) } } diff --git a/src/main/kotlin/gui/entity/EntityRenderer.kt b/src/main/kotlin/gui/entity/EntityRenderer.kt index a1b2577..435c628 100644 --- a/src/main/kotlin/gui/entity/EntityRenderer.kt +++ b/src/main/kotlin/gui/entity/EntityRenderer.kt @@ -30,10 +30,11 @@ object EntityRenderer { "Armadillo" to t(EntityType.ARMADILLO), "ArmorStand" to t(EntityType.ARMOR_STAND), "Axolotl" to t(EntityType.AXOLOTL), - "BREEZE" to t(EntityType.BREEZE), "Bat" to t(EntityType.BAT), "Bee" to t(EntityType.BEE), "Blaze" to t(EntityType.BLAZE), + "Bogged" to t(EntityType.BOGGED), + "Breeze" to t(EntityType.BREEZE), "CaveSpider" to t(EntityType.CAVE_SPIDER), "Chicken" to t(EntityType.CHICKEN), "Cod" to t(EntityType.COD), @@ -121,7 +122,8 @@ object EntityRenderer { for (modifierJson in modifiers) { val modifier = ErrorUtil.notNullOr( modifierJson["type"]?.asString?.let(entityModifiers::get), - "Could not create entity with id $entityId. Failed to apply modifier $modifierJson") { return null } + "Could not create entity with id $entityId. Failed to apply modifier $modifierJson" + ) { return null } entity = modifier.apply(entity, modifierJson) } return entity @@ -217,8 +219,8 @@ object EntityRenderer { val vector3f = Vector3f(0.0f, (entity.height / 2.0f + bottomOffset).toFloat(), 0.0f) InventoryScreen.drawEntity( context, - centerX, - centerY, + x1, y1, + x2, y2, size.toFloat(), vector3f, rotateToFaceTheFront, diff --git a/src/main/kotlin/gui/hud/MoulConfigHud.kt b/src/main/kotlin/gui/hud/MoulConfigHud.kt index e99b069..8259ebe 100644 --- a/src/main/kotlin/gui/hud/MoulConfigHud.kt +++ b/src/main/kotlin/gui/hud/MoulConfigHud.kt @@ -1,66 +1,68 @@ - package moe.nea.firmament.gui.hud -import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper import io.github.notenoughupdates.moulconfig.gui.GuiContext import io.github.notenoughupdates.moulconfig.gui.component.TextComponent +import io.github.notenoughupdates.moulconfig.platform.MoulConfigScreenComponent import net.minecraft.resource.ResourceManager import net.minecraft.resource.SynchronousResourceReloader +import net.minecraft.text.Text import moe.nea.firmament.events.FinalizeResourceManagerEvent import moe.nea.firmament.events.HudRenderEvent import moe.nea.firmament.gui.config.HudMeta +import moe.nea.firmament.jarvis.JarvisIntegration import moe.nea.firmament.util.MC import moe.nea.firmament.util.MoulConfigUtils abstract class MoulConfigHud( - val name: String, - val hudMeta: HudMeta, + val name: String, + val hudMeta: HudMeta, ) { - companion object { - private val componentWrapper by lazy { - object : GuiComponentWrapper(GuiContext(TextComponent("§cERROR"))) { - init { - this.client = MC.instance - } - } - } - } + companion object { + private val componentWrapper by lazy { + object : MoulConfigScreenComponent(Text.empty(), GuiContext(TextComponent("§cERROR")), null) { + init { + this.client = MC.instance + } + } + } + } - private var fragment: GuiContext? = null + private var fragment: GuiContext? = null - fun forceInit() { - } + fun forceInit() { + } - open fun shouldRender(): Boolean { - return true - } + open fun shouldRender(): Boolean { + return true + } - init { - require(name.matches("^[a-z_/]+$".toRegex())) - HudRenderEvent.subscribe("MoulConfigHud:render") { - if (!shouldRender()) return@subscribe - val renderContext = componentWrapper.createContext(it.context) - if (fragment == null) - loadFragment() - it.context.matrices.push() - hudMeta.applyTransformations(it.context.matrices) - val renderContextTranslated = - renderContext.translated(hudMeta.absoluteX, hudMeta.absoluteY, hudMeta.width, hudMeta.height) - .scaled(hudMeta.scale) - fragment!!.root.render(renderContextTranslated) - it.context.matrices.pop() - } - FinalizeResourceManagerEvent.subscribe("MoulConfigHud:finalizeResourceManager") { - MC.resourceManager.registerReloader(object : SynchronousResourceReloader { - override fun reload(manager: ResourceManager?) { - fragment = null - } - }) - } - } + init { + require(name.matches("^[a-z_/]+$".toRegex())) + HudRenderEvent.subscribe("MoulConfigHud:render") { + if (!shouldRender()) return@subscribe + val renderContext = componentWrapper.createContext(it.context) + if (fragment == null) + loadFragment() + it.context.matrices.pushMatrix() + hudMeta.applyTransformations(it.context.matrices) + val pos = hudMeta.getEffectivePosition(JarvisIntegration.jarvis) + val renderContextTranslated = + renderContext.translated(pos.x(), pos.y(), hudMeta.effectiveWidth, hudMeta.effectiveHeight) + .scaled(hudMeta.scale) + fragment!!.root.render(renderContextTranslated) + it.context.matrices.popMatrix() + } + FinalizeResourceManagerEvent.subscribe("MoulConfigHud:finalizeResourceManager") { + MC.resourceManager.registerReloader(object : SynchronousResourceReloader { + override fun reload(manager: ResourceManager?) { + fragment = null + } + }) + } + } - fun loadFragment() { - fragment = MoulConfigUtils.loadGui(name, this) - } + fun loadFragment() { + fragment = MoulConfigUtils.loadGui(name, this) + } } diff --git a/src/main/kotlin/repo/ItemCache.kt b/src/main/kotlin/repo/ItemCache.kt index 14decd8..72549e9 100644 --- a/src/main/kotlin/repo/ItemCache.kt +++ b/src/main/kotlin/repo/ItemCache.kt @@ -47,6 +47,7 @@ import moe.nea.firmament.util.directLiteralStringContent import moe.nea.firmament.util.mc.FirmamentDataComponentTypes import moe.nea.firmament.util.mc.appendLore import moe.nea.firmament.util.mc.displayNameAccordingToNbt +import moe.nea.firmament.util.mc.loadItemFromNbt import moe.nea.firmament.util.mc.loreAccordingToNbt import moe.nea.firmament.util.mc.modifyLore import moe.nea.firmament.util.mc.setCustomName @@ -70,7 +71,7 @@ object ItemCache : IReloadable { @ExpensiveItemCacheApi private fun NbtCompound.transformFrom10809ToModern() = convert189ToModern(this@transformFrom10809ToModern) - val currentSaveVersion = SharedConstants.getGameVersion().saveVersion.id + val currentSaveVersion = SharedConstants.getGameVersion().dataVersion().id @ExpensiveItemCacheApi fun convert189ToModern(nbtComponent: NbtCompound): NbtCompound? = @@ -171,7 +172,7 @@ object ItemCache : IReloadable { ?: return brokenItemStack(this) } val itemInstance = - ItemStack.fromNbt(MC.defaultRegistries, modernItemTag).getOrNull() ?: return brokenItemStack(this) + loadItemFromNbt( modernItemTag) ?: return brokenItemStack(this) if (usedOldNbt) { val tag = oldItemTag.getCompound("tag") val extraAttributes = tag.flatMap { it.getCompound("ExtraAttributes") } diff --git a/src/main/kotlin/repo/MiningRepoData.kt b/src/main/kotlin/repo/MiningRepoData.kt index e96a241..055253f 100644 --- a/src/main/kotlin/repo/MiningRepoData.kt +++ b/src/main/kotlin/repo/MiningRepoData.kt @@ -23,6 +23,7 @@ import moe.nea.firmament.util.SkyBlockIsland import moe.nea.firmament.util.SkyblockId import moe.nea.firmament.util.mc.FirmamentDataComponentTypes import moe.nea.firmament.util.mc.displayNameAccordingToNbt +import moe.nea.firmament.util.mc.loadItemFromNbt import moe.nea.firmament.util.skyblockId class MiningRepoData : IReloadable { @@ -118,7 +119,7 @@ class MiningRepoData : IReloadable { putString("id", itemId) putShort("Damage", damage) }) ?: return null - val itemStack = ItemStack.fromNbt(MC.defaultRegistries, newCompound).getOrNull() ?: return null + val itemStack = loadItemFromNbt(newCompound) ?: return null val blockItem = itemStack.item as? BlockItem ?: return null return blockItem.block } diff --git a/src/main/kotlin/util/FragmentGuiScreen.kt b/src/main/kotlin/util/FragmentGuiScreen.kt index 5e13d51..de53ac0 100644 --- a/src/main/kotlin/util/FragmentGuiScreen.kt +++ b/src/main/kotlin/util/FragmentGuiScreen.kt @@ -19,13 +19,9 @@ abstract class FragmentGuiScreen( popup = MoulConfigFragment(context, position) { popup = null } } - override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { - super.render(context, mouseX, mouseY, delta) - context.matrices.push() - context.matrices.translate(0f, 0f, 1000f) - popup?.render(context, mouseX, mouseY, delta) - context.matrices.pop() - } + fun renderPopup(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { + popup?.render(context, mouseX, mouseY, delta) + } private inline fun ifPopup(ifYes: (MoulConfigFragment) -> Unit): Boolean { val p = popup ?: return false @@ -65,7 +61,7 @@ abstract class FragmentGuiScreen( return ifPopup { if (!Rectangle( it.position, - Dimension(it.context.root.width, it.context.root.height) + Dimension(it.guiContext.root.width, it.guiContext.root.height) ).contains(Point(mouseX, mouseY)) && dismissOnOutOfBounds ) { diff --git a/src/main/kotlin/util/HoveredItemStack.kt b/src/main/kotlin/util/HoveredItemStack.kt index 526820a..1b54562 100644 --- a/src/main/kotlin/util/HoveredItemStack.kt +++ b/src/main/kotlin/util/HoveredItemStack.kt @@ -6,22 +6,33 @@ import net.minecraft.item.ItemStack import moe.nea.firmament.mixins.accessor.AccessorHandledScreen import moe.nea.firmament.util.compatloader.CompatLoader -interface HoveredItemStackProvider { +interface HoveredItemStackProvider : Comparable<HoveredItemStackProvider> { fun provideHoveredItemStack(screen: HandledScreen<*>): ItemStack? + override fun compareTo(other: HoveredItemStackProvider): Int { + return compareValues(this.prio, other.prio) + } + + val prio: Int get() = 0 - companion object : CompatLoader<HoveredItemStackProvider>(HoveredItemStackProvider::class) + companion object : CompatLoader<HoveredItemStackProvider>(HoveredItemStackProvider::class) { + val sorted = HoveredItemStackProvider.allValidInstances.sorted() + } } @AutoService(HoveredItemStackProvider::class) class VanillaScreenProvider : HoveredItemStackProvider { + override fun provideHoveredItemStack(screen: HandledScreen<*>): ItemStack? { screen as AccessorHandledScreen val vanillaSlot = screen.focusedSlot_Firmament?.stack return vanillaSlot } + + override val prio: Int + get() = -1 } val HandledScreen<*>.focusedItemStack: ItemStack? get() = - HoveredItemStackProvider.allValidInstances + HoveredItemStackProvider.sorted .firstNotNullOfOrNull { it.provideHoveredItemStack(this)?.takeIf { !it.isEmpty } } diff --git a/src/main/kotlin/util/MC.kt b/src/main/kotlin/util/MC.kt index e85b119..7ab0cbb 100644 --- a/src/main/kotlin/util/MC.kt +++ b/src/main/kotlin/util/MC.kt @@ -1,7 +1,7 @@ package moe.nea.firmament.util import io.github.moulberry.repo.data.Coordinate -import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper +import io.github.notenoughupdates.moulconfig.platform.MoulConfigScreenComponent import java.util.concurrent.ConcurrentLinkedQueue import kotlin.jvm.optionals.getOrNull import net.minecraft.client.MinecraftClient @@ -16,11 +16,13 @@ import net.minecraft.client.world.ClientWorld import net.minecraft.entity.Entity import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraft.nbt.NbtOps import net.minecraft.network.packet.c2s.play.CommandExecutionC2SPacket import net.minecraft.registry.BuiltinRegistries import net.minecraft.registry.Registry import net.minecraft.registry.RegistryKey import net.minecraft.registry.RegistryKeys +import net.minecraft.registry.RegistryOps import net.minecraft.registry.RegistryWrapper import net.minecraft.resource.ReloadableResourceManagerImpl import net.minecraft.text.Text @@ -74,7 +76,7 @@ object MC { fun sendCommand(command: String) { // TODO: add a queue to this and sendServerChat ErrorUtil.softCheck("Server commands have an implied /", !command.startsWith("/")) - player?.networkHandler?.sendCommand(command) + player?.networkHandler?.sendChatCommand(command) } fun onMainThread(block: () -> Unit) { @@ -117,6 +119,7 @@ object MC { inline val window get() = instance.window inline val currentRegistries: RegistryWrapper.WrapperLookup? get() = world?.registryManager val defaultRegistries: RegistryWrapper.WrapperLookup by lazy { BuiltinRegistries.createWrapperLookup() } + val defaultRegistryNbtOps by lazy { RegistryOps.of(NbtOps.INSTANCE, defaultRegistries) } inline val currentOrDefaultRegistries get() = currentRegistries ?: defaultRegistries val defaultItems: RegistryWrapper.Impl<Item> by lazy { defaultRegistries.getOrThrow(RegistryKeys.ITEM) } var currentTick = 0 @@ -128,7 +131,7 @@ object MC { private set val currentMoulConfigContext - get() = (screen as? GuiComponentWrapper)?.context + get() = (screen as? MoulConfigScreenComponent)?.guiContext fun openUrl(uri: String) { Util.getOperatingSystem().open(uri) diff --git a/src/main/kotlin/util/MoulConfigFragment.kt b/src/main/kotlin/util/MoulConfigFragment.kt index 28ccfd0..7e7f5db 100644 --- a/src/main/kotlin/util/MoulConfigFragment.kt +++ b/src/main/kotlin/util/MoulConfigFragment.kt @@ -1,44 +1,43 @@ - - package moe.nea.firmament.util -import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper import io.github.notenoughupdates.moulconfig.gui.GuiContext import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext +import io.github.notenoughupdates.moulconfig.platform.MoulConfigScreenComponent import me.shedaniel.math.Point import net.minecraft.client.gui.DrawContext +import net.minecraft.text.Text class MoulConfigFragment( - context: GuiContext, - val position: Point, - val dismiss: () -> Unit -) : GuiComponentWrapper(context) { - init { - this.init(MC.instance, MC.screen!!.width, MC.screen!!.height) - } - - override fun createContext(drawContext: DrawContext?): GuiImmediateContext { - val oldContext = super.createContext(drawContext) - return oldContext.translated( - position.x, - position.y, - context.root.width, - context.root.height, - ) - } - - - override fun render(drawContext: DrawContext?, i: Int, j: Int, f: Float) { - val ctx = createContext(drawContext) - val m = drawContext!!.matrices - m.push() - m.translate(position.x.toFloat(), position.y.toFloat(), 0F) - context.root.render(ctx) - m.pop() - ctx.renderContext.renderExtraLayers() - } - - override fun close() { - dismiss() - } + context: GuiContext, + val position: Point, + val dismiss: () -> Unit +) : MoulConfigScreenComponent(Text.empty(), context, null) { + init { + this.init(MC.instance, MC.screen!!.width, MC.screen!!.height) + } + + override fun createContext(drawContext: DrawContext?): GuiImmediateContext { + val oldContext = super.createContext(drawContext) + return oldContext.translated( + position.x, + position.y, + guiContext.root.width, + guiContext.root.height, + ) + } + + + override fun render(drawContext: DrawContext, i: Int, j: Int, f: Float) { + val ctx = createContext(drawContext) + val m = drawContext.matrices + m.pushMatrix() + m.translate(position.x.toFloat(), position.y.toFloat()) + guiContext.root.render(ctx) + m.popMatrix() + ctx.renderContext.renderExtraLayers() + } + + override fun close() { + dismiss() + } } diff --git a/src/main/kotlin/util/MoulConfigUtils.kt b/src/main/kotlin/util/MoulConfigUtils.kt index 51ff340..2f2fd5c 100644 --- a/src/main/kotlin/util/MoulConfigUtils.kt +++ b/src/main/kotlin/util/MoulConfigUtils.kt @@ -4,13 +4,14 @@ import io.github.notenoughupdates.moulconfig.common.IMinecraft import io.github.notenoughupdates.moulconfig.common.MyResourceLocation import io.github.notenoughupdates.moulconfig.gui.CloseEventListener import io.github.notenoughupdates.moulconfig.gui.GuiComponent -import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper import io.github.notenoughupdates.moulconfig.gui.GuiContext import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext import io.github.notenoughupdates.moulconfig.gui.KeyboardEvent import io.github.notenoughupdates.moulconfig.gui.MouseEvent import io.github.notenoughupdates.moulconfig.observer.GetSetter -import io.github.notenoughupdates.moulconfig.platform.ModernRenderContext +import io.github.notenoughupdates.moulconfig.platform.MoulConfigPlatform +import io.github.notenoughupdates.moulconfig.platform.MoulConfigRenderContext +import io.github.notenoughupdates.moulconfig.platform.MoulConfigScreenComponent import io.github.notenoughupdates.moulconfig.xml.ChildCount import io.github.notenoughupdates.moulconfig.xml.XMLContext import io.github.notenoughupdates.moulconfig.xml.XMLGuiLoader @@ -26,6 +27,7 @@ import kotlin.time.Duration.Companion.seconds import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.screen.Screen import net.minecraft.client.util.InputUtil +import net.minecraft.text.Text import moe.nea.firmament.gui.BarComponent import moe.nea.firmament.gui.FirmButtonComponent import moe.nea.firmament.gui.FirmHoverComponent @@ -226,9 +228,9 @@ object MoulConfigUtils { } fun wrapScreen(guiContext: GuiContext, parent: Screen?, onClose: () -> Unit = {}): Screen { - return object : GuiComponentWrapper(guiContext) { + return object : MoulConfigScreenComponent(Text.empty(), guiContext, null) { override fun close() { - if (context.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) { + if (guiContext.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) { client!!.setScreen(parent) onClose() } @@ -264,7 +266,7 @@ object MoulConfigUtils { h: Int, keyboardEvent: KeyboardEvent ): Boolean { - val immContext = createInPlaceFullContext(null, IMinecraft.instance.mouseX, IMinecraft.instance.mouseY) + val immContext = createInPlaceFullContext(null, IMinecraft.INSTANCE.mouseX, IMinecraft.INSTANCE.mouseY) if (component.keyboardEvent(keyboardEvent, immContext.translated(x, y, w, h))) return true if (component.context.getFocusedElement() != null) { @@ -292,9 +294,12 @@ object MoulConfigUtils { } fun createInPlaceFullContext(drawContext: DrawContext?, mouseX: Int, mouseY: Int): GuiImmediateContext { - assert(drawContext?.isUntranslatedGuiDrawContext() != false) - val context = drawContext?.let(::ModernRenderContext) - ?: IMinecraft.instance.provideTopLevelRenderContext() + ErrorUtil.softCheck( + "created moulconfig context with pre-existing translations.", + drawContext?.isUntranslatedGuiDrawContext() != false + ) + val context = drawContext?.let(::MoulConfigRenderContext) + ?: IMinecraft.INSTANCE.provideTopLevelRenderContext() val immContext = GuiImmediateContext( context, 0, 0, 0, 0, @@ -316,10 +321,10 @@ object MoulConfigUtils { mouseY: Int ) { val immContext = createInPlaceFullContext(this, mouseX, mouseY) - matrices.push() - matrices.translate(x.toFloat(), y.toFloat(), 0F) + matrices.pushMatrix() + matrices.translate(x.toFloat(), y.toFloat()) component.render(immContext.translated(x, y, w, h)) - matrices.pop() + matrices.popMatrix() } diff --git a/src/main/kotlin/util/SkyblockId.kt b/src/main/kotlin/util/SkyblockId.kt index 051ca86..03b8bf4 100644 --- a/src/main/kotlin/util/SkyblockId.kt +++ b/src/main/kotlin/util/SkyblockId.kt @@ -146,9 +146,9 @@ val ItemStack.skyblockUUIDString: String? private val timestampFormat = //"10/11/21 3:39 PM" DateTimeFormatterBuilder().apply { - appendValue(ChronoField.MONTH_OF_YEAR, 2) + appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NOT_NEGATIVE) appendLiteral("/") - appendValue(ChronoField.DAY_OF_MONTH, 2) + appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NOT_NEGATIVE) appendLiteral("/") appendValueReduced(ChronoField.YEAR, 2, 2, 1950) appendLiteral(" ") diff --git a/src/main/kotlin/util/json/CodecSerializer.kt b/src/main/kotlin/util/json/CodecSerializer.kt new file mode 100644 index 0000000..9ea08ad --- /dev/null +++ b/src/main/kotlin/util/json/CodecSerializer.kt @@ -0,0 +1,26 @@ +package util.json + +import com.mojang.serialization.Codec +import kotlinx.serialization.KSerializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.json.JsonElement +import moe.nea.firmament.util.json.KJsonOps + +abstract class CodecSerializer<T>(val codec: Codec<T>) : KSerializer<T> { + override val descriptor: SerialDescriptor + get() = JsonElement.serializer().descriptor + + override fun serialize(encoder: Encoder, value: T) { + encoder.encodeSerializableValue( + JsonElement.serializer(), + codec.encodeStart(KJsonOps.INSTANCE, value).orThrow + ) + } + + override fun deserialize(decoder: Decoder): T { + return codec.decode(KJsonOps.INSTANCE, decoder.decodeSerializableValue(JsonElement.serializer())) + .orThrow.first + } +} diff --git a/src/main/kotlin/util/mc/CustomRenderPassHelper.kt b/src/main/kotlin/util/mc/CustomRenderPassHelper.kt new file mode 100644 index 0000000..295f727 --- /dev/null +++ b/src/main/kotlin/util/mc/CustomRenderPassHelper.kt @@ -0,0 +1,160 @@ +package moe.nea.firmament.util.mc + +import com.mojang.blaze3d.buffers.GpuBuffer +import com.mojang.blaze3d.buffers.GpuBufferSlice +import com.mojang.blaze3d.buffers.Std140Builder +import com.mojang.blaze3d.pipeline.RenderPipeline +import com.mojang.blaze3d.systems.RenderPass +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.VertexFormat +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.util.OptionalDouble +import java.util.OptionalInt +import org.joml.Vector4f +import net.minecraft.client.gl.Framebuffer +import net.minecraft.client.render.BufferBuilder +import net.minecraft.client.render.BuiltBuffer +import net.minecraft.client.texture.AbstractTexture +import net.minecraft.client.util.BufferAllocator +import net.minecraft.util.Identifier +import net.minecraft.util.math.MathHelper +import moe.nea.firmament.util.ErrorUtil +import moe.nea.firmament.util.MC + + +class CustomRenderPassHelper( + val labelSupplier: () -> String, + val drawMode: VertexFormat.DrawMode, + val vertexFormat: VertexFormat, + val frameBuffer: Framebuffer, + val hasDepth: Boolean, +) : AutoCloseable { + private val scope = mutableListOf<AutoCloseable>() + private val preparations = mutableListOf<(RenderPass) -> Unit>() + val device = RenderSystem.getDevice() + private var hasPipelineAction = false + private var hasSetDefaultUniforms = false + val commandEncoder = device.createCommandEncoder() + fun setPipeline(pipeline: RenderPipeline) { + ErrorUtil.softCheck("Already has a pipeline", !hasPipelineAction) + hasPipelineAction = true + queueAction { + it.setPipeline(pipeline) + } + } + + fun bindSampler(name: String, texture: Identifier) { + bindSampler(name, MC.textureManager.getTexture(texture)) + } + + fun bindSampler(name: String, texture: AbstractTexture) { + queueAction { it.bindSampler(name, texture.glTextureView) } + } + + + fun dontSetDefaultUniforms() { + hasSetDefaultUniforms = true + } + + fun setAllDefaultUniforms() { + hasSetDefaultUniforms = true + queueAction { + RenderSystem.bindDefaultUniforms(it) + } + setUniform( + "DynamicTransforms", RenderSystem.getDynamicUniforms() + .write( + RenderSystem.getModelViewMatrix(), + Vector4f(1.0F, 1.0F, 1.0F, 1.0F), + RenderSystem.getModelOffset(), + RenderSystem.getTextureMatrix(), + RenderSystem.getShaderLineWidth() + ) + ) + } + + fun setUniform(name: String, slice: GpuBufferSlice) = queueAction { it.setUniform(name, slice) } + fun setUniform(name: String, slice: GpuBuffer) = queueAction { it.setUniform(name, slice) } + + fun setUniform(name: String, size: Int, labelSupplier: () -> String = { name }, init: (Std140Builder) -> Unit) { + val buffer = createUniformBuffer(labelSupplier, allocateByteBuf(size, init)) + setUniform(name, buffer) + } + + var vertices: BuiltBuffer? = null + + fun uploadVertices(size: Int, init: (BufferBuilder) -> Unit) { + uploadVertices( + BufferBuilder(queueClose(BufferAllocator(size)), drawMode, vertexFormat) + .also(init) + .end() + ) + } + + fun uploadVertices(buffer: BuiltBuffer) { + queueClose(buffer) + ErrorUtil.softCheck("Vertices have already been uploaded", vertices == null) + vertices = buffer + val vertexBuffer = vertexFormat.uploadImmediateVertexBuffer(buffer.buffer) + val indexBufferConstructor = RenderSystem.getSequentialBuffer(drawMode) + val indexBuffer = indexBufferConstructor.getIndexBuffer(buffer.drawParameters.indexCount) + queueAction { + it.setIndexBuffer(indexBuffer, indexBufferConstructor.indexType) + it.setVertexBuffer(0, vertexBuffer) + } + } + + fun createUniformBuffer(labelSupplier: () -> String, buffer: ByteBuffer): GpuBuffer { + return queueClose( + device.createBuffer( + labelSupplier::invoke, + GpuBuffer.USAGE_UNIFORM or GpuBuffer.USAGE_MAP_READ, + buffer + ) + ) + } + + fun allocateByteBuf(size: Int, init: (Std140Builder) -> Unit): ByteBuffer { + return Std140Builder.intoBuffer( // TODO: i really dont know about this 16 align? but it seems to be generally correct. + ByteBuffer + .allocateDirect(MathHelper.roundUpToMultiple(size, 16)) + .order(ByteOrder.nativeOrder()) + ).also(init).get() + } + + fun queueAction(action: (RenderPass) -> Unit) { + preparations.add(action) + } + + fun <T : AutoCloseable> queueClose(t: T): T = t.also { scope.add(it) } + override fun close() { + scope.reversed().forEach { it.close() } + } + + object DrawToken + + fun draw(): DrawToken { + val vertexData = (ErrorUtil.notNullOr(vertices, "No vertex data uploaded") { return DrawToken }) + ErrorUtil.softCheck("Missing default uniforms", hasSetDefaultUniforms) + ErrorUtil.softCheck("Missing a pipeline", hasPipelineAction) + val renderPass = queueClose( + commandEncoder.createRenderPass( + labelSupplier::invoke, + RenderSystem.outputColorTextureOverride ?: frameBuffer.getColorAttachmentView(), + OptionalInt.empty(), + (RenderSystem.outputDepthTextureOverride + ?: frameBuffer.getDepthAttachmentView()).takeIf { frameBuffer.useDepthAttachment && hasDepth }, + OptionalDouble.empty() + ) + ) + preparations.forEach { it(renderPass) } + renderPass.drawIndexed( + 0, + 0, + vertexData.drawParameters.indexCount, + 1 + ) + return DrawToken + } +} diff --git a/src/main/kotlin/util/mc/ItemUtil.kt b/src/main/kotlin/util/mc/ItemUtil.kt index 13519cf..3cabb8e 100644 --- a/src/main/kotlin/util/mc/ItemUtil.kt +++ b/src/main/kotlin/util/mc/ItemUtil.kt @@ -1,20 +1,30 @@ package moe.nea.firmament.util.mc +import kotlin.jvm.optionals.getOrNull import net.minecraft.item.ItemStack +import net.minecraft.nbt.NbtCompound +import net.minecraft.nbt.NbtOps +import net.minecraft.registry.RegistryOps +import net.minecraft.registry.RegistryWrapper import net.minecraft.text.Text +import moe.nea.firmament.util.MC fun ItemStack.appendLore(args: List<Text>) { - if (args.isEmpty()) return - modifyLore { - val loreList = loreAccordingToNbt.toMutableList() - for (arg in args) { - loreList.add(arg) - } - loreList - } + if (args.isEmpty()) return + modifyLore { + val loreList = loreAccordingToNbt.toMutableList() + for (arg in args) { + loreList.add(arg) + } + loreList + } } fun ItemStack.modifyLore(update: (List<Text>) -> List<Text>) { - val loreList = loreAccordingToNbt - loreAccordingToNbt = update(loreList) + val loreList = loreAccordingToNbt + loreAccordingToNbt = update(loreList) +} + +fun loadItemFromNbt(nbt: NbtCompound, registries: RegistryWrapper.WrapperLookup = MC.defaultRegistries): ItemStack? { + return ItemStack.CODEC.decode(RegistryOps.of(NbtOps.INSTANCE, registries), nbt).result().getOrNull()?.first } diff --git a/src/main/kotlin/util/render/CustomRenderLayers.kt b/src/main/kotlin/util/render/CustomRenderLayers.kt index 2da1de7..d88a1e4 100644 --- a/src/main/kotlin/util/render/CustomRenderLayers.kt +++ b/src/main/kotlin/util/render/CustomRenderLayers.kt @@ -11,7 +11,6 @@ import net.minecraft.client.render.RenderLayer import net.minecraft.client.render.RenderPhase import net.minecraft.client.render.VertexFormats import net.minecraft.util.Identifier -import net.minecraft.util.TriState import net.minecraft.util.Util import moe.nea.firmament.Firmament @@ -31,7 +30,7 @@ object CustomRenderPipelines { .withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST) .build() val COLORED_OMNIPRESENT_QUADS = - RenderPipeline.builder(RenderPipelines.MATRICES_COLOR_SNIPPET)// TODO: split this up to support better transparent ordering. + RenderPipeline.builder(RenderPipelines.TRANSFORMS_AND_PROJECTION_SNIPPET)// TODO: split this up to support better transparent ordering. .withLocation(Firmament.identifier("colored_omnipresent_quads")) .withVertexShader("core/position_color") .withFragmentShader("core/position_color") @@ -46,9 +45,9 @@ object CustomRenderPipelines { RenderPipeline.builder(RenderPipelines.POSITION_TEX_COLOR_SNIPPET) .withVertexFormat(VertexFormats.POSITION_TEXTURE_COLOR, DrawMode.TRIANGLES) .withLocation(Firmament.identifier("gui_textured_overlay_tris_circle")) - .withUniform("InnerCutoutRadius", UniformType.FLOAT) + .withUniform("CutoutRadius", UniformType.UNIFORM_BUFFER) .withFragmentShader(Firmament.identifier("circle_discard_color")) - .withBlend(BlendFunction.TRANSLUCENT) +// .withBlend(BlendFunction.TRANSLUCENT) .build() val PARALLAX_CAPE_SHADER = RenderPipeline.builder(RenderPipelines.ENTITY_SNIPPET) @@ -57,12 +56,12 @@ object CustomRenderPipelines { .withSampler("Sampler0") .withSampler("Sampler1") .withSampler("Sampler3") - .withUniform("Animation", UniformType.FLOAT) + .withUniform("Animation", UniformType.UNIFORM_BUFFER) .build() } object CustomRenderLayers { - inline fun memoizeTextured(crossinline func: (Identifier) -> RenderLayer) = memoize(func) + inline fun memoizeTextured(crossinline func: (Identifier) -> RenderLayer.MultiPhase) = memoize(func) inline fun <T, R> memoize(crossinline func: (T) -> R): Function<T, R> { return Util.memoize { it: T -> func(it) } } @@ -73,7 +72,7 @@ object CustomRenderLayers { RenderLayer.DEFAULT_BUFFER_SIZE, CustomRenderPipelines.GUI_TEXTURED_NO_DEPTH_TRIS, RenderLayer.MultiPhaseParameters.builder().texture( - RenderPhase.Texture(texture, TriState.DEFAULT, false) + RenderPhase.Texture(texture, false) ) .build(false) ) diff --git a/src/main/kotlin/util/render/DrawContextExt.kt b/src/main/kotlin/util/render/DrawContextExt.kt index a833c86..e63bf5f 100644 --- a/src/main/kotlin/util/render/DrawContextExt.kt +++ b/src/main/kotlin/util/render/DrawContextExt.kt @@ -2,26 +2,31 @@ package moe.nea.firmament.util.render import com.mojang.blaze3d.systems.RenderSystem import me.shedaniel.math.Color -import org.joml.Matrix4f +import org.joml.Vector2f +import org.joml.Vector3f import util.render.CustomRenderLayers +import kotlin.math.abs +import net.minecraft.client.gl.RenderPipelines import net.minecraft.client.gui.DrawContext -import net.minecraft.client.render.RenderLayer +import net.minecraft.client.gui.ScreenRect +import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.util.math.MatrixStack import net.minecraft.util.Identifier import moe.nea.firmament.util.MC fun DrawContext.isUntranslatedGuiDrawContext(): Boolean { - return (matrices.peek().positionMatrix.properties() and Matrix4f.PROPERTY_IDENTITY.toInt()) != 0 + return matrices.m00 == 1F && matrices.m11 == 1f && matrices.m01 == 0F && matrices.m10 == 0F && matrices.m20 == 0F && matrices.m21 == 0F } @Deprecated("Use the other drawGuiTexture") fun DrawContext.drawGuiTexture( x: Int, y: Int, z: Int, width: Int, height: Int, sprite: Identifier -) = this.drawGuiTexture(RenderLayer::getGuiTextured, sprite, x, y, width, height) +) = this.drawGuiTexture(RenderPipelines.GUI_TEXTURED, sprite, x, y, width, height) fun DrawContext.drawGuiTexture( sprite: Identifier, x: Int, y: Int, width: Int, height: Int -) = this.drawGuiTexture(RenderLayer::getGuiTextured, sprite, x, y, width, height) +) = this.drawGuiTexture(RenderPipelines.GUI_TEXTURED, sprite, x, y, width, height) fun DrawContext.drawTexture( sprite: Identifier, @@ -34,35 +39,130 @@ fun DrawContext.drawTexture( textureWidth: Int, textureHeight: Int ) { - this.drawTexture(RenderLayer::getGuiTextured, - sprite, - x, - y, - u, - v, - width, - height, - width, - height, - textureWidth, - textureHeight) + this.drawTexture( + RenderPipelines.GUI_TEXTURED, + sprite, + x, + y, + u, + v, + width, + height, + width, + height, + textureWidth, + textureHeight + ) } -fun DrawContext.drawLine(fromX: Int, fromY: Int, toX: Int, toY: Int, color: Color) { - // TODO: push scissors - // TODO: use matrix translations and a different render layer +data class LineRenderState( + override val x1: Int, + override val x2: Int, + override val y1: Int, + override val y2: Int, + override val scale: Float, + override val bounds: ScreenRect, + val lineWidth: Float, + val w: Int, + val h: Int, + val color: Int, + val direction: LineDirection, +) : MultiSpecialGuiRenderState() { + enum class LineDirection { + TOP_LEFT_TO_BOTTOM_RIGHT, + BOTTOM_LEFT_TO_TOP_RIGHT, + } + + override fun createRenderer(vertexConsumers: VertexConsumerProvider.Immediate): MultiSpecialGuiRenderer<out MultiSpecialGuiRenderState> { + return LineRenderer(vertexConsumers) + } + + override val scissorArea = null +} + +class LineRenderer(vertexConsumers: VertexConsumerProvider.Immediate) : + MultiSpecialGuiRenderer<LineRenderState>(vertexConsumers) { + override fun getElementClass(): Class<LineRenderState> { + return LineRenderState::class.java + } + + override fun getYOffset(height: Int, windowScaleFactor: Int): Float { + return height / 2F + } + + override fun render( + state: LineRenderState, + matrices: MatrixStack + ) { + val gr = MC.instance.gameRenderer + val client = MC.instance + gr.globalSettings + .set( + state.bounds.width, + state.bounds.height, + client.options.glintStrength.getValue(), + client.world?.time ?: 0L, + client.renderTickCounter, + client.options.menuBackgroundBlurrinessValue + ) + + RenderSystem.lineWidth(state.lineWidth) + val buf = vertexConsumers.getBuffer(CustomRenderLayers.LINES) + val matrix = matrices.peek() + val wh = state.w / 2F + val hh = state.h / 2F + val lowX = -wh + val lowY = if (state.direction == LineRenderState.LineDirection.BOTTOM_LEFT_TO_TOP_RIGHT) hh else -hh + val highX = wh + val highY = -lowY + val norm = Vector3f(highX - lowX, highY - lowY, 0F).normalize() + buf.vertex(matrix, lowX, lowY, 0F).color(state.color) + .normal(matrix, norm) + buf.vertex(matrix, highX, highY, 0F).color(state.color) + .normal(matrix, norm) + vertexConsumers.draw() + gr.globalSettings + .set( + client.window.framebufferWidth, + client.window.framebufferHeight, + client.options.glintStrength.getValue(), + client.world?.getTime() ?: 0L, + client.renderTickCounter, + client.options.menuBackgroundBlurrinessValue + ) + + } + + override fun getName(): String? { + return "Firmament Line Renderer" + } +} + + +fun DrawContext.drawLine(fromX: Int, fromY: Int, toX: Int, toY: Int, color: Color, lineWidth: Float = 1F) { if (toY < fromY) { drawLine(toX, toY, fromX, fromY, color) return } - RenderSystem.lineWidth(MC.window.scaleFactor.toFloat()) - draw { vertexConsumers -> - val buf = vertexConsumers.getBuffer(CustomRenderLayers.LINES) - val matrix = this.matrices.peek() - buf.vertex(matrix, fromX.toFloat(), fromY.toFloat(), 0F).color(color.color) - .normal(toX - fromX.toFloat(), toY - fromY.toFloat(), 0F) - buf.vertex(matrix, toX.toFloat(), toY.toFloat(), 0F).color(color.color) - .normal(toX - fromX.toFloat(), toY - fromY.toFloat(), 0F) - } + val originalRect = ScreenRect( + minOf(fromX, toX), minOf(toY, fromY), + abs(toX - fromX), abs(toY - fromY) + ).transform(matrices) + val expansionFactor = 3 + val rect = ScreenRect( + originalRect.left - expansionFactor, + originalRect.top - expansionFactor, + originalRect.width + expansionFactor * 2, + originalRect.height + expansionFactor * 2 + ) + // TODO: expand the bounds so that the thickness of the line can be used + // TODO: fix this up to work with scissorarea + state.addSpecialElement( + LineRenderState( + rect.left, rect.right, rect.top, rect.bottom, 1F, rect, lineWidth, + originalRect.width, originalRect.height, color.color, + if (fromX < toX) LineRenderState.LineDirection.TOP_LEFT_TO_BOTTOM_RIGHT else LineRenderState.LineDirection.BOTTOM_LEFT_TO_TOP_RIGHT + ) + ) } diff --git a/src/main/kotlin/util/render/DumpTexture.kt b/src/main/kotlin/util/render/DumpTexture.kt new file mode 100644 index 0000000..a7b4e78 --- /dev/null +++ b/src/main/kotlin/util/render/DumpTexture.kt @@ -0,0 +1,34 @@ +package moe.nea.firmament.util.render + +import com.mojang.blaze3d.buffers.GpuBuffer +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.textures.GpuTexture +import java.io.File +import net.minecraft.client.texture.NativeImage + +fun dumpTexture(gpuTexture: GpuTexture, name: String) { + val w = gpuTexture.getWidth(0) + val h = gpuTexture.getHeight(0) + val buffer = RenderSystem.getDevice() + .createBuffer( + { "Dump Buffer" }, + GpuBuffer.USAGE_COPY_DST or GpuBuffer.USAGE_MAP_READ, + w * h * gpuTexture.getFormat().pixelSize() + ) + val commandEncoder = RenderSystem.getDevice().createCommandEncoder() + commandEncoder.copyTextureToBuffer( + gpuTexture, buffer, 0, { + val nativeImage = NativeImage(w, h, false) + commandEncoder.mapBuffer(buffer, true, false).use { mappedView -> + for (i in 0..<w) { + for (j in 0..<h) { + val color = mappedView.data().getInt((j + i * w) * gpuTexture.format.pixelSize()) + nativeImage.setColor(j, h - i - 1, color) + } + } + } + buffer.close() + nativeImage.writeTo(File("$name.png")) + }, 0 + ) +} diff --git a/src/main/kotlin/util/render/FacingThePlayerContext.kt b/src/main/kotlin/util/render/FacingThePlayerContext.kt index 670beb6..76270c5 100644 --- a/src/main/kotlin/util/render/FacingThePlayerContext.kt +++ b/src/main/kotlin/util/render/FacingThePlayerContext.kt @@ -1,11 +1,13 @@ package moe.nea.firmament.util.render -import io.github.notenoughupdates.moulconfig.platform.next import org.joml.Matrix4f +import util.render.CustomRenderLayers import net.minecraft.client.font.TextRenderer import net.minecraft.client.render.LightmapTextureManager import net.minecraft.client.render.RenderLayer +import net.minecraft.client.render.RenderLayers +import net.minecraft.client.render.TexturedRenderLayers import net.minecraft.client.render.VertexConsumer import net.minecraft.text.Text import net.minecraft.util.Identifier @@ -38,14 +40,14 @@ class FacingThePlayerContext(val worldContext: RenderInWorldContext) { worldContext.vertexConsumers.getBuffer(RenderLayer.getTextBackgroundSeeThrough()) val matrix4f = worldContext.matrixStack.peek().positionMatrix vertexConsumer.vertex(matrix4f, -1.0f, -1.0f, 0.0f).color(background) - .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() + .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE) vertexConsumer.vertex(matrix4f, -1.0f, MC.font.fontHeight.toFloat(), 0.0f).color(background) - .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() + .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE) vertexConsumer.vertex(matrix4f, width.toFloat(), MC.font.fontHeight.toFloat(), 0.0f) .color(background) - .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() + .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE) vertexConsumer.vertex(matrix4f, width.toFloat(), -1.0f, 0.0f).color(background) - .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() + .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE) worldContext.matrixStack.translate(0F, 0F, 0.01F) MC.font.draw( @@ -70,22 +72,22 @@ class FacingThePlayerContext(val worldContext: RenderInWorldContext) { u1: Float, v1: Float, u2: Float, v2: Float, ) { - val buf = worldContext.vertexConsumers.getBuffer(RenderLayer.getGuiTexturedOverlay(texture)) + val buf = worldContext.vertexConsumers.getBuffer(CustomRenderLayers.GUI_TEXTURED_NO_DEPTH_TRIS.apply(texture)) // TODO: this is strictly an incorrect render layer val hw = width / 2F val hh = height / 2F val matrix4f: Matrix4f = worldContext.matrixStack.peek().positionMatrix buf.vertex(matrix4f, -hw, -hh, 0F) .color(-1) - .texture(u1, v1).next() + .texture(u1, v1) buf.vertex(matrix4f, -hw, +hh, 0F) .color(-1) - .texture(u1, v2).next() + .texture(u1, v2) buf.vertex(matrix4f, +hw, +hh, 0F) .color(-1) - .texture(u2, v2).next() + .texture(u2, v2) buf.vertex(matrix4f, +hw, -hh, 0F) .color(-1) - .texture(u2, v1).next() + .texture(u2, v1) worldContext.vertexConsumers.draw() } diff --git a/src/main/kotlin/util/render/MultiSpecialGuiRenderState.kt b/src/main/kotlin/util/render/MultiSpecialGuiRenderState.kt new file mode 100644 index 0000000..ce56df3 --- /dev/null +++ b/src/main/kotlin/util/render/MultiSpecialGuiRenderState.kt @@ -0,0 +1,48 @@ +package moe.nea.firmament.util.render + +import org.joml.Matrix3x2f +import net.minecraft.client.gui.ScreenRect +import net.minecraft.client.gui.render.SpecialGuiElementRenderer +import net.minecraft.client.gui.render.state.GuiRenderState +import net.minecraft.client.gui.render.state.special.SpecialGuiElementRenderState +import net.minecraft.client.render.VertexConsumerProvider + +abstract class MultiSpecialGuiRenderState : SpecialGuiElementRenderState { + // I wish i had manifolds @Self type here... Maybe i should switch to java after all :( + abstract fun createRenderer(vertexConsumers: VertexConsumerProvider.Immediate): MultiSpecialGuiRenderer<out MultiSpecialGuiRenderState> + abstract val x1: Int + abstract val x2: Int + abstract val y1: Int + abstract val y2: Int + abstract val scale: Float + abstract val bounds: ScreenRect? + abstract val scissorArea: ScreenRect? + override fun x1(): Int = x1 + + override fun x2(): Int = x2 + + override fun y1(): Int = y1 + + override fun y2(): Int = y2 + + override fun scale(): Float = scale + + override fun scissorArea(): ScreenRect? = scissorArea + + override fun bounds(): ScreenRect? = bounds + +} + +abstract class MultiSpecialGuiRenderer<T : MultiSpecialGuiRenderState>( + vertexConsumers: VertexConsumerProvider.Immediate +) : SpecialGuiElementRenderer<T>(vertexConsumers) { + var wasUsedThisFrame = false + fun consumeRender(): Boolean { + return wasUsedThisFrame.also { wasUsedThisFrame = false } + } + + override fun renderElement(element: T, state: GuiRenderState) { + wasUsedThisFrame = true + super.renderElement(element, state) + } +} diff --git a/src/main/kotlin/util/render/RenderCircleProgress.kt b/src/main/kotlin/util/render/RenderCircleProgress.kt index 81dde6f..301eec4 100644 --- a/src/main/kotlin/util/render/RenderCircleProgress.kt +++ b/src/main/kotlin/util/render/RenderCircleProgress.kt @@ -1,25 +1,126 @@ package moe.nea.firmament.util.render -import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.vertex.VertexFormat -import io.github.notenoughupdates.moulconfig.platform.next -import java.util.OptionalInt -import org.joml.Matrix4f +import org.joml.Matrix3x2f import util.render.CustomRenderLayers import net.minecraft.client.gui.DrawContext +import net.minecraft.client.gui.ScreenRect import net.minecraft.client.render.BufferBuilder import net.minecraft.client.render.RenderLayer +import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.util.BufferAllocator +import net.minecraft.client.util.math.MatrixStack import net.minecraft.util.Identifier import moe.nea.firmament.util.MC import moe.nea.firmament.util.collections.nonNegligibleSubSectionsAlignedWith import moe.nea.firmament.util.math.Projections +import moe.nea.firmament.util.mc.CustomRenderPassHelper object RenderCircleProgress { + + data class State( + override val x1: Int, + override val x2: Int, + override val y1: Int, + override val y2: Int, + val layer: RenderLayer.MultiPhase, + val u1: Float, + val u2: Float, + val v1: Float, + val v2: Float, + val angleRadians: ClosedFloatingPointRange<Float>, + val color: Int, + val innerCutoutRadius: Float, + override val scale: Float, + override val bounds: ScreenRect?, + override val scissorArea: ScreenRect?, + ) : MultiSpecialGuiRenderState() { + override fun createRenderer(vertexConsumers: VertexConsumerProvider.Immediate): MultiSpecialGuiRenderer<out MultiSpecialGuiRenderState> { + return Renderer(vertexConsumers) + } + } + + class Renderer(vertexConsumers: VertexConsumerProvider.Immediate) : + MultiSpecialGuiRenderer<State>(vertexConsumers) { + override fun render( + state: State, + matrices: MatrixStack + ) { + matrices.push() + matrices.translate(0F, -1F, 0F) + val sections = state.angleRadians.nonNegligibleSubSectionsAlignedWith((τ / 8f).toFloat()) + .zipWithNext().toList() + val u1 = state.u1 + val u2 = state.u2 + val v1 = state.v1 + val v2 = state.v2 + val color = state.color + val matrix = matrices.peek().positionMatrix + BufferAllocator(state.layer.vertexFormat.vertexSize * sections.size * 3).use { allocator -> + + val bufferBuilder = BufferBuilder(allocator, VertexFormat.DrawMode.TRIANGLES, state.layer.vertexFormat) + + for ((sectionStart, sectionEnd) in sections) { + val firstPoint = Projections.Two.projectAngleOntoUnitBox(sectionStart.toDouble()) + val secondPoint = Projections.Two.projectAngleOntoUnitBox(sectionEnd.toDouble()) + fun ilerp(f: Float): Float = + ilerp(-1f, 1f, f) + + bufferBuilder + .vertex(matrix, secondPoint.x, secondPoint.y, 0F) + .texture(lerp(u1, u2, ilerp(secondPoint.x)), lerp(v1, v2, ilerp(secondPoint.y))) + .color(color) + + bufferBuilder + .vertex(matrix, firstPoint.x, firstPoint.y, 0F) + .texture(lerp(u1, u2, ilerp(firstPoint.x)), lerp(v1, v2, ilerp(firstPoint.y))) + .color(color) + + bufferBuilder + .vertex(matrix, 0F, 0F, 0F) + .texture(lerp(u1, u2, ilerp(0F)), lerp(v1, v2, ilerp(0F))) + .color(color) + + } + + bufferBuilder.end().use { buffer -> + if (state.innerCutoutRadius <= 0) { + state.layer.draw(buffer) + return + } + CustomRenderPassHelper( + { "RenderCircleProgress" }, + VertexFormat.DrawMode.TRIANGLES, + state.layer.vertexFormat, + MC.instance.framebuffer, + false, + ).use { renderPass -> + renderPass.uploadVertices(buffer) + renderPass.setAllDefaultUniforms() + renderPass.setPipeline(state.layer.pipeline) + renderPass.setUniform("CutoutRadius", 4) { + it.putFloat(state.innerCutoutRadius) + } + renderPass.draw() + } + } + } + matrices.pop() + } + + override fun getElementClass(): Class<State> { + return State::class.java + } + + override fun getName(): String { + return "Firmament Circle" + } + } + fun renderCircularSlice( drawContext: DrawContext, - layer: RenderLayer, + layer: RenderLayer.MultiPhase, u1: Float, u2: Float, v1: Float, @@ -28,58 +129,21 @@ object RenderCircleProgress { color: Int = -1, innerCutoutRadius: Float = 0F ) { - drawContext.draw() - val sections = angleRadians.nonNegligibleSubSectionsAlignedWith((τ / 8f).toFloat()) - .zipWithNext().toList() - BufferAllocator(layer.vertexFormat.vertexSize * sections.size * 3).use { allocator -> - - val bufferBuilder = BufferBuilder(allocator, VertexFormat.DrawMode.TRIANGLES, layer.vertexFormat) - val matrix: Matrix4f = drawContext.matrices.peek().positionMatrix - - for ((sectionStart, sectionEnd) in sections) { - val firstPoint = Projections.Two.projectAngleOntoUnitBox(sectionStart.toDouble()) - val secondPoint = Projections.Two.projectAngleOntoUnitBox(sectionEnd.toDouble()) - fun ilerp(f: Float): Float = - ilerp(-1f, 1f, f) - - bufferBuilder - .vertex(matrix, secondPoint.x, secondPoint.y, 0F) - .texture(lerp(u1, u2, ilerp(secondPoint.x)), lerp(v1, v2, ilerp(secondPoint.y))) - .color(color) - .next() - bufferBuilder - .vertex(matrix, firstPoint.x, firstPoint.y, 0F) - .texture(lerp(u1, u2, ilerp(firstPoint.x)), lerp(v1, v2, ilerp(firstPoint.y))) - .color(color) - .next() - bufferBuilder - .vertex(matrix, 0F, 0F, 0F) - .texture(lerp(u1, u2, ilerp(0F)), lerp(v1, v2, ilerp(0F))) - .color(color) - .next() - } - - bufferBuilder.end().use { buffer -> - // TODO: write a better utility to pass uniforms :sob: ill even take a mixin at this point - if (innerCutoutRadius <= 0) { - layer.draw(buffer) - return - } - val vertexBuffer = layer.vertexFormat.uploadImmediateVertexBuffer(buffer.buffer) - val indexBufferConstructor = RenderSystem.getSequentialBuffer(VertexFormat.DrawMode.TRIANGLES) - val indexBuffer = indexBufferConstructor.getIndexBuffer(buffer.drawParameters.indexCount) - RenderSystem.getDevice().createCommandEncoder().createRenderPass( - MC.instance.framebuffer.colorAttachment, - OptionalInt.empty(), - ).use { renderPass -> - renderPass.setPipeline(layer.pipeline) - renderPass.setUniform("InnerCutoutRadius", innerCutoutRadius) - renderPass.setIndexBuffer(indexBuffer, indexBufferConstructor.indexType) - renderPass.setVertexBuffer(0, vertexBuffer) - renderPass.drawIndexed(0, buffer.drawParameters.indexCount) - } - } - } + val screenRect = ScreenRect(-1, -1, 2, 2).transform(drawContext.matrices) + drawContext.state.addSpecialElement( + State( + screenRect.left, screenRect.right, + screenRect.top, screenRect.bottom, + layer, + u1, u2, v1, v2, + angleRadians, + color, + innerCutoutRadius, + screenRect.width / 2F, + screenRect, + null + ) + ) } fun renderCircle( diff --git a/src/main/kotlin/util/render/RenderInWorldContext.kt b/src/main/kotlin/util/render/RenderInWorldContext.kt index c30ee19..0898190 100644 --- a/src/main/kotlin/util/render/RenderInWorldContext.kt +++ b/src/main/kotlin/util/render/RenderInWorldContext.kt @@ -1,7 +1,6 @@ package moe.nea.firmament.util.render import com.mojang.blaze3d.systems.RenderSystem -import io.github.notenoughupdates.moulconfig.platform.next import java.lang.Math.pow import org.joml.Matrix4f import org.joml.Vector3f @@ -28,18 +27,6 @@ class RenderInWorldContext private constructor( private val tickCounter: RenderTickCounter, val vertexConsumers: VertexConsumerProvider.Immediate, ) { - - - @Deprecated("stateful color management is no longer a thing") - fun color(color: me.shedaniel.math.Color) { - color(color.red / 255F, color.green / 255f, color.blue / 255f, color.alpha / 255f) - } - - @Deprecated("stateful color management is no longer a thing") - fun color(red: Float, green: Float, blue: Float, alpha: Float) { - RenderSystem.setShaderColor(red, green, blue, alpha) - } - fun block(blockPos: BlockPos, color: Int) { matrixStack.push() matrixStack.translate(blockPos.x.toFloat(), blockPos.y.toFloat(), blockPos.z.toFloat()) @@ -156,6 +143,7 @@ class RenderInWorldContext private constructor( fun wireframeCube(blockPos: BlockPos, lineWidth: Float = 10F) { val buf = vertexConsumers.getBuffer(RenderLayer.LINES) matrixStack.push() + // TODO: add color arg to this // TODO: this does not render through blocks (or water layers) anymore RenderSystem.lineWidth(lineWidth / pow(camera.pos.squaredDistanceTo(blockPos.toCenterPos()), 0.25).toFloat()) matrixStack.translate(blockPos.x.toFloat(), blockPos.y.toFloat(), blockPos.z.toFloat()) @@ -164,16 +152,16 @@ class RenderInWorldContext private constructor( vertexConsumers.draw() } - fun line(vararg points: Vec3d, lineWidth: Float = 10F) { - line(points.toList(), lineWidth) + fun line(vararg points: Vec3d, color: Int, lineWidth: Float = 10F) { + line(points.toList(), color, lineWidth) } - fun tracer(toWhere: Vec3d, lineWidth: Float = 3f) { + fun tracer(toWhere: Vec3d, color: Int, lineWidth: Float = 3f) { val cameraForward = Vector3f(0f, 0f, -1f).rotate(camera.rotation) - line(camera.pos.add(Vec3d(cameraForward)), toWhere, lineWidth = lineWidth) + line(camera.pos.add(Vec3d(cameraForward)), toWhere, color = color, lineWidth = lineWidth) } - fun line(points: List<Vec3d>, lineWidth: Float = 10F) { + fun line(points: List<Vec3d>, color: Int, lineWidth: Float = 10F) { RenderSystem.lineWidth(lineWidth) val buffer = vertexConsumers.getBuffer(CustomRenderLayers.LINES) @@ -188,11 +176,11 @@ class RenderInWorldContext private constructor( buffer.vertex(matrix.positionMatrix, a.x.toFloat(), a.y.toFloat(), a.z.toFloat()) .color(-1) .normal(matrix, lastNormal0.x, lastNormal0.y, lastNormal0.z) - .next() + buffer.vertex(matrix.positionMatrix, b.x.toFloat(), b.y.toFloat(), b.z.toFloat()) .color(-1) .normal(matrix, normal.x, normal.y, normal.z) - .next() + } } @@ -215,11 +203,11 @@ class RenderInWorldContext private constructor( buf.vertex(matrix.positionMatrix, i, j, k) .normal(matrix, normal.x, normal.y, normal.z) .color(-1) - .next() + buf.vertex(matrix.positionMatrix, x, y, z) .normal(matrix, normal.x, normal.y, normal.z) .color(-1) - .next() + } @@ -287,12 +275,6 @@ class RenderInWorldContext private constructor( } fun renderInWorld(event: WorldRenderLastEvent, block: RenderInWorldContext. () -> Unit) { - // TODO: there should be *no more global state*. the only thing we should be doing is render layers. that includes settings like culling, blending, shader color, and depth testing - // For now i will let these functions remain, but this needs to go before i do a full (non-beta) release -// RenderSystem.disableDepthTest() -// RenderSystem.enableBlend() -// RenderSystem.defaultBlendFunc() -// RenderSystem.disableCull() event.matrices.push() event.matrices.translate(-event.camera.pos.x, -event.camera.pos.y, -event.camera.pos.z) @@ -308,7 +290,6 @@ class RenderInWorldContext private constructor( event.matrices.pop() event.vertexConsumers.draw() - RenderSystem.setShaderColor(1F, 1F, 1F, 1F) } } } diff --git a/src/main/kotlin/util/render/TranslatedScissors.kt b/src/main/kotlin/util/render/TranslatedScissors.kt index 8f8bdcf..a091648 100644 --- a/src/main/kotlin/util/render/TranslatedScissors.kt +++ b/src/main/kotlin/util/render/TranslatedScissors.kt @@ -1,26 +1,27 @@ - package moe.nea.firmament.util.render -import org.joml.Matrix4f +import org.joml.Matrix3x2f +import org.joml.Vector3f import org.joml.Vector4f import net.minecraft.client.gui.DrawContext fun DrawContext.enableScissorWithTranslation(x1: Float, y1: Float, x2: Float, y2: Float) { - enableScissor(x1.toInt(), y1.toInt(), x2.toInt(), y2.toInt()) + enableScissor(x1.toInt(), y1.toInt(), x2.toInt(), y2.toInt()) } + fun DrawContext.enableScissorWithoutTranslation(x1: Float, y1: Float, x2: Float, y2: Float) { - val pMat = matrices.peek().positionMatrix.invert(Matrix4f()) - val target = Vector4f() + val pMat = Matrix3x2f(matrices).invert() + var target = Vector3f() - target.set(x1, y1, 0f, 1f) - target.mul(pMat) - val scissorX1 = target.x - val scissorY1 = target.y + target.set(x1, y1, 1F) + target.mul(pMat) + val scissorX1 = target.x + val scissorY1 = target.y - target.set(x2, y2, 0f, 1f) - target.mul(pMat) - val scissorX2 = target.x - val scissorY2 = target.y + target.set(x2, y2, 1F) + target.mul(pMat) + val scissorX2 = target.x + val scissorY2 = target.y - enableScissor(scissorX1.toInt(), scissorY1.toInt(), scissorX2.toInt(), scissorY2.toInt()) + enableScissor(scissorX1.toInt(), scissorY1.toInt(), scissorX2.toInt(), scissorY2.toInt()) } diff --git a/src/main/kotlin/util/textutil.kt b/src/main/kotlin/util/textutil.kt index cfda2e9..177b0af 100644 --- a/src/main/kotlin/util/textutil.kt +++ b/src/main/kotlin/util/textutil.kt @@ -179,10 +179,11 @@ fun Text.transformEachRecursively(function: (Text) -> Text): Text { val c = this.content if (c is TranslatableTextContent) { return Text.translatableWithFallback(c.key, c.fallback, *c.args.map { - (if (it is Text) it else Text.literal(it.toString())).transformEachRecursively(function) + (it as? Text ?: Text.literal(it.toString())).transformEachRecursively(function) }.toTypedArray()).also { new -> new.style = this.style new.siblings.clear() + val new = function(new) this.siblings.forEach { child -> new.siblings.add(child.transformEachRecursively(function)) } |
