aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCustomKeybinds.kt
blob: 4e24cf988088b3fc936fa8a0c0ace9b8f21cac1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package at.hannibal2.skyhanni.features.garden

import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.features.Garden
import at.hannibal2.skyhanni.events.GardenToolChangeEvent
import at.hannibal2.skyhanni.mixins.transformers.AccessorKeyBinding
import io.github.moulberry.moulconfig.internal.KeybindHelper
import net.minecraft.client.Minecraft
import net.minecraft.client.settings.KeyBinding
import net.minecraftforge.event.world.WorldEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent

class GardenCustomKeybinds {
    private val shConfig: Garden get() = SkyHanniMod.feature.garden
    private val mcSettings get() = Minecraft.getMinecraft().gameSettings

    private val cache = mutableMapOf<KeyBinding, Int>()
    private val map = mutableMapOf<KeyBinding, () -> Int>()

    init {
        map[mcSettings.keyBindAttack] = { shConfig.keyBindAttack }
        map[mcSettings.keyBindLeft] = { shConfig.keyBindLeft }
        map[mcSettings.keyBindRight] = { shConfig.keyBindRight }
        map[mcSettings.keyBindForward] = { shConfig.keyBindForward }
        map[mcSettings.keyBindBack] = { shConfig.keyBindBack }
        map[mcSettings.keyBindJump] = { shConfig.keyBindJump }
        map[mcSettings.keyBindSneak] = { shConfig.keyBindSneak }

        Runtime.getRuntime().addShutdownHook(Thread { reset() })
    }

    @SubscribeEvent
    fun onGardenToolChange(event: GardenToolChangeEvent) {
        update()
    }

    private fun update() {
        if (isEnabled() && GardenAPI.toolInHand != null) {
            applyCustomKeybinds()
        } else {
            reset()
        }
    }

    @SubscribeEvent
    fun onWorldChange(event: WorldEvent.Load) {
        reset()
    }

    private fun applyCustomKeybinds() {
        val alreadyBoundedKeys = mutableListOf<Int>()
        var counter = 0
        for ((mcBinding, skyHanniBinding) in map) {
            val newKeyCode = skyHanniBinding()
            if (newKeyCode == mcBinding.keyCode) continue

            disableAlreadyExistingKeybinds(newKeyCode, alreadyBoundedKeys)

            if (!cache.containsKey(mcBinding)) {
                cache[mcBinding] = mcBinding.keyCode
                mcBinding.unpressKeyIfDown()
            }

            mcBinding.keyCode = newKeyCode
            alreadyBoundedKeys.add(mcBinding.keyCodeDefault)
            counter++
        }

        if (counter > 0) {
            KeyBinding.resetKeyBindingArrayAndHash()
        }
    }

    private fun disableAlreadyExistingKeybinds(newKeyCode: Int, alreadyBoundedKeys: MutableList<Int>) {
        if (newKeyCode == 0) return
        for (keyBinding in mcSettings.keyBindings) {
            if (keyBinding.keyCode != newKeyCode) continue
            if (alreadyBoundedKeys.contains(keyBinding.keyCodeDefault)) continue
            keyBinding.unpressKeyIfDown()
            cache[keyBinding] = keyBinding.keyCode
            keyBinding.keyCode = 0
        }
    }

    private fun reset() {
        var counter = 0
        for ((key, keyCode) in cache) {
            if (key.keyCode != keyCode) {
                key.unpressKeyIfDown()
                counter++
                key.keyCode = keyCode
            }
        }
        cache.clear()
        if (counter > 0) {
            KeyBinding.resetKeyBindingArrayAndHash()
        }
    }

    private fun KeyBinding.unpressKeyIfDown() {
        if (KeybindHelper.isKeyDown(keyCode)) {
            (this as AccessorKeyBinding).skyhanni_unpressKey()
        }
    }

    private fun isEnabled() = GardenAPI.inGarden() && shConfig.keyBindEnabled
}