aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/utils/CombatUtils.kt
blob: b58aba42eb451c78e24f090a284e7ac58dca29cb (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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package at.hannibal2.skyhanni.utils

import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostCounter
import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostData
import at.hannibal2.skyhanni.mixins.transformers.MixinXPInformation
import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils
import io.github.moulberry.notenoughupdates.util.XPInformation

object CombatUtils {

    private var lastTotalXp = -1f
    private val xpGainQueue = mutableListOf<Float>()
    private var xpGainTimer = 0
    var lastUpdate: Long = -1
    private var skillInfo: XPInformation.SkillInfo? = null
    private var skillInfoLast: XPInformation.SkillInfo? = null
    private const val SKILL_TYPE = "Combat"
    var xpGainHourLast = -1f
    var xpGainHour = -1f
    var isKilling = false
    private var lastTotalKill = -1
    private val killGainQueue = mutableListOf<Int>()
    var lastKillUpdate: Long = -1
    var killGainHourLast = -1
    var killGainHour = -1
    private var gainTimer = 0

    // Todo: Why do we have two isKilling variables?
    @Suppress("ObjectPropertyNaming")
    var _isKilling = false

    private fun getSkillInfo(xpInformation: XPInformation.SkillInfo?): Float {
        return try {
            val a = xpInformation as? MixinXPInformation
            a!!.getTotalXp().toFloat()
        } catch (e: Error) {
            val xpInfo = xpInformation ?: return -1f
            xpInfo.totalXp
        }
    }

    /**
     * Taken from NotEnoughUpdates
     */
    fun calculateXP() {
        lastUpdate = System.currentTimeMillis()
        xpGainHourLast = xpGainHour
        skillInfoLast = skillInfo
        skillInfo = XPInformation.getInstance().getSkillInfo(SKILL_TYPE) ?: return
        val totalXp = getSkillInfo(skillInfo)
        if (lastTotalXp > 0) {
            val delta: Float = totalXp - lastTotalXp

            when {
                delta > 0 && delta < 1000 -> {
                    xpGainTimer = GhostCounter.config.pauseTimer
                    xpGainQueue.add(0, delta)
                    calculateXPHour()
                }

                xpGainTimer > 0 -> {
                    xpGainTimer--
                    xpGainQueue.add(0, 0f)
                    calculateXPHour()
                }

                delta <= 0 -> {
                    isKilling = false
                }
            }
        }
        lastTotalXp = totalXp
    }

    private fun calculateXPHour() {
        while (xpGainQueue.size > 30) {
            xpGainQueue.removeLast()
        }
        var totalGain = 0f
        for (f in xpGainQueue) totalGain += f
        xpGainHour = totalGain * (60 * 60) / xpGainQueue.size
        isKilling = true
    }

    fun calculateETA() {
        lastKillUpdate = System.currentTimeMillis()
        killGainHourLast = killGainHour

        GhostCounter.storage?.bestiaryNextLevel?.toInt()?.let { nextLevel ->
            GhostCounter.storage?.bestiaryCurrentKill?.toInt()?.let { kill ->
                val sum = GhostData.bestiaryData.filterKeys { it <= nextLevel - 1 }.values.sum()
                val cKill = sum + kill
                val totalKill = if (GhostCounter.config.showMax) GhostCounter.bestiaryCurrentKill else cKill

                if (lastTotalKill > 0) {
                    val delta: Int = totalKill - lastTotalKill
                    if (delta in 1..10 || gainTimer > 0) {
                        gainTimer = maxOf(gainTimer - 1, 0)
                        killGainQueue.add(0, delta)
                        while (killGainQueue.size > 30) {
                            killGainQueue.removeLast()
                        }

                        val totalGain = killGainQueue.sum()
                        killGainHour = totalGain * 3600 / killGainQueue.size
                        _isKilling = true
                    } else if (delta <= 0) {
                        _isKilling = false
                    }
                }
                lastTotalKill = totalKill
            }
        }
    }

    /**
     * Taken from NotEnoughUpdates
     */
    fun interp(now: Float, last: Float, lastUpdate: Long): Float {
        var interp = now
        if (last >= 0 && last != now) {
            var factor = (System.currentTimeMillis() - lastUpdate) / 1000f
            factor = LerpUtils.clampZeroOne(factor)
            interp = last + (now - last) * factor
        }
        return interp
    }
}