More ConfigurableItemHandler tests
This commit is contained in:
parent
5db3d665f0
commit
32da00423e
@ -80,12 +80,12 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
input: IItemHandler? = null,
|
||||
output: IItemHandler? = null,
|
||||
battery: IItemHandler? = null,
|
||||
val frontDefault: ItemHandlerMode = determineDefaultMode(input, output),
|
||||
val backDefault: ItemHandlerMode = determineDefaultMode(input, output),
|
||||
val leftDefault: ItemHandlerMode = determineDefaultMode(input, output),
|
||||
val rightDefault: ItemHandlerMode = determineDefaultMode(input, output),
|
||||
val topDefault: ItemHandlerMode = determineDefaultMode(input, output),
|
||||
val bottomDefault: ItemHandlerMode = determineDefaultMode(input, output),
|
||||
val frontDefault: ItemHandlerMode = determineDefaultMode(input, output, battery, RelativeSide.FRONT),
|
||||
val backDefault: ItemHandlerMode = determineDefaultMode(input, output, battery, RelativeSide.BACK),
|
||||
val leftDefault: ItemHandlerMode = determineDefaultMode(input, output, battery, RelativeSide.LEFT),
|
||||
val rightDefault: ItemHandlerMode = determineDefaultMode(input, output, battery, RelativeSide.RIGHT),
|
||||
val topDefault: ItemHandlerMode = determineDefaultMode(input, output, battery, RelativeSide.TOP),
|
||||
val bottomDefault: ItemHandlerMode = determineDefaultMode(input, output, battery, RelativeSide.BOTTOM),
|
||||
) {
|
||||
val sideless: IItemHandler
|
||||
|
||||
@ -281,15 +281,32 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun determineDefaultMode(input: IItemHandler?, output: IItemHandler?): ItemHandlerMode {
|
||||
if (input == null && output == null)
|
||||
private fun determineDefaultMode(input: IItemHandler?, output: IItemHandler?, battery: IItemHandler?, side: RelativeSide): ItemHandlerMode {
|
||||
if (side == RelativeSide.BACK && battery != null) {
|
||||
return ItemHandlerMode.BATTERY
|
||||
}
|
||||
|
||||
if (input == null && output == null) {
|
||||
return ItemHandlerMode.DISABLED
|
||||
else if (input != null && output != null)
|
||||
return ItemHandlerMode.INPUT_OUTPUT
|
||||
else if (output != null)
|
||||
} else if (input != null && output != null) {
|
||||
return when (side) {
|
||||
RelativeSide.FRONT, RelativeSide.BACK -> ItemHandlerMode.DISABLED
|
||||
RelativeSide.RIGHT, RelativeSide.TOP -> ItemHandlerMode.INPUT
|
||||
RelativeSide.LEFT, RelativeSide.BOTTOM -> ItemHandlerMode.OUTPUT
|
||||
}
|
||||
} else if (output != null) {
|
||||
if (side == RelativeSide.TOP) {
|
||||
return ItemHandlerMode.DISABLED
|
||||
} else {
|
||||
return ItemHandlerMode.OUTPUT
|
||||
else
|
||||
}
|
||||
} else {
|
||||
if (side == RelativeSide.BOTTOM) {
|
||||
return ItemHandlerMode.DISABLED
|
||||
} else {
|
||||
return ItemHandlerMode.INPUT
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import net.minecraftforge.common.util.LazyOptional
|
||||
import ru.dbotthepony.mc.otm.capability.*
|
||||
import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
|
||||
import ru.dbotthepony.mc.otm.capability.energy.ItemEnergyStorageImpl
|
||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.nbt.ifHas
|
||||
@ -28,6 +29,7 @@ import ru.dbotthepony.mc.otm.core.nbt.set
|
||||
|
||||
abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(p_155228_, p_155229_, p_155230_) {
|
||||
val batteryContainer = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
||||
val batteryItemHandler = batteryContainer.handler(HandlerFilter.Dischargeable)
|
||||
|
||||
init {
|
||||
savetable(::batteryContainer, BATTERY_KEY)
|
||||
|
@ -31,33 +31,29 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryDe
|
||||
return ChemicalGeneratorMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
val container = MatteryContainer(this::setChangedLight, SLOTS).also(::addDroppableContainer)
|
||||
val energy = GeneratorEnergyStorage(this::setChangedLight, CAPACITY, THROUGHPUT)
|
||||
val batteryContainer = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
||||
val residueContainer = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
||||
val fuelContainer = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
|
||||
|
||||
val itemHandler = container.handler(object : HandlerFilter {
|
||||
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||
if (slot == SLOT_INPUT)
|
||||
return ForgeHooks.getBurnTime(stack, null) > 0
|
||||
val batteryItemHandler = batteryContainer.handler(HandlerFilter.Chargeable)
|
||||
val residueItemHandler = batteryContainer.handler(HandlerFilter.OnlyOut)
|
||||
val fuelItemHandler = batteryContainer.handler(HandlerFilter.ChemicalFuel)
|
||||
|
||||
if (slot == SLOT_RESIDUE)
|
||||
return false
|
||||
val energy = GeneratorEnergyStorage(::setChangedLight, CAPACITY, THROUGHPUT)
|
||||
|
||||
return stack.getCapability(ForgeCapabilities.ENERGY).isPresent
|
||||
}
|
||||
|
||||
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
|
||||
if (slot == SLOT_RESIDUE) return true
|
||||
|
||||
return slot == SLOT_BATTERY &&
|
||||
(!stack.getCapability(ForgeCapabilities.ENERGY).isPresent || stack.getCapability(ForgeCapabilities.ENERGY).resolve().get().receiveEnergy(Int.MAX_VALUE, true) <= 0)
|
||||
}
|
||||
})
|
||||
val itemConfig = ConfigurableItemHandler(
|
||||
input = fuelItemHandler,
|
||||
output = residueItemHandler,
|
||||
battery = batteryItemHandler,
|
||||
backDefault = ItemHandlerMode.BATTERY)
|
||||
|
||||
init {
|
||||
savetable(::energy, ENERGY_KEY)
|
||||
savetable(::container, INVENTORY_KEY)
|
||||
savetable(::batteryContainer)
|
||||
savetable(::residueContainer)
|
||||
savetable(::fuelContainer)
|
||||
|
||||
exposeEnergyGlobally(energy)
|
||||
exposeItemsGlobally(itemHandler)
|
||||
|
||||
savetables.int(::workTicks, WORK_TICKS_KEY)
|
||||
savetables.int(::workTicksTotal, WORK_TICKS_TOTAL_KEY)
|
||||
@ -107,25 +103,25 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryDe
|
||||
}
|
||||
|
||||
if (workTicks == 0 && !redstoneControl.isBlockedByRedstone && checkFuelSlot) {
|
||||
if (!container[SLOT_INPUT].isEmpty) {
|
||||
val ticks = ForgeHooks.getBurnTime(container[SLOT_INPUT], null)
|
||||
val residue = container[SLOT_INPUT].item.getCraftingRemainingItem(container[SLOT_INPUT].copy().also { it.count = 1 })
|
||||
val canPutResidue = residue.isEmpty || container[SLOT_RESIDUE].isEmpty || ItemStack.isSameItemSameTags(container[SLOT_RESIDUE], residue) && container[SLOT_RESIDUE].count < container[2].maxStackSize
|
||||
if (!fuelContainer[0].isEmpty) {
|
||||
val ticks = ForgeHooks.getBurnTime(fuelContainer[0], null)
|
||||
val residue = fuelContainer[0].item.getCraftingRemainingItem(fuelContainer[0].copy().also { it.count = 1 })
|
||||
val canPutResidue = residue.isEmpty || residueContainer[0].isEmpty || ItemStack.isSameItemSameTags(residueContainer[0], residue) && residueContainer[0].count < residueContainer[0].maxStackSize
|
||||
|
||||
if (canPutResidue && ticks >= 4 && (energy.batteryLevel < Decimal.ONE || GENERATION_SPEED * (ticks / 4) + energy.batteryLevel <= energy.maxBatteryLevel)) {
|
||||
workTicksTotal = ticks / 4
|
||||
workTicks = ticks / 4
|
||||
container[SLOT_INPUT].shrink(1)
|
||||
fuelContainer[0].shrink(1)
|
||||
|
||||
if (!residue.isEmpty) {
|
||||
if (container[SLOT_RESIDUE].isEmpty) {
|
||||
container[SLOT_RESIDUE] = residue
|
||||
if (residueContainer[0].isEmpty) {
|
||||
residueContainer[0] = residue
|
||||
} else {
|
||||
container[SLOT_RESIDUE].count++
|
||||
residueContainer[0].count++
|
||||
}
|
||||
}
|
||||
|
||||
container.setChanged(SLOT_INPUT)
|
||||
fuelContainer.setChanged(0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,7 +130,7 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryDe
|
||||
|
||||
if (energy.batteryLevel.isZero) return
|
||||
|
||||
val item = container[SLOT_BATTERY]
|
||||
val item = batteryContainer[0]
|
||||
|
||||
if (!item.isEmpty) {
|
||||
item.energy?.let(this::workWithPower)
|
||||
@ -155,11 +151,6 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryDe
|
||||
private var _GENERATION_SPEED: DecimalConfigValue by WriteOnce()
|
||||
private var _CAPACITY: DecimalConfigValue by WriteOnce()
|
||||
|
||||
const val SLOT_INPUT = 0
|
||||
const val SLOT_BATTERY = 1
|
||||
const val SLOT_RESIDUE = 2
|
||||
const val SLOTS = 3
|
||||
|
||||
fun registerConfig(builder: ForgeConfigSpec.Builder) {
|
||||
builder.push(MNames.CHEMICAL_GENERATOR)
|
||||
|
||||
|
@ -63,16 +63,6 @@ class ChemicalGeneratorBlock : RotatableMatteryBlock(), EntityBlock {
|
||||
) {
|
||||
super.appendHoverText(itemStack, p_49817_, tooltips, p_49819_)
|
||||
GeneratorEnergyStorage.appendHoverText(itemStack, p_49817_, tooltips, p_49819_)
|
||||
|
||||
val tag = itemStack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag ?: return
|
||||
val container = MatteryContainer(ChemicalGeneratorBlockEntity.SLOTS)
|
||||
tag.map(MatteryBlockEntity.INVENTORY_KEY, container::deserializeNBT)
|
||||
|
||||
if (!container[ChemicalGeneratorBlockEntity.SLOT_BATTERY].isEmpty) {
|
||||
tooltips.add(TranslatableComponent("otm.item.block.stored_battery", container[ChemicalGeneratorBlockEntity.SLOT_BATTERY].displayName).withStyle(ChatFormatting.GRAY))
|
||||
|
||||
ItemEnergyStorageImpl.appendHoverText(container[ChemicalGeneratorBlockEntity.SLOT_BATTERY], tooltips)
|
||||
}
|
||||
}
|
||||
|
||||
private val shapes = getShapeForEachState(rotationProperty) { BlockShapes.CHEMICAL_GENERATOR.rotateFromNorth(it[rotationProperty]).computeShape() }
|
||||
|
@ -34,7 +34,7 @@ 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)
|
||||
makeDeviceControls(this, frame, redstone = menu.redstone, itemConfig = menu.itemConfig)
|
||||
|
||||
return frame
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package ru.dbotthepony.mc.otm.container
|
||||
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.common.ForgeHooks
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||
|
||||
interface HandlerFilter {
|
||||
fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||
@ -35,4 +37,34 @@ interface HandlerFilter {
|
||||
}
|
||||
|
||||
object Both : HandlerFilter
|
||||
|
||||
object Dischargeable : HandlerFilter {
|
||||
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||
return stack.getCapability(ForgeCapabilities.ENERGY).map { it.canExtract() && it.extractEnergy(Int.MAX_VALUE, true) > 0 }.orElse(false)
|
||||
}
|
||||
|
||||
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
|
||||
return stack.getCapability(ForgeCapabilities.ENERGY).map { !it.canExtract() || it.extractEnergy(Int.MAX_VALUE, true) <= 0 }.orElse(true)
|
||||
}
|
||||
}
|
||||
|
||||
object Chargeable : HandlerFilter {
|
||||
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||
return stack.getCapability(ForgeCapabilities.ENERGY).map { it.canReceive() && it.receiveEnergy(Int.MAX_VALUE, true) > 0 }.orElse(false)
|
||||
}
|
||||
|
||||
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
|
||||
return stack.getCapability(ForgeCapabilities.ENERGY).map { !it.canReceive() || it.receiveEnergy(Int.MAX_VALUE, true) <= 0 }.orElse(true)
|
||||
}
|
||||
}
|
||||
|
||||
object ChemicalFuel : HandlerFilter {
|
||||
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
|
||||
return ForgeHooks.getBurnTime(stack, null) <= 0
|
||||
}
|
||||
|
||||
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||
return ForgeHooks.getBurnTime(stack, null) > 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,9 @@ 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 ItemHandlerPlayerInput(val menu: MatteryMenu, val allowPull: Boolean = true, val allowPush: Boolean = true) {
|
||||
inner class Piece(val side: RelativeSide) {
|
||||
private val allowedFlags = MatteryDeviceBlockEntity.ItemHandlerMode.values().map { menu.mSynchronizer.bool() to it }
|
||||
|
@ -11,6 +11,7 @@ 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.input.ItemHandlerPlayerInput
|
||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
|
||||
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
|
||||
import ru.dbotthepony.mc.otm.registry.MMenus
|
||||
@ -19,28 +20,28 @@ class ChemicalGeneratorMenu @JvmOverloads constructor(id: Int, inv: Inventory, t
|
||||
: MatteryMenu(MMenus.CHEMICAL_GENERATOR, id, inv, tile) {
|
||||
|
||||
val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java)
|
||||
val itemConfig = ItemHandlerPlayerInput(this, allowPull = false, allowPush = true)
|
||||
|
||||
init {
|
||||
if (tile != null) {
|
||||
redstone.with(tile.redstoneControl::redstoneSetting)
|
||||
itemConfig.configure(tile.itemConfig)
|
||||
}
|
||||
}
|
||||
|
||||
val container = tile?.container ?: SimpleContainer(3)
|
||||
|
||||
val fuelSlot = object : MatterySlot(container, ChemicalGeneratorBlockEntity.SLOT_INPUT) {
|
||||
val fuelSlot = object : MatterySlot(tile?.fuelContainer ?: SimpleContainer(1), 0) {
|
||||
override fun mayPlace(itemStack: ItemStack): Boolean {
|
||||
return ForgeHooks.getBurnTime(itemStack, null) > 0
|
||||
}
|
||||
}
|
||||
|
||||
val residueSlot = object : MatterySlot(container, ChemicalGeneratorBlockEntity.SLOT_RESIDUE) {
|
||||
val residueSlot = object : MatterySlot(tile?.residueContainer ?: SimpleContainer(1), 0) {
|
||||
override fun mayPlace(itemStack: ItemStack): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
val batterySlot = object : MatterySlot(container, ChemicalGeneratorBlockEntity.SLOT_BATTERY) {
|
||||
val batterySlot = object : MatterySlot(tile?.batteryContainer ?: SimpleContainer(1), 0) {
|
||||
override fun mayPlace(itemStack: ItemStack): Boolean {
|
||||
itemStack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
|
||||
return it.canReceive()
|
||||
@ -54,7 +55,6 @@ 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),
|
||||
|
Loading…
Reference in New Issue
Block a user