diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt index b03a534fc..c37b24102 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt @@ -486,7 +486,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter } override fun insertStack(stack: ItemStackWrapper, simulate: Boolean): ItemStackWrapper { - if (energy.batteryLevel.isZero || !filter.match(stack.item)) + if (redstoneControl.isBlockedByRedstone || energy.batteryLevel.isZero || !filter.match(stack.item)) return stack val maxPossibleDemand = ITEM_STORAGE.energyPerOperation * stack.count @@ -531,7 +531,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter } override fun extractStack(id: UUID, amount: BigInteger, simulate: Boolean): ItemStackWrapper { - if (!amount.isPositive) + if (redstoneControl.isBlockedByRedstone || !amount.isPositive) return ItemStackWrapper.EMPTY val maxPossibleDemand = ITEM_STORAGE.energyPerOperation * amount diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt index 3b1762b84..19c4b3342 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt @@ -194,7 +194,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) } override fun insertItem(slot: Int, stack: ItemStack, simulate: Boolean): ItemStack { - if (!filter.match(stack)) + if (redstoneControl.isBlockedByRedstone || !filter.match(stack)) return stack val view = cell.storageGraph?.getVirtualComponent(ITEM_STORAGE) ?: return stack @@ -225,6 +225,9 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) } fun tick() { + if (redstoneControl.isBlockedByRedstone) + return + batteryChargeLoop() cell.tickEnergyDemanding() @@ -334,6 +337,9 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : } fun tick() { + if (redstoneControl.isBlockedByRedstone) + return + batteryChargeLoop() cell.tickEnergyDemanding() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StoragePowerSupplierBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StoragePowerSupplierBlockEntity.kt index d9cc36200..16c54f5e6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StoragePowerSupplierBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StoragePowerSupplierBlockEntity.kt @@ -76,6 +76,9 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState } fun tick() { + if (redstoneControl.isBlockedByRedstone) + return + batteryChargeLoop() if (energy.batteryLevel.isZero) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyCounterBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyCounterBlockEntity.kt index c7dbf226e..982838158 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyCounterBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyCounterBlockEntity.kt @@ -145,6 +145,9 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat override val energyFlow = FlowDirection.input(isInput) override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal { + if (redstoneControl.isBlockedByRedstone) + return Decimal.ZERO + val it = inputCapability.first if (it != null) { @@ -170,6 +173,9 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat } override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal { + if (redstoneControl.isBlockedByRedstone) + return Decimal.ZERO + val it = outputCapability.first if (it != null) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyServoBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyServoBlockEntity.kt index d7c4b9655..85d942161 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyServoBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyServoBlockEntity.kt @@ -133,6 +133,9 @@ class EnergyServoBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte } fun tick() { + if (redstoneControl.isBlockedByRedstone) + return + val charge = container[SLOT_CHARGE] val discharge = container[SLOT_DISCHARGE] 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 index 0cb929362..f0b8feab9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatteryAtlas.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatteryAtlas.kt @@ -22,9 +22,6 @@ data class MatteryAtlas( 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 grid(rows: Int, columns: Int) = GridAtlas(texture, this.width / rows, this.height / columns, rows = rows, columns = columns) - - @Deprecated("Construct grid directly instead") fun grid(width: Float, height: Float, rows: Int, columns: Int) = GridAtlas(texture, width, height, rows, columns) } 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 a2b160c72..c8fcecade 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 @@ -13,4 +13,5 @@ object WidgetLocation { 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) + val REDSTONE_CONTROLS = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/redstone.png"), 54f, 18f) } 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 84cde28be..1acecb411 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 @@ -46,4 +46,10 @@ object Widgets18 { val BUTTON_DISABLED_STRETCHABLE = makeButton(GRID) val BUTTON_DISABLED = GRID.next() val COOLDOWN = GRID.next() + + private val redstoneGrid = WidgetLocation.REDSTONE_CONTROLS.grid(rows = 1, columns = 3) + + val REDSTONE_IGNORED = redstoneGrid.next() + val REDSTONE_LOW = redstoneGrid.next() + val REDSTONE_HIGH = redstoneGrid.next() } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/HoloSignRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/HoloSignRenderer.kt index 5a5ed2bc9..80c8aa5c2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/HoloSignRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/HoloSignRenderer.kt @@ -31,7 +31,7 @@ class HoloSignRenderer(private val context: BlockEntityRendererProvider.Context) poseStack.pushPose() poseStack.rotateWithBlockFacing(tile.blockState.rotationThree) - poseStack.translate(0.5f, 0.5f, 0.6f) + poseStack.translate(0.5f, 0.5f, 0.5f) poseStack.scale(0.01f, 0.01f, 0.01f) val sorse = DynamicBufferSource.WORLD diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatteryScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatteryScreen.kt index 8679606a7..394c95677 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatteryScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatteryScreen.kt @@ -11,6 +11,7 @@ import net.minecraft.client.renderer.entity.ItemRenderer import net.minecraft.network.chat.Component import net.minecraft.world.entity.player.Inventory import net.minecraft.world.inventory.Slot +import net.minecraft.world.item.ItemStack import net.minecraftforge.client.event.ContainerScreenEvent.Render.Background import net.minecraftforge.client.event.ContainerScreenEvent.Render.Foreground import net.minecraftforge.common.MinecraftForge @@ -62,6 +63,40 @@ abstract class MatteryScreen(menu: T, inventory: Inventory, tit val quickCraftingType get() = quickCraftingType val isQuickCrafting get() = isQuickCrafting + fun renderItemStack(absoluteX: Float, absoluteY: Float, itemstack: ItemStack, countOverride: String? = null) { + if (!itemstack.isEmpty) { + RenderSystem.enableDepthTest() + + val systemPoseStack = RenderSystem.getModelViewStack() + + systemPoseStack.pushPose() + systemPoseStack.translate(absoluteX + 1f, absoluteY + 1f, 0f) + RenderSystem.applyModelViewMatrix() + RenderSystem.depthFunc(GL11.GL_LESS) + + // Thanks Mojang + // Very cool + // (for int x, int y, which are then cast into doubles anyway) + itemRenderer.blitOffset = 1f // Z pos + + itemRenderer.renderAndDecorateItem( + requireNotNull(ru.dbotthepony.mc.otm.client.minecraft.player) { "yo, dude, what the fuck" }, + itemstack, + 0, + 0, + (absoluteX + absoluteY * 1000f).toInt() + ) + + RenderSystem.depthFunc(GL11.GL_ALWAYS) + itemRenderer.renderGuiItemDecorations(font, itemstack, 0, 0, countOverride) + itemRenderer.blitOffset = 0f + + // too big accumulations can lead to Z near clipping issues + systemPoseStack.popPose() + RenderSystem.applyModelViewMatrix() + } + } + init { for (slot in menu.slots) { slot.x = Int.MAX_VALUE diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/HoloSignScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/HoloSignScreen.kt index 676642d71..213dba6a2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/HoloSignScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/HoloSignScreen.kt @@ -7,6 +7,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.Dock import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.input.NetworkedStringInputPanel import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.menu.decorative.HoloSignMenu @@ -24,6 +25,8 @@ class HoloSignScreen(menu: HoloSignMenu, inventory: Inventory, title: Component) lock.dockMargin = DockProperty(2f, 2f, 2f, 2f) lock.tooltip = TranslatableComponent("otm.gui.lock_holo_screen.tip") + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterBottlerScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterBottlerScreen.kt index dd91e10f2..713119729 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterBottlerScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterBottlerScreen.kt @@ -6,6 +6,7 @@ import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.client.screen.panels.* import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.MatterCapacitorSlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel @@ -37,10 +38,11 @@ class MatterBottlerScreen(menu: MatterBottlerMenu, inventory: Inventory, title: progress = ProgressGaugePanel(this, frame, menu.progressWidget, 90f, PROGRESS_ARROW_TOP) if (minecraft?.player?.isSpectator != true) { - val mode = ButtonPanel(this, frame, 46f, 69f, 100f, 20f, TranslatableComponent("otm.matter_bottler.switch_mode")) - mode.bind { menu.workFlow.switchValue() } + ButtonPanel(this, frame, 46f, 69f, 100f, 20f, TranslatableComponent("otm.matter_bottler.switch_mode"), onPress = menu.workFlow::switchValue) } + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterDecomposerScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterDecomposerScreen.kt index aa2143b70..ab2c64c78 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterDecomposerScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterDecomposerScreen.kt @@ -6,6 +6,7 @@ import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel @@ -27,6 +28,8 @@ class MatterDecomposerScreen(p_97741_: MatterDecomposerMenu, p_97742_: Inventory SlotPanel(this, frame, menu.outputMain, 74f, PROGRESS_SLOT_TOP) SlotPanel(this, frame, menu.outputStacking, 56f, PROGRESS_SLOT_TOP) + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterPanelScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterPanelScreen.kt index dda087779..87585c6c3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterPanelScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterPanelScreen.kt @@ -157,7 +157,7 @@ class MatterPanelScreen( } if (minecraft?.player?.isSpectator != true) { - ButtonPanel(this@MatterPanelScreen, frame, width = 80f, label = TranslatableComponent("otm.container.matter_panel.cancel_task"), onPress = { + ButtonPanel(this@MatterPanelScreen, frame, width = 80f, label = TranslatableComponent("otm.container.matter_panel.cancel_task"), onPress = Runnable { menu.requestTaskCancel(task.id) frame.remove() }).also { @@ -259,32 +259,32 @@ class MatterPanelScreen( } } - ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 8), onPress = { input.increase(8) }).also { + ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 8), onPress = Runnable { input.increase(8) }).also { it.dock = Dock.RIGHT it.dockLeft = 2f } - ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 64), onPress = { input.increase(64) }).also { + ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 64), onPress = Runnable { input.increase(64) }).also { it.dock = Dock.RIGHT it.dockLeft = 2f } - ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 256), onPress = { input.increase(256) }).also { + ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 256), onPress = Runnable { input.increase(256) }).also { it.dock = Dock.RIGHT it.dockLeft = 2f } - ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 8), onPress = { input.increase(-8) }).also { + ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 8), onPress = Runnable { input.increase(-8) }).also { it.dock = Dock.RIGHT it.dockLeft = 2f } - ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 64), onPress = { input.increase(-64) }).also { + ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 64), onPress = Runnable { input.increase(-64) }).also { it.dock = Dock.RIGHT it.dockLeft = 2f } - ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 256), onPress = { input.increase(-256) }).also { + ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 256), onPress = Runnable { input.increase(-256) }).also { it.dock = Dock.RIGHT it.dockLeft = 2f } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterRecyclerScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterRecyclerScreen.kt index ba839582a..beb48e502 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterRecyclerScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterRecyclerScreen.kt @@ -5,6 +5,7 @@ import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel @@ -23,6 +24,8 @@ class MatterRecyclerScreen(menu: MatterRecyclerMenu, inventory: Inventory, title ProgressGaugePanel(this, frame, menu.progress, 63f, PROGRESS_ARROW_TOP).flop = true SlotPanel(this, frame, menu.input, 93f, PROGRESS_SLOT_TOP) + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterReplicatorScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterReplicatorScreen.kt index 2305a1bfb..022b961ae 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterReplicatorScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterReplicatorScreen.kt @@ -5,6 +5,7 @@ import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel @@ -29,6 +30,8 @@ class MatterReplicatorScreen(p_97741_: MatterReplicatorMenu, p_97742_: Inventory SlotPanel(this, frame, menu.storageSlots[3], 80f, PROGRESS_SLOT_TOP + 22f) SlotPanel(this, frame, menu.storageSlots[4], 80f + 18f, PROGRESS_SLOT_TOP + 22f) + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterScannerScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterScannerScreen.kt index d08d3336f..524284ccc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterScannerScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterScannerScreen.kt @@ -6,6 +6,7 @@ import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.PatternGaugePanel import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel @@ -24,6 +25,8 @@ class MatterScannerScreen(p_97741_: MatterScannerMenu, p_97742_: Inventory, p_97 ProgressGaugePanel(this, frame, menu.progress, 63f, PROGRESS_ARROW_TOP).flop = true SlotPanel(this, frame, menu.input, 93f, PROGRESS_SLOT_TOP) + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/AbstractButtonPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/AbstractButtonPanel.kt new file mode 100644 index 000000000..15f224659 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/AbstractButtonPanel.kt @@ -0,0 +1,68 @@ +package ru.dbotthepony.mc.otm.client.screen.panels.button + +import com.mojang.blaze3d.platform.InputConstants +import net.minecraft.client.gui.screens.Screen +import net.minecraft.network.chat.Component +import ru.dbotthepony.mc.otm.client.playGuiClickSound +import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel +import java.util.function.IntConsumer +import java.util.function.IntPredicate + +abstract class AbstractButtonPanel( + screen: S, + parent: EditablePanel<*>?, + x: Float = 0f, + y: Float = 0f, + width: Float = 10f, + height: Float = 10f, +) : EditablePanel(screen, parent, x, y, width, height), IntPredicate { + var isPressed = false + protected set + + open var isDisabled = false + set(value) { + if (field != value) { + if (!value) { + isPressed = false + grabMouseInput = false + } + + field = value + } + } + + override fun test(value: Int): Boolean { + return value == InputConstants.MOUSE_BUTTON_LEFT + } + + protected abstract fun onClick(mouseButton: Int) + + override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { + if (isDisabled || isPressed || !test(button)) { + return true + } + + if (!tryToGrabMouseInput()) { + return true + } + + isPressed = true + playGuiClickSound() + return true + } + + override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean { + if (!isPressed || !test(button)) { + return true + } + + grabMouseInput = false + isPressed = false + + if (isHovered) { + onClick(button) + } + + return true + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/BooleanRectangleButtonPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/BooleanRectangleButtonPanel.kt index 74f75efa9..5d2563433 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/BooleanRectangleButtonPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/BooleanRectangleButtonPanel.kt @@ -20,12 +20,10 @@ abstract class BooleanRectangleButtonPanel( val skinElementInactive: AbstractMatterySprite? = null, val onChange: ((newValue: Boolean) -> Unit)? = null, ) : RectangleButtonPanel(screen, parent, x, y, width, height, null) { - override fun onClick(clickButton: Int) { - if (clickButton == InputConstants.MOUSE_BUTTON_LEFT) { - val newValue = !prop.value - prop.value = newValue - onChange?.invoke(newValue) - } + override fun onClick(mouseButton: Int) { + val newValue = !prop.value + prop.value = newValue + onChange?.invoke(newValue) } override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/ButtonPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/ButtonPanel.kt index d3aea862f..ac07c680c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/ButtonPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/ButtonPanel.kt @@ -9,6 +9,7 @@ import ru.dbotthepony.mc.otm.client.render.Widgets18 import ru.dbotthepony.mc.otm.client.render.drawAligned import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel import ru.dbotthepony.mc.otm.core.math.RGBAColor +import java.util.function.IntConsumer open class ButtonPanel( screen: S, @@ -17,9 +18,10 @@ open class ButtonPanel( y: Float = 0f, width: Float = 40f, height: Float = HEIGHT, - var label: Component -) : EditablePanel(screen, parent, x, y, width, height) { - constructor(screen: S, parent: EditablePanel<*>?, label: Component) : this(screen, parent, x = 0f, label = label) + var label: Component, + var onPress: IntConsumer? = null +) : AbstractButtonPanel(screen, parent, x, y, width, height) { + constructor(screen: S, parent: EditablePanel<*>?, label: Component, onPress: IntConsumer? = null) : this(screen, parent, x = 0f, label = label, onPress = onPress) constructor( screen: S, @@ -30,75 +32,28 @@ open class ButtonPanel( height: Float = HEIGHT, label: Component, onPress: Runnable - ) : this(screen, parent, x, y, width, height, label) { - this.callback = onPress - } - - protected var callback: Runnable? = null - protected var pressed = false - - protected open fun onClick(button: Int) { - callback?.run() - } - - override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { - if (isDisabled || pressed) { - return true - } - - if (!tryToGrabMouseInput()) { - return true - } - - pressed = true - playGuiClickSound() - return true - } - - override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean { - if (!pressed) { - return true - } - - grabMouseInput = false - pressed = false - - if (isHovered) { - onClick(button) - } - - return true - } - - fun bind(runnable: Runnable) { - callback = runnable - } + ) : this(screen, parent, x, y, width, height, label, onPress = IntConsumer { onPress.run() }) var textColor = RGBAColor.WHITE - var isDisabled = false - set(value) { - if (field != value) { - if (!value) { - pressed = false - grabMouseInput = false - } + override fun onClick(mouseButton: Int) { + onPress?.accept(mouseButton) + } - field = value - } - } - - override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) { + protected fun renderStretchableBackground(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) { if (isDisabled) { Widgets18.BUTTON_DISABLED_STRETCHABLE.render(stack, width = width, height = height) - } else if (pressed) { + } else if (isPressed) { Widgets18.BUTTON_PRESSED_STRETCHABLE.render(stack, width = width, height = height) } else if (isHovered) { Widgets18.BUTTON_HOVERED_STRETCHABLE.render(stack, width = width, height = height) } else { Widgets18.BUTTON_IDLE_STRETCHABLE.render(stack, width = width, height = height) } + } + override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) { + renderStretchableBackground(stack, mouseX, mouseY, partialTick) font.drawAligned(stack, label, TextAlign.CENTER_CENTER, width / 2f, height / 2f, textColor.toInt()) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt new file mode 100644 index 000000000..e5f01598c --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt @@ -0,0 +1,59 @@ +package ru.dbotthepony.mc.otm.client.screen.panels.button + +import com.mojang.blaze3d.vertex.PoseStack +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.Items +import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting +import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.client.render.Widgets18 +import ru.dbotthepony.mc.otm.client.screen.MatteryScreen +import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel +import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback + +fun > makeRedstoneSettingButton( + screen: S, + parent: EditablePanel<*>?, + x: Float = 0f, + y: Float = 0f, + control: IPlayerInputWithFeedback +): LargeEnumRectangleButtonPanel { + return object : LargeEnumRectangleButtonPanel( + screen, parent, x = x, y = y, + defaultValue = RedstoneSetting.LOW, enum = RedstoneSetting::class.java, + prop = control, + ) { + override var isDisabled: Boolean + get() = !control.test(minecraft.player) + set(value) {} + + init { + add(RedstoneSetting.IGNORED, tooltip = RedstoneSetting.IGNORED.description, skinElement = Widgets18.REDSTONE_IGNORED) + add(RedstoneSetting.LOW, tooltip = RedstoneSetting.LOW.description, skinElement = Widgets18.REDSTONE_LOW) + add(RedstoneSetting.HIGH, tooltip = RedstoneSetting.HIGH.description, skinElement = Widgets18.REDSTONE_HIGH) + } + } +} + +fun > makeDeviceControls( + screen: S, + parent: FramePanel, + redstone: IPlayerInputWithFeedback? = null +): EditablePanel { + val panel = object : EditablePanel(screen, parent, width = LargeEnumRectangleButtonPanel.SIZE, height = 0f, x = parent.width + 3f) { + override fun tick() { + super.tick() + x = parent.width + 3f + y = 0f + } + } + + var y = 0f + + if (redstone != null) { + y += makeRedstoneSettingButton(screen, panel, y = y, control = redstone).height + 2f + } + + panel.height = (y - 2f).coerceAtLeast(0f) + return panel +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/CheckBoxInputPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/CheckBoxInputPanel.kt index bc96b8d98..ff562de31 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/CheckBoxInputPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/CheckBoxInputPanel.kt @@ -1,8 +1,10 @@ package ru.dbotthepony.mc.otm.client.screen.panels.button import net.minecraft.client.gui.screens.Screen +import net.minecraft.world.entity.player.Player import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel +import ru.dbotthepony.mc.otm.core.GetterSetter import ru.dbotthepony.mc.otm.core.value import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback @@ -15,7 +17,7 @@ open class CheckBoxInputPanel @JvmOverloads constructor( width: Float = REGULAR_DIMENSIONS + 120f, height: Float = REGULAR_DIMENSIONS ) : CheckBoxPanel(screen, parent, x, y, width, height) { - override var checked: Boolean + override var isChecked: Boolean get() = widget.value set(value) {} @@ -23,7 +25,7 @@ open class CheckBoxInputPanel @JvmOverloads constructor( get() = !widget.test(minecraft.player) set(value) {} - override fun onClick() { - widget.accept(!checked) + override fun onClick(mouseButton: Int) { + widget.accept(!isChecked) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/CheckBoxPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/CheckBoxPanel.kt index 611c17599..a0281a043 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/CheckBoxPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/CheckBoxPanel.kt @@ -2,11 +2,13 @@ package ru.dbotthepony.mc.otm.client.screen.panels.button import com.mojang.blaze3d.platform.InputConstants import com.mojang.blaze3d.vertex.PoseStack +import it.unimi.dsi.fastutil.booleans.BooleanConsumer import net.minecraft.client.gui.screens.Screen import ru.dbotthepony.mc.otm.client.playGuiClickSound import ru.dbotthepony.mc.otm.client.render.AbstractMatterySprite import ru.dbotthepony.mc.otm.client.render.WidgetLocation import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel +import ru.dbotthepony.mc.otm.core.TextComponent open class CheckBoxPanel @JvmOverloads constructor( screen: S, @@ -14,34 +16,42 @@ open class CheckBoxPanel @JvmOverloads constructor( x: Float = 0f, y: Float = 0f, width: Float = REGULAR_DIMENSIONS, - height: Float = REGULAR_DIMENSIONS -) : EditablePanel(screen, parent, x, y, width, height) { - open var checked = false - open var isDisabled = false - protected var isPressed = false + height: Float = REGULAR_DIMENSIONS, + var onPress: BooleanConsumer? = null +) : AbstractButtonPanel(screen, parent, x, y, width, height) { + open var isChecked = false - override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) { + open val IDLE_UNCHECKED: AbstractMatterySprite = Companion.IDLE_UNCHECKED + open val IDLE_CHECKED: AbstractMatterySprite = Companion.IDLE_CHECKED + open val HOVERED_UNCHECKED: AbstractMatterySprite = Companion.HOVERED_UNCHECKED + open val HOVERED_CHECKED: AbstractMatterySprite = Companion.HOVERED_CHECKED + open val PRESSED_UNCHECKED: AbstractMatterySprite = Companion.PRESSED_UNCHECKED + open val PRESSED_CHECKED: AbstractMatterySprite = Companion.PRESSED_CHECKED + open val DISABLED_UNCHECKED: AbstractMatterySprite = Companion.DISABLED_UNCHECKED + open val DISABLED_CHECKED: AbstractMatterySprite = Companion.DISABLED_CHECKED + + protected fun renderCheckboxBackground(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) { if (isDisabled) { - if (checked) { + if (isChecked) { DISABLED_CHECKED.render(stack, width = width, height = height) } else { DISABLED_UNCHECKED.render(stack, width = width, height = height) } } else { if (isPressed) { - if (checked) { + if (isChecked) { PRESSED_CHECKED.render(stack, width = width, height = height) } else { PRESSED_UNCHECKED.render(stack, width = width, height = height) } } else if (isHovered) { - if (checked) { + if (isChecked) { HOVERED_CHECKED.render(stack, width = width, height = height) } else { HOVERED_UNCHECKED.render(stack, width = width, height = height) } } else { - if (checked) { + if (isChecked) { IDLE_CHECKED.render(stack, width = width, height = height) } else { IDLE_UNCHECKED.render(stack, width = width, height = height) @@ -50,31 +60,13 @@ open class CheckBoxPanel @JvmOverloads constructor( } } - protected open fun onClick() { - checked = !checked + override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) { + renderCheckboxBackground(stack, mouseX, mouseY, partialTick) } - override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { - if (!isDisabled && button == InputConstants.MOUSE_BUTTON_LEFT) { - grabMouseInput = true - isPressed = true - playGuiClickSound() - } - - return true - } - - override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean { - if (isPressed && button == InputConstants.MOUSE_BUTTON_LEFT) { - if (isHovered) { - onClick() - } - - isPressed = false - grabMouseInput = false - } - - return true + override fun onClick(mouseButton: Int) { + isChecked = !isChecked + onPress?.accept(isChecked) } companion object { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/EnumRectangleButtonPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/EnumRectangleButtonPanel.kt index 88ebba99e..e6e8e65f2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/EnumRectangleButtonPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/EnumRectangleButtonPanel.kt @@ -12,6 +12,7 @@ import ru.dbotthepony.mc.otm.core.GetterSetter import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.next import ru.dbotthepony.mc.otm.core.prev +import ru.dbotthepony.mc.otm.core.util.EnumValueCodec import ru.dbotthepony.mc.otm.core.value import java.util.* import kotlin.collections.ArrayList @@ -23,31 +24,25 @@ abstract class EnumRectangleButtonPanel>( y: Float = 0f, width: Float, height: Float, - val enum: Class, + enum: Class, val prop: GetterSetter, val defaultValue: T, - val onChange: ((newValue: T) -> Unit)? = null, ) : RectangleButtonPanel(screen, parent, x, y, width, height, null) { - private var building = true + val enum = EnumValueCodec.searchClass(enum) + private var isBuilding = true - protected val enumMapping = EnumMap>(enum) - protected val tooltipMapping = EnumMap(enum) + data class Entry>( + val key: T, + val skinElement: AbstractMatterySprite?, + val winding: UVWindingOrder = UVWindingOrder.NORMAL, + val tooltip: Component? = null + ) - fun addTooltip(value: T, component: Component): EnumRectangleButtonPanel { - check(tooltipMapping.put(value, component) == null) { "Already has mapping for $value" } - return this - } - - var mainTooltip: Component? = null - set(value) { - if (field != null) { - throw UnsupportedOperationException("Write once only") - } - - field = value - } + protected val enumMapping = EnumMap>(enum) fun isFullyDefined(): Boolean { + if (!isBuilding) return true + for (value in enum.enumConstants) { if (enumMapping[value] == null) { return false @@ -69,77 +64,54 @@ abstract class EnumRectangleButtonPanel>( return missing } - fun add(value: T, skinElement: AbstractMatterySprite, winding: UVWindingOrder = UVWindingOrder.NORMAL): EnumRectangleButtonPanel { - return add(value, skinElement to winding) + fun add(key: T, skinElement: AbstractMatterySprite? = null, tooltip: Component? = null, winding: UVWindingOrder = UVWindingOrder.NORMAL): EnumRectangleButtonPanel { + return add(Entry(key = key, skinElement = skinElement, winding = winding, tooltip = tooltip)) } - fun add(value: T, skinElement: AbstractMatterySprite, component: Component, winding: UVWindingOrder = UVWindingOrder.NORMAL): EnumRectangleButtonPanel { - return add(value, component, skinElement to winding) - } - - fun add(value: T, component: Component, skinElement: AbstractMatterySprite, winding: UVWindingOrder = UVWindingOrder.NORMAL): EnumRectangleButtonPanel { - return add(value, component, skinElement to winding) - } - - fun add(value: T, pair: Pair): EnumRectangleButtonPanel { - check(building) { "Not building" } - check(enumMapping.put(value, pair) == null) { "Already has mapping for $value" } - - if (enumMapping.size == enum.enumConstants.size) { - finish() - } - + fun add(entry: Entry): EnumRectangleButtonPanel { + check(isBuilding) { "Not building" } + check(enumMapping.put(entry.key, entry) == null) { "Already has mapping for ${entry.key}" } + if (enumMapping.size == enum.enumConstants.size) finish() return this } - fun add(value: T, component: Component, pair: Pair): EnumRectangleButtonPanel { - addTooltip(value, component) - return add(value, pair) - } - fun finish(): EnumRectangleButtonPanel { - check(building) { "Not building" } - check(isFullyDefined()) { - "Not all enums having their mapping defined, missing are: ${missingValues.joinToString(", ")}" - } - - building = false + check(isBuilding) { "Not building" } + check(isFullyDefined()) { "Not all enums having their mapping defined, missing are: ${missingValues.joinToString(", ")}" } + isBuilding = false return this } override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) { - check(!building) { "Still building this button!" } + check(!isBuilding) { "Still building this button!" } super.innerRender(stack, mouseX, mouseY, partialTick) - val pair = checkNotNull(enumMapping[prop.get()]) { "HOW" } - pair.first.render(stack, 0f, 0f, width, height, pair.second) + val entry = checkNotNull(enumMapping[prop.get()]) { "HOW" } + entry.skinElement?.render(stack, 0f, 0f, width, height, entry.winding) } override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { - check(!building) { "Still building this button!" } + check(!isBuilding) { "Still building this button!" } return super.mouseClickedInner(x, y, button) } override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean { - check(!building) { "Still building this button!" } + check(!isBuilding) { "Still building this button!" } return super.mouseReleasedInner(x, y, button) } - override fun onClick(clickButton: Int) { - when (clickButton) { - InputConstants.MOUSE_BUTTON_LEFT -> { - prop.value = prop.value.next(enum.enumConstants) - onChange?.invoke(prop.get()) - } - - InputConstants.MOUSE_BUTTON_RIGHT -> { - prop.value = prop.value.prev(enum.enumConstants) - onChange?.invoke(prop.get()) - } + override fun test(value: Int): Boolean { + return value == InputConstants.MOUSE_BUTTON_LEFT || + value == InputConstants.MOUSE_BUTTON_RIGHT || + value == InputConstants.MOUSE_BUTTON_MIDDLE + } + override fun onClick(mouseButton: Int) { + when (mouseButton) { + InputConstants.MOUSE_BUTTON_LEFT -> prop.value = prop.value.next(enum.enumConstants) + InputConstants.MOUSE_BUTTON_RIGHT -> prop.value = prop.value.prev(enum.enumConstants) InputConstants.MOUSE_BUTTON_MIDDLE -> { - if (prop.get() != defaultValue) { + if (prop.value != defaultValue) { prop.value = defaultValue - onChange?.invoke(prop.get()) } } } @@ -150,33 +122,27 @@ abstract class EnumRectangleButtonPanel>( return super.innerRenderTooltips(stack, mouseX, mouseY, partialTick) } - if (mainTooltip == null && tooltipMapping.size == 0) { + if (tooltip == null && tooltipList == null && enumMapping.values.none { it.tooltip != null }) { return super.innerRenderTooltips(stack, mouseX, mouseY, partialTick) } val listing = ArrayList() - if (mainTooltip != null) { - listing.add(mainTooltip!!) + if (tooltipList != null) { + listing.addAll(tooltipList!!) + listing.add(SPACE) + } else if (tooltip != null) { + listing.add(tooltip!!) listing.add(SPACE) } - for ((key, value) in tooltipMapping) { - if (key == prop.get()) { - listing.add(value.copy().withStyle(ChatFormatting.WHITE)) - } else { - listing.add(value.copy().withStyle(ChatFormatting.GRAY)) + for (entry in enumMapping.values) { + if (entry.tooltip != null) { + listing.add(entry.tooltip.copy().withStyle(if (entry.key == prop.get()) ChatFormatting.WHITE else ChatFormatting.GRAY)) } } - screen.renderComponentTooltip( - stack, - listing, - mouseX.toInt(), - mouseY.toInt(), - font - ) - + screen.renderComponentTooltip(stack, listing, mouseX.toInt(), mouseY.toInt(), font) return true } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/LargeEnumRectangleButtonPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/LargeEnumRectangleButtonPanel.kt index 2eae319de..2e0925ad0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/LargeEnumRectangleButtonPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/LargeEnumRectangleButtonPanel.kt @@ -15,8 +15,7 @@ open class LargeEnumRectangleButtonPanel>( enum: Class, prop: GetterSetter, defaultValue: T, - onChange: ((newValue: T) -> Unit)? = null, -) : EnumRectangleButtonPanel(screen, parent, x, y, width, height, enum, prop, defaultValue, onChange) { +) : EnumRectangleButtonPanel(screen, parent, x, y, width, height, enum, prop, defaultValue) { final override val IDLE = Widgets18.BUTTON_IDLE final override val HOVERED = Widgets18.BUTTON_HOVERED final override val PRESSED = Widgets18.BUTTON_PRESSED diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/RectangleButtonPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/RectangleButtonPanel.kt index ed7340ead..6a72b0dc7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/RectangleButtonPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/RectangleButtonPanel.kt @@ -5,6 +5,8 @@ import net.minecraft.client.gui.screens.Screen import ru.dbotthepony.mc.otm.client.playGuiClickSound import ru.dbotthepony.mc.otm.client.render.AbstractMatterySprite import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel +import ru.dbotthepony.mc.otm.core.TextComponent +import java.util.function.IntConsumer @Suppress("PropertyName") abstract class RectangleButtonPanel( @@ -14,35 +16,21 @@ abstract class RectangleButtonPanel( y: Float = 0f, width: Float, height: Float, - val onPress: ((clickButton: Int) -> Unit)? = null, -) : EditablePanel(screen, parent, x, y, width, height) { - protected var pressed = false - - protected open fun onClick(clickButton: Int) { - onPress?.invoke(clickButton) - } - + var onPress: IntConsumer? = null, +) : AbstractButtonPanel(screen, parent, x, y, width, height) { abstract val PRESSED: AbstractMatterySprite abstract val HOVERED: AbstractMatterySprite abstract val IDLE: AbstractMatterySprite abstract val DISABLED: AbstractMatterySprite - var isDisabled = false - set(value) { - if (field != value) { - if (!value) { - pressed = false - grabMouseInput = false - } + override fun onClick(mouseButton: Int) { + onPress?.accept(mouseButton) + } - field = value - } - } - - override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) { + protected fun renderSquareButton(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) { if (isDisabled) { DISABLED.render(stack, 0f, 0f, width, height) - } else if (pressed) { + } else if (isPressed) { PRESSED.render(stack, 0f, 0f, width, height) } else if (isHovered) { HOVERED.render(stack, 0f, 0f, width, height) @@ -51,31 +39,7 @@ abstract class RectangleButtonPanel( } } - override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { - if (!isDisabled) { - if (!pressed) { - playGuiClickSound() - } - - if (tryToGrabMouseInput()) { - pressed = true - } - } - - return true - } - - override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean { - if (!isDisabled && pressed) { - pressed = false - - if (isHovered) { - onClick(button) - } - } - - grabMouseInput = false - - return true + override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) { + renderSquareButton(stack, mouseX, mouseY, partialTick) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/SmallEnumRectangleButtonPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/SmallEnumRectangleButtonPanel.kt index c432c73a2..29444e7db 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/SmallEnumRectangleButtonPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/SmallEnumRectangleButtonPanel.kt @@ -15,8 +15,7 @@ open class SmallEnumRectangleButtonPanel>( enum: Class, prop: GetterSetter, defaultValue: T, - onChange: ((newValue: T) -> Unit)? = null, -) : EnumRectangleButtonPanel(screen, parent, x, y, width, height, enum, prop, defaultValue, onChange) { +) : EnumRectangleButtonPanel(screen, parent, x, y, width, height, enum, prop, defaultValue) { final override val IDLE = Widgets8.BUTTON_IDLE final override val HOVERED = Widgets8.BUTTON_HOVERED final override val PRESSED = Widgets8.BUTTON_PRESSED diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/QueryUserPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/QueryUserPanel.kt index 8e71cecbd..78e634dec 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/QueryUserPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/QueryUserPanel.kt @@ -44,22 +44,16 @@ open class QueryUserPanel( this.height = height + bottom.height + PADDING + PADDING_TOP + 4f - ButtonPanel(screen, bottom, width = font.width(TranslatableComponent("otm.gui.cancel")) + 12f, label = TranslatableComponent("otm.gui.cancel")).also { - it.bind { - onCancel?.run() - this.remove() - } - - it.dock = Dock.RIGHT - } + ButtonPanel(screen, bottom, width = font.width(TranslatableComponent("otm.gui.cancel")) + 12f, label = TranslatableComponent("otm.gui.cancel"), onPress = Runnable { + onCancel?.run() + this.remove() + }).dock = Dock.RIGHT if (onConfirm != null) { - ButtonPanel(screen, bottom, width = font.width(TranslatableComponent("otm.gui.confirm")) + 12f, label = TranslatableComponent("otm.gui.confirm")).also { - it.bind { - onConfirm.run() - this.remove() - } - + ButtonPanel(screen, bottom, width = font.width(TranslatableComponent("otm.gui.confirm")) + 12f, label = TranslatableComponent("otm.gui.confirm"), onPress = Runnable { + onConfirm.run() + this.remove() + }).also { it.dock = Dock.RIGHT it.dockRight = 2f } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt index 8bb20e1cd..37422cba5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt @@ -6,8 +6,6 @@ import net.minecraft.client.renderer.GameRenderer import net.minecraft.network.chat.Component import net.minecraft.world.item.ItemStack import net.minecraftforge.client.extensions.common.IClientItemExtensions -import org.lwjgl.opengl.GL11 -import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.render.* import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel @@ -27,40 +25,11 @@ abstract class AbstractSlotPanel> @JvmOverloads constru SLOT_BACKGROUND.render(stack, width = width, height = height) } - protected open fun renderRegular(stack: PoseStack, itemstack: ItemStack, count_override: String? = null) { + protected open fun renderRegular(stack: PoseStack, itemstack: ItemStack, countOverride: String? = null) { RenderSystem.setShader(GameRenderer::getPositionTexShader) if (!itemstack.isEmpty) { - RenderSystem.enableDepthTest() - - val systemPoseStack = RenderSystem.getModelViewStack() - - systemPoseStack.pushPose() - systemPoseStack.translate((absoluteX + 1f).toDouble(), (absoluteY + 1f).toDouble(), 0.0) - RenderSystem.applyModelViewMatrix() - RenderSystem.depthFunc(GL11.GL_LESS) - - // Thanks Mojang - // Very cool - // (for int x, int y, which are then cast into doubles anyway) - screen.itemRenderer.blitOffset = 1f // Z pos - - screen.itemRenderer.renderAndDecorateItem( - requireNotNull(minecraft.player) { "yo, dude, what the fuck" }, - itemstack, - 0, - 0, - (absoluteX + absoluteY * 1000f).toInt() - ) - - RenderSystem.depthFunc(GL11.GL_ALWAYS) - screen.itemRenderer.renderGuiItemDecorations(screen.font, itemstack, 0, 0, count_override) - screen.itemRenderer.blitOffset = 0f - - // too big accumulations can lead to Z near clipping issues - systemPoseStack.popPose() - RenderSystem.applyModelViewMatrix() - + screen.renderItemStack(absoluteX, absoluteY, itemstack, countOverride) clearDepth(stack) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/ItemMonitorScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/ItemMonitorScreen.kt index e1b67b61a..902b1e211 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/ItemMonitorScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/ItemMonitorScreen.kt @@ -139,16 +139,15 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp val refillPriority = SmallEnumRectangleButtonPanel(this, arrowLine, enum = ItemMonitorPlayerSettings.IngredientPriority::class.java, - prop = menu.settings::ingredientPriority.asGetterSetter(), - defaultValue = ItemMonitorPlayerSettings.IngredientPriority.SYSTEM, - onChange = { menu.sendSettingsToServer() }) + prop = menu.settings::ingredientPriority.asGetterSetter(watch = { _, _ -> menu.sendSettingsToServer() }), + defaultValue = ItemMonitorPlayerSettings.IngredientPriority.SYSTEM) - refillPriority.mainTooltip = TranslatableComponent("otm.gui.item_monitor.refill_source.desc") - refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.SYSTEM, ItemMonitorPlayerSettings.IngredientPriority.SYSTEM.component, Widgets8.WHITE_ARROW_DOWN, UVWindingOrder.FLIP) - refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.INVENTORY, ItemMonitorPlayerSettings.IngredientPriority.INVENTORY.component, Widgets8.WHITE_ARROW_DOWN) - refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.INVENTORY_FIRST, ItemMonitorPlayerSettings.IngredientPriority.INVENTORY_FIRST.component, Widgets8.ARROW_SIDEWAYS, UVWindingOrder.FLIP) - refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.SYSTEM_FIRST, ItemMonitorPlayerSettings.IngredientPriority.SYSTEM_FIRST.component, Widgets8.ARROW_SIDEWAYS) - refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.DO_NOT, ItemMonitorPlayerSettings.IngredientPriority.DO_NOT.component, Widgets8.MINUS) + refillPriority.tooltip = TranslatableComponent("otm.gui.item_monitor.refill_source.desc") + refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.SYSTEM, tooltip = ItemMonitorPlayerSettings.IngredientPriority.SYSTEM.component, skinElement = Widgets8.WHITE_ARROW_DOWN, winding = UVWindingOrder.FLIP) + refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.INVENTORY, tooltip = ItemMonitorPlayerSettings.IngredientPriority.INVENTORY.component, skinElement = Widgets8.WHITE_ARROW_DOWN) + refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.INVENTORY_FIRST, tooltip = ItemMonitorPlayerSettings.IngredientPriority.INVENTORY_FIRST.component, skinElement = Widgets8.ARROW_SIDEWAYS, winding = UVWindingOrder.FLIP) + refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.SYSTEM_FIRST, tooltip = ItemMonitorPlayerSettings.IngredientPriority.SYSTEM_FIRST.component, skinElement = Widgets8.ARROW_SIDEWAYS) + refillPriority.add(ItemMonitorPlayerSettings.IngredientPriority.DO_NOT, tooltip = ItemMonitorPlayerSettings.IngredientPriority.DO_NOT.component, skinElement = Widgets8.MINUS) refillPriority.dock = Dock.LEFT @@ -161,25 +160,23 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp val resultTarget = SmallEnumRectangleButtonPanel(this, resultAndButtons, y = 38f, enum = ItemMonitorPlayerSettings.ResultTarget::class.java, - prop = menu.settings::resultTarget.asGetterSetter(), - defaultValue = ItemMonitorPlayerSettings.ResultTarget.MIXED, - onChange = { menu.sendSettingsToServer() }) + prop = menu.settings::resultTarget.asGetterSetter(watch = { _, _ -> menu.sendSettingsToServer() }), + defaultValue = ItemMonitorPlayerSettings.ResultTarget.MIXED) - resultTarget.mainTooltip = TranslatableComponent("otm.gui.item_monitor.result_target.desc") - resultTarget.add(ItemMonitorPlayerSettings.ResultTarget.MIXED, ItemMonitorPlayerSettings.ResultTarget.MIXED.component, Widgets8.ARROW_SIDEWAYS) - resultTarget.add(ItemMonitorPlayerSettings.ResultTarget.ALL_INVENTORY, ItemMonitorPlayerSettings.ResultTarget.ALL_INVENTORY.component, Widgets8.ARROW_PAINTED_UP, UVWindingOrder.FLIP) - resultTarget.add(ItemMonitorPlayerSettings.ResultTarget.ALL_SYSTEM, ItemMonitorPlayerSettings.ResultTarget.ALL_SYSTEM.component, Widgets8.ARROW_PAINTED_UP) + resultTarget.tooltip = TranslatableComponent("otm.gui.item_monitor.result_target.desc") + resultTarget.add(ItemMonitorPlayerSettings.ResultTarget.MIXED, tooltip = ItemMonitorPlayerSettings.ResultTarget.MIXED.component, skinElement = Widgets8.ARROW_SIDEWAYS) + resultTarget.add(ItemMonitorPlayerSettings.ResultTarget.ALL_INVENTORY, tooltip = ItemMonitorPlayerSettings.ResultTarget.ALL_INVENTORY.component, skinElement = Widgets8.ARROW_PAINTED_UP, winding = UVWindingOrder.FLIP) + resultTarget.add(ItemMonitorPlayerSettings.ResultTarget.ALL_SYSTEM, tooltip = ItemMonitorPlayerSettings.ResultTarget.ALL_SYSTEM.component, skinElement = Widgets8.ARROW_PAINTED_UP) val craftingAmount = SmallEnumRectangleButtonPanel(this, resultAndButtons, x = 10f, y = 38f, enum = ItemMonitorPlayerSettings.Amount::class.java, - prop = menu.settings::craftingAmount.asGetterSetter(), - defaultValue = ItemMonitorPlayerSettings.Amount.STACK, - onChange = { menu.sendSettingsToServer() }) + prop = menu.settings::craftingAmount.asGetterSetter(watch = { _, _ -> menu.sendSettingsToServer() }), + defaultValue = ItemMonitorPlayerSettings.Amount.STACK) - craftingAmount.mainTooltip = TranslatableComponent("otm.gui.item_monitor.amount.desc") - craftingAmount.add(ItemMonitorPlayerSettings.Amount.ONE, ItemMonitorPlayerSettings.Amount.ONE.component, Widgets8.ONE) - craftingAmount.add(ItemMonitorPlayerSettings.Amount.STACK, ItemMonitorPlayerSettings.Amount.STACK.component, Widgets8.S) - craftingAmount.add(ItemMonitorPlayerSettings.Amount.FULL, ItemMonitorPlayerSettings.Amount.FULL.component, Widgets8.F) + craftingAmount.tooltip = TranslatableComponent("otm.gui.item_monitor.amount.desc") + craftingAmount.add(ItemMonitorPlayerSettings.Amount.ONE, tooltip = ItemMonitorPlayerSettings.Amount.ONE.component, skinElement = Widgets8.ONE) + craftingAmount.add(ItemMonitorPlayerSettings.Amount.STACK, tooltip = ItemMonitorPlayerSettings.Amount.STACK.component, skinElement = Widgets8.S) + craftingAmount.add(ItemMonitorPlayerSettings.Amount.FULL, tooltip = ItemMonitorPlayerSettings.Amount.FULL.component, skinElement = Widgets8.F) val craftingHistory = GridPanel(this, bottomPanel, width = 3 * 18f, height = 3 * 18f, columns = 3, rows = 3) craftingHistory.dock = Dock.LEFT diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageBusScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageBusScreen.kt index 7d0f3e5f0..8d759e8c3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageBusScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageBusScreen.kt @@ -6,6 +6,7 @@ import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.client.screen.panels.* import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.FilterSlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel @@ -28,6 +29,8 @@ class StorageBusScreen(menu: StorageBusMenu, inventory: Inventory, title: Compon CheckBoxLabelInputPanel(this, frame, menu.busFilterState, TranslatableComponent("otm.gui.filter.is_whitelist"), 59f, 78f, width = 170f) + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageExporterScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageExporterScreen.kt index 02bd2b59f..720e7f8c6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageExporterScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageExporterScreen.kt @@ -6,6 +6,7 @@ import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.client.screen.panels.* import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.FilterSlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel @@ -28,6 +29,8 @@ class StorageExporterScreen(menu: StorageExporterMenu, inventory: Inventory, tit CheckBoxLabelInputPanel(this, frame, menu.busFilterState, TranslatableComponent("otm.gui.filter.is_whitelist"), 59f, 78f, width = 170f) + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageImporterScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageImporterScreen.kt index 12f1b2155..27c850202 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageImporterScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StorageImporterScreen.kt @@ -6,6 +6,7 @@ import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.client.screen.panels.* import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.FilterSlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel @@ -28,6 +29,8 @@ class StorageImporterScreen(menu: StorageImporterMenu, inventory: Inventory, tit CheckBoxLabelInputPanel(this, frame, menu.busFilterState, TranslatableComponent("otm.gui.filter.is_whitelist"), 59f, 78f, width = 170f) + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StoragePowerSupplierScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StoragePowerSupplierScreen.kt index 294f9fcbb..d50b6a97c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StoragePowerSupplierScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/storage/StoragePowerSupplierScreen.kt @@ -5,6 +5,7 @@ import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.client.screen.panels.* +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.widget.HorizontalPowerGaugePanel @@ -66,6 +67,8 @@ class StoragePowerSupplierScreen(menu: StoragePowerSupplierMenu, inventory: Inve } } + makeDeviceControls(this, frame, redstone = menu.redstone) + 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 62069e936..7e621b80b 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 @@ -28,6 +28,7 @@ import ru.dbotthepony.mc.otm.client.render.drawRect import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.* import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel +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.slot.EquipmentBatterySlotPanel @@ -643,12 +644,10 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I researchCanvas.parent = research val bottom = EditablePanel(this, research, 0f, 0f, 0f, 20f) - val close = ButtonPanel(this, bottom, 0f, 0f, 90f, 20f, TranslatableComponent("otm.container.matter_panel.close")) + val close = ButtonPanel(this, bottom, 0f, 0f, 90f, 20f, TranslatableComponent("otm.container.matter_panel.close"), onPress = Runnable { research!!.remove() }) bottom.dock = Dock.BOTTOM - close.dock = Dock.RIGHT - close.bind { research!!.remove() } bottom.setDockMargin(0f, 0f, 4f, 4f) researchCanvas.setDockMargin(4f, 4f, 4f, 4f) @@ -732,6 +731,8 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I this.playerStrip = playerStrip + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/BatteryBankScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/BatteryBankScreen.kt index 9308536ac..bdc576dd3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/BatteryBankScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/BatteryBankScreen.kt @@ -6,12 +6,13 @@ import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel class BatteryBankScreen(menu: BatteryBankMenu, p_97742_: Inventory, p_97743_: Component) : MatteryScreen(menu, p_97742_, p_97743_) { - override fun makeMainFrame(): FramePanel> { + override fun makeMainFrame(): FramePanel> { val frame = super.makeMainFrame()!! WidePowerGaugePanel(this, frame, menu.powerLevel, LEFT_MARGIN, GAUGE_TOP_WITHOUT_SLOT) @@ -22,6 +23,8 @@ class BatteryBankScreen(menu: BatteryBankMenu, p_97742_: Inventory, p_97743_: Co for (i in 6 .. 11) BatterySlotPanel(this, frame, menu.storageSlots[i], 44f + 18 * (i - 6), 32f + 18f) + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/ChemicalGeneratorScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/ChemicalGeneratorScreen.kt index e61fdb4be..b0394c745 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/ChemicalGeneratorScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/ChemicalGeneratorScreen.kt @@ -4,6 +4,7 @@ import net.minecraft.network.chat.Component import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel @@ -12,7 +13,7 @@ import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel import ru.dbotthepony.mc.otm.menu.tech.ChemicalGeneratorMenu class ChemicalGeneratorScreen(menu: ChemicalGeneratorMenu, inventory: Inventory, title: Component) : MatteryScreen(menu, inventory, title) { - override fun makeMainFrame(): FramePanel> { + override fun makeMainFrame(): FramePanel> { val frame = super.makeMainFrame()!! WidePowerGaugePanel(this, frame, menu.energy, LEFT_MARGIN, GAUGE_TOP_WITH_SLOT) @@ -33,6 +34,8 @@ class ChemicalGeneratorScreen(menu: ChemicalGeneratorMenu, inventory: Inventory, SlotPanel(this, frame, menu.residueSlot, 56f, PROGRESS_SLOT_TOP) SlotPanel(this, frame, menu.fuelSlot, 104f, PROGRESS_SLOT_TOP) + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyCounterScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyCounterScreen.kt index a33529277..6fb3052db 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyCounterScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyCounterScreen.kt @@ -6,6 +6,7 @@ import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.client.screen.panels.* import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.input.NetworkNumberInputPanel import ru.dbotthepony.mc.otm.core.util.formatPower import ru.dbotthepony.mc.otm.menu.tech.EnergyCounterMenu @@ -81,10 +82,9 @@ class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title: label.setDockMargin(4f, 0f, 0f, 0f) if (!menu.ply.isSpectator) { - val button = ButtonPanel(this, frame, 0f, 0f, 0f, 20f, TranslatableComponent("block.overdrive_that_matters.energy_counter.switch")) + val button = ButtonPanel(this, frame, 0f, 0f, 0f, 20f, TranslatableComponent("block.overdrive_that_matters.energy_counter.switch"), onPress = Runnable { menu.switchDirection.input(null) }) button.dock = Dock.TOP button.setDockMargin(4f, 0f, 4f, 0f) - button.bind { menu.switchDirection.input(null) } } val infoPanels = frame.fetchChildren() @@ -107,6 +107,8 @@ class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title: limitsTab.onClose!!.run() + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyServoScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyServoScreen.kt index c49970006..a33f5d9e6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyServoScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyServoScreen.kt @@ -9,6 +9,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.Dock import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.widget.HorizontalPowerGaugePanel import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel import ru.dbotthepony.mc.otm.client.screen.widget.TallHorizontalPowerGaugePanel @@ -61,6 +62,8 @@ class EnergyServoScreen(menu: EnergyServoMenu, inventory: Inventory, title: Comp it.dockRight } + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/PlatePressScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/PlatePressScreen.kt index e4e6f1f1c..cd70a1ef1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/PlatePressScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/PlatePressScreen.kt @@ -5,6 +5,7 @@ import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel @@ -12,7 +13,7 @@ import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu class PlatePressScreen(menu: PlatePressMenu, inventory: Inventory, title: Component) : MatteryScreen(menu, inventory, title) { - override fun makeMainFrame(): FramePanel> { + override fun makeMainFrame(): FramePanel> { val frame = super.makeMainFrame()!! WidePowerGaugePanel(this, frame, menu.powerWidget, LEFT_MARGIN, GAUGE_TOP_WITH_SLOT) @@ -22,6 +23,8 @@ class PlatePressScreen(menu: PlatePressMenu, inventory: Inventory, title: Compon ProgressGaugePanel(this, frame, menu.progressGauge, 78f, PROGRESS_ARROW_TOP) SlotPanel(this, frame, menu.outputSlot, 104f, PROGRESS_SLOT_TOP) + makeDeviceControls(this, frame, redstone = menu.redstone) + return frame } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/GetterSetter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/GetterSetter.kt index 022140131..db519b33e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/GetterSetter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/GetterSetter.kt @@ -66,5 +66,28 @@ interface GetterSetter : Supplier, Consumer, ReadWriteProperty } } -fun KMutableProperty0.asGetterSetter() = GetterSetter.of(this) +fun KMutableProperty0.asGetterSetter(watch: ((old: V, new: V) -> Unit)? = null): GetterSetter { + return GetterSetter.of(this).let { + if (watch != null) { + it.watch(watch) + } else { + it + } + } +} + +fun GetterSetter.watch(watch: (old: V, new: V) -> Unit): GetterSetter { + return object : GetterSetter { + override fun get(): V { + return this@watch.get() + } + + override fun accept(t: V) { + val old = get() + this@watch.accept(t) + watch.invoke(old, t) + } + } +} + fun KMutableProperty0.asGetterOnly() = GetterSetter.of(Supplier { this.get() }, Consumer { /* do nothing */ }) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/DataStreams.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/DataStreams.kt index 83ca6a005..95c4308d3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/DataStreams.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/DataStreams.kt @@ -76,7 +76,8 @@ val VarLongValueCodec = StreamCodec(DataInputStream::readVarLongLE, DataOutputSt val BinaryStringCodec = StreamCodec(DataInputStream::readBinaryString, DataOutputStream::writeBinaryString) class EnumValueCodec>(clazz: Class, val writeByIndices: Boolean = false) : IStreamCodec { - private val values = search(clazz) ?: throw ClassCastException("$clazz does not have enum constants. Not an enum?") + val clazz = searchClass(clazz) + private val values = searchClass(clazz).enumConstants!! override fun read(stream: DataInputStream): V { if (writeByIndices) { @@ -109,14 +110,18 @@ class EnumValueCodec>(clazz: Class, val writeByIndices: Boole * * is there an already existing solution? */ - fun > search(clazz: Class): Array? { + fun > searchClass(clazz: Class): Class { var search: Class<*> = clazz while (search.enumConstants == null && search.superclass != null) { search = search.superclass } - return search.enumConstants as? Array + if (search.enumConstants == null) { + throw ClassCastException("$clazz does not represent an enum or enum subclass") + } + + return search as Class } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryPoweredMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryPoweredMenu.kt index 2f2f226a6..f8cfc8287 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryPoweredMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryPoweredMenu.kt @@ -5,6 +5,8 @@ import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import net.minecraft.world.SimpleContainer +import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting +import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback abstract class MatteryPoweredMenu protected constructor( menuType: MenuType<*>, @@ -14,6 +16,7 @@ abstract class MatteryPoweredMenu protected constructor( ) : MatteryMenu(menuType, containerID, inventory, tile) { val powerWidget: LevelGaugeWidget val batterySlot: BatterySlot + val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java) init { if (tile == null) { @@ -22,6 +25,7 @@ abstract class MatteryPoweredMenu protected constructor( } else { powerWidget = LevelGaugeWidget(this, tile.energy) batterySlot = BatterySlot(tile.batteryContainer, 0) + redstone.with(tile.redstoneControl::redstoneSetting) } addSlot(batterySlot) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/HoloSignMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/HoloSignMenu.kt index 402406f00..a9495dfa8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/HoloSignMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/HoloSignMenu.kt @@ -2,9 +2,11 @@ package ru.dbotthepony.mc.otm.menu.decorative import net.minecraft.world.entity.player.Inventory import net.minecraft.world.inventory.Slot +import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting import ru.dbotthepony.mc.otm.block.entity.decorative.HoloSignBlockEntity import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback +import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback import ru.dbotthepony.mc.otm.menu.input.StringInputWithFeedback import ru.dbotthepony.mc.otm.registry.MMenus @@ -15,14 +17,17 @@ class HoloSignMenu @JvmOverloads constructor( ) : MatteryMenu(MMenus.HOLO_SIGN, containerId, inventory, tile) { val text = StringInputWithFeedback(this) val locked = BooleanInputWithFeedback(this) + val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java) init { text.filter { it.isCreative || !locked.value } + redstone.filter { it.isCreative || !locked.value } locked.filter { it.isCreative } if (tile != null) { text.withConsumer { if (tile.locked) tile.text = it else tile.text = HoloSignBlockEntity.truncate(it) }.withSupplier(tile::text) locked.with(tile::locked) + redstone.with(tile.redstoneControl::redstoneSetting) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/AbstractPlayerInputWithFeedback.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/AbstractPlayerInputWithFeedback.kt index 077e9a9ff..8a4893d75 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/AbstractPlayerInputWithFeedback.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/AbstractPlayerInputWithFeedback.kt @@ -14,7 +14,33 @@ import kotlin.reflect.KMutableProperty0 * * Getting and setting values should ONLY be done clientside */ -interface IPlayerInputWithFeedback : GetterSetter, Predicate +interface IPlayerInputWithFeedback : GetterSetter, Predicate { + companion object { + fun of(getterSetter: GetterSetter): IPlayerInputWithFeedback { + return object : IPlayerInputWithFeedback, GetterSetter by getterSetter { + override fun test(t: Player?): Boolean { + return true + } + } + } + + fun of(getterSetter: GetterSetter, filter: Predicate): IPlayerInputWithFeedback { + return object : IPlayerInputWithFeedback, GetterSetter by getterSetter, Predicate by filter {} + } + + fun validPlayer(getterSetter: GetterSetter): IPlayerInputWithFeedback { + return object : IPlayerInputWithFeedback, GetterSetter by getterSetter { + override fun test(t: Player?): Boolean { + return t != null + } + } + } + } +} + +fun GetterSetter.wrapAsPlayerInput(filter: Predicate = Predicate { it != null }): IPlayerInputWithFeedback { + return IPlayerInputWithFeedback.of(this, filter) +} /** * Represents Server to Client synchronization and Client to Server input diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/EnumInputWithFeedback.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/EnumInputWithFeedback.kt new file mode 100644 index 000000000..f03279bd4 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/EnumInputWithFeedback.kt @@ -0,0 +1,22 @@ +package ru.dbotthepony.mc.otm.menu.input + +import ru.dbotthepony.mc.otm.core.GetterSetter +import ru.dbotthepony.mc.otm.core.util.EnumValueCodec +import ru.dbotthepony.mc.otm.menu.MatteryMenu +import kotlin.reflect.KMutableProperty0 + +class EnumInputWithFeedback>(menu: MatteryMenu, clazz: Class) : AbstractPlayerInputWithFeedback() { + val codec = EnumValueCodec(clazz) + private val default = codec.clazz.enumConstants!![0] + + override val input = menu.PlayerInput(codec, false) { consumer?.invoke(it) } + override val value by menu.mSynchronizer.ComputedField(getter = { supplier?.invoke() ?: default }, codec) + + constructor(menu: MatteryMenu, clazz: Class, state: KMutableProperty0) : this(menu, clazz) { + with(state) + } + + constructor(menu: MatteryMenu, clazz: Class, state: GetterSetter) : this(menu, clazz) { + with(state) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/BatteryBankMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/BatteryBankMenu.kt index e470ad129..69ba6fe18 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/BatteryBankMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/BatteryBankMenu.kt @@ -5,6 +5,7 @@ import kotlin.jvm.JvmOverloads import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.block.entity.tech.BatteryBankBlockEntity import net.minecraft.world.SimpleContainer +import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting import ru.dbotthepony.mc.otm.core.ImmutableList import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.capability.MatteryCapability @@ -12,6 +13,7 @@ import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.menu.BatterySlot import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatterySlot +import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback import ru.dbotthepony.mc.otm.registry.MMenus class BatteryBankMenu @JvmOverloads constructor( @@ -21,8 +23,13 @@ class BatteryBankMenu @JvmOverloads constructor( ) : MatteryMenu(MMenus.BATTERY_BANK, p_38852_, inventory, tile) { val powerLevel: LevelGaugeWidget override val storageSlots: List + val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java) init { + if (tile != null) { + redstone.with(tile.redstoneControl::redstoneSetting) + } + val container: Container = tile?.container ?: SimpleContainer(BatteryBankBlockEntity.CAPACITY) powerLevel = LevelGaugeWidget(this, tile?.getCapability(MatteryCapability.ENERGY)?.orNull()) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/ChemicalGeneratorMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/ChemicalGeneratorMenu.kt index 4950063cd..765217587 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/ChemicalGeneratorMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/ChemicalGeneratorMenu.kt @@ -5,10 +5,12 @@ import net.minecraft.world.entity.player.Inventory import net.minecraft.world.item.ItemStack import net.minecraftforge.common.ForgeHooks import net.minecraftforge.common.capabilities.ForgeCapabilities +import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting import ru.dbotthepony.mc.otm.block.entity.tech.ChemicalGeneratorBlockEntity import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatterySlot +import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget import ru.dbotthepony.mc.otm.registry.MMenus @@ -16,6 +18,14 @@ import ru.dbotthepony.mc.otm.registry.MMenus class ChemicalGeneratorMenu @JvmOverloads constructor(id: Int, inv: Inventory, tile: ChemicalGeneratorBlockEntity? = null) : MatteryMenu(MMenus.CHEMICAL_GENERATOR, id, inv, tile) { + val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java) + + init { + if (tile != null) { + redstone.with(tile.redstoneControl::redstoneSetting) + } + } + val container = tile?.container ?: SimpleContainer(3) val fuelSlot = object : MatterySlot(container, ChemicalGeneratorBlockEntity.SLOT_INPUT) { @@ -44,6 +54,7 @@ class ChemicalGeneratorMenu @JvmOverloads constructor(id: Int, inv: Inventory, t val energy = LevelGaugeWidget(this, tile?.energy) var burnTime by mSynchronizer.int() + override val storageSlots = listOf( addSlot(fuelSlot), addSlot(batterySlot), diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/EnergyCounterMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/EnergyCounterMenu.kt index 01aac2e7d..1242fe4db 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/EnergyCounterMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/EnergyCounterMenu.kt @@ -5,10 +5,12 @@ import kotlin.jvm.JvmOverloads import net.minecraft.world.entity.player.Inventory import net.minecraft.world.inventory.Slot import net.minecraft.world.level.block.Block +import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting import ru.dbotthepony.mc.otm.block.tech.EnergyCounterBlock import ru.dbotthepony.mc.otm.block.entity.tech.EnergyCounterBlockEntity import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.menu.MatteryMenu +import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback import ru.dbotthepony.mc.otm.registry.MMenus import java.math.BigDecimal @@ -28,6 +30,14 @@ class EnergyCounterMenu @JvmOverloads constructor( tile.level?.setBlock(tile.blockPos, tile.blockState.setValue(EnergyCounterBlock.INPUT_DIRECTION, tile.blockState.getValue(EnergyCounterBlock.INPUT_DIRECTION).opposite), Block.UPDATE_ALL) } + val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java) + + init { + if (tile != null) { + redstone.with(tile.redstoneControl::redstoneSetting) + } + } + var inputDirection by mSynchronizer.enum(Direction::class.java) val maxIOInput = bigDecimalInput { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/EnergyServoMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/EnergyServoMenu.kt index c452c4a83..cba9da535 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/EnergyServoMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/EnergyServoMenu.kt @@ -5,10 +5,12 @@ import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Inventory import net.minecraft.world.inventory.Slot import net.minecraft.world.item.ItemStack +import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting import ru.dbotthepony.mc.otm.block.entity.tech.EnergyServoBlockEntity import ru.dbotthepony.mc.otm.capability.energy import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatterySlot +import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.registry.MMenus @@ -22,6 +24,14 @@ class EnergyServoMenu @JvmOverloads constructor( val powerGauge = LevelGaugeWidget(this, tile?.energy) + val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java) + + init { + if (tile != null) { + redstone.with(tile.redstoneControl::redstoneSetting) + } + } + init { val container = tile?.container ?: SimpleContainer(2) diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/redstone.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/redstone.png new file mode 100644 index 000000000..bf86e17f0 Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/redstone.png differ diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/redstone.xcf b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/redstone.xcf new file mode 100644 index 000000000..df3bd09a5 Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets/redstone.xcf differ