package moe.nea.firmament.features.macros import kotlin.time.Duration.Companion.seconds import net.minecraft.client.util.InputUtil import net.minecraft.text.Text import moe.nea.firmament.annotations.Subscribe import moe.nea.firmament.events.HudRenderEvent import moe.nea.firmament.events.TickEvent import moe.nea.firmament.events.WorldKeyboardEvent import moe.nea.firmament.keybindings.SavedKeyBinding import moe.nea.firmament.util.MC import moe.nea.firmament.util.TimeMark import moe.nea.firmament.util.tr object ComboProcessor { var rootTrie: Branch = Branch(mapOf()) private set var activeTrie: Branch = rootTrie private set var isInputting = false var lastInput = TimeMark.farPast() val breadCrumbs = mutableListOf() init { val f = SavedKeyBinding(InputUtil.GLFW_KEY_F) val one = SavedKeyBinding(InputUtil.GLFW_KEY_1) val two = SavedKeyBinding(InputUtil.GLFW_KEY_2) setActions( MacroData.DConfig.data.comboActions ) } fun setActions(actions: List) { rootTrie = KeyComboTrie.fromComboList(actions) reset() } fun reset() { activeTrie = rootTrie lastInput = TimeMark.now() isInputting = false breadCrumbs.clear() } @Subscribe fun onTick(event: TickEvent) { if (isInputting && lastInput.passedTime() > 3.seconds) reset() } @Subscribe fun onRender(event: HudRenderEvent) { if (!isInputting) return if (!event.isRenderingHud) return event.context.matrices.push() val width = 120 event.context.matrices.translate( (MC.window.scaledWidth - width) / 2F, (MC.window.scaledHeight) / 2F + 8, 0F ) val breadCrumbText = breadCrumbs.joinToString(" > ") event.context.drawText( MC.font, tr("firmament.combo.active", "Current Combo: ").append(breadCrumbText), 0, 0, -1, true ) event.context.matrices.translate(0F, MC.font.fontHeight + 2F, 0F) for ((key, value) in activeTrie.nodes) { event.context.drawText( MC.font, Text.literal("$breadCrumbText > $key: ").append(value.label), 0, 0, -1, true ) event.context.matrices.translate(0F, MC.font.fontHeight + 1F, 0F) } event.context.matrices.pop() } @Subscribe fun onKeyBinding(event: WorldKeyboardEvent) { val nextEntry = activeTrie.nodes.entries .find { event.matches(it.key) } if (nextEntry == null) { reset() return } event.cancel() breadCrumbs.add(nextEntry.key) lastInput = TimeMark.now() isInputting = true val value = nextEntry.value when (value) { is Branch -> { activeTrie = value } is Leaf -> { value.execute() reset() } }.let { } } }