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/client/screen/MatteryScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatteryScreen.kt index e2d1adc06..7203df674 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 @@ -210,6 +210,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 { @@ -488,21 +490,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() } } @@ -630,10 +632,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 a5f01a0a0..b58449273 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 @@ -49,17 +49,13 @@ 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()) } } -open class EditablePanel @JvmOverloads constructor( +open class EditablePanel( val screen: S, parent: EditablePanel<*>?, @@ -954,46 +950,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) @@ -1011,8 +967,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 5ec271a7d..fe5e7769e 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..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 @@ -22,8 +22,9 @@ class Panel2ClickableIngredient

, T>(val panel: P, val ingre return source .stream() .map { it.panelOfTypeUnderCursor

(mouseX.toFloat(), mouseY.toFloat(), ignoreMouseInputLock = true) } - .filterNotNull() - .findAny() + .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) } } 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)