diff options
author | Linnea Gräf <nea@nea.moe> | 2023-11-12 05:30:36 +0100 |
---|---|---|
committer | Linnea Gräf <nea@nea.moe> | 2023-11-12 05:30:36 +0100 |
commit | e580023cce085c84361a00a5b6115fceac325259 (patch) | |
tree | f6eda203e1edc607ee97e24b414d208c3116be29 | |
parent | f5515b455d607ddda5b215a8c4c1df9ff03e4117 (diff) | |
download | firmament-e580023cce085c84361a00a5b6115fceac325259.tar.gz firmament-e580023cce085c84361a00a5b6115fceac325259.tar.bz2 firmament-e580023cce085c84361a00a5b6115fceac325259.zip |
Actually render inventory buttons
11 files changed, 144 insertions, 34 deletions
diff --git a/src/main/java/moe/nea/firmament/mixins/MixinHandledScreen.java b/src/main/java/moe/nea/firmament/mixins/MixinHandledScreen.java index 3972ffc..35856cb 100644 --- a/src/main/java/moe/nea/firmament/mixins/MixinHandledScreen.java +++ b/src/main/java/moe/nea/firmament/mixins/MixinHandledScreen.java @@ -35,6 +35,10 @@ public abstract class MixinHandledScreen<T extends ScreenHandler> { @Shadow public abstract T getScreenHandler(); + @Shadow + protected int y; + @Shadow + protected int x; @Unique PlayerInventory playerInventory; @@ -52,14 +56,17 @@ public abstract class MixinHandledScreen<T extends ScreenHandler> { @Inject(method = "mouseClicked", at = @At("HEAD"), cancellable = true) public void onMouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) { - if (ScreenClickEvent.Companion.publish(new ScreenClickEvent((HandledScreen<?>) (Object) this, mouseX, mouseY, button)).getCancelled()) { + if (HandledScreenClickEvent.Companion.publish(new HandledScreenClickEvent((HandledScreen<?>) (Object) this, mouseX, mouseY, button)).getCancelled()) { cir.setReturnValue(true); } } @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawForeground(Lnet/minecraft/client/gui/DrawContext;II)V", shift = At.Shift.AFTER)) public void onAfterRenderForeground(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { - HandledScreenForegroundEvent.Companion.publish(new HandledScreenForegroundEvent((HandledScreen<?>) (Object) this, mouseX, mouseY, delta)); + context.getMatrices().push(); + context.getMatrices().translate(-x, -y, 0); + HandledScreenForegroundEvent.Companion.publish(new HandledScreenForegroundEvent((HandledScreen<?>) (Object) this, context, mouseX, mouseY, delta)); + context.getMatrices().pop(); } @Inject(method = "onMouseClick(Lnet/minecraft/screen/slot/Slot;IILnet/minecraft/screen/slot/SlotActionType;)V", at = @At("HEAD"), cancellable = true) diff --git a/src/main/kotlin/moe/nea/firmament/events/ScreenClickEvent.kt b/src/main/kotlin/moe/nea/firmament/events/HandledScreenClickEvent.kt index 0977971..0c4d4f6 100644 --- a/src/main/kotlin/moe/nea/firmament/events/ScreenClickEvent.kt +++ b/src/main/kotlin/moe/nea/firmament/events/HandledScreenClickEvent.kt @@ -8,7 +8,7 @@ package moe.nea.firmament.events import net.minecraft.client.gui.screen.ingame.HandledScreen -data class ScreenClickEvent(val screen: HandledScreen<*>, val mouseX: Double, val mouseY: Double, val button: Int) : +data class HandledScreenClickEvent(val screen: HandledScreen<*>, val mouseX: Double, val mouseY: Double, val button: Int) : FirmamentEvent.Cancellable() { - companion object : FirmamentEventBus<ScreenClickEvent>() + companion object : FirmamentEventBus<HandledScreenClickEvent>() } diff --git a/src/main/kotlin/moe/nea/firmament/events/HandledScreenForegroundEvent.kt b/src/main/kotlin/moe/nea/firmament/events/HandledScreenForegroundEvent.kt index d45b484..95f9b70 100644 --- a/src/main/kotlin/moe/nea/firmament/events/HandledScreenForegroundEvent.kt +++ b/src/main/kotlin/moe/nea/firmament/events/HandledScreenForegroundEvent.kt @@ -6,11 +6,15 @@ package moe.nea.firmament.events +import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.screen.ingame.HandledScreen data class HandledScreenForegroundEvent( val screen: HandledScreen<*>, - val mouseX: Int, val mouseY: Int, val delta: Float + val context: DrawContext, + val mouseX: Int, + val mouseY: Int, + val delta: Float ) : FirmamentEvent() { companion object : FirmamentEventBus<HandledScreenForegroundEvent>() } diff --git a/src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt b/src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt index 2683775..4888f54 100644 --- a/src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt +++ b/src/main/kotlin/moe/nea/firmament/features/FeatureManager.kt @@ -23,6 +23,7 @@ import moe.nea.firmament.features.inventory.ItemRarityCosmetics import moe.nea.firmament.features.inventory.PriceData import moe.nea.firmament.features.inventory.SaveCursorPosition import moe.nea.firmament.features.inventory.SlotLocking +import moe.nea.firmament.features.inventory.buttons.InventoryButtons import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlay import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures import moe.nea.firmament.features.world.FairySouls @@ -56,6 +57,7 @@ object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "feature loadFeature(CraftingOverlay) loadFeature(PowerUserTools) loadFeature(ChatLinks) + loadFeature(InventoryButtons) loadFeature(CompatibliltyFeatures) loadFeature(QuickCommands) loadFeature(SaveCursorPosition) diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/InventoryButton.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/InventoryButton.kt new file mode 100644 index 0000000..e2cc00e --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/InventoryButton.kt @@ -0,0 +1,45 @@ +package moe.nea.firmament.features.inventory.buttons + +import me.shedaniel.math.Dimension +import me.shedaniel.math.Point +import me.shedaniel.math.Rectangle +import kotlinx.serialization.Serializable +import net.minecraft.item.ItemStack +import moe.nea.firmament.repo.ItemCache.asItemStack +import moe.nea.firmament.repo.RepoManager +import moe.nea.firmament.util.SkyblockId + +@Serializable +data class InventoryButton( + val x: Int, + val y: Int, + val anchorRight: Boolean, + val anchorBottom: Boolean, + var icon: String?, + var command: String?, +) { + companion object { + val dimensions = Dimension(18, 18) + fun getItemForName(icon: String): ItemStack { + return RepoManager.getNEUItem(SkyblockId(icon)).asItemStack(idHint = SkyblockId(icon)) + } + } + + fun isValid() = !icon.isNullOrBlank() && !command.isNullOrBlank() + + fun getPosition(guiRect: Rectangle): Point { + return Point( + (if (anchorRight) guiRect.maxX else guiRect.minX) + x, + (if (anchorBottom) guiRect.maxY else guiRect.minY) + y, + ) + } + + fun getBounds(guiRect: Rectangle): Rectangle { + return Rectangle(getPosition(guiRect), dimensions) + } + + fun getItem(): ItemStack { + return getItemForName(icon ?: "") + } + +} diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/InventoryButtonEditor.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/InventoryButtonEditor.kt index f269242..61dbdc6 100644 --- a/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/InventoryButtonEditor.kt +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/InventoryButtonEditor.kt @@ -3,20 +3,20 @@ package moe.nea.firmament.features.inventory.buttons import io.github.moulberry.moulconfig.common.IItemStack import io.github.moulberry.moulconfig.xml.Bind import io.github.notenoughupdates.moulconfig.platform.ModernItemStack -import me.shedaniel.math.Dimension import me.shedaniel.math.Point import me.shedaniel.math.Rectangle import org.lwjgl.glfw.GLFW import net.minecraft.client.gui.DrawContext import moe.nea.firmament.repo.ItemCache.asItemStack import moe.nea.firmament.repo.RepoManager +import moe.nea.firmament.util.FragmentGuiScreen import moe.nea.firmament.util.MoulConfigUtils import moe.nea.firmament.util.SkyblockId class InventoryButtonEditor( val lastGuiRect: Rectangle, ) : FragmentGuiScreen() { - class Editor(val originalButton: Button) { + class Editor(val originalButton: InventoryButton) { @field:Bind var command: String = originalButton.command ?: "" @@ -26,7 +26,7 @@ class InventoryButtonEditor( @Bind fun getItemIcon(): IItemStack { save() - return ModernItemStack.of(RepoManager.getNEUItem(SkyblockId(icon)).asItemStack(idHint = SkyblockId(icon))) + return ModernItemStack.of(InventoryButton.getItemForName(icon)) } fun save() { @@ -35,29 +35,14 @@ class InventoryButtonEditor( } } - data class Button( - val x: Int, - val y: Int, - val anchorRight: Boolean, - val anchorBottom: Boolean, - var icon: String?, - var command: String?, - ) { - fun isValid() = !icon.isNullOrBlank() && !command.isNullOrBlank() + val buttons: MutableList<InventoryButton> = + InventoryButtons.DConfig.data.buttons.map { it.copy() }.toMutableList() - fun getPosition(guiRect: Rectangle): Point { - return Point( - (if (anchorRight) guiRect.maxX else guiRect.minX) + x, - (if (anchorBottom) guiRect.maxY else guiRect.minY) + y, - ) - } - - fun getBounds(guiRect: Rectangle): Rectangle { - return Rectangle(getPosition(guiRect), Dimension(18, 18)) - } + override fun close() { + InventoryButtons.DConfig.data.buttons = buttons + super.close() } - val buttons = mutableListOf<Button>() override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { context.fill(lastGuiRect.minX, lastGuiRect.minY, lastGuiRect.maxX, lastGuiRect.maxY, -1) @@ -89,14 +74,20 @@ class InventoryButtonEditor( createPopup(MoulConfigUtils.loadGui("button_editor_fragment", Editor(clickedButton)), Point(mouseX, mouseY)) return true } - if (lastGuiRect.contains(mouseX, mouseY) || lastGuiRect.contains(Point(mouseX + 18, mouseY + 18))) return true + if (lastGuiRect.contains(mouseX, mouseY) || lastGuiRect.contains( + Point( + mouseX + InventoryButton.dimensions.width, + mouseY + InventoryButton.dimensions.height, + ) + ) + ) return true val mx = mouseX.toInt() val my = mouseY.toInt() val anchorRight = mx > lastGuiRect.maxX val anchorBottom = my > lastGuiRect.maxY val offsetX = mx - if (anchorRight) lastGuiRect.maxX else lastGuiRect.minX val offsetY = my - if (anchorBottom) lastGuiRect.maxY else lastGuiRect.minY - buttons.add(Button(offsetX, offsetY, anchorRight, anchorBottom, null, null)) + buttons.add(InventoryButton(offsetX, offsetY, anchorRight, anchorBottom, null, null)) return true } diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/InventoryButtons.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/InventoryButtons.kt new file mode 100644 index 0000000..7d476c9 --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/InventoryButtons.kt @@ -0,0 +1,61 @@ +package moe.nea.firmament.features.inventory.buttons + +import kotlinx.serialization.Serializable +import kotlinx.serialization.serializer +import moe.nea.firmament.events.HandledScreenClickEvent +import moe.nea.firmament.events.HandledScreenForegroundEvent +import moe.nea.firmament.events.HandledScreenPushREIEvent +import moe.nea.firmament.features.FirmamentFeature +import moe.nea.firmament.features.debug.DeveloperFeatures.getRectangle +import moe.nea.firmament.gui.config.ManagedConfig +import moe.nea.firmament.mixins.accessor.AccessorHandledScreen +import moe.nea.firmament.util.MC +import moe.nea.firmament.util.data.DataHolder + +object InventoryButtons : FirmamentFeature { + override val identifier: String + get() = "inventory-buttons" + + object TConfig : ManagedConfig(identifier) {} + object DConfig : DataHolder<Data>(serializer(), identifier, ::Data) + @Serializable + data class Data( + var buttons: MutableList<InventoryButton> = mutableListOf() + ) + + + override val config: ManagedConfig + get() = TConfig + + fun getValidButtons() = DConfig.data.buttons.asSequence().filter { it.isValid() } + override fun onLoad() { + HandledScreenForegroundEvent.subscribe { + it.screen as AccessorHandledScreen + val bounds = it.screen.getRectangle() + for (button in getValidButtons()) { + val buttonBounds = button.getBounds(bounds) + // TODO: render background + it.context.drawItem(button.getItem(), buttonBounds.minX + 1, buttonBounds.minY + 1) + } + } + HandledScreenClickEvent.subscribe { + it.screen as AccessorHandledScreen + val bounds = it.screen.getRectangle() + for (button in getValidButtons()) { + val buttonBounds = button.getBounds(bounds) + if (buttonBounds.contains(it.mouseX, it.mouseY)) { + MC.sendCommand(button.command!! /* non null invariant covered by getValidButtons */) + break + } + } + } + HandledScreenPushREIEvent.subscribe { + it.screen as AccessorHandledScreen + val bounds = it.screen.getRectangle() + for (button in getValidButtons()) { + val buttonBounds = button.getBounds(bounds) + it.block(buttonBounds) + } + } + } +} diff --git a/src/main/kotlin/moe/nea/firmament/rei/FirmamentReiPlugin.kt b/src/main/kotlin/moe/nea/firmament/rei/FirmamentReiPlugin.kt index a91cd71..917cf6c 100644 --- a/src/main/kotlin/moe/nea/firmament/rei/FirmamentReiPlugin.kt +++ b/src/main/kotlin/moe/nea/firmament/rei/FirmamentReiPlugin.kt @@ -42,7 +42,6 @@ class FirmamentReiPlugin : REIClientPlugin { val SKYBLOCK_ITEM_TYPE_ID = Identifier("firmament", "skyblockitems") } - override fun registerTransferHandlers(registry: TransferHandlerRegistry) { registry.register(TransferHandler { context -> val screen = context.containerScreen diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/FragmentGuiScreen.kt b/src/main/kotlin/moe/nea/firmament/util/FragmentGuiScreen.kt index 4f38f99..3323a72 100644 --- a/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/FragmentGuiScreen.kt +++ b/src/main/kotlin/moe/nea/firmament/util/FragmentGuiScreen.kt @@ -1,4 +1,4 @@ -package moe.nea.firmament.features.inventory.buttons +package moe.nea.firmament.util import io.github.moulberry.moulconfig.gui.GuiContext import me.shedaniel.math.Dimension @@ -7,6 +7,7 @@ import me.shedaniel.math.Rectangle import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.screen.Screen import net.minecraft.text.Text +import moe.nea.firmament.util.MoulConfigFragment abstract class FragmentGuiScreen( val dismissOnOutOfBounds: Boolean = true diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/MoulConfigFragment.kt b/src/main/kotlin/moe/nea/firmament/util/MoulConfigFragment.kt index 273dd20..2064db3 100644 --- a/src/main/kotlin/moe/nea/firmament/features/inventory/buttons/MoulConfigFragment.kt +++ b/src/main/kotlin/moe/nea/firmament/util/MoulConfigFragment.kt @@ -1,4 +1,4 @@ -package moe.nea.firmament.features.inventory.buttons +package moe.nea.firmament.util import io.github.moulberry.moulconfig.gui.GuiContext import io.github.moulberry.moulconfig.gui.GuiImmediateContext diff --git a/src/main/resources/assets/firmament/gui/button_editor_fragment.xml b/src/main/resources/assets/firmament/gui/button_editor_fragment.xml index b450c41..4830b16 100644 --- a/src/main/resources/assets/firmament/gui/button_editor_fragment.xml +++ b/src/main/resources/assets/firmament/gui/button_editor_fragment.xml @@ -4,7 +4,7 @@ <Panel> <Column> <Row> - <Text textAlign="CENTER" text="Icon"/> + <Text text="Icon"/> <ItemStack value="@getItemIcon"/> </Row> <TextField value="@icon" width="180"/> |