keybindings: Fix STICKY_INVERTED, hud toggle keybindings

This commit is contained in:
Bixilon 2021-09-11 19:29:12 +02:00
parent 65744d625f
commit 289a0875a3
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
9 changed files with 139 additions and 112 deletions

View File

@ -13,19 +13,9 @@
package de.bixilon.minosoft.config.config.game.controls package de.bixilon.minosoft.config.config.game.controls
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames.DEFAULT_KEY_BINDINGS
import de.bixilon.minosoft.config.key.KeyBinding import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.ResourceLocation
data class KeyBindingsGameConfig( data class KeyBindingsGameConfig(
val entries: MutableMap<ResourceLocation, KeyBinding> = mutableMapOf(), val entries: MutableMap<ResourceLocation, KeyBinding> = mutableMapOf(),
) { )
init {
for ((resourceLocation, keyBinding) in DEFAULT_KEY_BINDINGS) {
if (!entries.containsKey(resourceLocation)) {
// add key binding
entries[resourceLocation] = KeyBinding(keyBinding)
}
}
}
}

View File

@ -1,57 +0,0 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.config.config.game.controls
import de.bixilon.minosoft.config.key.KeyAction
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.registries.ResourceLocation
@Deprecated(message = "Use new system with providing default key bindings when registering instead of \"pre registering\" the key")
object KeyBindingsNames {
val TOGGLE_DEBUG_SCREEN = ResourceLocation("minosoft:toggle_debug_screen")
val DEBUG_MOUSE_CATCH = ResourceLocation("minosoft:debug_mouse_catch")
val TOGGLE_HUD = ResourceLocation("minosoft:toggle_hud")
val OPEN_CHAT = ResourceLocation("minosoft:open_chat")
val CLOSE = ResourceLocation("minosoft:close")
val DEFAULT_KEY_BINDINGS: Map<ResourceLocation, KeyBinding> = mapOf(
TOGGLE_DEBUG_SCREEN to KeyBinding(
mutableMapOf(
KeyAction.STICKY to mutableSetOf(KeyCodes.KEY_F3),
),
),
TOGGLE_HUD to KeyBinding(
mutableMapOf(
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_F1),
),
),
OPEN_CHAT to KeyBinding(
mutableMapOf(
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_T),
),
),
CLOSE to KeyBinding(
mutableMapOf(
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_ESCAPE),
),
ignoreConsumer = true,
),
)
}

View File

@ -39,7 +39,7 @@ enum class KeyAction {
MODIFIER, MODIFIER,
/** /**
* Pressing the key makes it sticky, you have to press it again to make it not pressed anymore * Pressing the key makes it sticky, you have to press it again to make it not pressed anymore. Initially not pressed.
*/ */
STICKY, STICKY,

View File

@ -49,6 +49,7 @@ import de.bixilon.minosoft.util.CountUpAndDownLatch
import de.bixilon.minosoft.util.KUtil.decide import de.bixilon.minosoft.util.KUtil.decide
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
import de.bixilon.minosoft.util.KUtil.toResourceLocation import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.KUtil.unsafeCast
import de.bixilon.minosoft.util.MMath.round10 import de.bixilon.minosoft.util.MMath.round10
import de.bixilon.minosoft.util.Queue import de.bixilon.minosoft.util.Queue
import de.bixilon.minosoft.util.Stopwatch import de.bixilon.minosoft.util.Stopwatch
@ -219,7 +220,7 @@ class RenderWindow(
} }
private fun registerGlobalKeyCombinations() { private fun registerGlobalKeyCombinations() {
inputHandler.registerKeyCallback("minosoft:debug_polygon".toResourceLocation(), KeyBinding( inputHandler.registerKeyCallback("minosoft:enable_debug_polygon".toResourceLocation(), KeyBinding(
mutableMapOf( mutableMapOf(
KeyAction.MODIFIER to mutableSetOf(KeyCodes.KEY_F4), KeyAction.MODIFIER to mutableSetOf(KeyCodes.KEY_F4),
KeyAction.STICKY to mutableSetOf(KeyCodes.KEY_P), KeyAction.STICKY to mutableSetOf(KeyCodes.KEY_P),
@ -361,6 +362,6 @@ class RenderWindow(
} }
operator fun <T : Renderer> get(renderer: RendererBuilder<T>): T? { operator fun <T : Renderer> get(renderer: RendererBuilder<T>): T? {
return rendererMap[renderer.RESOURCE_LOCATION] as T? return rendererMap[renderer.RESOURCE_LOCATION].unsafeCast()
} }
} }

View File

@ -14,20 +14,28 @@
package de.bixilon.minosoft.gui.rendering.gui.hud package de.bixilon.minosoft.gui.rendering.gui.hud
import de.bixilon.minosoft.Minosoft import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.config.key.KeyAction
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.Renderer import de.bixilon.minosoft.gui.rendering.Renderer
import de.bixilon.minosoft.gui.rendering.RendererBuilder import de.bixilon.minosoft.gui.rendering.RendererBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.hud.DebugHUD import de.bixilon.minosoft.gui.rendering.gui.hud.hud.DebugHUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.hud.HUD import de.bixilon.minosoft.gui.rendering.gui.hud.hud.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.hud.HUDElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
import de.bixilon.minosoft.gui.rendering.util.vec.Vec2Util.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.Vec2Util.EMPTY
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.KUtil.synchronizedListOf import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
import de.bixilon.minosoft.util.KUtil.toResourceLocation import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
import glm_.glm import glm_.glm
import glm_.mat4x4.Mat4 import glm_.mat4x4.Mat4
import glm_.vec2.Vec2 import glm_.vec2.Vec2
@ -41,25 +49,50 @@ class HUDRenderer(
private lateinit var mesh: GUIMesh private lateinit var mesh: GUIMesh
var scaledSize: Vec2i = renderWindow.window.size var scaledSize: Vec2i = renderWindow.window.size
private var matrix: Mat4 = Mat4() private var matrix: Mat4 = Mat4()
private var enabled = true
val hud: MutableList<HUD<*>> = synchronizedListOf( private val hudElements: MutableMap<ResourceLocation, HUDElement<*>> = synchronizedMapOf()
DebugHUD(this),
)
private var lastTickTime = 0L private var lastTickTime = 0L
fun registerElement(hudBuilder: HUDBuilder<*>) {
val hudElement = hudBuilder.build(this)
hudElements[hudBuilder.RESOURCE_LOCATION] = hudElement
val toggleKeyBinding = hudBuilder.ENABLE_KEY_BINDING ?: return
val toggleKeyBindingName = hudBuilder.ENABLE_KEY_BINDING_NAME ?: return
// ToDo: Default disabled elements like the debug screen?
renderWindow.inputHandler.registerKeyCallback(toggleKeyBindingName, toggleKeyBinding) { hudElement.enabled = it }
}
private fun registerDefaultElements() {
registerElement(DebugHUDElement)
}
override fun init() { override fun init() {
connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> { connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> {
scaledSize = Vec2i(Vec2(it.size) / Minosoft.config.config.game.hud.scale) scaledSize = Vec2i(Vec2(it.size) / Minosoft.config.config.game.hud.scale)
matrix = glm.ortho(0.0f, scaledSize.x.toFloat(), scaledSize.y.toFloat(), 0.0f) matrix = glm.ortho(0.0f, scaledSize.x.toFloat(), scaledSize.y.toFloat(), 0.0f)
for (hud in hud) { for (element in hudElements.toSynchronizedMap().values) {
hud.layout?.onParentChange() element.layout?.onParentChange()
} }
}) })
registerDefaultElements()
for (hud in this.hud) { for (element in this.hudElements.toSynchronizedMap().values) {
hud.init() element.init()
}
renderWindow.inputHandler.registerKeyCallback("minosoft:enable_hud".toResourceLocation(), KeyBinding(
mutableMapOf(
KeyAction.STICKY_INVERTED to mutableSetOf(KeyCodes.KEY_F1),
),
)) {
Log.log(LogMessageType.OTHER, LogLevels.INFO) { "Toggled hud: $it" }
enabled = it
} }
} }
@ -67,23 +100,30 @@ class HUDRenderer(
shader.load() shader.load()
renderWindow.textureManager.staticTextures.use(shader) renderWindow.textureManager.staticTextures.use(shader)
for (hud in this.hud) { for (element in this.hudElements.toSynchronizedMap().values) {
hud.postInit() element.postInit()
} }
} }
override fun draw() { override fun draw() {
if (!enabled) {
return
}
renderWindow.renderSystem.reset() renderWindow.renderSystem.reset()
if (this::mesh.isInitialized) { if (this::mesh.isInitialized) {
mesh.unload() mesh.unload()
} }
mesh = GUIMesh(renderWindow, matrix) mesh = GUIMesh(renderWindow, matrix)
val hudElements = hudElements.toSynchronizedMap().values
val time = System.currentTimeMillis() val time = System.currentTimeMillis()
if (time - lastTickTime > ProtocolDefinition.TICK_TIME) { if (time - lastTickTime > ProtocolDefinition.TICK_TIME) {
for (hud in this.hud) { for (element in hudElements) {
hud.tick() if (!element.enabled) {
continue
}
element.tick()
} }
lastTickTime = time lastTickTime = time
@ -91,12 +131,12 @@ class HUDRenderer(
// ToDo: size > maxSize // ToDo: size > maxSize
for (hud in this.hud) { for (element in hudElements) {
val z = 0 if (!element.enabled) {
val offset = Vec2i.EMPTY // ToDo: Element positioning continue
}
hud.layout?.render(offset, z, mesh) element.layout?.render(element.layoutOffset ?: Vec2i.EMPTY, 0, mesh)
hud.draw(offset, z, mesh) element.draw(mesh)
} }
mesh.load() mesh.load()
@ -107,7 +147,7 @@ class HUDRenderer(
} }
companion object : RendererBuilder<HUDRenderer> { companion object : RendererBuilder<HUDRenderer> {
override val RESOURCE_LOCATION = ResourceLocation("minosoft:hud_renderer") override val RESOURCE_LOCATION = "minosoft:hud_renderer".toResourceLocation()
override fun build(connection: PlayConnection, renderWindow: RenderWindow): HUDRenderer { override fun build(connection: PlayConnection, renderWindow: RenderWindow): HUDRenderer {
return HUDRenderer(connection, renderWindow) return HUDRenderer(connection, renderWindow)

View File

@ -14,14 +14,17 @@
package de.bixilon.minosoft.gui.rendering.gui.hud.hud package de.bixilon.minosoft.gui.rendering.gui.hud.hud
import de.bixilon.minosoft.Minosoft import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.config.key.KeyAction
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.abilities.Gamemodes import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.other.game.event.handlers.GameMoveChangeGameEventHandler import de.bixilon.minosoft.data.registries.other.game.event.handlers.GameMoveChangeGameEventHandler
import de.bixilon.minosoft.data.text.BaseComponent import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatColors import de.bixilon.minosoft.data.text.ChatColors
import de.bixilon.minosoft.data.text.TextComponent import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.world.Chunk import de.bixilon.minosoft.data.world.Chunk
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.block.WorldRenderer import de.bixilon.minosoft.gui.rendering.block.WorldRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments
@ -43,6 +46,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.terminal.RunConfiguration import de.bixilon.minosoft.terminal.RunConfiguration
import de.bixilon.minosoft.util.GitInfo import de.bixilon.minosoft.util.GitInfo
import de.bixilon.minosoft.util.KUtil.format import de.bixilon.minosoft.util.KUtil.format
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.MMath.round10 import de.bixilon.minosoft.util.MMath.round10
import de.bixilon.minosoft.util.SystemInformation import de.bixilon.minosoft.util.SystemInformation
import de.bixilon.minosoft.util.UnitFormatter.formatBytes import de.bixilon.minosoft.util.UnitFormatter.formatBytes
@ -50,8 +54,7 @@ import glm_.vec2.Vec2i
import glm_.vec4.Vec4i import glm_.vec4.Vec4i
import kotlin.math.abs import kotlin.math.abs
class DebugHUD(val hudRenderer: HUDRenderer) : HUD<GridLayout> { class DebugHUDElement(hudRenderer: HUDRenderer) : HUDElement<GridLayout>(hudRenderer) {
override val renderWindow: RenderWindow = hudRenderer.renderWindow
private val connection = renderWindow.connection private val connection = renderWindow.connection
override val layout = GridLayout(hudRenderer, Vec2i(3, 1)).apply { override val layout = GridLayout(hudRenderer, Vec2i(3, 1)).apply {
columnConstraints[0].apply { columnConstraints[0].apply {
@ -276,4 +279,18 @@ class DebugHUD(val hudRenderer: HUDRenderer) : HUD<GridLayout> {
super.tick() super.tick()
} }
} }
companion object : HUDBuilder<DebugHUDElement> {
override val RESOURCE_LOCATION: ResourceLocation = "minosoft:debug_hud".toResourceLocation()
override val ENABLE_KEY_BINDING_NAME: ResourceLocation = "minosoft:enable_debug_hud".toResourceLocation()
override val ENABLE_KEY_BINDING: KeyBinding = KeyBinding(
mutableMapOf(
KeyAction.STICKY to mutableSetOf(KeyCodes.KEY_F3),
),
)
override fun build(hudRenderer: HUDRenderer): DebugHUDElement {
return DebugHUDElement(hudRenderer)
}
}
} }

View File

@ -0,0 +1,28 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.hud
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.data.registries.CompanionResourceLocation
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
interface HUDBuilder<T : HUDElement<*>> : CompanionResourceLocation {
val ENABLE_KEY_BINDING_NAME: ResourceLocation?
get() = null
val ENABLE_KEY_BINDING: KeyBinding?
get() = null
fun build(hudRenderer: HUDRenderer): T
}

View File

@ -15,22 +15,27 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.hud
import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.gui.elements.layout.Layout import de.bixilon.minosoft.gui.rendering.gui.elements.layout.Layout
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import glm_.vec2.Vec2i import glm_.vec2.Vec2i
interface HUD<T : Layout> { abstract class HUDElement<T : Layout>(val hudRenderer: HUDRenderer) {
val renderWindow: RenderWindow val renderWindow: RenderWindow = hudRenderer.renderWindow
var enabled = true
val layout: T? open val layout: T?
get() = null get() = null
fun init() {} open val layoutOffset: Vec2i?
get() = null
fun postInit() {} open fun init() {}
fun draw(offset: Vec2i, z: Int, consumer: GUIVertexConsumer) {} open fun postInit() {}
fun tick() { open fun draw(consumer: GUIVertexConsumer) {}
open fun tick() {
layout?.tick() layout?.tick()
} }
} }

View File

@ -14,7 +14,6 @@
package de.bixilon.minosoft.gui.rendering.input.key package de.bixilon.minosoft.gui.rendering.input.key
import de.bixilon.minosoft.Minosoft import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
import de.bixilon.minosoft.config.key.KeyAction import de.bixilon.minosoft.config.key.KeyAction
import de.bixilon.minosoft.config.key.KeyBinding import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.config.key.KeyCodes import de.bixilon.minosoft.config.key.KeyCodes
@ -32,6 +31,7 @@ import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.util.KUtil.decide import de.bixilon.minosoft.util.KUtil.decide
import de.bixilon.minosoft.util.KUtil.toResourceLocation
class RenderWindowInputHandler( class RenderWindowInputHandler(
val renderWindow: RenderWindow, val renderWindow: RenderWindow,
@ -50,7 +50,7 @@ class RenderWindowInputHandler(
val leftClickHandler = LeftClickHandler(renderWindow) val leftClickHandler = LeftClickHandler(renderWindow)
init { init {
registerKeyCallback(KeyBindingsNames.DEBUG_MOUSE_CATCH, KeyBinding( registerKeyCallback("minosoft:debug_mouse_catch".toResourceLocation(), KeyBinding(
mutableMapOf( mutableMapOf(
KeyAction.MODIFIER to mutableSetOf(KeyCodes.KEY_F4), KeyAction.MODIFIER to mutableSetOf(KeyCodes.KEY_F4),
KeyAction.STICKY to mutableSetOf(KeyCodes.KEY_M), KeyAction.STICKY to mutableSetOf(KeyCodes.KEY_M),
@ -142,11 +142,7 @@ class RenderWindowInputHandler(
checksRun++ checksRun++
} }
fun checkSticky(keys: MutableSet<KeyCodes>, invert: Boolean) { fun checkSticky(keys: MutableSet<KeyCodes>) {
var alreadyActive = keyBindingsDown.contains(resourceLocation)
if (invert) {
alreadyActive = !alreadyActive
}
checksRun++ checksRun++
if (!keys.contains(keyCode)) { if (!keys.contains(keyCode)) {
thisIsChange = false thisIsChange = false
@ -156,15 +152,15 @@ class RenderWindowInputHandler(
thisIsChange = false thisIsChange = false
return return
} }
thisKeyBindingDown = !alreadyActive thisKeyBindingDown = !keyBindingsDown.contains(resourceLocation)
} }
pair.keyBinding.action[KeyAction.STICKY]?.let { pair.keyBinding.action[KeyAction.STICKY]?.let {
checkSticky(it, false) checkSticky(it)
} }
pair.keyBinding.action[KeyAction.STICKY_INVERTED]?.let { pair.keyBinding.action[KeyAction.STICKY_INVERTED]?.let {
checkSticky(it, true) checkSticky(it)
} }
pair.keyBinding.action[KeyAction.DOUBLE_PRESS]?.let { pair.keyBinding.action[KeyAction.DOUBLE_PRESS]?.let {
@ -239,6 +235,13 @@ class RenderWindowInputHandler(
callback(it) callback(it)
} }
} }
// Instant fire
if (keyBinding.action.containsKey(KeyAction.STICKY)) {
callback(false)
} else if (keyBinding.action.containsKey(KeyAction.STICKY_INVERTED)) {
keyBindingsDown += resourceLocation
callback(true)
}
} }
fun registerCheckCallback(vararg checks: Pair<ResourceLocation, KeyBinding>) { fun registerCheckCallback(vararg checks: Pair<ResourceLocation, KeyBinding>) {