From c1fbdfa1a64aad2dca124663be97b45b22f477b8 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 14:37:55 +0700 Subject: [PATCH 1/5] Get rid of slot provider interface --- .../mc/otm/client/screen/MatteryScreen.kt | 6 +-- .../otm/client/screen/panels/EditablePanel.kt | 48 +------------------ .../screen/panels/slot/FoldableSlotPanel.kt | 8 +--- .../client/screen/panels/slot/SlotPanel.kt | 7 ++- .../compat/jei/Panel2ClickableIngredient.kt | 2 +- 5 files changed, 11 insertions(+), 60 deletions(-) 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 d202792dd..5de69287f 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 @@ -623,10 +623,10 @@ abstract class MatteryScreen(menu: T, inventory: Inventory, tit val yFloat = y.toFloat() for (panel in panels) { - val (status, slot) = panel.findSlot(xFloat, yFloat) + val (findPanel, interrupt) = panel.panelOfTypeUnderCursor>(xFloat, yFloat) - if (status) { - return slot + if (interrupt) { + return findPanel?.slot } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt index 0ae78b18e..8d951de0e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt @@ -52,10 +52,6 @@ enum class DockResizeMode(val changeWidth: Boolean, val changeHeight: Boolean) { ALL(true, true), NONE(false, false), WIDTH(true, false), HEIGHT(false, true) } -interface ISlotPanel { - val slot: S -} - data class Rect2f(val x: Float, val y: Float, val width: Float, val height: Float) { fun toIntRect(): Rect2i { return Rect2i(x.roundToInt(), y.roundToInt(), width.roundToInt(), height.roundToInt()) @@ -972,46 +968,6 @@ open class EditablePanel @JvmOverloads constructor( } } - fun findSlot(mouseX: Float, mouseY: Float): Pair { - if (!isVisible()) { - return false to null - } - - if (!acceptMouseInput) { - return (mouseX >= absoluteX && - mouseX <= absoluteX + width && - mouseY >= absoluteY && - mouseY <= absoluteY + height) to null - } - - if (grabMouseInput && this is ISlotPanel<*>) { - return true to this.slot - } - - for (child in visibleChildrenInternal) { - val (status, slot) = child.findSlot(mouseX, mouseY) - - if (status) { - return true to slot - } - } - - if ( - mouseX >= absoluteX && - mouseX <= absoluteX + width && - mouseY >= absoluteY && - mouseY <= absoluteY + height - ) { - if (this is ISlotPanel<*>) { - return true to this.slot - } - - return true to null - } - - return false to null - } - data class PanelOfTypeResult(val panel: T?, val interrupt: Boolean) { constructor(panel: T) : this(panel, true) @@ -1029,8 +985,8 @@ open class EditablePanel @JvmOverloads constructor( } } - inline fun panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean = false): T? { - return panelOfTypeUnderCursor(mouseX, mouseY, ignoreMouseInputLock) { it is T }.panel + inline fun panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean = false): PanelOfTypeResult { + return panelOfTypeUnderCursor(mouseX, mouseY, ignoreMouseInputLock) { it is T } } fun panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean, tester: Predicate>): PanelOfTypeResult { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/FoldableSlotPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/FoldableSlotPanel.kt index a74d550bb..fc326f9e0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/FoldableSlotPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/FoldableSlotPanel.kt @@ -6,9 +6,8 @@ import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.util.BackgroundPanel 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.ISlotPanel -open class FoldableSlotPanel, out T : Slot> @JvmOverloads constructor( +open class FoldableSlotPanel, out T : Slot>( screen: S, parent: EditablePanel<*>?, val mainSlot: SlotPanel, @@ -17,7 +16,7 @@ open class FoldableSlotPanel, out T : Slot> @JvmOverloa y: Float = 0f, width: Float = AbstractSlotPanel.SIZE, height: Float = AbstractSlotPanel.SIZE, -) : EditablePanel(screen, parent, x, y, width, height), ISlotPanel { +) : EditablePanel(screen, parent, x, y, width, height) { init { mainSlot.parent = this mainSlot.dock = Dock.FILL @@ -72,9 +71,6 @@ open class FoldableSlotPanel, out T : Slot> @JvmOverloa } } - override val slot: T - get() = mainSlot.slot - var hoveringSince: SystemTime? = null protected set var hoverPanel: HoverPanel? = null diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/SlotPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/SlotPanel.kt index 41da7dc50..f081dde43 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/SlotPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/SlotPanel.kt @@ -13,19 +13,18 @@ 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.ISlotPanel import javax.annotation.Nonnull import kotlin.math.roundToInt -open class SlotPanel, out T : Slot> @JvmOverloads constructor( +open class SlotPanel, out T : Slot>( screen: S, parent: EditablePanel<*>?, - final override val slot: T, + val slot: T, x: Float = 0f, y: Float = 0f, width: Float = SIZE, height: Float = SIZE, -) : AbstractSlotPanel(screen, parent, x, y, width, height), ISlotPanel { +) : AbstractSlotPanel(screen, parent, x, y, width, height) { override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { screen.returnSlot = slot return true diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/Panel2ClickableIngredient.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/Panel2ClickableIngredient.kt index f61e9e81d..5188eabc8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/Panel2ClickableIngredient.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/Panel2ClickableIngredient.kt @@ -21,7 +21,7 @@ class Panel2ClickableIngredient

, T>(val panel: P, val ingre inline fun , T : Any> find(mouseX: Double, mouseY: Double, type: IIngredientType, source: Collection>, noinline provider: (P) -> T): Optional> { return source .stream() - .map { it.panelOfTypeUnderCursor

(mouseX.toFloat(), mouseY.toFloat(), ignoreMouseInputLock = true) } + .map { it.panelOfTypeUnderCursor

(mouseX.toFloat(), mouseY.toFloat(), ignoreMouseInputLock = true).panel } .filterNotNull() .findAny() .flatMap { a -> JEIPlugin.helpers.ingredientManager.createTypedIngredient(type, provider(a)).map { a to it } } From 6ff737a315ccdb8b79cef26b340e95055996e25d Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 14:38:53 +0700 Subject: [PATCH 2/5] Fix slots hidden behind by other panels still being visible to "lookup recipes" keybind --- .../mc/otm/compat/jei/Panel2ClickableIngredient.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/Panel2ClickableIngredient.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/Panel2ClickableIngredient.kt index 5188eabc8..61c1a4f18 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/Panel2ClickableIngredient.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/Panel2ClickableIngredient.kt @@ -21,9 +21,10 @@ class Panel2ClickableIngredient

, T>(val panel: P, val ingre inline fun , T : Any> find(mouseX: Double, mouseY: Double, type: IIngredientType, source: Collection>, noinline provider: (P) -> T): Optional> { return source .stream() - .map { it.panelOfTypeUnderCursor

(mouseX.toFloat(), mouseY.toFloat(), ignoreMouseInputLock = true).panel } - .filterNotNull() - .findAny() + .map { it.panelOfTypeUnderCursor

(mouseX.toFloat(), mouseY.toFloat(), ignoreMouseInputLock = true) } + .filter { it.interrupt } + .findFirst() + .flatMap { Optional.ofNullable(it.panel) } .flatMap { a -> JEIPlugin.helpers.ingredientManager.createTypedIngredient(type, provider(a)).map { a to it } } .map { Panel2ClickableIngredient(it.first!!, it.second) } } From aa93150f09fd31c8ddd5177d14c23f87f39c5fc6 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 14:40:03 +0700 Subject: [PATCH 3/5] We don't need jvm overloads here --- .../ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt index 8d951de0e..f646f67c0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt @@ -58,7 +58,7 @@ data class Rect2f(val x: Float, val y: Float, val width: Float, val height: Floa } } -open class EditablePanel @JvmOverloads constructor( +open class EditablePanel( val screen: S, parent: EditablePanel<*>?, From d65b8df579982a5d9553b777900d9d273983ce80 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 14:56:03 +0700 Subject: [PATCH 4/5] Now when positioning panels, exopack charge slots are considered into inventory frame height --- .../mc/otm/client/screen/MatteryScreen.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) 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 5de69287f..1d0bb769f 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 @@ -203,6 +203,8 @@ abstract class MatteryScreen(menu: T, inventory: Inventory, tit it.slotBackground = Widgets18.CHARGE_SLOT_BACKGROUND } } + + frame.dockMargin = frame.dockMargin.copy(bottom = frame.dockMargin.bottom + 2f + AbstractSlotPanel.SIZE) } init { @@ -481,21 +483,21 @@ abstract class MatteryScreen(menu: T, inventory: Inventory, tit val inventoryFrame = inventoryFrame if (mainFrame != null) { - top -= (mainFrame.height / 2).toInt() + top -= ((mainFrame.height + mainFrame.dockMargin.vertical) / 2).toInt() } if (inventoryFrame != null) { - top -= (inventoryFrame.height / 2).toInt() + top -= ((inventoryFrame.height + inventoryFrame.dockMargin.vertical) / 2).toInt() } if (mainFrame != null) { - mainFrame.setPos(width / 2 - mainFrame.width / 2, top.toFloat()) - top += mainFrame.height.toInt() + mainFrame.setPos(width / 2 - (mainFrame.width + mainFrame.dockMargin.horizontal) / 2, top.toFloat() + mainFrame.dockMargin.top) + top += (mainFrame.height + mainFrame.dockMargin.bottom).toInt() } if (inventoryFrame != null) { - inventoryFrame.setPos(width / 2 - inventoryFrame.width / 2, top.toFloat()) - top += inventoryFrame.height.toInt() + inventoryFrame.setPos(width / 2 - (inventoryFrame.width + inventoryFrame.dockMargin.horizontal) / 2, top.toFloat() + inventoryFrame.dockMargin.top) + top += (inventoryFrame.height + inventoryFrame.dockMargin.bottom).toInt() } } From 80155ba7bc6cbb72e5795a2804f4cc2c1d4897c4 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 17:53:17 +0700 Subject: [PATCH 5/5] Once again i demand you to STOP updating blockstates in being-unloaded chunks --- .../dbotthepony/mc/otm/block/entity/Cables.kt | 47 ++++++++++++++----- .../entity/cable/EnergyCableBlockEntity.kt | 13 +++-- .../ru/dbotthepony/mc/otm/graph/GraphNode.kt | 8 ++-- .../mc/otm/graph/storage/StorageNode.kt | 14 ++---- 4 files changed, 53 insertions(+), 29 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/Cables.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/Cables.kt index 9301f3efc..670dcbc81 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/Cables.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/Cables.kt @@ -11,25 +11,38 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.graph.matter.MatterNode import ru.dbotthepony.mc.otm.graph.storage.StorageGraph import ru.dbotthepony.mc.otm.graph.storage.StorageNode +import ru.dbotthepony.mc.otm.once import ru.dbotthepony.mc.otm.registry.MBlockEntities class MatterCableBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(MBlockEntities.MATTER_CABLE, p_155229_, p_155230_) { val matterNode = object : MatterNode() { override fun onNeighbour(link: Link) { if (link is DirectionLink) { - val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[link.direction]!!, true) + if (!SERVER_IS_LIVE) return + val level = level - if (newState !== blockState && SERVER_IS_LIVE) - level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) + level?.once { + if (!isValid) return@once + val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[link.direction]!!, true) + + if (newState !== blockState && SERVER_IS_LIVE) + level.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) + } } } override fun onUnNeighbour(link: Link) { if (link is DirectionLink) { - val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[link.direction]!!, false) + if (!SERVER_IS_LIVE) return + val level = level - if (newState !== blockState && SERVER_IS_LIVE) - level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) + level?.once { + if (!isValid) return@once + val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[link.direction]!!, false) + + if (newState !== blockState && SERVER_IS_LIVE) + level.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) + } } } } @@ -56,19 +69,29 @@ class StorageCableBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matt override fun onNeighbour(link: Link) { if (link is DirectionLink) { - val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[link.direction]!!, true) + if (!SERVER_IS_LIVE) return + val level = level - if (newState !== blockState && SERVER_IS_LIVE) - level!!.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) + level?.once { + val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[link.direction]!!, true) + + if (newState !== blockState && SERVER_IS_LIVE) + level.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) + } } } override fun onUnNeighbour(link: Link) { if (link is DirectionLink) { - val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[link.direction]!!, false) + if (!SERVER_IS_LIVE) return + val level = level - if (newState !== blockState && SERVER_IS_LIVE) - level!!.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) + level?.once { + val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[link.direction]!!, false) + + if (newState !== blockState && SERVER_IS_LIVE) + level.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) + } } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/cable/EnergyCableBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/cable/EnergyCableBlockEntity.kt index e9ce7b301..26817675e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/cable/EnergyCableBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/cable/EnergyCableBlockEntity.kt @@ -19,6 +19,7 @@ import ru.dbotthepony.mc.otm.core.math.BlockRotation import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.graph.GraphNode +import ru.dbotthepony.mc.otm.once import ru.dbotthepony.mc.otm.onceServer import java.util.Collections import java.util.EnumMap @@ -110,10 +111,16 @@ abstract class EnergyCableBlockEntity(type: BlockEntityType<*>, blockPos: BlockP } private fun updateBlockState(side: Direction, status: Boolean) { - val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[side]!!, status) + if (!SERVER_IS_LIVE) return + val level = level - if (newState !== blockState && SERVER_IS_LIVE) - level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) + level?.once { + if (!node.isValid) return@once + val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[side]!!, status) + + if (newState !== blockState && SERVER_IS_LIVE) + level.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) + } } // whenever this changes, graph#invalidatePathCache() MUST be called diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/GraphNode.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/GraphNode.kt index e6b2b754e..86d5f126e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/GraphNode.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/GraphNode.kt @@ -127,8 +127,8 @@ open class GraphNode, G : GraphNodeList>(val graphFact protected open fun onNeighbour(link: Link) {} protected open fun onUnNeighbour(link: Link) {} - protected open fun invalidate() {} - protected open fun revive() {} + protected open fun onInvalidated() {} + protected open fun onRevived() {} var isValid: Boolean = true set(value) { @@ -144,9 +144,9 @@ open class GraphNode, G : GraphNodeList>(val graphFact graph.removeNode(this as N) rebuildGraphs(neighbours.map { it.second }) - invalidate() + onInvalidated() } else { - revive() + onRevived() } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/storage/StorageNode.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/storage/StorageNode.kt index a176a192c..441b851c3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/storage/StorageNode.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/storage/StorageNode.kt @@ -6,12 +6,6 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.graph.GraphNode import ru.dbotthepony.mc.otm.storage.IStorage -import ru.dbotthepony.mc.otm.storage.IVirtualStorageComponent -import ru.dbotthepony.mc.otm.storage.StorageStack -import ru.dbotthepony.mc.otm.storage.VirtualComponent -import ru.dbotthepony.mc.otm.storage.powered.PoweredVirtualComponent -import java.util.* -import java.util.function.Supplier open class StorageNode(private val energyDemander: IMatteryEnergyStorage? = null) : GraphNode(::StorageGraph) { protected val components = ObjectArraySet>() @@ -19,9 +13,9 @@ open class StorageNode(private val energyDemander: IMatteryEnergyStorage? = null /** * Setting this to true will render non functional default [attachComponents], * make [addStorageComponent] and [removeStorageComponent] not add/remove components - * to attached graph, and [revive] not re-attach components. + * to attached graph, and [onRevived] not re-attach components. * - * [invalidate] and [removeComponents] still detach all components + * [onInvalidated] and [removeComponents] still detach all components */ protected var manualAttaching = false private var demandingEnergy = false @@ -103,13 +97,13 @@ open class StorageNode(private val energyDemander: IMatteryEnergyStorage? = null } } - override fun invalidate() { + override fun onInvalidated() { for (component in components) { graph.remove(component) } } - override fun revive() { + override fun onRevived() { if (!manualAttaching) { for (component in components) { graph.add(component)