feat: Add npc location exporter
This commit is contained in:
@@ -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 } }
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
data class KeyInputContinuation(val keybind: IKeyBinding, val onContinue: () -> Unit)
|
||||
|
||||
private val activeContinuations = mutableListOf<KeyInputContinuation>()
|
||||
private val activeContinuations = mutableListOf<KeyInputContinuation>()
|
||||
|
||||
fun registerContinuation(keyInputContinuation: KeyInputContinuation): () -> Unit {
|
||||
synchronized(InputHandler) {
|
||||
activeContinuations.add(keyInputContinuation)
|
||||
}
|
||||
return {
|
||||
synchronized(this) {
|
||||
activeContinuations.remove(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)
|
||||
}
|
||||
}
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user