This commit is contained in:
DBotThePony 2024-01-09 17:54:38 +07:00
commit 6d007f4a27
Signed by: DBot
GPG Key ID: DCC23B5715498507
9 changed files with 75 additions and 97 deletions

View File

@ -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.matter.MatterNode
import ru.dbotthepony.mc.otm.graph.storage.StorageGraph import ru.dbotthepony.mc.otm.graph.storage.StorageGraph
import ru.dbotthepony.mc.otm.graph.storage.StorageNode import ru.dbotthepony.mc.otm.graph.storage.StorageNode
import ru.dbotthepony.mc.otm.once
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
class MatterCableBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(MBlockEntities.MATTER_CABLE, p_155229_, p_155230_) { class MatterCableBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(MBlockEntities.MATTER_CABLE, p_155229_, p_155230_) {
val matterNode = object : MatterNode() { val matterNode = object : MatterNode() {
override fun onNeighbour(link: Link) { override fun onNeighbour(link: Link) {
if (link is DirectionLink) { 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?.once {
level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) 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) { override fun onUnNeighbour(link: Link) {
if (link is DirectionLink) { 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?.once {
level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) 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) { override fun onNeighbour(link: Link) {
if (link is DirectionLink) { 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?.once {
level!!.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) 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) { override fun onUnNeighbour(link: Link) {
if (link is DirectionLink) { 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?.once {
level!!.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) val newState = blockState.setValue(CableBlock.MAPPING_CONNECTION_PROP[link.direction]!!, false)
if (newState !== blockState && SERVER_IS_LIVE)
level.setBlock(blockPos, newState, Block.UPDATE_CLIENTS)
}
} }
} }
} }

View File

@ -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.Decimal
import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.core.math.RelativeSide
import ru.dbotthepony.mc.otm.graph.GraphNode import ru.dbotthepony.mc.otm.graph.GraphNode
import ru.dbotthepony.mc.otm.once
import ru.dbotthepony.mc.otm.onceServer import ru.dbotthepony.mc.otm.onceServer
import java.util.Collections import java.util.Collections
import java.util.EnumMap import java.util.EnumMap
@ -110,10 +111,16 @@ abstract class EnergyCableBlockEntity(type: BlockEntityType<*>, blockPos: BlockP
} }
private fun updateBlockState(side: Direction, status: Boolean) { 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?.once {
level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS) 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 // whenever this changes, graph#invalidatePathCache() MUST be called

View File

@ -211,6 +211,8 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
it.slotBackground = Widgets18.CHARGE_SLOT_BACKGROUND it.slotBackground = Widgets18.CHARGE_SLOT_BACKGROUND
} }
} }
frame.dockMargin = frame.dockMargin.copy(bottom = frame.dockMargin.bottom + 2f + AbstractSlotPanel.SIZE)
} }
init { init {
@ -489,21 +491,21 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
val inventoryFrame = inventoryFrame val inventoryFrame = inventoryFrame
if (mainFrame != null) { if (mainFrame != null) {
top -= (mainFrame.height / 2).toInt() top -= ((mainFrame.height + mainFrame.dockMargin.vertical) / 2).toInt()
} }
if (inventoryFrame != null) { if (inventoryFrame != null) {
top -= (inventoryFrame.height / 2).toInt() top -= ((inventoryFrame.height + inventoryFrame.dockMargin.vertical) / 2).toInt()
} }
if (mainFrame != null) { if (mainFrame != null) {
mainFrame.setPos(width / 2 - mainFrame.width / 2, top.toFloat()) mainFrame.setPos(width / 2 - (mainFrame.width + mainFrame.dockMargin.horizontal) / 2, top.toFloat() + mainFrame.dockMargin.top)
top += mainFrame.height.toInt() top += (mainFrame.height + mainFrame.dockMargin.bottom).toInt()
} }
if (inventoryFrame != null) { if (inventoryFrame != null) {
inventoryFrame.setPos(width / 2 - inventoryFrame.width / 2, top.toFloat()) inventoryFrame.setPos(width / 2 - (inventoryFrame.width + inventoryFrame.dockMargin.horizontal) / 2, top.toFloat() + inventoryFrame.dockMargin.top)
top += inventoryFrame.height.toInt() top += (inventoryFrame.height + inventoryFrame.dockMargin.bottom).toInt()
} }
} }
@ -631,10 +633,10 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
val yFloat = y.toFloat() val yFloat = y.toFloat()
for (panel in panels) { for (panel in panels) {
val (status, slot) = panel.findSlot(xFloat, yFloat) val (findPanel, interrupt) = panel.panelOfTypeUnderCursor<SlotPanel<*, *>>(xFloat, yFloat)
if (status) { if (interrupt) {
return slot return findPanel?.slot
} }
} }

View File

@ -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) ALL(true, true), NONE(false, false), WIDTH(true, false), HEIGHT(false, true)
} }
interface ISlotPanel<out S : Slot> {
val slot: S
}
data class Rect2f(val x: Float, val y: Float, val width: Float, val height: Float) { data class Rect2f(val x: Float, val y: Float, val width: Float, val height: Float) {
fun toIntRect(): Rect2i { fun toIntRect(): Rect2i {
return Rect2i(x.roundToInt(), y.roundToInt(), width.roundToInt(), height.roundToInt()) return Rect2i(x.roundToInt(), y.roundToInt(), width.roundToInt(), height.roundToInt())
} }
} }
open class EditablePanel<out S : Screen> @JvmOverloads constructor( open class EditablePanel<out S : Screen>(
val screen: S, val screen: S,
parent: EditablePanel<*>?, parent: EditablePanel<*>?,
@ -955,46 +951,6 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
} }
} }
fun findSlot(mouseX: Float, mouseY: Float): Pair<Boolean, Slot?> {
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<T>(val panel: T?, val interrupt: Boolean) { data class PanelOfTypeResult<T>(val panel: T?, val interrupt: Boolean) {
constructor(panel: T) : this(panel, true) constructor(panel: T) : this(panel, true)
@ -1012,8 +968,8 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
} }
} }
inline fun <reified T> panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean = false): T? { inline fun <reified T> panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean = false): PanelOfTypeResult<T> {
return panelOfTypeUnderCursor<T>(mouseX, mouseY, ignoreMouseInputLock) { it is T }.panel return panelOfTypeUnderCursor<T>(mouseX, mouseY, ignoreMouseInputLock) { it is T }
} }
fun <T> panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean, tester: Predicate<EditablePanel<*>>): PanelOfTypeResult<T> { fun <T> panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean, tester: Predicate<EditablePanel<*>>): PanelOfTypeResult<T> {

View File

@ -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.util.BackgroundPanel
import ru.dbotthepony.mc.otm.client.screen.panels.Dock 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.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.ISlotPanel
open class FoldableSlotPanel<out S : MatteryScreen<*>, out T : Slot> @JvmOverloads constructor( open class FoldableSlotPanel<out S : MatteryScreen<*>, out T : Slot>(
screen: S, screen: S,
parent: EditablePanel<*>?, parent: EditablePanel<*>?,
val mainSlot: SlotPanel<S, T>, val mainSlot: SlotPanel<S, T>,
@ -17,7 +16,7 @@ open class FoldableSlotPanel<out S : MatteryScreen<*>, out T : Slot> @JvmOverloa
y: Float = 0f, y: Float = 0f,
width: Float = AbstractSlotPanel.SIZE, width: Float = AbstractSlotPanel.SIZE,
height: Float = AbstractSlotPanel.SIZE, height: Float = AbstractSlotPanel.SIZE,
) : EditablePanel<S>(screen, parent, x, y, width, height), ISlotPanel<T> { ) : EditablePanel<S>(screen, parent, x, y, width, height) {
init { init {
mainSlot.parent = this mainSlot.parent = this
mainSlot.dock = Dock.FILL mainSlot.dock = Dock.FILL
@ -72,9 +71,6 @@ open class FoldableSlotPanel<out S : MatteryScreen<*>, out T : Slot> @JvmOverloa
} }
} }
override val slot: T
get() = mainSlot.slot
var hoveringSince: SystemTime? = null var hoveringSince: SystemTime? = null
protected set protected set
var hoverPanel: HoverPanel? = null var hoverPanel: HoverPanel? = null

View File

@ -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.render.Widgets18
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen 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.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.ISlotPanel
import javax.annotation.Nonnull import javax.annotation.Nonnull
import kotlin.math.roundToInt import kotlin.math.roundToInt
open class SlotPanel<out S : MatteryScreen<*>, out T : Slot> @JvmOverloads constructor( open class SlotPanel<out S : MatteryScreen<*>, out T : Slot>(
screen: S, screen: S,
parent: EditablePanel<*>?, parent: EditablePanel<*>?,
final override val slot: T, val slot: T,
x: Float = 0f, x: Float = 0f,
y: Float = 0f, y: Float = 0f,
width: Float = SIZE, width: Float = SIZE,
height: Float = SIZE, height: Float = SIZE,
) : AbstractSlotPanel<S>(screen, parent, x, y, width, height), ISlotPanel<T> { ) : AbstractSlotPanel<S>(screen, parent, x, y, width, height) {
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
screen.returnSlot = slot screen.returnSlot = slot
return true return true

View File

@ -22,8 +22,9 @@ class Panel2ClickableIngredient<P : EditablePanel<*>, T>(val panel: P, val ingre
return source return source
.stream() .stream()
.map { it.panelOfTypeUnderCursor<P>(mouseX.toFloat(), mouseY.toFloat(), ignoreMouseInputLock = true) } .map { it.panelOfTypeUnderCursor<P>(mouseX.toFloat(), mouseY.toFloat(), ignoreMouseInputLock = true) }
.filterNotNull() .filter { it.interrupt }
.findAny() .findFirst()
.flatMap { Optional.ofNullable(it.panel) }
.flatMap { a -> JEIPlugin.helpers.ingredientManager.createTypedIngredient(type, provider(a)).map { a to it } } .flatMap { a -> JEIPlugin.helpers.ingredientManager.createTypedIngredient(type, provider(a)).map { a to it } }
.map { Panel2ClickableIngredient(it.first!!, it.second) } .map { Panel2ClickableIngredient(it.first!!, it.second) }
} }

View File

@ -127,8 +127,8 @@ open class GraphNode<N : GraphNode<N, G>, G : GraphNodeList<N, G>>(val graphFact
protected open fun onNeighbour(link: Link) {} protected open fun onNeighbour(link: Link) {}
protected open fun onUnNeighbour(link: Link) {} protected open fun onUnNeighbour(link: Link) {}
protected open fun invalidate() {} protected open fun onInvalidated() {}
protected open fun revive() {} protected open fun onRevived() {}
var isValid: Boolean = true var isValid: Boolean = true
set(value) { set(value) {
@ -144,9 +144,9 @@ open class GraphNode<N : GraphNode<N, G>, G : GraphNodeList<N, G>>(val graphFact
graph.removeNode(this as N) graph.removeNode(this as N)
rebuildGraphs(neighbours.map { it.second }) rebuildGraphs(neighbours.map { it.second })
invalidate() onInvalidated()
} else { } else {
revive() onRevived()
} }
} }

View File

@ -6,12 +6,6 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.graph.GraphNode import ru.dbotthepony.mc.otm.graph.GraphNode
import ru.dbotthepony.mc.otm.storage.IStorage 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<StorageNode, StorageGraph>(::StorageGraph) { open class StorageNode(private val energyDemander: IMatteryEnergyStorage? = null) : GraphNode<StorageNode, StorageGraph>(::StorageGraph) {
protected val components = ObjectArraySet<IStorage<*>>() protected val components = ObjectArraySet<IStorage<*>>()
@ -19,9 +13,9 @@ open class StorageNode(private val energyDemander: IMatteryEnergyStorage? = null
/** /**
* Setting this to true will render non functional default [attachComponents], * Setting this to true will render non functional default [attachComponents],
* make [addStorageComponent] and [removeStorageComponent] not add/remove components * 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 protected var manualAttaching = false
private var demandingEnergy = 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) { for (component in components) {
graph.remove(component) graph.remove(component)
} }
} }
override fun revive() { override fun onRevived() {
if (!manualAttaching) { if (!manualAttaching) {
for (component in components) { for (component in components) {
graph.add(component) graph.add(component)