1+ /*
2+ * Skytils - Hypixel Skyblock Quality of Life Mod
3+ * Copyright (C) 2020-2023 Skytils
4+ *
5+ * This program is free software: you can redistribute it and/or modify
6+ * it under the terms of the GNU Affero General Public License as published
7+ * by the Free Software Foundation, either version 3 of the License, or
8+ * (at your option) any later version.
9+ *
10+ * This program is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU Affero General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU Affero General Public License
16+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
17+ */
18+ package gg.skytils.skytilsmod.utils.graphics.colors
19+
20+ import gg.skytils.skytilsmod.utils.bindColor
21+ import java.awt.Color
22+ import kotlin.math.min
23+
24+ class CyclingTwoColorGradient (var color1 : Color , var color2 : Color , var speed : Double , var offset : Double ) : CustomColor() {
25+
26+ fun getCurrentColor (): Color {
27+ var p = (System .currentTimeMillis() + offset) / speed
28+
29+ if (p > 1 ) {
30+ val decimal = p % 1
31+ val whole = p.toInt()
32+ p = if (whole % 2 == 0 ) decimal else (1 - decimal)
33+ }
34+
35+ return getGradient(p)
36+ }
37+
38+ fun getGradient (p : Double ): Color {
39+ val complement = 1 - p
40+ val r = (color1.red * p + color2.red * complement).toInt()
41+ val g = (color1.green * p + color2.green * complement).toInt()
42+ val b = (color1.blue * p + color2.blue * complement).toInt()
43+ val a = (color1.alpha * p + color2.alpha * complement).toInt()
44+
45+ return Color (r, g, b, a)
46+ }
47+
48+ override fun applyColor () = getCurrentColor().bindColor()
49+
50+ override fun toHSV (): FloatArray {
51+ val color = getCurrentColor()
52+ val r = color.red.toFloat()
53+ val g = color.blue.toFloat()
54+ val b = color.blue.toFloat()
55+ val a = color.alpha.toFloat()
56+ var hue: Float
57+ val saturation: Float
58+ val value: Float
59+ val cmax = r.coerceAtLeast(g).coerceAtLeast(b)
60+ val cmin = min(r.coerceAtMost(g), b)
61+ value = cmax
62+ saturation = if (cmax == 0f ) 0F else (cmax - cmin) / cmax
63+ if (saturation == 0f ) {
64+ hue = 0f
65+ } else {
66+ val redc = (cmax - r) / (cmax - cmin)
67+ val greenc = (cmax - g) / (cmax - cmin)
68+ val bluec = (cmax - b) / (cmax - cmin)
69+ hue = when {
70+ r == cmax -> {
71+ bluec - greenc
72+ }
73+ g == cmax -> {
74+ 2.0f + redc - bluec
75+ }
76+ else -> {
77+ 4.0f + greenc - redc
78+ }
79+ }
80+ hue / = 6.0f
81+ if (hue < 0 ) {
82+ hue + = 1.0f
83+ }
84+ }
85+ return floatArrayOf(hue, saturation, value, a)
86+ }
87+
88+ override fun toInt (): Int {
89+ return getCurrentColor().rgb
90+ }
91+
92+ override fun toString (): String {
93+ return " cyclingtwocolorgradient(${color1.rgb} ,${color2.rgb} ,$speed ,$offset )"
94+ }
95+
96+ override fun equals (other : Any? ): Boolean {
97+ if (this == = other) return true
98+ if (other is CyclingTwoColorGradient ) {
99+ return speed == other.speed && color1 == other.color1 && color2 == other.color2 && offset == other.offset
100+ }
101+ return false
102+ }
103+
104+ override fun hashCode (): Int {
105+ return doubleArrayOf(color1.rgb.toDouble(), color2.rgb.toDouble(), speed).contentHashCode()
106+ }
107+
108+ companion object {
109+ @JvmStatic
110+ fun fromString (string : String? ): CyclingTwoColorGradient {
111+ if (string == null ) throw NullPointerException (" Argument cannot be null!" )
112+ require(string.startsWith(" cyclingtwocolorgradient(" ) && string.endsWith(" )" )) { " Invalid cycling two color gradient format" }
113+ return try {
114+ val split = string.substringAfter(" cyclingtwocolorgradient(" ).substringBeforeLast(' )' ).split(" ," )
115+ val color1 = Color (split[0 ].toInt(), true )
116+ val color2 = Color (split[1 ].toInt(), true )
117+ val speed = split[2 ].toDouble()
118+ val offset = split[3 ].toDouble()
119+ CyclingTwoColorGradient (color1, color2, speed, offset)
120+ } catch (exception: NumberFormatException ) {
121+ throw IllegalArgumentException (" Invalid cycling two color gradient string" )
122+ } catch (exception: IndexOutOfBoundsException ) {
123+ throw IllegalArgumentException (" Invalid cycling two color gradient string" )
124+ }
125+ }
126+ }
127+ }
0 commit comments