From f866f2a401623b373335d22d705bfdfcf6d5da59 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 7 Mar 2025 21:00:01 +0700 Subject: [PATCH] Add "Charge androids" and "Charge exopacks" buttons --- .../mc/otm/datagen/lang/English.kt | 6 ++++ .../mc/otm/datagen/lang/Russian.kt | 6 ++++ .../entity/tech/AndroidChargerBlockEntity.kt | 20 +++++++++-- .../entity/tech/AndroidStationBlockEntity.kt | 29 +++++++++++----- .../mc/otm/client/render/Widgets18.kt | 2 ++ .../screen/tech/AndroidChargerScreen.kt | 31 +++++++++++++++++- .../screen/tech/AndroidStationScreen.kt | 14 +++++++- .../kotlin/ru/dbotthepony/mc/otm/core/Ext.kt | 9 +++-- .../mc/otm/menu/tech/AndroidChargerMenu.kt | 10 ++++++ .../mc/otm/menu/tech/AndroidStationMenu.kt | 6 ++-- .../textures/gui/widgets/widget_18.png | Bin 1292 -> 1412 bytes .../textures/gui/widgets/widget_18.xcf | Bin 9864 -> 12474 bytes 12 files changed, 114 insertions(+), 19 deletions(-) diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt index f217db8fe..673379cff 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt @@ -985,6 +985,12 @@ private fun gui(provider: MatteryLanguageProvider) { gui("exopack.accept_wireless_charge", "Accept wireless charging") gui("exopack.dont_accept_wireless_charge", "Do not accept wireless charging") + gui("charge_androids", "Charge Androids") + gui("dont_charge_androids", "Do not charge Androids") + + gui("charge_exopacks", "Charge Exopacks") + gui("dont_charge_exopacks", "Do not charge Exopacks") + gui("multiblock.formed", "Multiblock is formed: %s") gui("flywheel.current_loss_t", "Current energy loss per tick:") diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt index a5e49ff4c..ae0d7b49b 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt @@ -978,6 +978,12 @@ private fun gui(provider: MatteryLanguageProvider) { gui("exopack.accept_wireless_charge", "Принимать заряд от беспроводных зарядников") gui("exopack.dont_accept_wireless_charge", "Не принимать заряд от беспроводных зарядников") + gui("charge_androids", "Заряжать андроидов") + gui("dont_charge_androids", "Не заряжать андроидов") + + gui("charge_exopacks", "Заряжать экзопаки") + gui("dont_charge_exopacks", "Не заряжать экзопаки") + gui("multiblock.formed", "Мультиблок сформирован: %s") gui("flywheel.current_loss_t", "Текущая потеря энергии в тик:") diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AndroidChargerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AndroidChargerBlockEntity.kt index 8d2df30aa..17d1f79da 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AndroidChargerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AndroidChargerBlockEntity.kt @@ -30,14 +30,28 @@ class AndroidChargerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::markDirtyFast, MachinesConfig.ANDROID_CHARGER)) val energyConfig = ConfigurableEnergy(energy, modesTop = FlowDirection.NONE) + var chargeAndroids = true + set(value) { + field = value + markDirtyFast() + } + + var chargeExopacks = true + set(value) { + field = value + markDirtyFast() + } + init { savetables.stateful(energyConfig::energy, ENERGY_KEY) + savetablesConfig.bool(::chargeAndroids) + savetablesConfig.bool(::chargeExopacks) } override fun tick() { super.tick() - if (redstoneControl.isBlockedByRedstone) return + if (redstoneControl.isBlockedByRedstone || !chargeAndroids && !chargeExopacks) return val level = level ?: return var available = energyConfig.energy.extractEnergy(energyConfig.energy.batteryLevel, true) if (!available.isPositive) return @@ -49,14 +63,14 @@ class AndroidChargerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma for ((ent) in ents) { val ply = (ent as Player).matteryPlayer - if (ply.isAndroid) { + if (chargeAndroids && ply.isAndroid) { val received = ply.androidEnergy.receiveEnergyChecked(available, false) available -= received energyConfig.energy.extractEnergy(received, false) if (!available.isPositive) return } - if (ply.hasExopack && ply.acceptExopackChargeFromWirelessCharger) { + if (chargeExopacks && ply.hasExopack && ply.acceptExopackChargeFromWirelessCharger) { val received = ply.exopackEnergy.receiveEnergyChecked(available, false) available -= received energyConfig.energy.extractEnergy(received, false) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AndroidStationBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AndroidStationBlockEntity.kt index 42b2e62a0..3ef4f37e5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AndroidStationBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AndroidStationBlockEntity.kt @@ -17,21 +17,26 @@ import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.capability.moveEnergy import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.core.math.Decimal +import ru.dbotthepony.mc.otm.core.otmRandom +import ru.dbotthepony.mc.otm.core.shuffle +import ru.dbotthepony.mc.otm.core.util.countingLazy import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu import ru.dbotthepony.mc.otm.registry.game.MBlockEntities -class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : - MatteryPoweredBlockEntity(MBlockEntities.ANDROID_STATION, p_155229_, p_155230_), MenuProvider { - +class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.ANDROID_STATION, p_155229_, p_155230_), MenuProvider { override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { return AndroidStationMenu(containerID, inventory, this) } + private val workerState by countingLazy(blockStateChangesCounter) { + blockState.getValue(WorkerState.SEMI_WORKER_STATE) + } + override val energy: ProfiledEnergyStorage = ProfiledEnergyStorage(object : WorkerEnergyStorage(::markDirtyFast, MachinesConfig.AndroidStation.VALUES) { override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal { return super.extractEnergy(howMuch, simulate).also { if (!simulate && this.batteryLevel.isZero) { - if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.IDLE) { + if (workerState != WorkerState.IDLE) { level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS) } } @@ -41,7 +46,7 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal { return super.receiveEnergy(howMuch, simulate).also { if (!simulate && it.isPositive) { - if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.WORKING) { + if (workerState != WorkerState.WORKING) { level?.setBlock(blockPos, blockState.setValue( WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING @@ -53,9 +58,15 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : }) val energyConfig = ConfigurableEnergy(energy) + var chargeAndroids = true + set(value) { + field = value + markDirtyFast() + } init { savetables.stateful(::energy, ENERGY_KEY) + savetablesConfig.bool(::chargeAndroids) } private var tickedOnce = false @@ -66,20 +77,20 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : if (!tickedOnce) { tickedOnce = true - if (energy.batteryLevel.isPositive && blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.WORKING) { + if (energy.batteryLevel.isPositive && workerState != WorkerState.WORKING) { level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS) - } else if (energy.batteryLevel.isZero && blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.IDLE) { + } else if (!energy.batteryLevel.isPositive && workerState != WorkerState.IDLE) { level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS) } } - if (redstoneControl.isBlockedByRedstone) return + if (redstoneControl.isBlockedByRedstone || !chargeAndroids) return val level = level ?: return val x = blockPos.x.toDouble() val y = blockPos.y.toDouble() val z = blockPos.z.toDouble() - for (ent in level.getEntitiesOfClass(ServerPlayer::class.java, AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0))) { + for (ent in level.getEntitiesOfClass(ServerPlayer::class.java, AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0)).shuffle(level.otmRandom)) { if (ent.matteryPlayer.isAndroid) moveEnergy(energy, ent.matteryPlayer.androidEnergy, amount = energy.batteryLevel, simulate = false, ignoreFlowRestrictions = true) } 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 5949f6962..06bab6193 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 @@ -45,6 +45,8 @@ object Widgets18 { val SETTINGS_TAB = miscGrid.next() val WIRELESS_CHARGING_ENABLED = miscGrid.next() val WIRELESS_CHARGING_DISABLED = miscGrid.next() + val WIRELESS_CHARGING_ANDROIDS_ENABLED = miscGrid.next() + val WIRELESS_CHARGING_ANDROIDS_DISABLED = miscGrid.next() private val slotBgGrid = WidgetLocation.SLOT_BACKGROUNDS.grid(4, 4) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidChargerScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidChargerScreen.kt index 27b80cb22..a7e6b9fb4 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidChargerScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidChargerScreen.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.client.screen.tech import net.minecraft.network.chat.Component import net.minecraft.world.entity.player.Inventory +import ru.dbotthepony.mc.otm.client.render.Widgets18 import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.Dock import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel @@ -10,8 +11,10 @@ import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.SpritePanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel import ru.dbotthepony.mc.otm.client.screen.widget.TallHorizontalProfiledPowerGaugePanel +import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.menu.tech.AndroidChargerMenu class AndroidChargerScreen(menu: AndroidChargerMenu, inventory: Inventory, title: Component) : MatteryScreen(menu, inventory, title) { @@ -40,7 +43,33 @@ class AndroidChargerScreen(menu: AndroidChargerMenu, inventory: Inventory, title it.dockRight = 2f } - makeDeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, energyConfig = menu.energyConfig) + val controls = makeDeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, energyConfig = menu.energyConfig) + + if (menu.chargeExopacks != null) { + controls.addButton( + BooleanButtonPanel.square18( + this, frame, + prop = menu.chargeExopacks!!, + iconActive = Widgets18.WIRELESS_CHARGING_ENABLED, + iconInactive = Widgets18.WIRELESS_CHARGING_DISABLED, + tooltipActive = TranslatableComponent("otm.gui.charge_exopacks"), + tooltipInactive = TranslatableComponent("otm.gui.dont_charge_exopacks"), + ) + ) + } + + if (menu.chargeAndroids != null) { + controls.addButton( + BooleanButtonPanel.square18( + this, frame, + prop = menu.chargeAndroids!!, + iconActive = Widgets18.WIRELESS_CHARGING_ANDROIDS_ENABLED, + iconInactive = Widgets18.WIRELESS_CHARGING_ANDROIDS_DISABLED, + tooltipActive = TranslatableComponent("otm.gui.charge_androids"), + tooltipInactive = TranslatableComponent("otm.gui.dont_charge_androids"), + ) + ) + } return frame } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidStationScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidStationScreen.kt index 16acceee3..08190ec3c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidStationScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidStationScreen.kt @@ -34,6 +34,7 @@ import ru.dbotthepony.mc.otm.client.screen.widget.WideProfiledPowerGaugePanel import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.mc.otm.capability.matteryPlayer +import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel import ru.dbotthepony.mc.otm.core.RandomSource2Generator import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu import ru.dbotthepony.mc.otm.network.AndroidResearchRequestPacket @@ -717,7 +718,18 @@ class AndroidStationScreen(p_97741_: AndroidStationMenu, p_97742_: Inventory, p_ this.playerStrip = playerStrip - makeDeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, energyConfig = menu.energyConfig) + val controls = makeDeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, energyConfig = menu.energyConfig) + + controls.addButton( + BooleanButtonPanel.square18( + this, frame, + prop = menu.chargeAndroids, + iconActive = Widgets18.WIRELESS_CHARGING_ANDROIDS_ENABLED, + iconInactive = Widgets18.WIRELESS_CHARGING_ANDROIDS_DISABLED, + tooltipActive = TranslatableComponent("otm.gui.charge_androids"), + tooltipInactive = TranslatableComponent("otm.gui.dont_charge_androids"), + ) + ) return frame } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt index 718e617b1..97326b9b1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt @@ -188,17 +188,20 @@ fun > T.prev(values: Array): T { return values[next] } -fun IntArray.shuffle(random: RandomSource) { +fun IntArray.shuffle(random: RandomSource): IntArray { for (i in lastIndex downTo 1) { val j = random.nextInt(i + 1) val copy = this[i] this[i] = this[j] this[j] = copy } + + return this } -fun MutableList.shuffle(random: RandomSource) { - return Util.shuffle(this, random) +fun > L.shuffle(random: RandomSource): L { + Util.shuffle(this, random) + return this } fun List.random(random: RandomGenerator): T { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidChargerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidChargerMenu.kt index 196526d4d..be2b8c24e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidChargerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidChargerMenu.kt @@ -5,6 +5,7 @@ import ru.dbotthepony.mc.otm.block.entity.tech.AndroidChargerBlockEntity import ru.dbotthepony.mc.otm.block.entity.tech.AndroidChargerMiddleBlockEntity import ru.dbotthepony.mc.otm.block.entity.tech.AndroidChargerTopBlockEntity import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu +import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.registry.game.MMenus @@ -13,6 +14,9 @@ class AndroidChargerMenu : MatteryPoweredMenu { val energyConfig: EnergyConfigPlayerInput val profiledEnergy: ProfiledLevelGaugeWidget<*> + val chargeAndroids: BooleanInputWithFeedback? + val chargeExopacks: BooleanInputWithFeedback? + constructor( p_38852_: Int, inventory: Inventory, @@ -20,6 +24,8 @@ class AndroidChargerMenu : MatteryPoweredMenu { ) : super(MMenus.ANDROID_CHARGER, p_38852_, inventory, tile) { energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig) profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energyConfig?.energy, energyWidget) + chargeAndroids = BooleanInputWithFeedback(this, tile?.let { it::chargeAndroids }) + chargeExopacks = BooleanInputWithFeedback(this, tile?.let { it::chargeExopacks }) } constructor( @@ -29,6 +35,8 @@ class AndroidChargerMenu : MatteryPoweredMenu { ) : super(MMenus.ANDROID_CHARGER, p_38852_, inventory, tile?.lastTileEntity) { energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig) profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.lastTileEntity?.energyConfig?.energy, energyWidget) + chargeAndroids = null + chargeExopacks = null } constructor( @@ -38,6 +46,8 @@ class AndroidChargerMenu : MatteryPoweredMenu { ) : super(MMenus.ANDROID_CHARGER, p_38852_, inventory, tile?.lastTileEntity) { energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig) profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.lastTileEntity?.energyConfig?.energy, energyWidget) + chargeAndroids = null + chargeExopacks = null } init { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidStationMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidStationMenu.kt index 9b3f0da7e..974fa4823 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidStationMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidStationMenu.kt @@ -13,6 +13,7 @@ import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu import ru.dbotthepony.mc.otm.menu.MatterySlot +import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.registry.game.MMenus @@ -25,7 +26,7 @@ class AndroidStationMenu @JvmOverloads constructor( ) : MatteryPoweredMenu(MMenus.ANDROID_STATION, containerID, inventory, tile) { private fun container(target: (MatteryPlayer) -> KMutableProperty0): Container { if (player is ServerPlayer) - return PartContainer(target.invoke(player.matteryPlayer ?: throw NullPointerException("OTM player capability is missing"))) + return PartContainer(target.invoke(player.matteryPlayer)) else return SimpleContainer(1) } @@ -115,6 +116,7 @@ class AndroidStationMenu @JvmOverloads constructor( val equipment = makeEquipmentSlots() val energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig) val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energy, energyWidget) + val chargeAndroids = BooleanInputWithFeedback(this, tile?.let { it::chargeAndroids }) init { addInventorySlots() @@ -122,6 +124,6 @@ class AndroidStationMenu @JvmOverloads constructor( } override fun stillValid(player: Player): Boolean { - return super.stillValid(player) && player.matteryPlayer?.isAndroid == true + return super.stillValid(player) && player.matteryPlayer.isAndroid } } diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/widget_18.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/widget_18.png index 984eb0090e4df0f04d252134f3d0924fb5fc0f9c..f311ac0c68739fb05aed8308bc39f3da1659b8b2 100644 GIT binary patch delta 944 zcmV;h15f;n3WN)=;{ksRISRm|KSKZj1A<9JK~#9!?OHpIA~6sxqdvqEkxfX3H~}JH zj>`myWH&@)+<=H<)CNnB+{T~!bx)(MCyg{so1*+&uAdzM0Kou=CSuI6+wDx`bN~R` z?N%k^a=Dl&bv~Z~03d{5vRLc&S|#UpyZs{w0ARIRiG-EEt8yvQ zs$7b`DwiUFH_RNf0Y0Jqo>b1LJ}6cAWiMv>p#8Y?9U@{N_DyR)X9~|8Ji@otOZ2~S7>W;Epo;pNwQ@FhvA&BsZBCR1eF{Kp<2ty zS~5kE*5@^)ONwzPYDH2@*Yy2@vf3I`Z~2$80zgSdYlo!o7gXhcI^0^4WE$qRNn6WF z{{%^91ceA%a#A_(LQ>NaOPyqGyoJNHlv8ukswk#Wd=7skrPkLB^A>p!N8!0z(r8hP ztLQuWq*=5(rv810!|`7Mfp$<(8pr*-8ca(6lS_@65Na_-mr3Vxn_MDAXmQ|EPI!(R z90`RGUfvr{oZMeZQ-fLuBTG=N$ZUjCjECgJL?m*yWb03yT(VPxn1~oeVJQLMgr(0+ zpM}hKtTKOtoI_b#P-X&B3sO1#908>{#-Dd@?woVuL(5X)_DkxIQr|OYg6twuquo+- z%-xJEB@`kO)sljiz+AE2YK-7?xzAwv zxz)+8!{KnuuNbOy-tcfhJRHnBcvI-ZfvltW`8ltZ98n)KL4A@qSf%4pl+LGJOUYT5 zl|Je`XwZ&~lnGy7>~rwAD73gGrqRdTf-F}`V>x5!!?K|4g@nvXQSK+!R=@Up9C9@J zun2!Du4d!_sb<`|8>G42I>ojs7OO9lNtEHNQmOJM9vx-JYxFUz=4)omx$E5O1#{)R z_?!?_cdtcT%+ic=hjEfgAR-R(oX8gpu{0!KW9ZxbYlRvd7D zRz*gR$D_!i4u=B(02pIL9@b*9D6(@tpZ^E~0GQ9`Sw=3G%V>YR*=(}x?DzZ8c)46= z**Tp~qw#Du%d&I5UI75014R@{kP@T>DM3n*5~KtvK}wK92~vWTpy#6xRpq&GtMXj9 zRe3Iksyr74v|*;G26#j1-{snw)Cai>emIMsKIkydy@!Zsn0?b25h-?FB8u6Y;V8hK zWB+Zcou?DzKDB?8r^wx0h@7cOO10H-jHDW+Hb;>&6-hZq)}%1(^EI(e`iS6?lS62! za=c3BEQGoqTXbk)sT-9diCU|BzvDdZ5~)-EWvT!WvO%2?_kPD+{C|gANs>gvd}-1~ zIqCl(NsJ(4p_Clg&a03_I^tX>8JjQRa3$@;oODqXD_MVd4J5hhBg4Ez9+a}+T9q_e z6iZ#`EBd4=+8xjS{|beoDIoA(6olrbUXKQo(C_S0qY^?T=9Fd9zTC!_NHJO*c(Y?} z^G2_Pj4==Q1vk#_FS)5ftb^etC{|<=p%m>YJ~I}HDMym}$xbelQv;g_8%$#^0e8aO zaiY({#Cv~9Wd=Kkl2(vs1Gx$+a{4|3LVL8Y_b=|8ee(^a6ubT6`Xkr()J%|EBqG`^ zF~{6jq!bf~NL(eEQUZO&cJG@!$SxG-nUy*q;ysKHrtEQQ`^G~8PN}q7oHW-7XNCFF zo_HTiq+*F8Gn7UZBe zb*VSI3WY*ZUojNvyy13>xZS?}8-%=$;^${GB4HCWB#9%{>~`;8=yHzPy_mDeF<)Os z6=W0Dm~w&&@_vxuQ4Z((#J3_SScF;*xs_uTELI;nZ;o^#i0Z#a}ghJ64egUk_At&29sbc^D002ovPDHLkV1gnR Be{TQ) diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/widget_18.xcf b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/widget_18.xcf index f9b632cf4e2692ec0fb220f9b0dec6b29aea08fc..ad1bff632cc93ed840d5d52d044f945e448f2ce0 100644 GIT binary patch delta 1391 zcmd^8O=uHA6rP!6(`-#`OxhHa)NV|SX`;a&sED9QK>|_)@hs>`5xgiCdP(a=kwU8j z3Zm#iK@V+1Hr7y3Q?Qpxabi6PX%B_kfQt1XSZM3`_D!P6O?!2CJKx*y&3iL%zTN9R z6K96c(e9h)Kc{C14*P3`&eIAvEi2qStI%^?VQWTVa86;zh{ElU6z+JeaOVw$@h1v* zk14F1J%sROrtt!`yTanGcqv|qd~wL&Q*=y=z|t@cU=-;-}qkL&ulKfz}jep zm%IaJpRJ2_c8dGrnIWEwOtHT>B*p=+76%QH5idlp*bn9NA_sGp53~>0)IVBZU;Bvl z9Te*Om}4tn(N3kPTqBZ5MyPZUo0Nos&!mm40!x5#!n10*;Qf#VSwOS=CAoy=Bu*LU zQtSEGVv}+b%_>%wWwZ?!!y{Hs`Nvl$3-NqI^FbGp&=-|<>`zLatV54>U>bm-fL7<4 z#X`?I_^R(lP95IEI$5)B#3tj`t%Ab%P{4?|^LNTvNlN)6;MEMh50nYe+bE1a`kx7N za>K$@q-y*vSydvQqr3RDXOLfJCzwm(ci$Ai>uuU!`LR-rHUGqj+m8|VK66DoU}N43 z$a=3K>wN%nq|HVBAv@+P)QFY>-%`}BINzeepiqc&bq&03$0GZub|$>AwX4$njKS<2tETr@8QbjqT6 z3`gH%IQqrR21hB2-9t8(w^%(^JtvnPy|;`jU|FM=vV@7N5^pg#Q8q_HGmIt2kxjls LHu=fSL_W}8h9uie delta 517 zcmdm$*x@@NgVA_m=Ig+%3}C>r5JGcELTK(f2raYIXo(^SEnN(uWg{T8LK%cs zuARJ>QGW72Zkfr4f)@$^Bg2a_H^ zQV57yAYwe5Ahggt2n{A-YJeP`OAv9vRh$2a-DYDFUJtfR_%zHi;m4bKui5;5! zMnOtS>>iRiB0x6CE+7#5wpl^3o{34a9IRh*GEBeZYM}lk#>s!>@-{D3&rIgq?C5710Gn42dXYL!pkqxlAi%QmmjVq|1eYy_)SoC`BV paqH&$+Gm-VR9e6iDhptSsO$i{kAY$GTK(k7>-3X0uhZvY1OTUmZoU8j