From 5693ca266e68bbe692949dd8f821108911ba8a33 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 13 Jan 2023 16:35:33 +0700 Subject: [PATCH] Mattery atlas, update all atlas assets --- .../dbotthepony/mc/otm/client/MatteryGUI.kt | 2 +- .../client/render/AbstractMatterySprite.kt | 87 ++++++++++++++++++ .../otm/client/render/DynamicBufferSource.kt | 9 +- .../mc/otm/client/render/MatteryAtlas.kt | 24 +++++ .../mc/otm/client/render/MatterySprite.kt | 21 +++-- .../mc/otm/client/render/ResearchIcons.kt | 2 +- .../mc/otm/client/render/SkinElementType.kt | 43 +-------- .../mc/otm/client/render/SkinGrid.kt | 8 +- .../mc/otm/client/render/SubMatterySprite.kt | 33 +------ .../mc/otm/client/render/WidgetLocation.kt | 12 +-- .../mc/otm/client/render/Widgets.kt | 8 +- .../mc/otm/client/render/Widgets18.kt | 18 ++-- .../mc/otm/client/render/Widgets8.kt | 2 +- .../client/render/blockentity/BankRenderer.kt | 2 +- .../screen/panels/ScrollBarConstants.kt | 24 +++-- .../screen/panels/buttons/CheckBoxPanel.kt | 2 +- .../textures/gui/android_upgrades.png | Bin 2792 -> 2551 bytes .../textures/gui/player_bars.png | Bin 348 -> 287 bytes .../textures/gui/widgets/checkbox.png | Bin 838 -> 817 bytes .../gui/widgets/horizontal_gauges.png | Bin 277 -> 326 bytes .../gui/widgets/pattern_panel_tabs.png | Bin 366 -> 481 bytes .../textures/gui/widgets/progress_arrows.png | Bin 275 -> 291 bytes .../textures/gui/widgets/scrollbar.png | Bin 0 -> 330 bytes .../gui/widgets/scrollbar/background.png | Bin 165 -> 0 bytes .../gui/widgets/scrollbar/disabled.png | Bin 367 -> 0 bytes .../gui/widgets/scrollbar/hovered.png | Bin 373 -> 0 bytes .../textures/gui/widgets/scrollbar/idle.png | Bin 371 -> 0 bytes .../gui/widgets/scrollbar/pressed.png | Bin 373 -> 0 bytes .../textures/gui/widgets/scrollbar_slim.png | Bin 0 -> 322 bytes .../gui/widgets/scrollbar_slim/background.png | Bin 357 -> 0 bytes .../gui/widgets/scrollbar_slim/disabled.png | Bin 398 -> 0 bytes .../gui/widgets/scrollbar_slim/hovered.png | Bin 404 -> 0 bytes .../gui/widgets/scrollbar_slim/idle.png | Bin 403 -> 0 bytes .../gui/widgets/scrollbar_slim/pressed.png | Bin 404 -> 0 bytes .../textures/gui/widgets/vertical_gauges.png | Bin 494 -> 887 bytes 35 files changed, 179 insertions(+), 118 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatteryAtlas.kt create mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar.png delete mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/background.png delete mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/disabled.png delete mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/hovered.png delete mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/idle.png delete mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/pressed.png create mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim.png delete mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/background.png delete mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/disabled.png delete mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/hovered.png delete mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/idle.png delete mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/pressed.png diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt index 830d1e3da..a7f6ddbfc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt @@ -28,7 +28,7 @@ import java.util.* import kotlin.math.ceil object MatteryGUI { - private val BARS = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "player_bars"), 80f, 36f) + private val BARS = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/player_bars.png"), 80f, 35f) val CHARGE = BARS.subElement(height = 9f) val CHARGE_BG = BARS.subElement(y = 9f, height = 9f) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/AbstractMatterySprite.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/AbstractMatterySprite.kt index af06604b7..02435dc3e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/AbstractMatterySprite.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/AbstractMatterySprite.kt @@ -2,13 +2,20 @@ package ru.dbotthepony.mc.otm.client.render import com.google.gson.JsonObject import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.PoseStack import com.mojang.blaze3d.vertex.VertexConsumer +import com.mojang.blaze3d.vertex.VertexFormat +import net.minecraft.client.renderer.GameRenderer +import net.minecraft.client.renderer.RenderStateShard +import net.minecraft.client.renderer.RenderType import net.minecraft.network.FriendlyByteBuf import net.minecraft.resources.ResourceLocation +import org.lwjgl.opengl.GL11.GL_ALWAYS import ru.dbotthepony.mc.otm.core.RGBAColor import ru.dbotthepony.mc.otm.core.linearInterpolation import java.lang.ref.WeakReference +import java.util.concurrent.ConcurrentHashMap sealed class AbstractMatterySprite { /** @@ -305,4 +312,84 @@ sealed class AbstractMatterySprite { fun toNetwork(buff: FriendlyByteBuf) { type.toActualNetwork(this, buff) } + + + val renderTypeNoDepth by lazy { + noDepthCache.computeIfAbsent(texture) { + val builder = RenderType.CompositeState.builder() + + builder.setTextureState(RenderStateShard.TextureStateShard(it, false, false)) + builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionColorTexShader)) + builder.setDepthTestState(RenderStateShard.DepthTestStateShard("always", GL_ALWAYS)) + builder.setTransparencyState(RenderStateShard.TransparencyStateShard("normal_blend", { + RenderSystem.enableBlend() + RenderSystem.defaultBlendFunc() + }, { + RenderSystem.disableBlend() + })) + + @Suppress("INACCESSIBLE_TYPE") + RenderType.create("otm_gui_element_no_depth", + DefaultVertexFormat.POSITION_COLOR_TEX, + VertexFormat.Mode.QUADS, + 2048, + false, + false, + builder.createCompositeState(false)) as RenderType + } + } + + val renderTypeDepth by lazy { + depthCache.computeIfAbsent(texture) { + val builder = RenderType.CompositeState.builder() + + builder.setTextureState(RenderStateShard.TextureStateShard(it, false, false)) + builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionColorTexShader)) + builder.setTransparencyState(RenderStateShard.TransparencyStateShard("normal_blend", { + RenderSystem.enableBlend() + RenderSystem.defaultBlendFunc() + }, { + RenderSystem.disableBlend() + })) + + @Suppress("INACCESSIBLE_TYPE") + RenderType.create("otm_gui_element_depth", + DefaultVertexFormat.POSITION_COLOR_TEX, + VertexFormat.Mode.QUADS, + 2048, + false, + false, + builder.createCompositeState(false)) as RenderType + } + } + + val renderTypeWorld by lazy { + worldCache.computeIfAbsent(texture) { + val builder = RenderType.CompositeState.builder() + + builder.setTextureState(RenderStateShard.TextureStateShard(it, false, false)) + builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionColorTexShader)) + builder.setTransparencyState(RenderStateShard.TransparencyStateShard("normal_blend", { + RenderSystem.enableBlend() + RenderSystem.defaultBlendFunc() + }, { + RenderSystem.disableBlend() + })) + + @Suppress("INACCESSIBLE_TYPE") + RenderType.create("otm_gui_element_world", + DefaultVertexFormat.POSITION_COLOR_TEX, + VertexFormat.Mode.QUADS, + 8192, + false, + false, + builder.createCompositeState(false)) as RenderType + } + } + + companion object { + private val noDepthCache = ConcurrentHashMap() + private val depthCache = ConcurrentHashMap() + private val worldCache = ConcurrentHashMap() + } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/DynamicBufferSource.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/DynamicBufferSource.kt index 29c5c343d..0e0cfcf88 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/DynamicBufferSource.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/DynamicBufferSource.kt @@ -143,9 +143,12 @@ class DynamicBufferSource(val minimalInitialBufferSize: Int = 0, val maximalInit next = State(RenderType.waterMask(), ImmutableList.of(next.type), true, false) it.add(next) - it.add(State(AtlasMatterySprite.renderTypeDepth, ImmutableList.of(RenderType.waterMask()), true)) - it.add(State(AtlasMatterySprite.renderTypeNoDepth, ImmutableList.of(RenderType.waterMask()), true)) - it.add(State(AtlasMatterySprite.renderTypeWorld, ImmutableList.of(Sheets.signSheet()), true)) + // TODO + // it.add(State(AtlasMatterySprite.renderTypeDepth, ImmutableList.of(RenderType.waterMask()), true)) + // TODO + // it.add(State(AtlasMatterySprite.renderTypeNoDepth, ImmutableList.of(RenderType.waterMask()), true)) + // TODO + // it.add(State(AtlasMatterySprite.renderTypeWorld, ImmutableList.of(Sheets.signSheet()), true)) } private fun determineHeight(input: State, seen: MutableSet) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatteryAtlas.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatteryAtlas.kt new file mode 100644 index 000000000..4a9304fa8 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatteryAtlas.kt @@ -0,0 +1,24 @@ +package ru.dbotthepony.mc.otm.client.render + +import net.minecraft.resources.ResourceLocation + +data class MatteryAtlas( + val texture: ResourceLocation, + val width: Float, + val height: Float, + val winding: UVWindingOrder = UVWindingOrder.NORMAL, +) { + fun subElement( + x: Float = 0f, + y: Float = 0f, + width: Float = this.width, + height: Float = this.height, + winding: UVWindingOrder = this.winding, + ) = MatterySprite(texture, x = x, y = y, width = width, height = height, atlasHeight = this.height, atlasWidth = this.width, winding = winding) + + @Deprecated("Construct grid directly instead") + fun subGrid(rows: Int, columns: Int) = SkinGrid(texture, this.width / rows, this.height / columns, rows = rows, columns = columns) + + @Deprecated("Construct grid directly instead") + fun subGrid(width: Float, height: Float, rows: Int, columns: Int) = SkinGrid(texture, width, height, rows, columns) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatterySprite.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatterySprite.kt index afd08f149..352afb437 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatterySprite.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatterySprite.kt @@ -41,8 +41,8 @@ data class MatterySprite @JvmOverloads constructor( val y: Float, override val width: Float, override val height: Float, - val imageWidth: Float = 256f, - val imageHeight: Float = 256f, + val atlasWidth: Float = 256f, + val atlasHeight: Float = 256f, override val winding: UVWindingOrder = UVWindingOrder.NORMAL, ) : AbstractMatterySprite() { init { @@ -50,18 +50,19 @@ data class MatterySprite @JvmOverloads constructor( require(y >= 0f) { "Invalid y $y" } require(width > 0f) { "Invalid width $width" } require(height > 0f) { "Invalid height $height" } - require(imageWidth > 0f) { "Invalid image width $imageWidth" } - require(imageHeight > 0f) { "Invalid image height $imageHeight" } + require(atlasWidth > 0f) { "Invalid image width $atlasWidth" } + require(atlasHeight > 0f) { "Invalid image height $atlasHeight" } - require(width <= imageWidth) { "$width <= $imageWidth" } - require(height <= imageHeight) { "$height <= $imageHeight" } + require(width <= atlasWidth) { "$width <= $atlasWidth" } + require(height <= atlasHeight) { "$height <= $atlasHeight" } } - override val u0 = this.x / imageWidth - override val v0 = this.y / imageHeight - override val u1 = (this.x + width) / imageWidth - override val v1 = (this.y + height) / imageHeight + override val u0 = this.x / atlasWidth + override val v0 = this.y / atlasHeight + override val u1 = (this.x + width) / atlasWidth + override val v1 = (this.y + height) / atlasHeight override val type: SkinElementType get() = SkinElementType.SINGLE } + diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/ResearchIcons.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/ResearchIcons.kt index c80ea1ee3..8587d4197 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/ResearchIcons.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/ResearchIcons.kt @@ -34,7 +34,7 @@ object ResearchIcons { val KOT = ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/block/ph_kitty.png").element(0f, 0f, 32f, 32f, 32f, 32f) init { - val grid = SubSkinGrid(AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_upgrades"), 126f, 126f), 18f, 18f, 7, 7) + val grid = SkinGrid(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/android_upgrades.png"), 18f, 18f, 7, 7) ICON_TRANSFER = grid.next() ICON_ATTACK_BOOST = grid.next() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SkinElementType.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SkinElementType.kt index 6a729cf7c..a672e32ab 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SkinElementType.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SkinElementType.kt @@ -18,8 +18,8 @@ enum class SkinElementType { it["y"] = JsonPrimitive(value.y) it["width"] = JsonPrimitive(value.width) it["height"] = JsonPrimitive(value.height) - it["imageWidth"] = JsonPrimitive(value.imageWidth) - it["imageHeight"] = JsonPrimitive(value.imageHeight) + it["imageWidth"] = JsonPrimitive(value.atlasWidth) + it["imageHeight"] = JsonPrimitive(value.atlasHeight) it["winding"] = JsonPrimitive(value.winding.name) } } @@ -32,8 +32,8 @@ enum class SkinElementType { buff.writeFloat(value.y) buff.writeFloat(value.width) buff.writeFloat(value.height) - buff.writeFloat(value.imageWidth) - buff.writeFloat(value.imageHeight) + buff.writeFloat(value.atlasWidth) + buff.writeFloat(value.atlasHeight) buff.writeEnum(value.winding) } @@ -63,41 +63,6 @@ enum class SkinElementType { return MatterySprite(ResourceLocation.tryParse(texture) ?: throw JsonSyntaxException("Invalid resource location: $texture"), x, y, width, height, imageWidth, imageHeight, UVWindingOrder.valueOf(winding)) } }, - ATLAS { - override fun toJson(value: AbstractMatterySprite): JsonObject { - require(value is AtlasMatterySprite) { "Invalid skin element provided, expected AtlasSkinElement, got ${value::class.qualifiedName}" } - - return JsonObject().also { - it["location"] = JsonPrimitive(value.location.toString()) - it["width"] = JsonPrimitive(value.width) - it["height"] = JsonPrimitive(value.height) - } - } - - override fun toNetwork(value: AbstractMatterySprite, buff: FriendlyByteBuf) { - require(value is AtlasMatterySprite) { "Invalid skin element provided, expected AtlasSkinElement, got ${value::class.qualifiedName}" } - - buff.writeResourceLocation(value.location) - buff.writeFloat(value.width) - buff.writeFloat(value.height) - } - - override fun fromNetwork(buff: FriendlyByteBuf): AbstractMatterySprite { - val location = ResourceLocation(buff.readUtf()) - val width = buff.readFloat() - val height = buff.readFloat() - - return AtlasMatterySprite(location, width, height) - } - - override fun fromJson(element: JsonObject): AbstractMatterySprite { - val location = element["location"]?.asString ?: throw JsonSyntaxException("Missing location element") - val width = element["width"]?.asFloat ?: throw JsonSyntaxException("Missing width element") - val height = element["height"]?.asFloat ?: throw JsonSyntaxException("Missing height element") - - return AtlasMatterySprite(ResourceLocation.tryParse(location) ?: throw JsonSyntaxException("Invalid resource location: $location"), width, height) - } - }, SUBELEMENT { override fun toJson(value: AbstractMatterySprite): JsonObject { require(value is SubMatterySprite) { "Invalid skin element provided, expected SubSkinElement, got ${value::class.qualifiedName}" } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SkinGrid.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SkinGrid.kt index 7861590dd..f83cb71df 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SkinGrid.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SkinGrid.kt @@ -13,8 +13,8 @@ data class SkinGrid( var row = 0 var column = 0 - val imageWidth get() = width * columns - val imageHeight get() = height * rows + val atlasWidth get() = width * columns + val atlasHeight get() = height * rows val currentX: Float get() = column * width val currentY: Float get() = row * height @@ -36,7 +36,7 @@ data class SkinGrid( } fun next(): MatterySprite { - val element = MatterySprite(texture, currentX, currentY, width, height, imageWidth, imageHeight) + val element = MatterySprite(texture, currentX, currentY, width, height, atlasWidth, atlasHeight) skip() return element } @@ -54,5 +54,5 @@ data class SkinGrid( } operator fun get(column: Int, row: Int) = - MatterySprite(texture, column * width, row * height, width, height, imageWidth, imageHeight) + MatterySprite(texture, column * width, row * height, width, height, atlasWidth, atlasHeight) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SubMatterySprite.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SubMatterySprite.kt index 196317389..08b60e242 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SubMatterySprite.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SubMatterySprite.kt @@ -9,34 +9,11 @@ class SubMatterySprite( override val width: Float = parent.width, override val height: Float = parent.height, private val overrideWinding: UVWindingOrder? = null -) : AbstractMatterySprite.Mutable() { - override var u0: Float = 0f - private set - override var v0: Float = 0f - private set - override var u1: Float = 0f - private set - override var v1: Float = 0f - private set - - private fun calculateUVs() { - u0 = parent.u0 + (xOffset / parent.width) * (parent.u1 - parent.u0) - v0 = parent.v0 + (yOffset / parent.height) * (parent.v1 - parent.v0) - u1 = parent.u0 + ((xOffset + width) / parent.width) * (parent.u1 - parent.u0) - v1 = parent.v0 + ((yOffset + height) / parent.height) * (parent.v1 - parent.v0) - - notifyListeners() - } - - override fun parentChanges(parent: AbstractMatterySprite) = calculateUVs() - - init { - parent.addListener(this) - } - - init { - calculateUVs() - } +) : AbstractMatterySprite() { + override val u0 = parent.u0 + (xOffset / parent.width) * (parent.u1 - parent.u0) + override val v0 = parent.v0 + (yOffset / parent.height) * (parent.v1 - parent.v0) + override val u1 = parent.u0 + ((xOffset + width) / parent.width) * (parent.u1 - parent.u0) + override val v1 = parent.v0 + ((yOffset + height) / parent.height) * (parent.v1 - parent.v0) override val texture: ResourceLocation get() = parent.texture diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/WidgetLocation.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/WidgetLocation.kt index 813924b33..67431c658 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/WidgetLocation.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/WidgetLocation.kt @@ -6,11 +6,11 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters object WidgetLocation { val WIDGETS_18 = ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets_18.png") - val MISC = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/misc"), 64f, 64f) - val PATTERN_PANEL_TABS = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/pattern_panel_tabs"), 64f, 32f) + val MISC = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/misc.png"), 64f, 64f) + val PATTERN_PANEL_TABS = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/pattern_panel_tabs.png"), 64f, 32f) - val CHECKBOX = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/checkbox"), 32f, 64f) - val PROGRESS_ARROWS = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/progress_arrows"), 32f, 32f) - val HORIZONTAL_GAUGES = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/horizontal_gauges"), 128f, 64f) - val VERTICAL_GAUGES = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/vertical_gauges"), 128f, 48f) + val CHECKBOX = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/checkbox.png"), 32f, 64f) + val PROGRESS_ARROWS = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/progress_arrows.png"), 22f, 31f) + val HORIZONTAL_GAUGES = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/horizontal_gauges.png"), 96f, 54f) + val VERTICAL_GAUGES = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/vertical_gauges.png"), 90f, 48f) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets.kt index 0921111a3..3a23df616 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets.kt @@ -8,8 +8,8 @@ object Widgets { val ARROW_UP_BUTTON_PRESSED = WidgetLocation.MISC.subElement(0f, 18f + 6f * 2f, 18f, 6f) val ARROW_UP_BUTTON_DISABLED = WidgetLocation.MISC.subElement(0f, 18f + 6f * 3f, 18f, 6f) - val ARROW_DOWN_BUTTON_IDLE = ARROW_UP_BUTTON_IDLE.copy(overrideWinding = UVWindingOrder.FLIP) - val ARROW_DOWN_BUTTON_HOVERED = ARROW_UP_BUTTON_HOVERED.copy(overrideWinding = UVWindingOrder.FLIP) - val ARROW_DOWN_BUTTON_PRESSED = ARROW_UP_BUTTON_PRESSED.copy(overrideWinding = UVWindingOrder.FLIP) - val ARROW_DOWN_BUTTON_DISABLED = ARROW_UP_BUTTON_DISABLED.copy(overrideWinding = UVWindingOrder.FLIP) + val ARROW_DOWN_BUTTON_IDLE = ARROW_UP_BUTTON_IDLE.copy(winding = UVWindingOrder.FLIP) + val ARROW_DOWN_BUTTON_HOVERED = ARROW_UP_BUTTON_HOVERED.copy(winding = UVWindingOrder.FLIP) + val ARROW_DOWN_BUTTON_PRESSED = ARROW_UP_BUTTON_PRESSED.copy(winding = UVWindingOrder.FLIP) + val ARROW_DOWN_BUTTON_DISABLED = ARROW_UP_BUTTON_DISABLED.copy(winding = UVWindingOrder.FLIP) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets18.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets18.kt index 34a812e8d..d49145350 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets18.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets18.kt @@ -5,15 +5,15 @@ private fun makeButton(grid: SkinGrid): StretchingRectangleElement { val y = grid.currentY return StretchingRectangleElement( - topLeft = WidgetLocation.WIDGETS_18.element(x, y, 2f, 2f, grid.imageWidth, grid.imageHeight), - topRight = WidgetLocation.WIDGETS_18.element(x + 16f, y, 2f, 2f, grid.imageWidth, grid.imageHeight), - bottomLeft = WidgetLocation.WIDGETS_18.element(x, y + 16f, 2f, 2f, grid.imageWidth, grid.imageHeight), - bottomRight = WidgetLocation.WIDGETS_18.element(x + 16f, y + 16f, 2f, 2f, grid.imageWidth, grid.imageHeight), - middle = WidgetLocation.WIDGETS_18.element(x + 2f, y + 2f, 14f, 14f, grid.imageWidth, grid.imageHeight), - top = WidgetLocation.WIDGETS_18.element(x + 2f, y, 14f, 2f, grid.imageWidth, grid.imageHeight), - left = WidgetLocation.WIDGETS_18.element(x, y + 2f, 2f, 14f, grid.imageWidth, grid.imageHeight), - right = WidgetLocation.WIDGETS_18.element(x + 16f, y + 2f, 2f, 14f, grid.imageWidth, grid.imageHeight), - bottom = WidgetLocation.WIDGETS_18.element(x + 2f, y + 16f, 14f, 2f, grid.imageWidth, grid.imageHeight), + topLeft = WidgetLocation.WIDGETS_18.element(x, y, 2f, 2f, grid.atlasWidth, grid.atlasHeight), + topRight = WidgetLocation.WIDGETS_18.element(x + 16f, y, 2f, 2f, grid.atlasWidth, grid.atlasHeight), + bottomLeft = WidgetLocation.WIDGETS_18.element(x, y + 16f, 2f, 2f, grid.atlasWidth, grid.atlasHeight), + bottomRight = WidgetLocation.WIDGETS_18.element(x + 16f, y + 16f, 2f, 2f, grid.atlasWidth, grid.atlasHeight), + middle = WidgetLocation.WIDGETS_18.element(x + 2f, y + 2f, 14f, 14f, grid.atlasWidth, grid.atlasHeight), + top = WidgetLocation.WIDGETS_18.element(x + 2f, y, 14f, 2f, grid.atlasWidth, grid.atlasHeight), + left = WidgetLocation.WIDGETS_18.element(x, y + 2f, 2f, 14f, grid.atlasWidth, grid.atlasHeight), + right = WidgetLocation.WIDGETS_18.element(x + 16f, y + 2f, 2f, 14f, grid.atlasWidth, grid.atlasHeight), + bottom = WidgetLocation.WIDGETS_18.element(x + 2f, y + 16f, 14f, 2f, grid.atlasWidth, grid.atlasHeight), ) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets8.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets8.kt index 0a631c678..bd18562ab 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets8.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets8.kt @@ -4,7 +4,7 @@ import net.minecraft.resources.ResourceLocation import ru.dbotthepony.mc.otm.OverdriveThatMatters object Widgets8 { - val GRID = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets_8"), 64f, 32f).subGrid(8f, 8f, 64 / 8, 32 / 8) + val GRID = SkinGrid(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets_8.png"), 8f, 8f, 64 / 8, 32 / 8) val BUTTON_IDLE = GRID[0, 0] val BUTTON_HOVERED = GRID[0, 1] diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt index 716a5c5ce..ef8f5da50 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt @@ -52,7 +52,7 @@ abstract class BankRenderer(private val context: BlockEn val width = 9f val heightMax = 39.36f - val buffer = DynamicBufferSource.WORLD.getBuffer(AtlasMatterySprite.renderTypeWorld) + val buffer = DynamicBufferSource.WORLD.getBuffer(texture.renderTypeWorld) texture.uploadOntoPartialColor( stack, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/ScrollBarConstants.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/ScrollBarConstants.kt index 46242cf9c..f30839f85 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/ScrollBarConstants.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/ScrollBarConstants.kt @@ -2,30 +2,34 @@ package ru.dbotthepony.mc.otm.client.screen.panels import net.minecraft.resources.ResourceLocation import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.client.render.MatteryAtlas import ru.dbotthepony.mc.otm.client.render.subElement object ScrollBarConstants { const val WIDTH = 14f const val SLIM_WIDTH = 8f - val BACKGROUND = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/background"), 14f, 8f) - val BACKGROUND_SLIM = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/background"), 8f, 8f) + val NORMAL_ATLAS = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/scrollbar.png"), 62f, 15f) + val SLIM_ATLAS = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/scrollbar_slim.png"), 32f, 15f) + + val BACKGROUND = NORMAL_ATLAS.subElement(width = 14f, height = 8f) + val BACKGROUND_SLIM = SLIM_ATLAS.subElement(width = 8f, height = 8f) val TOP = BACKGROUND.subElement(height = 2f) val BODY = BACKGROUND.subElement(y = 2f, height = 5f) val BOTTOM = BACKGROUND.subElement(y = 6f, height = 2f) - val BUTTON = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/idle"), 12f, 15f) - val BUTTON_HOVER = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/hovered"), 12f, 15f) - val BUTTON_PRESS = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/pressed"), 12f, 15f) - val BUTTON_DISABLED = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/disabled"), 12f, 15f) + val BUTTON = NORMAL_ATLAS.subElement(x = 15f, width = 12f) + val BUTTON_HOVER = NORMAL_ATLAS.subElement(x = 15f + 12f, width = 12f) + val BUTTON_PRESS = NORMAL_ATLAS.subElement(x = 15f + 12f * 2f, width = 12f) + val BUTTON_DISABLED = NORMAL_ATLAS.subElement(x = 15f + 12f * 3f, width = 12f) val SLIM_TOP = BACKGROUND_SLIM.subElement(height = 2f) val SLIM_BODY = BACKGROUND_SLIM.subElement(y = 2f, height = 5f) val SLIM_BOTTOM = BACKGROUND_SLIM.subElement(y = 6f, height = 2f) - val SLIM_BUTTON = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/idle"), 6f, 15f) - val SLIM_BUTTON_HOVER = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/hovered"), 6f, 15f) - val SLIM_BUTTON_PRESS = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/pressed"), 6f, 15f) - val SLIM_BUTTON_DISABLED = AtlasMatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/disabled"), 6f, 15f) + val SLIM_BUTTON = SLIM_ATLAS.subElement(x = 9f, width = 6f) + val SLIM_BUTTON_HOVER = SLIM_ATLAS.subElement(x = 9f + 6f, width = 6f) + val SLIM_BUTTON_PRESS = SLIM_ATLAS.subElement(x = 9f + 6f * 2f, width = 6f) + val SLIM_BUTTON_DISABLED = SLIM_ATLAS.subElement(x = 9f + 6f * 3f, width = 6f) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/buttons/CheckBoxPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/buttons/CheckBoxPanel.kt index 6db631948..bbd0e6415 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/buttons/CheckBoxPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/buttons/CheckBoxPanel.kt @@ -91,7 +91,7 @@ open class CheckBoxPanel @JvmOverloads constructor( val DISABLED_CHECKED: AbstractMatterySprite init { - val grid = WidgetLocation.CHECKBOX.subGrid(REGULAR_DIMENSIONS, REGULAR_DIMENSIONS, 2, 4) + val grid = WidgetLocation.CHECKBOX.subGrid(columns = 2, rows = 4) IDLE_UNCHECKED = grid.next() IDLE_CHECKED = grid.next() diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/android_upgrades.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/android_upgrades.png index 8deae1d89b471315e9704158fa0ce8b322d20c56..ce32f5677b5ad6833defe8b74a05a58aaad055b7 100644 GIT binary patch delta 2527 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 N>HI~zC$^Y7{{nIbDb@f0 literal 2792 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 diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/player_bars.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/player_bars.png index 4c867588e72db77b743a676a3ee8de66f049f0b6..9b2f9356737a3358d6535c530209d3251db056dc 100644 GIT binary patch delta 244 zcmcb^G@nVaGr-TCmrII^fq{Y7)59eQNCyD1G6x%wWM1BTXriKN{T5Fb$B+!?x7Q81 z4mk)oTO8v_+Ml?d zd`@#y@g134XT2PK(;QATOkh-Gc47;OJ^NexyQFV0)3)5-mYGwgOtPL}q>uuWzsDSU z{R8{4o$o(AuIzm3RU?1y{`1W1=I>zgY%M%1cFnq)_|Th0gYo+Ix8GM7zMFkd)G+w>J#E zjyj06U96mTtD`j`F}F-{+B?UB-gOTi>IHFWvT$#_SXQH-#@HrO^!I#Y!OXHBOvaZN ze4YOL-tlW^ON(#ryW}^`Q-iTZ*uerqIBdH6@VEH)oAxDl4sUwK(3bcka^oqBzT<&b z4CxI8OdRSEq8`Y6E}O9X(shSJXTRF{^8bDOdgt8v_sl+j|NJpc>;HFaW`vn7!VD_6 zWADtZ4Tx04UFukvT{MK^TR<#7IOUDNG?^v4vV05EZeMD2kvUF@jg&?#4tRy9v7y z8%x1fu<&TS3L9%}Eo=or@Bp#2vQo5>u>P|V5`+j24D<13-ecws1P^nj<%YV!vWre~ zG@;GR&S~Kn8i^1kL{vB3!o<`_ikjo|j(}Qk<0^~)ji&UHYeGO19yAM1QFu|ff2~+h zyek|tm-V#pnQ)gQ7ZiR_x>4p=#aW+&Dl_J!l0(8VVJ%z5MiraOjwReD+@7{<$q&wy zIjwkIv6Wjjf9|PX7+JEXr<5+UjZwy!U=j_3RaVGRBrdBhic3=V6E*y;zJF3&hPYNR z#W74C3*Gml{@{1FZl<@VoD@kw{j=x2cR+X>N?V@yb>w-aW2k$AOS|IFAHu+g=vx)7 z{Q#mHaDG+Mj2*bxgqFvG?&!W$Co`DIz}u;O(=0UKK;wM5x1W7Z?ja>zjbFpwK6GX! zd!fd=8>)Nz^NimgiEkTna)dh9-B|zt010qNS#tmY4#5Bb4#5Gqk!$S$00C7=L_t(o zNA1|rZG|1$@AfM@VS*D}?ZRukJ;7 znx@~Y8}0iZkG1!Hr}OUp4S3tOxLRa}TY-`Z&e3_E)7i5MSQ{k+Me2?PW1*;k^M^B0 zblLG4VW3DIH85GMRJccOu;16|^)8)vEyC-%rb~OvvczNUy`T4T-GVV98S&H1a4S$U z!8uymCKm-de1 zh{xJ{Kkwzb1!F`q;-{J6R-j~pbF}7V(kftWlnfN9I~I(Eq5{qz&P35=$7h6rB6ZZj zWU*4=9=XAOKiY<2@Pq&VMD5Wn7$cGqKg|rc0woiiqcty+Rsn0HWS~ghv0y9|6>$D= vCWr&00000NkvXXu0mjfeD!zR literal 838 zcmV-M1G)T(P)EX>4Tx04R}tkv&MmKpe$i(@LdOI@m$PAwzYtAS&W0RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;qmz@Oie3JS*PxgfI+5Cns8h zQlOEPK_f{ip(ys}*i9hOVPKM5$^JL*X|Nax17Jm)F#ym3z&MWLZSOtq?gGFM8qaqL zIOpJ;Ya{S9SR@d`r)lB|53tta?yer8SioAF#8*||X|PBjhF>|l(*n7Onebu)8VRlI4PyIQ5~A!I&7Xm2LQt`h!;Z$xVx)IC>97IB=J=hcp5Ach~Za`?zBKI zVkW$pzy@W*4+1fy20WX<9>#zEDII{sI6+|_*F#Us?8)n6mvy-(t+D)2N|BoM=| z9NlSwT*ORxF@X)rh93lCNDX*4fjx`~FV-;|s&$;SV&C^o>Udce105XzFDeC@kW8KC QyZ`_I07*qoM6N<$g4?)m!2kdN diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/horizontal_gauges.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/horizontal_gauges.png index 83caab387ad6d3b2c44e19f6a07b3ef206b9b853..69916131808be41af77236c869c0c6135da9a2f8 100644 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^2|#Sd!3HEP{O4Q(QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4uLSEsD@VqQ1G^=i(^Pd+}qn5c@G(gFkH-^=E=I&TjEf1 zm0;8gBgY#`8WW{eUQ9S2^iFhRaJ-=FeLu_Rru!`7-{mf^udpk+U3-gpO35+jjg@SLrb zR=DRl+!K^;U`$|ZkYq?>n8BFvkG4ifMN6gCHsLQoCO|{#S9F5he4R}c>anMpkS4! zi(^QJ^V=KVTn7v|Tmyd>{*TskS^h|+U**d^zvg+KnJZkUFPQPhH*LEKP&o)3;A{xI zr?@OsY;v)GWVOTGpP#kn#{{!OBpGfnY}m2G{A0g|I0J(^gWJzne!6PU=WY7dU}fjV jz>vcbAp=tQNA|%##%hJ4SCwgxz~*|o`njxgN@xNAGGkW| diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/pattern_panel_tabs.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/pattern_panel_tabs.png index 6988d0fc445d382e3172c8cdeb23b7e0a404031a..14b5b1ad1b2eeb57816cadb89be9aaee0017372d 100644 GIT binary patch delta 460 zcmV;-0W<#Y0^tK8iBL{Q4GJ0x0000DNk~Le0000y0000N2nGNE09ThRhmj#6e{e`y za{vGi!Tl|IZGx&*s+e@i=Y0I6lrR&h7Kp+q(C8jqcN|CiT`e|qe@Gwck!l00 z%Am5J73=M5A!ECSAtnX0oq>oHVn;@<55d}3t`XLThIM5tX3t^6OES~tC??Zo9pf4p z=_;_gYSAlZZ@yPlZ@!yQ#VnvuWR^tTlXy93QywyxTMZM>cvjmpUdf>)k?nv4;@QgI z!PouM`awSRNSl{h8y$UlB9vYlZ{l}{$!8wvY5E5O3{JWH42lQ<0000B|3Aa^Q@oBqE@y#9WHAE+-(e7DJf6QI1t@sm)5S5w!~5-ogM5b- zc$|0t`|qybm#eTvDEMgNtY_XrZ}tTB30pbcToR|aRk32T^^XFH!VX6Flvaz=JcVoy z%er(#^LJHUt`}v9R5DSX{p@UBKH~|sBOPsTUKn18b>n&QTjH0UkP$D(c7{!Q3^z3{ z#-x@pZkq0PgQLNXp@eoY%2Dm)?R6weqrXUE;+ zndcVfl=AEhU9g7VvN+baOqO9y$bY}Qpg9{o3*(r2E(mD7p3k5sc8j%Qov-;0yUDk< nnlbKsAUOXu{}09kmHQa&AM@UExhdWU^els?tDnm{r-UW|P9B6_ diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/progress_arrows.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/progress_arrows.png index 97e06802276455560ed40e4d64134be8f3116acf..dc0c2a9a87fb045d498c4e65655241bfcab67b5b 100644 GIT binary patch delta 269 zcmbQtw3tb;Gr-TCmrII^fq{Y7)59eQNQ(inJO>+)e7xKC^F&33dd>om$YKTtzC$3) zD5~Mr0F>O}>EamT;l1^8pwJNk0oTB^tvUy^bQ(IwWa!%h;hwM^l5WOxm=+5zKe*!f-*?Oz-kLv^4Hoq+DxDwkt$uq|@Pdey>UkQA z4%&8UeCSXzwsH2IyDNFwyI(*fmIb~k_}mk2@igpA0auUP9Ja-B-yctws4QV}yArr1 zspnj~K#02D(i87wFGQ{WXMUXH_?Gq>)oa46u8;0s3{X)McXbcg;y(8`leOJcljsmx ROQ0thJYD@<);T3K0RX_rY0Cfr delta 253 zcmZ3?G?_`UGr-TCmrII^fq{Y7)59eQNGpIa2Q!d#S<-cEqM|}QPk>K|Yj=0||Ns9p zGBQBYcP7mTQYX&d-^dwRI96GIlAQa1~v$Xf3CQ->U@eR|`(FtyMoW sefphRQI&X>o7D{YjJC|5c}_^E?_SM$ljDV$C(tnrp00i_>zopr0P{RrEdT%j diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar.png new file mode 100644 index 0000000000000000000000000000000000000000..e15e25c3d023a24c1ec7319d4db4c6082421ba46 GIT binary patch literal 330 zcmeAS@N?(olHy`uVBq!ia0vp^c0kO}!3HGvJg@NqQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$AjK*9T-E{-7{-fu4&ay2^$uwLL~vFSH!iaVSg z@lx>3l~dI(c;6iHJO5DA$E|K-i@`ZB4$d>H)7o{vz2ASdaL?rBI;S%v*yfZRD?GA9 zn1yj!vG3)8dCx6g${e)p=-;HH=^M;-SU~#bu66DoQX@A^bPX(Fng3i;I`aPakWf)k z*T&v8xzW3l_w_h?#@VOOQuBHLv3*y~`|SJ4z458N+-p8ApP#vB-Rrs1U%tNYy>C$M zJt^h+gIV%r&Dl~V&DrmEA2fac)1!bl`;OG~$j8@qym{T59P;pi-L7?ub8i<|9Y6TB aL+&w$%AbutdLIM5%HZkh=d#Wzp$P!**o*T3 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/background.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/background.png deleted file mode 100644 index 187422eb75b26d4e73c6004e0baa414d42bba6d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!3HEhl+{lMQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4uLSEsD@VqP|(WL#W6%9IN8M9{Qr3eB@Rx`L=9ctRF;hg z*&0|p7*$nOd3qcel8hT&H5eANF*uf&f3GiMa4~0QX5jv5S9#GQKM80GgQu&X%Q~lo FCIFV$C$#_o diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/disabled.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/disabled.png deleted file mode 100644 index 767ab28675930ffe94326063ec69bba953a9606a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%DHgc*EaloaXxv=uk#I}GRZ9$ zba;5$B9@##9I3M+hQs07p(ecsJ~!V5i#VT4YA`W))pF}Q3Ridob*h%QMwFx^mZVxG z7o`Fz1|tI_BV9uST?6wFLjx;gBP(NbZ36=<1A~uAOlc?@a`RI%(<*UmXt3XP3#dT@ lZbM0CZfbE!Vr~JZ9#ad5CC_;uWdrpvc)I$ztaD0e0syw&VaEUf diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/hovered.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/hovered.png deleted file mode 100644 index 60457f250111541db0ec9907fe853a9ec84f1e8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%DHgc*EaloaX$Ia$N7xf4-#4~ z=sXWbMQoIxm=BBwS(1nt8xO!;F)O;q5n`nd}bj?m+#jC9V-A zDTyViR>?)FK#IZ0z{p6~&_LI~JjBqz%Gk)t*j(Gdz{EaloaX$G+zi7$-^ads| zwzkJSGajfiPhw(gTbyy}nn#XU31f*t7SmOq7mi&Ln}Ax@DVc2VzT^$mtycptHiCL!G6~* opau=N4JDbmsl_FUxdoVdOf4XmJm-Cs4b;Qn>FVdQ&MBb@023EvMF0Q* diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/pressed.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar/pressed.png deleted file mode 100644 index d1b456e8a0063781e7abfb4375421dab739b8469..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%DHgc*EaloaX$Ia$N7xf4-#4~ z=_urfBXGB(#XFt9Q(_?X0$hN2-iKP5A*61Rp1 r`(3wy8Z_WGlw{_n7MCRE7GUZzwSZXiocB>SP!EHrtDnm{r-UW|bfsma diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim.png new file mode 100644 index 0000000000000000000000000000000000000000..f8539f3e60c7b11534649b726bdb9fee417fae63 GIT binary patch literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^3P8-y!3HE-8_tRYDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMpx|{+7sn6}@3&JO`C1fsTrbWjkh?qMh3Sqq z?T>6asYf06G+ICQJO5BK?UG-hiov)yJ{k?i@x2YlcDPxxM1#c$+fAs&9>y;UbHo1 zZKT&f)qpEvWiyv?PWRV&_x$HirUgywSpu$`>dlY1bN;hN!EPqWKa3aNhPTA=x5RNC zc~m!V%j;cFq)XoAbJ^H_0LfQRKfYp>mW6Ke}6CtxP8N;ckI7_ PUS#le^>bP0l+XkK`lf&| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/background.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/background.png deleted file mode 100644 index b0a6eae96fc26e06e1117c7b964185c4674a6fdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 357 zcmeAS@N?(olHy`uVBq!ia0vp^93TuL7#^lP35jgR3=A9lx&I`x0{IHb9znhg z3{`3j3=J&|48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@fg!Ib3f?!xfDz5mR9Adj=a zBeIx*f$tCqGm2_>H2?+KOFVsD*`IN7uuCh5+?u}(D5T=);uyklJ=r8Z0R%V_6FCw= z42{I32Bstlp1c1Q85l|uIi7EOz%v!7UbVzEq9i4;B-JXpC>2OC7#SED=^7g78kmO| z8dw<{TNxT_8yHv_7_2zuWrm_5H$NpatrAUxsRd9EL__!UBhEk#8gLs*GILXlOA>Pn i5PB>^49u;J%&m-#AbQRyD;NRwFnGH9xvX3o4}_% zqzpY>977~7CvW+6o`LGccrS z@m+7Re3%T>tXkq4QIe8al4_M)lnSI6j0}v7bPWx34a`Ff4XliftqhH|4GgRd3|5@- zGDFdjo1c=IR*74~&FP=IfEqO5Hk4%MrWThZ<`y9IScDjuTN#;K85=h diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/hovered.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/hovered.png deleted file mode 100644 index 98f996d4d5c5f4ff4a094c5bccbf89279d71fa1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 404 zcmeAS@N?(olHy`uVBq!ia0vp^96&63o4}_% zq|7~C977~7C;$04pOMc(LQ*0^LgJj`PB$J9@BtC-l6{9lHyQvzgmMY5qG->HeMcD> zN*?o{4EU6M7iffPiEBhjN@7W>RdP`(kYX@0Ff!6LG|)9L4>2^bGB&m{G}bmSure@M zamvdKMMG|WN@iLmZVfl5f9e8i(16=el9`)YT#}eufY4(RVqk7%WNu|_1hM3dvH~b@ O7(8A5T-G@yGywq0m}Uw9 diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/idle.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/idle.png deleted file mode 100644 index 603961851597f9b7129170f1b846d59f270ce68d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 403 zcmeAS@N?(olHy`uVBq!ia0vp^96&63o4}_% zq|7{B977~7Up>E(x50pi;h^xRFiF8{n`X3X&S4T-#WP{`{z}uitOwtIZD0o>zjC2hRbPdcy3=OP|jjarg zwG9lc3=CGB@-jowkei>9nO2Eg!_DcRx_}xq;5L+G=B5^xB<2<%^jL%#m|Gc{TNxWc UEIFgB016uhPgg&ebxsLQ01ne@%m4rY diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/pressed.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/scrollbar_slim/pressed.png deleted file mode 100644 index 7b8b5dd0a0a3dc005eef6b0d9ce9f0059f918fbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 404 zcmeAS@N?(olHy`uVBq!ia0vp^96&63o4}_% zq|7~C977~7C;$04pOMc(LQ*0^LZWNooj5iSPy^z&&pgi`t^$fmNbm^mYMa32R&qay zfnkQd0PC9D7Ir`*R7+eVN>UO_QmvAUQh^kMk%5tsuAzahfq96bft9hbm7%e=fq|8Q z!HQE}W+)nR^HVa@DsgMLIsH=?P=f~ChLX(O)Z&uF+yaCiix2~IDgTe~DWM4fX7pt_ diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/vertical_gauges.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/vertical_gauges.png index 677f594224305e4809a7e27d13ed3ee6f2725ae8..c981a8143b9c6f55f1b285c4f086bfc1fa842623 100644 GIT binary patch literal 887 zcmeAS@N?(olHy`uVBq!ia0vp^Q9x|K!3HEJ9?!J{QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4uCLY*0oMf1_ovxPZ!6KinzCP99La&5OKX+FSy8}=!-j- z?JLoaUZZo6?1{?- z8crnce}DN?K41G`lbqdm=jFxK%5RgGU#@NZ zBe&xB>6-cC%k{hYAAEkc^QWDC9bfnN$}b!KeBYEXGnKJ^-s+OLl&S?5_wM{DtUGb} zeRgsA_MGf1JpBj$EQtIR@hx&)bwTZ3u*ic~KR(^A*~YMbae|!Yb>a8%=Z~v;T^IJB zFMD}r+x1XOkty$z4;r0T+8{nxbdI>~o@xX6aJQ+>(Tme6Siad-Eqrlf@oA>d&34nf zAHN7O{q|O4m&OMBj487#*I9Mxam7@BnPeOA^uo0jl5&mN{rd`P+Lyujj-eMX%h|p= zzlD93%q=O?!^$hPekIAeinErwE;l{>u2HLfo7>qB9Iv|l?pyANlMdy}?Va^d@QQfv zU(4wAy-?XVuAg<8Sr@0Q3oK&~vD{*s)#jd{KPz8SXZGuhax025z@CmbIrHr`$er~U zHD=tmO6oV`eB-+L!4`G*i)D>_fsWm44q|2ZpSwSMamMZg+uhSyK?18YX4UuiEjrB< zf6-*MWtSfJ8`pH!`K}KiZ-hB{gLv)!M_=+=14|+UVom<9H2^AF)tz?IW*y9d|1$fZ zy@z{QB-a7trLJecP3ruQZw-WmjAQJ@pVnV9_~9O~3bmPe-S!qU)Xz7%&vEy?zo^$( z-~a5MjO%RHb+%Uf+^=)SRF~BBuM__9?Zui08n^TcM13DuZ}ESiJuA)B{bFk4UZC*G zH#v6^#-#1NS^h%fmfDV6wN*y*bq~CLUbXrC1##E?KMmxkYsC83?7h3xn0Ni^A`OkZ z$D2~8xjxXF#d<#;9@?wEWo(7V#F2XCzyn6B&lvn+s}PpA>~UQ<3z%6LJYD@<);T3K F0RTa7pGp7# delta 474 zcmey)_KsPxGr-TCmrII^fq{Y7)59eQNH+kn0|zsZe9F=9J5f=gUNOKY#MRu~yt}*G z(9n>fL(KjE?&mLn3K$L?WH3KAAte>WZmto_1ybB4L4Lvi;ef%*pYan=n6tnmvY3H^ z?;r>>?wFYUmVtrM-qXb~B*XdbjE8xL6?j@Q@1*L!|9@cf>%*?XO{KHSrhfRYzb$Hh zz5WaZuK?+ae~~HPAarI?ayEz>!6S)EsT-6<(*!Wv6XR@0+kzomw zNW{mxjF!uoqRN>WJyXn;D0e_8do))@ z;OMf3=MBy=%zW1wYq>+%bNE*9)xVJ0AbVl%gjWqw8$L>H_;xcm!9aFH|G{(F2ihB| z^Q)L~TX$-Zh+av~nnQ*xqEr|K^YG2Gs+l3g?+CxI7p&6>M`yIcSO