aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/util
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2025-06-22 22:45:16 +0200
committerLinnea Gräf <nea@nea.moe>2025-06-22 22:45:16 +0200
commit1ab9094bde904b9671acf29c700e3c98d503c8fe (patch)
treeea0c2dc731a46a65a30748be01720c096ab3f83d /src/main/kotlin/util
parentfbc44e21393758ddf92397446d8e19f3f39a7317 (diff)
downloadFirmament-1ab9094bde904b9671acf29c700e3c98d503c8fe.tar.gz
Firmament-1ab9094bde904b9671acf29c700e3c98d503c8fe.tar.bz2
Firmament-1ab9094bde904b9671acf29c700e3c98d503c8fe.zip
feat: Add npc location exporter
Diffstat (limited to 'src/main/kotlin/util')
-rw-r--r--src/main/kotlin/util/HoveredItemStack.kt2
-rw-r--r--src/main/kotlin/util/MoulConfigUtils.kt39
-rw-r--r--src/main/kotlin/util/async/input.kt108
3 files changed, 100 insertions, 49 deletions
diff --git a/src/main/kotlin/util/HoveredItemStack.kt b/src/main/kotlin/util/HoveredItemStack.kt
index a2e4ad2..526820a 100644
--- a/src/main/kotlin/util/HoveredItemStack.kt
+++ b/src/main/kotlin/util/HoveredItemStack.kt
@@ -24,4 +24,4 @@ class VanillaScreenProvider : HoveredItemStackProvider {
val HandledScreen<*>.focusedItemStack: ItemStack?
get() =
HoveredItemStackProvider.allValidInstances
- .firstNotNullOfOrNull { it.provideHoveredItemStack(this) }
+ .firstNotNullOfOrNull { it.provideHoveredItemStack(this)?.takeIf { !it.isEmpty } }
diff --git a/src/main/kotlin/util/MoulConfigUtils.kt b/src/main/kotlin/util/MoulConfigUtils.kt
index a9e3241..51ff340 100644
--- a/src/main/kotlin/util/MoulConfigUtils.kt
+++ b/src/main/kotlin/util/MoulConfigUtils.kt
@@ -9,7 +9,6 @@ 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.gui.component.PanelComponent
import io.github.notenoughupdates.moulconfig.observer.GetSetter
import io.github.notenoughupdates.moulconfig.platform.ModernRenderContext
import io.github.notenoughupdates.moulconfig.xml.ChildCount
@@ -21,7 +20,6 @@ import java.io.File
import java.util.function.Supplier
import javax.xml.namespace.QName
import me.shedaniel.math.Color
-import org.jetbrains.annotations.Unmodifiable
import org.w3c.dom.Element
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
@@ -41,13 +39,15 @@ object MoulConfigUtils {
fun main(args: Array<out String>) {
generateXSD(File("MoulConfig.xsd"), XMLUniverse.MOULCONFIG_XML_NS)
generateXSD(File("MoulConfig.Firmament.xsd"), firmUrl)
- File("wrapper.xsd").writeText("""
+ File("wrapper.xsd").writeText(
+ """
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://notenoughupdates.org/moulconfig" schemaLocation="MoulConfig.xsd"/>
<xs:import namespace="http://firmament.nea.moe/moulconfig" schemaLocation="MoulConfig.Firmament.xsd"/>
</xs:schema>
- """.trimIndent())
+ """.trimIndent()
+ )
}
val firmUrl = "http://firmament.nea.moe/moulconfig"
@@ -96,9 +96,11 @@ object MoulConfigUtils {
override fun createInstance(context: XMLContext<*>, element: Element): FirmHoverComponent {
return FirmHoverComponent(
context.getChildFragment(element),
- context.getPropertyFromAttribute(element,
- QName("lines"),
- List::class.java) as Supplier<List<String>>,
+ context.getPropertyFromAttribute(
+ element,
+ QName("lines"),
+ List::class.java
+ ) as Supplier<List<String>>,
context.getPropertyFromAttribute(element, QName("delay"), Duration::class.java, 0.6.seconds),
)
}
@@ -223,16 +225,21 @@ object MoulConfigUtils {
generator.dumpToFile(file)
}
- fun loadScreen(name: String, bindTo: Any, parent: Screen?): Screen {
- return object : GuiComponentWrapper(loadGui(name, bindTo)) {
+ fun wrapScreen(guiContext: GuiContext, parent: Screen?, onClose: () -> Unit = {}): Screen {
+ return object : GuiComponentWrapper(guiContext) {
override fun close() {
if (context.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) {
client!!.setScreen(parent)
+ onClose()
}
}
}
}
+ fun loadScreen(name: String, bindTo: Any, parent: Screen?): Screen {
+ return wrapScreen(loadGui(name, bindTo), parent)
+ }
+
// TODO: move this utility into moulconfig (also rework guicontext into an interface so i can make this mesh better into vanilla)
fun GuiContext.adopt(element: GuiComponent) = element.foldRecursive(Unit, { comp, unit -> comp.context = this })
@@ -288,12 +295,14 @@ object MoulConfigUtils {
assert(drawContext?.isUntranslatedGuiDrawContext() != false)
val context = drawContext?.let(::ModernRenderContext)
?: IMinecraft.instance.provideTopLevelRenderContext()
- val immContext = GuiImmediateContext(context,
- 0, 0, 0, 0,
- mouseX, mouseY,
- mouseX, mouseY,
- mouseX.toFloat(),
- mouseY.toFloat())
+ val immContext = GuiImmediateContext(
+ context,
+ 0, 0, 0, 0,
+ mouseX, mouseY,
+ mouseX, mouseY,
+ mouseX.toFloat(),
+ mouseY.toFloat()
+ )
return immContext
}
diff --git a/src/main/kotlin/util/async/input.kt b/src/main/kotlin/util/async/input.kt
index f22c595..2c546ba 100644
--- a/src/main/kotlin/util/async/input.kt
+++ b/src/main/kotlin/util/async/input.kt
@@ -1,47 +1,89 @@
-
-
package moe.nea.firmament.util.async
+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 kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.resume
+import net.minecraft.client.gui.screen.Screen
import moe.nea.firmament.events.HandledScreenKeyPressedEvent
+import moe.nea.firmament.gui.FirmButtonComponent
import moe.nea.firmament.keybindings.IKeyBinding
+import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.MoulConfigUtils
+import moe.nea.firmament.util.ScreenUtil
private object InputHandler {
- data class KeyInputContinuation(val keybind: IKeyBinding, val onContinue: () -> Unit)
-
- private val activeContinuations = mutableListOf<KeyInputContinuation>()
-
- fun registerContinuation(keyInputContinuation: KeyInputContinuation): () -> Unit {
- synchronized(InputHandler) {
- activeContinuations.add(keyInputContinuation)
- }
- return {
- synchronized(this) {
- activeContinuations.remove(keyInputContinuation)
- }
- }
- }
-
- init {
- HandledScreenKeyPressedEvent.subscribe("Input:resumeAfterInput") { event ->
- synchronized(InputHandler) {
- val toRemove = activeContinuations.filter {
- event.matches(it.keybind)
- }
- toRemove.forEach { it.onContinue() }
- activeContinuations.removeAll(toRemove)
- }
- }
- }
+ data class KeyInputContinuation(val keybind: IKeyBinding, val onContinue: () -> Unit)
+
+ private val activeContinuations = mutableListOf<KeyInputContinuation>()
+
+ fun registerContinuation(keyInputContinuation: KeyInputContinuation): () -> Unit {
+ synchronized(InputHandler) {
+ activeContinuations.add(keyInputContinuation)
+ }
+ return {
+ synchronized(this) {
+ activeContinuations.remove(keyInputContinuation)
+ }
+ }
+ }
+
+ init {
+ HandledScreenKeyPressedEvent.subscribe("Input:resumeAfterInput") { event ->
+ synchronized(InputHandler) {
+ val toRemove = activeContinuations.filter {
+ event.matches(it.keybind)
+ }
+ toRemove.forEach { it.onContinue() }
+ activeContinuations.removeAll(toRemove)
+ }
+ }
+ }
}
suspend fun waitForInput(keybind: IKeyBinding): Unit = suspendCancellableCoroutine { cont ->
- val unregister =
- InputHandler.registerContinuation(InputHandler.KeyInputContinuation(keybind) { cont.resume(Unit) })
- cont.invokeOnCancellation {
- unregister()
- }
+ val unregister =
+ InputHandler.registerContinuation(InputHandler.KeyInputContinuation(keybind) { cont.resume(Unit) })
+ cont.invokeOnCancellation {
+ unregister()
+ }
}
+fun createPromptScreenGuiComponent(suggestion: String, prompt: String, action: Runnable) = (run {
+ val text = GetSetter.floating(suggestion)
+ GuiContext(
+ CenterComponent(
+ PanelComponent(
+ ColumnComponent(
+ TextFieldComponent(text, 120),
+ FirmButtonComponent(TextComponent(prompt), action = action)
+ )
+ )
+ )
+ ) to text
+})
+
+suspend fun waitForTextInput(suggestion: String, prompt: String) =
+ suspendCancellableCoroutine<String> { cont ->
+ lateinit var screen: Screen
+ lateinit var text: GetSetter<String>
+ val action = {
+ if (MC.screen === screen)
+ MC.screen = null
+ // TODO: should this exit
+ cont.resume(text.get())
+ }
+ val (gui, text_) = createPromptScreenGuiComponent(suggestion, prompt, action)
+ text = text_
+ screen = MoulConfigUtils.wrapScreen(gui, null, onClose = action)
+ ScreenUtil.setScreenLater(screen)
+ cont.invokeOnCancellation {
+ action()
+ }
+ }