Configurable Fluid Handler
This commit is contained in:
parent
e373512a61
commit
068e6ba3f9
@ -659,6 +659,7 @@ private fun gui(provider: MatteryLanguageProvider) {
|
||||
|
||||
gui("sides.item_config", "Item Configuration")
|
||||
gui("sides.energy_config", "Energy Configuration")
|
||||
gui("sides.fluid_config", "Fluid Configuration")
|
||||
|
||||
gui("sides.top", "Top")
|
||||
gui("sides.bottom", "Bottom")
|
||||
|
@ -664,6 +664,7 @@ private fun gui(provider: MatteryLanguageProvider) {
|
||||
|
||||
gui("sides.item_config", "Настройка предметов")
|
||||
gui("sides.energy_config", "Настройка энергии")
|
||||
gui("sides.fluid_config", "Настройка жидкости")
|
||||
|
||||
gui("sides.top", "Верхняя сторона")
|
||||
gui("sides.bottom", "Нижняя сторона")
|
||||
|
@ -13,6 +13,8 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||
import net.minecraftforge.fluids.FluidStack
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler
|
||||
import net.minecraftforge.items.IItemHandler
|
||||
import ru.dbotthepony.mc.otm.capability.CombinedItemHandler
|
||||
import ru.dbotthepony.mc.otm.capability.EmptyItemHandler
|
||||
@ -21,6 +23,7 @@ import ru.dbotthepony.mc.otm.capability.UnmodifiableItemHandler
|
||||
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.moveBetweenSlots
|
||||
import ru.dbotthepony.mc.otm.capability.moveEnergy
|
||||
import ru.dbotthepony.mc.otm.capability.moveFluid
|
||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||
import ru.dbotthepony.mc.otm.core.getValue
|
||||
import ru.dbotthepony.mc.otm.core.ifPresentK
|
||||
@ -84,6 +87,153 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
}
|
||||
}
|
||||
|
||||
inner class ConfigurableFluidHandler<T : IFluidHandler>(
|
||||
val capability: T,
|
||||
|
||||
val possibleModes: FlowDirection = FlowDirection.BI_DIRECTIONAL,
|
||||
|
||||
val frontDefault: FlowDirection = possibleModes,
|
||||
val backDefault: FlowDirection = possibleModes,
|
||||
val leftDefault: FlowDirection = possibleModes,
|
||||
val rightDefault: FlowDirection = possibleModes,
|
||||
val topDefault: FlowDirection = possibleModes,
|
||||
val bottomDefault: FlowDirection = possibleModes,
|
||||
) {
|
||||
init {
|
||||
exposeSideless(ForgeCapabilities.FLUID_HANDLER, capability)
|
||||
}
|
||||
|
||||
val front = Piece(RelativeSide.FRONT).also { it.flow = frontDefault }
|
||||
val back = Piece(RelativeSide.BACK).also { it.flow = backDefault }
|
||||
val left = Piece(RelativeSide.LEFT).also { it.flow = leftDefault }
|
||||
val right = Piece(RelativeSide.RIGHT).also { it.flow = rightDefault }
|
||||
val top = Piece(RelativeSide.TOP).also { it.flow = topDefault }
|
||||
val bottom = Piece(RelativeSide.BOTTOM).also { it.flow = bottomDefault }
|
||||
|
||||
val pieces = immutableMap {
|
||||
put(RelativeSide.FRONT, front)
|
||||
put(RelativeSide.BACK, back)
|
||||
put(RelativeSide.LEFT, left)
|
||||
put(RelativeSide.RIGHT, right)
|
||||
put(RelativeSide.TOP, top)
|
||||
put(RelativeSide.BOTTOM, bottom)
|
||||
}
|
||||
|
||||
val defaults = immutableMap {
|
||||
put(RelativeSide.FRONT, frontDefault)
|
||||
put(RelativeSide.BACK, backDefault)
|
||||
put(RelativeSide.LEFT, leftDefault)
|
||||
put(RelativeSide.RIGHT, rightDefault)
|
||||
put(RelativeSide.TOP, topDefault)
|
||||
put(RelativeSide.BOTTOM, bottomDefault)
|
||||
}
|
||||
|
||||
inner class Piece(val side: RelativeSide) : IFluidHandler, ITickable {
|
||||
init {
|
||||
tickList.always(this)
|
||||
|
||||
// https://tenor.com/view/simp-metal-gear-liquid-snake-running-gif-16717852
|
||||
savetables.enum(::flow, "fluid_${side}_flow", FlowDirection::valueOf)
|
||||
savetables.bool(::automatePull, "fluid_${side}_pull")
|
||||
savetables.bool(::automatePush, "fluid_${side}_push")
|
||||
}
|
||||
|
||||
private val controller = sides[side]!!.Cap(ForgeCapabilities.FLUID_HANDLER, this)
|
||||
private val neighbour by sides[side]!!.track(ForgeCapabilities.FLUID_HANDLER)
|
||||
|
||||
var flow by synchronizer.enum(possibleModes, setter = { value, access, setByRemote ->
|
||||
require(possibleModes.isSupertype(value)) { "Energy mode $value is not allowed (allowed modes: ${possibleModes.family})" }
|
||||
|
||||
if (access.read() != value) {
|
||||
access.write(value)
|
||||
|
||||
if (value == FlowDirection.NONE) {
|
||||
controller.close()
|
||||
} else {
|
||||
controller.close()
|
||||
controller.expose()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// var automatePull by synchronizer.bool().property
|
||||
var automatePull = false
|
||||
// var automatePush by synchronizer.bool().property
|
||||
var automatePush = false
|
||||
|
||||
override fun tick() {
|
||||
if (flow == FlowDirection.NONE || !automatePull && !automatePush || redstoneControl.isBlockedByRedstone)
|
||||
return
|
||||
|
||||
neighbour.ifPresentK {
|
||||
if (flow.input && automatePull) {
|
||||
moveFluid(source = it, destination = capability)
|
||||
}
|
||||
|
||||
if (flow.output && automatePush) {
|
||||
moveFluid(source = capability, destination = it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTanks(): Int {
|
||||
if (flow == FlowDirection.NONE) {
|
||||
return 0
|
||||
} else {
|
||||
return capability.getTanks()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getFluidInTank(tank: Int): FluidStack {
|
||||
if (flow == FlowDirection.NONE) {
|
||||
return FluidStack.EMPTY
|
||||
} else {
|
||||
return capability.getFluidInTank(tank)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTankCapacity(tank: Int): Int {
|
||||
if (flow == FlowDirection.NONE) {
|
||||
return 0
|
||||
} else {
|
||||
return capability.getTankCapacity(tank)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isFluidValid(tank: Int, stack: FluidStack): Boolean {
|
||||
if (flow.input) {
|
||||
return capability.isFluidValid(tank, stack)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
override fun fill(resource: FluidStack, action: IFluidHandler.FluidAction): Int {
|
||||
if (flow.input) {
|
||||
return capability.fill(resource, action)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
override fun drain(resource: FluidStack, action: IFluidHandler.FluidAction): FluidStack {
|
||||
if (flow.output) {
|
||||
return capability.drain(resource, action)
|
||||
} else {
|
||||
return FluidStack.EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
override fun drain(maxDrain: Int, action: IFluidHandler.FluidAction): FluidStack {
|
||||
if (flow.output) {
|
||||
return capability.drain(maxDrain, action)
|
||||
} else {
|
||||
return FluidStack.EMPTY
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class ConfigurableEnergy<T : IMatteryEnergyStorage>(
|
||||
val capability: T,
|
||||
|
||||
@ -129,6 +279,25 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
private val capControllers = exposeEnergy(side, this@Piece)
|
||||
private val neighbour by sides[side]!!.track(ForgeCapabilities.ENERGY)
|
||||
|
||||
override var batteryLevel: Decimal by capability::batteryLevel
|
||||
override val maxBatteryLevel: Decimal by capability::maxBatteryLevel
|
||||
override val missingPower: Decimal by capability::missingPower
|
||||
|
||||
override val canSetBatteryLevel: Boolean by capability::canSetBatteryLevel
|
||||
|
||||
// var automatePull by synchronizer.bool().property
|
||||
var automatePull = false
|
||||
// var automatePush by synchronizer.bool().property
|
||||
var automatePush = false
|
||||
|
||||
init {
|
||||
tickList.always(this)
|
||||
|
||||
savetables.enum(::energyFlow, "energy_${side}_flow", FlowDirection::valueOf)
|
||||
savetables.bool(::automatePull, "energy_${side}_pull")
|
||||
savetables.bool(::automatePush, "energy_${side}_push")
|
||||
}
|
||||
|
||||
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||
return capability.extractEnergy(howMuch, simulate)
|
||||
}
|
||||
@ -151,12 +320,6 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
return Decimal.ZERO
|
||||
}
|
||||
|
||||
override var batteryLevel: Decimal by capability::batteryLevel
|
||||
override val maxBatteryLevel: Decimal by capability::maxBatteryLevel
|
||||
override val missingPower: Decimal by capability::missingPower
|
||||
|
||||
override val canSetBatteryLevel: Boolean by capability::canSetBatteryLevel
|
||||
|
||||
override fun drainBattery(): Boolean {
|
||||
return capability.drainBattery()
|
||||
}
|
||||
@ -180,10 +343,6 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
tickList.always(this)
|
||||
}
|
||||
|
||||
override var energyFlow by synchronizer.enum(possibleModes, setter = { value, access, setByRemote ->
|
||||
require(possibleModes.isSupertype(value)) { "Energy mode $value is not allowed (allowed modes: ${possibleModes.family})" }
|
||||
|
||||
@ -201,15 +360,6 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
var automatePull by synchronizer.bool().property
|
||||
var automatePush by synchronizer.bool().property
|
||||
|
||||
init {
|
||||
savetables.enum(::energyFlow, "energy_${side}_flow", FlowDirection::valueOf)
|
||||
savetables.bool(::automatePull, "energy_${side}_pull")
|
||||
savetables.bool(::automatePush, "energy_${side}_push")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,9 +461,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
put(RelativeSide.BOTTOM, bottomDefault)
|
||||
}
|
||||
|
||||
inner class Piece(
|
||||
val side: RelativeSide,
|
||||
) : IItemHandler, ITickable {
|
||||
inner class Piece(val side: RelativeSide) : IItemHandler, ITickable {
|
||||
private var currentHandler: IItemHandler = EmptyItemHandler
|
||||
private val capController = sides[side]!!.Cap(ForgeCapabilities.ITEM_HANDLER, this)
|
||||
private val neighbour by sides[side]!!.track(ForgeCapabilities.ITEM_HANDLER)
|
||||
@ -346,7 +494,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
}
|
||||
})
|
||||
|
||||
var automatePull by synchronizer.bool(setter = { value, access, _ ->
|
||||
/*var automatePull by synchronizer.bool(setter = { value, access, _ ->
|
||||
if (access.readBoolean() != value) {
|
||||
access.write(value)
|
||||
|
||||
@ -366,7 +514,31 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
outerSlotPush = 0
|
||||
}
|
||||
}
|
||||
}).property
|
||||
}).property*/
|
||||
|
||||
var automatePull = false
|
||||
set(value) {
|
||||
if (field != value) {
|
||||
field = value
|
||||
|
||||
if (value) {
|
||||
innerSlotPush = 0
|
||||
outerSlotPush = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var automatePush = false
|
||||
set(value) {
|
||||
if (field != value) {
|
||||
field = value
|
||||
|
||||
if (value) {
|
||||
innerSlotPush = 0
|
||||
outerSlotPush = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
savetables.bool(::automatePull, "itemhandler_${side}_automatePull")
|
||||
|
@ -62,8 +62,9 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery
|
||||
bottomDefault = ItemHandlerMode.INPUT_OUTPUT,
|
||||
)
|
||||
|
||||
val fluidConfig = ConfigurableFluidHandler(fluid)
|
||||
|
||||
init {
|
||||
exposeGlobally(ForgeCapabilities.FLUID_HANDLER, fluid)
|
||||
savetables.stateful(::fluid, FLUID_KEY)
|
||||
savetables.stateful(::fillInput)
|
||||
savetables.stateful(::drainInput)
|
||||
|
@ -106,6 +106,7 @@ object Widgets18 {
|
||||
val BATTERY_ONLY = controlsGrid.next()
|
||||
val ITEMS_CONFIGURATION = controlsGrid.next()
|
||||
val ENERGY_CONFIGURATION = controlsGrid.next()
|
||||
val FLUID_CONFIGURATION = controlsGrid.next()
|
||||
|
||||
val LEFT_CONTROLS_ITEMS = controls2(LEFT_CONTROLS)
|
||||
val RIGHT_CONTROLS_ITEMS = controls2(RIGHT_CONTROLS)
|
||||
|
@ -30,7 +30,7 @@ class FluidTankScreen(menu: FluidTankMenu, inventory: Inventory, title: Componen
|
||||
|
||||
SlotPanel(this, frame, menu.output, x = 30f + s.width + 4f + 20f, y = 53f)
|
||||
|
||||
makeDeviceControls(this, frame, itemConfig = menu.itemConfig, redstoneConfig = menu.redstoneConfig)
|
||||
makeDeviceControls(this, frame, itemConfig = menu.itemConfig, redstoneConfig = menu.redstoneConfig, fluidConfig = menu.fluidConfig)
|
||||
makeCuriosPanel(this, frame, menu.equipment.curiosSlots, autoAlign = true)
|
||||
|
||||
PlayerEquipmentPanel(this, frame, armorSlots = menu.equipment.armorSlots).also {
|
||||
|
@ -13,6 +13,7 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
||||
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
|
||||
import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput
|
||||
import ru.dbotthepony.mc.otm.menu.input.FluidConfigPlayerInput
|
||||
import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback
|
||||
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
|
||||
import java.util.function.Predicate
|
||||
@ -66,6 +67,18 @@ private fun <S : MatteryScreen<*>> makeEnergyModeButton(screen: S, parent: Frame
|
||||
return button
|
||||
}
|
||||
|
||||
private fun <S : MatteryScreen<*>> makeFluidModeButton(screen: S, parent: FramePanel<S>, input: FluidConfigPlayerInput.Piece, side: RelativeSide): LargeEnumRectangleButtonPanel<S, FlowDirection> {
|
||||
val button = LargeEnumRectangleButtonPanel(screen, parent, enum = FlowDirection::class.java, prop = input.input, defaultValue = input.default)
|
||||
|
||||
for (v in FlowDirection.values()) {
|
||||
button.add(v, skinElement = Widgets18.CONTROLS[side]!![v]!!, tooltip = TranslatableComponent(v.translationKey))
|
||||
}
|
||||
|
||||
button.finish()
|
||||
|
||||
return button
|
||||
}
|
||||
|
||||
private fun moveButtons(
|
||||
front: EditablePanel<*>,
|
||||
back: EditablePanel<*>,
|
||||
@ -191,6 +204,35 @@ private fun <S : MatteryScreen<*>> makeEnergyConfigPanel(
|
||||
return frame
|
||||
}
|
||||
|
||||
private fun <S : MatteryScreen<*>> makeFluidConfigPanel(
|
||||
screen: S,
|
||||
inputs: FluidConfigPlayerInput
|
||||
): FramePanel<S> {
|
||||
val frame = object : FramePanel<S>(screen, 78f, 80f, TranslatableComponent("otm.gui.sides.fluid_config")) {
|
||||
override fun tickInner() {
|
||||
super.tickInner()
|
||||
|
||||
if (!isEverFocused()) {
|
||||
remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val front = makeFluidModeButton(screen, frame, inputs.pieces[RelativeSide.FRONT]!!, RelativeSide.FRONT).also { it.predicate = Predicate { inputs.possibleModes.isSupertype(it) } }
|
||||
val back = makeFluidModeButton(screen, frame, inputs.pieces[RelativeSide.BACK]!!, RelativeSide.BACK).also { it.predicate = Predicate { inputs.possibleModes.isSupertype(it) } }
|
||||
val left = makeFluidModeButton(screen, frame, inputs.pieces[RelativeSide.LEFT]!!, RelativeSide.LEFT).also { it.predicate = Predicate { inputs.possibleModes.isSupertype(it) } }
|
||||
val right = makeFluidModeButton(screen, frame, inputs.pieces[RelativeSide.RIGHT]!!, RelativeSide.RIGHT).also { it.predicate = Predicate { inputs.possibleModes.isSupertype(it) } }
|
||||
val top = makeFluidModeButton(screen, frame, inputs.pieces[RelativeSide.TOP]!!, RelativeSide.TOP).also { it.predicate = Predicate { inputs.possibleModes.isSupertype(it) } }
|
||||
val bottom = makeFluidModeButton(screen, frame, inputs.pieces[RelativeSide.BOTTOM]!!, RelativeSide.BOTTOM).also { it.predicate = Predicate { inputs.possibleModes.isSupertype(it) } }
|
||||
|
||||
pullPush(frame, inputs.pull, inputs.push)
|
||||
moveButtons(front, back, left, right, top, bottom)
|
||||
screen.addPanel(frame)
|
||||
frame.requestFocus()
|
||||
|
||||
return frame
|
||||
}
|
||||
|
||||
class DeviceControls<out S : MatteryScreen<*>>(
|
||||
screen: S,
|
||||
parent: FramePanel<S>,
|
||||
@ -198,9 +240,11 @@ class DeviceControls<out S : MatteryScreen<*>>(
|
||||
val redstoneConfig: IPlayerInputWithFeedback<RedstoneSetting>? = null,
|
||||
val itemConfig: ItemConfigPlayerInput? = null,
|
||||
val energyConfig: EnergyConfigPlayerInput? = null,
|
||||
val fluidConfig: FluidConfigPlayerInput? = null,
|
||||
) : EditablePanel<S>(screen, parent, x = parent.width + 3f, height = 0f, width = 0f) {
|
||||
val itemConfigButton: LargeRectangleButtonPanel<S>?
|
||||
val energyConfigButton: LargeRectangleButtonPanel<S>?
|
||||
val fluidConfigButton: LargeRectangleButtonPanel<S>?
|
||||
val redstoneControlsButton: LargeEnumRectangleButtonPanel<S, RedstoneSetting>?
|
||||
private var nextY = 0f
|
||||
|
||||
@ -262,6 +306,25 @@ class DeviceControls<out S : MatteryScreen<*>>(
|
||||
} else {
|
||||
energyConfigButton = null
|
||||
}
|
||||
|
||||
if (fluidConfig != null) {
|
||||
fluidConfigButton = addButton(object : LargeRectangleButtonPanel<S>(screen, this@DeviceControls, y = nextY, skinElement = Widgets18.FLUID_CONFIGURATION) {
|
||||
init {
|
||||
tooltip = TranslatableComponent("otm.gui.sides.fluid_config")
|
||||
}
|
||||
|
||||
override fun onClick(mouseButton: Int) {
|
||||
if (mouseButton == InputConstants.MOUSE_BUTTON_LEFT) {
|
||||
val frame = makeFluidConfigPanel(screen, fluidConfig)
|
||||
|
||||
frame.x = absoluteX + width / 2f - frame.width / 2f
|
||||
frame.y = absoluteY + height + 8f
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
fluidConfigButton = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun tickInner() {
|
||||
@ -278,6 +341,7 @@ fun <S : MatteryScreen<*>> makeDeviceControls(
|
||||
redstoneConfig: IPlayerInputWithFeedback<RedstoneSetting>? = null,
|
||||
itemConfig: ItemConfigPlayerInput? = null,
|
||||
energyConfig: EnergyConfigPlayerInput? = null,
|
||||
fluidConfig: FluidConfigPlayerInput? = null,
|
||||
): DeviceControls<S> {
|
||||
return DeviceControls(screen, parent, extra = extra, redstoneConfig = redstoneConfig, itemConfig = itemConfig, energyConfig = energyConfig)
|
||||
return DeviceControls(screen, parent, extra = extra, redstoneConfig = redstoneConfig, itemConfig = itemConfig, energyConfig = energyConfig, fluidConfig = fluidConfig)
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ import kotlin.reflect.KProperty0
|
||||
class Savetables : INBTSerializable<CompoundTag?> {
|
||||
private val entries = ArrayList<Entry<*, *>>()
|
||||
|
||||
interface Entry<V : Any?, T : Tag?> : INBTSerializable<T?> {
|
||||
sealed interface Entry<V : Any?, T : Tag?> : INBTSerializable<T?> {
|
||||
val name: String
|
||||
val type: Class<T>
|
||||
fun validate()
|
||||
|
@ -13,6 +13,7 @@ import ru.dbotthepony.mc.otm.menu.MachineOutputSlot
|
||||
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.input.FluidConfigPlayerInput
|
||||
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
|
||||
import ru.dbotthepony.mc.otm.menu.widget.FluidGaugeWidget
|
||||
import ru.dbotthepony.mc.otm.registry.MMenus
|
||||
@ -22,6 +23,7 @@ class FluidTankMenu(containerId: Int, inventory: Inventory, tile: FluidTankBlock
|
||||
val equipment = makeEquipmentSlots(true)
|
||||
val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig)
|
||||
val redstoneConfig = EnumInputWithFeedback<RedstoneSetting>(this)
|
||||
val fluidConfig = FluidConfigPlayerInput(this, tile?.fluidConfig)
|
||||
|
||||
val drainInput = object : MatterySlot(tile?.drainInput ?: SimpleContainer(1), 0) {
|
||||
override fun mayPlace(itemStack: ItemStack): Boolean {
|
||||
|
@ -0,0 +1,68 @@
|
||||
package ru.dbotthepony.mc.otm.menu.input
|
||||
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.core.immutableMap
|
||||
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||
|
||||
/**
|
||||
* [allowPull] and [allowPush] controls whenever player is allowed to change these options
|
||||
*/
|
||||
class FluidConfigPlayerInput(val menu: MatteryMenu, config: MatteryDeviceBlockEntity.ConfigurableFluidHandler<*>? = null, val allowPull: Boolean = false, val allowPush: Boolean = false) {
|
||||
var possibleModes by menu.mSynchronizer.enum(FlowDirection::class.java)
|
||||
private set
|
||||
|
||||
inner class Piece(val side: RelativeSide) {
|
||||
val pull = BooleanInputWithFeedback(menu)
|
||||
val push = BooleanInputWithFeedback(menu)
|
||||
val input = EnumInputWithFeedback<FlowDirection>(menu)
|
||||
|
||||
var default by menu.mSynchronizer.enum(FlowDirection.NONE)
|
||||
|
||||
init {
|
||||
pull.filter { allowPull }
|
||||
push.filter { allowPush }
|
||||
}
|
||||
|
||||
fun with(config: MatteryDeviceBlockEntity.ConfigurableFluidHandler<*>.Piece, parent: MatteryDeviceBlockEntity.ConfigurableFluidHandler<*>) {
|
||||
pull.with(config::automatePull)
|
||||
push.with(config::automatePush)
|
||||
input.withSupplier { config.flow }.withConsumer { if (parent.possibleModes.isSupertype(it)) config.flow = it }
|
||||
}
|
||||
}
|
||||
|
||||
val pieces = immutableMap { for (side in RelativeSide.values()) put(side, Piece(side)) }
|
||||
|
||||
// TODO
|
||||
val pull = BooleanInputWithFeedback(menu)
|
||||
|
||||
// TODO
|
||||
val push = BooleanInputWithFeedback(menu)
|
||||
|
||||
init {
|
||||
pull.filter { allowPull }
|
||||
push.filter { allowPush }
|
||||
}
|
||||
|
||||
fun with(config: MatteryDeviceBlockEntity.ConfigurableFluidHandler<*>) {
|
||||
possibleModes = config.possibleModes
|
||||
|
||||
for ((side, v) in config.pieces) {
|
||||
pieces[side]!!.with(v, config)
|
||||
pieces[side]!!.default = config.defaults[side]!!
|
||||
}
|
||||
|
||||
pull.withSupplier { pieces.values.all { it.pull.value } }
|
||||
push.withSupplier { pieces.values.all { it.push.value } }
|
||||
|
||||
pull.withConsumer { v -> pieces.values.forEach { it.pull.input.invoke(v) } }
|
||||
push.withConsumer { v -> pieces.values.forEach { it.push.input.invoke(v) } }
|
||||
}
|
||||
|
||||
init {
|
||||
if (config != null) {
|
||||
with(config)
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
Loading…
Reference in New Issue
Block a user