diff --git a/src/main/kotlin/gay/j10a1n15/sillygames/config/Config.kt b/src/main/kotlin/gay/j10a1n15/sillygames/config/Config.kt index ee1a804..c400b4f 100644 --- a/src/main/kotlin/gay/j10a1n15/sillygames/config/Config.kt +++ b/src/main/kotlin/gay/j10a1n15/sillygames/config/Config.kt @@ -1,12 +1,18 @@ package gay.j10a1n15.sillygames.config -import gay.j10a1n15.sillygames.utils.essentials.InfoProperty +import gay.j10a1n15.sillygames.utils.essentials.info.InfoProperty +import gay.j10a1n15.sillygames.utils.essentials.keybind.KeybindProperty import gg.essential.vigilance.Vigilant import gg.essential.vigilance.data.Property import gg.essential.vigilance.data.PropertyType import java.io.File object Config : Vigilant(File("./config/sillygames.toml")) { + /** + * -------------------------------------------------- + * | About | + * -------------------------------------------------- + */ @Property( type = PropertyType.CUSTOM, name = "Information", @@ -17,6 +23,104 @@ object Config : Vigilant(File("./config/sillygames.toml")) { @Suppress("unused") var informationAbout = "" + + /** + * -------------------------------------------------- + * | Keybinds | + * -------------------------------------------------- + */ + + @Property( + type = PropertyType.CUSTOM, + name = "Keybind Information", + description = "Primary and Secondary Keybinds work if you have a silly game as fullscreen.\n" + + "Secondary Keybinds are for when you have a game in Picture in Picture mode.", + category = "Keybinds", + customPropertyInfo = InfoProperty::class, + ) + @Suppress("unused") + var keybindInformation = "" + + @Property( + type = PropertyType.CUSTOM, + name = "Keybind Up", + description = "Keybinds for Silly Games.", + category = "Keybinds", + subcategory = "Primary", + customPropertyInfo = KeybindProperty::class, + ) + var keybindUp = 17 + + @Property( + type = PropertyType.CUSTOM, + name = "Keybind Down", + description = "Keybinds for Silly Games.", + category = "Keybinds", + subcategory = "Primary", + customPropertyInfo = KeybindProperty::class, + ) + var keybindDown: Int = 31 + + @Property( + type = PropertyType.CUSTOM, + name = "Keybind Left", + description = "Keybinds for Silly Games.", + category = "Keybinds", + subcategory = "Primary", + customPropertyInfo = KeybindProperty::class, + ) + var keybindLeft = 30 + + @Property( + type = PropertyType.CUSTOM, + name = "Keybind Right", + description = "Keybinds for Silly Games.", + category = "Keybinds", + subcategory = "Primary", + customPropertyInfo = KeybindProperty::class, + ) + var keybindRight = 32 + + @Property( + type = PropertyType.CUSTOM, + name = "Keybind Up", + description = "Keybinds for Silly Games.", + category = "Keybinds", + subcategory = "Secondary", + customPropertyInfo = KeybindProperty::class, + ) + var keybindUpSecondary: Int = 200 + + @Property( + type = PropertyType.CUSTOM, + name = "Keybind Down", + description = "Keybinds for Silly Games.", + category = "Keybinds", + subcategory = "Secondary", + customPropertyInfo = KeybindProperty::class, + ) + var keybindDownSecondary = 208 + + @Property( + type = PropertyType.CUSTOM, + name = "Keybind Left", + description = "Keybinds for Silly Games.", + category = "Keybinds", + subcategory = "Secondary", + customPropertyInfo = KeybindProperty::class, + ) + var keybindLeftSecondary = 203 + + @Property( + type = PropertyType.CUSTOM, + name = "Keybind Right", + description = "Keybinds for Silly Games.", + category = "Keybinds", + subcategory = "Secondary", + customPropertyInfo = KeybindProperty::class, + ) + var keybindRightSecondary = 205 + init { initialize() diff --git a/src/main/kotlin/gay/j10a1n15/sillygames/data/KeybindSet.kt b/src/main/kotlin/gay/j10a1n15/sillygames/data/KeybindSet.kt new file mode 100644 index 0000000..2081ac6 --- /dev/null +++ b/src/main/kotlin/gay/j10a1n15/sillygames/data/KeybindSet.kt @@ -0,0 +1,31 @@ +package gay.j10a1n15.sillygames.data + +import gay.j10a1n15.sillygames.SillyGames +import gay.j10a1n15.sillygames.utils.Vector2d + +class KeybindSet( + val keybindUp: Int, + val keybindDown: Int, + val keybindLeft: Int, + val keybindRight: Int, +) { + + fun getDirection(key: Int): Vector2d? { + return when (key) { + keybindUp -> Vector2d(0, -1) + keybindDown -> Vector2d(0, 1) + keybindLeft -> Vector2d(-1, 0) + keybindRight -> Vector2d(1, 0) + else -> null + } + } + + companion object { + private val config get() = SillyGames.config + + fun configPrimary() = KeybindSet(config.keybindUp, config.keybindDown, config.keybindLeft, config.keybindRight) + + fun configSecondary() = + KeybindSet(config.keybindUpSecondary, config.keybindDownSecondary, config.keybindLeftSecondary, config.keybindRightSecondary) + } +} diff --git a/src/main/kotlin/gay/j10a1n15/sillygames/events/EventHandler.kt b/src/main/kotlin/gay/j10a1n15/sillygames/events/EventHandler.kt index e191a8d..182e4cd 100644 --- a/src/main/kotlin/gay/j10a1n15/sillygames/events/EventHandler.kt +++ b/src/main/kotlin/gay/j10a1n15/sillygames/events/EventHandler.kt @@ -38,10 +38,12 @@ object EventHandler { } @SubscribeEvent - fun onKeyPressed(event: GuiScreenEvent.KeyboardInputEvent.Post) { + fun onKeyPressed(event: GuiScreenEvent.KeyboardInputEvent.Pre) { if (Keyboard.getEventKeyState() && Keyboard.getEventKey() != 0) { val key = Keyboard.getEventKey() - Events.KEYBOARD_DOWN.post(key) + if (Events.KEYBOARD_DOWN.post(key)) { + event.isCanceled = true + } } } } diff --git a/src/main/kotlin/gay/j10a1n15/sillygames/events/Events.kt b/src/main/kotlin/gay/j10a1n15/sillygames/events/Events.kt index 0a450c5..eeae222 100644 --- a/src/main/kotlin/gay/j10a1n15/sillygames/events/Events.kt +++ b/src/main/kotlin/gay/j10a1n15/sillygames/events/Events.kt @@ -6,7 +6,7 @@ object Events { val RENDER = EventType() val TICK = EventType() val KEYBOARD = EventType() - val KEYBOARD_DOWN = EventType() + val KEYBOARD_DOWN = CancellableEventType() } class EventType { @@ -20,5 +20,23 @@ class EventType { fun post(event: T) { listeners.forEach { it(event) } } +} + +class CancellableEventType { + private val listeners = mutableListOf<(T) -> Boolean>() + + fun register(listener: (T) -> Boolean) { + listeners.add(listener) + } + + fun post(event: T): Boolean { + var cancelled = false + listeners.forEach { + if (it(event)) { + cancelled = true + } + } + return cancelled + } } diff --git a/src/main/kotlin/gay/j10a1n15/sillygames/games/Game.kt b/src/main/kotlin/gay/j10a1n15/sillygames/games/Game.kt index 9e850db..0f5e6a6 100644 --- a/src/main/kotlin/gay/j10a1n15/sillygames/games/Game.kt +++ b/src/main/kotlin/gay/j10a1n15/sillygames/games/Game.kt @@ -11,7 +11,9 @@ abstract class Game { open fun onKeyHeld(key: Int) {} - open fun onKeyPressed(key: Int) {} + open fun onKeyPressed(key: Int): Boolean { + return false + } open val supportsPictureInPicture = false } diff --git a/src/main/kotlin/gay/j10a1n15/sillygames/games/GameManager.kt b/src/main/kotlin/gay/j10a1n15/sillygames/games/GameManager.kt index 8deb894..2eff4c3 100644 --- a/src/main/kotlin/gay/j10a1n15/sillygames/games/GameManager.kt +++ b/src/main/kotlin/gay/j10a1n15/sillygames/games/GameManager.kt @@ -9,6 +9,6 @@ object GameManager { init { Events.TICK.register { game?.onTick() } Events.KEYBOARD.register { game?.onKeyHeld(it) } - Events.KEYBOARD_DOWN.register { game?.onKeyPressed(it) } + Events.KEYBOARD_DOWN.register { game?.onKeyPressed(it) ?: false } } } diff --git a/src/main/kotlin/gay/j10a1n15/sillygames/games/Snake.kt b/src/main/kotlin/gay/j10a1n15/sillygames/games/Snake.kt index dd20b3f..ffc20e3 100644 --- a/src/main/kotlin/gay/j10a1n15/sillygames/games/Snake.kt +++ b/src/main/kotlin/gay/j10a1n15/sillygames/games/Snake.kt @@ -1,5 +1,6 @@ package gay.j10a1n15.sillygames.games +import gay.j10a1n15.sillygames.data.KeybindSet import gay.j10a1n15.sillygames.rpc.RpcInfo import gay.j10a1n15.sillygames.rpc.RpcProvider import gay.j10a1n15.sillygames.utils.Vector2d @@ -17,7 +18,6 @@ import gg.essential.elementa.dsl.constrain import gg.essential.elementa.dsl.constraint import gg.essential.elementa.dsl.percent import gg.essential.elementa.dsl.plus -import gg.essential.universal.UKeyboard import java.awt.Color class Snake : Game(), RpcProvider { @@ -68,13 +68,8 @@ class Snake : Game(), RpcProvider { override fun onKeyHeld(key: Int) { if (gameOver) return - val newDirection = when (key) { - UKeyboard.KEY_W -> Vector2d(0, -1) - UKeyboard.KEY_S -> Vector2d(0, 1) - UKeyboard.KEY_A -> Vector2d(-1, 0) - UKeyboard.KEY_D -> Vector2d(1, 0) - else -> return - } + // TODO: If in PIP, only use secondary keybinds + val newDirection = KeybindSet.configPrimary().getDirection(key) ?: KeybindSet.configSecondary().getDirection(key) ?: return if (newDirection + direction == Vector2d(0, 0)) return direction = newDirection diff --git a/src/main/kotlin/gay/j10a1n15/sillygames/games/wordle/Wordle.kt b/src/main/kotlin/gay/j10a1n15/sillygames/games/wordle/Wordle.kt index 6c1fb02..d0b17f2 100644 --- a/src/main/kotlin/gay/j10a1n15/sillygames/games/wordle/Wordle.kt +++ b/src/main/kotlin/gay/j10a1n15/sillygames/games/wordle/Wordle.kt @@ -255,12 +255,13 @@ class Wordle : Game(), RpcProvider { this.time = System.currentTimeMillis() } - override fun onKeyPressed(key: Int) { - if (wordIndexInput.hasFocus()) return + override fun onKeyPressed(key: Int): Boolean { + if (wordIndexInput.hasFocus()) return false when (key) { UKeyboard.KEY_ENTER -> guess() else -> state.keyPress(key) } + return false } override fun onTick() { diff --git a/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/InfoProperty.kt b/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/info/InfoProperty.kt similarity index 85% rename from src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/InfoProperty.kt rename to src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/info/InfoProperty.kt index 7a2df92..3055340 100644 --- a/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/InfoProperty.kt +++ b/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/info/InfoProperty.kt @@ -1,4 +1,4 @@ -package gay.j10a1n15.sillygames.utils.essentials +package gay.j10a1n15.sillygames.utils.essentials.info import gg.essential.vigilance.data.PropertyInfo import gg.essential.vigilance.gui.settings.SettingComponent diff --git a/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/InfoPropertyComponent.kt b/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/info/InfoPropertyComponent.kt similarity index 67% rename from src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/InfoPropertyComponent.kt rename to src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/info/InfoPropertyComponent.kt index aeebe7c..9fba8a6 100644 --- a/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/InfoPropertyComponent.kt +++ b/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/info/InfoPropertyComponent.kt @@ -1,4 +1,4 @@ -package gay.j10a1n15.sillygames.utils.essentials +package gay.j10a1n15.sillygames.utils.essentials.info import gg.essential.vigilance.gui.settings.SettingComponent diff --git a/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/keybind/KeybindProperty.kt b/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/keybind/KeybindProperty.kt new file mode 100644 index 0000000..442874b --- /dev/null +++ b/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/keybind/KeybindProperty.kt @@ -0,0 +1,10 @@ +package gay.j10a1n15.sillygames.utils.essentials.keybind + +import gg.essential.vigilance.data.PropertyInfo +import gg.essential.vigilance.gui.settings.SettingComponent + +class KeybindProperty : PropertyInfo() { + override fun createSettingComponent(initialValue: Any?): SettingComponent { + return KeybindPropertyComponent(initialValue as Int) + } +} diff --git a/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/keybind/KeybindPropertyComponent.kt b/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/keybind/KeybindPropertyComponent.kt new file mode 100644 index 0000000..eb2c49b --- /dev/null +++ b/src/main/kotlin/gay/j10a1n15/sillygames/utils/essentials/keybind/KeybindPropertyComponent.kt @@ -0,0 +1,74 @@ +package gay.j10a1n15.sillygames.utils.essentials.keybind + +import gay.j10a1n15.sillygames.events.Events +import gg.essential.elementa.components.UIBlock +import gg.essential.elementa.components.UIText +import gg.essential.elementa.constraints.CenterConstraint +import gg.essential.elementa.dsl.childOf +import gg.essential.elementa.dsl.constrain +import gg.essential.elementa.dsl.pixels +import gg.essential.elementa.dsl.toConstraint +import gg.essential.elementa.utils.withAlpha +import gg.essential.vigilance.gui.DataBackedSetting +import gg.essential.vigilance.gui.settings.SettingComponent +import org.lwjgl.input.Keyboard +import java.awt.Color + +class KeybindPropertyComponent(initialValue: Int) : SettingComponent() { + + private var listeningForKey = false + private var currentKey: Int = initialValue + private val keyDisplay: UIText + private val container: UIBlock + + init { + container = UIBlock().constrain { + x = (DataBackedSetting.INNER_PADDING + 10f).pixels(alignOpposite = true) + y = CenterConstraint() + width = 100.pixels() + height = 20.pixels() + color = Color.BLACK.withAlpha(0.25f).toConstraint() + }.onMouseEnter { + startListeningForKey() + }.onMouseLeave { + stopListeningForKey() + } as UIBlock childOf this + + keyDisplay = UIText(getKeyName(currentKey)).constrain { + x = CenterConstraint() + y = CenterConstraint() + } childOf container + + + Events.KEYBOARD_DOWN.register { onKeyTyped(it) } + } + + private fun startListeningForKey() { + listeningForKey = true + keyDisplay.setText("Press a key...") + } + + private fun onKeyTyped(keyCode: Int): Boolean { + if (listeningForKey && keyCode != Keyboard.KEY_NONE) { + setKeybind(keyCode) + stopListeningForKey() + return true + } + return false + } + + private fun setKeybind(keyCode: Int) { + currentKey = keyCode + keyDisplay.setText(getKeyName(keyCode)) + changeValue(currentKey) + } + + private fun stopListeningForKey() { + listeningForKey = false + keyDisplay.setText(getKeyName(currentKey)) + } + + private fun getKeyName(keyCode: Int): String { + return Keyboard.getKeyName(keyCode) ?: "None" + } +}